SemaDeclAttr.cpp revision aa0d25b44e510a5a62e7345f4fa3840a886841d2
1//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements decl-related attribute processing. 11// 12//===----------------------------------------------------------------------===// 13 14#include "Sema.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/DeclObjC.h" 17#include "clang/AST/Expr.h" 18#include "clang/Basic/Diagnostic.h" 19#include "clang/Basic/TargetInfo.h" 20#include "clang/Parse/DeclSpec.h" 21#include <llvm/ADT/StringExtras.h> 22using namespace clang; 23 24//===----------------------------------------------------------------------===// 25// Helper functions 26//===----------------------------------------------------------------------===// 27 28static const FunctionTypeProto *getFunctionProto(Decl *d) { 29 QualType Ty; 30 if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 31 Ty = decl->getType(); 32 else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 33 Ty = decl->getType(); 34 else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 35 Ty = decl->getUnderlyingType(); 36 else 37 return 0; 38 39 if (Ty->isFunctionPointerType()) 40 Ty = Ty->getAsPointerType()->getPointeeType(); 41 42 if (const FunctionType *FnTy = Ty->getAsFunctionType()) 43 return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType()); 44 45 return 0; 46} 47 48static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 49 const PointerType *PT = T->getAsPointerType(); 50 if (!PT) 51 return false; 52 53 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 54 if (!ClsT) 55 return false; 56 57 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 58 59 // FIXME: Should we walk the chain of classes? 60 return ClsName == &Ctx.Idents.get("NSString") || 61 ClsName == &Ctx.Idents.get("NSMutableString"); 62} 63 64//===----------------------------------------------------------------------===// 65// Attribute Implementations 66//===----------------------------------------------------------------------===// 67 68// FIXME: All this manual attribute parsing code is gross. At the 69// least add some helper functions to check most argument patterns (# 70// and types of args). 71 72static void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 73 Sema &S) { 74 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 75 if (tDecl == 0) { 76 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 77 return; 78 } 79 80 QualType curType = tDecl->getUnderlyingType(); 81 // check the attribute arguments. 82 if (Attr.getNumArgs() != 1) { 83 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 84 std::string("1")); 85 return; 86 } 87 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 88 llvm::APSInt vecSize(32); 89 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 90 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 91 "ext_vector_type", sizeExpr->getSourceRange()); 92 return; 93 } 94 // unlike gcc's vector_size attribute, we do not allow vectors to be defined 95 // in conjunction with complex types (pointers, arrays, functions, etc.). 96 if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 97 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 98 curType.getAsString()); 99 return; 100 } 101 // unlike gcc's vector_size attribute, the size is specified as the 102 // number of elements, not the number of bytes. 103 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 104 105 if (vectorSize == 0) { 106 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 107 sizeExpr->getSourceRange()); 108 return; 109 } 110 // Instantiate/Install the vector type, the number of elements is > 0. 111 tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 112 // Remember this typedef decl, we will need it later for diagnostics. 113 S.ExtVectorDecls.push_back(tDecl); 114} 115 116 117/// HandleVectorSizeAttribute - this attribute is only applicable to 118/// integral and float scalars, although arrays, pointers, and function 119/// return values are allowed in conjunction with this construct. Aggregates 120/// with this attribute are invalid, even if they are of the same size as a 121/// corresponding scalar. 122/// The raw attribute should contain precisely 1 argument, the vector size 123/// for the variable, measured in bytes. If curType and rawAttr are well 124/// formed, this routine will return a new vector type. 125static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 126 QualType CurType; 127 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 128 CurType = VD->getType(); 129 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 130 CurType = TD->getUnderlyingType(); 131 else { 132 S.Diag(D->getLocation(), diag::err_attr_wrong_decl, 133 std::string("vector_size"), 134 SourceRange(Attr.getLoc(), Attr.getLoc())); 135 return; 136 } 137 138 // Check the attribute arugments. 139 if (Attr.getNumArgs() != 1) { 140 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 141 std::string("1")); 142 return; 143 } 144 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 145 llvm::APSInt vecSize(32); 146 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 147 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 148 "vector_size", sizeExpr->getSourceRange()); 149 return; 150 } 151 // navigate to the base type - we need to provide for vector pointers, 152 // vector arrays, and functions returning vectors. 153 if (CurType->isPointerType() || CurType->isArrayType() || 154 CurType->isFunctionType()) { 155 assert(0 && "HandleVector(): Complex type construction unimplemented"); 156 /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 157 do { 158 if (PointerType *PT = dyn_cast<PointerType>(canonType)) 159 canonType = PT->getPointeeType().getTypePtr(); 160 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 161 canonType = AT->getElementType().getTypePtr(); 162 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 163 canonType = FT->getResultType().getTypePtr(); 164 } while (canonType->isPointerType() || canonType->isArrayType() || 165 canonType->isFunctionType()); 166 */ 167 } 168 // the base type must be integer or float. 169 if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) { 170 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 171 CurType.getAsString()); 172 return; 173 } 174 unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 175 // vecSize is specified in bytes - convert to bits. 176 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 177 178 // the vector size needs to be an integral multiple of the type size. 179 if (vectorSize % typeSize) { 180 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size, 181 sizeExpr->getSourceRange()); 182 return; 183 } 184 if (vectorSize == 0) { 185 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 186 sizeExpr->getSourceRange()); 187 return; 188 } 189 190 // Success! Instantiate the vector type, the number of elements is > 0, and 191 // not required to be a power of 2, unlike GCC. 192 CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 193 194 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 195 VD->setType(CurType); 196 else 197 cast<TypedefDecl>(D)->setUnderlyingType(CurType); 198} 199 200static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 201 // check the attribute arguments. 202 if (Attr.getNumArgs() > 0) { 203 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 204 std::string("0")); 205 return; 206 } 207 208 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 209 TD->addAttr(new PackedAttr()); 210 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 211 // If the alignment is less than or equal to 8 bits, the packed attribute 212 // has no effect. 213 if (!FD->getType()->isIncompleteType() && 214 S.Context.getTypeAlign(FD->getType()) <= 8) 215 S.Diag(Attr.getLoc(), 216 diag::warn_attribute_ignored_for_field_of_type, 217 Attr.getName()->getName(), FD->getType().getAsString()); 218 else 219 FD->addAttr(new PackedAttr()); 220 } else 221 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored, 222 Attr.getName()->getName()); 223} 224 225static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 226 // check the attribute arguments. 227 if (Attr.getNumArgs() > 0) { 228 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 229 std::string("0")); 230 return; 231 } 232 233 // The IBOutlet attribute only applies to instance variables of Objective-C 234 // classes. 235 if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d)) 236 ID->addAttr(new IBOutletAttr()); 237 else 238 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar); 239} 240 241static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 242 243 // GCC ignores the nonnull attribute on K&R style function 244 // prototypes, so we ignore it as well 245 const FunctionTypeProto *proto = getFunctionProto(d); 246 if (!proto) { 247 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 248 "nonnull", "function"); 249 return; 250 } 251 252 unsigned NumArgs = proto->getNumArgs(); 253 254 // The nonnull attribute only applies to pointers. 255 llvm::SmallVector<unsigned, 10> NonNullArgs; 256 257 for (AttributeList::arg_iterator I=Attr.arg_begin(), 258 E=Attr.arg_end(); I!=E; ++I) { 259 260 261 // The argument must be an integer constant expression. 262 Expr *Ex = static_cast<Expr *>(Attr.getArg(0)); 263 llvm::APSInt ArgNum(32); 264 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 265 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 266 "nonnull", Ex->getSourceRange()); 267 return; 268 } 269 270 unsigned x = (unsigned) ArgNum.getZExtValue(); 271 272 if (x < 1 || x > NumArgs) { 273 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 274 "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange()); 275 return; 276 } 277 278 --x; 279 280 // Is the function argument a pointer type? 281 if (!proto->getArgType(x)->isPointerType()) { 282 // FIXME: Should also highlight argument in decl. 283 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only, 284 "nonnull", Ex->getSourceRange()); 285 return; 286 } 287 288 NonNullArgs.push_back(x); 289 } 290 291 if (!NonNullArgs.empty()) { 292 unsigned* start = &NonNullArgs[0]; 293 unsigned size = NonNullArgs.size(); 294 std::sort(start, start + size); 295 d->addAttr(new NonNullAttr(start, size)); 296 } 297 else 298 d->addAttr(new NonNullAttr()); 299} 300 301static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 302 // check the attribute arguments. 303 if (Attr.getNumArgs() != 1) { 304 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 305 std::string("1")); 306 return; 307 } 308 309 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 310 Arg = Arg->IgnoreParenCasts(); 311 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 312 313 if (Str == 0 || Str->isWide()) { 314 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 315 "alias", std::string("1")); 316 return; 317 } 318 319 const char *Alias = Str->getStrData(); 320 unsigned AliasLen = Str->getByteLength(); 321 322 // FIXME: check if target symbol exists in current file 323 324 d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 325} 326 327static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 328 // check the attribute arguments. 329 if (Attr.getNumArgs() != 0) { 330 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 331 std::string("0")); 332 return; 333 } 334 335 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 336 if (!Fn) { 337 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 338 "noreturn", "function"); 339 return; 340 } 341 342 d->addAttr(new NoReturnAttr()); 343} 344 345static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 346 // check the attribute arguments. 347 if (Attr.getNumArgs() != 0) { 348 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 349 std::string("0")); 350 return; 351 } 352 353 if (!isa<VarDecl>(d) && !getFunctionProto(d)) { 354 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 355 "unused", "variable and function"); 356 return; 357 } 358 359 d->addAttr(new UnusedAttr()); 360} 361 362static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 363 // check the attribute arguments. 364 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 365 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 366 return; 367 } 368 369 int priority = 65535; // FIXME: Do not hardcode such constants. 370 if (Attr.getNumArgs() > 0) { 371 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 372 llvm::APSInt Idx(32); 373 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 374 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 375 "constructor", "1", E->getSourceRange()); 376 return; 377 } 378 priority = Idx.getZExtValue(); 379 } 380 381 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 382 if (!Fn) { 383 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 384 "constructor", "function"); 385 return; 386 } 387 388 d->addAttr(new ConstructorAttr(priority)); 389} 390 391static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 392 // check the attribute arguments. 393 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 394 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 395 return; 396 } 397 398 int priority = 65535; // FIXME: Do not hardcode such constants. 399 if (Attr.getNumArgs() > 0) { 400 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 401 llvm::APSInt Idx(32); 402 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 403 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 404 "destructor", "1", E->getSourceRange()); 405 return; 406 } 407 priority = Idx.getZExtValue(); 408 } 409 410 if (!isa<FunctionDecl>(d)) { 411 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 412 "destructor", "function"); 413 return; 414 } 415 416 d->addAttr(new DestructorAttr(priority)); 417} 418 419static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 420 // check the attribute arguments. 421 if (Attr.getNumArgs() != 0) { 422 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 423 std::string("0")); 424 return; 425 } 426 427 d->addAttr(new DeprecatedAttr()); 428} 429 430static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 431 // check the attribute arguments. 432 if (Attr.getNumArgs() != 1) { 433 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 434 std::string("1")); 435 return; 436 } 437 438 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 439 Arg = Arg->IgnoreParenCasts(); 440 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 441 442 if (Str == 0 || Str->isWide()) { 443 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 444 "visibility", std::string("1")); 445 return; 446 } 447 448 const char *TypeStr = Str->getStrData(); 449 unsigned TypeLen = Str->getByteLength(); 450 VisibilityAttr::VisibilityTypes type; 451 452 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 453 type = VisibilityAttr::DefaultVisibility; 454 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 455 type = VisibilityAttr::HiddenVisibility; 456 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 457 type = VisibilityAttr::HiddenVisibility; // FIXME 458 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 459 type = VisibilityAttr::ProtectedVisibility; 460 else { 461 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 462 "visibility", TypeStr); 463 return; 464 } 465 466 d->addAttr(new VisibilityAttr(type)); 467} 468 469static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { 470 if (!Attr.getParameterName()) { 471 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 472 "objc_gc", std::string("1")); 473 return; 474 } 475 476 if (Attr.getNumArgs() != 0) { 477 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 478 std::string("1")); 479 return; 480 } 481 482 const char *TypeStr = Attr.getParameterName()->getName(); 483 unsigned TypeLen = Attr.getParameterName()->getLength(); 484 485 ObjCGCAttr::GCAttrTypes type; 486 487 if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4)) 488 type = ObjCGCAttr::Weak; 489 else if (TypeLen == 5 && !memcmp(TypeStr, "strong", 5)) 490 type = ObjCGCAttr::Strong; 491 else { 492 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 493 "objc_gc", TypeStr); 494 return; 495 } 496 497 d->addAttr(new ObjCGCAttr(type)); 498} 499 500static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 501 // check the attribute arguments. 502 if (Attr.getNumArgs() != 0) { 503 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 504 std::string("0")); 505 return; 506 } 507 508 d->addAttr(new WeakAttr()); 509} 510 511static void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 512 // check the attribute arguments. 513 if (Attr.getNumArgs() != 0) { 514 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 515 std::string("0")); 516 return; 517 } 518 519 d->addAttr(new DLLImportAttr()); 520} 521 522static void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 523 // check the attribute arguments. 524 if (Attr.getNumArgs() != 0) { 525 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 526 std::string("0")); 527 return; 528 } 529 530 d->addAttr(new DLLExportAttr()); 531} 532 533static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 534 // check the attribute arguments. 535 if (Attr.getNumArgs() != 0) { 536 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 537 std::string("0")); 538 return; 539 } 540 541 d->addAttr(new StdCallAttr()); 542} 543 544static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 545 // check the attribute arguments. 546 if (Attr.getNumArgs() != 0) { 547 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 548 std::string("0")); 549 return; 550 } 551 552 d->addAttr(new FastCallAttr()); 553} 554 555static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 556 // check the attribute arguments. 557 if (Attr.getNumArgs() != 0) { 558 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 559 std::string("0")); 560 return; 561 } 562 563 d->addAttr(new NoThrowAttr()); 564} 565 566/// Handle __attribute__((format(type,idx,firstarg))) attributes 567/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 568static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 569 570 if (!Attr.getParameterName()) { 571 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 572 "format", std::string("1")); 573 return; 574 } 575 576 if (Attr.getNumArgs() != 2) { 577 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 578 std::string("3")); 579 return; 580 } 581 582 // GCC ignores the format attribute on K&R style function 583 // prototypes, so we ignore it as well 584 const FunctionTypeProto *proto = getFunctionProto(d); 585 586 if (!proto) { 587 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 588 "format", "function"); 589 return; 590 } 591 592 // FIXME: in C++ the implicit 'this' function parameter also counts. 593 // this is needed in order to be compatible with GCC 594 // the index must start in 1 and the limit is numargs+1 595 unsigned NumArgs = proto->getNumArgs(); 596 unsigned FirstIdx = 1; 597 598 const char *Format = Attr.getParameterName()->getName(); 599 unsigned FormatLen = Attr.getParameterName()->getLength(); 600 601 // Normalize the argument, __foo__ becomes foo. 602 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 603 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 604 Format += 2; 605 FormatLen -= 4; 606 } 607 608 bool Supported = false; 609 bool is_NSString = false; 610 bool is_strftime = false; 611 612 switch (FormatLen) { 613 default: break; 614 case 5: Supported = !memcmp(Format, "scanf", 5); break; 615 case 6: Supported = !memcmp(Format, "printf", 6); break; 616 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 617 case 8: 618 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 619 (is_NSString = !memcmp(Format, "NSString", 8)); 620 break; 621 } 622 623 if (!Supported) { 624 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 625 "format", Attr.getParameterName()->getName()); 626 return; 627 } 628 629 // checks for the 2nd argument 630 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 631 llvm::APSInt Idx(32); 632 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 633 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 634 "format", std::string("2"), IdxExpr->getSourceRange()); 635 return; 636 } 637 638 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 639 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 640 "format", std::string("2"), IdxExpr->getSourceRange()); 641 return; 642 } 643 644 // FIXME: Do we need to bounds check? 645 unsigned ArgIdx = Idx.getZExtValue() - 1; 646 647 // make sure the format string is really a string 648 QualType Ty = proto->getArgType(ArgIdx); 649 650 if (is_NSString) { 651 // FIXME: do we need to check if the type is NSString*? What are 652 // the semantics? 653 if (!isNSStringType(Ty, S.Context)) { 654 // FIXME: Should highlight the actual expression that has the 655 // wrong type. 656 S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString, 657 IdxExpr->getSourceRange()); 658 return; 659 } 660 } else if (!Ty->isPointerType() || 661 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 662 // FIXME: Should highlight the actual expression that has the 663 // wrong type. 664 S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string, 665 IdxExpr->getSourceRange()); 666 return; 667 } 668 669 // check the 3rd argument 670 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 671 llvm::APSInt FirstArg(32); 672 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 673 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 674 "format", std::string("3"), FirstArgExpr->getSourceRange()); 675 return; 676 } 677 678 // check if the function is variadic if the 3rd argument non-zero 679 if (FirstArg != 0) { 680 if (proto->isVariadic()) { 681 ++NumArgs; // +1 for ... 682 } else { 683 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 684 return; 685 } 686 } 687 688 // strftime requires FirstArg to be 0 because it doesn't read from any variable 689 // the input is just the current time + the format string 690 if (is_strftime) { 691 if (FirstArg != 0) { 692 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 693 FirstArgExpr->getSourceRange()); 694 return; 695 } 696 // if 0 it disables parameter checking (to use with e.g. va_list) 697 } else if (FirstArg != 0 && FirstArg != NumArgs) { 698 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 699 "format", std::string("3"), FirstArgExpr->getSourceRange()); 700 return; 701 } 702 703 d->addAttr(new FormatAttr(std::string(Format, FormatLen), 704 Idx.getZExtValue(), FirstArg.getZExtValue())); 705} 706 707static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 708 Sema &S) { 709 // check the attribute arguments. 710 if (Attr.getNumArgs() != 0) { 711 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 712 std::string("0")); 713 return; 714 } 715 716 TypeDecl *decl = dyn_cast<TypeDecl>(d); 717 718 if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) { 719 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 720 "transparent_union", "union"); 721 return; 722 } 723 724 //QualType QTy = Context.getTypeDeclType(decl); 725 //const RecordType *Ty = QTy->getAsUnionType(); 726 727// FIXME 728// Ty->addAttr(new TransparentUnionAttr()); 729} 730 731static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 732 // check the attribute arguments. 733 if (Attr.getNumArgs() != 1) { 734 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 735 std::string("1")); 736 return; 737 } 738 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 739 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 740 741 // Make sure that there is a string literal as the annotation's single 742 // argument. 743 if (!SE) { 744 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 745 return; 746 } 747 d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 748 SE->getByteLength()))); 749} 750 751static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 752 // check the attribute arguments. 753 if (Attr.getNumArgs() > 1) { 754 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 755 std::string("1")); 756 return; 757 } 758 759 unsigned Align = 0; 760 if (Attr.getNumArgs() == 0) { 761 // FIXME: This should be the target specific maximum alignment. 762 // (For now we just use 128 bits which is the maximum on X86. 763 Align = 128; 764 return; 765 } 766 767 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 768 llvm::APSInt Alignment(32); 769 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 770 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 771 "aligned", alignmentExpr->getSourceRange()); 772 return; 773 } 774 d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 775} 776 777/// HandleModeAttr - This attribute modifies the width of a decl with 778/// primitive type. 779/// 780/// Despite what would be logical, the mode attribute is a decl attribute, 781/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 782/// 'G' be HImode, not an intermediate pointer. 783/// 784static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 785 // This attribute isn't documented, but glibc uses it. It changes 786 // the width of an int or unsigned int to the specified size. 787 788 // Check that there aren't any arguments 789 if (Attr.getNumArgs() != 0) { 790 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 791 std::string("0")); 792 return; 793 } 794 795 IdentifierInfo *Name = Attr.getParameterName(); 796 if (!Name) { 797 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 798 return; 799 } 800 const char *Str = Name->getName(); 801 unsigned Len = Name->getLength(); 802 803 // Normalize the attribute name, __foo__ becomes foo. 804 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 805 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 806 Str += 2; 807 Len -= 4; 808 } 809 810 unsigned DestWidth = 0; 811 bool IntegerMode = true; 812 switch (Len) { 813 case 2: 814 if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 815 if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 816 if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 817 if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 818 if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 819 if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 820 if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 821 if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 822 if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 823 break; 824 case 4: 825 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 826 // pointer on PIC16 and other embedded platforms. 827 if (!memcmp(Str, "word", 4)) 828 DestWidth = S.Context.Target.getPointerWidth(0); 829 if (!memcmp(Str, "byte", 4)) 830 DestWidth = S.Context.Target.getCharWidth(); 831 break; 832 case 7: 833 if (!memcmp(Str, "pointer", 7)) 834 DestWidth = S.Context.Target.getPointerWidth(0); 835 break; 836 } 837 838 QualType OldTy; 839 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 840 OldTy = TD->getUnderlyingType(); 841 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 842 OldTy = VD->getType(); 843 else { 844 S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 845 SourceRange(Attr.getLoc(), Attr.getLoc())); 846 return; 847 } 848 849 // FIXME: Need proper fixed-width types 850 QualType NewTy; 851 switch (DestWidth) { 852 case 0: 853 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 854 return; 855 default: 856 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 857 return; 858 case 8: 859 assert(IntegerMode); 860 if (OldTy->isSignedIntegerType()) 861 NewTy = S.Context.SignedCharTy; 862 else 863 NewTy = S.Context.UnsignedCharTy; 864 break; 865 case 16: 866 assert(IntegerMode); 867 if (OldTy->isSignedIntegerType()) 868 NewTy = S.Context.ShortTy; 869 else 870 NewTy = S.Context.UnsignedShortTy; 871 break; 872 case 32: 873 if (!IntegerMode) 874 NewTy = S.Context.FloatTy; 875 else if (OldTy->isSignedIntegerType()) 876 NewTy = S.Context.IntTy; 877 else 878 NewTy = S.Context.UnsignedIntTy; 879 break; 880 case 64: 881 if (!IntegerMode) 882 NewTy = S.Context.DoubleTy; 883 else if (OldTy->isSignedIntegerType()) 884 NewTy = S.Context.LongLongTy; 885 else 886 NewTy = S.Context.UnsignedLongLongTy; 887 break; 888 } 889 890 if (!OldTy->getAsBuiltinType()) 891 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 892 else if (!(IntegerMode && OldTy->isIntegerType()) && 893 !(!IntegerMode && OldTy->isFloatingType())) { 894 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 895 } 896 897 // Install the new type. 898 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 899 TD->setUnderlyingType(NewTy); 900 else 901 cast<ValueDecl>(D)->setType(NewTy); 902} 903 904//===----------------------------------------------------------------------===// 905// Top Level Sema Entry Points 906//===----------------------------------------------------------------------===// 907 908/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 909/// the attribute applies to decls. If the attribute is a type attribute, just 910/// silently ignore it. 911static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 912 switch (Attr.getKind()) { 913 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 914 case AttributeList::AT_address_space: 915 // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 916 break; 917 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 918 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 919 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 920 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 921 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 922 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 923 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 924 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 925 case AttributeList::AT_ext_vector_type: 926 HandleExtVectorTypeAttr(D, Attr, S); 927 break; 928 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 929 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 930 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 931 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 932 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 933 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 934 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 935 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 936 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 937 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 938 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 939 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 940 case AttributeList::AT_transparent_union: 941 HandleTransparentUnionAttr(D, Attr, S); 942 break; 943 case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; 944 default: 945#if 0 946 // TODO: when we have the full set of attributes, warn about unknown ones. 947 S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 948 Attr->getName()->getName()); 949#endif 950 break; 951 } 952} 953 954/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 955/// attribute list to the specified decl, ignoring any type attributes. 956void Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 957 while (AttrList) { 958 ProcessDeclAttribute(D, *AttrList, *this); 959 AttrList = AttrList->getNext(); 960 } 961} 962 963 964/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 965/// it, apply them to D. This is a bit tricky because PD can have attributes 966/// specified in many different places, and we need to find and apply them all. 967void Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 968 // Apply decl attributes from the DeclSpec if present. 969 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 970 ProcessDeclAttributeList(D, Attrs); 971 972 // Walk the declarator structure, applying decl attributes that were in a type 973 // position to the decl itself. This handles cases like: 974 // int *__attr__(x)** D; 975 // when X is a decl attribute. 976 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 977 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 978 ProcessDeclAttributeList(D, Attrs); 979 980 // Finally, apply any attributes on the decl itself. 981 if (const AttributeList *Attrs = PD.getAttributes()) 982 ProcessDeclAttributeList(D, Attrs); 983} 984 985