Path: blob/main/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
35233 views
//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements decl-related attribute processing.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/ASTConsumer.h"13#include "clang/AST/ASTContext.h"14#include "clang/AST/ASTMutationListener.h"15#include "clang/AST/CXXInheritance.h"16#include "clang/AST/DeclCXX.h"17#include "clang/AST/DeclObjC.h"18#include "clang/AST/DeclTemplate.h"19#include "clang/AST/Expr.h"20#include "clang/AST/ExprCXX.h"21#include "clang/AST/Mangle.h"22#include "clang/AST/RecursiveASTVisitor.h"23#include "clang/AST/Type.h"24#include "clang/Basic/CharInfo.h"25#include "clang/Basic/Cuda.h"26#include "clang/Basic/DarwinSDKInfo.h"27#include "clang/Basic/HLSLRuntime.h"28#include "clang/Basic/IdentifierTable.h"29#include "clang/Basic/LangOptions.h"30#include "clang/Basic/SourceLocation.h"31#include "clang/Basic/SourceManager.h"32#include "clang/Basic/TargetBuiltins.h"33#include "clang/Basic/TargetInfo.h"34#include "clang/Lex/Preprocessor.h"35#include "clang/Sema/Attr.h"36#include "clang/Sema/DeclSpec.h"37#include "clang/Sema/DelayedDiagnostic.h"38#include "clang/Sema/Initialization.h"39#include "clang/Sema/Lookup.h"40#include "clang/Sema/ParsedAttr.h"41#include "clang/Sema/Scope.h"42#include "clang/Sema/ScopeInfo.h"43#include "clang/Sema/SemaAMDGPU.h"44#include "clang/Sema/SemaARM.h"45#include "clang/Sema/SemaAVR.h"46#include "clang/Sema/SemaBPF.h"47#include "clang/Sema/SemaCUDA.h"48#include "clang/Sema/SemaHLSL.h"49#include "clang/Sema/SemaInternal.h"50#include "clang/Sema/SemaM68k.h"51#include "clang/Sema/SemaMIPS.h"52#include "clang/Sema/SemaMSP430.h"53#include "clang/Sema/SemaObjC.h"54#include "clang/Sema/SemaOpenCL.h"55#include "clang/Sema/SemaOpenMP.h"56#include "clang/Sema/SemaRISCV.h"57#include "clang/Sema/SemaSYCL.h"58#include "clang/Sema/SemaSwift.h"59#include "clang/Sema/SemaWasm.h"60#include "clang/Sema/SemaX86.h"61#include "llvm/ADT/STLExtras.h"62#include "llvm/ADT/STLForwardCompat.h"63#include "llvm/ADT/StringExtras.h"64#include "llvm/Demangle/Demangle.h"65#include "llvm/IR/Assumptions.h"66#include "llvm/MC/MCSectionMachO.h"67#include "llvm/Support/Error.h"68#include "llvm/Support/MathExtras.h"69#include "llvm/Support/raw_ostream.h"70#include "llvm/TargetParser/Triple.h"71#include <optional>7273using namespace clang;74using namespace sema;7576namespace AttributeLangSupport {77enum LANG {78C,79Cpp,80ObjC81};82} // end namespace AttributeLangSupport8384static unsigned getNumAttributeArgs(const ParsedAttr &AL) {85// FIXME: Include the type in the argument list.86return AL.getNumArgs() + AL.hasParsedType();87}8889SourceLocation Sema::getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }9091/// Wrapper around checkUInt32Argument, with an extra check to be sure92/// that the result will fit into a regular (signed) int. All args have the same93/// purpose as they do in checkUInt32Argument.94template <typename AttrInfo>95static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,96int &Val, unsigned Idx = UINT_MAX) {97uint32_t UVal;98if (!S.checkUInt32Argument(AI, Expr, UVal, Idx))99return false;100101if (UVal > (uint32_t)std::numeric_limits<int>::max()) {102llvm::APSInt I(32); // for toString103I = UVal;104S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)105<< toString(I, 10, false) << 32 << /* Unsigned */ 0;106return false;107}108109Val = UVal;110return true;111}112113bool Sema::checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI,114const Expr *E, StringRef &Str,115SourceLocation *ArgLocation) {116const auto *Literal = dyn_cast<StringLiteral>(E->IgnoreParenCasts());117if (ArgLocation)118*ArgLocation = E->getBeginLoc();119120if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {121Diag(E->getBeginLoc(), diag::err_attribute_argument_type)122<< CI << AANT_ArgumentString;123return false;124}125126Str = Literal->getString();127return true;128}129130bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,131StringRef &Str,132SourceLocation *ArgLocation) {133// Look for identifiers. If we have one emit a hint to fix it to a literal.134if (AL.isArgIdent(ArgNum)) {135IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);136Diag(Loc->Loc, diag::err_attribute_argument_type)137<< AL << AANT_ArgumentString138<< FixItHint::CreateInsertion(Loc->Loc, "\"")139<< FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");140Str = Loc->Ident->getName();141if (ArgLocation)142*ArgLocation = Loc->Loc;143return true;144}145146// Now check for an actual string literal.147Expr *ArgExpr = AL.getArgAsExpr(ArgNum);148const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());149if (ArgLocation)150*ArgLocation = ArgExpr->getBeginLoc();151152if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {153Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)154<< AL << AANT_ArgumentString;155return false;156}157Str = Literal->getString();158return checkStringLiteralArgumentAttr(AL, ArgExpr, Str, ArgLocation);159}160161/// Check if the passed-in expression is of type int or bool.162static bool isIntOrBool(Expr *Exp) {163QualType QT = Exp->getType();164return QT->isBooleanType() || QT->isIntegerType();165}166167168// Check to see if the type is a smart pointer of some kind. We assume169// it's a smart pointer if it defines both operator-> and operator*.170static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {171auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,172OverloadedOperatorKind Op) {173DeclContextLookupResult Result =174Record->lookup(S.Context.DeclarationNames.getCXXOperatorName(Op));175return !Result.empty();176};177178const RecordDecl *Record = RT->getDecl();179bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);180bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);181if (foundStarOperator && foundArrowOperator)182return true;183184const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);185if (!CXXRecord)186return false;187188for (const auto &BaseSpecifier : CXXRecord->bases()) {189if (!foundStarOperator)190foundStarOperator = IsOverloadedOperatorPresent(191BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);192if (!foundArrowOperator)193foundArrowOperator = IsOverloadedOperatorPresent(194BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);195}196197if (foundStarOperator && foundArrowOperator)198return true;199200return false;201}202203/// Check if passed in Decl is a pointer type.204/// Note that this function may produce an error message.205/// \return true if the Decl is a pointer type; false otherwise206static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,207const ParsedAttr &AL) {208const auto *VD = cast<ValueDecl>(D);209QualType QT = VD->getType();210if (QT->isAnyPointerType())211return true;212213if (const auto *RT = QT->getAs<RecordType>()) {214// If it's an incomplete type, it could be a smart pointer; skip it.215// (We don't want to force template instantiation if we can avoid it,216// since that would alter the order in which templates are instantiated.)217if (RT->isIncompleteType())218return true;219220if (threadSafetyCheckIsSmartPointer(S, RT))221return true;222}223224S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;225return false;226}227228/// Checks that the passed in QualType either is of RecordType or points229/// to RecordType. Returns the relevant RecordType, null if it does not exit.230static const RecordType *getRecordType(QualType QT) {231if (const auto *RT = QT->getAs<RecordType>())232return RT;233234// Now check if we point to record type.235if (const auto *PT = QT->getAs<PointerType>())236return PT->getPointeeType()->getAs<RecordType>();237238return nullptr;239}240241template <typename AttrType>242static bool checkRecordDeclForAttr(const RecordDecl *RD) {243// Check if the record itself has the attribute.244if (RD->hasAttr<AttrType>())245return true;246247// Else check if any base classes have the attribute.248if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {249if (!CRD->forallBases([](const CXXRecordDecl *Base) {250return !Base->hasAttr<AttrType>();251}))252return true;253}254return false;255}256257static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {258const RecordType *RT = getRecordType(Ty);259260if (!RT)261return false;262263// Don't check for the capability if the class hasn't been defined yet.264if (RT->isIncompleteType())265return true;266267// Allow smart pointers to be used as capability objects.268// FIXME -- Check the type that the smart pointer points to.269if (threadSafetyCheckIsSmartPointer(S, RT))270return true;271272return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());273}274275static bool checkTypedefTypeForCapability(QualType Ty) {276const auto *TD = Ty->getAs<TypedefType>();277if (!TD)278return false;279280TypedefNameDecl *TN = TD->getDecl();281if (!TN)282return false;283284return TN->hasAttr<CapabilityAttr>();285}286287static bool typeHasCapability(Sema &S, QualType Ty) {288if (checkTypedefTypeForCapability(Ty))289return true;290291if (checkRecordTypeForCapability(S, Ty))292return true;293294return false;295}296297static bool isCapabilityExpr(Sema &S, const Expr *Ex) {298// Capability expressions are simple expressions involving the boolean logic299// operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once300// a DeclRefExpr is found, its type should be checked to determine whether it301// is a capability or not.302303if (const auto *E = dyn_cast<CastExpr>(Ex))304return isCapabilityExpr(S, E->getSubExpr());305else if (const auto *E = dyn_cast<ParenExpr>(Ex))306return isCapabilityExpr(S, E->getSubExpr());307else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {308if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||309E->getOpcode() == UO_Deref)310return isCapabilityExpr(S, E->getSubExpr());311return false;312} else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {313if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)314return isCapabilityExpr(S, E->getLHS()) &&315isCapabilityExpr(S, E->getRHS());316return false;317}318319return typeHasCapability(S, Ex->getType());320}321322/// Checks that all attribute arguments, starting from Sidx, resolve to323/// a capability object.324/// \param Sidx The attribute argument index to start checking with.325/// \param ParamIdxOk Whether an argument can be indexing into a function326/// parameter list.327static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,328const ParsedAttr &AL,329SmallVectorImpl<Expr *> &Args,330unsigned Sidx = 0,331bool ParamIdxOk = false) {332if (Sidx == AL.getNumArgs()) {333// If we don't have any capability arguments, the attribute implicitly334// refers to 'this'. So we need to make sure that 'this' exists, i.e. we're335// a non-static method, and that the class is a (scoped) capability.336const auto *MD = dyn_cast<const CXXMethodDecl>(D);337if (MD && !MD->isStatic()) {338const CXXRecordDecl *RD = MD->getParent();339// FIXME -- need to check this again on template instantiation340if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&341!checkRecordDeclForAttr<ScopedLockableAttr>(RD))342S.Diag(AL.getLoc(),343diag::warn_thread_attribute_not_on_capability_member)344<< AL << MD->getParent();345} else {346S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)347<< AL;348}349}350351for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {352Expr *ArgExp = AL.getArgAsExpr(Idx);353354if (ArgExp->isTypeDependent()) {355// FIXME -- need to check this again on template instantiation356Args.push_back(ArgExp);357continue;358}359360if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {361if (StrLit->getLength() == 0 ||362(StrLit->isOrdinary() && StrLit->getString() == "*")) {363// Pass empty strings to the analyzer without warnings.364// Treat "*" as the universal lock.365Args.push_back(ArgExp);366continue;367}368369// We allow constant strings to be used as a placeholder for expressions370// that are not valid C++ syntax, but warn that they are ignored.371S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;372Args.push_back(ArgExp);373continue;374}375376QualType ArgTy = ArgExp->getType();377378// A pointer to member expression of the form &MyClass::mu is treated379// specially -- we need to look at the type of the member.380if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))381if (UOp->getOpcode() == UO_AddrOf)382if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))383if (DRE->getDecl()->isCXXInstanceMember())384ArgTy = DRE->getDecl()->getType();385386// First see if we can just cast to record type, or pointer to record type.387const RecordType *RT = getRecordType(ArgTy);388389// Now check if we index into a record type function param.390if(!RT && ParamIdxOk) {391const auto *FD = dyn_cast<FunctionDecl>(D);392const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);393if(FD && IL) {394unsigned int NumParams = FD->getNumParams();395llvm::APInt ArgValue = IL->getValue();396uint64_t ParamIdxFromOne = ArgValue.getZExtValue();397uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;398if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {399S.Diag(AL.getLoc(),400diag::err_attribute_argument_out_of_bounds_extra_info)401<< AL << Idx + 1 << NumParams;402continue;403}404ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();405}406}407408// If the type does not have a capability, see if the components of the409// expression have capabilities. This allows for writing C code where the410// capability may be on the type, and the expression is a capability411// boolean logic expression. Eg) requires_capability(A || B && !C)412if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))413S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)414<< AL << ArgTy;415416Args.push_back(ArgExp);417}418}419420//===----------------------------------------------------------------------===//421// Attribute Implementations422//===----------------------------------------------------------------------===//423424static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {425if (!threadSafetyCheckIsPointer(S, D, AL))426return;427428D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));429}430431static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,432Expr *&Arg) {433SmallVector<Expr *, 1> Args;434// check that all arguments are lockable objects435checkAttrArgsAreCapabilityObjs(S, D, AL, Args);436unsigned Size = Args.size();437if (Size != 1)438return false;439440Arg = Args[0];441442return true;443}444445static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {446Expr *Arg = nullptr;447if (!checkGuardedByAttrCommon(S, D, AL, Arg))448return;449450D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));451}452453static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {454Expr *Arg = nullptr;455if (!checkGuardedByAttrCommon(S, D, AL, Arg))456return;457458if (!threadSafetyCheckIsPointer(S, D, AL))459return;460461D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));462}463464static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,465SmallVectorImpl<Expr *> &Args) {466if (!AL.checkAtLeastNumArgs(S, 1))467return false;468469// Check that this attribute only applies to lockable types.470QualType QT = cast<ValueDecl>(D)->getType();471if (!QT->isDependentType() && !typeHasCapability(S, QT)) {472S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;473return false;474}475476// Check that all arguments are lockable objects.477checkAttrArgsAreCapabilityObjs(S, D, AL, Args);478if (Args.empty())479return false;480481return true;482}483484static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {485SmallVector<Expr *, 1> Args;486if (!checkAcquireOrderAttrCommon(S, D, AL, Args))487return;488489Expr **StartArg = &Args[0];490D->addAttr(::new (S.Context)491AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));492}493494static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {495SmallVector<Expr *, 1> Args;496if (!checkAcquireOrderAttrCommon(S, D, AL, Args))497return;498499Expr **StartArg = &Args[0];500D->addAttr(::new (S.Context)501AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));502}503504static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,505SmallVectorImpl<Expr *> &Args) {506// zero or more arguments ok507// check that all arguments are lockable objects508checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);509510return true;511}512513static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {514SmallVector<Expr *, 1> Args;515if (!checkLockFunAttrCommon(S, D, AL, Args))516return;517518unsigned Size = Args.size();519Expr **StartArg = Size == 0 ? nullptr : &Args[0];520D->addAttr(::new (S.Context)521AssertSharedLockAttr(S.Context, AL, StartArg, Size));522}523524static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,525const ParsedAttr &AL) {526SmallVector<Expr *, 1> Args;527if (!checkLockFunAttrCommon(S, D, AL, Args))528return;529530unsigned Size = Args.size();531Expr **StartArg = Size == 0 ? nullptr : &Args[0];532D->addAttr(::new (S.Context)533AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));534}535536/// Checks to be sure that the given parameter number is in bounds, and537/// is an integral type. Will emit appropriate diagnostics if this returns538/// false.539///540/// AttrArgNo is used to actually retrieve the argument, so it's base-0.541template <typename AttrInfo>542static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,543unsigned AttrArgNo) {544assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");545Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);546ParamIdx Idx;547if (!S.checkFunctionOrMethodParameterIndex(D, AI, AttrArgNo + 1, AttrArg,548Idx))549return false;550551QualType ParamTy = getFunctionOrMethodParamType(D, Idx.getASTIndex());552if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {553SourceLocation SrcLoc = AttrArg->getBeginLoc();554S.Diag(SrcLoc, diag::err_attribute_integers_only)555<< AI << getFunctionOrMethodParamRange(D, Idx.getASTIndex());556return false;557}558return true;559}560561static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {562if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))563return;564565assert(isFuncOrMethodForAttrSubject(D) && hasFunctionProto(D));566567QualType RetTy = getFunctionOrMethodResultType(D);568if (!RetTy->isPointerType()) {569S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;570return;571}572573const Expr *SizeExpr = AL.getArgAsExpr(0);574int SizeArgNoVal;575// Parameter indices are 1-indexed, hence Index=1576if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))577return;578if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/0))579return;580ParamIdx SizeArgNo(SizeArgNoVal, D);581582ParamIdx NumberArgNo;583if (AL.getNumArgs() == 2) {584const Expr *NumberExpr = AL.getArgAsExpr(1);585int Val;586// Parameter indices are 1-based, hence Index=2587if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))588return;589if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/1))590return;591NumberArgNo = ParamIdx(Val, D);592}593594D->addAttr(::new (S.Context)595AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));596}597598static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,599SmallVectorImpl<Expr *> &Args) {600if (!AL.checkAtLeastNumArgs(S, 1))601return false;602603if (!isIntOrBool(AL.getArgAsExpr(0))) {604S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)605<< AL << 1 << AANT_ArgumentIntOrBool;606return false;607}608609// check that all arguments are lockable objects610checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);611612return true;613}614615static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,616const ParsedAttr &AL) {617SmallVector<Expr*, 2> Args;618if (!checkTryLockFunAttrCommon(S, D, AL, Args))619return;620621D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(622S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));623}624625static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,626const ParsedAttr &AL) {627SmallVector<Expr*, 2> Args;628if (!checkTryLockFunAttrCommon(S, D, AL, Args))629return;630631D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(632S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));633}634635static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {636// check that the argument is lockable object637SmallVector<Expr*, 1> Args;638checkAttrArgsAreCapabilityObjs(S, D, AL, Args);639unsigned Size = Args.size();640if (Size == 0)641return;642643D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));644}645646static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {647if (!AL.checkAtLeastNumArgs(S, 1))648return;649650// check that all arguments are lockable objects651SmallVector<Expr*, 1> Args;652checkAttrArgsAreCapabilityObjs(S, D, AL, Args);653unsigned Size = Args.size();654if (Size == 0)655return;656Expr **StartArg = &Args[0];657658D->addAttr(::new (S.Context)659LocksExcludedAttr(S.Context, AL, StartArg, Size));660}661662static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,663Expr *&Cond, StringRef &Msg) {664Cond = AL.getArgAsExpr(0);665if (!Cond->isTypeDependent()) {666ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);667if (Converted.isInvalid())668return false;669Cond = Converted.get();670}671672if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))673return false;674675if (Msg.empty())676Msg = "<no message provided>";677678SmallVector<PartialDiagnosticAt, 8> Diags;679if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&680!Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),681Diags)) {682S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;683for (const PartialDiagnosticAt &PDiag : Diags)684S.Diag(PDiag.first, PDiag.second);685return false;686}687return true;688}689690static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {691S.Diag(AL.getLoc(), diag::ext_clang_enable_if);692693Expr *Cond;694StringRef Msg;695if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))696D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));697}698699static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {700StringRef NewUserDiagnostic;701if (!S.checkStringLiteralArgumentAttr(AL, 0, NewUserDiagnostic))702return;703if (ErrorAttr *EA = S.mergeErrorAttr(D, AL, NewUserDiagnostic))704D->addAttr(EA);705}706707static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,708const ParsedAttr &AL) {709const auto *PD = isa<CXXRecordDecl>(D)710? cast<DeclContext>(D)711: D->getDeclContext()->getRedeclContext();712if (const auto *RD = dyn_cast<CXXRecordDecl>(PD); RD && RD->isLocalClass()) {713S.Diag(AL.getLoc(),714diag::warn_attribute_exclude_from_explicit_instantiation_local_class)715<< AL << /*IsMember=*/!isa<CXXRecordDecl>(D);716return;717}718D->addAttr(::new (S.Context)719ExcludeFromExplicitInstantiationAttr(S.Context, AL));720}721722namespace {723/// Determines if a given Expr references any of the given function's724/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).725class ArgumentDependenceChecker726: public RecursiveASTVisitor<ArgumentDependenceChecker> {727#ifndef NDEBUG728const CXXRecordDecl *ClassType;729#endif730llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;731bool Result;732733public:734ArgumentDependenceChecker(const FunctionDecl *FD) {735#ifndef NDEBUG736if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))737ClassType = MD->getParent();738else739ClassType = nullptr;740#endif741Parms.insert(FD->param_begin(), FD->param_end());742}743744bool referencesArgs(Expr *E) {745Result = false;746TraverseStmt(E);747return Result;748}749750bool VisitCXXThisExpr(CXXThisExpr *E) {751assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&752"`this` doesn't refer to the enclosing class?");753Result = true;754return false;755}756757bool VisitDeclRefExpr(DeclRefExpr *DRE) {758if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))759if (Parms.count(PVD)) {760Result = true;761return false;762}763return true;764}765};766}767768static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D,769const ParsedAttr &AL) {770const auto *DeclFD = cast<FunctionDecl>(D);771772if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(DeclFD))773if (!MethodDecl->isStatic()) {774S.Diag(AL.getLoc(), diag::err_attribute_no_member_function) << AL;775return;776}777778auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {779SourceLocation Loc = [&]() {780auto Union = AL.getArg(Index - 1);781if (Union.is<Expr *>())782return Union.get<Expr *>()->getBeginLoc();783return Union.get<IdentifierLoc *>()->Loc;784}();785786S.Diag(Loc, diag::err_attribute_argument_n_type) << AL << Index << T;787};788789FunctionDecl *AttrFD = [&]() -> FunctionDecl * {790if (!AL.isArgExpr(0))791return nullptr;792auto *F = dyn_cast_if_present<DeclRefExpr>(AL.getArgAsExpr(0));793if (!F)794return nullptr;795return dyn_cast_if_present<FunctionDecl>(F->getFoundDecl());796}();797798if (!AttrFD || !AttrFD->getBuiltinID(true)) {799DiagnoseType(1, AANT_ArgumentBuiltinFunction);800return;801}802803if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {804S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments_for)805<< AL << AttrFD << AttrFD->getNumParams();806return;807}808809SmallVector<unsigned, 8> Indices;810811for (unsigned I = 1; I < AL.getNumArgs(); ++I) {812if (!AL.isArgExpr(I)) {813DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);814return;815}816817const Expr *IndexExpr = AL.getArgAsExpr(I);818uint32_t Index;819820if (!S.checkUInt32Argument(AL, IndexExpr, Index, I + 1, false))821return;822823if (Index > DeclFD->getNumParams()) {824S.Diag(AL.getLoc(), diag::err_attribute_bounds_for_function)825<< AL << Index << DeclFD << DeclFD->getNumParams();826return;827}828829QualType T1 = AttrFD->getParamDecl(I - 1)->getType();830QualType T2 = DeclFD->getParamDecl(Index - 1)->getType();831832if (T1.getCanonicalType().getUnqualifiedType() !=833T2.getCanonicalType().getUnqualifiedType()) {834S.Diag(IndexExpr->getBeginLoc(), diag::err_attribute_parameter_types)835<< AL << Index << DeclFD << T2 << I << AttrFD << T1;836return;837}838839Indices.push_back(Index - 1);840}841842D->addAttr(::new (S.Context) DiagnoseAsBuiltinAttr(843S.Context, AL, AttrFD, Indices.data(), Indices.size()));844}845846static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {847S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);848849Expr *Cond;850StringRef Msg;851if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))852return;853854StringRef DiagTypeStr;855if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))856return;857858DiagnoseIfAttr::DiagnosticType DiagType;859if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {860S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),861diag::err_diagnose_if_invalid_diagnostic_type);862return;863}864865bool ArgDependent = false;866if (const auto *FD = dyn_cast<FunctionDecl>(D))867ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);868D->addAttr(::new (S.Context) DiagnoseIfAttr(869S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));870}871872static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {873static constexpr const StringRef kWildcard = "*";874875llvm::SmallVector<StringRef, 16> Names;876bool HasWildcard = false;877878const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {879if (Name == kWildcard)880HasWildcard = true;881Names.push_back(Name);882};883884// Add previously defined attributes.885if (const auto *NBA = D->getAttr<NoBuiltinAttr>())886for (StringRef BuiltinName : NBA->builtinNames())887AddBuiltinName(BuiltinName);888889// Add current attributes.890if (AL.getNumArgs() == 0)891AddBuiltinName(kWildcard);892else893for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {894StringRef BuiltinName;895SourceLocation LiteralLoc;896if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))897return;898899if (Builtin::Context::isBuiltinFunc(BuiltinName))900AddBuiltinName(BuiltinName);901else902S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)903<< BuiltinName << AL;904}905906// Repeating the same attribute is fine.907llvm::sort(Names);908Names.erase(std::unique(Names.begin(), Names.end()), Names.end());909910// Empty no_builtin must be on its own.911if (HasWildcard && Names.size() > 1)912S.Diag(D->getLocation(),913diag::err_attribute_no_builtin_wildcard_or_builtin_name)914<< AL;915916if (D->hasAttr<NoBuiltinAttr>())917D->dropAttr<NoBuiltinAttr>();918D->addAttr(::new (S.Context)919NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));920}921922static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {923if (D->hasAttr<PassObjectSizeAttr>()) {924S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;925return;926}927928Expr *E = AL.getArgAsExpr(0);929uint32_t Type;930if (!S.checkUInt32Argument(AL, E, Type, /*Idx=*/1))931return;932933// pass_object_size's argument is passed in as the second argument of934// __builtin_object_size. So, it has the same constraints as that second935// argument; namely, it must be in the range [0, 3].936if (Type > 3) {937S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)938<< AL << 0 << 3 << E->getSourceRange();939return;940}941942// pass_object_size is only supported on constant pointer parameters; as a943// kindness to users, we allow the parameter to be non-const for declarations.944// At this point, we have no clue if `D` belongs to a function declaration or945// definition, so we defer the constness check until later.946if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {947S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;948return;949}950951D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));952}953954static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {955ConsumableAttr::ConsumedState DefaultState;956957if (AL.isArgIdent(0)) {958IdentifierLoc *IL = AL.getArgAsIdent(0);959if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),960DefaultState)) {961S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL962<< IL->Ident;963return;964}965} else {966S.Diag(AL.getLoc(), diag::err_attribute_argument_type)967<< AL << AANT_ArgumentIdentifier;968return;969}970971D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));972}973974static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,975const ParsedAttr &AL) {976QualType ThisType = MD->getFunctionObjectParameterType();977978if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {979if (!RD->hasAttr<ConsumableAttr>()) {980S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;981982return false;983}984}985986return true;987}988989static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {990if (!AL.checkAtLeastNumArgs(S, 1))991return;992993if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))994return;995996SmallVector<CallableWhenAttr::ConsumedState, 3> States;997for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {998CallableWhenAttr::ConsumedState CallableState;9991000StringRef StateString;1001SourceLocation Loc;1002if (AL.isArgIdent(ArgIndex)) {1003IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);1004StateString = Ident->Ident->getName();1005Loc = Ident->Loc;1006} else {1007if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))1008return;1009}10101011if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,1012CallableState)) {1013S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;1014return;1015}10161017States.push_back(CallableState);1018}10191020D->addAttr(::new (S.Context)1021CallableWhenAttr(S.Context, AL, States.data(), States.size()));1022}10231024static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1025ParamTypestateAttr::ConsumedState ParamState;10261027if (AL.isArgIdent(0)) {1028IdentifierLoc *Ident = AL.getArgAsIdent(0);1029StringRef StateString = Ident->Ident->getName();10301031if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,1032ParamState)) {1033S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)1034<< AL << StateString;1035return;1036}1037} else {1038S.Diag(AL.getLoc(), diag::err_attribute_argument_type)1039<< AL << AANT_ArgumentIdentifier;1040return;1041}10421043// FIXME: This check is currently being done in the analysis. It can be1044// enabled here only after the parser propagates attributes at1045// template specialization definition, not declaration.1046//QualType ReturnType = cast<ParmVarDecl>(D)->getType();1047//const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();1048//1049//if (!RD || !RD->hasAttr<ConsumableAttr>()) {1050// S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<1051// ReturnType.getAsString();1052// return;1053//}10541055D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));1056}10571058static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1059ReturnTypestateAttr::ConsumedState ReturnState;10601061if (AL.isArgIdent(0)) {1062IdentifierLoc *IL = AL.getArgAsIdent(0);1063if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),1064ReturnState)) {1065S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL1066<< IL->Ident;1067return;1068}1069} else {1070S.Diag(AL.getLoc(), diag::err_attribute_argument_type)1071<< AL << AANT_ArgumentIdentifier;1072return;1073}10741075// FIXME: This check is currently being done in the analysis. It can be1076// enabled here only after the parser propagates attributes at1077// template specialization definition, not declaration.1078// QualType ReturnType;1079//1080// if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {1081// ReturnType = Param->getType();1082//1083//} else if (const CXXConstructorDecl *Constructor =1084// dyn_cast<CXXConstructorDecl>(D)) {1085// ReturnType = Constructor->getFunctionObjectParameterType();1086//1087//} else {1088//1089// ReturnType = cast<FunctionDecl>(D)->getCallResultType();1090//}1091//1092// const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();1093//1094// if (!RD || !RD->hasAttr<ConsumableAttr>()) {1095// S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<1096// ReturnType.getAsString();1097// return;1098//}10991100D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));1101}11021103static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1104if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))1105return;11061107SetTypestateAttr::ConsumedState NewState;1108if (AL.isArgIdent(0)) {1109IdentifierLoc *Ident = AL.getArgAsIdent(0);1110StringRef Param = Ident->Ident->getName();1111if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {1112S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL1113<< Param;1114return;1115}1116} else {1117S.Diag(AL.getLoc(), diag::err_attribute_argument_type)1118<< AL << AANT_ArgumentIdentifier;1119return;1120}11211122D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));1123}11241125static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1126if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))1127return;11281129TestTypestateAttr::ConsumedState TestState;1130if (AL.isArgIdent(0)) {1131IdentifierLoc *Ident = AL.getArgAsIdent(0);1132StringRef Param = Ident->Ident->getName();1133if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {1134S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL1135<< Param;1136return;1137}1138} else {1139S.Diag(AL.getLoc(), diag::err_attribute_argument_type)1140<< AL << AANT_ArgumentIdentifier;1141return;1142}11431144D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));1145}11461147static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1148// Remember this typedef decl, we will need it later for diagnostics.1149S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));1150}11511152static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1153if (auto *TD = dyn_cast<TagDecl>(D))1154TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));1155else if (auto *FD = dyn_cast<FieldDecl>(D)) {1156bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&1157!FD->getType()->isIncompleteType() &&1158FD->isBitField() &&1159S.Context.getTypeAlign(FD->getType()) <= 8);11601161if (S.getASTContext().getTargetInfo().getTriple().isPS()) {1162if (BitfieldByteAligned)1163// The PS4/PS5 targets need to maintain ABI backwards compatibility.1164S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)1165<< AL << FD->getType();1166else1167FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));1168} else {1169// Report warning about changed offset in the newer compiler versions.1170if (BitfieldByteAligned)1171S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);11721173FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));1174}11751176} else1177S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;1178}11791180static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {1181auto *RD = cast<CXXRecordDecl>(D);1182ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();1183assert(CTD && "attribute does not appertain to this declaration");11841185ParsedType PT = AL.getTypeArg();1186TypeSourceInfo *TSI = nullptr;1187QualType T = S.GetTypeFromParser(PT, &TSI);1188if (!TSI)1189TSI = S.Context.getTrivialTypeSourceInfo(T, AL.getLoc());11901191if (!T.hasQualifiers() && T->isTypedefNameType()) {1192// Find the template name, if this type names a template specialization.1193const TemplateDecl *Template = nullptr;1194if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(1195T->getAsCXXRecordDecl())) {1196Template = CTSD->getSpecializedTemplate();1197} else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {1198while (TST && TST->isTypeAlias())1199TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();1200if (TST)1201Template = TST->getTemplateName().getAsTemplateDecl();1202}12031204if (Template && declaresSameEntity(Template, CTD)) {1205D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));1206return;1207}1208}12091210S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)1211<< T << CTD;1212if (const auto *TT = T->getAs<TypedefType>())1213S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)1214<< TT->getDecl();1215}12161217bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {1218if (RefOkay) {1219if (T->isReferenceType())1220return true;1221} else {1222T = T.getNonReferenceType();1223}12241225// The nonnull attribute, and other similar attributes, can be applied to a1226// transparent union that contains a pointer type.1227if (const RecordType *UT = T->getAsUnionType()) {1228if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {1229RecordDecl *UD = UT->getDecl();1230for (const auto *I : UD->fields()) {1231QualType QT = I->getType();1232if (QT->isAnyPointerType() || QT->isBlockPointerType())1233return true;1234}1235}1236}12371238return T->isAnyPointerType() || T->isBlockPointerType();1239}12401241static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,1242SourceRange AttrParmRange,1243SourceRange TypeRange,1244bool isReturnValue = false) {1245if (!S.isValidPointerAttrType(T)) {1246if (isReturnValue)1247S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)1248<< AL << AttrParmRange << TypeRange;1249else1250S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)1251<< AL << AttrParmRange << TypeRange << 0;1252return false;1253}1254return true;1255}12561257static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1258SmallVector<ParamIdx, 8> NonNullArgs;1259for (unsigned I = 0; I < AL.getNumArgs(); ++I) {1260Expr *Ex = AL.getArgAsExpr(I);1261ParamIdx Idx;1262if (!S.checkFunctionOrMethodParameterIndex(D, AL, I + 1, Ex, Idx))1263return;12641265// Is the function argument a pointer type?1266if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&1267!attrNonNullArgCheck(1268S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL,1269Ex->getSourceRange(),1270getFunctionOrMethodParamRange(D, Idx.getASTIndex())))1271continue;12721273NonNullArgs.push_back(Idx);1274}12751276// If no arguments were specified to __attribute__((nonnull)) then all pointer1277// arguments have a nonnull attribute; warn if there aren't any. Skip this1278// check if the attribute came from a macro expansion or a template1279// instantiation.1280if (NonNullArgs.empty() && AL.getLoc().isFileID() &&1281!S.inTemplateInstantiation()) {1282bool AnyPointers = isFunctionOrMethodVariadic(D);1283for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);1284I != E && !AnyPointers; ++I) {1285QualType T = getFunctionOrMethodParamType(D, I);1286if (T->isDependentType() || S.isValidPointerAttrType(T))1287AnyPointers = true;1288}12891290if (!AnyPointers)1291S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);1292}12931294ParamIdx *Start = NonNullArgs.data();1295unsigned Size = NonNullArgs.size();1296llvm::array_pod_sort(Start, Start + Size);1297D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));1298}12991300static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,1301const ParsedAttr &AL) {1302if (AL.getNumArgs() > 0) {1303if (D->getFunctionType()) {1304handleNonNullAttr(S, D, AL);1305} else {1306S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)1307<< D->getSourceRange();1308}1309return;1310}13111312// Is the argument a pointer type?1313if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),1314D->getSourceRange()))1315return;13161317D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));1318}13191320static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1321QualType ResultType = getFunctionOrMethodResultType(D);1322SourceRange SR = getFunctionOrMethodResultSourceRange(D);1323if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,1324/* isReturnValue */ true))1325return;13261327D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));1328}13291330static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1331if (D->isInvalidDecl())1332return;13331334// noescape only applies to pointer types.1335QualType T = cast<ParmVarDecl>(D)->getType();1336if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {1337S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)1338<< AL << AL.getRange() << 0;1339return;1340}13411342D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));1343}13441345static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1346Expr *E = AL.getArgAsExpr(0),1347*OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr;1348S.AddAssumeAlignedAttr(D, AL, E, OE);1349}13501351static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1352S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));1353}13541355void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,1356Expr *OE) {1357QualType ResultType = getFunctionOrMethodResultType(D);1358SourceRange SR = getFunctionOrMethodResultSourceRange(D);13591360AssumeAlignedAttr TmpAttr(Context, CI, E, OE);1361SourceLocation AttrLoc = TmpAttr.getLocation();13621363if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {1364Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)1365<< &TmpAttr << TmpAttr.getRange() << SR;1366return;1367}13681369if (!E->isValueDependent()) {1370std::optional<llvm::APSInt> I = llvm::APSInt(64);1371if (!(I = E->getIntegerConstantExpr(Context))) {1372if (OE)1373Diag(AttrLoc, diag::err_attribute_argument_n_type)1374<< &TmpAttr << 1 << AANT_ArgumentIntegerConstant1375<< E->getSourceRange();1376else1377Diag(AttrLoc, diag::err_attribute_argument_type)1378<< &TmpAttr << AANT_ArgumentIntegerConstant1379<< E->getSourceRange();1380return;1381}13821383if (!I->isPowerOf2()) {1384Diag(AttrLoc, diag::err_alignment_not_power_of_two)1385<< E->getSourceRange();1386return;1387}13881389if (*I > Sema::MaximumAlignment)1390Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)1391<< CI.getRange() << Sema::MaximumAlignment;1392}13931394if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Context)) {1395Diag(AttrLoc, diag::err_attribute_argument_n_type)1396<< &TmpAttr << 2 << AANT_ArgumentIntegerConstant1397<< OE->getSourceRange();1398return;1399}14001401D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));1402}14031404void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,1405Expr *ParamExpr) {1406QualType ResultType = getFunctionOrMethodResultType(D);14071408AllocAlignAttr TmpAttr(Context, CI, ParamIdx());1409SourceLocation AttrLoc = CI.getLoc();14101411if (!ResultType->isDependentType() &&1412!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {1413Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)1414<< &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);1415return;1416}14171418ParamIdx Idx;1419const auto *FuncDecl = cast<FunctionDecl>(D);1420if (!checkFunctionOrMethodParameterIndex(FuncDecl, TmpAttr,1421/*AttrArgNum=*/1, ParamExpr, Idx))1422return;14231424QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());1425if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&1426!Ty->isAlignValT()) {1427Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)1428<< &TmpAttr1429<< FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();1430return;1431}14321433D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));1434}14351436/// Normalize the attribute, __foo__ becomes foo.1437/// Returns true if normalization was applied.1438static bool normalizeName(StringRef &AttrName) {1439if (AttrName.size() > 4 && AttrName.starts_with("__") &&1440AttrName.ends_with("__")) {1441AttrName = AttrName.drop_front(2).drop_back(2);1442return true;1443}1444return false;1445}14461447static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1448// This attribute must be applied to a function declaration. The first1449// argument to the attribute must be an identifier, the name of the resource,1450// for example: malloc. The following arguments must be argument indexes, the1451// arguments must be of integer type for Returns, otherwise of pointer type.1452// The difference between Holds and Takes is that a pointer may still be used1453// after being held. free() should be __attribute((ownership_takes)), whereas1454// a list append function may well be __attribute((ownership_holds)).14551456if (!AL.isArgIdent(0)) {1457S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)1458<< AL << 1 << AANT_ArgumentIdentifier;1459return;1460}14611462// Figure out our Kind.1463OwnershipAttr::OwnershipKind K =1464OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();14651466// Check arguments.1467switch (K) {1468case OwnershipAttr::Takes:1469case OwnershipAttr::Holds:1470if (AL.getNumArgs() < 2) {1471S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;1472return;1473}1474break;1475case OwnershipAttr::Returns:1476if (AL.getNumArgs() > 2) {1477S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;1478return;1479}1480break;1481}14821483IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;14841485StringRef ModuleName = Module->getName();1486if (normalizeName(ModuleName)) {1487Module = &S.PP.getIdentifierTable().get(ModuleName);1488}14891490SmallVector<ParamIdx, 8> OwnershipArgs;1491for (unsigned i = 1; i < AL.getNumArgs(); ++i) {1492Expr *Ex = AL.getArgAsExpr(i);1493ParamIdx Idx;1494if (!S.checkFunctionOrMethodParameterIndex(D, AL, i, Ex, Idx))1495return;14961497// Is the function argument a pointer type?1498QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex());1499int Err = -1; // No error1500switch (K) {1501case OwnershipAttr::Takes:1502case OwnershipAttr::Holds:1503if (!T->isAnyPointerType() && !T->isBlockPointerType())1504Err = 0;1505break;1506case OwnershipAttr::Returns:1507if (!T->isIntegerType())1508Err = 1;1509break;1510}1511if (-1 != Err) {1512S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err1513<< Ex->getSourceRange();1514return;1515}15161517// Check we don't have a conflict with another ownership attribute.1518for (const auto *I : D->specific_attrs<OwnershipAttr>()) {1519// Cannot have two ownership attributes of different kinds for the same1520// index.1521if (I->getOwnKind() != K && llvm::is_contained(I->args(), Idx)) {1522S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)1523<< AL << I1524<< (AL.isRegularKeywordAttribute() ||1525I->isRegularKeywordAttribute());1526return;1527} else if (K == OwnershipAttr::Returns &&1528I->getOwnKind() == OwnershipAttr::Returns) {1529// A returns attribute conflicts with any other returns attribute using1530// a different index.1531if (!llvm::is_contained(I->args(), Idx)) {1532S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)1533<< I->args_begin()->getSourceIndex();1534if (I->args_size())1535S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)1536<< Idx.getSourceIndex() << Ex->getSourceRange();1537return;1538}1539}1540}1541OwnershipArgs.push_back(Idx);1542}15431544ParamIdx *Start = OwnershipArgs.data();1545unsigned Size = OwnershipArgs.size();1546llvm::array_pod_sort(Start, Start + Size);1547D->addAttr(::new (S.Context)1548OwnershipAttr(S.Context, AL, Module, Start, Size));1549}15501551static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1552// Check the attribute arguments.1553if (AL.getNumArgs() > 1) {1554S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;1555return;1556}15571558// gcc rejects1559// class c {1560// static int a __attribute__((weakref ("v2")));1561// static int b() __attribute__((weakref ("f3")));1562// };1563// and ignores the attributes of1564// void f(void) {1565// static int a __attribute__((weakref ("v2")));1566// }1567// we reject them1568const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();1569if (!Ctx->isFileContext()) {1570S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)1571<< cast<NamedDecl>(D);1572return;1573}15741575// The GCC manual says1576//1577// At present, a declaration to which `weakref' is attached can only1578// be `static'.1579//1580// It also says1581//1582// Without a TARGET,1583// given as an argument to `weakref' or to `alias', `weakref' is1584// equivalent to `weak'.1585//1586// gcc 4.4.1 will accept1587// int a7 __attribute__((weakref));1588// as1589// int a7 __attribute__((weak));1590// This looks like a bug in gcc. We reject that for now. We should revisit1591// it if this behaviour is actually used.15921593// GCC rejects1594// static ((alias ("y"), weakref)).1595// Should we? How to check that weakref is before or after alias?15961597// FIXME: it would be good for us to keep the WeakRefAttr as-written instead1598// of transforming it into an AliasAttr. The WeakRefAttr never uses the1599// StringRef parameter it was given anyway.1600StringRef Str;1601if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))1602// GCC will accept anything as the argument of weakref. Should we1603// check for an existing decl?1604D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));16051606D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));1607}16081609// Mark alias/ifunc target as used. Due to name mangling, we look up the1610// demangled name ignoring parameters (not supported by microsoftDemangle1611// https://github.com/llvm/llvm-project/issues/88825). This should handle the1612// majority of use cases while leaving namespace scope names unmarked.1613static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,1614StringRef Str) {1615std::unique_ptr<char, llvm::FreeDeleter> Demangled;1616if (S.getASTContext().getCXXABIKind() != TargetCXXABI::Microsoft)1617Demangled.reset(llvm::itaniumDemangle(Str, /*ParseParams=*/false));1618std::unique_ptr<MangleContext> MC(S.Context.createMangleContext());1619SmallString<256> Name;16201621const DeclarationNameInfo Target(1622&S.Context.Idents.get(Demangled ? Demangled.get() : Str), AL.getLoc());1623LookupResult LR(S, Target, Sema::LookupOrdinaryName);1624if (S.LookupName(LR, S.TUScope)) {1625for (NamedDecl *ND : LR) {1626if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND))1627continue;1628if (MC->shouldMangleDeclName(ND)) {1629llvm::raw_svector_ostream Out(Name);1630Name.clear();1631MC->mangleName(GlobalDecl(ND), Out);1632} else {1633Name = ND->getIdentifier()->getName();1634}1635if (Name == Str)1636ND->markUsed(S.Context);1637}1638}1639}16401641static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1642StringRef Str;1643if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))1644return;16451646// Aliases should be on declarations, not definitions.1647const auto *FD = cast<FunctionDecl>(D);1648if (FD->isThisDeclarationADefinition()) {1649S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;1650return;1651}16521653markUsedForAliasOrIfunc(S, D, AL, Str);1654D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));1655}16561657static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1658StringRef Str;1659if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))1660return;16611662if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {1663S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);1664return;1665}16661667if (S.Context.getTargetInfo().getTriple().isNVPTX()) {1668CudaVersion Version =1669ToCudaVersion(S.Context.getTargetInfo().getSDKVersion());1670if (Version != CudaVersion::UNKNOWN && Version < CudaVersion::CUDA_100)1671S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);1672}16731674// Aliases should be on declarations, not definitions.1675if (const auto *FD = dyn_cast<FunctionDecl>(D)) {1676if (FD->isThisDeclarationADefinition()) {1677S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;1678return;1679}1680} else {1681const auto *VD = cast<VarDecl>(D);1682if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {1683S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;1684return;1685}1686}16871688markUsedForAliasOrIfunc(S, D, AL, Str);1689D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));1690}16911692static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1693StringRef Model;1694SourceLocation LiteralLoc;1695// Check that it is a string.1696if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))1697return;16981699// Check that the value.1700if (Model != "global-dynamic" && Model != "local-dynamic"1701&& Model != "initial-exec" && Model != "local-exec") {1702S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);1703return;1704}17051706D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));1707}17081709static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1710QualType ResultType = getFunctionOrMethodResultType(D);1711if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {1712D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));1713return;1714}17151716S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)1717<< AL << getFunctionOrMethodResultSourceRange(D);1718}17191720static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1721// Ensure we don't combine these with themselves, since that causes some1722// confusing behavior.1723if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {1724if (checkAttrMutualExclusion<CPUSpecificAttr>(S, D, AL))1725return;17261727if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {1728S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;1729S.Diag(Other->getLocation(), diag::note_conflicting_attribute);1730return;1731}1732} else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {1733if (checkAttrMutualExclusion<CPUDispatchAttr>(S, D, AL))1734return;17351736if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {1737S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;1738S.Diag(Other->getLocation(), diag::note_conflicting_attribute);1739return;1740}1741}17421743FunctionDecl *FD = cast<FunctionDecl>(D);17441745if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {1746if (MD->getParent()->isLambda()) {1747S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;1748return;1749}1750}17511752if (!AL.checkAtLeastNumArgs(S, 1))1753return;17541755SmallVector<IdentifierInfo *, 8> CPUs;1756for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {1757if (!AL.isArgIdent(ArgNo)) {1758S.Diag(AL.getLoc(), diag::err_attribute_argument_type)1759<< AL << AANT_ArgumentIdentifier;1760return;1761}17621763IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);1764StringRef CPUName = CPUArg->Ident->getName().trim();17651766if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName)) {1767S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)1768<< CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);1769return;1770}17711772const TargetInfo &Target = S.Context.getTargetInfo();1773if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {1774return Target.CPUSpecificManglingCharacter(CPUName) ==1775Target.CPUSpecificManglingCharacter(Cur->getName());1776})) {1777S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);1778return;1779}1780CPUs.push_back(CPUArg->Ident);1781}17821783FD->setIsMultiVersion(true);1784if (AL.getKind() == ParsedAttr::AT_CPUSpecific)1785D->addAttr(::new (S.Context)1786CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));1787else1788D->addAttr(::new (S.Context)1789CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));1790}17911792static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1793if (S.LangOpts.CPlusPlus) {1794S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)1795<< AL << AttributeLangSupport::Cpp;1796return;1797}17981799D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));1800}18011802static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1803if (AL.isDeclspecAttribute()) {1804const auto &Triple = S.getASTContext().getTargetInfo().getTriple();1805const auto &Arch = Triple.getArch();1806if (Arch != llvm::Triple::x86 &&1807(Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {1808S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)1809<< AL << Triple.getArchName();1810return;1811}18121813// This form is not allowed to be written on a member function (static or1814// nonstatic) when in Microsoft compatibility mode.1815if (S.getLangOpts().MSVCCompat && isa<CXXMethodDecl>(D)) {1816S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)1817<< AL << AL.isRegularKeywordAttribute() << "non-member functions";1818return;1819}1820}18211822D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));1823}18241825static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {1826if (hasDeclarator(D)) return;18271828if (!isa<ObjCMethodDecl>(D)) {1829S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)1830<< Attrs << Attrs.isRegularKeywordAttribute()1831<< ExpectedFunctionOrMethod;1832return;1833}18341835D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));1836}18371838static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {1839// The [[_Noreturn]] spelling is deprecated in C23, so if that was used,1840// issue an appropriate diagnostic. However, don't issue a diagnostic if the1841// attribute name comes from a macro expansion. We don't want to punish users1842// who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'1843// is defined as a macro which expands to '_Noreturn').1844if (!S.getLangOpts().CPlusPlus &&1845A.getSemanticSpelling() == CXX11NoReturnAttr::C23_Noreturn &&1846!(A.getLoc().isMacroID() &&1847S.getSourceManager().isInSystemMacro(A.getLoc())))1848S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();18491850D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));1851}18521853static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {1854if (!S.getLangOpts().CFProtectionBranch)1855S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);1856else1857handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);1858}18591860bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {1861if (!Attrs.checkExactlyNumArgs(*this, 0)) {1862Attrs.setInvalid();1863return true;1864}18651866return false;1867}18681869bool Sema::CheckAttrTarget(const ParsedAttr &AL) {1870// Check whether the attribute is valid on the current target.1871if (!AL.existsInTarget(Context.getTargetInfo())) {1872Diag(AL.getLoc(), AL.isRegularKeywordAttribute()1873? diag::err_keyword_not_supported_on_target1874: diag::warn_unknown_attribute_ignored)1875<< AL << AL.getRange();1876AL.setInvalid();1877return true;1878}18791880return false;1881}18821883static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {18841885// The checking path for 'noreturn' and 'analyzer_noreturn' are different1886// because 'analyzer_noreturn' does not impact the type.1887if (!isFunctionOrMethodOrBlockForAttrSubject(D)) {1888ValueDecl *VD = dyn_cast<ValueDecl>(D);1889if (!VD || (!VD->getType()->isBlockPointerType() &&1890!VD->getType()->isFunctionPointerType())) {1891S.Diag(AL.getLoc(), AL.isStandardAttributeSyntax()1892? diag::err_attribute_wrong_decl_type1893: diag::warn_attribute_wrong_decl_type)1894<< AL << AL.isRegularKeywordAttribute()1895<< ExpectedFunctionMethodOrBlock;1896return;1897}1898}18991900D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));1901}19021903// PS3 PPU-specific.1904static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1905/*1906Returning a Vector Class in Registers19071908According to the PPU ABI specifications, a class with a single member of1909vector type is returned in memory when used as the return value of a1910function.1911This results in inefficient code when implementing vector classes. To return1912the value in a single vector register, add the vecreturn attribute to the1913class definition. This attribute is also applicable to struct types.19141915Example:19161917struct Vector1918{1919__vector float xyzw;1920} __attribute__((vecreturn));19211922Vector Add(Vector lhs, Vector rhs)1923{1924Vector result;1925result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);1926return result; // This will be returned in a register1927}1928*/1929if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {1930S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;1931return;1932}19331934const auto *R = cast<RecordDecl>(D);1935int count = 0;19361937if (!isa<CXXRecordDecl>(R)) {1938S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);1939return;1940}19411942if (!cast<CXXRecordDecl>(R)->isPOD()) {1943S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);1944return;1945}19461947for (const auto *I : R->fields()) {1948if ((count == 1) || !I->getType()->isVectorType()) {1949S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);1950return;1951}1952count++;1953}19541955D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));1956}19571958static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,1959const ParsedAttr &AL) {1960if (isa<ParmVarDecl>(D)) {1961// [[carries_dependency]] can only be applied to a parameter if it is a1962// parameter of a function declaration or lambda.1963if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {1964S.Diag(AL.getLoc(),1965diag::err_carries_dependency_param_not_function_decl);1966return;1967}1968}19691970D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));1971}19721973static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1974bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();19751976// If this is spelled as the standard C++17 attribute, but not in C++17, warn1977// about using it as an extension.1978if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)1979S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;19801981D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));1982}19831984static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1985uint32_t priority = ConstructorAttr::DefaultPriority;1986if (S.getLangOpts().HLSL && AL.getNumArgs()) {1987S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);1988return;1989}1990if (AL.getNumArgs() &&1991!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority))1992return;19931994D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));1995}19961997static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {1998uint32_t priority = DestructorAttr::DefaultPriority;1999if (AL.getNumArgs() &&2000!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority))2001return;20022003D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));2004}20052006template <typename AttrTy>2007static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {2008// Handle the case where the attribute has a text message.2009StringRef Str;2010if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))2011return;20122013D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));2014}20152016static bool checkAvailabilityAttr(Sema &S, SourceRange Range,2017IdentifierInfo *Platform,2018VersionTuple Introduced,2019VersionTuple Deprecated,2020VersionTuple Obsoleted) {2021StringRef PlatformName2022= AvailabilityAttr::getPrettyPlatformName(Platform->getName());2023if (PlatformName.empty())2024PlatformName = Platform->getName();20252026// Ensure that Introduced <= Deprecated <= Obsoleted (although not all2027// of these steps are needed).2028if (!Introduced.empty() && !Deprecated.empty() &&2029!(Introduced <= Deprecated)) {2030S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)2031<< 1 << PlatformName << Deprecated.getAsString()2032<< 0 << Introduced.getAsString();2033return true;2034}20352036if (!Introduced.empty() && !Obsoleted.empty() &&2037!(Introduced <= Obsoleted)) {2038S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)2039<< 2 << PlatformName << Obsoleted.getAsString()2040<< 0 << Introduced.getAsString();2041return true;2042}20432044if (!Deprecated.empty() && !Obsoleted.empty() &&2045!(Deprecated <= Obsoleted)) {2046S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)2047<< 2 << PlatformName << Obsoleted.getAsString()2048<< 1 << Deprecated.getAsString();2049return true;2050}20512052return false;2053}20542055/// Check whether the two versions match.2056///2057/// If either version tuple is empty, then they are assumed to match. If2058/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.2059static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,2060bool BeforeIsOkay) {2061if (X.empty() || Y.empty())2062return true;20632064if (X == Y)2065return true;20662067if (BeforeIsOkay && X < Y)2068return true;20692070return false;2071}20722073AvailabilityAttr *Sema::mergeAvailabilityAttr(2074NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,2075bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,2076VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,2077bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,2078int Priority, IdentifierInfo *Environment) {2079VersionTuple MergedIntroduced = Introduced;2080VersionTuple MergedDeprecated = Deprecated;2081VersionTuple MergedObsoleted = Obsoleted;2082bool FoundAny = false;2083bool OverrideOrImpl = false;2084switch (AMK) {2085case AMK_None:2086case AMK_Redeclaration:2087OverrideOrImpl = false;2088break;20892090case AMK_Override:2091case AMK_ProtocolImplementation:2092case AMK_OptionalProtocolImplementation:2093OverrideOrImpl = true;2094break;2095}20962097if (D->hasAttrs()) {2098AttrVec &Attrs = D->getAttrs();2099for (unsigned i = 0, e = Attrs.size(); i != e;) {2100const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);2101if (!OldAA) {2102++i;2103continue;2104}21052106IdentifierInfo *OldPlatform = OldAA->getPlatform();2107if (OldPlatform != Platform) {2108++i;2109continue;2110}21112112IdentifierInfo *OldEnvironment = OldAA->getEnvironment();2113if (OldEnvironment != Environment) {2114++i;2115continue;2116}21172118// If there is an existing availability attribute for this platform that2119// has a lower priority use the existing one and discard the new2120// attribute.2121if (OldAA->getPriority() < Priority)2122return nullptr;21232124// If there is an existing attribute for this platform that has a higher2125// priority than the new attribute then erase the old one and continue2126// processing the attributes.2127if (OldAA->getPriority() > Priority) {2128Attrs.erase(Attrs.begin() + i);2129--e;2130continue;2131}21322133FoundAny = true;2134VersionTuple OldIntroduced = OldAA->getIntroduced();2135VersionTuple OldDeprecated = OldAA->getDeprecated();2136VersionTuple OldObsoleted = OldAA->getObsoleted();2137bool OldIsUnavailable = OldAA->getUnavailable();21382139if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||2140!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||2141!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||2142!(OldIsUnavailable == IsUnavailable ||2143(OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {2144if (OverrideOrImpl) {2145int Which = -1;2146VersionTuple FirstVersion;2147VersionTuple SecondVersion;2148if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {2149Which = 0;2150FirstVersion = OldIntroduced;2151SecondVersion = Introduced;2152} else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {2153Which = 1;2154FirstVersion = Deprecated;2155SecondVersion = OldDeprecated;2156} else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {2157Which = 2;2158FirstVersion = Obsoleted;2159SecondVersion = OldObsoleted;2160}21612162if (Which == -1) {2163Diag(OldAA->getLocation(),2164diag::warn_mismatched_availability_override_unavail)2165<< AvailabilityAttr::getPrettyPlatformName(Platform->getName())2166<< (AMK == AMK_Override);2167} else if (Which != 1 && AMK == AMK_OptionalProtocolImplementation) {2168// Allow different 'introduced' / 'obsoleted' availability versions2169// on a method that implements an optional protocol requirement. It2170// makes less sense to allow this for 'deprecated' as the user can't2171// see if the method is 'deprecated' as 'respondsToSelector' will2172// still return true when the method is deprecated.2173++i;2174continue;2175} else {2176Diag(OldAA->getLocation(),2177diag::warn_mismatched_availability_override)2178<< Which2179<< AvailabilityAttr::getPrettyPlatformName(Platform->getName())2180<< FirstVersion.getAsString() << SecondVersion.getAsString()2181<< (AMK == AMK_Override);2182}2183if (AMK == AMK_Override)2184Diag(CI.getLoc(), diag::note_overridden_method);2185else2186Diag(CI.getLoc(), diag::note_protocol_method);2187} else {2188Diag(OldAA->getLocation(), diag::warn_mismatched_availability);2189Diag(CI.getLoc(), diag::note_previous_attribute);2190}21912192Attrs.erase(Attrs.begin() + i);2193--e;2194continue;2195}21962197VersionTuple MergedIntroduced2 = MergedIntroduced;2198VersionTuple MergedDeprecated2 = MergedDeprecated;2199VersionTuple MergedObsoleted2 = MergedObsoleted;22002201if (MergedIntroduced2.empty())2202MergedIntroduced2 = OldIntroduced;2203if (MergedDeprecated2.empty())2204MergedDeprecated2 = OldDeprecated;2205if (MergedObsoleted2.empty())2206MergedObsoleted2 = OldObsoleted;22072208if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,2209MergedIntroduced2, MergedDeprecated2,2210MergedObsoleted2)) {2211Attrs.erase(Attrs.begin() + i);2212--e;2213continue;2214}22152216MergedIntroduced = MergedIntroduced2;2217MergedDeprecated = MergedDeprecated2;2218MergedObsoleted = MergedObsoleted2;2219++i;2220}2221}22222223if (FoundAny &&2224MergedIntroduced == Introduced &&2225MergedDeprecated == Deprecated &&2226MergedObsoleted == Obsoleted)2227return nullptr;22282229// Only create a new attribute if !OverrideOrImpl, but we want to do2230// the checking.2231if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,2232MergedDeprecated, MergedObsoleted) &&2233!OverrideOrImpl) {2234auto *Avail = ::new (Context) AvailabilityAttr(2235Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,2236Message, IsStrict, Replacement, Priority, Environment);2237Avail->setImplicit(Implicit);2238return Avail;2239}2240return nullptr;2241}22422243static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {2244if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(2245D)) {2246S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)2247<< AL;2248return;2249}22502251if (!AL.checkExactlyNumArgs(S, 1))2252return;2253IdentifierLoc *Platform = AL.getArgAsIdent(0);22542255IdentifierInfo *II = Platform->Ident;2256if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())2257S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)2258<< Platform->Ident;22592260auto *ND = dyn_cast<NamedDecl>(D);2261if (!ND) // We warned about this already, so just return.2262return;22632264AvailabilityChange Introduced = AL.getAvailabilityIntroduced();2265AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();2266AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();2267bool IsUnavailable = AL.getUnavailableLoc().isValid();2268bool IsStrict = AL.getStrictLoc().isValid();2269StringRef Str;2270if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getMessageExpr()))2271Str = SE->getString();2272StringRef Replacement;2273if (const auto *SE =2274dyn_cast_if_present<StringLiteral>(AL.getReplacementExpr()))2275Replacement = SE->getString();22762277if (II->isStr("swift")) {2278if (Introduced.isValid() || Obsoleted.isValid() ||2279(!IsUnavailable && !Deprecated.isValid())) {2280S.Diag(AL.getLoc(),2281diag::warn_availability_swift_unavailable_deprecated_only);2282return;2283}2284}22852286if (II->isStr("fuchsia")) {2287std::optional<unsigned> Min, Sub;2288if ((Min = Introduced.Version.getMinor()) ||2289(Sub = Introduced.Version.getSubminor())) {2290S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);2291return;2292}2293}22942295if (S.getLangOpts().HLSL && IsStrict)2296S.Diag(AL.getStrictLoc(), diag::err_availability_unexpected_parameter)2297<< "strict" << /* HLSL */ 0;22982299int PriorityModifier = AL.isPragmaClangAttribute()2300? Sema::AP_PragmaClangAttribute2301: Sema::AP_Explicit;23022303const IdentifierLoc *EnvironmentLoc = AL.getEnvironment();2304IdentifierInfo *IIEnvironment = nullptr;2305if (EnvironmentLoc) {2306if (S.getLangOpts().HLSL) {2307IIEnvironment = EnvironmentLoc->Ident;2308if (AvailabilityAttr::getEnvironmentType(2309EnvironmentLoc->Ident->getName()) ==2310llvm::Triple::EnvironmentType::UnknownEnvironment)2311S.Diag(EnvironmentLoc->Loc, diag::warn_availability_unknown_environment)2312<< EnvironmentLoc->Ident;2313} else {2314S.Diag(EnvironmentLoc->Loc, diag::err_availability_unexpected_parameter)2315<< "environment" << /* C/C++ */ 1;2316}2317}23182319AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(2320ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,2321Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,2322Sema::AMK_None, PriorityModifier, IIEnvironment);2323if (NewAttr)2324D->addAttr(NewAttr);23252326// Transcribe "ios" to "watchos" (and add a new attribute) if the versioning2327// matches before the start of the watchOS platform.2328if (S.Context.getTargetInfo().getTriple().isWatchOS()) {2329IdentifierInfo *NewII = nullptr;2330if (II->getName() == "ios")2331NewII = &S.Context.Idents.get("watchos");2332else if (II->getName() == "ios_app_extension")2333NewII = &S.Context.Idents.get("watchos_app_extension");23342335if (NewII) {2336const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();2337const auto *IOSToWatchOSMapping =2338SDKInfo ? SDKInfo->getVersionMapping(2339DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())2340: nullptr;23412342auto adjustWatchOSVersion =2343[IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {2344if (Version.empty())2345return Version;2346auto MinimumWatchOSVersion = VersionTuple(2, 0);23472348if (IOSToWatchOSMapping) {2349if (auto MappedVersion = IOSToWatchOSMapping->map(2350Version, MinimumWatchOSVersion, std::nullopt)) {2351return *MappedVersion;2352}2353}23542355auto Major = Version.getMajor();2356auto NewMajor = Major >= 9 ? Major - 7 : 0;2357if (NewMajor >= 2) {2358if (Version.getMinor()) {2359if (Version.getSubminor())2360return VersionTuple(NewMajor, *Version.getMinor(),2361*Version.getSubminor());2362else2363return VersionTuple(NewMajor, *Version.getMinor());2364}2365return VersionTuple(NewMajor);2366}23672368return MinimumWatchOSVersion;2369};23702371auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);2372auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);2373auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);23742375AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(2376ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,2377NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,2378Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,2379IIEnvironment);2380if (NewAttr)2381D->addAttr(NewAttr);2382}2383} else if (S.Context.getTargetInfo().getTriple().isTvOS()) {2384// Transcribe "ios" to "tvos" (and add a new attribute) if the versioning2385// matches before the start of the tvOS platform.2386IdentifierInfo *NewII = nullptr;2387if (II->getName() == "ios")2388NewII = &S.Context.Idents.get("tvos");2389else if (II->getName() == "ios_app_extension")2390NewII = &S.Context.Idents.get("tvos_app_extension");23912392if (NewII) {2393const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();2394const auto *IOSToTvOSMapping =2395SDKInfo ? SDKInfo->getVersionMapping(2396DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())2397: nullptr;23982399auto AdjustTvOSVersion =2400[IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {2401if (Version.empty())2402return Version;24032404if (IOSToTvOSMapping) {2405if (auto MappedVersion = IOSToTvOSMapping->map(2406Version, VersionTuple(0, 0), std::nullopt)) {2407return *MappedVersion;2408}2409}2410return Version;2411};24122413auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);2414auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);2415auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);24162417AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(2418ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,2419NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,2420Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,2421IIEnvironment);2422if (NewAttr)2423D->addAttr(NewAttr);2424}2425} else if (S.Context.getTargetInfo().getTriple().getOS() ==2426llvm::Triple::IOS &&2427S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {2428auto GetSDKInfo = [&]() {2429return S.getDarwinSDKInfoForAvailabilityChecking(AL.getRange().getBegin(),2430"macOS");2431};24322433// Transcribe "ios" to "maccatalyst" (and add a new attribute).2434IdentifierInfo *NewII = nullptr;2435if (II->getName() == "ios")2436NewII = &S.Context.Idents.get("maccatalyst");2437else if (II->getName() == "ios_app_extension")2438NewII = &S.Context.Idents.get("maccatalyst_app_extension");2439if (NewII) {2440auto MinMacCatalystVersion = [](const VersionTuple &V) {2441if (V.empty())2442return V;2443if (V.getMajor() < 13 ||2444(V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))2445return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.2446return V;2447};2448AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(2449ND, AL, NewII, true /*Implicit*/,2450MinMacCatalystVersion(Introduced.Version),2451MinMacCatalystVersion(Deprecated.Version),2452MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,2453IsStrict, Replacement, Sema::AMK_None,2454PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);2455if (NewAttr)2456D->addAttr(NewAttr);2457} else if (II->getName() == "macos" && GetSDKInfo() &&2458(!Introduced.Version.empty() || !Deprecated.Version.empty() ||2459!Obsoleted.Version.empty())) {2460if (const auto *MacOStoMacCatalystMapping =2461GetSDKInfo()->getVersionMapping(2462DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {2463// Infer Mac Catalyst availability from the macOS availability attribute2464// if it has versioned availability. Don't infer 'unavailable'. This2465// inferred availability has lower priority than the other availability2466// attributes that are inferred from 'ios'.2467NewII = &S.Context.Idents.get("maccatalyst");2468auto RemapMacOSVersion =2469[&](const VersionTuple &V) -> std::optional<VersionTuple> {2470if (V.empty())2471return std::nullopt;2472// API_TO_BE_DEPRECATED is 100000.2473if (V.getMajor() == 100000)2474return VersionTuple(100000);2475// The minimum iosmac version is 13.12476return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1),2477std::nullopt);2478};2479std::optional<VersionTuple> NewIntroduced =2480RemapMacOSVersion(Introduced.Version),2481NewDeprecated =2482RemapMacOSVersion(Deprecated.Version),2483NewObsoleted =2484RemapMacOSVersion(Obsoleted.Version);2485if (NewIntroduced || NewDeprecated || NewObsoleted) {2486auto VersionOrEmptyVersion =2487[](const std::optional<VersionTuple> &V) -> VersionTuple {2488return V ? *V : VersionTuple();2489};2490AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(2491ND, AL, NewII, true /*Implicit*/,2492VersionOrEmptyVersion(NewIntroduced),2493VersionOrEmptyVersion(NewDeprecated),2494VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,2495IsStrict, Replacement, Sema::AMK_None,2496PriorityModifier + Sema::AP_InferredFromOtherPlatform +2497Sema::AP_InferredFromOtherPlatform,2498IIEnvironment);2499if (NewAttr)2500D->addAttr(NewAttr);2501}2502}2503}2504}2505}25062507static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,2508const ParsedAttr &AL) {2509if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 4))2510return;25112512StringRef Language;2513if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(0)))2514Language = SE->getString();2515StringRef DefinedIn;2516if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(1)))2517DefinedIn = SE->getString();2518bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;2519StringRef USR;2520if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(3)))2521USR = SE->getString();25222523D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(2524S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));2525}25262527template <class T>2528static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,2529typename T::VisibilityType value) {2530T *existingAttr = D->getAttr<T>();2531if (existingAttr) {2532typename T::VisibilityType existingValue = existingAttr->getVisibility();2533if (existingValue == value)2534return nullptr;2535S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);2536S.Diag(CI.getLoc(), diag::note_previous_attribute);2537D->dropAttr<T>();2538}2539return ::new (S.Context) T(S.Context, CI, value);2540}25412542VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,2543const AttributeCommonInfo &CI,2544VisibilityAttr::VisibilityType Vis) {2545return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);2546}25472548TypeVisibilityAttr *2549Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,2550TypeVisibilityAttr::VisibilityType Vis) {2551return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);2552}25532554static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,2555bool isTypeVisibility) {2556// Visibility attributes don't mean anything on a typedef.2557if (isa<TypedefNameDecl>(D)) {2558S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;2559return;2560}25612562// 'type_visibility' can only go on a type or namespace.2563if (isTypeVisibility && !(isa<TagDecl>(D) || isa<ObjCInterfaceDecl>(D) ||2564isa<NamespaceDecl>(D))) {2565S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)2566<< AL << AL.isRegularKeywordAttribute() << ExpectedTypeOrNamespace;2567return;2568}25692570// Check that the argument is a string literal.2571StringRef TypeStr;2572SourceLocation LiteralLoc;2573if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))2574return;25752576VisibilityAttr::VisibilityType type;2577if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {2578S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL2579<< TypeStr;2580return;2581}25822583// Complain about attempts to use protected visibility on targets2584// (like Darwin) that don't support it.2585if (type == VisibilityAttr::Protected &&2586!S.Context.getTargetInfo().hasProtectedVisibility()) {2587S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);2588type = VisibilityAttr::Default;2589}25902591Attr *newAttr;2592if (isTypeVisibility) {2593newAttr = S.mergeTypeVisibilityAttr(2594D, AL, (TypeVisibilityAttr::VisibilityType)type);2595} else {2596newAttr = S.mergeVisibilityAttr(D, AL, type);2597}2598if (newAttr)2599D->addAttr(newAttr);2600}26012602static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {2603unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;2604if (AL.getNumArgs() > 0) {2605Expr *E = AL.getArgAsExpr(0);2606std::optional<llvm::APSInt> Idx = llvm::APSInt(32);2607if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {2608S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)2609<< AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();2610return;2611}26122613if (Idx->isSigned() && Idx->isNegative()) {2614S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)2615<< E->getSourceRange();2616return;2617}26182619sentinel = Idx->getZExtValue();2620}26212622unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;2623if (AL.getNumArgs() > 1) {2624Expr *E = AL.getArgAsExpr(1);2625std::optional<llvm::APSInt> Idx = llvm::APSInt(32);2626if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {2627S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)2628<< AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();2629return;2630}2631nullPos = Idx->getZExtValue();26322633if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {2634// FIXME: This error message could be improved, it would be nice2635// to say what the bounds actually are.2636S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)2637<< E->getSourceRange();2638return;2639}2640}26412642if (const auto *FD = dyn_cast<FunctionDecl>(D)) {2643const FunctionType *FT = FD->getType()->castAs<FunctionType>();2644if (isa<FunctionNoProtoType>(FT)) {2645S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);2646return;2647}26482649if (!cast<FunctionProtoType>(FT)->isVariadic()) {2650S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;2651return;2652}2653} else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {2654if (!MD->isVariadic()) {2655S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;2656return;2657}2658} else if (const auto *BD = dyn_cast<BlockDecl>(D)) {2659if (!BD->isVariadic()) {2660S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;2661return;2662}2663} else if (const auto *V = dyn_cast<VarDecl>(D)) {2664QualType Ty = V->getType();2665if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {2666const FunctionType *FT = Ty->isFunctionPointerType()2667? D->getFunctionType()2668: Ty->castAs<BlockPointerType>()2669->getPointeeType()2670->castAs<FunctionType>();2671if (!cast<FunctionProtoType>(FT)->isVariadic()) {2672int m = Ty->isFunctionPointerType() ? 0 : 1;2673S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;2674return;2675}2676} else {2677S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)2678<< AL << AL.isRegularKeywordAttribute()2679<< ExpectedFunctionMethodOrBlock;2680return;2681}2682} else {2683S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)2684<< AL << AL.isRegularKeywordAttribute()2685<< ExpectedFunctionMethodOrBlock;2686return;2687}2688D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));2689}26902691static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {2692if (D->getFunctionType() &&2693D->getFunctionType()->getReturnType()->isVoidType() &&2694!isa<CXXConstructorDecl>(D)) {2695S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;2696return;2697}2698if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))2699if (MD->getReturnType()->isVoidType()) {2700S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;2701return;2702}27032704StringRef Str;2705if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {2706// The standard attribute cannot be applied to variable declarations such2707// as a function pointer.2708if (isa<VarDecl>(D))2709S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)2710<< AL << AL.isRegularKeywordAttribute()2711<< "functions, classes, or enumerations";27122713// If this is spelled as the standard C++17 attribute, but not in C++17,2714// warn about using it as an extension. If there are attribute arguments,2715// then claim it's a C++20 extension instead.2716// FIXME: If WG14 does not seem likely to adopt the same feature, add an2717// extension warning for C23 mode.2718const LangOptions &LO = S.getLangOpts();2719if (AL.getNumArgs() == 1) {2720if (LO.CPlusPlus && !LO.CPlusPlus20)2721S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;27222723// Since this is spelled [[nodiscard]], get the optional string2724// literal. If in C++ mode, but not in C++20 mode, diagnose as an2725// extension.2726// FIXME: C23 should support this feature as well, even as an extension.2727if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))2728return;2729} else if (LO.CPlusPlus && !LO.CPlusPlus17)2730S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;2731}27322733if ((!AL.isGNUAttribute() &&2734!(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&2735isa<TypedefNameDecl>(D)) {2736S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling)2737<< AL.isGNUScope();2738return;2739}27402741D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));2742}27432744static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {2745// weak_import only applies to variable & function declarations.2746bool isDef = false;2747if (!D->canBeWeakImported(isDef)) {2748if (isDef)2749S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)2750<< "weak_import";2751else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||2752(S.Context.getTargetInfo().getTriple().isOSDarwin() &&2753(isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {2754// Nothing to warn about here.2755} else2756S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)2757<< AL << AL.isRegularKeywordAttribute() << ExpectedVariableOrFunction;27582759return;2760}27612762D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));2763}27642765// Handles reqd_work_group_size and work_group_size_hint.2766template <typename WorkGroupAttr>2767static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {2768uint32_t WGSize[3];2769for (unsigned i = 0; i < 3; ++i) {2770const Expr *E = AL.getArgAsExpr(i);2771if (!S.checkUInt32Argument(AL, E, WGSize[i], i,2772/*StrictlyUnsigned=*/true))2773return;2774if (WGSize[i] == 0) {2775S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)2776<< AL << E->getSourceRange();2777return;2778}2779}27802781WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();2782if (Existing && !(Existing->getXDim() == WGSize[0] &&2783Existing->getYDim() == WGSize[1] &&2784Existing->getZDim() == WGSize[2]))2785S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;27862787D->addAttr(::new (S.Context)2788WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));2789}27902791static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {2792if (!AL.hasParsedType()) {2793S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;2794return;2795}27962797TypeSourceInfo *ParmTSI = nullptr;2798QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);2799assert(ParmTSI && "no type source info for attribute argument");28002801if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&2802(ParmType->isBooleanType() ||2803!ParmType->isIntegralType(S.getASTContext()))) {2804S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;2805return;2806}28072808if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {2809if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {2810S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;2811return;2812}2813}28142815D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));2816}28172818SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,2819StringRef Name) {2820// Explicit or partial specializations do not inherit2821// the section attribute from the primary template.2822if (const auto *FD = dyn_cast<FunctionDecl>(D)) {2823if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&2824FD->isFunctionTemplateSpecialization())2825return nullptr;2826}2827if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {2828if (ExistingAttr->getName() == Name)2829return nullptr;2830Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)2831<< 1 /*section*/;2832Diag(CI.getLoc(), diag::note_previous_attribute);2833return nullptr;2834}2835return ::new (Context) SectionAttr(Context, CI, Name);2836}28372838llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {2839if (!Context.getTargetInfo().getTriple().isOSDarwin())2840return llvm::Error::success();28412842// Let MCSectionMachO validate this.2843StringRef Segment, Section;2844unsigned TAA, StubSize;2845bool HasTAA;2846return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,2847TAA, HasTAA, StubSize);2848}28492850bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {2851if (llvm::Error E = isValidSectionSpecifier(SecName)) {2852Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)2853<< toString(std::move(E)) << 1 /*'section'*/;2854return false;2855}2856return true;2857}28582859static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {2860// Make sure that there is a string literal as the sections's single2861// argument.2862StringRef Str;2863SourceLocation LiteralLoc;2864if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))2865return;28662867if (!S.checkSectionName(LiteralLoc, Str))2868return;28692870SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);2871if (NewAttr) {2872D->addAttr(NewAttr);2873if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl,2874ObjCPropertyDecl>(D))2875S.UnifySection(NewAttr->getName(),2876ASTContext::PSF_Execute | ASTContext::PSF_Read,2877cast<NamedDecl>(D));2878}2879}28802881static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {2882StringRef Str;2883SourceLocation LiteralLoc;2884// Check that it is a string.2885if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))2886return;28872888llvm::CodeModel::Model CM;2889if (!CodeModelAttr::ConvertStrToModel(Str, CM)) {2890S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;2891return;2892}28932894D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));2895}28962897// This is used for `__declspec(code_seg("segname"))` on a decl.2898// `#pragma code_seg("segname")` uses checkSectionName() instead.2899static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,2900StringRef CodeSegName) {2901if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {2902S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)2903<< toString(std::move(E)) << 0 /*'code-seg'*/;2904return false;2905}29062907return true;2908}29092910CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,2911StringRef Name) {2912// Explicit or partial specializations do not inherit2913// the code_seg attribute from the primary template.2914if (const auto *FD = dyn_cast<FunctionDecl>(D)) {2915if (FD->isFunctionTemplateSpecialization())2916return nullptr;2917}2918if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {2919if (ExistingAttr->getName() == Name)2920return nullptr;2921Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)2922<< 0 /*codeseg*/;2923Diag(CI.getLoc(), diag::note_previous_attribute);2924return nullptr;2925}2926return ::new (Context) CodeSegAttr(Context, CI, Name);2927}29282929static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {2930StringRef Str;2931SourceLocation LiteralLoc;2932if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))2933return;2934if (!checkCodeSegName(S, LiteralLoc, Str))2935return;2936if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {2937if (!ExistingAttr->isImplicit()) {2938S.Diag(AL.getLoc(),2939ExistingAttr->getName() == Str2940? diag::warn_duplicate_codeseg_attribute2941: diag::err_conflicting_codeseg_attribute);2942return;2943}2944D->dropAttr<CodeSegAttr>();2945}2946if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))2947D->addAttr(CSA);2948}29492950bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {2951enum FirstParam { Unsupported, Duplicate, Unknown };2952enum SecondParam { None, CPU, Tune };2953enum ThirdParam { Target, TargetClones };2954if (AttrStr.contains("fpmath="))2955return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)2956<< Unsupported << None << "fpmath=" << Target;29572958// Diagnose use of tune if target doesn't support it.2959if (!Context.getTargetInfo().supportsTargetAttributeTune() &&2960AttrStr.contains("tune="))2961return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)2962<< Unsupported << None << "tune=" << Target;29632964ParsedTargetAttr ParsedAttrs =2965Context.getTargetInfo().parseTargetAttr(AttrStr);29662967if (!ParsedAttrs.CPU.empty() &&2968!Context.getTargetInfo().isValidCPUName(ParsedAttrs.CPU))2969return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)2970<< Unknown << CPU << ParsedAttrs.CPU << Target;29712972if (!ParsedAttrs.Tune.empty() &&2973!Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))2974return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)2975<< Unknown << Tune << ParsedAttrs.Tune << Target;29762977if (Context.getTargetInfo().getTriple().isRISCV() &&2978ParsedAttrs.Duplicate != "")2979return Diag(LiteralLoc, diag::err_duplicate_target_attribute)2980<< Duplicate << None << ParsedAttrs.Duplicate << Target;29812982if (ParsedAttrs.Duplicate != "")2983return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)2984<< Duplicate << None << ParsedAttrs.Duplicate << Target;29852986for (const auto &Feature : ParsedAttrs.Features) {2987auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.2988if (!Context.getTargetInfo().isValidFeatureName(CurFeature))2989return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)2990<< Unsupported << None << CurFeature << Target;2991}29922993TargetInfo::BranchProtectionInfo BPI{};2994StringRef DiagMsg;2995if (ParsedAttrs.BranchProtection.empty())2996return false;2997if (!Context.getTargetInfo().validateBranchProtection(2998ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI, DiagMsg)) {2999if (DiagMsg.empty())3000return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)3001<< Unsupported << None << "branch-protection" << Target;3002return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)3003<< DiagMsg;3004}3005if (!DiagMsg.empty())3006Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;30073008return false;3009}30103011bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,3012StringRef AttrStr) {3013enum FirstParam { Unsupported };3014enum SecondParam { None };3015enum ThirdParam { Target, TargetClones, TargetVersion };3016llvm::SmallVector<StringRef, 8> Features;3017AttrStr.split(Features, "+");3018for (auto &CurFeature : Features) {3019CurFeature = CurFeature.trim();3020if (CurFeature == "default")3021continue;3022if (!Context.getTargetInfo().validateCpuSupports(CurFeature))3023return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)3024<< Unsupported << None << CurFeature << TargetVersion;3025}3026return false;3027}30283029static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3030StringRef Str;3031SourceLocation LiteralLoc;3032if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||3033S.checkTargetVersionAttr(LiteralLoc, D, Str))3034return;3035TargetVersionAttr *NewAttr =3036::new (S.Context) TargetVersionAttr(S.Context, AL, Str);3037D->addAttr(NewAttr);3038}30393040static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3041StringRef Str;3042SourceLocation LiteralLoc;3043if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||3044S.checkTargetAttr(LiteralLoc, Str))3045return;30463047TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);3048D->addAttr(NewAttr);3049}30503051bool Sema::checkTargetClonesAttrString(3052SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,3053Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,3054SmallVectorImpl<SmallString<64>> &StringsBuffer) {3055enum FirstParam { Unsupported, Duplicate, Unknown };3056enum SecondParam { None, CPU, Tune };3057enum ThirdParam { Target, TargetClones };3058HasCommas = HasCommas || Str.contains(',');3059const TargetInfo &TInfo = Context.getTargetInfo();3060// Warn on empty at the beginning of a string.3061if (Str.size() == 0)3062return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)3063<< Unsupported << None << "" << TargetClones;30643065std::pair<StringRef, StringRef> Parts = {{}, Str};3066while (!Parts.second.empty()) {3067Parts = Parts.second.split(',');3068StringRef Cur = Parts.first.trim();3069SourceLocation CurLoc =3070Literal->getLocationOfByte(Cur.data() - Literal->getString().data(),3071getSourceManager(), getLangOpts(), TInfo);30723073bool DefaultIsDupe = false;3074bool HasCodeGenImpact = false;3075if (Cur.empty())3076return Diag(CurLoc, diag::warn_unsupported_target_attribute)3077<< Unsupported << None << "" << TargetClones;30783079if (TInfo.getTriple().isAArch64()) {3080// AArch64 target clones specific3081if (Cur == "default") {3082DefaultIsDupe = HasDefault;3083HasDefault = true;3084if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)3085Diag(CurLoc, diag::warn_target_clone_duplicate_options);3086else3087StringsBuffer.push_back(Cur);3088} else {3089std::pair<StringRef, StringRef> CurParts = {{}, Cur};3090llvm::SmallVector<StringRef, 8> CurFeatures;3091while (!CurParts.second.empty()) {3092CurParts = CurParts.second.split('+');3093StringRef CurFeature = CurParts.first.trim();3094if (!TInfo.validateCpuSupports(CurFeature)) {3095Diag(CurLoc, diag::warn_unsupported_target_attribute)3096<< Unsupported << None << CurFeature << TargetClones;3097continue;3098}3099if (TInfo.doesFeatureAffectCodeGen(CurFeature))3100HasCodeGenImpact = true;3101CurFeatures.push_back(CurFeature);3102}3103// Canonize TargetClones Attributes3104llvm::sort(CurFeatures);3105SmallString<64> Res;3106for (auto &CurFeat : CurFeatures) {3107if (!Res.empty())3108Res.append("+");3109Res.append(CurFeat);3110}3111if (llvm::is_contained(StringsBuffer, Res) || DefaultIsDupe)3112Diag(CurLoc, diag::warn_target_clone_duplicate_options);3113else if (!HasCodeGenImpact)3114// Ignore features in target_clone attribute that don't impact3115// code generation3116Diag(CurLoc, diag::warn_target_clone_no_impact_options);3117else if (!Res.empty()) {3118StringsBuffer.push_back(Res);3119HasNotDefault = true;3120}3121}3122} else {3123// Other targets ( currently X86 )3124if (Cur.starts_with("arch=")) {3125if (!Context.getTargetInfo().isValidCPUName(3126Cur.drop_front(sizeof("arch=") - 1)))3127return Diag(CurLoc, diag::warn_unsupported_target_attribute)3128<< Unsupported << CPU << Cur.drop_front(sizeof("arch=") - 1)3129<< TargetClones;3130} else if (Cur == "default") {3131DefaultIsDupe = HasDefault;3132HasDefault = true;3133} else if (!Context.getTargetInfo().isValidFeatureName(Cur))3134return Diag(CurLoc, diag::warn_unsupported_target_attribute)3135<< Unsupported << None << Cur << TargetClones;3136if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)3137Diag(CurLoc, diag::warn_target_clone_duplicate_options);3138// Note: Add even if there are duplicates, since it changes name mangling.3139StringsBuffer.push_back(Cur);3140}3141}3142if (Str.rtrim().ends_with(","))3143return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)3144<< Unsupported << None << "" << TargetClones;3145return false;3146}31473148static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3149if (S.Context.getTargetInfo().getTriple().isAArch64() &&3150!S.Context.getTargetInfo().hasFeature("fmv"))3151return;31523153// Ensure we don't combine these with themselves, since that causes some3154// confusing behavior.3155if (const auto *Other = D->getAttr<TargetClonesAttr>()) {3156S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;3157S.Diag(Other->getLocation(), diag::note_conflicting_attribute);3158return;3159}3160if (checkAttrMutualExclusion<TargetClonesAttr>(S, D, AL))3161return;31623163SmallVector<StringRef, 2> Strings;3164SmallVector<SmallString<64>, 2> StringsBuffer;3165bool HasCommas = false, HasDefault = false, HasNotDefault = false;31663167for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {3168StringRef CurStr;3169SourceLocation LiteralLoc;3170if (!S.checkStringLiteralArgumentAttr(AL, I, CurStr, &LiteralLoc) ||3171S.checkTargetClonesAttrString(3172LiteralLoc, CurStr,3173cast<StringLiteral>(AL.getArgAsExpr(I)->IgnoreParenCasts()), D,3174HasDefault, HasCommas, HasNotDefault, StringsBuffer))3175return;3176}3177for (auto &SmallStr : StringsBuffer)3178Strings.push_back(SmallStr.str());31793180if (HasCommas && AL.getNumArgs() > 1)3181S.Diag(AL.getLoc(), diag::warn_target_clone_mixed_values);31823183if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasDefault) {3184// Add default attribute if there is no one3185HasDefault = true;3186Strings.push_back("default");3187}31883189if (!HasDefault) {3190S.Diag(AL.getLoc(), diag::err_target_clone_must_have_default);3191return;3192}31933194// FIXME: We could probably figure out how to get this to work for lambdas3195// someday.3196if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {3197if (MD->getParent()->isLambda()) {3198S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)3199<< static_cast<unsigned>(MultiVersionKind::TargetClones)3200<< /*Lambda*/ 9;3201return;3202}3203}32043205// No multiversion if we have default version only.3206if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasNotDefault)3207return;32083209cast<FunctionDecl>(D)->setIsMultiVersion();3210TargetClonesAttr *NewAttr = ::new (S.Context)3211TargetClonesAttr(S.Context, AL, Strings.data(), Strings.size());3212D->addAttr(NewAttr);3213}32143215static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3216Expr *E = AL.getArgAsExpr(0);3217uint32_t VecWidth;3218if (!S.checkUInt32Argument(AL, E, VecWidth)) {3219AL.setInvalid();3220return;3221}32223223MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();3224if (Existing && Existing->getVectorWidth() != VecWidth) {3225S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;3226return;3227}32283229D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));3230}32313232static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3233Expr *E = AL.getArgAsExpr(0);3234SourceLocation Loc = E->getExprLoc();3235FunctionDecl *FD = nullptr;3236DeclarationNameInfo NI;32373238// gcc only allows for simple identifiers. Since we support more than gcc, we3239// will warn the user.3240if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {3241if (DRE->hasQualifier())3242S.Diag(Loc, diag::warn_cleanup_ext);3243FD = dyn_cast<FunctionDecl>(DRE->getDecl());3244NI = DRE->getNameInfo();3245if (!FD) {3246S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 13247<< NI.getName();3248return;3249}3250} else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {3251if (ULE->hasExplicitTemplateArgs())3252S.Diag(Loc, diag::warn_cleanup_ext);3253FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);3254NI = ULE->getNameInfo();3255if (!FD) {3256S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 23257<< NI.getName();3258if (ULE->getType() == S.Context.OverloadTy)3259S.NoteAllOverloadCandidates(ULE);3260return;3261}3262} else {3263S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;3264return;3265}32663267if (FD->getNumParams() != 1) {3268S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)3269<< NI.getName();3270return;3271}32723273// We're currently more strict than GCC about what function types we accept.3274// If this ever proves to be a problem it should be easy to fix.3275QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());3276QualType ParamTy = FD->getParamDecl(0)->getType();3277if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),3278ParamTy, Ty) != Sema::Compatible) {3279S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)3280<< NI.getName() << ParamTy << Ty;3281return;3282}3283VarDecl *VD = cast<VarDecl>(D);3284// Create a reference to the variable declaration. This is a fake/dummy3285// reference.3286DeclRefExpr *VariableReference = DeclRefExpr::Create(3287S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false,3288DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(),3289VK_LValue);32903291// Create a unary operator expression that represents taking the address of3292// the variable. This is a fake/dummy expression.3293Expr *AddressOfVariable = UnaryOperator::Create(3294S.Context, VariableReference, UnaryOperatorKind::UO_AddrOf,3295S.Context.getPointerType(VD->getType()), VK_PRValue, OK_Ordinary, Loc,3296+false, FPOptionsOverride{});32973298// Create a function call expression. This is a fake/dummy call expression.3299CallExpr *FunctionCallExpression =3300CallExpr::Create(S.Context, E, ArrayRef{AddressOfVariable},3301S.Context.VoidTy, VK_PRValue, Loc, FPOptionsOverride{});33023303if (S.CheckFunctionCall(FD, FunctionCallExpression,3304FD->getType()->getAs<FunctionProtoType>())) {3305return;3306}33073308D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));3309}33103311static void handleEnumExtensibilityAttr(Sema &S, Decl *D,3312const ParsedAttr &AL) {3313if (!AL.isArgIdent(0)) {3314S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)3315<< AL << 0 << AANT_ArgumentIdentifier;3316return;3317}33183319EnumExtensibilityAttr::Kind ExtensibilityKind;3320IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;3321if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),3322ExtensibilityKind)) {3323S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;3324return;3325}33263327D->addAttr(::new (S.Context)3328EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));3329}33303331/// Handle __attribute__((format_arg((idx)))) attribute based on3332/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html3333static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3334const Expr *IdxExpr = AL.getArgAsExpr(0);3335ParamIdx Idx;3336if (!S.checkFunctionOrMethodParameterIndex(D, AL, 1, IdxExpr, Idx))3337return;33383339// Make sure the format string is really a string.3340QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());33413342bool NotNSStringTy = !S.ObjC().isNSStringType(Ty);3343if (NotNSStringTy && !S.ObjC().isCFStringType(Ty) &&3344(!Ty->isPointerType() ||3345!Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {3346S.Diag(AL.getLoc(), diag::err_format_attribute_not)3347<< IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);3348return;3349}3350Ty = getFunctionOrMethodResultType(D);3351// replace instancetype with the class type3352auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();3353if (Ty->getAs<TypedefType>() == Instancetype)3354if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))3355if (auto *Interface = OMD->getClassInterface())3356Ty = S.Context.getObjCObjectPointerType(3357QualType(Interface->getTypeForDecl(), 0));3358if (!S.ObjC().isNSStringType(Ty, /*AllowNSAttributedString=*/true) &&3359!S.ObjC().isCFStringType(Ty) &&3360(!Ty->isPointerType() ||3361!Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {3362S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)3363<< (NotNSStringTy ? "string type" : "NSString")3364<< IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);3365return;3366}33673368D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));3369}33703371enum FormatAttrKind {3372CFStringFormat,3373NSStringFormat,3374StrftimeFormat,3375SupportedFormat,3376IgnoredFormat,3377InvalidFormat3378};33793380/// getFormatAttrKind - Map from format attribute names to supported format3381/// types.3382static FormatAttrKind getFormatAttrKind(StringRef Format) {3383return llvm::StringSwitch<FormatAttrKind>(Format)3384// Check for formats that get handled specially.3385.Case("NSString", NSStringFormat)3386.Case("CFString", CFStringFormat)3387.Case("strftime", StrftimeFormat)33883389// Otherwise, check for supported formats.3390.Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)3391.Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)3392.Case("kprintf", SupportedFormat) // OpenBSD.3393.Case("freebsd_kprintf", SupportedFormat) // FreeBSD.3394.Case("os_trace", SupportedFormat)3395.Case("os_log", SupportedFormat)33963397.Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)3398.Default(InvalidFormat);3399}34003401/// Handle __attribute__((init_priority(priority))) attributes based on3402/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html3403static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3404if (!S.getLangOpts().CPlusPlus) {3405S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;3406return;3407}34083409if (S.getLangOpts().HLSL) {3410S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);3411return;3412}34133414if (S.getCurFunctionOrMethodDecl()) {3415S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);3416AL.setInvalid();3417return;3418}3419QualType T = cast<VarDecl>(D)->getType();3420if (S.Context.getAsArrayType(T))3421T = S.Context.getBaseElementType(T);3422if (!T->getAs<RecordType>()) {3423S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);3424AL.setInvalid();3425return;3426}34273428Expr *E = AL.getArgAsExpr(0);3429uint32_t prioritynum;3430if (!S.checkUInt32Argument(AL, E, prioritynum)) {3431AL.setInvalid();3432return;3433}34343435// Only perform the priority check if the attribute is outside of a system3436// header. Values <= 100 are reserved for the implementation, and libc++3437// benefits from being able to specify values in that range.3438if ((prioritynum < 101 || prioritynum > 65535) &&3439!S.getSourceManager().isInSystemHeader(AL.getLoc())) {3440S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)3441<< E->getSourceRange() << AL << 101 << 65535;3442AL.setInvalid();3443return;3444}3445D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));3446}34473448ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,3449StringRef NewUserDiagnostic) {3450if (const auto *EA = D->getAttr<ErrorAttr>()) {3451std::string NewAttr = CI.getNormalizedFullName();3452assert((NewAttr == "error" || NewAttr == "warning") &&3453"unexpected normalized full name");3454bool Match = (EA->isError() && NewAttr == "error") ||3455(EA->isWarning() && NewAttr == "warning");3456if (!Match) {3457Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)3458<< CI << EA3459<< (CI.isRegularKeywordAttribute() ||3460EA->isRegularKeywordAttribute());3461Diag(CI.getLoc(), diag::note_conflicting_attribute);3462return nullptr;3463}3464if (EA->getUserDiagnostic() != NewUserDiagnostic) {3465Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;3466Diag(EA->getLoc(), diag::note_previous_attribute);3467}3468D->dropAttr<ErrorAttr>();3469}3470return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);3471}34723473FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,3474IdentifierInfo *Format, int FormatIdx,3475int FirstArg) {3476// Check whether we already have an equivalent format attribute.3477for (auto *F : D->specific_attrs<FormatAttr>()) {3478if (F->getType() == Format &&3479F->getFormatIdx() == FormatIdx &&3480F->getFirstArg() == FirstArg) {3481// If we don't have a valid location for this attribute, adopt the3482// location.3483if (F->getLocation().isInvalid())3484F->setRange(CI.getRange());3485return nullptr;3486}3487}34883489return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);3490}34913492/// Handle __attribute__((format(type,idx,firstarg))) attributes based on3493/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html3494static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3495if (!AL.isArgIdent(0)) {3496S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)3497<< AL << 1 << AANT_ArgumentIdentifier;3498return;3499}35003501// In C++ the implicit 'this' function parameter also counts, and they are3502// counted from one.3503bool HasImplicitThisParam = isInstanceMethod(D);3504unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;35053506IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;3507StringRef Format = II->getName();35083509if (normalizeName(Format)) {3510// If we've modified the string name, we need a new identifier for it.3511II = &S.Context.Idents.get(Format);3512}35133514// Check for supported formats.3515FormatAttrKind Kind = getFormatAttrKind(Format);35163517if (Kind == IgnoredFormat)3518return;35193520if (Kind == InvalidFormat) {3521S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)3522<< AL << II->getName();3523return;3524}35253526// checks for the 2nd argument3527Expr *IdxExpr = AL.getArgAsExpr(1);3528uint32_t Idx;3529if (!S.checkUInt32Argument(AL, IdxExpr, Idx, 2))3530return;35313532if (Idx < 1 || Idx > NumArgs) {3533S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)3534<< AL << 2 << IdxExpr->getSourceRange();3535return;3536}35373538// FIXME: Do we need to bounds check?3539unsigned ArgIdx = Idx - 1;35403541if (HasImplicitThisParam) {3542if (ArgIdx == 0) {3543S.Diag(AL.getLoc(),3544diag::err_format_attribute_implicit_this_format_string)3545<< IdxExpr->getSourceRange();3546return;3547}3548ArgIdx--;3549}35503551// make sure the format string is really a string3552QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);35533554if (!S.ObjC().isNSStringType(Ty, true) && !S.ObjC().isCFStringType(Ty) &&3555(!Ty->isPointerType() ||3556!Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {3557S.Diag(AL.getLoc(), diag::err_format_attribute_not)3558<< IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, ArgIdx);3559return;3560}35613562// check the 3rd argument3563Expr *FirstArgExpr = AL.getArgAsExpr(2);3564uint32_t FirstArg;3565if (!S.checkUInt32Argument(AL, FirstArgExpr, FirstArg, 3))3566return;35673568// FirstArg == 0 is is always valid.3569if (FirstArg != 0) {3570if (Kind == StrftimeFormat) {3571// If the kind is strftime, FirstArg must be 0 because strftime does not3572// use any variadic arguments.3573S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)3574<< FirstArgExpr->getSourceRange()3575<< FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(), "0");3576return;3577} else if (isFunctionOrMethodVariadic(D)) {3578// Else, if the function is variadic, then FirstArg must be 0 or the3579// "position" of the ... parameter. It's unusual to use 0 with variadic3580// functions, so the fixit proposes the latter.3581if (FirstArg != NumArgs + 1) {3582S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)3583<< AL << 3 << FirstArgExpr->getSourceRange()3584<< FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(),3585std::to_string(NumArgs + 1));3586return;3587}3588} else {3589// Inescapable GCC compatibility diagnostic.3590S.Diag(D->getLocation(), diag::warn_gcc_requires_variadic_function) << AL;3591if (FirstArg <= Idx) {3592// Else, the function is not variadic, and FirstArg must be 0 or any3593// parameter after the format parameter. We don't offer a fixit because3594// there are too many possible good values.3595S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)3596<< AL << 3 << FirstArgExpr->getSourceRange();3597return;3598}3599}3600}36013602FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);3603if (NewAttr)3604D->addAttr(NewAttr);3605}36063607/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.3608static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3609// The index that identifies the callback callee is mandatory.3610if (AL.getNumArgs() == 0) {3611S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)3612<< AL.getRange();3613return;3614}36153616bool HasImplicitThisParam = isInstanceMethod(D);3617int32_t NumArgs = getFunctionOrMethodNumParams(D);36183619FunctionDecl *FD = D->getAsFunction();3620assert(FD && "Expected a function declaration!");36213622llvm::StringMap<int> NameIdxMapping;3623NameIdxMapping["__"] = -1;36243625NameIdxMapping["this"] = 0;36263627int Idx = 1;3628for (const ParmVarDecl *PVD : FD->parameters())3629NameIdxMapping[PVD->getName()] = Idx++;36303631auto UnknownName = NameIdxMapping.end();36323633SmallVector<int, 8> EncodingIndices;3634for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {3635SourceRange SR;3636int32_t ArgIdx;36373638if (AL.isArgIdent(I)) {3639IdentifierLoc *IdLoc = AL.getArgAsIdent(I);3640auto It = NameIdxMapping.find(IdLoc->Ident->getName());3641if (It == UnknownName) {3642S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)3643<< IdLoc->Ident << IdLoc->Loc;3644return;3645}36463647SR = SourceRange(IdLoc->Loc);3648ArgIdx = It->second;3649} else if (AL.isArgExpr(I)) {3650Expr *IdxExpr = AL.getArgAsExpr(I);36513652// If the expression is not parseable as an int32_t we have a problem.3653if (!S.checkUInt32Argument(AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,3654false)) {3655S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)3656<< AL << (I + 1) << IdxExpr->getSourceRange();3657return;3658}36593660// Check oob, excluding the special values, 0 and -1.3661if (ArgIdx < -1 || ArgIdx > NumArgs) {3662S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)3663<< AL << (I + 1) << IdxExpr->getSourceRange();3664return;3665}36663667SR = IdxExpr->getSourceRange();3668} else {3669llvm_unreachable("Unexpected ParsedAttr argument type!");3670}36713672if (ArgIdx == 0 && !HasImplicitThisParam) {3673S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)3674<< (I + 1) << SR;3675return;3676}36773678// Adjust for the case we do not have an implicit "this" parameter. In this3679// case we decrease all positive values by 1 to get LLVM argument indices.3680if (!HasImplicitThisParam && ArgIdx > 0)3681ArgIdx -= 1;36823683EncodingIndices.push_back(ArgIdx);3684}36853686int CalleeIdx = EncodingIndices.front();3687// Check if the callee index is proper, thus not "this" and not "unknown".3688// This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"3689// is false and positive if "HasImplicitThisParam" is true.3690if (CalleeIdx < (int)HasImplicitThisParam) {3691S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)3692<< AL.getRange();3693return;3694}36953696// Get the callee type, note the index adjustment as the AST doesn't contain3697// the this type (which the callee cannot reference anyway!).3698const Type *CalleeType =3699getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)3700.getTypePtr();3701if (!CalleeType || !CalleeType->isFunctionPointerType()) {3702S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)3703<< AL.getRange();3704return;3705}37063707const Type *CalleeFnType =3708CalleeType->getPointeeType()->getUnqualifiedDesugaredType();37093710// TODO: Check the type of the callee arguments.37113712const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);3713if (!CalleeFnProtoType) {3714S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)3715<< AL.getRange();3716return;3717}37183719if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {3720S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)3721<< AL << (unsigned)(EncodingIndices.size() - 1);3722return;3723}37243725if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {3726S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)3727<< AL << (unsigned)(EncodingIndices.size() - 1);3728return;3729}37303731if (CalleeFnProtoType->isVariadic()) {3732S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();3733return;3734}37353736// Do not allow multiple callback attributes.3737if (D->hasAttr<CallbackAttr>()) {3738S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();3739return;3740}37413742D->addAttr(::new (S.Context) CallbackAttr(3743S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));3744}37453746static bool isFunctionLike(const Type &T) {3747// Check for explicit function types.3748// 'called_once' is only supported in Objective-C and it has3749// function pointers and block pointers.3750return T.isFunctionPointerType() || T.isBlockPointerType();3751}37523753/// Handle 'called_once' attribute.3754static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3755// 'called_once' only applies to parameters representing functions.3756QualType T = cast<ParmVarDecl>(D)->getType();37573758if (!isFunctionLike(*T)) {3759S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);3760return;3761}37623763D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));3764}37653766static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3767// Try to find the underlying union declaration.3768RecordDecl *RD = nullptr;3769const auto *TD = dyn_cast<TypedefNameDecl>(D);3770if (TD && TD->getUnderlyingType()->isUnionType())3771RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();3772else3773RD = dyn_cast<RecordDecl>(D);37743775if (!RD || !RD->isUnion()) {3776S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)3777<< AL << AL.isRegularKeywordAttribute() << ExpectedUnion;3778return;3779}37803781if (!RD->isCompleteDefinition()) {3782if (!RD->isBeingDefined())3783S.Diag(AL.getLoc(),3784diag::warn_transparent_union_attribute_not_definition);3785return;3786}37873788RecordDecl::field_iterator Field = RD->field_begin(),3789FieldEnd = RD->field_end();3790if (Field == FieldEnd) {3791S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);3792return;3793}37943795FieldDecl *FirstField = *Field;3796QualType FirstType = FirstField->getType();3797if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {3798S.Diag(FirstField->getLocation(),3799diag::warn_transparent_union_attribute_floating)3800<< FirstType->isVectorType() << FirstType;3801return;3802}38033804if (FirstType->isIncompleteType())3805return;3806uint64_t FirstSize = S.Context.getTypeSize(FirstType);3807uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);3808for (; Field != FieldEnd; ++Field) {3809QualType FieldType = Field->getType();3810if (FieldType->isIncompleteType())3811return;3812// FIXME: this isn't fully correct; we also need to test whether the3813// members of the union would all have the same calling convention as the3814// first member of the union. Checking just the size and alignment isn't3815// sufficient (consider structs passed on the stack instead of in registers3816// as an example).3817if (S.Context.getTypeSize(FieldType) != FirstSize ||3818S.Context.getTypeAlign(FieldType) > FirstAlign) {3819// Warn if we drop the attribute.3820bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;3821unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType)3822: S.Context.getTypeAlign(FieldType);3823S.Diag(Field->getLocation(),3824diag::warn_transparent_union_attribute_field_size_align)3825<< isSize << *Field << FieldBits;3826unsigned FirstBits = isSize ? FirstSize : FirstAlign;3827S.Diag(FirstField->getLocation(),3828diag::note_transparent_union_first_field_size_align)3829<< isSize << FirstBits;3830return;3831}3832}38333834RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));3835}38363837void Sema::AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,3838StringRef Str, MutableArrayRef<Expr *> Args) {3839auto *Attr = AnnotateAttr::Create(Context, Str, Args.data(), Args.size(), CI);3840if (ConstantFoldAttrArgs(3841CI, MutableArrayRef<Expr *>(Attr->args_begin(), Attr->args_end()))) {3842D->addAttr(Attr);3843}3844}38453846static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3847// Make sure that there is a string literal as the annotation's first3848// argument.3849StringRef Str;3850if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))3851return;38523853llvm::SmallVector<Expr *, 4> Args;3854Args.reserve(AL.getNumArgs() - 1);3855for (unsigned Idx = 1; Idx < AL.getNumArgs(); Idx++) {3856assert(!AL.isArgIdent(Idx));3857Args.push_back(AL.getArgAsExpr(Idx));3858}38593860S.AddAnnotationAttr(D, AL, Str, Args);3861}38623863static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3864S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));3865}38663867void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {3868AlignValueAttr TmpAttr(Context, CI, E);3869SourceLocation AttrLoc = CI.getLoc();38703871QualType T;3872if (const auto *TD = dyn_cast<TypedefNameDecl>(D))3873T = TD->getUnderlyingType();3874else if (const auto *VD = dyn_cast<ValueDecl>(D))3875T = VD->getType();3876else3877llvm_unreachable("Unknown decl type for align_value");38783879if (!T->isDependentType() && !T->isAnyPointerType() &&3880!T->isReferenceType() && !T->isMemberPointerType()) {3881Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)3882<< &TmpAttr << T << D->getSourceRange();3883return;3884}38853886if (!E->isValueDependent()) {3887llvm::APSInt Alignment;3888ExprResult ICE = VerifyIntegerConstantExpression(3889E, &Alignment, diag::err_align_value_attribute_argument_not_int);3890if (ICE.isInvalid())3891return;38923893if (!Alignment.isPowerOf2()) {3894Diag(AttrLoc, diag::err_alignment_not_power_of_two)3895<< E->getSourceRange();3896return;3897}38983899D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));3900return;3901}39023903// Save dependent expressions in the AST to be instantiated.3904D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));3905}39063907static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {3908if (AL.hasParsedType()) {3909const ParsedType &TypeArg = AL.getTypeArg();3910TypeSourceInfo *TInfo;3911(void)S.GetTypeFromParser(3912ParsedType::getFromOpaquePtr(TypeArg.getAsOpaquePtr()), &TInfo);3913if (AL.isPackExpansion() &&3914!TInfo->getType()->containsUnexpandedParameterPack()) {3915S.Diag(AL.getEllipsisLoc(),3916diag::err_pack_expansion_without_parameter_packs);3917return;3918}39193920if (!AL.isPackExpansion() &&3921S.DiagnoseUnexpandedParameterPack(TInfo->getTypeLoc().getBeginLoc(),3922TInfo, Sema::UPPC_Expression))3923return;39243925S.AddAlignedAttr(D, AL, TInfo, AL.isPackExpansion());3926return;3927}39283929// check the attribute arguments.3930if (AL.getNumArgs() > 1) {3931S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;3932return;3933}39343935if (AL.getNumArgs() == 0) {3936D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));3937return;3938}39393940Expr *E = AL.getArgAsExpr(0);3941if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) {3942S.Diag(AL.getEllipsisLoc(),3943diag::err_pack_expansion_without_parameter_packs);3944return;3945}39463947if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))3948return;39493950S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());3951}39523953/// Perform checking of type validity3954///3955/// C++11 [dcl.align]p1:3956/// An alignment-specifier may be applied to a variable or to a class3957/// data member, but it shall not be applied to a bit-field, a function3958/// parameter, the formal parameter of a catch clause, or a variable3959/// declared with the register storage class specifier. An3960/// alignment-specifier may also be applied to the declaration of a class3961/// or enumeration type.3962/// CWG 2354:3963/// CWG agreed to remove permission for alignas to be applied to3964/// enumerations.3965/// C11 6.7.5/2:3966/// An alignment attribute shall not be specified in a declaration of3967/// a typedef, or a bit-field, or a function, or a parameter, or an3968/// object declared with the register storage-class specifier.3969static bool validateAlignasAppliedType(Sema &S, Decl *D,3970const AlignedAttr &Attr,3971SourceLocation AttrLoc) {3972int DiagKind = -1;3973if (isa<ParmVarDecl>(D)) {3974DiagKind = 0;3975} else if (const auto *VD = dyn_cast<VarDecl>(D)) {3976if (VD->getStorageClass() == SC_Register)3977DiagKind = 1;3978if (VD->isExceptionVariable())3979DiagKind = 2;3980} else if (const auto *FD = dyn_cast<FieldDecl>(D)) {3981if (FD->isBitField())3982DiagKind = 3;3983} else if (const auto *ED = dyn_cast<EnumDecl>(D)) {3984if (ED->getLangOpts().CPlusPlus)3985DiagKind = 4;3986} else if (!isa<TagDecl>(D)) {3987return S.Diag(AttrLoc, diag::err_attribute_wrong_decl_type)3988<< &Attr << Attr.isRegularKeywordAttribute()3989<< (Attr.isC11() ? ExpectedVariableOrField3990: ExpectedVariableFieldOrTag);3991}3992if (DiagKind != -1) {3993return S.Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)3994<< &Attr << DiagKind;3995}3996return false;3997}39983999void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,4000bool IsPackExpansion) {4001AlignedAttr TmpAttr(Context, CI, true, E);4002SourceLocation AttrLoc = CI.getLoc();40034004// C++11 alignas(...) and C11 _Alignas(...) have additional requirements.4005if (TmpAttr.isAlignas() &&4006validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))4007return;40084009if (E->isValueDependent()) {4010// We can't support a dependent alignment on a non-dependent type,4011// because we have no way to model that a type is "alignment-dependent"4012// but not dependent in any other way.4013if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {4014if (!TND->getUnderlyingType()->isDependentType()) {4015Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)4016<< E->getSourceRange();4017return;4018}4019}40204021// Save dependent expressions in the AST to be instantiated.4022AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);4023AA->setPackExpansion(IsPackExpansion);4024D->addAttr(AA);4025return;4026}40274028// FIXME: Cache the number on the AL object?4029llvm::APSInt Alignment;4030ExprResult ICE = VerifyIntegerConstantExpression(4031E, &Alignment, diag::err_aligned_attribute_argument_not_int);4032if (ICE.isInvalid())4033return;40344035uint64_t MaximumAlignment = Sema::MaximumAlignment;4036if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())4037MaximumAlignment = std::min(MaximumAlignment, uint64_t(8192));4038if (Alignment > MaximumAlignment) {4039Diag(AttrLoc, diag::err_attribute_aligned_too_great)4040<< MaximumAlignment << E->getSourceRange();4041return;4042}40434044uint64_t AlignVal = Alignment.getZExtValue();4045// C++11 [dcl.align]p2:4046// -- if the constant expression evaluates to zero, the alignment4047// specifier shall have no effect4048// C11 6.7.5p6:4049// An alignment specification of zero has no effect.4050if (!(TmpAttr.isAlignas() && !Alignment)) {4051if (!llvm::isPowerOf2_64(AlignVal)) {4052Diag(AttrLoc, diag::err_alignment_not_power_of_two)4053<< E->getSourceRange();4054return;4055}4056}40574058const auto *VD = dyn_cast<VarDecl>(D);4059if (VD) {4060unsigned MaxTLSAlign =4061Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())4062.getQuantity();4063if (MaxTLSAlign && AlignVal > MaxTLSAlign &&4064VD->getTLSKind() != VarDecl::TLS_None) {4065Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)4066<< (unsigned)AlignVal << VD << MaxTLSAlign;4067return;4068}4069}40704071// On AIX, an aligned attribute can not decrease the alignment when applied4072// to a variable declaration with vector type.4073if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {4074const Type *Ty = VD->getType().getTypePtr();4075if (Ty->isVectorType() && AlignVal < 16) {4076Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)4077<< VD->getType() << 16;4078return;4079}4080}40814082AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());4083AA->setPackExpansion(IsPackExpansion);4084AA->setCachedAlignmentValue(4085static_cast<unsigned>(AlignVal * Context.getCharWidth()));4086D->addAttr(AA);4087}40884089void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,4090TypeSourceInfo *TS, bool IsPackExpansion) {4091AlignedAttr TmpAttr(Context, CI, false, TS);4092SourceLocation AttrLoc = CI.getLoc();40934094// C++11 alignas(...) and C11 _Alignas(...) have additional requirements.4095if (TmpAttr.isAlignas() &&4096validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))4097return;40984099if (TS->getType()->isDependentType()) {4100// We can't support a dependent alignment on a non-dependent type,4101// because we have no way to model that a type is "type-dependent"4102// but not dependent in any other way.4103if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {4104if (!TND->getUnderlyingType()->isDependentType()) {4105Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)4106<< TS->getTypeLoc().getSourceRange();4107return;4108}4109}41104111AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);4112AA->setPackExpansion(IsPackExpansion);4113D->addAttr(AA);4114return;4115}41164117const auto *VD = dyn_cast<VarDecl>(D);4118unsigned AlignVal = TmpAttr.getAlignment(Context);4119// On AIX, an aligned attribute can not decrease the alignment when applied4120// to a variable declaration with vector type.4121if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {4122const Type *Ty = VD->getType().getTypePtr();4123if (Ty->isVectorType() &&4124Context.toCharUnitsFromBits(AlignVal).getQuantity() < 16) {4125Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)4126<< VD->getType() << 16;4127return;4128}4129}41304131AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);4132AA->setPackExpansion(IsPackExpansion);4133AA->setCachedAlignmentValue(AlignVal);4134D->addAttr(AA);4135}41364137void Sema::CheckAlignasUnderalignment(Decl *D) {4138assert(D->hasAttrs() && "no attributes on decl");41394140QualType UnderlyingTy, DiagTy;4141if (const auto *VD = dyn_cast<ValueDecl>(D)) {4142UnderlyingTy = DiagTy = VD->getType();4143} else {4144UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));4145if (const auto *ED = dyn_cast<EnumDecl>(D))4146UnderlyingTy = ED->getIntegerType();4147}4148if (DiagTy->isDependentType() || DiagTy->isIncompleteType())4149return;41504151// C++11 [dcl.align]p5, C11 6.7.5/4:4152// The combined effect of all alignment attributes in a declaration shall4153// not specify an alignment that is less strict than the alignment that4154// would otherwise be required for the entity being declared.4155AlignedAttr *AlignasAttr = nullptr;4156AlignedAttr *LastAlignedAttr = nullptr;4157unsigned Align = 0;4158for (auto *I : D->specific_attrs<AlignedAttr>()) {4159if (I->isAlignmentDependent())4160return;4161if (I->isAlignas())4162AlignasAttr = I;4163Align = std::max(Align, I->getAlignment(Context));4164LastAlignedAttr = I;4165}41664167if (Align && DiagTy->isSizelessType()) {4168Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)4169<< LastAlignedAttr << DiagTy;4170} else if (AlignasAttr && Align) {4171CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);4172CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);4173if (NaturalAlign > RequestedAlign)4174Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)4175<< DiagTy << (unsigned)NaturalAlign.getQuantity();4176}4177}41784179bool Sema::checkMSInheritanceAttrOnDefinition(4180CXXRecordDecl *RD, SourceRange Range, bool BestCase,4181MSInheritanceModel ExplicitModel) {4182assert(RD->hasDefinition() && "RD has no definition!");41834184// We may not have seen base specifiers or any virtual methods yet. We will4185// have to wait until the record is defined to catch any mismatches.4186if (!RD->getDefinition()->isCompleteDefinition())4187return false;41884189// The unspecified model never matches what a definition could need.4190if (ExplicitModel == MSInheritanceModel::Unspecified)4191return false;41924193if (BestCase) {4194if (RD->calculateInheritanceModel() == ExplicitModel)4195return false;4196} else {4197if (RD->calculateInheritanceModel() <= ExplicitModel)4198return false;4199}42004201Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)4202<< 0 /*definition*/;4203Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;4204return true;4205}42064207/// parseModeAttrArg - Parses attribute mode string and returns parsed type4208/// attribute.4209static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,4210bool &IntegerMode, bool &ComplexMode,4211FloatModeKind &ExplicitType) {4212IntegerMode = true;4213ComplexMode = false;4214ExplicitType = FloatModeKind::NoFloat;4215switch (Str.size()) {4216case 2:4217switch (Str[0]) {4218case 'Q':4219DestWidth = 8;4220break;4221case 'H':4222DestWidth = 16;4223break;4224case 'S':4225DestWidth = 32;4226break;4227case 'D':4228DestWidth = 64;4229break;4230case 'X':4231DestWidth = 96;4232break;4233case 'K': // KFmode - IEEE quad precision (__float128)4234ExplicitType = FloatModeKind::Float128;4235DestWidth = Str[1] == 'I' ? 0 : 128;4236break;4237case 'T':4238ExplicitType = FloatModeKind::LongDouble;4239DestWidth = 128;4240break;4241case 'I':4242ExplicitType = FloatModeKind::Ibm128;4243DestWidth = Str[1] == 'I' ? 0 : 128;4244break;4245}4246if (Str[1] == 'F') {4247IntegerMode = false;4248} else if (Str[1] == 'C') {4249IntegerMode = false;4250ComplexMode = true;4251} else if (Str[1] != 'I') {4252DestWidth = 0;4253}4254break;4255case 4:4256// FIXME: glibc uses 'word' to define register_t; this is narrower than a4257// pointer on PIC16 and other embedded platforms.4258if (Str == "word")4259DestWidth = S.Context.getTargetInfo().getRegisterWidth();4260else if (Str == "byte")4261DestWidth = S.Context.getTargetInfo().getCharWidth();4262break;4263case 7:4264if (Str == "pointer")4265DestWidth = S.Context.getTargetInfo().getPointerWidth(LangAS::Default);4266break;4267case 11:4268if (Str == "unwind_word")4269DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();4270break;4271}4272}42734274/// handleModeAttr - This attribute modifies the width of a decl with primitive4275/// type.4276///4277/// Despite what would be logical, the mode attribute is a decl attribute, not a4278/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be4279/// HImode, not an intermediate pointer.4280static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4281// This attribute isn't documented, but glibc uses it. It changes4282// the width of an int or unsigned int to the specified size.4283if (!AL.isArgIdent(0)) {4284S.Diag(AL.getLoc(), diag::err_attribute_argument_type)4285<< AL << AANT_ArgumentIdentifier;4286return;4287}42884289IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident;42904291S.AddModeAttr(D, AL, Name);4292}42934294void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,4295IdentifierInfo *Name, bool InInstantiation) {4296StringRef Str = Name->getName();4297normalizeName(Str);4298SourceLocation AttrLoc = CI.getLoc();42994300unsigned DestWidth = 0;4301bool IntegerMode = true;4302bool ComplexMode = false;4303FloatModeKind ExplicitType = FloatModeKind::NoFloat;4304llvm::APInt VectorSize(64, 0);4305if (Str.size() >= 4 && Str[0] == 'V') {4306// Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).4307size_t StrSize = Str.size();4308size_t VectorStringLength = 0;4309while ((VectorStringLength + 1) < StrSize &&4310isdigit(Str[VectorStringLength + 1]))4311++VectorStringLength;4312if (VectorStringLength &&4313!Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&4314VectorSize.isPowerOf2()) {4315parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,4316IntegerMode, ComplexMode, ExplicitType);4317// Avoid duplicate warning from template instantiation.4318if (!InInstantiation)4319Diag(AttrLoc, diag::warn_vector_mode_deprecated);4320} else {4321VectorSize = 0;4322}4323}43244325if (!VectorSize)4326parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,4327ExplicitType);43284329// FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t4330// and friends, at least with glibc.4331// FIXME: Make sure floating-point mappings are accurate4332// FIXME: Support XF and TF types4333if (!DestWidth) {4334Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;4335return;4336}43374338QualType OldTy;4339if (const auto *TD = dyn_cast<TypedefNameDecl>(D))4340OldTy = TD->getUnderlyingType();4341else if (const auto *ED = dyn_cast<EnumDecl>(D)) {4342// Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.4343// Try to get type from enum declaration, default to int.4344OldTy = ED->getIntegerType();4345if (OldTy.isNull())4346OldTy = Context.IntTy;4347} else4348OldTy = cast<ValueDecl>(D)->getType();43494350if (OldTy->isDependentType()) {4351D->addAttr(::new (Context) ModeAttr(Context, CI, Name));4352return;4353}43544355// Base type can also be a vector type (see PR17453).4356// Distinguish between base type and base element type.4357QualType OldElemTy = OldTy;4358if (const auto *VT = OldTy->getAs<VectorType>())4359OldElemTy = VT->getElementType();43604361// GCC allows 'mode' attribute on enumeration types (even incomplete), except4362// for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete4363// type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.4364if ((isa<EnumDecl>(D) || OldElemTy->getAs<EnumType>()) &&4365VectorSize.getBoolValue()) {4366Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();4367return;4368}4369bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&4370!OldElemTy->isBitIntType()) ||4371OldElemTy->getAs<EnumType>();43724373if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&4374!IntegralOrAnyEnumType)4375Diag(AttrLoc, diag::err_mode_not_primitive);4376else if (IntegerMode) {4377if (!IntegralOrAnyEnumType)4378Diag(AttrLoc, diag::err_mode_wrong_type);4379} else if (ComplexMode) {4380if (!OldElemTy->isComplexType())4381Diag(AttrLoc, diag::err_mode_wrong_type);4382} else {4383if (!OldElemTy->isFloatingType())4384Diag(AttrLoc, diag::err_mode_wrong_type);4385}43864387QualType NewElemTy;43884389if (IntegerMode)4390NewElemTy = Context.getIntTypeForBitwidth(DestWidth,4391OldElemTy->isSignedIntegerType());4392else4393NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);43944395if (NewElemTy.isNull()) {4396// Only emit diagnostic on host for 128-bit mode attribute4397if (!(DestWidth == 128 && getLangOpts().CUDAIsDevice))4398Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;4399return;4400}44014402if (ComplexMode) {4403NewElemTy = Context.getComplexType(NewElemTy);4404}44054406QualType NewTy = NewElemTy;4407if (VectorSize.getBoolValue()) {4408NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(),4409VectorKind::Generic);4410} else if (const auto *OldVT = OldTy->getAs<VectorType>()) {4411// Complex machine mode does not support base vector types.4412if (ComplexMode) {4413Diag(AttrLoc, diag::err_complex_mode_vector_type);4414return;4415}4416unsigned NumElements = Context.getTypeSize(OldElemTy) *4417OldVT->getNumElements() /4418Context.getTypeSize(NewElemTy);4419NewTy =4420Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());4421}44224423if (NewTy.isNull()) {4424Diag(AttrLoc, diag::err_mode_wrong_type);4425return;4426}44274428// Install the new type.4429if (auto *TD = dyn_cast<TypedefNameDecl>(D))4430TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);4431else if (auto *ED = dyn_cast<EnumDecl>(D))4432ED->setIntegerType(NewTy);4433else4434cast<ValueDecl>(D)->setType(NewTy);44354436D->addAttr(::new (Context) ModeAttr(Context, CI, Name));4437}44384439static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4440D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));4441}44424443AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,4444const AttributeCommonInfo &CI,4445const IdentifierInfo *Ident) {4446if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {4447Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;4448Diag(Optnone->getLocation(), diag::note_conflicting_attribute);4449return nullptr;4450}44514452if (D->hasAttr<AlwaysInlineAttr>())4453return nullptr;44544455return ::new (Context) AlwaysInlineAttr(Context, CI);4456}44574458InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,4459const ParsedAttr &AL) {4460if (const auto *VD = dyn_cast<VarDecl>(D)) {4461// Attribute applies to Var but not any subclass of it (like ParmVar,4462// ImplicitParm or VarTemplateSpecialization).4463if (VD->getKind() != Decl::Var) {4464Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)4465<< AL << AL.isRegularKeywordAttribute()4466<< (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass4467: ExpectedVariableOrFunction);4468return nullptr;4469}4470// Attribute does not apply to non-static local variables.4471if (VD->hasLocalStorage()) {4472Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);4473return nullptr;4474}4475}44764477return ::new (Context) InternalLinkageAttr(Context, AL);4478}4479InternalLinkageAttr *4480Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {4481if (const auto *VD = dyn_cast<VarDecl>(D)) {4482// Attribute applies to Var but not any subclass of it (like ParmVar,4483// ImplicitParm or VarTemplateSpecialization).4484if (VD->getKind() != Decl::Var) {4485Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)4486<< &AL << AL.isRegularKeywordAttribute()4487<< (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass4488: ExpectedVariableOrFunction);4489return nullptr;4490}4491// Attribute does not apply to non-static local variables.4492if (VD->hasLocalStorage()) {4493Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);4494return nullptr;4495}4496}44974498return ::new (Context) InternalLinkageAttr(Context, AL);4499}45004501MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {4502if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {4503Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";4504Diag(Optnone->getLocation(), diag::note_conflicting_attribute);4505return nullptr;4506}45074508if (D->hasAttr<MinSizeAttr>())4509return nullptr;45104511return ::new (Context) MinSizeAttr(Context, CI);4512}45134514OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,4515const AttributeCommonInfo &CI) {4516if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {4517Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;4518Diag(CI.getLoc(), diag::note_conflicting_attribute);4519D->dropAttr<AlwaysInlineAttr>();4520}4521if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {4522Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;4523Diag(CI.getLoc(), diag::note_conflicting_attribute);4524D->dropAttr<MinSizeAttr>();4525}45264527if (D->hasAttr<OptimizeNoneAttr>())4528return nullptr;45294530return ::new (Context) OptimizeNoneAttr(Context, CI);4531}45324533static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4534if (AlwaysInlineAttr *Inline =4535S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))4536D->addAttr(Inline);4537}45384539static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4540if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))4541D->addAttr(MinSize);4542}45434544static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4545if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))4546D->addAttr(Optnone);4547}45484549static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4550const auto *VD = cast<VarDecl>(D);4551if (VD->hasLocalStorage()) {4552S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);4553return;4554}4555// constexpr variable may already get an implicit constant attr, which should4556// be replaced by the explicit constant attr.4557if (auto *A = D->getAttr<CUDAConstantAttr>()) {4558if (!A->isImplicit())4559return;4560D->dropAttr<CUDAConstantAttr>();4561}4562D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));4563}45644565static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4566const auto *VD = cast<VarDecl>(D);4567// extern __shared__ is only allowed on arrays with no length (e.g.4568// "int x[]").4569if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&4570!isa<IncompleteArrayType>(VD->getType())) {4571S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;4572return;4573}4574if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&4575S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)4576<< llvm::to_underlying(S.CUDA().CurrentTarget()))4577return;4578D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));4579}45804581static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4582const auto *FD = cast<FunctionDecl>(D);4583if (!FD->getReturnType()->isVoidType() &&4584!FD->getReturnType()->getAs<AutoType>() &&4585!FD->getReturnType()->isInstantiationDependentType()) {4586SourceRange RTRange = FD->getReturnTypeSourceRange();4587S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)4588<< FD->getType()4589<< (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")4590: FixItHint());4591return;4592}4593if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {4594if (Method->isInstance()) {4595S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)4596<< Method;4597return;4598}4599S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;4600}4601// Only warn for "inline" when compiling for host, to cut down on noise.4602if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)4603S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;46044605if (AL.getKind() == ParsedAttr::AT_NVPTXKernel)4606D->addAttr(::new (S.Context) NVPTXKernelAttr(S.Context, AL));4607else4608D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));4609// In host compilation the kernel is emitted as a stub function, which is4610// a helper function for launching the kernel. The instructions in the helper4611// function has nothing to do with the source code of the kernel. Do not emit4612// debug info for the stub function to avoid confusing the debugger.4613if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)4614D->addAttr(NoDebugAttr::CreateImplicit(S.Context));4615}46164617static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4618if (const auto *VD = dyn_cast<VarDecl>(D)) {4619if (VD->hasLocalStorage()) {4620S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);4621return;4622}4623}46244625if (auto *A = D->getAttr<CUDADeviceAttr>()) {4626if (!A->isImplicit())4627return;4628D->dropAttr<CUDADeviceAttr>();4629}4630D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));4631}46324633static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4634if (const auto *VD = dyn_cast<VarDecl>(D)) {4635if (VD->hasLocalStorage()) {4636S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);4637return;4638}4639}4640if (!D->hasAttr<HIPManagedAttr>())4641D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));4642if (!D->hasAttr<CUDADeviceAttr>())4643D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));4644}46454646static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4647const auto *Fn = cast<FunctionDecl>(D);4648if (!Fn->isInlineSpecified()) {4649S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);4650return;4651}46524653if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)4654S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);46554656D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));4657}46584659static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4660if (hasDeclarator(D)) return;46614662// Diagnostic is emitted elsewhere: here we store the (valid) AL4663// in the Decl node for syntactic reasoning, e.g., pretty-printing.4664CallingConv CC;4665if (S.CheckCallingConvAttr(4666AL, CC, /*FD*/ nullptr,4667S.CUDA().IdentifyTarget(dyn_cast<FunctionDecl>(D))))4668return;46694670if (!isa<ObjCMethodDecl>(D)) {4671S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)4672<< AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;4673return;4674}46754676switch (AL.getKind()) {4677case ParsedAttr::AT_FastCall:4678D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));4679return;4680case ParsedAttr::AT_StdCall:4681D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));4682return;4683case ParsedAttr::AT_ThisCall:4684D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));4685return;4686case ParsedAttr::AT_CDecl:4687D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));4688return;4689case ParsedAttr::AT_Pascal:4690D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));4691return;4692case ParsedAttr::AT_SwiftCall:4693D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));4694return;4695case ParsedAttr::AT_SwiftAsyncCall:4696D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));4697return;4698case ParsedAttr::AT_VectorCall:4699D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));4700return;4701case ParsedAttr::AT_MSABI:4702D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));4703return;4704case ParsedAttr::AT_SysVABI:4705D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));4706return;4707case ParsedAttr::AT_RegCall:4708D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));4709return;4710case ParsedAttr::AT_Pcs: {4711PcsAttr::PCSType PCS;4712switch (CC) {4713case CC_AAPCS:4714PCS = PcsAttr::AAPCS;4715break;4716case CC_AAPCS_VFP:4717PCS = PcsAttr::AAPCS_VFP;4718break;4719default:4720llvm_unreachable("unexpected calling convention in pcs attribute");4721}47224723D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));4724return;4725}4726case ParsedAttr::AT_AArch64VectorPcs:4727D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));4728return;4729case ParsedAttr::AT_AArch64SVEPcs:4730D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));4731return;4732case ParsedAttr::AT_AMDGPUKernelCall:4733D->addAttr(::new (S.Context) AMDGPUKernelCallAttr(S.Context, AL));4734return;4735case ParsedAttr::AT_IntelOclBicc:4736D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));4737return;4738case ParsedAttr::AT_PreserveMost:4739D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));4740return;4741case ParsedAttr::AT_PreserveAll:4742D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));4743return;4744case ParsedAttr::AT_M68kRTD:4745D->addAttr(::new (S.Context) M68kRTDAttr(S.Context, AL));4746return;4747case ParsedAttr::AT_PreserveNone:4748D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));4749return;4750case ParsedAttr::AT_RISCVVectorCC:4751D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));4752return;4753default:4754llvm_unreachable("unexpected attribute kind");4755}4756}47574758static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4759if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {4760// Suppression attribute with GSL spelling requires at least 1 argument.4761if (!AL.checkAtLeastNumArgs(S, 1))4762return;4763}47644765std::vector<StringRef> DiagnosticIdentifiers;4766for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {4767StringRef RuleName;47684769if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr))4770return;47714772DiagnosticIdentifiers.push_back(RuleName);4773}4774D->addAttr(::new (S.Context)4775SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),4776DiagnosticIdentifiers.size()));4777}47784779static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4780TypeSourceInfo *DerefTypeLoc = nullptr;4781QualType ParmType;4782if (AL.hasParsedType()) {4783ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);47844785unsigned SelectIdx = ~0U;4786if (ParmType->isReferenceType())4787SelectIdx = 0;4788else if (ParmType->isArrayType())4789SelectIdx = 1;47904791if (SelectIdx != ~0U) {4792S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)4793<< SelectIdx << AL;4794return;4795}4796}47974798// To check if earlier decl attributes do not conflict the newly parsed ones4799// we always add (and check) the attribute to the canonical decl. We need4800// to repeat the check for attribute mutual exclusion because we're attaching4801// all of the attributes to the canonical declaration rather than the current4802// declaration.4803D = D->getCanonicalDecl();4804if (AL.getKind() == ParsedAttr::AT_Owner) {4805if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))4806return;4807if (const auto *OAttr = D->getAttr<OwnerAttr>()) {4808const Type *ExistingDerefType = OAttr->getDerefTypeLoc()4809? OAttr->getDerefType().getTypePtr()4810: nullptr;4811if (ExistingDerefType != ParmType.getTypePtrOrNull()) {4812S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)4813<< AL << OAttr4814<< (AL.isRegularKeywordAttribute() ||4815OAttr->isRegularKeywordAttribute());4816S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);4817}4818return;4819}4820for (Decl *Redecl : D->redecls()) {4821Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));4822}4823} else {4824if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))4825return;4826if (const auto *PAttr = D->getAttr<PointerAttr>()) {4827const Type *ExistingDerefType = PAttr->getDerefTypeLoc()4828? PAttr->getDerefType().getTypePtr()4829: nullptr;4830if (ExistingDerefType != ParmType.getTypePtrOrNull()) {4831S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)4832<< AL << PAttr4833<< (AL.isRegularKeywordAttribute() ||4834PAttr->isRegularKeywordAttribute());4835S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);4836}4837return;4838}4839for (Decl *Redecl : D->redecls()) {4840Redecl->addAttr(::new (S.Context)4841PointerAttr(S.Context, AL, DerefTypeLoc));4842}4843}4844}48454846static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {4847if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))4848return;4849if (!D->hasAttr<RandomizeLayoutAttr>())4850D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));4851}48524853static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,4854const ParsedAttr &AL) {4855if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))4856return;4857if (!D->hasAttr<NoRandomizeLayoutAttr>())4858D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));4859}48604861bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,4862const FunctionDecl *FD,4863CUDAFunctionTarget CFT) {4864if (Attrs.isInvalid())4865return true;48664867if (Attrs.hasProcessingCache()) {4868CC = (CallingConv) Attrs.getProcessingCache();4869return false;4870}48714872unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;4873if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) {4874Attrs.setInvalid();4875return true;4876}48774878// TODO: diagnose uses of these conventions on the wrong target.4879switch (Attrs.getKind()) {4880case ParsedAttr::AT_CDecl:4881CC = CC_C;4882break;4883case ParsedAttr::AT_FastCall:4884CC = CC_X86FastCall;4885break;4886case ParsedAttr::AT_StdCall:4887CC = CC_X86StdCall;4888break;4889case ParsedAttr::AT_ThisCall:4890CC = CC_X86ThisCall;4891break;4892case ParsedAttr::AT_Pascal:4893CC = CC_X86Pascal;4894break;4895case ParsedAttr::AT_SwiftCall:4896CC = CC_Swift;4897break;4898case ParsedAttr::AT_SwiftAsyncCall:4899CC = CC_SwiftAsync;4900break;4901case ParsedAttr::AT_VectorCall:4902CC = CC_X86VectorCall;4903break;4904case ParsedAttr::AT_AArch64VectorPcs:4905CC = CC_AArch64VectorCall;4906break;4907case ParsedAttr::AT_AArch64SVEPcs:4908CC = CC_AArch64SVEPCS;4909break;4910case ParsedAttr::AT_AMDGPUKernelCall:4911CC = CC_AMDGPUKernelCall;4912break;4913case ParsedAttr::AT_RegCall:4914CC = CC_X86RegCall;4915break;4916case ParsedAttr::AT_MSABI:4917CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :4918CC_Win64;4919break;4920case ParsedAttr::AT_SysVABI:4921CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :4922CC_C;4923break;4924case ParsedAttr::AT_Pcs: {4925StringRef StrRef;4926if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) {4927Attrs.setInvalid();4928return true;4929}4930if (StrRef == "aapcs") {4931CC = CC_AAPCS;4932break;4933} else if (StrRef == "aapcs-vfp") {4934CC = CC_AAPCS_VFP;4935break;4936}49374938Attrs.setInvalid();4939Diag(Attrs.getLoc(), diag::err_invalid_pcs);4940return true;4941}4942case ParsedAttr::AT_IntelOclBicc:4943CC = CC_IntelOclBicc;4944break;4945case ParsedAttr::AT_PreserveMost:4946CC = CC_PreserveMost;4947break;4948case ParsedAttr::AT_PreserveAll:4949CC = CC_PreserveAll;4950break;4951case ParsedAttr::AT_M68kRTD:4952CC = CC_M68kRTD;4953break;4954case ParsedAttr::AT_PreserveNone:4955CC = CC_PreserveNone;4956break;4957case ParsedAttr::AT_RISCVVectorCC:4958CC = CC_RISCVVectorCall;4959break;4960default: llvm_unreachable("unexpected attribute kind");4961}49624963TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;4964const TargetInfo &TI = Context.getTargetInfo();4965// CUDA functions may have host and/or device attributes which indicate4966// their targeted execution environment, therefore the calling convention4967// of functions in CUDA should be checked against the target deduced based4968// on their host/device attributes.4969if (LangOpts.CUDA) {4970auto *Aux = Context.getAuxTargetInfo();4971assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);4972auto CudaTarget = FD ? CUDA().IdentifyTarget(FD) : CFT;4973bool CheckHost = false, CheckDevice = false;4974switch (CudaTarget) {4975case CUDAFunctionTarget::HostDevice:4976CheckHost = true;4977CheckDevice = true;4978break;4979case CUDAFunctionTarget::Host:4980CheckHost = true;4981break;4982case CUDAFunctionTarget::Device:4983case CUDAFunctionTarget::Global:4984CheckDevice = true;4985break;4986case CUDAFunctionTarget::InvalidTarget:4987llvm_unreachable("unexpected cuda target");4988}4989auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;4990auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;4991if (CheckHost && HostTI)4992A = HostTI->checkCallingConvention(CC);4993if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)4994A = DeviceTI->checkCallingConvention(CC);4995} else {4996A = TI.checkCallingConvention(CC);4997}49984999switch (A) {5000case TargetInfo::CCCR_OK:5001break;50025003case TargetInfo::CCCR_Ignore:5004// Treat an ignored convention as if it was an explicit C calling convention5005// attribute. For example, __stdcall on Win x64 functions as __cdecl, so5006// that command line flags that change the default convention to5007// __vectorcall don't affect declarations marked __stdcall.5008CC = CC_C;5009break;50105011case TargetInfo::CCCR_Error:5012Diag(Attrs.getLoc(), diag::error_cconv_unsupported)5013<< Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;5014break;50155016case TargetInfo::CCCR_Warning: {5017Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)5018<< Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;50195020// This convention is not valid for the target. Use the default function or5021// method calling convention.5022bool IsCXXMethod = false, IsVariadic = false;5023if (FD) {5024IsCXXMethod = FD->isCXXInstanceMember();5025IsVariadic = FD->isVariadic();5026}5027CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);5028break;5029}5030}50315032Attrs.setProcessingCache((unsigned) CC);5033return false;5034}50355036bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {5037if (AL.isInvalid())5038return true;50395040if (!AL.checkExactlyNumArgs(*this, 1)) {5041AL.setInvalid();5042return true;5043}50445045uint32_t NP;5046Expr *NumParamsExpr = AL.getArgAsExpr(0);5047if (!checkUInt32Argument(AL, NumParamsExpr, NP)) {5048AL.setInvalid();5049return true;5050}50515052if (Context.getTargetInfo().getRegParmMax() == 0) {5053Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)5054<< NumParamsExpr->getSourceRange();5055AL.setInvalid();5056return true;5057}50585059numParams = NP;5060if (numParams > Context.getTargetInfo().getRegParmMax()) {5061Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)5062<< Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();5063AL.setInvalid();5064return true;5065}50665067return false;5068}50695070// Helper to get OffloadArch.5071static OffloadArch getOffloadArch(const TargetInfo &TI) {5072if (!TI.getTriple().isNVPTX())5073llvm_unreachable("getOffloadArch is only valid for NVPTX triple");5074auto &TO = TI.getTargetOpts();5075return StringToOffloadArch(TO.CPU);5076}50775078// Checks whether an argument of launch_bounds attribute is5079// acceptable, performs implicit conversion to Rvalue, and returns5080// non-nullptr Expr result on success. Otherwise, it returns nullptr5081// and may output an error.5082static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,5083const CUDALaunchBoundsAttr &AL,5084const unsigned Idx) {5085if (S.DiagnoseUnexpandedParameterPack(E))5086return nullptr;50875088// Accept template arguments for now as they depend on something else.5089// We'll get to check them when they eventually get instantiated.5090if (E->isValueDependent())5091return E;50925093std::optional<llvm::APSInt> I = llvm::APSInt(64);5094if (!(I = E->getIntegerConstantExpr(S.Context))) {5095S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)5096<< &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();5097return nullptr;5098}5099// Make sure we can fit it in 32 bits.5100if (!I->isIntN(32)) {5101S.Diag(E->getExprLoc(), diag::err_ice_too_large)5102<< toString(*I, 10, false) << 32 << /* Unsigned */ 1;5103return nullptr;5104}5105if (*I < 0)5106S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)5107<< &AL << Idx << E->getSourceRange();51085109// We may need to perform implicit conversion of the argument.5110InitializedEntity Entity = InitializedEntity::InitializeParameter(5111S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);5112ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);5113assert(!ValArg.isInvalid() &&5114"Unexpected PerformCopyInitialization() failure.");51155116return ValArg.getAs<Expr>();5117}51185119CUDALaunchBoundsAttr *5120Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads,5121Expr *MinBlocks, Expr *MaxBlocks) {5122CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);5123MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);5124if (!MaxThreads)5125return nullptr;51265127if (MinBlocks) {5128MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);5129if (!MinBlocks)5130return nullptr;5131}51325133if (MaxBlocks) {5134// '.maxclusterrank' ptx directive requires .target sm_90 or higher.5135auto SM = getOffloadArch(Context.getTargetInfo());5136if (SM == OffloadArch::UNKNOWN || SM < OffloadArch::SM_90) {5137Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)5138<< OffloadArchToString(SM) << CI << MaxBlocks->getSourceRange();5139// Ignore it by setting MaxBlocks to null;5140MaxBlocks = nullptr;5141} else {5142MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2);5143if (!MaxBlocks)5144return nullptr;5145}5146}51475148return ::new (Context)5149CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);5150}51515152void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,5153Expr *MaxThreads, Expr *MinBlocks,5154Expr *MaxBlocks) {5155if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))5156D->addAttr(Attr);5157}51585159static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5160if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))5161return;51625163S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),5164AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,5165AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);5166}51675168static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,5169const ParsedAttr &AL) {5170if (!AL.isArgIdent(0)) {5171S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)5172<< AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;5173return;5174}51755176ParamIdx ArgumentIdx;5177if (!S.checkFunctionOrMethodParameterIndex(D, AL, 2, AL.getArgAsExpr(1),5178ArgumentIdx))5179return;51805181ParamIdx TypeTagIdx;5182if (!S.checkFunctionOrMethodParameterIndex(D, AL, 3, AL.getArgAsExpr(2),5183TypeTagIdx))5184return;51855186bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";5187if (IsPointer) {5188// Ensure that buffer has a pointer type.5189unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();5190if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||5191!getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())5192S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;5193}51945195D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(5196S.Context, AL, AL.getArgAsIdent(0)->Ident, ArgumentIdx, TypeTagIdx,5197IsPointer));5198}51995200static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,5201const ParsedAttr &AL) {5202if (!AL.isArgIdent(0)) {5203S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)5204<< AL << 1 << AANT_ArgumentIdentifier;5205return;5206}52075208if (!AL.checkExactlyNumArgs(S, 1))5209return;52105211if (!isa<VarDecl>(D)) {5212S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)5213<< AL << AL.isRegularKeywordAttribute() << ExpectedVariable;5214return;5215}52165217IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->Ident;5218TypeSourceInfo *MatchingCTypeLoc = nullptr;5219S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);5220assert(MatchingCTypeLoc && "no type source info for attribute argument");52215222D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(5223S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),5224AL.getMustBeNull()));5225}52265227static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5228ParamIdx ArgCount;52295230if (!S.checkFunctionOrMethodParameterIndex(D, AL, 1, AL.getArgAsExpr(0),5231ArgCount,5232true /* CanIndexImplicitThis */))5233return;52345235// ArgCount isn't a parameter index [0;n), it's a count [1;n]5236D->addAttr(::new (S.Context)5237XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));5238}52395240static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,5241const ParsedAttr &AL) {5242if (S.Context.getTargetInfo().getTriple().isOSAIX()) {5243S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;5244return;5245}5246uint32_t Count = 0, Offset = 0;5247if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Count, 0, true))5248return;5249if (AL.getNumArgs() == 2) {5250Expr *Arg = AL.getArgAsExpr(1);5251if (!S.checkUInt32Argument(AL, Arg, Offset, 1, true))5252return;5253if (Count < Offset) {5254S.Diag(S.getAttrLoc(AL), diag::err_attribute_argument_out_of_range)5255<< &AL << 0 << Count << Arg->getBeginLoc();5256return;5257}5258}5259D->addAttr(::new (S.Context)5260PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));5261}52625263static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5264if (!AL.isArgIdent(0)) {5265S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)5266<< AL << 1 << AANT_ArgumentIdentifier;5267return;5268}52695270IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;5271unsigned BuiltinID = Ident->getBuiltinID();5272StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();52735274bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();5275bool IsARM = S.Context.getTargetInfo().getTriple().isARM();5276bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();5277bool IsHLSL = S.Context.getLangOpts().HLSL;5278if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||5279(IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&5280!S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||5281(IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||5282(!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) {5283S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;5284return;5285}52865287D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));5288}52895290static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5291if (AL.isUsedAsTypeAttr())5292return;52935294if (auto *CRD = dyn_cast<CXXRecordDecl>(D);5295!CRD || !(CRD->isClass() || CRD->isStruct())) {5296S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type_str)5297<< AL << AL.isRegularKeywordAttribute() << "classes";5298return;5299}53005301handleSimpleAttribute<TypeNullableAttr>(S, D, AL);5302}53035304static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5305if (!AL.hasParsedType()) {5306S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;5307return;5308}53095310TypeSourceInfo *ParmTSI = nullptr;5311QualType QT = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);5312assert(ParmTSI && "no type source info for attribute argument");5313S.RequireCompleteType(ParmTSI->getTypeLoc().getBeginLoc(), QT,5314diag::err_incomplete_type);53155316D->addAttr(::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));5317}53185319//===----------------------------------------------------------------------===//5320// Microsoft specific attribute handlers.5321//===----------------------------------------------------------------------===//53225323UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,5324StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {5325if (const auto *UA = D->getAttr<UuidAttr>()) {5326if (declaresSameEntity(UA->getGuidDecl(), GuidDecl))5327return nullptr;5328if (!UA->getGuid().empty()) {5329Diag(UA->getLocation(), diag::err_mismatched_uuid);5330Diag(CI.getLoc(), diag::note_previous_uuid);5331D->dropAttr<UuidAttr>();5332}5333}53345335return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);5336}53375338static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5339if (!S.LangOpts.CPlusPlus) {5340S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)5341<< AL << AttributeLangSupport::C;5342return;5343}53445345StringRef OrigStrRef;5346SourceLocation LiteralLoc;5347if (!S.checkStringLiteralArgumentAttr(AL, 0, OrigStrRef, &LiteralLoc))5348return;53495350// GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or5351// "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.5352StringRef StrRef = OrigStrRef;5353if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')5354StrRef = StrRef.drop_front().drop_back();53555356// Validate GUID length.5357if (StrRef.size() != 36) {5358S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);5359return;5360}53615362for (unsigned i = 0; i < 36; ++i) {5363if (i == 8 || i == 13 || i == 18 || i == 23) {5364if (StrRef[i] != '-') {5365S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);5366return;5367}5368} else if (!isHexDigit(StrRef[i])) {5369S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);5370return;5371}5372}53735374// Convert to our parsed format and canonicalize.5375MSGuidDecl::Parts Parsed;5376StrRef.substr(0, 8).getAsInteger(16, Parsed.Part1);5377StrRef.substr(9, 4).getAsInteger(16, Parsed.Part2);5378StrRef.substr(14, 4).getAsInteger(16, Parsed.Part3);5379for (unsigned i = 0; i != 8; ++i)5380StrRef.substr(19 + 2 * i + (i >= 2 ? 1 : 0), 2)5381.getAsInteger(16, Parsed.Part4And5[i]);5382MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parsed);53835384// FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's5385// the only thing in the [] list, the [] too), and add an insertion of5386// __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas5387// separating attributes nor of the [ and the ] are in the AST.5388// Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"5389// on cfe-dev.5390if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.5391S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);53925393UuidAttr *UA = S.mergeUuidAttr(D, AL, OrigStrRef, Guid);5394if (UA)5395D->addAttr(UA);5396}53975398static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5399if (!S.LangOpts.CPlusPlus) {5400S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)5401<< AL << AttributeLangSupport::C;5402return;5403}5404MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(5405D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());5406if (IA) {5407D->addAttr(IA);5408S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D));5409}5410}54115412static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5413const auto *VD = cast<VarDecl>(D);5414if (!S.Context.getTargetInfo().isTLSSupported()) {5415S.Diag(AL.getLoc(), diag::err_thread_unsupported);5416return;5417}5418if (VD->getTSCSpec() != TSCS_unspecified) {5419S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable);5420return;5421}5422if (VD->hasLocalStorage()) {5423S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";5424return;5425}5426D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));5427}54285429static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5430if (!S.getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2022_3)) {5431S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)5432<< AL << AL.getRange();5433return;5434}5435auto *FD = cast<FunctionDecl>(D);5436if (FD->isConstexprSpecified() || FD->isConsteval()) {5437S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)5438<< FD->isConsteval() << FD;5439return;5440}5441if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {5442if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {5443S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)5444<< /*virtual*/ 2 << MD;5445return;5446}5447}5448D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));5449}54505451static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5452SmallVector<StringRef, 4> Tags;5453for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {5454StringRef Tag;5455if (!S.checkStringLiteralArgumentAttr(AL, I, Tag))5456return;5457Tags.push_back(Tag);5458}54595460if (const auto *NS = dyn_cast<NamespaceDecl>(D)) {5461if (!NS->isInline()) {5462S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;5463return;5464}5465if (NS->isAnonymousNamespace()) {5466S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;5467return;5468}5469if (AL.getNumArgs() == 0)5470Tags.push_back(NS->getName());5471} else if (!AL.checkAtLeastNumArgs(S, 1))5472return;54735474// Store tags sorted and without duplicates.5475llvm::sort(Tags);5476Tags.erase(std::unique(Tags.begin(), Tags.end()), Tags.end());54775478D->addAttr(::new (S.Context)5479AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));5480}54815482static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {5483for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {5484if (I->getBTFDeclTag() == Tag)5485return true;5486}5487return false;5488}54895490static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5491StringRef Str;5492if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))5493return;5494if (hasBTFDeclTagAttr(D, Str))5495return;54965497D->addAttr(::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));5498}54995500BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {5501if (hasBTFDeclTagAttr(D, AL.getBTFDeclTag()))5502return nullptr;5503return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());5504}55055506static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5507// Dispatch the interrupt attribute based on the current target.5508switch (S.Context.getTargetInfo().getTriple().getArch()) {5509case llvm::Triple::msp430:5510S.MSP430().handleInterruptAttr(D, AL);5511break;5512case llvm::Triple::mipsel:5513case llvm::Triple::mips:5514S.MIPS().handleInterruptAttr(D, AL);5515break;5516case llvm::Triple::m68k:5517S.M68k().handleInterruptAttr(D, AL);5518break;5519case llvm::Triple::x86:5520case llvm::Triple::x86_64:5521S.X86().handleAnyInterruptAttr(D, AL);5522break;5523case llvm::Triple::avr:5524S.AVR().handleInterruptAttr(D, AL);5525break;5526case llvm::Triple::riscv32:5527case llvm::Triple::riscv64:5528S.RISCV().handleInterruptAttr(D, AL);5529break;5530default:5531S.ARM().handleInterruptAttr(D, AL);5532break;5533}5534}55355536static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {5537uint32_t Version;5538Expr *VersionExpr = static_cast<Expr *>(AL.getArgAsExpr(0));5539if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Version))5540return;55415542// TODO: Investigate what happens with the next major version of MSVC.5543if (Version != LangOptions::MSVC2015 / 100) {5544S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)5545<< AL << Version << VersionExpr->getSourceRange();5546return;5547}55485549// The attribute expects a "major" version number like 19, but new versions of5550// MSVC have moved to updating the "minor", or less significant numbers, so we5551// have to multiply by 100 now.5552Version *= 100;55535554D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));5555}55565557DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,5558const AttributeCommonInfo &CI) {5559if (D->hasAttr<DLLExportAttr>()) {5560Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";5561return nullptr;5562}55635564if (D->hasAttr<DLLImportAttr>())5565return nullptr;55665567return ::new (Context) DLLImportAttr(Context, CI);5568}55695570DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,5571const AttributeCommonInfo &CI) {5572if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {5573Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;5574D->dropAttr<DLLImportAttr>();5575}55765577if (D->hasAttr<DLLExportAttr>())5578return nullptr;55795580return ::new (Context) DLLExportAttr(Context, CI);5581}55825583static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {5584if (isa<ClassTemplatePartialSpecializationDecl>(D) &&5585(S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {5586S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;5587return;5588}55895590if (const auto *FD = dyn_cast<FunctionDecl>(D)) {5591if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&5592!(S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {5593// MinGW doesn't allow dllimport on inline functions.5594S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)5595<< A;5596return;5597}5598}55995600if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {5601if ((S.Context.getTargetInfo().shouldDLLImportComdatSymbols()) &&5602MD->getParent()->isLambda()) {5603S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;5604return;5605}5606}56075608Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport5609? (Attr *)S.mergeDLLExportAttr(D, A)5610: (Attr *)S.mergeDLLImportAttr(D, A);5611if (NewAttr)5612D->addAttr(NewAttr);5613}56145615MSInheritanceAttr *5616Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,5617bool BestCase,5618MSInheritanceModel Model) {5619if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {5620if (IA->getInheritanceModel() == Model)5621return nullptr;5622Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)5623<< 1 /*previous declaration*/;5624Diag(CI.getLoc(), diag::note_previous_ms_inheritance);5625D->dropAttr<MSInheritanceAttr>();5626}56275628auto *RD = cast<CXXRecordDecl>(D);5629if (RD->hasDefinition()) {5630if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,5631Model)) {5632return nullptr;5633}5634} else {5635if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {5636Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)5637<< 1 /*partial specialization*/;5638return nullptr;5639}5640if (RD->getDescribedClassTemplate()) {5641Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)5642<< 0 /*primary template*/;5643return nullptr;5644}5645}56465647return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);5648}56495650static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5651// The capability attributes take a single string parameter for the name of5652// the capability they represent. The lockable attribute does not take any5653// parameters. However, semantically, both attributes represent the same5654// concept, and so they use the same semantic attribute. Eventually, the5655// lockable attribute will be removed.5656//5657// For backward compatibility, any capability which has no specified string5658// literal will be considered a "mutex."5659StringRef N("mutex");5660SourceLocation LiteralLoc;5661if (AL.getKind() == ParsedAttr::AT_Capability &&5662!S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc))5663return;56645665D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));5666}56675668static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5669SmallVector<Expr*, 1> Args;5670if (!checkLockFunAttrCommon(S, D, AL, Args))5671return;56725673D->addAttr(::new (S.Context)5674AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));5675}56765677static void handleAcquireCapabilityAttr(Sema &S, Decl *D,5678const ParsedAttr &AL) {5679SmallVector<Expr*, 1> Args;5680if (!checkLockFunAttrCommon(S, D, AL, Args))5681return;56825683D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),5684Args.size()));5685}56865687static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,5688const ParsedAttr &AL) {5689SmallVector<Expr*, 2> Args;5690if (!checkTryLockFunAttrCommon(S, D, AL, Args))5691return;56925693D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(5694S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));5695}56965697static void handleReleaseCapabilityAttr(Sema &S, Decl *D,5698const ParsedAttr &AL) {5699// Check that all arguments are lockable objects.5700SmallVector<Expr *, 1> Args;5701checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);57025703D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),5704Args.size()));5705}57065707static void handleRequiresCapabilityAttr(Sema &S, Decl *D,5708const ParsedAttr &AL) {5709if (!AL.checkAtLeastNumArgs(S, 1))5710return;57115712// check that all arguments are lockable objects5713SmallVector<Expr*, 1> Args;5714checkAttrArgsAreCapabilityObjs(S, D, AL, Args);5715if (Args.empty())5716return;57175718RequiresCapabilityAttr *RCA = ::new (S.Context)5719RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());57205721D->addAttr(RCA);5722}57235724static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5725if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) {5726if (NSD->isAnonymousNamespace()) {5727S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace);5728// Do not want to attach the attribute to the namespace because that will5729// cause confusing diagnostic reports for uses of declarations within the5730// namespace.5731return;5732}5733} else if (isa<UsingDecl, UnresolvedUsingTypenameDecl,5734UnresolvedUsingValueDecl>(D)) {5735S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)5736<< AL;5737return;5738}57395740// Handle the cases where the attribute has a text message.5741StringRef Str, Replacement;5742if (AL.isArgExpr(0) && AL.getArgAsExpr(0) &&5743!S.checkStringLiteralArgumentAttr(AL, 0, Str))5744return;57455746// Support a single optional message only for Declspec and [[]] spellings.5747if (AL.isDeclspecAttribute() || AL.isStandardAttributeSyntax())5748AL.checkAtMostNumArgs(S, 1);5749else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) &&5750!S.checkStringLiteralArgumentAttr(AL, 1, Replacement))5751return;57525753if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())5754S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;57555756D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));5757}57585759static bool isGlobalVar(const Decl *D) {5760if (const auto *S = dyn_cast<VarDecl>(D))5761return S->hasGlobalStorage();5762return false;5763}57645765static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {5766return Sanitizer == "address" || Sanitizer == "hwaddress" ||5767Sanitizer == "memtag";5768}57695770static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5771if (!AL.checkAtLeastNumArgs(S, 1))5772return;57735774std::vector<StringRef> Sanitizers;57755776for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {5777StringRef SanitizerName;5778SourceLocation LiteralLoc;57795780if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc))5781return;57825783if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==5784SanitizerMask() &&5785SanitizerName != "coverage")5786S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;5787else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))5788S.Diag(D->getLocation(), diag::warn_attribute_type_not_supported_global)5789<< AL << SanitizerName;5790Sanitizers.push_back(SanitizerName);5791}57925793D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),5794Sanitizers.size()));5795}57965797static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,5798const ParsedAttr &AL) {5799StringRef AttrName = AL.getAttrName()->getName();5800normalizeName(AttrName);5801StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName)5802.Case("no_address_safety_analysis", "address")5803.Case("no_sanitize_address", "address")5804.Case("no_sanitize_thread", "thread")5805.Case("no_sanitize_memory", "memory");5806if (isGlobalVar(D) && SanitizerName != "address")5807S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)5808<< AL << AL.isRegularKeywordAttribute() << ExpectedFunction;58095810// FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a5811// NoSanitizeAttr object; but we need to calculate the correct spelling list5812// index rather than incorrectly assume the index for NoSanitizeSpecificAttr5813// has the same spellings as the index for NoSanitizeAttr. We don't have a5814// general way to "translate" between the two, so this hack attempts to work5815// around the issue with hard-coded indices. This is critical for calling5816// getSpelling() or prettyPrint() on the resulting semantic attribute object5817// without failing assertions.5818unsigned TranslatedSpellingIndex = 0;5819if (AL.isStandardAttributeSyntax())5820TranslatedSpellingIndex = 1;58215822AttributeCommonInfo Info = AL;5823Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);5824D->addAttr(::new (S.Context)5825NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));5826}58275828static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5829if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))5830D->addAttr(Internal);5831}58325833static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5834// Check that the argument is a string literal.5835StringRef KindStr;5836SourceLocation LiteralLoc;5837if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))5838return;58395840ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;5841if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr, Kind)) {5842S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)5843<< AL << KindStr;5844return;5845}58465847D->dropAttr<ZeroCallUsedRegsAttr>();5848D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));5849}58505851static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {5852auto *FD = dyn_cast<FieldDecl>(D);5853assert(FD);58545855auto *CountExpr = AL.getArgAsExpr(0);5856if (!CountExpr)5857return;58585859bool CountInBytes;5860bool OrNull;5861switch (AL.getKind()) {5862case ParsedAttr::AT_CountedBy:5863CountInBytes = false;5864OrNull = false;5865break;5866case ParsedAttr::AT_CountedByOrNull:5867CountInBytes = false;5868OrNull = true;5869break;5870case ParsedAttr::AT_SizedBy:5871CountInBytes = true;5872OrNull = false;5873break;5874case ParsedAttr::AT_SizedByOrNull:5875CountInBytes = true;5876OrNull = true;5877break;5878default:5879llvm_unreachable("unexpected counted_by family attribute");5880}58815882llvm::SmallVector<TypeCoupledDeclRefInfo, 1> Decls;5883if (S.CheckCountedByAttrOnField(FD, CountExpr, Decls, CountInBytes, OrNull))5884return;58855886QualType CAT = S.BuildCountAttributedArrayOrPointerType(5887FD->getType(), CountExpr, CountInBytes, OrNull);5888FD->setType(CAT);5889}58905891static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,5892const ParsedAttr &AL) {5893StringRef KindStr;5894SourceLocation LiteralLoc;5895if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))5896return;58975898FunctionReturnThunksAttr::Kind Kind;5899if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr, Kind)) {5900S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)5901<< AL << KindStr;5902return;5903}5904// FIXME: it would be good to better handle attribute merging rather than5905// silently replacing the existing attribute, so long as it does not break5906// the expected codegen tests.5907D->dropAttr<FunctionReturnThunksAttr>();5908D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));5909}59105911static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D,5912const ParsedAttr &AL) {5913assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");5914handleSimpleAttribute<AvailableOnlyInDefaultEvalMethodAttr>(S, D, AL);5915}59165917static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5918auto *VDecl = dyn_cast<VarDecl>(D);5919if (VDecl && !VDecl->isFunctionPointerType()) {5920S.Diag(AL.getLoc(), diag::warn_attribute_ignored_non_function_pointer)5921<< AL << VDecl;5922return;5923}5924D->addAttr(NoMergeAttr::Create(S.Context, AL));5925}59265927static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5928D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));5929}59305931static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {5932if (!cast<VarDecl>(D)->hasGlobalStorage()) {5933S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)5934<< (A.getKind() == ParsedAttr::AT_AlwaysDestroy);5935return;5936}59375938if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)5939handleSimpleAttribute<AlwaysDestroyAttr>(S, D, A);5940else5941handleSimpleAttribute<NoDestroyAttr>(S, D, A);5942}59435944static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5945assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&5946"uninitialized is only valid on automatic duration variables");5947D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));5948}59495950static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5951// Check that the return type is a `typedef int kern_return_t` or a typedef5952// around it, because otherwise MIG convention checks make no sense.5953// BlockDecl doesn't store a return type, so it's annoying to check,5954// so let's skip it for now.5955if (!isa<BlockDecl>(D)) {5956QualType T = getFunctionOrMethodResultType(D);5957bool IsKernReturnT = false;5958while (const auto *TT = T->getAs<TypedefType>()) {5959IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");5960T = TT->desugar();5961}5962if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {5963S.Diag(D->getBeginLoc(),5964diag::warn_mig_server_routine_does_not_return_kern_return_t);5965return;5966}5967}59685969handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL);5970}59715972static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5973// Warn if the return type is not a pointer or reference type.5974if (auto *FD = dyn_cast<FunctionDecl>(D)) {5975QualType RetTy = FD->getReturnType();5976if (!RetTy->isPointerType() && !RetTy->isReferenceType()) {5977S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)5978<< AL.getRange() << RetTy;5979return;5980}5981}59825983handleSimpleAttribute<MSAllocatorAttr>(S, D, AL);5984}59855986static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {5987if (AL.isUsedAsTypeAttr())5988return;5989// Warn if the parameter is definitely not an output parameter.5990if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {5991if (PVD->getType()->isIntegerType()) {5992S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)5993<< AL.getRange();5994return;5995}5996}5997StringRef Argument;5998if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))5999return;6000D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));6001}60026003template<typename Attr>6004static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {6005StringRef Argument;6006if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))6007return;6008D->addAttr(Attr::Create(S.Context, Argument, AL));6009}60106011template<typename Attr>6012static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {6013D->addAttr(Attr::Create(S.Context, AL));6014}60156016static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {6017// The guard attribute takes a single identifier argument.60186019if (!AL.isArgIdent(0)) {6020S.Diag(AL.getLoc(), diag::err_attribute_argument_type)6021<< AL << AANT_ArgumentIdentifier;6022return;6023}60246025CFGuardAttr::GuardArg Arg;6026IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;6027if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {6028S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;6029return;6030}60316032D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));6033}603460356036template <typename AttrTy>6037static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {6038auto Attrs = D->specific_attrs<AttrTy>();6039auto I = llvm::find_if(Attrs,6040[Name](const AttrTy *A) {6041return A->getTCBName() == Name;6042});6043return I == Attrs.end() ? nullptr : *I;6044}60456046template <typename AttrTy, typename ConflictingAttrTy>6047static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {6048StringRef Argument;6049if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))6050return;60516052// A function cannot be have both regular and leaf membership in the same TCB.6053if (const ConflictingAttrTy *ConflictingAttr =6054findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {6055// We could attach a note to the other attribute but in this case6056// there's no need given how the two are very close to each other.6057S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)6058<< AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()6059<< Argument;60606061// Error recovery: drop the non-leaf attribute so that to suppress6062// all future warnings caused by erroneous attributes. The leaf attribute6063// needs to be kept because it can only suppresses warnings, not cause them.6064D->dropAttr<EnforceTCBAttr>();6065return;6066}60676068D->addAttr(AttrTy::Create(S.Context, Argument, AL));6069}60706071template <typename AttrTy, typename ConflictingAttrTy>6072static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {6073// Check if the new redeclaration has different leaf-ness in the same TCB.6074StringRef TCBName = AL.getTCBName();6075if (const ConflictingAttrTy *ConflictingAttr =6076findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {6077S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)6078<< ConflictingAttr->getAttrName()->getName()6079<< AL.getAttrName()->getName() << TCBName;60806081// Add a note so that the user could easily find the conflicting attribute.6082S.Diag(AL.getLoc(), diag::note_conflicting_attribute);60836084// More error recovery.6085D->dropAttr<EnforceTCBAttr>();6086return nullptr;6087}60886089ASTContext &Context = S.getASTContext();6090return ::new(Context) AttrTy(Context, AL, AL.getTCBName());6091}60926093EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {6094return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(6095*this, D, AL);6096}60976098EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr(6099Decl *D, const EnforceTCBLeafAttr &AL) {6100return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(6101*this, D, AL);6102}61036104static void handleVTablePointerAuthentication(Sema &S, Decl *D,6105const ParsedAttr &AL) {6106CXXRecordDecl *Decl = cast<CXXRecordDecl>(D);6107const uint32_t NumArgs = AL.getNumArgs();6108if (NumArgs > 4) {6109S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;6110AL.setInvalid();6111}61126113if (NumArgs == 0) {6114S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL;6115AL.setInvalid();6116return;6117}61186119if (D->getAttr<VTablePointerAuthenticationAttr>()) {6120S.Diag(AL.getLoc(), diag::err_duplicated_vtable_pointer_auth) << Decl;6121AL.setInvalid();6122}61236124auto KeyType = VTablePointerAuthenticationAttr::VPtrAuthKeyType::DefaultKey;6125if (AL.isArgIdent(0)) {6126IdentifierLoc *IL = AL.getArgAsIdent(0);6127if (!VTablePointerAuthenticationAttr::ConvertStrToVPtrAuthKeyType(6128IL->Ident->getName(), KeyType)) {6129S.Diag(IL->Loc, diag::err_invalid_authentication_key) << IL->Ident;6130AL.setInvalid();6131}6132if (KeyType == VTablePointerAuthenticationAttr::DefaultKey &&6133!S.getLangOpts().PointerAuthCalls) {6134S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 0;6135AL.setInvalid();6136}6137} else {6138S.Diag(AL.getLoc(), diag::err_attribute_argument_type)6139<< AL << AANT_ArgumentIdentifier;6140return;6141}61426143auto AddressDiversityMode = VTablePointerAuthenticationAttr::6144AddressDiscriminationMode::DefaultAddressDiscrimination;6145if (AL.getNumArgs() > 1) {6146if (AL.isArgIdent(1)) {6147IdentifierLoc *IL = AL.getArgAsIdent(1);6148if (!VTablePointerAuthenticationAttr::6149ConvertStrToAddressDiscriminationMode(IL->Ident->getName(),6150AddressDiversityMode)) {6151S.Diag(IL->Loc, diag::err_invalid_address_discrimination) << IL->Ident;6152AL.setInvalid();6153}6154if (AddressDiversityMode ==6155VTablePointerAuthenticationAttr::DefaultAddressDiscrimination &&6156!S.getLangOpts().PointerAuthCalls) {6157S.Diag(IL->Loc, diag::err_no_default_vtable_pointer_auth) << 1;6158AL.setInvalid();6159}6160} else {6161S.Diag(AL.getLoc(), diag::err_attribute_argument_type)6162<< AL << AANT_ArgumentIdentifier;6163}6164}61656166auto ED = VTablePointerAuthenticationAttr::ExtraDiscrimination::6167DefaultExtraDiscrimination;6168if (AL.getNumArgs() > 2) {6169if (AL.isArgIdent(2)) {6170IdentifierLoc *IL = AL.getArgAsIdent(2);6171if (!VTablePointerAuthenticationAttr::ConvertStrToExtraDiscrimination(6172IL->Ident->getName(), ED)) {6173S.Diag(IL->Loc, diag::err_invalid_extra_discrimination) << IL->Ident;6174AL.setInvalid();6175}6176if (ED == VTablePointerAuthenticationAttr::DefaultExtraDiscrimination &&6177!S.getLangOpts().PointerAuthCalls) {6178S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 2;6179AL.setInvalid();6180}6181} else {6182S.Diag(AL.getLoc(), diag::err_attribute_argument_type)6183<< AL << AANT_ArgumentIdentifier;6184}6185}61866187uint32_t CustomDiscriminationValue = 0;6188if (ED == VTablePointerAuthenticationAttr::CustomDiscrimination) {6189if (NumArgs < 4) {6190S.Diag(AL.getLoc(), diag::err_missing_custom_discrimination) << AL << 4;6191AL.setInvalid();6192return;6193}6194if (NumArgs > 4) {6195S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;6196AL.setInvalid();6197}61986199if (!AL.isArgExpr(3) || !S.checkUInt32Argument(AL, AL.getArgAsExpr(3),6200CustomDiscriminationValue)) {6201S.Diag(AL.getLoc(), diag::err_invalid_custom_discrimination);6202AL.setInvalid();6203}6204} else if (NumArgs > 3) {6205S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 3;6206AL.setInvalid();6207}62086209Decl->addAttr(::new (S.Context) VTablePointerAuthenticationAttr(6210S.Context, AL, KeyType, AddressDiversityMode, ED,6211CustomDiscriminationValue));6212}62136214//===----------------------------------------------------------------------===//6215// Top Level Sema Entry Points6216//===----------------------------------------------------------------------===//62176218// Returns true if the attribute must delay setting its arguments until after6219// template instantiation, and false otherwise.6220static bool MustDelayAttributeArguments(const ParsedAttr &AL) {6221// Only attributes that accept expression parameter packs can delay arguments.6222if (!AL.acceptsExprPack())6223return false;62246225bool AttrHasVariadicArg = AL.hasVariadicArg();6226unsigned AttrNumArgs = AL.getNumArgMembers();6227for (size_t I = 0; I < std::min(AL.getNumArgs(), AttrNumArgs); ++I) {6228bool IsLastAttrArg = I == (AttrNumArgs - 1);6229// If the argument is the last argument and it is variadic it can contain6230// any expression.6231if (IsLastAttrArg && AttrHasVariadicArg)6232return false;6233Expr *E = AL.getArgAsExpr(I);6234bool ArgMemberCanHoldExpr = AL.isParamExpr(I);6235// If the expression is a pack expansion then arguments must be delayed6236// unless the argument is an expression and it is the last argument of the6237// attribute.6238if (isa<PackExpansionExpr>(E))6239return !(IsLastAttrArg && ArgMemberCanHoldExpr);6240// Last case is if the expression is value dependent then it must delay6241// arguments unless the corresponding argument is able to hold the6242// expression.6243if (E->isValueDependent() && !ArgMemberCanHoldExpr)6244return true;6245}6246return false;6247}62486249/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if6250/// the attribute applies to decls. If the attribute is a type attribute, just6251/// silently ignore it if a GNU attribute.6252static void6253ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,6254const Sema::ProcessDeclAttributeOptions &Options) {6255if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)6256return;62576258// Ignore C++11 attributes on declarator chunks: they appertain to the type6259// instead. Note, isCXX11Attribute() will look at whether the attribute is6260// [[]] or alignas, while isC23Attribute() will only look at [[]]. This is6261// important for ensuring that alignas in C23 is properly handled on a6262// structure member declaration because it is a type-specifier-qualifier in6263// C but still applies to the declaration rather than the type.6264if ((S.getLangOpts().CPlusPlus ? AL.isCXX11Attribute()6265: AL.isC23Attribute()) &&6266!Options.IncludeCXX11Attributes)6267return;62686269// Unknown attributes are automatically warned on. Target-specific attributes6270// which do not apply to the current target architecture are treated as6271// though they were unknown attributes.6272if (AL.getKind() == ParsedAttr::UnknownAttribute ||6273!AL.existsInTarget(S.Context.getTargetInfo())) {6274S.Diag(AL.getLoc(),6275AL.isRegularKeywordAttribute()6276? (unsigned)diag::err_keyword_not_supported_on_target6277: AL.isDeclspecAttribute()6278? (unsigned)diag::warn_unhandled_ms_attribute_ignored6279: (unsigned)diag::warn_unknown_attribute_ignored)6280<< AL << AL.getRange();6281return;6282}62836284// Check if argument population must delayed to after template instantiation.6285bool MustDelayArgs = MustDelayAttributeArguments(AL);62866287// Argument number check must be skipped if arguments are delayed.6288if (S.checkCommonAttributeFeatures(D, AL, MustDelayArgs))6289return;62906291if (MustDelayArgs) {6292AL.handleAttrWithDelayedArgs(S, D);6293return;6294}62956296switch (AL.getKind()) {6297default:6298if (AL.getInfo().handleDeclAttribute(S, D, AL) != ParsedAttrInfo::NotHandled)6299break;6300if (!AL.isStmtAttr()) {6301assert(AL.isTypeAttr() && "Non-type attribute not handled");6302}6303if (AL.isTypeAttr()) {6304if (Options.IgnoreTypeAttributes)6305break;6306if (!AL.isStandardAttributeSyntax() && !AL.isRegularKeywordAttribute()) {6307// Non-[[]] type attributes are handled in processTypeAttrs(); silently6308// move on.6309break;6310}63116312// According to the C and C++ standards, we should never see a6313// [[]] type attribute on a declaration. However, we have in the past6314// allowed some type attributes to "slide" to the `DeclSpec`, so we need6315// to continue to support this legacy behavior. We only do this, however,6316// if6317// - we actually have a `DeclSpec`, i.e. if we're looking at a6318// `DeclaratorDecl`, or6319// - we are looking at an alias-declaration, where historically we have6320// allowed type attributes after the identifier to slide to the type.6321if (AL.slidesFromDeclToDeclSpecLegacyBehavior() &&6322isa<DeclaratorDecl, TypeAliasDecl>(D)) {6323// Suggest moving the attribute to the type instead, but only for our6324// own vendor attributes; moving other vendors' attributes might hurt6325// portability.6326if (AL.isClangScope()) {6327S.Diag(AL.getLoc(), diag::warn_type_attribute_deprecated_on_decl)6328<< AL << D->getLocation();6329}63306331// Allow this type attribute to be handled in processTypeAttrs();6332// silently move on.6333break;6334}63356336if (AL.getKind() == ParsedAttr::AT_Regparm) {6337// `regparm` is a special case: It's a type attribute but we still want6338// to treat it as if it had been written on the declaration because that6339// way we'll be able to handle it directly in `processTypeAttr()`.6340// If we treated `regparm` it as if it had been written on the6341// `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`6342// would try to move it to the declarator, but that doesn't work: We6343// can't remove the attribute from the list of declaration attributes6344// because it might be needed by other declarators in the same6345// declaration.6346break;6347}63486349if (AL.getKind() == ParsedAttr::AT_VectorSize) {6350// `vector_size` is a special case: It's a type attribute semantically,6351// but GCC expects the [[]] syntax to be written on the declaration (and6352// warns that the attribute has no effect if it is placed on the6353// decl-specifier-seq).6354// Silently move on and allow the attribute to be handled in6355// processTypeAttr().6356break;6357}63586359if (AL.getKind() == ParsedAttr::AT_NoDeref) {6360// FIXME: `noderef` currently doesn't work correctly in [[]] syntax.6361// See https://github.com/llvm/llvm-project/issues/55790 for details.6362// We allow processTypeAttrs() to emit a warning and silently move on.6363break;6364}6365}6366// N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a6367// statement attribute is not written on a declaration, but this code is6368// needed for type attributes as well as statement attributes in Attr.td6369// that do not list any subjects.6370S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)6371<< AL << AL.isRegularKeywordAttribute() << D->getLocation();6372break;6373case ParsedAttr::AT_Interrupt:6374handleInterruptAttr(S, D, AL);6375break;6376case ParsedAttr::AT_X86ForceAlignArgPointer:6377S.X86().handleForceAlignArgPointerAttr(D, AL);6378break;6379case ParsedAttr::AT_ReadOnlyPlacement:6380handleSimpleAttribute<ReadOnlyPlacementAttr>(S, D, AL);6381break;6382case ParsedAttr::AT_DLLExport:6383case ParsedAttr::AT_DLLImport:6384handleDLLAttr(S, D, AL);6385break;6386case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:6387S.AMDGPU().handleAMDGPUFlatWorkGroupSizeAttr(D, AL);6388break;6389case ParsedAttr::AT_AMDGPUWavesPerEU:6390S.AMDGPU().handleAMDGPUWavesPerEUAttr(D, AL);6391break;6392case ParsedAttr::AT_AMDGPUNumSGPR:6393S.AMDGPU().handleAMDGPUNumSGPRAttr(D, AL);6394break;6395case ParsedAttr::AT_AMDGPUNumVGPR:6396S.AMDGPU().handleAMDGPUNumVGPRAttr(D, AL);6397break;6398case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:6399S.AMDGPU().handleAMDGPUMaxNumWorkGroupsAttr(D, AL);6400break;6401case ParsedAttr::AT_AVRSignal:6402S.AVR().handleSignalAttr(D, AL);6403break;6404case ParsedAttr::AT_BPFPreserveAccessIndex:6405S.BPF().handlePreserveAccessIndexAttr(D, AL);6406break;6407case ParsedAttr::AT_BPFPreserveStaticOffset:6408handleSimpleAttribute<BPFPreserveStaticOffsetAttr>(S, D, AL);6409break;6410case ParsedAttr::AT_BTFDeclTag:6411handleBTFDeclTagAttr(S, D, AL);6412break;6413case ParsedAttr::AT_WebAssemblyExportName:6414S.Wasm().handleWebAssemblyExportNameAttr(D, AL);6415break;6416case ParsedAttr::AT_WebAssemblyImportModule:6417S.Wasm().handleWebAssemblyImportModuleAttr(D, AL);6418break;6419case ParsedAttr::AT_WebAssemblyImportName:6420S.Wasm().handleWebAssemblyImportNameAttr(D, AL);6421break;6422case ParsedAttr::AT_IBOutlet:6423S.ObjC().handleIBOutlet(D, AL);6424break;6425case ParsedAttr::AT_IBOutletCollection:6426S.ObjC().handleIBOutletCollection(D, AL);6427break;6428case ParsedAttr::AT_IFunc:6429handleIFuncAttr(S, D, AL);6430break;6431case ParsedAttr::AT_Alias:6432handleAliasAttr(S, D, AL);6433break;6434case ParsedAttr::AT_Aligned:6435handleAlignedAttr(S, D, AL);6436break;6437case ParsedAttr::AT_AlignValue:6438handleAlignValueAttr(S, D, AL);6439break;6440case ParsedAttr::AT_AllocSize:6441handleAllocSizeAttr(S, D, AL);6442break;6443case ParsedAttr::AT_AlwaysInline:6444handleAlwaysInlineAttr(S, D, AL);6445break;6446case ParsedAttr::AT_AnalyzerNoReturn:6447handleAnalyzerNoReturnAttr(S, D, AL);6448break;6449case ParsedAttr::AT_TLSModel:6450handleTLSModelAttr(S, D, AL);6451break;6452case ParsedAttr::AT_Annotate:6453handleAnnotateAttr(S, D, AL);6454break;6455case ParsedAttr::AT_Availability:6456handleAvailabilityAttr(S, D, AL);6457break;6458case ParsedAttr::AT_CarriesDependency:6459handleDependencyAttr(S, scope, D, AL);6460break;6461case ParsedAttr::AT_CPUDispatch:6462case ParsedAttr::AT_CPUSpecific:6463handleCPUSpecificAttr(S, D, AL);6464break;6465case ParsedAttr::AT_Common:6466handleCommonAttr(S, D, AL);6467break;6468case ParsedAttr::AT_CUDAConstant:6469handleConstantAttr(S, D, AL);6470break;6471case ParsedAttr::AT_PassObjectSize:6472handlePassObjectSizeAttr(S, D, AL);6473break;6474case ParsedAttr::AT_Constructor:6475handleConstructorAttr(S, D, AL);6476break;6477case ParsedAttr::AT_Deprecated:6478handleDeprecatedAttr(S, D, AL);6479break;6480case ParsedAttr::AT_Destructor:6481handleDestructorAttr(S, D, AL);6482break;6483case ParsedAttr::AT_EnableIf:6484handleEnableIfAttr(S, D, AL);6485break;6486case ParsedAttr::AT_Error:6487handleErrorAttr(S, D, AL);6488break;6489case ParsedAttr::AT_ExcludeFromExplicitInstantiation:6490handleExcludeFromExplicitInstantiationAttr(S, D, AL);6491break;6492case ParsedAttr::AT_DiagnoseIf:6493handleDiagnoseIfAttr(S, D, AL);6494break;6495case ParsedAttr::AT_DiagnoseAsBuiltin:6496handleDiagnoseAsBuiltinAttr(S, D, AL);6497break;6498case ParsedAttr::AT_NoBuiltin:6499handleNoBuiltinAttr(S, D, AL);6500break;6501case ParsedAttr::AT_ExtVectorType:6502handleExtVectorTypeAttr(S, D, AL);6503break;6504case ParsedAttr::AT_ExternalSourceSymbol:6505handleExternalSourceSymbolAttr(S, D, AL);6506break;6507case ParsedAttr::AT_MinSize:6508handleMinSizeAttr(S, D, AL);6509break;6510case ParsedAttr::AT_OptimizeNone:6511handleOptimizeNoneAttr(S, D, AL);6512break;6513case ParsedAttr::AT_EnumExtensibility:6514handleEnumExtensibilityAttr(S, D, AL);6515break;6516case ParsedAttr::AT_SYCLKernel:6517S.SYCL().handleKernelAttr(D, AL);6518break;6519case ParsedAttr::AT_SYCLSpecialClass:6520handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL);6521break;6522case ParsedAttr::AT_Format:6523handleFormatAttr(S, D, AL);6524break;6525case ParsedAttr::AT_FormatArg:6526handleFormatArgAttr(S, D, AL);6527break;6528case ParsedAttr::AT_Callback:6529handleCallbackAttr(S, D, AL);6530break;6531case ParsedAttr::AT_CalledOnce:6532handleCalledOnceAttr(S, D, AL);6533break;6534case ParsedAttr::AT_NVPTXKernel:6535case ParsedAttr::AT_CUDAGlobal:6536handleGlobalAttr(S, D, AL);6537break;6538case ParsedAttr::AT_CUDADevice:6539handleDeviceAttr(S, D, AL);6540break;6541case ParsedAttr::AT_HIPManaged:6542handleManagedAttr(S, D, AL);6543break;6544case ParsedAttr::AT_GNUInline:6545handleGNUInlineAttr(S, D, AL);6546break;6547case ParsedAttr::AT_CUDALaunchBounds:6548handleLaunchBoundsAttr(S, D, AL);6549break;6550case ParsedAttr::AT_Restrict:6551handleRestrictAttr(S, D, AL);6552break;6553case ParsedAttr::AT_Mode:6554handleModeAttr(S, D, AL);6555break;6556case ParsedAttr::AT_NonNull:6557if (auto *PVD = dyn_cast<ParmVarDecl>(D))6558handleNonNullAttrParameter(S, PVD, AL);6559else6560handleNonNullAttr(S, D, AL);6561break;6562case ParsedAttr::AT_ReturnsNonNull:6563handleReturnsNonNullAttr(S, D, AL);6564break;6565case ParsedAttr::AT_NoEscape:6566handleNoEscapeAttr(S, D, AL);6567break;6568case ParsedAttr::AT_MaybeUndef:6569handleSimpleAttribute<MaybeUndefAttr>(S, D, AL);6570break;6571case ParsedAttr::AT_AssumeAligned:6572handleAssumeAlignedAttr(S, D, AL);6573break;6574case ParsedAttr::AT_AllocAlign:6575handleAllocAlignAttr(S, D, AL);6576break;6577case ParsedAttr::AT_Ownership:6578handleOwnershipAttr(S, D, AL);6579break;6580case ParsedAttr::AT_Naked:6581handleNakedAttr(S, D, AL);6582break;6583case ParsedAttr::AT_NoReturn:6584handleNoReturnAttr(S, D, AL);6585break;6586case ParsedAttr::AT_CXX11NoReturn:6587handleStandardNoReturnAttr(S, D, AL);6588break;6589case ParsedAttr::AT_AnyX86NoCfCheck:6590handleNoCfCheckAttr(S, D, AL);6591break;6592case ParsedAttr::AT_NoThrow:6593if (!AL.isUsedAsTypeAttr())6594handleSimpleAttribute<NoThrowAttr>(S, D, AL);6595break;6596case ParsedAttr::AT_CUDAShared:6597handleSharedAttr(S, D, AL);6598break;6599case ParsedAttr::AT_VecReturn:6600handleVecReturnAttr(S, D, AL);6601break;6602case ParsedAttr::AT_ObjCOwnership:6603S.ObjC().handleOwnershipAttr(D, AL);6604break;6605case ParsedAttr::AT_ObjCPreciseLifetime:6606S.ObjC().handlePreciseLifetimeAttr(D, AL);6607break;6608case ParsedAttr::AT_ObjCReturnsInnerPointer:6609S.ObjC().handleReturnsInnerPointerAttr(D, AL);6610break;6611case ParsedAttr::AT_ObjCRequiresSuper:6612S.ObjC().handleRequiresSuperAttr(D, AL);6613break;6614case ParsedAttr::AT_ObjCBridge:6615S.ObjC().handleBridgeAttr(D, AL);6616break;6617case ParsedAttr::AT_ObjCBridgeMutable:6618S.ObjC().handleBridgeMutableAttr(D, AL);6619break;6620case ParsedAttr::AT_ObjCBridgeRelated:6621S.ObjC().handleBridgeRelatedAttr(D, AL);6622break;6623case ParsedAttr::AT_ObjCDesignatedInitializer:6624S.ObjC().handleDesignatedInitializer(D, AL);6625break;6626case ParsedAttr::AT_ObjCRuntimeName:6627S.ObjC().handleRuntimeName(D, AL);6628break;6629case ParsedAttr::AT_ObjCBoxable:6630S.ObjC().handleBoxable(D, AL);6631break;6632case ParsedAttr::AT_NSErrorDomain:6633S.ObjC().handleNSErrorDomain(D, AL);6634break;6635case ParsedAttr::AT_CFConsumed:6636case ParsedAttr::AT_NSConsumed:6637case ParsedAttr::AT_OSConsumed:6638S.ObjC().AddXConsumedAttr(D, AL,6639S.ObjC().parsedAttrToRetainOwnershipKind(AL),6640/*IsTemplateInstantiation=*/false);6641break;6642case ParsedAttr::AT_OSReturnsRetainedOnZero:6643handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(6644S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),6645diag::warn_ns_attribute_wrong_parameter_type,6646/*Extra Args=*/AL, /*pointer-to-OSObject-pointer*/ 3, AL.getRange());6647break;6648case ParsedAttr::AT_OSReturnsRetainedOnNonZero:6649handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnNonZeroAttr>(6650S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),6651diag::warn_ns_attribute_wrong_parameter_type,6652/*Extra Args=*/AL, /*pointer-to-OSObject-poointer*/ 3, AL.getRange());6653break;6654case ParsedAttr::AT_NSReturnsAutoreleased:6655case ParsedAttr::AT_NSReturnsNotRetained:6656case ParsedAttr::AT_NSReturnsRetained:6657case ParsedAttr::AT_CFReturnsNotRetained:6658case ParsedAttr::AT_CFReturnsRetained:6659case ParsedAttr::AT_OSReturnsNotRetained:6660case ParsedAttr::AT_OSReturnsRetained:6661S.ObjC().handleXReturnsXRetainedAttr(D, AL);6662break;6663case ParsedAttr::AT_WorkGroupSizeHint:6664handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);6665break;6666case ParsedAttr::AT_ReqdWorkGroupSize:6667handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);6668break;6669case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:6670S.OpenCL().handleSubGroupSize(D, AL);6671break;6672case ParsedAttr::AT_VecTypeHint:6673handleVecTypeHint(S, D, AL);6674break;6675case ParsedAttr::AT_InitPriority:6676handleInitPriorityAttr(S, D, AL);6677break;6678case ParsedAttr::AT_Packed:6679handlePackedAttr(S, D, AL);6680break;6681case ParsedAttr::AT_PreferredName:6682handlePreferredName(S, D, AL);6683break;6684case ParsedAttr::AT_Section:6685handleSectionAttr(S, D, AL);6686break;6687case ParsedAttr::AT_CodeModel:6688handleCodeModelAttr(S, D, AL);6689break;6690case ParsedAttr::AT_RandomizeLayout:6691handleRandomizeLayoutAttr(S, D, AL);6692break;6693case ParsedAttr::AT_NoRandomizeLayout:6694handleNoRandomizeLayoutAttr(S, D, AL);6695break;6696case ParsedAttr::AT_CodeSeg:6697handleCodeSegAttr(S, D, AL);6698break;6699case ParsedAttr::AT_Target:6700handleTargetAttr(S, D, AL);6701break;6702case ParsedAttr::AT_TargetVersion:6703handleTargetVersionAttr(S, D, AL);6704break;6705case ParsedAttr::AT_TargetClones:6706handleTargetClonesAttr(S, D, AL);6707break;6708case ParsedAttr::AT_MinVectorWidth:6709handleMinVectorWidthAttr(S, D, AL);6710break;6711case ParsedAttr::AT_Unavailable:6712handleAttrWithMessage<UnavailableAttr>(S, D, AL);6713break;6714case ParsedAttr::AT_OMPAssume:6715S.OpenMP().handleOMPAssumeAttr(D, AL);6716break;6717case ParsedAttr::AT_ObjCDirect:6718S.ObjC().handleDirectAttr(D, AL);6719break;6720case ParsedAttr::AT_ObjCDirectMembers:6721S.ObjC().handleDirectMembersAttr(D, AL);6722handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);6723break;6724case ParsedAttr::AT_ObjCExplicitProtocolImpl:6725S.ObjC().handleSuppresProtocolAttr(D, AL);6726break;6727case ParsedAttr::AT_Unused:6728handleUnusedAttr(S, D, AL);6729break;6730case ParsedAttr::AT_Visibility:6731handleVisibilityAttr(S, D, AL, false);6732break;6733case ParsedAttr::AT_TypeVisibility:6734handleVisibilityAttr(S, D, AL, true);6735break;6736case ParsedAttr::AT_WarnUnusedResult:6737handleWarnUnusedResult(S, D, AL);6738break;6739case ParsedAttr::AT_WeakRef:6740handleWeakRefAttr(S, D, AL);6741break;6742case ParsedAttr::AT_WeakImport:6743handleWeakImportAttr(S, D, AL);6744break;6745case ParsedAttr::AT_TransparentUnion:6746handleTransparentUnionAttr(S, D, AL);6747break;6748case ParsedAttr::AT_ObjCMethodFamily:6749S.ObjC().handleMethodFamilyAttr(D, AL);6750break;6751case ParsedAttr::AT_ObjCNSObject:6752S.ObjC().handleNSObject(D, AL);6753break;6754case ParsedAttr::AT_ObjCIndependentClass:6755S.ObjC().handleIndependentClass(D, AL);6756break;6757case ParsedAttr::AT_Blocks:6758S.ObjC().handleBlocksAttr(D, AL);6759break;6760case ParsedAttr::AT_Sentinel:6761handleSentinelAttr(S, D, AL);6762break;6763case ParsedAttr::AT_Cleanup:6764handleCleanupAttr(S, D, AL);6765break;6766case ParsedAttr::AT_NoDebug:6767handleNoDebugAttr(S, D, AL);6768break;6769case ParsedAttr::AT_CmseNSEntry:6770S.ARM().handleCmseNSEntryAttr(D, AL);6771break;6772case ParsedAttr::AT_StdCall:6773case ParsedAttr::AT_CDecl:6774case ParsedAttr::AT_FastCall:6775case ParsedAttr::AT_ThisCall:6776case ParsedAttr::AT_Pascal:6777case ParsedAttr::AT_RegCall:6778case ParsedAttr::AT_SwiftCall:6779case ParsedAttr::AT_SwiftAsyncCall:6780case ParsedAttr::AT_VectorCall:6781case ParsedAttr::AT_MSABI:6782case ParsedAttr::AT_SysVABI:6783case ParsedAttr::AT_Pcs:6784case ParsedAttr::AT_IntelOclBicc:6785case ParsedAttr::AT_PreserveMost:6786case ParsedAttr::AT_PreserveAll:6787case ParsedAttr::AT_AArch64VectorPcs:6788case ParsedAttr::AT_AArch64SVEPcs:6789case ParsedAttr::AT_AMDGPUKernelCall:6790case ParsedAttr::AT_M68kRTD:6791case ParsedAttr::AT_PreserveNone:6792case ParsedAttr::AT_RISCVVectorCC:6793handleCallConvAttr(S, D, AL);6794break;6795case ParsedAttr::AT_Suppress:6796handleSuppressAttr(S, D, AL);6797break;6798case ParsedAttr::AT_Owner:6799case ParsedAttr::AT_Pointer:6800handleLifetimeCategoryAttr(S, D, AL);6801break;6802case ParsedAttr::AT_OpenCLAccess:6803S.OpenCL().handleAccessAttr(D, AL);6804break;6805case ParsedAttr::AT_OpenCLNoSVM:6806S.OpenCL().handleNoSVMAttr(D, AL);6807break;6808case ParsedAttr::AT_SwiftContext:6809S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftContext);6810break;6811case ParsedAttr::AT_SwiftAsyncContext:6812S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftAsyncContext);6813break;6814case ParsedAttr::AT_SwiftErrorResult:6815S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftErrorResult);6816break;6817case ParsedAttr::AT_SwiftIndirectResult:6818S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftIndirectResult);6819break;6820case ParsedAttr::AT_InternalLinkage:6821handleInternalLinkageAttr(S, D, AL);6822break;6823case ParsedAttr::AT_ZeroCallUsedRegs:6824handleZeroCallUsedRegsAttr(S, D, AL);6825break;6826case ParsedAttr::AT_FunctionReturnThunks:6827handleFunctionReturnThunksAttr(S, D, AL);6828break;6829case ParsedAttr::AT_NoMerge:6830handleNoMergeAttr(S, D, AL);6831break;6832case ParsedAttr::AT_NoUniqueAddress:6833handleNoUniqueAddressAttr(S, D, AL);6834break;68356836case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:6837handleAvailableOnlyInDefaultEvalMethod(S, D, AL);6838break;68396840case ParsedAttr::AT_CountedBy:6841case ParsedAttr::AT_CountedByOrNull:6842case ParsedAttr::AT_SizedBy:6843case ParsedAttr::AT_SizedByOrNull:6844handleCountedByAttrField(S, D, AL);6845break;68466847// Microsoft attributes:6848case ParsedAttr::AT_LayoutVersion:6849handleLayoutVersion(S, D, AL);6850break;6851case ParsedAttr::AT_Uuid:6852handleUuidAttr(S, D, AL);6853break;6854case ParsedAttr::AT_MSInheritance:6855handleMSInheritanceAttr(S, D, AL);6856break;6857case ParsedAttr::AT_Thread:6858handleDeclspecThreadAttr(S, D, AL);6859break;6860case ParsedAttr::AT_MSConstexpr:6861handleMSConstexprAttr(S, D, AL);6862break;6863case ParsedAttr::AT_HybridPatchable:6864handleSimpleAttribute<HybridPatchableAttr>(S, D, AL);6865break;68666867// HLSL attributes:6868case ParsedAttr::AT_HLSLNumThreads:6869S.HLSL().handleNumThreadsAttr(D, AL);6870break;6871case ParsedAttr::AT_HLSLSV_GroupIndex:6872handleSimpleAttribute<HLSLSV_GroupIndexAttr>(S, D, AL);6873break;6874case ParsedAttr::AT_HLSLSV_DispatchThreadID:6875S.HLSL().handleSV_DispatchThreadIDAttr(D, AL);6876break;6877case ParsedAttr::AT_HLSLPackOffset:6878S.HLSL().handlePackOffsetAttr(D, AL);6879break;6880case ParsedAttr::AT_HLSLShader:6881S.HLSL().handleShaderAttr(D, AL);6882break;6883case ParsedAttr::AT_HLSLResourceBinding:6884S.HLSL().handleResourceBindingAttr(D, AL);6885break;6886case ParsedAttr::AT_HLSLResourceClass:6887S.HLSL().handleResourceClassAttr(D, AL);6888break;6889case ParsedAttr::AT_HLSLParamModifier:6890S.HLSL().handleParamModifierAttr(D, AL);6891break;68926893case ParsedAttr::AT_AbiTag:6894handleAbiTagAttr(S, D, AL);6895break;6896case ParsedAttr::AT_CFGuard:6897handleCFGuardAttr(S, D, AL);6898break;68996900// Thread safety attributes:6901case ParsedAttr::AT_AssertExclusiveLock:6902handleAssertExclusiveLockAttr(S, D, AL);6903break;6904case ParsedAttr::AT_AssertSharedLock:6905handleAssertSharedLockAttr(S, D, AL);6906break;6907case ParsedAttr::AT_PtGuardedVar:6908handlePtGuardedVarAttr(S, D, AL);6909break;6910case ParsedAttr::AT_NoSanitize:6911handleNoSanitizeAttr(S, D, AL);6912break;6913case ParsedAttr::AT_NoSanitizeSpecific:6914handleNoSanitizeSpecificAttr(S, D, AL);6915break;6916case ParsedAttr::AT_GuardedBy:6917handleGuardedByAttr(S, D, AL);6918break;6919case ParsedAttr::AT_PtGuardedBy:6920handlePtGuardedByAttr(S, D, AL);6921break;6922case ParsedAttr::AT_ExclusiveTrylockFunction:6923handleExclusiveTrylockFunctionAttr(S, D, AL);6924break;6925case ParsedAttr::AT_LockReturned:6926handleLockReturnedAttr(S, D, AL);6927break;6928case ParsedAttr::AT_LocksExcluded:6929handleLocksExcludedAttr(S, D, AL);6930break;6931case ParsedAttr::AT_SharedTrylockFunction:6932handleSharedTrylockFunctionAttr(S, D, AL);6933break;6934case ParsedAttr::AT_AcquiredBefore:6935handleAcquiredBeforeAttr(S, D, AL);6936break;6937case ParsedAttr::AT_AcquiredAfter:6938handleAcquiredAfterAttr(S, D, AL);6939break;69406941// Capability analysis attributes.6942case ParsedAttr::AT_Capability:6943case ParsedAttr::AT_Lockable:6944handleCapabilityAttr(S, D, AL);6945break;6946case ParsedAttr::AT_RequiresCapability:6947handleRequiresCapabilityAttr(S, D, AL);6948break;69496950case ParsedAttr::AT_AssertCapability:6951handleAssertCapabilityAttr(S, D, AL);6952break;6953case ParsedAttr::AT_AcquireCapability:6954handleAcquireCapabilityAttr(S, D, AL);6955break;6956case ParsedAttr::AT_ReleaseCapability:6957handleReleaseCapabilityAttr(S, D, AL);6958break;6959case ParsedAttr::AT_TryAcquireCapability:6960handleTryAcquireCapabilityAttr(S, D, AL);6961break;69626963// Consumed analysis attributes.6964case ParsedAttr::AT_Consumable:6965handleConsumableAttr(S, D, AL);6966break;6967case ParsedAttr::AT_CallableWhen:6968handleCallableWhenAttr(S, D, AL);6969break;6970case ParsedAttr::AT_ParamTypestate:6971handleParamTypestateAttr(S, D, AL);6972break;6973case ParsedAttr::AT_ReturnTypestate:6974handleReturnTypestateAttr(S, D, AL);6975break;6976case ParsedAttr::AT_SetTypestate:6977handleSetTypestateAttr(S, D, AL);6978break;6979case ParsedAttr::AT_TestTypestate:6980handleTestTypestateAttr(S, D, AL);6981break;69826983// Type safety attributes.6984case ParsedAttr::AT_ArgumentWithTypeTag:6985handleArgumentWithTypeTagAttr(S, D, AL);6986break;6987case ParsedAttr::AT_TypeTagForDatatype:6988handleTypeTagForDatatypeAttr(S, D, AL);6989break;69906991// Swift attributes.6992case ParsedAttr::AT_SwiftAsyncName:6993S.Swift().handleAsyncName(D, AL);6994break;6995case ParsedAttr::AT_SwiftAttr:6996S.Swift().handleAttrAttr(D, AL);6997break;6998case ParsedAttr::AT_SwiftBridge:6999S.Swift().handleBridge(D, AL);7000break;7001case ParsedAttr::AT_SwiftError:7002S.Swift().handleError(D, AL);7003break;7004case ParsedAttr::AT_SwiftName:7005S.Swift().handleName(D, AL);7006break;7007case ParsedAttr::AT_SwiftNewType:7008S.Swift().handleNewType(D, AL);7009break;7010case ParsedAttr::AT_SwiftAsync:7011S.Swift().handleAsyncAttr(D, AL);7012break;7013case ParsedAttr::AT_SwiftAsyncError:7014S.Swift().handleAsyncError(D, AL);7015break;70167017// XRay attributes.7018case ParsedAttr::AT_XRayLogArgs:7019handleXRayLogArgsAttr(S, D, AL);7020break;70217022case ParsedAttr::AT_PatchableFunctionEntry:7023handlePatchableFunctionEntryAttr(S, D, AL);7024break;70257026case ParsedAttr::AT_AlwaysDestroy:7027case ParsedAttr::AT_NoDestroy:7028handleDestroyAttr(S, D, AL);7029break;70307031case ParsedAttr::AT_Uninitialized:7032handleUninitializedAttr(S, D, AL);7033break;70347035case ParsedAttr::AT_ObjCExternallyRetained:7036S.ObjC().handleExternallyRetainedAttr(D, AL);7037break;70387039case ParsedAttr::AT_MIGServerRoutine:7040handleMIGServerRoutineAttr(S, D, AL);7041break;70427043case ParsedAttr::AT_MSAllocator:7044handleMSAllocatorAttr(S, D, AL);7045break;70467047case ParsedAttr::AT_ArmBuiltinAlias:7048S.ARM().handleBuiltinAliasAttr(D, AL);7049break;70507051case ParsedAttr::AT_ArmLocallyStreaming:7052handleSimpleAttribute<ArmLocallyStreamingAttr>(S, D, AL);7053break;70547055case ParsedAttr::AT_ArmNew:7056S.ARM().handleNewAttr(D, AL);7057break;70587059case ParsedAttr::AT_AcquireHandle:7060handleAcquireHandleAttr(S, D, AL);7061break;70627063case ParsedAttr::AT_ReleaseHandle:7064handleHandleAttr<ReleaseHandleAttr>(S, D, AL);7065break;70667067case ParsedAttr::AT_UnsafeBufferUsage:7068handleUnsafeBufferUsage<UnsafeBufferUsageAttr>(S, D, AL);7069break;70707071case ParsedAttr::AT_UseHandle:7072handleHandleAttr<UseHandleAttr>(S, D, AL);7073break;70747075case ParsedAttr::AT_EnforceTCB:7076handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);7077break;70787079case ParsedAttr::AT_EnforceTCBLeaf:7080handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);7081break;70827083case ParsedAttr::AT_BuiltinAlias:7084handleBuiltinAliasAttr(S, D, AL);7085break;70867087case ParsedAttr::AT_PreferredType:7088handlePreferredTypeAttr(S, D, AL);7089break;70907091case ParsedAttr::AT_UsingIfExists:7092handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);7093break;70947095case ParsedAttr::AT_TypeNullable:7096handleNullableTypeAttr(S, D, AL);7097break;70987099case ParsedAttr::AT_VTablePointerAuthentication:7100handleVTablePointerAuthentication(S, D, AL);7101break;7102}7103}71047105void Sema::ProcessDeclAttributeList(7106Scope *S, Decl *D, const ParsedAttributesView &AttrList,7107const ProcessDeclAttributeOptions &Options) {7108if (AttrList.empty())7109return;71107111for (const ParsedAttr &AL : AttrList)7112ProcessDeclAttribute(*this, S, D, AL, Options);71137114// FIXME: We should be able to handle these cases in TableGen.7115// GCC accepts7116// static int a9 __attribute__((weakref));7117// but that looks really pointless. We reject it.7118if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {7119Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)7120<< cast<NamedDecl>(D);7121D->dropAttr<WeakRefAttr>();7122return;7123}71247125// FIXME: We should be able to handle this in TableGen as well. It would be7126// good to have a way to specify "these attributes must appear as a group",7127// for these. Additionally, it would be good to have a way to specify "these7128// attribute must never appear as a group" for attributes like cold and hot.7129if (!D->hasAttr<OpenCLKernelAttr>()) {7130// These attributes cannot be applied to a non-kernel function.7131if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {7132// FIXME: This emits a different error message than7133// diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.7134Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;7135D->setInvalidDecl();7136} else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {7137Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;7138D->setInvalidDecl();7139} else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {7140Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;7141D->setInvalidDecl();7142} else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {7143Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;7144D->setInvalidDecl();7145} else if (!D->hasAttr<CUDAGlobalAttr>()) {7146if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {7147Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)7148<< A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;7149D->setInvalidDecl();7150} else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {7151Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)7152<< A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;7153D->setInvalidDecl();7154} else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {7155Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)7156<< A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;7157D->setInvalidDecl();7158} else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {7159Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)7160<< A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;7161D->setInvalidDecl();7162}7163}7164}71657166// Do this check after processing D's attributes because the attribute7167// objc_method_family can change whether the given method is in the init7168// family, and it can be applied after objc_designated_initializer. This is a7169// bit of a hack, but we need it to be compatible with versions of clang that7170// processed the attribute list in the wrong order.7171if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&7172cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {7173Diag(D->getLocation(), diag::err_designated_init_attr_non_init);7174D->dropAttr<ObjCDesignatedInitializerAttr>();7175}7176}71777178void Sema::ProcessDeclAttributeDelayed(Decl *D,7179const ParsedAttributesView &AttrList) {7180for (const ParsedAttr &AL : AttrList)7181if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {7182handleTransparentUnionAttr(*this, D, AL);7183break;7184}71857186// For BPFPreserveAccessIndexAttr, we want to populate the attributes7187// to fields and inner records as well.7188if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())7189BPF().handlePreserveAIRecord(cast<RecordDecl>(D));7190}71917192bool Sema::ProcessAccessDeclAttributeList(7193AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {7194for (const ParsedAttr &AL : AttrList) {7195if (AL.getKind() == ParsedAttr::AT_Annotate) {7196ProcessDeclAttribute(*this, nullptr, ASDecl, AL,7197ProcessDeclAttributeOptions());7198} else {7199Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);7200return true;7201}7202}7203return false;7204}72057206/// checkUnusedDeclAttributes - Check a list of attributes to see if it7207/// contains any decl attributes that we should warn about.7208static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) {7209for (const ParsedAttr &AL : A) {7210// Only warn if the attribute is an unignored, non-type attribute.7211if (AL.isUsedAsTypeAttr() || AL.isInvalid())7212continue;7213if (AL.getKind() == ParsedAttr::IgnoredAttribute)7214continue;72157216if (AL.getKind() == ParsedAttr::UnknownAttribute) {7217S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)7218<< AL << AL.getRange();7219} else {7220S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) << AL7221<< AL.getRange();7222}7223}7224}72257226void Sema::checkUnusedDeclAttributes(Declarator &D) {7227::checkUnusedDeclAttributes(*this, D.getDeclarationAttributes());7228::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes());7229::checkUnusedDeclAttributes(*this, D.getAttributes());7230for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)7231::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());7232}72337234NamedDecl *Sema::DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,7235SourceLocation Loc) {7236assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));7237NamedDecl *NewD = nullptr;7238if (auto *FD = dyn_cast<FunctionDecl>(ND)) {7239FunctionDecl *NewFD;7240// FIXME: Missing call to CheckFunctionDeclaration().7241// FIXME: Mangling?7242// FIXME: Is the qualifier info correct?7243// FIXME: Is the DeclContext correct?7244NewFD = FunctionDecl::Create(7245FD->getASTContext(), FD->getDeclContext(), Loc, Loc,7246DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None,7247getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,7248FD->hasPrototype(), ConstexprSpecKind::Unspecified,7249FD->getTrailingRequiresClause());7250NewD = NewFD;72517252if (FD->getQualifier())7253NewFD->setQualifierInfo(FD->getQualifierLoc());72547255// Fake up parameter variables; they are declared as if this were7256// a typedef.7257QualType FDTy = FD->getType();7258if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {7259SmallVector<ParmVarDecl*, 16> Params;7260for (const auto &AI : FT->param_types()) {7261ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);7262Param->setScopeInfo(0, Params.size());7263Params.push_back(Param);7264}7265NewFD->setParams(Params);7266}7267} else if (auto *VD = dyn_cast<VarDecl>(ND)) {7268NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),7269VD->getInnerLocStart(), VD->getLocation(), II,7270VD->getType(), VD->getTypeSourceInfo(),7271VD->getStorageClass());7272if (VD->getQualifier())7273cast<VarDecl>(NewD)->setQualifierInfo(VD->getQualifierLoc());7274}7275return NewD;7276}72777278void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W) {7279if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))7280IdentifierInfo *NDId = ND->getIdentifier();7281NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());7282NewD->addAttr(7283AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));7284NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));7285WeakTopLevelDecl.push_back(NewD);7286// FIXME: "hideous" code from Sema::LazilyCreateBuiltin7287// to insert Decl at TU scope, sorry.7288DeclContext *SavedContext = CurContext;7289CurContext = Context.getTranslationUnitDecl();7290NewD->setDeclContext(CurContext);7291NewD->setLexicalDeclContext(CurContext);7292PushOnScopeChains(NewD, S);7293CurContext = SavedContext;7294} else { // just add weak to existing7295ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));7296}7297}72987299void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {7300// It's valid to "forward-declare" #pragma weak, in which case we7301// have to do this.7302LoadExternalWeakUndeclaredIdentifiers();7303if (WeakUndeclaredIdentifiers.empty())7304return;7305NamedDecl *ND = nullptr;7306if (auto *VD = dyn_cast<VarDecl>(D))7307if (VD->isExternC())7308ND = VD;7309if (auto *FD = dyn_cast<FunctionDecl>(D))7310if (FD->isExternC())7311ND = FD;7312if (!ND)7313return;7314if (IdentifierInfo *Id = ND->getIdentifier()) {7315auto I = WeakUndeclaredIdentifiers.find(Id);7316if (I != WeakUndeclaredIdentifiers.end()) {7317auto &WeakInfos = I->second;7318for (const auto &W : WeakInfos)7319DeclApplyPragmaWeak(S, ND, W);7320std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;7321WeakInfos.swap(EmptyWeakInfos);7322}7323}7324}73257326/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in7327/// it, apply them to D. This is a bit tricky because PD can have attributes7328/// specified in many different places, and we need to find and apply them all.7329void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {7330// Ordering of attributes can be important, so we take care to process7331// attributes in the order in which they appeared in the source code.73327333auto ProcessAttributesWithSliding =7334[&](const ParsedAttributesView &Src,7335const ProcessDeclAttributeOptions &Options) {7336ParsedAttributesView NonSlidingAttrs;7337for (ParsedAttr &AL : Src) {7338// FIXME: this sliding is specific to standard attributes and should7339// eventually be deprecated and removed as those are not intended to7340// slide to anything.7341if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) &&7342AL.slidesFromDeclToDeclSpecLegacyBehavior()) {7343// Skip processing the attribute, but do check if it appertains to7344// the declaration. This is needed for the `MatrixType` attribute,7345// which, despite being a type attribute, defines a `SubjectList`7346// that only allows it to be used on typedef declarations.7347AL.diagnoseAppertainsTo(*this, D);7348} else {7349NonSlidingAttrs.addAtEnd(&AL);7350}7351}7352ProcessDeclAttributeList(S, D, NonSlidingAttrs, Options);7353};73547355// First, process attributes that appeared on the declaration itself (but7356// only if they don't have the legacy behavior of "sliding" to the DeclSepc).7357ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {});73587359// Apply decl attributes from the DeclSpec if present.7360ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(),7361ProcessDeclAttributeOptions()7362.WithIncludeCXX11Attributes(false)7363.WithIgnoreTypeAttributes(true));73647365// Walk the declarator structure, applying decl attributes that were in a type7366// position to the decl itself. This handles cases like:7367// int *__attr__(x)** D;7368// when X is a decl attribute.7369for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {7370ProcessDeclAttributeList(S, D, PD.getTypeObject(i).getAttrs(),7371ProcessDeclAttributeOptions()7372.WithIncludeCXX11Attributes(false)7373.WithIgnoreTypeAttributes(true));7374}73757376// Finally, apply any attributes on the decl itself.7377ProcessDeclAttributeList(S, D, PD.getAttributes());73787379// Apply additional attributes specified by '#pragma clang attribute'.7380AddPragmaAttributes(S, D);73817382// Look for API notes that map to attributes.7383ProcessAPINotes(D);7384}73857386/// Is the given declaration allowed to use a forbidden type?7387/// If so, it'll still be annotated with an attribute that makes it7388/// illegal to actually use.7389static bool isForbiddenTypeAllowed(Sema &S, Decl *D,7390const DelayedDiagnostic &diag,7391UnavailableAttr::ImplicitReason &reason) {7392// Private ivars are always okay. Unfortunately, people don't7393// always properly make their ivars private, even in system headers.7394// Plus we need to make fields okay, too.7395if (!isa<FieldDecl>(D) && !isa<ObjCPropertyDecl>(D) &&7396!isa<FunctionDecl>(D))7397return false;73987399// Silently accept unsupported uses of __weak in both user and system7400// declarations when it's been disabled, for ease of integration with7401// -fno-objc-arc files. We do have to take some care against attempts7402// to define such things; for now, we've only done that for ivars7403// and properties.7404if ((isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {7405if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||7406diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {7407reason = UnavailableAttr::IR_ForbiddenWeak;7408return true;7409}7410}74117412// Allow all sorts of things in system headers.7413if (S.Context.getSourceManager().isInSystemHeader(D->getLocation())) {7414// Currently, all the failures dealt with this way are due to ARC7415// restrictions.7416reason = UnavailableAttr::IR_ARCForbiddenType;7417return true;7418}74197420return false;7421}74227423/// Handle a delayed forbidden-type diagnostic.7424static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD,7425Decl *D) {7426auto Reason = UnavailableAttr::IR_None;7427if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) {7428assert(Reason && "didn't set reason?");7429D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc));7430return;7431}7432if (S.getLangOpts().ObjCAutoRefCount)7433if (const auto *FD = dyn_cast<FunctionDecl>(D)) {7434// FIXME: we may want to suppress diagnostics for all7435// kind of forbidden type messages on unavailable functions.7436if (FD->hasAttr<UnavailableAttr>() &&7437DD.getForbiddenTypeDiagnostic() ==7438diag::err_arc_array_param_no_ownership) {7439DD.Triggered = true;7440return;7441}7442}74437444S.Diag(DD.Loc, DD.getForbiddenTypeDiagnostic())7445<< DD.getForbiddenTypeOperand() << DD.getForbiddenTypeArgument();7446DD.Triggered = true;7447}744874497450void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {7451assert(DelayedDiagnostics.getCurrentPool());7452DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();7453DelayedDiagnostics.popWithoutEmitting(state);74547455// When delaying diagnostics to run in the context of a parsed7456// declaration, we only want to actually emit anything if parsing7457// succeeds.7458if (!decl) return;74597460// We emit all the active diagnostics in this pool or any of its7461// parents. In general, we'll get one pool for the decl spec7462// and a child pool for each declarator; in a decl group like:7463// deprecated_typedef foo, *bar, baz();7464// only the declarator pops will be passed decls. This is correct;7465// we really do need to consider delayed diagnostics from the decl spec7466// for each of the different declarations.7467const DelayedDiagnosticPool *pool = &poppedPool;7468do {7469bool AnyAccessFailures = false;7470for (DelayedDiagnosticPool::pool_iterator7471i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {7472// This const_cast is a bit lame. Really, Triggered should be mutable.7473DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);7474if (diag.Triggered)7475continue;74767477switch (diag.Kind) {7478case DelayedDiagnostic::Availability:7479// Don't bother giving deprecation/unavailable diagnostics if7480// the decl is invalid.7481if (!decl->isInvalidDecl())7482handleDelayedAvailabilityCheck(diag, decl);7483break;74847485case DelayedDiagnostic::Access:7486// Only produce one access control diagnostic for a structured binding7487// declaration: we don't need to tell the user that all the fields are7488// inaccessible one at a time.7489if (AnyAccessFailures && isa<DecompositionDecl>(decl))7490continue;7491HandleDelayedAccessCheck(diag, decl);7492if (diag.Triggered)7493AnyAccessFailures = true;7494break;74957496case DelayedDiagnostic::ForbiddenType:7497handleDelayedForbiddenType(*this, diag, decl);7498break;7499}7500}7501} while ((pool = pool->getParent()));7502}75037504void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {7505DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();7506assert(curPool && "re-emitting in undelayed context not supported");7507curPool->steal(pool);7508}750975107511