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