SemaDeclAttr.cpp revision bf91650557d9afa08e3d311a9c0a10d73c62cbfc
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/TargetInfo.h" 19#include "clang/Parse/DeclSpec.h" 20#include <llvm/ADT/StringExtras.h> 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// Helper functions 25//===----------------------------------------------------------------------===// 26 27static const FunctionType *getFunctionType(Decl *d, bool blocksToo = true) { 28 QualType Ty; 29 if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 30 Ty = decl->getType(); 31 else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 32 Ty = decl->getType(); 33 else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 34 Ty = decl->getUnderlyingType(); 35 else 36 return 0; 37 38 if (Ty->isFunctionPointerType()) 39 Ty = Ty->getAsPointerType()->getPointeeType(); 40 else if (blocksToo && Ty->isBlockPointerType()) 41 Ty = Ty->getAsBlockPointerType()->getPointeeType(); 42 43 return Ty->getAsFunctionType(); 44} 45 46// FIXME: We should provide an abstraction around a method or function 47// to provide the following bits of information. 48 49/// isFunctionOrMethod - Return true if the given decl has function 50/// type (function or function-typed variable) or an Objective-C 51/// method. 52static bool isFunctionOrMethod(Decl *d) { 53 return getFunctionType(d, false) || isa<ObjCMethodDecl>(d); 54} 55 56/// isFunctionOrMethodOrBlock - Return true if the given decl has function 57/// type (function or function-typed variable) or an Objective-C 58/// method or a block. 59static bool isFunctionOrMethodOrBlock(Decl *d) { 60 if (isFunctionOrMethod(d)) 61 return true; 62 // check for block is more involved. 63 if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 64 QualType Ty = V->getType(); 65 return Ty->isBlockPointerType(); 66 } 67 return isa<BlockDecl>(d); 68} 69 70/// hasFunctionProto - Return true if the given decl has a argument 71/// information. This decl should have already passed 72/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 73static bool hasFunctionProto(Decl *d) { 74 if (const FunctionType *FnTy = getFunctionType(d)) 75 return isa<FunctionProtoType>(FnTy); 76 else { 77 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 78 return true; 79 } 80} 81 82/// getFunctionOrMethodNumArgs - Return number of function or method 83/// arguments. It is an error to call this on a K&R function (use 84/// hasFunctionProto first). 85static unsigned getFunctionOrMethodNumArgs(Decl *d) { 86 if (const FunctionType *FnTy = getFunctionType(d)) 87 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 88 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 89 return BD->getNumParams(); 90 return cast<ObjCMethodDecl>(d)->param_size(); 91} 92 93static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 94 if (const FunctionType *FnTy = getFunctionType(d)) 95 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 96 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 97 return BD->getParamDecl(Idx)->getType(); 98 99 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 100} 101 102static QualType getFunctionOrMethodResultType(Decl *d) { 103 if (const FunctionType *FnTy = getFunctionType(d)) 104 return cast<FunctionProtoType>(FnTy)->getResultType(); 105 return cast<ObjCMethodDecl>(d)->getResultType(); 106} 107 108static bool isFunctionOrMethodVariadic(Decl *d) { 109 if (const FunctionType *FnTy = getFunctionType(d)) { 110 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 111 return proto->isVariadic(); 112 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 113 return BD->IsVariadic(); 114 else { 115 return cast<ObjCMethodDecl>(d)->isVariadic(); 116 } 117} 118 119static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 120 const ObjCObjectPointerType *PT = T->getAsObjCObjectPointerType(); 121 if (!PT) 122 return false; 123 124 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 125 if (!ClsT) 126 return false; 127 128 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 129 130 // FIXME: Should we walk the chain of classes? 131 return ClsName == &Ctx.Idents.get("NSString") || 132 ClsName == &Ctx.Idents.get("NSMutableString"); 133} 134 135static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 136 const PointerType *PT = T->getAsPointerType(); 137 if (!PT) 138 return false; 139 140 const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 141 if (!RT) 142 return false; 143 144 const RecordDecl *RD = RT->getDecl(); 145 if (RD->getTagKind() != TagDecl::TK_struct) 146 return false; 147 148 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 149} 150 151//===----------------------------------------------------------------------===// 152// Attribute Implementations 153//===----------------------------------------------------------------------===// 154 155// FIXME: All this manual attribute parsing code is gross. At the 156// least add some helper functions to check most argument patterns (# 157// and types of args). 158 159static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 160 const AttributeList &Attr, Sema &S) { 161 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 162 if (tDecl == 0) { 163 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 164 return; 165 } 166 167 QualType curType = tDecl->getUnderlyingType(); 168 169 Expr *sizeExpr; 170 171 // Special case where the argument is a template id. 172 if (Attr.getParameterName()) { 173 sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(), 174 Attr.getParameterName(), 175 false, 0, false).takeAs<Expr>(); 176 } else { 177 // check the attribute arguments. 178 if (Attr.getNumArgs() != 1) { 179 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 180 return; 181 } 182 sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 183 } 184 185 // Instantiate/Install the vector type, and let Sema build the type for us. 186 // This will run the reguired checks. 187 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 188 if (!T.isNull()) { 189 tDecl->setUnderlyingType(T); 190 191 // Remember this typedef decl, we will need it later for diagnostics. 192 S.ExtVectorDecls.push_back(tDecl); 193 } 194} 195 196 197/// HandleVectorSizeAttribute - this attribute is only applicable to integral 198/// and float scalars, although arrays, pointers, and function return values are 199/// allowed in conjunction with this construct. Aggregates with this attribute 200/// are invalid, even if they are of the same size as a corresponding scalar. 201/// The raw attribute should contain precisely 1 argument, the vector size for 202/// the variable, measured in bytes. If curType and rawAttr are well formed, 203/// this routine will return a new vector type. 204static void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 205 QualType CurType; 206 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 207 CurType = VD->getType(); 208 else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 209 CurType = TD->getUnderlyingType(); 210 else { 211 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 212 << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 213 return; 214 } 215 216 // Check the attribute arugments. 217 if (Attr.getNumArgs() != 1) { 218 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 219 return; 220 } 221 Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 222 llvm::APSInt vecSize(32); 223 if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 224 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 225 << "vector_size" << sizeExpr->getSourceRange(); 226 return; 227 } 228 // navigate to the base type - we need to provide for vector pointers, vector 229 // arrays, and functions returning vectors. 230 if (CurType->isPointerType() || CurType->isArrayType() || 231 CurType->isFunctionType()) { 232 S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType; 233 return; 234 /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 235 do { 236 if (PointerType *PT = dyn_cast<PointerType>(canonType)) 237 canonType = PT->getPointeeType().getTypePtr(); 238 else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 239 canonType = AT->getElementType().getTypePtr(); 240 else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 241 canonType = FT->getResultType().getTypePtr(); 242 } while (canonType->isPointerType() || canonType->isArrayType() || 243 canonType->isFunctionType()); 244 */ 245 } 246 // the base type must be integer or float, and can't already be a vector. 247 if (CurType->isVectorType() || 248 (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { 249 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 250 return; 251 } 252 unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 253 // vecSize is specified in bytes - convert to bits. 254 unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 255 256 // the vector size needs to be an integral multiple of the type size. 257 if (vectorSize % typeSize) { 258 S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 259 << sizeExpr->getSourceRange(); 260 return; 261 } 262 if (vectorSize == 0) { 263 S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 264 << sizeExpr->getSourceRange(); 265 return; 266 } 267 268 // Success! Instantiate the vector type, the number of elements is > 0, and 269 // not required to be a power of 2, unlike GCC. 270 CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 271 272 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 273 VD->setType(CurType); 274 else 275 cast<TypedefDecl>(D)->setUnderlyingType(CurType); 276} 277 278static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 279 // check the attribute arguments. 280 if (Attr.getNumArgs() > 0) { 281 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 282 return; 283 } 284 285 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 286 TD->addAttr(::new (S.Context) PackedAttr(1)); 287 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 288 // If the alignment is less than or equal to 8 bits, the packed attribute 289 // has no effect. 290 if (!FD->getType()->isIncompleteType() && 291 S.Context.getTypeAlign(FD->getType()) <= 8) 292 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 293 << Attr.getName() << FD->getType(); 294 else 295 FD->addAttr(::new (S.Context) PackedAttr(1)); 296 } else 297 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 298} 299 300static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 301 // check the attribute arguments. 302 if (Attr.getNumArgs() > 0) { 303 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 304 return; 305 } 306 307 // The IBOutlet attribute only applies to instance variables of Objective-C 308 // classes. 309 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 310 d->addAttr(::new (S.Context) IBOutletAttr()); 311 else 312 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 313} 314 315static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 316 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 317 // ignore it as well 318 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 319 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 320 << Attr.getName() << 0 /*function*/; 321 return; 322 } 323 324 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 325 326 // The nonnull attribute only applies to pointers. 327 llvm::SmallVector<unsigned, 10> NonNullArgs; 328 329 for (AttributeList::arg_iterator I=Attr.arg_begin(), 330 E=Attr.arg_end(); I!=E; ++I) { 331 332 333 // The argument must be an integer constant expression. 334 Expr *Ex = static_cast<Expr *>(*I); 335 llvm::APSInt ArgNum(32); 336 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 337 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 338 << "nonnull" << Ex->getSourceRange(); 339 return; 340 } 341 342 unsigned x = (unsigned) ArgNum.getZExtValue(); 343 344 if (x < 1 || x > NumArgs) { 345 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 346 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 347 return; 348 } 349 350 --x; 351 352 // Is the function argument a pointer type? 353 QualType T = getFunctionOrMethodArgType(d, x); 354 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 355 // FIXME: Should also highlight argument in decl. 356 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 357 << "nonnull" << Ex->getSourceRange(); 358 continue; 359 } 360 361 NonNullArgs.push_back(x); 362 } 363 364 // If no arguments were specified to __attribute__((nonnull)) then all pointer 365 // arguments have a nonnull attribute. 366 if (NonNullArgs.empty()) { 367 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 368 QualType T = getFunctionOrMethodArgType(d, I); 369 if (T->isAnyPointerType() || T->isBlockPointerType()) 370 NonNullArgs.push_back(I); 371 } 372 373 if (NonNullArgs.empty()) { 374 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 375 return; 376 } 377 } 378 379 unsigned* start = &NonNullArgs[0]; 380 unsigned size = NonNullArgs.size(); 381 std::sort(start, start + size); 382 d->addAttr(::new (S.Context) NonNullAttr(start, size)); 383} 384 385static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 386 // check the attribute arguments. 387 if (Attr.getNumArgs() != 1) { 388 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 389 return; 390 } 391 392 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 393 Arg = Arg->IgnoreParenCasts(); 394 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 395 396 if (Str == 0 || Str->isWide()) { 397 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 398 << "alias" << 1; 399 return; 400 } 401 402 const char *Alias = Str->getStrData(); 403 unsigned AliasLen = Str->getByteLength(); 404 405 // FIXME: check if target symbol exists in current file 406 407 d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 408} 409 410static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 411 Sema &S) { 412 // check the attribute arguments. 413 if (Attr.getNumArgs() != 0) { 414 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 415 return; 416 } 417 418 if (!isa<FunctionDecl>(d)) { 419 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 420 << Attr.getName() << 0 /*function*/; 421 return; 422 } 423 424 d->addAttr(::new (S.Context) AlwaysInlineAttr()); 425} 426 427static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 428 Sema &S) { 429 // check the attribute arguments. 430 if (Attr.getNumArgs() != 0) { 431 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 432 return false; 433 } 434 435 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 436 ValueDecl *VD = dyn_cast<ValueDecl>(d); 437 if (VD == 0 || !VD->getType()->isBlockPointerType()) { 438 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 439 << Attr.getName() << 0 /*function*/; 440 return false; 441 } 442 } 443 444 return true; 445} 446 447static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 448 if (HandleCommonNoReturnAttr(d, Attr, S)) 449 d->addAttr(::new (S.Context) NoReturnAttr()); 450} 451 452static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 453 Sema &S) { 454 if (HandleCommonNoReturnAttr(d, Attr, S)) 455 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 456} 457 458static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 459 // check the attribute arguments. 460 if (Attr.getNumArgs() != 0) { 461 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 462 return; 463 } 464 465 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 466 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 467 << Attr.getName() << 2 /*variable and function*/; 468 return; 469 } 470 471 d->addAttr(::new (S.Context) UnusedAttr()); 472} 473 474static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 475 // check the attribute arguments. 476 if (Attr.getNumArgs() != 0) { 477 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 478 return; 479 } 480 481 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 482 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 483 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 484 return; 485 } 486 } else if (!isFunctionOrMethod(d)) { 487 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 488 << Attr.getName() << 2 /*variable and function*/; 489 return; 490 } 491 492 d->addAttr(::new (S.Context) UsedAttr()); 493} 494 495static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 496 // check the attribute arguments. 497 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 498 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 499 << "0 or 1"; 500 return; 501 } 502 503 int priority = 65535; // FIXME: Do not hardcode such constants. 504 if (Attr.getNumArgs() > 0) { 505 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 506 llvm::APSInt Idx(32); 507 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 508 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 509 << "constructor" << 1 << E->getSourceRange(); 510 return; 511 } 512 priority = Idx.getZExtValue(); 513 } 514 515 if (!isa<FunctionDecl>(d)) { 516 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 517 << Attr.getName() << 0 /*function*/; 518 return; 519 } 520 521 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 522} 523 524static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 525 // check the attribute arguments. 526 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 527 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 528 << "0 or 1"; 529 return; 530 } 531 532 int priority = 65535; // FIXME: Do not hardcode such constants. 533 if (Attr.getNumArgs() > 0) { 534 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 535 llvm::APSInt Idx(32); 536 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 537 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 538 << "destructor" << 1 << E->getSourceRange(); 539 return; 540 } 541 priority = Idx.getZExtValue(); 542 } 543 544 if (!isa<FunctionDecl>(d)) { 545 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 546 << Attr.getName() << 0 /*function*/; 547 return; 548 } 549 550 d->addAttr(::new (S.Context) DestructorAttr(priority)); 551} 552 553static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 554 // check the attribute arguments. 555 if (Attr.getNumArgs() != 0) { 556 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 557 return; 558 } 559 560 d->addAttr(::new (S.Context) DeprecatedAttr()); 561} 562 563static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 564 // check the attribute arguments. 565 if (Attr.getNumArgs() != 0) { 566 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 567 return; 568 } 569 570 d->addAttr(::new (S.Context) UnavailableAttr()); 571} 572 573static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 574 // check the attribute arguments. 575 if (Attr.getNumArgs() != 1) { 576 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 577 return; 578 } 579 580 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 581 Arg = Arg->IgnoreParenCasts(); 582 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 583 584 if (Str == 0 || Str->isWide()) { 585 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 586 << "visibility" << 1; 587 return; 588 } 589 590 const char *TypeStr = Str->getStrData(); 591 unsigned TypeLen = Str->getByteLength(); 592 VisibilityAttr::VisibilityTypes type; 593 594 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 595 type = VisibilityAttr::DefaultVisibility; 596 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 597 type = VisibilityAttr::HiddenVisibility; 598 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 599 type = VisibilityAttr::HiddenVisibility; // FIXME 600 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 601 type = VisibilityAttr::ProtectedVisibility; 602 else { 603 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 604 return; 605 } 606 607 d->addAttr(::new (S.Context) VisibilityAttr(type)); 608} 609 610static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 611 Sema &S) { 612 if (Attr.getNumArgs() != 0) { 613 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 614 return; 615 } 616 617 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 618 if (OCI == 0) { 619 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 620 return; 621 } 622 623 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 624} 625 626static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 627 if (Attr.getNumArgs() != 0) { 628 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 629 return; 630 } 631 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 632 QualType T = TD->getUnderlyingType(); 633 if (!T->isPointerType() || 634 !T->getAsPointerType()->getPointeeType()->isRecordType()) { 635 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 636 return; 637 } 638 } 639 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 640} 641 642static void 643HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 644 if (Attr.getNumArgs() != 0) { 645 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 646 return; 647 } 648 649 if (!isa<FunctionDecl>(D)) { 650 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 651 return; 652 } 653 654 D->addAttr(::new (S.Context) OverloadableAttr()); 655} 656 657static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 658 if (!Attr.getParameterName()) { 659 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 660 << "blocks" << 1; 661 return; 662 } 663 664 if (Attr.getNumArgs() != 0) { 665 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 666 return; 667 } 668 669 BlocksAttr::BlocksAttrTypes type; 670 if (Attr.getParameterName()->isStr("byref")) 671 type = BlocksAttr::ByRef; 672 else { 673 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 674 << "blocks" << Attr.getParameterName(); 675 return; 676 } 677 678 d->addAttr(::new (S.Context) BlocksAttr(type)); 679} 680 681static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 682 // check the attribute arguments. 683 if (Attr.getNumArgs() > 2) { 684 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 685 << "0, 1 or 2"; 686 return; 687 } 688 689 int sentinel = 0; 690 if (Attr.getNumArgs() > 0) { 691 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 692 llvm::APSInt Idx(32); 693 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 694 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 695 << "sentinel" << 1 << E->getSourceRange(); 696 return; 697 } 698 sentinel = Idx.getZExtValue(); 699 700 if (sentinel < 0) { 701 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 702 << E->getSourceRange(); 703 return; 704 } 705 } 706 707 int nullPos = 0; 708 if (Attr.getNumArgs() > 1) { 709 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 710 llvm::APSInt Idx(32); 711 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 712 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 713 << "sentinel" << 2 << E->getSourceRange(); 714 return; 715 } 716 nullPos = Idx.getZExtValue(); 717 718 if (nullPos > 1 || nullPos < 0) { 719 // FIXME: This error message could be improved, it would be nice 720 // to say what the bounds actually are. 721 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 722 << E->getSourceRange(); 723 return; 724 } 725 } 726 727 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 728 const FunctionType *FT = FD->getType()->getAsFunctionType(); 729 assert(FT && "FunctionDecl has non-function type?"); 730 731 if (isa<FunctionNoProtoType>(FT)) { 732 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 733 return; 734 } 735 736 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 737 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 738 return; 739 } 740 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 741 if (!MD->isVariadic()) { 742 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 743 return; 744 } 745 } else if (isa<BlockDecl>(d)) { 746 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 747 // caller. 748 ; 749 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 750 QualType Ty = V->getType(); 751 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 752 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 753 : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType(); 754 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 755 int m = Ty->isFunctionPointerType() ? 0 : 1; 756 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 757 return; 758 } 759 } 760 else { 761 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 762 << Attr.getName() << 6 /*function, method or block */; 763 return; 764 } 765 } else { 766 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 767 << Attr.getName() << 6 /*function, method or block */; 768 return; 769 } 770 d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 771} 772 773static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 774 // check the attribute arguments. 775 if (Attr.getNumArgs() != 0) { 776 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 777 return; 778 } 779 780 // TODO: could also be applied to methods? 781 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 782 if (!Fn) { 783 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 784 << Attr.getName() << 0 /*function*/; 785 return; 786 } 787 788 Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 789} 790 791static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 792 // check the attribute arguments. 793 if (Attr.getNumArgs() != 0) { 794 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 795 return; 796 } 797 798 /* weak only applies to non-static declarations */ 799 bool isStatic = false; 800 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 801 isStatic = VD->getStorageClass() == VarDecl::Static; 802 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 803 isStatic = FD->getStorageClass() == FunctionDecl::Static; 804 } 805 if (isStatic) { 806 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 807 dyn_cast<NamedDecl>(D)->getNameAsString(); 808 return; 809 } 810 811 // TODO: could also be applied to methods? 812 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 813 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 814 << Attr.getName() << 2 /*variable and function*/; 815 return; 816 } 817 818 D->addAttr(::new (S.Context) WeakAttr()); 819} 820 821static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 822 // check the attribute arguments. 823 if (Attr.getNumArgs() != 0) { 824 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 825 return; 826 } 827 828 // weak_import only applies to variable & function declarations. 829 bool isDef = false; 830 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 831 isDef = (!VD->hasExternalStorage() || VD->getInit()); 832 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 833 isDef = FD->getBody(); 834 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 835 // We ignore weak import on properties and methods 836 return; 837 } else { 838 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 839 << Attr.getName() << 2 /*variable and function*/; 840 return; 841 } 842 843 // Merge should handle any subsequent violations. 844 if (isDef) { 845 S.Diag(Attr.getLoc(), 846 diag::warn_attribute_weak_import_invalid_on_definition) 847 << "weak_import" << 2 /*variable and function*/; 848 return; 849 } 850 851 D->addAttr(::new (S.Context) WeakImportAttr()); 852} 853 854static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 855 // check the attribute arguments. 856 if (Attr.getNumArgs() != 0) { 857 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 858 return; 859 } 860 861 // Attribute can be applied only to functions or variables. 862 if (isa<VarDecl>(D)) { 863 D->addAttr(::new (S.Context) DLLImportAttr()); 864 return; 865 } 866 867 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 868 if (!FD) { 869 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 870 << Attr.getName() << 2 /*variable and function*/; 871 return; 872 } 873 874 // Currently, the dllimport attribute is ignored for inlined functions. 875 // Warning is emitted. 876 if (FD->isInline()) { 877 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 878 return; 879 } 880 881 // The attribute is also overridden by a subsequent declaration as dllexport. 882 // Warning is emitted. 883 for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 884 nextAttr = nextAttr->getNext()) { 885 if (nextAttr->getKind() == AttributeList::AT_dllexport) { 886 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 887 return; 888 } 889 } 890 891 if (D->getAttr<DLLExportAttr>()) { 892 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 893 return; 894 } 895 896 D->addAttr(::new (S.Context) DLLImportAttr()); 897} 898 899static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 900 // check the attribute arguments. 901 if (Attr.getNumArgs() != 0) { 902 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 903 return; 904 } 905 906 // Attribute can be applied only to functions or variables. 907 if (isa<VarDecl>(D)) { 908 D->addAttr(::new (S.Context) DLLExportAttr()); 909 return; 910 } 911 912 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 913 if (!FD) { 914 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 915 << Attr.getName() << 2 /*variable and function*/; 916 return; 917 } 918 919 // Currently, the dllexport attribute is ignored for inlined functions, unless 920 // the -fkeep-inline-functions flag has been used. Warning is emitted; 921 if (FD->isInline()) { 922 // FIXME: ... unless the -fkeep-inline-functions flag has been used. 923 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 924 return; 925 } 926 927 D->addAttr(::new (S.Context) DLLExportAttr()); 928} 929 930static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 931 Sema &S) { 932 // Attribute has 3 arguments. 933 if (Attr.getNumArgs() != 3) { 934 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 935 return; 936 } 937 938 unsigned WGSize[3]; 939 for (unsigned i = 0; i < 3; ++i) { 940 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 941 llvm::APSInt ArgNum(32); 942 if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 943 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 944 << "reqd_work_group_size" << E->getSourceRange(); 945 return; 946 } 947 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 948 } 949 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 950 WGSize[2])); 951} 952 953static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 954 // Attribute has no arguments. 955 if (Attr.getNumArgs() != 1) { 956 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 957 return; 958 } 959 960 // Make sure that there is a string literal as the sections's single 961 // argument. 962 StringLiteral *SE = 963 dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 964 if (!SE) { 965 // FIXME 966 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 967 return; 968 } 969 D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 970 SE->getByteLength()))); 971} 972 973static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 974 // Attribute has no arguments. 975 if (Attr.getNumArgs() != 0) { 976 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 977 return; 978 } 979 980 // Attribute can be applied only to functions. 981 if (!isa<FunctionDecl>(d)) { 982 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 983 << Attr.getName() << 0 /*function*/; 984 return; 985 } 986 987 // stdcall and fastcall attributes are mutually incompatible. 988 if (d->getAttr<FastCallAttr>()) { 989 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 990 << "stdcall" << "fastcall"; 991 return; 992 } 993 994 d->addAttr(::new (S.Context) StdCallAttr()); 995} 996 997static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 998 // Attribute has no arguments. 999 if (Attr.getNumArgs() != 0) { 1000 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1001 return; 1002 } 1003 1004 if (!isa<FunctionDecl>(d)) { 1005 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1006 << Attr.getName() << 0 /*function*/; 1007 return; 1008 } 1009 1010 // stdcall and fastcall attributes are mutually incompatible. 1011 if (d->getAttr<StdCallAttr>()) { 1012 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1013 << "fastcall" << "stdcall"; 1014 return; 1015 } 1016 1017 d->addAttr(::new (S.Context) FastCallAttr()); 1018} 1019 1020static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1021 // check the attribute arguments. 1022 if (Attr.getNumArgs() != 0) { 1023 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1024 return; 1025 } 1026 1027 d->addAttr(::new (S.Context) NoThrowAttr()); 1028} 1029 1030static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1031 // check the attribute arguments. 1032 if (Attr.getNumArgs() != 0) { 1033 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1034 return; 1035 } 1036 1037 d->addAttr(::new (S.Context) ConstAttr()); 1038} 1039 1040static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1041 // check the attribute arguments. 1042 if (Attr.getNumArgs() != 0) { 1043 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1044 return; 1045 } 1046 1047 d->addAttr(::new (S.Context) PureAttr()); 1048} 1049 1050static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1051 // Match gcc which ignores cleanup attrs when compiling C++. 1052 if (S.getLangOptions().CPlusPlus) 1053 return; 1054 1055 if (!Attr.getParameterName()) { 1056 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1057 return; 1058 } 1059 1060 if (Attr.getNumArgs() != 0) { 1061 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1062 return; 1063 } 1064 1065 VarDecl *VD = dyn_cast<VarDecl>(d); 1066 1067 if (!VD || !VD->hasLocalStorage()) { 1068 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1069 return; 1070 } 1071 1072 // Look up the function 1073 NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 1074 Sema::LookupOrdinaryName); 1075 if (!CleanupDecl) { 1076 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1077 Attr.getParameterName(); 1078 return; 1079 } 1080 1081 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1082 if (!FD) { 1083 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1084 Attr.getParameterName(); 1085 return; 1086 } 1087 1088 if (FD->getNumParams() != 1) { 1089 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1090 Attr.getParameterName(); 1091 return; 1092 } 1093 1094 // We're currently more strict than GCC about what function types we accept. 1095 // If this ever proves to be a problem it should be easy to fix. 1096 QualType Ty = S.Context.getPointerType(VD->getType()); 1097 QualType ParamTy = FD->getParamDecl(0)->getType(); 1098 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1099 S.Diag(Attr.getLoc(), 1100 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1101 Attr.getParameterName() << ParamTy << Ty; 1102 return; 1103 } 1104 1105 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1106} 1107 1108/// Handle __attribute__((format_arg((idx)))) attribute based on 1109/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1110static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1111 if (Attr.getNumArgs() != 1) { 1112 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1113 return; 1114 } 1115 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1116 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1117 << Attr.getName() << 0 /*function*/; 1118 return; 1119 } 1120 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1121 // needed in order to be compatible with GCC the index must start with 1. 1122 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1123 unsigned FirstIdx = 1; 1124 // checks for the 2nd argument 1125 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1126 llvm::APSInt Idx(32); 1127 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1128 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1129 << "format" << 2 << IdxExpr->getSourceRange(); 1130 return; 1131 } 1132 1133 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1134 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1135 << "format" << 2 << IdxExpr->getSourceRange(); 1136 return; 1137 } 1138 1139 unsigned ArgIdx = Idx.getZExtValue() - 1; 1140 1141 // make sure the format string is really a string 1142 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1143 1144 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1145 if (not_nsstring_type && 1146 !isCFStringType(Ty, S.Context) && 1147 (!Ty->isPointerType() || 1148 !Ty->getAsPointerType()->getPointeeType()->isCharType())) { 1149 // FIXME: Should highlight the actual expression that has the wrong type. 1150 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1151 << (not_nsstring_type ? "a string type" : "an NSString") 1152 << IdxExpr->getSourceRange(); 1153 return; 1154 } 1155 Ty = getFunctionOrMethodResultType(d); 1156 if (!isNSStringType(Ty, S.Context) && 1157 !isCFStringType(Ty, S.Context) && 1158 (!Ty->isPointerType() || 1159 !Ty->getAsPointerType()->getPointeeType()->isCharType())) { 1160 // FIXME: Should highlight the actual expression that has the wrong type. 1161 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1162 << (not_nsstring_type ? "string type" : "NSString") 1163 << IdxExpr->getSourceRange(); 1164 return; 1165 } 1166 1167 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 1168} 1169 1170/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1171/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1172static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1173 1174 if (!Attr.getParameterName()) { 1175 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1176 << "format" << 1; 1177 return; 1178 } 1179 1180 if (Attr.getNumArgs() != 2) { 1181 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1182 return; 1183 } 1184 1185 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1186 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1187 << Attr.getName() << 0 /*function*/; 1188 return; 1189 } 1190 1191 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1192 // needed in order to be compatible with GCC the index must start in 1 and the 1193 // limit is numargs+1 1194 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1195 unsigned FirstIdx = 1; 1196 1197 const char *Format = Attr.getParameterName()->getName(); 1198 unsigned FormatLen = Attr.getParameterName()->getLength(); 1199 1200 // Normalize the argument, __foo__ becomes foo. 1201 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 1202 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 1203 Format += 2; 1204 FormatLen -= 4; 1205 } 1206 1207 bool Supported = false; 1208 bool is_NSString = false; 1209 bool is_strftime = false; 1210 bool is_CFString = false; 1211 1212 switch (FormatLen) { 1213 default: break; 1214 case 5: Supported = !memcmp(Format, "scanf", 5); break; 1215 case 6: Supported = !memcmp(Format, "printf", 6); break; 1216 case 7: Supported = !memcmp(Format, "strfmon", 7); break; 1217 case 8: 1218 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1219 (is_NSString = !memcmp(Format, "NSString", 8)) || 1220 (is_CFString = !memcmp(Format, "CFString", 8)); 1221 break; 1222 } 1223 1224 if (!Supported) { 1225 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1226 << "format" << Attr.getParameterName()->getName(); 1227 return; 1228 } 1229 1230 // checks for the 2nd argument 1231 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1232 llvm::APSInt Idx(32); 1233 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1234 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1235 << "format" << 2 << IdxExpr->getSourceRange(); 1236 return; 1237 } 1238 1239 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1240 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1241 << "format" << 2 << IdxExpr->getSourceRange(); 1242 return; 1243 } 1244 1245 // FIXME: Do we need to bounds check? 1246 unsigned ArgIdx = Idx.getZExtValue() - 1; 1247 1248 // make sure the format string is really a string 1249 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1250 1251 if (is_CFString) { 1252 if (!isCFStringType(Ty, S.Context)) { 1253 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1254 << "a CFString" << IdxExpr->getSourceRange(); 1255 return; 1256 } 1257 } else if (is_NSString) { 1258 // FIXME: do we need to check if the type is NSString*? What are the 1259 // semantics? 1260 if (!isNSStringType(Ty, S.Context)) { 1261 // FIXME: Should highlight the actual expression that has the wrong type. 1262 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1263 << "an NSString" << IdxExpr->getSourceRange(); 1264 return; 1265 } 1266 } else if (!Ty->isPointerType() || 1267 !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 1268 // FIXME: Should highlight the actual expression that has the wrong type. 1269 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1270 << "a string type" << IdxExpr->getSourceRange(); 1271 return; 1272 } 1273 1274 // check the 3rd argument 1275 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1276 llvm::APSInt FirstArg(32); 1277 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1278 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1279 << "format" << 3 << FirstArgExpr->getSourceRange(); 1280 return; 1281 } 1282 1283 // check if the function is variadic if the 3rd argument non-zero 1284 if (FirstArg != 0) { 1285 if (isFunctionOrMethodVariadic(d)) { 1286 ++NumArgs; // +1 for ... 1287 } else { 1288 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1289 return; 1290 } 1291 } 1292 1293 // strftime requires FirstArg to be 0 because it doesn't read from any 1294 // variable the input is just the current time + the format string. 1295 if (is_strftime) { 1296 if (FirstArg != 0) { 1297 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1298 << FirstArgExpr->getSourceRange(); 1299 return; 1300 } 1301 // if 0 it disables parameter checking (to use with e.g. va_list) 1302 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1303 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1304 << "format" << 3 << FirstArgExpr->getSourceRange(); 1305 return; 1306 } 1307 1308 d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 1309 Idx.getZExtValue(), FirstArg.getZExtValue())); 1310} 1311 1312static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1313 Sema &S) { 1314 // check the attribute arguments. 1315 if (Attr.getNumArgs() != 0) { 1316 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1317 return; 1318 } 1319 1320 // Try to find the underlying union declaration. 1321 RecordDecl *RD = 0; 1322 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1323 if (TD && TD->getUnderlyingType()->isUnionType()) 1324 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1325 else 1326 RD = dyn_cast<RecordDecl>(d); 1327 1328 if (!RD || !RD->isUnion()) { 1329 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1330 << Attr.getName() << 1 /*union*/; 1331 return; 1332 } 1333 1334 if (!RD->isDefinition()) { 1335 S.Diag(Attr.getLoc(), 1336 diag::warn_transparent_union_attribute_not_definition); 1337 return; 1338 } 1339 1340 RecordDecl::field_iterator Field = RD->field_begin(), 1341 FieldEnd = RD->field_end(); 1342 if (Field == FieldEnd) { 1343 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1344 return; 1345 } 1346 1347 FieldDecl *FirstField = *Field; 1348 QualType FirstType = FirstField->getType(); 1349 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1350 S.Diag(FirstField->getLocation(), 1351 diag::warn_transparent_union_attribute_floating); 1352 return; 1353 } 1354 1355 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1356 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1357 for (; Field != FieldEnd; ++Field) { 1358 QualType FieldType = Field->getType(); 1359 if (S.Context.getTypeSize(FieldType) != FirstSize || 1360 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1361 // Warn if we drop the attribute. 1362 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1363 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1364 : S.Context.getTypeAlign(FieldType); 1365 S.Diag(Field->getLocation(), 1366 diag::warn_transparent_union_attribute_field_size_align) 1367 << isSize << Field->getDeclName() << FieldBits; 1368 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1369 S.Diag(FirstField->getLocation(), 1370 diag::note_transparent_union_first_field_size_align) 1371 << isSize << FirstBits; 1372 return; 1373 } 1374 } 1375 1376 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1377} 1378 1379static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1380 // check the attribute arguments. 1381 if (Attr.getNumArgs() != 1) { 1382 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1383 return; 1384 } 1385 Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 1386 StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 1387 1388 // Make sure that there is a string literal as the annotation's single 1389 // argument. 1390 if (!SE) { 1391 S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 1392 return; 1393 } 1394 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1395 SE->getByteLength()))); 1396} 1397 1398static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1399 // check the attribute arguments. 1400 if (Attr.getNumArgs() > 1) { 1401 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1402 return; 1403 } 1404 1405 unsigned Align = 0; 1406 if (Attr.getNumArgs() == 0) { 1407 // FIXME: This should be the target specific maximum alignment. 1408 // (For now we just use 128 bits which is the maximum on X86). 1409 Align = 128; 1410 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1411 return; 1412 } 1413 1414 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1415 llvm::APSInt Alignment(32); 1416 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1417 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1418 << "aligned" << alignmentExpr->getSourceRange(); 1419 return; 1420 } 1421 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1422 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1423 << alignmentExpr->getSourceRange(); 1424 return; 1425 } 1426 1427 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1428} 1429 1430/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1431/// type. 1432/// 1433/// Despite what would be logical, the mode attribute is a decl attribute, not a 1434/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1435/// HImode, not an intermediate pointer. 1436static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1437 // This attribute isn't documented, but glibc uses it. It changes 1438 // the width of an int or unsigned int to the specified size. 1439 1440 // Check that there aren't any arguments 1441 if (Attr.getNumArgs() != 0) { 1442 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1443 return; 1444 } 1445 1446 IdentifierInfo *Name = Attr.getParameterName(); 1447 if (!Name) { 1448 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1449 return; 1450 } 1451 const char *Str = Name->getName(); 1452 unsigned Len = Name->getLength(); 1453 1454 // Normalize the attribute name, __foo__ becomes foo. 1455 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1456 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1457 Str += 2; 1458 Len -= 4; 1459 } 1460 1461 unsigned DestWidth = 0; 1462 bool IntegerMode = true; 1463 bool ComplexMode = false; 1464 switch (Len) { 1465 case 2: 1466 switch (Str[0]) { 1467 case 'Q': DestWidth = 8; break; 1468 case 'H': DestWidth = 16; break; 1469 case 'S': DestWidth = 32; break; 1470 case 'D': DestWidth = 64; break; 1471 case 'X': DestWidth = 96; break; 1472 case 'T': DestWidth = 128; break; 1473 } 1474 if (Str[1] == 'F') { 1475 IntegerMode = false; 1476 } else if (Str[1] == 'C') { 1477 IntegerMode = false; 1478 ComplexMode = true; 1479 } else if (Str[1] != 'I') { 1480 DestWidth = 0; 1481 } 1482 break; 1483 case 4: 1484 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1485 // pointer on PIC16 and other embedded platforms. 1486 if (!memcmp(Str, "word", 4)) 1487 DestWidth = S.Context.Target.getPointerWidth(0); 1488 if (!memcmp(Str, "byte", 4)) 1489 DestWidth = S.Context.Target.getCharWidth(); 1490 break; 1491 case 7: 1492 if (!memcmp(Str, "pointer", 7)) 1493 DestWidth = S.Context.Target.getPointerWidth(0); 1494 break; 1495 } 1496 1497 QualType OldTy; 1498 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1499 OldTy = TD->getUnderlyingType(); 1500 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1501 OldTy = VD->getType(); 1502 else { 1503 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1504 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1505 return; 1506 } 1507 1508 if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 1509 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1510 else if (IntegerMode) { 1511 if (!OldTy->isIntegralType()) 1512 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1513 } else if (ComplexMode) { 1514 if (!OldTy->isComplexType()) 1515 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1516 } else { 1517 if (!OldTy->isFloatingType()) 1518 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1519 } 1520 1521 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1522 // and friends, at least with glibc. 1523 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1524 // width on unusual platforms. 1525 // FIXME: Make sure floating-point mappings are accurate 1526 // FIXME: Support XF and TF types 1527 QualType NewTy; 1528 switch (DestWidth) { 1529 case 0: 1530 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1531 return; 1532 default: 1533 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1534 return; 1535 case 8: 1536 if (!IntegerMode) { 1537 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1538 return; 1539 } 1540 if (OldTy->isSignedIntegerType()) 1541 NewTy = S.Context.SignedCharTy; 1542 else 1543 NewTy = S.Context.UnsignedCharTy; 1544 break; 1545 case 16: 1546 if (!IntegerMode) { 1547 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1548 return; 1549 } 1550 if (OldTy->isSignedIntegerType()) 1551 NewTy = S.Context.ShortTy; 1552 else 1553 NewTy = S.Context.UnsignedShortTy; 1554 break; 1555 case 32: 1556 if (!IntegerMode) 1557 NewTy = S.Context.FloatTy; 1558 else if (OldTy->isSignedIntegerType()) 1559 NewTy = S.Context.IntTy; 1560 else 1561 NewTy = S.Context.UnsignedIntTy; 1562 break; 1563 case 64: 1564 if (!IntegerMode) 1565 NewTy = S.Context.DoubleTy; 1566 else if (OldTy->isSignedIntegerType()) 1567 NewTy = S.Context.LongLongTy; 1568 else 1569 NewTy = S.Context.UnsignedLongLongTy; 1570 break; 1571 case 96: 1572 NewTy = S.Context.LongDoubleTy; 1573 break; 1574 case 128: 1575 if (!IntegerMode) { 1576 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1577 return; 1578 } 1579 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1580 break; 1581 } 1582 1583 if (ComplexMode) { 1584 NewTy = S.Context.getComplexType(NewTy); 1585 } 1586 1587 // Install the new type. 1588 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1589 TD->setUnderlyingType(NewTy); 1590 else 1591 cast<ValueDecl>(D)->setType(NewTy); 1592} 1593 1594static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1595 // check the attribute arguments. 1596 if (Attr.getNumArgs() > 0) { 1597 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1598 return; 1599 } 1600 1601 if (!isFunctionOrMethod(d)) { 1602 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1603 << Attr.getName() << 0 /*function*/; 1604 return; 1605 } 1606 1607 d->addAttr(::new (S.Context) NodebugAttr()); 1608} 1609 1610static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1611 // check the attribute arguments. 1612 if (Attr.getNumArgs() != 0) { 1613 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1614 return; 1615 } 1616 1617 if (!isa<FunctionDecl>(d)) { 1618 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1619 << Attr.getName() << 0 /*function*/; 1620 return; 1621 } 1622 1623 d->addAttr(::new (S.Context) NoinlineAttr()); 1624} 1625 1626static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1627 // check the attribute arguments. 1628 if (Attr.getNumArgs() != 0) { 1629 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1630 return; 1631 } 1632 1633 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1634 if (Fn == 0) { 1635 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1636 << Attr.getName() << 0 /*function*/; 1637 return; 1638 } 1639 1640 if (!Fn->isInline()) { 1641 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1642 return; 1643 } 1644 1645 d->addAttr(::new (S.Context) GNUInlineAttr()); 1646} 1647 1648static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1649 // check the attribute arguments. 1650 if (Attr.getNumArgs() != 1) { 1651 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1652 return; 1653 } 1654 1655 if (!isFunctionOrMethod(d)) { 1656 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1657 << Attr.getName() << 0 /*function*/; 1658 return; 1659 } 1660 1661 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1662 llvm::APSInt NumParams(32); 1663 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1664 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1665 << "regparm" << NumParamsExpr->getSourceRange(); 1666 return; 1667 } 1668 1669 if (S.Context.Target.getRegParmMax() == 0) { 1670 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1671 << NumParamsExpr->getSourceRange(); 1672 return; 1673 } 1674 1675 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1676 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1677 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1678 return; 1679 } 1680 1681 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1682} 1683 1684//===----------------------------------------------------------------------===// 1685// Checker-specific attribute handlers. 1686//===----------------------------------------------------------------------===// 1687 1688static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1689 Sema &S) { 1690 1691 QualType RetTy; 1692 1693 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1694 RetTy = MD->getResultType(); 1695 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1696 RetTy = FD->getResultType(); 1697 else { 1698 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1699 << Attr.getName() << 3 /* function or method */; 1700 return; 1701 } 1702 1703 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType() 1704 || RetTy->getAsObjCObjectPointerType())) { 1705 S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 1706 << Attr.getName(); 1707 return; 1708 } 1709 1710 switch (Attr.getKind()) { 1711 default: 1712 assert(0 && "invalid ownership attribute"); 1713 return; 1714 case AttributeList::AT_cf_returns_retained: 1715 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1716 return; 1717 case AttributeList::AT_ns_returns_retained: 1718 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1719 return; 1720 }; 1721} 1722 1723//===----------------------------------------------------------------------===// 1724// Top Level Sema Entry Points 1725//===----------------------------------------------------------------------===// 1726 1727/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1728/// the attribute applies to decls. If the attribute is a type attribute, just 1729/// silently ignore it. 1730static void ProcessDeclAttribute(Scope *scope, Decl *D, 1731 const AttributeList &Attr, Sema &S) { 1732 if (Attr.isDeclspecAttribute()) 1733 // FIXME: Try to deal with __declspec attributes! 1734 return; 1735 switch (Attr.getKind()) { 1736 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1737 case AttributeList::AT_address_space: 1738 case AttributeList::AT_objc_gc: 1739 // Ignore these, these are type attributes, handled by 1740 // ProcessTypeAttributes. 1741 break; 1742 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1743 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1744 case AttributeList::AT_always_inline: 1745 HandleAlwaysInlineAttr (D, Attr, S); break; 1746 case AttributeList::AT_analyzer_noreturn: 1747 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1748 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1749 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1750 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1751 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1752 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1753 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1754 case AttributeList::AT_ext_vector_type: 1755 HandleExtVectorTypeAttr(scope, D, Attr, S); 1756 break; 1757 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1758 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1759 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1760 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 1761 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1762 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1763 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1764 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1765 1766 // Checker-specific. 1767 case AttributeList::AT_ns_returns_retained: 1768 case AttributeList::AT_cf_returns_retained: 1769 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1770 1771 case AttributeList::AT_reqd_wg_size: 1772 HandleReqdWorkGroupSize(D, Attr, S); break; 1773 1774 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1775 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1776 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1777 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1778 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1779 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1780 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1781 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1782 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1783 break; 1784 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1785 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1786 case AttributeList::AT_transparent_union: 1787 HandleTransparentUnionAttr(D, Attr, S); 1788 break; 1789 case AttributeList::AT_objc_exception: 1790 HandleObjCExceptionAttr(D, Attr, S); 1791 break; 1792 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1793 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1794 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1795 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1796 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1797 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1798 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1799 case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 1800 case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 1801 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1802 case AttributeList::IgnoredAttribute: 1803 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1804 // Just ignore 1805 break; 1806 default: 1807 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1808 break; 1809 } 1810} 1811 1812/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1813/// attribute list to the specified decl, ignoring any type attributes. 1814void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1815 while (AttrList) { 1816 ProcessDeclAttribute(S, D, *AttrList, *this); 1817 AttrList = AttrList->getNext(); 1818 } 1819} 1820 1821/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1822/// it, apply them to D. This is a bit tricky because PD can have attributes 1823/// specified in many different places, and we need to find and apply them all. 1824void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1825 // Apply decl attributes from the DeclSpec if present. 1826 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1827 ProcessDeclAttributeList(S, D, Attrs); 1828 1829 // Walk the declarator structure, applying decl attributes that were in a type 1830 // position to the decl itself. This handles cases like: 1831 // int *__attr__(x)** D; 1832 // when X is a decl attribute. 1833 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1834 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1835 ProcessDeclAttributeList(S, D, Attrs); 1836 1837 // Finally, apply any attributes on the decl itself. 1838 if (const AttributeList *Attrs = PD.getAttributes()) 1839 ProcessDeclAttributeList(S, D, Attrs); 1840} 1841