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