SemaDeclAttr.cpp revision 3c989027f68e2d9dfd57c018ccc550bd9fb79920
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 IgnoredFormat, 1119 InvalidFormat 1120}; 1121 1122/// getFormatAttrKind - Map from format attribute names to supported format 1123/// types. 1124static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 1125 // Check for formats that get handled specially. 1126 if (Format == "NSString") 1127 return NSStringFormat; 1128 if (Format == "CFString") 1129 return CFStringFormat; 1130 if (Format == "strftime") 1131 return StrftimeFormat; 1132 1133 // Otherwise, check for supported formats. 1134 if (Format == "scanf" || Format == "printf" || Format == "printf0" || 1135 Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 1136 Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1137 Format == "zcmn_err") 1138 return SupportedFormat; 1139 1140 if (Format == "gcc_tdiag") 1141 return IgnoredFormat; 1142 1143 return InvalidFormat; 1144} 1145 1146/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1147/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1148static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1149 1150 if (!Attr.getParameterName()) { 1151 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1152 << "format" << 1; 1153 return; 1154 } 1155 1156 if (Attr.getNumArgs() != 2) { 1157 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 1158 return; 1159 } 1160 1161 if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1162 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1163 << Attr.getName() << 0 /*function*/; 1164 return; 1165 } 1166 1167 unsigned NumArgs = getFunctionOrMethodNumArgs(d); 1168 unsigned FirstIdx = 1; 1169 1170 llvm::StringRef Format = Attr.getParameterName()->getName(); 1171 1172 // Normalize the argument, __foo__ becomes foo. 1173 if (Format.startswith("__") && Format.endswith("__")) 1174 Format = Format.substr(2, Format.size() - 4); 1175 1176 // Check for supported formats. 1177 FormatAttrKind Kind = getFormatAttrKind(Format); 1178 1179 if (Kind == IgnoredFormat) 1180 return; 1181 1182 if (Kind == InvalidFormat) { 1183 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1184 << "format" << Attr.getParameterName()->getName(); 1185 return; 1186 } 1187 1188 // checks for the 2nd argument 1189 Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1190 llvm::APSInt Idx(32); 1191 if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1192 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1193 << "format" << 2 << IdxExpr->getSourceRange(); 1194 return; 1195 } 1196 1197 // FIXME: We should handle the implicit 'this' parameter in a more generic 1198 // way that can be used for other arguments. 1199 bool HasImplicitThisParam = false; 1200 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 1201 if (MD->isInstance()) { 1202 HasImplicitThisParam = true; 1203 NumArgs++; 1204 } 1205 } 1206 1207 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1208 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1209 << "format" << 2 << IdxExpr->getSourceRange(); 1210 return; 1211 } 1212 1213 // FIXME: Do we need to bounds check? 1214 unsigned ArgIdx = Idx.getZExtValue() - 1; 1215 1216 if (HasImplicitThisParam) { 1217 if (ArgIdx == 0) { 1218 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1219 << "a string type" << IdxExpr->getSourceRange(); 1220 return; 1221 } 1222 ArgIdx--; 1223 } 1224 1225 // make sure the format string is really a string 1226 QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1227 1228 if (Kind == CFStringFormat) { 1229 if (!isCFStringType(Ty, S.Context)) { 1230 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1231 << "a CFString" << IdxExpr->getSourceRange(); 1232 return; 1233 } 1234 } else if (Kind == NSStringFormat) { 1235 // FIXME: do we need to check if the type is NSString*? What are the 1236 // semantics? 1237 if (!isNSStringType(Ty, S.Context)) { 1238 // FIXME: Should highlight the actual expression that has the wrong type. 1239 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1240 << "an NSString" << IdxExpr->getSourceRange(); 1241 return; 1242 } 1243 } else if (!Ty->isPointerType() || 1244 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1245 // FIXME: Should highlight the actual expression that has the wrong type. 1246 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1247 << "a string type" << IdxExpr->getSourceRange(); 1248 return; 1249 } 1250 1251 // check the 3rd argument 1252 Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1253 llvm::APSInt FirstArg(32); 1254 if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1255 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 1256 << "format" << 3 << FirstArgExpr->getSourceRange(); 1257 return; 1258 } 1259 1260 // check if the function is variadic if the 3rd argument non-zero 1261 if (FirstArg != 0) { 1262 if (isFunctionOrMethodVariadic(d)) { 1263 ++NumArgs; // +1 for ... 1264 } else { 1265 S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 1266 return; 1267 } 1268 } 1269 1270 // strftime requires FirstArg to be 0 because it doesn't read from any 1271 // variable the input is just the current time + the format string. 1272 if (Kind == StrftimeFormat) { 1273 if (FirstArg != 0) { 1274 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1275 << FirstArgExpr->getSourceRange(); 1276 return; 1277 } 1278 // if 0 it disables parameter checking (to use with e.g. va_list) 1279 } else if (FirstArg != 0 && FirstArg != NumArgs) { 1280 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1281 << "format" << 3 << FirstArgExpr->getSourceRange(); 1282 return; 1283 } 1284 1285 d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(), 1286 FirstArg.getZExtValue())); 1287} 1288 1289static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 1290 Sema &S) { 1291 // check the attribute arguments. 1292 if (Attr.getNumArgs() != 0) { 1293 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1294 return; 1295 } 1296 1297 // Try to find the underlying union declaration. 1298 RecordDecl *RD = 0; 1299 TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1300 if (TD && TD->getUnderlyingType()->isUnionType()) 1301 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1302 else 1303 RD = dyn_cast<RecordDecl>(d); 1304 1305 if (!RD || !RD->isUnion()) { 1306 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1307 << Attr.getName() << 1 /*union*/; 1308 return; 1309 } 1310 1311 if (!RD->isDefinition()) { 1312 S.Diag(Attr.getLoc(), 1313 diag::warn_transparent_union_attribute_not_definition); 1314 return; 1315 } 1316 1317 RecordDecl::field_iterator Field = RD->field_begin(), 1318 FieldEnd = RD->field_end(); 1319 if (Field == FieldEnd) { 1320 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 1321 return; 1322 } 1323 1324 FieldDecl *FirstField = *Field; 1325 QualType FirstType = FirstField->getType(); 1326 if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1327 S.Diag(FirstField->getLocation(), 1328 diag::warn_transparent_union_attribute_floating); 1329 return; 1330 } 1331 1332 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 1333 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 1334 for (; Field != FieldEnd; ++Field) { 1335 QualType FieldType = Field->getType(); 1336 if (S.Context.getTypeSize(FieldType) != FirstSize || 1337 S.Context.getTypeAlign(FieldType) != FirstAlign) { 1338 // Warn if we drop the attribute. 1339 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1340 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 1341 : S.Context.getTypeAlign(FieldType); 1342 S.Diag(Field->getLocation(), 1343 diag::warn_transparent_union_attribute_field_size_align) 1344 << isSize << Field->getDeclName() << FieldBits; 1345 unsigned FirstBits = isSize? FirstSize : FirstAlign; 1346 S.Diag(FirstField->getLocation(), 1347 diag::note_transparent_union_first_field_size_align) 1348 << isSize << FirstBits; 1349 return; 1350 } 1351 } 1352 1353 RD->addAttr(::new (S.Context) TransparentUnionAttr()); 1354} 1355 1356static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1357 // check the attribute arguments. 1358 if (Attr.getNumArgs() != 1) { 1359 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1360 return; 1361 } 1362 Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1363 StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1364 1365 // Make sure that there is a string literal as the annotation's single 1366 // argument. 1367 if (!SE) { 1368 S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 1369 return; 1370 } 1371 d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); 1372} 1373 1374static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1375 // check the attribute arguments. 1376 if (Attr.getNumArgs() > 1) { 1377 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1378 return; 1379 } 1380 1381 //FIXME: The C++0x version of this attribute has more limited applicabilty 1382 // than GNU's, and should error out when it is used to specify a 1383 // weaker alignment, rather than being silently ignored. 1384 1385 unsigned Align = 0; 1386 if (Attr.getNumArgs() == 0) { 1387 // FIXME: This should be the target specific maximum alignment. 1388 // (For now we just use 128 bits which is the maximum on X86). 1389 Align = 128; 1390 d->addAttr(::new (S.Context) AlignedAttr(Align)); 1391 return; 1392 } 1393 1394 Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 1395 llvm::APSInt Alignment(32); 1396 if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1397 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1398 << "aligned" << alignmentExpr->getSourceRange(); 1399 return; 1400 } 1401 if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1402 S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1403 << alignmentExpr->getSourceRange(); 1404 return; 1405 } 1406 1407 d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 1408} 1409 1410/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1411/// type. 1412/// 1413/// Despite what would be logical, the mode attribute is a decl attribute, not a 1414/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1415/// HImode, not an intermediate pointer. 1416static void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1417 // This attribute isn't documented, but glibc uses it. It changes 1418 // the width of an int or unsigned int to the specified size. 1419 1420 // Check that there aren't any arguments 1421 if (Attr.getNumArgs() != 0) { 1422 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1423 return; 1424 } 1425 1426 IdentifierInfo *Name = Attr.getParameterName(); 1427 if (!Name) { 1428 S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1429 return; 1430 } 1431 1432 llvm::StringRef Str = Attr.getParameterName()->getName(); 1433 1434 // Normalize the attribute name, __foo__ becomes foo. 1435 if (Str.startswith("__") && Str.endswith("__")) 1436 Str = Str.substr(2, Str.size() - 4); 1437 1438 unsigned DestWidth = 0; 1439 bool IntegerMode = true; 1440 bool ComplexMode = false; 1441 switch (Str.size()) { 1442 case 2: 1443 switch (Str[0]) { 1444 case 'Q': DestWidth = 8; break; 1445 case 'H': DestWidth = 16; break; 1446 case 'S': DestWidth = 32; break; 1447 case 'D': DestWidth = 64; break; 1448 case 'X': DestWidth = 96; break; 1449 case 'T': DestWidth = 128; break; 1450 } 1451 if (Str[1] == 'F') { 1452 IntegerMode = false; 1453 } else if (Str[1] == 'C') { 1454 IntegerMode = false; 1455 ComplexMode = true; 1456 } else if (Str[1] != 'I') { 1457 DestWidth = 0; 1458 } 1459 break; 1460 case 4: 1461 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1462 // pointer on PIC16 and other embedded platforms. 1463 if (Str == "word") 1464 DestWidth = S.Context.Target.getPointerWidth(0); 1465 else if (Str == "byte") 1466 DestWidth = S.Context.Target.getCharWidth(); 1467 break; 1468 case 7: 1469 if (Str == "pointer") 1470 DestWidth = S.Context.Target.getPointerWidth(0); 1471 break; 1472 } 1473 1474 QualType OldTy; 1475 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1476 OldTy = TD->getUnderlyingType(); 1477 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1478 OldTy = VD->getType(); 1479 else { 1480 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1481 << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1482 return; 1483 } 1484 1485 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 1486 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1487 else if (IntegerMode) { 1488 if (!OldTy->isIntegralType()) 1489 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1490 } else if (ComplexMode) { 1491 if (!OldTy->isComplexType()) 1492 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1493 } else { 1494 if (!OldTy->isFloatingType()) 1495 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1496 } 1497 1498 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1499 // and friends, at least with glibc. 1500 // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1501 // width on unusual platforms. 1502 // FIXME: Make sure floating-point mappings are accurate 1503 // FIXME: Support XF and TF types 1504 QualType NewTy; 1505 switch (DestWidth) { 1506 case 0: 1507 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1508 return; 1509 default: 1510 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1511 return; 1512 case 8: 1513 if (!IntegerMode) { 1514 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1515 return; 1516 } 1517 if (OldTy->isSignedIntegerType()) 1518 NewTy = S.Context.SignedCharTy; 1519 else 1520 NewTy = S.Context.UnsignedCharTy; 1521 break; 1522 case 16: 1523 if (!IntegerMode) { 1524 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1525 return; 1526 } 1527 if (OldTy->isSignedIntegerType()) 1528 NewTy = S.Context.ShortTy; 1529 else 1530 NewTy = S.Context.UnsignedShortTy; 1531 break; 1532 case 32: 1533 if (!IntegerMode) 1534 NewTy = S.Context.FloatTy; 1535 else if (OldTy->isSignedIntegerType()) 1536 NewTy = S.Context.IntTy; 1537 else 1538 NewTy = S.Context.UnsignedIntTy; 1539 break; 1540 case 64: 1541 if (!IntegerMode) 1542 NewTy = S.Context.DoubleTy; 1543 else if (OldTy->isSignedIntegerType()) 1544 if (S.Context.Target.getLongWidth() == 64) 1545 NewTy = S.Context.LongTy; 1546 else 1547 NewTy = S.Context.LongLongTy; 1548 else 1549 if (S.Context.Target.getLongWidth() == 64) 1550 NewTy = S.Context.UnsignedLongTy; 1551 else 1552 NewTy = S.Context.UnsignedLongLongTy; 1553 break; 1554 case 96: 1555 NewTy = S.Context.LongDoubleTy; 1556 break; 1557 case 128: 1558 if (!IntegerMode) { 1559 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1560 return; 1561 } 1562 if (OldTy->isSignedIntegerType()) 1563 NewTy = S.Context.Int128Ty; 1564 else 1565 NewTy = S.Context.UnsignedInt128Ty; 1566 break; 1567 } 1568 1569 if (ComplexMode) { 1570 NewTy = S.Context.getComplexType(NewTy); 1571 } 1572 1573 // Install the new type. 1574 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1575 // FIXME: preserve existing source info. 1576 TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1577 } else 1578 cast<ValueDecl>(D)->setType(NewTy); 1579} 1580 1581static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1582 // check the attribute arguments. 1583 if (Attr.getNumArgs() > 0) { 1584 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1585 return; 1586 } 1587 1588 if (!isFunctionOrMethod(d)) { 1589 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1590 << Attr.getName() << 0 /*function*/; 1591 return; 1592 } 1593 1594 d->addAttr(::new (S.Context) NoDebugAttr()); 1595} 1596 1597static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1598 // check the attribute arguments. 1599 if (Attr.getNumArgs() != 0) { 1600 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1601 return; 1602 } 1603 1604 if (!isa<FunctionDecl>(d)) { 1605 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1606 << Attr.getName() << 0 /*function*/; 1607 return; 1608 } 1609 1610 d->addAttr(::new (S.Context) NoInlineAttr()); 1611} 1612 1613static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1614 // check the attribute arguments. 1615 if (Attr.getNumArgs() != 0) { 1616 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1617 return; 1618 } 1619 1620 FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1621 if (Fn == 0) { 1622 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1623 << Attr.getName() << 0 /*function*/; 1624 return; 1625 } 1626 1627 if (!Fn->isInlineSpecified()) { 1628 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1629 return; 1630 } 1631 1632 d->addAttr(::new (S.Context) GNUInlineAttr()); 1633} 1634 1635static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1636 // check the attribute arguments. 1637 if (Attr.getNumArgs() != 1) { 1638 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1639 return; 1640 } 1641 1642 if (!isFunctionOrMethod(d)) { 1643 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1644 << Attr.getName() << 0 /*function*/; 1645 return; 1646 } 1647 1648 Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 1649 llvm::APSInt NumParams(32); 1650 if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 1651 S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1652 << "regparm" << NumParamsExpr->getSourceRange(); 1653 return; 1654 } 1655 1656 if (S.Context.Target.getRegParmMax() == 0) { 1657 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 1658 << NumParamsExpr->getSourceRange(); 1659 return; 1660 } 1661 1662 if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1663 S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1664 << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 1665 return; 1666 } 1667 1668 d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1669} 1670 1671static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1672 // check the attribute arguments. 1673 if (Attr.getNumArgs() != 0) { 1674 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1675 return; 1676 } 1677 1678 if (!isa<CXXRecordDecl>(d) 1679 && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 1680 S.Diag(Attr.getLoc(), 1681 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1682 : diag::warn_attribute_wrong_decl_type) 1683 << Attr.getName() << 7 /*virtual method or class*/; 1684 return; 1685 } 1686 1687 // FIXME: Conform to C++0x redeclaration rules. 1688 1689 if (d->getAttr<FinalAttr>()) { 1690 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 1691 return; 1692 } 1693 1694 d->addAttr(::new (S.Context) FinalAttr()); 1695} 1696 1697//===----------------------------------------------------------------------===// 1698// C++0x member checking attributes 1699//===----------------------------------------------------------------------===// 1700 1701static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1702 if (Attr.getNumArgs() != 0) { 1703 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1704 return; 1705 } 1706 1707 if (!isa<CXXRecordDecl>(d)) { 1708 S.Diag(Attr.getLoc(), 1709 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1710 : diag::warn_attribute_wrong_decl_type) 1711 << Attr.getName() << 9 /*class*/; 1712 return; 1713 } 1714 1715 if (d->getAttr<BaseCheckAttr>()) { 1716 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 1717 return; 1718 } 1719 1720 d->addAttr(::new (S.Context) BaseCheckAttr()); 1721} 1722 1723static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1724 if (Attr.getNumArgs() != 0) { 1725 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1726 return; 1727 } 1728 1729 if (!isa<RecordDecl>(d->getDeclContext())) { 1730 // FIXME: It's not the type that's the problem 1731 S.Diag(Attr.getLoc(), 1732 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1733 : diag::warn_attribute_wrong_decl_type) 1734 << Attr.getName() << 11 /*member*/; 1735 return; 1736 } 1737 1738 // FIXME: Conform to C++0x redeclaration rules. 1739 1740 if (d->getAttr<HidingAttr>()) { 1741 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 1742 return; 1743 } 1744 1745 d->addAttr(::new (S.Context) HidingAttr()); 1746} 1747 1748static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1749 if (Attr.getNumArgs() != 0) { 1750 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1751 return; 1752 } 1753 1754 if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 1755 // FIXME: It's not the type that's the problem 1756 S.Diag(Attr.getLoc(), 1757 Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1758 : diag::warn_attribute_wrong_decl_type) 1759 << Attr.getName() << 10 /*virtual method*/; 1760 return; 1761 } 1762 1763 // FIXME: Conform to C++0x redeclaration rules. 1764 1765 if (d->getAttr<OverrideAttr>()) { 1766 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 1767 return; 1768 } 1769 1770 d->addAttr(::new (S.Context) OverrideAttr()); 1771} 1772 1773//===----------------------------------------------------------------------===// 1774// Checker-specific attribute handlers. 1775//===----------------------------------------------------------------------===// 1776 1777static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1778 Sema &S) { 1779 1780 QualType RetTy; 1781 1782 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 1783 RetTy = MD->getResultType(); 1784 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 1785 RetTy = FD->getResultType(); 1786 else { 1787 SourceLocation L = Attr.getLoc(); 1788 S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 1789 << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1790 return; 1791 } 1792 1793 if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1794 || RetTy->getAs<ObjCObjectPointerType>())) { 1795 SourceLocation L = Attr.getLoc(); 1796 S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 1797 << SourceRange(L, L) << Attr.getName(); 1798 return; 1799 } 1800 1801 switch (Attr.getKind()) { 1802 default: 1803 assert(0 && "invalid ownership attribute"); 1804 return; 1805 case AttributeList::AT_cf_returns_not_retained: 1806 d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr()); 1807 return; 1808 case AttributeList::AT_ns_returns_not_retained: 1809 d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr()); 1810 return; 1811 case AttributeList::AT_cf_returns_retained: 1812 d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1813 return; 1814 case AttributeList::AT_ns_returns_retained: 1815 d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1816 return; 1817 }; 1818} 1819 1820static bool isKnownDeclSpecAttr(const AttributeList &Attr) { 1821 return Attr.getKind() == AttributeList::AT_dllimport || 1822 Attr.getKind() == AttributeList::AT_dllexport; 1823} 1824 1825//===----------------------------------------------------------------------===// 1826// Top Level Sema Entry Points 1827//===----------------------------------------------------------------------===// 1828 1829/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1830/// the attribute applies to decls. If the attribute is a type attribute, just 1831/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 1832/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 1833static void ProcessDeclAttribute(Scope *scope, Decl *D, 1834 const AttributeList &Attr, Sema &S) { 1835 if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 1836 // FIXME: Try to deal with other __declspec attributes! 1837 return; 1838 switch (Attr.getKind()) { 1839 case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 1840 case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 1841 case AttributeList::AT_address_space: 1842 case AttributeList::AT_objc_gc: 1843 case AttributeList::AT_vector_size: 1844 // Ignore these, these are type attributes, handled by 1845 // ProcessTypeAttributes. 1846 break; 1847 case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 1848 case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1849 case AttributeList::AT_always_inline: 1850 HandleAlwaysInlineAttr (D, Attr, S); break; 1851 case AttributeList::AT_analyzer_noreturn: 1852 HandleAnalyzerNoReturnAttr (D, Attr, S); break; 1853 case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 1854 case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 1855 case AttributeList::AT_carries_dependency: 1856 HandleDependencyAttr (D, Attr, S); break; 1857 case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 1858 case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 1859 case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 1860 case AttributeList::AT_ext_vector_type: 1861 HandleExtVectorTypeAttr(scope, D, Attr, S); 1862 break; 1863 case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 1864 case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1865 case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1866 case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 1867 case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 1868 case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1869 case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1870 case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 1871 case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 1872 case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1873 case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 1874 1875 // Checker-specific. 1876 case AttributeList::AT_ns_returns_not_retained: 1877 case AttributeList::AT_cf_returns_not_retained: 1878 case AttributeList::AT_ns_returns_retained: 1879 case AttributeList::AT_cf_returns_retained: 1880 HandleNSReturnsRetainedAttr(D, Attr, S); break; 1881 1882 case AttributeList::AT_reqd_wg_size: 1883 HandleReqdWorkGroupSize(D, Attr, S); break; 1884 1885 case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 1886 case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 1887 case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 1888 case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1889 case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 1890 case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 1891 case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1892 break; 1893 case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1894 case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 1895 case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 1896 case AttributeList::AT_transparent_union: 1897 HandleTransparentUnionAttr(D, Attr, S); 1898 break; 1899 case AttributeList::AT_objc_exception: 1900 HandleObjCExceptionAttr(D, Attr, S); 1901 break; 1902 case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1903 case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 1904 case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1905 case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1906 case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1907 case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1908 case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1909 case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 1910 case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 1911 case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1912 case AttributeList::IgnoredAttribute: 1913 case AttributeList::AT_no_instrument_function: // Interacts with -pg. 1914 // Just ignore 1915 break; 1916 case AttributeList::AT_stdcall: 1917 case AttributeList::AT_cdecl: 1918 case AttributeList::AT_fastcall: 1919 // These are all treated as type attributes. 1920 break; 1921 default: 1922 // Ask target about the attribute. 1923 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 1924 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 1925 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1926 break; 1927 } 1928} 1929 1930/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1931/// attribute list to the specified decl, ignoring any type attributes. 1932void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1933 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 1934 ProcessDeclAttribute(S, D, *l, *this); 1935 } 1936 1937 // GCC accepts 1938 // static int a9 __attribute__((weakref)); 1939 // but that looks really pointless. We reject it. 1940 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 1941 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 1942 dyn_cast<NamedDecl>(D)->getNameAsString(); 1943 return; 1944 } 1945} 1946 1947/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1948/// #pragma weak needs a non-definition decl and source may not have one 1949NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 1950 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1951 NamedDecl *NewD = 0; 1952 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1953 NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1954 FD->getLocation(), DeclarationName(II), 1955 FD->getType(), FD->getTypeSourceInfo()); 1956 if (FD->getQualifier()) { 1957 FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 1958 NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 1959 } 1960 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1961 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1962 VD->getLocation(), II, 1963 VD->getType(), VD->getTypeSourceInfo(), 1964 VD->getStorageClass()); 1965 if (VD->getQualifier()) { 1966 VarDecl *NewVD = cast<VarDecl>(NewD); 1967 NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 1968 } 1969 } 1970 return NewD; 1971} 1972 1973/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1974/// applied to it, possibly with an alias. 1975void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1976 if (W.getUsed()) return; // only do this once 1977 W.setUsed(true); 1978 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1979 IdentifierInfo *NDId = ND->getIdentifier(); 1980 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1981 NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName())); 1982 NewD->addAttr(::new (Context) WeakAttr()); 1983 WeakTopLevelDecl.push_back(NewD); 1984 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1985 // to insert Decl at TU scope, sorry. 1986 DeclContext *SavedContext = CurContext; 1987 CurContext = Context.getTranslationUnitDecl(); 1988 PushOnScopeChains(NewD, S); 1989 CurContext = SavedContext; 1990 } else { // just add weak to existing 1991 ND->addAttr(::new (Context) WeakAttr()); 1992 } 1993} 1994 1995/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 1996/// it, apply them to D. This is a bit tricky because PD can have attributes 1997/// specified in many different places, and we need to find and apply them all. 1998void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1999 // Handle #pragma weak 2000 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2001 if (ND->hasLinkage()) { 2002 WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2003 if (W != WeakInfo()) { 2004 // Identifier referenced by #pragma weak before it was declared 2005 DeclApplyPragmaWeak(S, ND, W); 2006 WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2007 } 2008 } 2009 } 2010 2011 // Apply decl attributes from the DeclSpec if present. 2012 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 2013 ProcessDeclAttributeList(S, D, Attrs); 2014 2015 // Walk the declarator structure, applying decl attributes that were in a type 2016 // position to the decl itself. This handles cases like: 2017 // int *__attr__(x)** D; 2018 // when X is a decl attribute. 2019 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 2020 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 2021 ProcessDeclAttributeList(S, D, Attrs); 2022 2023 // Finally, apply any attributes on the decl itself. 2024 if (const AttributeList *Attrs = PD.getAttributes()) 2025 ProcessDeclAttributeList(S, D, Attrs); 2026} 2027 2028/// PushParsingDeclaration - Enter a new "scope" of deprecation 2029/// warnings. 2030/// 2031/// The state token we use is the start index of this scope 2032/// on the warning stack. 2033Action::ParsingDeclStackState Sema::PushParsingDeclaration() { 2034 ParsingDeclDepth++; 2035 return (ParsingDeclStackState) DelayedDiagnostics.size(); 2036} 2037 2038void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 2039 assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 2040 ParsingDeclDepth--; 2041 2042 if (DelayedDiagnostics.empty()) 2043 return; 2044 2045 unsigned SavedIndex = (unsigned) S; 2046 assert(SavedIndex <= DelayedDiagnostics.size() && 2047 "saved index is out of bounds"); 2048 2049 unsigned E = DelayedDiagnostics.size(); 2050 2051 // We only want to actually emit delayed diagnostics when we 2052 // successfully parsed a decl. 2053 Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 2054 if (D) { 2055 // We really do want to start with 0 here. We get one push for a 2056 // decl spec and another for each declarator; in a decl group like: 2057 // deprecated_typedef foo, *bar, baz(); 2058 // only the declarator pops will be passed decls. This is correct; 2059 // we really do need to consider delayed diagnostics from the decl spec 2060 // for each of the different declarations. 2061 for (unsigned I = 0; I != E; ++I) { 2062 if (DelayedDiagnostics[I].Triggered) 2063 continue; 2064 2065 switch (DelayedDiagnostics[I].Kind) { 2066 case DelayedDiagnostic::Deprecation: 2067 HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 2068 break; 2069 2070 case DelayedDiagnostic::Access: 2071 HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 2072 break; 2073 } 2074 } 2075 } 2076 2077 // Destroy all the delayed diagnostics we're about to pop off. 2078 for (unsigned I = SavedIndex; I != E; ++I) 2079 DelayedDiagnostics[I].destroy(); 2080 2081 DelayedDiagnostics.set_size(SavedIndex); 2082} 2083 2084static bool isDeclDeprecated(Decl *D) { 2085 do { 2086 if (D->hasAttr<DeprecatedAttr>()) 2087 return true; 2088 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 2089 return false; 2090} 2091 2092void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 2093 Decl *Ctx) { 2094 if (isDeclDeprecated(Ctx)) 2095 return; 2096 2097 DD.Triggered = true; 2098 Diag(DD.Loc, diag::warn_deprecated) 2099 << DD.DeprecationData.Decl->getDeclName(); 2100} 2101 2102void Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 2103 // Delay if we're currently parsing a declaration. 2104 if (ParsingDeclDepth) { 2105 DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 2106 return; 2107 } 2108 2109 // Otherwise, don't warn if our current context is deprecated. 2110 if (isDeclDeprecated(cast<Decl>(CurContext))) 2111 return; 2112 2113 Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 2114} 2115