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