SemaDeclAttr.cpp revision e88b6e3c31125b4bb55d60aa3b982735d308c792
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 "TargetAttributesSema.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/Expr.h" 19#include "clang/Basic/TargetInfo.h" 20#include "clang/Parse/DeclSpec.h" 21#include "llvm/ADT/StringExtras.h" 22using namespace clang; 23 24//===----------------------------------------------------------------------===// 25// Helper functions 26//===----------------------------------------------------------------------===// 27 28static const FunctionType *getFunctionType(const Decl *d, 29 bool blocksToo = true) { 30 QualType Ty; 31 if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 32 Ty = decl->getType(); 33 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 34 Ty = decl->getType(); 35 else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 36 Ty = decl->getUnderlyingType(); 37 else 38 return 0; 39 40 if (Ty->isFunctionPointerType()) 41 Ty = Ty->getAs<PointerType>()->getPointeeType(); 42 else if (blocksToo && Ty->isBlockPointerType()) 43 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 44 45 return Ty->getAs<FunctionType>(); 46} 47 48// FIXME: We should provide an abstraction around a method or function 49// to provide the following bits of information. 50 51/// isFunction - Return true if the given decl has function 52/// type (function or function-typed variable). 53static bool isFunction(const Decl *d) { 54 return getFunctionType(d, false) != NULL; 55} 56 57/// isFunctionOrMethod - Return true if the given decl has function 58/// type (function or function-typed variable) or an Objective-C 59/// method. 60static bool isFunctionOrMethod(const Decl *d) { 61 return isFunction(d)|| isa<ObjCMethodDecl>(d); 62} 63 64/// isFunctionOrMethodOrBlock - Return true if the given decl has function 65/// type (function or function-typed variable) or an Objective-C 66/// method or a block. 67static bool isFunctionOrMethodOrBlock(const Decl *d) { 68 if (isFunctionOrMethod(d)) 69 return true; 70 // check for block is more involved. 71 if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 72 QualType Ty = V->getType(); 73 return Ty->isBlockPointerType(); 74 } 75 return isa<BlockDecl>(d); 76} 77 78/// hasFunctionProto - Return true if the given decl has a argument 79/// information. This decl should have already passed 80/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 81static bool hasFunctionProto(const Decl *d) { 82 if (const FunctionType *FnTy = getFunctionType(d)) 83 return isa<FunctionProtoType>(FnTy); 84 else { 85 assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 86 return true; 87 } 88} 89 90/// getFunctionOrMethodNumArgs - Return number of function or method 91/// arguments. It is an error to call this on a K&R function (use 92/// hasFunctionProto first). 93static unsigned getFunctionOrMethodNumArgs(const Decl *d) { 94 if (const FunctionType *FnTy = getFunctionType(d)) 95 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 96 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 97 return BD->getNumParams(); 98 return cast<ObjCMethodDecl>(d)->param_size(); 99} 100 101static QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 102 if (const FunctionType *FnTy = getFunctionType(d)) 103 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 104 if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 105 return BD->getParamDecl(Idx)->getType(); 106 107 return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 108} 109 110static QualType getFunctionOrMethodResultType(const Decl *d) { 111 if (const FunctionType *FnTy = getFunctionType(d)) 112 return cast<FunctionProtoType>(FnTy)->getResultType(); 113 return cast<ObjCMethodDecl>(d)->getResultType(); 114} 115 116static bool isFunctionOrMethodVariadic(const Decl *d) { 117 if (const FunctionType *FnTy = getFunctionType(d)) { 118 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 119 return proto->isVariadic(); 120 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 121 return BD->IsVariadic(); 122 else { 123 return cast<ObjCMethodDecl>(d)->isVariadic(); 124 } 125} 126 127static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 128 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 129 if (!PT) 130 return false; 131 132 const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>(); 133 if (!ClsT) 134 return false; 135 136 IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 137 138 // FIXME: Should we walk the chain of classes? 139 return ClsName == &Ctx.Idents.get("NSString") || 140 ClsName == &Ctx.Idents.get("NSMutableString"); 141} 142 143static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 144 const PointerType *PT = T->getAs<PointerType>(); 145 if (!PT) 146 return false; 147 148 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 149 if (!RT) 150 return false; 151 152 const RecordDecl *RD = RT->getDecl(); 153 if (RD->getTagKind() != TagDecl::TK_struct) 154 return false; 155 156 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 157} 158 159//===----------------------------------------------------------------------===// 160// Attribute Implementations 161//===----------------------------------------------------------------------===// 162 163// FIXME: All this manual attribute parsing code is gross. At the 164// least add some helper functions to check most argument patterns (# 165// and types of args). 166 167static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 168 const AttributeList &Attr, Sema &S) { 169 TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 170 if (tDecl == 0) { 171 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 172 return; 173 } 174 175 QualType curType = tDecl->getUnderlyingType(); 176 177 Expr *sizeExpr; 178 179 // Special case where the argument is a template id. 180 if (Attr.getParameterName()) { 181 CXXScopeSpec SS; 182 UnqualifiedId id; 183 id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 184 sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 185 } else { 186 // check the attribute arguments. 187 if (Attr.getNumArgs() != 1) { 188 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 189 return; 190 } 191 sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 192 } 193 194 // Instantiate/Install the vector type, and let Sema build the type for us. 195 // This will run the reguired checks. 196 QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 197 if (!T.isNull()) { 198 // FIXME: preserve the old source info. 199 tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 200 201 // Remember this typedef decl, we will need it later for diagnostics. 202 S.ExtVectorDecls.push_back(tDecl); 203 } 204} 205 206static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 207 // check the attribute arguments. 208 if (Attr.getNumArgs() > 0) { 209 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 210 return; 211 } 212 213 if (TagDecl *TD = dyn_cast<TagDecl>(d)) 214 TD->addAttr(::new (S.Context) PackedAttr); 215 else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 216 // If the alignment is less than or equal to 8 bits, the packed attribute 217 // has no effect. 218 if (!FD->getType()->isIncompleteType() && 219 S.Context.getTypeAlign(FD->getType()) <= 8) 220 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 221 << Attr.getName() << FD->getType(); 222 else 223 FD->addAttr(::new (S.Context) PackedAttr); 224 } else 225 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 226} 227 228static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 229 // check the attribute arguments. 230 if (Attr.getNumArgs() > 0) { 231 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 232 return; 233 } 234 235 // The IBAction attributes only apply to instance methods. 236 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 237 if (MD->isInstanceMethod()) { 238 d->addAttr(::new (S.Context) IBActionAttr()); 239 return; 240 } 241 242 S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 243} 244 245static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 246 // check the attribute arguments. 247 if (Attr.getNumArgs() > 0) { 248 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 249 return; 250 } 251 252 // The IBOutlet attributes only apply to instance variables of 253 // Objective-C classes. 254 if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 255 d->addAttr(::new (S.Context) IBOutletAttr()); 256 return; 257 } 258 259 S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 260} 261 262static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 263 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 264 // ignore it as well 265 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 266 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 267 << Attr.getName() << 0 /*function*/; 268 return; 269 } 270 271 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 272 273 // The nonnull attribute only applies to pointers. 274 llvm::SmallVector<unsigned, 10> NonNullArgs; 275 276 for (AttributeList::arg_iterator I=Attr.arg_begin(), 277 E=Attr.arg_end(); I!=E; ++I) { 278 279 280 // The argument must be an integer constant expression. 281 Expr *Ex = static_cast<Expr *>(*I); 282 llvm::APSInt ArgNum(32); 283 if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 284 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 285 << "nonnull" << Ex->getSourceRange(); 286 return; 287 } 288 289 unsigned x = (unsigned) ArgNum.getZExtValue(); 290 291 if (x < 1 || x > NumArgs) { 292 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 293 << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 294 return; 295 } 296 297 --x; 298 299 // Is the function argument a pointer type? 300 QualType T = getFunctionOrMethodArgType(d, x); 301 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 302 // FIXME: Should also highlight argument in decl. 303 S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 304 << "nonnull" << Ex->getSourceRange(); 305 continue; 306 } 307 308 NonNullArgs.push_back(x); 309 } 310 311 // If no arguments were specified to __attribute__((nonnull)) then all pointer 312 // arguments have a nonnull attribute. 313 if (NonNullArgs.empty()) { 314 for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 315 QualType T = getFunctionOrMethodArgType(d, I); 316 if (T->isAnyPointerType() || T->isBlockPointerType()) 317 NonNullArgs.push_back(I); 318 } 319 320 if (NonNullArgs.empty()) { 321 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 322 return; 323 } 324 } 325 326 unsigned* start = &NonNullArgs[0]; 327 unsigned size = NonNullArgs.size(); 328 std::sort(start, start + size); 329 d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size)); 330} 331 332static bool isStaticVarOrStaticFunciton(Decl *D) { 333 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 334 return VD->getStorageClass() == VarDecl::Static; 335 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 336 return FD->getStorageClass() == FunctionDecl::Static; 337 return false; 338} 339 340static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 341 // Check the attribute arguments. 342 if (Attr.getNumArgs() > 1) { 343 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 344 return; 345 } 346 347 // gcc rejects 348 // class c { 349 // static int a __attribute__((weakref ("v2"))); 350 // static int b() __attribute__((weakref ("f3"))); 351 // }; 352 // and ignores the attributes of 353 // void f(void) { 354 // static int a __attribute__((weakref ("v2"))); 355 // } 356 // we reject them 357 if (const DeclContext *Ctx = d->getDeclContext()) { 358 Ctx = Ctx->getLookupContext(); 359 if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) { 360 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 361 dyn_cast<NamedDecl>(d)->getNameAsString(); 362 return; 363 } 364 } 365 366 // The GCC manual says 367 // 368 // At present, a declaration to which `weakref' is attached can only 369 // be `static'. 370 // 371 // It also says 372 // 373 // Without a TARGET, 374 // given as an argument to `weakref' or to `alias', `weakref' is 375 // equivalent to `weak'. 376 // 377 // gcc 4.4.1 will accept 378 // int a7 __attribute__((weakref)); 379 // as 380 // int a7 __attribute__((weak)); 381 // This looks like a bug in gcc. We reject that for now. We should revisit 382 // it if this behaviour is actually used. 383 384 if (!isStaticVarOrStaticFunciton(d)) { 385 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 386 dyn_cast<NamedDecl>(d)->getNameAsString(); 387 return; 388 } 389 390 // GCC rejects 391 // static ((alias ("y"), weakref)). 392 // Should we? How to check that weakref is before or after alias? 393 394 if (Attr.getNumArgs() == 1) { 395 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 396 Arg = Arg->IgnoreParenCasts(); 397 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 398 399 if (Str == 0 || Str->isWide()) { 400 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 401 << "weakref" << 1; 402 return; 403 } 404 // GCC will accept anything as the argument of weakref. Should we 405 // check for an existing decl? 406 d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 407 } 408 409 d->addAttr(::new (S.Context) WeakRefAttr()); 410} 411 412static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 413 // check the attribute arguments. 414 if (Attr.getNumArgs() != 1) { 415 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 416 return; 417 } 418 419 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 420 Arg = Arg->IgnoreParenCasts(); 421 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 422 423 if (Str == 0 || Str->isWide()) { 424 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 425 << "alias" << 1; 426 return; 427 } 428 429 // FIXME: check if target symbol exists in current file 430 431 d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 432} 433 434static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 435 Sema &S) { 436 // check the attribute arguments. 437 if (Attr.getNumArgs() != 0) { 438 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 439 return; 440 } 441 442 if (!isa<FunctionDecl>(d)) { 443 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 444 << Attr.getName() << 0 /*function*/; 445 return; 446 } 447 448 d->addAttr(::new (S.Context) AlwaysInlineAttr()); 449} 450 451static void HandleMallocAttr(Decl *d, const AttributeList &Attr, 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; 456 } 457 458 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 459 QualType RetTy = FD->getResultType(); 460 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 461 d->addAttr(::new (S.Context) MallocAttr()); 462 return; 463 } 464 } 465 466 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 467} 468 469static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 470 Sema &S) { 471 // check the attribute arguments. 472 if (Attr.getNumArgs() != 0) { 473 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 474 return false; 475 } 476 477 if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 478 ValueDecl *VD = dyn_cast<ValueDecl>(d); 479 if (VD == 0 || (!VD->getType()->isBlockPointerType() 480 && !VD->getType()->isFunctionPointerType())) { 481 S.Diag(Attr.getLoc(), 482 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 483 : diag::warn_attribute_wrong_decl_type) 484 << Attr.getName() << 0 /*function*/; 485 return false; 486 } 487 } 488 489 return true; 490} 491 492static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 493 // Don't apply as a decl attribute to ValueDecl. 494 // FIXME: probably ought to diagnose this. 495 if (isa<ValueDecl>(d)) 496 return; 497 498 if (HandleCommonNoReturnAttr(d, Attr, S)) 499 d->addAttr(::new (S.Context) NoReturnAttr()); 500} 501 502static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 503 Sema &S) { 504 if (HandleCommonNoReturnAttr(d, Attr, S)) 505 d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 506} 507 508static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 509 if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 510 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 511 << Attr.getName() << 8 /*function, method, or parameter*/; 512 return; 513 } 514 // FIXME: Actually store the attribute on the declaration 515} 516 517static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 518 // check the attribute arguments. 519 if (Attr.getNumArgs() != 0) { 520 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 521 return; 522 } 523 524 if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d)) { 525 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 526 << Attr.getName() << 2 /*variable and function*/; 527 return; 528 } 529 530 d->addAttr(::new (S.Context) UnusedAttr()); 531} 532 533static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 534 // check the attribute arguments. 535 if (Attr.getNumArgs() != 0) { 536 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 537 return; 538 } 539 540 if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 541 if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 542 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 543 return; 544 } 545 } else if (!isFunctionOrMethod(d)) { 546 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 547 << Attr.getName() << 2 /*variable and function*/; 548 return; 549 } 550 551 d->addAttr(::new (S.Context) UsedAttr()); 552} 553 554static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 555 // check the attribute arguments. 556 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 557 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 558 << "0 or 1"; 559 return; 560 } 561 562 int priority = 65535; // FIXME: Do not hardcode such constants. 563 if (Attr.getNumArgs() > 0) { 564 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 565 llvm::APSInt Idx(32); 566 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 567 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 568 << "constructor" << 1 << E->getSourceRange(); 569 return; 570 } 571 priority = Idx.getZExtValue(); 572 } 573 574 if (!isa<FunctionDecl>(d)) { 575 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 576 << Attr.getName() << 0 /*function*/; 577 return; 578 } 579 580 d->addAttr(::new (S.Context) ConstructorAttr(priority)); 581} 582 583static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 584 // check the attribute arguments. 585 if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 586 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 587 << "0 or 1"; 588 return; 589 } 590 591 int priority = 65535; // FIXME: Do not hardcode such constants. 592 if (Attr.getNumArgs() > 0) { 593 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 594 llvm::APSInt Idx(32); 595 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 596 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 597 << "destructor" << 1 << E->getSourceRange(); 598 return; 599 } 600 priority = Idx.getZExtValue(); 601 } 602 603 if (!isa<FunctionDecl>(d)) { 604 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 605 << Attr.getName() << 0 /*function*/; 606 return; 607 } 608 609 d->addAttr(::new (S.Context) DestructorAttr(priority)); 610} 611 612static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 613 // check the attribute arguments. 614 if (Attr.getNumArgs() != 0) { 615 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 616 return; 617 } 618 619 d->addAttr(::new (S.Context) DeprecatedAttr()); 620} 621 622static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 623 // check the attribute arguments. 624 if (Attr.getNumArgs() != 0) { 625 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 626 return; 627 } 628 629 d->addAttr(::new (S.Context) UnavailableAttr()); 630} 631 632static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 633 // check the attribute arguments. 634 if (Attr.getNumArgs() != 1) { 635 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 636 return; 637 } 638 639 Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 640 Arg = Arg->IgnoreParenCasts(); 641 StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 642 643 if (Str == 0 || Str->isWide()) { 644 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 645 << "visibility" << 1; 646 return; 647 } 648 649 llvm::StringRef TypeStr = Str->getString(); 650 VisibilityAttr::VisibilityTypes type; 651 652 if (TypeStr == "default") 653 type = VisibilityAttr::DefaultVisibility; 654 else if (TypeStr == "hidden") 655 type = VisibilityAttr::HiddenVisibility; 656 else if (TypeStr == "internal") 657 type = VisibilityAttr::HiddenVisibility; // FIXME 658 else if (TypeStr == "protected") 659 type = VisibilityAttr::ProtectedVisibility; 660 else { 661 S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 662 return; 663 } 664 665 d->addAttr(::new (S.Context) VisibilityAttr(type)); 666} 667 668static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 669 Sema &S) { 670 if (Attr.getNumArgs() != 0) { 671 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 672 return; 673 } 674 675 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 676 if (OCI == 0) { 677 S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 678 return; 679 } 680 681 D->addAttr(::new (S.Context) ObjCExceptionAttr()); 682} 683 684static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 685 if (Attr.getNumArgs() != 0) { 686 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 687 return; 688 } 689 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 690 QualType T = TD->getUnderlyingType(); 691 if (!T->isPointerType() || 692 !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 693 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 694 return; 695 } 696 } 697 D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 698} 699 700static void 701HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 702 if (Attr.getNumArgs() != 0) { 703 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 704 return; 705 } 706 707 if (!isa<FunctionDecl>(D)) { 708 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 709 return; 710 } 711 712 D->addAttr(::new (S.Context) OverloadableAttr()); 713} 714 715static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 716 if (!Attr.getParameterName()) { 717 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 718 << "blocks" << 1; 719 return; 720 } 721 722 if (Attr.getNumArgs() != 0) { 723 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 724 return; 725 } 726 727 BlocksAttr::BlocksAttrTypes type; 728 if (Attr.getParameterName()->isStr("byref")) 729 type = BlocksAttr::ByRef; 730 else { 731 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 732 << "blocks" << Attr.getParameterName(); 733 return; 734 } 735 736 d->addAttr(::new (S.Context) BlocksAttr(type)); 737} 738 739static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 740 // check the attribute arguments. 741 if (Attr.getNumArgs() > 2) { 742 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 743 << "0, 1 or 2"; 744 return; 745 } 746 747 int sentinel = 0; 748 if (Attr.getNumArgs() > 0) { 749 Expr *E = static_cast<Expr *>(Attr.getArg(0)); 750 llvm::APSInt Idx(32); 751 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 752 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 753 << "sentinel" << 1 << E->getSourceRange(); 754 return; 755 } 756 sentinel = Idx.getZExtValue(); 757 758 if (sentinel < 0) { 759 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 760 << E->getSourceRange(); 761 return; 762 } 763 } 764 765 int nullPos = 0; 766 if (Attr.getNumArgs() > 1) { 767 Expr *E = static_cast<Expr *>(Attr.getArg(1)); 768 llvm::APSInt Idx(32); 769 if (!E->isIntegerConstantExpr(Idx, S.Context)) { 770 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 771 << "sentinel" << 2 << E->getSourceRange(); 772 return; 773 } 774 nullPos = Idx.getZExtValue(); 775 776 if (nullPos > 1 || nullPos < 0) { 777 // FIXME: This error message could be improved, it would be nice 778 // to say what the bounds actually are. 779 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 780 << E->getSourceRange(); 781 return; 782 } 783 } 784 785 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 786 const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 787 assert(FT && "FunctionDecl has non-function type?"); 788 789 if (isa<FunctionNoProtoType>(FT)) { 790 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 791 return; 792 } 793 794 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 795 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 796 return; 797 } 798 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 799 if (!MD->isVariadic()) { 800 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 801 return; 802 } 803 } else if (isa<BlockDecl>(d)) { 804 // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 805 // caller. 806 ; 807 } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 808 QualType Ty = V->getType(); 809 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 810 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 811 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 812 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 813 int m = Ty->isFunctionPointerType() ? 0 : 1; 814 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 815 return; 816 } 817 } else { 818 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 819 << Attr.getName() << 6 /*function, method or block */; 820 return; 821 } 822 } else { 823 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 824 << Attr.getName() << 6 /*function, method or block */; 825 return; 826 } 827 d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 828} 829 830static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 831 // check the attribute arguments. 832 if (Attr.getNumArgs() != 0) { 833 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 834 return; 835 } 836 837 if (!isFunction(D)) { 838 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 839 << Attr.getName() << 0 /*function*/; 840 return; 841 } 842 843 if (getFunctionType(D)->getResultType()->isVoidType()) { 844 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function) 845 << Attr.getName(); 846 return; 847 } 848 849 D->addAttr(::new (S.Context) WarnUnusedResultAttr()); 850} 851 852static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 853 // check the attribute arguments. 854 if (Attr.getNumArgs() != 0) { 855 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 856 return; 857 } 858 859 /* weak only applies to non-static declarations */ 860 if (isStaticVarOrStaticFunciton(D)) { 861 S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 862 dyn_cast<NamedDecl>(D)->getNameAsString(); 863 return; 864 } 865 866 // TODO: could also be applied to methods? 867 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 868 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 869 << Attr.getName() << 2 /*variable and function*/; 870 return; 871 } 872 873 D->addAttr(::new (S.Context) WeakAttr()); 874} 875 876static void HandleWeakImportAttr(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 // weak_import only applies to variable & function declarations. 884 bool isDef = false; 885 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 886 isDef = (!VD->hasExternalStorage() || VD->getInit()); 887 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 888 isDef = FD->getBody(); 889 } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 890 // We ignore weak import on properties and methods 891 return; 892 } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 893 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 894 << Attr.getName() << 2 /*variable and function*/; 895 return; 896 } 897 898 // Merge should handle any subsequent violations. 899 if (isDef) { 900 S.Diag(Attr.getLoc(), 901 diag::warn_attribute_weak_import_invalid_on_definition) 902 << "weak_import" << 2 /*variable and function*/; 903 return; 904 } 905 906 D->addAttr(::new (S.Context) WeakImportAttr()); 907} 908 909static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 910 Sema &S) { 911 // Attribute has 3 arguments. 912 if (Attr.getNumArgs() != 3) { 913 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 914 return; 915 } 916 917 unsigned WGSize[3]; 918 for (unsigned i = 0; i < 3; ++i) { 919 Expr *E = static_cast<Expr *>(Attr.getArg(i)); 920 llvm::APSInt ArgNum(32); 921 if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 922 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 923 << "reqd_work_group_size" << E->getSourceRange(); 924 return; 925 } 926 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 927 } 928 D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 929 WGSize[2])); 930} 931 932static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 933 // Attribute has no arguments. 934 if (Attr.getNumArgs() != 1) { 935 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 936 return; 937 } 938 939 // Make sure that there is a string literal as the sections's single 940 // argument. 941 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 942 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 943 if (!SE) { 944 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 945 return; 946 } 947 948 // If the target wants to validate the section specifier, make it happen. 949 std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 950 if (!Error.empty()) { 951 S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 952 << Error; 953 return; 954 } 955 956 // This attribute cannot be applied to local variables. 957 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 958 S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 959 return; 960 } 961 962 D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString())); 963} 964 965 966static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 967 // check the attribute arguments. 968 if (Attr.getNumArgs() != 0) { 969 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 970 return; 971 } 972 973 d->addAttr(::new (S.Context) NoThrowAttr()); 974} 975 976static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 977 // check the attribute arguments. 978 if (Attr.getNumArgs() != 0) { 979 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 980 return; 981 } 982 983 d->addAttr(::new (S.Context) ConstAttr()); 984} 985 986static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 987 // check the attribute arguments. 988 if (Attr.getNumArgs() != 0) { 989 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 990 return; 991 } 992 993 d->addAttr(::new (S.Context) PureAttr()); 994} 995 996static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 997 if (!Attr.getParameterName()) { 998 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 999 return; 1000 } 1001 1002 if (Attr.getNumArgs() != 0) { 1003 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1004 return; 1005 } 1006 1007 VarDecl *VD = dyn_cast<VarDecl>(d); 1008 1009 if (!VD || !VD->hasLocalStorage()) { 1010 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1011 return; 1012 } 1013 1014 // Look up the function 1015 NamedDecl *CleanupDecl 1016 = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1017 Sema::LookupOrdinaryName); 1018 if (!CleanupDecl) { 1019 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1020 Attr.getParameterName(); 1021 return; 1022 } 1023 1024 FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1025 if (!FD) { 1026 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1027 Attr.getParameterName(); 1028 return; 1029 } 1030 1031 if (FD->getNumParams() != 1) { 1032 S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1033 Attr.getParameterName(); 1034 return; 1035 } 1036 1037 // We're currently more strict than GCC about what function types we accept. 1038 // If this ever proves to be a problem it should be easy to fix. 1039 QualType Ty = S.Context.getPointerType(VD->getType()); 1040 QualType ParamTy = FD->getParamDecl(0)->getType(); 1041 if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1042 S.Diag(Attr.getLoc(), 1043 diag::err_attribute_cleanup_func_arg_incompatible_type) << 1044 Attr.getParameterName() << ParamTy << Ty; 1045 return; 1046 } 1047 1048 d->addAttr(::new (S.Context) CleanupAttr(FD)); 1049} 1050 1051/// Handle __attribute__((format_arg((idx)))) attribute based on 1052/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1053static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1054 if (Attr.getNumArgs() != 1) { 1055 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1056 return; 1057 } 1058 if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1059 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1060 << Attr.getName() << 0 /*function*/; 1061 return; 1062 } 1063 // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1064 // needed in order to be compatible with GCC the index must start with 1. 1065 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1066 unsigned FirstIdx = 1; 1067 // checks for the 2nd argument 1068 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1069 llvm::APSInt Idx(32); 1070 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1071 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1072 << "format" << 2 << IdxExpr->getSourceRange(); 1073 return; 1074 } 1075 1076 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1077 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1078 << "format" << 2 << IdxExpr->getSourceRange(); 1079 return; 1080 } 1081 1082 unsigned ArgIdx = Idx.getZExtValue() - 1; 1083 1084 // make sure the format string is really a string 1085 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1086 1087 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 1088 if (not_nsstring_type && 1089 !isCFStringType(Ty, S.Context) && 1090 (!Ty->isPointerType() || 1091 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1092 // FIXME: Should highlight the actual expression that has the wrong type. 1093 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1094 << (not_nsstring_type ? "a string type" : "an NSString") 1095 << IdxExpr->getSourceRange(); 1096 return; 1097 } 1098 Ty = getFunctionOrMethodResultType(d); 1099 if (!isNSStringType(Ty, S.Context) && 1100 !isCFStringType(Ty, S.Context) && 1101 (!Ty->isPointerType() || 1102 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 1103 // FIXME: Should highlight the actual expression that has the wrong type. 1104 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1105 << (not_nsstring_type ? "string type" : "NSString") 1106 << IdxExpr->getSourceRange(); 1107 return; 1108 } 1109 1110 d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 1111} 1112 1113enum FormatAttrKind { 1114 CFStringFormat, 1115 NSStringFormat, 1116 StrftimeFormat, 1117 SupportedFormat, 1118 InvalidFormat 1119}; 1120 1121/// getFormatAttrKind - Map from format attribute names to supported format 1122/// types. 1123static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1124 // Check for formats that get handled specially. 1125 if (Format == "NSString") 1126 return NSStringFormat; 1127 if (Format == "CFString") 1128 return CFStringFormat; 1129 if (Format == "strftime") 1130 return StrftimeFormat; 1131 1132 // Otherwise, check for supported formats. 1133 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1134 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1135 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1136 Format == "zcmn_err") 1137 return SupportedFormat; 1138 1139 return InvalidFormat; 1140} 1141 1142/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1143/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1144static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1145 1146 if (!Attr.getParameterName()) { 1147 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1148 << "format" << 1; 1149 return; 1150 } 1151 1152 if (Attr.getNumArgs() != 2) { 1153 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1154 return; 1155 } 1156 1157 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1158 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1159 << Attr.getName() << 0 /*function*/; 1160 return; 1161 } 1162 1163 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1164 unsigned FirstIdx = 1; 1165 1166 llvm::StringRef Format = Attr.getParameterName()->getName(); 1167 1168 // Normalize the argument, __foo__ becomes foo. 1169 if (Format.startswith("__") && Format.endswith("__")) 1170 Format = Format.substr(2, Format.size() - 4); 1171 1172 // Check for supported formats. 1173 FormatAttrKind Kind = getFormatAttrKind(Format); 1174 if (Kind == InvalidFormat) { 1175 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1176 << "format" << Attr.getParameterName()->getName(); 1177 return; 1178 } 1179 1180 // checks for the 2nd argument 1181 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1182 llvm::APSInt Idx(32); 1183 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1184 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1185 << "format" << 2 << IdxExpr->getSourceRange(); 1186 return; 1187 } 1188 1189 // FIXME: We should handle the implicit 'this' parameter in a more generic 1190 // way that can be used for other arguments. 1191 bool HasImplicitThisParam = false; 1192 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1193 if (MD->isInstance()) { 1194 HasImplicitThisParam = true; 1195 NumArgs++; 1196 } 1197 } 1198 1199 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1200 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1201 << "format" << 2 << IdxExpr->getSourceRange(); 1202 return; 1203 } 1204 1205 // FIXME: Do we need to bounds check? 1206 unsigned ArgIdx = Idx.getZExtValue() - 1; 1207 1208 if (HasImplicitThisParam) { 1209 if (ArgIdx == 0) { 1210 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1211 << "a string type" << IdxExpr->getSourceRange(); 1212 return; 1213 } 1214 ArgIdx--; 1215 } 1216 1217 // make sure the format string is really a string 1218 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1219 1220 if (Kind == CFStringFormat) { 1221 if (!isCFStringType(Ty, S.Context)) { 1222 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1223 << "a CFString" << IdxExpr->getSourceRange(); 1224 return; 1225 } 1226 } else if (Kind == NSStringFormat) { 1227 // FIXME: do we need to check if the type is NSString*? What are the 1228 // semantics? 1229 if (!isNSStringType(Ty, S.Context)) { 1230 // FIXME: Should highlight the actual expression that has the wrong type. 1231 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1232 << "an NSString" << IdxExpr->getSourceRange(); 1233 return; 1234 } 1235 } else if (!Ty->isPointerType() || 1236 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1237 // FIXME: Should highlight the actual expression that has the wrong type. 1238 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1239 << "a string type" << IdxExpr->getSourceRange(); 1240 return; 1241 } 1242 1243 // check the 3rd argument 1244 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1245 llvm::APSInt FirstArg(32); 1246 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1247 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1248 << "format" << 3 << FirstArgExpr->getSourceRange(); 1249 return; 1250 } 1251 1252 // check if the function is variadic if the 3rd argument non-zero 1253 if (FirstArg != 0) { 1254 if (isFunctionOrMethodVariadic(d)) { 1255 ++NumArgs; // +1 for ... 1256 } else { 1257 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1258 return; 1259 } 1260 } 1261 1262 // strftime requires FirstArg to be 0 because it doesn't read from any 1263 // variable the input is just the current time + the format string. 1264 if (Kind == StrftimeFormat) { 1265 if (FirstArg != 0) { 1266 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1267 << FirstArgExpr->getSourceRange(); 1268 return; 1269 } 1270 // if 0 it disables parameter checking (to use with e.g. va_list) 1271 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1272 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1273 << "format" << 3 << FirstArgExpr->getSourceRange(); 1274 return; 1275 } 1276 1277 d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(), 1278 FirstArg.getZExtValue())); 1279} 1280 1281static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1282 Sema &S) { 1283 // check the attribute arguments. 1284 if (Attr.getNumArgs() != 0) { 1285 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1286 return; 1287 } 1288 1289 // Try to find the underlying union declaration. 1290 RecordDecl *RD = 0; 1291 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1292 if (TD && TD->getUnderlyingType()->isUnionType()) 1293 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1294 else 1295 RD = dyn_cast<RecordDecl>(d); 1296 1297 if (!RD || !RD->isUnion()) { 1298 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1299 << Attr.getName() << 1 /*union*/; 1300 return; 1301 } 1302 1303 if (!RD->isDefinition()) { 1304 S.Diag(Attr.getLoc(), 1305 diag::warn_transparent_union_attribute_not_definition); 1306 return; 1307 } 1308 1309 RecordDecl::field_iterator Field = RD->field_begin(), 1310 FieldEnd = RD->field_end(); 1311 if (Field == FieldEnd) { 1312 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1313 return; 1314 } 1315 1316 FieldDecl *FirstField = *Field; 1317 QualType FirstType = FirstField->getType(); 1318 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1319 S.Diag(FirstField->getLocation(), 1320 diag::warn_transparent_union_attribute_floating); 1321 return; 1322 } 1323 1324 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1325 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1326 for (; Field != FieldEnd; ++Field) { 1327 QualType FieldType = Field->getType(); 1328 if (S.Context.getTypeSize(FieldType) != FirstSize || 1329 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1330 // Warn if we drop the attribute. 1331 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1332 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1333 : S.Context.getTypeAlign(FieldType); 1334 S.Diag(Field->getLocation(), 1335 diag::warn_transparent_union_attribute_field_size_align) 1336 << isSize << Field->getDeclName() << FieldBits; 1337 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1338 S.Diag(FirstField->getLocation(), 1339 diag::note_transparent_union_first_field_size_align) 1340 << isSize << FirstBits; 1341 return; 1342 } 1343 } 1344 1345 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1346} 1347 1348static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1349 // check the attribute arguments. 1350 if (Attr.getNumArgs() != 1) { 1351 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1352 return; 1353 } 1354 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1355 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1356 1357 // Make sure that there is a string literal as the annotation's single 1358 // argument. 1359 if (!SE) { 1360 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1361 return; 1362 } 1363 d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); 1364} 1365 1366static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1367 // check the attribute arguments. 1368 if (Attr.getNumArgs() > 1) { 1369 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1370 return; 1371 } 1372 1373 //FIXME: The C++0x version of this attribute has more limited applicabilty 1374 // than GNU's, and should error out when it is used to specify a 1375 // weaker alignment, rather than being silently ignored. 1376 1377 unsigned Align = 0; 1378 if (Attr.getNumArgs() == 0) { 1379 // FIXME: This should be the target specific maximum alignment. 1380 // (For now we just use 128 bits which is the maximum on X86). 1381 Align = 128; 1382 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1383 return; 1384 } 1385 1386 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1387 llvm::APSInt Alignment(32); 1388 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1389 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1390 << "aligned" << alignmentExpr->getSourceRange(); 1391 return; 1392 } 1393 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1394 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1395 << alignmentExpr->getSourceRange(); 1396 return; 1397 } 1398 1399 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1400} 1401 1402/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1403/// type. 1404/// 1405/// Despite what would be logical, the mode attribute is a decl attribute, not a 1406/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1407/// HImode, not an intermediate pointer. 1408static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1409 // This attribute isn't documented, but glibc uses it. It changes 1410 // the width of an int or unsigned int to the specified size. 1411 1412 // Check that there aren't any arguments 1413 if (Attr.getNumArgs() != 0) { 1414 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1415 return; 1416 } 1417 1418 IdentifierInfo *Name = Attr.getParameterName(); 1419 if (!Name) { 1420 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1421 return; 1422 } 1423 1424 llvm::StringRef Str = Attr.getParameterName()->getName(); 1425 1426 // Normalize the attribute name, __foo__ becomes foo. 1427 if (Str.startswith("__") && Str.endswith("__")) 1428 Str = Str.substr(2, Str.size() - 4); 1429 1430 unsigned DestWidth = 0; 1431 bool IntegerMode = true; 1432 bool ComplexMode = false; 1433 switch (Str.size()) { 1434 case 2: 1435 switch (Str[0]) { 1436 case 'Q': DestWidth = 8; break; 1437 case 'H': DestWidth = 16; break; 1438 case 'S': DestWidth = 32; break; 1439 case 'D': DestWidth = 64; break; 1440 case 'X': DestWidth = 96; break; 1441 case 'T': DestWidth = 128; break; 1442 } 1443 if (Str[1] == 'F') { 1444 IntegerMode = false; 1445 } else if (Str[1] == 'C') { 1446 IntegerMode = false; 1447 ComplexMode = true; 1448 } else if (Str[1] != 'I') { 1449 DestWidth = 0; 1450 } 1451 break; 1452 case 4: 1453 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1454 // pointer on PIC16 and other embedded platforms. 1455 if (Str == "word") 1456 DestWidth = S.Context.Target.getPointerWidth(0); 1457 else if (Str == "byte") 1458 DestWidth = S.Context.Target.getCharWidth(); 1459 break; 1460 case 7: 1461 if (Str == "pointer") 1462 DestWidth = S.Context.Target.getPointerWidth(0); 1463 break; 1464 } 1465 1466 QualType OldTy; 1467 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1468 OldTy = TD->getUnderlyingType(); 1469 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1470 OldTy = VD->getType(); 1471 else { 1472 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1473 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1474 return; 1475 } 1476 1477 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1478 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1479 else if (IntegerMode) { 1480 if (!OldTy->isIntegralType()) 1481 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1482 } else if (ComplexMode) { 1483 if (!OldTy->isComplexType()) 1484 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1485 } else { 1486 if (!OldTy->isFloatingType()) 1487 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1488 } 1489 1490 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1491 // and friends, at least with glibc. 1492 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1493 // width on unusual platforms. 1494 // FIXME: Make sure floating-point mappings are accurate 1495 // FIXME: Support XF and TF types 1496 QualType NewTy; 1497 switch (DestWidth) { 1498 case 0: 1499 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1500 return; 1501 default: 1502 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1503 return; 1504 case 8: 1505 if (!IntegerMode) { 1506 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1507 return; 1508 } 1509 if (OldTy->isSignedIntegerType()) 1510 NewTy = S.Context.SignedCharTy; 1511 else 1512 NewTy = S.Context.UnsignedCharTy; 1513 break; 1514 case 16: 1515 if (!IntegerMode) { 1516 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1517 return; 1518 } 1519 if (OldTy->isSignedIntegerType()) 1520 NewTy = S.Context.ShortTy; 1521 else 1522 NewTy = S.Context.UnsignedShortTy; 1523 break; 1524 case 32: 1525 if (!IntegerMode) 1526 NewTy = S.Context.FloatTy; 1527 else if (OldTy->isSignedIntegerType()) 1528 NewTy = S.Context.IntTy; 1529 else 1530 NewTy = S.Context.UnsignedIntTy; 1531 break; 1532 case 64: 1533 if (!IntegerMode) 1534 NewTy = S.Context.DoubleTy; 1535 else if (OldTy->isSignedIntegerType()) 1536 if (S.Context.Target.getLongWidth() == 64) 1537 NewTy = S.Context.LongTy; 1538 else 1539 NewTy = S.Context.LongLongTy; 1540 else 1541 if (S.Context.Target.getLongWidth() == 64) 1542 NewTy = S.Context.UnsignedLongTy; 1543 else 1544 NewTy = S.Context.UnsignedLongLongTy; 1545 break; 1546 case 96: 1547 NewTy = S.Context.LongDoubleTy; 1548 break; 1549 case 128: 1550 if (!IntegerMode) { 1551 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1552 return; 1553 } 1554 if (OldTy->isSignedIntegerType()) 1555 NewTy = S.Context.Int128Ty; 1556 else 1557 NewTy = S.Context.UnsignedInt128Ty; 1558 break; 1559 } 1560 1561 if (ComplexMode) { 1562 NewTy = S.Context.getComplexType(NewTy); 1563 } 1564 1565 // Install the new type. 1566 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1567 // FIXME: preserve existing source info. 1568 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1569 } else 1570 cast<ValueDecl>(D)->setType(NewTy); 1571} 1572 1573static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1574 // check the attribute arguments. 1575 if (Attr.getNumArgs() > 0) { 1576 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1577 return; 1578 } 1579 1580 if (!isFunctionOrMethod(d)) { 1581 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1582 << Attr.getName() << 0 /*function*/; 1583 return; 1584 } 1585 1586 d->addAttr(::new (S.Context) NoDebugAttr()); 1587} 1588 1589static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1590 // check the attribute arguments. 1591 if (Attr.getNumArgs() != 0) { 1592 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1593 return; 1594 } 1595 1596 if (!isa<FunctionDecl>(d)) { 1597 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1598 << Attr.getName() << 0 /*function*/; 1599 return; 1600 } 1601 1602 d->addAttr(::new (S.Context) NoInlineAttr()); 1603} 1604 1605static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1606 // check the attribute arguments. 1607 if (Attr.getNumArgs() != 0) { 1608 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1609 return; 1610 } 1611 1612 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1613 if (Fn == 0) { 1614 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1615 << Attr.getName() << 0 /*function*/; 1616 return; 1617 } 1618 1619 if (!Fn->isInlineSpecified()) { 1620 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1621 return; 1622 } 1623 1624 d->addAttr(::new (S.Context) GNUInlineAttr()); 1625} 1626 1627static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1628 // check the attribute arguments. 1629 if (Attr.getNumArgs() != 1) { 1630 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 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 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1641 llvm::APSInt NumParams(32); 1642 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1643 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1644 << "regparm" << NumParamsExpr->getSourceRange(); 1645 return; 1646 } 1647 1648 if (S.Context.Target.getRegParmMax() == 0) { 1649 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1650 << NumParamsExpr->getSourceRange(); 1651 return; 1652 } 1653 1654 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1655 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1656 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1657 return; 1658 } 1659 1660 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1661} 1662 1663static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1664 // check the attribute arguments. 1665 if (Attr.getNumArgs() != 0) { 1666 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1667 return; 1668 } 1669 1670 if (!isa<CXXRecordDecl>(d) 1671 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 1672 S.Diag(Attr.getLoc(), 1673 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1674 : diag::warn_attribute_wrong_decl_type) 1675 << Attr.getName() << 7 /*virtual method or class*/; 1676 return; 1677 } 1678 1679 // FIXME: Conform to C++0x redeclaration rules. 1680 1681 if (d->getAttr<FinalAttr>()) { 1682 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 1683 return; 1684 } 1685 1686 d->addAttr(::new (S.Context) FinalAttr()); 1687} 1688 1689//===----------------------------------------------------------------------===// 1690// C++0x member checking attributes 1691//===----------------------------------------------------------------------===// 1692 1693static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1694 if (Attr.getNumArgs() != 0) { 1695 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1696 return; 1697 } 1698 1699 if (!isa<CXXRecordDecl>(d)) { 1700 S.Diag(Attr.getLoc(), 1701 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1702 : diag::warn_attribute_wrong_decl_type) 1703 << Attr.getName() << 9 /*class*/; 1704 return; 1705 } 1706 1707 if (d->getAttr<BaseCheckAttr>()) { 1708 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 1709 return; 1710 } 1711 1712 d->addAttr(::new (S.Context) BaseCheckAttr()); 1713} 1714 1715static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1716 if (Attr.getNumArgs() != 0) { 1717 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1718 return; 1719 } 1720 1721 if (!isa<RecordDecl>(d->getDeclContext())) { 1722 // FIXME: It's not the type that's the problem 1723 S.Diag(Attr.getLoc(), 1724 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1725 : diag::warn_attribute_wrong_decl_type) 1726 << Attr.getName() << 11 /*member*/; 1727 return; 1728 } 1729 1730 // FIXME: Conform to C++0x redeclaration rules. 1731 1732 if (d->getAttr<HidingAttr>()) { 1733 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 1734 return; 1735 } 1736 1737 d->addAttr(::new (S.Context) HidingAttr()); 1738} 1739 1740static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1741 if (Attr.getNumArgs() != 0) { 1742 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1743 return; 1744 } 1745 1746 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 1747 // FIXME: It's not the type that's the problem 1748 S.Diag(Attr.getLoc(), 1749 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1750 : diag::warn_attribute_wrong_decl_type) 1751 << Attr.getName() << 10 /*virtual method*/; 1752 return; 1753 } 1754 1755 // FIXME: Conform to C++0x redeclaration rules. 1756 1757 if (d->getAttr<OverrideAttr>()) { 1758 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 1759 return; 1760 } 1761 1762 d->addAttr(::new (S.Context) OverrideAttr()); 1763} 1764 1765//===----------------------------------------------------------------------===// 1766// Checker-specific attribute handlers. 1767//===----------------------------------------------------------------------===// 1768 1769static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1770 Sema &S) { 1771 1772 QualType RetTy; 1773 1774 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1775 RetTy = MD->getResultType(); 1776 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1777 RetTy = FD->getResultType(); 1778 else { 1779 SourceLocation L = Attr.getLoc(); 1780 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 1781 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1782 return; 1783 } 1784 1785 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1786 || RetTy->getAs<ObjCObjectPointerType>())) { 1787 SourceLocation L = Attr.getLoc(); 1788 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 1789 << SourceRange(L, L) << Attr.getName(); 1790 return; 1791 } 1792 1793 switch (Attr.getKind()) { 1794 default: 1795 assert(0 && "invalid ownership attribute"); 1796 return; 1797 case AttributeList::AT_cf_returns_not_retained: 1798 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr()); 1799 return; 1800 case AttributeList::AT_ns_returns_not_retained: 1801 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr()); 1802 return; 1803 case AttributeList::AT_cf_returns_retained: 1804 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1805 return; 1806 case AttributeList::AT_ns_returns_retained: 1807 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1808 return; 1809 }; 1810} 1811 1812static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 1813 return Attr.getKind() == AttributeList::AT_dllimport || 1814 Attr.getKind() == AttributeList::AT_dllexport; 1815} 1816 1817//===----------------------------------------------------------------------===// 1818// Top Level Sema Entry Points 1819//===----------------------------------------------------------------------===// 1820 1821/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1822/// the attribute applies to decls. If the attribute is a type attribute, just 1823/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 1824/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 1825static void ProcessDeclAttribute(Scope *scope, Decl *D, 1826 const AttributeList &Attr, Sema &S) { 1827 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 1828 // FIXME: Try to deal with other __declspec attributes! 1829 return; 1830 switch (Attr.getKind()) { 1831 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 1832 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 1833 case AttributeList::AT_address_space: 1834 case AttributeList::AT_objc_gc: 1835 case AttributeList::AT_vector_size: 1836 // Ignore these, these are type attributes, handled by 1837 // ProcessTypeAttributes. 1838 break; 1839 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1840 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1841 case AttributeList::AT_always_inline: 1842 HandleAlwaysInlineAttr (D, Attr, S); break; 1843 case AttributeList::AT_analyzer_noreturn: 1844 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1845 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1846 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 1847 case AttributeList::AT_carries_dependency: 1848 HandleDependencyAttr (D, Attr, S); break; 1849 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 1850 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 1851 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 1852 case AttributeList::AT_ext_vector_type: 1853 HandleExtVectorTypeAttr(scope, D, Attr, S); 1854 break; 1855 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 1856 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1857 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1858 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 1859 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 1860 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1861 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1862 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1863 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1864 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1865 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 1866 1867 // Checker-specific. 1868 case AttributeList::AT_ns_returns_not_retained: 1869 case AttributeList::AT_cf_returns_not_retained: 1870 case AttributeList::AT_ns_returns_retained: 1871 case AttributeList::AT_cf_returns_retained: 1872 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1873 1874 case AttributeList::AT_reqd_wg_size: 1875 HandleReqdWorkGroupSize(D, Attr, S); break; 1876 1877 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1878 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1879 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 1880 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1881 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1882 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 1883 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1884 break; 1885 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1886 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 1887 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 1888 case AttributeList::AT_transparent_union: 1889 HandleTransparentUnionAttr(D, Attr, S); 1890 break; 1891 case AttributeList::AT_objc_exception: 1892 HandleObjCExceptionAttr(D, Attr, S); 1893 break; 1894 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1895 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1896 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1897 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1898 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1899 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1900 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1901 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 1902 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 1903 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1904 case AttributeList::IgnoredAttribute: 1905 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1906 // Just ignore 1907 break; 1908 case AttributeList::AT_stdcall: 1909 case AttributeList::AT_cdecl: 1910 case AttributeList::AT_fastcall: 1911 // These are all treated as type attributes. 1912 break; 1913 default: 1914 // Ask target about the attribute. 1915 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 1916 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 1917 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1918 break; 1919 } 1920} 1921 1922/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1923/// attribute list to the specified decl, ignoring any type attributes. 1924void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1925 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 1926 ProcessDeclAttribute(S, D, *l, *this); 1927 } 1928 1929 // GCC accepts 1930 // static int a9 __attribute__((weakref)); 1931 // but that looks really pointless. We reject it. 1932 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 1933 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 1934 dyn_cast<NamedDecl>(D)->getNameAsString(); 1935 return; 1936 } 1937} 1938 1939/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1940/// #pragma weak needs a non-definition decl and source may not have one 1941NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 1942 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1943 NamedDecl *NewD = 0; 1944 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1945 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1946 FD->getLocation(), DeclarationName(II), 1947 FD->getType(), FD->getTypeSourceInfo()); 1948 if (FD->getQualifier()) { 1949 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 1950 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 1951 } 1952 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1953 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1954 VD->getLocation(), II, 1955 VD->getType(), VD->getTypeSourceInfo(), 1956 VD->getStorageClass()); 1957 if (VD->getQualifier()) { 1958 VarDecl *NewVD = cast<VarDecl>(NewD); 1959 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 1960 } 1961 } 1962 return NewD; 1963} 1964 1965/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1966/// applied to it, possibly with an alias. 1967void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1968 if (W.getUsed()) return; // only do this once 1969 W.setUsed(true); 1970 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1971 IdentifierInfo *NDId = ND->getIdentifier(); 1972 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1973 NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName())); 1974 NewD->addAttr(::new (Context) WeakAttr()); 1975 WeakTopLevelDecl.push_back(NewD); 1976 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1977 // to insert Decl at TU scope, sorry. 1978 DeclContext *SavedContext = CurContext; 1979 CurContext = Context.getTranslationUnitDecl(); 1980 PushOnScopeChains(NewD, S); 1981 CurContext = SavedContext; 1982 } else { // just add weak to existing 1983 ND->addAttr(::new (Context) WeakAttr()); 1984 } 1985} 1986 1987/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1988/// it, apply them to D. This is a bit tricky because PD can have attributes 1989/// specified in many different places, and we need to find and apply them all. 1990void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1991 // Handle #pragma weak 1992 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1993 if (ND->hasLinkage()) { 1994 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1995 if (W != WeakInfo()) { 1996 // Identifier referenced by #pragma weak before it was declared 1997 DeclApplyPragmaWeak(S, ND, W); 1998 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1999 } 2000 } 2001 } 2002 2003 // Apply decl attributes from the DeclSpec if present. 2004 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2005 ProcessDeclAttributeList(S, D, Attrs); 2006 2007 // Walk the declarator structure, applying decl attributes that were in a type 2008 // position to the decl itself. This handles cases like: 2009 // int *__attr__(x)** D; 2010 // when X is a decl attribute. 2011 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2012 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2013 ProcessDeclAttributeList(S, D, Attrs); 2014 2015 // Finally, apply any attributes on the decl itself. 2016 if (const AttributeList *Attrs = PD.getAttributes()) 2017 ProcessDeclAttributeList(S, D, Attrs); 2018} 2019 2020/// PushParsingDeclaration - Enter a new "scope" of deprecation 2021/// warnings. 2022/// 2023/// The state token we use is the start index of this scope 2024/// on the warning stack. 2025Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 2026 ParsingDeclDepth++; 2027 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2028} 2029 2030void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 2031 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2032 ParsingDeclDepth--; 2033 2034 if (DelayedDiagnostics.empty()) 2035 return; 2036 2037 unsigned SavedIndex = (unsigned) S; 2038 assert(SavedIndex <= DelayedDiagnostics.size() && 2039 "saved index is out of bounds"); 2040 2041 // We only want to actually emit delayed diagnostics when we 2042 // successfully parsed a decl. 2043 Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 2044 if (D) { 2045 // We really do want to start with 0 here. We get one push for a 2046 // decl spec and another for each declarator; in a decl group like: 2047 // deprecated_typedef foo, *bar, baz(); 2048 // only the declarator pops will be passed decls. This is correct; 2049 // we really do need to consider delayed diagnostics from the decl spec 2050 // for each of the different declarations. 2051 for (unsigned I = 0, E = DelayedDiagnostics.size(); I != E; ++I) { 2052 if (DelayedDiagnostics[I].Triggered) 2053 continue; 2054 2055 switch (DelayedDiagnostics[I].Kind) { 2056 case DelayedDiagnostic::Deprecation: 2057 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2058 break; 2059 2060 case DelayedDiagnostic::Access: 2061 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2062 break; 2063 } 2064 } 2065 } 2066 2067 DelayedDiagnostics.set_size(SavedIndex); 2068} 2069 2070static bool isDeclDeprecated(Decl *D) { 2071 do { 2072 if (D->hasAttr<DeprecatedAttr>()) 2073 return true; 2074 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2075 return false; 2076} 2077 2078void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 2079 Decl *Ctx) { 2080 if (isDeclDeprecated(Ctx)) 2081 return; 2082 2083 DD.Triggered = true; 2084 Diag(DD.Loc, diag::warn_deprecated) 2085 << DD.DeprecationData.Decl->getDeclName(); 2086} 2087 2088void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 2089 // Delay if we're currently parsing a declaration. 2090 if (ParsingDeclDepth) { 2091 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 2092 return; 2093 } 2094 2095 // Otherwise, don't warn if our current context is deprecated. 2096 if (isDeclDeprecated(cast<Decl>(CurContext))) 2097 return; 2098 2099 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2100} 2101