1193326Sed//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements decl-related attribute processing. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14212904Sdim#include "clang/Sema/SemaInternal.h" 15193326Sed#include "clang/AST/ASTContext.h" 16239462Sdim#include "clang/AST/CXXInheritance.h" 17212904Sdim#include "clang/AST/DeclCXX.h" 18249423Sdim#include "clang/AST/DeclObjC.h" 19226633Sdim#include "clang/AST/DeclTemplate.h" 20193326Sed#include "clang/AST/Expr.h" 21276479Sdim#include "clang/AST/ExprCXX.h" 22249423Sdim#include "clang/AST/Mangle.h" 23288943Sdim#include "clang/AST/ASTMutationListener.h" 24249423Sdim#include "clang/Basic/CharInfo.h" 25224145Sdim#include "clang/Basic/SourceManager.h" 26193326Sed#include "clang/Basic/TargetInfo.h" 27261991Sdim#include "clang/Lex/Preprocessor.h" 28212904Sdim#include "clang/Sema/DeclSpec.h" 29212904Sdim#include "clang/Sema/DelayedDiagnostic.h" 30226633Sdim#include "clang/Sema/Lookup.h" 31249423Sdim#include "clang/Sema/Scope.h" 32198092Srdivacky#include "llvm/ADT/StringExtras.h" 33280031Sdim#include "llvm/Support/MathExtras.h" 34193326Sedusing namespace clang; 35212904Sdimusing namespace sema; 36193326Sed 37276479Sdimnamespace AttributeLangSupport { 38276479Sdim enum LANG { 39276479Sdim C, 40276479Sdim Cpp, 41276479Sdim ObjC 42276479Sdim }; 43276479Sdim} 44221345Sdim 45193326Sed//===----------------------------------------------------------------------===// 46193326Sed// Helper functions 47193326Sed//===----------------------------------------------------------------------===// 48193326Sed 49198092Srdivacky/// isFunctionOrMethod - Return true if the given decl has function 50193326Sed/// type (function or function-typed variable) or an Objective-C 51193326Sed/// method. 52224145Sdimstatic bool isFunctionOrMethod(const Decl *D) { 53276479Sdim return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D); 54193326Sed} 55288943Sdim/// \brief Return true if the given decl has function type (function or 56288943Sdim/// function-typed variable) or an Objective-C method or a block. 57288943Sdimstatic bool isFunctionOrMethodOrBlock(const Decl *D) { 58288943Sdim return isFunctionOrMethod(D) || isa<BlockDecl>(D); 59288943Sdim} 60193326Sed 61218893Sdim/// Return true if the given decl has a declarator that should have 62218893Sdim/// been processed by Sema::GetTypeForDeclarator. 63224145Sdimstatic bool hasDeclarator(const Decl *D) { 64224145Sdim // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 65224145Sdim return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 66224145Sdim isa<ObjCPropertyDecl>(D); 67218893Sdim} 68218893Sdim 69193326Sed/// hasFunctionProto - Return true if the given decl has a argument 70193326Sed/// information. This decl should have already passed 71193326Sed/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 72224145Sdimstatic bool hasFunctionProto(const Decl *D) { 73276479Sdim if (const FunctionType *FnTy = D->getFunctionType()) 74193326Sed return isa<FunctionProtoType>(FnTy); 75276479Sdim return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D); 76193326Sed} 77193326Sed 78276479Sdim/// getFunctionOrMethodNumParams - Return number of function or method 79276479Sdim/// parameters. It is an error to call this on a K&R function (use 80193326Sed/// hasFunctionProto first). 81276479Sdimstatic unsigned getFunctionOrMethodNumParams(const Decl *D) { 82276479Sdim if (const FunctionType *FnTy = D->getFunctionType()) 83276479Sdim return cast<FunctionProtoType>(FnTy)->getNumParams(); 84224145Sdim if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 85193326Sed return BD->getNumParams(); 86224145Sdim return cast<ObjCMethodDecl>(D)->param_size(); 87193326Sed} 88193326Sed 89276479Sdimstatic QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) { 90276479Sdim if (const FunctionType *FnTy = D->getFunctionType()) 91276479Sdim return cast<FunctionProtoType>(FnTy)->getParamType(Idx); 92224145Sdim if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 93193326Sed return BD->getParamDecl(Idx)->getType(); 94198092Srdivacky 95276479Sdim return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType(); 96193326Sed} 97193326Sed 98280031Sdimstatic SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) { 99280031Sdim if (const auto *FD = dyn_cast<FunctionDecl>(D)) 100280031Sdim return FD->getParamDecl(Idx)->getSourceRange(); 101280031Sdim if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) 102280031Sdim return MD->parameters()[Idx]->getSourceRange(); 103280031Sdim if (const auto *BD = dyn_cast<BlockDecl>(D)) 104280031Sdim return BD->getParamDecl(Idx)->getSourceRange(); 105280031Sdim return SourceRange(); 106280031Sdim} 107280031Sdim 108224145Sdimstatic QualType getFunctionOrMethodResultType(const Decl *D) { 109276479Sdim if (const FunctionType *FnTy = D->getFunctionType()) 110276479Sdim return cast<FunctionType>(FnTy)->getReturnType(); 111276479Sdim return cast<ObjCMethodDecl>(D)->getReturnType(); 112193326Sed} 113193326Sed 114280031Sdimstatic SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) { 115280031Sdim if (const auto *FD = dyn_cast<FunctionDecl>(D)) 116280031Sdim return FD->getReturnTypeSourceRange(); 117280031Sdim if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) 118280031Sdim return MD->getReturnTypeSourceRange(); 119280031Sdim return SourceRange(); 120280031Sdim} 121280031Sdim 122224145Sdimstatic bool isFunctionOrMethodVariadic(const Decl *D) { 123276479Sdim if (const FunctionType *FnTy = D->getFunctionType()) { 124193326Sed const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 125193326Sed return proto->isVariadic(); 126280031Sdim } 127280031Sdim if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 128207619Srdivacky return BD->isVariadic(); 129280031Sdim 130280031Sdim return cast<ObjCMethodDecl>(D)->isVariadic(); 131193326Sed} 132193326Sed 133224145Sdimstatic bool isInstanceMethod(const Decl *D) { 134224145Sdim if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 135218893Sdim return MethodDecl->isInstance(); 136218893Sdim return false; 137218893Sdim} 138218893Sdim 139193326Sedstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 140198092Srdivacky const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 141193326Sed if (!PT) 142193326Sed return false; 143198092Srdivacky 144208600Srdivacky ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 145208600Srdivacky if (!Cls) 146193326Sed return false; 147198092Srdivacky 148208600Srdivacky IdentifierInfo* ClsName = Cls->getIdentifier(); 149198092Srdivacky 150193326Sed // FIXME: Should we walk the chain of classes? 151193326Sed return ClsName == &Ctx.Idents.get("NSString") || 152193326Sed ClsName == &Ctx.Idents.get("NSMutableString"); 153193326Sed} 154193326Sed 155193326Sedstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 156198092Srdivacky const PointerType *PT = T->getAs<PointerType>(); 157193326Sed if (!PT) 158193326Sed return false; 159193326Sed 160198092Srdivacky const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 161193326Sed if (!RT) 162193326Sed return false; 163198092Srdivacky 164193326Sed const RecordDecl *RD = RT->getDecl(); 165208600Srdivacky if (RD->getTagKind() != TTK_Struct) 166193326Sed return false; 167193326Sed 168193326Sed return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 169193326Sed} 170193326Sed 171261991Sdimstatic unsigned getNumAttributeArgs(const AttributeList &Attr) { 172261991Sdim // FIXME: Include the type in the argument list. 173261991Sdim return Attr.getNumArgs() + Attr.hasParsedType(); 174261991Sdim} 175261991Sdim 176280031Sdimtemplate <typename Compare> 177280031Sdimstatic bool checkAttributeNumArgsImpl(Sema &S, const AttributeList &Attr, 178280031Sdim unsigned Num, unsigned Diag, 179280031Sdim Compare Comp) { 180280031Sdim if (Comp(getNumAttributeArgs(Attr), Num)) { 181280031Sdim S.Diag(Attr.getLoc(), Diag) << Attr.getName() << Num; 182224145Sdim return false; 183224145Sdim } 184224145Sdim 185224145Sdim return true; 186224145Sdim} 187224145Sdim 188280031Sdim/// \brief Check if the attribute has exactly as many args as Num. May 189280031Sdim/// output an error. 190280031Sdimstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 191280031Sdim unsigned Num) { 192280031Sdim return checkAttributeNumArgsImpl(S, Attr, Num, 193280031Sdim diag::err_attribute_wrong_number_arguments, 194280031Sdim std::not_equal_to<unsigned>()); 195280031Sdim} 196280031Sdim 197226633Sdim/// \brief Check if the attribute has at least as many args as Num. May 198226633Sdim/// output an error. 199226633Sdimstatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 200261991Sdim unsigned Num) { 201280031Sdim return checkAttributeNumArgsImpl(S, Attr, Num, 202280031Sdim diag::err_attribute_too_few_arguments, 203280031Sdim std::less<unsigned>()); 204280031Sdim} 205226633Sdim 206280031Sdim/// \brief Check if the attribute has at most as many args as Num. May 207280031Sdim/// output an error. 208280031Sdimstatic bool checkAttributeAtMostNumArgs(Sema &S, const AttributeList &Attr, 209280031Sdim unsigned Num) { 210280031Sdim return checkAttributeNumArgsImpl(S, Attr, Num, 211280031Sdim diag::err_attribute_too_many_arguments, 212280031Sdim std::greater<unsigned>()); 213226633Sdim} 214226633Sdim 215276479Sdim/// \brief If Expr is a valid integer constant, get the value of the integer 216276479Sdim/// expression and return success or failure. May output an error. 217276479Sdimstatic bool checkUInt32Argument(Sema &S, const AttributeList &Attr, 218276479Sdim const Expr *Expr, uint32_t &Val, 219276479Sdim unsigned Idx = UINT_MAX) { 220276479Sdim llvm::APSInt I(32); 221276479Sdim if (Expr->isTypeDependent() || Expr->isValueDependent() || 222276479Sdim !Expr->isIntegerConstantExpr(I, S.Context)) { 223276479Sdim if (Idx != UINT_MAX) 224276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 225276479Sdim << Attr.getName() << Idx << AANT_ArgumentIntegerConstant 226276479Sdim << Expr->getSourceRange(); 227276479Sdim else 228276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 229276479Sdim << Attr.getName() << AANT_ArgumentIntegerConstant 230276479Sdim << Expr->getSourceRange(); 231276479Sdim return false; 232276479Sdim } 233280031Sdim 234280031Sdim if (!I.isIntN(32)) { 235280031Sdim S.Diag(Expr->getExprLoc(), diag::err_ice_too_large) 236280031Sdim << I.toString(10, false) << 32 << /* Unsigned */ 1; 237280031Sdim return false; 238280031Sdim } 239280031Sdim 240276479Sdim Val = (uint32_t)I.getZExtValue(); 241276479Sdim return true; 242276479Sdim} 243276479Sdim 244276479Sdim/// \brief Diagnose mutually exclusive attributes when present on a given 245276479Sdim/// declaration. Returns true if diagnosed. 246276479Sdimtemplate <typename AttrTy> 247296417Sdimstatic bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range, 248296417Sdim IdentifierInfo *Ident) { 249276479Sdim if (AttrTy *A = D->getAttr<AttrTy>()) { 250296417Sdim S.Diag(Range.getBegin(), diag::err_attributes_are_not_compatible) << Ident 251296417Sdim << A; 252296417Sdim S.Diag(A->getLocation(), diag::note_conflicting_attribute); 253276479Sdim return true; 254276479Sdim } 255276479Sdim return false; 256276479Sdim} 257276479Sdim 258276479Sdim/// \brief Check if IdxExpr is a valid parameter index for a function or 259239462Sdim/// instance method D. May output an error. 260226633Sdim/// 261239462Sdim/// \returns true if IdxExpr is a valid index. 262276479Sdimstatic bool checkFunctionOrMethodParameterIndex(Sema &S, const Decl *D, 263276479Sdim const AttributeList &Attr, 264276479Sdim unsigned AttrArgNum, 265276479Sdim const Expr *IdxExpr, 266276479Sdim uint64_t &Idx) { 267288943Sdim assert(isFunctionOrMethodOrBlock(D)); 268239462Sdim 269239462Sdim // In C++ the implicit 'this' function parameter also counts. 270239462Sdim // Parameters are counted from one. 271261991Sdim bool HP = hasFunctionProto(D); 272261991Sdim bool HasImplicitThisParam = isInstanceMethod(D); 273261991Sdim bool IV = HP && isFunctionOrMethodVariadic(D); 274276479Sdim unsigned NumParams = 275276479Sdim (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam; 276239462Sdim 277239462Sdim llvm::APSInt IdxInt; 278239462Sdim if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 279239462Sdim !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { 280276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 281276479Sdim << Attr.getName() << AttrArgNum << AANT_ArgumentIntegerConstant 282276479Sdim << IdxExpr->getSourceRange(); 283239462Sdim return false; 284239462Sdim } 285239462Sdim 286239462Sdim Idx = IdxInt.getLimitedValue(); 287276479Sdim if (Idx < 1 || (!IV && Idx > NumParams)) { 288276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 289276479Sdim << Attr.getName() << AttrArgNum << IdxExpr->getSourceRange(); 290239462Sdim return false; 291239462Sdim } 292239462Sdim Idx--; // Convert to zero-based. 293239462Sdim if (HasImplicitThisParam) { 294239462Sdim if (Idx == 0) { 295276479Sdim S.Diag(Attr.getLoc(), 296239462Sdim diag::err_attribute_invalid_implicit_this_argument) 297276479Sdim << Attr.getName() << IdxExpr->getSourceRange(); 298239462Sdim return false; 299239462Sdim } 300239462Sdim --Idx; 301239462Sdim } 302239462Sdim 303239462Sdim return true; 304239462Sdim} 305239462Sdim 306261991Sdim/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal. 307261991Sdim/// If not emit an error and return false. If the argument is an identifier it 308261991Sdim/// will emit an error with a fixit hint and treat it as if it was a string 309261991Sdim/// literal. 310261991Sdimbool Sema::checkStringLiteralArgumentAttr(const AttributeList &Attr, 311261991Sdim unsigned ArgNum, StringRef &Str, 312261991Sdim SourceLocation *ArgLocation) { 313261991Sdim // Look for identifiers. If we have one emit a hint to fix it to a literal. 314261991Sdim if (Attr.isArgIdent(ArgNum)) { 315261991Sdim IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum); 316261991Sdim Diag(Loc->Loc, diag::err_attribute_argument_type) 317261991Sdim << Attr.getName() << AANT_ArgumentString 318261991Sdim << FixItHint::CreateInsertion(Loc->Loc, "\"") 319296417Sdim << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\""); 320261991Sdim Str = Loc->Ident->getName(); 321261991Sdim if (ArgLocation) 322261991Sdim *ArgLocation = Loc->Loc; 323261991Sdim return true; 324261991Sdim } 325261991Sdim 326261991Sdim // Now check for an actual string literal. 327261991Sdim Expr *ArgExpr = Attr.getArgAsExpr(ArgNum); 328261991Sdim StringLiteral *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts()); 329261991Sdim if (ArgLocation) 330261991Sdim *ArgLocation = ArgExpr->getLocStart(); 331261991Sdim 332261991Sdim if (!Literal || !Literal->isAscii()) { 333261991Sdim Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) 334261991Sdim << Attr.getName() << AANT_ArgumentString; 335261991Sdim return false; 336261991Sdim } 337261991Sdim 338261991Sdim Str = Literal->getString(); 339261991Sdim return true; 340261991Sdim} 341261991Sdim 342276479Sdim/// \brief Applies the given attribute to the Decl without performing any 343276479Sdim/// additional semantic checking. 344276479Sdimtemplate <typename AttrType> 345276479Sdimstatic void handleSimpleAttribute(Sema &S, Decl *D, 346276479Sdim const AttributeList &Attr) { 347276479Sdim D->addAttr(::new (S.Context) AttrType(Attr.getRange(), S.Context, 348276479Sdim Attr.getAttributeSpellingListIndex())); 349226633Sdim} 350226633Sdim 351296417Sdimtemplate <typename AttrType> 352296417Sdimstatic void handleSimpleAttributeWithExclusions(Sema &S, Decl *D, 353296417Sdim const AttributeList &Attr) { 354296417Sdim handleSimpleAttribute<AttrType>(S, D, Attr); 355296417Sdim} 356296417Sdim 357296417Sdim/// \brief Applies the given attribute to the Decl so long as the Decl doesn't 358296417Sdim/// already have one of the given incompatible attributes. 359296417Sdimtemplate <typename AttrType, typename IncompatibleAttrType, 360296417Sdim typename... IncompatibleAttrTypes> 361296417Sdimstatic void handleSimpleAttributeWithExclusions(Sema &S, Decl *D, 362296417Sdim const AttributeList &Attr) { 363296417Sdim if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, Attr.getRange(), 364296417Sdim Attr.getName())) 365296417Sdim return; 366296417Sdim handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D, 367296417Sdim Attr); 368296417Sdim} 369296417Sdim 370226633Sdim/// \brief Check if the passed-in expression is of type int or bool. 371226633Sdimstatic bool isIntOrBool(Expr *Exp) { 372226633Sdim QualType QT = Exp->getType(); 373226633Sdim return QT->isBooleanType() || QT->isIntegerType(); 374226633Sdim} 375226633Sdim 376239462Sdim 377239462Sdim// Check to see if the type is a smart pointer of some kind. We assume 378239462Sdim// it's a smart pointer if it defines both operator-> and operator*. 379239462Sdimstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { 380288943Sdim DeclContextLookupResult Res1 = RT->getDecl()->lookup( 381288943Sdim S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); 382249423Sdim if (Res1.empty()) 383239462Sdim return false; 384239462Sdim 385288943Sdim DeclContextLookupResult Res2 = RT->getDecl()->lookup( 386288943Sdim S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); 387249423Sdim if (Res2.empty()) 388239462Sdim return false; 389239462Sdim 390239462Sdim return true; 391239462Sdim} 392239462Sdim 393226633Sdim/// \brief Check if passed in Decl is a pointer type. 394226633Sdim/// Note that this function may produce an error message. 395226633Sdim/// \return true if the Decl is a pointer type; false otherwise 396239462Sdimstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 397239462Sdim const AttributeList &Attr) { 398276479Sdim const ValueDecl *vd = cast<ValueDecl>(D); 399276479Sdim QualType QT = vd->getType(); 400276479Sdim if (QT->isAnyPointerType()) 401276479Sdim return true; 402276479Sdim 403276479Sdim if (const RecordType *RT = QT->getAs<RecordType>()) { 404276479Sdim // If it's an incomplete type, it could be a smart pointer; skip it. 405276479Sdim // (We don't want to force template instantiation if we can avoid it, 406276479Sdim // since that would alter the order in which templates are instantiated.) 407276479Sdim if (RT->isIncompleteType()) 408226633Sdim return true; 409239462Sdim 410276479Sdim if (threadSafetyCheckIsSmartPointer(S, RT)) 411276479Sdim return true; 412276479Sdim } 413239462Sdim 414276479Sdim S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 415276479Sdim << Attr.getName() << QT; 416226633Sdim return false; 417226633Sdim} 418226633Sdim 419226633Sdim/// \brief Checks that the passed in QualType either is of RecordType or points 420226633Sdim/// to RecordType. Returns the relevant RecordType, null if it does not exit. 421226633Sdimstatic const RecordType *getRecordType(QualType QT) { 422226633Sdim if (const RecordType *RT = QT->getAs<RecordType>()) 423226633Sdim return RT; 424226633Sdim 425226633Sdim // Now check if we point to record type. 426226633Sdim if (const PointerType *PT = QT->getAs<PointerType>()) 427226633Sdim return PT->getPointeeType()->getAs<RecordType>(); 428226633Sdim 429276479Sdim return nullptr; 430226633Sdim} 431226633Sdim 432276479Sdimstatic bool checkRecordTypeForCapability(Sema &S, QualType Ty) { 433234353Sdim const RecordType *RT = getRecordType(Ty); 434239462Sdim 435276479Sdim if (!RT) 436276479Sdim return false; 437239462Sdim 438276479Sdim // Don't check for the capability if the class hasn't been defined yet. 439234353Sdim if (RT->isIncompleteType()) 440276479Sdim return true; 441239462Sdim 442276479Sdim // Allow smart pointers to be used as capability objects. 443239462Sdim // FIXME -- Check the type that the smart pointer points to. 444239462Sdim if (threadSafetyCheckIsSmartPointer(S, RT)) 445276479Sdim return true; 446239462Sdim 447276479Sdim // Check if the record itself has a capability. 448239462Sdim RecordDecl *RD = RT->getDecl(); 449276479Sdim if (RD->hasAttr<CapabilityAttr>()) 450276479Sdim return true; 451239462Sdim 452276479Sdim // Else check if any base classes have a capability. 453239462Sdim if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { 454239462Sdim CXXBasePaths BPaths(false, false); 455296417Sdim if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath &) { 456296417Sdim const auto *Type = BS->getType()->getAs<RecordType>(); 457296417Sdim return Type->getDecl()->hasAttr<CapabilityAttr>(); 458296417Sdim }, BPaths)) 459276479Sdim return true; 460226633Sdim } 461276479Sdim return false; 462276479Sdim} 463239462Sdim 464276479Sdimstatic bool checkTypedefTypeForCapability(QualType Ty) { 465276479Sdim const auto *TD = Ty->getAs<TypedefType>(); 466276479Sdim if (!TD) 467276479Sdim return false; 468276479Sdim 469276479Sdim TypedefNameDecl *TN = TD->getDecl(); 470276479Sdim if (!TN) 471276479Sdim return false; 472276479Sdim 473276479Sdim return TN->hasAttr<CapabilityAttr>(); 474226633Sdim} 475226633Sdim 476276479Sdimstatic bool typeHasCapability(Sema &S, QualType Ty) { 477276479Sdim if (checkTypedefTypeForCapability(Ty)) 478276479Sdim return true; 479276479Sdim 480276479Sdim if (checkRecordTypeForCapability(S, Ty)) 481276479Sdim return true; 482276479Sdim 483276479Sdim return false; 484276479Sdim} 485276479Sdim 486276479Sdimstatic bool isCapabilityExpr(Sema &S, const Expr *Ex) { 487276479Sdim // Capability expressions are simple expressions involving the boolean logic 488276479Sdim // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once 489276479Sdim // a DeclRefExpr is found, its type should be checked to determine whether it 490276479Sdim // is a capability or not. 491276479Sdim 492276479Sdim if (const auto *E = dyn_cast<DeclRefExpr>(Ex)) 493276479Sdim return typeHasCapability(S, E->getType()); 494276479Sdim else if (const auto *E = dyn_cast<CastExpr>(Ex)) 495276479Sdim return isCapabilityExpr(S, E->getSubExpr()); 496276479Sdim else if (const auto *E = dyn_cast<ParenExpr>(Ex)) 497276479Sdim return isCapabilityExpr(S, E->getSubExpr()); 498276479Sdim else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) { 499276479Sdim if (E->getOpcode() == UO_LNot) 500276479Sdim return isCapabilityExpr(S, E->getSubExpr()); 501276479Sdim return false; 502276479Sdim } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) { 503276479Sdim if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr) 504276479Sdim return isCapabilityExpr(S, E->getLHS()) && 505276479Sdim isCapabilityExpr(S, E->getRHS()); 506276479Sdim return false; 507276479Sdim } 508276479Sdim 509276479Sdim return false; 510276479Sdim} 511276479Sdim 512276479Sdim/// \brief Checks that all attribute arguments, starting from Sidx, resolve to 513276479Sdim/// a capability object. 514226633Sdim/// \param Sidx The attribute argument index to start checking with. 515226633Sdim/// \param ParamIdxOk Whether an argument can be indexing into a function 516226633Sdim/// parameter list. 517276479Sdimstatic void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D, 518276479Sdim const AttributeList &Attr, 519276479Sdim SmallVectorImpl<Expr *> &Args, 520276479Sdim int Sidx = 0, 521276479Sdim bool ParamIdxOk = false) { 522276479Sdim for (unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 523261991Sdim Expr *ArgExp = Attr.getArgAsExpr(Idx); 524226633Sdim 525226633Sdim if (ArgExp->isTypeDependent()) { 526239462Sdim // FIXME -- need to check this again on template instantiation 527226633Sdim Args.push_back(ArgExp); 528226633Sdim continue; 529226633Sdim } 530226633Sdim 531239462Sdim if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 532243830Sdim if (StrLit->getLength() == 0 || 533261991Sdim (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) { 534243830Sdim // Pass empty strings to the analyzer without warnings. 535243830Sdim // Treat "*" as the universal lock. 536243830Sdim Args.push_back(ArgExp); 537239462Sdim continue; 538243830Sdim } 539239462Sdim 540239462Sdim // We allow constant strings to be used as a placeholder for expressions 541239462Sdim // that are not valid C++ syntax, but warn that they are ignored. 542239462Sdim S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 543239462Sdim Attr.getName(); 544243830Sdim Args.push_back(ArgExp); 545239462Sdim continue; 546239462Sdim } 547239462Sdim 548226633Sdim QualType ArgTy = ArgExp->getType(); 549226633Sdim 550239462Sdim // A pointer to member expression of the form &MyClass::mu is treated 551239462Sdim // specially -- we need to look at the type of the member. 552239462Sdim if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 553239462Sdim if (UOp->getOpcode() == UO_AddrOf) 554239462Sdim if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 555239462Sdim if (DRE->getDecl()->isCXXInstanceMember()) 556239462Sdim ArgTy = DRE->getDecl()->getType(); 557239462Sdim 558276479Sdim // First see if we can just cast to record type, or pointer to record type. 559226633Sdim const RecordType *RT = getRecordType(ArgTy); 560226633Sdim 561226633Sdim // Now check if we index into a record type function param. 562226633Sdim if(!RT && ParamIdxOk) { 563226633Sdim FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 564226633Sdim IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 565226633Sdim if(FD && IL) { 566226633Sdim unsigned int NumParams = FD->getNumParams(); 567226633Sdim llvm::APInt ArgValue = IL->getValue(); 568226633Sdim uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 569226633Sdim uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 570226633Sdim if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 571226633Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 572226633Sdim << Attr.getName() << Idx + 1 << NumParams; 573239462Sdim continue; 574226633Sdim } 575226633Sdim ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 576226633Sdim } 577226633Sdim } 578226633Sdim 579276479Sdim // If the type does not have a capability, see if the components of the 580276479Sdim // expression have capabilities. This allows for writing C code where the 581276479Sdim // capability may be on the type, and the expression is a capability 582276479Sdim // boolean logic expression. Eg) requires_capability(A || B && !C) 583276479Sdim if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp)) 584276479Sdim S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 585276479Sdim << Attr.getName() << ArgTy; 586226633Sdim 587226633Sdim Args.push_back(ArgExp); 588226633Sdim } 589226633Sdim} 590226633Sdim 591193326Sed//===----------------------------------------------------------------------===// 592193326Sed// Attribute Implementations 593193326Sed//===----------------------------------------------------------------------===// 594193326Sed 595239462Sdimstatic void handlePtGuardedVarAttr(Sema &S, Decl *D, 596249423Sdim const AttributeList &Attr) { 597239462Sdim if (!threadSafetyCheckIsPointer(S, D, Attr)) 598239462Sdim return; 599239462Sdim 600249423Sdim D->addAttr(::new (S.Context) 601249423Sdim PtGuardedVarAttr(Attr.getRange(), S.Context, 602249423Sdim Attr.getAttributeSpellingListIndex())); 603239462Sdim} 604239462Sdim 605239462Sdimstatic bool checkGuardedByAttrCommon(Sema &S, Decl *D, 606239462Sdim const AttributeList &Attr, 607239462Sdim Expr* &Arg) { 608239462Sdim SmallVector<Expr*, 1> Args; 609239462Sdim // check that all arguments are lockable objects 610276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 611239462Sdim unsigned Size = Args.size(); 612239462Sdim if (Size != 1) 613239462Sdim return false; 614239462Sdim 615239462Sdim Arg = Args[0]; 616239462Sdim 617239462Sdim return true; 618239462Sdim} 619239462Sdim 620239462Sdimstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) { 621276479Sdim Expr *Arg = nullptr; 622239462Sdim if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 623226633Sdim return; 624226633Sdim 625276479Sdim D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg, 626276479Sdim Attr.getAttributeSpellingListIndex())); 627239462Sdim} 628226633Sdim 629239462Sdimstatic void handlePtGuardedByAttr(Sema &S, Decl *D, 630239462Sdim const AttributeList &Attr) { 631276479Sdim Expr *Arg = nullptr; 632239462Sdim if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 633239462Sdim return; 634239462Sdim 635239462Sdim if (!threadSafetyCheckIsPointer(S, D, Attr)) 636239462Sdim return; 637239462Sdim 638239462Sdim D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 639276479Sdim S.Context, Arg, 640276479Sdim Attr.getAttributeSpellingListIndex())); 641226633Sdim} 642226633Sdim 643239462Sdimstatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, 644239462Sdim const AttributeList &Attr, 645261991Sdim SmallVectorImpl<Expr *> &Args) { 646226633Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 647239462Sdim return false; 648226633Sdim 649239462Sdim // Check that this attribute only applies to lockable types. 650276479Sdim QualType QT = cast<ValueDecl>(D)->getType(); 651296417Sdim if (!QT->isDependentType() && !typeHasCapability(S, QT)) { 652296417Sdim S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 653296417Sdim << Attr.getName(); 654296417Sdim return false; 655226633Sdim } 656226633Sdim 657239462Sdim // Check that all arguments are lockable objects. 658276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 659251662Sdim if (Args.empty()) 660239462Sdim return false; 661239462Sdim 662239462Sdim return true; 663239462Sdim} 664239462Sdim 665239462Sdimstatic void handleAcquiredAfterAttr(Sema &S, Decl *D, 666239462Sdim const AttributeList &Attr) { 667226633Sdim SmallVector<Expr*, 1> Args; 668239462Sdim if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 669226633Sdim return; 670226633Sdim 671239462Sdim Expr **StartArg = &Args[0]; 672249423Sdim D->addAttr(::new (S.Context) 673249423Sdim AcquiredAfterAttr(Attr.getRange(), S.Context, 674249423Sdim StartArg, Args.size(), 675249423Sdim Attr.getAttributeSpellingListIndex())); 676239462Sdim} 677226633Sdim 678239462Sdimstatic void handleAcquiredBeforeAttr(Sema &S, Decl *D, 679239462Sdim const AttributeList &Attr) { 680239462Sdim SmallVector<Expr*, 1> Args; 681239462Sdim if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 682239462Sdim return; 683239462Sdim 684239462Sdim Expr **StartArg = &Args[0]; 685249423Sdim D->addAttr(::new (S.Context) 686249423Sdim AcquiredBeforeAttr(Attr.getRange(), S.Context, 687249423Sdim StartArg, Args.size(), 688249423Sdim Attr.getAttributeSpellingListIndex())); 689226633Sdim} 690226633Sdim 691239462Sdimstatic bool checkLockFunAttrCommon(Sema &S, Decl *D, 692239462Sdim const AttributeList &Attr, 693261991Sdim SmallVectorImpl<Expr *> &Args) { 694226633Sdim // zero or more arguments ok 695226633Sdim // check that all arguments are lockable objects 696276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 697239462Sdim 698239462Sdim return true; 699239462Sdim} 700239462Sdim 701261991Sdimstatic void handleAssertSharedLockAttr(Sema &S, Decl *D, 702261991Sdim const AttributeList &Attr) { 703261991Sdim SmallVector<Expr*, 1> Args; 704261991Sdim if (!checkLockFunAttrCommon(S, D, Attr, Args)) 705261991Sdim return; 706261991Sdim 707261991Sdim unsigned Size = Args.size(); 708276479Sdim Expr **StartArg = Size == 0 ? nullptr : &Args[0]; 709261991Sdim D->addAttr(::new (S.Context) 710261991Sdim AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size, 711261991Sdim Attr.getAttributeSpellingListIndex())); 712261991Sdim} 713261991Sdim 714261991Sdimstatic void handleAssertExclusiveLockAttr(Sema &S, Decl *D, 715261991Sdim const AttributeList &Attr) { 716261991Sdim SmallVector<Expr*, 1> Args; 717261991Sdim if (!checkLockFunAttrCommon(S, D, Attr, Args)) 718261991Sdim return; 719261991Sdim 720261991Sdim unsigned Size = Args.size(); 721276479Sdim Expr **StartArg = Size == 0 ? nullptr : &Args[0]; 722261991Sdim D->addAttr(::new (S.Context) 723261991Sdim AssertExclusiveLockAttr(Attr.getRange(), S.Context, 724261991Sdim StartArg, Size, 725261991Sdim Attr.getAttributeSpellingListIndex())); 726261991Sdim} 727261991Sdim 728261991Sdim 729239462Sdimstatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D, 730239462Sdim const AttributeList &Attr, 731261991Sdim SmallVectorImpl<Expr *> &Args) { 732226633Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 733239462Sdim return false; 734226633Sdim 735261991Sdim if (!isIntOrBool(Attr.getArgAsExpr(0))) { 736261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 737261991Sdim << Attr.getName() << 1 << AANT_ArgumentIntOrBool; 738239462Sdim return false; 739226633Sdim } 740226633Sdim 741239462Sdim // check that all arguments are lockable objects 742276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 1); 743239462Sdim 744239462Sdim return true; 745239462Sdim} 746239462Sdim 747239462Sdimstatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, 748239462Sdim const AttributeList &Attr) { 749226633Sdim SmallVector<Expr*, 2> Args; 750239462Sdim if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 751226633Sdim return; 752226633Sdim 753249423Sdim D->addAttr(::new (S.Context) 754249423Sdim SharedTrylockFunctionAttr(Attr.getRange(), S.Context, 755261991Sdim Attr.getArgAsExpr(0), 756261991Sdim Args.data(), Args.size(), 757249423Sdim Attr.getAttributeSpellingListIndex())); 758239462Sdim} 759226633Sdim 760239462Sdimstatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, 761239462Sdim const AttributeList &Attr) { 762239462Sdim SmallVector<Expr*, 2> Args; 763239462Sdim if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 764239462Sdim return; 765239462Sdim 766280031Sdim D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr( 767280031Sdim Attr.getRange(), S.Context, Attr.getArgAsExpr(0), Args.data(), 768280031Sdim Args.size(), Attr.getAttributeSpellingListIndex())); 769226633Sdim} 770226633Sdim 771226633Sdimstatic void handleLockReturnedAttr(Sema &S, Decl *D, 772226633Sdim const AttributeList &Attr) { 773226633Sdim // check that the argument is lockable object 774239462Sdim SmallVector<Expr*, 1> Args; 775276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 776239462Sdim unsigned Size = Args.size(); 777239462Sdim if (Size == 0) 778239462Sdim return; 779226633Sdim 780249423Sdim D->addAttr(::new (S.Context) 781249423Sdim LockReturnedAttr(Attr.getRange(), S.Context, Args[0], 782249423Sdim Attr.getAttributeSpellingListIndex())); 783226633Sdim} 784226633Sdim 785226633Sdimstatic void handleLocksExcludedAttr(Sema &S, Decl *D, 786226633Sdim const AttributeList &Attr) { 787226633Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 788226633Sdim return; 789226633Sdim 790226633Sdim // check that all arguments are lockable objects 791226633Sdim SmallVector<Expr*, 1> Args; 792276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 793239462Sdim unsigned Size = Args.size(); 794239462Sdim if (Size == 0) 795226633Sdim return; 796239462Sdim Expr **StartArg = &Args[0]; 797226633Sdim 798249423Sdim D->addAttr(::new (S.Context) 799249423Sdim LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size, 800249423Sdim Attr.getAttributeSpellingListIndex())); 801226633Sdim} 802226633Sdim 803276479Sdimstatic void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) { 804276479Sdim Expr *Cond = Attr.getArgAsExpr(0); 805276479Sdim if (!Cond->isTypeDependent()) { 806276479Sdim ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); 807276479Sdim if (Converted.isInvalid()) 808276479Sdim return; 809276479Sdim Cond = Converted.get(); 810276479Sdim } 811276479Sdim 812276479Sdim StringRef Msg; 813276479Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 1, Msg)) 814276479Sdim return; 815276479Sdim 816276479Sdim SmallVector<PartialDiagnosticAt, 8> Diags; 817276479Sdim if (!Cond->isValueDependent() && 818276479Sdim !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D), 819276479Sdim Diags)) { 820276479Sdim S.Diag(Attr.getLoc(), diag::err_enable_if_never_constant_expr); 821276479Sdim for (int I = 0, N = Diags.size(); I != N; ++I) 822276479Sdim S.Diag(Diags[I].first, Diags[I].second); 823276479Sdim return; 824276479Sdim } 825276479Sdim 826276479Sdim D->addAttr(::new (S.Context) 827276479Sdim EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg, 828276479Sdim Attr.getAttributeSpellingListIndex())); 829276479Sdim} 830276479Sdim 831296417Sdimstatic void handlePassObjectSizeAttr(Sema &S, Decl *D, 832296417Sdim const AttributeList &Attr) { 833296417Sdim if (D->hasAttr<PassObjectSizeAttr>()) { 834296417Sdim S.Diag(D->getLocStart(), diag::err_attribute_only_once_per_parameter) 835296417Sdim << Attr.getName(); 836296417Sdim return; 837296417Sdim } 838296417Sdim 839296417Sdim Expr *E = Attr.getArgAsExpr(0); 840296417Sdim uint32_t Type; 841296417Sdim if (!checkUInt32Argument(S, Attr, E, Type, /*Idx=*/1)) 842296417Sdim return; 843296417Sdim 844296417Sdim // pass_object_size's argument is passed in as the second argument of 845296417Sdim // __builtin_object_size. So, it has the same constraints as that second 846296417Sdim // argument; namely, it must be in the range [0, 3]. 847296417Sdim if (Type > 3) { 848296417Sdim S.Diag(E->getLocStart(), diag::err_attribute_argument_outof_range) 849296417Sdim << Attr.getName() << 0 << 3 << E->getSourceRange(); 850296417Sdim return; 851296417Sdim } 852296417Sdim 853296417Sdim // pass_object_size is only supported on constant pointer parameters; as a 854296417Sdim // kindness to users, we allow the parameter to be non-const for declarations. 855296417Sdim // At this point, we have no clue if `D` belongs to a function declaration or 856296417Sdim // definition, so we defer the constness check until later. 857296417Sdim if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) { 858296417Sdim S.Diag(D->getLocStart(), diag::err_attribute_pointers_only) 859296417Sdim << Attr.getName() << 1; 860296417Sdim return; 861296417Sdim } 862296417Sdim 863296417Sdim D->addAttr(::new (S.Context) 864296417Sdim PassObjectSizeAttr(Attr.getRange(), S.Context, (int)Type, 865296417Sdim Attr.getAttributeSpellingListIndex())); 866296417Sdim} 867296417Sdim 868261991Sdimstatic void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 869261991Sdim ConsumableAttr::ConsumedState DefaultState; 870226633Sdim 871261991Sdim if (Attr.isArgIdent(0)) { 872261991Sdim IdentifierLoc *IL = Attr.getArgAsIdent(0); 873261991Sdim if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(), 874261991Sdim DefaultState)) { 875261991Sdim S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) 876261991Sdim << Attr.getName() << IL->Ident; 877261991Sdim return; 878261991Sdim } 879261991Sdim } else { 880261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 881261991Sdim << Attr.getName() << AANT_ArgumentIdentifier; 882261991Sdim return; 883261991Sdim } 884261991Sdim 885261991Sdim D->addAttr(::new (S.Context) 886261991Sdim ConsumableAttr(Attr.getRange(), S.Context, DefaultState, 887261991Sdim Attr.getAttributeSpellingListIndex())); 888261991Sdim} 889261991Sdim 890276479Sdim 891261991Sdimstatic bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD, 892261991Sdim const AttributeList &Attr) { 893261991Sdim ASTContext &CurrContext = S.getASTContext(); 894261991Sdim QualType ThisType = MD->getThisType(CurrContext)->getPointeeType(); 895261991Sdim 896261991Sdim if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) { 897261991Sdim if (!RD->hasAttr<ConsumableAttr>()) { 898261991Sdim S.Diag(Attr.getLoc(), diag::warn_attr_on_unconsumable_class) << 899261991Sdim RD->getNameAsString(); 900261991Sdim 901261991Sdim return false; 902261991Sdim } 903261991Sdim } 904261991Sdim 905261991Sdim return true; 906261991Sdim} 907261991Sdim 908261991Sdim 909261991Sdimstatic void handleCallableWhenAttr(Sema &S, Decl *D, 910261991Sdim const AttributeList &Attr) { 911261991Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 912261991Sdim return; 913261991Sdim 914261991Sdim if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 915261991Sdim return; 916261991Sdim 917261991Sdim SmallVector<CallableWhenAttr::ConsumedState, 3> States; 918261991Sdim for (unsigned ArgIndex = 0; ArgIndex < Attr.getNumArgs(); ++ArgIndex) { 919261991Sdim CallableWhenAttr::ConsumedState CallableState; 920261991Sdim 921261991Sdim StringRef StateString; 922261991Sdim SourceLocation Loc; 923280031Sdim if (Attr.isArgIdent(ArgIndex)) { 924280031Sdim IdentifierLoc *Ident = Attr.getArgAsIdent(ArgIndex); 925280031Sdim StateString = Ident->Ident->getName(); 926280031Sdim Loc = Ident->Loc; 927280031Sdim } else { 928280031Sdim if (!S.checkStringLiteralArgumentAttr(Attr, ArgIndex, StateString, &Loc)) 929280031Sdim return; 930280031Sdim } 931261991Sdim 932261991Sdim if (!CallableWhenAttr::ConvertStrToConsumedState(StateString, 933261991Sdim CallableState)) { 934261991Sdim S.Diag(Loc, diag::warn_attribute_type_not_supported) 935261991Sdim << Attr.getName() << StateString; 936261991Sdim return; 937261991Sdim } 938261991Sdim 939261991Sdim States.push_back(CallableState); 940261991Sdim } 941261991Sdim 942261991Sdim D->addAttr(::new (S.Context) 943261991Sdim CallableWhenAttr(Attr.getRange(), S.Context, States.data(), 944261991Sdim States.size(), Attr.getAttributeSpellingListIndex())); 945261991Sdim} 946261991Sdim 947261991Sdim 948261991Sdimstatic void handleParamTypestateAttr(Sema &S, Decl *D, 949261991Sdim const AttributeList &Attr) { 950261991Sdim ParamTypestateAttr::ConsumedState ParamState; 951261991Sdim 952261991Sdim if (Attr.isArgIdent(0)) { 953261991Sdim IdentifierLoc *Ident = Attr.getArgAsIdent(0); 954261991Sdim StringRef StateString = Ident->Ident->getName(); 955261991Sdim 956261991Sdim if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString, 957261991Sdim ParamState)) { 958261991Sdim S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 959261991Sdim << Attr.getName() << StateString; 960261991Sdim return; 961261991Sdim } 962261991Sdim } else { 963261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 964261991Sdim Attr.getName() << AANT_ArgumentIdentifier; 965261991Sdim return; 966261991Sdim } 967261991Sdim 968261991Sdim // FIXME: This check is currently being done in the analysis. It can be 969261991Sdim // enabled here only after the parser propagates attributes at 970261991Sdim // template specialization definition, not declaration. 971261991Sdim //QualType ReturnType = cast<ParmVarDecl>(D)->getType(); 972261991Sdim //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); 973261991Sdim // 974261991Sdim //if (!RD || !RD->hasAttr<ConsumableAttr>()) { 975261991Sdim // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << 976261991Sdim // ReturnType.getAsString(); 977261991Sdim // return; 978261991Sdim //} 979261991Sdim 980261991Sdim D->addAttr(::new (S.Context) 981261991Sdim ParamTypestateAttr(Attr.getRange(), S.Context, ParamState, 982261991Sdim Attr.getAttributeSpellingListIndex())); 983261991Sdim} 984261991Sdim 985261991Sdim 986261991Sdimstatic void handleReturnTypestateAttr(Sema &S, Decl *D, 987261991Sdim const AttributeList &Attr) { 988261991Sdim ReturnTypestateAttr::ConsumedState ReturnState; 989261991Sdim 990261991Sdim if (Attr.isArgIdent(0)) { 991261991Sdim IdentifierLoc *IL = Attr.getArgAsIdent(0); 992261991Sdim if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(), 993261991Sdim ReturnState)) { 994261991Sdim S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) 995261991Sdim << Attr.getName() << IL->Ident; 996261991Sdim return; 997261991Sdim } 998261991Sdim } else { 999261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1000261991Sdim Attr.getName() << AANT_ArgumentIdentifier; 1001261991Sdim return; 1002261991Sdim } 1003261991Sdim 1004261991Sdim // FIXME: This check is currently being done in the analysis. It can be 1005261991Sdim // enabled here only after the parser propagates attributes at 1006261991Sdim // template specialization definition, not declaration. 1007261991Sdim //QualType ReturnType; 1008261991Sdim // 1009261991Sdim //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) { 1010261991Sdim // ReturnType = Param->getType(); 1011261991Sdim // 1012261991Sdim //} else if (const CXXConstructorDecl *Constructor = 1013261991Sdim // dyn_cast<CXXConstructorDecl>(D)) { 1014261991Sdim // ReturnType = Constructor->getThisType(S.getASTContext())->getPointeeType(); 1015261991Sdim // 1016261991Sdim //} else { 1017261991Sdim // 1018261991Sdim // ReturnType = cast<FunctionDecl>(D)->getCallResultType(); 1019261991Sdim //} 1020261991Sdim // 1021261991Sdim //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl(); 1022261991Sdim // 1023261991Sdim //if (!RD || !RD->hasAttr<ConsumableAttr>()) { 1024261991Sdim // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) << 1025261991Sdim // ReturnType.getAsString(); 1026261991Sdim // return; 1027261991Sdim //} 1028261991Sdim 1029261991Sdim D->addAttr(::new (S.Context) 1030261991Sdim ReturnTypestateAttr(Attr.getRange(), S.Context, ReturnState, 1031261991Sdim Attr.getAttributeSpellingListIndex())); 1032261991Sdim} 1033261991Sdim 1034261991Sdim 1035261991Sdimstatic void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1036261991Sdim if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 1037261991Sdim return; 1038261991Sdim 1039261991Sdim SetTypestateAttr::ConsumedState NewState; 1040261991Sdim if (Attr.isArgIdent(0)) { 1041261991Sdim IdentifierLoc *Ident = Attr.getArgAsIdent(0); 1042261991Sdim StringRef Param = Ident->Ident->getName(); 1043261991Sdim if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) { 1044261991Sdim S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 1045261991Sdim << Attr.getName() << Param; 1046261991Sdim return; 1047261991Sdim } 1048261991Sdim } else { 1049261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1050261991Sdim Attr.getName() << AANT_ArgumentIdentifier; 1051261991Sdim return; 1052261991Sdim } 1053261991Sdim 1054261991Sdim D->addAttr(::new (S.Context) 1055261991Sdim SetTypestateAttr(Attr.getRange(), S.Context, NewState, 1056261991Sdim Attr.getAttributeSpellingListIndex())); 1057261991Sdim} 1058261991Sdim 1059261991Sdimstatic void handleTestTypestateAttr(Sema &S, Decl *D, 1060261991Sdim const AttributeList &Attr) { 1061261991Sdim if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr)) 1062261991Sdim return; 1063261991Sdim 1064261991Sdim TestTypestateAttr::ConsumedState TestState; 1065261991Sdim if (Attr.isArgIdent(0)) { 1066261991Sdim IdentifierLoc *Ident = Attr.getArgAsIdent(0); 1067261991Sdim StringRef Param = Ident->Ident->getName(); 1068261991Sdim if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) { 1069261991Sdim S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) 1070261991Sdim << Attr.getName() << Param; 1071261991Sdim return; 1072261991Sdim } 1073261991Sdim } else { 1074261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << 1075261991Sdim Attr.getName() << AANT_ArgumentIdentifier; 1076261991Sdim return; 1077261991Sdim } 1078261991Sdim 1079261991Sdim D->addAttr(::new (S.Context) 1080261991Sdim TestTypestateAttr(Attr.getRange(), S.Context, TestState, 1081261991Sdim Attr.getAttributeSpellingListIndex())); 1082261991Sdim} 1083261991Sdim 1084224145Sdimstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 1085224145Sdim const AttributeList &Attr) { 1086249423Sdim // Remember this typedef decl, we will need it later for diagnostics. 1087276479Sdim S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D)); 1088193326Sed} 1089193326Sed 1090224145Sdimstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1091224145Sdim if (TagDecl *TD = dyn_cast<TagDecl>(D)) 1092276479Sdim TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context, 1093276479Sdim Attr.getAttributeSpellingListIndex())); 1094224145Sdim else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 1095296417Sdim // Report warning about changed offset in the newer compiler versions. 1096243830Sdim if (!FD->getType()->isDependentType() && 1097296417Sdim !FD->getType()->isIncompleteType() && FD->isBitField() && 1098193326Sed S.Context.getTypeAlign(FD->getType()) <= 8) 1099296417Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_packed_for_bitfield); 1100296417Sdim 1101296417Sdim FD->addAttr(::new (S.Context) PackedAttr( 1102296417Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 1103193326Sed } else 1104193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1105193326Sed} 1106193326Sed 1107226633Sdimstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 1108226633Sdim // The IBOutlet/IBOutletCollection attributes only apply to instance 1109226633Sdim // variables or properties of Objective-C classes. The outlet must also 1110226633Sdim // have an object reference type. 1111226633Sdim if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 1112226633Sdim if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 1113234353Sdim S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 1114226633Sdim << Attr.getName() << VD->getType() << 0; 1115226633Sdim return false; 1116226633Sdim } 1117226633Sdim } 1118226633Sdim else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 1119226633Sdim if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 1120234353Sdim S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 1121226633Sdim << Attr.getName() << PD->getType() << 1; 1122226633Sdim return false; 1123226633Sdim } 1124226633Sdim } 1125226633Sdim else { 1126226633Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 1127226633Sdim return false; 1128226633Sdim } 1129234353Sdim 1130226633Sdim return true; 1131226633Sdim} 1132226633Sdim 1133224145Sdimstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 1134226633Sdim if (!checkIBOutletCommon(S, D, Attr)) 1135204643Srdivacky return; 1136204643Srdivacky 1137249423Sdim D->addAttr(::new (S.Context) 1138249423Sdim IBOutletAttr(Attr.getRange(), S.Context, 1139249423Sdim Attr.getAttributeSpellingListIndex())); 1140193326Sed} 1141193326Sed 1142224145Sdimstatic void handleIBOutletCollection(Sema &S, Decl *D, 1143224145Sdim const AttributeList &Attr) { 1144208600Srdivacky 1145208600Srdivacky // The iboutletcollection attribute can have zero or one arguments. 1146261991Sdim if (Attr.getNumArgs() > 1) { 1147261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1148261991Sdim << Attr.getName() << 1; 1149208600Srdivacky return; 1150208600Srdivacky } 1151208600Srdivacky 1152226633Sdim if (!checkIBOutletCommon(S, D, Attr)) 1153208600Srdivacky return; 1154226633Sdim 1155261991Sdim ParsedType PT; 1156261991Sdim 1157261991Sdim if (Attr.hasParsedType()) 1158261991Sdim PT = Attr.getTypeArg(); 1159261991Sdim else { 1160261991Sdim PT = S.getTypeName(S.Context.Idents.get("NSObject"), Attr.getLoc(), 1161261991Sdim S.getScopeForContext(D->getDeclContext()->getParent())); 1162261991Sdim if (!PT) { 1163261991Sdim S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << "NSObject"; 1164261991Sdim return; 1165261991Sdim } 1166212904Sdim } 1167261991Sdim 1168276479Sdim TypeSourceInfo *QTLoc = nullptr; 1169261991Sdim QualType QT = S.GetTypeFromParser(PT, &QTLoc); 1170261991Sdim if (!QTLoc) 1171261991Sdim QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc()); 1172261991Sdim 1173212904Sdim // Diagnose use of non-object type in iboutletcollection attribute. 1174212904Sdim // FIXME. Gnu attribute extension ignores use of builtin types in 1175212904Sdim // attributes. So, __attribute__((iboutletcollection(char))) will be 1176212904Sdim // treated as __attribute__((iboutletcollection())). 1177234353Sdim if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 1178261991Sdim S.Diag(Attr.getLoc(), 1179261991Sdim QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype 1180261991Sdim : diag::err_iboutletcollection_type) << QT; 1181212904Sdim return; 1182212904Sdim } 1183261991Sdim 1184249423Sdim D->addAttr(::new (S.Context) 1185261991Sdim IBOutletCollectionAttr(Attr.getRange(), S.Context, QTLoc, 1186249423Sdim Attr.getAttributeSpellingListIndex())); 1187208600Srdivacky} 1188208600Srdivacky 1189280031Sdimbool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { 1190280031Sdim if (RefOkay) { 1191280031Sdim if (T->isReferenceType()) 1192280031Sdim return true; 1193280031Sdim } else { 1194280031Sdim T = T.getNonReferenceType(); 1195280031Sdim } 1196280031Sdim 1197280031Sdim // The nonnull attribute, and other similar attributes, can be applied to a 1198280031Sdim // transparent union that contains a pointer type. 1199280031Sdim if (const RecordType *UT = T->getAsUnionType()) { 1200224145Sdim if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 1201224145Sdim RecordDecl *UD = UT->getDecl(); 1202276479Sdim for (const auto *I : UD->fields()) { 1203276479Sdim QualType QT = I->getType(); 1204280031Sdim if (QT->isAnyPointerType() || QT->isBlockPointerType()) 1205280031Sdim return true; 1206224145Sdim } 1207224145Sdim } 1208280031Sdim } 1209280031Sdim 1210280031Sdim return T->isAnyPointerType() || T->isBlockPointerType(); 1211224145Sdim} 1212224145Sdim 1213276479Sdimstatic bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr, 1214280031Sdim SourceRange AttrParmRange, 1215280031Sdim SourceRange TypeRange, 1216280031Sdim bool isReturnValue = false) { 1217280031Sdim if (!S.isValidPointerAttrType(T)) { 1218296417Sdim if (isReturnValue) 1219296417Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only) 1220296417Sdim << Attr.getName() << AttrParmRange << TypeRange; 1221296417Sdim else 1222296417Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_pointers_only) 1223296417Sdim << Attr.getName() << AttrParmRange << TypeRange << 0; 1224276479Sdim return false; 1225239462Sdim } 1226276479Sdim return true; 1227239462Sdim} 1228239462Sdim 1229224145Sdimstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1230261991Sdim SmallVector<unsigned, 8> NonNullArgs; 1231280031Sdim for (unsigned I = 0; I < Attr.getNumArgs(); ++I) { 1232280031Sdim Expr *Ex = Attr.getArgAsExpr(I); 1233261991Sdim uint64_t Idx; 1234280031Sdim if (!checkFunctionOrMethodParameterIndex(S, D, Attr, I + 1, Ex, Idx)) 1235193326Sed return; 1236198092Srdivacky 1237193326Sed // Is the function argument a pointer type? 1238280031Sdim if (Idx < getFunctionOrMethodNumParams(D) && 1239280031Sdim !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr, 1240280031Sdim Ex->getSourceRange(), 1241280031Sdim getFunctionOrMethodParamRange(D, Idx))) 1242193326Sed continue; 1243198092Srdivacky 1244261991Sdim NonNullArgs.push_back(Idx); 1245193326Sed } 1246198092Srdivacky 1247198092Srdivacky // If no arguments were specified to __attribute__((nonnull)) then all pointer 1248280031Sdim // arguments have a nonnull attribute; warn if there aren't any. Skip this 1249280031Sdim // check if the attribute came from a macro expansion or a template 1250280031Sdim // instantiation. 1251280031Sdim if (NonNullArgs.empty() && Attr.getLoc().isFileID() && 1252280031Sdim S.ActiveTemplateInstantiations.empty()) { 1253280031Sdim bool AnyPointers = isFunctionOrMethodVariadic(D); 1254280031Sdim for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); 1255280031Sdim I != E && !AnyPointers; ++I) { 1256280031Sdim QualType T = getFunctionOrMethodParamType(D, I); 1257280031Sdim if (T->isDependentType() || S.isValidPointerAttrType(T)) 1258280031Sdim AnyPointers = true; 1259193326Sed } 1260198092Srdivacky 1261280031Sdim if (!AnyPointers) 1262280031Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 1263193326Sed } 1264193326Sed 1265280031Sdim unsigned *Start = NonNullArgs.data(); 1266280031Sdim unsigned Size = NonNullArgs.size(); 1267280031Sdim llvm::array_pod_sort(Start, Start + Size); 1268249423Sdim D->addAttr(::new (S.Context) 1269280031Sdim NonNullAttr(Attr.getRange(), S.Context, Start, Size, 1270249423Sdim Attr.getAttributeSpellingListIndex())); 1271193326Sed} 1272193326Sed 1273276479Sdimstatic void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, 1274276479Sdim const AttributeList &Attr) { 1275276479Sdim if (Attr.getNumArgs() > 0) { 1276276479Sdim if (D->getFunctionType()) { 1277276479Sdim handleNonNullAttr(S, D, Attr); 1278276479Sdim } else { 1279276479Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_parm_no_args) 1280276479Sdim << D->getSourceRange(); 1281276479Sdim } 1282276479Sdim return; 1283261991Sdim } 1284276479Sdim 1285276479Sdim // Is the argument a pointer type? 1286280031Sdim if (!attrNonNullArgCheck(S, D->getType(), Attr, SourceRange(), 1287280031Sdim D->getSourceRange())) 1288276479Sdim return; 1289276479Sdim 1290276479Sdim D->addAttr(::new (S.Context) 1291276479Sdim NonNullAttr(Attr.getRange(), S.Context, nullptr, 0, 1292276479Sdim Attr.getAttributeSpellingListIndex())); 1293261991Sdim} 1294261991Sdim 1295276479Sdimstatic void handleReturnsNonNullAttr(Sema &S, Decl *D, 1296276479Sdim const AttributeList &Attr) { 1297276479Sdim QualType ResultType = getFunctionOrMethodResultType(D); 1298280031Sdim SourceRange SR = getFunctionOrMethodResultSourceRange(D); 1299280031Sdim if (!attrNonNullArgCheck(S, ResultType, Attr, SourceRange(), SR, 1300276479Sdim /* isReturnValue */ true)) 1301276479Sdim return; 1302276479Sdim 1303276479Sdim D->addAttr(::new (S.Context) 1304276479Sdim ReturnsNonNullAttr(Attr.getRange(), S.Context, 1305276479Sdim Attr.getAttributeSpellingListIndex())); 1306276479Sdim} 1307276479Sdim 1308280031Sdimstatic void handleAssumeAlignedAttr(Sema &S, Decl *D, 1309280031Sdim const AttributeList &Attr) { 1310280031Sdim Expr *E = Attr.getArgAsExpr(0), 1311280031Sdim *OE = Attr.getNumArgs() > 1 ? Attr.getArgAsExpr(1) : nullptr; 1312280031Sdim S.AddAssumeAlignedAttr(Attr.getRange(), D, E, OE, 1313280031Sdim Attr.getAttributeSpellingListIndex()); 1314280031Sdim} 1315280031Sdim 1316280031Sdimvoid Sema::AddAssumeAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 1317280031Sdim Expr *OE, unsigned SpellingListIndex) { 1318280031Sdim QualType ResultType = getFunctionOrMethodResultType(D); 1319280031Sdim SourceRange SR = getFunctionOrMethodResultSourceRange(D); 1320280031Sdim 1321280031Sdim AssumeAlignedAttr TmpAttr(AttrRange, Context, E, OE, SpellingListIndex); 1322280031Sdim SourceLocation AttrLoc = AttrRange.getBegin(); 1323280031Sdim 1324280031Sdim if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) { 1325280031Sdim Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only) 1326280031Sdim << &TmpAttr << AttrRange << SR; 1327280031Sdim return; 1328280031Sdim } 1329280031Sdim 1330280031Sdim if (!E->isValueDependent()) { 1331280031Sdim llvm::APSInt I(64); 1332280031Sdim if (!E->isIntegerConstantExpr(I, Context)) { 1333280031Sdim if (OE) 1334280031Sdim Diag(AttrLoc, diag::err_attribute_argument_n_type) 1335280031Sdim << &TmpAttr << 1 << AANT_ArgumentIntegerConstant 1336280031Sdim << E->getSourceRange(); 1337280031Sdim else 1338280031Sdim Diag(AttrLoc, diag::err_attribute_argument_type) 1339280031Sdim << &TmpAttr << AANT_ArgumentIntegerConstant 1340280031Sdim << E->getSourceRange(); 1341280031Sdim return; 1342280031Sdim } 1343280031Sdim 1344280031Sdim if (!I.isPowerOf2()) { 1345280031Sdim Diag(AttrLoc, diag::err_alignment_not_power_of_two) 1346280031Sdim << E->getSourceRange(); 1347280031Sdim return; 1348280031Sdim } 1349280031Sdim } 1350280031Sdim 1351280031Sdim if (OE) { 1352280031Sdim if (!OE->isValueDependent()) { 1353280031Sdim llvm::APSInt I(64); 1354280031Sdim if (!OE->isIntegerConstantExpr(I, Context)) { 1355280031Sdim Diag(AttrLoc, diag::err_attribute_argument_n_type) 1356280031Sdim << &TmpAttr << 2 << AANT_ArgumentIntegerConstant 1357280031Sdim << OE->getSourceRange(); 1358280031Sdim return; 1359280031Sdim } 1360280031Sdim } 1361280031Sdim } 1362280031Sdim 1363280031Sdim D->addAttr(::new (Context) 1364280031Sdim AssumeAlignedAttr(AttrRange, Context, E, OE, SpellingListIndex)); 1365280031Sdim} 1366280031Sdim 1367296417Sdim/// Normalize the attribute, __foo__ becomes foo. 1368296417Sdim/// Returns true if normalization was applied. 1369296417Sdimstatic bool normalizeName(StringRef &AttrName) { 1370296417Sdim if (AttrName.size() > 4 && AttrName.startswith("__") && 1371296417Sdim AttrName.endswith("__")) { 1372296417Sdim AttrName = AttrName.drop_front(2).drop_back(2); 1373296417Sdim return true; 1374296417Sdim } 1375296417Sdim return false; 1376296417Sdim} 1377296417Sdim 1378224145Sdimstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 1379261991Sdim // This attribute must be applied to a function declaration. The first 1380261991Sdim // argument to the attribute must be an identifier, the name of the resource, 1381261991Sdim // for example: malloc. The following arguments must be argument indexes, the 1382261991Sdim // arguments must be of integer type for Returns, otherwise of pointer type. 1383212904Sdim // The difference between Holds and Takes is that a pointer may still be used 1384261991Sdim // after being held. free() should be __attribute((ownership_takes)), whereas 1385212904Sdim // a list append function may well be __attribute((ownership_holds)). 1386212904Sdim 1387261991Sdim if (!AL.isArgIdent(0)) { 1388261991Sdim S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type) 1389261991Sdim << AL.getName() << 1 << AANT_ArgumentIdentifier; 1390212904Sdim return; 1391212904Sdim } 1392261991Sdim 1393276479Sdim // Figure out our Kind. 1394276479Sdim OwnershipAttr::OwnershipKind K = 1395276479Sdim OwnershipAttr(AL.getLoc(), S.Context, nullptr, nullptr, 0, 1396276479Sdim AL.getAttributeSpellingListIndex()).getOwnKind(); 1397276479Sdim 1398276479Sdim // Check arguments. 1399276479Sdim switch (K) { 1400276479Sdim case OwnershipAttr::Takes: 1401276479Sdim case OwnershipAttr::Holds: 1402261991Sdim if (AL.getNumArgs() < 2) { 1403276479Sdim S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) 1404276479Sdim << AL.getName() << 2; 1405212904Sdim return; 1406212904Sdim } 1407212904Sdim break; 1408276479Sdim case OwnershipAttr::Returns: 1409261991Sdim if (AL.getNumArgs() > 2) { 1410276479Sdim S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) 1411276479Sdim << AL.getName() << 1; 1412212904Sdim return; 1413212904Sdim } 1414212904Sdim break; 1415212904Sdim } 1416212904Sdim 1417276479Sdim IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident; 1418212904Sdim 1419276479Sdim StringRef ModuleName = Module->getName(); 1420296417Sdim if (normalizeName(ModuleName)) { 1421276479Sdim Module = &S.PP.getIdentifierTable().get(ModuleName); 1422276479Sdim } 1423212904Sdim 1424261991Sdim SmallVector<unsigned, 8> OwnershipArgs; 1425261991Sdim for (unsigned i = 1; i < AL.getNumArgs(); ++i) { 1426261991Sdim Expr *Ex = AL.getArgAsExpr(i); 1427261991Sdim uint64_t Idx; 1428276479Sdim if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx)) 1429261991Sdim return; 1430212904Sdim 1431261991Sdim // Is the function argument a pointer type? 1432276479Sdim QualType T = getFunctionOrMethodParamType(D, Idx); 1433261991Sdim int Err = -1; // No error 1434212904Sdim switch (K) { 1435261991Sdim case OwnershipAttr::Takes: 1436261991Sdim case OwnershipAttr::Holds: 1437261991Sdim if (!T->isAnyPointerType() && !T->isBlockPointerType()) 1438261991Sdim Err = 0; 1439261991Sdim break; 1440261991Sdim case OwnershipAttr::Returns: 1441261991Sdim if (!T->isIntegerType()) 1442261991Sdim Err = 1; 1443261991Sdim break; 1444212904Sdim } 1445261991Sdim if (-1 != Err) { 1446261991Sdim S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err 1447261991Sdim << Ex->getSourceRange(); 1448261991Sdim return; 1449212904Sdim } 1450212904Sdim 1451212904Sdim // Check we don't have a conflict with another ownership attribute. 1452276479Sdim for (const auto *I : D->specific_attrs<OwnershipAttr>()) { 1453280031Sdim // Cannot have two ownership attributes of different kinds for the same 1454280031Sdim // index. 1455276479Sdim if (I->getOwnKind() != K && I->args_end() != 1456276479Sdim std::find(I->args_begin(), I->args_end(), Idx)) { 1457261991Sdim S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1458276479Sdim << AL.getName() << I; 1459261991Sdim return; 1460280031Sdim } else if (K == OwnershipAttr::Returns && 1461280031Sdim I->getOwnKind() == OwnershipAttr::Returns) { 1462280031Sdim // A returns attribute conflicts with any other returns attribute using 1463280031Sdim // a different index. Note, diagnostic reporting is 1-based, but stored 1464280031Sdim // argument indexes are 0-based. 1465280031Sdim if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) { 1466280031Sdim S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch) 1467280031Sdim << *(I->args_begin()) + 1; 1468280031Sdim if (I->args_size()) 1469280031Sdim S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch) 1470280031Sdim << (unsigned)Idx + 1 << Ex->getSourceRange(); 1471280031Sdim return; 1472280031Sdim } 1473212904Sdim } 1474212904Sdim } 1475261991Sdim OwnershipArgs.push_back(Idx); 1476212904Sdim } 1477212904Sdim 1478212904Sdim unsigned* start = OwnershipArgs.data(); 1479212904Sdim unsigned size = OwnershipArgs.size(); 1480212904Sdim llvm::array_pod_sort(start, start + size); 1481212904Sdim 1482249423Sdim D->addAttr(::new (S.Context) 1483276479Sdim OwnershipAttr(AL.getLoc(), S.Context, Module, start, size, 1484249423Sdim AL.getAttributeSpellingListIndex())); 1485212904Sdim} 1486212904Sdim 1487224145Sdimstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1488204643Srdivacky // Check the attribute arguments. 1489204643Srdivacky if (Attr.getNumArgs() > 1) { 1490261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1491261991Sdim << Attr.getName() << 1; 1492204643Srdivacky return; 1493204643Srdivacky } 1494204643Srdivacky 1495224145Sdim NamedDecl *nd = cast<NamedDecl>(D); 1496218893Sdim 1497204643Srdivacky // gcc rejects 1498204643Srdivacky // class c { 1499204643Srdivacky // static int a __attribute__((weakref ("v2"))); 1500204643Srdivacky // static int b() __attribute__((weakref ("f3"))); 1501204643Srdivacky // }; 1502204643Srdivacky // and ignores the attributes of 1503204643Srdivacky // void f(void) { 1504204643Srdivacky // static int a __attribute__((weakref ("v2"))); 1505204643Srdivacky // } 1506204643Srdivacky // we reject them 1507224145Sdim const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 1508212904Sdim if (!Ctx->isFileContext()) { 1509276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) 1510276479Sdim << nd; 1511212904Sdim return; 1512204643Srdivacky } 1513204643Srdivacky 1514204643Srdivacky // The GCC manual says 1515204643Srdivacky // 1516204643Srdivacky // At present, a declaration to which `weakref' is attached can only 1517204643Srdivacky // be `static'. 1518204643Srdivacky // 1519204643Srdivacky // It also says 1520204643Srdivacky // 1521204643Srdivacky // Without a TARGET, 1522204643Srdivacky // given as an argument to `weakref' or to `alias', `weakref' is 1523204643Srdivacky // equivalent to `weak'. 1524204643Srdivacky // 1525204643Srdivacky // gcc 4.4.1 will accept 1526204643Srdivacky // int a7 __attribute__((weakref)); 1527204643Srdivacky // as 1528204643Srdivacky // int a7 __attribute__((weak)); 1529204643Srdivacky // This looks like a bug in gcc. We reject that for now. We should revisit 1530204643Srdivacky // it if this behaviour is actually used. 1531204643Srdivacky 1532204643Srdivacky // GCC rejects 1533204643Srdivacky // static ((alias ("y"), weakref)). 1534204643Srdivacky // Should we? How to check that weakref is before or after alias? 1535204643Srdivacky 1536261991Sdim // FIXME: it would be good for us to keep the WeakRefAttr as-written instead 1537261991Sdim // of transforming it into an AliasAttr. The WeakRefAttr never uses the 1538261991Sdim // StringRef parameter it was given anyway. 1539261991Sdim StringRef Str; 1540261991Sdim if (Attr.getNumArgs() && S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 1541204643Srdivacky // GCC will accept anything as the argument of weakref. Should we 1542204643Srdivacky // check for an existing decl? 1543261991Sdim D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, 1544261991Sdim Attr.getAttributeSpellingListIndex())); 1545204643Srdivacky 1546249423Sdim D->addAttr(::new (S.Context) 1547249423Sdim WeakRefAttr(Attr.getRange(), S.Context, 1548249423Sdim Attr.getAttributeSpellingListIndex())); 1549204643Srdivacky} 1550204643Srdivacky 1551224145Sdimstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1552261991Sdim StringRef Str; 1553261991Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 1554193326Sed return; 1555198092Srdivacky 1556226633Sdim if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1557218893Sdim S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1558218893Sdim return; 1559218893Sdim } 1560218893Sdim 1561288943Sdim // Aliases should be on declarations, not definitions. 1562288943Sdim if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 1563288943Sdim if (FD->isThisDeclarationADefinition()) { 1564288943Sdim S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << FD; 1565288943Sdim return; 1566288943Sdim } 1567288943Sdim } else { 1568288943Sdim const auto *VD = cast<VarDecl>(D); 1569288943Sdim if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) { 1570288943Sdim S.Diag(Attr.getLoc(), diag::err_alias_is_definition) << VD; 1571288943Sdim return; 1572288943Sdim } 1573288943Sdim } 1574288943Sdim 1575193326Sed // FIXME: check if target symbol exists in current file 1576198092Srdivacky 1577261991Sdim D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, 1578249423Sdim Attr.getAttributeSpellingListIndex())); 1579193326Sed} 1580193326Sed 1581239462Sdimstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1582296417Sdim if (checkAttrMutualExclusion<HotAttr>(S, D, Attr.getRange(), Attr.getName())) 1583239462Sdim return; 1584239462Sdim 1585249423Sdim D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context, 1586249423Sdim Attr.getAttributeSpellingListIndex())); 1587239462Sdim} 1588239462Sdim 1589239462Sdimstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1590296417Sdim if (checkAttrMutualExclusion<ColdAttr>(S, D, Attr.getRange(), Attr.getName())) 1591239462Sdim return; 1592239462Sdim 1593249423Sdim D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context, 1594249423Sdim Attr.getAttributeSpellingListIndex())); 1595239462Sdim} 1596239462Sdim 1597239462Sdimstatic void handleTLSModelAttr(Sema &S, Decl *D, 1598239462Sdim const AttributeList &Attr) { 1599261991Sdim StringRef Model; 1600261991Sdim SourceLocation LiteralLoc; 1601239462Sdim // Check that it is a string. 1602261991Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc)) 1603239462Sdim return; 1604239462Sdim 1605239462Sdim // Check that the value. 1606239462Sdim if (Model != "global-dynamic" && Model != "local-dynamic" 1607239462Sdim && Model != "initial-exec" && Model != "local-exec") { 1608261991Sdim S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg); 1609239462Sdim return; 1610239462Sdim } 1611239462Sdim 1612249423Sdim D->addAttr(::new (S.Context) 1613249423Sdim TLSModelAttr(Attr.getRange(), S.Context, Model, 1614249423Sdim Attr.getAttributeSpellingListIndex())); 1615239462Sdim} 1616239462Sdim 1617288943Sdimstatic void handleRestrictAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1618288943Sdim QualType ResultType = getFunctionOrMethodResultType(D); 1619288943Sdim if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) { 1620288943Sdim D->addAttr(::new (S.Context) RestrictAttr( 1621288943Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 1622288943Sdim return; 1623198092Srdivacky } 1624198092Srdivacky 1625288943Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only) 1626288943Sdim << Attr.getName() << getFunctionOrMethodResultSourceRange(D); 1627198092Srdivacky} 1628198092Srdivacky 1629224145Sdimstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1630261991Sdim if (S.LangOpts.CPlusPlus) { 1631276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) 1632296417Sdim << Attr.getName() << AttributeLangSupport::Cpp; 1633261991Sdim return; 1634261991Sdim } 1635261991Sdim 1636296417Sdim if (CommonAttr *CA = S.mergeCommonAttr(D, Attr.getRange(), Attr.getName(), 1637296417Sdim Attr.getAttributeSpellingListIndex())) 1638296417Sdim D->addAttr(CA); 1639218893Sdim} 1640218893Sdim 1641296417Sdimstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1642296417Sdim if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, Attr.getRange(), 1643296417Sdim Attr.getName())) 1644296417Sdim return; 1645296417Sdim 1646296417Sdim D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context, 1647296417Sdim Attr.getAttributeSpellingListIndex())); 1648296417Sdim} 1649296417Sdim 1650224145Sdimstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 1651224145Sdim if (hasDeclarator(D)) return; 1652218893Sdim 1653218893Sdim if (S.CheckNoReturnAttr(attr)) return; 1654218893Sdim 1655224145Sdim if (!isa<ObjCMethodDecl>(D)) { 1656218893Sdim S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1657221345Sdim << attr.getName() << ExpectedFunctionOrMethod; 1658218893Sdim return; 1659218893Sdim } 1660218893Sdim 1661249423Sdim D->addAttr(::new (S.Context) 1662249423Sdim NoReturnAttr(attr.getRange(), S.Context, 1663249423Sdim attr.getAttributeSpellingListIndex())); 1664218893Sdim} 1665218893Sdim 1666218893Sdimbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1667261991Sdim if (!checkAttributeNumArgs(*this, attr, 0)) { 1668218893Sdim attr.setInvalid(); 1669218893Sdim return true; 1670218893Sdim } 1671218893Sdim 1672218893Sdim return false; 1673218893Sdim} 1674218893Sdim 1675224145Sdimstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 1676224145Sdim const AttributeList &Attr) { 1677212904Sdim 1678212904Sdim // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1679212904Sdim // because 'analyzer_noreturn' does not impact the type. 1680288943Sdim if (!isFunctionOrMethodOrBlock(D)) { 1681224145Sdim ValueDecl *VD = dyn_cast<ValueDecl>(D); 1682276479Sdim if (!VD || (!VD->getType()->isBlockPointerType() && 1683276479Sdim !VD->getType()->isFunctionPointerType())) { 1684199990Srdivacky S.Diag(Attr.getLoc(), 1685249423Sdim Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type 1686296417Sdim : diag::warn_attribute_wrong_decl_type) 1687221345Sdim << Attr.getName() << ExpectedFunctionMethodOrBlock; 1688212904Sdim return; 1689193326Sed } 1690193326Sed } 1691212904Sdim 1692249423Sdim D->addAttr(::new (S.Context) 1693249423Sdim AnalyzerNoReturnAttr(Attr.getRange(), S.Context, 1694249423Sdim Attr.getAttributeSpellingListIndex())); 1695193326Sed} 1696193326Sed 1697212904Sdim// PS3 PPU-specific. 1698224145Sdimstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1699212904Sdim/* 1700212904Sdim Returning a Vector Class in Registers 1701212904Sdim 1702218893Sdim According to the PPU ABI specifications, a class with a single member of 1703218893Sdim vector type is returned in memory when used as the return value of a function. 1704218893Sdim This results in inefficient code when implementing vector classes. To return 1705218893Sdim the value in a single vector register, add the vecreturn attribute to the 1706218893Sdim class definition. This attribute is also applicable to struct types. 1707212904Sdim 1708212904Sdim Example: 1709212904Sdim 1710212904Sdim struct Vector 1711212904Sdim { 1712212904Sdim __vector float xyzw; 1713212904Sdim } __attribute__((vecreturn)); 1714212904Sdim 1715212904Sdim Vector Add(Vector lhs, Vector rhs) 1716212904Sdim { 1717212904Sdim Vector result; 1718212904Sdim result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 1719212904Sdim return result; // This will be returned in a register 1720212904Sdim } 1721212904Sdim*/ 1722276479Sdim if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) { 1723276479Sdim S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << A; 1724212904Sdim return; 1725212904Sdim } 1726193326Sed 1727224145Sdim RecordDecl *record = cast<RecordDecl>(D); 1728218893Sdim int count = 0; 1729218893Sdim 1730218893Sdim if (!isa<CXXRecordDecl>(record)) { 1731218893Sdim S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 1732218893Sdim return; 1733218893Sdim } 1734218893Sdim 1735218893Sdim if (!cast<CXXRecordDecl>(record)->isPOD()) { 1736218893Sdim S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 1737218893Sdim return; 1738218893Sdim } 1739218893Sdim 1740276479Sdim for (const auto *I : record->fields()) { 1741276479Sdim if ((count == 1) || !I->getType()->isVectorType()) { 1742218893Sdim S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 1743218893Sdim return; 1744218893Sdim } 1745218893Sdim count++; 1746218893Sdim } 1747218893Sdim 1748249423Sdim D->addAttr(::new (S.Context) 1749249423Sdim VecReturnAttr(Attr.getRange(), S.Context, 1750249423Sdim Attr.getAttributeSpellingListIndex())); 1751193326Sed} 1752193326Sed 1753249423Sdimstatic void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D, 1754249423Sdim const AttributeList &Attr) { 1755249423Sdim if (isa<ParmVarDecl>(D)) { 1756249423Sdim // [[carries_dependency]] can only be applied to a parameter if it is a 1757249423Sdim // parameter of a function declaration or lambda. 1758249423Sdim if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) { 1759249423Sdim S.Diag(Attr.getLoc(), 1760249423Sdim diag::err_carries_dependency_param_not_function_decl); 1761249423Sdim return; 1762249423Sdim } 1763199990Srdivacky } 1764249423Sdim 1765249423Sdim D->addAttr(::new (S.Context) CarriesDependencyAttr( 1766249423Sdim Attr.getRange(), S.Context, 1767249423Sdim Attr.getAttributeSpellingListIndex())); 1768199990Srdivacky} 1769199990Srdivacky 1770296417Sdimstatic void handleNotTailCalledAttr(Sema &S, Decl *D, 1771296417Sdim const AttributeList &Attr) { 1772296417Sdim if (checkAttrMutualExclusion<AlwaysInlineAttr>(S, D, Attr.getRange(), 1773296417Sdim Attr.getName())) 1774296417Sdim return; 1775296417Sdim 1776296417Sdim D->addAttr(::new (S.Context) NotTailCalledAttr( 1777296417Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 1778296417Sdim} 1779296417Sdim 1780296417Sdimstatic void handleDisableTailCallsAttr(Sema &S, Decl *D, 1781296417Sdim const AttributeList &Attr) { 1782296417Sdim if (checkAttrMutualExclusion<NakedAttr>(S, D, Attr.getRange(), 1783296417Sdim Attr.getName())) 1784296417Sdim return; 1785296417Sdim 1786296417Sdim D->addAttr(::new (S.Context) DisableTailCallsAttr( 1787296417Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 1788296417Sdim} 1789296417Sdim 1790224145Sdimstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1791224145Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1792261991Sdim if (VD->hasLocalStorage()) { 1793276479Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1794193326Sed return; 1795193326Sed } 1796224145Sdim } else if (!isFunctionOrMethod(D)) { 1797193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1798221345Sdim << Attr.getName() << ExpectedVariableOrFunction; 1799193326Sed return; 1800193326Sed } 1801198092Srdivacky 1802249423Sdim D->addAttr(::new (S.Context) 1803249423Sdim UsedAttr(Attr.getRange(), S.Context, 1804249423Sdim Attr.getAttributeSpellingListIndex())); 1805193326Sed} 1806193326Sed 1807224145Sdimstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1808276479Sdim uint32_t priority = ConstructorAttr::DefaultPriority; 1809280031Sdim if (Attr.getNumArgs() && 1810276479Sdim !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority)) 1811193326Sed return; 1812193326Sed 1813249423Sdim D->addAttr(::new (S.Context) 1814249423Sdim ConstructorAttr(Attr.getRange(), S.Context, priority, 1815249423Sdim Attr.getAttributeSpellingListIndex())); 1816193326Sed} 1817193326Sed 1818224145Sdimstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1819276479Sdim uint32_t priority = DestructorAttr::DefaultPriority; 1820280031Sdim if (Attr.getNumArgs() && 1821276479Sdim !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority)) 1822193326Sed return; 1823193326Sed 1824249423Sdim D->addAttr(::new (S.Context) 1825249423Sdim DestructorAttr(Attr.getRange(), S.Context, priority, 1826249423Sdim Attr.getAttributeSpellingListIndex())); 1827193326Sed} 1828193326Sed 1829239462Sdimtemplate <typename AttrTy> 1830261991Sdimstatic void handleAttrWithMessage(Sema &S, Decl *D, 1831261991Sdim const AttributeList &Attr) { 1832239462Sdim // Handle the case where the attribute has a text message. 1833226633Sdim StringRef Str; 1834280031Sdim if (Attr.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 1835261991Sdim return; 1836198092Srdivacky 1837249423Sdim D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str, 1838249423Sdim Attr.getAttributeSpellingListIndex())); 1839193326Sed} 1840193326Sed 1841276479Sdimstatic void handleObjCSuppresProtocolAttr(Sema &S, Decl *D, 1842276479Sdim const AttributeList &Attr) { 1843276479Sdim if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) { 1844276479Sdim S.Diag(Attr.getLoc(), diag::err_objc_attr_protocol_requires_definition) 1845276479Sdim << Attr.getName() << Attr.getRange(); 1846234353Sdim return; 1847234353Sdim } 1848234353Sdim 1849249423Sdim D->addAttr(::new (S.Context) 1850276479Sdim ObjCExplicitProtocolImplAttr(Attr.getRange(), S.Context, 1851276479Sdim Attr.getAttributeSpellingListIndex())); 1852234353Sdim} 1853234353Sdim 1854239462Sdimstatic bool checkAvailabilityAttr(Sema &S, SourceRange Range, 1855239462Sdim IdentifierInfo *Platform, 1856239462Sdim VersionTuple Introduced, 1857239462Sdim VersionTuple Deprecated, 1858239462Sdim VersionTuple Obsoleted) { 1859239462Sdim StringRef PlatformName 1860239462Sdim = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 1861239462Sdim if (PlatformName.empty()) 1862239462Sdim PlatformName = Platform->getName(); 1863239462Sdim 1864239462Sdim // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 1865239462Sdim // of these steps are needed). 1866239462Sdim if (!Introduced.empty() && !Deprecated.empty() && 1867239462Sdim !(Introduced <= Deprecated)) { 1868239462Sdim S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 1869239462Sdim << 1 << PlatformName << Deprecated.getAsString() 1870239462Sdim << 0 << Introduced.getAsString(); 1871239462Sdim return true; 1872239462Sdim } 1873239462Sdim 1874239462Sdim if (!Introduced.empty() && !Obsoleted.empty() && 1875239462Sdim !(Introduced <= Obsoleted)) { 1876239462Sdim S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 1877239462Sdim << 2 << PlatformName << Obsoleted.getAsString() 1878239462Sdim << 0 << Introduced.getAsString(); 1879239462Sdim return true; 1880239462Sdim } 1881239462Sdim 1882239462Sdim if (!Deprecated.empty() && !Obsoleted.empty() && 1883239462Sdim !(Deprecated <= Obsoleted)) { 1884239462Sdim S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 1885239462Sdim << 2 << PlatformName << Obsoleted.getAsString() 1886239462Sdim << 1 << Deprecated.getAsString(); 1887239462Sdim return true; 1888239462Sdim } 1889239462Sdim 1890239462Sdim return false; 1891239462Sdim} 1892239462Sdim 1893249423Sdim/// \brief Check whether the two versions match. 1894249423Sdim/// 1895249423Sdim/// If either version tuple is empty, then they are assumed to match. If 1896249423Sdim/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y. 1897249423Sdimstatic bool versionsMatch(const VersionTuple &X, const VersionTuple &Y, 1898249423Sdim bool BeforeIsOkay) { 1899249423Sdim if (X.empty() || Y.empty()) 1900249423Sdim return true; 1901249423Sdim 1902249423Sdim if (X == Y) 1903249423Sdim return true; 1904249423Sdim 1905249423Sdim if (BeforeIsOkay && X < Y) 1906249423Sdim return true; 1907249423Sdim 1908249423Sdim return false; 1909249423Sdim} 1910249423Sdim 1911249423SdimAvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, 1912239462Sdim IdentifierInfo *Platform, 1913239462Sdim VersionTuple Introduced, 1914239462Sdim VersionTuple Deprecated, 1915239462Sdim VersionTuple Obsoleted, 1916239462Sdim bool IsUnavailable, 1917249423Sdim StringRef Message, 1918296417Sdim AvailabilityMergeKind AMK, 1919249423Sdim unsigned AttrSpellingListIndex) { 1920239462Sdim VersionTuple MergedIntroduced = Introduced; 1921239462Sdim VersionTuple MergedDeprecated = Deprecated; 1922239462Sdim VersionTuple MergedObsoleted = Obsoleted; 1923239462Sdim bool FoundAny = false; 1924296417Sdim bool OverrideOrImpl = false; 1925296417Sdim switch (AMK) { 1926296417Sdim case AMK_None: 1927296417Sdim case AMK_Redeclaration: 1928296417Sdim OverrideOrImpl = false; 1929296417Sdim break; 1930239462Sdim 1931296417Sdim case AMK_Override: 1932296417Sdim case AMK_ProtocolImplementation: 1933296417Sdim OverrideOrImpl = true; 1934296417Sdim break; 1935296417Sdim } 1936296417Sdim 1937239462Sdim if (D->hasAttrs()) { 1938239462Sdim AttrVec &Attrs = D->getAttrs(); 1939239462Sdim for (unsigned i = 0, e = Attrs.size(); i != e;) { 1940239462Sdim const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); 1941239462Sdim if (!OldAA) { 1942239462Sdim ++i; 1943239462Sdim continue; 1944239462Sdim } 1945239462Sdim 1946239462Sdim IdentifierInfo *OldPlatform = OldAA->getPlatform(); 1947239462Sdim if (OldPlatform != Platform) { 1948239462Sdim ++i; 1949239462Sdim continue; 1950239462Sdim } 1951239462Sdim 1952296417Sdim // If there is an existing availability attribute for this platform that 1953296417Sdim // is explicit and the new one is implicit use the explicit one and 1954296417Sdim // discard the new implicit attribute. 1955296417Sdim if (OldAA->getRange().isValid() && Range.isInvalid()) { 1956296417Sdim return nullptr; 1957296417Sdim } 1958296417Sdim 1959296417Sdim // If there is an existing attribute for this platform that is implicit 1960296417Sdim // and the new attribute is explicit then erase the old one and 1961296417Sdim // continue processing the attributes. 1962296417Sdim if (Range.isValid() && OldAA->getRange().isInvalid()) { 1963296417Sdim Attrs.erase(Attrs.begin() + i); 1964296417Sdim --e; 1965296417Sdim continue; 1966296417Sdim } 1967296417Sdim 1968239462Sdim FoundAny = true; 1969239462Sdim VersionTuple OldIntroduced = OldAA->getIntroduced(); 1970239462Sdim VersionTuple OldDeprecated = OldAA->getDeprecated(); 1971239462Sdim VersionTuple OldObsoleted = OldAA->getObsoleted(); 1972239462Sdim bool OldIsUnavailable = OldAA->getUnavailable(); 1973239462Sdim 1974296417Sdim if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) || 1975296417Sdim !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) || 1976296417Sdim !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) || 1977249423Sdim !(OldIsUnavailable == IsUnavailable || 1978296417Sdim (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) { 1979296417Sdim if (OverrideOrImpl) { 1980249423Sdim int Which = -1; 1981249423Sdim VersionTuple FirstVersion; 1982249423Sdim VersionTuple SecondVersion; 1983296417Sdim if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) { 1984249423Sdim Which = 0; 1985249423Sdim FirstVersion = OldIntroduced; 1986249423Sdim SecondVersion = Introduced; 1987296417Sdim } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) { 1988249423Sdim Which = 1; 1989249423Sdim FirstVersion = Deprecated; 1990249423Sdim SecondVersion = OldDeprecated; 1991296417Sdim } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) { 1992249423Sdim Which = 2; 1993249423Sdim FirstVersion = Obsoleted; 1994249423Sdim SecondVersion = OldObsoleted; 1995249423Sdim } 1996249423Sdim 1997249423Sdim if (Which == -1) { 1998249423Sdim Diag(OldAA->getLocation(), 1999249423Sdim diag::warn_mismatched_availability_override_unavail) 2000296417Sdim << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) 2001296417Sdim << (AMK == AMK_Override); 2002249423Sdim } else { 2003249423Sdim Diag(OldAA->getLocation(), 2004249423Sdim diag::warn_mismatched_availability_override) 2005249423Sdim << Which 2006249423Sdim << AvailabilityAttr::getPrettyPlatformName(Platform->getName()) 2007296417Sdim << FirstVersion.getAsString() << SecondVersion.getAsString() 2008296417Sdim << (AMK == AMK_Override); 2009249423Sdim } 2010296417Sdim if (AMK == AMK_Override) 2011296417Sdim Diag(Range.getBegin(), diag::note_overridden_method); 2012296417Sdim else 2013296417Sdim Diag(Range.getBegin(), diag::note_protocol_method); 2014249423Sdim } else { 2015249423Sdim Diag(OldAA->getLocation(), diag::warn_mismatched_availability); 2016249423Sdim Diag(Range.getBegin(), diag::note_previous_attribute); 2017249423Sdim } 2018249423Sdim 2019239462Sdim Attrs.erase(Attrs.begin() + i); 2020239462Sdim --e; 2021239462Sdim continue; 2022239462Sdim } 2023239462Sdim 2024239462Sdim VersionTuple MergedIntroduced2 = MergedIntroduced; 2025239462Sdim VersionTuple MergedDeprecated2 = MergedDeprecated; 2026239462Sdim VersionTuple MergedObsoleted2 = MergedObsoleted; 2027239462Sdim 2028239462Sdim if (MergedIntroduced2.empty()) 2029239462Sdim MergedIntroduced2 = OldIntroduced; 2030239462Sdim if (MergedDeprecated2.empty()) 2031239462Sdim MergedDeprecated2 = OldDeprecated; 2032239462Sdim if (MergedObsoleted2.empty()) 2033239462Sdim MergedObsoleted2 = OldObsoleted; 2034239462Sdim 2035239462Sdim if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, 2036239462Sdim MergedIntroduced2, MergedDeprecated2, 2037239462Sdim MergedObsoleted2)) { 2038239462Sdim Attrs.erase(Attrs.begin() + i); 2039239462Sdim --e; 2040239462Sdim continue; 2041239462Sdim } 2042239462Sdim 2043239462Sdim MergedIntroduced = MergedIntroduced2; 2044239462Sdim MergedDeprecated = MergedDeprecated2; 2045239462Sdim MergedObsoleted = MergedObsoleted2; 2046239462Sdim ++i; 2047239462Sdim } 2048239462Sdim } 2049239462Sdim 2050239462Sdim if (FoundAny && 2051239462Sdim MergedIntroduced == Introduced && 2052239462Sdim MergedDeprecated == Deprecated && 2053239462Sdim MergedObsoleted == Obsoleted) 2054276479Sdim return nullptr; 2055239462Sdim 2056296417Sdim // Only create a new attribute if !OverrideOrImpl, but we want to do 2057251662Sdim // the checking. 2058239462Sdim if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, 2059251662Sdim MergedDeprecated, MergedObsoleted) && 2060296417Sdim !OverrideOrImpl) { 2061239462Sdim return ::new (Context) AvailabilityAttr(Range, Context, Platform, 2062239462Sdim Introduced, Deprecated, 2063249423Sdim Obsoleted, IsUnavailable, Message, 2064249423Sdim AttrSpellingListIndex); 2065239462Sdim } 2066276479Sdim return nullptr; 2067239462Sdim} 2068239462Sdim 2069224145Sdimstatic void handleAvailabilityAttr(Sema &S, Decl *D, 2070224145Sdim const AttributeList &Attr) { 2071261991Sdim if (!checkAttributeNumArgs(S, Attr, 1)) 2072261991Sdim return; 2073261991Sdim IdentifierLoc *Platform = Attr.getArgAsIdent(0); 2074249423Sdim unsigned Index = Attr.getAttributeSpellingListIndex(); 2075249423Sdim 2076261991Sdim IdentifierInfo *II = Platform->Ident; 2077261991Sdim if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty()) 2078261991Sdim S.Diag(Platform->Loc, diag::warn_availability_unknown_platform) 2079261991Sdim << Platform->Ident; 2080221345Sdim 2081249423Sdim NamedDecl *ND = dyn_cast<NamedDecl>(D); 2082249423Sdim if (!ND) { 2083249423Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2084249423Sdim return; 2085249423Sdim } 2086249423Sdim 2087221345Sdim AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 2088221345Sdim AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 2089221345Sdim AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 2090221345Sdim bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 2091234353Sdim StringRef Str; 2092261991Sdim if (const StringLiteral *SE = 2093261991Sdim dyn_cast_or_null<StringLiteral>(Attr.getMessageExpr())) 2094234353Sdim Str = SE->getString(); 2095239462Sdim 2096261991Sdim AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II, 2097239462Sdim Introduced.Version, 2098239462Sdim Deprecated.Version, 2099239462Sdim Obsoleted.Version, 2100249423Sdim IsUnavailable, Str, 2101296417Sdim Sema::AMK_None, 2102249423Sdim Index); 2103239462Sdim if (NewAttr) 2104239462Sdim D->addAttr(NewAttr); 2105296417Sdim 2106296417Sdim // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning 2107296417Sdim // matches before the start of the watchOS platform. 2108296417Sdim if (S.Context.getTargetInfo().getTriple().isWatchOS()) { 2109296417Sdim IdentifierInfo *NewII = nullptr; 2110296417Sdim if (II->getName() == "ios") 2111296417Sdim NewII = &S.Context.Idents.get("watchos"); 2112296417Sdim else if (II->getName() == "ios_app_extension") 2113296417Sdim NewII = &S.Context.Idents.get("watchos_app_extension"); 2114296417Sdim 2115296417Sdim if (NewII) { 2116296417Sdim auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple { 2117296417Sdim if (Version.empty()) 2118296417Sdim return Version; 2119296417Sdim auto Major = Version.getMajor(); 2120296417Sdim auto NewMajor = Major >= 9 ? Major - 7 : 0; 2121296417Sdim if (NewMajor >= 2) { 2122296417Sdim if (Version.getMinor().hasValue()) { 2123296417Sdim if (Version.getSubminor().hasValue()) 2124296417Sdim return VersionTuple(NewMajor, Version.getMinor().getValue(), 2125296417Sdim Version.getSubminor().getValue()); 2126296417Sdim else 2127296417Sdim return VersionTuple(NewMajor, Version.getMinor().getValue()); 2128296417Sdim } 2129296417Sdim } 2130296417Sdim 2131296417Sdim return VersionTuple(2, 0); 2132296417Sdim }; 2133296417Sdim 2134296417Sdim auto NewIntroduced = adjustWatchOSVersion(Introduced.Version); 2135296417Sdim auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version); 2136296417Sdim auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version); 2137296417Sdim 2138296417Sdim AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, 2139296417Sdim SourceRange(), 2140296417Sdim NewII, 2141296417Sdim NewIntroduced, 2142296417Sdim NewDeprecated, 2143296417Sdim NewObsoleted, 2144296417Sdim IsUnavailable, Str, 2145296417Sdim Sema::AMK_None, 2146296417Sdim Index); 2147296417Sdim if (NewAttr) 2148296417Sdim D->addAttr(NewAttr); 2149296417Sdim } 2150296417Sdim } else if (S.Context.getTargetInfo().getTriple().isTvOS()) { 2151296417Sdim // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning 2152296417Sdim // matches before the start of the tvOS platform. 2153296417Sdim IdentifierInfo *NewII = nullptr; 2154296417Sdim if (II->getName() == "ios") 2155296417Sdim NewII = &S.Context.Idents.get("tvos"); 2156296417Sdim else if (II->getName() == "ios_app_extension") 2157296417Sdim NewII = &S.Context.Idents.get("tvos_app_extension"); 2158296417Sdim 2159296417Sdim if (NewII) { 2160296417Sdim AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, 2161296417Sdim SourceRange(), 2162296417Sdim NewII, 2163296417Sdim Introduced.Version, 2164296417Sdim Deprecated.Version, 2165296417Sdim Obsoleted.Version, 2166296417Sdim IsUnavailable, Str, 2167296417Sdim Sema::AMK_None, 2168296417Sdim Index); 2169296417Sdim if (NewAttr) 2170296417Sdim D->addAttr(NewAttr); 2171296417Sdim } 2172296417Sdim } 2173221345Sdim} 2174221345Sdim 2175249423Sdimtemplate <class T> 2176249423Sdimstatic T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range, 2177249423Sdim typename T::VisibilityType value, 2178249423Sdim unsigned attrSpellingListIndex) { 2179249423Sdim T *existingAttr = D->getAttr<T>(); 2180249423Sdim if (existingAttr) { 2181249423Sdim typename T::VisibilityType existingValue = existingAttr->getVisibility(); 2182249423Sdim if (existingValue == value) 2183276479Sdim return nullptr; 2184249423Sdim S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility); 2185249423Sdim S.Diag(range.getBegin(), diag::note_previous_attribute); 2186249423Sdim D->dropAttr<T>(); 2187249423Sdim } 2188249423Sdim return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex); 2189249423Sdim} 2190249423Sdim 2191239462SdimVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, 2192249423Sdim VisibilityAttr::VisibilityType Vis, 2193249423Sdim unsigned AttrSpellingListIndex) { 2194249423Sdim return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis, 2195249423Sdim AttrSpellingListIndex); 2196249423Sdim} 2197249423Sdim 2198249423SdimTypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range, 2199249423Sdim TypeVisibilityAttr::VisibilityType Vis, 2200249423Sdim unsigned AttrSpellingListIndex) { 2201249423Sdim return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis, 2202249423Sdim AttrSpellingListIndex); 2203249423Sdim} 2204249423Sdim 2205249423Sdimstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr, 2206249423Sdim bool isTypeVisibility) { 2207249423Sdim // Visibility attributes don't mean anything on a typedef. 2208239462Sdim if (isa<TypedefNameDecl>(D)) { 2209249423Sdim S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored) 2210249423Sdim << Attr.getName(); 2211249423Sdim return; 2212239462Sdim } 2213249423Sdim 2214249423Sdim // 'type_visibility' can only go on a type or namespace. 2215249423Sdim if (isTypeVisibility && 2216249423Sdim !(isa<TagDecl>(D) || 2217249423Sdim isa<ObjCInterfaceDecl>(D) || 2218249423Sdim isa<NamespaceDecl>(D))) { 2219249423Sdim S.Diag(Attr.getRange().getBegin(), diag::err_attribute_wrong_decl_type) 2220249423Sdim << Attr.getName() << ExpectedTypeOrNamespace; 2221249423Sdim return; 2222239462Sdim } 2223239462Sdim 2224261991Sdim // Check that the argument is a string literal. 2225261991Sdim StringRef TypeStr; 2226261991Sdim SourceLocation LiteralLoc; 2227261991Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, TypeStr, &LiteralLoc)) 2228193326Sed return; 2229198092Srdivacky 2230261991Sdim VisibilityAttr::VisibilityType type; 2231261991Sdim if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) { 2232261991Sdim S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) 2233261991Sdim << Attr.getName() << TypeStr; 2234193326Sed return; 2235193326Sed } 2236249423Sdim 2237261991Sdim // Complain about attempts to use protected visibility on targets 2238261991Sdim // (like Darwin) that don't support it. 2239261991Sdim if (type == VisibilityAttr::Protected && 2240261991Sdim !S.Context.getTargetInfo().hasProtectedVisibility()) { 2241261991Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 2242212904Sdim type = VisibilityAttr::Default; 2243193326Sed } 2244198092Srdivacky 2245249423Sdim unsigned Index = Attr.getAttributeSpellingListIndex(); 2246249423Sdim clang::Attr *newAttr; 2247249423Sdim if (isTypeVisibility) { 2248249423Sdim newAttr = S.mergeTypeVisibilityAttr(D, Attr.getRange(), 2249249423Sdim (TypeVisibilityAttr::VisibilityType) type, 2250249423Sdim Index); 2251249423Sdim } else { 2252249423Sdim newAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type, Index); 2253249423Sdim } 2254249423Sdim if (newAttr) 2255249423Sdim D->addAttr(newAttr); 2256193326Sed} 2257193326Sed 2258224145Sdimstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 2259224145Sdim const AttributeList &Attr) { 2260276479Sdim ObjCMethodDecl *method = cast<ObjCMethodDecl>(decl); 2261261991Sdim if (!Attr.isArgIdent(0)) { 2262261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2263261991Sdim << Attr.getName() << 1 << AANT_ArgumentIdentifier; 2264221345Sdim return; 2265221345Sdim } 2266221345Sdim 2267261991Sdim IdentifierLoc *IL = Attr.getArgAsIdent(0); 2268261991Sdim ObjCMethodFamilyAttr::FamilyKind F; 2269261991Sdim if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) { 2270261991Sdim S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << Attr.getName() 2271261991Sdim << IL->Ident; 2272221345Sdim return; 2273221345Sdim } 2274221345Sdim 2275276479Sdim if (F == ObjCMethodFamilyAttr::OMF_init && 2276276479Sdim !method->getReturnType()->isObjCObjectPointerType()) { 2277224145Sdim S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 2278276479Sdim << method->getReturnType(); 2279224145Sdim // Ignore the attribute. 2280224145Sdim return; 2281224145Sdim } 2282224145Sdim 2283226633Sdim method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 2284276479Sdim S.Context, F, 2285276479Sdim Attr.getAttributeSpellingListIndex())); 2286221345Sdim} 2287221345Sdim 2288224145Sdimstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 2289221345Sdim if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2290193326Sed QualType T = TD->getUnderlyingType(); 2291243830Sdim if (!T->isCARCBridgableType()) { 2292193326Sed S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 2293193326Sed return; 2294193326Sed } 2295193326Sed } 2296239462Sdim else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 2297239462Sdim QualType T = PD->getType(); 2298243830Sdim if (!T->isCARCBridgableType()) { 2299239462Sdim S.Diag(PD->getLocation(), diag::err_nsobject_attribute); 2300239462Sdim return; 2301239462Sdim } 2302239462Sdim } 2303239462Sdim else { 2304234353Sdim // It is okay to include this attribute on properties, e.g.: 2305234353Sdim // 2306234353Sdim // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 2307234353Sdim // 2308234353Sdim // In this case it follows tradition and suppresses an error in the above 2309234353Sdim // case. 2310234353Sdim S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 2311234353Sdim } 2312249423Sdim D->addAttr(::new (S.Context) 2313249423Sdim ObjCNSObjectAttr(Attr.getRange(), S.Context, 2314249423Sdim Attr.getAttributeSpellingListIndex())); 2315193326Sed} 2316193326Sed 2317288943Sdimstatic void handleObjCIndependentClass(Sema &S, Decl *D, const AttributeList &Attr) { 2318288943Sdim if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2319288943Sdim QualType T = TD->getUnderlyingType(); 2320288943Sdim if (!T->isObjCObjectPointerType()) { 2321288943Sdim S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute); 2322288943Sdim return; 2323288943Sdim } 2324288943Sdim } else { 2325288943Sdim S.Diag(D->getLocation(), diag::warn_independentclass_attribute); 2326288943Sdim return; 2327288943Sdim } 2328288943Sdim D->addAttr(::new (S.Context) 2329288943Sdim ObjCIndependentClassAttr(Attr.getRange(), S.Context, 2330288943Sdim Attr.getAttributeSpellingListIndex())); 2331288943Sdim} 2332288943Sdim 2333224145Sdimstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2334261991Sdim if (!Attr.isArgIdent(0)) { 2335261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2336261991Sdim << Attr.getName() << 1 << AANT_ArgumentIdentifier; 2337193326Sed return; 2338193326Sed } 2339198092Srdivacky 2340261991Sdim IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; 2341212904Sdim BlocksAttr::BlockType type; 2342261991Sdim if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) { 2343193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 2344261991Sdim << Attr.getName() << II; 2345193326Sed return; 2346193326Sed } 2347198092Srdivacky 2348249423Sdim D->addAttr(::new (S.Context) 2349249423Sdim BlocksAttr(Attr.getRange(), S.Context, type, 2350249423Sdim Attr.getAttributeSpellingListIndex())); 2351193326Sed} 2352193326Sed 2353224145Sdimstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2354276479Sdim unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel; 2355193326Sed if (Attr.getNumArgs() > 0) { 2356261991Sdim Expr *E = Attr.getArgAsExpr(0); 2357193326Sed llvm::APSInt Idx(32); 2358208600Srdivacky if (E->isTypeDependent() || E->isValueDependent() || 2359208600Srdivacky !E->isIntegerConstantExpr(Idx, S.Context)) { 2360261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2361261991Sdim << Attr.getName() << 1 << AANT_ArgumentIntegerConstant 2362261991Sdim << E->getSourceRange(); 2363193326Sed return; 2364193326Sed } 2365198092Srdivacky 2366226633Sdim if (Idx.isSigned() && Idx.isNegative()) { 2367193326Sed S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 2368193326Sed << E->getSourceRange(); 2369193326Sed return; 2370193326Sed } 2371226633Sdim 2372226633Sdim sentinel = Idx.getZExtValue(); 2373193326Sed } 2374193326Sed 2375276479Sdim unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos; 2376193326Sed if (Attr.getNumArgs() > 1) { 2377261991Sdim Expr *E = Attr.getArgAsExpr(1); 2378193326Sed llvm::APSInt Idx(32); 2379208600Srdivacky if (E->isTypeDependent() || E->isValueDependent() || 2380208600Srdivacky !E->isIntegerConstantExpr(Idx, S.Context)) { 2381261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2382261991Sdim << Attr.getName() << 2 << AANT_ArgumentIntegerConstant 2383261991Sdim << E->getSourceRange(); 2384193326Sed return; 2385193326Sed } 2386193326Sed nullPos = Idx.getZExtValue(); 2387198092Srdivacky 2388226633Sdim if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 2389193326Sed // FIXME: This error message could be improved, it would be nice 2390193326Sed // to say what the bounds actually are. 2391193326Sed S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 2392193326Sed << E->getSourceRange(); 2393193326Sed return; 2394193326Sed } 2395193326Sed } 2396193326Sed 2397224145Sdim if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 2398226633Sdim const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 2399193326Sed if (isa<FunctionNoProtoType>(FT)) { 2400193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 2401193326Sed return; 2402193326Sed } 2403198092Srdivacky 2404193326Sed if (!cast<FunctionProtoType>(FT)->isVariadic()) { 2405193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2406193326Sed return; 2407198092Srdivacky } 2408224145Sdim } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 2409193326Sed if (!MD->isVariadic()) { 2410193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2411193326Sed return; 2412193326Sed } 2413234353Sdim } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 2414234353Sdim if (!BD->isVariadic()) { 2415234353Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 2416234353Sdim return; 2417234353Sdim } 2418224145Sdim } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 2419193326Sed QualType Ty = V->getType(); 2420193326Sed if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 2421276479Sdim const FunctionType *FT = Ty->isFunctionPointerType() 2422276479Sdim ? D->getFunctionType() 2423218893Sdim : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 2424193326Sed if (!cast<FunctionProtoType>(FT)->isVariadic()) { 2425193326Sed int m = Ty->isFunctionPointerType() ? 0 : 1; 2426193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 2427193326Sed return; 2428193326Sed } 2429198092Srdivacky } else { 2430193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2431221345Sdim << Attr.getName() << ExpectedFunctionMethodOrBlock; 2432193326Sed return; 2433193326Sed } 2434193326Sed } else { 2435193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2436221345Sdim << Attr.getName() << ExpectedFunctionMethodOrBlock; 2437193326Sed return; 2438193326Sed } 2439249423Sdim D->addAttr(::new (S.Context) 2440249423Sdim SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos, 2441249423Sdim Attr.getAttributeSpellingListIndex())); 2442193326Sed} 2443193326Sed 2444224145Sdimstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 2445276479Sdim if (D->getFunctionType() && 2446276479Sdim D->getFunctionType()->getReturnType()->isVoidType()) { 2447206084Srdivacky S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2448206084Srdivacky << Attr.getName() << 0; 2449201361Srdivacky return; 2450201361Srdivacky } 2451206084Srdivacky if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 2452276479Sdim if (MD->getReturnType()->isVoidType()) { 2453206084Srdivacky S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2454206084Srdivacky << Attr.getName() << 1; 2455206084Srdivacky return; 2456206084Srdivacky } 2457206084Srdivacky 2458249423Sdim D->addAttr(::new (S.Context) 2459249423Sdim WarnUnusedResultAttr(Attr.getRange(), S.Context, 2460249423Sdim Attr.getAttributeSpellingListIndex())); 2461193326Sed} 2462193326Sed 2463224145Sdimstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2464193326Sed // weak_import only applies to variable & function declarations. 2465193326Sed bool isDef = false; 2466221345Sdim if (!D->canBeWeakImported(isDef)) { 2467221345Sdim if (isDef) 2468261991Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_invalid_on_definition) 2469261991Sdim << "weak_import"; 2470221345Sdim else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 2471226633Sdim (S.Context.getTargetInfo().getTriple().isOSDarwin() && 2472234353Sdim (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 2473221345Sdim // Nothing to warn about here. 2474221345Sdim } else 2475207619Srdivacky S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2476221345Sdim << Attr.getName() << ExpectedVariableOrFunction; 2477193326Sed 2478193326Sed return; 2479193326Sed } 2480193326Sed 2481249423Sdim D->addAttr(::new (S.Context) 2482249423Sdim WeakImportAttr(Attr.getRange(), S.Context, 2483249423Sdim Attr.getAttributeSpellingListIndex())); 2484193326Sed} 2485193326Sed 2486239462Sdim// Handles reqd_work_group_size and work_group_size_hint. 2487276479Sdimtemplate <typename WorkGroupAttr> 2488239462Sdimstatic void handleWorkGroupSize(Sema &S, Decl *D, 2489239462Sdim const AttributeList &Attr) { 2490276479Sdim uint32_t WGSize[3]; 2491195099Sed for (unsigned i = 0; i < 3; ++i) { 2492276479Sdim const Expr *E = Attr.getArgAsExpr(i); 2493276479Sdim if (!checkUInt32Argument(S, Attr, E, WGSize[i], i)) 2494195099Sed return; 2495276479Sdim if (WGSize[i] == 0) { 2496276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) 2497276479Sdim << Attr.getName() << E->getSourceRange(); 2498276479Sdim return; 2499195099Sed } 2500195099Sed } 2501239462Sdim 2502276479Sdim WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>(); 2503276479Sdim if (Existing && !(Existing->getXDim() == WGSize[0] && 2504276479Sdim Existing->getYDim() == WGSize[1] && 2505276479Sdim Existing->getZDim() == WGSize[2])) 2506276479Sdim S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName(); 2507239462Sdim 2508276479Sdim D->addAttr(::new (S.Context) WorkGroupAttr(Attr.getRange(), S.Context, 2509276479Sdim WGSize[0], WGSize[1], WGSize[2], 2510249423Sdim Attr.getAttributeSpellingListIndex())); 2511195099Sed} 2512195099Sed 2513249423Sdimstatic void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) { 2514261991Sdim if (!Attr.hasParsedType()) { 2515261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 2516261991Sdim << Attr.getName() << 1; 2517249423Sdim return; 2518261991Sdim } 2519249423Sdim 2520276479Sdim TypeSourceInfo *ParmTSI = nullptr; 2521261991Sdim QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI); 2522261991Sdim assert(ParmTSI && "no type source info for attribute argument"); 2523249423Sdim 2524249423Sdim if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() && 2525249423Sdim (ParmType->isBooleanType() || 2526249423Sdim !ParmType->isIntegralType(S.getASTContext()))) { 2527249423Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_vec_type_hint) 2528249423Sdim << ParmType; 2529249423Sdim return; 2530249423Sdim } 2531249423Sdim 2532276479Sdim if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) { 2533261991Sdim if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) { 2534249423Sdim S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName(); 2535249423Sdim return; 2536249423Sdim } 2537249423Sdim } 2538249423Sdim 2539249423Sdim D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context, 2540276479Sdim ParmTSI, 2541276479Sdim Attr.getAttributeSpellingListIndex())); 2542249423Sdim} 2543249423Sdim 2544239462SdimSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, 2545249423Sdim StringRef Name, 2546249423Sdim unsigned AttrSpellingListIndex) { 2547239462Sdim if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { 2548239462Sdim if (ExistingAttr->getName() == Name) 2549276479Sdim return nullptr; 2550239462Sdim Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); 2551239462Sdim Diag(Range.getBegin(), diag::note_previous_attribute); 2552276479Sdim return nullptr; 2553239462Sdim } 2554249423Sdim return ::new (Context) SectionAttr(Range, Context, Name, 2555249423Sdim AttrSpellingListIndex); 2556239462Sdim} 2557239462Sdim 2558288943Sdimbool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) { 2559288943Sdim std::string Error = Context.getTargetInfo().isValidSectionSpecifier(SecName); 2560288943Sdim if (!Error.empty()) { 2561288943Sdim Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error; 2562288943Sdim return false; 2563288943Sdim } 2564288943Sdim return true; 2565288943Sdim} 2566288943Sdim 2567224145Sdimstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2568193326Sed // Make sure that there is a string literal as the sections's single 2569193326Sed // argument. 2570261991Sdim StringRef Str; 2571261991Sdim SourceLocation LiteralLoc; 2572261991Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc)) 2573193326Sed return; 2574198092Srdivacky 2575288943Sdim if (!S.checkSectionName(LiteralLoc, Str)) 2576288943Sdim return; 2577288943Sdim 2578198092Srdivacky // If the target wants to validate the section specifier, make it happen. 2579261991Sdim std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str); 2580202379Srdivacky if (!Error.empty()) { 2581261991Sdim S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) 2582202379Srdivacky << Error; 2583198092Srdivacky return; 2584198092Srdivacky } 2585198092Srdivacky 2586249423Sdim unsigned Index = Attr.getAttributeSpellingListIndex(); 2587261991Sdim SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index); 2588239462Sdim if (NewAttr) 2589239462Sdim D->addAttr(NewAttr); 2590193326Sed} 2591193326Sed 2592288943Sdim// Check for things we'd like to warn about, no errors or validation for now. 2593288943Sdim// TODO: Validation should use a backend target library that specifies 2594288943Sdim// the allowable subtarget features and cpus. We could use something like a 2595288943Sdim// TargetCodeGenInfo hook here to do validation. 2596288943Sdimvoid Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { 2597288943Sdim for (auto Str : {"tune=", "fpmath="}) 2598288943Sdim if (AttrStr.find(Str) != StringRef::npos) 2599288943Sdim Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Str; 2600288943Sdim} 2601199482Srdivacky 2602288943Sdimstatic void handleTargetAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2603288943Sdim StringRef Str; 2604288943Sdim SourceLocation LiteralLoc; 2605288943Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &LiteralLoc)) 2606288943Sdim return; 2607288943Sdim S.checkTargetAttr(LiteralLoc, Str); 2608288943Sdim unsigned Index = Attr.getAttributeSpellingListIndex(); 2609288943Sdim TargetAttr *NewAttr = 2610288943Sdim ::new (S.Context) TargetAttr(Attr.getRange(), S.Context, Str, Index); 2611288943Sdim D->addAttr(NewAttr); 2612288943Sdim} 2613288943Sdim 2614288943Sdim 2615224145Sdimstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2616276479Sdim VarDecl *VD = cast<VarDecl>(D); 2617276479Sdim if (!VD->hasLocalStorage()) { 2618261991Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2619193326Sed return; 2620193326Sed } 2621198092Srdivacky 2622261991Sdim Expr *E = Attr.getArgAsExpr(0); 2623261991Sdim SourceLocation Loc = E->getExprLoc(); 2624276479Sdim FunctionDecl *FD = nullptr; 2625261991Sdim DeclarationNameInfo NI; 2626198092Srdivacky 2627261991Sdim // gcc only allows for simple identifiers. Since we support more than gcc, we 2628261991Sdim // will warn the user. 2629261991Sdim if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 2630261991Sdim if (DRE->hasQualifier()) 2631261991Sdim S.Diag(Loc, diag::warn_cleanup_ext); 2632261991Sdim FD = dyn_cast<FunctionDecl>(DRE->getDecl()); 2633261991Sdim NI = DRE->getNameInfo(); 2634261991Sdim if (!FD) { 2635261991Sdim S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1 2636261991Sdim << NI.getName(); 2637261991Sdim return; 2638261991Sdim } 2639261991Sdim } else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { 2640261991Sdim if (ULE->hasExplicitTemplateArgs()) 2641261991Sdim S.Diag(Loc, diag::warn_cleanup_ext); 2642261991Sdim FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true); 2643261991Sdim NI = ULE->getNameInfo(); 2644261991Sdim if (!FD) { 2645261991Sdim S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2 2646261991Sdim << NI.getName(); 2647261991Sdim if (ULE->getType() == S.Context.OverloadTy) 2648261991Sdim S.NoteAllOverloadCandidates(ULE); 2649261991Sdim return; 2650261991Sdim } 2651261991Sdim } else { 2652261991Sdim S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0; 2653193326Sed return; 2654193326Sed } 2655193326Sed 2656193326Sed if (FD->getNumParams() != 1) { 2657261991Sdim S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg) 2658261991Sdim << NI.getName(); 2659193326Sed return; 2660193326Sed } 2661198092Srdivacky 2662193326Sed // We're currently more strict than GCC about what function types we accept. 2663193326Sed // If this ever proves to be a problem it should be easy to fix. 2664193326Sed QualType Ty = S.Context.getPointerType(VD->getType()); 2665193326Sed QualType ParamTy = FD->getParamDecl(0)->getType(); 2666218893Sdim if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2667218893Sdim ParamTy, Ty) != Sema::Compatible) { 2668261991Sdim S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type) 2669261991Sdim << NI.getName() << ParamTy << Ty; 2670193326Sed return; 2671193326Sed } 2672198092Srdivacky 2673249423Sdim D->addAttr(::new (S.Context) 2674249423Sdim CleanupAttr(Attr.getRange(), S.Context, FD, 2675249423Sdim Attr.getAttributeSpellingListIndex())); 2676193326Sed} 2677193326Sed 2678198092Srdivacky/// Handle __attribute__((format_arg((idx)))) attribute based on 2679198092Srdivacky/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 2680224145Sdimstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2681261991Sdim Expr *IdxExpr = Attr.getArgAsExpr(0); 2682276479Sdim uint64_t Idx; 2683276479Sdim if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, IdxExpr, Idx)) 2684193326Sed return; 2685198092Srdivacky 2686296417Sdim // Make sure the format string is really a string. 2687276479Sdim QualType Ty = getFunctionOrMethodParamType(D, Idx); 2688198092Srdivacky 2689296417Sdim bool NotNSStringTy = !isNSStringType(Ty, S.Context); 2690296417Sdim if (NotNSStringTy && 2691193326Sed !isCFStringType(Ty, S.Context) && 2692193326Sed (!Ty->isPointerType() || 2693198092Srdivacky !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 2694193326Sed S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2695296417Sdim << "a string type" << IdxExpr->getSourceRange() 2696296417Sdim << getFunctionOrMethodParamRange(D, 0); 2697193326Sed return; 2698198092Srdivacky } 2699224145Sdim Ty = getFunctionOrMethodResultType(D); 2700193326Sed if (!isNSStringType(Ty, S.Context) && 2701193326Sed !isCFStringType(Ty, S.Context) && 2702193326Sed (!Ty->isPointerType() || 2703198092Srdivacky !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 2704193326Sed S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2705296417Sdim << (NotNSStringTy ? "string type" : "NSString") 2706280031Sdim << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0); 2707193326Sed return; 2708198092Srdivacky } 2709198092Srdivacky 2710276479Sdim // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex 2711261991Sdim // because that has corrected for the implicit this parameter, and is zero- 2712261991Sdim // based. The attribute expects what the user wrote explicitly. 2713261991Sdim llvm::APSInt Val; 2714261991Sdim IdxExpr->EvaluateAsInt(Val, S.Context); 2715261991Sdim 2716249423Sdim D->addAttr(::new (S.Context) 2717261991Sdim FormatArgAttr(Attr.getRange(), S.Context, Val.getZExtValue(), 2718249423Sdim Attr.getAttributeSpellingListIndex())); 2719193326Sed} 2720193326Sed 2721198398Srdivackyenum FormatAttrKind { 2722198398Srdivacky CFStringFormat, 2723198398Srdivacky NSStringFormat, 2724198398Srdivacky StrftimeFormat, 2725198398Srdivacky SupportedFormat, 2726206084Srdivacky IgnoredFormat, 2727198398Srdivacky InvalidFormat 2728198398Srdivacky}; 2729198398Srdivacky 2730198398Srdivacky/// getFormatAttrKind - Map from format attribute names to supported format 2731198398Srdivacky/// types. 2732226633Sdimstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 2733239462Sdim return llvm::StringSwitch<FormatAttrKind>(Format) 2734239462Sdim // Check for formats that get handled specially. 2735239462Sdim .Case("NSString", NSStringFormat) 2736239462Sdim .Case("CFString", CFStringFormat) 2737239462Sdim .Case("strftime", StrftimeFormat) 2738198398Srdivacky 2739239462Sdim // Otherwise, check for supported formats. 2740239462Sdim .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) 2741239462Sdim .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) 2742239462Sdim .Case("kprintf", SupportedFormat) // OpenBSD. 2743280031Sdim .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. 2744288943Sdim .Case("os_trace", SupportedFormat) 2745198398Srdivacky 2746239462Sdim .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) 2747239462Sdim .Default(InvalidFormat); 2748198398Srdivacky} 2749198398Srdivacky 2750210299Sed/// Handle __attribute__((init_priority(priority))) attributes based on 2751210299Sed/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 2752224145Sdimstatic void handleInitPriorityAttr(Sema &S, Decl *D, 2753224145Sdim const AttributeList &Attr) { 2754234353Sdim if (!S.getLangOpts().CPlusPlus) { 2755210299Sed S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2756210299Sed return; 2757210299Sed } 2758210299Sed 2759276479Sdim if (S.getCurFunctionOrMethodDecl()) { 2760210299Sed S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2761210299Sed Attr.setInvalid(); 2762210299Sed return; 2763210299Sed } 2764276479Sdim QualType T = cast<VarDecl>(D)->getType(); 2765210299Sed if (S.Context.getAsArrayType(T)) 2766210299Sed T = S.Context.getBaseElementType(T); 2767210299Sed if (!T->getAs<RecordType>()) { 2768210299Sed S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2769210299Sed Attr.setInvalid(); 2770210299Sed return; 2771210299Sed } 2772276479Sdim 2773276479Sdim Expr *E = Attr.getArgAsExpr(0); 2774276479Sdim uint32_t prioritynum; 2775276479Sdim if (!checkUInt32Argument(S, Attr, E, prioritynum)) { 2776210299Sed Attr.setInvalid(); 2777210299Sed return; 2778210299Sed } 2779276479Sdim 2780210299Sed if (prioritynum < 101 || prioritynum > 65535) { 2781210299Sed S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2782296417Sdim << E->getSourceRange() << Attr.getName() << 101 << 65535; 2783210299Sed Attr.setInvalid(); 2784210299Sed return; 2785210299Sed } 2786249423Sdim D->addAttr(::new (S.Context) 2787249423Sdim InitPriorityAttr(Attr.getRange(), S.Context, prioritynum, 2788249423Sdim Attr.getAttributeSpellingListIndex())); 2789210299Sed} 2790210299Sed 2791261991SdimFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, 2792261991Sdim IdentifierInfo *Format, int FormatIdx, 2793261991Sdim int FirstArg, 2794249423Sdim unsigned AttrSpellingListIndex) { 2795239462Sdim // Check whether we already have an equivalent format attribute. 2796276479Sdim for (auto *F : D->specific_attrs<FormatAttr>()) { 2797276479Sdim if (F->getType() == Format && 2798276479Sdim F->getFormatIdx() == FormatIdx && 2799276479Sdim F->getFirstArg() == FirstArg) { 2800239462Sdim // If we don't have a valid location for this attribute, adopt the 2801239462Sdim // location. 2802276479Sdim if (F->getLocation().isInvalid()) 2803276479Sdim F->setRange(Range); 2804276479Sdim return nullptr; 2805239462Sdim } 2806239462Sdim } 2807239462Sdim 2808261991Sdim return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, 2809261991Sdim FirstArg, AttrSpellingListIndex); 2810239462Sdim} 2811239462Sdim 2812198092Srdivacky/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2813198092Srdivacky/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 2814224145Sdimstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2815261991Sdim if (!Attr.isArgIdent(0)) { 2816261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 2817261991Sdim << Attr.getName() << 1 << AANT_ArgumentIdentifier; 2818193326Sed return; 2819193326Sed } 2820193326Sed 2821218893Sdim // In C++ the implicit 'this' function parameter also counts, and they are 2822218893Sdim // counted from one. 2823224145Sdim bool HasImplicitThisParam = isInstanceMethod(D); 2824276479Sdim unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam; 2825193326Sed 2826261991Sdim IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident; 2827261991Sdim StringRef Format = II->getName(); 2828193326Sed 2829296417Sdim if (normalizeName(Format)) { 2830261991Sdim // If we've modified the string name, we need a new identifier for it. 2831261991Sdim II = &S.Context.Idents.get(Format); 2832261991Sdim } 2833193326Sed 2834198398Srdivacky // Check for supported formats. 2835198398Srdivacky FormatAttrKind Kind = getFormatAttrKind(Format); 2836206084Srdivacky 2837206084Srdivacky if (Kind == IgnoredFormat) 2838206084Srdivacky return; 2839206084Srdivacky 2840198398Srdivacky if (Kind == InvalidFormat) { 2841193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 2842276479Sdim << Attr.getName() << II->getName(); 2843193326Sed return; 2844193326Sed } 2845193326Sed 2846193326Sed // checks for the 2nd argument 2847261991Sdim Expr *IdxExpr = Attr.getArgAsExpr(1); 2848276479Sdim uint32_t Idx; 2849276479Sdim if (!checkUInt32Argument(S, Attr, IdxExpr, Idx, 2)) 2850193326Sed return; 2851193326Sed 2852276479Sdim if (Idx < 1 || Idx > NumArgs) { 2853193326Sed S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 2854276479Sdim << Attr.getName() << 2 << IdxExpr->getSourceRange(); 2855193326Sed return; 2856193326Sed } 2857193326Sed 2858193326Sed // FIXME: Do we need to bounds check? 2859276479Sdim unsigned ArgIdx = Idx - 1; 2860198092Srdivacky 2861199482Srdivacky if (HasImplicitThisParam) { 2862199482Srdivacky if (ArgIdx == 0) { 2863218893Sdim S.Diag(Attr.getLoc(), 2864218893Sdim diag::err_format_attribute_implicit_this_format_string) 2865218893Sdim << IdxExpr->getSourceRange(); 2866199482Srdivacky return; 2867199482Srdivacky } 2868199482Srdivacky ArgIdx--; 2869199482Srdivacky } 2870198092Srdivacky 2871193326Sed // make sure the format string is really a string 2872276479Sdim QualType Ty = getFunctionOrMethodParamType(D, ArgIdx); 2873193326Sed 2874198398Srdivacky if (Kind == CFStringFormat) { 2875193326Sed if (!isCFStringType(Ty, S.Context)) { 2876193326Sed S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2877280031Sdim << "a CFString" << IdxExpr->getSourceRange() 2878280031Sdim << getFunctionOrMethodParamRange(D, ArgIdx); 2879193326Sed return; 2880193326Sed } 2881198398Srdivacky } else if (Kind == NSStringFormat) { 2882193326Sed // FIXME: do we need to check if the type is NSString*? What are the 2883193326Sed // semantics? 2884193326Sed if (!isNSStringType(Ty, S.Context)) { 2885193326Sed S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2886280031Sdim << "an NSString" << IdxExpr->getSourceRange() 2887280031Sdim << getFunctionOrMethodParamRange(D, ArgIdx); 2888193326Sed return; 2889198092Srdivacky } 2890193326Sed } else if (!Ty->isPointerType() || 2891198092Srdivacky !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2892193326Sed S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2893280031Sdim << "a string type" << IdxExpr->getSourceRange() 2894280031Sdim << getFunctionOrMethodParamRange(D, ArgIdx); 2895193326Sed return; 2896193326Sed } 2897193326Sed 2898193326Sed // check the 3rd argument 2899261991Sdim Expr *FirstArgExpr = Attr.getArgAsExpr(2); 2900276479Sdim uint32_t FirstArg; 2901276479Sdim if (!checkUInt32Argument(S, Attr, FirstArgExpr, FirstArg, 3)) 2902193326Sed return; 2903193326Sed 2904193326Sed // check if the function is variadic if the 3rd argument non-zero 2905193326Sed if (FirstArg != 0) { 2906224145Sdim if (isFunctionOrMethodVariadic(D)) { 2907193326Sed ++NumArgs; // +1 for ... 2908193326Sed } else { 2909224145Sdim S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 2910193326Sed return; 2911193326Sed } 2912193326Sed } 2913193326Sed 2914193326Sed // strftime requires FirstArg to be 0 because it doesn't read from any 2915193326Sed // variable the input is just the current time + the format string. 2916198398Srdivacky if (Kind == StrftimeFormat) { 2917193326Sed if (FirstArg != 0) { 2918193326Sed S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2919193326Sed << FirstArgExpr->getSourceRange(); 2920193326Sed return; 2921193326Sed } 2922193326Sed // if 0 it disables parameter checking (to use with e.g. va_list) 2923193326Sed } else if (FirstArg != 0 && FirstArg != NumArgs) { 2924193326Sed S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 2925276479Sdim << Attr.getName() << 3 << FirstArgExpr->getSourceRange(); 2926193326Sed return; 2927193326Sed } 2928193326Sed 2929261991Sdim FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II, 2930276479Sdim Idx, FirstArg, 2931249423Sdim Attr.getAttributeSpellingListIndex()); 2932239462Sdim if (NewAttr) 2933239462Sdim D->addAttr(NewAttr); 2934193326Sed} 2935193326Sed 2936224145Sdimstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 2937224145Sdim const AttributeList &Attr) { 2938193326Sed // Try to find the underlying union declaration. 2939276479Sdim RecordDecl *RD = nullptr; 2940224145Sdim TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 2941193326Sed if (TD && TD->getUnderlyingType()->isUnionType()) 2942193326Sed RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 2943193326Sed else 2944224145Sdim RD = dyn_cast<RecordDecl>(D); 2945193326Sed 2946193326Sed if (!RD || !RD->isUnion()) { 2947193326Sed S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2948221345Sdim << Attr.getName() << ExpectedUnion; 2949193326Sed return; 2950193326Sed } 2951193326Sed 2952226633Sdim if (!RD->isCompleteDefinition()) { 2953198092Srdivacky S.Diag(Attr.getLoc(), 2954193326Sed diag::warn_transparent_union_attribute_not_definition); 2955193326Sed return; 2956193326Sed } 2957193326Sed 2958195341Sed RecordDecl::field_iterator Field = RD->field_begin(), 2959195341Sed FieldEnd = RD->field_end(); 2960193326Sed if (Field == FieldEnd) { 2961193326Sed S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 2962193326Sed return; 2963193326Sed } 2964193326Sed 2965193326Sed FieldDecl *FirstField = *Field; 2966193326Sed QualType FirstType = FirstField->getType(); 2967210299Sed if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2968198092Srdivacky S.Diag(FirstField->getLocation(), 2969210299Sed diag::warn_transparent_union_attribute_floating) 2970210299Sed << FirstType->isVectorType() << FirstType; 2971193326Sed return; 2972193326Sed } 2973193326Sed 2974193326Sed uint64_t FirstSize = S.Context.getTypeSize(FirstType); 2975193326Sed uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 2976193326Sed for (; Field != FieldEnd; ++Field) { 2977193326Sed QualType FieldType = Field->getType(); 2978276479Sdim // FIXME: this isn't fully correct; we also need to test whether the 2979276479Sdim // members of the union would all have the same calling convention as the 2980276479Sdim // first member of the union. Checking just the size and alignment isn't 2981276479Sdim // sufficient (consider structs passed on the stack instead of in registers 2982276479Sdim // as an example). 2983193326Sed if (S.Context.getTypeSize(FieldType) != FirstSize || 2984276479Sdim S.Context.getTypeAlign(FieldType) > FirstAlign) { 2985193326Sed // Warn if we drop the attribute. 2986193326Sed bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2987198092Srdivacky unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 2988193326Sed : S.Context.getTypeAlign(FieldType); 2989198092Srdivacky S.Diag(Field->getLocation(), 2990193326Sed diag::warn_transparent_union_attribute_field_size_align) 2991193326Sed << isSize << Field->getDeclName() << FieldBits; 2992193326Sed unsigned FirstBits = isSize? FirstSize : FirstAlign; 2993198092Srdivacky S.Diag(FirstField->getLocation(), 2994193326Sed diag::note_transparent_union_first_field_size_align) 2995193326Sed << isSize << FirstBits; 2996193326Sed return; 2997193326Sed } 2998193326Sed } 2999193326Sed 3000249423Sdim RD->addAttr(::new (S.Context) 3001249423Sdim TransparentUnionAttr(Attr.getRange(), S.Context, 3002249423Sdim Attr.getAttributeSpellingListIndex())); 3003193326Sed} 3004193326Sed 3005224145Sdimstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3006193326Sed // Make sure that there is a string literal as the annotation's single 3007193326Sed // argument. 3008261991Sdim StringRef Str; 3009261991Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str)) 3010193326Sed return; 3011226633Sdim 3012226633Sdim // Don't duplicate annotations that are already set. 3013276479Sdim for (const auto *I : D->specific_attrs<AnnotateAttr>()) { 3014276479Sdim if (I->getAnnotation() == Str) 3015261991Sdim return; 3016226633Sdim } 3017249423Sdim 3018249423Sdim D->addAttr(::new (S.Context) 3019261991Sdim AnnotateAttr(Attr.getRange(), S.Context, Str, 3020249423Sdim Attr.getAttributeSpellingListIndex())); 3021193326Sed} 3022193326Sed 3023280031Sdimstatic void handleAlignValueAttr(Sema &S, Decl *D, 3024280031Sdim const AttributeList &Attr) { 3025280031Sdim S.AddAlignValueAttr(Attr.getRange(), D, Attr.getArgAsExpr(0), 3026280031Sdim Attr.getAttributeSpellingListIndex()); 3027280031Sdim} 3028280031Sdim 3029280031Sdimvoid Sema::AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, 3030280031Sdim unsigned SpellingListIndex) { 3031280031Sdim AlignValueAttr TmpAttr(AttrRange, Context, E, SpellingListIndex); 3032280031Sdim SourceLocation AttrLoc = AttrRange.getBegin(); 3033280031Sdim 3034280031Sdim QualType T; 3035280031Sdim if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3036280031Sdim T = TD->getUnderlyingType(); 3037280031Sdim else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 3038280031Sdim T = VD->getType(); 3039280031Sdim else 3040280031Sdim llvm_unreachable("Unknown decl type for align_value"); 3041280031Sdim 3042280031Sdim if (!T->isDependentType() && !T->isAnyPointerType() && 3043280031Sdim !T->isReferenceType() && !T->isMemberPointerType()) { 3044280031Sdim Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only) 3045280031Sdim << &TmpAttr /*TmpAttr.getName()*/ << T << D->getSourceRange(); 3046280031Sdim return; 3047280031Sdim } 3048280031Sdim 3049280031Sdim if (!E->isValueDependent()) { 3050296417Sdim llvm::APSInt Alignment; 3051280031Sdim ExprResult ICE 3052280031Sdim = VerifyIntegerConstantExpression(E, &Alignment, 3053280031Sdim diag::err_align_value_attribute_argument_not_int, 3054280031Sdim /*AllowFold*/ false); 3055280031Sdim if (ICE.isInvalid()) 3056280031Sdim return; 3057280031Sdim 3058280031Sdim if (!Alignment.isPowerOf2()) { 3059280031Sdim Diag(AttrLoc, diag::err_alignment_not_power_of_two) 3060280031Sdim << E->getSourceRange(); 3061280031Sdim return; 3062280031Sdim } 3063280031Sdim 3064280031Sdim D->addAttr(::new (Context) 3065280031Sdim AlignValueAttr(AttrRange, Context, ICE.get(), 3066280031Sdim SpellingListIndex)); 3067280031Sdim return; 3068280031Sdim } 3069280031Sdim 3070280031Sdim // Save dependent expressions in the AST to be instantiated. 3071280031Sdim D->addAttr(::new (Context) AlignValueAttr(TmpAttr)); 3072280031Sdim return; 3073280031Sdim} 3074280031Sdim 3075224145Sdimstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3076193326Sed // check the attribute arguments. 3077193326Sed if (Attr.getNumArgs() > 1) { 3078261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 3079261991Sdim << Attr.getName() << 1; 3080193326Sed return; 3081193326Sed } 3082239462Sdim 3083193326Sed if (Attr.getNumArgs() == 0) { 3084249423Sdim D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, 3085276479Sdim true, nullptr, Attr.getAttributeSpellingListIndex())); 3086193326Sed return; 3087193326Sed } 3088198092Srdivacky 3089261991Sdim Expr *E = Attr.getArgAsExpr(0); 3090249423Sdim if (Attr.isPackExpansion() && !E->containsUnexpandedParameterPack()) { 3091249423Sdim S.Diag(Attr.getEllipsisLoc(), 3092249423Sdim diag::err_pack_expansion_without_parameter_packs); 3093249423Sdim return; 3094249423Sdim } 3095210299Sed 3096249423Sdim if (!Attr.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E)) 3097234353Sdim return; 3098234353Sdim 3099288943Sdim if (E->isValueDependent()) { 3100288943Sdim if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) { 3101288943Sdim if (!TND->getUnderlyingType()->isDependentType()) { 3102288943Sdim S.Diag(Attr.getLoc(), diag::err_alignment_dependent_typedef_name) 3103288943Sdim << E->getSourceRange(); 3104288943Sdim return; 3105288943Sdim } 3106288943Sdim } 3107288943Sdim } 3108288943Sdim 3109249423Sdim S.AddAlignedAttr(Attr.getRange(), D, E, Attr.getAttributeSpellingListIndex(), 3110249423Sdim Attr.isPackExpansion()); 3111249423Sdim} 3112249423Sdim 3113249423Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 3114249423Sdim unsigned SpellingListIndex, bool IsPackExpansion) { 3115249423Sdim AlignedAttr TmpAttr(AttrRange, Context, true, E, SpellingListIndex); 3116249423Sdim SourceLocation AttrLoc = AttrRange.getBegin(); 3117249423Sdim 3118249423Sdim // C++11 alignas(...) and C11 _Alignas(...) have additional requirements. 3119249423Sdim if (TmpAttr.isAlignas()) { 3120249423Sdim // C++11 [dcl.align]p1: 3121249423Sdim // An alignment-specifier may be applied to a variable or to a class 3122249423Sdim // data member, but it shall not be applied to a bit-field, a function 3123249423Sdim // parameter, the formal parameter of a catch clause, or a variable 3124249423Sdim // declared with the register storage class specifier. An 3125249423Sdim // alignment-specifier may also be applied to the declaration of a class 3126249423Sdim // or enumeration type. 3127249423Sdim // C11 6.7.5/2: 3128249423Sdim // An alignment attribute shall not be specified in a declaration of 3129249423Sdim // a typedef, or a bit-field, or a function, or a parameter, or an 3130249423Sdim // object declared with the register storage-class specifier. 3131249423Sdim int DiagKind = -1; 3132249423Sdim if (isa<ParmVarDecl>(D)) { 3133249423Sdim DiagKind = 0; 3134249423Sdim } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3135249423Sdim if (VD->getStorageClass() == SC_Register) 3136249423Sdim DiagKind = 1; 3137249423Sdim if (VD->isExceptionVariable()) 3138249423Sdim DiagKind = 2; 3139249423Sdim } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 3140249423Sdim if (FD->isBitField()) 3141249423Sdim DiagKind = 3; 3142249423Sdim } else if (!isa<TagDecl>(D)) { 3143276479Sdim Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr 3144249423Sdim << (TmpAttr.isC11() ? ExpectedVariableOrField 3145249423Sdim : ExpectedVariableFieldOrTag); 3146249423Sdim return; 3147249423Sdim } 3148249423Sdim if (DiagKind != -1) { 3149249423Sdim Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type) 3150276479Sdim << &TmpAttr << DiagKind; 3151249423Sdim return; 3152249423Sdim } 3153249423Sdim } 3154249423Sdim 3155210299Sed if (E->isTypeDependent() || E->isValueDependent()) { 3156210299Sed // Save dependent expressions in the AST to be instantiated. 3157249423Sdim AlignedAttr *AA = ::new (Context) AlignedAttr(TmpAttr); 3158249423Sdim AA->setPackExpansion(IsPackExpansion); 3159249423Sdim D->addAttr(AA); 3160210299Sed return; 3161210299Sed } 3162249423Sdim 3163212904Sdim // FIXME: Cache the number on the Attr object? 3164296417Sdim llvm::APSInt Alignment; 3165239462Sdim ExprResult ICE 3166239462Sdim = VerifyIntegerConstantExpression(E, &Alignment, 3167239462Sdim diag::err_aligned_attribute_argument_not_int, 3168239462Sdim /*AllowFold*/ false); 3169234353Sdim if (ICE.isInvalid()) 3170193326Sed return; 3171249423Sdim 3172296417Sdim uint64_t AlignVal = Alignment.getZExtValue(); 3173296417Sdim 3174249423Sdim // C++11 [dcl.align]p2: 3175249423Sdim // -- if the constant expression evaluates to zero, the alignment 3176249423Sdim // specifier shall have no effect 3177249423Sdim // C11 6.7.5p6: 3178249423Sdim // An alignment specification of zero has no effect. 3179288943Sdim if (!(TmpAttr.isAlignas() && !Alignment)) { 3180296417Sdim if (!llvm::isPowerOf2_64(AlignVal)) { 3181288943Sdim Diag(AttrLoc, diag::err_alignment_not_power_of_two) 3182288943Sdim << E->getSourceRange(); 3183288943Sdim return; 3184288943Sdim } 3185193326Sed } 3186249423Sdim 3187276479Sdim // Alignment calculations can wrap around if it's greater than 2**28. 3188296417Sdim unsigned MaxValidAlignment = 3189296417Sdim Context.getTargetInfo().getTriple().isOSBinFormatCOFF() ? 8192 3190296417Sdim : 268435456; 3191296417Sdim if (AlignVal > MaxValidAlignment) { 3192276479Sdim Diag(AttrLoc, diag::err_attribute_aligned_too_great) << MaxValidAlignment 3193276479Sdim << E->getSourceRange(); 3194276479Sdim return; 3195239462Sdim } 3196193326Sed 3197296417Sdim if (Context.getTargetInfo().isTLSSupported()) { 3198296417Sdim unsigned MaxTLSAlign = 3199296417Sdim Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign()) 3200296417Sdim .getQuantity(); 3201296417Sdim auto *VD = dyn_cast<VarDecl>(D); 3202296417Sdim if (MaxTLSAlign && AlignVal > MaxTLSAlign && VD && 3203296417Sdim VD->getTLSKind() != VarDecl::TLS_None) { 3204296417Sdim Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum) 3205296417Sdim << (unsigned)AlignVal << VD << MaxTLSAlign; 3206296417Sdim return; 3207296417Sdim } 3208296417Sdim } 3209296417Sdim 3210249423Sdim AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true, 3211276479Sdim ICE.get(), SpellingListIndex); 3212249423Sdim AA->setPackExpansion(IsPackExpansion); 3213249423Sdim D->addAttr(AA); 3214193326Sed} 3215193326Sed 3216249423Sdimvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, 3217249423Sdim unsigned SpellingListIndex, bool IsPackExpansion) { 3218212904Sdim // FIXME: Cache the number on the Attr object if non-dependent? 3219212904Sdim // FIXME: Perform checking of type validity 3220249423Sdim AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, false, TS, 3221249423Sdim SpellingListIndex); 3222249423Sdim AA->setPackExpansion(IsPackExpansion); 3223249423Sdim D->addAttr(AA); 3224212904Sdim} 3225212904Sdim 3226249423Sdimvoid Sema::CheckAlignasUnderalignment(Decl *D) { 3227249423Sdim assert(D->hasAttrs() && "no attributes on decl"); 3228249423Sdim 3229288943Sdim QualType UnderlyingTy, DiagTy; 3230288943Sdim if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 3231288943Sdim UnderlyingTy = DiagTy = VD->getType(); 3232288943Sdim } else { 3233288943Sdim UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D)); 3234288943Sdim if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) 3235288943Sdim UnderlyingTy = ED->getIntegerType(); 3236288943Sdim } 3237288943Sdim if (DiagTy->isDependentType() || DiagTy->isIncompleteType()) 3238249423Sdim return; 3239249423Sdim 3240249423Sdim // C++11 [dcl.align]p5, C11 6.7.5/4: 3241249423Sdim // The combined effect of all alignment attributes in a declaration shall 3242249423Sdim // not specify an alignment that is less strict than the alignment that 3243249423Sdim // would otherwise be required for the entity being declared. 3244276479Sdim AlignedAttr *AlignasAttr = nullptr; 3245249423Sdim unsigned Align = 0; 3246276479Sdim for (auto *I : D->specific_attrs<AlignedAttr>()) { 3247249423Sdim if (I->isAlignmentDependent()) 3248249423Sdim return; 3249249423Sdim if (I->isAlignas()) 3250276479Sdim AlignasAttr = I; 3251249423Sdim Align = std::max(Align, I->getAlignment(Context)); 3252249423Sdim } 3253249423Sdim 3254249423Sdim if (AlignasAttr && Align) { 3255249423Sdim CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align); 3256288943Sdim CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy); 3257249423Sdim if (NaturalAlign > RequestedAlign) 3258249423Sdim Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned) 3259288943Sdim << DiagTy << (unsigned)NaturalAlign.getQuantity(); 3260249423Sdim } 3261249423Sdim} 3262249423Sdim 3263276479Sdimbool Sema::checkMSInheritanceAttrOnDefinition( 3264276479Sdim CXXRecordDecl *RD, SourceRange Range, bool BestCase, 3265276479Sdim MSInheritanceAttr::Spelling SemanticSpelling) { 3266276479Sdim assert(RD->hasDefinition() && "RD has no definition!"); 3267276479Sdim 3268276479Sdim // We may not have seen base specifiers or any virtual methods yet. We will 3269276479Sdim // have to wait until the record is defined to catch any mismatches. 3270276479Sdim if (!RD->getDefinition()->isCompleteDefinition()) 3271276479Sdim return false; 3272276479Sdim 3273276479Sdim // The unspecified model never matches what a definition could need. 3274276479Sdim if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) 3275276479Sdim return false; 3276276479Sdim 3277276479Sdim if (BestCase) { 3278276479Sdim if (RD->calculateInheritanceModel() == SemanticSpelling) 3279276479Sdim return false; 3280276479Sdim } else { 3281276479Sdim if (RD->calculateInheritanceModel() <= SemanticSpelling) 3282276479Sdim return false; 3283276479Sdim } 3284276479Sdim 3285276479Sdim Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) 3286276479Sdim << 0 /*definition*/; 3287276479Sdim Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) 3288276479Sdim << RD->getNameAsString(); 3289276479Sdim return true; 3290276479Sdim} 3291276479Sdim 3292296417Sdim/// parseModeAttrArg - Parses attribute mode string and returns parsed type 3293296417Sdim/// attribute. 3294296417Sdimstatic void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth, 3295296417Sdim bool &IntegerMode, bool &ComplexMode) { 3296198398Srdivacky switch (Str.size()) { 3297193326Sed case 2: 3298193326Sed switch (Str[0]) { 3299296417Sdim case 'Q': 3300296417Sdim DestWidth = 8; 3301296417Sdim break; 3302296417Sdim case 'H': 3303296417Sdim DestWidth = 16; 3304296417Sdim break; 3305296417Sdim case 'S': 3306296417Sdim DestWidth = 32; 3307296417Sdim break; 3308296417Sdim case 'D': 3309296417Sdim DestWidth = 64; 3310296417Sdim break; 3311296417Sdim case 'X': 3312296417Sdim DestWidth = 96; 3313296417Sdim break; 3314296417Sdim case 'T': 3315296417Sdim DestWidth = 128; 3316296417Sdim break; 3317193326Sed } 3318193326Sed if (Str[1] == 'F') { 3319193326Sed IntegerMode = false; 3320193326Sed } else if (Str[1] == 'C') { 3321193326Sed IntegerMode = false; 3322193326Sed ComplexMode = true; 3323193326Sed } else if (Str[1] != 'I') { 3324193326Sed DestWidth = 0; 3325193326Sed } 3326193326Sed break; 3327193326Sed case 4: 3328193326Sed // FIXME: glibc uses 'word' to define register_t; this is narrower than a 3329193326Sed // pointer on PIC16 and other embedded platforms. 3330198398Srdivacky if (Str == "word") 3331226633Sdim DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3332198398Srdivacky else if (Str == "byte") 3333226633Sdim DestWidth = S.Context.getTargetInfo().getCharWidth(); 3334193326Sed break; 3335193326Sed case 7: 3336198398Srdivacky if (Str == "pointer") 3337226633Sdim DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3338193326Sed break; 3339249423Sdim case 11: 3340249423Sdim if (Str == "unwind_word") 3341249423Sdim DestWidth = S.Context.getTargetInfo().getUnwindWordWidth(); 3342249423Sdim break; 3343193326Sed } 3344296417Sdim} 3345193326Sed 3346296417Sdim/// handleModeAttr - This attribute modifies the width of a decl with primitive 3347296417Sdim/// type. 3348296417Sdim/// 3349296417Sdim/// Despite what would be logical, the mode attribute is a decl attribute, not a 3350296417Sdim/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 3351296417Sdim/// HImode, not an intermediate pointer. 3352296417Sdimstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3353296417Sdim // This attribute isn't documented, but glibc uses it. It changes 3354296417Sdim // the width of an int or unsigned int to the specified size. 3355296417Sdim if (!Attr.isArgIdent(0)) { 3356296417Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() 3357296417Sdim << AANT_ArgumentIdentifier; 3358296417Sdim return; 3359296417Sdim } 3360296417Sdim 3361296417Sdim IdentifierInfo *Name = Attr.getArgAsIdent(0)->Ident; 3362296417Sdim StringRef Str = Name->getName(); 3363296417Sdim 3364296417Sdim normalizeName(Str); 3365296417Sdim 3366296417Sdim unsigned DestWidth = 0; 3367296417Sdim bool IntegerMode = true; 3368296417Sdim bool ComplexMode = false; 3369296417Sdim llvm::APInt VectorSize(64, 0); 3370296417Sdim if (Str.size() >= 4 && Str[0] == 'V') { 3371296417Sdim // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2). 3372296417Sdim size_t StrSize = Str.size(); 3373296417Sdim size_t VectorStringLength = 0; 3374296417Sdim while ((VectorStringLength + 1) < StrSize && 3375296417Sdim isdigit(Str[VectorStringLength + 1])) 3376296417Sdim ++VectorStringLength; 3377296417Sdim if (VectorStringLength && 3378296417Sdim !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) && 3379296417Sdim VectorSize.isPowerOf2()) { 3380296417Sdim parseModeAttrArg(S, Str.substr(VectorStringLength + 1), DestWidth, 3381296417Sdim IntegerMode, ComplexMode); 3382296417Sdim S.Diag(Attr.getLoc(), diag::warn_vector_mode_deprecated); 3383296417Sdim } else { 3384296417Sdim VectorSize = 0; 3385296417Sdim } 3386296417Sdim } 3387296417Sdim 3388296417Sdim if (!VectorSize) 3389296417Sdim parseModeAttrArg(S, Str, DestWidth, IntegerMode, ComplexMode); 3390296417Sdim 3391193326Sed QualType OldTy; 3392221345Sdim if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3393193326Sed OldTy = TD->getUnderlyingType(); 3394193326Sed else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 3395193326Sed OldTy = VD->getType(); 3396193326Sed else { 3397193326Sed S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 3398276479Sdim << Attr.getName() << Attr.getRange(); 3399193326Sed return; 3400193326Sed } 3401193326Sed 3402288943Sdim // Base type can also be a vector type (see PR17453). 3403288943Sdim // Distinguish between base type and base element type. 3404288943Sdim QualType OldElemTy = OldTy; 3405288943Sdim if (const VectorType *VT = OldTy->getAs<VectorType>()) 3406288943Sdim OldElemTy = VT->getElementType(); 3407288943Sdim 3408288943Sdim if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType()) 3409193326Sed S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 3410193326Sed else if (IntegerMode) { 3411288943Sdim if (!OldElemTy->isIntegralOrEnumerationType()) 3412193326Sed S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3413193326Sed } else if (ComplexMode) { 3414288943Sdim if (!OldElemTy->isComplexType()) 3415193326Sed S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3416193326Sed } else { 3417288943Sdim if (!OldElemTy->isFloatingType()) 3418193326Sed S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3419193326Sed } 3420193326Sed 3421193326Sed // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 3422193326Sed // and friends, at least with glibc. 3423193326Sed // FIXME: Make sure floating-point mappings are accurate 3424193326Sed // FIXME: Support XF and TF types 3425261991Sdim if (!DestWidth) { 3426276479Sdim S.Diag(Attr.getLoc(), diag::err_machine_mode) << 0 /*Unknown*/ << Name; 3427193326Sed return; 3428261991Sdim } 3429261991Sdim 3430288943Sdim QualType NewElemTy; 3431261991Sdim 3432261991Sdim if (IntegerMode) 3433288943Sdim NewElemTy = S.Context.getIntTypeForBitwidth( 3434288943Sdim DestWidth, OldElemTy->isSignedIntegerType()); 3435261991Sdim else 3436288943Sdim NewElemTy = S.Context.getRealTypeForBitwidth(DestWidth); 3437261991Sdim 3438288943Sdim if (NewElemTy.isNull()) { 3439276479Sdim S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name; 3440193326Sed return; 3441193326Sed } 3442193326Sed 3443193326Sed if (ComplexMode) { 3444288943Sdim NewElemTy = S.Context.getComplexType(NewElemTy); 3445193326Sed } 3446193326Sed 3447288943Sdim QualType NewTy = NewElemTy; 3448296417Sdim if (VectorSize.getBoolValue()) { 3449296417Sdim NewTy = S.Context.getVectorType(NewTy, VectorSize.getZExtValue(), 3450296417Sdim VectorType::GenericVector); 3451296417Sdim } else if (const VectorType *OldVT = OldTy->getAs<VectorType>()) { 3452288943Sdim // Complex machine mode does not support base vector types. 3453288943Sdim if (ComplexMode) { 3454288943Sdim S.Diag(Attr.getLoc(), diag::err_complex_mode_vector_type); 3455288943Sdim return; 3456288943Sdim } 3457288943Sdim unsigned NumElements = S.Context.getTypeSize(OldElemTy) * 3458288943Sdim OldVT->getNumElements() / 3459288943Sdim S.Context.getTypeSize(NewElemTy); 3460288943Sdim NewTy = 3461288943Sdim S.Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind()); 3462288943Sdim } 3463288943Sdim 3464288943Sdim if (NewTy.isNull()) { 3465288943Sdim S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 3466288943Sdim return; 3467288943Sdim } 3468288943Sdim 3469193326Sed // Install the new type. 3470261991Sdim if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3471261991Sdim TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy); 3472261991Sdim else 3473193326Sed cast<ValueDecl>(D)->setType(NewTy); 3474261991Sdim 3475261991Sdim D->addAttr(::new (S.Context) 3476261991Sdim ModeAttr(Attr.getRange(), S.Context, Name, 3477261991Sdim Attr.getAttributeSpellingListIndex())); 3478193326Sed} 3479193326Sed 3480224145Sdimstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3481239462Sdim if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 3482239462Sdim if (!VD->hasGlobalStorage()) 3483239462Sdim S.Diag(Attr.getLoc(), 3484239462Sdim diag::warn_attribute_requires_functions_or_static_globals) 3485239462Sdim << Attr.getName(); 3486239462Sdim } else if (!isFunctionOrMethod(D)) { 3487239462Sdim S.Diag(Attr.getLoc(), 3488239462Sdim diag::warn_attribute_requires_functions_or_static_globals) 3489239462Sdim << Attr.getName(); 3490193326Sed return; 3491193326Sed } 3492198092Srdivacky 3493249423Sdim D->addAttr(::new (S.Context) 3494249423Sdim NoDebugAttr(Attr.getRange(), S.Context, 3495249423Sdim Attr.getAttributeSpellingListIndex())); 3496193326Sed} 3497193326Sed 3498280031SdimAlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D, SourceRange Range, 3499280031Sdim IdentifierInfo *Ident, 3500280031Sdim unsigned AttrSpellingListIndex) { 3501280031Sdim if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) { 3502280031Sdim Diag(Range.getBegin(), diag::warn_attribute_ignored) << Ident; 3503280031Sdim Diag(Optnone->getLocation(), diag::note_conflicting_attribute); 3504280031Sdim return nullptr; 3505280031Sdim } 3506280031Sdim 3507280031Sdim if (D->hasAttr<AlwaysInlineAttr>()) 3508280031Sdim return nullptr; 3509280031Sdim 3510280031Sdim return ::new (Context) AlwaysInlineAttr(Range, Context, 3511280031Sdim AttrSpellingListIndex); 3512280031Sdim} 3513280031Sdim 3514296417SdimCommonAttr *Sema::mergeCommonAttr(Decl *D, SourceRange Range, 3515296417Sdim IdentifierInfo *Ident, 3516296417Sdim unsigned AttrSpellingListIndex) { 3517296417Sdim if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, Range, Ident)) 3518296417Sdim return nullptr; 3519296417Sdim 3520296417Sdim return ::new (Context) CommonAttr(Range, Context, AttrSpellingListIndex); 3521296417Sdim} 3522296417Sdim 3523296417SdimInternalLinkageAttr * 3524296417SdimSema::mergeInternalLinkageAttr(Decl *D, SourceRange Range, 3525296417Sdim IdentifierInfo *Ident, 3526296417Sdim unsigned AttrSpellingListIndex) { 3527296417Sdim if (auto VD = dyn_cast<VarDecl>(D)) { 3528296417Sdim // Attribute applies to Var but not any subclass of it (like ParmVar, 3529296417Sdim // ImplicitParm or VarTemplateSpecialization). 3530296417Sdim if (VD->getKind() != Decl::Var) { 3531296417Sdim Diag(Range.getBegin(), diag::warn_attribute_wrong_decl_type) 3532296417Sdim << Ident << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass 3533296417Sdim : ExpectedVariableOrFunction); 3534296417Sdim return nullptr; 3535296417Sdim } 3536296417Sdim // Attribute does not apply to non-static local variables. 3537296417Sdim if (VD->hasLocalStorage()) { 3538296417Sdim Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage); 3539296417Sdim return nullptr; 3540296417Sdim } 3541296417Sdim } 3542296417Sdim 3543296417Sdim if (checkAttrMutualExclusion<CommonAttr>(*this, D, Range, Ident)) 3544296417Sdim return nullptr; 3545296417Sdim 3546296417Sdim return ::new (Context) 3547296417Sdim InternalLinkageAttr(Range, Context, AttrSpellingListIndex); 3548296417Sdim} 3549296417Sdim 3550280031SdimMinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range, 3551280031Sdim unsigned AttrSpellingListIndex) { 3552280031Sdim if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) { 3553280031Sdim Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'minsize'"; 3554280031Sdim Diag(Optnone->getLocation(), diag::note_conflicting_attribute); 3555280031Sdim return nullptr; 3556280031Sdim } 3557280031Sdim 3558280031Sdim if (D->hasAttr<MinSizeAttr>()) 3559280031Sdim return nullptr; 3560280031Sdim 3561280031Sdim return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex); 3562280031Sdim} 3563280031Sdim 3564280031SdimOptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range, 3565280031Sdim unsigned AttrSpellingListIndex) { 3566280031Sdim if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) { 3567280031Sdim Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline; 3568280031Sdim Diag(Range.getBegin(), diag::note_conflicting_attribute); 3569280031Sdim D->dropAttr<AlwaysInlineAttr>(); 3570280031Sdim } 3571280031Sdim if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) { 3572280031Sdim Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize; 3573280031Sdim Diag(Range.getBegin(), diag::note_conflicting_attribute); 3574280031Sdim D->dropAttr<MinSizeAttr>(); 3575280031Sdim } 3576280031Sdim 3577280031Sdim if (D->hasAttr<OptimizeNoneAttr>()) 3578280031Sdim return nullptr; 3579280031Sdim 3580280031Sdim return ::new (Context) OptimizeNoneAttr(Range, Context, 3581280031Sdim AttrSpellingListIndex); 3582280031Sdim} 3583280031Sdim 3584276479Sdimstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 3585276479Sdim const AttributeList &Attr) { 3586296417Sdim if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, Attr.getRange(), 3587296417Sdim Attr.getName())) 3588296417Sdim return; 3589296417Sdim 3590280031Sdim if (AlwaysInlineAttr *Inline = S.mergeAlwaysInlineAttr( 3591280031Sdim D, Attr.getRange(), Attr.getName(), 3592280031Sdim Attr.getAttributeSpellingListIndex())) 3593280031Sdim D->addAttr(Inline); 3594280031Sdim} 3595198092Srdivacky 3596280031Sdimstatic void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3597280031Sdim if (MinSizeAttr *MinSize = S.mergeMinSizeAttr( 3598280031Sdim D, Attr.getRange(), Attr.getAttributeSpellingListIndex())) 3599280031Sdim D->addAttr(MinSize); 3600193326Sed} 3601193326Sed 3602276479Sdimstatic void handleOptimizeNoneAttr(Sema &S, Decl *D, 3603276479Sdim const AttributeList &Attr) { 3604280031Sdim if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr( 3605280031Sdim D, Attr.getRange(), Attr.getAttributeSpellingListIndex())) 3606280031Sdim D->addAttr(Optnone); 3607218893Sdim} 3608218893Sdim 3609224145Sdimstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3610296417Sdim if (checkAttrMutualExclusion<CUDADeviceAttr>(S, D, Attr.getRange(), 3611296417Sdim Attr.getName()) || 3612296417Sdim checkAttrMutualExclusion<CUDAHostAttr>(S, D, Attr.getRange(), 3613296417Sdim Attr.getName())) { 3614296417Sdim return; 3615296417Sdim } 3616276479Sdim FunctionDecl *FD = cast<FunctionDecl>(D); 3617276479Sdim if (!FD->getReturnType()->isVoidType()) { 3618276479Sdim SourceRange RTRange = FD->getReturnTypeSourceRange(); 3619276479Sdim S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 3620276479Sdim << FD->getType() 3621276479Sdim << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void") 3622276479Sdim : FixItHint()); 3623276479Sdim return; 3624218893Sdim } 3625218893Sdim 3626276479Sdim D->addAttr(::new (S.Context) 3627276479Sdim CUDAGlobalAttr(Attr.getRange(), S.Context, 3628280031Sdim Attr.getAttributeSpellingListIndex())); 3629296417Sdim 3630218893Sdim} 3631218893Sdim 3632224145Sdimstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3633276479Sdim FunctionDecl *Fn = cast<FunctionDecl>(D); 3634198893Srdivacky if (!Fn->isInlineSpecified()) { 3635193326Sed S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 3636193326Sed return; 3637193326Sed } 3638198092Srdivacky 3639249423Sdim D->addAttr(::new (S.Context) 3640249423Sdim GNUInlineAttr(Attr.getRange(), S.Context, 3641249423Sdim Attr.getAttributeSpellingListIndex())); 3642193326Sed} 3643193326Sed 3644224145Sdimstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3645224145Sdim if (hasDeclarator(D)) return; 3646218893Sdim 3647224145Sdim // Diagnostic is emitted elsewhere: here we store the (valid) Attr 3648207619Srdivacky // in the Decl node for syntactic reasoning, e.g., pretty-printing. 3649218893Sdim CallingConv CC; 3650288943Sdim if (S.CheckCallingConvAttr(Attr, CC, /*FD*/nullptr)) 3651218893Sdim return; 3652207619Srdivacky 3653224145Sdim if (!isa<ObjCMethodDecl>(D)) { 3654224145Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3655224145Sdim << Attr.getName() << ExpectedFunctionOrMethod; 3656218893Sdim return; 3657218893Sdim } 3658218893Sdim 3659224145Sdim switch (Attr.getKind()) { 3660239462Sdim case AttributeList::AT_FastCall: 3661249423Sdim D->addAttr(::new (S.Context) 3662249423Sdim FastCallAttr(Attr.getRange(), S.Context, 3663249423Sdim Attr.getAttributeSpellingListIndex())); 3664207619Srdivacky return; 3665239462Sdim case AttributeList::AT_StdCall: 3666249423Sdim D->addAttr(::new (S.Context) 3667249423Sdim StdCallAttr(Attr.getRange(), S.Context, 3668249423Sdim Attr.getAttributeSpellingListIndex())); 3669207619Srdivacky return; 3670239462Sdim case AttributeList::AT_ThisCall: 3671249423Sdim D->addAttr(::new (S.Context) 3672249423Sdim ThisCallAttr(Attr.getRange(), S.Context, 3673249423Sdim Attr.getAttributeSpellingListIndex())); 3674212904Sdim return; 3675239462Sdim case AttributeList::AT_CDecl: 3676249423Sdim D->addAttr(::new (S.Context) 3677249423Sdim CDeclAttr(Attr.getRange(), S.Context, 3678249423Sdim Attr.getAttributeSpellingListIndex())); 3679207619Srdivacky return; 3680239462Sdim case AttributeList::AT_Pascal: 3681249423Sdim D->addAttr(::new (S.Context) 3682249423Sdim PascalAttr(Attr.getRange(), S.Context, 3683249423Sdim Attr.getAttributeSpellingListIndex())); 3684212904Sdim return; 3685280031Sdim case AttributeList::AT_VectorCall: 3686280031Sdim D->addAttr(::new (S.Context) 3687280031Sdim VectorCallAttr(Attr.getRange(), S.Context, 3688280031Sdim Attr.getAttributeSpellingListIndex())); 3689280031Sdim return; 3690256030Sdim case AttributeList::AT_MSABI: 3691256030Sdim D->addAttr(::new (S.Context) 3692256030Sdim MSABIAttr(Attr.getRange(), S.Context, 3693256030Sdim Attr.getAttributeSpellingListIndex())); 3694256030Sdim return; 3695256030Sdim case AttributeList::AT_SysVABI: 3696256030Sdim D->addAttr(::new (S.Context) 3697256030Sdim SysVABIAttr(Attr.getRange(), S.Context, 3698256030Sdim Attr.getAttributeSpellingListIndex())); 3699256030Sdim return; 3700239462Sdim case AttributeList::AT_Pcs: { 3701221345Sdim PcsAttr::PCSType PCS; 3702239462Sdim switch (CC) { 3703239462Sdim case CC_AAPCS: 3704221345Sdim PCS = PcsAttr::AAPCS; 3705239462Sdim break; 3706239462Sdim case CC_AAPCS_VFP: 3707221345Sdim PCS = PcsAttr::AAPCS_VFP; 3708239462Sdim break; 3709239462Sdim default: 3710239462Sdim llvm_unreachable("unexpected calling convention in pcs attribute"); 3711221345Sdim } 3712221345Sdim 3713249423Sdim D->addAttr(::new (S.Context) 3714249423Sdim PcsAttr(Attr.getRange(), S.Context, PCS, 3715249423Sdim Attr.getAttributeSpellingListIndex())); 3716243830Sdim return; 3717221345Sdim } 3718249423Sdim case AttributeList::AT_IntelOclBicc: 3719249423Sdim D->addAttr(::new (S.Context) 3720249423Sdim IntelOclBiccAttr(Attr.getRange(), S.Context, 3721249423Sdim Attr.getAttributeSpellingListIndex())); 3722249423Sdim return; 3723243830Sdim 3724207619Srdivacky default: 3725207619Srdivacky llvm_unreachable("unexpected attribute kind"); 3726207619Srdivacky } 3727207619Srdivacky} 3728207619Srdivacky 3729249423Sdimbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 3730249423Sdim const FunctionDecl *FD) { 3731218893Sdim if (attr.isInvalid()) 3732218893Sdim return true; 3733218893Sdim 3734239462Sdim unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0; 3735261991Sdim if (!checkAttributeNumArgs(*this, attr, ReqArgs)) { 3736218893Sdim attr.setInvalid(); 3737218893Sdim return true; 3738193326Sed } 3739193326Sed 3740276479Sdim // TODO: diagnose uses of these conventions on the wrong target. 3741218893Sdim switch (attr.getKind()) { 3742239462Sdim case AttributeList::AT_CDecl: CC = CC_C; break; 3743239462Sdim case AttributeList::AT_FastCall: CC = CC_X86FastCall; break; 3744239462Sdim case AttributeList::AT_StdCall: CC = CC_X86StdCall; break; 3745239462Sdim case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break; 3746239462Sdim case AttributeList::AT_Pascal: CC = CC_X86Pascal; break; 3747280031Sdim case AttributeList::AT_VectorCall: CC = CC_X86VectorCall; break; 3748256030Sdim case AttributeList::AT_MSABI: 3749256030Sdim CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C : 3750256030Sdim CC_X86_64Win64; 3751256030Sdim break; 3752256030Sdim case AttributeList::AT_SysVABI: 3753256030Sdim CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV : 3754256030Sdim CC_C; 3755256030Sdim break; 3756239462Sdim case AttributeList::AT_Pcs: { 3757261991Sdim StringRef StrRef; 3758261991Sdim if (!checkStringLiteralArgumentAttr(attr, 0, StrRef)) { 3759221345Sdim attr.setInvalid(); 3760221345Sdim return true; 3761221345Sdim } 3762221345Sdim if (StrRef == "aapcs") { 3763221345Sdim CC = CC_AAPCS; 3764221345Sdim break; 3765221345Sdim } else if (StrRef == "aapcs-vfp") { 3766221345Sdim CC = CC_AAPCS_VFP; 3767221345Sdim break; 3768221345Sdim } 3769239462Sdim 3770239462Sdim attr.setInvalid(); 3771239462Sdim Diag(attr.getLoc(), diag::err_invalid_pcs); 3772239462Sdim return true; 3773221345Sdim } 3774249423Sdim case AttributeList::AT_IntelOclBicc: CC = CC_IntelOclBicc; break; 3775234353Sdim default: llvm_unreachable("unexpected attribute kind"); 3776218893Sdim } 3777218893Sdim 3778243830Sdim const TargetInfo &TI = Context.getTargetInfo(); 3779243830Sdim TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); 3780288943Sdim if (A != TargetInfo::CCCR_OK) { 3781288943Sdim if (A == TargetInfo::CCCR_Warning) 3782288943Sdim Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); 3783249423Sdim 3784288943Sdim // This convention is not valid for the target. Use the default function or 3785288943Sdim // method calling convention. 3786249423Sdim TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown; 3787249423Sdim if (FD) 3788249423Sdim MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member : 3789249423Sdim TargetInfo::CCMT_NonMember; 3790249423Sdim CC = TI.getDefaultCallingConv(MT); 3791243830Sdim } 3792243830Sdim 3793218893Sdim return false; 3794218893Sdim} 3795218893Sdim 3796218893Sdim/// Checks a regparm attribute, returning true if it is ill-formed and 3797218893Sdim/// otherwise setting numParams to the appropriate value. 3798224145Sdimbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 3799224145Sdim if (Attr.isInvalid()) 3800218893Sdim return true; 3801218893Sdim 3802261991Sdim if (!checkAttributeNumArgs(*this, Attr, 1)) { 3803224145Sdim Attr.setInvalid(); 3804218893Sdim return true; 3805218893Sdim } 3806218893Sdim 3807276479Sdim uint32_t NP; 3808261991Sdim Expr *NumParamsExpr = Attr.getArgAsExpr(0); 3809276479Sdim if (!checkUInt32Argument(*this, Attr, NumParamsExpr, NP)) { 3810224145Sdim Attr.setInvalid(); 3811218893Sdim return true; 3812193326Sed } 3813193326Sed 3814226633Sdim if (Context.getTargetInfo().getRegParmMax() == 0) { 3815224145Sdim Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 3816193326Sed << NumParamsExpr->getSourceRange(); 3817224145Sdim Attr.setInvalid(); 3818218893Sdim return true; 3819193326Sed } 3820193326Sed 3821276479Sdim numParams = NP; 3822226633Sdim if (numParams > Context.getTargetInfo().getRegParmMax()) { 3823224145Sdim Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3824226633Sdim << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 3825224145Sdim Attr.setInvalid(); 3826218893Sdim return true; 3827193326Sed } 3828193326Sed 3829218893Sdim return false; 3830193326Sed} 3831193326Sed 3832288943Sdim// Checks whether an argument of launch_bounds attribute is acceptable 3833288943Sdim// May output an error. 3834288943Sdimstatic bool checkLaunchBoundsArgument(Sema &S, Expr *E, 3835288943Sdim const CUDALaunchBoundsAttr &Attr, 3836288943Sdim const unsigned Idx) { 3837288943Sdim 3838288943Sdim if (S.DiagnoseUnexpandedParameterPack(E)) 3839288943Sdim return false; 3840288943Sdim 3841288943Sdim // Accept template arguments for now as they depend on something else. 3842288943Sdim // We'll get to check them when they eventually get instantiated. 3843288943Sdim if (E->isValueDependent()) 3844288943Sdim return true; 3845288943Sdim 3846288943Sdim llvm::APSInt I(64); 3847288943Sdim if (!E->isIntegerConstantExpr(I, S.Context)) { 3848288943Sdim S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type) 3849288943Sdim << &Attr << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange(); 3850288943Sdim return false; 3851288943Sdim } 3852288943Sdim // Make sure we can fit it in 32 bits. 3853288943Sdim if (!I.isIntN(32)) { 3854288943Sdim S.Diag(E->getExprLoc(), diag::err_ice_too_large) << I.toString(10, false) 3855288943Sdim << 32 << /* Unsigned */ 1; 3856288943Sdim return false; 3857288943Sdim } 3858288943Sdim if (I < 0) 3859288943Sdim S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative) 3860288943Sdim << &Attr << Idx << E->getSourceRange(); 3861288943Sdim 3862288943Sdim return true; 3863288943Sdim} 3864288943Sdim 3865288943Sdimvoid Sema::AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, 3866288943Sdim Expr *MinBlocks, unsigned SpellingListIndex) { 3867288943Sdim CUDALaunchBoundsAttr TmpAttr(AttrRange, Context, MaxThreads, MinBlocks, 3868288943Sdim SpellingListIndex); 3869288943Sdim 3870288943Sdim if (!checkLaunchBoundsArgument(*this, MaxThreads, TmpAttr, 0)) 3871288943Sdim return; 3872288943Sdim 3873288943Sdim if (MinBlocks && !checkLaunchBoundsArgument(*this, MinBlocks, TmpAttr, 1)) 3874288943Sdim return; 3875288943Sdim 3876288943Sdim D->addAttr(::new (Context) CUDALaunchBoundsAttr( 3877288943Sdim AttrRange, Context, MaxThreads, MinBlocks, SpellingListIndex)); 3878288943Sdim} 3879288943Sdim 3880276479Sdimstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, 3881276479Sdim const AttributeList &Attr) { 3882288943Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1) || 3883288943Sdim !checkAttributeAtMostNumArgs(S, Attr, 2)) 3884276479Sdim return; 3885218893Sdim 3886288943Sdim S.AddLaunchBoundsAttr(Attr.getRange(), D, Attr.getArgAsExpr(0), 3887288943Sdim Attr.getNumArgs() > 1 ? Attr.getArgAsExpr(1) : nullptr, 3888288943Sdim Attr.getAttributeSpellingListIndex()); 3889199990Srdivacky} 3890199990Srdivacky 3891239462Sdimstatic void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, 3892239462Sdim const AttributeList &Attr) { 3893261991Sdim if (!Attr.isArgIdent(0)) { 3894261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 3895261991Sdim << Attr.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier; 3896239462Sdim return; 3897239462Sdim } 3898261991Sdim 3899261991Sdim if (!checkAttributeNumArgs(S, Attr, 3)) 3900239462Sdim return; 3901239462Sdim 3902261991Sdim IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident; 3903239462Sdim 3904239462Sdim if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 3905239462Sdim S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 3906239462Sdim << Attr.getName() << ExpectedFunctionOrMethod; 3907239462Sdim return; 3908239462Sdim } 3909239462Sdim 3910239462Sdim uint64_t ArgumentIdx; 3911276479Sdim if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 2, Attr.getArgAsExpr(1), 3912276479Sdim ArgumentIdx)) 3913239462Sdim return; 3914239462Sdim 3915239462Sdim uint64_t TypeTagIdx; 3916276479Sdim if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 3, Attr.getArgAsExpr(2), 3917276479Sdim TypeTagIdx)) 3918239462Sdim return; 3919239462Sdim 3920276479Sdim bool IsPointer = (Attr.getName()->getName() == "pointer_with_type_tag"); 3921239462Sdim if (IsPointer) { 3922239462Sdim // Ensure that buffer has a pointer type. 3923276479Sdim QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx); 3924239462Sdim if (!BufferTy->isPointerType()) { 3925239462Sdim S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only) 3926296417Sdim << Attr.getName() << 0; 3927239462Sdim } 3928239462Sdim } 3929239462Sdim 3930249423Sdim D->addAttr(::new (S.Context) 3931249423Sdim ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind, 3932249423Sdim ArgumentIdx, TypeTagIdx, IsPointer, 3933249423Sdim Attr.getAttributeSpellingListIndex())); 3934239462Sdim} 3935239462Sdim 3936239462Sdimstatic void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, 3937239462Sdim const AttributeList &Attr) { 3938261991Sdim if (!Attr.isArgIdent(0)) { 3939261991Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) 3940261991Sdim << Attr.getName() << 1 << AANT_ArgumentIdentifier; 3941239462Sdim return; 3942239462Sdim } 3943261991Sdim 3944261991Sdim if (!checkAttributeNumArgs(S, Attr, 1)) 3945261991Sdim return; 3946239462Sdim 3947276479Sdim if (!isa<VarDecl>(D)) { 3948276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 3949276479Sdim << Attr.getName() << ExpectedVariable; 3950276479Sdim return; 3951276479Sdim } 3952276479Sdim 3953261991Sdim IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident; 3954276479Sdim TypeSourceInfo *MatchingCTypeLoc = nullptr; 3955261991Sdim S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc); 3956261991Sdim assert(MatchingCTypeLoc && "no type source info for attribute argument"); 3957239462Sdim 3958249423Sdim D->addAttr(::new (S.Context) 3959249423Sdim TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind, 3960261991Sdim MatchingCTypeLoc, 3961249423Sdim Attr.getLayoutCompatible(), 3962249423Sdim Attr.getMustBeNull(), 3963249423Sdim Attr.getAttributeSpellingListIndex())); 3964239462Sdim} 3965239462Sdim 3966193326Sed//===----------------------------------------------------------------------===// 3967218893Sdim// Checker-specific attribute handlers. 3968199990Srdivacky//===----------------------------------------------------------------------===// 3969199990Srdivacky 3970276479Sdimstatic bool isValidSubjectOfNSReturnsRetainedAttribute(QualType type) { 3971276479Sdim return type->isDependentType() || 3972276479Sdim type->isObjCRetainableType(); 3973276479Sdim} 3974276479Sdim 3975218893Sdimstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 3976226633Sdim return type->isDependentType() || 3977226633Sdim type->isObjCObjectPointerType() || 3978226633Sdim S.Context.isObjCNSObjectType(type); 3979199990Srdivacky} 3980218893Sdimstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 3981226633Sdim return type->isDependentType() || 3982226633Sdim type->isPointerType() || 3983226633Sdim isValidSubjectOfNSAttribute(S, type); 3984218893Sdim} 3985199990Srdivacky 3986224145Sdimstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3987276479Sdim ParmVarDecl *param = cast<ParmVarDecl>(D); 3988276479Sdim bool typeOK, cf; 3989199990Srdivacky 3990239462Sdim if (Attr.getKind() == AttributeList::AT_NSConsumed) { 3991218893Sdim typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3992218893Sdim cf = false; 3993218893Sdim } else { 3994218893Sdim typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3995218893Sdim cf = true; 3996199990Srdivacky } 3997199990Srdivacky 3998218893Sdim if (!typeOK) { 3999224145Sdim S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 4000226633Sdim << Attr.getRange() << Attr.getName() << cf; 4001199990Srdivacky return; 4002199990Srdivacky } 4003199990Srdivacky 4004218893Sdim if (cf) 4005249423Sdim param->addAttr(::new (S.Context) 4006249423Sdim CFConsumedAttr(Attr.getRange(), S.Context, 4007249423Sdim Attr.getAttributeSpellingListIndex())); 4008218893Sdim else 4009249423Sdim param->addAttr(::new (S.Context) 4010249423Sdim NSConsumedAttr(Attr.getRange(), S.Context, 4011249423Sdim Attr.getAttributeSpellingListIndex())); 4012199990Srdivacky} 4013199990Srdivacky 4014224145Sdimstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 4015224145Sdim const AttributeList &Attr) { 4016193326Sed 4017218893Sdim QualType returnType; 4018198092Srdivacky 4019224145Sdim if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 4020276479Sdim returnType = MD->getReturnType(); 4021234353Sdim else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 4022239462Sdim (Attr.getKind() == AttributeList::AT_NSReturnsRetained)) 4023224145Sdim return; // ignore: was handled as a type attribute 4024243830Sdim else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 4025243830Sdim returnType = PD->getType(); 4026224145Sdim else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 4027276479Sdim returnType = FD->getReturnType(); 4028288943Sdim else if (auto *Param = dyn_cast<ParmVarDecl>(D)) { 4029288943Sdim returnType = Param->getType()->getPointeeType(); 4030288943Sdim if (returnType.isNull()) { 4031288943Sdim S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 4032288943Sdim << Attr.getName() << /*pointer-to-CF*/2 4033288943Sdim << Attr.getRange(); 4034288943Sdim return; 4035288943Sdim } 4036288943Sdim } else { 4037288943Sdim AttributeDeclKind ExpectedDeclKind; 4038288943Sdim switch (Attr.getKind()) { 4039288943Sdim default: llvm_unreachable("invalid ownership attribute"); 4040288943Sdim case AttributeList::AT_NSReturnsRetained: 4041288943Sdim case AttributeList::AT_NSReturnsAutoreleased: 4042288943Sdim case AttributeList::AT_NSReturnsNotRetained: 4043288943Sdim ExpectedDeclKind = ExpectedFunctionOrMethod; 4044288943Sdim break; 4045288943Sdim 4046288943Sdim case AttributeList::AT_CFReturnsRetained: 4047288943Sdim case AttributeList::AT_CFReturnsNotRetained: 4048288943Sdim ExpectedDeclKind = ExpectedFunctionMethodOrParameter; 4049288943Sdim break; 4050288943Sdim } 4051224145Sdim S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 4052288943Sdim << Attr.getRange() << Attr.getName() << ExpectedDeclKind; 4053193326Sed return; 4054193326Sed } 4055198092Srdivacky 4056218893Sdim bool typeOK; 4057218893Sdim bool cf; 4058224145Sdim switch (Attr.getKind()) { 4059234353Sdim default: llvm_unreachable("invalid ownership attribute"); 4060276479Sdim case AttributeList::AT_NSReturnsRetained: 4061276479Sdim typeOK = isValidSubjectOfNSReturnsRetainedAttribute(returnType); 4062276479Sdim cf = false; 4063276479Sdim break; 4064276479Sdim 4065239462Sdim case AttributeList::AT_NSReturnsAutoreleased: 4066239462Sdim case AttributeList::AT_NSReturnsNotRetained: 4067218893Sdim typeOK = isValidSubjectOfNSAttribute(S, returnType); 4068218893Sdim cf = false; 4069218893Sdim break; 4070218893Sdim 4071239462Sdim case AttributeList::AT_CFReturnsRetained: 4072239462Sdim case AttributeList::AT_CFReturnsNotRetained: 4073218893Sdim typeOK = isValidSubjectOfCFAttribute(S, returnType); 4074218893Sdim cf = true; 4075218893Sdim break; 4076218893Sdim } 4077218893Sdim 4078218893Sdim if (!typeOK) { 4079288943Sdim if (isa<ParmVarDecl>(D)) { 4080288943Sdim S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 4081288943Sdim << Attr.getName() << /*pointer-to-CF*/2 4082288943Sdim << Attr.getRange(); 4083288943Sdim } else { 4084288943Sdim // Needs to be kept in sync with warn_ns_attribute_wrong_return_type. 4085288943Sdim enum : unsigned { 4086288943Sdim Function, 4087288943Sdim Method, 4088288943Sdim Property 4089288943Sdim } SubjectKind = Function; 4090288943Sdim if (isa<ObjCMethodDecl>(D)) 4091288943Sdim SubjectKind = Method; 4092288943Sdim else if (isa<ObjCPropertyDecl>(D)) 4093288943Sdim SubjectKind = Property; 4094288943Sdim S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 4095288943Sdim << Attr.getName() << SubjectKind << cf 4096288943Sdim << Attr.getRange(); 4097288943Sdim } 4098198092Srdivacky return; 4099193326Sed } 4100198092Srdivacky 4101224145Sdim switch (Attr.getKind()) { 4102193326Sed default: 4103226633Sdim llvm_unreachable("invalid ownership attribute"); 4104239462Sdim case AttributeList::AT_NSReturnsAutoreleased: 4105280031Sdim D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr( 4106280031Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 4107218893Sdim return; 4108239462Sdim case AttributeList::AT_CFReturnsNotRetained: 4109280031Sdim D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr( 4110280031Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 4111204643Srdivacky return; 4112239462Sdim case AttributeList::AT_NSReturnsNotRetained: 4113280031Sdim D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr( 4114280031Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 4115204643Srdivacky return; 4116239462Sdim case AttributeList::AT_CFReturnsRetained: 4117280031Sdim D->addAttr(::new (S.Context) CFReturnsRetainedAttr( 4118280031Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 4119193326Sed return; 4120239462Sdim case AttributeList::AT_NSReturnsRetained: 4121280031Sdim D->addAttr(::new (S.Context) NSReturnsRetainedAttr( 4122280031Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 4123193326Sed return; 4124193326Sed }; 4125193326Sed} 4126193326Sed 4127226633Sdimstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 4128226633Sdim const AttributeList &attr) { 4129261991Sdim const int EP_ObjCMethod = 1; 4130261991Sdim const int EP_ObjCProperty = 2; 4131261991Sdim 4132226633Sdim SourceLocation loc = attr.getLoc(); 4133261991Sdim QualType resultType; 4134276479Sdim if (isa<ObjCMethodDecl>(D)) 4135276479Sdim resultType = cast<ObjCMethodDecl>(D)->getReturnType(); 4136261991Sdim else 4137276479Sdim resultType = cast<ObjCPropertyDecl>(D)->getType(); 4138226633Sdim 4139226633Sdim if (!resultType->isReferenceType() && 4140226633Sdim (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 4141261991Sdim S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 4142226633Sdim << SourceRange(loc) 4143276479Sdim << attr.getName() 4144276479Sdim << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty) 4145261991Sdim << /*non-retainable pointer*/ 2; 4146226633Sdim 4147226633Sdim // Drop the attribute. 4148226633Sdim return; 4149226633Sdim } 4150226633Sdim 4151280031Sdim D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr( 4152280031Sdim attr.getRange(), S.Context, attr.getAttributeSpellingListIndex())); 4153226633Sdim} 4154226633Sdim 4155243830Sdimstatic void handleObjCRequiresSuperAttr(Sema &S, Decl *D, 4156243830Sdim const AttributeList &attr) { 4157276479Sdim ObjCMethodDecl *method = cast<ObjCMethodDecl>(D); 4158243830Sdim 4159243830Sdim DeclContext *DC = method->getDeclContext(); 4160243830Sdim if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) { 4161243830Sdim S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 4162243830Sdim << attr.getName() << 0; 4163243830Sdim S.Diag(PDecl->getLocation(), diag::note_protocol_decl); 4164243830Sdim return; 4165243830Sdim } 4166243830Sdim if (method->getMethodFamily() == OMF_dealloc) { 4167243830Sdim S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 4168243830Sdim << attr.getName() << 1; 4169243830Sdim return; 4170243830Sdim } 4171243830Sdim 4172249423Sdim method->addAttr(::new (S.Context) 4173249423Sdim ObjCRequiresSuperAttr(attr.getRange(), S.Context, 4174249423Sdim attr.getAttributeSpellingListIndex())); 4175243830Sdim} 4176243830Sdim 4177276479Sdimstatic void handleCFAuditedTransferAttr(Sema &S, Decl *D, 4178276479Sdim const AttributeList &Attr) { 4179296417Sdim if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr.getRange(), 4180296417Sdim Attr.getName())) 4181226633Sdim return; 4182226633Sdim 4183276479Sdim D->addAttr(::new (S.Context) 4184276479Sdim CFAuditedTransferAttr(Attr.getRange(), S.Context, 4185276479Sdim Attr.getAttributeSpellingListIndex())); 4186276479Sdim} 4187226633Sdim 4188276479Sdimstatic void handleCFUnknownTransferAttr(Sema &S, Decl *D, 4189276479Sdim const AttributeList &Attr) { 4190296417Sdim if (checkAttrMutualExclusion<CFAuditedTransferAttr>(S, D, Attr.getRange(), 4191296417Sdim Attr.getName())) 4192226633Sdim return; 4193226633Sdim 4194276479Sdim D->addAttr(::new (S.Context) 4195276479Sdim CFUnknownTransferAttr(Attr.getRange(), S.Context, 4196276479Sdim Attr.getAttributeSpellingListIndex())); 4197226633Sdim} 4198226633Sdim 4199276479Sdimstatic void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D, 4200226633Sdim const AttributeList &Attr) { 4201276479Sdim IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr; 4202226633Sdim 4203276479Sdim if (!Parm) { 4204276479Sdim S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; 4205276479Sdim return; 4206226633Sdim } 4207288943Sdim 4208288943Sdim // Typedefs only allow objc_bridge(id) and have some additional checking. 4209288943Sdim if (auto TD = dyn_cast<TypedefNameDecl>(D)) { 4210288943Sdim if (!Parm->Ident->isStr("id")) { 4211288943Sdim S.Diag(Attr.getLoc(), diag::err_objc_attr_typedef_not_id) 4212288943Sdim << Attr.getName(); 4213288943Sdim return; 4214288943Sdim } 4215288943Sdim 4216288943Sdim // Only allow 'cv void *'. 4217288943Sdim QualType T = TD->getUnderlyingType(); 4218288943Sdim if (!T->isVoidPointerType()) { 4219288943Sdim S.Diag(Attr.getLoc(), diag::err_objc_attr_typedef_not_void_pointer); 4220288943Sdim return; 4221288943Sdim } 4222288943Sdim } 4223276479Sdim 4224249423Sdim D->addAttr(::new (S.Context) 4225276479Sdim ObjCBridgeAttr(Attr.getRange(), S.Context, Parm->Ident, 4226249423Sdim Attr.getAttributeSpellingListIndex())); 4227226633Sdim} 4228226633Sdim 4229276479Sdimstatic void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D, 4230276479Sdim const AttributeList &Attr) { 4231276479Sdim IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr; 4232276479Sdim 4233276479Sdim if (!Parm) { 4234276479Sdim S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; 4235261991Sdim return; 4236261991Sdim } 4237261991Sdim 4238276479Sdim D->addAttr(::new (S.Context) 4239276479Sdim ObjCBridgeMutableAttr(Attr.getRange(), S.Context, Parm->Ident, 4240276479Sdim Attr.getAttributeSpellingListIndex())); 4241276479Sdim} 4242276479Sdim 4243276479Sdimstatic void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D, 4244276479Sdim const AttributeList &Attr) { 4245276479Sdim IdentifierInfo *RelatedClass = 4246276479Sdim Attr.isArgIdent(0) ? Attr.getArgAsIdent(0)->Ident : nullptr; 4247276479Sdim if (!RelatedClass) { 4248276479Sdim S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0; 4249261991Sdim return; 4250261991Sdim } 4251276479Sdim IdentifierInfo *ClassMethod = 4252276479Sdim Attr.getArgAsIdent(1) ? Attr.getArgAsIdent(1)->Ident : nullptr; 4253276479Sdim IdentifierInfo *InstanceMethod = 4254276479Sdim Attr.getArgAsIdent(2) ? Attr.getArgAsIdent(2)->Ident : nullptr; 4255276479Sdim D->addAttr(::new (S.Context) 4256276479Sdim ObjCBridgeRelatedAttr(Attr.getRange(), S.Context, RelatedClass, 4257276479Sdim ClassMethod, InstanceMethod, 4258276479Sdim Attr.getAttributeSpellingListIndex())); 4259276479Sdim} 4260276479Sdim 4261276479Sdimstatic void handleObjCDesignatedInitializer(Sema &S, Decl *D, 4262276479Sdim const AttributeList &Attr) { 4263276479Sdim ObjCInterfaceDecl *IFace; 4264280031Sdim if (ObjCCategoryDecl *CatDecl = 4265280031Sdim dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) 4266276479Sdim IFace = CatDecl->getClassInterface(); 4267276479Sdim else 4268276479Sdim IFace = cast<ObjCInterfaceDecl>(D->getDeclContext()); 4269288943Sdim 4270288943Sdim if (!IFace) 4271288943Sdim return; 4272288943Sdim 4273276479Sdim IFace->setHasDesignatedInitializers(); 4274276479Sdim D->addAttr(::new (S.Context) 4275276479Sdim ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context, 4276276479Sdim Attr.getAttributeSpellingListIndex())); 4277276479Sdim} 4278276479Sdim 4279276479Sdimstatic void handleObjCRuntimeName(Sema &S, Decl *D, 4280276479Sdim const AttributeList &Attr) { 4281276479Sdim StringRef MetaDataName; 4282276479Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName)) 4283261991Sdim return; 4284261991Sdim D->addAttr(::new (S.Context) 4285276479Sdim ObjCRuntimeNameAttr(Attr.getRange(), S.Context, 4286276479Sdim MetaDataName, 4287276479Sdim Attr.getAttributeSpellingListIndex())); 4288261991Sdim} 4289261991Sdim 4290288943Sdim// when a user wants to use objc_boxable with a union or struct 4291288943Sdim// but she doesn't have access to the declaration (legacy/third-party code) 4292288943Sdim// then she can 'enable' this feature via trick with a typedef 4293288943Sdim// e.g.: 4294288943Sdim// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct; 4295288943Sdimstatic void handleObjCBoxable(Sema &S, Decl *D, const AttributeList &Attr) { 4296288943Sdim bool notify = false; 4297288943Sdim 4298288943Sdim RecordDecl *RD = dyn_cast<RecordDecl>(D); 4299288943Sdim if (RD && RD->getDefinition()) { 4300288943Sdim RD = RD->getDefinition(); 4301288943Sdim notify = true; 4302288943Sdim } 4303288943Sdim 4304288943Sdim if (RD) { 4305288943Sdim ObjCBoxableAttr *BoxableAttr = ::new (S.Context) 4306288943Sdim ObjCBoxableAttr(Attr.getRange(), S.Context, 4307288943Sdim Attr.getAttributeSpellingListIndex()); 4308288943Sdim RD->addAttr(BoxableAttr); 4309288943Sdim if (notify) { 4310288943Sdim // we need to notify ASTReader/ASTWriter about 4311288943Sdim // modification of existing declaration 4312288943Sdim if (ASTMutationListener *L = S.getASTMutationListener()) 4313288943Sdim L->AddedAttributeToRecord(BoxableAttr, RD); 4314288943Sdim } 4315288943Sdim } 4316288943Sdim} 4317288943Sdim 4318224145Sdimstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 4319224145Sdim const AttributeList &Attr) { 4320224145Sdim if (hasDeclarator(D)) return; 4321224145Sdim 4322224145Sdim S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4323234353Sdim << Attr.getRange() << Attr.getName() << ExpectedVariable; 4324224145Sdim} 4325224145Sdim 4326224145Sdimstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 4327224145Sdim const AttributeList &Attr) { 4328224145Sdim ValueDecl *vd = cast<ValueDecl>(D); 4329224145Sdim QualType type = vd->getType(); 4330224145Sdim 4331224145Sdim if (!type->isDependentType() && 4332224145Sdim !type->isObjCLifetimeType()) { 4333224145Sdim S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 4334224145Sdim << type; 4335224145Sdim return; 4336224145Sdim } 4337224145Sdim 4338224145Sdim Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 4339224145Sdim 4340224145Sdim // If we have no lifetime yet, check the lifetime we're presumably 4341224145Sdim // going to infer. 4342224145Sdim if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 4343224145Sdim lifetime = type->getObjCARCImplicitLifetime(); 4344224145Sdim 4345224145Sdim switch (lifetime) { 4346224145Sdim case Qualifiers::OCL_None: 4347224145Sdim assert(type->isDependentType() && 4348224145Sdim "didn't infer lifetime for non-dependent type?"); 4349224145Sdim break; 4350224145Sdim 4351224145Sdim case Qualifiers::OCL_Weak: // meaningful 4352224145Sdim case Qualifiers::OCL_Strong: // meaningful 4353224145Sdim break; 4354224145Sdim 4355224145Sdim case Qualifiers::OCL_ExplicitNone: 4356224145Sdim case Qualifiers::OCL_Autoreleasing: 4357224145Sdim S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 4358224145Sdim << (lifetime == Qualifiers::OCL_Autoreleasing); 4359224145Sdim break; 4360224145Sdim } 4361224145Sdim 4362224145Sdim D->addAttr(::new (S.Context) 4363249423Sdim ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context, 4364249423Sdim Attr.getAttributeSpellingListIndex())); 4365224145Sdim} 4366224145Sdim 4367193326Sed//===----------------------------------------------------------------------===// 4368218893Sdim// Microsoft specific attribute handlers. 4369218893Sdim//===----------------------------------------------------------------------===// 4370218893Sdim 4371224145Sdimstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4372276479Sdim if (!S.LangOpts.CPlusPlus) { 4373276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) 4374276479Sdim << Attr.getName() << AttributeLangSupport::C; 4375261991Sdim return; 4376276479Sdim } 4377224145Sdim 4378276479Sdim if (!isa<CXXRecordDecl>(D)) { 4379276479Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4380276479Sdim << Attr.getName() << ExpectedClass; 4381276479Sdim return; 4382276479Sdim } 4383276479Sdim 4384261991Sdim StringRef StrRef; 4385261991Sdim SourceLocation LiteralLoc; 4386261991Sdim if (!S.checkStringLiteralArgumentAttr(Attr, 0, StrRef, &LiteralLoc)) 4387261991Sdim return; 4388218893Sdim 4389261991Sdim // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 4390261991Sdim // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former. 4391261991Sdim if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}') 4392261991Sdim StrRef = StrRef.drop_front().drop_back(); 4393218893Sdim 4394261991Sdim // Validate GUID length. 4395261991Sdim if (StrRef.size() != 36) { 4396261991Sdim S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 4397261991Sdim return; 4398261991Sdim } 4399234353Sdim 4400261991Sdim for (unsigned i = 0; i < 36; ++i) { 4401261991Sdim if (i == 8 || i == 13 || i == 18 || i == 23) { 4402261991Sdim if (StrRef[i] != '-') { 4403261991Sdim S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 4404218893Sdim return; 4405218893Sdim } 4406261991Sdim } else if (!isHexDigit(StrRef[i])) { 4407261991Sdim S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid); 4408261991Sdim return; 4409218893Sdim } 4410261991Sdim } 4411218893Sdim 4412261991Sdim D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, StrRef, 4413261991Sdim Attr.getAttributeSpellingListIndex())); 4414218893Sdim} 4415218893Sdim 4416276479Sdimstatic void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4417276479Sdim if (!S.LangOpts.CPlusPlus) { 4418276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) 4419276479Sdim << Attr.getName() << AttributeLangSupport::C; 4420243830Sdim return; 4421276479Sdim } 4422276479Sdim MSInheritanceAttr *IA = S.mergeMSInheritanceAttr( 4423276479Sdim D, Attr.getRange(), /*BestCase=*/true, 4424276479Sdim Attr.getAttributeSpellingListIndex(), 4425276479Sdim (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling()); 4426276479Sdim if (IA) 4427276479Sdim D->addAttr(IA); 4428276479Sdim} 4429243830Sdim 4430276479Sdimstatic void handleDeclspecThreadAttr(Sema &S, Decl *D, 4431276479Sdim const AttributeList &Attr) { 4432276479Sdim VarDecl *VD = cast<VarDecl>(D); 4433276479Sdim if (!S.Context.getTargetInfo().isTLSSupported()) { 4434276479Sdim S.Diag(Attr.getLoc(), diag::err_thread_unsupported); 4435276479Sdim return; 4436276479Sdim } 4437276479Sdim if (VD->getTSCSpec() != TSCS_unspecified) { 4438276479Sdim S.Diag(Attr.getLoc(), diag::err_declspec_thread_on_thread_variable); 4439276479Sdim return; 4440276479Sdim } 4441276479Sdim if (VD->hasLocalStorage()) { 4442276479Sdim S.Diag(Attr.getLoc(), diag::err_thread_non_global) << "__declspec(thread)"; 4443276479Sdim return; 4444276479Sdim } 4445276479Sdim VD->addAttr(::new (S.Context) ThreadAttr( 4446276479Sdim Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); 4447239462Sdim} 4448239462Sdim 4449276479Sdimstatic void handleARMInterruptAttr(Sema &S, Decl *D, 4450276479Sdim const AttributeList &Attr) { 4451276479Sdim // Check the attribute arguments. 4452276479Sdim if (Attr.getNumArgs() > 1) { 4453276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) 4454276479Sdim << Attr.getName() << 1; 4455261991Sdim return; 4456276479Sdim } 4457261991Sdim 4458276479Sdim StringRef Str; 4459276479Sdim SourceLocation ArgLoc; 4460276479Sdim 4461276479Sdim if (Attr.getNumArgs() == 0) 4462276479Sdim Str = ""; 4463276479Sdim else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc)) 4464276479Sdim return; 4465276479Sdim 4466276479Sdim ARMInterruptAttr::InterruptType Kind; 4467276479Sdim if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { 4468276479Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 4469276479Sdim << Attr.getName() << Str << ArgLoc; 4470276479Sdim return; 4471276479Sdim } 4472276479Sdim 4473276479Sdim unsigned Index = Attr.getAttributeSpellingListIndex(); 4474276479Sdim D->addAttr(::new (S.Context) 4475276479Sdim ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index)); 4476239462Sdim} 4477239462Sdim 4478276479Sdimstatic void handleMSP430InterruptAttr(Sema &S, Decl *D, 4479276479Sdim const AttributeList &Attr) { 4480276479Sdim if (!checkAttributeNumArgs(S, Attr, 1)) 4481261991Sdim return; 4482276479Sdim 4483276479Sdim if (!Attr.isArgExpr(0)) { 4484276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName() 4485276479Sdim << AANT_ArgumentIntegerConstant; 4486276479Sdim return; 4487276479Sdim } 4488276479Sdim 4489276479Sdim // FIXME: Check for decl - it should be void ()(void). 4490276479Sdim 4491276479Sdim Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); 4492276479Sdim llvm::APSInt NumParams(32); 4493276479Sdim if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 4494276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) 4495276479Sdim << Attr.getName() << AANT_ArgumentIntegerConstant 4496276479Sdim << NumParamsExpr->getSourceRange(); 4497276479Sdim return; 4498276479Sdim } 4499276479Sdim 4500276479Sdim unsigned Num = NumParams.getLimitedValue(255); 4501276479Sdim if ((Num & 1) || Num > 30) { 4502276479Sdim S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 4503276479Sdim << Attr.getName() << (int)NumParams.getSExtValue() 4504276479Sdim << NumParamsExpr->getSourceRange(); 4505276479Sdim return; 4506276479Sdim } 4507276479Sdim 4508261991Sdim D->addAttr(::new (S.Context) 4509276479Sdim MSP430InterruptAttr(Attr.getLoc(), S.Context, Num, 4510276479Sdim Attr.getAttributeSpellingListIndex())); 4511276479Sdim D->addAttr(UsedAttr::CreateImplicit(S.Context)); 4512239462Sdim} 4513239462Sdim 4514296417Sdimstatic void handleMipsInterruptAttr(Sema &S, Decl *D, 4515296417Sdim const AttributeList &Attr) { 4516296417Sdim // Only one optional argument permitted. 4517296417Sdim if (Attr.getNumArgs() > 1) { 4518296417Sdim S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) 4519296417Sdim << Attr.getName() << 1; 4520296417Sdim return; 4521296417Sdim } 4522296417Sdim 4523296417Sdim StringRef Str; 4524296417Sdim SourceLocation ArgLoc; 4525296417Sdim 4526296417Sdim if (Attr.getNumArgs() == 0) 4527296417Sdim Str = ""; 4528296417Sdim else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc)) 4529296417Sdim return; 4530296417Sdim 4531296417Sdim // Semantic checks for a function with the 'interrupt' attribute for MIPS: 4532296417Sdim // a) Must be a function. 4533296417Sdim // b) Must have no parameters. 4534296417Sdim // c) Must have the 'void' return type. 4535296417Sdim // d) Cannot have the 'mips16' attribute, as that instruction set 4536296417Sdim // lacks the 'eret' instruction. 4537296417Sdim // e) The attribute itself must either have no argument or one of the 4538296417Sdim // valid interrupt types, see [MipsInterruptDocs]. 4539296417Sdim 4540296417Sdim if (!isFunctionOrMethod(D)) { 4541296417Sdim S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) 4542296417Sdim << "'interrupt'" << ExpectedFunctionOrMethod; 4543296417Sdim return; 4544296417Sdim } 4545296417Sdim 4546296417Sdim if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { 4547296417Sdim S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute) 4548296417Sdim << 0; 4549296417Sdim return; 4550296417Sdim } 4551296417Sdim 4552296417Sdim if (!getFunctionOrMethodResultType(D)->isVoidType()) { 4553296417Sdim S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute) 4554296417Sdim << 1; 4555296417Sdim return; 4556296417Sdim } 4557296417Sdim 4558296417Sdim if (checkAttrMutualExclusion<Mips16Attr>(S, D, Attr.getRange(), 4559296417Sdim Attr.getName())) 4560296417Sdim return; 4561296417Sdim 4562296417Sdim MipsInterruptAttr::InterruptType Kind; 4563296417Sdim if (!MipsInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { 4564296417Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 4565296417Sdim << Attr.getName() << "'" + std::string(Str) + "'"; 4566296417Sdim return; 4567296417Sdim } 4568296417Sdim 4569296417Sdim D->addAttr(::new (S.Context) MipsInterruptAttr( 4570296417Sdim Attr.getLoc(), S.Context, Kind, Attr.getAttributeSpellingListIndex())); 4571296417Sdim} 4572296417Sdim 4573276479Sdimstatic void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4574276479Sdim // Dispatch the interrupt attribute based on the current target. 4575276479Sdim if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430) 4576276479Sdim handleMSP430InterruptAttr(S, D, Attr); 4577296417Sdim else if (S.Context.getTargetInfo().getTriple().getArch() == 4578296417Sdim llvm::Triple::mipsel || 4579296417Sdim S.Context.getTargetInfo().getTriple().getArch() == 4580296417Sdim llvm::Triple::mips) 4581296417Sdim handleMipsInterruptAttr(S, D, Attr); 4582276479Sdim else 4583276479Sdim handleARMInterruptAttr(S, D, Attr); 4584276479Sdim} 4585276479Sdim 4586280031Sdimstatic void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, 4587280031Sdim const AttributeList &Attr) { 4588280031Sdim uint32_t NumRegs; 4589280031Sdim Expr *NumRegsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); 4590280031Sdim if (!checkUInt32Argument(S, Attr, NumRegsExpr, NumRegs)) 4591280031Sdim return; 4592280031Sdim 4593280031Sdim D->addAttr(::new (S.Context) 4594280031Sdim AMDGPUNumVGPRAttr(Attr.getLoc(), S.Context, 4595280031Sdim NumRegs, 4596280031Sdim Attr.getAttributeSpellingListIndex())); 4597280031Sdim} 4598280031Sdim 4599280031Sdimstatic void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, 4600280031Sdim const AttributeList &Attr) { 4601280031Sdim uint32_t NumRegs; 4602280031Sdim Expr *NumRegsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0)); 4603280031Sdim if (!checkUInt32Argument(S, Attr, NumRegsExpr, NumRegs)) 4604280031Sdim return; 4605280031Sdim 4606280031Sdim D->addAttr(::new (S.Context) 4607280031Sdim AMDGPUNumSGPRAttr(Attr.getLoc(), S.Context, 4608280031Sdim NumRegs, 4609280031Sdim Attr.getAttributeSpellingListIndex())); 4610280031Sdim} 4611280031Sdim 4612276479Sdimstatic void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D, 4613276479Sdim const AttributeList& Attr) { 4614276479Sdim // If we try to apply it to a function pointer, don't warn, but don't 4615276479Sdim // do anything, either. It doesn't matter anyway, because there's nothing 4616276479Sdim // special about calling a force_align_arg_pointer function. 4617276479Sdim ValueDecl *VD = dyn_cast<ValueDecl>(D); 4618276479Sdim if (VD && VD->getType()->isFunctionPointerType()) 4619261991Sdim return; 4620276479Sdim // Also don't warn on function pointer typedefs. 4621276479Sdim TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 4622276479Sdim if (TD && (TD->getUnderlyingType()->isFunctionPointerType() || 4623276479Sdim TD->getUnderlyingType()->isFunctionType())) 4624276479Sdim return; 4625276479Sdim // Attribute can only be applied to function types. 4626276479Sdim if (!isa<FunctionDecl>(D)) { 4627276479Sdim S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4628276479Sdim << Attr.getName() << /* function */0; 4629276479Sdim return; 4630276479Sdim } 4631276479Sdim 4632261991Sdim D->addAttr(::new (S.Context) 4633276479Sdim X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context, 4634276479Sdim Attr.getAttributeSpellingListIndex())); 4635261991Sdim} 4636261991Sdim 4637276479SdimDLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range, 4638276479Sdim unsigned AttrSpellingListIndex) { 4639276479Sdim if (D->hasAttr<DLLExportAttr>()) { 4640276479Sdim Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'"; 4641276479Sdim return nullptr; 4642276479Sdim } 4643276479Sdim 4644276479Sdim if (D->hasAttr<DLLImportAttr>()) 4645276479Sdim return nullptr; 4646276479Sdim 4647276479Sdim return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex); 4648276479Sdim} 4649276479Sdim 4650276479SdimDLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range, 4651276479Sdim unsigned AttrSpellingListIndex) { 4652276479Sdim if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) { 4653276479Sdim Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import; 4654276479Sdim D->dropAttr<DLLImportAttr>(); 4655276479Sdim } 4656276479Sdim 4657276479Sdim if (D->hasAttr<DLLExportAttr>()) 4658276479Sdim return nullptr; 4659276479Sdim 4660276479Sdim return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex); 4661276479Sdim} 4662276479Sdim 4663276479Sdimstatic void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) { 4664276479Sdim if (isa<ClassTemplatePartialSpecializationDecl>(D) && 4665276479Sdim S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { 4666276479Sdim S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) 4667276479Sdim << A.getName(); 4668276479Sdim return; 4669276479Sdim } 4670276479Sdim 4671280031Sdim if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 4672280031Sdim if (FD->isInlined() && A.getKind() == AttributeList::AT_DLLImport && 4673280031Sdim !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { 4674280031Sdim // MinGW doesn't allow dllimport on inline functions. 4675280031Sdim S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline) 4676280031Sdim << A.getName(); 4677280031Sdim return; 4678280031Sdim } 4679280031Sdim } 4680280031Sdim 4681296417Sdim if (auto *MD = dyn_cast<CXXMethodDecl>(D)) { 4682296417Sdim if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && 4683296417Sdim MD->getParent()->isLambda()) { 4684296417Sdim S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A.getName(); 4685296417Sdim return; 4686296417Sdim } 4687296417Sdim } 4688296417Sdim 4689276479Sdim unsigned Index = A.getAttributeSpellingListIndex(); 4690276479Sdim Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport 4691276479Sdim ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index) 4692276479Sdim : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index); 4693276479Sdim if (NewAttr) 4694276479Sdim D->addAttr(NewAttr); 4695276479Sdim} 4696276479Sdim 4697276479SdimMSInheritanceAttr * 4698276479SdimSema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, 4699276479Sdim unsigned AttrSpellingListIndex, 4700276479Sdim MSInheritanceAttr::Spelling SemanticSpelling) { 4701276479Sdim if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) { 4702276479Sdim if (IA->getSemanticSpelling() == SemanticSpelling) 4703276479Sdim return nullptr; 4704276479Sdim Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance) 4705276479Sdim << 1 /*previous declaration*/; 4706276479Sdim Diag(Range.getBegin(), diag::note_previous_ms_inheritance); 4707276479Sdim D->dropAttr<MSInheritanceAttr>(); 4708276479Sdim } 4709276479Sdim 4710276479Sdim CXXRecordDecl *RD = cast<CXXRecordDecl>(D); 4711276479Sdim if (RD->hasDefinition()) { 4712276479Sdim if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase, 4713276479Sdim SemanticSpelling)) { 4714276479Sdim return nullptr; 4715276479Sdim } 4716276479Sdim } else { 4717276479Sdim if (isa<ClassTemplatePartialSpecializationDecl>(RD)) { 4718276479Sdim Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance) 4719276479Sdim << 1 /*partial specialization*/; 4720276479Sdim return nullptr; 4721276479Sdim } 4722276479Sdim if (RD->getDescribedClassTemplate()) { 4723276479Sdim Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance) 4724276479Sdim << 0 /*primary template*/; 4725276479Sdim return nullptr; 4726276479Sdim } 4727276479Sdim } 4728276479Sdim 4729276479Sdim return ::new (Context) 4730276479Sdim MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex); 4731276479Sdim} 4732276479Sdim 4733276479Sdimstatic void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4734276479Sdim // The capability attributes take a single string parameter for the name of 4735276479Sdim // the capability they represent. The lockable attribute does not take any 4736276479Sdim // parameters. However, semantically, both attributes represent the same 4737276479Sdim // concept, and so they use the same semantic attribute. Eventually, the 4738276479Sdim // lockable attribute will be removed. 4739276479Sdim // 4740276479Sdim // For backward compatibility, any capability which has no specified string 4741276479Sdim // literal will be considered a "mutex." 4742276479Sdim StringRef N("mutex"); 4743276479Sdim SourceLocation LiteralLoc; 4744276479Sdim if (Attr.getKind() == AttributeList::AT_Capability && 4745276479Sdim !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc)) 4746276479Sdim return; 4747276479Sdim 4748276479Sdim // Currently, there are only two names allowed for a capability: role and 4749276479Sdim // mutex (case insensitive). Diagnose other capability names. 4750276479Sdim if (!N.equals_lower("mutex") && !N.equals_lower("role")) 4751276479Sdim S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N; 4752276479Sdim 4753276479Sdim D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N, 4754276479Sdim Attr.getAttributeSpellingListIndex())); 4755276479Sdim} 4756276479Sdim 4757276479Sdimstatic void handleAssertCapabilityAttr(Sema &S, Decl *D, 4758276479Sdim const AttributeList &Attr) { 4759276479Sdim D->addAttr(::new (S.Context) AssertCapabilityAttr(Attr.getRange(), S.Context, 4760276479Sdim Attr.getArgAsExpr(0), 4761276479Sdim Attr.getAttributeSpellingListIndex())); 4762276479Sdim} 4763276479Sdim 4764276479Sdimstatic void handleAcquireCapabilityAttr(Sema &S, Decl *D, 4765276479Sdim const AttributeList &Attr) { 4766276479Sdim SmallVector<Expr*, 1> Args; 4767276479Sdim if (!checkLockFunAttrCommon(S, D, Attr, Args)) 4768276479Sdim return; 4769276479Sdim 4770276479Sdim D->addAttr(::new (S.Context) AcquireCapabilityAttr(Attr.getRange(), 4771276479Sdim S.Context, 4772276479Sdim Args.data(), Args.size(), 4773276479Sdim Attr.getAttributeSpellingListIndex())); 4774276479Sdim} 4775276479Sdim 4776276479Sdimstatic void handleTryAcquireCapabilityAttr(Sema &S, Decl *D, 4777276479Sdim const AttributeList &Attr) { 4778276479Sdim SmallVector<Expr*, 2> Args; 4779276479Sdim if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 4780276479Sdim return; 4781276479Sdim 4782276479Sdim D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(Attr.getRange(), 4783276479Sdim S.Context, 4784276479Sdim Attr.getArgAsExpr(0), 4785276479Sdim Args.data(), 4786276479Sdim Args.size(), 4787276479Sdim Attr.getAttributeSpellingListIndex())); 4788276479Sdim} 4789276479Sdim 4790276479Sdimstatic void handleReleaseCapabilityAttr(Sema &S, Decl *D, 4791276479Sdim const AttributeList &Attr) { 4792276479Sdim // Check that all arguments are lockable objects. 4793276479Sdim SmallVector<Expr *, 1> Args; 4794276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, true); 4795276479Sdim 4796276479Sdim D->addAttr(::new (S.Context) ReleaseCapabilityAttr( 4797276479Sdim Attr.getRange(), S.Context, Args.data(), Args.size(), 4798276479Sdim Attr.getAttributeSpellingListIndex())); 4799276479Sdim} 4800276479Sdim 4801276479Sdimstatic void handleRequiresCapabilityAttr(Sema &S, Decl *D, 4802276479Sdim const AttributeList &Attr) { 4803276479Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 4804276479Sdim return; 4805276479Sdim 4806276479Sdim // check that all arguments are lockable objects 4807276479Sdim SmallVector<Expr*, 1> Args; 4808276479Sdim checkAttrArgsAreCapabilityObjs(S, D, Attr, Args); 4809276479Sdim if (Args.empty()) 4810276479Sdim return; 4811276479Sdim 4812276479Sdim RequiresCapabilityAttr *RCA = ::new (S.Context) 4813276479Sdim RequiresCapabilityAttr(Attr.getRange(), S.Context, Args.data(), 4814276479Sdim Args.size(), Attr.getAttributeSpellingListIndex()); 4815276479Sdim 4816276479Sdim D->addAttr(RCA); 4817276479Sdim} 4818276479Sdim 4819280031Sdimstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4820280031Sdim if (auto *NSD = dyn_cast<NamespaceDecl>(D)) { 4821280031Sdim if (NSD->isAnonymousNamespace()) { 4822280031Sdim S.Diag(Attr.getLoc(), diag::warn_deprecated_anonymous_namespace); 4823280031Sdim // Do not want to attach the attribute to the namespace because that will 4824280031Sdim // cause confusing diagnostic reports for uses of declarations within the 4825280031Sdim // namespace. 4826280031Sdim return; 4827280031Sdim } 4828280031Sdim } 4829288943Sdim 4830288943Sdim if (!S.getLangOpts().CPlusPlus14) 4831288943Sdim if (Attr.isCXX11Attribute() && 4832288943Sdim !(Attr.hasScope() && Attr.getScopeName()->isStr("gnu"))) 4833288943Sdim S.Diag(Attr.getLoc(), diag::ext_deprecated_attr_is_a_cxx14_extension); 4834288943Sdim 4835280031Sdim handleAttrWithMessage<DeprecatedAttr>(S, D, Attr); 4836280031Sdim} 4837280031Sdim 4838288943Sdimstatic void handleNoSanitizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4839288943Sdim if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 4840288943Sdim return; 4841288943Sdim 4842288943Sdim std::vector<std::string> Sanitizers; 4843288943Sdim 4844288943Sdim for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) { 4845288943Sdim StringRef SanitizerName; 4846288943Sdim SourceLocation LiteralLoc; 4847288943Sdim 4848288943Sdim if (!S.checkStringLiteralArgumentAttr(Attr, I, SanitizerName, &LiteralLoc)) 4849288943Sdim return; 4850288943Sdim 4851288943Sdim if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) == 0) 4852288943Sdim S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName; 4853288943Sdim 4854288943Sdim Sanitizers.push_back(SanitizerName); 4855288943Sdim } 4856288943Sdim 4857288943Sdim D->addAttr(::new (S.Context) NoSanitizeAttr( 4858288943Sdim Attr.getRange(), S.Context, Sanitizers.data(), Sanitizers.size(), 4859288943Sdim Attr.getAttributeSpellingListIndex())); 4860288943Sdim} 4861288943Sdim 4862288943Sdimstatic void handleNoSanitizeSpecificAttr(Sema &S, Decl *D, 4863288943Sdim const AttributeList &Attr) { 4864296417Sdim StringRef AttrName = Attr.getName()->getName(); 4865296417Sdim normalizeName(AttrName); 4866288943Sdim std::string SanitizerName = 4867296417Sdim llvm::StringSwitch<std::string>(AttrName) 4868288943Sdim .Case("no_address_safety_analysis", "address") 4869288943Sdim .Case("no_sanitize_address", "address") 4870288943Sdim .Case("no_sanitize_thread", "thread") 4871288943Sdim .Case("no_sanitize_memory", "memory"); 4872288943Sdim D->addAttr(::new (S.Context) 4873288943Sdim NoSanitizeAttr(Attr.getRange(), S.Context, &SanitizerName, 1, 4874288943Sdim Attr.getAttributeSpellingListIndex())); 4875288943Sdim} 4876288943Sdim 4877296417Sdimstatic void handleInternalLinkageAttr(Sema &S, Decl *D, 4878296417Sdim const AttributeList &Attr) { 4879296417Sdim if (InternalLinkageAttr *Internal = 4880296417Sdim S.mergeInternalLinkageAttr(D, Attr.getRange(), Attr.getName(), 4881296417Sdim Attr.getAttributeSpellingListIndex())) 4882296417Sdim D->addAttr(Internal); 4883296417Sdim} 4884296417Sdim 4885261991Sdim/// Handles semantic checking for features that are common to all attributes, 4886261991Sdim/// such as checking whether a parameter was properly specified, or the correct 4887261991Sdim/// number of arguments were passed, etc. 4888261991Sdimstatic bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D, 4889261991Sdim const AttributeList &Attr) { 4890261991Sdim // Several attributes carry different semantics than the parsing requires, so 4891261991Sdim // those are opted out of the common handling. 4892261991Sdim // 4893261991Sdim // We also bail on unknown and ignored attributes because those are handled 4894261991Sdim // as part of the target-specific handling logic. 4895261991Sdim if (Attr.hasCustomParsing() || 4896276479Sdim Attr.getKind() == AttributeList::UnknownAttribute) 4897261991Sdim return false; 4898261991Sdim 4899276479Sdim // Check whether the attribute requires specific language extensions to be 4900276479Sdim // enabled. 4901276479Sdim if (!Attr.diagnoseLangOpts(S)) 4902276479Sdim return true; 4903276479Sdim 4904280031Sdim if (Attr.getMinArgs() == Attr.getMaxArgs()) { 4905280031Sdim // If there are no optional arguments, then checking for the argument count 4906280031Sdim // is trivial. 4907280031Sdim if (!checkAttributeNumArgs(S, Attr, Attr.getMinArgs())) 4908280031Sdim return true; 4909280031Sdim } else { 4910280031Sdim // There are optional arguments, so checking is slightly more involved. 4911280031Sdim if (Attr.getMinArgs() && 4912280031Sdim !checkAttributeAtLeastNumArgs(S, Attr, Attr.getMinArgs())) 4913280031Sdim return true; 4914280031Sdim else if (!Attr.hasVariadicArg() && Attr.getMaxArgs() && 4915280031Sdim !checkAttributeAtMostNumArgs(S, Attr, Attr.getMaxArgs())) 4916280031Sdim return true; 4917280031Sdim } 4918276479Sdim 4919276479Sdim // Check whether the attribute appertains to the given subject. 4920276479Sdim if (!Attr.diagnoseAppertainsTo(S, D)) 4921276479Sdim return true; 4922276479Sdim 4923261991Sdim return false; 4924261991Sdim} 4925261991Sdim 4926218893Sdim//===----------------------------------------------------------------------===// 4927193326Sed// Top Level Sema Entry Points 4928193326Sed//===----------------------------------------------------------------------===// 4929193326Sed 4930261991Sdim/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 4931261991Sdim/// the attribute applies to decls. If the attribute is a type attribute, just 4932261991Sdim/// silently ignore it if a GNU attribute. 4933261991Sdimstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 4934261991Sdim const AttributeList &Attr, 4935261991Sdim bool IncludeCXX11Attributes) { 4936276479Sdim if (Attr.isInvalid() || Attr.getKind() == AttributeList::IgnoredAttribute) 4937261991Sdim return; 4938207619Srdivacky 4939261991Sdim // Ignore C++11 attributes on declarator chunks: they appertain to the type 4940261991Sdim // instead. 4941261991Sdim if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes) 4942261991Sdim return; 4943261991Sdim 4944276479Sdim // Unknown attributes are automatically warned on. Target-specific attributes 4945276479Sdim // which do not apply to the current target architecture are treated as 4946276479Sdim // though they were unknown attributes. 4947276479Sdim if (Attr.getKind() == AttributeList::UnknownAttribute || 4948296417Sdim !Attr.existsInTarget(S.Context.getTargetInfo())) { 4949276479Sdim S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() 4950276479Sdim ? diag::warn_unhandled_ms_attribute_ignored 4951276479Sdim : diag::warn_unknown_attribute_ignored) 4952276479Sdim << Attr.getName(); 4953276479Sdim return; 4954276479Sdim } 4955276479Sdim 4956261991Sdim if (handleCommonAttributeFeatures(S, scope, D, Attr)) 4957261991Sdim return; 4958261991Sdim 4959193326Sed switch (Attr.getKind()) { 4960276479Sdim default: 4961276479Sdim // Type attributes are handled elsewhere; silently move on. 4962276479Sdim assert(Attr.isTypeAttr() && "Non-type attribute not handled"); 4963276479Sdim break; 4964276479Sdim case AttributeList::AT_Interrupt: 4965276479Sdim handleInterruptAttr(S, D, Attr); 4966276479Sdim break; 4967276479Sdim case AttributeList::AT_X86ForceAlignArgPointer: 4968276479Sdim handleX86ForceAlignArgPointerAttr(S, D, Attr); 4969276479Sdim break; 4970276479Sdim case AttributeList::AT_DLLExport: 4971276479Sdim case AttributeList::AT_DLLImport: 4972276479Sdim handleDLLAttr(S, D, Attr); 4973276479Sdim break; 4974276479Sdim case AttributeList::AT_Mips16: 4975296417Sdim handleSimpleAttributeWithExclusions<Mips16Attr, MipsInterruptAttr>(S, D, 4976296417Sdim Attr); 4977276479Sdim break; 4978276479Sdim case AttributeList::AT_NoMips16: 4979276479Sdim handleSimpleAttribute<NoMips16Attr>(S, D, Attr); 4980276479Sdim break; 4981280031Sdim case AttributeList::AT_AMDGPUNumVGPR: 4982280031Sdim handleAMDGPUNumVGPRAttr(S, D, Attr); 4983280031Sdim break; 4984280031Sdim case AttributeList::AT_AMDGPUNumSGPR: 4985280031Sdim handleAMDGPUNumSGPRAttr(S, D, Attr); 4986280031Sdim break; 4987276479Sdim case AttributeList::AT_IBAction: 4988276479Sdim handleSimpleAttribute<IBActionAttr>(S, D, Attr); 4989276479Sdim break; 4990276479Sdim case AttributeList::AT_IBOutlet: 4991276479Sdim handleIBOutlet(S, D, Attr); 4992276479Sdim break; 4993249423Sdim case AttributeList::AT_IBOutletCollection: 4994276479Sdim handleIBOutletCollection(S, D, Attr); 4995193326Sed break; 4996276479Sdim case AttributeList::AT_Alias: 4997276479Sdim handleAliasAttr(S, D, Attr); 4998276479Sdim break; 4999276479Sdim case AttributeList::AT_Aligned: 5000276479Sdim handleAlignedAttr(S, D, Attr); 5001276479Sdim break; 5002280031Sdim case AttributeList::AT_AlignValue: 5003280031Sdim handleAlignValueAttr(S, D, Attr); 5004280031Sdim break; 5005239462Sdim case AttributeList::AT_AlwaysInline: 5006276479Sdim handleAlwaysInlineAttr(S, D, Attr); 5007276479Sdim break; 5008239462Sdim case AttributeList::AT_AnalyzerNoReturn: 5009276479Sdim handleAnalyzerNoReturnAttr(S, D, Attr); 5010276479Sdim break; 5011276479Sdim case AttributeList::AT_TLSModel: 5012276479Sdim handleTLSModelAttr(S, D, Attr); 5013276479Sdim break; 5014276479Sdim case AttributeList::AT_Annotate: 5015276479Sdim handleAnnotateAttr(S, D, Attr); 5016276479Sdim break; 5017276479Sdim case AttributeList::AT_Availability: 5018276479Sdim handleAvailabilityAttr(S, D, Attr); 5019276479Sdim break; 5020239462Sdim case AttributeList::AT_CarriesDependency: 5021249423Sdim handleDependencyAttr(S, scope, D, Attr); 5022249423Sdim break; 5023276479Sdim case AttributeList::AT_Common: 5024276479Sdim handleCommonAttr(S, D, Attr); 5025276479Sdim break; 5026276479Sdim case AttributeList::AT_CUDAConstant: 5027296417Sdim handleSimpleAttributeWithExclusions<CUDAConstantAttr, CUDASharedAttr>(S, D, 5028296417Sdim Attr); 5029276479Sdim break; 5030296417Sdim case AttributeList::AT_PassObjectSize: 5031296417Sdim handlePassObjectSizeAttr(S, D, Attr); 5032296417Sdim break; 5033276479Sdim case AttributeList::AT_Constructor: 5034276479Sdim handleConstructorAttr(S, D, Attr); 5035276479Sdim break; 5036249423Sdim case AttributeList::AT_CXX11NoReturn: 5037276479Sdim handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr); 5038249423Sdim break; 5039239462Sdim case AttributeList::AT_Deprecated: 5040280031Sdim handleDeprecatedAttr(S, D, Attr); 5041239462Sdim break; 5042276479Sdim case AttributeList::AT_Destructor: 5043276479Sdim handleDestructorAttr(S, D, Attr); 5044276479Sdim break; 5045276479Sdim case AttributeList::AT_EnableIf: 5046276479Sdim handleEnableIfAttr(S, D, Attr); 5047276479Sdim break; 5048239462Sdim case AttributeList::AT_ExtVectorType: 5049224145Sdim handleExtVectorTypeAttr(S, scope, D, Attr); 5050193326Sed break; 5051243830Sdim case AttributeList::AT_MinSize: 5052280031Sdim handleMinSizeAttr(S, D, Attr); 5053243830Sdim break; 5054276479Sdim case AttributeList::AT_OptimizeNone: 5055276479Sdim handleOptimizeNoneAttr(S, D, Attr); 5056276479Sdim break; 5057288943Sdim case AttributeList::AT_FlagEnum: 5058288943Sdim handleSimpleAttribute<FlagEnumAttr>(S, D, Attr); 5059288943Sdim break; 5060276479Sdim case AttributeList::AT_Flatten: 5061276479Sdim handleSimpleAttribute<FlattenAttr>(S, D, Attr); 5062276479Sdim break; 5063276479Sdim case AttributeList::AT_Format: 5064276479Sdim handleFormatAttr(S, D, Attr); 5065276479Sdim break; 5066276479Sdim case AttributeList::AT_FormatArg: 5067276479Sdim handleFormatArgAttr(S, D, Attr); 5068276479Sdim break; 5069276479Sdim case AttributeList::AT_CUDAGlobal: 5070276479Sdim handleGlobalAttr(S, D, Attr); 5071276479Sdim break; 5072276479Sdim case AttributeList::AT_CUDADevice: 5073296417Sdim handleSimpleAttributeWithExclusions<CUDADeviceAttr, CUDAGlobalAttr>(S, D, 5074296417Sdim Attr); 5075276479Sdim break; 5076276479Sdim case AttributeList::AT_CUDAHost: 5077296417Sdim handleSimpleAttributeWithExclusions<CUDAHostAttr, CUDAGlobalAttr>(S, D, 5078296417Sdim Attr); 5079276479Sdim break; 5080276479Sdim case AttributeList::AT_GNUInline: 5081276479Sdim handleGNUInlineAttr(S, D, Attr); 5082276479Sdim break; 5083239462Sdim case AttributeList::AT_CUDALaunchBounds: 5084224145Sdim handleLaunchBoundsAttr(S, D, Attr); 5085218893Sdim break; 5086288943Sdim case AttributeList::AT_Restrict: 5087288943Sdim handleRestrictAttr(S, D, Attr); 5088276479Sdim break; 5089276479Sdim case AttributeList::AT_MayAlias: 5090276479Sdim handleSimpleAttribute<MayAliasAttr>(S, D, Attr); 5091276479Sdim break; 5092276479Sdim case AttributeList::AT_Mode: 5093276479Sdim handleModeAttr(S, D, Attr); 5094276479Sdim break; 5095296417Sdim case AttributeList::AT_NoAlias: 5096296417Sdim handleSimpleAttribute<NoAliasAttr>(S, D, Attr); 5097296417Sdim break; 5098276479Sdim case AttributeList::AT_NoCommon: 5099276479Sdim handleSimpleAttribute<NoCommonAttr>(S, D, Attr); 5100276479Sdim break; 5101276479Sdim case AttributeList::AT_NoSplitStack: 5102276479Sdim handleSimpleAttribute<NoSplitStackAttr>(S, D, Attr); 5103276479Sdim break; 5104276479Sdim case AttributeList::AT_NonNull: 5105276479Sdim if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(D)) 5106276479Sdim handleNonNullAttrParameter(S, PVD, Attr); 5107276479Sdim else 5108276479Sdim handleNonNullAttr(S, D, Attr); 5109276479Sdim break; 5110276479Sdim case AttributeList::AT_ReturnsNonNull: 5111276479Sdim handleReturnsNonNullAttr(S, D, Attr); 5112276479Sdim break; 5113280031Sdim case AttributeList::AT_AssumeAligned: 5114280031Sdim handleAssumeAlignedAttr(S, D, Attr); 5115280031Sdim break; 5116276479Sdim case AttributeList::AT_Overloadable: 5117276479Sdim handleSimpleAttribute<OverloadableAttr>(S, D, Attr); 5118276479Sdim break; 5119276479Sdim case AttributeList::AT_Ownership: 5120276479Sdim handleOwnershipAttr(S, D, Attr); 5121276479Sdim break; 5122276479Sdim case AttributeList::AT_Cold: 5123276479Sdim handleColdAttr(S, D, Attr); 5124276479Sdim break; 5125276479Sdim case AttributeList::AT_Hot: 5126276479Sdim handleHotAttr(S, D, Attr); 5127276479Sdim break; 5128276479Sdim case AttributeList::AT_Naked: 5129296417Sdim handleNakedAttr(S, D, Attr); 5130276479Sdim break; 5131276479Sdim case AttributeList::AT_NoReturn: 5132276479Sdim handleNoReturnAttr(S, D, Attr); 5133276479Sdim break; 5134276479Sdim case AttributeList::AT_NoThrow: 5135276479Sdim handleSimpleAttribute<NoThrowAttr>(S, D, Attr); 5136276479Sdim break; 5137276479Sdim case AttributeList::AT_CUDAShared: 5138296417Sdim handleSimpleAttributeWithExclusions<CUDASharedAttr, CUDAConstantAttr>(S, D, 5139296417Sdim Attr); 5140276479Sdim break; 5141276479Sdim case AttributeList::AT_VecReturn: 5142276479Sdim handleVecReturnAttr(S, D, Attr); 5143276479Sdim break; 5144193326Sed 5145239462Sdim case AttributeList::AT_ObjCOwnership: 5146276479Sdim handleObjCOwnershipAttr(S, D, Attr); 5147276479Sdim break; 5148239462Sdim case AttributeList::AT_ObjCPreciseLifetime: 5149276479Sdim handleObjCPreciseLifetimeAttr(S, D, Attr); 5150276479Sdim break; 5151224145Sdim 5152239462Sdim case AttributeList::AT_ObjCReturnsInnerPointer: 5153276479Sdim handleObjCReturnsInnerPointerAttr(S, D, Attr); 5154276479Sdim break; 5155226633Sdim 5156243830Sdim case AttributeList::AT_ObjCRequiresSuper: 5157276479Sdim handleObjCRequiresSuperAttr(S, D, Attr); 5158276479Sdim break; 5159276479Sdim 5160261991Sdim case AttributeList::AT_ObjCBridge: 5161276479Sdim handleObjCBridgeAttr(S, scope, D, Attr); 5162276479Sdim break; 5163226633Sdim 5164276479Sdim case AttributeList::AT_ObjCBridgeMutable: 5165276479Sdim handleObjCBridgeMutableAttr(S, scope, D, Attr); 5166276479Sdim break; 5167276479Sdim 5168276479Sdim case AttributeList::AT_ObjCBridgeRelated: 5169276479Sdim handleObjCBridgeRelatedAttr(S, scope, D, Attr); 5170276479Sdim break; 5171276479Sdim 5172276479Sdim case AttributeList::AT_ObjCDesignatedInitializer: 5173276479Sdim handleObjCDesignatedInitializer(S, D, Attr); 5174276479Sdim break; 5175276479Sdim 5176276479Sdim case AttributeList::AT_ObjCRuntimeName: 5177276479Sdim handleObjCRuntimeName(S, D, Attr); 5178276479Sdim break; 5179288943Sdim 5180288943Sdim case AttributeList::AT_ObjCBoxable: 5181288943Sdim handleObjCBoxable(S, D, Attr); 5182288943Sdim break; 5183276479Sdim 5184239462Sdim case AttributeList::AT_CFAuditedTransfer: 5185276479Sdim handleCFAuditedTransferAttr(S, D, Attr); 5186276479Sdim break; 5187239462Sdim case AttributeList::AT_CFUnknownTransfer: 5188276479Sdim handleCFUnknownTransferAttr(S, D, Attr); 5189276479Sdim break; 5190226633Sdim 5191239462Sdim case AttributeList::AT_CFConsumed: 5192276479Sdim case AttributeList::AT_NSConsumed: 5193276479Sdim handleNSConsumedAttr(S, D, Attr); 5194276479Sdim break; 5195239462Sdim case AttributeList::AT_NSConsumesSelf: 5196276479Sdim handleSimpleAttribute<NSConsumesSelfAttr>(S, D, Attr); 5197276479Sdim break; 5198218893Sdim 5199239462Sdim case AttributeList::AT_NSReturnsAutoreleased: 5200239462Sdim case AttributeList::AT_NSReturnsNotRetained: 5201239462Sdim case AttributeList::AT_CFReturnsNotRetained: 5202239462Sdim case AttributeList::AT_NSReturnsRetained: 5203239462Sdim case AttributeList::AT_CFReturnsRetained: 5204276479Sdim handleNSReturnsRetainedAttr(S, D, Attr); 5205276479Sdim break; 5206239462Sdim case AttributeList::AT_WorkGroupSizeHint: 5207276479Sdim handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, Attr); 5208276479Sdim break; 5209239462Sdim case AttributeList::AT_ReqdWorkGroupSize: 5210276479Sdim handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, Attr); 5211276479Sdim break; 5212249423Sdim case AttributeList::AT_VecTypeHint: 5213276479Sdim handleVecTypeHint(S, D, Attr); 5214276479Sdim break; 5215249423Sdim 5216276479Sdim case AttributeList::AT_InitPriority: 5217276479Sdim handleInitPriorityAttr(S, D, Attr); 5218276479Sdim break; 5219276479Sdim 5220276479Sdim case AttributeList::AT_Packed: 5221276479Sdim handlePackedAttr(S, D, Attr); 5222276479Sdim break; 5223276479Sdim case AttributeList::AT_Section: 5224276479Sdim handleSectionAttr(S, D, Attr); 5225276479Sdim break; 5226288943Sdim case AttributeList::AT_Target: 5227288943Sdim handleTargetAttr(S, D, Attr); 5228288943Sdim break; 5229239462Sdim case AttributeList::AT_Unavailable: 5230261991Sdim handleAttrWithMessage<UnavailableAttr>(S, D, Attr); 5231239462Sdim break; 5232276479Sdim case AttributeList::AT_ArcWeakrefUnavailable: 5233276479Sdim handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, Attr); 5234193326Sed break; 5235239462Sdim case AttributeList::AT_ObjCRootClass: 5236276479Sdim handleSimpleAttribute<ObjCRootClassAttr>(S, D, Attr); 5237234353Sdim break; 5238276479Sdim case AttributeList::AT_ObjCExplicitProtocolImpl: 5239276479Sdim handleObjCSuppresProtocolAttr(S, D, Attr); 5240234353Sdim break; 5241276479Sdim case AttributeList::AT_ObjCRequiresPropertyDefs: 5242276479Sdim handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, Attr); 5243276479Sdim break; 5244276479Sdim case AttributeList::AT_Unused: 5245276479Sdim handleSimpleAttribute<UnusedAttr>(S, D, Attr); 5246276479Sdim break; 5247239462Sdim case AttributeList::AT_ReturnsTwice: 5248276479Sdim handleSimpleAttribute<ReturnsTwiceAttr>(S, D, Attr); 5249226633Sdim break; 5250296417Sdim case AttributeList::AT_NotTailCalled: 5251296417Sdim handleNotTailCalledAttr(S, D, Attr); 5252296417Sdim break; 5253296417Sdim case AttributeList::AT_DisableTailCalls: 5254296417Sdim handleDisableTailCallsAttr(S, D, Attr); 5255296417Sdim break; 5256276479Sdim case AttributeList::AT_Used: 5257276479Sdim handleUsedAttr(S, D, Attr); 5258276479Sdim break; 5259249423Sdim case AttributeList::AT_Visibility: 5260249423Sdim handleVisibilityAttr(S, D, Attr, false); 5261249423Sdim break; 5262249423Sdim case AttributeList::AT_TypeVisibility: 5263249423Sdim handleVisibilityAttr(S, D, Attr, true); 5264249423Sdim break; 5265261991Sdim case AttributeList::AT_WarnUnused: 5266276479Sdim handleSimpleAttribute<WarnUnusedAttr>(S, D, Attr); 5267261991Sdim break; 5268276479Sdim case AttributeList::AT_WarnUnusedResult: 5269276479Sdim handleWarnUnusedResult(S, D, Attr); 5270224145Sdim break; 5271276479Sdim case AttributeList::AT_Weak: 5272276479Sdim handleSimpleAttribute<WeakAttr>(S, D, Attr); 5273276479Sdim break; 5274276479Sdim case AttributeList::AT_WeakRef: 5275276479Sdim handleWeakRefAttr(S, D, Attr); 5276276479Sdim break; 5277276479Sdim case AttributeList::AT_WeakImport: 5278276479Sdim handleWeakImportAttr(S, D, Attr); 5279276479Sdim break; 5280239462Sdim case AttributeList::AT_TransparentUnion: 5281224145Sdim handleTransparentUnionAttr(S, D, Attr); 5282193326Sed break; 5283239462Sdim case AttributeList::AT_ObjCException: 5284276479Sdim handleSimpleAttribute<ObjCExceptionAttr>(S, D, Attr); 5285193326Sed break; 5286239462Sdim case AttributeList::AT_ObjCMethodFamily: 5287224145Sdim handleObjCMethodFamilyAttr(S, D, Attr); 5288221345Sdim break; 5289276479Sdim case AttributeList::AT_ObjCNSObject: 5290276479Sdim handleObjCNSObject(S, D, Attr); 5291193326Sed break; 5292288943Sdim case AttributeList::AT_ObjCIndependentClass: 5293288943Sdim handleObjCIndependentClass(S, D, Attr); 5294288943Sdim break; 5295276479Sdim case AttributeList::AT_Blocks: 5296276479Sdim handleBlocksAttr(S, D, Attr); 5297210299Sed break; 5298276479Sdim case AttributeList::AT_Sentinel: 5299276479Sdim handleSentinelAttr(S, D, Attr); 5300276479Sdim break; 5301276479Sdim case AttributeList::AT_Const: 5302276479Sdim handleSimpleAttribute<ConstAttr>(S, D, Attr); 5303276479Sdim break; 5304276479Sdim case AttributeList::AT_Pure: 5305276479Sdim handleSimpleAttribute<PureAttr>(S, D, Attr); 5306276479Sdim break; 5307276479Sdim case AttributeList::AT_Cleanup: 5308276479Sdim handleCleanupAttr(S, D, Attr); 5309276479Sdim break; 5310276479Sdim case AttributeList::AT_NoDebug: 5311276479Sdim handleNoDebugAttr(S, D, Attr); 5312276479Sdim break; 5313276479Sdim case AttributeList::AT_NoDuplicate: 5314276479Sdim handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr); 5315276479Sdim break; 5316276479Sdim case AttributeList::AT_NoInline: 5317276479Sdim handleSimpleAttribute<NoInlineAttr>(S, D, Attr); 5318276479Sdim break; 5319276479Sdim case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg. 5320276479Sdim handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, Attr); 5321276479Sdim break; 5322239462Sdim case AttributeList::AT_StdCall: 5323239462Sdim case AttributeList::AT_CDecl: 5324239462Sdim case AttributeList::AT_FastCall: 5325239462Sdim case AttributeList::AT_ThisCall: 5326239462Sdim case AttributeList::AT_Pascal: 5327280031Sdim case AttributeList::AT_VectorCall: 5328256030Sdim case AttributeList::AT_MSABI: 5329256030Sdim case AttributeList::AT_SysVABI: 5330239462Sdim case AttributeList::AT_Pcs: 5331249423Sdim case AttributeList::AT_IntelOclBicc: 5332224145Sdim handleCallConvAttr(S, D, Attr); 5333203955Srdivacky break; 5334239462Sdim case AttributeList::AT_OpenCLKernel: 5335276479Sdim handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr); 5336218893Sdim break; 5337249423Sdim case AttributeList::AT_OpenCLImageAccess: 5338276479Sdim handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr); 5339249423Sdim break; 5340296417Sdim case AttributeList::AT_InternalLinkage: 5341296417Sdim handleInternalLinkageAttr(S, D, Attr); 5342296417Sdim break; 5343239462Sdim 5344239462Sdim // Microsoft attributes: 5345288943Sdim case AttributeList::AT_MSNoVTable: 5346288943Sdim handleSimpleAttribute<MSNoVTableAttr>(S, D, Attr); 5347239462Sdim break; 5348288943Sdim case AttributeList::AT_MSStruct: 5349288943Sdim handleSimpleAttribute<MSStructAttr>(S, D, Attr); 5350288943Sdim break; 5351239462Sdim case AttributeList::AT_Uuid: 5352224145Sdim handleUuidAttr(S, D, Attr); 5353218893Sdim break; 5354276479Sdim case AttributeList::AT_MSInheritance: 5355276479Sdim handleMSInheritanceAttr(S, D, Attr); 5356239462Sdim break; 5357276479Sdim case AttributeList::AT_SelectAny: 5358276479Sdim handleSimpleAttribute<SelectAnyAttr>(S, D, Attr); 5359239462Sdim break; 5360276479Sdim case AttributeList::AT_Thread: 5361276479Sdim handleDeclspecThreadAttr(S, D, Attr); 5362239462Sdim break; 5363226633Sdim 5364226633Sdim // Thread safety attributes: 5365261991Sdim case AttributeList::AT_AssertExclusiveLock: 5366261991Sdim handleAssertExclusiveLockAttr(S, D, Attr); 5367261991Sdim break; 5368261991Sdim case AttributeList::AT_AssertSharedLock: 5369261991Sdim handleAssertSharedLockAttr(S, D, Attr); 5370261991Sdim break; 5371239462Sdim case AttributeList::AT_GuardedVar: 5372276479Sdim handleSimpleAttribute<GuardedVarAttr>(S, D, Attr); 5373226633Sdim break; 5374239462Sdim case AttributeList::AT_PtGuardedVar: 5375239462Sdim handlePtGuardedVarAttr(S, D, Attr); 5376226633Sdim break; 5377239462Sdim case AttributeList::AT_ScopedLockable: 5378276479Sdim handleSimpleAttribute<ScopedLockableAttr>(S, D, Attr); 5379226633Sdim break; 5380288943Sdim case AttributeList::AT_NoSanitize: 5381288943Sdim handleNoSanitizeAttr(S, D, Attr); 5382234353Sdim break; 5383288943Sdim case AttributeList::AT_NoSanitizeSpecific: 5384288943Sdim handleNoSanitizeSpecificAttr(S, D, Attr); 5385288943Sdim break; 5386239462Sdim case AttributeList::AT_NoThreadSafetyAnalysis: 5387276479Sdim handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, Attr); 5388226633Sdim break; 5389239462Sdim case AttributeList::AT_GuardedBy: 5390226633Sdim handleGuardedByAttr(S, D, Attr); 5391226633Sdim break; 5392239462Sdim case AttributeList::AT_PtGuardedBy: 5393239462Sdim handlePtGuardedByAttr(S, D, Attr); 5394226633Sdim break; 5395239462Sdim case AttributeList::AT_ExclusiveTrylockFunction: 5396239462Sdim handleExclusiveTrylockFunctionAttr(S, D, Attr); 5397226633Sdim break; 5398239462Sdim case AttributeList::AT_LockReturned: 5399226633Sdim handleLockReturnedAttr(S, D, Attr); 5400226633Sdim break; 5401239462Sdim case AttributeList::AT_LocksExcluded: 5402226633Sdim handleLocksExcludedAttr(S, D, Attr); 5403226633Sdim break; 5404239462Sdim case AttributeList::AT_SharedTrylockFunction: 5405239462Sdim handleSharedTrylockFunctionAttr(S, D, Attr); 5406226633Sdim break; 5407239462Sdim case AttributeList::AT_AcquiredBefore: 5408239462Sdim handleAcquiredBeforeAttr(S, D, Attr); 5409226633Sdim break; 5410239462Sdim case AttributeList::AT_AcquiredAfter: 5411239462Sdim handleAcquiredAfterAttr(S, D, Attr); 5412226633Sdim break; 5413226633Sdim 5414276479Sdim // Capability analysis attributes. 5415276479Sdim case AttributeList::AT_Capability: 5416276479Sdim case AttributeList::AT_Lockable: 5417276479Sdim handleCapabilityAttr(S, D, Attr); 5418276479Sdim break; 5419276479Sdim case AttributeList::AT_RequiresCapability: 5420276479Sdim handleRequiresCapabilityAttr(S, D, Attr); 5421276479Sdim break; 5422276479Sdim 5423276479Sdim case AttributeList::AT_AssertCapability: 5424276479Sdim handleAssertCapabilityAttr(S, D, Attr); 5425276479Sdim break; 5426276479Sdim case AttributeList::AT_AcquireCapability: 5427276479Sdim handleAcquireCapabilityAttr(S, D, Attr); 5428276479Sdim break; 5429276479Sdim case AttributeList::AT_ReleaseCapability: 5430276479Sdim handleReleaseCapabilityAttr(S, D, Attr); 5431276479Sdim break; 5432276479Sdim case AttributeList::AT_TryAcquireCapability: 5433276479Sdim handleTryAcquireCapabilityAttr(S, D, Attr); 5434276479Sdim break; 5435276479Sdim 5436261991Sdim // Consumed analysis attributes. 5437261991Sdim case AttributeList::AT_Consumable: 5438261991Sdim handleConsumableAttr(S, D, Attr); 5439261991Sdim break; 5440276479Sdim case AttributeList::AT_ConsumableAutoCast: 5441276479Sdim handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, Attr); 5442276479Sdim break; 5443276479Sdim case AttributeList::AT_ConsumableSetOnRead: 5444276479Sdim handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, Attr); 5445276479Sdim break; 5446261991Sdim case AttributeList::AT_CallableWhen: 5447261991Sdim handleCallableWhenAttr(S, D, Attr); 5448261991Sdim break; 5449261991Sdim case AttributeList::AT_ParamTypestate: 5450261991Sdim handleParamTypestateAttr(S, D, Attr); 5451261991Sdim break; 5452261991Sdim case AttributeList::AT_ReturnTypestate: 5453261991Sdim handleReturnTypestateAttr(S, D, Attr); 5454261991Sdim break; 5455261991Sdim case AttributeList::AT_SetTypestate: 5456261991Sdim handleSetTypestateAttr(S, D, Attr); 5457261991Sdim break; 5458261991Sdim case AttributeList::AT_TestTypestate: 5459261991Sdim handleTestTypestateAttr(S, D, Attr); 5460261991Sdim break; 5461261991Sdim 5462239462Sdim // Type safety attributes. 5463239462Sdim case AttributeList::AT_ArgumentWithTypeTag: 5464239462Sdim handleArgumentWithTypeTagAttr(S, D, Attr); 5465239462Sdim break; 5466239462Sdim case AttributeList::AT_TypeTagForDatatype: 5467239462Sdim handleTypeTagForDatatypeAttr(S, D, Attr); 5468239462Sdim break; 5469193326Sed } 5470193326Sed} 5471193326Sed 5472193326Sed/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 5473193326Sed/// attribute list to the specified decl, ignoring any type attributes. 5474218893Sdimvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 5475218893Sdim const AttributeList *AttrList, 5476249423Sdim bool IncludeCXX11Attributes) { 5477249423Sdim for (const AttributeList* l = AttrList; l; l = l->getNext()) 5478261991Sdim ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes); 5479204643Srdivacky 5480276479Sdim // FIXME: We should be able to handle these cases in TableGen. 5481204643Srdivacky // GCC accepts 5482204643Srdivacky // static int a9 __attribute__((weakref)); 5483204643Srdivacky // but that looks really pointless. We reject it. 5484261991Sdim if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 5485276479Sdim Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) 5486276479Sdim << cast<NamedDecl>(D); 5487249423Sdim D->dropAttr<WeakRefAttr>(); 5488204643Srdivacky return; 5489204643Srdivacky } 5490276479Sdim 5491280031Sdim // FIXME: We should be able to handle this in TableGen as well. It would be 5492280031Sdim // good to have a way to specify "these attributes must appear as a group", 5493280031Sdim // for these. Additionally, it would be good to have a way to specify "these 5494280031Sdim // attribute must never appear as a group" for attributes like cold and hot. 5495276479Sdim if (!D->hasAttr<OpenCLKernelAttr>()) { 5496276479Sdim // These attributes cannot be applied to a non-kernel function. 5497276479Sdim if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) { 5498280031Sdim // FIXME: This emits a different error message than 5499280031Sdim // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction. 5500276479Sdim Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; 5501276479Sdim D->setInvalidDecl(); 5502280031Sdim } else if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) { 5503276479Sdim Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; 5504276479Sdim D->setInvalidDecl(); 5505280031Sdim } else if (Attr *A = D->getAttr<VecTypeHintAttr>()) { 5506276479Sdim Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A; 5507276479Sdim D->setInvalidDecl(); 5508280031Sdim } else if (Attr *A = D->getAttr<AMDGPUNumVGPRAttr>()) { 5509280031Sdim Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) 5510280031Sdim << A << ExpectedKernelFunction; 5511280031Sdim D->setInvalidDecl(); 5512280031Sdim } else if (Attr *A = D->getAttr<AMDGPUNumSGPRAttr>()) { 5513280031Sdim Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) 5514280031Sdim << A << ExpectedKernelFunction; 5515280031Sdim D->setInvalidDecl(); 5516276479Sdim } 5517276479Sdim } 5518193326Sed} 5519193326Sed 5520226633Sdim// Annotation attributes are the only attributes allowed after an access 5521226633Sdim// specifier. 5522226633Sdimbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 5523226633Sdim const AttributeList *AttrList) { 5524226633Sdim for (const AttributeList* l = AttrList; l; l = l->getNext()) { 5525239462Sdim if (l->getKind() == AttributeList::AT_Annotate) { 5526280031Sdim ProcessDeclAttribute(*this, nullptr, ASDecl, *l, l->isCXX11Attribute()); 5527226633Sdim } else { 5528226633Sdim Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 5529226633Sdim return true; 5530226633Sdim } 5531226633Sdim } 5532226633Sdim 5533226633Sdim return false; 5534226633Sdim} 5535226633Sdim 5536226633Sdim/// checkUnusedDeclAttributes - Check a list of attributes to see if it 5537226633Sdim/// contains any decl attributes that we should warn about. 5538226633Sdimstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 5539226633Sdim for ( ; A; A = A->getNext()) { 5540226633Sdim // Only warn if the attribute is an unignored, non-type attribute. 5541249423Sdim if (A->isUsedAsTypeAttr() || A->isInvalid()) continue; 5542226633Sdim if (A->getKind() == AttributeList::IgnoredAttribute) continue; 5543226633Sdim 5544226633Sdim if (A->getKind() == AttributeList::UnknownAttribute) { 5545226633Sdim S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 5546226633Sdim << A->getName() << A->getRange(); 5547226633Sdim } else { 5548226633Sdim S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 5549226633Sdim << A->getName() << A->getRange(); 5550226633Sdim } 5551226633Sdim } 5552226633Sdim} 5553226633Sdim 5554226633Sdim/// checkUnusedDeclAttributes - Given a declarator which is not being 5555226633Sdim/// used to build a declaration, complain about any decl attributes 5556226633Sdim/// which might be lying around on it. 5557226633Sdimvoid Sema::checkUnusedDeclAttributes(Declarator &D) { 5558226633Sdim ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 5559226633Sdim ::checkUnusedDeclAttributes(*this, D.getAttributes()); 5560226633Sdim for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 5561226633Sdim ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 5562226633Sdim} 5563226633Sdim 5564198092Srdivacky/// DeclClonePragmaWeak - clone existing decl (maybe definition), 5565239462Sdim/// \#pragma weak needs a non-definition decl and source may not have one. 5566226633SdimNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 5567226633Sdim SourceLocation Loc) { 5568198092Srdivacky assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 5569276479Sdim NamedDecl *NewD = nullptr; 5570198092Srdivacky if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 5571226633Sdim FunctionDecl *NewFD; 5572226633Sdim // FIXME: Missing call to CheckFunctionDeclaration(). 5573226633Sdim // FIXME: Mangling? 5574226633Sdim // FIXME: Is the qualifier info correct? 5575226633Sdim // FIXME: Is the DeclContext correct? 5576226633Sdim NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 5577226633Sdim Loc, Loc, DeclarationName(II), 5578226633Sdim FD->getType(), FD->getTypeSourceInfo(), 5579249423Sdim SC_None, false/*isInlineSpecified*/, 5580226633Sdim FD->hasPrototype(), 5581226633Sdim false/*isConstexprSpecified*/); 5582226633Sdim NewD = NewFD; 5583226633Sdim 5584226633Sdim if (FD->getQualifier()) 5585219077Sdim NewFD->setQualifierInfo(FD->getQualifierLoc()); 5586226633Sdim 5587226633Sdim // Fake up parameter variables; they are declared as if this were 5588226633Sdim // a typedef. 5589226633Sdim QualType FDTy = FD->getType(); 5590226633Sdim if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 5591226633Sdim SmallVector<ParmVarDecl*, 16> Params; 5592276479Sdim for (const auto &AI : FT->param_types()) { 5593276479Sdim ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI); 5594226633Sdim Param->setScopeInfo(0, Params.size()); 5595226633Sdim Params.push_back(Param); 5596226633Sdim } 5597226633Sdim NewFD->setParams(Params); 5598205219Srdivacky } 5599198092Srdivacky } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 5600198092Srdivacky NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 5601221345Sdim VD->getInnerLocStart(), VD->getLocation(), II, 5602200583Srdivacky VD->getType(), VD->getTypeSourceInfo(), 5603249423Sdim VD->getStorageClass()); 5604205219Srdivacky if (VD->getQualifier()) { 5605205219Srdivacky VarDecl *NewVD = cast<VarDecl>(NewD); 5606219077Sdim NewVD->setQualifierInfo(VD->getQualifierLoc()); 5607205219Srdivacky } 5608198092Srdivacky } 5609198092Srdivacky return NewD; 5610198092Srdivacky} 5611198092Srdivacky 5612239462Sdim/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak 5613198092Srdivacky/// applied to it, possibly with an alias. 5614198092Srdivackyvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 5615198092Srdivacky if (W.getUsed()) return; // only do this once 5616198092Srdivacky W.setUsed(true); 5617198092Srdivacky if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 5618198092Srdivacky IdentifierInfo *NDId = ND->getIdentifier(); 5619226633Sdim NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 5620276479Sdim NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(), 5621276479Sdim W.getLocation())); 5622276479Sdim NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation())); 5623198092Srdivacky WeakTopLevelDecl.push_back(NewD); 5624198092Srdivacky // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 5625198092Srdivacky // to insert Decl at TU scope, sorry. 5626198092Srdivacky DeclContext *SavedContext = CurContext; 5627198092Srdivacky CurContext = Context.getTranslationUnitDecl(); 5628276479Sdim NewD->setDeclContext(CurContext); 5629276479Sdim NewD->setLexicalDeclContext(CurContext); 5630198092Srdivacky PushOnScopeChains(NewD, S); 5631198092Srdivacky CurContext = SavedContext; 5632198092Srdivacky } else { // just add weak to existing 5633276479Sdim ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation())); 5634198092Srdivacky } 5635198092Srdivacky} 5636198092Srdivacky 5637249423Sdimvoid Sema::ProcessPragmaWeak(Scope *S, Decl *D) { 5638218893Sdim // It's valid to "forward-declare" #pragma weak, in which case we 5639218893Sdim // have to do this. 5640249423Sdim LoadExternalWeakUndeclaredIdentifiers(); 5641249423Sdim if (!WeakUndeclaredIdentifiers.empty()) { 5642276479Sdim NamedDecl *ND = nullptr; 5643249423Sdim if (VarDecl *VD = dyn_cast<VarDecl>(D)) 5644249423Sdim if (VD->isExternC()) 5645249423Sdim ND = VD; 5646249423Sdim if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 5647249423Sdim if (FD->isExternC()) 5648249423Sdim ND = FD; 5649249423Sdim if (ND) { 5650249423Sdim if (IdentifierInfo *Id = ND->getIdentifier()) { 5651288943Sdim auto I = WeakUndeclaredIdentifiers.find(Id); 5652249423Sdim if (I != WeakUndeclaredIdentifiers.end()) { 5653249423Sdim WeakInfo W = I->second; 5654249423Sdim DeclApplyPragmaWeak(S, ND, W); 5655249423Sdim WeakUndeclaredIdentifiers[Id] = W; 5656218893Sdim } 5657198092Srdivacky } 5658198092Srdivacky } 5659198092Srdivacky } 5660249423Sdim} 5661198092Srdivacky 5662249423Sdim/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 5663249423Sdim/// it, apply them to D. This is a bit tricky because PD can have attributes 5664249423Sdim/// specified in many different places, and we need to find and apply them all. 5665261991Sdimvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 5666193326Sed // Apply decl attributes from the DeclSpec if present. 5667218893Sdim if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 5668261991Sdim ProcessDeclAttributeList(S, D, Attrs); 5669198092Srdivacky 5670193326Sed // Walk the declarator structure, applying decl attributes that were in a type 5671193326Sed // position to the decl itself. This handles cases like: 5672193326Sed // int *__attr__(x)** D; 5673193326Sed // when X is a decl attribute. 5674193326Sed for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 5675193326Sed if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 5676261991Sdim ProcessDeclAttributeList(S, D, Attrs, /*IncludeCXX11Attributes=*/false); 5677198092Srdivacky 5678193326Sed // Finally, apply any attributes on the decl itself. 5679193326Sed if (const AttributeList *Attrs = PD.getAttributes()) 5680261991Sdim ProcessDeclAttributeList(S, D, Attrs); 5681193326Sed} 5682198893Srdivacky 5683224145Sdim/// Is the given declaration allowed to use a forbidden type? 5684296417Sdim/// If so, it'll still be annotated with an attribute that makes it 5685296417Sdim/// illegal to actually use. 5686296417Sdimstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl, 5687296417Sdim const DelayedDiagnostic &diag, 5688296417Sdim UnavailableAttr::ImplicitReason &reason) { 5689224145Sdim // Private ivars are always okay. Unfortunately, people don't 5690224145Sdim // always properly make their ivars private, even in system headers. 5691224145Sdim // Plus we need to make fields okay, too. 5692226633Sdim if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 5693226633Sdim !isa<FunctionDecl>(decl)) 5694224145Sdim return false; 5695224145Sdim 5696296417Sdim // Silently accept unsupported uses of __weak in both user and system 5697296417Sdim // declarations when it's been disabled, for ease of integration with 5698296417Sdim // -fno-objc-arc files. We do have to take some care against attempts 5699296417Sdim // to define such things; for now, we've only done that for ivars 5700296417Sdim // and properties. 5701296417Sdim if ((isa<ObjCIvarDecl>(decl) || isa<ObjCPropertyDecl>(decl))) { 5702296417Sdim if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled || 5703296417Sdim diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) { 5704296417Sdim reason = UnavailableAttr::IR_ForbiddenWeak; 5705296417Sdim return true; 5706296417Sdim } 5707296417Sdim } 5708296417Sdim 5709296417Sdim // Allow all sorts of things in system headers. 5710296417Sdim if (S.Context.getSourceManager().isInSystemHeader(decl->getLocation())) { 5711296417Sdim // Currently, all the failures dealt with this way are due to ARC 5712296417Sdim // restrictions. 5713296417Sdim reason = UnavailableAttr::IR_ARCForbiddenType; 5714296417Sdim return true; 5715296417Sdim } 5716296417Sdim 5717296417Sdim return false; 5718224145Sdim} 5719224145Sdim 5720224145Sdim/// Handle a delayed forbidden-type diagnostic. 5721224145Sdimstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 5722224145Sdim Decl *decl) { 5723296417Sdim auto reason = UnavailableAttr::IR_None; 5724296417Sdim if (decl && isForbiddenTypeAllowed(S, decl, diag, reason)) { 5725296417Sdim assert(reason && "didn't set reason?"); 5726296417Sdim decl->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", reason, 5727296417Sdim diag.Loc)); 5728224145Sdim return; 5729224145Sdim } 5730234353Sdim if (S.getLangOpts().ObjCAutoRefCount) 5731226633Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 5732239462Sdim // FIXME: we may want to suppress diagnostics for all 5733226633Sdim // kind of forbidden type messages on unavailable functions. 5734226633Sdim if (FD->hasAttr<UnavailableAttr>() && 5735226633Sdim diag.getForbiddenTypeDiagnostic() == 5736226633Sdim diag::err_arc_array_param_no_ownership) { 5737226633Sdim diag.Triggered = true; 5738226633Sdim return; 5739226633Sdim } 5740226633Sdim } 5741224145Sdim 5742224145Sdim S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 5743224145Sdim << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 5744224145Sdim diag.Triggered = true; 5745224145Sdim} 5746224145Sdim 5747280031Sdim 5748280031Sdimstatic bool isDeclDeprecated(Decl *D) { 5749280031Sdim do { 5750280031Sdim if (D->isDeprecated()) 5751280031Sdim return true; 5752280031Sdim // A category implicitly has the availability of the interface. 5753280031Sdim if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 5754288943Sdim if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface()) 5755288943Sdim return Interface->isDeprecated(); 5756280031Sdim } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 5757280031Sdim return false; 5758280031Sdim} 5759280031Sdim 5760280031Sdimstatic bool isDeclUnavailable(Decl *D) { 5761280031Sdim do { 5762280031Sdim if (D->isUnavailable()) 5763280031Sdim return true; 5764280031Sdim // A category implicitly has the availability of the interface. 5765280031Sdim if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 5766288943Sdim if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface()) 5767288943Sdim return Interface->isUnavailable(); 5768280031Sdim } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 5769280031Sdim return false; 5770280031Sdim} 5771280031Sdim 5772288943Sdimstatic void DoEmitAvailabilityWarning(Sema &S, Sema::AvailabilityDiagnostic K, 5773280031Sdim Decl *Ctx, const NamedDecl *D, 5774280031Sdim StringRef Message, SourceLocation Loc, 5775280031Sdim const ObjCInterfaceDecl *UnknownObjCClass, 5776280031Sdim const ObjCPropertyDecl *ObjCProperty, 5777280031Sdim bool ObjCPropertyAccess) { 5778280031Sdim // Diagnostics for deprecated or unavailable. 5779280031Sdim unsigned diag, diag_message, diag_fwdclass_message; 5780296417Sdim unsigned diag_available_here = diag::note_availability_specified_here; 5781280031Sdim 5782280031Sdim // Matches 'diag::note_property_attribute' options. 5783280031Sdim unsigned property_note_select; 5784280031Sdim 5785280031Sdim // Matches diag::note_availability_specified_here. 5786280031Sdim unsigned available_here_select_kind; 5787280031Sdim 5788280031Sdim // Don't warn if our current context is deprecated or unavailable. 5789280031Sdim switch (K) { 5790288943Sdim case Sema::AD_Deprecation: 5791288943Sdim if (isDeclDeprecated(Ctx) || isDeclUnavailable(Ctx)) 5792280031Sdim return; 5793280031Sdim diag = !ObjCPropertyAccess ? diag::warn_deprecated 5794280031Sdim : diag::warn_property_method_deprecated; 5795280031Sdim diag_message = diag::warn_deprecated_message; 5796280031Sdim diag_fwdclass_message = diag::warn_deprecated_fwdclass_message; 5797280031Sdim property_note_select = /* deprecated */ 0; 5798280031Sdim available_here_select_kind = /* deprecated */ 2; 5799280031Sdim break; 5800280031Sdim 5801288943Sdim case Sema::AD_Unavailable: 5802280031Sdim if (isDeclUnavailable(Ctx)) 5803280031Sdim return; 5804280031Sdim diag = !ObjCPropertyAccess ? diag::err_unavailable 5805280031Sdim : diag::err_property_method_unavailable; 5806280031Sdim diag_message = diag::err_unavailable_message; 5807280031Sdim diag_fwdclass_message = diag::warn_unavailable_fwdclass_message; 5808280031Sdim property_note_select = /* unavailable */ 1; 5809280031Sdim available_here_select_kind = /* unavailable */ 0; 5810296417Sdim 5811296417Sdim if (auto attr = D->getAttr<UnavailableAttr>()) { 5812296417Sdim if (attr->isImplicit() && attr->getImplicitReason()) { 5813296417Sdim // Most of these failures are due to extra restrictions in ARC; 5814296417Sdim // reflect that in the primary diagnostic when applicable. 5815296417Sdim auto flagARCError = [&] { 5816296417Sdim if (S.getLangOpts().ObjCAutoRefCount && 5817296417Sdim S.getSourceManager().isInSystemHeader(D->getLocation())) 5818296417Sdim diag = diag::err_unavailable_in_arc; 5819296417Sdim }; 5820296417Sdim 5821296417Sdim switch (attr->getImplicitReason()) { 5822296417Sdim case UnavailableAttr::IR_None: break; 5823296417Sdim 5824296417Sdim case UnavailableAttr::IR_ARCForbiddenType: 5825296417Sdim flagARCError(); 5826296417Sdim diag_available_here = diag::note_arc_forbidden_type; 5827296417Sdim break; 5828296417Sdim 5829296417Sdim case UnavailableAttr::IR_ForbiddenWeak: 5830296417Sdim if (S.getLangOpts().ObjCWeakRuntime) 5831296417Sdim diag_available_here = diag::note_arc_weak_disabled; 5832296417Sdim else 5833296417Sdim diag_available_here = diag::note_arc_weak_no_runtime; 5834296417Sdim break; 5835296417Sdim 5836296417Sdim case UnavailableAttr::IR_ARCForbiddenConversion: 5837296417Sdim flagARCError(); 5838296417Sdim diag_available_here = diag::note_performs_forbidden_arc_conversion; 5839296417Sdim break; 5840296417Sdim 5841296417Sdim case UnavailableAttr::IR_ARCInitReturnsUnrelated: 5842296417Sdim flagARCError(); 5843296417Sdim diag_available_here = diag::note_arc_init_returns_unrelated; 5844296417Sdim break; 5845296417Sdim 5846296417Sdim case UnavailableAttr::IR_ARCFieldWithOwnership: 5847296417Sdim flagARCError(); 5848296417Sdim diag_available_here = diag::note_arc_field_with_ownership; 5849296417Sdim break; 5850296417Sdim } 5851296417Sdim } 5852296417Sdim } 5853296417Sdim 5854280031Sdim break; 5855280031Sdim 5856288943Sdim case Sema::AD_Partial: 5857288943Sdim diag = diag::warn_partial_availability; 5858288943Sdim diag_message = diag::warn_partial_message; 5859288943Sdim diag_fwdclass_message = diag::warn_partial_fwdclass_message; 5860288943Sdim property_note_select = /* partial */ 2; 5861288943Sdim available_here_select_kind = /* partial */ 3; 5862288943Sdim break; 5863280031Sdim } 5864280031Sdim 5865280031Sdim if (!Message.empty()) { 5866280031Sdim S.Diag(Loc, diag_message) << D << Message; 5867280031Sdim if (ObjCProperty) 5868280031Sdim S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) 5869280031Sdim << ObjCProperty->getDeclName() << property_note_select; 5870280031Sdim } else if (!UnknownObjCClass) { 5871280031Sdim S.Diag(Loc, diag) << D; 5872280031Sdim if (ObjCProperty) 5873280031Sdim S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) 5874280031Sdim << ObjCProperty->getDeclName() << property_note_select; 5875280031Sdim } else { 5876280031Sdim S.Diag(Loc, diag_fwdclass_message) << D; 5877280031Sdim S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 5878280031Sdim } 5879280031Sdim 5880296417Sdim S.Diag(D->getLocation(), diag_available_here) 5881280031Sdim << D << available_here_select_kind; 5882288943Sdim if (K == Sema::AD_Partial) 5883288943Sdim S.Diag(Loc, diag::note_partial_availability_silence) << D; 5884280031Sdim} 5885280031Sdim 5886280031Sdimstatic void handleDelayedAvailabilityCheck(Sema &S, DelayedDiagnostic &DD, 5887280031Sdim Decl *Ctx) { 5888288943Sdim assert(DD.Kind == DelayedDiagnostic::Deprecation || 5889288943Sdim DD.Kind == DelayedDiagnostic::Unavailable); 5890288943Sdim Sema::AvailabilityDiagnostic AD = DD.Kind == DelayedDiagnostic::Deprecation 5891288943Sdim ? Sema::AD_Deprecation 5892288943Sdim : Sema::AD_Unavailable; 5893280031Sdim DD.Triggered = true; 5894288943Sdim DoEmitAvailabilityWarning( 5895288943Sdim S, AD, Ctx, DD.getDeprecationDecl(), DD.getDeprecationMessage(), DD.Loc, 5896288943Sdim DD.getUnknownObjCClass(), DD.getObjCProperty(), false); 5897280031Sdim} 5898280031Sdim 5899239462Sdimvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { 5900239462Sdim assert(DelayedDiagnostics.getCurrentPool()); 5901239462Sdim DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); 5902239462Sdim DelayedDiagnostics.popWithoutEmitting(state); 5903218893Sdim 5904239462Sdim // When delaying diagnostics to run in the context of a parsed 5905239462Sdim // declaration, we only want to actually emit anything if parsing 5906239462Sdim // succeeds. 5907239462Sdim if (!decl) return; 5908218893Sdim 5909239462Sdim // We emit all the active diagnostics in this pool or any of its 5910239462Sdim // parents. In general, we'll get one pool for the decl spec 5911239462Sdim // and a child pool for each declarator; in a decl group like: 5912239462Sdim // deprecated_typedef foo, *bar, baz(); 5913239462Sdim // only the declarator pops will be passed decls. This is correct; 5914239462Sdim // we really do need to consider delayed diagnostics from the decl spec 5915239462Sdim // for each of the different declarations. 5916239462Sdim const DelayedDiagnosticPool *pool = &poppedPool; 5917239462Sdim do { 5918239462Sdim for (DelayedDiagnosticPool::pool_iterator 5919239462Sdim i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { 5920239462Sdim // This const_cast is a bit lame. Really, Triggered should be mutable. 5921239462Sdim DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); 5922218893Sdim if (diag.Triggered) 5923203955Srdivacky continue; 5924198893Srdivacky 5925218893Sdim switch (diag.Kind) { 5926203955Srdivacky case DelayedDiagnostic::Deprecation: 5927276479Sdim case DelayedDiagnostic::Unavailable: 5928276479Sdim // Don't bother giving deprecation/unavailable diagnostics if 5929276479Sdim // the decl is invalid. 5930234353Sdim if (!decl->isInvalidDecl()) 5931280031Sdim handleDelayedAvailabilityCheck(*this, diag, decl); 5932203955Srdivacky break; 5933203955Srdivacky 5934203955Srdivacky case DelayedDiagnostic::Access: 5935239462Sdim HandleDelayedAccessCheck(diag, decl); 5936203955Srdivacky break; 5937224145Sdim 5938224145Sdim case DelayedDiagnostic::ForbiddenType: 5939239462Sdim handleDelayedForbiddenType(*this, diag, decl); 5940224145Sdim break; 5941198893Srdivacky } 5942198893Srdivacky } 5943239462Sdim } while ((pool = pool->getParent())); 5944239462Sdim} 5945198893Srdivacky 5946239462Sdim/// Given a set of delayed diagnostics, re-emit them as if they had 5947239462Sdim/// been delayed in the current context instead of in the given pool. 5948239462Sdim/// Essentially, this just moves them to the current pool. 5949239462Sdimvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { 5950239462Sdim DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); 5951239462Sdim assert(curPool && "re-emitting in undelayed context not supported"); 5952239462Sdim curPool->steal(pool); 5953198893Srdivacky} 5954198893Srdivacky 5955276479Sdimvoid Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD, 5956276479Sdim NamedDecl *D, StringRef Message, 5957276479Sdim SourceLocation Loc, 5958276479Sdim const ObjCInterfaceDecl *UnknownObjCClass, 5959276479Sdim const ObjCPropertyDecl *ObjCProperty, 5960276479Sdim bool ObjCPropertyAccess) { 5961198893Srdivacky // Delay if we're currently parsing a declaration. 5962288943Sdim if (DelayedDiagnostics.shouldDelayDiagnostics() && AD != AD_Partial) { 5963280031Sdim DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability( 5964280031Sdim AD, Loc, D, UnknownObjCClass, ObjCProperty, Message, 5965280031Sdim ObjCPropertyAccess)); 5966198893Srdivacky return; 5967198893Srdivacky } 5968198893Srdivacky 5969276479Sdim Decl *Ctx = cast<Decl>(getCurLexicalContext()); 5970288943Sdim DoEmitAvailabilityWarning(*this, AD, Ctx, D, Message, Loc, UnknownObjCClass, 5971288943Sdim ObjCProperty, ObjCPropertyAccess); 5972198893Srdivacky} 5973