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