SemaDeclAttr.cpp revision 43954311b4159a6f058ff19a5d66817afe0d025f
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->getAs<PointerType>()->getPointeeType(); 40 else if (blocksToo && Ty->isBlockPointerType()) 41 Ty = Ty->getAs<BlockPointerType>()->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->getAs<PointerType>(); 137 if (!PT) 138 return false; 139 140 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 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); 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); 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 void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 428 // check the attribute arguments. 429 if (Attr.getNumArgs() != 0) { 430 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 431 return; 432 } 433 434 if (!isFunctionOrMethod(d)) { 435 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 436 << Attr.getName() << 0 /*function*/; 437 return; 438 } 439 440 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 441 if (!FD->getResultType()->isPointerType()) { 442 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 443 return; 444 } 445 } 446 447 d->addAttr(::new (S.Context) MallocAttr()); 448} 449 450static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 451 Sema &S) { 452 // check the attribute arguments. 453 if (Attr.getNumArgs() != 0) { 454 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 455 return false; 456 } 457 458 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 459 ValueDecl *VD = dyn_cast<ValueDecl>(d); 460 if (VD == 0 || !VD->getType()->isBlockPointerType()) { 461 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 462 << Attr.getName() << 0 /*function*/; 463 return false; 464 } 465 } 466 467 return true; 468} 469 470static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 471 if (HandleCommonNoReturnAttr(d, Attr, S)) 472 d->addAttr(::new (S.Context) NoReturnAttr()); 473} 474 475static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 476 Sema &S) { 477 if (HandleCommonNoReturnAttr(d, Attr, S)) 478 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 479} 480 481static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 482 // check the attribute arguments. 483 if (Attr.getNumArgs() != 0) { 484 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 485 return; 486 } 487 488 if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 489 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 490 << Attr.getName() << 2 /*variable and function*/; 491 return; 492 } 493 494 d->addAttr(::new (S.Context) UnusedAttr()); 495} 496 497static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 498 // check the attribute arguments. 499 if (Attr.getNumArgs() != 0) { 500 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 501 return; 502 } 503 504 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 505 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 506 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 507 return; 508 } 509 } else if (!isFunctionOrMethod(d)) { 510 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 511 << Attr.getName() << 2 /*variable and function*/; 512 return; 513 } 514 515 d->addAttr(::new (S.Context) UsedAttr()); 516} 517 518static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 519 // check the attribute arguments. 520 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 521 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 522 << "0 or 1"; 523 return; 524 } 525 526 int priority = 65535; // FIXME: Do not hardcode such constants. 527 if (Attr.getNumArgs() > 0) { 528 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 529 llvm::APSInt Idx(32); 530 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 531 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 532 << "constructor" << 1 << E->getSourceRange(); 533 return; 534 } 535 priority = Idx.getZExtValue(); 536 } 537 538 if (!isa<FunctionDecl>(d)) { 539 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 540 << Attr.getName() << 0 /*function*/; 541 return; 542 } 543 544 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 545} 546 547static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 548 // check the attribute arguments. 549 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 550 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 551 << "0 or 1"; 552 return; 553 } 554 555 int priority = 65535; // FIXME: Do not hardcode such constants. 556 if (Attr.getNumArgs() > 0) { 557 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 558 llvm::APSInt Idx(32); 559 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 560 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 561 << "destructor" << 1 << E->getSourceRange(); 562 return; 563 } 564 priority = Idx.getZExtValue(); 565 } 566 567 if (!isa<FunctionDecl>(d)) { 568 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 569 << Attr.getName() << 0 /*function*/; 570 return; 571 } 572 573 d->addAttr(::new (S.Context) DestructorAttr(priority)); 574} 575 576static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 577 // check the attribute arguments. 578 if (Attr.getNumArgs() != 0) { 579 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 580 return; 581 } 582 583 d->addAttr(::new (S.Context) DeprecatedAttr()); 584} 585 586static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 587 // check the attribute arguments. 588 if (Attr.getNumArgs() != 0) { 589 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 590 return; 591 } 592 593 d->addAttr(::new (S.Context) UnavailableAttr()); 594} 595 596static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 597 // check the attribute arguments. 598 if (Attr.getNumArgs() != 1) { 599 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 600 return; 601 } 602 603 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 604 Arg = Arg->IgnoreParenCasts(); 605 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 606 607 if (Str == 0 || Str->isWide()) { 608 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 609 << "visibility" << 1; 610 return; 611 } 612 613 const char *TypeStr = Str->getStrData(); 614 unsigned TypeLen = Str->getByteLength(); 615 VisibilityAttr::VisibilityTypes type; 616 617 if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 618 type = VisibilityAttr::DefaultVisibility; 619 else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 620 type = VisibilityAttr::HiddenVisibility; 621 else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 622 type = VisibilityAttr::HiddenVisibility; // FIXME 623 else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 624 type = VisibilityAttr::ProtectedVisibility; 625 else { 626 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 627 return; 628 } 629 630 d->addAttr(::new (S.Context) VisibilityAttr(type)); 631} 632 633static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 634 Sema &S) { 635 if (Attr.getNumArgs() != 0) { 636 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 637 return; 638 } 639 640 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 641 if (OCI == 0) { 642 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 643 return; 644 } 645 646 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 647} 648 649static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 650 if (Attr.getNumArgs() != 0) { 651 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 652 return; 653 } 654 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 655 QualType T = TD->getUnderlyingType(); 656 if (!T->isPointerType() || 657 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 658 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 659 return; 660 } 661 } 662 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 663} 664 665static void 666HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 667 if (Attr.getNumArgs() != 0) { 668 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 669 return; 670 } 671 672 if (!isa<FunctionDecl>(D)) { 673 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 674 return; 675 } 676 677 D->addAttr(::new (S.Context) OverloadableAttr()); 678} 679 680static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 681 if (!Attr.getParameterName()) { 682 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 683 << "blocks" << 1; 684 return; 685 } 686 687 if (Attr.getNumArgs() != 0) { 688 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 689 return; 690 } 691 692 BlocksAttr::BlocksAttrTypes type; 693 if (Attr.getParameterName()->isStr("byref")) 694 type = BlocksAttr::ByRef; 695 else { 696 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 697 << "blocks" << Attr.getParameterName(); 698 return; 699 } 700 701 d->addAttr(::new (S.Context) BlocksAttr(type)); 702} 703 704static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 705 // check the attribute arguments. 706 if (Attr.getNumArgs() > 2) { 707 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 708 << "0, 1 or 2"; 709 return; 710 } 711 712 int sentinel = 0; 713 if (Attr.getNumArgs() > 0) { 714 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 715 llvm::APSInt Idx(32); 716 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 717 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 718 << "sentinel" << 1 << E->getSourceRange(); 719 return; 720 } 721 sentinel = Idx.getZExtValue(); 722 723 if (sentinel < 0) { 724 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 725 << E->getSourceRange(); 726 return; 727 } 728 } 729 730 int nullPos = 0; 731 if (Attr.getNumArgs() > 1) { 732 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 733 llvm::APSInt Idx(32); 734 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 735 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 736 << "sentinel" << 2 << E->getSourceRange(); 737 return; 738 } 739 nullPos = Idx.getZExtValue(); 740 741 if (nullPos > 1 || nullPos < 0) { 742 // FIXME: This error message could be improved, it would be nice 743 // to say what the bounds actually are. 744 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 745 << E->getSourceRange(); 746 return; 747 } 748 } 749 750 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 751 const FunctionType *FT = FD->getType()->getAsFunctionType(); 752 assert(FT && "FunctionDecl has non-function type?"); 753 754 if (isa<FunctionNoProtoType>(FT)) { 755 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 756 return; 757 } 758 759 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 760 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 761 return; 762 } 763 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 764 if (!MD->isVariadic()) { 765 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 766 return; 767 } 768 } else if (isa<BlockDecl>(d)) { 769 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 770 // caller. 771 ; 772 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 773 QualType Ty = V->getType(); 774 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 775 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 776 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAsFunctionType(); 777 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 778 int m = Ty->isFunctionPointerType() ? 0 : 1; 779 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 780 return; 781 } 782 } else { 783 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 784 << Attr.getName() << 6 /*function, method or block */; 785 return; 786 } 787 } else { 788 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 789 << Attr.getName() << 6 /*function, method or block */; 790 return; 791 } 792 d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 793} 794 795static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 796 // check the attribute arguments. 797 if (Attr.getNumArgs() != 0) { 798 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 799 return; 800 } 801 802 // TODO: could also be applied to methods? 803 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 804 if (!Fn) { 805 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 806 << Attr.getName() << 0 /*function*/; 807 return; 808 } 809 810 Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 811} 812 813static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 814 // check the attribute arguments. 815 if (Attr.getNumArgs() != 0) { 816 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 817 return; 818 } 819 820 /* weak only applies to non-static declarations */ 821 bool isStatic = false; 822 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 823 isStatic = VD->getStorageClass() == VarDecl::Static; 824 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 825 isStatic = FD->getStorageClass() == FunctionDecl::Static; 826 } 827 if (isStatic) { 828 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 829 dyn_cast<NamedDecl>(D)->getNameAsString(); 830 return; 831 } 832 833 // TODO: could also be applied to methods? 834 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 835 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 836 << Attr.getName() << 2 /*variable and function*/; 837 return; 838 } 839 840 D->addAttr(::new (S.Context) WeakAttr()); 841} 842 843static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 844 // check the attribute arguments. 845 if (Attr.getNumArgs() != 0) { 846 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 847 return; 848 } 849 850 // weak_import only applies to variable & function declarations. 851 bool isDef = false; 852 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 853 isDef = (!VD->hasExternalStorage() || VD->getInit()); 854 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 855 isDef = FD->getBody(); 856 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 857 // We ignore weak import on properties and methods 858 return; 859 } else { 860 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 861 << Attr.getName() << 2 /*variable and function*/; 862 return; 863 } 864 865 // Merge should handle any subsequent violations. 866 if (isDef) { 867 S.Diag(Attr.getLoc(), 868 diag::warn_attribute_weak_import_invalid_on_definition) 869 << "weak_import" << 2 /*variable and function*/; 870 return; 871 } 872 873 D->addAttr(::new (S.Context) WeakImportAttr()); 874} 875 876static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 877 // check the attribute arguments. 878 if (Attr.getNumArgs() != 0) { 879 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 880 return; 881 } 882 883 // Attribute can be applied only to functions or variables. 884 if (isa<VarDecl>(D)) { 885 D->addAttr(::new (S.Context) DLLImportAttr()); 886 return; 887 } 888 889 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 890 if (!FD) { 891 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 892 << Attr.getName() << 2 /*variable and function*/; 893 return; 894 } 895 896 // Currently, the dllimport attribute is ignored for inlined functions. 897 // Warning is emitted. 898 if (FD->isInline()) { 899 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 900 return; 901 } 902 903 // The attribute is also overridden by a subsequent declaration as dllexport. 904 // Warning is emitted. 905 for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 906 nextAttr = nextAttr->getNext()) { 907 if (nextAttr->getKind() == AttributeList::AT_dllexport) { 908 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 909 return; 910 } 911 } 912 913 if (D->getAttr<DLLExportAttr>()) { 914 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 915 return; 916 } 917 918 D->addAttr(::new (S.Context) DLLImportAttr()); 919} 920 921static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 922 // check the attribute arguments. 923 if (Attr.getNumArgs() != 0) { 924 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 925 return; 926 } 927 928 // Attribute can be applied only to functions or variables. 929 if (isa<VarDecl>(D)) { 930 D->addAttr(::new (S.Context) DLLExportAttr()); 931 return; 932 } 933 934 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 935 if (!FD) { 936 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 937 << Attr.getName() << 2 /*variable and function*/; 938 return; 939 } 940 941 // Currently, the dllexport attribute is ignored for inlined functions, unless 942 // the -fkeep-inline-functions flag has been used. Warning is emitted; 943 if (FD->isInline()) { 944 // FIXME: ... unless the -fkeep-inline-functions flag has been used. 945 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 946 return; 947 } 948 949 D->addAttr(::new (S.Context) DLLExportAttr()); 950} 951 952static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 953 Sema &S) { 954 // Attribute has 3 arguments. 955 if (Attr.getNumArgs() != 3) { 956 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 957 return; 958 } 959 960 unsigned WGSize[3]; 961 for (unsigned i = 0; i < 3; ++i) { 962 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 963 llvm::APSInt ArgNum(32); 964 if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 965 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 966 << "reqd_work_group_size" << E->getSourceRange(); 967 return; 968 } 969 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 970 } 971 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 972 WGSize[2])); 973} 974 975static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 976 // Attribute has no arguments. 977 if (Attr.getNumArgs() != 1) { 978 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 979 return; 980 } 981 982 // Make sure that there is a string literal as the sections's single 983 // argument. 984 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 985 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 986 if (!SE) { 987 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 988 return; 989 } 990 991 std::string SectionStr(SE->getStrData(), SE->getByteLength()); 992 993 // If the target wants to validate the section specifier, make it happen. 994 std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr); 995 if (Error.empty()) { 996 D->addAttr(::new (S.Context) SectionAttr(SectionStr)); 997 return; 998 } 999 1000 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1001 << Error; 1002 1003} 1004 1005static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1006 // Attribute has no arguments. 1007 if (Attr.getNumArgs() != 0) { 1008 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1009 return; 1010 } 1011 1012 // Attribute can be applied only to functions. 1013 if (!isa<FunctionDecl>(d)) { 1014 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1015 << Attr.getName() << 0 /*function*/; 1016 return; 1017 } 1018 1019 // stdcall and fastcall attributes are mutually incompatible. 1020 if (d->getAttr<FastCallAttr>()) { 1021 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1022 << "stdcall" << "fastcall"; 1023 return; 1024 } 1025 1026 d->addAttr(::new (S.Context) StdCallAttr()); 1027} 1028 1029static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1030 // Attribute has no arguments. 1031 if (Attr.getNumArgs() != 0) { 1032 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1033 return; 1034 } 1035 1036 if (!isa<FunctionDecl>(d)) { 1037 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1038 << Attr.getName() << 0 /*function*/; 1039 return; 1040 } 1041 1042 // stdcall and fastcall attributes are mutually incompatible. 1043 if (d->getAttr<StdCallAttr>()) { 1044 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1045 << "fastcall" << "stdcall"; 1046 return; 1047 } 1048 1049 d->addAttr(::new (S.Context) FastCallAttr()); 1050} 1051 1052static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1053 // check the attribute arguments. 1054 if (Attr.getNumArgs() != 0) { 1055 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1056 return; 1057 } 1058 1059 d->addAttr(::new (S.Context) NoThrowAttr()); 1060} 1061 1062static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1063 // check the attribute arguments. 1064 if (Attr.getNumArgs() != 0) { 1065 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1066 return; 1067 } 1068 1069 d->addAttr(::new (S.Context) ConstAttr()); 1070} 1071 1072static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1073 // check the attribute arguments. 1074 if (Attr.getNumArgs() != 0) { 1075 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1076 return; 1077 } 1078 1079 d->addAttr(::new (S.Context) PureAttr()); 1080} 1081 1082static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1083 // Match gcc which ignores cleanup attrs when compiling C++. 1084 if (S.getLangOptions().CPlusPlus) 1085 return; 1086 1087 if (!Attr.getParameterName()) { 1088 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1089 return; 1090 } 1091 1092 if (Attr.getNumArgs() != 0) { 1093 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1094 return; 1095 } 1096 1097 VarDecl *VD = dyn_cast<VarDecl>(d); 1098 1099 if (!VD || !VD->hasLocalStorage()) { 1100 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1101 return; 1102 } 1103 1104 // Look up the function 1105 NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 1106 Sema::LookupOrdinaryName); 1107 if (!CleanupDecl) { 1108 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1109 Attr.getParameterName(); 1110 return; 1111 } 1112 1113 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1114 if (!FD) { 1115 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1116 Attr.getParameterName(); 1117 return; 1118 } 1119 1120 if (FD->getNumParams() != 1) { 1121 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1122 Attr.getParameterName(); 1123 return; 1124 } 1125 1126 // We're currently more strict than GCC about what function types we accept. 1127 // If this ever proves to be a problem it should be easy to fix. 1128 QualType Ty = S.Context.getPointerType(VD->getType()); 1129 QualType ParamTy = FD->getParamDecl(0)->getType(); 1130 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1131 S.Diag(Attr.getLoc(), 1132 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1133 Attr.getParameterName() << ParamTy << Ty; 1134 return; 1135 } 1136 1137 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1138} 1139 1140/// Handle __attribute__((format_arg((idx)))) attribute based on 1141/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1142static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1143 if (Attr.getNumArgs() != 1) { 1144 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1145 return; 1146 } 1147 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1148 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1149 << Attr.getName() << 0 /*function*/; 1150 return; 1151 } 1152 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1153 // needed in order to be compatible with GCC the index must start with 1. 1154 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1155 unsigned FirstIdx = 1; 1156 // checks for the 2nd argument 1157 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1158 llvm::APSInt Idx(32); 1159 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1160 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1161 << "format" << 2 << IdxExpr->getSourceRange(); 1162 return; 1163 } 1164 1165 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1166 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1167 << "format" << 2 << IdxExpr->getSourceRange(); 1168 return; 1169 } 1170 1171 unsigned ArgIdx = Idx.getZExtValue() - 1; 1172 1173 // make sure the format string is really a string 1174 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1175 1176 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1177 if (not_nsstring_type && 1178 !isCFStringType(Ty, S.Context) && 1179 (!Ty->isPointerType() || 1180 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1181 // FIXME: Should highlight the actual expression that has the wrong type. 1182 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1183 << (not_nsstring_type ? "a string type" : "an NSString") 1184 << IdxExpr->getSourceRange(); 1185 return; 1186 } 1187 Ty = getFunctionOrMethodResultType(d); 1188 if (!isNSStringType(Ty, S.Context) && 1189 !isCFStringType(Ty, S.Context) && 1190 (!Ty->isPointerType() || 1191 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1192 // FIXME: Should highlight the actual expression that has the wrong type. 1193 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1194 << (not_nsstring_type ? "string type" : "NSString") 1195 << IdxExpr->getSourceRange(); 1196 return; 1197 } 1198 1199 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 1200} 1201 1202/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1203/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1204static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1205 1206 if (!Attr.getParameterName()) { 1207 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1208 << "format" << 1; 1209 return; 1210 } 1211 1212 if (Attr.getNumArgs() != 2) { 1213 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1214 return; 1215 } 1216 1217 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1218 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1219 << Attr.getName() << 0 /*function*/; 1220 return; 1221 } 1222 1223 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1224 // needed in order to be compatible with GCC the index must start in 1 and the 1225 // limit is numargs+1 1226 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1227 unsigned FirstIdx = 1; 1228 1229 const char *Format = Attr.getParameterName()->getName(); 1230 unsigned FormatLen = Attr.getParameterName()->getLength(); 1231 1232 // Normalize the argument, __foo__ becomes foo. 1233 if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 1234 Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 1235 Format += 2; 1236 FormatLen -= 4; 1237 } 1238 1239 bool Supported = false; 1240 bool is_NSString = false; 1241 bool is_strftime = false; 1242 bool is_CFString = false; 1243 1244 switch (FormatLen) { 1245 default: break; 1246 case 5: Supported = !memcmp(Format, "scanf", 5); break; 1247 case 6: Supported = !memcmp(Format, "printf", 6); break; 1248 case 7: Supported = !memcmp(Format, "printf0", 7) || 1249 !memcmp(Format, "strfmon", 7); break; 1250 case 8: 1251 Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1252 (is_NSString = !memcmp(Format, "NSString", 8)) || 1253 (is_CFString = !memcmp(Format, "CFString", 8)); 1254 break; 1255 } 1256 1257 if (!Supported) { 1258 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1259 << "format" << Attr.getParameterName()->getName(); 1260 return; 1261 } 1262 1263 // checks for the 2nd argument 1264 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1265 llvm::APSInt Idx(32); 1266 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1267 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1268 << "format" << 2 << IdxExpr->getSourceRange(); 1269 return; 1270 } 1271 1272 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1273 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1274 << "format" << 2 << IdxExpr->getSourceRange(); 1275 return; 1276 } 1277 1278 // FIXME: Do we need to bounds check? 1279 unsigned ArgIdx = Idx.getZExtValue() - 1; 1280 1281 // make sure the format string is really a string 1282 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1283 1284 if (is_CFString) { 1285 if (!isCFStringType(Ty, S.Context)) { 1286 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1287 << "a CFString" << IdxExpr->getSourceRange(); 1288 return; 1289 } 1290 } else if (is_NSString) { 1291 // FIXME: do we need to check if the type is NSString*? What are the 1292 // semantics? 1293 if (!isNSStringType(Ty, S.Context)) { 1294 // FIXME: Should highlight the actual expression that has the wrong type. 1295 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1296 << "an NSString" << IdxExpr->getSourceRange(); 1297 return; 1298 } 1299 } else if (!Ty->isPointerType() || 1300 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1301 // FIXME: Should highlight the actual expression that has the wrong type. 1302 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1303 << "a string type" << IdxExpr->getSourceRange(); 1304 return; 1305 } 1306 1307 // check the 3rd argument 1308 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1309 llvm::APSInt FirstArg(32); 1310 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1311 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1312 << "format" << 3 << FirstArgExpr->getSourceRange(); 1313 return; 1314 } 1315 1316 // check if the function is variadic if the 3rd argument non-zero 1317 if (FirstArg != 0) { 1318 if (isFunctionOrMethodVariadic(d)) { 1319 ++NumArgs; // +1 for ... 1320 } else { 1321 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1322 return; 1323 } 1324 } 1325 1326 // strftime requires FirstArg to be 0 because it doesn't read from any 1327 // variable the input is just the current time + the format string. 1328 if (is_strftime) { 1329 if (FirstArg != 0) { 1330 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1331 << FirstArgExpr->getSourceRange(); 1332 return; 1333 } 1334 // if 0 it disables parameter checking (to use with e.g. va_list) 1335 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1336 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1337 << "format" << 3 << FirstArgExpr->getSourceRange(); 1338 return; 1339 } 1340 1341 d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 1342 Idx.getZExtValue(), FirstArg.getZExtValue())); 1343} 1344 1345static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1346 Sema &S) { 1347 // check the attribute arguments. 1348 if (Attr.getNumArgs() != 0) { 1349 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1350 return; 1351 } 1352 1353 // Try to find the underlying union declaration. 1354 RecordDecl *RD = 0; 1355 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1356 if (TD && TD->getUnderlyingType()->isUnionType()) 1357 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1358 else 1359 RD = dyn_cast<RecordDecl>(d); 1360 1361 if (!RD || !RD->isUnion()) { 1362 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1363 << Attr.getName() << 1 /*union*/; 1364 return; 1365 } 1366 1367 if (!RD->isDefinition()) { 1368 S.Diag(Attr.getLoc(), 1369 diag::warn_transparent_union_attribute_not_definition); 1370 return; 1371 } 1372 1373 RecordDecl::field_iterator Field = RD->field_begin(), 1374 FieldEnd = RD->field_end(); 1375 if (Field == FieldEnd) { 1376 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1377 return; 1378 } 1379 1380 FieldDecl *FirstField = *Field; 1381 QualType FirstType = FirstField->getType(); 1382 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1383 S.Diag(FirstField->getLocation(), 1384 diag::warn_transparent_union_attribute_floating); 1385 return; 1386 } 1387 1388 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1389 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1390 for (; Field != FieldEnd; ++Field) { 1391 QualType FieldType = Field->getType(); 1392 if (S.Context.getTypeSize(FieldType) != FirstSize || 1393 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1394 // Warn if we drop the attribute. 1395 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1396 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1397 : S.Context.getTypeAlign(FieldType); 1398 S.Diag(Field->getLocation(), 1399 diag::warn_transparent_union_attribute_field_size_align) 1400 << isSize << Field->getDeclName() << FieldBits; 1401 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1402 S.Diag(FirstField->getLocation(), 1403 diag::note_transparent_union_first_field_size_align) 1404 << isSize << FirstBits; 1405 return; 1406 } 1407 } 1408 1409 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1410} 1411 1412static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1413 // check the attribute arguments. 1414 if (Attr.getNumArgs() != 1) { 1415 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1416 return; 1417 } 1418 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1419 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1420 1421 // Make sure that there is a string literal as the annotation's single 1422 // argument. 1423 if (!SE) { 1424 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1425 return; 1426 } 1427 d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 1428 SE->getByteLength()))); 1429} 1430 1431static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1432 // check the attribute arguments. 1433 if (Attr.getNumArgs() > 1) { 1434 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1435 return; 1436 } 1437 1438 unsigned Align = 0; 1439 if (Attr.getNumArgs() == 0) { 1440 // FIXME: This should be the target specific maximum alignment. 1441 // (For now we just use 128 bits which is the maximum on X86). 1442 Align = 128; 1443 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1444 return; 1445 } 1446 1447 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1448 llvm::APSInt Alignment(32); 1449 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1450 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1451 << "aligned" << alignmentExpr->getSourceRange(); 1452 return; 1453 } 1454 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1455 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1456 << alignmentExpr->getSourceRange(); 1457 return; 1458 } 1459 1460 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1461} 1462 1463/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1464/// type. 1465/// 1466/// Despite what would be logical, the mode attribute is a decl attribute, not a 1467/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1468/// HImode, not an intermediate pointer. 1469static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1470 // This attribute isn't documented, but glibc uses it. It changes 1471 // the width of an int or unsigned int to the specified size. 1472 1473 // Check that there aren't any arguments 1474 if (Attr.getNumArgs() != 0) { 1475 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1476 return; 1477 } 1478 1479 IdentifierInfo *Name = Attr.getParameterName(); 1480 if (!Name) { 1481 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1482 return; 1483 } 1484 const char *Str = Name->getName(); 1485 unsigned Len = Name->getLength(); 1486 1487 // Normalize the attribute name, __foo__ becomes foo. 1488 if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1489 Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1490 Str += 2; 1491 Len -= 4; 1492 } 1493 1494 unsigned DestWidth = 0; 1495 bool IntegerMode = true; 1496 bool ComplexMode = false; 1497 switch (Len) { 1498 case 2: 1499 switch (Str[0]) { 1500 case 'Q': DestWidth = 8; break; 1501 case 'H': DestWidth = 16; break; 1502 case 'S': DestWidth = 32; break; 1503 case 'D': DestWidth = 64; break; 1504 case 'X': DestWidth = 96; break; 1505 case 'T': DestWidth = 128; break; 1506 } 1507 if (Str[1] == 'F') { 1508 IntegerMode = false; 1509 } else if (Str[1] == 'C') { 1510 IntegerMode = false; 1511 ComplexMode = true; 1512 } else if (Str[1] != 'I') { 1513 DestWidth = 0; 1514 } 1515 break; 1516 case 4: 1517 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1518 // pointer on PIC16 and other embedded platforms. 1519 if (!memcmp(Str, "word", 4)) 1520 DestWidth = S.Context.Target.getPointerWidth(0); 1521 if (!memcmp(Str, "byte", 4)) 1522 DestWidth = S.Context.Target.getCharWidth(); 1523 break; 1524 case 7: 1525 if (!memcmp(Str, "pointer", 7)) 1526 DestWidth = S.Context.Target.getPointerWidth(0); 1527 break; 1528 } 1529 1530 QualType OldTy; 1531 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1532 OldTy = TD->getUnderlyingType(); 1533 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1534 OldTy = VD->getType(); 1535 else { 1536 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1537 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1538 return; 1539 } 1540 1541 if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 1542 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1543 else if (IntegerMode) { 1544 if (!OldTy->isIntegralType()) 1545 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1546 } else if (ComplexMode) { 1547 if (!OldTy->isComplexType()) 1548 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1549 } else { 1550 if (!OldTy->isFloatingType()) 1551 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1552 } 1553 1554 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1555 // and friends, at least with glibc. 1556 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1557 // width on unusual platforms. 1558 // FIXME: Make sure floating-point mappings are accurate 1559 // FIXME: Support XF and TF types 1560 QualType NewTy; 1561 switch (DestWidth) { 1562 case 0: 1563 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1564 return; 1565 default: 1566 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1567 return; 1568 case 8: 1569 if (!IntegerMode) { 1570 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1571 return; 1572 } 1573 if (OldTy->isSignedIntegerType()) 1574 NewTy = S.Context.SignedCharTy; 1575 else 1576 NewTy = S.Context.UnsignedCharTy; 1577 break; 1578 case 16: 1579 if (!IntegerMode) { 1580 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1581 return; 1582 } 1583 if (OldTy->isSignedIntegerType()) 1584 NewTy = S.Context.ShortTy; 1585 else 1586 NewTy = S.Context.UnsignedShortTy; 1587 break; 1588 case 32: 1589 if (!IntegerMode) 1590 NewTy = S.Context.FloatTy; 1591 else if (OldTy->isSignedIntegerType()) 1592 NewTy = S.Context.IntTy; 1593 else 1594 NewTy = S.Context.UnsignedIntTy; 1595 break; 1596 case 64: 1597 if (!IntegerMode) 1598 NewTy = S.Context.DoubleTy; 1599 else if (OldTy->isSignedIntegerType()) 1600 NewTy = S.Context.LongLongTy; 1601 else 1602 NewTy = S.Context.UnsignedLongLongTy; 1603 break; 1604 case 96: 1605 NewTy = S.Context.LongDoubleTy; 1606 break; 1607 case 128: 1608 if (!IntegerMode) { 1609 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1610 return; 1611 } 1612 NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1613 break; 1614 } 1615 1616 if (ComplexMode) { 1617 NewTy = S.Context.getComplexType(NewTy); 1618 } 1619 1620 // Install the new type. 1621 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1622 TD->setUnderlyingType(NewTy); 1623 else 1624 cast<ValueDecl>(D)->setType(NewTy); 1625} 1626 1627static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1628 // check the attribute arguments. 1629 if (Attr.getNumArgs() > 0) { 1630 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1631 return; 1632 } 1633 1634 if (!isFunctionOrMethod(d)) { 1635 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1636 << Attr.getName() << 0 /*function*/; 1637 return; 1638 } 1639 1640 d->addAttr(::new (S.Context) NodebugAttr()); 1641} 1642 1643static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1644 // check the attribute arguments. 1645 if (Attr.getNumArgs() != 0) { 1646 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1647 return; 1648 } 1649 1650 if (!isa<FunctionDecl>(d)) { 1651 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1652 << Attr.getName() << 0 /*function*/; 1653 return; 1654 } 1655 1656 d->addAttr(::new (S.Context) NoinlineAttr()); 1657} 1658 1659static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1660 // check the attribute arguments. 1661 if (Attr.getNumArgs() != 0) { 1662 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1663 return; 1664 } 1665 1666 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1667 if (Fn == 0) { 1668 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1669 << Attr.getName() << 0 /*function*/; 1670 return; 1671 } 1672 1673 if (!Fn->isInline()) { 1674 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1675 return; 1676 } 1677 1678 d->addAttr(::new (S.Context) GNUInlineAttr()); 1679} 1680 1681static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1682 // check the attribute arguments. 1683 if (Attr.getNumArgs() != 1) { 1684 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1685 return; 1686 } 1687 1688 if (!isFunctionOrMethod(d)) { 1689 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1690 << Attr.getName() << 0 /*function*/; 1691 return; 1692 } 1693 1694 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1695 llvm::APSInt NumParams(32); 1696 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1697 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1698 << "regparm" << NumParamsExpr->getSourceRange(); 1699 return; 1700 } 1701 1702 if (S.Context.Target.getRegParmMax() == 0) { 1703 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1704 << NumParamsExpr->getSourceRange(); 1705 return; 1706 } 1707 1708 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1709 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1710 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1711 return; 1712 } 1713 1714 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1715} 1716 1717//===----------------------------------------------------------------------===// 1718// Checker-specific attribute handlers. 1719//===----------------------------------------------------------------------===// 1720 1721static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1722 Sema &S) { 1723 1724 QualType RetTy; 1725 1726 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1727 RetTy = MD->getResultType(); 1728 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1729 RetTy = FD->getResultType(); 1730 else { 1731 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1732 << Attr.getName() << 3 /* function or method */; 1733 return; 1734 } 1735 1736 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1737 || RetTy->getAsObjCObjectPointerType())) { 1738 S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 1739 << Attr.getName(); 1740 return; 1741 } 1742 1743 switch (Attr.getKind()) { 1744 default: 1745 assert(0 && "invalid ownership attribute"); 1746 return; 1747 case AttributeList::AT_cf_returns_retained: 1748 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1749 return; 1750 case AttributeList::AT_ns_returns_retained: 1751 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1752 return; 1753 }; 1754} 1755 1756//===----------------------------------------------------------------------===// 1757// Top Level Sema Entry Points 1758//===----------------------------------------------------------------------===// 1759 1760/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1761/// the attribute applies to decls. If the attribute is a type attribute, just 1762/// silently ignore it. 1763static void ProcessDeclAttribute(Scope *scope, Decl *D, 1764 const AttributeList &Attr, Sema &S) { 1765 if (Attr.isDeclspecAttribute()) 1766 // FIXME: Try to deal with __declspec attributes! 1767 return; 1768 switch (Attr.getKind()) { 1769 case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1770 case AttributeList::AT_address_space: 1771 case AttributeList::AT_objc_gc: 1772 // Ignore these, these are type attributes, handled by 1773 // ProcessTypeAttributes. 1774 break; 1775 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1776 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1777 case AttributeList::AT_always_inline: 1778 HandleAlwaysInlineAttr (D, Attr, S); break; 1779 case AttributeList::AT_analyzer_noreturn: 1780 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1781 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1782 case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1783 case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 1784 case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1785 case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 1786 case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 1787 case AttributeList::AT_ext_vector_type: 1788 HandleExtVectorTypeAttr(scope, D, Attr, S); 1789 break; 1790 case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1791 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1792 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1793 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 1794 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1795 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1796 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1797 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1798 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1799 1800 // Checker-specific. 1801 case AttributeList::AT_ns_returns_retained: 1802 case AttributeList::AT_cf_returns_retained: 1803 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1804 1805 case AttributeList::AT_reqd_wg_size: 1806 HandleReqdWorkGroupSize(D, Attr, S); break; 1807 1808 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1809 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1810 case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1811 case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 1812 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1813 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1814 case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 1815 case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1816 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1817 break; 1818 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1819 case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1820 case AttributeList::AT_transparent_union: 1821 HandleTransparentUnionAttr(D, Attr, S); 1822 break; 1823 case AttributeList::AT_objc_exception: 1824 HandleObjCExceptionAttr(D, Attr, S); 1825 break; 1826 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1827 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1828 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1829 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1830 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1831 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1832 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1833 case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 1834 case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 1835 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1836 case AttributeList::IgnoredAttribute: 1837 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1838 // Just ignore 1839 break; 1840 default: 1841 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1842 break; 1843 } 1844} 1845 1846/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1847/// attribute list to the specified decl, ignoring any type attributes. 1848void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1849 while (AttrList) { 1850 ProcessDeclAttribute(S, D, *AttrList, *this); 1851 AttrList = AttrList->getNext(); 1852 } 1853} 1854 1855/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1856/// #pragma weak needs a non-definition decl and source may not have one 1857NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) 1858{ 1859 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1860 NamedDecl *NewD = 0; 1861 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1862 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1863 FD->getLocation(), DeclarationName(II), 1864 FD->getType()); 1865 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1866 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1867 VD->getLocation(), II, 1868 VD->getType(), VD->getStorageClass()); 1869 } 1870 return NewD; 1871} 1872 1873/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1874/// applied to it, possibly with an alias. 1875void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1876 if (!W.getUsed()) { // only do this once 1877 W.setUsed(true); 1878 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1879 IdentifierInfo *NDId = ND->getIdentifier(); 1880 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1881 NewD->addAttr(::new (Context) AliasAttr(NDId->getName())); 1882 NewD->addAttr(::new (Context) WeakAttr()); 1883 WeakTopLevelDecl.push_back(NewD); 1884 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1885 // to insert Decl at TU scope, sorry. 1886 DeclContext *SavedContext = CurContext; 1887 CurContext = Context.getTranslationUnitDecl(); 1888 PushOnScopeChains(NewD, S); 1889 CurContext = SavedContext; 1890 } else { // just add weak to existing 1891 ND->addAttr(::new (Context) WeakAttr()); 1892 } 1893 } 1894} 1895 1896/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1897/// it, apply them to D. This is a bit tricky because PD can have attributes 1898/// specified in many different places, and we need to find and apply them all. 1899void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1900 // Handle #pragma weak 1901 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1902 if (ND->hasLinkage()) { 1903 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1904 if (W != WeakInfo()) { 1905 // Identifier referenced by #pragma weak before it was declared 1906 DeclApplyPragmaWeak(S, ND, W); 1907 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1908 } 1909 } 1910 } 1911 1912 // Apply decl attributes from the DeclSpec if present. 1913 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 1914 ProcessDeclAttributeList(S, D, Attrs); 1915 1916 // Walk the declarator structure, applying decl attributes that were in a type 1917 // position to the decl itself. This handles cases like: 1918 // int *__attr__(x)** D; 1919 // when X is a decl attribute. 1920 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 1921 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 1922 ProcessDeclAttributeList(S, D, Attrs); 1923 1924 // Finally, apply any attributes on the decl itself. 1925 if (const AttributeList *Attrs = PD.getAttributes()) 1926 ProcessDeclAttributeList(S, D, Attrs); 1927} 1928