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