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