SemaDeclAttr.cpp revision 3daade9020b55e5369256b6536e6c2f6f7a15060
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 "clang/Sema/SemaInternal.h" 15#include "TargetAttributesSema.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/CXXInheritance.h" 18#include "clang/AST/DeclCXX.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/AST/DeclTemplate.h" 21#include "clang/AST/Expr.h" 22#include "clang/AST/Mangle.h" 23#include "clang/Basic/CharInfo.h" 24#include "clang/Basic/SourceManager.h" 25#include "clang/Basic/TargetInfo.h" 26#include "clang/Lex/Preprocessor.h" 27#include "clang/Sema/DeclSpec.h" 28#include "clang/Sema/DelayedDiagnostic.h" 29#include "clang/Sema/Lookup.h" 30#include "clang/Sema/Scope.h" 31#include "llvm/ADT/StringExtras.h" 32using namespace clang; 33using namespace sema; 34 35/// These constants match the enumerated choices of 36/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 37enum AttributeDeclKind { 38 ExpectedFunction, 39 ExpectedUnion, 40 ExpectedVariableOrFunction, 41 ExpectedFunctionOrMethod, 42 ExpectedParameter, 43 ExpectedFunctionMethodOrBlock, 44 ExpectedFunctionMethodOrClass, 45 ExpectedFunctionMethodOrParameter, 46 ExpectedClass, 47 ExpectedVariable, 48 ExpectedMethod, 49 ExpectedVariableFunctionOrLabel, 50 ExpectedFieldOrGlobalVar, 51 ExpectedStruct, 52 ExpectedVariableFunctionOrTag, 53 ExpectedTLSVar, 54 ExpectedVariableOrField, 55 ExpectedVariableFieldOrTag, 56 ExpectedTypeOrNamespace, 57 ExpectedObjectiveCInterface, 58 ExpectedMethodOrProperty 59}; 60 61//===----------------------------------------------------------------------===// 62// Helper functions 63//===----------------------------------------------------------------------===// 64 65static const FunctionType *getFunctionType(const Decl *D, 66 bool blocksToo = true) { 67 QualType Ty; 68 if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 69 Ty = decl->getType(); 70 else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 71 Ty = decl->getType(); 72 else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 73 Ty = decl->getUnderlyingType(); 74 else 75 return 0; 76 77 if (Ty->isFunctionPointerType()) 78 Ty = Ty->getAs<PointerType>()->getPointeeType(); 79 else if (blocksToo && Ty->isBlockPointerType()) 80 Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 81 82 return Ty->getAs<FunctionType>(); 83} 84 85// FIXME: We should provide an abstraction around a method or function 86// to provide the following bits of information. 87 88/// isFunction - Return true if the given decl has function 89/// type (function or function-typed variable). 90static bool isFunction(const Decl *D) { 91 return getFunctionType(D, false) != NULL; 92} 93 94/// isFunctionOrMethod - Return true if the given decl has function 95/// type (function or function-typed variable) or an Objective-C 96/// method. 97static bool isFunctionOrMethod(const Decl *D) { 98 return isFunction(D) || isa<ObjCMethodDecl>(D); 99} 100 101/// isFunctionOrMethodOrBlock - Return true if the given decl has function 102/// type (function or function-typed variable) or an Objective-C 103/// method or a block. 104static bool isFunctionOrMethodOrBlock(const Decl *D) { 105 if (isFunctionOrMethod(D)) 106 return true; 107 // check for block is more involved. 108 if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 109 QualType Ty = V->getType(); 110 return Ty->isBlockPointerType(); 111 } 112 return isa<BlockDecl>(D); 113} 114 115/// Return true if the given decl has a declarator that should have 116/// been processed by Sema::GetTypeForDeclarator. 117static bool hasDeclarator(const Decl *D) { 118 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 119 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 120 isa<ObjCPropertyDecl>(D); 121} 122 123/// hasFunctionProto - Return true if the given decl has a argument 124/// information. This decl should have already passed 125/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 126static bool hasFunctionProto(const Decl *D) { 127 if (const FunctionType *FnTy = getFunctionType(D)) 128 return isa<FunctionProtoType>(FnTy); 129 else { 130 assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 131 return true; 132 } 133} 134 135/// getFunctionOrMethodNumArgs - Return number of function or method 136/// arguments. It is an error to call this on a K&R function (use 137/// hasFunctionProto first). 138static unsigned getFunctionOrMethodNumArgs(const Decl *D) { 139 if (const FunctionType *FnTy = getFunctionType(D)) 140 return cast<FunctionProtoType>(FnTy)->getNumArgs(); 141 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 142 return BD->getNumParams(); 143 return cast<ObjCMethodDecl>(D)->param_size(); 144} 145 146static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 147 if (const FunctionType *FnTy = getFunctionType(D)) 148 return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 149 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 150 return BD->getParamDecl(Idx)->getType(); 151 152 return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 153} 154 155static QualType getFunctionOrMethodResultType(const Decl *D) { 156 if (const FunctionType *FnTy = getFunctionType(D)) 157 return cast<FunctionProtoType>(FnTy)->getResultType(); 158 return cast<ObjCMethodDecl>(D)->getResultType(); 159} 160 161static bool isFunctionOrMethodVariadic(const Decl *D) { 162 if (const FunctionType *FnTy = getFunctionType(D)) { 163 const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 164 return proto->isVariadic(); 165 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 166 return BD->isVariadic(); 167 else { 168 return cast<ObjCMethodDecl>(D)->isVariadic(); 169 } 170} 171 172static bool isInstanceMethod(const Decl *D) { 173 if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 174 return MethodDecl->isInstance(); 175 return false; 176} 177 178static inline bool isNSStringType(QualType T, ASTContext &Ctx) { 179 const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 180 if (!PT) 181 return false; 182 183 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 184 if (!Cls) 185 return false; 186 187 IdentifierInfo* ClsName = Cls->getIdentifier(); 188 189 // FIXME: Should we walk the chain of classes? 190 return ClsName == &Ctx.Idents.get("NSString") || 191 ClsName == &Ctx.Idents.get("NSMutableString"); 192} 193 194static inline bool isCFStringType(QualType T, ASTContext &Ctx) { 195 const PointerType *PT = T->getAs<PointerType>(); 196 if (!PT) 197 return false; 198 199 const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 200 if (!RT) 201 return false; 202 203 const RecordDecl *RD = RT->getDecl(); 204 if (RD->getTagKind() != TTK_Struct) 205 return false; 206 207 return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 208} 209 210static unsigned getNumAttributeArgs(const AttributeList &Attr) { 211 // FIXME: Include the type in the argument list. 212 return Attr.getNumArgs() + Attr.hasParsedType(); 213} 214 215/// \brief Check if the attribute has exactly as many args as Num. May 216/// output an error. 217static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 218 unsigned Num) { 219 if (getNumAttributeArgs(Attr) != Num) { 220 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 221 << Attr.getName() << Num; 222 return false; 223 } 224 225 return true; 226} 227 228 229/// \brief Check if the attribute has at least as many args as Num. May 230/// output an error. 231static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 232 unsigned Num) { 233 if (getNumAttributeArgs(Attr) < Num) { 234 S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 235 return false; 236 } 237 238 return true; 239} 240 241/// \brief Check if IdxExpr is a valid argument index for a function or 242/// instance method D. May output an error. 243/// 244/// \returns true if IdxExpr is a valid index. 245static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D, 246 StringRef AttrName, 247 SourceLocation AttrLoc, 248 unsigned AttrArgNum, 249 const Expr *IdxExpr, 250 uint64_t &Idx) 251{ 252 assert(isFunctionOrMethod(D)); 253 254 // In C++ the implicit 'this' function parameter also counts. 255 // Parameters are counted from one. 256 bool HP = hasFunctionProto(D); 257 bool HasImplicitThisParam = isInstanceMethod(D); 258 bool IV = HP && isFunctionOrMethodVariadic(D); 259 unsigned NumArgs = (HP ? getFunctionOrMethodNumArgs(D) : 0) + 260 HasImplicitThisParam; 261 262 llvm::APSInt IdxInt; 263 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 264 !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { 265 std::string Name = std::string("'") + AttrName.str() + std::string("'"); 266 S.Diag(AttrLoc, diag::err_attribute_argument_n_type) << Name.c_str() 267 << AttrArgNum << AANT_ArgumentIntegerConstant << IdxExpr->getSourceRange(); 268 return false; 269 } 270 271 Idx = IdxInt.getLimitedValue(); 272 if (Idx < 1 || (!IV && Idx > NumArgs)) { 273 S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds) 274 << AttrName << AttrArgNum << IdxExpr->getSourceRange(); 275 return false; 276 } 277 Idx--; // Convert to zero-based. 278 if (HasImplicitThisParam) { 279 if (Idx == 0) { 280 S.Diag(AttrLoc, 281 diag::err_attribute_invalid_implicit_this_argument) 282 << AttrName << IdxExpr->getSourceRange(); 283 return false; 284 } 285 --Idx; 286 } 287 288 return true; 289} 290 291/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal. 292/// If not emit an error and return false. If the argument is an identifier it 293/// will emit an error with a fixit hint and treat it as if it was a string 294/// literal. 295bool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr, 296 unsigned ArgNum, StringRef &Str, 297 SourceLocation *ArgLocation) { 298 // Look for identifiers. If we have one emit a hint to fix it to a literal. 299 if (Attr.isArgIdent(ArgNum)) { 300 IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum); 301 Diag(Loc->Loc, diag::err_attribute_argument_type) 302 << Attr.getName() << AANT_ArgumentString 303 << FixItHint::CreateInsertion(Loc->Loc, "\"") 304 << FixItHint::CreateInsertion(PP.getLocForEndOfToken(Loc->Loc), "\""); 305 Str = Loc->Ident->getName(); 306 if (ArgLocation) 307 *ArgLocation = Loc->Loc; 308 return true; 309 } 310 311 // Now check for an actual string literal. 312 Expr *ArgExpr = Attr.getArgAsExpr(ArgNum); 313 StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts()); 314 if (ArgLocation) 315 *ArgLocation = ArgExpr->getLocStart(); 316 317 if (!Literal || !Literal->isAscii()) { 318 Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) 319 << Attr.getName() << AANT_ArgumentString; 320 return false; 321 } 322 323 Str = Literal->getString(); 324 return true; 325} 326 327/// 328/// \brief Check if passed in Decl is a field or potentially shared global var 329/// \return true if the Decl is a field or potentially shared global variable 330/// 331static bool mayBeSharedVariable(const Decl *D) { 332 if (isa<FieldDecl>(D)) 333 return true; 334 if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 335 return vd->hasGlobalStorage() && !vd->getTLSKind(); 336 337 return false; 338} 339 340/// \brief Check if the passed-in expression is of type int or bool. 341static bool isIntOrBool(Expr *Exp) { 342 QualType QT = Exp->getType(); 343 return QT->isBooleanType() || QT->isIntegerType(); 344} 345 346 347// Check to see if the type is a smart pointer of some kind. We assume 348// it's a smart pointer if it defines both operator-> and operator*. 349static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { 350 DeclContextLookupConstResult Res1 = RT->getDecl()->lookup( 351 S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); 352 if (Res1.empty()) 353 return false; 354 355 DeclContextLookupConstResult Res2 = RT->getDecl()->lookup( 356 S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); 357 if (Res2.empty()) 358 return false; 359 360 return true; 361} 362 363/// \brief Check if passed in Decl is a pointer type. 364/// Note that this function may produce an error message. 365/// \return true if the Decl is a pointer type; false otherwise 366static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 367 const AttributeList &Attr) { 368 if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 369 QualType QT = vd->getType(); 370 if (QT->isAnyPointerType()) 371 return true; 372 373 if (const RecordType *RT = QT->getAs<RecordType>()) { 374 // If it's an incomplete type, it could be a smart pointer; skip it. 375 // (We don't want to force template instantiation if we can avoid it, 376 // since that would alter the order in which templates are instantiated.) 377 if (RT->isIncompleteType()) 378 return true; 379 380 if (threadSafetyCheckIsSmartPointer(S, RT)) 381 return true; 382 } 383 384 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 385 << Attr.getName()->getName() << QT; 386 } else { 387 S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 388 << Attr.getName(); 389 } 390 return false; 391} 392 393/// \brief Checks that the passed in QualType either is of RecordType or points 394/// to RecordType. Returns the relevant RecordType, null if it does not exit. 395static const RecordType *getRecordType(QualType QT) { 396 if (const RecordType *RT = QT->getAs<RecordType>()) 397 return RT; 398 399 // Now check if we point to record type. 400 if (const PointerType *PT = QT->getAs<PointerType>()) 401 return PT->getPointeeType()->getAs<RecordType>(); 402 403 return 0; 404} 405 406 407static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier, 408 CXXBasePath &Path, void *Unused) { 409 const RecordType *RT = Specifier->getType()->getAs<RecordType>(); 410 if (RT->getDecl()->getAttr<LockableAttr>()) 411 return true; 412 return false; 413} 414 415 416/// \brief Thread Safety Analysis: Checks that the passed in RecordType 417/// resolves to a lockable object. 418static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 419 QualType Ty) { 420 const RecordType *RT = getRecordType(Ty); 421 422 // Warn if could not get record type for this argument. 423 if (!RT) { 424 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class) 425 << Attr.getName() << Ty.getAsString(); 426 return; 427 } 428 429 // Don't check for lockable if the class hasn't been defined yet. 430 if (RT->isIncompleteType()) 431 return; 432 433 // Allow smart pointers to be used as lockable objects. 434 // FIXME -- Check the type that the smart pointer points to. 435 if (threadSafetyCheckIsSmartPointer(S, RT)) 436 return; 437 438 // Check if the type is lockable. 439 RecordDecl *RD = RT->getDecl(); 440 if (RD->getAttr<LockableAttr>()) 441 return; 442 443 // Else check if any base classes are lockable. 444 if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { 445 CXXBasePaths BPaths(false, false); 446 if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths)) 447 return; 448 } 449 450 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 451 << Attr.getName() << Ty.getAsString(); 452} 453 454/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 455/// from Sidx, resolve to a lockable object. 456/// \param Sidx The attribute argument index to start checking with. 457/// \param ParamIdxOk Whether an argument can be indexing into a function 458/// parameter list. 459static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 460 const AttributeList &Attr, 461 SmallVectorImpl<Expr*> &Args, 462 int Sidx = 0, 463 bool ParamIdxOk = false) { 464 for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 465 Expr *ArgExp = Attr.getArgAsExpr(Idx); 466 467 if (ArgExp->isTypeDependent()) { 468 // FIXME -- need to check this again on template instantiation 469 Args.push_back(ArgExp); 470 continue; 471 } 472 473 if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 474 if (StrLit->getLength() == 0 || 475 (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) { 476 // Pass empty strings to the analyzer without warnings. 477 // Treat "*" as the universal lock. 478 Args.push_back(ArgExp); 479 continue; 480 } 481 482 // We allow constant strings to be used as a placeholder for expressions 483 // that are not valid C++ syntax, but warn that they are ignored. 484 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 485 Attr.getName(); 486 Args.push_back(ArgExp); 487 continue; 488 } 489 490 QualType ArgTy = ArgExp->getType(); 491 492 // A pointer to member expression of the form &MyClass::mu is treated 493 // specially -- we need to look at the type of the member. 494 if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 495 if (UOp->getOpcode() == UO_AddrOf) 496 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 497 if (DRE->getDecl()->isCXXInstanceMember()) 498 ArgTy = DRE->getDecl()->getType(); 499 500 // First see if we can just cast to record type, or point to record type. 501 const RecordType *RT = getRecordType(ArgTy); 502 503 // Now check if we index into a record type function param. 504 if(!RT && ParamIdxOk) { 505 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 506 IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 507 if(FD && IL) { 508 unsigned int NumParams = FD->getNumParams(); 509 llvm::APInt ArgValue = IL->getValue(); 510 uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 511 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 512 if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 513 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 514 << Attr.getName() << Idx + 1 << NumParams; 515 continue; 516 } 517 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 518 } 519 } 520 521 checkForLockableRecord(S, D, Attr, ArgTy); 522 523 Args.push_back(ArgExp); 524 } 525} 526 527//===----------------------------------------------------------------------===// 528// Attribute Implementations 529//===----------------------------------------------------------------------===// 530 531// FIXME: All this manual attribute parsing code is gross. At the 532// least add some helper functions to check most argument patterns (# 533// and types of args). 534 535enum ThreadAttributeDeclKind { 536 ThreadExpectedFieldOrGlobalVar, 537 ThreadExpectedFunctionOrMethod, 538 ThreadExpectedClassOrStruct 539}; 540 541static bool checkGuardedVarAttrCommon(Sema &S, Decl *D, 542 const AttributeList &Attr) { 543 // D must be either a member field or global (potentially shared) variable. 544 if (!mayBeSharedVariable(D)) { 545 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 546 << Attr.getName() << ThreadExpectedFieldOrGlobalVar; 547 return false; 548 } 549 550 return true; 551} 552 553static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) { 554 if (!checkGuardedVarAttrCommon(S, D, Attr)) 555 return; 556 557 D->addAttr(::new (S.Context) 558 GuardedVarAttr(Attr.getRange(), S.Context, 559 Attr.getAttributeSpellingListIndex())); 560} 561 562static void handlePtGuardedVarAttr(Sema &S, Decl *D, 563 const AttributeList &Attr) { 564 if (!checkGuardedVarAttrCommon(S, D, Attr)) 565 return; 566 567 if (!threadSafetyCheckIsPointer(S, D, Attr)) 568 return; 569 570 D->addAttr(::new (S.Context) 571 PtGuardedVarAttr(Attr.getRange(), S.Context, 572 Attr.getAttributeSpellingListIndex())); 573} 574 575static bool checkGuardedByAttrCommon(Sema &S, Decl *D, 576 const AttributeList &Attr, 577 Expr* &Arg) { 578 // D must be either a member field or global (potentially shared) variable. 579 if (!mayBeSharedVariable(D)) { 580 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 581 << Attr.getName() << ThreadExpectedFieldOrGlobalVar; 582 return false; 583 } 584 585 SmallVector<Expr*, 1> Args; 586 // check that all arguments are lockable objects 587 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 588 unsigned Size = Args.size(); 589 if (Size != 1) 590 return false; 591 592 Arg = Args[0]; 593 594 return true; 595} 596 597static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) { 598 Expr *Arg = 0; 599 if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 600 return; 601 602 D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 603} 604 605static void handlePtGuardedByAttr(Sema &S, Decl *D, 606 const AttributeList &Attr) { 607 Expr *Arg = 0; 608 if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 609 return; 610 611 if (!threadSafetyCheckIsPointer(S, D, Attr)) 612 return; 613 614 D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 615 S.Context, Arg)); 616} 617 618static bool checkLockableAttrCommon(Sema &S, Decl *D, 619 const AttributeList &Attr) { 620 // FIXME: Lockable structs for C code. 621 if (!isa<RecordDecl>(D)) { 622 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 623 << Attr.getName() << ThreadExpectedClassOrStruct; 624 return false; 625 } 626 627 return true; 628} 629 630static void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 631 if (!checkLockableAttrCommon(S, D, Attr)) 632 return; 633 634 D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 635} 636 637static void handleScopedLockableAttr(Sema &S, Decl *D, 638 const AttributeList &Attr) { 639 if (!checkLockableAttrCommon(S, D, Attr)) 640 return; 641 642 D->addAttr(::new (S.Context) 643 ScopedLockableAttr(Attr.getRange(), S.Context, 644 Attr.getAttributeSpellingListIndex())); 645} 646 647static void handleNoThreadSafetyAnalysis(Sema &S, Decl *D, 648 const AttributeList &Attr) { 649 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 650 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 651 << Attr.getName() << ThreadExpectedFunctionOrMethod; 652 return; 653 } 654 655 D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 656 S.Context)); 657} 658 659static void handleNoSanitizeAddressAttr(Sema &S, Decl *D, 660 const AttributeList &Attr) { 661 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 662 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 663 << Attr.getName() << ExpectedFunctionOrMethod; 664 return; 665 } 666 667 D->addAttr(::new (S.Context) 668 NoSanitizeAddressAttr(Attr.getRange(), S.Context, 669 Attr.getAttributeSpellingListIndex())); 670} 671 672static void handleNoSanitizeMemory(Sema &S, Decl *D, 673 const AttributeList &Attr) { 674 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 675 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 676 << Attr.getName() << ExpectedFunctionOrMethod; 677 return; 678 } 679 680 D->addAttr(::new (S.Context) NoSanitizeMemoryAttr(Attr.getRange(), 681 S.Context)); 682} 683 684static void handleNoSanitizeThread(Sema &S, Decl *D, 685 const AttributeList &Attr) { 686 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 687 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 688 << Attr.getName() << ExpectedFunctionOrMethod; 689 return; 690 } 691 692 D->addAttr(::new (S.Context) NoSanitizeThreadAttr(Attr.getRange(), 693 S.Context)); 694} 695 696static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, 697 const AttributeList &Attr, 698 SmallVectorImpl<Expr *> &Args) { 699 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 700 return false; 701 702 // D must be either a member field or global (potentially shared) variable. 703 ValueDecl *VD = dyn_cast<ValueDecl>(D); 704 if (!VD || !mayBeSharedVariable(D)) { 705 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 706 << Attr.getName() << ThreadExpectedFieldOrGlobalVar; 707 return false; 708 } 709 710 // Check that this attribute only applies to lockable types. 711 QualType QT = VD->getType(); 712 if (!QT->isDependentType()) { 713 const RecordType *RT = getRecordType(QT); 714 if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 715 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 716 << Attr.getName(); 717 return false; 718 } 719 } 720 721 // Check that all arguments are lockable objects. 722 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 723 if (Args.empty()) 724 return false; 725 726 return true; 727} 728 729static void handleAcquiredAfterAttr(Sema &S, Decl *D, 730 const AttributeList &Attr) { 731 SmallVector<Expr*, 1> Args; 732 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 733 return; 734 735 Expr **StartArg = &Args[0]; 736 D->addAttr(::new (S.Context) 737 AcquiredAfterAttr(Attr.getRange(), S.Context, 738 StartArg, Args.size(), 739 Attr.getAttributeSpellingListIndex())); 740} 741 742static void handleAcquiredBeforeAttr(Sema &S, Decl *D, 743 const AttributeList &Attr) { 744 SmallVector<Expr*, 1> Args; 745 if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 746 return; 747 748 Expr **StartArg = &Args[0]; 749 D->addAttr(::new (S.Context) 750 AcquiredBeforeAttr(Attr.getRange(), S.Context, 751 StartArg, Args.size(), 752 Attr.getAttributeSpellingListIndex())); 753} 754 755static bool checkLockFunAttrCommon(Sema &S, Decl *D, 756 const AttributeList &Attr, 757 SmallVectorImpl<Expr *> &Args) { 758 // zero or more arguments ok 759 760 // check that the attribute is applied to a function 761 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 762 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 763 << Attr.getName() << ThreadExpectedFunctionOrMethod; 764 return false; 765 } 766 767 // check that all arguments are lockable objects 768 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 769 770 return true; 771} 772 773static void handleSharedLockFunctionAttr(Sema &S, Decl *D, 774 const AttributeList &Attr) { 775 SmallVector<Expr*, 1> Args; 776 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 777 return; 778 779 unsigned Size = Args.size(); 780 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 781 D->addAttr(::new (S.Context) 782 SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size, 783 Attr.getAttributeSpellingListIndex())); 784} 785 786static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D, 787 const AttributeList &Attr) { 788 SmallVector<Expr*, 1> Args; 789 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 790 return; 791 792 unsigned Size = Args.size(); 793 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 794 D->addAttr(::new (S.Context) 795 ExclusiveLockFunctionAttr(Attr.getRange(), S.Context, 796 StartArg, Size, 797 Attr.getAttributeSpellingListIndex())); 798} 799 800static void handleAssertSharedLockAttr(Sema &S, Decl *D, 801 const AttributeList &Attr) { 802 SmallVector<Expr*, 1> Args; 803 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 804 return; 805 806 unsigned Size = Args.size(); 807 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 808 D->addAttr(::new (S.Context) 809 AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size, 810 Attr.getAttributeSpellingListIndex())); 811} 812 813static void handleAssertExclusiveLockAttr(Sema &S, Decl *D, 814 const AttributeList &Attr) { 815 SmallVector<Expr*, 1> Args; 816 if (!checkLockFunAttrCommon(S, D, Attr, Args)) 817 return; 818 819 unsigned Size = Args.size(); 820 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 821 D->addAttr(::new (S.Context) 822 AssertExclusiveLockAttr(Attr.getRange(), S.Context, 823 StartArg, Size, 824 Attr.getAttributeSpellingListIndex())); 825} 826 827 828static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, 829 const AttributeList &Attr, 830 SmallVectorImpl<Expr *> &Args) { 831 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 832 return false; 833 834 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 835 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 836 << Attr.getName() << ThreadExpectedFunctionOrMethod; 837 return false; 838 } 839 840 if (!isIntOrBool(Attr.getArgAsExpr(0))) { 841 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 842 << Attr.getName() << 1 << AANT_ArgumentIntOrBool; 843 return false; 844 } 845 846 // check that all arguments are lockable objects 847 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1); 848 849 return true; 850} 851 852static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, 853 const AttributeList &Attr) { 854 SmallVector<Expr*, 2> Args; 855 if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 856 return; 857 858 D->addAttr(::new (S.Context) 859 SharedTrylockFunctionAttr(Attr.getRange(), S.Context, 860 Attr.getArgAsExpr(0), 861 Args.data(), Args.size(), 862 Attr.getAttributeSpellingListIndex())); 863} 864 865static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, 866 const AttributeList &Attr) { 867 SmallVector<Expr*, 2> Args; 868 if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 869 return; 870 871 D->addAttr(::new (S.Context) 872 ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context, 873 Attr.getArgAsExpr(0), 874 Args.data(), Args.size(), 875 Attr.getAttributeSpellingListIndex())); 876} 877 878static bool checkLocksRequiredCommon(Sema &S, Decl *D, 879 const AttributeList &Attr, 880 SmallVectorImpl<Expr *> &Args) { 881 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 882 return false; 883 884 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 885 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 886 << Attr.getName() << ThreadExpectedFunctionOrMethod; 887 return false; 888 } 889 890 // check that all arguments are lockable objects 891 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 892 if (Args.empty()) 893 return false; 894 895 return true; 896} 897 898static void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D, 899 const AttributeList &Attr) { 900 SmallVector<Expr*, 1> Args; 901 if (!checkLocksRequiredCommon(S, D, Attr, Args)) 902 return; 903 904 Expr **StartArg = &Args[0]; 905 D->addAttr(::new (S.Context) 906 ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context, 907 StartArg, Args.size(), 908 Attr.getAttributeSpellingListIndex())); 909} 910 911static void handleSharedLocksRequiredAttr(Sema &S, Decl *D, 912 const AttributeList &Attr) { 913 SmallVector<Expr*, 1> Args; 914 if (!checkLocksRequiredCommon(S, D, Attr, Args)) 915 return; 916 917 Expr **StartArg = &Args[0]; 918 D->addAttr(::new (S.Context) 919 SharedLocksRequiredAttr(Attr.getRange(), S.Context, 920 StartArg, Args.size(), 921 Attr.getAttributeSpellingListIndex())); 922} 923 924static void handleUnlockFunAttr(Sema &S, Decl *D, 925 const AttributeList &Attr) { 926 // zero or more arguments ok 927 928 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 929 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 930 << Attr.getName() << ThreadExpectedFunctionOrMethod; 931 return; 932 } 933 934 // check that all arguments are lockable objects 935 SmallVector<Expr*, 1> Args; 936 checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 937 unsigned Size = Args.size(); 938 Expr **StartArg = Size == 0 ? 0 : &Args[0]; 939 940 D->addAttr(::new (S.Context) 941 UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size, 942 Attr.getAttributeSpellingListIndex())); 943} 944 945static void handleLockReturnedAttr(Sema &S, Decl *D, 946 const AttributeList &Attr) { 947 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 948 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 949 << Attr.getName() << ThreadExpectedFunctionOrMethod; 950 return; 951 } 952 953 // check that the argument is lockable object 954 SmallVector<Expr*, 1> Args; 955 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 956 unsigned Size = Args.size(); 957 if (Size == 0) 958 return; 959 960 D->addAttr(::new (S.Context) 961 LockReturnedAttr(Attr.getRange(), S.Context, Args[0], 962 Attr.getAttributeSpellingListIndex())); 963} 964 965static void handleLocksExcludedAttr(Sema &S, Decl *D, 966 const AttributeList &Attr) { 967 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 968 return; 969 970 if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 971 S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 972 << Attr.getName() << ThreadExpectedFunctionOrMethod; 973 return; 974 } 975 976 // check that all arguments are lockable objects 977 SmallVector<Expr*, 1> Args; 978 checkAttrArgsAreLockableObjs(S, D, Attr, Args); 979 unsigned Size = Args.size(); 980 if (Size == 0) 981 return; 982 Expr **StartArg = &Args[0]; 983 984 D->addAttr(::new (S.Context) 985 LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size, 986 Attr.getAttributeSpellingListIndex())); 987} 988 989static void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 990 ConsumableAttr::ConsumedState DefaultState; 991 992 if (Attr.isArgIdent(0)) { 993 IdentifierLoc *IL = Attr.getArgAsIdent(0); 994 if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(), 995 DefaultState)) { 996 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) 997 << Attr.getName() << IL->Ident; 998 return; 999 } 1000 } else { 1001 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 1002 << Attr.getName() << AANT_ArgumentIdentifier; 1003 return; 1004 } 1005 1006 if (!isa<CXXRecordDecl>(D)) { 1007 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << 1008 Attr.getName() << ExpectedClass; 1009 return; 1010 } 1011 1012 D->addAttr(::new (S.Context) 1013 ConsumableAttr(Attr.getRange(), S.Context, DefaultState, 1014 Attr.getAttributeSpellingListIndex())); 1015} 1016 1017static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, 1018 const AttributeList &Attr) { 1019 ASTContext &CurrContext = S.getASTContext(); 1020 QualType ThisType = MD->getThisType(CurrContext)->getPointeeType(); 1021 1022 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) { 1023 if (!RD->hasAttr<ConsumableAttr>()) { 1024 S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) << 1025 RD->getNameAsString(); 1026 1027 return false; 1028 } 1029 } 1030 1031 return true; 1032} 1033 1034 1035static void handleCallableWhenAttr(Sema &S, Decl *D, 1036 const AttributeList &Attr) { 1037 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 1038 return; 1039 1040 if (!isa<CXXMethodDecl>(D)) { 1041 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << 1042 Attr.getName() << ExpectedMethod; 1043 return; 1044 } 1045 1046 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 1047 return; 1048 1049 SmallVector<CallableWhenAttr::ConsumedState, 3> States; 1050 for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) { 1051 CallableWhenAttr::ConsumedState CallableState; 1052 1053 StringRef StateString; 1054 SourceLocation Loc; 1055 if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc)) 1056 return; 1057 1058 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString, 1059 CallableState)) { 1060 S.Diag(Loc, diag::warn_attribute_type_not_supported) 1061 << Attr.getName() << StateString; 1062 return; 1063 } 1064 1065 States.push_back(CallableState); 1066 } 1067 1068 D->addAttr(::new (S.Context) 1069 CallableWhenAttr(Attr.getRange(), S.Context, States.data(), 1070 States.size(), Attr.getAttributeSpellingListIndex())); 1071} 1072 1073 1074static void handleParamTypestateAttr(Sema &S, Decl *D, 1075 const AttributeList &Attr) { 1076 if (!checkAttributeNumArgs(S, Attr, 1)) return; 1077 1078 if (!isa<ParmVarDecl>(D)) { 1079 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << 1080 Attr.getName() << ExpectedParameter; 1081 return; 1082 } 1083 1084 ParamTypestateAttr::ConsumedState ParamState; 1085 1086 if (Attr.isArgIdent(0)) { 1087 IdentifierLoc *Ident = Attr.getArgAsIdent(0); 1088 StringRef StateString = Ident->Ident->getName(); 1089 1090 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString, 1091 ParamState)) { 1092 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 1093 << Attr.getName() << StateString; 1094 return; 1095 } 1096 } else { 1097 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1098 Attr.getName() << AANT_ArgumentIdentifier; 1099 return; 1100 } 1101 1102 // FIXME: This check is currently being done in the analysis. It can be 1103 // enabled here only after the parser propagates attributes at 1104 // template specialization definition, not declaration. 1105 //QualType ReturnType = cast<ParmVarDecl>(D)->getType(); 1106 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); 1107 // 1108 //if (!RD || !RD->hasAttr<ConsumableAttr>()) { 1109 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << 1110 // ReturnType.getAsString(); 1111 // return; 1112 //} 1113 1114 D->addAttr(::new (S.Context) 1115 ParamTypestateAttr(Attr.getRange(), S.Context, ParamState, 1116 Attr.getAttributeSpellingListIndex())); 1117} 1118 1119 1120static void handleReturnTypestateAttr(Sema &S, Decl *D, 1121 const AttributeList &Attr) { 1122 if (!checkAttributeNumArgs(S, Attr, 1)) return; 1123 1124 if (!(isa<FunctionDecl>(D) || isa<ParmVarDecl>(D))) { 1125 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << 1126 Attr.getName() << ExpectedFunctionMethodOrParameter; 1127 return; 1128 } 1129 1130 ReturnTypestateAttr::ConsumedState ReturnState; 1131 1132 if (Attr.isArgIdent(0)) { 1133 IdentifierLoc *IL = Attr.getArgAsIdent(0); 1134 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(), 1135 ReturnState)) { 1136 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) 1137 << Attr.getName() << IL->Ident; 1138 return; 1139 } 1140 } else { 1141 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1142 Attr.getName() << AANT_ArgumentIdentifier; 1143 return; 1144 } 1145 1146 // FIXME: This check is currently being done in the analysis. It can be 1147 // enabled here only after the parser propagates attributes at 1148 // template specialization definition, not declaration. 1149 //QualType ReturnType; 1150 // 1151 //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) { 1152 // ReturnType = Param->getType(); 1153 // 1154 //} else if (const CXXConstructorDecl *Constructor = 1155 // dyn_cast<CXXConstructorDecl>(D)) { 1156 // ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType(); 1157 // 1158 //} else { 1159 // 1160 // ReturnType = cast<FunctionDecl>(D)->getCallResultType(); 1161 //} 1162 // 1163 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); 1164 // 1165 //if (!RD || !RD->hasAttr<ConsumableAttr>()) { 1166 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << 1167 // ReturnType.getAsString(); 1168 // return; 1169 //} 1170 1171 D->addAttr(::new (S.Context) 1172 ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState, 1173 Attr.getAttributeSpellingListIndex())); 1174} 1175 1176 1177static void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1178 if (!checkAttributeNumArgs(S, Attr, 1)) 1179 return; 1180 1181 if (!isa<CXXMethodDecl>(D)) { 1182 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << 1183 Attr.getName() << ExpectedMethod; 1184 return; 1185 } 1186 1187 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 1188 return; 1189 1190 SetTypestateAttr::ConsumedState NewState; 1191 if (Attr.isArgIdent(0)) { 1192 IdentifierLoc *Ident = Attr.getArgAsIdent(0); 1193 StringRef Param = Ident->Ident->getName(); 1194 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) { 1195 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 1196 << Attr.getName() << Param; 1197 return; 1198 } 1199 } else { 1200 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1201 Attr.getName() << AANT_ArgumentIdentifier; 1202 return; 1203 } 1204 1205 D->addAttr(::new (S.Context) 1206 SetTypestateAttr(Attr.getRange(), S.Context, NewState, 1207 Attr.getAttributeSpellingListIndex())); 1208} 1209 1210static void handleTestTypestateAttr(Sema &S, Decl *D, 1211 const AttributeList &Attr) { 1212 if (!checkAttributeNumArgs(S, Attr, 1)) 1213 return; 1214 1215 if (!isa<CXXMethodDecl>(D)) { 1216 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << 1217 Attr.getName() << ExpectedMethod; 1218 return; 1219 } 1220 1221 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 1222 return; 1223 1224 TestTypestateAttr::ConsumedState TestState; 1225 if (Attr.isArgIdent(0)) { 1226 IdentifierLoc *Ident = Attr.getArgAsIdent(0); 1227 StringRef Param = Ident->Ident->getName(); 1228 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) { 1229 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 1230 << Attr.getName() << Param; 1231 return; 1232 } 1233 } else { 1234 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1235 Attr.getName() << AANT_ArgumentIdentifier; 1236 return; 1237 } 1238 1239 D->addAttr(::new (S.Context) 1240 TestTypestateAttr(Attr.getRange(), S.Context, TestState, 1241 Attr.getAttributeSpellingListIndex())); 1242} 1243 1244static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 1245 const AttributeList &Attr) { 1246 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 1247 if (TD == 0) { 1248 // __attribute__((ext_vector_type(N))) can only be applied to typedefs 1249 // and type-ids. 1250 S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 1251 return; 1252 } 1253 1254 // Remember this typedef decl, we will need it later for diagnostics. 1255 S.ExtVectorDecls.push_back(TD); 1256} 1257 1258static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1259 if (TagDecl *TD = dyn_cast<TagDecl>(D)) 1260 TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 1261 else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 1262 // If the alignment is less than or equal to 8 bits, the packed attribute 1263 // has no effect. 1264 if (!FD->getType()->isDependentType() && 1265 !FD->getType()->isIncompleteType() && 1266 S.Context.getTypeAlign(FD->getType()) <= 8) 1267 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 1268 << Attr.getName() << FD->getType(); 1269 else 1270 FD->addAttr(::new (S.Context) 1271 PackedAttr(Attr.getRange(), S.Context, 1272 Attr.getAttributeSpellingListIndex())); 1273 } else 1274 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1275} 1276 1277static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1278 if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) 1279 RD->addAttr(::new (S.Context) 1280 MsStructAttr(Attr.getRange(), S.Context, 1281 Attr.getAttributeSpellingListIndex())); 1282 else 1283 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1284} 1285 1286static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 1287 // The IBAction attributes only apply to instance methods. 1288 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1289 if (MD->isInstanceMethod()) { 1290 D->addAttr(::new (S.Context) 1291 IBActionAttr(Attr.getRange(), S.Context, 1292 Attr.getAttributeSpellingListIndex())); 1293 return; 1294 } 1295 1296 S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 1297} 1298 1299static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 1300 // The IBOutlet/IBOutletCollection attributes only apply to instance 1301 // variables or properties of Objective-C classes. The outlet must also 1302 // have an object reference type. 1303 if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 1304 if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 1305 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 1306 << Attr.getName() << VD->getType() << 0; 1307 return false; 1308 } 1309 } 1310 else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 1311 if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 1312 S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 1313 << Attr.getName() << PD->getType() << 1; 1314 return false; 1315 } 1316 } 1317 else { 1318 S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 1319 return false; 1320 } 1321 1322 return true; 1323} 1324 1325static void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 1326 if (!checkIBOutletCommon(S, D, Attr)) 1327 return; 1328 1329 D->addAttr(::new (S.Context) 1330 IBOutletAttr(Attr.getRange(), S.Context, 1331 Attr.getAttributeSpellingListIndex())); 1332} 1333 1334static void handleIBOutletCollection(Sema &S, Decl *D, 1335 const AttributeList &Attr) { 1336 1337 // The iboutletcollection attribute can have zero or one arguments. 1338 if (Attr.getNumArgs() > 1) { 1339 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1340 << Attr.getName() << 1; 1341 return; 1342 } 1343 1344 if (!checkIBOutletCommon(S, D, Attr)) 1345 return; 1346 1347 ParsedType PT; 1348 1349 if (Attr.hasParsedType()) 1350 PT = Attr.getTypeArg(); 1351 else { 1352 PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(), 1353 S.getScopeForContext(D->getDeclContext()->getParent())); 1354 if (!PT) { 1355 S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject"; 1356 return; 1357 } 1358 } 1359 1360 TypeSourceInfo *QTLoc = 0; 1361 QualType QT = S.GetTypeFromParser(PT, &QTLoc); 1362 if (!QTLoc) 1363 QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc()); 1364 1365 // Diagnose use of non-object type in iboutletcollection attribute. 1366 // FIXME. Gnu attribute extension ignores use of builtin types in 1367 // attributes. So, __attribute__((iboutletcollection(char))) will be 1368 // treated as __attribute__((iboutletcollection())). 1369 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 1370 S.Diag(Attr.getLoc(), 1371 QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype 1372 : diag::err_iboutletcollection_type) << QT; 1373 return; 1374 } 1375 1376 D->addAttr(::new (S.Context) 1377 IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc, 1378 Attr.getAttributeSpellingListIndex())); 1379} 1380 1381static void possibleTransparentUnionPointerType(QualType &T) { 1382 if (const RecordType *UT = T->getAsUnionType()) 1383 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 1384 RecordDecl *UD = UT->getDecl(); 1385 for (RecordDecl::field_iterator it = UD->field_begin(), 1386 itend = UD->field_end(); it != itend; ++it) { 1387 QualType QT = it->getType(); 1388 if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 1389 T = QT; 1390 return; 1391 } 1392 } 1393 } 1394} 1395 1396static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1397 if (!isFunctionOrMethod(D)) { 1398 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1399 << Attr.getName() << ExpectedFunctionOrMethod; 1400 return; 1401 } 1402 1403 if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 1404 return; 1405 1406 SmallVector<unsigned, 8> SizeArgs; 1407 for (unsigned i = 0; i < Attr.getNumArgs(); ++i) { 1408 Expr *Ex = Attr.getArgAsExpr(i); 1409 uint64_t Idx; 1410 if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(), 1411 Attr.getLoc(), i + 1, Ex, Idx)) 1412 return; 1413 1414 // check if the function argument is of an integer type 1415 QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType(); 1416 if (!T->isIntegerType()) { 1417 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 1418 << Attr.getName() << AANT_ArgumentIntegerConstant 1419 << Ex->getSourceRange(); 1420 return; 1421 } 1422 SizeArgs.push_back(Idx); 1423 } 1424 1425 // check if the function returns a pointer 1426 if (!getFunctionType(D)->getResultType()->isAnyPointerType()) { 1427 S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 1428 << Attr.getName() << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange(); 1429 } 1430 1431 D->addAttr(::new (S.Context) 1432 AllocSizeAttr(Attr.getRange(), S.Context, 1433 SizeArgs.data(), SizeArgs.size(), 1434 Attr.getAttributeSpellingListIndex())); 1435} 1436 1437static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1438 // GCC ignores the nonnull attribute on K&R style function prototypes, so we 1439 // ignore it as well 1440 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 1441 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1442 << Attr.getName() << ExpectedFunction; 1443 return; 1444 } 1445 1446 SmallVector<unsigned, 8> NonNullArgs; 1447 for (unsigned i = 0; i < Attr.getNumArgs(); ++i) { 1448 Expr *Ex = Attr.getArgAsExpr(i); 1449 uint64_t Idx; 1450 if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(), 1451 Attr.getLoc(), i + 1, Ex, Idx)) 1452 return; 1453 1454 // Is the function argument a pointer type? 1455 QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType(); 1456 possibleTransparentUnionPointerType(T); 1457 1458 if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1459 // FIXME: Should also highlight argument in decl. 1460 S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 1461 << "nonnull" << Ex->getSourceRange(); 1462 continue; 1463 } 1464 1465 NonNullArgs.push_back(Idx); 1466 } 1467 1468 // If no arguments were specified to __attribute__((nonnull)) then all pointer 1469 // arguments have a nonnull attribute. 1470 if (NonNullArgs.empty()) { 1471 for (unsigned i = 0, e = getFunctionOrMethodNumArgs(D); i != e; ++i) { 1472 QualType T = getFunctionOrMethodArgType(D, i).getNonReferenceType(); 1473 possibleTransparentUnionPointerType(T); 1474 if (T->isAnyPointerType() || T->isBlockPointerType()) 1475 NonNullArgs.push_back(i); 1476 } 1477 1478 // No pointer arguments? 1479 if (NonNullArgs.empty()) { 1480 // Warn the trivial case only if attribute is not coming from a 1481 // macro instantiation. 1482 if (Attr.getLoc().isFileID()) 1483 S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 1484 return; 1485 } 1486 } 1487 1488 unsigned *start = &NonNullArgs[0]; 1489 unsigned size = NonNullArgs.size(); 1490 llvm::array_pod_sort(start, start + size); 1491 D->addAttr(::new (S.Context) 1492 NonNullAttr(Attr.getRange(), S.Context, start, size, 1493 Attr.getAttributeSpellingListIndex())); 1494} 1495 1496static const char *ownershipKindToDiagName(OwnershipAttr::OwnershipKind K) { 1497 switch (K) { 1498 case OwnershipAttr::Holds: return "'ownership_holds'"; 1499 case OwnershipAttr::Takes: return "'ownership_takes'"; 1500 case OwnershipAttr::Returns: return "'ownership_returns'"; 1501 } 1502 llvm_unreachable("unknown ownership"); 1503} 1504 1505static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 1506 // This attribute must be applied to a function declaration. The first 1507 // argument to the attribute must be an identifier, the name of the resource, 1508 // for example: malloc. The following arguments must be argument indexes, the 1509 // arguments must be of integer type for Returns, otherwise of pointer type. 1510 // The difference between Holds and Takes is that a pointer may still be used 1511 // after being held. free() should be __attribute((ownership_takes)), whereas 1512 // a list append function may well be __attribute((ownership_holds)). 1513 1514 if (!AL.isArgIdent(0)) { 1515 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) 1516 << AL.getName() << 1 << AANT_ArgumentIdentifier; 1517 return; 1518 } 1519 1520 // Figure out our Kind, and check arguments while we're at it. 1521 OwnershipAttr::OwnershipKind K; 1522 switch (AL.getKind()) { 1523 case AttributeList::AT_ownership_takes: 1524 K = OwnershipAttr::Takes; 1525 if (AL.getNumArgs() < 2) { 1526 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << 2; 1527 return; 1528 } 1529 break; 1530 case AttributeList::AT_ownership_holds: 1531 K = OwnershipAttr::Holds; 1532 if (AL.getNumArgs() < 2) { 1533 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << 2; 1534 return; 1535 } 1536 break; 1537 case AttributeList::AT_ownership_returns: 1538 K = OwnershipAttr::Returns; 1539 1540 if (AL.getNumArgs() > 2) { 1541 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1542 return; 1543 } 1544 break; 1545 default: 1546 // This should never happen given how we are called. 1547 llvm_unreachable("Unknown ownership attribute"); 1548 } 1549 1550 if (!isFunction(D) || !hasFunctionProto(D)) { 1551 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 1552 << AL.getName() << ExpectedFunction; 1553 return; 1554 } 1555 1556 StringRef Module = AL.getArgAsIdent(0)->Ident->getName(); 1557 1558 // Normalize the argument, __foo__ becomes foo. 1559 if (Module.startswith("__") && Module.endswith("__")) 1560 Module = Module.substr(2, Module.size() - 4); 1561 1562 SmallVector<unsigned, 8> OwnershipArgs; 1563 for (unsigned i = 1; i < AL.getNumArgs(); ++i) { 1564 Expr *Ex = AL.getArgAsExpr(i); 1565 uint64_t Idx; 1566 if (!checkFunctionOrMethodArgumentIndex(S, D, AL.getName()->getName(), 1567 AL.getLoc(), i, Ex, Idx)) 1568 return; 1569 1570 // Is the function argument a pointer type? 1571 QualType T = getFunctionOrMethodArgType(D, Idx); 1572 int Err = -1; // No error 1573 switch (K) { 1574 case OwnershipAttr::Takes: 1575 case OwnershipAttr::Holds: 1576 if (!T->isAnyPointerType() && !T->isBlockPointerType()) 1577 Err = 0; 1578 break; 1579 case OwnershipAttr::Returns: 1580 if (!T->isIntegerType()) 1581 Err = 1; 1582 break; 1583 } 1584 if (-1 != Err) { 1585 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err 1586 << Ex->getSourceRange(); 1587 return; 1588 } 1589 1590 // Check we don't have a conflict with another ownership attribute. 1591 for (specific_attr_iterator<OwnershipAttr> 1592 i = D->specific_attr_begin<OwnershipAttr>(), 1593 e = D->specific_attr_end<OwnershipAttr>(); i != e; ++i) { 1594 if ((*i)->getOwnKind() != K && (*i)->args_end() != 1595 std::find((*i)->args_begin(), (*i)->args_end(), Idx)) { 1596 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1597 << AL.getName() << ownershipKindToDiagName((*i)->getOwnKind()); 1598 return; 1599 } 1600 } 1601 OwnershipArgs.push_back(Idx); 1602 } 1603 1604 unsigned* start = OwnershipArgs.data(); 1605 unsigned size = OwnershipArgs.size(); 1606 llvm::array_pod_sort(start, start + size); 1607 1608 D->addAttr(::new (S.Context) 1609 OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size, 1610 AL.getAttributeSpellingListIndex())); 1611} 1612 1613static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1614 // Check the attribute arguments. 1615 if (Attr.getNumArgs() > 1) { 1616 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1617 << Attr.getName() << 1; 1618 return; 1619 } 1620 1621 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1622 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1623 << Attr.getName() << ExpectedVariableOrFunction; 1624 return; 1625 } 1626 1627 NamedDecl *nd = cast<NamedDecl>(D); 1628 1629 // gcc rejects 1630 // class c { 1631 // static int a __attribute__((weakref ("v2"))); 1632 // static int b() __attribute__((weakref ("f3"))); 1633 // }; 1634 // and ignores the attributes of 1635 // void f(void) { 1636 // static int a __attribute__((weakref ("v2"))); 1637 // } 1638 // we reject them 1639 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 1640 if (!Ctx->isFileContext()) { 1641 S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1642 nd->getNameAsString(); 1643 return; 1644 } 1645 1646 // The GCC manual says 1647 // 1648 // At present, a declaration to which `weakref' is attached can only 1649 // be `static'. 1650 // 1651 // It also says 1652 // 1653 // Without a TARGET, 1654 // given as an argument to `weakref' or to `alias', `weakref' is 1655 // equivalent to `weak'. 1656 // 1657 // gcc 4.4.1 will accept 1658 // int a7 __attribute__((weakref)); 1659 // as 1660 // int a7 __attribute__((weak)); 1661 // This looks like a bug in gcc. We reject that for now. We should revisit 1662 // it if this behaviour is actually used. 1663 1664 // GCC rejects 1665 // static ((alias ("y"), weakref)). 1666 // Should we? How to check that weakref is before or after alias? 1667 1668 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead 1669 // of transforming it into an AliasAttr. The WeakRefAttr never uses the 1670 // StringRef parameter it was given anyway. 1671 StringRef Str; 1672 if (Attr.getNumArgs() && S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 1673 // GCC will accept anything as the argument of weakref. Should we 1674 // check for an existing decl? 1675 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, 1676 Attr.getAttributeSpellingListIndex())); 1677 1678 D->addAttr(::new (S.Context) 1679 WeakRefAttr(Attr.getRange(), S.Context, 1680 Attr.getAttributeSpellingListIndex())); 1681} 1682 1683static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1684 StringRef Str; 1685 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 1686 return; 1687 1688 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1689 S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1690 return; 1691 } 1692 1693 // FIXME: check if target symbol exists in current file 1694 1695 D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, 1696 Attr.getAttributeSpellingListIndex())); 1697} 1698 1699static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1700 if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) { 1701 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1702 << Attr.getName() << ExpectedFunctionOrMethod; 1703 return; 1704 } 1705 1706 D->addAttr(::new (S.Context) 1707 MinSizeAttr(Attr.getRange(), S.Context, 1708 Attr.getAttributeSpellingListIndex())); 1709} 1710 1711static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1712 if (!isa<FunctionDecl>(D)) { 1713 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1714 << Attr.getName() << ExpectedFunction; 1715 return; 1716 } 1717 1718 if (D->hasAttr<HotAttr>()) { 1719 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1720 << Attr.getName() << "hot"; 1721 return; 1722 } 1723 1724 D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context, 1725 Attr.getAttributeSpellingListIndex())); 1726} 1727 1728static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1729 if (!isa<FunctionDecl>(D)) { 1730 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1731 << Attr.getName() << ExpectedFunction; 1732 return; 1733 } 1734 1735 if (D->hasAttr<ColdAttr>()) { 1736 S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1737 << Attr.getName() << "cold"; 1738 return; 1739 } 1740 1741 D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context, 1742 Attr.getAttributeSpellingListIndex())); 1743} 1744 1745static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1746 if (!isa<FunctionDecl>(D)) { 1747 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1748 << Attr.getName() << ExpectedFunction; 1749 return; 1750 } 1751 1752 D->addAttr(::new (S.Context) 1753 NakedAttr(Attr.getRange(), S.Context, 1754 Attr.getAttributeSpellingListIndex())); 1755} 1756 1757static void handleAlwaysInlineAttr(Sema &S, Decl *D, 1758 const AttributeList &Attr) { 1759 if (!isa<FunctionDecl>(D)) { 1760 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1761 << Attr.getName() << ExpectedFunction; 1762 return; 1763 } 1764 1765 D->addAttr(::new (S.Context) 1766 AlwaysInlineAttr(Attr.getRange(), S.Context, 1767 Attr.getAttributeSpellingListIndex())); 1768} 1769 1770static void handleTLSModelAttr(Sema &S, Decl *D, 1771 const AttributeList &Attr) { 1772 StringRef Model; 1773 SourceLocation LiteralLoc; 1774 // Check that it is a string. 1775 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc)) 1776 return; 1777 1778 if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) { 1779 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1780 << Attr.getName() << ExpectedTLSVar; 1781 return; 1782 } 1783 1784 // Check that the value. 1785 if (Model != "global-dynamic" && Model != "local-dynamic" 1786 && Model != "initial-exec" && Model != "local-exec") { 1787 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg); 1788 return; 1789 } 1790 1791 D->addAttr(::new (S.Context) 1792 TLSModelAttr(Attr.getRange(), S.Context, Model, 1793 Attr.getAttributeSpellingListIndex())); 1794} 1795 1796static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1797 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1798 QualType RetTy = FD->getResultType(); 1799 if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1800 D->addAttr(::new (S.Context) 1801 MallocAttr(Attr.getRange(), S.Context, 1802 Attr.getAttributeSpellingListIndex())); 1803 return; 1804 } 1805 } 1806 1807 S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 1808} 1809 1810static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1811 D->addAttr(::new (S.Context) 1812 MayAliasAttr(Attr.getRange(), S.Context, 1813 Attr.getAttributeSpellingListIndex())); 1814} 1815 1816static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1817 if (isa<VarDecl>(D)) 1818 D->addAttr(::new (S.Context) 1819 NoCommonAttr(Attr.getRange(), S.Context, 1820 Attr.getAttributeSpellingListIndex())); 1821 else 1822 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1823 << Attr.getName() << ExpectedVariable; 1824} 1825 1826static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1827 if (S.LangOpts.CPlusPlus) { 1828 S.Diag(Attr.getLoc(), diag::err_common_not_supported_cplusplus); 1829 return; 1830 } 1831 1832 if (isa<VarDecl>(D)) 1833 D->addAttr(::new (S.Context) 1834 CommonAttr(Attr.getRange(), S.Context, 1835 Attr.getAttributeSpellingListIndex())); 1836 else 1837 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1838 << Attr.getName() << ExpectedVariable; 1839} 1840 1841static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 1842 if (hasDeclarator(D)) return; 1843 1844 if (S.CheckNoReturnAttr(attr)) return; 1845 1846 if (!isa<ObjCMethodDecl>(D)) { 1847 S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1848 << attr.getName() << ExpectedFunctionOrMethod; 1849 return; 1850 } 1851 1852 D->addAttr(::new (S.Context) 1853 NoReturnAttr(attr.getRange(), S.Context, 1854 attr.getAttributeSpellingListIndex())); 1855} 1856 1857bool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1858 if (!checkAttributeNumArgs(*this, attr, 0)) { 1859 attr.setInvalid(); 1860 return true; 1861 } 1862 1863 return false; 1864} 1865 1866static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 1867 const AttributeList &Attr) { 1868 1869 // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1870 // because 'analyzer_noreturn' does not impact the type. 1871 if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 1872 ValueDecl *VD = dyn_cast<ValueDecl>(D); 1873 if (VD == 0 || (!VD->getType()->isBlockPointerType() 1874 && !VD->getType()->isFunctionPointerType())) { 1875 S.Diag(Attr.getLoc(), 1876 Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type 1877 : diag::warn_attribute_wrong_decl_type) 1878 << Attr.getName() << ExpectedFunctionMethodOrBlock; 1879 return; 1880 } 1881 } 1882 1883 D->addAttr(::new (S.Context) 1884 AnalyzerNoReturnAttr(Attr.getRange(), S.Context, 1885 Attr.getAttributeSpellingListIndex())); 1886} 1887 1888static void handleCXX11NoReturnAttr(Sema &S, Decl *D, 1889 const AttributeList &Attr) { 1890 // C++11 [dcl.attr.noreturn]p1: 1891 // The attribute may be applied to the declarator-id in a function 1892 // declaration. 1893 FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 1894 if (!FD) { 1895 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1896 << Attr.getName() << ExpectedFunctionOrMethod; 1897 return; 1898 } 1899 1900 D->addAttr(::new (S.Context) 1901 CXX11NoReturnAttr(Attr.getRange(), S.Context, 1902 Attr.getAttributeSpellingListIndex())); 1903} 1904 1905// PS3 PPU-specific. 1906static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1907/* 1908 Returning a Vector Class in Registers 1909 1910 According to the PPU ABI specifications, a class with a single member of 1911 vector type is returned in memory when used as the return value of a function. 1912 This results in inefficient code when implementing vector classes. To return 1913 the value in a single vector register, add the vecreturn attribute to the 1914 class definition. This attribute is also applicable to struct types. 1915 1916 Example: 1917 1918 struct Vector 1919 { 1920 __vector float xyzw; 1921 } __attribute__((vecreturn)); 1922 1923 Vector Add(Vector lhs, Vector rhs) 1924 { 1925 Vector result; 1926 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 1927 return result; // This will be returned in a register 1928 } 1929*/ 1930 if (!isa<RecordDecl>(D)) { 1931 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1932 << Attr.getName() << ExpectedClass; 1933 return; 1934 } 1935 1936 if (D->getAttr<VecReturnAttr>()) { 1937 S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 1938 return; 1939 } 1940 1941 RecordDecl *record = cast<RecordDecl>(D); 1942 int count = 0; 1943 1944 if (!isa<CXXRecordDecl>(record)) { 1945 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 1946 return; 1947 } 1948 1949 if (!cast<CXXRecordDecl>(record)->isPOD()) { 1950 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 1951 return; 1952 } 1953 1954 for (RecordDecl::field_iterator iter = record->field_begin(); 1955 iter != record->field_end(); iter++) { 1956 if ((count == 1) || !iter->getType()->isVectorType()) { 1957 S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 1958 return; 1959 } 1960 count++; 1961 } 1962 1963 D->addAttr(::new (S.Context) 1964 VecReturnAttr(Attr.getRange(), S.Context, 1965 Attr.getAttributeSpellingListIndex())); 1966} 1967 1968static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, 1969 const AttributeList &Attr) { 1970 if (isa<ParmVarDecl>(D)) { 1971 // [[carries_dependency]] can only be applied to a parameter if it is a 1972 // parameter of a function declaration or lambda. 1973 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) { 1974 S.Diag(Attr.getLoc(), 1975 diag::err_carries_dependency_param_not_function_decl); 1976 return; 1977 } 1978 } else if (!isa<FunctionDecl>(D)) { 1979 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1980 << Attr.getName() << ExpectedFunctionMethodOrParameter; 1981 return; 1982 } 1983 1984 D->addAttr(::new (S.Context) CarriesDependencyAttr( 1985 Attr.getRange(), S.Context, 1986 Attr.getAttributeSpellingListIndex())); 1987} 1988 1989static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1990 if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 1991 !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) { 1992 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1993 << Attr.getName() << ExpectedVariableFunctionOrLabel; 1994 return; 1995 } 1996 1997 D->addAttr(::new (S.Context) 1998 UnusedAttr(Attr.getRange(), S.Context, 1999 Attr.getAttributeSpellingListIndex())); 2000} 2001 2002static void handleReturnsTwiceAttr(Sema &S, Decl *D, 2003 const AttributeList &Attr) { 2004 if (!isa<FunctionDecl>(D)) { 2005 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2006 << Attr.getName() << ExpectedFunction; 2007 return; 2008 } 2009 2010 D->addAttr(::new (S.Context) 2011 ReturnsTwiceAttr(Attr.getRange(), S.Context, 2012 Attr.getAttributeSpellingListIndex())); 2013} 2014 2015static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2016 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 2017 if (VD->hasLocalStorage()) { 2018 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 2019 return; 2020 } 2021 } else if (!isFunctionOrMethod(D)) { 2022 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2023 << Attr.getName() << ExpectedVariableOrFunction; 2024 return; 2025 } 2026 2027 D->addAttr(::new (S.Context) 2028 UsedAttr(Attr.getRange(), S.Context, 2029 Attr.getAttributeSpellingListIndex())); 2030} 2031 2032static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2033 // check the attribute arguments. 2034 if (Attr.getNumArgs() > 1) { 2035 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 2036 return; 2037 } 2038 2039 int priority = 65535; // FIXME: Do not hardcode such constants. 2040 if (Attr.getNumArgs() > 0) { 2041 Expr *E = Attr.getArgAsExpr(0); 2042 llvm::APSInt Idx(32); 2043 if (E->isTypeDependent() || E->isValueDependent() || 2044 !E->isIntegerConstantExpr(Idx, S.Context)) { 2045 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2046 << Attr.getName() << 1 << AANT_ArgumentIntegerConstant 2047 << E->getSourceRange(); 2048 return; 2049 } 2050 priority = Idx.getZExtValue(); 2051 } 2052 2053 if (!isa<FunctionDecl>(D)) { 2054 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2055 << Attr.getName() << ExpectedFunction; 2056 return; 2057 } 2058 2059 D->addAttr(::new (S.Context) 2060 ConstructorAttr(Attr.getRange(), S.Context, priority, 2061 Attr.getAttributeSpellingListIndex())); 2062} 2063 2064static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2065 // check the attribute arguments. 2066 if (Attr.getNumArgs() > 1) { 2067 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 2068 return; 2069 } 2070 2071 int priority = 65535; // FIXME: Do not hardcode such constants. 2072 if (Attr.getNumArgs() > 0) { 2073 Expr *E = Attr.getArgAsExpr(0); 2074 llvm::APSInt Idx(32); 2075 if (E->isTypeDependent() || E->isValueDependent() || 2076 !E->isIntegerConstantExpr(Idx, S.Context)) { 2077 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2078 << Attr.getName() << 1 << AANT_ArgumentIntegerConstant 2079 << E->getSourceRange(); 2080 return; 2081 } 2082 priority = Idx.getZExtValue(); 2083 } 2084 2085 if (!isa<FunctionDecl>(D)) { 2086 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2087 << Attr.getName() << ExpectedFunction; 2088 return; 2089 } 2090 2091 D->addAttr(::new (S.Context) 2092 DestructorAttr(Attr.getRange(), S.Context, priority, 2093 Attr.getAttributeSpellingListIndex())); 2094} 2095 2096template <typename AttrTy> 2097static void handleAttrWithMessage(Sema &S, Decl *D, 2098 const AttributeList &Attr) { 2099 unsigned NumArgs = Attr.getNumArgs(); 2100 if (NumArgs > 1) { 2101 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 2102 return; 2103 } 2104 2105 // Handle the case where the attribute has a text message. 2106 StringRef Str; 2107 if (NumArgs == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 2108 return; 2109 2110 D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str, 2111 Attr.getAttributeSpellingListIndex())); 2112} 2113 2114static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 2115 const AttributeList &Attr) { 2116 D->addAttr(::new (S.Context) 2117 ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context, 2118 Attr.getAttributeSpellingListIndex())); 2119} 2120 2121static void handleObjCRootClassAttr(Sema &S, Decl *D, 2122 const AttributeList &Attr) { 2123 if (!isa<ObjCInterfaceDecl>(D)) { 2124 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 2125 << Attr.getName() << ExpectedObjectiveCInterface; 2126 return; 2127 } 2128 2129 D->addAttr(::new (S.Context) 2130 ObjCRootClassAttr(Attr.getRange(), S.Context, 2131 Attr.getAttributeSpellingListIndex())); 2132} 2133 2134static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 2135 const AttributeList &Attr) { 2136 if (!isa<ObjCInterfaceDecl>(D)) { 2137 S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); 2138 return; 2139 } 2140 2141 D->addAttr(::new (S.Context) 2142 ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context, 2143 Attr.getAttributeSpellingListIndex())); 2144} 2145 2146static bool checkAvailabilityAttr(Sema &S, SourceRange Range, 2147 IdentifierInfo *Platform, 2148 VersionTuple Introduced, 2149 VersionTuple Deprecated, 2150 VersionTuple Obsoleted) { 2151 StringRef PlatformName 2152 = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 2153 if (PlatformName.empty()) 2154 PlatformName = Platform->getName(); 2155 2156 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 2157 // of these steps are needed). 2158 if (!Introduced.empty() && !Deprecated.empty() && 2159 !(Introduced <= Deprecated)) { 2160 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 2161 << 1 << PlatformName << Deprecated.getAsString() 2162 << 0 << Introduced.getAsString(); 2163 return true; 2164 } 2165 2166 if (!Introduced.empty() && !Obsoleted.empty() && 2167 !(Introduced <= Obsoleted)) { 2168 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 2169 << 2 << PlatformName << Obsoleted.getAsString() 2170 << 0 << Introduced.getAsString(); 2171 return true; 2172 } 2173 2174 if (!Deprecated.empty() && !Obsoleted.empty() && 2175 !(Deprecated <= Obsoleted)) { 2176 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 2177 << 2 << PlatformName << Obsoleted.getAsString() 2178 << 1 << Deprecated.getAsString(); 2179 return true; 2180 } 2181 2182 return false; 2183} 2184 2185/// \brief Check whether the two versions match. 2186/// 2187/// If either version tuple is empty, then they are assumed to match. If 2188/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y. 2189static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y, 2190 bool BeforeIsOkay) { 2191 if (X.empty() || Y.empty()) 2192 return true; 2193 2194 if (X == Y) 2195 return true; 2196 2197 if (BeforeIsOkay && X < Y) 2198 return true; 2199 2200 return false; 2201} 2202 2203AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, 2204 IdentifierInfo *Platform, 2205 VersionTuple Introduced, 2206 VersionTuple Deprecated, 2207 VersionTuple Obsoleted, 2208 bool IsUnavailable, 2209 StringRef Message, 2210 bool Override, 2211 unsigned AttrSpellingListIndex) { 2212 VersionTuple MergedIntroduced = Introduced; 2213 VersionTuple MergedDeprecated = Deprecated; 2214 VersionTuple MergedObsoleted = Obsoleted; 2215 bool FoundAny = false; 2216 2217 if (D->hasAttrs()) { 2218 AttrVec &Attrs = D->getAttrs(); 2219 for (unsigned i = 0, e = Attrs.size(); i != e;) { 2220 const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); 2221 if (!OldAA) { 2222 ++i; 2223 continue; 2224 } 2225 2226 IdentifierInfo *OldPlatform = OldAA->getPlatform(); 2227 if (OldPlatform != Platform) { 2228 ++i; 2229 continue; 2230 } 2231 2232 FoundAny = true; 2233 VersionTuple OldIntroduced = OldAA->getIntroduced(); 2234 VersionTuple OldDeprecated = OldAA->getDeprecated(); 2235 VersionTuple OldObsoleted = OldAA->getObsoleted(); 2236 bool OldIsUnavailable = OldAA->getUnavailable(); 2237 2238 if (!versionsMatch(OldIntroduced, Introduced, Override) || 2239 !versionsMatch(Deprecated, OldDeprecated, Override) || 2240 !versionsMatch(Obsoleted, OldObsoleted, Override) || 2241 !(OldIsUnavailable == IsUnavailable || 2242 (Override && !OldIsUnavailable && IsUnavailable))) { 2243 if (Override) { 2244 int Which = -1; 2245 VersionTuple FirstVersion; 2246 VersionTuple SecondVersion; 2247 if (!versionsMatch(OldIntroduced, Introduced, Override)) { 2248 Which = 0; 2249 FirstVersion = OldIntroduced; 2250 SecondVersion = Introduced; 2251 } else if (!versionsMatch(Deprecated, OldDeprecated, Override)) { 2252 Which = 1; 2253 FirstVersion = Deprecated; 2254 SecondVersion = OldDeprecated; 2255 } else if (!versionsMatch(Obsoleted, OldObsoleted, Override)) { 2256 Which = 2; 2257 FirstVersion = Obsoleted; 2258 SecondVersion = OldObsoleted; 2259 } 2260 2261 if (Which == -1) { 2262 Diag(OldAA->getLocation(), 2263 diag::warn_mismatched_availability_override_unavail) 2264 << AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 2265 } else { 2266 Diag(OldAA->getLocation(), 2267 diag::warn_mismatched_availability_override) 2268 << Which 2269 << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) 2270 << FirstVersion.getAsString() << SecondVersion.getAsString(); 2271 } 2272 Diag(Range.getBegin(), diag::note_overridden_method); 2273 } else { 2274 Diag(OldAA->getLocation(), diag::warn_mismatched_availability); 2275 Diag(Range.getBegin(), diag::note_previous_attribute); 2276 } 2277 2278 Attrs.erase(Attrs.begin() + i); 2279 --e; 2280 continue; 2281 } 2282 2283 VersionTuple MergedIntroduced2 = MergedIntroduced; 2284 VersionTuple MergedDeprecated2 = MergedDeprecated; 2285 VersionTuple MergedObsoleted2 = MergedObsoleted; 2286 2287 if (MergedIntroduced2.empty()) 2288 MergedIntroduced2 = OldIntroduced; 2289 if (MergedDeprecated2.empty()) 2290 MergedDeprecated2 = OldDeprecated; 2291 if (MergedObsoleted2.empty()) 2292 MergedObsoleted2 = OldObsoleted; 2293 2294 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, 2295 MergedIntroduced2, MergedDeprecated2, 2296 MergedObsoleted2)) { 2297 Attrs.erase(Attrs.begin() + i); 2298 --e; 2299 continue; 2300 } 2301 2302 MergedIntroduced = MergedIntroduced2; 2303 MergedDeprecated = MergedDeprecated2; 2304 MergedObsoleted = MergedObsoleted2; 2305 ++i; 2306 } 2307 } 2308 2309 if (FoundAny && 2310 MergedIntroduced == Introduced && 2311 MergedDeprecated == Deprecated && 2312 MergedObsoleted == Obsoleted) 2313 return NULL; 2314 2315 // Only create a new attribute if !Override, but we want to do 2316 // the checking. 2317 if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, 2318 MergedDeprecated, MergedObsoleted) && 2319 !Override) { 2320 return ::new (Context) AvailabilityAttr(Range, Context, Platform, 2321 Introduced, Deprecated, 2322 Obsoleted, IsUnavailable, Message, 2323 AttrSpellingListIndex); 2324 } 2325 return NULL; 2326} 2327 2328static void handleAvailabilityAttr(Sema &S, Decl *D, 2329 const AttributeList &Attr) { 2330 if (!checkAttributeNumArgs(S, Attr, 1)) 2331 return; 2332 IdentifierLoc *Platform = Attr.getArgAsIdent(0); 2333 unsigned Index = Attr.getAttributeSpellingListIndex(); 2334 2335 IdentifierInfo *II = Platform->Ident; 2336 if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty()) 2337 S.Diag(Platform->Loc, diag::warn_availability_unknown_platform) 2338 << Platform->Ident; 2339 2340 NamedDecl *ND = dyn_cast<NamedDecl>(D); 2341 if (!ND) { 2342 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2343 return; 2344 } 2345 2346 AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 2347 AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 2348 AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 2349 bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 2350 StringRef Str; 2351 if (const StringLiteral *SE = 2352 dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr())) 2353 Str = SE->getString(); 2354 2355 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II, 2356 Introduced.Version, 2357 Deprecated.Version, 2358 Obsoleted.Version, 2359 IsUnavailable, Str, 2360 /*Override=*/false, 2361 Index); 2362 if (NewAttr) 2363 D->addAttr(NewAttr); 2364} 2365 2366template <class T> 2367static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range, 2368 typename T::VisibilityType value, 2369 unsigned attrSpellingListIndex) { 2370 T *existingAttr = D->getAttr<T>(); 2371 if (existingAttr) { 2372 typename T::VisibilityType existingValue = existingAttr->getVisibility(); 2373 if (existingValue == value) 2374 return NULL; 2375 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility); 2376 S.Diag(range.getBegin(), diag::note_previous_attribute); 2377 D->dropAttr<T>(); 2378 } 2379 return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex); 2380} 2381 2382VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, 2383 VisibilityAttr::VisibilityType Vis, 2384 unsigned AttrSpellingListIndex) { 2385 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis, 2386 AttrSpellingListIndex); 2387} 2388 2389TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range, 2390 TypeVisibilityAttr::VisibilityType Vis, 2391 unsigned AttrSpellingListIndex) { 2392 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis, 2393 AttrSpellingListIndex); 2394} 2395 2396static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr, 2397 bool isTypeVisibility) { 2398 // Visibility attributes don't mean anything on a typedef. 2399 if (isa<TypedefNameDecl>(D)) { 2400 S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored) 2401 << Attr.getName(); 2402 return; 2403 } 2404 2405 // 'type_visibility' can only go on a type or namespace. 2406 if (isTypeVisibility && 2407 !(isa<TagDecl>(D) || 2408 isa<ObjCInterfaceDecl>(D) || 2409 isa<NamespaceDecl>(D))) { 2410 S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type) 2411 << Attr.getName() << ExpectedTypeOrNamespace; 2412 return; 2413 } 2414 2415 // Check that the argument is a string literal. 2416 StringRef TypeStr; 2417 SourceLocation LiteralLoc; 2418 if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc)) 2419 return; 2420 2421 VisibilityAttr::VisibilityType type; 2422 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) { 2423 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) 2424 << Attr.getName() << TypeStr; 2425 return; 2426 } 2427 2428 // Complain about attempts to use protected visibility on targets 2429 // (like Darwin) that don't support it. 2430 if (type == VisibilityAttr::Protected && 2431 !S.Context.getTargetInfo().hasProtectedVisibility()) { 2432 S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 2433 type = VisibilityAttr::Default; 2434 } 2435 2436 unsigned Index = Attr.getAttributeSpellingListIndex(); 2437 clang::Attr *newAttr; 2438 if (isTypeVisibility) { 2439 newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(), 2440 (TypeVisibilityAttr::VisibilityType) type, 2441 Index); 2442 } else { 2443 newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index); 2444 } 2445 if (newAttr) 2446 D->addAttr(newAttr); 2447} 2448 2449static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 2450 const AttributeList &Attr) { 2451 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 2452 if (!method) { 2453 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 2454 << ExpectedMethod; 2455 return; 2456 } 2457 2458 if (!Attr.isArgIdent(0)) { 2459 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2460 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 2461 return; 2462 } 2463 2464 IdentifierLoc *IL = Attr.getArgAsIdent(0); 2465 ObjCMethodFamilyAttr::FamilyKind F; 2466 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) { 2467 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName() 2468 << IL->Ident; 2469 return; 2470 } 2471 2472 if (F == ObjCMethodFamilyAttr::OMF_init && 2473 !method->getResultType()->isObjCObjectPointerType()) { 2474 S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 2475 << method->getResultType(); 2476 // Ignore the attribute. 2477 return; 2478 } 2479 2480 method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 2481 S.Context, F)); 2482} 2483 2484static void handleObjCExceptionAttr(Sema &S, Decl *D, 2485 const AttributeList &Attr) { 2486 ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 2487 if (OCI == 0) { 2488 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 2489 << Attr.getName() << ExpectedObjectiveCInterface; 2490 return; 2491 } 2492 2493 D->addAttr(::new (S.Context) 2494 ObjCExceptionAttr(Attr.getRange(), S.Context, 2495 Attr.getAttributeSpellingListIndex())); 2496} 2497 2498static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 2499 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2500 QualType T = TD->getUnderlyingType(); 2501 if (!T->isCARCBridgableType()) { 2502 S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 2503 return; 2504 } 2505 } 2506 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 2507 QualType T = PD->getType(); 2508 if (!T->isCARCBridgableType()) { 2509 S.Diag(PD->getLocation(), diag::err_nsobject_attribute); 2510 return; 2511 } 2512 } 2513 else { 2514 // It is okay to include this attribute on properties, e.g.: 2515 // 2516 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 2517 // 2518 // In this case it follows tradition and suppresses an error in the above 2519 // case. 2520 S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 2521 } 2522 D->addAttr(::new (S.Context) 2523 ObjCNSObjectAttr(Attr.getRange(), S.Context, 2524 Attr.getAttributeSpellingListIndex())); 2525} 2526 2527static void 2528handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2529 if (!isa<FunctionDecl>(D)) { 2530 S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 2531 return; 2532 } 2533 2534 D->addAttr(::new (S.Context) 2535 OverloadableAttr(Attr.getRange(), S.Context, 2536 Attr.getAttributeSpellingListIndex())); 2537} 2538 2539static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2540 if (!Attr.isArgIdent(0)) { 2541 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2542 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 2543 return; 2544 } 2545 2546 IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; 2547 BlocksAttr::BlockType type; 2548 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) { 2549 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 2550 << Attr.getName() << II; 2551 return; 2552 } 2553 2554 D->addAttr(::new (S.Context) 2555 BlocksAttr(Attr.getRange(), S.Context, type, 2556 Attr.getAttributeSpellingListIndex())); 2557} 2558 2559static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2560 // check the attribute arguments. 2561 if (Attr.getNumArgs() > 2) { 2562 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 2563 return; 2564 } 2565 2566 unsigned sentinel = 0; 2567 if (Attr.getNumArgs() > 0) { 2568 Expr *E = Attr.getArgAsExpr(0); 2569 llvm::APSInt Idx(32); 2570 if (E->isTypeDependent() || E->isValueDependent() || 2571 !E->isIntegerConstantExpr(Idx, S.Context)) { 2572 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2573 << Attr.getName() << 1 << AANT_ArgumentIntegerConstant 2574 << E->getSourceRange(); 2575 return; 2576 } 2577 2578 if (Idx.isSigned() && Idx.isNegative()) { 2579 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 2580 << E->getSourceRange(); 2581 return; 2582 } 2583 2584 sentinel = Idx.getZExtValue(); 2585 } 2586 2587 unsigned nullPos = 0; 2588 if (Attr.getNumArgs() > 1) { 2589 Expr *E = Attr.getArgAsExpr(1); 2590 llvm::APSInt Idx(32); 2591 if (E->isTypeDependent() || E->isValueDependent() || 2592 !E->isIntegerConstantExpr(Idx, S.Context)) { 2593 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2594 << Attr.getName() << 2 << AANT_ArgumentIntegerConstant 2595 << E->getSourceRange(); 2596 return; 2597 } 2598 nullPos = Idx.getZExtValue(); 2599 2600 if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 2601 // FIXME: This error message could be improved, it would be nice 2602 // to say what the bounds actually are. 2603 S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 2604 << E->getSourceRange(); 2605 return; 2606 } 2607 } 2608 2609 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 2610 const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 2611 if (isa<FunctionNoProtoType>(FT)) { 2612 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 2613 return; 2614 } 2615 2616 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 2617 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2618 return; 2619 } 2620 } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 2621 if (!MD->isVariadic()) { 2622 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2623 return; 2624 } 2625 } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 2626 if (!BD->isVariadic()) { 2627 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 2628 return; 2629 } 2630 } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 2631 QualType Ty = V->getType(); 2632 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 2633 const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 2634 : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 2635 if (!cast<FunctionProtoType>(FT)->isVariadic()) { 2636 int m = Ty->isFunctionPointerType() ? 0 : 1; 2637 S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 2638 return; 2639 } 2640 } else { 2641 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2642 << Attr.getName() << ExpectedFunctionMethodOrBlock; 2643 return; 2644 } 2645 } else { 2646 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2647 << Attr.getName() << ExpectedFunctionMethodOrBlock; 2648 return; 2649 } 2650 D->addAttr(::new (S.Context) 2651 SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos, 2652 Attr.getAttributeSpellingListIndex())); 2653} 2654 2655static void handleWarnUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2656 if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) 2657 RD->addAttr(::new (S.Context) WarnUnusedAttr(Attr.getRange(), S.Context)); 2658 else 2659 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2660} 2661 2662static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 2663 if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) { 2664 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2665 << Attr.getName() << ExpectedFunctionMethodOrClass; 2666 return; 2667 } 2668 2669 if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 2670 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2671 << Attr.getName() << 0; 2672 return; 2673 } 2674 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 2675 if (MD->getResultType()->isVoidType()) { 2676 S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2677 << Attr.getName() << 1; 2678 return; 2679 } 2680 2681 D->addAttr(::new (S.Context) 2682 WarnUnusedResultAttr(Attr.getRange(), S.Context, 2683 Attr.getAttributeSpellingListIndex())); 2684} 2685 2686static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2687 if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 2688 if (isa<CXXRecordDecl>(D)) { 2689 D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 2690 return; 2691 } 2692 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2693 << Attr.getName() << ExpectedVariableOrFunction; 2694 return; 2695 } 2696 2697 NamedDecl *nd = cast<NamedDecl>(D); 2698 2699 nd->addAttr(::new (S.Context) 2700 WeakAttr(Attr.getRange(), S.Context, 2701 Attr.getAttributeSpellingListIndex())); 2702} 2703 2704static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2705 // weak_import only applies to variable & function declarations. 2706 bool isDef = false; 2707 if (!D->canBeWeakImported(isDef)) { 2708 if (isDef) 2709 S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition) 2710 << "weak_import"; 2711 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 2712 (S.Context.getTargetInfo().getTriple().isOSDarwin() && 2713 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 2714 // Nothing to warn about here. 2715 } else 2716 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2717 << Attr.getName() << ExpectedVariableOrFunction; 2718 2719 return; 2720 } 2721 2722 D->addAttr(::new (S.Context) 2723 WeakImportAttr(Attr.getRange(), S.Context, 2724 Attr.getAttributeSpellingListIndex())); 2725} 2726 2727// Handles reqd_work_group_size and work_group_size_hint. 2728static void handleWorkGroupSize(Sema &S, Decl *D, 2729 const AttributeList &Attr) { 2730 unsigned WGSize[3]; 2731 for (unsigned i = 0; i < 3; ++i) { 2732 Expr *E = Attr.getArgAsExpr(i); 2733 llvm::APSInt ArgNum(32); 2734 if (E->isTypeDependent() || E->isValueDependent() || 2735 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 2736 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 2737 << Attr.getName() << AANT_ArgumentIntegerConstant 2738 << E->getSourceRange(); 2739 return; 2740 } 2741 WGSize[i] = (unsigned) ArgNum.getZExtValue(); 2742 } 2743 2744 if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize 2745 && D->hasAttr<ReqdWorkGroupSizeAttr>()) { 2746 ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>(); 2747 if (!(A->getXDim() == WGSize[0] && 2748 A->getYDim() == WGSize[1] && 2749 A->getZDim() == WGSize[2])) { 2750 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << 2751 Attr.getName(); 2752 } 2753 } 2754 2755 if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint 2756 && D->hasAttr<WorkGroupSizeHintAttr>()) { 2757 WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>(); 2758 if (!(A->getXDim() == WGSize[0] && 2759 A->getYDim() == WGSize[1] && 2760 A->getZDim() == WGSize[2])) { 2761 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << 2762 Attr.getName(); 2763 } 2764 } 2765 2766 if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize) 2767 D->addAttr(::new (S.Context) 2768 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 2769 WGSize[0], WGSize[1], WGSize[2], 2770 Attr.getAttributeSpellingListIndex())); 2771 else 2772 D->addAttr(::new (S.Context) 2773 WorkGroupSizeHintAttr(Attr.getRange(), S.Context, 2774 WGSize[0], WGSize[1], WGSize[2], 2775 Attr.getAttributeSpellingListIndex())); 2776} 2777 2778static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { 2779 assert(Attr.getKind() == AttributeList::AT_VecTypeHint); 2780 2781 if (!Attr.hasParsedType()) { 2782 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 2783 << Attr.getName() << 1; 2784 return; 2785 } 2786 2787 TypeSourceInfo *ParmTSI = 0; 2788 QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI); 2789 assert(ParmTSI && "no type source info for attribute argument"); 2790 2791 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() && 2792 (ParmType->isBooleanType() || 2793 !ParmType->isIntegralType(S.getASTContext()))) { 2794 S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint) 2795 << ParmType; 2796 return; 2797 } 2798 2799 if (Attr.getKind() == AttributeList::AT_VecTypeHint && 2800 D->hasAttr<VecTypeHintAttr>()) { 2801 VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>(); 2802 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) { 2803 S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName(); 2804 return; 2805 } 2806 } 2807 2808 D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context, 2809 ParmTSI)); 2810} 2811 2812SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, 2813 StringRef Name, 2814 unsigned AttrSpellingListIndex) { 2815 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { 2816 if (ExistingAttr->getName() == Name) 2817 return NULL; 2818 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); 2819 Diag(Range.getBegin(), diag::note_previous_attribute); 2820 return NULL; 2821 } 2822 return ::new (Context) SectionAttr(Range, Context, Name, 2823 AttrSpellingListIndex); 2824} 2825 2826static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2827 // Make sure that there is a string literal as the sections's single 2828 // argument. 2829 StringRef Str; 2830 SourceLocation LiteralLoc; 2831 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc)) 2832 return; 2833 2834 // If the target wants to validate the section specifier, make it happen. 2835 std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str); 2836 if (!Error.empty()) { 2837 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) 2838 << Error; 2839 return; 2840 } 2841 2842 // This attribute cannot be applied to local variables. 2843 if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2844 S.Diag(LiteralLoc, diag::err_attribute_section_local_variable); 2845 return; 2846 } 2847 2848 unsigned Index = Attr.getAttributeSpellingListIndex(); 2849 SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index); 2850 if (NewAttr) 2851 D->addAttr(NewAttr); 2852} 2853 2854 2855static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2856 if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2857 if (Existing->getLocation().isInvalid()) 2858 Existing->setRange(Attr.getRange()); 2859 } else { 2860 D->addAttr(::new (S.Context) 2861 NoThrowAttr(Attr.getRange(), S.Context, 2862 Attr.getAttributeSpellingListIndex())); 2863 } 2864} 2865 2866static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2867 if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2868 if (Existing->getLocation().isInvalid()) 2869 Existing->setRange(Attr.getRange()); 2870 } else { 2871 D->addAttr(::new (S.Context) 2872 ConstAttr(Attr.getRange(), S.Context, 2873 Attr.getAttributeSpellingListIndex() )); 2874 } 2875} 2876 2877static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2878 D->addAttr(::new (S.Context) 2879 PureAttr(Attr.getRange(), S.Context, 2880 Attr.getAttributeSpellingListIndex())); 2881} 2882 2883static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2884 VarDecl *VD = dyn_cast<VarDecl>(D); 2885 if (!VD || !VD->hasLocalStorage()) { 2886 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2887 return; 2888 } 2889 2890 Expr *E = Attr.getArgAsExpr(0); 2891 SourceLocation Loc = E->getExprLoc(); 2892 FunctionDecl *FD = 0; 2893 DeclarationNameInfo NI; 2894 2895 // gcc only allows for simple identifiers. Since we support more than gcc, we 2896 // will warn the user. 2897 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 2898 if (DRE->hasQualifier()) 2899 S.Diag(Loc, diag::warn_cleanup_ext); 2900 FD = dyn_cast<FunctionDecl>(DRE->getDecl()); 2901 NI = DRE->getNameInfo(); 2902 if (!FD) { 2903 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1 2904 << NI.getName(); 2905 return; 2906 } 2907 } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { 2908 if (ULE->hasExplicitTemplateArgs()) 2909 S.Diag(Loc, diag::warn_cleanup_ext); 2910 FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true); 2911 NI = ULE->getNameInfo(); 2912 if (!FD) { 2913 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2 2914 << NI.getName(); 2915 if (ULE->getType() == S.Context.OverloadTy) 2916 S.NoteAllOverloadCandidates(ULE); 2917 return; 2918 } 2919 } else { 2920 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0; 2921 return; 2922 } 2923 2924 if (FD->getNumParams() != 1) { 2925 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg) 2926 << NI.getName(); 2927 return; 2928 } 2929 2930 // We're currently more strict than GCC about what function types we accept. 2931 // If this ever proves to be a problem it should be easy to fix. 2932 QualType Ty = S.Context.getPointerType(VD->getType()); 2933 QualType ParamTy = FD->getParamDecl(0)->getType(); 2934 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2935 ParamTy, Ty) != Sema::Compatible) { 2936 S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) 2937 << NI.getName() << ParamTy << Ty; 2938 return; 2939 } 2940 2941 D->addAttr(::new (S.Context) 2942 CleanupAttr(Attr.getRange(), S.Context, FD, 2943 Attr.getAttributeSpellingListIndex())); 2944} 2945 2946/// Handle __attribute__((format_arg((idx)))) attribute based on 2947/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 2948static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2949 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 2950 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2951 << Attr.getName() << ExpectedFunction; 2952 return; 2953 } 2954 2955 Expr *IdxExpr = Attr.getArgAsExpr(0); 2956 uint64_t ArgIdx; 2957 if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(), 2958 Attr.getLoc(), 1, IdxExpr, ArgIdx)) 2959 return; 2960 2961 // make sure the format string is really a string 2962 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2963 2964 bool not_nsstring_type = !isNSStringType(Ty, S.Context); 2965 if (not_nsstring_type && 2966 !isCFStringType(Ty, S.Context) && 2967 (!Ty->isPointerType() || 2968 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 2969 // FIXME: Should highlight the actual expression that has the wrong type. 2970 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2971 << (not_nsstring_type ? "a string type" : "an NSString") 2972 << IdxExpr->getSourceRange(); 2973 return; 2974 } 2975 Ty = getFunctionOrMethodResultType(D); 2976 if (!isNSStringType(Ty, S.Context) && 2977 !isCFStringType(Ty, S.Context) && 2978 (!Ty->isPointerType() || 2979 !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 2980 // FIXME: Should highlight the actual expression that has the wrong type. 2981 S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2982 << (not_nsstring_type ? "string type" : "NSString") 2983 << IdxExpr->getSourceRange(); 2984 return; 2985 } 2986 2987 // We cannot use the ArgIdx returned from checkFunctionOrMethodArgumentIndex 2988 // because that has corrected for the implicit this parameter, and is zero- 2989 // based. The attribute expects what the user wrote explicitly. 2990 llvm::APSInt Val; 2991 IdxExpr->EvaluateAsInt(Val, S.Context); 2992 2993 D->addAttr(::new (S.Context) 2994 FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(), 2995 Attr.getAttributeSpellingListIndex())); 2996} 2997 2998enum FormatAttrKind { 2999 CFStringFormat, 3000 NSStringFormat, 3001 StrftimeFormat, 3002 SupportedFormat, 3003 IgnoredFormat, 3004 InvalidFormat 3005}; 3006 3007/// getFormatAttrKind - Map from format attribute names to supported format 3008/// types. 3009static FormatAttrKind getFormatAttrKind(StringRef Format) { 3010 return llvm::StringSwitch<FormatAttrKind>(Format) 3011 // Check for formats that get handled specially. 3012 .Case("NSString", NSStringFormat) 3013 .Case("CFString", CFStringFormat) 3014 .Case("strftime", StrftimeFormat) 3015 3016 // Otherwise, check for supported formats. 3017 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) 3018 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) 3019 .Case("kprintf", SupportedFormat) // OpenBSD. 3020 3021 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) 3022 .Default(InvalidFormat); 3023} 3024 3025/// Handle __attribute__((init_priority(priority))) attributes based on 3026/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 3027static void handleInitPriorityAttr(Sema &S, Decl *D, 3028 const AttributeList &Attr) { 3029 if (!S.getLangOpts().CPlusPlus) { 3030 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 3031 return; 3032 } 3033 3034 if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 3035 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 3036 Attr.setInvalid(); 3037 return; 3038 } 3039 QualType T = dyn_cast<VarDecl>(D)->getType(); 3040 if (S.Context.getAsArrayType(T)) 3041 T = S.Context.getBaseElementType(T); 3042 if (!T->getAs<RecordType>()) { 3043 S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 3044 Attr.setInvalid(); 3045 return; 3046 } 3047 3048 Expr *priorityExpr = Attr.getArgAsExpr(0); 3049 3050 llvm::APSInt priority(32); 3051 if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 3052 !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 3053 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 3054 << Attr.getName() << AANT_ArgumentIntegerConstant 3055 << priorityExpr->getSourceRange(); 3056 Attr.setInvalid(); 3057 return; 3058 } 3059 unsigned prioritynum = priority.getZExtValue(); 3060 if (prioritynum < 101 || prioritynum > 65535) { 3061 S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 3062 << priorityExpr->getSourceRange(); 3063 Attr.setInvalid(); 3064 return; 3065 } 3066 D->addAttr(::new (S.Context) 3067 InitPriorityAttr(Attr.getRange(), S.Context, prioritynum, 3068 Attr.getAttributeSpellingListIndex())); 3069} 3070 3071FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, 3072 IdentifierInfo *Format, int FormatIdx, 3073 int FirstArg, 3074 unsigned AttrSpellingListIndex) { 3075 // Check whether we already have an equivalent format attribute. 3076 for (specific_attr_iterator<FormatAttr> 3077 i = D->specific_attr_begin<FormatAttr>(), 3078 e = D->specific_attr_end<FormatAttr>(); 3079 i != e ; ++i) { 3080 FormatAttr *f = *i; 3081 if (f->getType() == Format && 3082 f->getFormatIdx() == FormatIdx && 3083 f->getFirstArg() == FirstArg) { 3084 // If we don't have a valid location for this attribute, adopt the 3085 // location. 3086 if (f->getLocation().isInvalid()) 3087 f->setRange(Range); 3088 return NULL; 3089 } 3090 } 3091 3092 return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, 3093 FirstArg, AttrSpellingListIndex); 3094} 3095 3096/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 3097/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 3098static void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3099 if (!Attr.isArgIdent(0)) { 3100 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 3101 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 3102 return; 3103 } 3104 3105 if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 3106 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3107 << Attr.getName() << ExpectedFunction; 3108 return; 3109 } 3110 3111 // In C++ the implicit 'this' function parameter also counts, and they are 3112 // counted from one. 3113 bool HasImplicitThisParam = isInstanceMethod(D); 3114 unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 3115 unsigned FirstIdx = 1; 3116 3117 IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; 3118 StringRef Format = II->getName(); 3119 3120 // Normalize the argument, __foo__ becomes foo. 3121 if (Format.startswith("__") && Format.endswith("__")) { 3122 Format = Format.substr(2, Format.size() - 4); 3123 // If we've modified the string name, we need a new identifier for it. 3124 II = &S.Context.Idents.get(Format); 3125 } 3126 3127 // Check for supported formats. 3128 FormatAttrKind Kind = getFormatAttrKind(Format); 3129 3130 if (Kind == IgnoredFormat) 3131 return; 3132 3133 if (Kind == InvalidFormat) { 3134 S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 3135 << "format" << II->getName(); 3136 return; 3137 } 3138 3139 // checks for the 2nd argument 3140 Expr *IdxExpr = Attr.getArgAsExpr(1); 3141 llvm::APSInt Idx(32); 3142 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 3143 !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 3144 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 3145 << Attr.getName() << 2 << AANT_ArgumentIntegerConstant 3146 << IdxExpr->getSourceRange(); 3147 return; 3148 } 3149 3150 if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 3151 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 3152 << "format" << 2 << IdxExpr->getSourceRange(); 3153 return; 3154 } 3155 3156 // FIXME: Do we need to bounds check? 3157 unsigned ArgIdx = Idx.getZExtValue() - 1; 3158 3159 if (HasImplicitThisParam) { 3160 if (ArgIdx == 0) { 3161 S.Diag(Attr.getLoc(), 3162 diag::err_format_attribute_implicit_this_format_string) 3163 << IdxExpr->getSourceRange(); 3164 return; 3165 } 3166 ArgIdx--; 3167 } 3168 3169 // make sure the format string is really a string 3170 QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 3171 3172 if (Kind == CFStringFormat) { 3173 if (!isCFStringType(Ty, S.Context)) { 3174 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 3175 << "a CFString" << IdxExpr->getSourceRange(); 3176 return; 3177 } 3178 } else if (Kind == NSStringFormat) { 3179 // FIXME: do we need to check if the type is NSString*? What are the 3180 // semantics? 3181 if (!isNSStringType(Ty, S.Context)) { 3182 // FIXME: Should highlight the actual expression that has the wrong type. 3183 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 3184 << "an NSString" << IdxExpr->getSourceRange(); 3185 return; 3186 } 3187 } else if (!Ty->isPointerType() || 3188 !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 3189 // FIXME: Should highlight the actual expression that has the wrong type. 3190 S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 3191 << "a string type" << IdxExpr->getSourceRange(); 3192 return; 3193 } 3194 3195 // check the 3rd argument 3196 Expr *FirstArgExpr = Attr.getArgAsExpr(2); 3197 llvm::APSInt FirstArg(32); 3198 if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 3199 !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 3200 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 3201 << Attr.getName() << 3 << AANT_ArgumentIntegerConstant 3202 << FirstArgExpr->getSourceRange(); 3203 return; 3204 } 3205 3206 // check if the function is variadic if the 3rd argument non-zero 3207 if (FirstArg != 0) { 3208 if (isFunctionOrMethodVariadic(D)) { 3209 ++NumArgs; // +1 for ... 3210 } else { 3211 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 3212 return; 3213 } 3214 } 3215 3216 // strftime requires FirstArg to be 0 because it doesn't read from any 3217 // variable the input is just the current time + the format string. 3218 if (Kind == StrftimeFormat) { 3219 if (FirstArg != 0) { 3220 S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 3221 << FirstArgExpr->getSourceRange(); 3222 return; 3223 } 3224 // if 0 it disables parameter checking (to use with e.g. va_list) 3225 } else if (FirstArg != 0 && FirstArg != NumArgs) { 3226 S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 3227 << "format" << 3 << FirstArgExpr->getSourceRange(); 3228 return; 3229 } 3230 3231 FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II, 3232 Idx.getZExtValue(), 3233 FirstArg.getZExtValue(), 3234 Attr.getAttributeSpellingListIndex()); 3235 if (NewAttr) 3236 D->addAttr(NewAttr); 3237} 3238 3239static void handleTransparentUnionAttr(Sema &S, Decl *D, 3240 const AttributeList &Attr) { 3241 // Try to find the underlying union declaration. 3242 RecordDecl *RD = 0; 3243 TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 3244 if (TD && TD->getUnderlyingType()->isUnionType()) 3245 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 3246 else 3247 RD = dyn_cast<RecordDecl>(D); 3248 3249 if (!RD || !RD->isUnion()) { 3250 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3251 << Attr.getName() << ExpectedUnion; 3252 return; 3253 } 3254 3255 if (!RD->isCompleteDefinition()) { 3256 S.Diag(Attr.getLoc(), 3257 diag::warn_transparent_union_attribute_not_definition); 3258 return; 3259 } 3260 3261 RecordDecl::field_iterator Field = RD->field_begin(), 3262 FieldEnd = RD->field_end(); 3263 if (Field == FieldEnd) { 3264 S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 3265 return; 3266 } 3267 3268 FieldDecl *FirstField = *Field; 3269 QualType FirstType = FirstField->getType(); 3270 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 3271 S.Diag(FirstField->getLocation(), 3272 diag::warn_transparent_union_attribute_floating) 3273 << FirstType->isVectorType() << FirstType; 3274 return; 3275 } 3276 3277 uint64_t FirstSize = S.Context.getTypeSize(FirstType); 3278 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 3279 for (; Field != FieldEnd; ++Field) { 3280 QualType FieldType = Field->getType(); 3281 if (S.Context.getTypeSize(FieldType) != FirstSize || 3282 S.Context.getTypeAlign(FieldType) != FirstAlign) { 3283 // Warn if we drop the attribute. 3284 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 3285 unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 3286 : S.Context.getTypeAlign(FieldType); 3287 S.Diag(Field->getLocation(), 3288 diag::warn_transparent_union_attribute_field_size_align) 3289 << isSize << Field->getDeclName() << FieldBits; 3290 unsigned FirstBits = isSize? FirstSize : FirstAlign; 3291 S.Diag(FirstField->getLocation(), 3292 diag::note_transparent_union_first_field_size_align) 3293 << isSize << FirstBits; 3294 return; 3295 } 3296 } 3297 3298 RD->addAttr(::new (S.Context) 3299 TransparentUnionAttr(Attr.getRange(), S.Context, 3300 Attr.getAttributeSpellingListIndex())); 3301} 3302 3303static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3304 // Make sure that there is a string literal as the annotation's single 3305 // argument. 3306 StringRef Str; 3307 if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 3308 return; 3309 3310 // Don't duplicate annotations that are already set. 3311 for (specific_attr_iterator<AnnotateAttr> 3312 i = D->specific_attr_begin<AnnotateAttr>(), 3313 e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 3314 if ((*i)->getAnnotation() == Str) 3315 return; 3316 } 3317 3318 D->addAttr(::new (S.Context) 3319 AnnotateAttr(Attr.getRange(), S.Context, Str, 3320 Attr.getAttributeSpellingListIndex())); 3321} 3322 3323static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3324 // check the attribute arguments. 3325 if (Attr.getNumArgs() > 1) { 3326 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 3327 << Attr.getName() << 1; 3328 return; 3329 } 3330 3331 if (Attr.getNumArgs() == 0) { 3332 D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, 3333 true, 0, Attr.getAttributeSpellingListIndex())); 3334 return; 3335 } 3336 3337 Expr *E = Attr.getArgAsExpr(0); 3338 if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) { 3339 S.Diag(Attr.getEllipsisLoc(), 3340 diag::err_pack_expansion_without_parameter_packs); 3341 return; 3342 } 3343 3344 if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E)) 3345 return; 3346 3347 S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(), 3348 Attr.isPackExpansion()); 3349} 3350 3351void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 3352 unsigned SpellingListIndex, bool IsPackExpansion) { 3353 AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex); 3354 SourceLocation AttrLoc = AttrRange.getBegin(); 3355 3356 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements. 3357 if (TmpAttr.isAlignas()) { 3358 // C++11 [dcl.align]p1: 3359 // An alignment-specifier may be applied to a variable or to a class 3360 // data member, but it shall not be applied to a bit-field, a function 3361 // parameter, the formal parameter of a catch clause, or a variable 3362 // declared with the register storage class specifier. An 3363 // alignment-specifier may also be applied to the declaration of a class 3364 // or enumeration type. 3365 // C11 6.7.5/2: 3366 // An alignment attribute shall not be specified in a declaration of 3367 // a typedef, or a bit-field, or a function, or a parameter, or an 3368 // object declared with the register storage-class specifier. 3369 int DiagKind = -1; 3370 if (isa<ParmVarDecl>(D)) { 3371 DiagKind = 0; 3372 } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3373 if (VD->getStorageClass() == SC_Register) 3374 DiagKind = 1; 3375 if (VD->isExceptionVariable()) 3376 DiagKind = 2; 3377 } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 3378 if (FD->isBitField()) 3379 DiagKind = 3; 3380 } else if (!isa<TagDecl>(D)) { 3381 Diag(AttrLoc, diag::err_attribute_wrong_decl_type) 3382 << (TmpAttr.isC11() ? "'_Alignas'" : "'alignas'") 3383 << (TmpAttr.isC11() ? ExpectedVariableOrField 3384 : ExpectedVariableFieldOrTag); 3385 return; 3386 } 3387 if (DiagKind != -1) { 3388 Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type) 3389 << TmpAttr.isC11() << DiagKind; 3390 return; 3391 } 3392 } 3393 3394 if (E->isTypeDependent() || E->isValueDependent()) { 3395 // Save dependent expressions in the AST to be instantiated. 3396 AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr); 3397 AA->setPackExpansion(IsPackExpansion); 3398 D->addAttr(AA); 3399 return; 3400 } 3401 3402 // FIXME: Cache the number on the Attr object? 3403 llvm::APSInt Alignment(32); 3404 ExprResult ICE 3405 = VerifyIntegerConstantExpression(E, &Alignment, 3406 diag::err_aligned_attribute_argument_not_int, 3407 /*AllowFold*/ false); 3408 if (ICE.isInvalid()) 3409 return; 3410 3411 // C++11 [dcl.align]p2: 3412 // -- if the constant expression evaluates to zero, the alignment 3413 // specifier shall have no effect 3414 // C11 6.7.5p6: 3415 // An alignment specification of zero has no effect. 3416 if (!(TmpAttr.isAlignas() && !Alignment) && 3417 !llvm::isPowerOf2_64(Alignment.getZExtValue())) { 3418 Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 3419 << E->getSourceRange(); 3420 return; 3421 } 3422 3423 if (TmpAttr.isDeclspec()) { 3424 // We've already verified it's a power of 2, now let's make sure it's 3425 // 8192 or less. 3426 if (Alignment.getZExtValue() > 8192) { 3427 Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192) 3428 << E->getSourceRange(); 3429 return; 3430 } 3431 } 3432 3433 AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true, 3434 ICE.take(), SpellingListIndex); 3435 AA->setPackExpansion(IsPackExpansion); 3436 D->addAttr(AA); 3437} 3438 3439void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, 3440 unsigned SpellingListIndex, bool IsPackExpansion) { 3441 // FIXME: Cache the number on the Attr object if non-dependent? 3442 // FIXME: Perform checking of type validity 3443 AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS, 3444 SpellingListIndex); 3445 AA->setPackExpansion(IsPackExpansion); 3446 D->addAttr(AA); 3447} 3448 3449void Sema::CheckAlignasUnderalignment(Decl *D) { 3450 assert(D->hasAttrs() && "no attributes on decl"); 3451 3452 QualType Ty; 3453 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 3454 Ty = VD->getType(); 3455 else 3456 Ty = Context.getTagDeclType(cast<TagDecl>(D)); 3457 if (Ty->isDependentType() || Ty->isIncompleteType()) 3458 return; 3459 3460 // C++11 [dcl.align]p5, C11 6.7.5/4: 3461 // The combined effect of all alignment attributes in a declaration shall 3462 // not specify an alignment that is less strict than the alignment that 3463 // would otherwise be required for the entity being declared. 3464 AlignedAttr *AlignasAttr = 0; 3465 unsigned Align = 0; 3466 for (specific_attr_iterator<AlignedAttr> 3467 I = D->specific_attr_begin<AlignedAttr>(), 3468 E = D->specific_attr_end<AlignedAttr>(); I != E; ++I) { 3469 if (I->isAlignmentDependent()) 3470 return; 3471 if (I->isAlignas()) 3472 AlignasAttr = *I; 3473 Align = std::max(Align, I->getAlignment(Context)); 3474 } 3475 3476 if (AlignasAttr && Align) { 3477 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align); 3478 CharUnits NaturalAlign = Context.getTypeAlignInChars(Ty); 3479 if (NaturalAlign > RequestedAlign) 3480 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned) 3481 << Ty << (unsigned)NaturalAlign.getQuantity(); 3482 } 3483} 3484 3485/// handleModeAttr - This attribute modifies the width of a decl with primitive 3486/// type. 3487/// 3488/// Despite what would be logical, the mode attribute is a decl attribute, not a 3489/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 3490/// HImode, not an intermediate pointer. 3491static void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3492 // This attribute isn't documented, but glibc uses it. It changes 3493 // the width of an int or unsigned int to the specified size. 3494 if (!Attr.isArgIdent(0)) { 3495 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() 3496 << AANT_ArgumentIdentifier; 3497 return; 3498 } 3499 3500 IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident; 3501 StringRef Str = Name->getName(); 3502 3503 // Normalize the attribute name, __foo__ becomes foo. 3504 if (Str.startswith("__") && Str.endswith("__")) 3505 Str = Str.substr(2, Str.size() - 4); 3506 3507 unsigned DestWidth = 0; 3508 bool IntegerMode = true; 3509 bool ComplexMode = false; 3510 switch (Str.size()) { 3511 case 2: 3512 switch (Str[0]) { 3513 case 'Q': DestWidth = 8; break; 3514 case 'H': DestWidth = 16; break; 3515 case 'S': DestWidth = 32; break; 3516 case 'D': DestWidth = 64; break; 3517 case 'X': DestWidth = 96; break; 3518 case 'T': DestWidth = 128; break; 3519 } 3520 if (Str[1] == 'F') { 3521 IntegerMode = false; 3522 } else if (Str[1] == 'C') { 3523 IntegerMode = false; 3524 ComplexMode = true; 3525 } else if (Str[1] != 'I') { 3526 DestWidth = 0; 3527 } 3528 break; 3529 case 4: 3530 // FIXME: glibc uses 'word' to define register_t; this is narrower than a 3531 // pointer on PIC16 and other embedded platforms. 3532 if (Str == "word") 3533 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3534 else if (Str == "byte") 3535 DestWidth = S.Context.getTargetInfo().getCharWidth(); 3536 break; 3537 case 7: 3538 if (Str == "pointer") 3539 DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3540 break; 3541 case 11: 3542 if (Str == "unwind_word") 3543 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth(); 3544 break; 3545 } 3546 3547 QualType OldTy; 3548 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3549 OldTy = TD->getUnderlyingType(); 3550 else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 3551 OldTy = VD->getType(); 3552 else { 3553 S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 3554 << "mode" << Attr.getRange(); 3555 return; 3556 } 3557 3558 if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 3559 S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 3560 else if (IntegerMode) { 3561 if (!OldTy->isIntegralOrEnumerationType()) 3562 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3563 } else if (ComplexMode) { 3564 if (!OldTy->isComplexType()) 3565 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3566 } else { 3567 if (!OldTy->isFloatingType()) 3568 S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3569 } 3570 3571 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 3572 // and friends, at least with glibc. 3573 // FIXME: Make sure floating-point mappings are accurate 3574 // FIXME: Support XF and TF types 3575 if (!DestWidth) { 3576 S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 3577 return; 3578 } 3579 3580 QualType NewTy; 3581 3582 if (IntegerMode) 3583 NewTy = S.Context.getIntTypeForBitwidth(DestWidth, 3584 OldTy->isSignedIntegerType()); 3585 else 3586 NewTy = S.Context.getRealTypeForBitwidth(DestWidth); 3587 3588 if (NewTy.isNull()) { 3589 S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 3590 return; 3591 } 3592 3593 if (ComplexMode) { 3594 NewTy = S.Context.getComplexType(NewTy); 3595 } 3596 3597 // Install the new type. 3598 if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3599 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy); 3600 else 3601 cast<ValueDecl>(D)->setType(NewTy); 3602 3603 D->addAttr(::new (S.Context) 3604 ModeAttr(Attr.getRange(), S.Context, Name, 3605 Attr.getAttributeSpellingListIndex())); 3606} 3607 3608static void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3609 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 3610 if (!VD->hasGlobalStorage()) 3611 S.Diag(Attr.getLoc(), 3612 diag::warn_attribute_requires_functions_or_static_globals) 3613 << Attr.getName(); 3614 } else if (!isFunctionOrMethod(D)) { 3615 S.Diag(Attr.getLoc(), 3616 diag::warn_attribute_requires_functions_or_static_globals) 3617 << Attr.getName(); 3618 return; 3619 } 3620 3621 D->addAttr(::new (S.Context) 3622 NoDebugAttr(Attr.getRange(), S.Context, 3623 Attr.getAttributeSpellingListIndex())); 3624} 3625 3626static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3627 if (!isa<FunctionDecl>(D)) { 3628 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3629 << Attr.getName() << ExpectedFunction; 3630 return; 3631 } 3632 3633 D->addAttr(::new (S.Context) 3634 NoInlineAttr(Attr.getRange(), S.Context, 3635 Attr.getAttributeSpellingListIndex())); 3636} 3637 3638static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 3639 const AttributeList &Attr) { 3640 if (!isa<FunctionDecl>(D)) { 3641 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3642 << Attr.getName() << ExpectedFunction; 3643 return; 3644 } 3645 3646 D->addAttr(::new (S.Context) 3647 NoInstrumentFunctionAttr(Attr.getRange(), S.Context, 3648 Attr.getAttributeSpellingListIndex())); 3649} 3650 3651static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3652 if (S.LangOpts.CUDA) { 3653 if (!isa<VarDecl>(D)) { 3654 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3655 << Attr.getName() << ExpectedVariable; 3656 return; 3657 } 3658 3659 D->addAttr(::new (S.Context) 3660 CUDAConstantAttr(Attr.getRange(), S.Context, 3661 Attr.getAttributeSpellingListIndex())); 3662 } else { 3663 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 3664 } 3665} 3666 3667static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3668 if (S.LangOpts.CUDA) { 3669 // check the attribute arguments. 3670 if (Attr.getNumArgs() != 0) { 3671 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 3672 << Attr.getName() << 0; 3673 return; 3674 } 3675 3676 if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 3677 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3678 << Attr.getName() << ExpectedVariableOrFunction; 3679 return; 3680 } 3681 3682 D->addAttr(::new (S.Context) 3683 CUDADeviceAttr(Attr.getRange(), S.Context, 3684 Attr.getAttributeSpellingListIndex())); 3685 } else { 3686 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 3687 } 3688} 3689 3690static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3691 if (S.LangOpts.CUDA) { 3692 if (!isa<FunctionDecl>(D)) { 3693 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3694 << Attr.getName() << ExpectedFunction; 3695 return; 3696 } 3697 3698 FunctionDecl *FD = cast<FunctionDecl>(D); 3699 if (!FD->getResultType()->isVoidType()) { 3700 TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 3701 if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) { 3702 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 3703 << FD->getType() 3704 << FixItHint::CreateReplacement(FTL.getResultLoc().getSourceRange(), 3705 "void"); 3706 } else { 3707 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 3708 << FD->getType(); 3709 } 3710 return; 3711 } 3712 3713 D->addAttr(::new (S.Context) 3714 CUDAGlobalAttr(Attr.getRange(), S.Context, 3715 Attr.getAttributeSpellingListIndex())); 3716 } else { 3717 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 3718 } 3719} 3720 3721static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3722 if (S.LangOpts.CUDA) { 3723 if (!isa<FunctionDecl>(D)) { 3724 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3725 << Attr.getName() << ExpectedFunction; 3726 return; 3727 } 3728 3729 D->addAttr(::new (S.Context) 3730 CUDAHostAttr(Attr.getRange(), S.Context, 3731 Attr.getAttributeSpellingListIndex())); 3732 } else { 3733 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 3734 } 3735} 3736 3737static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3738 if (S.LangOpts.CUDA) { 3739 if (!isa<VarDecl>(D)) { 3740 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3741 << Attr.getName() << ExpectedVariable; 3742 return; 3743 } 3744 3745 D->addAttr(::new (S.Context) 3746 CUDASharedAttr(Attr.getRange(), S.Context, 3747 Attr.getAttributeSpellingListIndex())); 3748 } else { 3749 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 3750 } 3751} 3752 3753static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3754 FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 3755 if (Fn == 0) { 3756 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3757 << Attr.getName() << ExpectedFunction; 3758 return; 3759 } 3760 3761 if (!Fn->isInlineSpecified()) { 3762 S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 3763 return; 3764 } 3765 3766 D->addAttr(::new (S.Context) 3767 GNUInlineAttr(Attr.getRange(), S.Context, 3768 Attr.getAttributeSpellingListIndex())); 3769} 3770 3771static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3772 if (hasDeclarator(D)) return; 3773 3774 const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 3775 // Diagnostic is emitted elsewhere: here we store the (valid) Attr 3776 // in the Decl node for syntactic reasoning, e.g., pretty-printing. 3777 CallingConv CC; 3778 if (S.CheckCallingConvAttr(Attr, CC, FD)) 3779 return; 3780 3781 if (!isa<ObjCMethodDecl>(D)) { 3782 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3783 << Attr.getName() << ExpectedFunctionOrMethod; 3784 return; 3785 } 3786 3787 switch (Attr.getKind()) { 3788 case AttributeList::AT_FastCall: 3789 D->addAttr(::new (S.Context) 3790 FastCallAttr(Attr.getRange(), S.Context, 3791 Attr.getAttributeSpellingListIndex())); 3792 return; 3793 case AttributeList::AT_StdCall: 3794 D->addAttr(::new (S.Context) 3795 StdCallAttr(Attr.getRange(), S.Context, 3796 Attr.getAttributeSpellingListIndex())); 3797 return; 3798 case AttributeList::AT_ThisCall: 3799 D->addAttr(::new (S.Context) 3800 ThisCallAttr(Attr.getRange(), S.Context, 3801 Attr.getAttributeSpellingListIndex())); 3802 return; 3803 case AttributeList::AT_CDecl: 3804 D->addAttr(::new (S.Context) 3805 CDeclAttr(Attr.getRange(), S.Context, 3806 Attr.getAttributeSpellingListIndex())); 3807 return; 3808 case AttributeList::AT_Pascal: 3809 D->addAttr(::new (S.Context) 3810 PascalAttr(Attr.getRange(), S.Context, 3811 Attr.getAttributeSpellingListIndex())); 3812 return; 3813 case AttributeList::AT_MSABI: 3814 D->addAttr(::new (S.Context) 3815 MSABIAttr(Attr.getRange(), S.Context, 3816 Attr.getAttributeSpellingListIndex())); 3817 return; 3818 case AttributeList::AT_SysVABI: 3819 D->addAttr(::new (S.Context) 3820 SysVABIAttr(Attr.getRange(), S.Context, 3821 Attr.getAttributeSpellingListIndex())); 3822 return; 3823 case AttributeList::AT_Pcs: { 3824 PcsAttr::PCSType PCS; 3825 switch (CC) { 3826 case CC_AAPCS: 3827 PCS = PcsAttr::AAPCS; 3828 break; 3829 case CC_AAPCS_VFP: 3830 PCS = PcsAttr::AAPCS_VFP; 3831 break; 3832 default: 3833 llvm_unreachable("unexpected calling convention in pcs attribute"); 3834 } 3835 3836 D->addAttr(::new (S.Context) 3837 PcsAttr(Attr.getRange(), S.Context, PCS, 3838 Attr.getAttributeSpellingListIndex())); 3839 return; 3840 } 3841 case AttributeList::AT_PnaclCall: 3842 D->addAttr(::new (S.Context) 3843 PnaclCallAttr(Attr.getRange(), S.Context, 3844 Attr.getAttributeSpellingListIndex())); 3845 return; 3846 case AttributeList::AT_IntelOclBicc: 3847 D->addAttr(::new (S.Context) 3848 IntelOclBiccAttr(Attr.getRange(), S.Context, 3849 Attr.getAttributeSpellingListIndex())); 3850 return; 3851 3852 default: 3853 llvm_unreachable("unexpected attribute kind"); 3854 } 3855} 3856 3857static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 3858 D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 3859} 3860 3861static void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){ 3862 Expr *E = Attr.getArgAsExpr(0); 3863 llvm::APSInt ArgNum(32); 3864 if (E->isTypeDependent() || E->isValueDependent() || 3865 !E->isIntegerConstantExpr(ArgNum, S.Context)) { 3866 S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 3867 << Attr.getName() << AANT_ArgumentIntegerConstant 3868 << E->getSourceRange(); 3869 return; 3870 } 3871 3872 D->addAttr(::new (S.Context) OpenCLImageAccessAttr( 3873 Attr.getRange(), S.Context, ArgNum.getZExtValue())); 3874} 3875 3876bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 3877 const FunctionDecl *FD) { 3878 if (attr.isInvalid()) 3879 return true; 3880 3881 unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0; 3882 if (!checkAttributeNumArgs(*this, attr, ReqArgs)) { 3883 attr.setInvalid(); 3884 return true; 3885 } 3886 3887 // TODO: diagnose uses of these conventions on the wrong target. Or, better 3888 // move to TargetAttributesSema one day. 3889 switch (attr.getKind()) { 3890 case AttributeList::AT_CDecl: CC = CC_C; break; 3891 case AttributeList::AT_FastCall: CC = CC_X86FastCall; break; 3892 case AttributeList::AT_StdCall: CC = CC_X86StdCall; break; 3893 case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break; 3894 case AttributeList::AT_Pascal: CC = CC_X86Pascal; break; 3895 case AttributeList::AT_MSABI: 3896 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C : 3897 CC_X86_64Win64; 3898 break; 3899 case AttributeList::AT_SysVABI: 3900 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV : 3901 CC_C; 3902 break; 3903 case AttributeList::AT_Pcs: { 3904 StringRef StrRef; 3905 if (!checkStringLiteralArgumentAttr(attr, 0, StrRef)) { 3906 attr.setInvalid(); 3907 return true; 3908 } 3909 if (StrRef == "aapcs") { 3910 CC = CC_AAPCS; 3911 break; 3912 } else if (StrRef == "aapcs-vfp") { 3913 CC = CC_AAPCS_VFP; 3914 break; 3915 } 3916 3917 attr.setInvalid(); 3918 Diag(attr.getLoc(), diag::err_invalid_pcs); 3919 return true; 3920 } 3921 case AttributeList::AT_PnaclCall: CC = CC_PnaclCall; break; 3922 case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break; 3923 default: llvm_unreachable("unexpected attribute kind"); 3924 } 3925 3926 const TargetInfo &TI = Context.getTargetInfo(); 3927 TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); 3928 if (A == TargetInfo::CCCR_Warning) { 3929 Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); 3930 3931 TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown; 3932 if (FD) 3933 MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member : 3934 TargetInfo::CCMT_NonMember; 3935 CC = TI.getDefaultCallingConv(MT); 3936 } 3937 3938 return false; 3939} 3940 3941static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3942 if (hasDeclarator(D)) return; 3943 3944 unsigned numParams; 3945 if (S.CheckRegparmAttr(Attr, numParams)) 3946 return; 3947 3948 if (!isa<ObjCMethodDecl>(D)) { 3949 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3950 << Attr.getName() << ExpectedFunctionOrMethod; 3951 return; 3952 } 3953 3954 D->addAttr(::new (S.Context) 3955 RegparmAttr(Attr.getRange(), S.Context, numParams, 3956 Attr.getAttributeSpellingListIndex())); 3957} 3958 3959/// Checks a regparm attribute, returning true if it is ill-formed and 3960/// otherwise setting numParams to the appropriate value. 3961bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 3962 if (Attr.isInvalid()) 3963 return true; 3964 3965 if (!checkAttributeNumArgs(*this, Attr, 1)) { 3966 Attr.setInvalid(); 3967 return true; 3968 } 3969 3970 Expr *NumParamsExpr = Attr.getArgAsExpr(0); 3971 llvm::APSInt NumParams(32); 3972 if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3973 !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 3974 Diag(Attr.getLoc(), diag::err_attribute_argument_type) 3975 << Attr.getName() << AANT_ArgumentIntegerConstant 3976 << NumParamsExpr->getSourceRange(); 3977 Attr.setInvalid(); 3978 return true; 3979 } 3980 3981 if (Context.getTargetInfo().getRegParmMax() == 0) { 3982 Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 3983 << NumParamsExpr->getSourceRange(); 3984 Attr.setInvalid(); 3985 return true; 3986 } 3987 3988 numParams = NumParams.getZExtValue(); 3989 if (numParams > Context.getTargetInfo().getRegParmMax()) { 3990 Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3991 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 3992 Attr.setInvalid(); 3993 return true; 3994 } 3995 3996 return false; 3997} 3998 3999static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 4000 if (S.LangOpts.CUDA) { 4001 // check the attribute arguments. 4002 if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 4003 // FIXME: 0 is not okay. 4004 S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 4005 return; 4006 } 4007 4008 if (!isFunctionOrMethod(D)) { 4009 S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4010 << Attr.getName() << ExpectedFunctionOrMethod; 4011 return; 4012 } 4013 4014 Expr *MaxThreadsExpr = Attr.getArgAsExpr(0); 4015 llvm::APSInt MaxThreads(32); 4016 if (MaxThreadsExpr->isTypeDependent() || 4017 MaxThreadsExpr->isValueDependent() || 4018 !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 4019 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 4020 << Attr.getName() << 1 << AANT_ArgumentIntegerConstant 4021 << MaxThreadsExpr->getSourceRange(); 4022 return; 4023 } 4024 4025 llvm::APSInt MinBlocks(32); 4026 if (Attr.getNumArgs() > 1) { 4027 Expr *MinBlocksExpr = Attr.getArgAsExpr(1); 4028 if (MinBlocksExpr->isTypeDependent() || 4029 MinBlocksExpr->isValueDependent() || 4030 !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 4031 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 4032 << Attr.getName() << 2 << AANT_ArgumentIntegerConstant 4033 << MinBlocksExpr->getSourceRange(); 4034 return; 4035 } 4036 } 4037 4038 D->addAttr(::new (S.Context) 4039 CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 4040 MaxThreads.getZExtValue(), 4041 MinBlocks.getZExtValue(), 4042 Attr.getAttributeSpellingListIndex())); 4043 } else { 4044 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 4045 } 4046} 4047 4048static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, 4049 const AttributeList &Attr) { 4050 if (!Attr.isArgIdent(0)) { 4051 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 4052 << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier; 4053 return; 4054 } 4055 4056 if (!checkAttributeNumArgs(S, Attr, 3)) 4057 return; 4058 4059 StringRef AttrName = Attr.getName()->getName(); 4060 IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident; 4061 4062 if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 4063 S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 4064 << Attr.getName() << ExpectedFunctionOrMethod; 4065 return; 4066 } 4067 4068 uint64_t ArgumentIdx; 4069 if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, 4070 Attr.getLoc(), 2, 4071 Attr.getArgAsExpr(1), ArgumentIdx)) 4072 return; 4073 4074 uint64_t TypeTagIdx; 4075 if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, 4076 Attr.getLoc(), 3, 4077 Attr.getArgAsExpr(2), TypeTagIdx)) 4078 return; 4079 4080 bool IsPointer = (AttrName == "pointer_with_type_tag"); 4081 if (IsPointer) { 4082 // Ensure that buffer has a pointer type. 4083 QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx); 4084 if (!BufferTy->isPointerType()) { 4085 S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only) 4086 << Attr.getName(); 4087 } 4088 } 4089 4090 D->addAttr(::new (S.Context) 4091 ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind, 4092 ArgumentIdx, TypeTagIdx, IsPointer, 4093 Attr.getAttributeSpellingListIndex())); 4094} 4095 4096static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, 4097 const AttributeList &Attr) { 4098 if (!Attr.isArgIdent(0)) { 4099 S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 4100 << Attr.getName() << 1 << AANT_ArgumentIdentifier; 4101 return; 4102 } 4103 4104 if (!checkAttributeNumArgs(S, Attr, 1)) 4105 return; 4106 4107 IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident; 4108 TypeSourceInfo *MatchingCTypeLoc = 0; 4109 S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc); 4110 assert(MatchingCTypeLoc && "no type source info for attribute argument"); 4111 4112 D->addAttr(::new (S.Context) 4113 TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind, 4114 MatchingCTypeLoc, 4115 Attr.getLayoutCompatible(), 4116 Attr.getMustBeNull(), 4117 Attr.getAttributeSpellingListIndex())); 4118} 4119 4120//===----------------------------------------------------------------------===// 4121// Checker-specific attribute handlers. 4122//===----------------------------------------------------------------------===// 4123 4124static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 4125 return type->isDependentType() || 4126 type->isObjCObjectPointerType() || 4127 S.Context.isObjCNSObjectType(type); 4128} 4129static bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 4130 return type->isDependentType() || 4131 type->isPointerType() || 4132 isValidSubjectOfNSAttribute(S, type); 4133} 4134 4135static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4136 ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 4137 if (!param) { 4138 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 4139 << Attr.getRange() << Attr.getName() << ExpectedParameter; 4140 return; 4141 } 4142 4143 bool typeOK, cf; 4144 if (Attr.getKind() == AttributeList::AT_NSConsumed) { 4145 typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 4146 cf = false; 4147 } else { 4148 typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 4149 cf = true; 4150 } 4151 4152 if (!typeOK) { 4153 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 4154 << Attr.getRange() << Attr.getName() << cf; 4155 return; 4156 } 4157 4158 if (cf) 4159 param->addAttr(::new (S.Context) 4160 CFConsumedAttr(Attr.getRange(), S.Context, 4161 Attr.getAttributeSpellingListIndex())); 4162 else 4163 param->addAttr(::new (S.Context) 4164 NSConsumedAttr(Attr.getRange(), S.Context, 4165 Attr.getAttributeSpellingListIndex())); 4166} 4167 4168static void handleNSConsumesSelfAttr(Sema &S, Decl *D, 4169 const AttributeList &Attr) { 4170 if (!isa<ObjCMethodDecl>(D)) { 4171 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 4172 << Attr.getRange() << Attr.getName() << ExpectedMethod; 4173 return; 4174 } 4175 4176 D->addAttr(::new (S.Context) 4177 NSConsumesSelfAttr(Attr.getRange(), S.Context, 4178 Attr.getAttributeSpellingListIndex())); 4179} 4180 4181static void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 4182 const AttributeList &Attr) { 4183 4184 QualType returnType; 4185 4186 if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 4187 returnType = MD->getResultType(); 4188 else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 4189 (Attr.getKind() == AttributeList::AT_NSReturnsRetained)) 4190 return; // ignore: was handled as a type attribute 4191 else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 4192 returnType = PD->getType(); 4193 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 4194 returnType = FD->getResultType(); 4195 else { 4196 S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 4197 << Attr.getRange() << Attr.getName() 4198 << ExpectedFunctionOrMethod; 4199 return; 4200 } 4201 4202 bool typeOK; 4203 bool cf; 4204 switch (Attr.getKind()) { 4205 default: llvm_unreachable("invalid ownership attribute"); 4206 case AttributeList::AT_NSReturnsAutoreleased: 4207 case AttributeList::AT_NSReturnsRetained: 4208 case AttributeList::AT_NSReturnsNotRetained: 4209 typeOK = isValidSubjectOfNSAttribute(S, returnType); 4210 cf = false; 4211 break; 4212 4213 case AttributeList::AT_CFReturnsRetained: 4214 case AttributeList::AT_CFReturnsNotRetained: 4215 typeOK = isValidSubjectOfCFAttribute(S, returnType); 4216 cf = true; 4217 break; 4218 } 4219 4220 if (!typeOK) { 4221 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 4222 << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 4223 return; 4224 } 4225 4226 switch (Attr.getKind()) { 4227 default: 4228 llvm_unreachable("invalid ownership attribute"); 4229 case AttributeList::AT_NSReturnsAutoreleased: 4230 D->addAttr(::new (S.Context) 4231 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context, 4232 Attr.getAttributeSpellingListIndex())); 4233 return; 4234 case AttributeList::AT_CFReturnsNotRetained: 4235 D->addAttr(::new (S.Context) 4236 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context, 4237 Attr.getAttributeSpellingListIndex())); 4238 return; 4239 case AttributeList::AT_NSReturnsNotRetained: 4240 D->addAttr(::new (S.Context) 4241 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context, 4242 Attr.getAttributeSpellingListIndex())); 4243 return; 4244 case AttributeList::AT_CFReturnsRetained: 4245 D->addAttr(::new (S.Context) 4246 CFReturnsRetainedAttr(Attr.getRange(), S.Context, 4247 Attr.getAttributeSpellingListIndex())); 4248 return; 4249 case AttributeList::AT_NSReturnsRetained: 4250 D->addAttr(::new (S.Context) 4251 NSReturnsRetainedAttr(Attr.getRange(), S.Context, 4252 Attr.getAttributeSpellingListIndex())); 4253 return; 4254 }; 4255} 4256 4257static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 4258 const AttributeList &attr) { 4259 const int EP_ObjCMethod = 1; 4260 const int EP_ObjCProperty = 2; 4261 4262 SourceLocation loc = attr.getLoc(); 4263 QualType resultType; 4264 4265 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 4266 4267 if (!method) { 4268 ObjCPropertyDecl *property = dyn_cast<ObjCPropertyDecl>(D); 4269 if (!property) { 4270 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4271 << SourceRange(loc, loc) << attr.getName() << ExpectedMethodOrProperty; 4272 return; 4273 } 4274 resultType = property->getType(); 4275 } 4276 else 4277 // Check that the method returns a normal pointer. 4278 resultType = method->getResultType(); 4279 4280 if (!resultType->isReferenceType() && 4281 (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 4282 S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 4283 << SourceRange(loc) 4284 << attr.getName() << (method ? EP_ObjCMethod : EP_ObjCProperty) 4285 << /*non-retainable pointer*/ 2; 4286 4287 // Drop the attribute. 4288 return; 4289 } 4290 4291 D->addAttr(::new (S.Context) 4292 ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context, 4293 attr.getAttributeSpellingListIndex())); 4294} 4295 4296static void handleObjCRequiresSuperAttr(Sema &S, Decl *D, 4297 const AttributeList &attr) { 4298 SourceLocation loc = attr.getLoc(); 4299 ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 4300 4301 if (!method) { 4302 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4303 << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 4304 return; 4305 } 4306 DeclContext *DC = method->getDeclContext(); 4307 if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) { 4308 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 4309 << attr.getName() << 0; 4310 S.Diag(PDecl->getLocation(), diag::note_protocol_decl); 4311 return; 4312 } 4313 if (method->getMethodFamily() == OMF_dealloc) { 4314 S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 4315 << attr.getName() << 1; 4316 return; 4317 } 4318 4319 method->addAttr(::new (S.Context) 4320 ObjCRequiresSuperAttr(attr.getRange(), S.Context, 4321 attr.getAttributeSpellingListIndex())); 4322} 4323 4324/// Handle cf_audited_transfer and cf_unknown_transfer. 4325static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 4326 if (!isa<FunctionDecl>(D)) { 4327 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4328 << A.getRange() << A.getName() << ExpectedFunction; 4329 return; 4330 } 4331 4332 bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer); 4333 4334 // Check whether there's a conflicting attribute already present. 4335 Attr *Existing; 4336 if (IsAudited) { 4337 Existing = D->getAttr<CFUnknownTransferAttr>(); 4338 } else { 4339 Existing = D->getAttr<CFAuditedTransferAttr>(); 4340 } 4341 if (Existing) { 4342 S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 4343 << A.getName() 4344 << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 4345 << A.getRange() << Existing->getRange(); 4346 return; 4347 } 4348 4349 // All clear; add the attribute. 4350 if (IsAudited) { 4351 D->addAttr(::new (S.Context) 4352 CFAuditedTransferAttr(A.getRange(), S.Context, 4353 A.getAttributeSpellingListIndex())); 4354 } else { 4355 D->addAttr(::new (S.Context) 4356 CFUnknownTransferAttr(A.getRange(), S.Context, 4357 A.getAttributeSpellingListIndex())); 4358 } 4359} 4360 4361static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 4362 const AttributeList &Attr) { 4363 RecordDecl *RD = dyn_cast<RecordDecl>(D); 4364 if (!RD || RD->isUnion()) { 4365 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4366 << Attr.getRange() << Attr.getName() << ExpectedStruct; 4367 } 4368 4369 IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0; 4370 4371 // In Objective-C, verify that the type names an Objective-C type. 4372 // We don't want to check this outside of ObjC because people sometimes 4373 // do crazy C declarations of Objective-C types. 4374 if (Parm && S.getLangOpts().ObjC1) { 4375 // Check for an existing type with this name. 4376 LookupResult R(S, DeclarationName(Parm->Ident), Parm->Loc, 4377 Sema::LookupOrdinaryName); 4378 if (S.LookupName(R, Sc)) { 4379 NamedDecl *Target = R.getFoundDecl(); 4380 if (Target && !isa<ObjCInterfaceDecl>(Target)) { 4381 S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 4382 S.Diag(Target->getLocStart(), diag::note_declared_at); 4383 } 4384 } 4385 } 4386 4387 D->addAttr(::new (S.Context) 4388 NSBridgedAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0, 4389 Attr.getAttributeSpellingListIndex())); 4390} 4391 4392static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D, 4393 const AttributeList &Attr) { 4394 if (!isa<RecordDecl>(D)) { 4395 S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute) 4396 << S.getLangOpts().CPlusPlus; 4397 return; 4398 } 4399 4400 if (Attr.getNumArgs() != 1) { 4401 S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id); 4402 return; 4403 } 4404 IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0; 4405 if (!Parm) { 4406 S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id); 4407 return; 4408 } 4409 4410 D->addAttr(::new (S.Context) 4411 ObjCBridgeAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0, 4412 Attr.getAttributeSpellingListIndex())); 4413} 4414 4415static void handleObjCOwnershipAttr(Sema &S, Decl *D, 4416 const AttributeList &Attr) { 4417 if (hasDeclarator(D)) return; 4418 4419 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4420 << Attr.getRange() << Attr.getName() << ExpectedVariable; 4421} 4422 4423static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 4424 const AttributeList &Attr) { 4425 if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 4426 S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4427 << Attr.getRange() << Attr.getName() << ExpectedVariable; 4428 return; 4429 } 4430 4431 ValueDecl *vd = cast<ValueDecl>(D); 4432 QualType type = vd->getType(); 4433 4434 if (!type->isDependentType() && 4435 !type->isObjCLifetimeType()) { 4436 S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 4437 << type; 4438 return; 4439 } 4440 4441 Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 4442 4443 // If we have no lifetime yet, check the lifetime we're presumably 4444 // going to infer. 4445 if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 4446 lifetime = type->getObjCARCImplicitLifetime(); 4447 4448 switch (lifetime) { 4449 case Qualifiers::OCL_None: 4450 assert(type->isDependentType() && 4451 "didn't infer lifetime for non-dependent type?"); 4452 break; 4453 4454 case Qualifiers::OCL_Weak: // meaningful 4455 case Qualifiers::OCL_Strong: // meaningful 4456 break; 4457 4458 case Qualifiers::OCL_ExplicitNone: 4459 case Qualifiers::OCL_Autoreleasing: 4460 S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 4461 << (lifetime == Qualifiers::OCL_Autoreleasing); 4462 break; 4463 } 4464 4465 D->addAttr(::new (S.Context) 4466 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context, 4467 Attr.getAttributeSpellingListIndex())); 4468} 4469 4470//===----------------------------------------------------------------------===// 4471// Microsoft specific attribute handlers. 4472//===----------------------------------------------------------------------===// 4473 4474// Check if MS extensions or some other language extensions are enabled. If 4475// not, issue a diagnostic that the given attribute is unused. 4476static bool checkMicrosoftExt(Sema &S, const AttributeList &Attr, 4477 bool OtherExtension = false) { 4478 if (S.LangOpts.MicrosoftExt || OtherExtension) 4479 return true; 4480 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 4481 return false; 4482} 4483 4484static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4485 if (!checkMicrosoftExt(S, Attr, S.LangOpts.Borland)) 4486 return; 4487 4488 StringRef StrRef; 4489 SourceLocation LiteralLoc; 4490 if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc)) 4491 return; 4492 4493 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 4494 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former. 4495 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}') 4496 StrRef = StrRef.drop_front().drop_back(); 4497 4498 // Validate GUID length. 4499 if (StrRef.size() != 36) { 4500 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 4501 return; 4502 } 4503 4504 for (unsigned i = 0; i < 36; ++i) { 4505 if (i == 8 || i == 13 || i == 18 || i == 23) { 4506 if (StrRef[i] != '-') { 4507 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 4508 return; 4509 } 4510 } else if (!isHexDigit(StrRef[i])) { 4511 S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 4512 return; 4513 } 4514 } 4515 4516 D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef, 4517 Attr.getAttributeSpellingListIndex())); 4518} 4519 4520static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4521 if (!checkMicrosoftExt(S, Attr)) 4522 return; 4523 4524 AttributeList::Kind Kind = Attr.getKind(); 4525 if (Kind == AttributeList::AT_SingleInheritance) 4526 D->addAttr( 4527 ::new (S.Context) 4528 SingleInheritanceAttr(Attr.getRange(), S.Context, 4529 Attr.getAttributeSpellingListIndex())); 4530 else if (Kind == AttributeList::AT_MultipleInheritance) 4531 D->addAttr( 4532 ::new (S.Context) 4533 MultipleInheritanceAttr(Attr.getRange(), S.Context, 4534 Attr.getAttributeSpellingListIndex())); 4535 else if (Kind == AttributeList::AT_VirtualInheritance) 4536 D->addAttr( 4537 ::new (S.Context) 4538 VirtualInheritanceAttr(Attr.getRange(), S.Context, 4539 Attr.getAttributeSpellingListIndex())); 4540} 4541 4542static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4543 if (!checkMicrosoftExt(S, Attr)) 4544 return; 4545 4546 AttributeList::Kind Kind = Attr.getKind(); 4547 if (Kind == AttributeList::AT_Win64) 4548 D->addAttr( 4549 ::new (S.Context) Win64Attr(Attr.getRange(), S.Context, 4550 Attr.getAttributeSpellingListIndex())); 4551} 4552 4553static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4554 if (!checkMicrosoftExt(S, Attr)) 4555 return; 4556 D->addAttr(::new (S.Context) 4557 ForceInlineAttr(Attr.getRange(), S.Context, 4558 Attr.getAttributeSpellingListIndex())); 4559} 4560 4561static void handleSelectAnyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4562 if (!checkMicrosoftExt(S, Attr)) 4563 return; 4564 // Check linkage after possibly merging declaratinos. See 4565 // checkAttributesAfterMerging(). 4566 D->addAttr(::new (S.Context) 4567 SelectAnyAttr(Attr.getRange(), S.Context, 4568 Attr.getAttributeSpellingListIndex())); 4569} 4570 4571/// Handles semantic checking for features that are common to all attributes, 4572/// such as checking whether a parameter was properly specified, or the correct 4573/// number of arguments were passed, etc. 4574static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D, 4575 const AttributeList &Attr) { 4576 // Several attributes carry different semantics than the parsing requires, so 4577 // those are opted out of the common handling. 4578 // 4579 // We also bail on unknown and ignored attributes because those are handled 4580 // as part of the target-specific handling logic. 4581 if (Attr.hasCustomParsing() || 4582 Attr.getKind() == AttributeList::UnknownAttribute || 4583 Attr.getKind() == AttributeList::IgnoredAttribute) 4584 return false; 4585 4586 // If there are no optional arguments, then checking for the argument count 4587 // is trivial. 4588 if (Attr.getMinArgs() == Attr.getMaxArgs() && 4589 !checkAttributeNumArgs(S, Attr, Attr.getMinArgs())) 4590 return true; 4591 return false; 4592} 4593 4594//===----------------------------------------------------------------------===// 4595// Top Level Sema Entry Points 4596//===----------------------------------------------------------------------===// 4597 4598/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 4599/// the attribute applies to decls. If the attribute is a type attribute, just 4600/// silently ignore it if a GNU attribute. 4601static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 4602 const AttributeList &Attr, 4603 bool IncludeCXX11Attributes) { 4604 if (Attr.isInvalid()) 4605 return; 4606 4607 // Ignore C++11 attributes on declarator chunks: they appertain to the type 4608 // instead. 4609 if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes) 4610 return; 4611 4612 if (handleCommonAttributeFeatures(S, scope, D, Attr)) 4613 return; 4614 4615 switch (Attr.getKind()) { 4616 case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break; 4617 case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break; 4618 case AttributeList::AT_IBOutletCollection: 4619 handleIBOutletCollection(S, D, Attr); break; 4620 case AttributeList::AT_AddressSpace: 4621 case AttributeList::AT_ObjCGC: 4622 case AttributeList::AT_VectorSize: 4623 case AttributeList::AT_NeonVectorType: 4624 case AttributeList::AT_NeonPolyVectorType: 4625 case AttributeList::AT_Ptr32: 4626 case AttributeList::AT_Ptr64: 4627 case AttributeList::AT_SPtr: 4628 case AttributeList::AT_UPtr: 4629 // Ignore these, these are type attributes, handled by 4630 // ProcessTypeAttributes. 4631 break; 4632 case AttributeList::AT_Alias: handleAliasAttr (S, D, Attr); break; 4633 case AttributeList::AT_Aligned: handleAlignedAttr (S, D, Attr); break; 4634 case AttributeList::AT_AllocSize: handleAllocSizeAttr (S, D, Attr); break; 4635 case AttributeList::AT_AlwaysInline: 4636 handleAlwaysInlineAttr (S, D, Attr); break; 4637 case AttributeList::AT_AnalyzerNoReturn: 4638 handleAnalyzerNoReturnAttr (S, D, Attr); break; 4639 case AttributeList::AT_TLSModel: handleTLSModelAttr (S, D, Attr); break; 4640 case AttributeList::AT_Annotate: handleAnnotateAttr (S, D, Attr); break; 4641 case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break; 4642 case AttributeList::AT_CarriesDependency: 4643 handleDependencyAttr(S, scope, D, Attr); 4644 break; 4645 case AttributeList::AT_Common: handleCommonAttr (S, D, Attr); break; 4646 case AttributeList::AT_CUDAConstant:handleConstantAttr (S, D, Attr); break; 4647 case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break; 4648 case AttributeList::AT_CXX11NoReturn: 4649 handleCXX11NoReturnAttr(S, D, Attr); 4650 break; 4651 case AttributeList::AT_Deprecated: 4652 handleAttrWithMessage<DeprecatedAttr>(S, D, Attr); 4653 break; 4654 case AttributeList::AT_Destructor: handleDestructorAttr (S, D, Attr); break; 4655 case AttributeList::AT_ExtVectorType: 4656 handleExtVectorTypeAttr(S, scope, D, Attr); 4657 break; 4658 case AttributeList::AT_MinSize: 4659 handleMinSizeAttr(S, D, Attr); 4660 break; 4661 case AttributeList::AT_Format: handleFormatAttr (S, D, Attr); break; 4662 case AttributeList::AT_FormatArg: handleFormatArgAttr (S, D, Attr); break; 4663 case AttributeList::AT_CUDAGlobal: handleGlobalAttr (S, D, Attr); break; 4664 case AttributeList::AT_CUDADevice: handleDeviceAttr (S, D, Attr); break; 4665 case AttributeList::AT_CUDAHost: handleHostAttr (S, D, Attr); break; 4666 case AttributeList::AT_GNUInline: handleGNUInlineAttr (S, D, Attr); break; 4667 case AttributeList::AT_CUDALaunchBounds: 4668 handleLaunchBoundsAttr(S, D, Attr); 4669 break; 4670 case AttributeList::AT_Malloc: handleMallocAttr (S, D, Attr); break; 4671 case AttributeList::AT_MayAlias: handleMayAliasAttr (S, D, Attr); break; 4672 case AttributeList::AT_Mode: handleModeAttr (S, D, Attr); break; 4673 case AttributeList::AT_NoCommon: handleNoCommonAttr (S, D, Attr); break; 4674 case AttributeList::AT_NonNull: handleNonNullAttr (S, D, Attr); break; 4675 case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break; 4676 case AttributeList::AT_ownership_returns: 4677 case AttributeList::AT_ownership_takes: 4678 case AttributeList::AT_ownership_holds: 4679 handleOwnershipAttr (S, D, Attr); break; 4680 case AttributeList::AT_Cold: handleColdAttr (S, D, Attr); break; 4681 case AttributeList::AT_Hot: handleHotAttr (S, D, Attr); break; 4682 case AttributeList::AT_Naked: handleNakedAttr (S, D, Attr); break; 4683 case AttributeList::AT_NoReturn: handleNoReturnAttr (S, D, Attr); break; 4684 case AttributeList::AT_NoThrow: handleNothrowAttr (S, D, Attr); break; 4685 case AttributeList::AT_CUDAShared: handleSharedAttr (S, D, Attr); break; 4686 case AttributeList::AT_VecReturn: handleVecReturnAttr (S, D, Attr); break; 4687 4688 case AttributeList::AT_ObjCOwnership: 4689 handleObjCOwnershipAttr(S, D, Attr); break; 4690 case AttributeList::AT_ObjCPreciseLifetime: 4691 handleObjCPreciseLifetimeAttr(S, D, Attr); break; 4692 4693 case AttributeList::AT_ObjCReturnsInnerPointer: 4694 handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 4695 4696 case AttributeList::AT_ObjCRequiresSuper: 4697 handleObjCRequiresSuperAttr(S, D, Attr); break; 4698 4699 case AttributeList::AT_NSBridged: 4700 handleNSBridgedAttr(S, scope, D, Attr); break; 4701 4702 case AttributeList::AT_ObjCBridge: 4703 handleObjCBridgeAttr(S, scope, D, Attr); break; 4704 4705 case AttributeList::AT_CFAuditedTransfer: 4706 case AttributeList::AT_CFUnknownTransfer: 4707 handleCFTransferAttr(S, D, Attr); break; 4708 4709 // Checker-specific. 4710 case AttributeList::AT_CFConsumed: 4711 case AttributeList::AT_NSConsumed: handleNSConsumedAttr (S, D, Attr); break; 4712 case AttributeList::AT_NSConsumesSelf: 4713 handleNSConsumesSelfAttr(S, D, Attr); break; 4714 4715 case AttributeList::AT_NSReturnsAutoreleased: 4716 case AttributeList::AT_NSReturnsNotRetained: 4717 case AttributeList::AT_CFReturnsNotRetained: 4718 case AttributeList::AT_NSReturnsRetained: 4719 case AttributeList::AT_CFReturnsRetained: 4720 handleNSReturnsRetainedAttr(S, D, Attr); break; 4721 4722 case AttributeList::AT_WorkGroupSizeHint: 4723 case AttributeList::AT_ReqdWorkGroupSize: 4724 handleWorkGroupSize(S, D, Attr); break; 4725 4726 case AttributeList::AT_VecTypeHint: 4727 handleVecTypeHint(S, D, Attr); break; 4728 4729 case AttributeList::AT_InitPriority: 4730 handleInitPriorityAttr(S, D, Attr); break; 4731 4732 case AttributeList::AT_Packed: handlePackedAttr (S, D, Attr); break; 4733 case AttributeList::AT_Section: handleSectionAttr (S, D, Attr); break; 4734 case AttributeList::AT_Unavailable: 4735 handleAttrWithMessage<UnavailableAttr>(S, D, Attr); 4736 break; 4737 case AttributeList::AT_ArcWeakrefUnavailable: 4738 handleArcWeakrefUnavailableAttr (S, D, Attr); 4739 break; 4740 case AttributeList::AT_ObjCRootClass: 4741 handleObjCRootClassAttr(S, D, Attr); 4742 break; 4743 case AttributeList::AT_ObjCRequiresPropertyDefs: 4744 handleObjCRequiresPropertyDefsAttr (S, D, Attr); 4745 break; 4746 case AttributeList::AT_Unused: handleUnusedAttr (S, D, Attr); break; 4747 case AttributeList::AT_ReturnsTwice: 4748 handleReturnsTwiceAttr(S, D, Attr); 4749 break; 4750 case AttributeList::AT_Used: handleUsedAttr (S, D, Attr); break; 4751 case AttributeList::AT_Visibility: 4752 handleVisibilityAttr(S, D, Attr, false); 4753 break; 4754 case AttributeList::AT_TypeVisibility: 4755 handleVisibilityAttr(S, D, Attr, true); 4756 break; 4757 case AttributeList::AT_WarnUnused: 4758 handleWarnUnusedAttr(S, D, Attr); 4759 break; 4760 case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr); 4761 break; 4762 case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break; 4763 case AttributeList::AT_WeakRef: handleWeakRefAttr (S, D, Attr); break; 4764 case AttributeList::AT_WeakImport: handleWeakImportAttr (S, D, Attr); break; 4765 case AttributeList::AT_TransparentUnion: 4766 handleTransparentUnionAttr(S, D, Attr); 4767 break; 4768 case AttributeList::AT_ObjCException: 4769 handleObjCExceptionAttr(S, D, Attr); 4770 break; 4771 case AttributeList::AT_ObjCMethodFamily: 4772 handleObjCMethodFamilyAttr(S, D, Attr); 4773 break; 4774 case AttributeList::AT_ObjCNSObject:handleObjCNSObject (S, D, Attr); break; 4775 case AttributeList::AT_Blocks: handleBlocksAttr (S, D, Attr); break; 4776 case AttributeList::AT_Sentinel: handleSentinelAttr (S, D, Attr); break; 4777 case AttributeList::AT_Const: handleConstAttr (S, D, Attr); break; 4778 case AttributeList::AT_Pure: handlePureAttr (S, D, Attr); break; 4779 case AttributeList::AT_Cleanup: handleCleanupAttr (S, D, Attr); break; 4780 case AttributeList::AT_NoDebug: handleNoDebugAttr (S, D, Attr); break; 4781 case AttributeList::AT_NoInline: handleNoInlineAttr (S, D, Attr); break; 4782 case AttributeList::AT_Regparm: handleRegparmAttr (S, D, Attr); break; 4783 case AttributeList::IgnoredAttribute: 4784 // Just ignore 4785 break; 4786 case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg. 4787 handleNoInstrumentFunctionAttr(S, D, Attr); 4788 break; 4789 case AttributeList::AT_StdCall: 4790 case AttributeList::AT_CDecl: 4791 case AttributeList::AT_FastCall: 4792 case AttributeList::AT_ThisCall: 4793 case AttributeList::AT_Pascal: 4794 case AttributeList::AT_MSABI: 4795 case AttributeList::AT_SysVABI: 4796 case AttributeList::AT_Pcs: 4797 case AttributeList::AT_PnaclCall: 4798 case AttributeList::AT_IntelOclBicc: 4799 handleCallConvAttr(S, D, Attr); 4800 break; 4801 case AttributeList::AT_OpenCLKernel: 4802 handleOpenCLKernelAttr(S, D, Attr); 4803 break; 4804 case AttributeList::AT_OpenCLImageAccess: 4805 handleOpenCLImageAccessAttr(S, D, Attr); 4806 break; 4807 4808 // Microsoft attributes: 4809 case AttributeList::AT_MsStruct: 4810 handleMsStructAttr(S, D, Attr); 4811 break; 4812 case AttributeList::AT_Uuid: 4813 handleUuidAttr(S, D, Attr); 4814 break; 4815 case AttributeList::AT_SingleInheritance: 4816 case AttributeList::AT_MultipleInheritance: 4817 case AttributeList::AT_VirtualInheritance: 4818 handleInheritanceAttr(S, D, Attr); 4819 break; 4820 case AttributeList::AT_Win64: 4821 handlePortabilityAttr(S, D, Attr); 4822 break; 4823 case AttributeList::AT_ForceInline: 4824 handleForceInlineAttr(S, D, Attr); 4825 break; 4826 case AttributeList::AT_SelectAny: 4827 handleSelectAnyAttr(S, D, Attr); 4828 break; 4829 4830 // Thread safety attributes: 4831 case AttributeList::AT_AssertExclusiveLock: 4832 handleAssertExclusiveLockAttr(S, D, Attr); 4833 break; 4834 case AttributeList::AT_AssertSharedLock: 4835 handleAssertSharedLockAttr(S, D, Attr); 4836 break; 4837 case AttributeList::AT_GuardedVar: 4838 handleGuardedVarAttr(S, D, Attr); 4839 break; 4840 case AttributeList::AT_PtGuardedVar: 4841 handlePtGuardedVarAttr(S, D, Attr); 4842 break; 4843 case AttributeList::AT_ScopedLockable: 4844 handleScopedLockableAttr(S, D, Attr); 4845 break; 4846 case AttributeList::AT_NoSanitizeAddress: 4847 handleNoSanitizeAddressAttr(S, D, Attr); 4848 break; 4849 case AttributeList::AT_NoThreadSafetyAnalysis: 4850 handleNoThreadSafetyAnalysis(S, D, Attr); 4851 break; 4852 case AttributeList::AT_NoSanitizeThread: 4853 handleNoSanitizeThread(S, D, Attr); 4854 break; 4855 case AttributeList::AT_NoSanitizeMemory: 4856 handleNoSanitizeMemory(S, D, Attr); 4857 break; 4858 case AttributeList::AT_Lockable: 4859 handleLockableAttr(S, D, Attr); 4860 break; 4861 case AttributeList::AT_GuardedBy: 4862 handleGuardedByAttr(S, D, Attr); 4863 break; 4864 case AttributeList::AT_PtGuardedBy: 4865 handlePtGuardedByAttr(S, D, Attr); 4866 break; 4867 case AttributeList::AT_ExclusiveLockFunction: 4868 handleExclusiveLockFunctionAttr(S, D, Attr); 4869 break; 4870 case AttributeList::AT_ExclusiveLocksRequired: 4871 handleExclusiveLocksRequiredAttr(S, D, Attr); 4872 break; 4873 case AttributeList::AT_ExclusiveTrylockFunction: 4874 handleExclusiveTrylockFunctionAttr(S, D, Attr); 4875 break; 4876 case AttributeList::AT_LockReturned: 4877 handleLockReturnedAttr(S, D, Attr); 4878 break; 4879 case AttributeList::AT_LocksExcluded: 4880 handleLocksExcludedAttr(S, D, Attr); 4881 break; 4882 case AttributeList::AT_SharedLockFunction: 4883 handleSharedLockFunctionAttr(S, D, Attr); 4884 break; 4885 case AttributeList::AT_SharedLocksRequired: 4886 handleSharedLocksRequiredAttr(S, D, Attr); 4887 break; 4888 case AttributeList::AT_SharedTrylockFunction: 4889 handleSharedTrylockFunctionAttr(S, D, Attr); 4890 break; 4891 case AttributeList::AT_UnlockFunction: 4892 handleUnlockFunAttr(S, D, Attr); 4893 break; 4894 case AttributeList::AT_AcquiredBefore: 4895 handleAcquiredBeforeAttr(S, D, Attr); 4896 break; 4897 case AttributeList::AT_AcquiredAfter: 4898 handleAcquiredAfterAttr(S, D, Attr); 4899 break; 4900 4901 // Consumed analysis attributes. 4902 case AttributeList::AT_Consumable: 4903 handleConsumableAttr(S, D, Attr); 4904 break; 4905 case AttributeList::AT_CallableWhen: 4906 handleCallableWhenAttr(S, D, Attr); 4907 break; 4908 case AttributeList::AT_ParamTypestate: 4909 handleParamTypestateAttr(S, D, Attr); 4910 break; 4911 case AttributeList::AT_ReturnTypestate: 4912 handleReturnTypestateAttr(S, D, Attr); 4913 break; 4914 case AttributeList::AT_SetTypestate: 4915 handleSetTypestateAttr(S, D, Attr); 4916 break; 4917 case AttributeList::AT_TestTypestate: 4918 handleTestTypestateAttr(S, D, Attr); 4919 break; 4920 4921 // Type safety attributes. 4922 case AttributeList::AT_ArgumentWithTypeTag: 4923 handleArgumentWithTypeTagAttr(S, D, Attr); 4924 break; 4925 case AttributeList::AT_TypeTagForDatatype: 4926 handleTypeTagForDatatypeAttr(S, D, Attr); 4927 break; 4928 4929 default: 4930 // Ask target about the attribute. 4931 const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 4932 if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 4933 S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ? 4934 diag::warn_unhandled_ms_attribute_ignored : 4935 diag::warn_unknown_attribute_ignored) << Attr.getName(); 4936 break; 4937 } 4938} 4939 4940/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 4941/// attribute list to the specified decl, ignoring any type attributes. 4942void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 4943 const AttributeList *AttrList, 4944 bool IncludeCXX11Attributes) { 4945 for (const AttributeList* l = AttrList; l; l = l->getNext()) 4946 ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes); 4947 4948 // GCC accepts 4949 // static int a9 __attribute__((weakref)); 4950 // but that looks really pointless. We reject it. 4951 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 4952 Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 4953 cast<NamedDecl>(D)->getNameAsString(); 4954 D->dropAttr<WeakRefAttr>(); 4955 return; 4956 } 4957} 4958 4959// Annotation attributes are the only attributes allowed after an access 4960// specifier. 4961bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 4962 const AttributeList *AttrList) { 4963 for (const AttributeList* l = AttrList; l; l = l->getNext()) { 4964 if (l->getKind() == AttributeList::AT_Annotate) { 4965 handleAnnotateAttr(*this, ASDecl, *l); 4966 } else { 4967 Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 4968 return true; 4969 } 4970 } 4971 4972 return false; 4973} 4974 4975/// checkUnusedDeclAttributes - Check a list of attributes to see if it 4976/// contains any decl attributes that we should warn about. 4977static void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 4978 for ( ; A; A = A->getNext()) { 4979 // Only warn if the attribute is an unignored, non-type attribute. 4980 if (A->isUsedAsTypeAttr() || A->isInvalid()) continue; 4981 if (A->getKind() == AttributeList::IgnoredAttribute) continue; 4982 4983 if (A->getKind() == AttributeList::UnknownAttribute) { 4984 S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 4985 << A->getName() << A->getRange(); 4986 } else { 4987 S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 4988 << A->getName() << A->getRange(); 4989 } 4990 } 4991} 4992 4993/// checkUnusedDeclAttributes - Given a declarator which is not being 4994/// used to build a declaration, complain about any decl attributes 4995/// which might be lying around on it. 4996void Sema::checkUnusedDeclAttributes(Declarator &D) { 4997 ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 4998 ::checkUnusedDeclAttributes(*this, D.getAttributes()); 4999 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 5000 ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 5001} 5002 5003/// DeclClonePragmaWeak - clone existing decl (maybe definition), 5004/// \#pragma weak needs a non-definition decl and source may not have one. 5005NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 5006 SourceLocation Loc) { 5007 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 5008 NamedDecl *NewD = 0; 5009 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 5010 FunctionDecl *NewFD; 5011 // FIXME: Missing call to CheckFunctionDeclaration(). 5012 // FIXME: Mangling? 5013 // FIXME: Is the qualifier info correct? 5014 // FIXME: Is the DeclContext correct? 5015 NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 5016 Loc, Loc, DeclarationName(II), 5017 FD->getType(), FD->getTypeSourceInfo(), 5018 SC_None, false/*isInlineSpecified*/, 5019 FD->hasPrototype(), 5020 false/*isConstexprSpecified*/); 5021 NewD = NewFD; 5022 5023 if (FD->getQualifier()) 5024 NewFD->setQualifierInfo(FD->getQualifierLoc()); 5025 5026 // Fake up parameter variables; they are declared as if this were 5027 // a typedef. 5028 QualType FDTy = FD->getType(); 5029 if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 5030 SmallVector<ParmVarDecl*, 16> Params; 5031 for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 5032 AE = FT->arg_type_end(); AI != AE; ++AI) { 5033 ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 5034 Param->setScopeInfo(0, Params.size()); 5035 Params.push_back(Param); 5036 } 5037 NewFD->setParams(Params); 5038 } 5039 } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 5040 NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 5041 VD->getInnerLocStart(), VD->getLocation(), II, 5042 VD->getType(), VD->getTypeSourceInfo(), 5043 VD->getStorageClass()); 5044 if (VD->getQualifier()) { 5045 VarDecl *NewVD = cast<VarDecl>(NewD); 5046 NewVD->setQualifierInfo(VD->getQualifierLoc()); 5047 } 5048 } 5049 return NewD; 5050} 5051 5052/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak 5053/// applied to it, possibly with an alias. 5054void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 5055 if (W.getUsed()) return; // only do this once 5056 W.setUsed(true); 5057 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 5058 IdentifierInfo *NDId = ND->getIdentifier(); 5059 NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 5060 NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 5061 NDId->getName())); 5062 NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 5063 WeakTopLevelDecl.push_back(NewD); 5064 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 5065 // to insert Decl at TU scope, sorry. 5066 DeclContext *SavedContext = CurContext; 5067 CurContext = Context.getTranslationUnitDecl(); 5068 PushOnScopeChains(NewD, S); 5069 CurContext = SavedContext; 5070 } else { // just add weak to existing 5071 ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 5072 } 5073} 5074 5075void Sema::ProcessPragmaWeak(Scope *S, Decl *D) { 5076 // It's valid to "forward-declare" #pragma weak, in which case we 5077 // have to do this. 5078 LoadExternalWeakUndeclaredIdentifiers(); 5079 if (!WeakUndeclaredIdentifiers.empty()) { 5080 NamedDecl *ND = NULL; 5081 if (VarDecl *VD = dyn_cast<VarDecl>(D)) 5082 if (VD->isExternC()) 5083 ND = VD; 5084 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 5085 if (FD->isExternC()) 5086 ND = FD; 5087 if (ND) { 5088 if (IdentifierInfo *Id = ND->getIdentifier()) { 5089 llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 5090 = WeakUndeclaredIdentifiers.find(Id); 5091 if (I != WeakUndeclaredIdentifiers.end()) { 5092 WeakInfo W = I->second; 5093 DeclApplyPragmaWeak(S, ND, W); 5094 WeakUndeclaredIdentifiers[Id] = W; 5095 } 5096 } 5097 } 5098 } 5099} 5100 5101/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 5102/// it, apply them to D. This is a bit tricky because PD can have attributes 5103/// specified in many different places, and we need to find and apply them all. 5104void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 5105 // Apply decl attributes from the DeclSpec if present. 5106 if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 5107 ProcessDeclAttributeList(S, D, Attrs); 5108 5109 // Walk the declarator structure, applying decl attributes that were in a type 5110 // position to the decl itself. This handles cases like: 5111 // int *__attr__(x)** D; 5112 // when X is a decl attribute. 5113 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 5114 if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 5115 ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false); 5116 5117 // Finally, apply any attributes on the decl itself. 5118 if (const AttributeList *Attrs = PD.getAttributes()) 5119 ProcessDeclAttributeList(S, D, Attrs); 5120} 5121 5122/// Is the given declaration allowed to use a forbidden type? 5123static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 5124 // Private ivars are always okay. Unfortunately, people don't 5125 // always properly make their ivars private, even in system headers. 5126 // Plus we need to make fields okay, too. 5127 // Function declarations in sys headers will be marked unavailable. 5128 if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 5129 !isa<FunctionDecl>(decl)) 5130 return false; 5131 5132 // Require it to be declared in a system header. 5133 return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 5134} 5135 5136/// Handle a delayed forbidden-type diagnostic. 5137static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 5138 Decl *decl) { 5139 if (decl && isForbiddenTypeAllowed(S, decl)) { 5140 decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 5141 "this system declaration uses an unsupported type")); 5142 return; 5143 } 5144 if (S.getLangOpts().ObjCAutoRefCount) 5145 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 5146 // FIXME: we may want to suppress diagnostics for all 5147 // kind of forbidden type messages on unavailable functions. 5148 if (FD->hasAttr<UnavailableAttr>() && 5149 diag.getForbiddenTypeDiagnostic() == 5150 diag::err_arc_array_param_no_ownership) { 5151 diag.Triggered = true; 5152 return; 5153 } 5154 } 5155 5156 S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 5157 << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 5158 diag.Triggered = true; 5159} 5160 5161void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { 5162 assert(DelayedDiagnostics.getCurrentPool()); 5163 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); 5164 DelayedDiagnostics.popWithoutEmitting(state); 5165 5166 // When delaying diagnostics to run in the context of a parsed 5167 // declaration, we only want to actually emit anything if parsing 5168 // succeeds. 5169 if (!decl) return; 5170 5171 // We emit all the active diagnostics in this pool or any of its 5172 // parents. In general, we'll get one pool for the decl spec 5173 // and a child pool for each declarator; in a decl group like: 5174 // deprecated_typedef foo, *bar, baz(); 5175 // only the declarator pops will be passed decls. This is correct; 5176 // we really do need to consider delayed diagnostics from the decl spec 5177 // for each of the different declarations. 5178 const DelayedDiagnosticPool *pool = &poppedPool; 5179 do { 5180 for (DelayedDiagnosticPool::pool_iterator 5181 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { 5182 // This const_cast is a bit lame. Really, Triggered should be mutable. 5183 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); 5184 if (diag.Triggered) 5185 continue; 5186 5187 switch (diag.Kind) { 5188 case DelayedDiagnostic::Deprecation: 5189 // Don't bother giving deprecation diagnostics if the decl is invalid. 5190 if (!decl->isInvalidDecl()) 5191 HandleDelayedDeprecationCheck(diag, decl); 5192 break; 5193 5194 case DelayedDiagnostic::Access: 5195 HandleDelayedAccessCheck(diag, decl); 5196 break; 5197 5198 case DelayedDiagnostic::ForbiddenType: 5199 handleDelayedForbiddenType(*this, diag, decl); 5200 break; 5201 } 5202 } 5203 } while ((pool = pool->getParent())); 5204} 5205 5206/// Given a set of delayed diagnostics, re-emit them as if they had 5207/// been delayed in the current context instead of in the given pool. 5208/// Essentially, this just moves them to the current pool. 5209void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { 5210 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); 5211 assert(curPool && "re-emitting in undelayed context not supported"); 5212 curPool->steal(pool); 5213} 5214 5215static bool isDeclDeprecated(Decl *D) { 5216 do { 5217 if (D->isDeprecated()) 5218 return true; 5219 // A category implicitly has the availability of the interface. 5220 if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 5221 return CatD->getClassInterface()->isDeprecated(); 5222 } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 5223 return false; 5224} 5225 5226static void 5227DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message, 5228 SourceLocation Loc, 5229 const ObjCInterfaceDecl *UnknownObjCClass, 5230 const ObjCPropertyDecl *ObjCPropery) { 5231 DeclarationName Name = D->getDeclName(); 5232 if (!Message.empty()) { 5233 S.Diag(Loc, diag::warn_deprecated_message) << Name << Message; 5234 S.Diag(D->getLocation(), 5235 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 5236 : diag::note_previous_decl) << Name; 5237 if (ObjCPropery) 5238 S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute) 5239 << ObjCPropery->getDeclName() << 0; 5240 } else if (!UnknownObjCClass) { 5241 S.Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 5242 S.Diag(D->getLocation(), 5243 isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 5244 : diag::note_previous_decl) << Name; 5245 if (ObjCPropery) 5246 S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute) 5247 << ObjCPropery->getDeclName() << 0; 5248 } else { 5249 S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name; 5250 S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 5251 } 5252} 5253 5254void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 5255 Decl *Ctx) { 5256 if (isDeclDeprecated(Ctx)) 5257 return; 5258 5259 DD.Triggered = true; 5260 DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(), 5261 DD.getDeprecationMessage(), DD.Loc, 5262 DD.getUnknownObjCClass(), 5263 DD.getObjCProperty()); 5264} 5265 5266void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 5267 SourceLocation Loc, 5268 const ObjCInterfaceDecl *UnknownObjCClass, 5269 const ObjCPropertyDecl *ObjCProperty) { 5270 // Delay if we're currently parsing a declaration. 5271 if (DelayedDiagnostics.shouldDelayDiagnostics()) { 5272 DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 5273 UnknownObjCClass, 5274 ObjCProperty, 5275 Message)); 5276 return; 5277 } 5278 5279 // Otherwise, don't warn if our current context is deprecated. 5280 if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 5281 return; 5282 DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty); 5283} 5284