xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
10b57cec5SDimitry Andric //===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements decl-related attribute processing.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTMutationListener.h"
160b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
200b57cec5SDimitry Andric #include "clang/AST/Expr.h"
210b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
220b57cec5SDimitry Andric #include "clang/AST/Mangle.h"
230b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
24e8d8bef9SDimitry Andric #include "clang/AST/Type.h"
250b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
265f757f3fSDimitry Andric #include "clang/Basic/Cuda.h"
27fe6060f1SDimitry Andric #include "clang/Basic/DarwinSDKInfo.h"
28bdd1243dSDimitry Andric #include "clang/Basic/HLSLRuntime.h"
290fca6ea1SDimitry Andric #include "clang/Basic/IdentifierTable.h"
3081ad6265SDimitry Andric #include "clang/Basic/LangOptions.h"
31e8d8bef9SDimitry Andric #include "clang/Basic/SourceLocation.h"
320b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
33480093f4SDimitry Andric #include "clang/Basic/TargetBuiltins.h"
340b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
350b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
360fca6ea1SDimitry Andric #include "clang/Sema/Attr.h"
370b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h"
380b57cec5SDimitry Andric #include "clang/Sema/DelayedDiagnostic.h"
390b57cec5SDimitry Andric #include "clang/Sema/Initialization.h"
400b57cec5SDimitry Andric #include "clang/Sema/Lookup.h"
41e8d8bef9SDimitry Andric #include "clang/Sema/ParsedAttr.h"
420b57cec5SDimitry Andric #include "clang/Sema/Scope.h"
430b57cec5SDimitry Andric #include "clang/Sema/ScopeInfo.h"
440fca6ea1SDimitry Andric #include "clang/Sema/SemaAMDGPU.h"
450fca6ea1SDimitry Andric #include "clang/Sema/SemaARM.h"
460fca6ea1SDimitry Andric #include "clang/Sema/SemaAVR.h"
470fca6ea1SDimitry Andric #include "clang/Sema/SemaBPF.h"
480fca6ea1SDimitry Andric #include "clang/Sema/SemaCUDA.h"
490fca6ea1SDimitry Andric #include "clang/Sema/SemaHLSL.h"
500b57cec5SDimitry Andric #include "clang/Sema/SemaInternal.h"
510fca6ea1SDimitry Andric #include "clang/Sema/SemaM68k.h"
520fca6ea1SDimitry Andric #include "clang/Sema/SemaMIPS.h"
530fca6ea1SDimitry Andric #include "clang/Sema/SemaMSP430.h"
540fca6ea1SDimitry Andric #include "clang/Sema/SemaObjC.h"
550fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenCL.h"
560fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenMP.h"
570fca6ea1SDimitry Andric #include "clang/Sema/SemaRISCV.h"
580fca6ea1SDimitry Andric #include "clang/Sema/SemaSYCL.h"
590fca6ea1SDimitry Andric #include "clang/Sema/SemaSwift.h"
600fca6ea1SDimitry Andric #include "clang/Sema/SemaWasm.h"
610fca6ea1SDimitry Andric #include "clang/Sema/SemaX86.h"
620b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
630fca6ea1SDimitry Andric #include "llvm/ADT/STLForwardCompat.h"
640b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
650fca6ea1SDimitry Andric #include "llvm/Demangle/Demangle.h"
66e8d8bef9SDimitry Andric #include "llvm/IR/Assumptions.h"
67fe6060f1SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
68fe6060f1SDimitry Andric #include "llvm/Support/Error.h"
690b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
70e8d8bef9SDimitry Andric #include "llvm/Support/raw_ostream.h"
710fca6ea1SDimitry Andric #include "llvm/TargetParser/Triple.h"
72bdd1243dSDimitry Andric #include <optional>
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric using namespace clang;
750b57cec5SDimitry Andric using namespace sema;
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric namespace AttributeLangSupport {
780b57cec5SDimitry Andric   enum LANG {
790b57cec5SDimitry Andric     C,
800b57cec5SDimitry Andric     Cpp,
810b57cec5SDimitry Andric     ObjC
820b57cec5SDimitry Andric   };
830b57cec5SDimitry Andric } // end namespace AttributeLangSupport
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
860b57cec5SDimitry Andric   // FIXME: Include the type in the argument list.
870b57cec5SDimitry Andric   return AL.getNumArgs() + AL.hasParsedType();
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
900fca6ea1SDimitry Andric SourceLocation Sema::getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric /// Wrapper around checkUInt32Argument, with an extra check to be sure
930b57cec5SDimitry Andric /// that the result will fit into a regular (signed) int. All args have the same
940b57cec5SDimitry Andric /// purpose as they do in checkUInt32Argument.
950b57cec5SDimitry Andric template <typename AttrInfo>
960b57cec5SDimitry Andric static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
970b57cec5SDimitry Andric                                      int &Val, unsigned Idx = UINT_MAX) {
980b57cec5SDimitry Andric   uint32_t UVal;
990fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AI, Expr, UVal, Idx))
1000b57cec5SDimitry Andric     return false;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
1030b57cec5SDimitry Andric     llvm::APSInt I(32); // for toString
1040b57cec5SDimitry Andric     I = UVal;
1050b57cec5SDimitry Andric     S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
106fe6060f1SDimitry Andric         << toString(I, 10, false) << 32 << /* Unsigned */ 0;
1070b57cec5SDimitry Andric     return false;
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   Val = UVal;
1110b57cec5SDimitry Andric   return true;
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
11481ad6265SDimitry Andric bool Sema::checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI,
11581ad6265SDimitry Andric                                           const Expr *E, StringRef &Str,
11681ad6265SDimitry Andric                                           SourceLocation *ArgLocation) {
11781ad6265SDimitry Andric   const auto *Literal = dyn_cast<StringLiteral>(E->IgnoreParenCasts());
11881ad6265SDimitry Andric   if (ArgLocation)
11981ad6265SDimitry Andric     *ArgLocation = E->getBeginLoc();
12081ad6265SDimitry Andric 
1215f757f3fSDimitry Andric   if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
12281ad6265SDimitry Andric     Diag(E->getBeginLoc(), diag::err_attribute_argument_type)
12381ad6265SDimitry Andric         << CI << AANT_ArgumentString;
12481ad6265SDimitry Andric     return false;
12581ad6265SDimitry Andric   }
12681ad6265SDimitry Andric 
12781ad6265SDimitry Andric   Str = Literal->getString();
12881ad6265SDimitry Andric   return true;
12981ad6265SDimitry Andric }
13081ad6265SDimitry Andric 
1310b57cec5SDimitry Andric bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
1320b57cec5SDimitry Andric                                           StringRef &Str,
1330b57cec5SDimitry Andric                                           SourceLocation *ArgLocation) {
1340b57cec5SDimitry Andric   // Look for identifiers. If we have one emit a hint to fix it to a literal.
1350b57cec5SDimitry Andric   if (AL.isArgIdent(ArgNum)) {
1360b57cec5SDimitry Andric     IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);
1370b57cec5SDimitry Andric     Diag(Loc->Loc, diag::err_attribute_argument_type)
1380b57cec5SDimitry Andric         << AL << AANT_ArgumentString
1390b57cec5SDimitry Andric         << FixItHint::CreateInsertion(Loc->Loc, "\"")
1400b57cec5SDimitry Andric         << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");
1410b57cec5SDimitry Andric     Str = Loc->Ident->getName();
1420b57cec5SDimitry Andric     if (ArgLocation)
1430b57cec5SDimitry Andric       *ArgLocation = Loc->Loc;
1440b57cec5SDimitry Andric     return true;
1450b57cec5SDimitry Andric   }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   // Now check for an actual string literal.
1480b57cec5SDimitry Andric   Expr *ArgExpr = AL.getArgAsExpr(ArgNum);
1495f757f3fSDimitry Andric   const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
1505f757f3fSDimitry Andric   if (ArgLocation)
1515f757f3fSDimitry Andric     *ArgLocation = ArgExpr->getBeginLoc();
1525f757f3fSDimitry Andric 
1535f757f3fSDimitry Andric   if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
1545f757f3fSDimitry Andric     Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
1555f757f3fSDimitry Andric         << AL << AANT_ArgumentString;
1565f757f3fSDimitry Andric     return false;
1575f757f3fSDimitry Andric   }
1585f757f3fSDimitry Andric   Str = Literal->getString();
15981ad6265SDimitry Andric   return checkStringLiteralArgumentAttr(AL, ArgExpr, Str, ArgLocation);
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric /// Check if the passed-in expression is of type int or bool.
1630b57cec5SDimitry Andric static bool isIntOrBool(Expr *Exp) {
1640b57cec5SDimitry Andric   QualType QT = Exp->getType();
1650b57cec5SDimitry Andric   return QT->isBooleanType() || QT->isIntegerType();
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric // Check to see if the type is a smart pointer of some kind.  We assume
1700b57cec5SDimitry Andric // it's a smart pointer if it defines both operator-> and operator*.
1710b57cec5SDimitry Andric static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
1720b57cec5SDimitry Andric   auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
1730b57cec5SDimitry Andric                                           OverloadedOperatorKind Op) {
1740b57cec5SDimitry Andric     DeclContextLookupResult Result =
1750b57cec5SDimitry Andric         Record->lookup(S.Context.DeclarationNames.getCXXOperatorName(Op));
1760b57cec5SDimitry Andric     return !Result.empty();
1770b57cec5SDimitry Andric   };
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   const RecordDecl *Record = RT->getDecl();
1800b57cec5SDimitry Andric   bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
1810b57cec5SDimitry Andric   bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
1820b57cec5SDimitry Andric   if (foundStarOperator && foundArrowOperator)
1830b57cec5SDimitry Andric     return true;
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);
1860b57cec5SDimitry Andric   if (!CXXRecord)
1870b57cec5SDimitry Andric     return false;
1880b57cec5SDimitry Andric 
18906c3fb27SDimitry Andric   for (const auto &BaseSpecifier : CXXRecord->bases()) {
1900b57cec5SDimitry Andric     if (!foundStarOperator)
1910b57cec5SDimitry Andric       foundStarOperator = IsOverloadedOperatorPresent(
1920b57cec5SDimitry Andric           BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
1930b57cec5SDimitry Andric     if (!foundArrowOperator)
1940b57cec5SDimitry Andric       foundArrowOperator = IsOverloadedOperatorPresent(
1950b57cec5SDimitry Andric           BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
1960b57cec5SDimitry Andric   }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   if (foundStarOperator && foundArrowOperator)
1990b57cec5SDimitry Andric     return true;
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   return false;
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric /// Check if passed in Decl is a pointer type.
2050b57cec5SDimitry Andric /// Note that this function may produce an error message.
2060b57cec5SDimitry Andric /// \return true if the Decl is a pointer type; false otherwise
2070b57cec5SDimitry Andric static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
2080b57cec5SDimitry Andric                                        const ParsedAttr &AL) {
2090b57cec5SDimitry Andric   const auto *VD = cast<ValueDecl>(D);
2100b57cec5SDimitry Andric   QualType QT = VD->getType();
2110b57cec5SDimitry Andric   if (QT->isAnyPointerType())
2120b57cec5SDimitry Andric     return true;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   if (const auto *RT = QT->getAs<RecordType>()) {
2150b57cec5SDimitry Andric     // If it's an incomplete type, it could be a smart pointer; skip it.
2160b57cec5SDimitry Andric     // (We don't want to force template instantiation if we can avoid it,
2170b57cec5SDimitry Andric     // since that would alter the order in which templates are instantiated.)
2180b57cec5SDimitry Andric     if (RT->isIncompleteType())
2190b57cec5SDimitry Andric       return true;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric     if (threadSafetyCheckIsSmartPointer(S, RT))
2220b57cec5SDimitry Andric       return true;
2230b57cec5SDimitry Andric   }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
2260b57cec5SDimitry Andric   return false;
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric /// Checks that the passed in QualType either is of RecordType or points
2300b57cec5SDimitry Andric /// to RecordType. Returns the relevant RecordType, null if it does not exit.
2310b57cec5SDimitry Andric static const RecordType *getRecordType(QualType QT) {
2320b57cec5SDimitry Andric   if (const auto *RT = QT->getAs<RecordType>())
2330b57cec5SDimitry Andric     return RT;
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   // Now check if we point to record type.
2360b57cec5SDimitry Andric   if (const auto *PT = QT->getAs<PointerType>())
2370b57cec5SDimitry Andric     return PT->getPointeeType()->getAs<RecordType>();
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   return nullptr;
2400b57cec5SDimitry Andric }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric template <typename AttrType>
2430b57cec5SDimitry Andric static bool checkRecordDeclForAttr(const RecordDecl *RD) {
2440b57cec5SDimitry Andric   // Check if the record itself has the attribute.
2450b57cec5SDimitry Andric   if (RD->hasAttr<AttrType>())
2460b57cec5SDimitry Andric     return true;
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   // Else check if any base classes have the attribute.
2490b57cec5SDimitry Andric   if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
250fe6060f1SDimitry Andric     if (!CRD->forallBases([](const CXXRecordDecl *Base) {
251fe6060f1SDimitry Andric           return !Base->hasAttr<AttrType>();
252fe6060f1SDimitry Andric         }))
2530b57cec5SDimitry Andric       return true;
2540b57cec5SDimitry Andric   }
2550b57cec5SDimitry Andric   return false;
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
2590b57cec5SDimitry Andric   const RecordType *RT = getRecordType(Ty);
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   if (!RT)
2620b57cec5SDimitry Andric     return false;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   // Don't check for the capability if the class hasn't been defined yet.
2650b57cec5SDimitry Andric   if (RT->isIncompleteType())
2660b57cec5SDimitry Andric     return true;
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   // Allow smart pointers to be used as capability objects.
2690b57cec5SDimitry Andric   // FIXME -- Check the type that the smart pointer points to.
2700b57cec5SDimitry Andric   if (threadSafetyCheckIsSmartPointer(S, RT))
2710b57cec5SDimitry Andric     return true;
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric static bool checkTypedefTypeForCapability(QualType Ty) {
2770b57cec5SDimitry Andric   const auto *TD = Ty->getAs<TypedefType>();
2780b57cec5SDimitry Andric   if (!TD)
2790b57cec5SDimitry Andric     return false;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   TypedefNameDecl *TN = TD->getDecl();
2820b57cec5SDimitry Andric   if (!TN)
2830b57cec5SDimitry Andric     return false;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   return TN->hasAttr<CapabilityAttr>();
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric static bool typeHasCapability(Sema &S, QualType Ty) {
2890b57cec5SDimitry Andric   if (checkTypedefTypeForCapability(Ty))
2900b57cec5SDimitry Andric     return true;
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   if (checkRecordTypeForCapability(S, Ty))
2930b57cec5SDimitry Andric     return true;
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   return false;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
2990b57cec5SDimitry Andric   // Capability expressions are simple expressions involving the boolean logic
3000b57cec5SDimitry Andric   // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
3010b57cec5SDimitry Andric   // a DeclRefExpr is found, its type should be checked to determine whether it
3020b57cec5SDimitry Andric   // is a capability or not.
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   if (const auto *E = dyn_cast<CastExpr>(Ex))
3050b57cec5SDimitry Andric     return isCapabilityExpr(S, E->getSubExpr());
3060b57cec5SDimitry Andric   else if (const auto *E = dyn_cast<ParenExpr>(Ex))
3070b57cec5SDimitry Andric     return isCapabilityExpr(S, E->getSubExpr());
3080b57cec5SDimitry Andric   else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
3090b57cec5SDimitry Andric     if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
3100b57cec5SDimitry Andric         E->getOpcode() == UO_Deref)
3110b57cec5SDimitry Andric       return isCapabilityExpr(S, E->getSubExpr());
3120b57cec5SDimitry Andric     return false;
3130b57cec5SDimitry Andric   } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
3140b57cec5SDimitry Andric     if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
3150b57cec5SDimitry Andric       return isCapabilityExpr(S, E->getLHS()) &&
3160b57cec5SDimitry Andric              isCapabilityExpr(S, E->getRHS());
3170b57cec5SDimitry Andric     return false;
3180b57cec5SDimitry Andric   }
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   return typeHasCapability(S, Ex->getType());
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric /// Checks that all attribute arguments, starting from Sidx, resolve to
3240b57cec5SDimitry Andric /// a capability object.
3250b57cec5SDimitry Andric /// \param Sidx The attribute argument index to start checking with.
3260b57cec5SDimitry Andric /// \param ParamIdxOk Whether an argument can be indexing into a function
3270b57cec5SDimitry Andric /// parameter list.
3280b57cec5SDimitry Andric static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
3290b57cec5SDimitry Andric                                            const ParsedAttr &AL,
3300b57cec5SDimitry Andric                                            SmallVectorImpl<Expr *> &Args,
3310b57cec5SDimitry Andric                                            unsigned Sidx = 0,
3320b57cec5SDimitry Andric                                            bool ParamIdxOk = false) {
3330b57cec5SDimitry Andric   if (Sidx == AL.getNumArgs()) {
3340b57cec5SDimitry Andric     // If we don't have any capability arguments, the attribute implicitly
3350b57cec5SDimitry Andric     // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
3360b57cec5SDimitry Andric     // a non-static method, and that the class is a (scoped) capability.
3370b57cec5SDimitry Andric     const auto *MD = dyn_cast<const CXXMethodDecl>(D);
3380b57cec5SDimitry Andric     if (MD && !MD->isStatic()) {
3390b57cec5SDimitry Andric       const CXXRecordDecl *RD = MD->getParent();
3400b57cec5SDimitry Andric       // FIXME -- need to check this again on template instantiation
3410b57cec5SDimitry Andric       if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
3420b57cec5SDimitry Andric           !checkRecordDeclForAttr<ScopedLockableAttr>(RD))
3430b57cec5SDimitry Andric         S.Diag(AL.getLoc(),
3440b57cec5SDimitry Andric                diag::warn_thread_attribute_not_on_capability_member)
3450b57cec5SDimitry Andric             << AL << MD->getParent();
3460b57cec5SDimitry Andric     } else {
3470b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
3480b57cec5SDimitry Andric           << AL;
3490b57cec5SDimitry Andric     }
3500b57cec5SDimitry Andric   }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {
3530b57cec5SDimitry Andric     Expr *ArgExp = AL.getArgAsExpr(Idx);
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric     if (ArgExp->isTypeDependent()) {
3560b57cec5SDimitry Andric       // FIXME -- need to check this again on template instantiation
3570b57cec5SDimitry Andric       Args.push_back(ArgExp);
3580b57cec5SDimitry Andric       continue;
3590b57cec5SDimitry Andric     }
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric     if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
3620b57cec5SDimitry Andric       if (StrLit->getLength() == 0 ||
3630fca6ea1SDimitry Andric           (StrLit->isOrdinary() && StrLit->getString() == "*")) {
3640b57cec5SDimitry Andric         // Pass empty strings to the analyzer without warnings.
3650b57cec5SDimitry Andric         // Treat "*" as the universal lock.
3660b57cec5SDimitry Andric         Args.push_back(ArgExp);
3670b57cec5SDimitry Andric         continue;
3680b57cec5SDimitry Andric       }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric       // We allow constant strings to be used as a placeholder for expressions
3710b57cec5SDimitry Andric       // that are not valid C++ syntax, but warn that they are ignored.
3720b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
3730b57cec5SDimitry Andric       Args.push_back(ArgExp);
3740b57cec5SDimitry Andric       continue;
3750b57cec5SDimitry Andric     }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric     QualType ArgTy = ArgExp->getType();
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric     // A pointer to member expression of the form  &MyClass::mu is treated
3800b57cec5SDimitry Andric     // specially -- we need to look at the type of the member.
3810b57cec5SDimitry Andric     if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))
3820b57cec5SDimitry Andric       if (UOp->getOpcode() == UO_AddrOf)
3830b57cec5SDimitry Andric         if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
3840b57cec5SDimitry Andric           if (DRE->getDecl()->isCXXInstanceMember())
3850b57cec5SDimitry Andric             ArgTy = DRE->getDecl()->getType();
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric     // First see if we can just cast to record type, or pointer to record type.
3880b57cec5SDimitry Andric     const RecordType *RT = getRecordType(ArgTy);
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric     // Now check if we index into a record type function param.
3910b57cec5SDimitry Andric     if(!RT && ParamIdxOk) {
3920b57cec5SDimitry Andric       const auto *FD = dyn_cast<FunctionDecl>(D);
3930b57cec5SDimitry Andric       const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
3940b57cec5SDimitry Andric       if(FD && IL) {
3950b57cec5SDimitry Andric         unsigned int NumParams = FD->getNumParams();
3960b57cec5SDimitry Andric         llvm::APInt ArgValue = IL->getValue();
3970b57cec5SDimitry Andric         uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
3980b57cec5SDimitry Andric         uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
3990b57cec5SDimitry Andric         if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
4000b57cec5SDimitry Andric           S.Diag(AL.getLoc(),
4010b57cec5SDimitry Andric                  diag::err_attribute_argument_out_of_bounds_extra_info)
4020b57cec5SDimitry Andric               << AL << Idx + 1 << NumParams;
4030b57cec5SDimitry Andric           continue;
4040b57cec5SDimitry Andric         }
4050b57cec5SDimitry Andric         ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
4060b57cec5SDimitry Andric       }
4070b57cec5SDimitry Andric     }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric     // If the type does not have a capability, see if the components of the
4100b57cec5SDimitry Andric     // expression have capabilities. This allows for writing C code where the
4110b57cec5SDimitry Andric     // capability may be on the type, and the expression is a capability
4120b57cec5SDimitry Andric     // boolean logic expression. Eg) requires_capability(A || B && !C)
4130b57cec5SDimitry Andric     if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
4140b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
4150b57cec5SDimitry Andric           << AL << ArgTy;
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric     Args.push_back(ArgExp);
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4220b57cec5SDimitry Andric // Attribute Implementations
4230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4260b57cec5SDimitry Andric   if (!threadSafetyCheckIsPointer(S, D, AL))
4270b57cec5SDimitry Andric     return;
4280b57cec5SDimitry Andric 
429a7dea167SDimitry Andric   D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
4330b57cec5SDimitry Andric                                      Expr *&Arg) {
4340b57cec5SDimitry Andric   SmallVector<Expr *, 1> Args;
4350b57cec5SDimitry Andric   // check that all arguments are lockable objects
4360b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
4370b57cec5SDimitry Andric   unsigned Size = Args.size();
4380b57cec5SDimitry Andric   if (Size != 1)
4390b57cec5SDimitry Andric     return false;
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric   Arg = Args[0];
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   return true;
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4470b57cec5SDimitry Andric   Expr *Arg = nullptr;
4480b57cec5SDimitry Andric   if (!checkGuardedByAttrCommon(S, D, AL, Arg))
4490b57cec5SDimitry Andric     return;
4500b57cec5SDimitry Andric 
451a7dea167SDimitry Andric   D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4550b57cec5SDimitry Andric   Expr *Arg = nullptr;
4560b57cec5SDimitry Andric   if (!checkGuardedByAttrCommon(S, D, AL, Arg))
4570b57cec5SDimitry Andric     return;
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   if (!threadSafetyCheckIsPointer(S, D, AL))
4600b57cec5SDimitry Andric     return;
4610b57cec5SDimitry Andric 
462a7dea167SDimitry Andric   D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
4630b57cec5SDimitry Andric }
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
4660b57cec5SDimitry Andric                                         SmallVectorImpl<Expr *> &Args) {
467fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
4680b57cec5SDimitry Andric     return false;
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   // Check that this attribute only applies to lockable types.
4710b57cec5SDimitry Andric   QualType QT = cast<ValueDecl>(D)->getType();
4720b57cec5SDimitry Andric   if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
4730b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
4740b57cec5SDimitry Andric     return false;
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   // Check that all arguments are lockable objects.
4780b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
4790b57cec5SDimitry Andric   if (Args.empty())
4800b57cec5SDimitry Andric     return false;
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   return true;
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4860b57cec5SDimitry Andric   SmallVector<Expr *, 1> Args;
4870b57cec5SDimitry Andric   if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
4880b57cec5SDimitry Andric     return;
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   Expr **StartArg = &Args[0];
491a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
492a7dea167SDimitry Andric                  AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
4930b57cec5SDimitry Andric }
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4960b57cec5SDimitry Andric   SmallVector<Expr *, 1> Args;
4970b57cec5SDimitry Andric   if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
4980b57cec5SDimitry Andric     return;
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   Expr **StartArg = &Args[0];
501a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
502a7dea167SDimitry Andric                  AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
5060b57cec5SDimitry Andric                                    SmallVectorImpl<Expr *> &Args) {
5070b57cec5SDimitry Andric   // zero or more arguments ok
5080b57cec5SDimitry Andric   // check that all arguments are lockable objects
5090b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric   return true;
5120b57cec5SDimitry Andric }
5130b57cec5SDimitry Andric 
5140b57cec5SDimitry Andric static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5150b57cec5SDimitry Andric   SmallVector<Expr *, 1> Args;
5160b57cec5SDimitry Andric   if (!checkLockFunAttrCommon(S, D, AL, Args))
5170b57cec5SDimitry Andric     return;
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   unsigned Size = Args.size();
5200b57cec5SDimitry Andric   Expr **StartArg = Size == 0 ? nullptr : &Args[0];
5210b57cec5SDimitry Andric   D->addAttr(::new (S.Context)
522a7dea167SDimitry Andric                  AssertSharedLockAttr(S.Context, AL, StartArg, Size));
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
5260b57cec5SDimitry Andric                                           const ParsedAttr &AL) {
5270b57cec5SDimitry Andric   SmallVector<Expr *, 1> Args;
5280b57cec5SDimitry Andric   if (!checkLockFunAttrCommon(S, D, AL, Args))
5290b57cec5SDimitry Andric     return;
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   unsigned Size = Args.size();
5320b57cec5SDimitry Andric   Expr **StartArg = Size == 0 ? nullptr : &Args[0];
533a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
534a7dea167SDimitry Andric                  AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
5350b57cec5SDimitry Andric }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric /// Checks to be sure that the given parameter number is in bounds, and
5380b57cec5SDimitry Andric /// is an integral type. Will emit appropriate diagnostics if this returns
5390b57cec5SDimitry Andric /// false.
5400b57cec5SDimitry Andric ///
5410b57cec5SDimitry Andric /// AttrArgNo is used to actually retrieve the argument, so it's base-0.
5420b57cec5SDimitry Andric template <typename AttrInfo>
543fe6060f1SDimitry Andric static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
544fe6060f1SDimitry Andric                                     unsigned AttrArgNo) {
5450b57cec5SDimitry Andric   assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
5460b57cec5SDimitry Andric   Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
5470b57cec5SDimitry Andric   ParamIdx Idx;
5480fca6ea1SDimitry Andric   if (!S.checkFunctionOrMethodParameterIndex(D, AI, AttrArgNo + 1, AttrArg,
5490b57cec5SDimitry Andric                                              Idx))
5500b57cec5SDimitry Andric     return false;
5510b57cec5SDimitry Andric 
552fe6060f1SDimitry Andric   QualType ParamTy = getFunctionOrMethodParamType(D, Idx.getASTIndex());
553fe6060f1SDimitry Andric   if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {
5540b57cec5SDimitry Andric     SourceLocation SrcLoc = AttrArg->getBeginLoc();
5550b57cec5SDimitry Andric     S.Diag(SrcLoc, diag::err_attribute_integers_only)
556fe6060f1SDimitry Andric         << AI << getFunctionOrMethodParamRange(D, Idx.getASTIndex());
5570b57cec5SDimitry Andric     return false;
5580b57cec5SDimitry Andric   }
5590b57cec5SDimitry Andric   return true;
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
563fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
5640b57cec5SDimitry Andric     return;
5650b57cec5SDimitry Andric 
5660fca6ea1SDimitry Andric   assert(isFuncOrMethodForAttrSubject(D) && hasFunctionProto(D));
567fe6060f1SDimitry Andric 
568fe6060f1SDimitry Andric   QualType RetTy = getFunctionOrMethodResultType(D);
569fe6060f1SDimitry Andric   if (!RetTy->isPointerType()) {
5700b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
5710b57cec5SDimitry Andric     return;
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   const Expr *SizeExpr = AL.getArgAsExpr(0);
5750b57cec5SDimitry Andric   int SizeArgNoVal;
5760b57cec5SDimitry Andric   // Parameter indices are 1-indexed, hence Index=1
5770b57cec5SDimitry Andric   if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
5780b57cec5SDimitry Andric     return;
579fe6060f1SDimitry Andric   if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/0))
5800b57cec5SDimitry Andric     return;
5810b57cec5SDimitry Andric   ParamIdx SizeArgNo(SizeArgNoVal, D);
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric   ParamIdx NumberArgNo;
5840b57cec5SDimitry Andric   if (AL.getNumArgs() == 2) {
5850b57cec5SDimitry Andric     const Expr *NumberExpr = AL.getArgAsExpr(1);
5860b57cec5SDimitry Andric     int Val;
5870b57cec5SDimitry Andric     // Parameter indices are 1-based, hence Index=2
5880b57cec5SDimitry Andric     if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
5890b57cec5SDimitry Andric       return;
590fe6060f1SDimitry Andric     if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/1))
5910b57cec5SDimitry Andric       return;
5920b57cec5SDimitry Andric     NumberArgNo = ParamIdx(Val, D);
5930b57cec5SDimitry Andric   }
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   D->addAttr(::new (S.Context)
596a7dea167SDimitry Andric                  AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
6000b57cec5SDimitry Andric                                       SmallVectorImpl<Expr *> &Args) {
601fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
6020b57cec5SDimitry Andric     return false;
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   if (!isIntOrBool(AL.getArgAsExpr(0))) {
6050b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
6060b57cec5SDimitry Andric         << AL << 1 << AANT_ArgumentIntOrBool;
6070b57cec5SDimitry Andric     return false;
6080b57cec5SDimitry Andric   }
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric   // check that all arguments are lockable objects
6110b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   return true;
6140b57cec5SDimitry Andric }
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
6170b57cec5SDimitry Andric                                             const ParsedAttr &AL) {
6180b57cec5SDimitry Andric   SmallVector<Expr*, 2> Args;
6190b57cec5SDimitry Andric   if (!checkTryLockFunAttrCommon(S, D, AL, Args))
6200b57cec5SDimitry Andric     return;
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric   D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
623a7dea167SDimitry Andric       S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
6240b57cec5SDimitry Andric }
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
6270b57cec5SDimitry Andric                                                const ParsedAttr &AL) {
6280b57cec5SDimitry Andric   SmallVector<Expr*, 2> Args;
6290b57cec5SDimitry Andric   if (!checkTryLockFunAttrCommon(S, D, AL, Args))
6300b57cec5SDimitry Andric     return;
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric   D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
633a7dea167SDimitry Andric       S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6370b57cec5SDimitry Andric   // check that the argument is lockable object
6380b57cec5SDimitry Andric   SmallVector<Expr*, 1> Args;
6390b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
6400b57cec5SDimitry Andric   unsigned Size = Args.size();
6410b57cec5SDimitry Andric   if (Size == 0)
6420b57cec5SDimitry Andric     return;
6430b57cec5SDimitry Andric 
644a7dea167SDimitry Andric   D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
648fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
6490b57cec5SDimitry Andric     return;
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   // check that all arguments are lockable objects
6520b57cec5SDimitry Andric   SmallVector<Expr*, 1> Args;
6530b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
6540b57cec5SDimitry Andric   unsigned Size = Args.size();
6550b57cec5SDimitry Andric   if (Size == 0)
6560b57cec5SDimitry Andric     return;
6570b57cec5SDimitry Andric   Expr **StartArg = &Args[0];
6580b57cec5SDimitry Andric 
6590b57cec5SDimitry Andric   D->addAttr(::new (S.Context)
660a7dea167SDimitry Andric                  LocksExcludedAttr(S.Context, AL, StartArg, Size));
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
6640b57cec5SDimitry Andric                                        Expr *&Cond, StringRef &Msg) {
6650b57cec5SDimitry Andric   Cond = AL.getArgAsExpr(0);
6660b57cec5SDimitry Andric   if (!Cond->isTypeDependent()) {
6670b57cec5SDimitry Andric     ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
6680b57cec5SDimitry Andric     if (Converted.isInvalid())
6690b57cec5SDimitry Andric       return false;
6700b57cec5SDimitry Andric     Cond = Converted.get();
6710b57cec5SDimitry Andric   }
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))
6740b57cec5SDimitry Andric     return false;
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric   if (Msg.empty())
6770b57cec5SDimitry Andric     Msg = "<no message provided>";
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric   SmallVector<PartialDiagnosticAt, 8> Diags;
6800b57cec5SDimitry Andric   if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&
6810b57cec5SDimitry Andric       !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
6820b57cec5SDimitry Andric                                                 Diags)) {
6830b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
6840b57cec5SDimitry Andric     for (const PartialDiagnosticAt &PDiag : Diags)
6850b57cec5SDimitry Andric       S.Diag(PDiag.first, PDiag.second);
6860b57cec5SDimitry Andric     return false;
6870b57cec5SDimitry Andric   }
6880b57cec5SDimitry Andric   return true;
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6920b57cec5SDimitry Andric   S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   Expr *Cond;
6950b57cec5SDimitry Andric   StringRef Msg;
6960b57cec5SDimitry Andric   if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
697a7dea167SDimitry Andric     D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
6980b57cec5SDimitry Andric }
6990b57cec5SDimitry Andric 
700349cc55cSDimitry Andric static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
701349cc55cSDimitry Andric   StringRef NewUserDiagnostic;
702349cc55cSDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, NewUserDiagnostic))
703349cc55cSDimitry Andric     return;
704349cc55cSDimitry Andric   if (ErrorAttr *EA = S.mergeErrorAttr(D, AL, NewUserDiagnostic))
705349cc55cSDimitry Andric     D->addAttr(EA);
706349cc55cSDimitry Andric }
707349cc55cSDimitry Andric 
7080fca6ea1SDimitry Andric static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
7090fca6ea1SDimitry Andric                                                        const ParsedAttr &AL) {
7100fca6ea1SDimitry Andric   const auto *PD = isa<CXXRecordDecl>(D)
7110fca6ea1SDimitry Andric                        ? cast<DeclContext>(D)
7120fca6ea1SDimitry Andric                        : D->getDeclContext()->getRedeclContext();
7130fca6ea1SDimitry Andric   if (const auto *RD = dyn_cast<CXXRecordDecl>(PD); RD && RD->isLocalClass()) {
7140fca6ea1SDimitry Andric     S.Diag(AL.getLoc(),
7150fca6ea1SDimitry Andric            diag::warn_attribute_exclude_from_explicit_instantiation_local_class)
7160fca6ea1SDimitry Andric         << AL << /*IsMember=*/!isa<CXXRecordDecl>(D);
7170fca6ea1SDimitry Andric     return;
7180fca6ea1SDimitry Andric   }
7190fca6ea1SDimitry Andric   D->addAttr(::new (S.Context)
7200fca6ea1SDimitry Andric                  ExcludeFromExplicitInstantiationAttr(S.Context, AL));
7210fca6ea1SDimitry Andric }
7220fca6ea1SDimitry Andric 
7230b57cec5SDimitry Andric namespace {
7240b57cec5SDimitry Andric /// Determines if a given Expr references any of the given function's
7250b57cec5SDimitry Andric /// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
7260b57cec5SDimitry Andric class ArgumentDependenceChecker
7270b57cec5SDimitry Andric     : public RecursiveASTVisitor<ArgumentDependenceChecker> {
7280b57cec5SDimitry Andric #ifndef NDEBUG
7290b57cec5SDimitry Andric   const CXXRecordDecl *ClassType;
7300b57cec5SDimitry Andric #endif
7310b57cec5SDimitry Andric   llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
7320b57cec5SDimitry Andric   bool Result;
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric public:
7350b57cec5SDimitry Andric   ArgumentDependenceChecker(const FunctionDecl *FD) {
7360b57cec5SDimitry Andric #ifndef NDEBUG
7370b57cec5SDimitry Andric     if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
7380b57cec5SDimitry Andric       ClassType = MD->getParent();
7390b57cec5SDimitry Andric     else
7400b57cec5SDimitry Andric       ClassType = nullptr;
7410b57cec5SDimitry Andric #endif
7420b57cec5SDimitry Andric     Parms.insert(FD->param_begin(), FD->param_end());
7430b57cec5SDimitry Andric   }
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric   bool referencesArgs(Expr *E) {
7460b57cec5SDimitry Andric     Result = false;
7470b57cec5SDimitry Andric     TraverseStmt(E);
7480b57cec5SDimitry Andric     return Result;
7490b57cec5SDimitry Andric   }
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric   bool VisitCXXThisExpr(CXXThisExpr *E) {
7520b57cec5SDimitry Andric     assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
7530b57cec5SDimitry Andric            "`this` doesn't refer to the enclosing class?");
7540b57cec5SDimitry Andric     Result = true;
7550b57cec5SDimitry Andric     return false;
7560b57cec5SDimitry Andric   }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
7590b57cec5SDimitry Andric     if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7600b57cec5SDimitry Andric       if (Parms.count(PVD)) {
7610b57cec5SDimitry Andric         Result = true;
7620b57cec5SDimitry Andric         return false;
7630b57cec5SDimitry Andric       }
7640b57cec5SDimitry Andric     return true;
7650b57cec5SDimitry Andric   }
7660b57cec5SDimitry Andric };
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric 
7690eae32dcSDimitry Andric static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D,
7700eae32dcSDimitry Andric                                         const ParsedAttr &AL) {
7710eae32dcSDimitry Andric   const auto *DeclFD = cast<FunctionDecl>(D);
7720eae32dcSDimitry Andric 
7730eae32dcSDimitry Andric   if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(DeclFD))
7740eae32dcSDimitry Andric     if (!MethodDecl->isStatic()) {
7750eae32dcSDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_no_member_function) << AL;
7760eae32dcSDimitry Andric       return;
7770eae32dcSDimitry Andric     }
7780eae32dcSDimitry Andric 
7790eae32dcSDimitry Andric   auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {
7800eae32dcSDimitry Andric     SourceLocation Loc = [&]() {
7810eae32dcSDimitry Andric       auto Union = AL.getArg(Index - 1);
7820eae32dcSDimitry Andric       if (Union.is<Expr *>())
7830eae32dcSDimitry Andric         return Union.get<Expr *>()->getBeginLoc();
7840eae32dcSDimitry Andric       return Union.get<IdentifierLoc *>()->Loc;
7850eae32dcSDimitry Andric     }();
7860eae32dcSDimitry Andric 
7870eae32dcSDimitry Andric     S.Diag(Loc, diag::err_attribute_argument_n_type) << AL << Index << T;
7880eae32dcSDimitry Andric   };
7890eae32dcSDimitry Andric 
7900eae32dcSDimitry Andric   FunctionDecl *AttrFD = [&]() -> FunctionDecl * {
7910eae32dcSDimitry Andric     if (!AL.isArgExpr(0))
7920eae32dcSDimitry Andric       return nullptr;
7935f757f3fSDimitry Andric     auto *F = dyn_cast_if_present<DeclRefExpr>(AL.getArgAsExpr(0));
7940eae32dcSDimitry Andric     if (!F)
7950eae32dcSDimitry Andric       return nullptr;
7965f757f3fSDimitry Andric     return dyn_cast_if_present<FunctionDecl>(F->getFoundDecl());
7970eae32dcSDimitry Andric   }();
7980eae32dcSDimitry Andric 
7990eae32dcSDimitry Andric   if (!AttrFD || !AttrFD->getBuiltinID(true)) {
8000eae32dcSDimitry Andric     DiagnoseType(1, AANT_ArgumentBuiltinFunction);
8010eae32dcSDimitry Andric     return;
8020eae32dcSDimitry Andric   }
8030eae32dcSDimitry Andric 
8040eae32dcSDimitry Andric   if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {
8050eae32dcSDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments_for)
8060eae32dcSDimitry Andric         << AL << AttrFD << AttrFD->getNumParams();
8070eae32dcSDimitry Andric     return;
8080eae32dcSDimitry Andric   }
8090eae32dcSDimitry Andric 
8100eae32dcSDimitry Andric   SmallVector<unsigned, 8> Indices;
8110eae32dcSDimitry Andric 
8120eae32dcSDimitry Andric   for (unsigned I = 1; I < AL.getNumArgs(); ++I) {
8130eae32dcSDimitry Andric     if (!AL.isArgExpr(I)) {
8140eae32dcSDimitry Andric       DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);
8150eae32dcSDimitry Andric       return;
8160eae32dcSDimitry Andric     }
8170eae32dcSDimitry Andric 
8180eae32dcSDimitry Andric     const Expr *IndexExpr = AL.getArgAsExpr(I);
8190eae32dcSDimitry Andric     uint32_t Index;
8200eae32dcSDimitry Andric 
8210fca6ea1SDimitry Andric     if (!S.checkUInt32Argument(AL, IndexExpr, Index, I + 1, false))
8220eae32dcSDimitry Andric       return;
8230eae32dcSDimitry Andric 
8240eae32dcSDimitry Andric     if (Index > DeclFD->getNumParams()) {
8250eae32dcSDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_bounds_for_function)
8260eae32dcSDimitry Andric           << AL << Index << DeclFD << DeclFD->getNumParams();
8270eae32dcSDimitry Andric       return;
8280eae32dcSDimitry Andric     }
8290eae32dcSDimitry Andric 
8300eae32dcSDimitry Andric     QualType T1 = AttrFD->getParamDecl(I - 1)->getType();
8310eae32dcSDimitry Andric     QualType T2 = DeclFD->getParamDecl(Index - 1)->getType();
8320eae32dcSDimitry Andric 
8330eae32dcSDimitry Andric     if (T1.getCanonicalType().getUnqualifiedType() !=
8340eae32dcSDimitry Andric         T2.getCanonicalType().getUnqualifiedType()) {
8350eae32dcSDimitry Andric       S.Diag(IndexExpr->getBeginLoc(), diag::err_attribute_parameter_types)
8360eae32dcSDimitry Andric           << AL << Index << DeclFD << T2 << I << AttrFD << T1;
8370eae32dcSDimitry Andric       return;
8380eae32dcSDimitry Andric     }
8390eae32dcSDimitry Andric 
8400eae32dcSDimitry Andric     Indices.push_back(Index - 1);
8410eae32dcSDimitry Andric   }
8420eae32dcSDimitry Andric 
8430eae32dcSDimitry Andric   D->addAttr(::new (S.Context) DiagnoseAsBuiltinAttr(
8440eae32dcSDimitry Andric       S.Context, AL, AttrFD, Indices.data(), Indices.size()));
8450eae32dcSDimitry Andric }
8460eae32dcSDimitry Andric 
8470b57cec5SDimitry Andric static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8480b57cec5SDimitry Andric   S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric   Expr *Cond;
8510b57cec5SDimitry Andric   StringRef Msg;
8520b57cec5SDimitry Andric   if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
8530b57cec5SDimitry Andric     return;
8540b57cec5SDimitry Andric 
8550b57cec5SDimitry Andric   StringRef DiagTypeStr;
8560b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))
8570b57cec5SDimitry Andric     return;
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric   DiagnoseIfAttr::DiagnosticType DiagType;
8600b57cec5SDimitry Andric   if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
8610b57cec5SDimitry Andric     S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
8620b57cec5SDimitry Andric            diag::err_diagnose_if_invalid_diagnostic_type);
8630b57cec5SDimitry Andric     return;
8640b57cec5SDimitry Andric   }
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric   bool ArgDependent = false;
8670b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D))
8680b57cec5SDimitry Andric     ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
8690b57cec5SDimitry Andric   D->addAttr(::new (S.Context) DiagnoseIfAttr(
870a7dea167SDimitry Andric       S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
8710b57cec5SDimitry Andric }
8720b57cec5SDimitry Andric 
873480093f4SDimitry Andric static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
874480093f4SDimitry Andric   static constexpr const StringRef kWildcard = "*";
875480093f4SDimitry Andric 
876480093f4SDimitry Andric   llvm::SmallVector<StringRef, 16> Names;
877480093f4SDimitry Andric   bool HasWildcard = false;
878480093f4SDimitry Andric 
879480093f4SDimitry Andric   const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
880480093f4SDimitry Andric     if (Name == kWildcard)
881480093f4SDimitry Andric       HasWildcard = true;
882480093f4SDimitry Andric     Names.push_back(Name);
883480093f4SDimitry Andric   };
884480093f4SDimitry Andric 
885480093f4SDimitry Andric   // Add previously defined attributes.
886480093f4SDimitry Andric   if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
887480093f4SDimitry Andric     for (StringRef BuiltinName : NBA->builtinNames())
888480093f4SDimitry Andric       AddBuiltinName(BuiltinName);
889480093f4SDimitry Andric 
890480093f4SDimitry Andric   // Add current attributes.
891480093f4SDimitry Andric   if (AL.getNumArgs() == 0)
892480093f4SDimitry Andric     AddBuiltinName(kWildcard);
893480093f4SDimitry Andric   else
894480093f4SDimitry Andric     for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
895480093f4SDimitry Andric       StringRef BuiltinName;
896480093f4SDimitry Andric       SourceLocation LiteralLoc;
897480093f4SDimitry Andric       if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
898480093f4SDimitry Andric         return;
899480093f4SDimitry Andric 
900480093f4SDimitry Andric       if (Builtin::Context::isBuiltinFunc(BuiltinName))
901480093f4SDimitry Andric         AddBuiltinName(BuiltinName);
902480093f4SDimitry Andric       else
903480093f4SDimitry Andric         S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
9045ffd83dbSDimitry Andric             << BuiltinName << AL;
905480093f4SDimitry Andric     }
906480093f4SDimitry Andric 
907480093f4SDimitry Andric   // Repeating the same attribute is fine.
908480093f4SDimitry Andric   llvm::sort(Names);
909480093f4SDimitry Andric   Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
910480093f4SDimitry Andric 
911480093f4SDimitry Andric   // Empty no_builtin must be on its own.
912480093f4SDimitry Andric   if (HasWildcard && Names.size() > 1)
913480093f4SDimitry Andric     S.Diag(D->getLocation(),
914480093f4SDimitry Andric            diag::err_attribute_no_builtin_wildcard_or_builtin_name)
9155ffd83dbSDimitry Andric         << AL;
916480093f4SDimitry Andric 
917480093f4SDimitry Andric   if (D->hasAttr<NoBuiltinAttr>())
918480093f4SDimitry Andric     D->dropAttr<NoBuiltinAttr>();
919480093f4SDimitry Andric   D->addAttr(::new (S.Context)
920480093f4SDimitry Andric                  NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
921480093f4SDimitry Andric }
922480093f4SDimitry Andric 
9230b57cec5SDimitry Andric static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9240b57cec5SDimitry Andric   if (D->hasAttr<PassObjectSizeAttr>()) {
9250b57cec5SDimitry Andric     S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
9260b57cec5SDimitry Andric     return;
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric   Expr *E = AL.getArgAsExpr(0);
9300b57cec5SDimitry Andric   uint32_t Type;
9310fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, E, Type, /*Idx=*/1))
9320b57cec5SDimitry Andric     return;
9330b57cec5SDimitry Andric 
9340b57cec5SDimitry Andric   // pass_object_size's argument is passed in as the second argument of
9350b57cec5SDimitry Andric   // __builtin_object_size. So, it has the same constraints as that second
9360b57cec5SDimitry Andric   // argument; namely, it must be in the range [0, 3].
9370b57cec5SDimitry Andric   if (Type > 3) {
9380b57cec5SDimitry Andric     S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
9390b57cec5SDimitry Andric         << AL << 0 << 3 << E->getSourceRange();
9400b57cec5SDimitry Andric     return;
9410b57cec5SDimitry Andric   }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   // pass_object_size is only supported on constant pointer parameters; as a
9440b57cec5SDimitry Andric   // kindness to users, we allow the parameter to be non-const for declarations.
9450b57cec5SDimitry Andric   // At this point, we have no clue if `D` belongs to a function declaration or
9460b57cec5SDimitry Andric   // definition, so we defer the constness check until later.
9470b57cec5SDimitry Andric   if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
9480b57cec5SDimitry Andric     S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
9490b57cec5SDimitry Andric     return;
9500b57cec5SDimitry Andric   }
9510b57cec5SDimitry Andric 
952a7dea167SDimitry Andric   D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
9530b57cec5SDimitry Andric }
9540b57cec5SDimitry Andric 
9550b57cec5SDimitry Andric static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
9560b57cec5SDimitry Andric   ConsumableAttr::ConsumedState DefaultState;
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   if (AL.isArgIdent(0)) {
9590b57cec5SDimitry Andric     IdentifierLoc *IL = AL.getArgAsIdent(0);
9600b57cec5SDimitry Andric     if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
9610b57cec5SDimitry Andric                                                    DefaultState)) {
9620b57cec5SDimitry Andric       S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
9630b57cec5SDimitry Andric                                                                << IL->Ident;
9640b57cec5SDimitry Andric       return;
9650b57cec5SDimitry Andric     }
9660b57cec5SDimitry Andric   } else {
9670b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
9680b57cec5SDimitry Andric         << AL << AANT_ArgumentIdentifier;
9690b57cec5SDimitry Andric     return;
9700b57cec5SDimitry Andric   }
9710b57cec5SDimitry Andric 
972a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
9760b57cec5SDimitry Andric                                     const ParsedAttr &AL) {
9775f757f3fSDimitry Andric   QualType ThisType = MD->getFunctionObjectParameterType();
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
9800b57cec5SDimitry Andric     if (!RD->hasAttr<ConsumableAttr>()) {
9815ffd83dbSDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
9820b57cec5SDimitry Andric 
9830b57cec5SDimitry Andric       return false;
9840b57cec5SDimitry Andric     }
9850b57cec5SDimitry Andric   }
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric   return true;
9880b57cec5SDimitry Andric }
9890b57cec5SDimitry Andric 
9900b57cec5SDimitry Andric static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
991fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
9920b57cec5SDimitry Andric     return;
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric   if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
9950b57cec5SDimitry Andric     return;
9960b57cec5SDimitry Andric 
9970b57cec5SDimitry Andric   SmallVector<CallableWhenAttr::ConsumedState, 3> States;
9980b57cec5SDimitry Andric   for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
9990b57cec5SDimitry Andric     CallableWhenAttr::ConsumedState CallableState;
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric     StringRef StateString;
10020b57cec5SDimitry Andric     SourceLocation Loc;
10030b57cec5SDimitry Andric     if (AL.isArgIdent(ArgIndex)) {
10040b57cec5SDimitry Andric       IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);
10050b57cec5SDimitry Andric       StateString = Ident->Ident->getName();
10060b57cec5SDimitry Andric       Loc = Ident->Loc;
10070b57cec5SDimitry Andric     } else {
10080b57cec5SDimitry Andric       if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))
10090b57cec5SDimitry Andric         return;
10100b57cec5SDimitry Andric     }
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric     if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
10130b57cec5SDimitry Andric                                                      CallableState)) {
10140b57cec5SDimitry Andric       S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
10150b57cec5SDimitry Andric       return;
10160b57cec5SDimitry Andric     }
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric     States.push_back(CallableState);
10190b57cec5SDimitry Andric   }
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric   D->addAttr(::new (S.Context)
1022a7dea167SDimitry Andric                  CallableWhenAttr(S.Context, AL, States.data(), States.size()));
10230b57cec5SDimitry Andric }
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
10260b57cec5SDimitry Andric   ParamTypestateAttr::ConsumedState ParamState;
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric   if (AL.isArgIdent(0)) {
10290b57cec5SDimitry Andric     IdentifierLoc *Ident = AL.getArgAsIdent(0);
10300b57cec5SDimitry Andric     StringRef StateString = Ident->Ident->getName();
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric     if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
10330b57cec5SDimitry Andric                                                        ParamState)) {
10340b57cec5SDimitry Andric       S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
10350b57cec5SDimitry Andric           << AL << StateString;
10360b57cec5SDimitry Andric       return;
10370b57cec5SDimitry Andric     }
10380b57cec5SDimitry Andric   } else {
10390b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
10400b57cec5SDimitry Andric         << AL << AANT_ArgumentIdentifier;
10410b57cec5SDimitry Andric     return;
10420b57cec5SDimitry Andric   }
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   // FIXME: This check is currently being done in the analysis.  It can be
10450b57cec5SDimitry Andric   //        enabled here only after the parser propagates attributes at
10460b57cec5SDimitry Andric   //        template specialization definition, not declaration.
10470b57cec5SDimitry Andric   //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
10480b57cec5SDimitry Andric   //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
10490b57cec5SDimitry Andric   //
10500b57cec5SDimitry Andric   //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
10510b57cec5SDimitry Andric   //    S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
10520b57cec5SDimitry Andric   //      ReturnType.getAsString();
10530b57cec5SDimitry Andric   //    return;
10540b57cec5SDimitry Andric   //}
10550b57cec5SDimitry Andric 
1056a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
10570b57cec5SDimitry Andric }
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
10600b57cec5SDimitry Andric   ReturnTypestateAttr::ConsumedState ReturnState;
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric   if (AL.isArgIdent(0)) {
10630b57cec5SDimitry Andric     IdentifierLoc *IL = AL.getArgAsIdent(0);
10640b57cec5SDimitry Andric     if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
10650b57cec5SDimitry Andric                                                         ReturnState)) {
10660b57cec5SDimitry Andric       S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
10670b57cec5SDimitry Andric                                                                << IL->Ident;
10680b57cec5SDimitry Andric       return;
10690b57cec5SDimitry Andric     }
10700b57cec5SDimitry Andric   } else {
10710b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
10720b57cec5SDimitry Andric         << AL << AANT_ArgumentIdentifier;
10730b57cec5SDimitry Andric     return;
10740b57cec5SDimitry Andric   }
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   // FIXME: This check is currently being done in the analysis.  It can be
10770b57cec5SDimitry Andric   //        enabled here only after the parser propagates attributes at
10780b57cec5SDimitry Andric   //        template specialization definition, not declaration.
10790b57cec5SDimitry Andric   // QualType ReturnType;
10800b57cec5SDimitry Andric   //
10810b57cec5SDimitry Andric   // if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
10820b57cec5SDimitry Andric   //  ReturnType = Param->getType();
10830b57cec5SDimitry Andric   //
10840b57cec5SDimitry Andric   //} else if (const CXXConstructorDecl *Constructor =
10850b57cec5SDimitry Andric   //             dyn_cast<CXXConstructorDecl>(D)) {
10865f757f3fSDimitry Andric   //  ReturnType = Constructor->getFunctionObjectParameterType();
10870b57cec5SDimitry Andric   //
10880b57cec5SDimitry Andric   //} else {
10890b57cec5SDimitry Andric   //
10900b57cec5SDimitry Andric   //  ReturnType = cast<FunctionDecl>(D)->getCallResultType();
10910b57cec5SDimitry Andric   //}
10920b57cec5SDimitry Andric   //
10930b57cec5SDimitry Andric   // const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
10940b57cec5SDimitry Andric   //
10950b57cec5SDimitry Andric   // if (!RD || !RD->hasAttr<ConsumableAttr>()) {
10960b57cec5SDimitry Andric   //    S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
10970b57cec5SDimitry Andric   //      ReturnType.getAsString();
10980b57cec5SDimitry Andric   //    return;
10990b57cec5SDimitry Andric   //}
11000b57cec5SDimitry Andric 
1101a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
11050b57cec5SDimitry Andric   if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
11060b57cec5SDimitry Andric     return;
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric   SetTypestateAttr::ConsumedState NewState;
11090b57cec5SDimitry Andric   if (AL.isArgIdent(0)) {
11100b57cec5SDimitry Andric     IdentifierLoc *Ident = AL.getArgAsIdent(0);
11110b57cec5SDimitry Andric     StringRef Param = Ident->Ident->getName();
11120b57cec5SDimitry Andric     if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
11130b57cec5SDimitry Andric       S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
11140b57cec5SDimitry Andric                                                                   << Param;
11150b57cec5SDimitry Andric       return;
11160b57cec5SDimitry Andric     }
11170b57cec5SDimitry Andric   } else {
11180b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
11190b57cec5SDimitry Andric         << AL << AANT_ArgumentIdentifier;
11200b57cec5SDimitry Andric     return;
11210b57cec5SDimitry Andric   }
11220b57cec5SDimitry Andric 
1123a7dea167SDimitry Andric   D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
11240b57cec5SDimitry Andric }
11250b57cec5SDimitry Andric 
11260b57cec5SDimitry Andric static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
11270b57cec5SDimitry Andric   if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
11280b57cec5SDimitry Andric     return;
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric   TestTypestateAttr::ConsumedState TestState;
11310b57cec5SDimitry Andric   if (AL.isArgIdent(0)) {
11320b57cec5SDimitry Andric     IdentifierLoc *Ident = AL.getArgAsIdent(0);
11330b57cec5SDimitry Andric     StringRef Param = Ident->Ident->getName();
11340b57cec5SDimitry Andric     if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
11350b57cec5SDimitry Andric       S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
11360b57cec5SDimitry Andric                                                                   << Param;
11370b57cec5SDimitry Andric       return;
11380b57cec5SDimitry Andric     }
11390b57cec5SDimitry Andric   } else {
11400b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
11410b57cec5SDimitry Andric         << AL << AANT_ArgumentIdentifier;
11420b57cec5SDimitry Andric     return;
11430b57cec5SDimitry Andric   }
11440b57cec5SDimitry Andric 
1145a7dea167SDimitry Andric   D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
11460b57cec5SDimitry Andric }
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
11490b57cec5SDimitry Andric   // Remember this typedef decl, we will need it later for diagnostics.
11500b57cec5SDimitry Andric   S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
11510b57cec5SDimitry Andric }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
11540b57cec5SDimitry Andric   if (auto *TD = dyn_cast<TagDecl>(D))
1155a7dea167SDimitry Andric     TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
11560b57cec5SDimitry Andric   else if (auto *FD = dyn_cast<FieldDecl>(D)) {
11570b57cec5SDimitry Andric     bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
11580b57cec5SDimitry Andric                                 !FD->getType()->isIncompleteType() &&
11590b57cec5SDimitry Andric                                 FD->isBitField() &&
11600b57cec5SDimitry Andric                                 S.Context.getTypeAlign(FD->getType()) <= 8);
11610b57cec5SDimitry Andric 
116281ad6265SDimitry Andric     if (S.getASTContext().getTargetInfo().getTriple().isPS()) {
11630b57cec5SDimitry Andric       if (BitfieldByteAligned)
116481ad6265SDimitry Andric         // The PS4/PS5 targets need to maintain ABI backwards compatibility.
11650b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
11660b57cec5SDimitry Andric             << AL << FD->getType();
11670b57cec5SDimitry Andric       else
1168a7dea167SDimitry Andric         FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
11690b57cec5SDimitry Andric     } else {
11700b57cec5SDimitry Andric       // Report warning about changed offset in the newer compiler versions.
11710b57cec5SDimitry Andric       if (BitfieldByteAligned)
11720b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
11730b57cec5SDimitry Andric 
1174a7dea167SDimitry Andric       FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
11750b57cec5SDimitry Andric     }
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   } else
11780b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
11790b57cec5SDimitry Andric }
11800b57cec5SDimitry Andric 
1181e8d8bef9SDimitry Andric static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1182e8d8bef9SDimitry Andric   auto *RD = cast<CXXRecordDecl>(D);
1183e8d8bef9SDimitry Andric   ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1184e8d8bef9SDimitry Andric   assert(CTD && "attribute does not appertain to this declaration");
1185e8d8bef9SDimitry Andric 
1186e8d8bef9SDimitry Andric   ParsedType PT = AL.getTypeArg();
1187e8d8bef9SDimitry Andric   TypeSourceInfo *TSI = nullptr;
1188e8d8bef9SDimitry Andric   QualType T = S.GetTypeFromParser(PT, &TSI);
1189e8d8bef9SDimitry Andric   if (!TSI)
1190e8d8bef9SDimitry Andric     TSI = S.Context.getTrivialTypeSourceInfo(T, AL.getLoc());
1191e8d8bef9SDimitry Andric 
1192e8d8bef9SDimitry Andric   if (!T.hasQualifiers() && T->isTypedefNameType()) {
1193e8d8bef9SDimitry Andric     // Find the template name, if this type names a template specialization.
1194e8d8bef9SDimitry Andric     const TemplateDecl *Template = nullptr;
11955f757f3fSDimitry Andric     if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
1196e8d8bef9SDimitry Andric             T->getAsCXXRecordDecl())) {
1197e8d8bef9SDimitry Andric       Template = CTSD->getSpecializedTemplate();
1198e8d8bef9SDimitry Andric     } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
1199e8d8bef9SDimitry Andric       while (TST && TST->isTypeAlias())
1200e8d8bef9SDimitry Andric         TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1201e8d8bef9SDimitry Andric       if (TST)
1202e8d8bef9SDimitry Andric         Template = TST->getTemplateName().getAsTemplateDecl();
1203e8d8bef9SDimitry Andric     }
1204e8d8bef9SDimitry Andric 
1205e8d8bef9SDimitry Andric     if (Template && declaresSameEntity(Template, CTD)) {
1206e8d8bef9SDimitry Andric       D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1207e8d8bef9SDimitry Andric       return;
1208e8d8bef9SDimitry Andric     }
1209e8d8bef9SDimitry Andric   }
1210e8d8bef9SDimitry Andric 
1211e8d8bef9SDimitry Andric   S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
1212e8d8bef9SDimitry Andric       << T << CTD;
1213e8d8bef9SDimitry Andric   if (const auto *TT = T->getAs<TypedefType>())
1214e8d8bef9SDimitry Andric     S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
1215e8d8bef9SDimitry Andric         << TT->getDecl();
1216e8d8bef9SDimitry Andric }
1217e8d8bef9SDimitry Andric 
12180b57cec5SDimitry Andric bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
12190b57cec5SDimitry Andric   if (RefOkay) {
12200b57cec5SDimitry Andric     if (T->isReferenceType())
12210b57cec5SDimitry Andric       return true;
12220b57cec5SDimitry Andric   } else {
12230b57cec5SDimitry Andric     T = T.getNonReferenceType();
12240b57cec5SDimitry Andric   }
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric   // The nonnull attribute, and other similar attributes, can be applied to a
12270b57cec5SDimitry Andric   // transparent union that contains a pointer type.
12280b57cec5SDimitry Andric   if (const RecordType *UT = T->getAsUnionType()) {
12290b57cec5SDimitry Andric     if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
12300b57cec5SDimitry Andric       RecordDecl *UD = UT->getDecl();
12310b57cec5SDimitry Andric       for (const auto *I : UD->fields()) {
12320b57cec5SDimitry Andric         QualType QT = I->getType();
12330b57cec5SDimitry Andric         if (QT->isAnyPointerType() || QT->isBlockPointerType())
12340b57cec5SDimitry Andric           return true;
12350b57cec5SDimitry Andric       }
12360b57cec5SDimitry Andric     }
12370b57cec5SDimitry Andric   }
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric   return T->isAnyPointerType() || T->isBlockPointerType();
12400b57cec5SDimitry Andric }
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
12430b57cec5SDimitry Andric                                 SourceRange AttrParmRange,
12440b57cec5SDimitry Andric                                 SourceRange TypeRange,
12450b57cec5SDimitry Andric                                 bool isReturnValue = false) {
12460b57cec5SDimitry Andric   if (!S.isValidPointerAttrType(T)) {
12470b57cec5SDimitry Andric     if (isReturnValue)
12480b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
12490b57cec5SDimitry Andric           << AL << AttrParmRange << TypeRange;
12500b57cec5SDimitry Andric     else
12510b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
12520b57cec5SDimitry Andric           << AL << AttrParmRange << TypeRange << 0;
12530b57cec5SDimitry Andric     return false;
12540b57cec5SDimitry Andric   }
12550b57cec5SDimitry Andric   return true;
12560b57cec5SDimitry Andric }
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
12590b57cec5SDimitry Andric   SmallVector<ParamIdx, 8> NonNullArgs;
12600b57cec5SDimitry Andric   for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
12610b57cec5SDimitry Andric     Expr *Ex = AL.getArgAsExpr(I);
12620b57cec5SDimitry Andric     ParamIdx Idx;
12630fca6ea1SDimitry Andric     if (!S.checkFunctionOrMethodParameterIndex(D, AL, I + 1, Ex, Idx))
12640b57cec5SDimitry Andric       return;
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric     // Is the function argument a pointer type?
12670b57cec5SDimitry Andric     if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&
12680b57cec5SDimitry Andric         !attrNonNullArgCheck(
12690b57cec5SDimitry Andric             S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL,
12700b57cec5SDimitry Andric             Ex->getSourceRange(),
12710b57cec5SDimitry Andric             getFunctionOrMethodParamRange(D, Idx.getASTIndex())))
12720b57cec5SDimitry Andric       continue;
12730b57cec5SDimitry Andric 
12740b57cec5SDimitry Andric     NonNullArgs.push_back(Idx);
12750b57cec5SDimitry Andric   }
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   // If no arguments were specified to __attribute__((nonnull)) then all pointer
12780b57cec5SDimitry Andric   // arguments have a nonnull attribute; warn if there aren't any. Skip this
12790b57cec5SDimitry Andric   // check if the attribute came from a macro expansion or a template
12800b57cec5SDimitry Andric   // instantiation.
12810b57cec5SDimitry Andric   if (NonNullArgs.empty() && AL.getLoc().isFileID() &&
12820b57cec5SDimitry Andric       !S.inTemplateInstantiation()) {
12830b57cec5SDimitry Andric     bool AnyPointers = isFunctionOrMethodVariadic(D);
12840b57cec5SDimitry Andric     for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
12850b57cec5SDimitry Andric          I != E && !AnyPointers; ++I) {
12860b57cec5SDimitry Andric       QualType T = getFunctionOrMethodParamType(D, I);
12870b57cec5SDimitry Andric       if (T->isDependentType() || S.isValidPointerAttrType(T))
12880b57cec5SDimitry Andric         AnyPointers = true;
12890b57cec5SDimitry Andric     }
12900b57cec5SDimitry Andric 
12910b57cec5SDimitry Andric     if (!AnyPointers)
12920b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
12930b57cec5SDimitry Andric   }
12940b57cec5SDimitry Andric 
12950b57cec5SDimitry Andric   ParamIdx *Start = NonNullArgs.data();
12960b57cec5SDimitry Andric   unsigned Size = NonNullArgs.size();
12970b57cec5SDimitry Andric   llvm::array_pod_sort(Start, Start + Size);
1298a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
12990b57cec5SDimitry Andric }
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
13020b57cec5SDimitry Andric                                        const ParsedAttr &AL) {
13030b57cec5SDimitry Andric   if (AL.getNumArgs() > 0) {
13040b57cec5SDimitry Andric     if (D->getFunctionType()) {
13050b57cec5SDimitry Andric       handleNonNullAttr(S, D, AL);
13060b57cec5SDimitry Andric     } else {
13070b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
13080b57cec5SDimitry Andric         << D->getSourceRange();
13090b57cec5SDimitry Andric     }
13100b57cec5SDimitry Andric     return;
13110b57cec5SDimitry Andric   }
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric   // Is the argument a pointer type?
13140b57cec5SDimitry Andric   if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
13150b57cec5SDimitry Andric                            D->getSourceRange()))
13160b57cec5SDimitry Andric     return;
13170b57cec5SDimitry Andric 
1318a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
13190b57cec5SDimitry Andric }
13200b57cec5SDimitry Andric 
13210b57cec5SDimitry Andric static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
13220b57cec5SDimitry Andric   QualType ResultType = getFunctionOrMethodResultType(D);
13230b57cec5SDimitry Andric   SourceRange SR = getFunctionOrMethodResultSourceRange(D);
13240b57cec5SDimitry Andric   if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,
13250b57cec5SDimitry Andric                            /* isReturnValue */ true))
13260b57cec5SDimitry Andric     return;
13270b57cec5SDimitry Andric 
1328a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
13290b57cec5SDimitry Andric }
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
13320b57cec5SDimitry Andric   if (D->isInvalidDecl())
13330b57cec5SDimitry Andric     return;
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric   // noescape only applies to pointer types.
13360b57cec5SDimitry Andric   QualType T = cast<ParmVarDecl>(D)->getType();
13370b57cec5SDimitry Andric   if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
13380b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
13390b57cec5SDimitry Andric         << AL << AL.getRange() << 0;
13400b57cec5SDimitry Andric     return;
13410b57cec5SDimitry Andric   }
13420b57cec5SDimitry Andric 
1343a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
13440b57cec5SDimitry Andric }
13450b57cec5SDimitry Andric 
13460b57cec5SDimitry Andric static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
13470b57cec5SDimitry Andric   Expr *E = AL.getArgAsExpr(0),
13480b57cec5SDimitry Andric        *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr;
1349a7dea167SDimitry Andric   S.AddAssumeAlignedAttr(D, AL, E, OE);
13500b57cec5SDimitry Andric }
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1353a7dea167SDimitry Andric   S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
13540b57cec5SDimitry Andric }
13550b57cec5SDimitry Andric 
1356a7dea167SDimitry Andric void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1357a7dea167SDimitry Andric                                 Expr *OE) {
13580b57cec5SDimitry Andric   QualType ResultType = getFunctionOrMethodResultType(D);
13590b57cec5SDimitry Andric   SourceRange SR = getFunctionOrMethodResultSourceRange(D);
13600b57cec5SDimitry Andric 
1361a7dea167SDimitry Andric   AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1362a7dea167SDimitry Andric   SourceLocation AttrLoc = TmpAttr.getLocation();
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric   if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
13650b57cec5SDimitry Andric     Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1366a7dea167SDimitry Andric         << &TmpAttr << TmpAttr.getRange() << SR;
13670b57cec5SDimitry Andric     return;
13680b57cec5SDimitry Andric   }
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric   if (!E->isValueDependent()) {
1371bdd1243dSDimitry Andric     std::optional<llvm::APSInt> I = llvm::APSInt(64);
1372e8d8bef9SDimitry Andric     if (!(I = E->getIntegerConstantExpr(Context))) {
13730b57cec5SDimitry Andric       if (OE)
13740b57cec5SDimitry Andric         Diag(AttrLoc, diag::err_attribute_argument_n_type)
13750b57cec5SDimitry Andric           << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
13760b57cec5SDimitry Andric           << E->getSourceRange();
13770b57cec5SDimitry Andric       else
13780b57cec5SDimitry Andric         Diag(AttrLoc, diag::err_attribute_argument_type)
13790b57cec5SDimitry Andric           << &TmpAttr << AANT_ArgumentIntegerConstant
13800b57cec5SDimitry Andric           << E->getSourceRange();
13810b57cec5SDimitry Andric       return;
13820b57cec5SDimitry Andric     }
13830b57cec5SDimitry Andric 
1384e8d8bef9SDimitry Andric     if (!I->isPowerOf2()) {
13850b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_alignment_not_power_of_two)
13860b57cec5SDimitry Andric         << E->getSourceRange();
13870b57cec5SDimitry Andric       return;
13880b57cec5SDimitry Andric     }
13895ffd83dbSDimitry Andric 
1390e8d8bef9SDimitry Andric     if (*I > Sema::MaximumAlignment)
13915ffd83dbSDimitry Andric       Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
13925ffd83dbSDimitry Andric           << CI.getRange() << Sema::MaximumAlignment;
13930b57cec5SDimitry Andric   }
13940b57cec5SDimitry Andric 
1395e8d8bef9SDimitry Andric   if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Context)) {
13960b57cec5SDimitry Andric     Diag(AttrLoc, diag::err_attribute_argument_n_type)
13970b57cec5SDimitry Andric         << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
13980b57cec5SDimitry Andric         << OE->getSourceRange();
13990b57cec5SDimitry Andric     return;
14000b57cec5SDimitry Andric   }
14010b57cec5SDimitry Andric 
1402a7dea167SDimitry Andric   D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
14030b57cec5SDimitry Andric }
14040b57cec5SDimitry Andric 
1405a7dea167SDimitry Andric void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
1406a7dea167SDimitry Andric                              Expr *ParamExpr) {
14070b57cec5SDimitry Andric   QualType ResultType = getFunctionOrMethodResultType(D);
14080b57cec5SDimitry Andric 
1409a7dea167SDimitry Andric   AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
1410a7dea167SDimitry Andric   SourceLocation AttrLoc = CI.getLoc();
14110b57cec5SDimitry Andric 
14120b57cec5SDimitry Andric   if (!ResultType->isDependentType() &&
14130b57cec5SDimitry Andric       !isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
14140b57cec5SDimitry Andric     Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1415a7dea167SDimitry Andric         << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
14160b57cec5SDimitry Andric     return;
14170b57cec5SDimitry Andric   }
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric   ParamIdx Idx;
14200b57cec5SDimitry Andric   const auto *FuncDecl = cast<FunctionDecl>(D);
14210fca6ea1SDimitry Andric   if (!checkFunctionOrMethodParameterIndex(FuncDecl, TmpAttr,
14220b57cec5SDimitry Andric                                            /*AttrArgNum=*/1, ParamExpr, Idx))
14230b57cec5SDimitry Andric     return;
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
14265ffd83dbSDimitry Andric   if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
14275ffd83dbSDimitry Andric       !Ty->isAlignValT()) {
14280b57cec5SDimitry Andric     Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
14290b57cec5SDimitry Andric         << &TmpAttr
14300b57cec5SDimitry Andric         << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
14310b57cec5SDimitry Andric     return;
14320b57cec5SDimitry Andric   }
14330b57cec5SDimitry Andric 
1434a7dea167SDimitry Andric   D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
14350b57cec5SDimitry Andric }
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric /// Normalize the attribute, __foo__ becomes foo.
14380b57cec5SDimitry Andric /// Returns true if normalization was applied.
14390b57cec5SDimitry Andric static bool normalizeName(StringRef &AttrName) {
14405f757f3fSDimitry Andric   if (AttrName.size() > 4 && AttrName.starts_with("__") &&
14415f757f3fSDimitry Andric       AttrName.ends_with("__")) {
14420b57cec5SDimitry Andric     AttrName = AttrName.drop_front(2).drop_back(2);
14430b57cec5SDimitry Andric     return true;
14440b57cec5SDimitry Andric   }
14450b57cec5SDimitry Andric   return false;
14460b57cec5SDimitry Andric }
14470b57cec5SDimitry Andric 
14480b57cec5SDimitry Andric static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
14490b57cec5SDimitry Andric   // This attribute must be applied to a function declaration. The first
14500b57cec5SDimitry Andric   // argument to the attribute must be an identifier, the name of the resource,
14510b57cec5SDimitry Andric   // for example: malloc. The following arguments must be argument indexes, the
14520b57cec5SDimitry Andric   // arguments must be of integer type for Returns, otherwise of pointer type.
14530b57cec5SDimitry Andric   // The difference between Holds and Takes is that a pointer may still be used
14540b57cec5SDimitry Andric   // after being held. free() should be __attribute((ownership_takes)), whereas
14550b57cec5SDimitry Andric   // a list append function may well be __attribute((ownership_holds)).
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric   if (!AL.isArgIdent(0)) {
14580b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
14590b57cec5SDimitry Andric         << AL << 1 << AANT_ArgumentIdentifier;
14600b57cec5SDimitry Andric     return;
14610b57cec5SDimitry Andric   }
14620b57cec5SDimitry Andric 
14630b57cec5SDimitry Andric   // Figure out our Kind.
14640b57cec5SDimitry Andric   OwnershipAttr::OwnershipKind K =
1465a7dea167SDimitry Andric       OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric   // Check arguments.
14680b57cec5SDimitry Andric   switch (K) {
14690b57cec5SDimitry Andric   case OwnershipAttr::Takes:
14700b57cec5SDimitry Andric   case OwnershipAttr::Holds:
14710b57cec5SDimitry Andric     if (AL.getNumArgs() < 2) {
14720b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
14730b57cec5SDimitry Andric       return;
14740b57cec5SDimitry Andric     }
14750b57cec5SDimitry Andric     break;
14760b57cec5SDimitry Andric   case OwnershipAttr::Returns:
14770b57cec5SDimitry Andric     if (AL.getNumArgs() > 2) {
14780b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
14790b57cec5SDimitry Andric       return;
14800b57cec5SDimitry Andric     }
14810b57cec5SDimitry Andric     break;
14820b57cec5SDimitry Andric   }
14830b57cec5SDimitry Andric 
14840b57cec5SDimitry Andric   IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric   StringRef ModuleName = Module->getName();
14870b57cec5SDimitry Andric   if (normalizeName(ModuleName)) {
14880b57cec5SDimitry Andric     Module = &S.PP.getIdentifierTable().get(ModuleName);
14890b57cec5SDimitry Andric   }
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric   SmallVector<ParamIdx, 8> OwnershipArgs;
14920b57cec5SDimitry Andric   for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
14930b57cec5SDimitry Andric     Expr *Ex = AL.getArgAsExpr(i);
14940b57cec5SDimitry Andric     ParamIdx Idx;
14950fca6ea1SDimitry Andric     if (!S.checkFunctionOrMethodParameterIndex(D, AL, i, Ex, Idx))
14960b57cec5SDimitry Andric       return;
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric     // Is the function argument a pointer type?
14990b57cec5SDimitry Andric     QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex());
15000b57cec5SDimitry Andric     int Err = -1;  // No error
15010b57cec5SDimitry Andric     switch (K) {
15020b57cec5SDimitry Andric       case OwnershipAttr::Takes:
15030b57cec5SDimitry Andric       case OwnershipAttr::Holds:
15040b57cec5SDimitry Andric         if (!T->isAnyPointerType() && !T->isBlockPointerType())
15050b57cec5SDimitry Andric           Err = 0;
15060b57cec5SDimitry Andric         break;
15070b57cec5SDimitry Andric       case OwnershipAttr::Returns:
15080b57cec5SDimitry Andric         if (!T->isIntegerType())
15090b57cec5SDimitry Andric           Err = 1;
15100b57cec5SDimitry Andric         break;
15110b57cec5SDimitry Andric     }
15120b57cec5SDimitry Andric     if (-1 != Err) {
15130b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
15140b57cec5SDimitry Andric                                                     << Ex->getSourceRange();
15150b57cec5SDimitry Andric       return;
15160b57cec5SDimitry Andric     }
15170b57cec5SDimitry Andric 
15180b57cec5SDimitry Andric     // Check we don't have a conflict with another ownership attribute.
15190b57cec5SDimitry Andric     for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
15200b57cec5SDimitry Andric       // Cannot have two ownership attributes of different kinds for the same
15210b57cec5SDimitry Andric       // index.
1522bdd1243dSDimitry Andric       if (I->getOwnKind() != K && llvm::is_contained(I->args(), Idx)) {
152306c3fb27SDimitry Andric           S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
152406c3fb27SDimitry Andric               << AL << I
152506c3fb27SDimitry Andric               << (AL.isRegularKeywordAttribute() ||
152606c3fb27SDimitry Andric                   I->isRegularKeywordAttribute());
15270b57cec5SDimitry Andric           return;
15280b57cec5SDimitry Andric       } else if (K == OwnershipAttr::Returns &&
15290b57cec5SDimitry Andric                  I->getOwnKind() == OwnershipAttr::Returns) {
15300b57cec5SDimitry Andric         // A returns attribute conflicts with any other returns attribute using
15310b57cec5SDimitry Andric         // a different index.
1532349cc55cSDimitry Andric         if (!llvm::is_contained(I->args(), Idx)) {
15330b57cec5SDimitry Andric           S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
15340b57cec5SDimitry Andric               << I->args_begin()->getSourceIndex();
15350b57cec5SDimitry Andric           if (I->args_size())
15360b57cec5SDimitry Andric             S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
15370b57cec5SDimitry Andric                 << Idx.getSourceIndex() << Ex->getSourceRange();
15380b57cec5SDimitry Andric           return;
15390b57cec5SDimitry Andric         }
15400b57cec5SDimitry Andric       }
15410b57cec5SDimitry Andric     }
15420b57cec5SDimitry Andric     OwnershipArgs.push_back(Idx);
15430b57cec5SDimitry Andric   }
15440b57cec5SDimitry Andric 
15450b57cec5SDimitry Andric   ParamIdx *Start = OwnershipArgs.data();
15460b57cec5SDimitry Andric   unsigned Size = OwnershipArgs.size();
15470b57cec5SDimitry Andric   llvm::array_pod_sort(Start, Start + Size);
15480b57cec5SDimitry Andric   D->addAttr(::new (S.Context)
1549a7dea167SDimitry Andric                  OwnershipAttr(S.Context, AL, Module, Start, Size));
15500b57cec5SDimitry Andric }
15510b57cec5SDimitry Andric 
15520b57cec5SDimitry Andric static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
15530b57cec5SDimitry Andric   // Check the attribute arguments.
15540b57cec5SDimitry Andric   if (AL.getNumArgs() > 1) {
15550b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
15560b57cec5SDimitry Andric     return;
15570b57cec5SDimitry Andric   }
15580b57cec5SDimitry Andric 
15590b57cec5SDimitry Andric   // gcc rejects
15600b57cec5SDimitry Andric   // class c {
15610b57cec5SDimitry Andric   //   static int a __attribute__((weakref ("v2")));
15620b57cec5SDimitry Andric   //   static int b() __attribute__((weakref ("f3")));
15630b57cec5SDimitry Andric   // };
15640b57cec5SDimitry Andric   // and ignores the attributes of
15650b57cec5SDimitry Andric   // void f(void) {
15660b57cec5SDimitry Andric   //   static int a __attribute__((weakref ("v2")));
15670b57cec5SDimitry Andric   // }
15680b57cec5SDimitry Andric   // we reject them
15690b57cec5SDimitry Andric   const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
15700b57cec5SDimitry Andric   if (!Ctx->isFileContext()) {
15710b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
15720b57cec5SDimitry Andric         << cast<NamedDecl>(D);
15730b57cec5SDimitry Andric     return;
15740b57cec5SDimitry Andric   }
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric   // The GCC manual says
15770b57cec5SDimitry Andric   //
15780b57cec5SDimitry Andric   // At present, a declaration to which `weakref' is attached can only
15790b57cec5SDimitry Andric   // be `static'.
15800b57cec5SDimitry Andric   //
15810b57cec5SDimitry Andric   // It also says
15820b57cec5SDimitry Andric   //
15830b57cec5SDimitry Andric   // Without a TARGET,
15840b57cec5SDimitry Andric   // given as an argument to `weakref' or to `alias', `weakref' is
15850b57cec5SDimitry Andric   // equivalent to `weak'.
15860b57cec5SDimitry Andric   //
15870b57cec5SDimitry Andric   // gcc 4.4.1 will accept
15880b57cec5SDimitry Andric   // int a7 __attribute__((weakref));
15890b57cec5SDimitry Andric   // as
15900b57cec5SDimitry Andric   // int a7 __attribute__((weak));
15910b57cec5SDimitry Andric   // This looks like a bug in gcc. We reject that for now. We should revisit
15920b57cec5SDimitry Andric   // it if this behaviour is actually used.
15930b57cec5SDimitry Andric 
15940b57cec5SDimitry Andric   // GCC rejects
15950b57cec5SDimitry Andric   // static ((alias ("y"), weakref)).
15960b57cec5SDimitry Andric   // Should we? How to check that weakref is before or after alias?
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric   // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
15990b57cec5SDimitry Andric   // of transforming it into an AliasAttr.  The WeakRefAttr never uses the
16000b57cec5SDimitry Andric   // StringRef parameter it was given anyway.
16010b57cec5SDimitry Andric   StringRef Str;
16020b57cec5SDimitry Andric   if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))
16030b57cec5SDimitry Andric     // GCC will accept anything as the argument of weakref. Should we
16040b57cec5SDimitry Andric     // check for an existing decl?
1605a7dea167SDimitry Andric     D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
16060b57cec5SDimitry Andric 
1607a7dea167SDimitry Andric   D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
16080b57cec5SDimitry Andric }
16090b57cec5SDimitry Andric 
16100fca6ea1SDimitry Andric // Mark alias/ifunc target as used. Due to name mangling, we look up the
16110fca6ea1SDimitry Andric // demangled name ignoring parameters (not supported by microsoftDemangle
16120fca6ea1SDimitry Andric // https://github.com/llvm/llvm-project/issues/88825). This should handle the
16130fca6ea1SDimitry Andric // majority of use cases while leaving namespace scope names unmarked.
16140fca6ea1SDimitry Andric static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
16150fca6ea1SDimitry Andric                                     StringRef Str) {
16160fca6ea1SDimitry Andric   std::unique_ptr<char, llvm::FreeDeleter> Demangled;
16170fca6ea1SDimitry Andric   if (S.getASTContext().getCXXABIKind() != TargetCXXABI::Microsoft)
16180fca6ea1SDimitry Andric     Demangled.reset(llvm::itaniumDemangle(Str, /*ParseParams=*/false));
16190fca6ea1SDimitry Andric   std::unique_ptr<MangleContext> MC(S.Context.createMangleContext());
16200fca6ea1SDimitry Andric   SmallString<256> Name;
16210fca6ea1SDimitry Andric 
16220fca6ea1SDimitry Andric   const DeclarationNameInfo Target(
16230fca6ea1SDimitry Andric       &S.Context.Idents.get(Demangled ? Demangled.get() : Str), AL.getLoc());
16240fca6ea1SDimitry Andric   LookupResult LR(S, Target, Sema::LookupOrdinaryName);
16250fca6ea1SDimitry Andric   if (S.LookupName(LR, S.TUScope)) {
16260fca6ea1SDimitry Andric     for (NamedDecl *ND : LR) {
16270fca6ea1SDimitry Andric       if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND))
16280fca6ea1SDimitry Andric         continue;
16290fca6ea1SDimitry Andric       if (MC->shouldMangleDeclName(ND)) {
16300fca6ea1SDimitry Andric         llvm::raw_svector_ostream Out(Name);
16310fca6ea1SDimitry Andric         Name.clear();
16320fca6ea1SDimitry Andric         MC->mangleName(GlobalDecl(ND), Out);
16330fca6ea1SDimitry Andric       } else {
16340fca6ea1SDimitry Andric         Name = ND->getIdentifier()->getName();
16350fca6ea1SDimitry Andric       }
16360fca6ea1SDimitry Andric       if (Name == Str)
16370fca6ea1SDimitry Andric         ND->markUsed(S.Context);
16380fca6ea1SDimitry Andric     }
16390fca6ea1SDimitry Andric   }
16400fca6ea1SDimitry Andric }
16410fca6ea1SDimitry Andric 
16420b57cec5SDimitry Andric static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
16430b57cec5SDimitry Andric   StringRef Str;
16440b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
16450b57cec5SDimitry Andric     return;
16460b57cec5SDimitry Andric 
16470b57cec5SDimitry Andric   // Aliases should be on declarations, not definitions.
16480b57cec5SDimitry Andric   const auto *FD = cast<FunctionDecl>(D);
16490b57cec5SDimitry Andric   if (FD->isThisDeclarationADefinition()) {
16500b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
16510b57cec5SDimitry Andric     return;
16520b57cec5SDimitry Andric   }
16530b57cec5SDimitry Andric 
16540fca6ea1SDimitry Andric   markUsedForAliasOrIfunc(S, D, AL, Str);
1655a7dea167SDimitry Andric   D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
16560b57cec5SDimitry Andric }
16570b57cec5SDimitry Andric 
16580b57cec5SDimitry Andric static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
16590b57cec5SDimitry Andric   StringRef Str;
16600b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
16610b57cec5SDimitry Andric     return;
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric   if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
16640b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
16650b57cec5SDimitry Andric     return;
16660b57cec5SDimitry Andric   }
16675f757f3fSDimitry Andric 
16680b57cec5SDimitry Andric   if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
16695f757f3fSDimitry Andric     CudaVersion Version =
16705f757f3fSDimitry Andric         ToCudaVersion(S.Context.getTargetInfo().getSDKVersion());
16715f757f3fSDimitry Andric     if (Version != CudaVersion::UNKNOWN && Version < CudaVersion::CUDA_100)
16720b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
16730b57cec5SDimitry Andric   }
16740b57cec5SDimitry Andric 
16750b57cec5SDimitry Andric   // Aliases should be on declarations, not definitions.
16760b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
16770b57cec5SDimitry Andric     if (FD->isThisDeclarationADefinition()) {
16780b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
16790b57cec5SDimitry Andric       return;
16800b57cec5SDimitry Andric     }
16810b57cec5SDimitry Andric   } else {
16820b57cec5SDimitry Andric     const auto *VD = cast<VarDecl>(D);
16830b57cec5SDimitry Andric     if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
16840b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
16850b57cec5SDimitry Andric       return;
16860b57cec5SDimitry Andric     }
16870b57cec5SDimitry Andric   }
16880b57cec5SDimitry Andric 
16890fca6ea1SDimitry Andric   markUsedForAliasOrIfunc(S, D, AL, Str);
1690a7dea167SDimitry Andric   D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
16910b57cec5SDimitry Andric }
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
16940b57cec5SDimitry Andric   StringRef Model;
16950b57cec5SDimitry Andric   SourceLocation LiteralLoc;
16960b57cec5SDimitry Andric   // Check that it is a string.
16970b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))
16980b57cec5SDimitry Andric     return;
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric   // Check that the value.
17010b57cec5SDimitry Andric   if (Model != "global-dynamic" && Model != "local-dynamic"
17020b57cec5SDimitry Andric       && Model != "initial-exec" && Model != "local-exec") {
17030b57cec5SDimitry Andric     S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
17040b57cec5SDimitry Andric     return;
17050b57cec5SDimitry Andric   }
17060b57cec5SDimitry Andric 
1707a7dea167SDimitry Andric   D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric 
17100b57cec5SDimitry Andric static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
17110b57cec5SDimitry Andric   QualType ResultType = getFunctionOrMethodResultType(D);
17120b57cec5SDimitry Andric   if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
1713a7dea167SDimitry Andric     D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
17140b57cec5SDimitry Andric     return;
17150b57cec5SDimitry Andric   }
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric   S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
17180b57cec5SDimitry Andric       << AL << getFunctionOrMethodResultSourceRange(D);
17190b57cec5SDimitry Andric }
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
17224824e7fdSDimitry Andric   // Ensure we don't combine these with themselves, since that causes some
17234824e7fdSDimitry Andric   // confusing behavior.
17244824e7fdSDimitry Andric   if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {
17254824e7fdSDimitry Andric     if (checkAttrMutualExclusion<CPUSpecificAttr>(S, D, AL))
17264824e7fdSDimitry Andric       return;
17274824e7fdSDimitry Andric 
17284824e7fdSDimitry Andric     if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {
17294824e7fdSDimitry Andric       S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
17304824e7fdSDimitry Andric       S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
17314824e7fdSDimitry Andric       return;
17324824e7fdSDimitry Andric     }
17334824e7fdSDimitry Andric   } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {
17344824e7fdSDimitry Andric     if (checkAttrMutualExclusion<CPUDispatchAttr>(S, D, AL))
17354824e7fdSDimitry Andric       return;
17364824e7fdSDimitry Andric 
17374824e7fdSDimitry Andric     if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {
17384824e7fdSDimitry Andric       S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
17394824e7fdSDimitry Andric       S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
17404824e7fdSDimitry Andric       return;
17414824e7fdSDimitry Andric     }
17424824e7fdSDimitry Andric   }
17434824e7fdSDimitry Andric 
17440b57cec5SDimitry Andric   FunctionDecl *FD = cast<FunctionDecl>(D);
17450b57cec5SDimitry Andric 
17460b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
17470b57cec5SDimitry Andric     if (MD->getParent()->isLambda()) {
17480b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
17490b57cec5SDimitry Andric       return;
17500b57cec5SDimitry Andric     }
17510b57cec5SDimitry Andric   }
17520b57cec5SDimitry Andric 
1753fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
17540b57cec5SDimitry Andric     return;
17550b57cec5SDimitry Andric 
17560b57cec5SDimitry Andric   SmallVector<IdentifierInfo *, 8> CPUs;
17570b57cec5SDimitry Andric   for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {
17580b57cec5SDimitry Andric     if (!AL.isArgIdent(ArgNo)) {
17590b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
17600b57cec5SDimitry Andric           << AL << AANT_ArgumentIdentifier;
17610b57cec5SDimitry Andric       return;
17620b57cec5SDimitry Andric     }
17630b57cec5SDimitry Andric 
17640b57cec5SDimitry Andric     IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);
17650b57cec5SDimitry Andric     StringRef CPUName = CPUArg->Ident->getName().trim();
17660b57cec5SDimitry Andric 
17670b57cec5SDimitry Andric     if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName)) {
17680b57cec5SDimitry Andric       S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)
17690b57cec5SDimitry Andric           << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
17700b57cec5SDimitry Andric       return;
17710b57cec5SDimitry Andric     }
17720b57cec5SDimitry Andric 
17730b57cec5SDimitry Andric     const TargetInfo &Target = S.Context.getTargetInfo();
17740b57cec5SDimitry Andric     if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {
17750b57cec5SDimitry Andric           return Target.CPUSpecificManglingCharacter(CPUName) ==
17760b57cec5SDimitry Andric                  Target.CPUSpecificManglingCharacter(Cur->getName());
17770b57cec5SDimitry Andric         })) {
17780b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
17790b57cec5SDimitry Andric       return;
17800b57cec5SDimitry Andric     }
17810b57cec5SDimitry Andric     CPUs.push_back(CPUArg->Ident);
17820b57cec5SDimitry Andric   }
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric   FD->setIsMultiVersion(true);
17850b57cec5SDimitry Andric   if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
1786a7dea167SDimitry Andric     D->addAttr(::new (S.Context)
1787a7dea167SDimitry Andric                    CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
17880b57cec5SDimitry Andric   else
1789a7dea167SDimitry Andric     D->addAttr(::new (S.Context)
1790a7dea167SDimitry Andric                    CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
17910b57cec5SDimitry Andric }
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
17940b57cec5SDimitry Andric   if (S.LangOpts.CPlusPlus) {
17950b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
17960b57cec5SDimitry Andric         << AL << AttributeLangSupport::Cpp;
17970b57cec5SDimitry Andric     return;
17980b57cec5SDimitry Andric   }
17990b57cec5SDimitry Andric 
1800fe6060f1SDimitry Andric   D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));
18010b57cec5SDimitry Andric }
18020b57cec5SDimitry Andric 
18030b57cec5SDimitry Andric static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
18040b57cec5SDimitry Andric   if (AL.isDeclspecAttribute()) {
18050b57cec5SDimitry Andric     const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
18060b57cec5SDimitry Andric     const auto &Arch = Triple.getArch();
18070b57cec5SDimitry Andric     if (Arch != llvm::Triple::x86 &&
18080b57cec5SDimitry Andric         (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {
18090b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
18100b57cec5SDimitry Andric           << AL << Triple.getArchName();
18110b57cec5SDimitry Andric       return;
18120b57cec5SDimitry Andric     }
181381ad6265SDimitry Andric 
181481ad6265SDimitry Andric     // This form is not allowed to be written on a member function (static or
181581ad6265SDimitry Andric     // nonstatic) when in Microsoft compatibility mode.
181681ad6265SDimitry Andric     if (S.getLangOpts().MSVCCompat && isa<CXXMethodDecl>(D)) {
181781ad6265SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
181806c3fb27SDimitry Andric           << AL << AL.isRegularKeywordAttribute() << "non-member functions";
181981ad6265SDimitry Andric       return;
182081ad6265SDimitry Andric     }
18210b57cec5SDimitry Andric   }
18220b57cec5SDimitry Andric 
1823a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
18240b57cec5SDimitry Andric }
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
18270b57cec5SDimitry Andric   if (hasDeclarator(D)) return;
18280b57cec5SDimitry Andric 
18290b57cec5SDimitry Andric   if (!isa<ObjCMethodDecl>(D)) {
18300b57cec5SDimitry Andric     S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
183106c3fb27SDimitry Andric         << Attrs << Attrs.isRegularKeywordAttribute()
183206c3fb27SDimitry Andric         << ExpectedFunctionOrMethod;
18330b57cec5SDimitry Andric     return;
18340b57cec5SDimitry Andric   }
18350b57cec5SDimitry Andric 
1836a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
18370b57cec5SDimitry Andric }
18380b57cec5SDimitry Andric 
183981ad6265SDimitry Andric static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
18405f757f3fSDimitry Andric   // The [[_Noreturn]] spelling is deprecated in C23, so if that was used,
184181ad6265SDimitry Andric   // issue an appropriate diagnostic. However, don't issue a diagnostic if the
184281ad6265SDimitry Andric   // attribute name comes from a macro expansion. We don't want to punish users
184381ad6265SDimitry Andric   // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
184481ad6265SDimitry Andric   // is defined as a macro which expands to '_Noreturn').
184581ad6265SDimitry Andric   if (!S.getLangOpts().CPlusPlus &&
18465f757f3fSDimitry Andric       A.getSemanticSpelling() == CXX11NoReturnAttr::C23_Noreturn &&
184781ad6265SDimitry Andric       !(A.getLoc().isMacroID() &&
184881ad6265SDimitry Andric         S.getSourceManager().isInSystemMacro(A.getLoc())))
184981ad6265SDimitry Andric     S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
185081ad6265SDimitry Andric 
185181ad6265SDimitry Andric   D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));
185281ad6265SDimitry Andric }
185381ad6265SDimitry Andric 
18540b57cec5SDimitry Andric static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
18550b57cec5SDimitry Andric   if (!S.getLangOpts().CFProtectionBranch)
18560b57cec5SDimitry Andric     S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
18570b57cec5SDimitry Andric   else
18580b57cec5SDimitry Andric     handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);
18590b57cec5SDimitry Andric }
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
1862fe6060f1SDimitry Andric   if (!Attrs.checkExactlyNumArgs(*this, 0)) {
18630b57cec5SDimitry Andric     Attrs.setInvalid();
18640b57cec5SDimitry Andric     return true;
18650b57cec5SDimitry Andric   }
18660b57cec5SDimitry Andric 
18670b57cec5SDimitry Andric   return false;
18680b57cec5SDimitry Andric }
18690b57cec5SDimitry Andric 
18700b57cec5SDimitry Andric bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
18710b57cec5SDimitry Andric   // Check whether the attribute is valid on the current target.
18720b57cec5SDimitry Andric   if (!AL.existsInTarget(Context.getTargetInfo())) {
187306c3fb27SDimitry Andric     Diag(AL.getLoc(), AL.isRegularKeywordAttribute()
187406c3fb27SDimitry Andric                           ? diag::err_keyword_not_supported_on_target
187506c3fb27SDimitry Andric                           : diag::warn_unknown_attribute_ignored)
1876e8d8bef9SDimitry Andric         << AL << AL.getRange();
18770b57cec5SDimitry Andric     AL.setInvalid();
18780b57cec5SDimitry Andric     return true;
18790b57cec5SDimitry Andric   }
18800b57cec5SDimitry Andric 
18810b57cec5SDimitry Andric   return false;
18820b57cec5SDimitry Andric }
18830b57cec5SDimitry Andric 
18840b57cec5SDimitry Andric static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
18850b57cec5SDimitry Andric 
18860b57cec5SDimitry Andric   // The checking path for 'noreturn' and 'analyzer_noreturn' are different
18870b57cec5SDimitry Andric   // because 'analyzer_noreturn' does not impact the type.
18880fca6ea1SDimitry Andric   if (!isFunctionOrMethodOrBlockForAttrSubject(D)) {
18890b57cec5SDimitry Andric     ValueDecl *VD = dyn_cast<ValueDecl>(D);
18900b57cec5SDimitry Andric     if (!VD || (!VD->getType()->isBlockPointerType() &&
18910b57cec5SDimitry Andric                 !VD->getType()->isFunctionPointerType())) {
1892fe6060f1SDimitry Andric       S.Diag(AL.getLoc(), AL.isStandardAttributeSyntax()
18930b57cec5SDimitry Andric                               ? diag::err_attribute_wrong_decl_type
18940b57cec5SDimitry Andric                               : diag::warn_attribute_wrong_decl_type)
189506c3fb27SDimitry Andric           << AL << AL.isRegularKeywordAttribute()
189606c3fb27SDimitry Andric           << ExpectedFunctionMethodOrBlock;
18970b57cec5SDimitry Andric       return;
18980b57cec5SDimitry Andric     }
18990b57cec5SDimitry Andric   }
19000b57cec5SDimitry Andric 
1901a7dea167SDimitry Andric   D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
19020b57cec5SDimitry Andric }
19030b57cec5SDimitry Andric 
19040b57cec5SDimitry Andric // PS3 PPU-specific.
19050b57cec5SDimitry Andric static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
19060b57cec5SDimitry Andric   /*
19070b57cec5SDimitry Andric     Returning a Vector Class in Registers
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric     According to the PPU ABI specifications, a class with a single member of
19100b57cec5SDimitry Andric     vector type is returned in memory when used as the return value of a
19110b57cec5SDimitry Andric     function.
19120b57cec5SDimitry Andric     This results in inefficient code when implementing vector classes. To return
19130b57cec5SDimitry Andric     the value in a single vector register, add the vecreturn attribute to the
19140b57cec5SDimitry Andric     class definition. This attribute is also applicable to struct types.
19150b57cec5SDimitry Andric 
19160b57cec5SDimitry Andric     Example:
19170b57cec5SDimitry Andric 
19180b57cec5SDimitry Andric     struct Vector
19190b57cec5SDimitry Andric     {
19200b57cec5SDimitry Andric       __vector float xyzw;
19210b57cec5SDimitry Andric     } __attribute__((vecreturn));
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric     Vector Add(Vector lhs, Vector rhs)
19240b57cec5SDimitry Andric     {
19250b57cec5SDimitry Andric       Vector result;
19260b57cec5SDimitry Andric       result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
19270b57cec5SDimitry Andric       return result; // This will be returned in a register
19280b57cec5SDimitry Andric     }
19290b57cec5SDimitry Andric   */
19300b57cec5SDimitry Andric   if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
19310b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
19320b57cec5SDimitry Andric     return;
19330b57cec5SDimitry Andric   }
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric   const auto *R = cast<RecordDecl>(D);
19360b57cec5SDimitry Andric   int count = 0;
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric   if (!isa<CXXRecordDecl>(R)) {
19390b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
19400b57cec5SDimitry Andric     return;
19410b57cec5SDimitry Andric   }
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric   if (!cast<CXXRecordDecl>(R)->isPOD()) {
19440b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
19450b57cec5SDimitry Andric     return;
19460b57cec5SDimitry Andric   }
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric   for (const auto *I : R->fields()) {
19490b57cec5SDimitry Andric     if ((count == 1) || !I->getType()->isVectorType()) {
19500b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
19510b57cec5SDimitry Andric       return;
19520b57cec5SDimitry Andric     }
19530b57cec5SDimitry Andric     count++;
19540b57cec5SDimitry Andric   }
19550b57cec5SDimitry Andric 
1956a7dea167SDimitry Andric   D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
19570b57cec5SDimitry Andric }
19580b57cec5SDimitry Andric 
19590b57cec5SDimitry Andric static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
19600b57cec5SDimitry Andric                                  const ParsedAttr &AL) {
19610b57cec5SDimitry Andric   if (isa<ParmVarDecl>(D)) {
19620b57cec5SDimitry Andric     // [[carries_dependency]] can only be applied to a parameter if it is a
19630b57cec5SDimitry Andric     // parameter of a function declaration or lambda.
19640b57cec5SDimitry Andric     if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
19650b57cec5SDimitry Andric       S.Diag(AL.getLoc(),
19660b57cec5SDimitry Andric              diag::err_carries_dependency_param_not_function_decl);
19670b57cec5SDimitry Andric       return;
19680b57cec5SDimitry Andric     }
19690b57cec5SDimitry Andric   }
19700b57cec5SDimitry Andric 
1971a7dea167SDimitry Andric   D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
19720b57cec5SDimitry Andric }
19730b57cec5SDimitry Andric 
19740b57cec5SDimitry Andric static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
19750b57cec5SDimitry Andric   bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
19760b57cec5SDimitry Andric 
19770b57cec5SDimitry Andric   // If this is spelled as the standard C++17 attribute, but not in C++17, warn
19780b57cec5SDimitry Andric   // about using it as an extension.
19790b57cec5SDimitry Andric   if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
19800b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
19810b57cec5SDimitry Andric 
1982a7dea167SDimitry Andric   D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
19830b57cec5SDimitry Andric }
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
19860b57cec5SDimitry Andric   uint32_t priority = ConstructorAttr::DefaultPriority;
1987bdd1243dSDimitry Andric   if (S.getLangOpts().HLSL && AL.getNumArgs()) {
1988bdd1243dSDimitry Andric     S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
1989bdd1243dSDimitry Andric     return;
1990bdd1243dSDimitry Andric   }
19910b57cec5SDimitry Andric   if (AL.getNumArgs() &&
19920fca6ea1SDimitry Andric       !S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority))
19930b57cec5SDimitry Andric     return;
19940b57cec5SDimitry Andric 
1995a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
19960b57cec5SDimitry Andric }
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
19990b57cec5SDimitry Andric   uint32_t priority = DestructorAttr::DefaultPriority;
20000b57cec5SDimitry Andric   if (AL.getNumArgs() &&
20010fca6ea1SDimitry Andric       !S.checkUInt32Argument(AL, AL.getArgAsExpr(0), priority))
20020b57cec5SDimitry Andric     return;
20030b57cec5SDimitry Andric 
2004a7dea167SDimitry Andric   D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
20050b57cec5SDimitry Andric }
20060b57cec5SDimitry Andric 
20070b57cec5SDimitry Andric template <typename AttrTy>
20080b57cec5SDimitry Andric static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
20090b57cec5SDimitry Andric   // Handle the case where the attribute has a text message.
20100b57cec5SDimitry Andric   StringRef Str;
20110b57cec5SDimitry Andric   if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))
20120b57cec5SDimitry Andric     return;
20130b57cec5SDimitry Andric 
2014a7dea167SDimitry Andric   D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
20150b57cec5SDimitry Andric }
20160b57cec5SDimitry Andric 
20170b57cec5SDimitry Andric static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
20180b57cec5SDimitry Andric                                   IdentifierInfo *Platform,
20190b57cec5SDimitry Andric                                   VersionTuple Introduced,
20200b57cec5SDimitry Andric                                   VersionTuple Deprecated,
20210b57cec5SDimitry Andric                                   VersionTuple Obsoleted) {
20220b57cec5SDimitry Andric   StringRef PlatformName
20230b57cec5SDimitry Andric     = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
20240b57cec5SDimitry Andric   if (PlatformName.empty())
20250b57cec5SDimitry Andric     PlatformName = Platform->getName();
20260b57cec5SDimitry Andric 
20270b57cec5SDimitry Andric   // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
20280b57cec5SDimitry Andric   // of these steps are needed).
20290b57cec5SDimitry Andric   if (!Introduced.empty() && !Deprecated.empty() &&
20300b57cec5SDimitry Andric       !(Introduced <= Deprecated)) {
20310b57cec5SDimitry Andric     S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
20320b57cec5SDimitry Andric       << 1 << PlatformName << Deprecated.getAsString()
20330b57cec5SDimitry Andric       << 0 << Introduced.getAsString();
20340b57cec5SDimitry Andric     return true;
20350b57cec5SDimitry Andric   }
20360b57cec5SDimitry Andric 
20370b57cec5SDimitry Andric   if (!Introduced.empty() && !Obsoleted.empty() &&
20380b57cec5SDimitry Andric       !(Introduced <= Obsoleted)) {
20390b57cec5SDimitry Andric     S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
20400b57cec5SDimitry Andric       << 2 << PlatformName << Obsoleted.getAsString()
20410b57cec5SDimitry Andric       << 0 << Introduced.getAsString();
20420b57cec5SDimitry Andric     return true;
20430b57cec5SDimitry Andric   }
20440b57cec5SDimitry Andric 
20450b57cec5SDimitry Andric   if (!Deprecated.empty() && !Obsoleted.empty() &&
20460b57cec5SDimitry Andric       !(Deprecated <= Obsoleted)) {
20470b57cec5SDimitry Andric     S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
20480b57cec5SDimitry Andric       << 2 << PlatformName << Obsoleted.getAsString()
20490b57cec5SDimitry Andric       << 1 << Deprecated.getAsString();
20500b57cec5SDimitry Andric     return true;
20510b57cec5SDimitry Andric   }
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric   return false;
20540b57cec5SDimitry Andric }
20550b57cec5SDimitry Andric 
20560b57cec5SDimitry Andric /// Check whether the two versions match.
20570b57cec5SDimitry Andric ///
20580b57cec5SDimitry Andric /// If either version tuple is empty, then they are assumed to match. If
20590b57cec5SDimitry Andric /// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
20600b57cec5SDimitry Andric static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
20610b57cec5SDimitry Andric                           bool BeforeIsOkay) {
20620b57cec5SDimitry Andric   if (X.empty() || Y.empty())
20630b57cec5SDimitry Andric     return true;
20640b57cec5SDimitry Andric 
20650b57cec5SDimitry Andric   if (X == Y)
20660b57cec5SDimitry Andric     return true;
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric   if (BeforeIsOkay && X < Y)
20690b57cec5SDimitry Andric     return true;
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric   return false;
20720b57cec5SDimitry Andric }
20730b57cec5SDimitry Andric 
20740b57cec5SDimitry Andric AvailabilityAttr *Sema::mergeAvailabilityAttr(
2075a7dea167SDimitry Andric     NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
2076a7dea167SDimitry Andric     bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2077a7dea167SDimitry Andric     VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2078a7dea167SDimitry Andric     bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
20790fca6ea1SDimitry Andric     int Priority, IdentifierInfo *Environment) {
20800b57cec5SDimitry Andric   VersionTuple MergedIntroduced = Introduced;
20810b57cec5SDimitry Andric   VersionTuple MergedDeprecated = Deprecated;
20820b57cec5SDimitry Andric   VersionTuple MergedObsoleted = Obsoleted;
20830b57cec5SDimitry Andric   bool FoundAny = false;
20840b57cec5SDimitry Andric   bool OverrideOrImpl = false;
20850b57cec5SDimitry Andric   switch (AMK) {
20860b57cec5SDimitry Andric   case AMK_None:
20870b57cec5SDimitry Andric   case AMK_Redeclaration:
20880b57cec5SDimitry Andric     OverrideOrImpl = false;
20890b57cec5SDimitry Andric     break;
20900b57cec5SDimitry Andric 
20910b57cec5SDimitry Andric   case AMK_Override:
20920b57cec5SDimitry Andric   case AMK_ProtocolImplementation:
2093fe6060f1SDimitry Andric   case AMK_OptionalProtocolImplementation:
20940b57cec5SDimitry Andric     OverrideOrImpl = true;
20950b57cec5SDimitry Andric     break;
20960b57cec5SDimitry Andric   }
20970b57cec5SDimitry Andric 
20980b57cec5SDimitry Andric   if (D->hasAttrs()) {
20990b57cec5SDimitry Andric     AttrVec &Attrs = D->getAttrs();
21000b57cec5SDimitry Andric     for (unsigned i = 0, e = Attrs.size(); i != e;) {
21010b57cec5SDimitry Andric       const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
21020b57cec5SDimitry Andric       if (!OldAA) {
21030b57cec5SDimitry Andric         ++i;
21040b57cec5SDimitry Andric         continue;
21050b57cec5SDimitry Andric       }
21060b57cec5SDimitry Andric 
21070b57cec5SDimitry Andric       IdentifierInfo *OldPlatform = OldAA->getPlatform();
21080b57cec5SDimitry Andric       if (OldPlatform != Platform) {
21090b57cec5SDimitry Andric         ++i;
21100b57cec5SDimitry Andric         continue;
21110b57cec5SDimitry Andric       }
21120b57cec5SDimitry Andric 
21130fca6ea1SDimitry Andric       IdentifierInfo *OldEnvironment = OldAA->getEnvironment();
21140fca6ea1SDimitry Andric       if (OldEnvironment != Environment) {
21150fca6ea1SDimitry Andric         ++i;
21160fca6ea1SDimitry Andric         continue;
21170fca6ea1SDimitry Andric       }
21180fca6ea1SDimitry Andric 
21190b57cec5SDimitry Andric       // If there is an existing availability attribute for this platform that
21200b57cec5SDimitry Andric       // has a lower priority use the existing one and discard the new
21210b57cec5SDimitry Andric       // attribute.
21220b57cec5SDimitry Andric       if (OldAA->getPriority() < Priority)
21230b57cec5SDimitry Andric         return nullptr;
21240b57cec5SDimitry Andric 
21250b57cec5SDimitry Andric       // If there is an existing attribute for this platform that has a higher
21260b57cec5SDimitry Andric       // priority than the new attribute then erase the old one and continue
21270b57cec5SDimitry Andric       // processing the attributes.
21280b57cec5SDimitry Andric       if (OldAA->getPriority() > Priority) {
21290b57cec5SDimitry Andric         Attrs.erase(Attrs.begin() + i);
21300b57cec5SDimitry Andric         --e;
21310b57cec5SDimitry Andric         continue;
21320b57cec5SDimitry Andric       }
21330b57cec5SDimitry Andric 
21340b57cec5SDimitry Andric       FoundAny = true;
21350b57cec5SDimitry Andric       VersionTuple OldIntroduced = OldAA->getIntroduced();
21360b57cec5SDimitry Andric       VersionTuple OldDeprecated = OldAA->getDeprecated();
21370b57cec5SDimitry Andric       VersionTuple OldObsoleted = OldAA->getObsoleted();
21380b57cec5SDimitry Andric       bool OldIsUnavailable = OldAA->getUnavailable();
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric       if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
21410b57cec5SDimitry Andric           !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||
21420b57cec5SDimitry Andric           !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||
21430b57cec5SDimitry Andric           !(OldIsUnavailable == IsUnavailable ||
21440b57cec5SDimitry Andric             (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
21450b57cec5SDimitry Andric         if (OverrideOrImpl) {
21460b57cec5SDimitry Andric           int Which = -1;
21470b57cec5SDimitry Andric           VersionTuple FirstVersion;
21480b57cec5SDimitry Andric           VersionTuple SecondVersion;
21490b57cec5SDimitry Andric           if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
21500b57cec5SDimitry Andric             Which = 0;
21510b57cec5SDimitry Andric             FirstVersion = OldIntroduced;
21520b57cec5SDimitry Andric             SecondVersion = Introduced;
21530b57cec5SDimitry Andric           } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {
21540b57cec5SDimitry Andric             Which = 1;
21550b57cec5SDimitry Andric             FirstVersion = Deprecated;
21560b57cec5SDimitry Andric             SecondVersion = OldDeprecated;
21570b57cec5SDimitry Andric           } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
21580b57cec5SDimitry Andric             Which = 2;
21590b57cec5SDimitry Andric             FirstVersion = Obsoleted;
21600b57cec5SDimitry Andric             SecondVersion = OldObsoleted;
21610b57cec5SDimitry Andric           }
21620b57cec5SDimitry Andric 
21630b57cec5SDimitry Andric           if (Which == -1) {
21640b57cec5SDimitry Andric             Diag(OldAA->getLocation(),
21650b57cec5SDimitry Andric                  diag::warn_mismatched_availability_override_unavail)
21660b57cec5SDimitry Andric               << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
21670b57cec5SDimitry Andric               << (AMK == AMK_Override);
2168fe6060f1SDimitry Andric           } else if (Which != 1 && AMK == AMK_OptionalProtocolImplementation) {
2169fe6060f1SDimitry Andric             // Allow different 'introduced' / 'obsoleted' availability versions
2170fe6060f1SDimitry Andric             // on a method that implements an optional protocol requirement. It
2171fe6060f1SDimitry Andric             // makes less sense to allow this for 'deprecated' as the user can't
2172fe6060f1SDimitry Andric             // see if the method is 'deprecated' as 'respondsToSelector' will
2173fe6060f1SDimitry Andric             // still return true when the method is deprecated.
2174fe6060f1SDimitry Andric             ++i;
2175fe6060f1SDimitry Andric             continue;
21760b57cec5SDimitry Andric           } else {
21770b57cec5SDimitry Andric             Diag(OldAA->getLocation(),
21780b57cec5SDimitry Andric                  diag::warn_mismatched_availability_override)
21790b57cec5SDimitry Andric               << Which
21800b57cec5SDimitry Andric               << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
21810b57cec5SDimitry Andric               << FirstVersion.getAsString() << SecondVersion.getAsString()
21820b57cec5SDimitry Andric               << (AMK == AMK_Override);
21830b57cec5SDimitry Andric           }
21840b57cec5SDimitry Andric           if (AMK == AMK_Override)
2185a7dea167SDimitry Andric             Diag(CI.getLoc(), diag::note_overridden_method);
21860b57cec5SDimitry Andric           else
2187a7dea167SDimitry Andric             Diag(CI.getLoc(), diag::note_protocol_method);
21880b57cec5SDimitry Andric         } else {
21890b57cec5SDimitry Andric           Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2190a7dea167SDimitry Andric           Diag(CI.getLoc(), diag::note_previous_attribute);
21910b57cec5SDimitry Andric         }
21920b57cec5SDimitry Andric 
21930b57cec5SDimitry Andric         Attrs.erase(Attrs.begin() + i);
21940b57cec5SDimitry Andric         --e;
21950b57cec5SDimitry Andric         continue;
21960b57cec5SDimitry Andric       }
21970b57cec5SDimitry Andric 
21980b57cec5SDimitry Andric       VersionTuple MergedIntroduced2 = MergedIntroduced;
21990b57cec5SDimitry Andric       VersionTuple MergedDeprecated2 = MergedDeprecated;
22000b57cec5SDimitry Andric       VersionTuple MergedObsoleted2 = MergedObsoleted;
22010b57cec5SDimitry Andric 
22020b57cec5SDimitry Andric       if (MergedIntroduced2.empty())
22030b57cec5SDimitry Andric         MergedIntroduced2 = OldIntroduced;
22040b57cec5SDimitry Andric       if (MergedDeprecated2.empty())
22050b57cec5SDimitry Andric         MergedDeprecated2 = OldDeprecated;
22060b57cec5SDimitry Andric       if (MergedObsoleted2.empty())
22070b57cec5SDimitry Andric         MergedObsoleted2 = OldObsoleted;
22080b57cec5SDimitry Andric 
22090b57cec5SDimitry Andric       if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
22100b57cec5SDimitry Andric                                 MergedIntroduced2, MergedDeprecated2,
22110b57cec5SDimitry Andric                                 MergedObsoleted2)) {
22120b57cec5SDimitry Andric         Attrs.erase(Attrs.begin() + i);
22130b57cec5SDimitry Andric         --e;
22140b57cec5SDimitry Andric         continue;
22150b57cec5SDimitry Andric       }
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric       MergedIntroduced = MergedIntroduced2;
22180b57cec5SDimitry Andric       MergedDeprecated = MergedDeprecated2;
22190b57cec5SDimitry Andric       MergedObsoleted = MergedObsoleted2;
22200b57cec5SDimitry Andric       ++i;
22210b57cec5SDimitry Andric     }
22220b57cec5SDimitry Andric   }
22230b57cec5SDimitry Andric 
22240b57cec5SDimitry Andric   if (FoundAny &&
22250b57cec5SDimitry Andric       MergedIntroduced == Introduced &&
22260b57cec5SDimitry Andric       MergedDeprecated == Deprecated &&
22270b57cec5SDimitry Andric       MergedObsoleted == Obsoleted)
22280b57cec5SDimitry Andric     return nullptr;
22290b57cec5SDimitry Andric 
22300b57cec5SDimitry Andric   // Only create a new attribute if !OverrideOrImpl, but we want to do
22310b57cec5SDimitry Andric   // the checking.
2232a7dea167SDimitry Andric   if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
22330b57cec5SDimitry Andric                              MergedDeprecated, MergedObsoleted) &&
22340b57cec5SDimitry Andric       !OverrideOrImpl) {
2235a7dea167SDimitry Andric     auto *Avail = ::new (Context) AvailabilityAttr(
2236a7dea167SDimitry Andric         Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
22370fca6ea1SDimitry Andric         Message, IsStrict, Replacement, Priority, Environment);
22380b57cec5SDimitry Andric     Avail->setImplicit(Implicit);
22390b57cec5SDimitry Andric     return Avail;
22400b57cec5SDimitry Andric   }
22410b57cec5SDimitry Andric   return nullptr;
22420b57cec5SDimitry Andric }
22430b57cec5SDimitry Andric 
22440b57cec5SDimitry Andric static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2245fe6060f1SDimitry Andric   if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(
2246fe6060f1SDimitry Andric           D)) {
2247fe6060f1SDimitry Andric     S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
2248fe6060f1SDimitry Andric         << AL;
2249fe6060f1SDimitry Andric     return;
2250fe6060f1SDimitry Andric   }
2251fe6060f1SDimitry Andric 
2252fe6060f1SDimitry Andric   if (!AL.checkExactlyNumArgs(S, 1))
22530b57cec5SDimitry Andric     return;
22540b57cec5SDimitry Andric   IdentifierLoc *Platform = AL.getArgAsIdent(0);
22550b57cec5SDimitry Andric 
22560b57cec5SDimitry Andric   IdentifierInfo *II = Platform->Ident;
22570b57cec5SDimitry Andric   if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
22580b57cec5SDimitry Andric     S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
22590b57cec5SDimitry Andric       << Platform->Ident;
22600b57cec5SDimitry Andric 
22610b57cec5SDimitry Andric   auto *ND = dyn_cast<NamedDecl>(D);
22620b57cec5SDimitry Andric   if (!ND) // We warned about this already, so just return.
22630b57cec5SDimitry Andric     return;
22640b57cec5SDimitry Andric 
22650b57cec5SDimitry Andric   AvailabilityChange Introduced = AL.getAvailabilityIntroduced();
22660b57cec5SDimitry Andric   AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();
22670b57cec5SDimitry Andric   AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();
22680b57cec5SDimitry Andric   bool IsUnavailable = AL.getUnavailableLoc().isValid();
22690b57cec5SDimitry Andric   bool IsStrict = AL.getStrictLoc().isValid();
22700b57cec5SDimitry Andric   StringRef Str;
22715f757f3fSDimitry Andric   if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getMessageExpr()))
22720b57cec5SDimitry Andric     Str = SE->getString();
22730b57cec5SDimitry Andric   StringRef Replacement;
22745f757f3fSDimitry Andric   if (const auto *SE =
22755f757f3fSDimitry Andric           dyn_cast_if_present<StringLiteral>(AL.getReplacementExpr()))
22760b57cec5SDimitry Andric     Replacement = SE->getString();
22770b57cec5SDimitry Andric 
22780b57cec5SDimitry Andric   if (II->isStr("swift")) {
22790b57cec5SDimitry Andric     if (Introduced.isValid() || Obsoleted.isValid() ||
22800b57cec5SDimitry Andric         (!IsUnavailable && !Deprecated.isValid())) {
22810b57cec5SDimitry Andric       S.Diag(AL.getLoc(),
22820b57cec5SDimitry Andric              diag::warn_availability_swift_unavailable_deprecated_only);
22830b57cec5SDimitry Andric       return;
22840b57cec5SDimitry Andric     }
22850b57cec5SDimitry Andric   }
22860b57cec5SDimitry Andric 
2287349cc55cSDimitry Andric   if (II->isStr("fuchsia")) {
2288bdd1243dSDimitry Andric     std::optional<unsigned> Min, Sub;
2289349cc55cSDimitry Andric     if ((Min = Introduced.Version.getMinor()) ||
2290349cc55cSDimitry Andric         (Sub = Introduced.Version.getSubminor())) {
2291349cc55cSDimitry Andric       S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor);
2292349cc55cSDimitry Andric       return;
2293349cc55cSDimitry Andric     }
2294349cc55cSDimitry Andric   }
2295349cc55cSDimitry Andric 
22960fca6ea1SDimitry Andric   if (S.getLangOpts().HLSL && IsStrict)
22970fca6ea1SDimitry Andric     S.Diag(AL.getStrictLoc(), diag::err_availability_unexpected_parameter)
22980fca6ea1SDimitry Andric         << "strict" << /* HLSL */ 0;
22990fca6ea1SDimitry Andric 
23000b57cec5SDimitry Andric   int PriorityModifier = AL.isPragmaClangAttribute()
23010b57cec5SDimitry Andric                              ? Sema::AP_PragmaClangAttribute
23020b57cec5SDimitry Andric                              : Sema::AP_Explicit;
23030fca6ea1SDimitry Andric 
23040fca6ea1SDimitry Andric   const IdentifierLoc *EnvironmentLoc = AL.getEnvironment();
23050fca6ea1SDimitry Andric   IdentifierInfo *IIEnvironment = nullptr;
23060fca6ea1SDimitry Andric   if (EnvironmentLoc) {
23070fca6ea1SDimitry Andric     if (S.getLangOpts().HLSL) {
23080fca6ea1SDimitry Andric       IIEnvironment = EnvironmentLoc->Ident;
23090fca6ea1SDimitry Andric       if (AvailabilityAttr::getEnvironmentType(
23100fca6ea1SDimitry Andric               EnvironmentLoc->Ident->getName()) ==
23110fca6ea1SDimitry Andric           llvm::Triple::EnvironmentType::UnknownEnvironment)
23120fca6ea1SDimitry Andric         S.Diag(EnvironmentLoc->Loc, diag::warn_availability_unknown_environment)
23130fca6ea1SDimitry Andric             << EnvironmentLoc->Ident;
23140fca6ea1SDimitry Andric     } else {
23150fca6ea1SDimitry Andric       S.Diag(EnvironmentLoc->Loc, diag::err_availability_unexpected_parameter)
23160fca6ea1SDimitry Andric           << "environment" << /* C/C++ */ 1;
23170fca6ea1SDimitry Andric     }
23180fca6ea1SDimitry Andric   }
23190fca6ea1SDimitry Andric 
23200b57cec5SDimitry Andric   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2321a7dea167SDimitry Andric       ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2322a7dea167SDimitry Andric       Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
23230fca6ea1SDimitry Andric       Sema::AMK_None, PriorityModifier, IIEnvironment);
23240b57cec5SDimitry Andric   if (NewAttr)
23250b57cec5SDimitry Andric     D->addAttr(NewAttr);
23260b57cec5SDimitry Andric 
23270b57cec5SDimitry Andric   // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
23280b57cec5SDimitry Andric   // matches before the start of the watchOS platform.
23290b57cec5SDimitry Andric   if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
23300b57cec5SDimitry Andric     IdentifierInfo *NewII = nullptr;
23310b57cec5SDimitry Andric     if (II->getName() == "ios")
23320b57cec5SDimitry Andric       NewII = &S.Context.Idents.get("watchos");
23330b57cec5SDimitry Andric     else if (II->getName() == "ios_app_extension")
23340b57cec5SDimitry Andric       NewII = &S.Context.Idents.get("watchos_app_extension");
23350b57cec5SDimitry Andric 
23360b57cec5SDimitry Andric     if (NewII) {
233704eeddc0SDimitry Andric       const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
233804eeddc0SDimitry Andric       const auto *IOSToWatchOSMapping =
233904eeddc0SDimitry Andric           SDKInfo ? SDKInfo->getVersionMapping(
234004eeddc0SDimitry Andric                         DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())
234104eeddc0SDimitry Andric                   : nullptr;
234204eeddc0SDimitry Andric 
234304eeddc0SDimitry Andric       auto adjustWatchOSVersion =
234404eeddc0SDimitry Andric           [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
23450b57cec5SDimitry Andric         if (Version.empty())
23460b57cec5SDimitry Andric           return Version;
234704eeddc0SDimitry Andric         auto MinimumWatchOSVersion = VersionTuple(2, 0);
234804eeddc0SDimitry Andric 
234904eeddc0SDimitry Andric         if (IOSToWatchOSMapping) {
235004eeddc0SDimitry Andric           if (auto MappedVersion = IOSToWatchOSMapping->map(
2351bdd1243dSDimitry Andric                   Version, MinimumWatchOSVersion, std::nullopt)) {
2352bdd1243dSDimitry Andric             return *MappedVersion;
235304eeddc0SDimitry Andric           }
235404eeddc0SDimitry Andric         }
235504eeddc0SDimitry Andric 
23560b57cec5SDimitry Andric         auto Major = Version.getMajor();
23570b57cec5SDimitry Andric         auto NewMajor = Major >= 9 ? Major - 7 : 0;
23580b57cec5SDimitry Andric         if (NewMajor >= 2) {
235981ad6265SDimitry Andric           if (Version.getMinor()) {
236081ad6265SDimitry Andric             if (Version.getSubminor())
2361bdd1243dSDimitry Andric               return VersionTuple(NewMajor, *Version.getMinor(),
2362bdd1243dSDimitry Andric                                   *Version.getSubminor());
23630b57cec5SDimitry Andric             else
2364bdd1243dSDimitry Andric               return VersionTuple(NewMajor, *Version.getMinor());
23650b57cec5SDimitry Andric           }
23660b57cec5SDimitry Andric           return VersionTuple(NewMajor);
23670b57cec5SDimitry Andric         }
23680b57cec5SDimitry Andric 
236904eeddc0SDimitry Andric         return MinimumWatchOSVersion;
23700b57cec5SDimitry Andric       };
23710b57cec5SDimitry Andric 
23720b57cec5SDimitry Andric       auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
23730b57cec5SDimitry Andric       auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
23740b57cec5SDimitry Andric       auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
23750b57cec5SDimitry Andric 
23760b57cec5SDimitry Andric       AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2377a7dea167SDimitry Andric           ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2378a7dea167SDimitry Andric           NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
23790fca6ea1SDimitry Andric           Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,
23800fca6ea1SDimitry Andric           IIEnvironment);
23810b57cec5SDimitry Andric       if (NewAttr)
23820b57cec5SDimitry Andric         D->addAttr(NewAttr);
23830b57cec5SDimitry Andric     }
23840b57cec5SDimitry Andric   } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
23850b57cec5SDimitry Andric     // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
23860b57cec5SDimitry Andric     // matches before the start of the tvOS platform.
23870b57cec5SDimitry Andric     IdentifierInfo *NewII = nullptr;
23880b57cec5SDimitry Andric     if (II->getName() == "ios")
23890b57cec5SDimitry Andric       NewII = &S.Context.Idents.get("tvos");
23900b57cec5SDimitry Andric     else if (II->getName() == "ios_app_extension")
23910b57cec5SDimitry Andric       NewII = &S.Context.Idents.get("tvos_app_extension");
23920b57cec5SDimitry Andric 
23930b57cec5SDimitry Andric     if (NewII) {
239404eeddc0SDimitry Andric       const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
239504eeddc0SDimitry Andric       const auto *IOSToTvOSMapping =
239604eeddc0SDimitry Andric           SDKInfo ? SDKInfo->getVersionMapping(
239704eeddc0SDimitry Andric                         DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())
239804eeddc0SDimitry Andric                   : nullptr;
239904eeddc0SDimitry Andric 
240004eeddc0SDimitry Andric       auto AdjustTvOSVersion =
240104eeddc0SDimitry Andric           [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
240204eeddc0SDimitry Andric         if (Version.empty())
240304eeddc0SDimitry Andric           return Version;
240404eeddc0SDimitry Andric 
240504eeddc0SDimitry Andric         if (IOSToTvOSMapping) {
2406bdd1243dSDimitry Andric           if (auto MappedVersion = IOSToTvOSMapping->map(
2407bdd1243dSDimitry Andric                   Version, VersionTuple(0, 0), std::nullopt)) {
240881ad6265SDimitry Andric             return *MappedVersion;
240904eeddc0SDimitry Andric           }
241004eeddc0SDimitry Andric         }
241104eeddc0SDimitry Andric         return Version;
241204eeddc0SDimitry Andric       };
241304eeddc0SDimitry Andric 
241404eeddc0SDimitry Andric       auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
241504eeddc0SDimitry Andric       auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
241604eeddc0SDimitry Andric       auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
241704eeddc0SDimitry Andric 
24180b57cec5SDimitry Andric       AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
241904eeddc0SDimitry Andric           ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
242004eeddc0SDimitry Andric           NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
24210fca6ea1SDimitry Andric           Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,
24220fca6ea1SDimitry Andric           IIEnvironment);
24230b57cec5SDimitry Andric       if (NewAttr)
24240b57cec5SDimitry Andric         D->addAttr(NewAttr);
24250b57cec5SDimitry Andric     }
2426fe6060f1SDimitry Andric   } else if (S.Context.getTargetInfo().getTriple().getOS() ==
2427fe6060f1SDimitry Andric                  llvm::Triple::IOS &&
2428fe6060f1SDimitry Andric              S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
2429fe6060f1SDimitry Andric     auto GetSDKInfo = [&]() {
2430fe6060f1SDimitry Andric       return S.getDarwinSDKInfoForAvailabilityChecking(AL.getRange().getBegin(),
2431fe6060f1SDimitry Andric                                                        "macOS");
2432fe6060f1SDimitry Andric     };
2433fe6060f1SDimitry Andric 
2434fe6060f1SDimitry Andric     // Transcribe "ios" to "maccatalyst" (and add a new attribute).
2435fe6060f1SDimitry Andric     IdentifierInfo *NewII = nullptr;
2436fe6060f1SDimitry Andric     if (II->getName() == "ios")
2437fe6060f1SDimitry Andric       NewII = &S.Context.Idents.get("maccatalyst");
2438fe6060f1SDimitry Andric     else if (II->getName() == "ios_app_extension")
2439fe6060f1SDimitry Andric       NewII = &S.Context.Idents.get("maccatalyst_app_extension");
2440fe6060f1SDimitry Andric     if (NewII) {
2441fe6060f1SDimitry Andric       auto MinMacCatalystVersion = [](const VersionTuple &V) {
2442fe6060f1SDimitry Andric         if (V.empty())
2443fe6060f1SDimitry Andric           return V;
2444fe6060f1SDimitry Andric         if (V.getMajor() < 13 ||
2445fe6060f1SDimitry Andric             (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
2446fe6060f1SDimitry Andric           return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
2447fe6060f1SDimitry Andric         return V;
2448fe6060f1SDimitry Andric       };
2449fe6060f1SDimitry Andric       AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
245006c3fb27SDimitry Andric           ND, AL, NewII, true /*Implicit*/,
2451fe6060f1SDimitry Andric           MinMacCatalystVersion(Introduced.Version),
2452fe6060f1SDimitry Andric           MinMacCatalystVersion(Deprecated.Version),
2453fe6060f1SDimitry Andric           MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
2454fe6060f1SDimitry Andric           IsStrict, Replacement, Sema::AMK_None,
24550fca6ea1SDimitry Andric           PriorityModifier + Sema::AP_InferredFromOtherPlatform, IIEnvironment);
2456fe6060f1SDimitry Andric       if (NewAttr)
2457fe6060f1SDimitry Andric         D->addAttr(NewAttr);
2458fe6060f1SDimitry Andric     } else if (II->getName() == "macos" && GetSDKInfo() &&
2459fe6060f1SDimitry Andric                (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
2460fe6060f1SDimitry Andric                 !Obsoleted.Version.empty())) {
2461fe6060f1SDimitry Andric       if (const auto *MacOStoMacCatalystMapping =
2462fe6060f1SDimitry Andric               GetSDKInfo()->getVersionMapping(
2463fe6060f1SDimitry Andric                   DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2464fe6060f1SDimitry Andric         // Infer Mac Catalyst availability from the macOS availability attribute
2465fe6060f1SDimitry Andric         // if it has versioned availability. Don't infer 'unavailable'. This
2466fe6060f1SDimitry Andric         // inferred availability has lower priority than the other availability
2467fe6060f1SDimitry Andric         // attributes that are inferred from 'ios'.
2468fe6060f1SDimitry Andric         NewII = &S.Context.Idents.get("maccatalyst");
2469fe6060f1SDimitry Andric         auto RemapMacOSVersion =
2470bdd1243dSDimitry Andric             [&](const VersionTuple &V) -> std::optional<VersionTuple> {
2471fe6060f1SDimitry Andric           if (V.empty())
2472bdd1243dSDimitry Andric             return std::nullopt;
2473fe6060f1SDimitry Andric           // API_TO_BE_DEPRECATED is 100000.
2474fe6060f1SDimitry Andric           if (V.getMajor() == 100000)
2475fe6060f1SDimitry Andric             return VersionTuple(100000);
2476fe6060f1SDimitry Andric           // The minimum iosmac version is 13.1
2477bdd1243dSDimitry Andric           return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1),
2478bdd1243dSDimitry Andric                                                 std::nullopt);
2479fe6060f1SDimitry Andric         };
2480bdd1243dSDimitry Andric         std::optional<VersionTuple> NewIntroduced =
2481fe6060f1SDimitry Andric                                         RemapMacOSVersion(Introduced.Version),
2482fe6060f1SDimitry Andric                                     NewDeprecated =
2483fe6060f1SDimitry Andric                                         RemapMacOSVersion(Deprecated.Version),
2484fe6060f1SDimitry Andric                                     NewObsoleted =
2485fe6060f1SDimitry Andric                                         RemapMacOSVersion(Obsoleted.Version);
2486fe6060f1SDimitry Andric         if (NewIntroduced || NewDeprecated || NewObsoleted) {
2487fe6060f1SDimitry Andric           auto VersionOrEmptyVersion =
2488bdd1243dSDimitry Andric               [](const std::optional<VersionTuple> &V) -> VersionTuple {
2489fe6060f1SDimitry Andric             return V ? *V : VersionTuple();
2490fe6060f1SDimitry Andric           };
2491fe6060f1SDimitry Andric           AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
249206c3fb27SDimitry Andric               ND, AL, NewII, true /*Implicit*/,
2493fe6060f1SDimitry Andric               VersionOrEmptyVersion(NewIntroduced),
2494fe6060f1SDimitry Andric               VersionOrEmptyVersion(NewDeprecated),
2495fe6060f1SDimitry Andric               VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
2496fe6060f1SDimitry Andric               IsStrict, Replacement, Sema::AMK_None,
2497fe6060f1SDimitry Andric               PriorityModifier + Sema::AP_InferredFromOtherPlatform +
24980fca6ea1SDimitry Andric                   Sema::AP_InferredFromOtherPlatform,
24990fca6ea1SDimitry Andric               IIEnvironment);
2500fe6060f1SDimitry Andric           if (NewAttr)
2501fe6060f1SDimitry Andric             D->addAttr(NewAttr);
2502fe6060f1SDimitry Andric         }
2503fe6060f1SDimitry Andric       }
2504fe6060f1SDimitry Andric     }
25050b57cec5SDimitry Andric   }
25060b57cec5SDimitry Andric }
25070b57cec5SDimitry Andric 
25080b57cec5SDimitry Andric static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
25090b57cec5SDimitry Andric                                            const ParsedAttr &AL) {
251006c3fb27SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 4))
25110b57cec5SDimitry Andric     return;
25120b57cec5SDimitry Andric 
25130b57cec5SDimitry Andric   StringRef Language;
25145f757f3fSDimitry Andric   if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(0)))
25150b57cec5SDimitry Andric     Language = SE->getString();
25160b57cec5SDimitry Andric   StringRef DefinedIn;
25175f757f3fSDimitry Andric   if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(1)))
25180b57cec5SDimitry Andric     DefinedIn = SE->getString();
25190b57cec5SDimitry Andric   bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
252006c3fb27SDimitry Andric   StringRef USR;
25215f757f3fSDimitry Andric   if (const auto *SE = dyn_cast_if_present<StringLiteral>(AL.getArgAsExpr(3)))
252206c3fb27SDimitry Andric     USR = SE->getString();
25230b57cec5SDimitry Andric 
25240b57cec5SDimitry Andric   D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
252506c3fb27SDimitry Andric       S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));
25260b57cec5SDimitry Andric }
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric template <class T>
2529a7dea167SDimitry Andric static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
2530a7dea167SDimitry Andric                               typename T::VisibilityType value) {
25310b57cec5SDimitry Andric   T *existingAttr = D->getAttr<T>();
25320b57cec5SDimitry Andric   if (existingAttr) {
25330b57cec5SDimitry Andric     typename T::VisibilityType existingValue = existingAttr->getVisibility();
25340b57cec5SDimitry Andric     if (existingValue == value)
25350b57cec5SDimitry Andric       return nullptr;
25360b57cec5SDimitry Andric     S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2537a7dea167SDimitry Andric     S.Diag(CI.getLoc(), diag::note_previous_attribute);
25380b57cec5SDimitry Andric     D->dropAttr<T>();
25390b57cec5SDimitry Andric   }
2540a7dea167SDimitry Andric   return ::new (S.Context) T(S.Context, CI, value);
25410b57cec5SDimitry Andric }
25420b57cec5SDimitry Andric 
2543a7dea167SDimitry Andric VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
2544a7dea167SDimitry Andric                                           const AttributeCommonInfo &CI,
2545a7dea167SDimitry Andric                                           VisibilityAttr::VisibilityType Vis) {
2546a7dea167SDimitry Andric   return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
25470b57cec5SDimitry Andric }
25480b57cec5SDimitry Andric 
2549a7dea167SDimitry Andric TypeVisibilityAttr *
2550a7dea167SDimitry Andric Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
2551a7dea167SDimitry Andric                               TypeVisibilityAttr::VisibilityType Vis) {
2552a7dea167SDimitry Andric   return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
25530b57cec5SDimitry Andric }
25540b57cec5SDimitry Andric 
25550b57cec5SDimitry Andric static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
25560b57cec5SDimitry Andric                                  bool isTypeVisibility) {
25570b57cec5SDimitry Andric   // Visibility attributes don't mean anything on a typedef.
25580b57cec5SDimitry Andric   if (isa<TypedefNameDecl>(D)) {
25590b57cec5SDimitry Andric     S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
25600b57cec5SDimitry Andric     return;
25610b57cec5SDimitry Andric   }
25620b57cec5SDimitry Andric 
25630b57cec5SDimitry Andric   // 'type_visibility' can only go on a type or namespace.
256406c3fb27SDimitry Andric   if (isTypeVisibility && !(isa<TagDecl>(D) || isa<ObjCInterfaceDecl>(D) ||
25650b57cec5SDimitry Andric                             isa<NamespaceDecl>(D))) {
25660b57cec5SDimitry Andric     S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
256706c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << ExpectedTypeOrNamespace;
25680b57cec5SDimitry Andric     return;
25690b57cec5SDimitry Andric   }
25700b57cec5SDimitry Andric 
25710b57cec5SDimitry Andric   // Check that the argument is a string literal.
25720b57cec5SDimitry Andric   StringRef TypeStr;
25730b57cec5SDimitry Andric   SourceLocation LiteralLoc;
25740b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
25750b57cec5SDimitry Andric     return;
25760b57cec5SDimitry Andric 
25770b57cec5SDimitry Andric   VisibilityAttr::VisibilityType type;
25780b57cec5SDimitry Andric   if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
25790b57cec5SDimitry Andric     S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
25800b57cec5SDimitry Andric                                                                 << TypeStr;
25810b57cec5SDimitry Andric     return;
25820b57cec5SDimitry Andric   }
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   // Complain about attempts to use protected visibility on targets
25850b57cec5SDimitry Andric   // (like Darwin) that don't support it.
25860b57cec5SDimitry Andric   if (type == VisibilityAttr::Protected &&
25870b57cec5SDimitry Andric       !S.Context.getTargetInfo().hasProtectedVisibility()) {
25880b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
25890b57cec5SDimitry Andric     type = VisibilityAttr::Default;
25900b57cec5SDimitry Andric   }
25910b57cec5SDimitry Andric 
25920b57cec5SDimitry Andric   Attr *newAttr;
25930b57cec5SDimitry Andric   if (isTypeVisibility) {
2594a7dea167SDimitry Andric     newAttr = S.mergeTypeVisibilityAttr(
2595a7dea167SDimitry Andric         D, AL, (TypeVisibilityAttr::VisibilityType)type);
25960b57cec5SDimitry Andric   } else {
2597a7dea167SDimitry Andric     newAttr = S.mergeVisibilityAttr(D, AL, type);
25980b57cec5SDimitry Andric   }
25990b57cec5SDimitry Andric   if (newAttr)
26000b57cec5SDimitry Andric     D->addAttr(newAttr);
26010b57cec5SDimitry Andric }
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
26040b57cec5SDimitry Andric   unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
26050b57cec5SDimitry Andric   if (AL.getNumArgs() > 0) {
26060b57cec5SDimitry Andric     Expr *E = AL.getArgAsExpr(0);
2607bdd1243dSDimitry Andric     std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
2608349cc55cSDimitry Andric     if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
26090b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
26100b57cec5SDimitry Andric           << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
26110b57cec5SDimitry Andric       return;
26120b57cec5SDimitry Andric     }
26130b57cec5SDimitry Andric 
2614e8d8bef9SDimitry Andric     if (Idx->isSigned() && Idx->isNegative()) {
26150b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
26160b57cec5SDimitry Andric         << E->getSourceRange();
26170b57cec5SDimitry Andric       return;
26180b57cec5SDimitry Andric     }
26190b57cec5SDimitry Andric 
2620e8d8bef9SDimitry Andric     sentinel = Idx->getZExtValue();
26210b57cec5SDimitry Andric   }
26220b57cec5SDimitry Andric 
26230b57cec5SDimitry Andric   unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
26240b57cec5SDimitry Andric   if (AL.getNumArgs() > 1) {
26250b57cec5SDimitry Andric     Expr *E = AL.getArgAsExpr(1);
2626bdd1243dSDimitry Andric     std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
2627349cc55cSDimitry Andric     if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
26280b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
26290b57cec5SDimitry Andric           << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
26300b57cec5SDimitry Andric       return;
26310b57cec5SDimitry Andric     }
2632e8d8bef9SDimitry Andric     nullPos = Idx->getZExtValue();
26330b57cec5SDimitry Andric 
2634e8d8bef9SDimitry Andric     if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
26350b57cec5SDimitry Andric       // FIXME: This error message could be improved, it would be nice
26360b57cec5SDimitry Andric       // to say what the bounds actually are.
26370b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
26380b57cec5SDimitry Andric         << E->getSourceRange();
26390b57cec5SDimitry Andric       return;
26400b57cec5SDimitry Andric     }
26410b57cec5SDimitry Andric   }
26420b57cec5SDimitry Andric 
26430b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
26440b57cec5SDimitry Andric     const FunctionType *FT = FD->getType()->castAs<FunctionType>();
26450b57cec5SDimitry Andric     if (isa<FunctionNoProtoType>(FT)) {
26460b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
26470b57cec5SDimitry Andric       return;
26480b57cec5SDimitry Andric     }
26490b57cec5SDimitry Andric 
26500b57cec5SDimitry Andric     if (!cast<FunctionProtoType>(FT)->isVariadic()) {
26510b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
26520b57cec5SDimitry Andric       return;
26530b57cec5SDimitry Andric     }
26540b57cec5SDimitry Andric   } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
26550b57cec5SDimitry Andric     if (!MD->isVariadic()) {
26560b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
26570b57cec5SDimitry Andric       return;
26580b57cec5SDimitry Andric     }
26590b57cec5SDimitry Andric   } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
26600b57cec5SDimitry Andric     if (!BD->isVariadic()) {
26610b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
26620b57cec5SDimitry Andric       return;
26630b57cec5SDimitry Andric     }
26640b57cec5SDimitry Andric   } else if (const auto *V = dyn_cast<VarDecl>(D)) {
26650b57cec5SDimitry Andric     QualType Ty = V->getType();
26660b57cec5SDimitry Andric     if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
26670b57cec5SDimitry Andric       const FunctionType *FT = Ty->isFunctionPointerType()
26680b57cec5SDimitry Andric                                    ? D->getFunctionType()
2669fe6060f1SDimitry Andric                                    : Ty->castAs<BlockPointerType>()
2670fe6060f1SDimitry Andric                                          ->getPointeeType()
2671fe6060f1SDimitry Andric                                          ->castAs<FunctionType>();
26720b57cec5SDimitry Andric       if (!cast<FunctionProtoType>(FT)->isVariadic()) {
26730b57cec5SDimitry Andric         int m = Ty->isFunctionPointerType() ? 0 : 1;
26740b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
26750b57cec5SDimitry Andric         return;
26760b57cec5SDimitry Andric       }
26770b57cec5SDimitry Andric     } else {
26780b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
267906c3fb27SDimitry Andric           << AL << AL.isRegularKeywordAttribute()
268006c3fb27SDimitry Andric           << ExpectedFunctionMethodOrBlock;
26810b57cec5SDimitry Andric       return;
26820b57cec5SDimitry Andric     }
26830b57cec5SDimitry Andric   } else {
26840b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
268506c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute()
268606c3fb27SDimitry Andric         << ExpectedFunctionMethodOrBlock;
26870b57cec5SDimitry Andric     return;
26880b57cec5SDimitry Andric   }
2689a7dea167SDimitry Andric   D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
26900b57cec5SDimitry Andric }
26910b57cec5SDimitry Andric 
26920b57cec5SDimitry Andric static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
26930b57cec5SDimitry Andric   if (D->getFunctionType() &&
2694a7dea167SDimitry Andric       D->getFunctionType()->getReturnType()->isVoidType() &&
2695a7dea167SDimitry Andric       !isa<CXXConstructorDecl>(D)) {
26960b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
26970b57cec5SDimitry Andric     return;
26980b57cec5SDimitry Andric   }
26990b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
27000b57cec5SDimitry Andric     if (MD->getReturnType()->isVoidType()) {
27010b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
27020b57cec5SDimitry Andric       return;
27030b57cec5SDimitry Andric     }
27040b57cec5SDimitry Andric 
2705a7dea167SDimitry Andric   StringRef Str;
2706fe6060f1SDimitry Andric   if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {
27075ffd83dbSDimitry Andric     // The standard attribute cannot be applied to variable declarations such
27085ffd83dbSDimitry Andric     // as a function pointer.
27095ffd83dbSDimitry Andric     if (isa<VarDecl>(D))
27105ffd83dbSDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
271106c3fb27SDimitry Andric           << AL << AL.isRegularKeywordAttribute()
271206c3fb27SDimitry Andric           << "functions, classes, or enumerations";
27135ffd83dbSDimitry Andric 
2714a7dea167SDimitry Andric     // If this is spelled as the standard C++17 attribute, but not in C++17,
2715a7dea167SDimitry Andric     // warn about using it as an extension. If there are attribute arguments,
27165f757f3fSDimitry Andric     // then claim it's a C++20 extension instead.
2717a7dea167SDimitry Andric     // FIXME: If WG14 does not seem likely to adopt the same feature, add an
27185f757f3fSDimitry Andric     // extension warning for C23 mode.
2719a7dea167SDimitry Andric     const LangOptions &LO = S.getLangOpts();
2720a7dea167SDimitry Andric     if (AL.getNumArgs() == 1) {
27215ffd83dbSDimitry Andric       if (LO.CPlusPlus && !LO.CPlusPlus20)
27225ffd83dbSDimitry Andric         S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
27230b57cec5SDimitry Andric 
2724bdd1243dSDimitry Andric       // Since this is spelled [[nodiscard]], get the optional string
27255f757f3fSDimitry Andric       // literal. If in C++ mode, but not in C++20 mode, diagnose as an
2726a7dea167SDimitry Andric       // extension.
27275f757f3fSDimitry Andric       // FIXME: C23 should support this feature as well, even as an extension.
2728a7dea167SDimitry Andric       if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
2729a7dea167SDimitry Andric         return;
2730a7dea167SDimitry Andric     } else if (LO.CPlusPlus && !LO.CPlusPlus17)
2731a7dea167SDimitry Andric       S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2732a7dea167SDimitry Andric   }
2733a7dea167SDimitry Andric 
273481ad6265SDimitry Andric   if ((!AL.isGNUAttribute() &&
273581ad6265SDimitry Andric        !(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&
273681ad6265SDimitry Andric       isa<TypedefNameDecl>(D)) {
273781ad6265SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_unused_result_typedef_unsupported_spelling)
273881ad6265SDimitry Andric         << AL.isGNUScope();
273981ad6265SDimitry Andric     return;
274081ad6265SDimitry Andric   }
274181ad6265SDimitry Andric 
2742a7dea167SDimitry Andric   D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
27430b57cec5SDimitry Andric }
27440b57cec5SDimitry Andric 
27450b57cec5SDimitry Andric static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
27460b57cec5SDimitry Andric   // weak_import only applies to variable & function declarations.
27470b57cec5SDimitry Andric   bool isDef = false;
27480b57cec5SDimitry Andric   if (!D->canBeWeakImported(isDef)) {
27490b57cec5SDimitry Andric     if (isDef)
27500b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
27510b57cec5SDimitry Andric         << "weak_import";
27520b57cec5SDimitry Andric     else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
27530b57cec5SDimitry Andric              (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
27540b57cec5SDimitry Andric               (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
27550b57cec5SDimitry Andric       // Nothing to warn about here.
27560b57cec5SDimitry Andric     } else
27570b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
275806c3fb27SDimitry Andric           << AL << AL.isRegularKeywordAttribute() << ExpectedVariableOrFunction;
27590b57cec5SDimitry Andric 
27600b57cec5SDimitry Andric     return;
27610b57cec5SDimitry Andric   }
27620b57cec5SDimitry Andric 
2763a7dea167SDimitry Andric   D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
27640b57cec5SDimitry Andric }
27650b57cec5SDimitry Andric 
27660b57cec5SDimitry Andric // Handles reqd_work_group_size and work_group_size_hint.
27670b57cec5SDimitry Andric template <typename WorkGroupAttr>
27680b57cec5SDimitry Andric static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
27690b57cec5SDimitry Andric   uint32_t WGSize[3];
27700b57cec5SDimitry Andric   for (unsigned i = 0; i < 3; ++i) {
27710b57cec5SDimitry Andric     const Expr *E = AL.getArgAsExpr(i);
27720fca6ea1SDimitry Andric     if (!S.checkUInt32Argument(AL, E, WGSize[i], i,
27730b57cec5SDimitry Andric                                /*StrictlyUnsigned=*/true))
27740b57cec5SDimitry Andric       return;
27750b57cec5SDimitry Andric     if (WGSize[i] == 0) {
27760b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
27770b57cec5SDimitry Andric           << AL << E->getSourceRange();
27780b57cec5SDimitry Andric       return;
27790b57cec5SDimitry Andric     }
27800b57cec5SDimitry Andric   }
27810b57cec5SDimitry Andric 
27820b57cec5SDimitry Andric   WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
27830b57cec5SDimitry Andric   if (Existing && !(Existing->getXDim() == WGSize[0] &&
27840b57cec5SDimitry Andric                     Existing->getYDim() == WGSize[1] &&
27850b57cec5SDimitry Andric                     Existing->getZDim() == WGSize[2]))
27860b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
27870b57cec5SDimitry Andric 
2788a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
2789a7dea167SDimitry Andric                  WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
27900b57cec5SDimitry Andric }
27910b57cec5SDimitry Andric 
27920b57cec5SDimitry Andric static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
27930b57cec5SDimitry Andric   if (!AL.hasParsedType()) {
27940b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
27950b57cec5SDimitry Andric     return;
27960b57cec5SDimitry Andric   }
27970b57cec5SDimitry Andric 
27980b57cec5SDimitry Andric   TypeSourceInfo *ParmTSI = nullptr;
27990b57cec5SDimitry Andric   QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
28000b57cec5SDimitry Andric   assert(ParmTSI && "no type source info for attribute argument");
28010b57cec5SDimitry Andric 
28020b57cec5SDimitry Andric   if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
28030b57cec5SDimitry Andric       (ParmType->isBooleanType() ||
28040b57cec5SDimitry Andric        !ParmType->isIntegralType(S.getASTContext()))) {
2805480093f4SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
28060b57cec5SDimitry Andric     return;
28070b57cec5SDimitry Andric   }
28080b57cec5SDimitry Andric 
28090b57cec5SDimitry Andric   if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
28100b57cec5SDimitry Andric     if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
28110b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
28120b57cec5SDimitry Andric       return;
28130b57cec5SDimitry Andric     }
28140b57cec5SDimitry Andric   }
28150b57cec5SDimitry Andric 
2816a7dea167SDimitry Andric   D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
28170b57cec5SDimitry Andric }
28180b57cec5SDimitry Andric 
2819a7dea167SDimitry Andric SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
2820a7dea167SDimitry Andric                                     StringRef Name) {
28210b57cec5SDimitry Andric   // Explicit or partial specializations do not inherit
28220b57cec5SDimitry Andric   // the section attribute from the primary template.
28230b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2824a7dea167SDimitry Andric     if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
28250b57cec5SDimitry Andric         FD->isFunctionTemplateSpecialization())
28260b57cec5SDimitry Andric       return nullptr;
28270b57cec5SDimitry Andric   }
28280b57cec5SDimitry Andric   if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
28290b57cec5SDimitry Andric     if (ExistingAttr->getName() == Name)
28300b57cec5SDimitry Andric       return nullptr;
28310b57cec5SDimitry Andric     Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
28320b57cec5SDimitry Andric          << 1 /*section*/;
2833a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::note_previous_attribute);
28340b57cec5SDimitry Andric     return nullptr;
28350b57cec5SDimitry Andric   }
2836a7dea167SDimitry Andric   return ::new (Context) SectionAttr(Context, CI, Name);
28370b57cec5SDimitry Andric }
28380b57cec5SDimitry Andric 
2839fe6060f1SDimitry Andric llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
2840fe6060f1SDimitry Andric   if (!Context.getTargetInfo().getTriple().isOSDarwin())
2841fe6060f1SDimitry Andric     return llvm::Error::success();
2842fe6060f1SDimitry Andric 
2843fe6060f1SDimitry Andric   // Let MCSectionMachO validate this.
2844fe6060f1SDimitry Andric   StringRef Segment, Section;
2845fe6060f1SDimitry Andric   unsigned TAA, StubSize;
2846fe6060f1SDimitry Andric   bool HasTAA;
2847fe6060f1SDimitry Andric   return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,
2848fe6060f1SDimitry Andric                                                      TAA, HasTAA, StubSize);
2849fe6060f1SDimitry Andric }
2850fe6060f1SDimitry Andric 
28510b57cec5SDimitry Andric bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
2852fe6060f1SDimitry Andric   if (llvm::Error E = isValidSectionSpecifier(SecName)) {
2853fe6060f1SDimitry Andric     Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
2854fe6060f1SDimitry Andric         << toString(std::move(E)) << 1 /*'section'*/;
28550b57cec5SDimitry Andric     return false;
28560b57cec5SDimitry Andric   }
28570b57cec5SDimitry Andric   return true;
28580b57cec5SDimitry Andric }
28590b57cec5SDimitry Andric 
28600b57cec5SDimitry Andric static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
28610b57cec5SDimitry Andric   // Make sure that there is a string literal as the sections's single
28620b57cec5SDimitry Andric   // argument.
28630b57cec5SDimitry Andric   StringRef Str;
28640b57cec5SDimitry Andric   SourceLocation LiteralLoc;
28650b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
28660b57cec5SDimitry Andric     return;
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric   if (!S.checkSectionName(LiteralLoc, Str))
28690b57cec5SDimitry Andric     return;
28700b57cec5SDimitry Andric 
2871a7dea167SDimitry Andric   SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
2872e8d8bef9SDimitry Andric   if (NewAttr) {
28730b57cec5SDimitry Andric     D->addAttr(NewAttr);
2874e8d8bef9SDimitry Andric     if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl,
2875e8d8bef9SDimitry Andric             ObjCPropertyDecl>(D))
2876e8d8bef9SDimitry Andric       S.UnifySection(NewAttr->getName(),
2877e8d8bef9SDimitry Andric                      ASTContext::PSF_Execute | ASTContext::PSF_Read,
2878e8d8bef9SDimitry Andric                      cast<NamedDecl>(D));
2879e8d8bef9SDimitry Andric   }
28800b57cec5SDimitry Andric }
28810b57cec5SDimitry Andric 
28821db9f3b2SDimitry Andric static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
28831db9f3b2SDimitry Andric   StringRef Str;
28841db9f3b2SDimitry Andric   SourceLocation LiteralLoc;
28851db9f3b2SDimitry Andric   // Check that it is a string.
28861db9f3b2SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
28871db9f3b2SDimitry Andric     return;
28881db9f3b2SDimitry Andric 
28891db9f3b2SDimitry Andric   llvm::CodeModel::Model CM;
28901db9f3b2SDimitry Andric   if (!CodeModelAttr::ConvertStrToModel(Str, CM)) {
28911db9f3b2SDimitry Andric     S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str;
28921db9f3b2SDimitry Andric     return;
28931db9f3b2SDimitry Andric   }
28941db9f3b2SDimitry Andric 
28951db9f3b2SDimitry Andric   D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM));
28961db9f3b2SDimitry Andric }
28971db9f3b2SDimitry Andric 
28980b57cec5SDimitry Andric // This is used for `__declspec(code_seg("segname"))` on a decl.
28990b57cec5SDimitry Andric // `#pragma code_seg("segname")` uses checkSectionName() instead.
29000b57cec5SDimitry Andric static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
29010b57cec5SDimitry Andric                              StringRef CodeSegName) {
2902fe6060f1SDimitry Andric   if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {
29030b57cec5SDimitry Andric     S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
2904fe6060f1SDimitry Andric         << toString(std::move(E)) << 0 /*'code-seg'*/;
29050b57cec5SDimitry Andric     return false;
29060b57cec5SDimitry Andric   }
29070b57cec5SDimitry Andric 
29080b57cec5SDimitry Andric   return true;
29090b57cec5SDimitry Andric }
29100b57cec5SDimitry Andric 
2911a7dea167SDimitry Andric CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
2912a7dea167SDimitry Andric                                     StringRef Name) {
29130b57cec5SDimitry Andric   // Explicit or partial specializations do not inherit
29140b57cec5SDimitry Andric   // the code_seg attribute from the primary template.
29150b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
29160b57cec5SDimitry Andric     if (FD->isFunctionTemplateSpecialization())
29170b57cec5SDimitry Andric       return nullptr;
29180b57cec5SDimitry Andric   }
29190b57cec5SDimitry Andric   if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
29200b57cec5SDimitry Andric     if (ExistingAttr->getName() == Name)
29210b57cec5SDimitry Andric       return nullptr;
29220b57cec5SDimitry Andric     Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
29230b57cec5SDimitry Andric          << 0 /*codeseg*/;
2924a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::note_previous_attribute);
29250b57cec5SDimitry Andric     return nullptr;
29260b57cec5SDimitry Andric   }
2927a7dea167SDimitry Andric   return ::new (Context) CodeSegAttr(Context, CI, Name);
29280b57cec5SDimitry Andric }
29290b57cec5SDimitry Andric 
29300b57cec5SDimitry Andric static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
29310b57cec5SDimitry Andric   StringRef Str;
29320b57cec5SDimitry Andric   SourceLocation LiteralLoc;
29330b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
29340b57cec5SDimitry Andric     return;
29350b57cec5SDimitry Andric   if (!checkCodeSegName(S, LiteralLoc, Str))
29360b57cec5SDimitry Andric     return;
29370b57cec5SDimitry Andric   if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
29380b57cec5SDimitry Andric     if (!ExistingAttr->isImplicit()) {
29390b57cec5SDimitry Andric       S.Diag(AL.getLoc(),
29400b57cec5SDimitry Andric              ExistingAttr->getName() == Str
29410b57cec5SDimitry Andric              ? diag::warn_duplicate_codeseg_attribute
29420b57cec5SDimitry Andric              : diag::err_conflicting_codeseg_attribute);
29430b57cec5SDimitry Andric       return;
29440b57cec5SDimitry Andric     }
29450b57cec5SDimitry Andric     D->dropAttr<CodeSegAttr>();
29460b57cec5SDimitry Andric   }
2947a7dea167SDimitry Andric   if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
29480b57cec5SDimitry Andric     D->addAttr(CSA);
29490b57cec5SDimitry Andric }
29500b57cec5SDimitry Andric 
29510b57cec5SDimitry Andric bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
2952e8d8bef9SDimitry Andric   enum FirstParam { Unsupported, Duplicate, Unknown };
2953bdd1243dSDimitry Andric   enum SecondParam { None, CPU, Tune };
29544824e7fdSDimitry Andric   enum ThirdParam { Target, TargetClones };
2955349cc55cSDimitry Andric   if (AttrStr.contains("fpmath="))
29560b57cec5SDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
29574824e7fdSDimitry Andric            << Unsupported << None << "fpmath=" << Target;
2958e8d8bef9SDimitry Andric 
2959e8d8bef9SDimitry Andric   // Diagnose use of tune if target doesn't support it.
2960e8d8bef9SDimitry Andric   if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
2961349cc55cSDimitry Andric       AttrStr.contains("tune="))
2962e8d8bef9SDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
29634824e7fdSDimitry Andric            << Unsupported << None << "tune=" << Target;
29640b57cec5SDimitry Andric 
2965bdd1243dSDimitry Andric   ParsedTargetAttr ParsedAttrs =
2966bdd1243dSDimitry Andric       Context.getTargetInfo().parseTargetAttr(AttrStr);
29670b57cec5SDimitry Andric 
2968bdd1243dSDimitry Andric   if (!ParsedAttrs.CPU.empty() &&
2969bdd1243dSDimitry Andric       !Context.getTargetInfo().isValidCPUName(ParsedAttrs.CPU))
29700b57cec5SDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
2971bdd1243dSDimitry Andric            << Unknown << CPU << ParsedAttrs.CPU << Target;
2972e8d8bef9SDimitry Andric 
2973e8d8bef9SDimitry Andric   if (!ParsedAttrs.Tune.empty() &&
2974e8d8bef9SDimitry Andric       !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))
2975e8d8bef9SDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
29764824e7fdSDimitry Andric            << Unknown << Tune << ParsedAttrs.Tune << Target;
29770b57cec5SDimitry Andric 
29785f757f3fSDimitry Andric   if (Context.getTargetInfo().getTriple().isRISCV() &&
29795f757f3fSDimitry Andric       ParsedAttrs.Duplicate != "")
29805f757f3fSDimitry Andric     return Diag(LiteralLoc, diag::err_duplicate_target_attribute)
29815f757f3fSDimitry Andric            << Duplicate << None << ParsedAttrs.Duplicate << Target;
29825f757f3fSDimitry Andric 
2983bdd1243dSDimitry Andric   if (ParsedAttrs.Duplicate != "")
29840b57cec5SDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
2985bdd1243dSDimitry Andric            << Duplicate << None << ParsedAttrs.Duplicate << Target;
29860b57cec5SDimitry Andric 
29870b57cec5SDimitry Andric   for (const auto &Feature : ParsedAttrs.Features) {
29880b57cec5SDimitry Andric     auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
29890b57cec5SDimitry Andric     if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
29900b57cec5SDimitry Andric       return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
29914824e7fdSDimitry Andric              << Unsupported << None << CurFeature << Target;
29920b57cec5SDimitry Andric   }
29930b57cec5SDimitry Andric 
29940fca6ea1SDimitry Andric   TargetInfo::BranchProtectionInfo BPI{};
29954824e7fdSDimitry Andric   StringRef DiagMsg;
29964824e7fdSDimitry Andric   if (ParsedAttrs.BranchProtection.empty())
29974824e7fdSDimitry Andric     return false;
29984824e7fdSDimitry Andric   if (!Context.getTargetInfo().validateBranchProtection(
2999bdd1243dSDimitry Andric           ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI, DiagMsg)) {
30004824e7fdSDimitry Andric     if (DiagMsg.empty())
3001480093f4SDimitry Andric       return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
30024824e7fdSDimitry Andric              << Unsupported << None << "branch-protection" << Target;
3003480093f4SDimitry Andric     return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
30044824e7fdSDimitry Andric            << DiagMsg;
3005480093f4SDimitry Andric   }
30064824e7fdSDimitry Andric   if (!DiagMsg.empty())
30074824e7fdSDimitry Andric     Diag(LiteralLoc, diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3008480093f4SDimitry Andric 
30090b57cec5SDimitry Andric   return false;
30100b57cec5SDimitry Andric }
30110b57cec5SDimitry Andric 
30120fca6ea1SDimitry Andric bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
30130fca6ea1SDimitry Andric                                   StringRef AttrStr) {
3014bdd1243dSDimitry Andric   enum FirstParam { Unsupported };
3015bdd1243dSDimitry Andric   enum SecondParam { None };
3016bdd1243dSDimitry Andric   enum ThirdParam { Target, TargetClones, TargetVersion };
3017bdd1243dSDimitry Andric   llvm::SmallVector<StringRef, 8> Features;
3018bdd1243dSDimitry Andric   AttrStr.split(Features, "+");
3019bdd1243dSDimitry Andric   for (auto &CurFeature : Features) {
3020bdd1243dSDimitry Andric     CurFeature = CurFeature.trim();
3021bdd1243dSDimitry Andric     if (CurFeature == "default")
3022bdd1243dSDimitry Andric       continue;
3023bdd1243dSDimitry Andric     if (!Context.getTargetInfo().validateCpuSupports(CurFeature))
3024bdd1243dSDimitry Andric       return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3025bdd1243dSDimitry Andric              << Unsupported << None << CurFeature << TargetVersion;
3026bdd1243dSDimitry Andric   }
3027bdd1243dSDimitry Andric   return false;
3028bdd1243dSDimitry Andric }
3029bdd1243dSDimitry Andric 
3030bdd1243dSDimitry Andric static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3031bdd1243dSDimitry Andric   StringRef Str;
3032bdd1243dSDimitry Andric   SourceLocation LiteralLoc;
3033bdd1243dSDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
30340fca6ea1SDimitry Andric       S.checkTargetVersionAttr(LiteralLoc, D, Str))
3035bdd1243dSDimitry Andric     return;
3036bdd1243dSDimitry Andric   TargetVersionAttr *NewAttr =
3037bdd1243dSDimitry Andric       ::new (S.Context) TargetVersionAttr(S.Context, AL, Str);
3038bdd1243dSDimitry Andric   D->addAttr(NewAttr);
3039bdd1243dSDimitry Andric }
3040bdd1243dSDimitry Andric 
30410b57cec5SDimitry Andric static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
30420b57cec5SDimitry Andric   StringRef Str;
30430b57cec5SDimitry Andric   SourceLocation LiteralLoc;
30440b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
30450b57cec5SDimitry Andric       S.checkTargetAttr(LiteralLoc, Str))
30460b57cec5SDimitry Andric     return;
30470b57cec5SDimitry Andric 
3048a7dea167SDimitry Andric   TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
30490b57cec5SDimitry Andric   D->addAttr(NewAttr);
30500b57cec5SDimitry Andric }
30510b57cec5SDimitry Andric 
3052bdd1243dSDimitry Andric bool Sema::checkTargetClonesAttrString(
3053bdd1243dSDimitry Andric     SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,
30540fca6ea1SDimitry Andric     Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,
3055bdd1243dSDimitry Andric     SmallVectorImpl<SmallString<64>> &StringsBuffer) {
30564824e7fdSDimitry Andric   enum FirstParam { Unsupported, Duplicate, Unknown };
3057bdd1243dSDimitry Andric   enum SecondParam { None, CPU, Tune };
30584824e7fdSDimitry Andric   enum ThirdParam { Target, TargetClones };
30594824e7fdSDimitry Andric   HasCommas = HasCommas || Str.contains(',');
306006c3fb27SDimitry Andric   const TargetInfo &TInfo = Context.getTargetInfo();
30614824e7fdSDimitry Andric   // Warn on empty at the beginning of a string.
30624824e7fdSDimitry Andric   if (Str.size() == 0)
30634824e7fdSDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
30644824e7fdSDimitry Andric            << Unsupported << None << "" << TargetClones;
30654824e7fdSDimitry Andric 
30664824e7fdSDimitry Andric   std::pair<StringRef, StringRef> Parts = {{}, Str};
30674824e7fdSDimitry Andric   while (!Parts.second.empty()) {
30684824e7fdSDimitry Andric     Parts = Parts.second.split(',');
30694824e7fdSDimitry Andric     StringRef Cur = Parts.first.trim();
307006c3fb27SDimitry Andric     SourceLocation CurLoc =
307106c3fb27SDimitry Andric         Literal->getLocationOfByte(Cur.data() - Literal->getString().data(),
307206c3fb27SDimitry Andric                                    getSourceManager(), getLangOpts(), TInfo);
30734824e7fdSDimitry Andric 
30744824e7fdSDimitry Andric     bool DefaultIsDupe = false;
3075bdd1243dSDimitry Andric     bool HasCodeGenImpact = false;
30764824e7fdSDimitry Andric     if (Cur.empty())
30774824e7fdSDimitry Andric       return Diag(CurLoc, diag::warn_unsupported_target_attribute)
30784824e7fdSDimitry Andric              << Unsupported << None << "" << TargetClones;
30794824e7fdSDimitry Andric 
308006c3fb27SDimitry Andric     if (TInfo.getTriple().isAArch64()) {
3081bdd1243dSDimitry Andric       // AArch64 target clones specific
3082bdd1243dSDimitry Andric       if (Cur == "default") {
3083bdd1243dSDimitry Andric         DefaultIsDupe = HasDefault;
3084bdd1243dSDimitry Andric         HasDefault = true;
3085bdd1243dSDimitry Andric         if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)
3086bdd1243dSDimitry Andric           Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3087bdd1243dSDimitry Andric         else
3088bdd1243dSDimitry Andric           StringsBuffer.push_back(Cur);
3089bdd1243dSDimitry Andric       } else {
3090bdd1243dSDimitry Andric         std::pair<StringRef, StringRef> CurParts = {{}, Cur};
3091bdd1243dSDimitry Andric         llvm::SmallVector<StringRef, 8> CurFeatures;
3092bdd1243dSDimitry Andric         while (!CurParts.second.empty()) {
3093bdd1243dSDimitry Andric           CurParts = CurParts.second.split('+');
3094bdd1243dSDimitry Andric           StringRef CurFeature = CurParts.first.trim();
309506c3fb27SDimitry Andric           if (!TInfo.validateCpuSupports(CurFeature)) {
3096bdd1243dSDimitry Andric             Diag(CurLoc, diag::warn_unsupported_target_attribute)
3097bdd1243dSDimitry Andric                 << Unsupported << None << CurFeature << TargetClones;
3098bdd1243dSDimitry Andric             continue;
3099bdd1243dSDimitry Andric           }
310006c3fb27SDimitry Andric           if (TInfo.doesFeatureAffectCodeGen(CurFeature))
3101bdd1243dSDimitry Andric             HasCodeGenImpact = true;
3102bdd1243dSDimitry Andric           CurFeatures.push_back(CurFeature);
3103bdd1243dSDimitry Andric         }
3104bdd1243dSDimitry Andric         // Canonize TargetClones Attributes
3105bdd1243dSDimitry Andric         llvm::sort(CurFeatures);
3106bdd1243dSDimitry Andric         SmallString<64> Res;
3107bdd1243dSDimitry Andric         for (auto &CurFeat : CurFeatures) {
31080fca6ea1SDimitry Andric           if (!Res.empty())
3109bdd1243dSDimitry Andric             Res.append("+");
3110bdd1243dSDimitry Andric           Res.append(CurFeat);
3111bdd1243dSDimitry Andric         }
3112bdd1243dSDimitry Andric         if (llvm::is_contained(StringsBuffer, Res) || DefaultIsDupe)
3113bdd1243dSDimitry Andric           Diag(CurLoc, diag::warn_target_clone_duplicate_options);
3114bdd1243dSDimitry Andric         else if (!HasCodeGenImpact)
3115bdd1243dSDimitry Andric           // Ignore features in target_clone attribute that don't impact
3116bdd1243dSDimitry Andric           // code generation
3117bdd1243dSDimitry Andric           Diag(CurLoc, diag::warn_target_clone_no_impact_options);
3118bdd1243dSDimitry Andric         else if (!Res.empty()) {
3119bdd1243dSDimitry Andric           StringsBuffer.push_back(Res);
3120bdd1243dSDimitry Andric           HasNotDefault = true;
3121bdd1243dSDimitry Andric         }
3122bdd1243dSDimitry Andric       }
3123bdd1243dSDimitry Andric     } else {
3124bdd1243dSDimitry Andric       // Other targets ( currently X86 )
31255f757f3fSDimitry Andric       if (Cur.starts_with("arch=")) {
31264824e7fdSDimitry Andric         if (!Context.getTargetInfo().isValidCPUName(
31274824e7fdSDimitry Andric                 Cur.drop_front(sizeof("arch=") - 1)))
31284824e7fdSDimitry Andric           return Diag(CurLoc, diag::warn_unsupported_target_attribute)
3129bdd1243dSDimitry Andric                  << Unsupported << CPU << Cur.drop_front(sizeof("arch=") - 1)
3130bdd1243dSDimitry Andric                  << TargetClones;
31314824e7fdSDimitry Andric       } else if (Cur == "default") {
31324824e7fdSDimitry Andric         DefaultIsDupe = HasDefault;
31334824e7fdSDimitry Andric         HasDefault = true;
31344824e7fdSDimitry Andric       } else if (!Context.getTargetInfo().isValidFeatureName(Cur))
31354824e7fdSDimitry Andric         return Diag(CurLoc, diag::warn_unsupported_target_attribute)
31364824e7fdSDimitry Andric                << Unsupported << None << Cur << TargetClones;
3137bdd1243dSDimitry Andric       if (llvm::is_contained(StringsBuffer, Cur) || DefaultIsDupe)
31384824e7fdSDimitry Andric         Diag(CurLoc, diag::warn_target_clone_duplicate_options);
31394824e7fdSDimitry Andric       // Note: Add even if there are duplicates, since it changes name mangling.
3140bdd1243dSDimitry Andric       StringsBuffer.push_back(Cur);
31414824e7fdSDimitry Andric     }
3142bdd1243dSDimitry Andric   }
31435f757f3fSDimitry Andric   if (Str.rtrim().ends_with(","))
31444824e7fdSDimitry Andric     return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
31454824e7fdSDimitry Andric            << Unsupported << None << "" << TargetClones;
31464824e7fdSDimitry Andric   return false;
31474824e7fdSDimitry Andric }
31484824e7fdSDimitry Andric 
31494824e7fdSDimitry Andric static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3150bdd1243dSDimitry Andric   if (S.Context.getTargetInfo().getTriple().isAArch64() &&
3151bdd1243dSDimitry Andric       !S.Context.getTargetInfo().hasFeature("fmv"))
3152bdd1243dSDimitry Andric     return;
3153bdd1243dSDimitry Andric 
31544824e7fdSDimitry Andric   // Ensure we don't combine these with themselves, since that causes some
31554824e7fdSDimitry Andric   // confusing behavior.
31564824e7fdSDimitry Andric   if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
31574824e7fdSDimitry Andric     S.Diag(AL.getLoc(), diag::err_disallowed_duplicate_attribute) << AL;
31584824e7fdSDimitry Andric     S.Diag(Other->getLocation(), diag::note_conflicting_attribute);
31594824e7fdSDimitry Andric     return;
31604824e7fdSDimitry Andric   }
31614824e7fdSDimitry Andric   if (checkAttrMutualExclusion<TargetClonesAttr>(S, D, AL))
31624824e7fdSDimitry Andric     return;
31634824e7fdSDimitry Andric 
31644824e7fdSDimitry Andric   SmallVector<StringRef, 2> Strings;
3165bdd1243dSDimitry Andric   SmallVector<SmallString<64>, 2> StringsBuffer;
3166bdd1243dSDimitry Andric   bool HasCommas = false, HasDefault = false, HasNotDefault = false;
31674824e7fdSDimitry Andric 
31684824e7fdSDimitry Andric   for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
31694824e7fdSDimitry Andric     StringRef CurStr;
31704824e7fdSDimitry Andric     SourceLocation LiteralLoc;
31714824e7fdSDimitry Andric     if (!S.checkStringLiteralArgumentAttr(AL, I, CurStr, &LiteralLoc) ||
31724824e7fdSDimitry Andric         S.checkTargetClonesAttrString(
31734824e7fdSDimitry Andric             LiteralLoc, CurStr,
31740fca6ea1SDimitry Andric             cast<StringLiteral>(AL.getArgAsExpr(I)->IgnoreParenCasts()), D,
3175bdd1243dSDimitry Andric             HasDefault, HasCommas, HasNotDefault, StringsBuffer))
31764824e7fdSDimitry Andric       return;
31774824e7fdSDimitry Andric   }
3178bdd1243dSDimitry Andric   for (auto &SmallStr : StringsBuffer)
3179bdd1243dSDimitry Andric     Strings.push_back(SmallStr.str());
31804824e7fdSDimitry Andric 
31814824e7fdSDimitry Andric   if (HasCommas && AL.getNumArgs() > 1)
31824824e7fdSDimitry Andric     S.Diag(AL.getLoc(), diag::warn_target_clone_mixed_values);
31834824e7fdSDimitry Andric 
3184bdd1243dSDimitry Andric   if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasDefault) {
3185bdd1243dSDimitry Andric     // Add default attribute if there is no one
3186bdd1243dSDimitry Andric     HasDefault = true;
3187bdd1243dSDimitry Andric     Strings.push_back("default");
3188bdd1243dSDimitry Andric   }
3189bdd1243dSDimitry Andric 
31904824e7fdSDimitry Andric   if (!HasDefault) {
31914824e7fdSDimitry Andric     S.Diag(AL.getLoc(), diag::err_target_clone_must_have_default);
31924824e7fdSDimitry Andric     return;
31934824e7fdSDimitry Andric   }
31944824e7fdSDimitry Andric 
31954824e7fdSDimitry Andric   // FIXME: We could probably figure out how to get this to work for lambdas
31964824e7fdSDimitry Andric   // someday.
31974824e7fdSDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
31984824e7fdSDimitry Andric     if (MD->getParent()->isLambda()) {
31994824e7fdSDimitry Andric       S.Diag(D->getLocation(), diag::err_multiversion_doesnt_support)
32004824e7fdSDimitry Andric           << static_cast<unsigned>(MultiVersionKind::TargetClones)
32014824e7fdSDimitry Andric           << /*Lambda*/ 9;
32024824e7fdSDimitry Andric       return;
32034824e7fdSDimitry Andric     }
32044824e7fdSDimitry Andric   }
32054824e7fdSDimitry Andric 
3206bdd1243dSDimitry Andric   // No multiversion if we have default version only.
3207bdd1243dSDimitry Andric   if (S.Context.getTargetInfo().getTriple().isAArch64() && !HasNotDefault)
3208bdd1243dSDimitry Andric     return;
3209bdd1243dSDimitry Andric 
32104824e7fdSDimitry Andric   cast<FunctionDecl>(D)->setIsMultiVersion();
32114824e7fdSDimitry Andric   TargetClonesAttr *NewAttr = ::new (S.Context)
32124824e7fdSDimitry Andric       TargetClonesAttr(S.Context, AL, Strings.data(), Strings.size());
32134824e7fdSDimitry Andric   D->addAttr(NewAttr);
32144824e7fdSDimitry Andric }
32154824e7fdSDimitry Andric 
32160b57cec5SDimitry Andric static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
32170b57cec5SDimitry Andric   Expr *E = AL.getArgAsExpr(0);
32180b57cec5SDimitry Andric   uint32_t VecWidth;
32190fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, E, VecWidth)) {
32200b57cec5SDimitry Andric     AL.setInvalid();
32210b57cec5SDimitry Andric     return;
32220b57cec5SDimitry Andric   }
32230b57cec5SDimitry Andric 
32240b57cec5SDimitry Andric   MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
32250b57cec5SDimitry Andric   if (Existing && Existing->getVectorWidth() != VecWidth) {
32260b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
32270b57cec5SDimitry Andric     return;
32280b57cec5SDimitry Andric   }
32290b57cec5SDimitry Andric 
3230a7dea167SDimitry Andric   D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
32310b57cec5SDimitry Andric }
32320b57cec5SDimitry Andric 
32330b57cec5SDimitry Andric static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
32340b57cec5SDimitry Andric   Expr *E = AL.getArgAsExpr(0);
32350b57cec5SDimitry Andric   SourceLocation Loc = E->getExprLoc();
32360b57cec5SDimitry Andric   FunctionDecl *FD = nullptr;
32370b57cec5SDimitry Andric   DeclarationNameInfo NI;
32380b57cec5SDimitry Andric 
32390b57cec5SDimitry Andric   // gcc only allows for simple identifiers. Since we support more than gcc, we
32400b57cec5SDimitry Andric   // will warn the user.
32410b57cec5SDimitry Andric   if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
32420b57cec5SDimitry Andric     if (DRE->hasQualifier())
32430b57cec5SDimitry Andric       S.Diag(Loc, diag::warn_cleanup_ext);
32440b57cec5SDimitry Andric     FD = dyn_cast<FunctionDecl>(DRE->getDecl());
32450b57cec5SDimitry Andric     NI = DRE->getNameInfo();
32460b57cec5SDimitry Andric     if (!FD) {
32470b57cec5SDimitry Andric       S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
32480b57cec5SDimitry Andric         << NI.getName();
32490b57cec5SDimitry Andric       return;
32500b57cec5SDimitry Andric     }
32510b57cec5SDimitry Andric   } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
32520b57cec5SDimitry Andric     if (ULE->hasExplicitTemplateArgs())
32530b57cec5SDimitry Andric       S.Diag(Loc, diag::warn_cleanup_ext);
32540b57cec5SDimitry Andric     FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
32550b57cec5SDimitry Andric     NI = ULE->getNameInfo();
32560b57cec5SDimitry Andric     if (!FD) {
32570b57cec5SDimitry Andric       S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
32580b57cec5SDimitry Andric         << NI.getName();
32590b57cec5SDimitry Andric       if (ULE->getType() == S.Context.OverloadTy)
32600b57cec5SDimitry Andric         S.NoteAllOverloadCandidates(ULE);
32610b57cec5SDimitry Andric       return;
32620b57cec5SDimitry Andric     }
32630b57cec5SDimitry Andric   } else {
32640b57cec5SDimitry Andric     S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
32650b57cec5SDimitry Andric     return;
32660b57cec5SDimitry Andric   }
32670b57cec5SDimitry Andric 
32680b57cec5SDimitry Andric   if (FD->getNumParams() != 1) {
32690b57cec5SDimitry Andric     S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
32700b57cec5SDimitry Andric       << NI.getName();
32710b57cec5SDimitry Andric     return;
32720b57cec5SDimitry Andric   }
32730b57cec5SDimitry Andric 
32740b57cec5SDimitry Andric   // We're currently more strict than GCC about what function types we accept.
32750b57cec5SDimitry Andric   // If this ever proves to be a problem it should be easy to fix.
32760b57cec5SDimitry Andric   QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
32770b57cec5SDimitry Andric   QualType ParamTy = FD->getParamDecl(0)->getType();
32780b57cec5SDimitry Andric   if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
32790b57cec5SDimitry Andric                                    ParamTy, Ty) != Sema::Compatible) {
32800b57cec5SDimitry Andric     S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
32810b57cec5SDimitry Andric       << NI.getName() << ParamTy << Ty;
32820b57cec5SDimitry Andric     return;
32830b57cec5SDimitry Andric   }
32840fca6ea1SDimitry Andric   VarDecl *VD = cast<VarDecl>(D);
32850fca6ea1SDimitry Andric   // Create a reference to the variable declaration. This is a fake/dummy
32860fca6ea1SDimitry Andric   // reference.
32870fca6ea1SDimitry Andric   DeclRefExpr *VariableReference = DeclRefExpr::Create(
32880fca6ea1SDimitry Andric       S.Context, NestedNameSpecifierLoc{}, FD->getLocation(), VD, false,
32890fca6ea1SDimitry Andric       DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, VD->getType(),
32900fca6ea1SDimitry Andric       VK_LValue);
32910fca6ea1SDimitry Andric 
32920fca6ea1SDimitry Andric   // Create a unary operator expression that represents taking the address of
32930fca6ea1SDimitry Andric   // the variable. This is a fake/dummy expression.
32940fca6ea1SDimitry Andric   Expr *AddressOfVariable = UnaryOperator::Create(
32950fca6ea1SDimitry Andric       S.Context, VariableReference, UnaryOperatorKind::UO_AddrOf,
32960fca6ea1SDimitry Andric       S.Context.getPointerType(VD->getType()), VK_PRValue, OK_Ordinary, Loc,
32970fca6ea1SDimitry Andric       +false, FPOptionsOverride{});
32980fca6ea1SDimitry Andric 
32990fca6ea1SDimitry Andric   // Create a function call expression. This is a fake/dummy call expression.
33000fca6ea1SDimitry Andric   CallExpr *FunctionCallExpression =
33010fca6ea1SDimitry Andric       CallExpr::Create(S.Context, E, ArrayRef{AddressOfVariable},
33020fca6ea1SDimitry Andric                        S.Context.VoidTy, VK_PRValue, Loc, FPOptionsOverride{});
33030fca6ea1SDimitry Andric 
33040fca6ea1SDimitry Andric   if (S.CheckFunctionCall(FD, FunctionCallExpression,
33050fca6ea1SDimitry Andric                           FD->getType()->getAs<FunctionProtoType>())) {
33060fca6ea1SDimitry Andric     return;
33070fca6ea1SDimitry Andric   }
33080b57cec5SDimitry Andric 
3309a7dea167SDimitry Andric   D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
33100b57cec5SDimitry Andric }
33110b57cec5SDimitry Andric 
33120b57cec5SDimitry Andric static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
33130b57cec5SDimitry Andric                                         const ParsedAttr &AL) {
33140b57cec5SDimitry Andric   if (!AL.isArgIdent(0)) {
33150b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
33160b57cec5SDimitry Andric         << AL << 0 << AANT_ArgumentIdentifier;
33170b57cec5SDimitry Andric     return;
33180b57cec5SDimitry Andric   }
33190b57cec5SDimitry Andric 
33200b57cec5SDimitry Andric   EnumExtensibilityAttr::Kind ExtensibilityKind;
33210b57cec5SDimitry Andric   IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
33220b57cec5SDimitry Andric   if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
33230b57cec5SDimitry Andric                                                ExtensibilityKind)) {
33240b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
33250b57cec5SDimitry Andric     return;
33260b57cec5SDimitry Andric   }
33270b57cec5SDimitry Andric 
3328a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
3329a7dea167SDimitry Andric                  EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
33300b57cec5SDimitry Andric }
33310b57cec5SDimitry Andric 
33320b57cec5SDimitry Andric /// Handle __attribute__((format_arg((idx)))) attribute based on
33330b57cec5SDimitry Andric /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
33340b57cec5SDimitry Andric static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
333506c3fb27SDimitry Andric   const Expr *IdxExpr = AL.getArgAsExpr(0);
33360b57cec5SDimitry Andric   ParamIdx Idx;
33370fca6ea1SDimitry Andric   if (!S.checkFunctionOrMethodParameterIndex(D, AL, 1, IdxExpr, Idx))
33380b57cec5SDimitry Andric     return;
33390b57cec5SDimitry Andric 
33400b57cec5SDimitry Andric   // Make sure the format string is really a string.
33410b57cec5SDimitry Andric   QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
33420b57cec5SDimitry Andric 
33430fca6ea1SDimitry Andric   bool NotNSStringTy = !S.ObjC().isNSStringType(Ty);
33440fca6ea1SDimitry Andric   if (NotNSStringTy && !S.ObjC().isCFStringType(Ty) &&
33450b57cec5SDimitry Andric       (!Ty->isPointerType() ||
3346a7dea167SDimitry Andric        !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
33470b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_format_attribute_not)
334881ad6265SDimitry Andric         << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
33490b57cec5SDimitry Andric     return;
33500b57cec5SDimitry Andric   }
33510b57cec5SDimitry Andric   Ty = getFunctionOrMethodResultType(D);
3352349cc55cSDimitry Andric   // replace instancetype with the class type
3353349cc55cSDimitry Andric   auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();
3354349cc55cSDimitry Andric   if (Ty->getAs<TypedefType>() == Instancetype)
3355349cc55cSDimitry Andric     if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3356349cc55cSDimitry Andric       if (auto *Interface = OMD->getClassInterface())
3357349cc55cSDimitry Andric         Ty = S.Context.getObjCObjectPointerType(
3358349cc55cSDimitry Andric             QualType(Interface->getTypeForDecl(), 0));
33590fca6ea1SDimitry Andric   if (!S.ObjC().isNSStringType(Ty, /*AllowNSAttributedString=*/true) &&
33600fca6ea1SDimitry Andric       !S.ObjC().isCFStringType(Ty) &&
33610b57cec5SDimitry Andric       (!Ty->isPointerType() ||
3362a7dea167SDimitry Andric        !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
33630b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
33640b57cec5SDimitry Andric         << (NotNSStringTy ? "string type" : "NSString")
33650b57cec5SDimitry Andric         << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
33660b57cec5SDimitry Andric     return;
33670b57cec5SDimitry Andric   }
33680b57cec5SDimitry Andric 
3369a7dea167SDimitry Andric   D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
33700b57cec5SDimitry Andric }
33710b57cec5SDimitry Andric 
33720b57cec5SDimitry Andric enum FormatAttrKind {
33730b57cec5SDimitry Andric   CFStringFormat,
33740b57cec5SDimitry Andric   NSStringFormat,
33750b57cec5SDimitry Andric   StrftimeFormat,
33760b57cec5SDimitry Andric   SupportedFormat,
33770b57cec5SDimitry Andric   IgnoredFormat,
33780b57cec5SDimitry Andric   InvalidFormat
33790b57cec5SDimitry Andric };
33800b57cec5SDimitry Andric 
33810b57cec5SDimitry Andric /// getFormatAttrKind - Map from format attribute names to supported format
33820b57cec5SDimitry Andric /// types.
33830b57cec5SDimitry Andric static FormatAttrKind getFormatAttrKind(StringRef Format) {
33840b57cec5SDimitry Andric   return llvm::StringSwitch<FormatAttrKind>(Format)
33850b57cec5SDimitry Andric       // Check for formats that get handled specially.
33860b57cec5SDimitry Andric       .Case("NSString", NSStringFormat)
33870b57cec5SDimitry Andric       .Case("CFString", CFStringFormat)
33880b57cec5SDimitry Andric       .Case("strftime", StrftimeFormat)
33890b57cec5SDimitry Andric 
33900b57cec5SDimitry Andric       // Otherwise, check for supported formats.
33910b57cec5SDimitry Andric       .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
33920b57cec5SDimitry Andric       .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
33930b57cec5SDimitry Andric       .Case("kprintf", SupportedFormat)         // OpenBSD.
33940b57cec5SDimitry Andric       .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
33950b57cec5SDimitry Andric       .Case("os_trace", SupportedFormat)
33960b57cec5SDimitry Andric       .Case("os_log", SupportedFormat)
33970b57cec5SDimitry Andric 
33980b57cec5SDimitry Andric       .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
33990b57cec5SDimitry Andric       .Default(InvalidFormat);
34000b57cec5SDimitry Andric }
34010b57cec5SDimitry Andric 
34020b57cec5SDimitry Andric /// Handle __attribute__((init_priority(priority))) attributes based on
34030b57cec5SDimitry Andric /// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
34040b57cec5SDimitry Andric static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
34050b57cec5SDimitry Andric   if (!S.getLangOpts().CPlusPlus) {
34060b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
34070b57cec5SDimitry Andric     return;
34080b57cec5SDimitry Andric   }
34090b57cec5SDimitry Andric 
3410bdd1243dSDimitry Andric   if (S.getLangOpts().HLSL) {
3411bdd1243dSDimitry Andric     S.Diag(AL.getLoc(), diag::err_hlsl_init_priority_unsupported);
3412bdd1243dSDimitry Andric     return;
3413bdd1243dSDimitry Andric   }
3414bdd1243dSDimitry Andric 
34150b57cec5SDimitry Andric   if (S.getCurFunctionOrMethodDecl()) {
34160b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
34170b57cec5SDimitry Andric     AL.setInvalid();
34180b57cec5SDimitry Andric     return;
34190b57cec5SDimitry Andric   }
34200b57cec5SDimitry Andric   QualType T = cast<VarDecl>(D)->getType();
34210b57cec5SDimitry Andric   if (S.Context.getAsArrayType(T))
34220b57cec5SDimitry Andric     T = S.Context.getBaseElementType(T);
34230b57cec5SDimitry Andric   if (!T->getAs<RecordType>()) {
34240b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
34250b57cec5SDimitry Andric     AL.setInvalid();
34260b57cec5SDimitry Andric     return;
34270b57cec5SDimitry Andric   }
34280b57cec5SDimitry Andric 
34290b57cec5SDimitry Andric   Expr *E = AL.getArgAsExpr(0);
34300b57cec5SDimitry Andric   uint32_t prioritynum;
34310fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, E, prioritynum)) {
34320b57cec5SDimitry Andric     AL.setInvalid();
34330b57cec5SDimitry Andric     return;
34340b57cec5SDimitry Andric   }
34350b57cec5SDimitry Andric 
3436eaeb601bSDimitry Andric   // Only perform the priority check if the attribute is outside of a system
3437eaeb601bSDimitry Andric   // header. Values <= 100 are reserved for the implementation, and libc++
3438eaeb601bSDimitry Andric   // benefits from being able to specify values in that range.
3439eaeb601bSDimitry Andric   if ((prioritynum < 101 || prioritynum > 65535) &&
3440eaeb601bSDimitry Andric       !S.getSourceManager().isInSystemHeader(AL.getLoc())) {
34410b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
34420b57cec5SDimitry Andric         << E->getSourceRange() << AL << 101 << 65535;
34430b57cec5SDimitry Andric     AL.setInvalid();
34440b57cec5SDimitry Andric     return;
34450b57cec5SDimitry Andric   }
3446a7dea167SDimitry Andric   D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
34470b57cec5SDimitry Andric }
34480b57cec5SDimitry Andric 
3449349cc55cSDimitry Andric ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
3450349cc55cSDimitry Andric                                 StringRef NewUserDiagnostic) {
3451349cc55cSDimitry Andric   if (const auto *EA = D->getAttr<ErrorAttr>()) {
3452349cc55cSDimitry Andric     std::string NewAttr = CI.getNormalizedFullName();
3453349cc55cSDimitry Andric     assert((NewAttr == "error" || NewAttr == "warning") &&
3454349cc55cSDimitry Andric            "unexpected normalized full name");
3455349cc55cSDimitry Andric     bool Match = (EA->isError() && NewAttr == "error") ||
3456349cc55cSDimitry Andric                  (EA->isWarning() && NewAttr == "warning");
3457349cc55cSDimitry Andric     if (!Match) {
3458349cc55cSDimitry Andric       Diag(EA->getLocation(), diag::err_attributes_are_not_compatible)
345906c3fb27SDimitry Andric           << CI << EA
346006c3fb27SDimitry Andric           << (CI.isRegularKeywordAttribute() ||
346106c3fb27SDimitry Andric               EA->isRegularKeywordAttribute());
3462349cc55cSDimitry Andric       Diag(CI.getLoc(), diag::note_conflicting_attribute);
3463349cc55cSDimitry Andric       return nullptr;
3464349cc55cSDimitry Andric     }
3465349cc55cSDimitry Andric     if (EA->getUserDiagnostic() != NewUserDiagnostic) {
3466349cc55cSDimitry Andric       Diag(CI.getLoc(), diag::warn_duplicate_attribute) << EA;
3467349cc55cSDimitry Andric       Diag(EA->getLoc(), diag::note_previous_attribute);
3468349cc55cSDimitry Andric     }
3469349cc55cSDimitry Andric     D->dropAttr<ErrorAttr>();
3470349cc55cSDimitry Andric   }
3471349cc55cSDimitry Andric   return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
3472349cc55cSDimitry Andric }
3473349cc55cSDimitry Andric 
3474a7dea167SDimitry Andric FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
34750b57cec5SDimitry Andric                                   IdentifierInfo *Format, int FormatIdx,
3476a7dea167SDimitry Andric                                   int FirstArg) {
34770b57cec5SDimitry Andric   // Check whether we already have an equivalent format attribute.
34780b57cec5SDimitry Andric   for (auto *F : D->specific_attrs<FormatAttr>()) {
34790b57cec5SDimitry Andric     if (F->getType() == Format &&
34800b57cec5SDimitry Andric         F->getFormatIdx() == FormatIdx &&
34810b57cec5SDimitry Andric         F->getFirstArg() == FirstArg) {
34820b57cec5SDimitry Andric       // If we don't have a valid location for this attribute, adopt the
34830b57cec5SDimitry Andric       // location.
34840b57cec5SDimitry Andric       if (F->getLocation().isInvalid())
3485a7dea167SDimitry Andric         F->setRange(CI.getRange());
34860b57cec5SDimitry Andric       return nullptr;
34870b57cec5SDimitry Andric     }
34880b57cec5SDimitry Andric   }
34890b57cec5SDimitry Andric 
3490a7dea167SDimitry Andric   return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
34910b57cec5SDimitry Andric }
34920b57cec5SDimitry Andric 
34930b57cec5SDimitry Andric /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
34940b57cec5SDimitry Andric /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
34950b57cec5SDimitry Andric static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
34960b57cec5SDimitry Andric   if (!AL.isArgIdent(0)) {
34970b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
34980b57cec5SDimitry Andric         << AL << 1 << AANT_ArgumentIdentifier;
34990b57cec5SDimitry Andric     return;
35000b57cec5SDimitry Andric   }
35010b57cec5SDimitry Andric 
35020b57cec5SDimitry Andric   // In C++ the implicit 'this' function parameter also counts, and they are
35030b57cec5SDimitry Andric   // counted from one.
35040b57cec5SDimitry Andric   bool HasImplicitThisParam = isInstanceMethod(D);
35050b57cec5SDimitry Andric   unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
35060b57cec5SDimitry Andric 
35070b57cec5SDimitry Andric   IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
35080b57cec5SDimitry Andric   StringRef Format = II->getName();
35090b57cec5SDimitry Andric 
35100b57cec5SDimitry Andric   if (normalizeName(Format)) {
35110b57cec5SDimitry Andric     // If we've modified the string name, we need a new identifier for it.
35120b57cec5SDimitry Andric     II = &S.Context.Idents.get(Format);
35130b57cec5SDimitry Andric   }
35140b57cec5SDimitry Andric 
35150b57cec5SDimitry Andric   // Check for supported formats.
35160b57cec5SDimitry Andric   FormatAttrKind Kind = getFormatAttrKind(Format);
35170b57cec5SDimitry Andric 
35180b57cec5SDimitry Andric   if (Kind == IgnoredFormat)
35190b57cec5SDimitry Andric     return;
35200b57cec5SDimitry Andric 
35210b57cec5SDimitry Andric   if (Kind == InvalidFormat) {
35220b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
35230b57cec5SDimitry Andric         << AL << II->getName();
35240b57cec5SDimitry Andric     return;
35250b57cec5SDimitry Andric   }
35260b57cec5SDimitry Andric 
35270b57cec5SDimitry Andric   // checks for the 2nd argument
35280b57cec5SDimitry Andric   Expr *IdxExpr = AL.getArgAsExpr(1);
35290b57cec5SDimitry Andric   uint32_t Idx;
35300fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, IdxExpr, Idx, 2))
35310b57cec5SDimitry Andric     return;
35320b57cec5SDimitry Andric 
35330b57cec5SDimitry Andric   if (Idx < 1 || Idx > NumArgs) {
35340b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
35350b57cec5SDimitry Andric         << AL << 2 << IdxExpr->getSourceRange();
35360b57cec5SDimitry Andric     return;
35370b57cec5SDimitry Andric   }
35380b57cec5SDimitry Andric 
35390b57cec5SDimitry Andric   // FIXME: Do we need to bounds check?
35400b57cec5SDimitry Andric   unsigned ArgIdx = Idx - 1;
35410b57cec5SDimitry Andric 
35420b57cec5SDimitry Andric   if (HasImplicitThisParam) {
35430b57cec5SDimitry Andric     if (ArgIdx == 0) {
35440b57cec5SDimitry Andric       S.Diag(AL.getLoc(),
35450b57cec5SDimitry Andric              diag::err_format_attribute_implicit_this_format_string)
35460b57cec5SDimitry Andric         << IdxExpr->getSourceRange();
35470b57cec5SDimitry Andric       return;
35480b57cec5SDimitry Andric     }
35490b57cec5SDimitry Andric     ArgIdx--;
35500b57cec5SDimitry Andric   }
35510b57cec5SDimitry Andric 
35520b57cec5SDimitry Andric   // make sure the format string is really a string
35530b57cec5SDimitry Andric   QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
35540b57cec5SDimitry Andric 
35550fca6ea1SDimitry Andric   if (!S.ObjC().isNSStringType(Ty, true) && !S.ObjC().isCFStringType(Ty) &&
355681ad6265SDimitry Andric       (!Ty->isPointerType() ||
355781ad6265SDimitry Andric        !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
35580b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_format_attribute_not)
355981ad6265SDimitry Andric       << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, ArgIdx);
35600b57cec5SDimitry Andric     return;
35610b57cec5SDimitry Andric   }
35620b57cec5SDimitry Andric 
35630b57cec5SDimitry Andric   // check the 3rd argument
35640b57cec5SDimitry Andric   Expr *FirstArgExpr = AL.getArgAsExpr(2);
35650b57cec5SDimitry Andric   uint32_t FirstArg;
35660fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, FirstArgExpr, FirstArg, 3))
35670b57cec5SDimitry Andric     return;
35680b57cec5SDimitry Andric 
3569bdd1243dSDimitry Andric   // FirstArg == 0 is is always valid.
35700b57cec5SDimitry Andric   if (FirstArg != 0) {
35710b57cec5SDimitry Andric     if (Kind == StrftimeFormat) {
3572bdd1243dSDimitry Andric       // If the kind is strftime, FirstArg must be 0 because strftime does not
3573bdd1243dSDimitry Andric       // use any variadic arguments.
35740b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
3575bdd1243dSDimitry Andric           << FirstArgExpr->getSourceRange()
3576bdd1243dSDimitry Andric           << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(), "0");
3577bdd1243dSDimitry Andric       return;
3578bdd1243dSDimitry Andric     } else if (isFunctionOrMethodVariadic(D)) {
3579bdd1243dSDimitry Andric       // Else, if the function is variadic, then FirstArg must be 0 or the
3580bdd1243dSDimitry Andric       // "position" of the ... parameter. It's unusual to use 0 with variadic
3581bdd1243dSDimitry Andric       // functions, so the fixit proposes the latter.
3582bdd1243dSDimitry Andric       if (FirstArg != NumArgs + 1) {
3583bdd1243dSDimitry Andric         S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3584bdd1243dSDimitry Andric             << AL << 3 << FirstArgExpr->getSourceRange()
3585bdd1243dSDimitry Andric             << FixItHint::CreateReplacement(FirstArgExpr->getSourceRange(),
3586bdd1243dSDimitry Andric                                             std::to_string(NumArgs + 1));
35870b57cec5SDimitry Andric         return;
35880b57cec5SDimitry Andric       }
3589bdd1243dSDimitry Andric     } else {
3590bdd1243dSDimitry Andric       // Inescapable GCC compatibility diagnostic.
3591bdd1243dSDimitry Andric       S.Diag(D->getLocation(), diag::warn_gcc_requires_variadic_function) << AL;
3592bdd1243dSDimitry Andric       if (FirstArg <= Idx) {
3593bdd1243dSDimitry Andric         // Else, the function is not variadic, and FirstArg must be 0 or any
3594bdd1243dSDimitry Andric         // parameter after the format parameter. We don't offer a fixit because
3595bdd1243dSDimitry Andric         // there are too many possible good values.
35960b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
35970b57cec5SDimitry Andric             << AL << 3 << FirstArgExpr->getSourceRange();
35980b57cec5SDimitry Andric         return;
35990b57cec5SDimitry Andric       }
3600bdd1243dSDimitry Andric     }
3601bdd1243dSDimitry Andric   }
36020b57cec5SDimitry Andric 
3603a7dea167SDimitry Andric   FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);
36040b57cec5SDimitry Andric   if (NewAttr)
36050b57cec5SDimitry Andric     D->addAttr(NewAttr);
36060b57cec5SDimitry Andric }
36070b57cec5SDimitry Andric 
36080b57cec5SDimitry Andric /// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
36090b57cec5SDimitry Andric static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
36100b57cec5SDimitry Andric   // The index that identifies the callback callee is mandatory.
36110b57cec5SDimitry Andric   if (AL.getNumArgs() == 0) {
36120b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
36130b57cec5SDimitry Andric         << AL.getRange();
36140b57cec5SDimitry Andric     return;
36150b57cec5SDimitry Andric   }
36160b57cec5SDimitry Andric 
36170b57cec5SDimitry Andric   bool HasImplicitThisParam = isInstanceMethod(D);
36180b57cec5SDimitry Andric   int32_t NumArgs = getFunctionOrMethodNumParams(D);
36190b57cec5SDimitry Andric 
36200b57cec5SDimitry Andric   FunctionDecl *FD = D->getAsFunction();
36210b57cec5SDimitry Andric   assert(FD && "Expected a function declaration!");
36220b57cec5SDimitry Andric 
36230b57cec5SDimitry Andric   llvm::StringMap<int> NameIdxMapping;
36240b57cec5SDimitry Andric   NameIdxMapping["__"] = -1;
36250b57cec5SDimitry Andric 
36260b57cec5SDimitry Andric   NameIdxMapping["this"] = 0;
36270b57cec5SDimitry Andric 
36280b57cec5SDimitry Andric   int Idx = 1;
36290b57cec5SDimitry Andric   for (const ParmVarDecl *PVD : FD->parameters())
36300b57cec5SDimitry Andric     NameIdxMapping[PVD->getName()] = Idx++;
36310b57cec5SDimitry Andric 
36320b57cec5SDimitry Andric   auto UnknownName = NameIdxMapping.end();
36330b57cec5SDimitry Andric 
36340b57cec5SDimitry Andric   SmallVector<int, 8> EncodingIndices;
36350b57cec5SDimitry Andric   for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
36360b57cec5SDimitry Andric     SourceRange SR;
36370b57cec5SDimitry Andric     int32_t ArgIdx;
36380b57cec5SDimitry Andric 
36390b57cec5SDimitry Andric     if (AL.isArgIdent(I)) {
36400b57cec5SDimitry Andric       IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
36410b57cec5SDimitry Andric       auto It = NameIdxMapping.find(IdLoc->Ident->getName());
36420b57cec5SDimitry Andric       if (It == UnknownName) {
36430b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
36440b57cec5SDimitry Andric             << IdLoc->Ident << IdLoc->Loc;
36450b57cec5SDimitry Andric         return;
36460b57cec5SDimitry Andric       }
36470b57cec5SDimitry Andric 
36480b57cec5SDimitry Andric       SR = SourceRange(IdLoc->Loc);
36490b57cec5SDimitry Andric       ArgIdx = It->second;
36500b57cec5SDimitry Andric     } else if (AL.isArgExpr(I)) {
36510b57cec5SDimitry Andric       Expr *IdxExpr = AL.getArgAsExpr(I);
36520b57cec5SDimitry Andric 
36530b57cec5SDimitry Andric       // If the expression is not parseable as an int32_t we have a problem.
36540fca6ea1SDimitry Andric       if (!S.checkUInt32Argument(AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
36550b57cec5SDimitry Andric                                  false)) {
36560b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
36570b57cec5SDimitry Andric             << AL << (I + 1) << IdxExpr->getSourceRange();
36580b57cec5SDimitry Andric         return;
36590b57cec5SDimitry Andric       }
36600b57cec5SDimitry Andric 
36610b57cec5SDimitry Andric       // Check oob, excluding the special values, 0 and -1.
36620b57cec5SDimitry Andric       if (ArgIdx < -1 || ArgIdx > NumArgs) {
36630b57cec5SDimitry Andric         S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
36640b57cec5SDimitry Andric             << AL << (I + 1) << IdxExpr->getSourceRange();
36650b57cec5SDimitry Andric         return;
36660b57cec5SDimitry Andric       }
36670b57cec5SDimitry Andric 
36680b57cec5SDimitry Andric       SR = IdxExpr->getSourceRange();
36690b57cec5SDimitry Andric     } else {
36700b57cec5SDimitry Andric       llvm_unreachable("Unexpected ParsedAttr argument type!");
36710b57cec5SDimitry Andric     }
36720b57cec5SDimitry Andric 
36730b57cec5SDimitry Andric     if (ArgIdx == 0 && !HasImplicitThisParam) {
36740b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
36750b57cec5SDimitry Andric           << (I + 1) << SR;
36760b57cec5SDimitry Andric       return;
36770b57cec5SDimitry Andric     }
36780b57cec5SDimitry Andric 
36790b57cec5SDimitry Andric     // Adjust for the case we do not have an implicit "this" parameter. In this
36800b57cec5SDimitry Andric     // case we decrease all positive values by 1 to get LLVM argument indices.
36810b57cec5SDimitry Andric     if (!HasImplicitThisParam && ArgIdx > 0)
36820b57cec5SDimitry Andric       ArgIdx -= 1;
36830b57cec5SDimitry Andric 
36840b57cec5SDimitry Andric     EncodingIndices.push_back(ArgIdx);
36850b57cec5SDimitry Andric   }
36860b57cec5SDimitry Andric 
36870b57cec5SDimitry Andric   int CalleeIdx = EncodingIndices.front();
36880b57cec5SDimitry Andric   // Check if the callee index is proper, thus not "this" and not "unknown".
36890b57cec5SDimitry Andric   // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
36900b57cec5SDimitry Andric   // is false and positive if "HasImplicitThisParam" is true.
36910b57cec5SDimitry Andric   if (CalleeIdx < (int)HasImplicitThisParam) {
36920b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
36930b57cec5SDimitry Andric         << AL.getRange();
36940b57cec5SDimitry Andric     return;
36950b57cec5SDimitry Andric   }
36960b57cec5SDimitry Andric 
36970b57cec5SDimitry Andric   // Get the callee type, note the index adjustment as the AST doesn't contain
36980b57cec5SDimitry Andric   // the this type (which the callee cannot reference anyway!).
36990b57cec5SDimitry Andric   const Type *CalleeType =
37000b57cec5SDimitry Andric       getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
37010b57cec5SDimitry Andric           .getTypePtr();
37020b57cec5SDimitry Andric   if (!CalleeType || !CalleeType->isFunctionPointerType()) {
37030b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
37040b57cec5SDimitry Andric         << AL.getRange();
37050b57cec5SDimitry Andric     return;
37060b57cec5SDimitry Andric   }
37070b57cec5SDimitry Andric 
37080b57cec5SDimitry Andric   const Type *CalleeFnType =
37090b57cec5SDimitry Andric       CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
37100b57cec5SDimitry Andric 
37110b57cec5SDimitry Andric   // TODO: Check the type of the callee arguments.
37120b57cec5SDimitry Andric 
37130b57cec5SDimitry Andric   const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
37140b57cec5SDimitry Andric   if (!CalleeFnProtoType) {
37150b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
37160b57cec5SDimitry Andric         << AL.getRange();
37170b57cec5SDimitry Andric     return;
37180b57cec5SDimitry Andric   }
37190b57cec5SDimitry Andric 
37200b57cec5SDimitry Andric   if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
37210b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
37220b57cec5SDimitry Andric         << AL << (unsigned)(EncodingIndices.size() - 1);
37230b57cec5SDimitry Andric     return;
37240b57cec5SDimitry Andric   }
37250b57cec5SDimitry Andric 
37260b57cec5SDimitry Andric   if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
37270b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
37280b57cec5SDimitry Andric         << AL << (unsigned)(EncodingIndices.size() - 1);
37290b57cec5SDimitry Andric     return;
37300b57cec5SDimitry Andric   }
37310b57cec5SDimitry Andric 
37320b57cec5SDimitry Andric   if (CalleeFnProtoType->isVariadic()) {
37330b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
37340b57cec5SDimitry Andric     return;
37350b57cec5SDimitry Andric   }
37360b57cec5SDimitry Andric 
37370b57cec5SDimitry Andric   // Do not allow multiple callback attributes.
37380b57cec5SDimitry Andric   if (D->hasAttr<CallbackAttr>()) {
37390b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
37400b57cec5SDimitry Andric     return;
37410b57cec5SDimitry Andric   }
37420b57cec5SDimitry Andric 
37430b57cec5SDimitry Andric   D->addAttr(::new (S.Context) CallbackAttr(
3744a7dea167SDimitry Andric       S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
37450b57cec5SDimitry Andric }
37460b57cec5SDimitry Andric 
3747e8d8bef9SDimitry Andric static bool isFunctionLike(const Type &T) {
3748e8d8bef9SDimitry Andric   // Check for explicit function types.
3749e8d8bef9SDimitry Andric   // 'called_once' is only supported in Objective-C and it has
3750e8d8bef9SDimitry Andric   // function pointers and block pointers.
3751e8d8bef9SDimitry Andric   return T.isFunctionPointerType() || T.isBlockPointerType();
3752e8d8bef9SDimitry Andric }
3753e8d8bef9SDimitry Andric 
3754e8d8bef9SDimitry Andric /// Handle 'called_once' attribute.
3755e8d8bef9SDimitry Andric static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3756e8d8bef9SDimitry Andric   // 'called_once' only applies to parameters representing functions.
3757e8d8bef9SDimitry Andric   QualType T = cast<ParmVarDecl>(D)->getType();
3758e8d8bef9SDimitry Andric 
3759e8d8bef9SDimitry Andric   if (!isFunctionLike(*T)) {
3760e8d8bef9SDimitry Andric     S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
3761e8d8bef9SDimitry Andric     return;
3762e8d8bef9SDimitry Andric   }
3763e8d8bef9SDimitry Andric 
3764e8d8bef9SDimitry Andric   D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
3765e8d8bef9SDimitry Andric }
3766e8d8bef9SDimitry Andric 
37670b57cec5SDimitry Andric static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
37680b57cec5SDimitry Andric   // Try to find the underlying union declaration.
37690b57cec5SDimitry Andric   RecordDecl *RD = nullptr;
37700b57cec5SDimitry Andric   const auto *TD = dyn_cast<TypedefNameDecl>(D);
37710b57cec5SDimitry Andric   if (TD && TD->getUnderlyingType()->isUnionType())
37720b57cec5SDimitry Andric     RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
37730b57cec5SDimitry Andric   else
37740b57cec5SDimitry Andric     RD = dyn_cast<RecordDecl>(D);
37750b57cec5SDimitry Andric 
37760b57cec5SDimitry Andric   if (!RD || !RD->isUnion()) {
377706c3fb27SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
377806c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << ExpectedUnion;
37790b57cec5SDimitry Andric     return;
37800b57cec5SDimitry Andric   }
37810b57cec5SDimitry Andric 
37820b57cec5SDimitry Andric   if (!RD->isCompleteDefinition()) {
37830b57cec5SDimitry Andric     if (!RD->isBeingDefined())
37840b57cec5SDimitry Andric       S.Diag(AL.getLoc(),
37850b57cec5SDimitry Andric              diag::warn_transparent_union_attribute_not_definition);
37860b57cec5SDimitry Andric     return;
37870b57cec5SDimitry Andric   }
37880b57cec5SDimitry Andric 
37890b57cec5SDimitry Andric   RecordDecl::field_iterator Field = RD->field_begin(),
37900b57cec5SDimitry Andric                           FieldEnd = RD->field_end();
37910b57cec5SDimitry Andric   if (Field == FieldEnd) {
37920b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
37930b57cec5SDimitry Andric     return;
37940b57cec5SDimitry Andric   }
37950b57cec5SDimitry Andric 
37960b57cec5SDimitry Andric   FieldDecl *FirstField = *Field;
37970b57cec5SDimitry Andric   QualType FirstType = FirstField->getType();
37980b57cec5SDimitry Andric   if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
37990b57cec5SDimitry Andric     S.Diag(FirstField->getLocation(),
38000b57cec5SDimitry Andric            diag::warn_transparent_union_attribute_floating)
38010b57cec5SDimitry Andric       << FirstType->isVectorType() << FirstType;
38020b57cec5SDimitry Andric     return;
38030b57cec5SDimitry Andric   }
38040b57cec5SDimitry Andric 
38050b57cec5SDimitry Andric   if (FirstType->isIncompleteType())
38060b57cec5SDimitry Andric     return;
38070b57cec5SDimitry Andric   uint64_t FirstSize = S.Context.getTypeSize(FirstType);
38080b57cec5SDimitry Andric   uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
38090b57cec5SDimitry Andric   for (; Field != FieldEnd; ++Field) {
38100b57cec5SDimitry Andric     QualType FieldType = Field->getType();
38110b57cec5SDimitry Andric     if (FieldType->isIncompleteType())
38120b57cec5SDimitry Andric       return;
38130b57cec5SDimitry Andric     // FIXME: this isn't fully correct; we also need to test whether the
38140b57cec5SDimitry Andric     // members of the union would all have the same calling convention as the
38150b57cec5SDimitry Andric     // first member of the union. Checking just the size and alignment isn't
38160b57cec5SDimitry Andric     // sufficient (consider structs passed on the stack instead of in registers
38170b57cec5SDimitry Andric     // as an example).
38180b57cec5SDimitry Andric     if (S.Context.getTypeSize(FieldType) != FirstSize ||
38190b57cec5SDimitry Andric         S.Context.getTypeAlign(FieldType) > FirstAlign) {
38200b57cec5SDimitry Andric       // Warn if we drop the attribute.
38210b57cec5SDimitry Andric       bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
38220b57cec5SDimitry Andric       unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType)
38230b57cec5SDimitry Andric                                   : S.Context.getTypeAlign(FieldType);
38240b57cec5SDimitry Andric       S.Diag(Field->getLocation(),
38250b57cec5SDimitry Andric              diag::warn_transparent_union_attribute_field_size_align)
3826e8d8bef9SDimitry Andric           << isSize << *Field << FieldBits;
38270b57cec5SDimitry Andric       unsigned FirstBits = isSize ? FirstSize : FirstAlign;
38280b57cec5SDimitry Andric       S.Diag(FirstField->getLocation(),
38290b57cec5SDimitry Andric              diag::note_transparent_union_first_field_size_align)
38300b57cec5SDimitry Andric           << isSize << FirstBits;
38310b57cec5SDimitry Andric       return;
38320b57cec5SDimitry Andric     }
38330b57cec5SDimitry Andric   }
38340b57cec5SDimitry Andric 
3835a7dea167SDimitry Andric   RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
38360b57cec5SDimitry Andric }
38370b57cec5SDimitry Andric 
3838e8d8bef9SDimitry Andric void Sema::AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,
3839e8d8bef9SDimitry Andric                              StringRef Str, MutableArrayRef<Expr *> Args) {
3840e8d8bef9SDimitry Andric   auto *Attr = AnnotateAttr::Create(Context, Str, Args.data(), Args.size(), CI);
384181ad6265SDimitry Andric   if (ConstantFoldAttrArgs(
384281ad6265SDimitry Andric           CI, MutableArrayRef<Expr *>(Attr->args_begin(), Attr->args_end()))) {
3843e8d8bef9SDimitry Andric     D->addAttr(Attr);
3844e8d8bef9SDimitry Andric   }
384581ad6265SDimitry Andric }
3846e8d8bef9SDimitry Andric 
38470b57cec5SDimitry Andric static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3848e8d8bef9SDimitry Andric   // Make sure that there is a string literal as the annotation's first
38490b57cec5SDimitry Andric   // argument.
38500b57cec5SDimitry Andric   StringRef Str;
38510b57cec5SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
38520b57cec5SDimitry Andric     return;
38530b57cec5SDimitry Andric 
3854e8d8bef9SDimitry Andric   llvm::SmallVector<Expr *, 4> Args;
3855e8d8bef9SDimitry Andric   Args.reserve(AL.getNumArgs() - 1);
3856e8d8bef9SDimitry Andric   for (unsigned Idx = 1; Idx < AL.getNumArgs(); Idx++) {
3857e8d8bef9SDimitry Andric     assert(!AL.isArgIdent(Idx));
3858e8d8bef9SDimitry Andric     Args.push_back(AL.getArgAsExpr(Idx));
38590b57cec5SDimitry Andric   }
38600b57cec5SDimitry Andric 
3861e8d8bef9SDimitry Andric   S.AddAnnotationAttr(D, AL, Str, Args);
38620b57cec5SDimitry Andric }
38630b57cec5SDimitry Andric 
38640b57cec5SDimitry Andric static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3865a7dea167SDimitry Andric   S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
38660b57cec5SDimitry Andric }
38670b57cec5SDimitry Andric 
3868a7dea167SDimitry Andric void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
3869a7dea167SDimitry Andric   AlignValueAttr TmpAttr(Context, CI, E);
3870a7dea167SDimitry Andric   SourceLocation AttrLoc = CI.getLoc();
38710b57cec5SDimitry Andric 
38720b57cec5SDimitry Andric   QualType T;
38730b57cec5SDimitry Andric   if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
38740b57cec5SDimitry Andric     T = TD->getUnderlyingType();
38750b57cec5SDimitry Andric   else if (const auto *VD = dyn_cast<ValueDecl>(D))
38760b57cec5SDimitry Andric     T = VD->getType();
38770b57cec5SDimitry Andric   else
38780b57cec5SDimitry Andric     llvm_unreachable("Unknown decl type for align_value");
38790b57cec5SDimitry Andric 
38800b57cec5SDimitry Andric   if (!T->isDependentType() && !T->isAnyPointerType() &&
38810b57cec5SDimitry Andric       !T->isReferenceType() && !T->isMemberPointerType()) {
38820b57cec5SDimitry Andric     Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
38835ffd83dbSDimitry Andric       << &TmpAttr << T << D->getSourceRange();
38840b57cec5SDimitry Andric     return;
38850b57cec5SDimitry Andric   }
38860b57cec5SDimitry Andric 
38870b57cec5SDimitry Andric   if (!E->isValueDependent()) {
38880b57cec5SDimitry Andric     llvm::APSInt Alignment;
3889e8d8bef9SDimitry Andric     ExprResult ICE = VerifyIntegerConstantExpression(
3890e8d8bef9SDimitry Andric         E, &Alignment, diag::err_align_value_attribute_argument_not_int);
38910b57cec5SDimitry Andric     if (ICE.isInvalid())
38920b57cec5SDimitry Andric       return;
38930b57cec5SDimitry Andric 
38940b57cec5SDimitry Andric     if (!Alignment.isPowerOf2()) {
38950b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_alignment_not_power_of_two)
38960b57cec5SDimitry Andric         << E->getSourceRange();
38970b57cec5SDimitry Andric       return;
38980b57cec5SDimitry Andric     }
38990b57cec5SDimitry Andric 
3900a7dea167SDimitry Andric     D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
39010b57cec5SDimitry Andric     return;
39020b57cec5SDimitry Andric   }
39030b57cec5SDimitry Andric 
39040b57cec5SDimitry Andric   // Save dependent expressions in the AST to be instantiated.
3905a7dea167SDimitry Andric   D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
39060b57cec5SDimitry Andric }
39070b57cec5SDimitry Andric 
39080b57cec5SDimitry Andric static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
390906c3fb27SDimitry Andric   if (AL.hasParsedType()) {
391006c3fb27SDimitry Andric     const ParsedType &TypeArg = AL.getTypeArg();
391106c3fb27SDimitry Andric     TypeSourceInfo *TInfo;
391206c3fb27SDimitry Andric     (void)S.GetTypeFromParser(
391306c3fb27SDimitry Andric         ParsedType::getFromOpaquePtr(TypeArg.getAsOpaquePtr()), &TInfo);
391406c3fb27SDimitry Andric     if (AL.isPackExpansion() &&
391506c3fb27SDimitry Andric         !TInfo->getType()->containsUnexpandedParameterPack()) {
391606c3fb27SDimitry Andric       S.Diag(AL.getEllipsisLoc(),
391706c3fb27SDimitry Andric              diag::err_pack_expansion_without_parameter_packs);
391806c3fb27SDimitry Andric       return;
391906c3fb27SDimitry Andric     }
392006c3fb27SDimitry Andric 
392106c3fb27SDimitry Andric     if (!AL.isPackExpansion() &&
392206c3fb27SDimitry Andric         S.DiagnoseUnexpandedParameterPack(TInfo->getTypeLoc().getBeginLoc(),
392306c3fb27SDimitry Andric                                           TInfo, Sema::UPPC_Expression))
392406c3fb27SDimitry Andric       return;
392506c3fb27SDimitry Andric 
392606c3fb27SDimitry Andric     S.AddAlignedAttr(D, AL, TInfo, AL.isPackExpansion());
392706c3fb27SDimitry Andric     return;
392806c3fb27SDimitry Andric   }
392906c3fb27SDimitry Andric 
39300b57cec5SDimitry Andric   // check the attribute arguments.
39310b57cec5SDimitry Andric   if (AL.getNumArgs() > 1) {
39320b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
39330b57cec5SDimitry Andric     return;
39340b57cec5SDimitry Andric   }
39350b57cec5SDimitry Andric 
39360b57cec5SDimitry Andric   if (AL.getNumArgs() == 0) {
3937a7dea167SDimitry Andric     D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
39380b57cec5SDimitry Andric     return;
39390b57cec5SDimitry Andric   }
39400b57cec5SDimitry Andric 
39410b57cec5SDimitry Andric   Expr *E = AL.getArgAsExpr(0);
39420b57cec5SDimitry Andric   if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
39430b57cec5SDimitry Andric     S.Diag(AL.getEllipsisLoc(),
39440b57cec5SDimitry Andric            diag::err_pack_expansion_without_parameter_packs);
39450b57cec5SDimitry Andric     return;
39460b57cec5SDimitry Andric   }
39470b57cec5SDimitry Andric 
39480b57cec5SDimitry Andric   if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
39490b57cec5SDimitry Andric     return;
39500b57cec5SDimitry Andric 
3951a7dea167SDimitry Andric   S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
39520b57cec5SDimitry Andric }
39530b57cec5SDimitry Andric 
395406c3fb27SDimitry Andric /// Perform checking of type validity
395506c3fb27SDimitry Andric ///
395606c3fb27SDimitry Andric /// C++11 [dcl.align]p1:
395706c3fb27SDimitry Andric ///   An alignment-specifier may be applied to a variable or to a class
395806c3fb27SDimitry Andric ///   data member, but it shall not be applied to a bit-field, a function
395906c3fb27SDimitry Andric ///   parameter, the formal parameter of a catch clause, or a variable
396006c3fb27SDimitry Andric ///   declared with the register storage class specifier. An
396106c3fb27SDimitry Andric ///   alignment-specifier may also be applied to the declaration of a class
396206c3fb27SDimitry Andric ///   or enumeration type.
396306c3fb27SDimitry Andric /// CWG 2354:
396406c3fb27SDimitry Andric ///   CWG agreed to remove permission for alignas to be applied to
396506c3fb27SDimitry Andric ///   enumerations.
396606c3fb27SDimitry Andric /// C11 6.7.5/2:
396706c3fb27SDimitry Andric ///   An alignment attribute shall not be specified in a declaration of
396806c3fb27SDimitry Andric ///   a typedef, or a bit-field, or a function, or a parameter, or an
396906c3fb27SDimitry Andric ///   object declared with the register storage-class specifier.
397006c3fb27SDimitry Andric static bool validateAlignasAppliedType(Sema &S, Decl *D,
397106c3fb27SDimitry Andric                                        const AlignedAttr &Attr,
397206c3fb27SDimitry Andric                                        SourceLocation AttrLoc) {
39730b57cec5SDimitry Andric   int DiagKind = -1;
39740b57cec5SDimitry Andric   if (isa<ParmVarDecl>(D)) {
39750b57cec5SDimitry Andric     DiagKind = 0;
39760b57cec5SDimitry Andric   } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
39770b57cec5SDimitry Andric     if (VD->getStorageClass() == SC_Register)
39780b57cec5SDimitry Andric       DiagKind = 1;
39790b57cec5SDimitry Andric     if (VD->isExceptionVariable())
39800b57cec5SDimitry Andric       DiagKind = 2;
39810b57cec5SDimitry Andric   } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
39820b57cec5SDimitry Andric     if (FD->isBitField())
39830b57cec5SDimitry Andric       DiagKind = 3;
398481ad6265SDimitry Andric   } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
398581ad6265SDimitry Andric     if (ED->getLangOpts().CPlusPlus)
398681ad6265SDimitry Andric       DiagKind = 4;
39870b57cec5SDimitry Andric   } else if (!isa<TagDecl>(D)) {
398806c3fb27SDimitry Andric     return S.Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
398906c3fb27SDimitry Andric            << &Attr << Attr.isRegularKeywordAttribute()
399006c3fb27SDimitry Andric            << (Attr.isC11() ? ExpectedVariableOrField
39910b57cec5SDimitry Andric                             : ExpectedVariableFieldOrTag);
39920b57cec5SDimitry Andric   }
39930b57cec5SDimitry Andric   if (DiagKind != -1) {
399406c3fb27SDimitry Andric     return S.Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
399506c3fb27SDimitry Andric            << &Attr << DiagKind;
399606c3fb27SDimitry Andric   }
399706c3fb27SDimitry Andric   return false;
399806c3fb27SDimitry Andric }
399906c3fb27SDimitry Andric 
400006c3fb27SDimitry Andric void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
400106c3fb27SDimitry Andric                           bool IsPackExpansion) {
400206c3fb27SDimitry Andric   AlignedAttr TmpAttr(Context, CI, true, E);
400306c3fb27SDimitry Andric   SourceLocation AttrLoc = CI.getLoc();
400406c3fb27SDimitry Andric 
400506c3fb27SDimitry Andric   // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
400606c3fb27SDimitry Andric   if (TmpAttr.isAlignas() &&
400706c3fb27SDimitry Andric       validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
40080b57cec5SDimitry Andric     return;
40090b57cec5SDimitry Andric 
40100b57cec5SDimitry Andric   if (E->isValueDependent()) {
40110b57cec5SDimitry Andric     // We can't support a dependent alignment on a non-dependent type,
40120b57cec5SDimitry Andric     // because we have no way to model that a type is "alignment-dependent"
40130b57cec5SDimitry Andric     // but not dependent in any other way.
40140b57cec5SDimitry Andric     if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
40150b57cec5SDimitry Andric       if (!TND->getUnderlyingType()->isDependentType()) {
40160b57cec5SDimitry Andric         Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
40170b57cec5SDimitry Andric             << E->getSourceRange();
40180b57cec5SDimitry Andric         return;
40190b57cec5SDimitry Andric       }
40200b57cec5SDimitry Andric     }
40210b57cec5SDimitry Andric 
40220b57cec5SDimitry Andric     // Save dependent expressions in the AST to be instantiated.
4023a7dea167SDimitry Andric     AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
40240b57cec5SDimitry Andric     AA->setPackExpansion(IsPackExpansion);
40250b57cec5SDimitry Andric     D->addAttr(AA);
40260b57cec5SDimitry Andric     return;
40270b57cec5SDimitry Andric   }
40280b57cec5SDimitry Andric 
40290b57cec5SDimitry Andric   // FIXME: Cache the number on the AL object?
40300b57cec5SDimitry Andric   llvm::APSInt Alignment;
4031e8d8bef9SDimitry Andric   ExprResult ICE = VerifyIntegerConstantExpression(
4032e8d8bef9SDimitry Andric       E, &Alignment, diag::err_aligned_attribute_argument_not_int);
40330b57cec5SDimitry Andric   if (ICE.isInvalid())
40340b57cec5SDimitry Andric     return;
40350b57cec5SDimitry Andric 
403606c3fb27SDimitry Andric   uint64_t MaximumAlignment = Sema::MaximumAlignment;
403706c3fb27SDimitry Andric   if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
403806c3fb27SDimitry Andric     MaximumAlignment = std::min(MaximumAlignment, uint64_t(8192));
403906c3fb27SDimitry Andric   if (Alignment > MaximumAlignment) {
404006c3fb27SDimitry Andric     Diag(AttrLoc, diag::err_attribute_aligned_too_great)
404106c3fb27SDimitry Andric         << MaximumAlignment << E->getSourceRange();
404206c3fb27SDimitry Andric     return;
404306c3fb27SDimitry Andric   }
404406c3fb27SDimitry Andric 
40450b57cec5SDimitry Andric   uint64_t AlignVal = Alignment.getZExtValue();
40460b57cec5SDimitry Andric   // C++11 [dcl.align]p2:
40470b57cec5SDimitry Andric   //   -- if the constant expression evaluates to zero, the alignment
40480b57cec5SDimitry Andric   //      specifier shall have no effect
40490b57cec5SDimitry Andric   // C11 6.7.5p6:
40500b57cec5SDimitry Andric   //   An alignment specification of zero has no effect.
40510b57cec5SDimitry Andric   if (!(TmpAttr.isAlignas() && !Alignment)) {
40520b57cec5SDimitry Andric     if (!llvm::isPowerOf2_64(AlignVal)) {
40530b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_alignment_not_power_of_two)
40540b57cec5SDimitry Andric         << E->getSourceRange();
40550b57cec5SDimitry Andric       return;
40560b57cec5SDimitry Andric     }
40570b57cec5SDimitry Andric   }
40580b57cec5SDimitry Andric 
4059349cc55cSDimitry Andric   const auto *VD = dyn_cast<VarDecl>(D);
4060bdd1243dSDimitry Andric   if (VD) {
40610b57cec5SDimitry Andric     unsigned MaxTLSAlign =
40620b57cec5SDimitry Andric         Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())
40630b57cec5SDimitry Andric             .getQuantity();
4064349cc55cSDimitry Andric     if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
40650b57cec5SDimitry Andric         VD->getTLSKind() != VarDecl::TLS_None) {
40660b57cec5SDimitry Andric       Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
40670b57cec5SDimitry Andric           << (unsigned)AlignVal << VD << MaxTLSAlign;
40680b57cec5SDimitry Andric       return;
40690b57cec5SDimitry Andric     }
40700b57cec5SDimitry Andric   }
40710b57cec5SDimitry Andric 
4072349cc55cSDimitry Andric   // On AIX, an aligned attribute can not decrease the alignment when applied
4073349cc55cSDimitry Andric   // to a variable declaration with vector type.
4074349cc55cSDimitry Andric   if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4075349cc55cSDimitry Andric     const Type *Ty = VD->getType().getTypePtr();
4076349cc55cSDimitry Andric     if (Ty->isVectorType() && AlignVal < 16) {
4077349cc55cSDimitry Andric       Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
4078349cc55cSDimitry Andric           << VD->getType() << 16;
4079349cc55cSDimitry Andric       return;
4080349cc55cSDimitry Andric     }
4081349cc55cSDimitry Andric   }
4082349cc55cSDimitry Andric 
4083a7dea167SDimitry Andric   AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
40840b57cec5SDimitry Andric   AA->setPackExpansion(IsPackExpansion);
408506c3fb27SDimitry Andric   AA->setCachedAlignmentValue(
408606c3fb27SDimitry Andric       static_cast<unsigned>(AlignVal * Context.getCharWidth()));
40870b57cec5SDimitry Andric   D->addAttr(AA);
40880b57cec5SDimitry Andric }
40890b57cec5SDimitry Andric 
4090a7dea167SDimitry Andric void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
4091a7dea167SDimitry Andric                           TypeSourceInfo *TS, bool IsPackExpansion) {
409206c3fb27SDimitry Andric   AlignedAttr TmpAttr(Context, CI, false, TS);
409306c3fb27SDimitry Andric   SourceLocation AttrLoc = CI.getLoc();
409406c3fb27SDimitry Andric 
409506c3fb27SDimitry Andric   // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
409606c3fb27SDimitry Andric   if (TmpAttr.isAlignas() &&
409706c3fb27SDimitry Andric       validateAlignasAppliedType(*this, D, TmpAttr, AttrLoc))
409806c3fb27SDimitry Andric     return;
409906c3fb27SDimitry Andric 
410006c3fb27SDimitry Andric   if (TS->getType()->isDependentType()) {
410106c3fb27SDimitry Andric     // We can't support a dependent alignment on a non-dependent type,
410206c3fb27SDimitry Andric     // because we have no way to model that a type is "type-dependent"
410306c3fb27SDimitry Andric     // but not dependent in any other way.
410406c3fb27SDimitry Andric     if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
410506c3fb27SDimitry Andric       if (!TND->getUnderlyingType()->isDependentType()) {
410606c3fb27SDimitry Andric         Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
410706c3fb27SDimitry Andric             << TS->getTypeLoc().getSourceRange();
410806c3fb27SDimitry Andric         return;
410906c3fb27SDimitry Andric       }
411006c3fb27SDimitry Andric     }
411106c3fb27SDimitry Andric 
4112a7dea167SDimitry Andric     AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
41130b57cec5SDimitry Andric     AA->setPackExpansion(IsPackExpansion);
41140b57cec5SDimitry Andric     D->addAttr(AA);
411506c3fb27SDimitry Andric     return;
411606c3fb27SDimitry Andric   }
411706c3fb27SDimitry Andric 
411806c3fb27SDimitry Andric   const auto *VD = dyn_cast<VarDecl>(D);
411906c3fb27SDimitry Andric   unsigned AlignVal = TmpAttr.getAlignment(Context);
412006c3fb27SDimitry Andric   // On AIX, an aligned attribute can not decrease the alignment when applied
412106c3fb27SDimitry Andric   // to a variable declaration with vector type.
412206c3fb27SDimitry Andric   if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
412306c3fb27SDimitry Andric     const Type *Ty = VD->getType().getTypePtr();
412406c3fb27SDimitry Andric     if (Ty->isVectorType() &&
412506c3fb27SDimitry Andric         Context.toCharUnitsFromBits(AlignVal).getQuantity() < 16) {
412606c3fb27SDimitry Andric       Diag(VD->getLocation(), diag::warn_aligned_attr_underaligned)
412706c3fb27SDimitry Andric           << VD->getType() << 16;
412806c3fb27SDimitry Andric       return;
412906c3fb27SDimitry Andric     }
413006c3fb27SDimitry Andric   }
413106c3fb27SDimitry Andric 
413206c3fb27SDimitry Andric   AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
413306c3fb27SDimitry Andric   AA->setPackExpansion(IsPackExpansion);
413406c3fb27SDimitry Andric   AA->setCachedAlignmentValue(AlignVal);
413506c3fb27SDimitry Andric   D->addAttr(AA);
41360b57cec5SDimitry Andric }
41370b57cec5SDimitry Andric 
41380b57cec5SDimitry Andric void Sema::CheckAlignasUnderalignment(Decl *D) {
41390b57cec5SDimitry Andric   assert(D->hasAttrs() && "no attributes on decl");
41400b57cec5SDimitry Andric 
41410b57cec5SDimitry Andric   QualType UnderlyingTy, DiagTy;
41420b57cec5SDimitry Andric   if (const auto *VD = dyn_cast<ValueDecl>(D)) {
41430b57cec5SDimitry Andric     UnderlyingTy = DiagTy = VD->getType();
41440b57cec5SDimitry Andric   } else {
41450b57cec5SDimitry Andric     UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));
41460b57cec5SDimitry Andric     if (const auto *ED = dyn_cast<EnumDecl>(D))
41470b57cec5SDimitry Andric       UnderlyingTy = ED->getIntegerType();
41480b57cec5SDimitry Andric   }
41490b57cec5SDimitry Andric   if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
41500b57cec5SDimitry Andric     return;
41510b57cec5SDimitry Andric 
41520b57cec5SDimitry Andric   // C++11 [dcl.align]p5, C11 6.7.5/4:
41530b57cec5SDimitry Andric   //   The combined effect of all alignment attributes in a declaration shall
41540b57cec5SDimitry Andric   //   not specify an alignment that is less strict than the alignment that
41550b57cec5SDimitry Andric   //   would otherwise be required for the entity being declared.
41560b57cec5SDimitry Andric   AlignedAttr *AlignasAttr = nullptr;
41575ffd83dbSDimitry Andric   AlignedAttr *LastAlignedAttr = nullptr;
41580b57cec5SDimitry Andric   unsigned Align = 0;
41590b57cec5SDimitry Andric   for (auto *I : D->specific_attrs<AlignedAttr>()) {
41600b57cec5SDimitry Andric     if (I->isAlignmentDependent())
41610b57cec5SDimitry Andric       return;
41620b57cec5SDimitry Andric     if (I->isAlignas())
41630b57cec5SDimitry Andric       AlignasAttr = I;
41640b57cec5SDimitry Andric     Align = std::max(Align, I->getAlignment(Context));
41655ffd83dbSDimitry Andric     LastAlignedAttr = I;
41660b57cec5SDimitry Andric   }
41670b57cec5SDimitry Andric 
41685ffd83dbSDimitry Andric   if (Align && DiagTy->isSizelessType()) {
41695ffd83dbSDimitry Andric     Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
41705ffd83dbSDimitry Andric         << LastAlignedAttr << DiagTy;
41715ffd83dbSDimitry Andric   } else if (AlignasAttr && Align) {
41720b57cec5SDimitry Andric     CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
41730b57cec5SDimitry Andric     CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
41740b57cec5SDimitry Andric     if (NaturalAlign > RequestedAlign)
41750b57cec5SDimitry Andric       Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
41760b57cec5SDimitry Andric         << DiagTy << (unsigned)NaturalAlign.getQuantity();
41770b57cec5SDimitry Andric   }
41780b57cec5SDimitry Andric }
41790b57cec5SDimitry Andric 
41800b57cec5SDimitry Andric bool Sema::checkMSInheritanceAttrOnDefinition(
41810b57cec5SDimitry Andric     CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4182480093f4SDimitry Andric     MSInheritanceModel ExplicitModel) {
41830b57cec5SDimitry Andric   assert(RD->hasDefinition() && "RD has no definition!");
41840b57cec5SDimitry Andric 
41850b57cec5SDimitry Andric   // We may not have seen base specifiers or any virtual methods yet.  We will
41860b57cec5SDimitry Andric   // have to wait until the record is defined to catch any mismatches.
41870b57cec5SDimitry Andric   if (!RD->getDefinition()->isCompleteDefinition())
41880b57cec5SDimitry Andric     return false;
41890b57cec5SDimitry Andric 
41900b57cec5SDimitry Andric   // The unspecified model never matches what a definition could need.
4191480093f4SDimitry Andric   if (ExplicitModel == MSInheritanceModel::Unspecified)
41920b57cec5SDimitry Andric     return false;
41930b57cec5SDimitry Andric 
41940b57cec5SDimitry Andric   if (BestCase) {
4195480093f4SDimitry Andric     if (RD->calculateInheritanceModel() == ExplicitModel)
41960b57cec5SDimitry Andric       return false;
41970b57cec5SDimitry Andric   } else {
4198480093f4SDimitry Andric     if (RD->calculateInheritanceModel() <= ExplicitModel)
41990b57cec5SDimitry Andric       return false;
42000b57cec5SDimitry Andric   }
42010b57cec5SDimitry Andric 
42020b57cec5SDimitry Andric   Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
42030b57cec5SDimitry Andric       << 0 /*definition*/;
42045ffd83dbSDimitry Andric   Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
42050b57cec5SDimitry Andric   return true;
42060b57cec5SDimitry Andric }
42070b57cec5SDimitry Andric 
42080b57cec5SDimitry Andric /// parseModeAttrArg - Parses attribute mode string and returns parsed type
42090b57cec5SDimitry Andric /// attribute.
42100b57cec5SDimitry Andric static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
42115ffd83dbSDimitry Andric                              bool &IntegerMode, bool &ComplexMode,
4212349cc55cSDimitry Andric                              FloatModeKind &ExplicitType) {
42130b57cec5SDimitry Andric   IntegerMode = true;
42140b57cec5SDimitry Andric   ComplexMode = false;
4215349cc55cSDimitry Andric   ExplicitType = FloatModeKind::NoFloat;
42160b57cec5SDimitry Andric   switch (Str.size()) {
42170b57cec5SDimitry Andric   case 2:
42180b57cec5SDimitry Andric     switch (Str[0]) {
42190b57cec5SDimitry Andric     case 'Q':
42200b57cec5SDimitry Andric       DestWidth = 8;
42210b57cec5SDimitry Andric       break;
42220b57cec5SDimitry Andric     case 'H':
42230b57cec5SDimitry Andric       DestWidth = 16;
42240b57cec5SDimitry Andric       break;
42250b57cec5SDimitry Andric     case 'S':
42260b57cec5SDimitry Andric       DestWidth = 32;
42270b57cec5SDimitry Andric       break;
42280b57cec5SDimitry Andric     case 'D':
42290b57cec5SDimitry Andric       DestWidth = 64;
42300b57cec5SDimitry Andric       break;
42310b57cec5SDimitry Andric     case 'X':
42320b57cec5SDimitry Andric       DestWidth = 96;
42330b57cec5SDimitry Andric       break;
42345ffd83dbSDimitry Andric     case 'K': // KFmode - IEEE quad precision (__float128)
4235349cc55cSDimitry Andric       ExplicitType = FloatModeKind::Float128;
42365ffd83dbSDimitry Andric       DestWidth = Str[1] == 'I' ? 0 : 128;
42375ffd83dbSDimitry Andric       break;
42380b57cec5SDimitry Andric     case 'T':
4239349cc55cSDimitry Andric       ExplicitType = FloatModeKind::LongDouble;
42400b57cec5SDimitry Andric       DestWidth = 128;
42410b57cec5SDimitry Andric       break;
4242349cc55cSDimitry Andric     case 'I':
4243349cc55cSDimitry Andric       ExplicitType = FloatModeKind::Ibm128;
4244349cc55cSDimitry Andric       DestWidth = Str[1] == 'I' ? 0 : 128;
4245349cc55cSDimitry Andric       break;
42460b57cec5SDimitry Andric     }
42470b57cec5SDimitry Andric     if (Str[1] == 'F') {
42480b57cec5SDimitry Andric       IntegerMode = false;
42490b57cec5SDimitry Andric     } else if (Str[1] == 'C') {
42500b57cec5SDimitry Andric       IntegerMode = false;
42510b57cec5SDimitry Andric       ComplexMode = true;
42520b57cec5SDimitry Andric     } else if (Str[1] != 'I') {
42530b57cec5SDimitry Andric       DestWidth = 0;
42540b57cec5SDimitry Andric     }
42550b57cec5SDimitry Andric     break;
42560b57cec5SDimitry Andric   case 4:
42570b57cec5SDimitry Andric     // FIXME: glibc uses 'word' to define register_t; this is narrower than a
42580b57cec5SDimitry Andric     // pointer on PIC16 and other embedded platforms.
42590b57cec5SDimitry Andric     if (Str == "word")
42600b57cec5SDimitry Andric       DestWidth = S.Context.getTargetInfo().getRegisterWidth();
42610b57cec5SDimitry Andric     else if (Str == "byte")
42620b57cec5SDimitry Andric       DestWidth = S.Context.getTargetInfo().getCharWidth();
42630b57cec5SDimitry Andric     break;
42640b57cec5SDimitry Andric   case 7:
42650b57cec5SDimitry Andric     if (Str == "pointer")
4266bdd1243dSDimitry Andric       DestWidth = S.Context.getTargetInfo().getPointerWidth(LangAS::Default);
42670b57cec5SDimitry Andric     break;
42680b57cec5SDimitry Andric   case 11:
42690b57cec5SDimitry Andric     if (Str == "unwind_word")
42700b57cec5SDimitry Andric       DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
42710b57cec5SDimitry Andric     break;
42720b57cec5SDimitry Andric   }
42730b57cec5SDimitry Andric }
42740b57cec5SDimitry Andric 
42750b57cec5SDimitry Andric /// handleModeAttr - This attribute modifies the width of a decl with primitive
42760b57cec5SDimitry Andric /// type.
42770b57cec5SDimitry Andric ///
42780b57cec5SDimitry Andric /// Despite what would be logical, the mode attribute is a decl attribute, not a
42790b57cec5SDimitry Andric /// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
42800b57cec5SDimitry Andric /// HImode, not an intermediate pointer.
42810b57cec5SDimitry Andric static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
42820b57cec5SDimitry Andric   // This attribute isn't documented, but glibc uses it.  It changes
42830b57cec5SDimitry Andric   // the width of an int or unsigned int to the specified size.
42840b57cec5SDimitry Andric   if (!AL.isArgIdent(0)) {
42850b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
42860b57cec5SDimitry Andric         << AL << AANT_ArgumentIdentifier;
42870b57cec5SDimitry Andric     return;
42880b57cec5SDimitry Andric   }
42890b57cec5SDimitry Andric 
42900b57cec5SDimitry Andric   IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident;
42910b57cec5SDimitry Andric 
4292a7dea167SDimitry Andric   S.AddModeAttr(D, AL, Name);
42930b57cec5SDimitry Andric }
42940b57cec5SDimitry Andric 
4295a7dea167SDimitry Andric void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
4296a7dea167SDimitry Andric                        IdentifierInfo *Name, bool InInstantiation) {
42970b57cec5SDimitry Andric   StringRef Str = Name->getName();
42980b57cec5SDimitry Andric   normalizeName(Str);
4299a7dea167SDimitry Andric   SourceLocation AttrLoc = CI.getLoc();
43000b57cec5SDimitry Andric 
43010b57cec5SDimitry Andric   unsigned DestWidth = 0;
43020b57cec5SDimitry Andric   bool IntegerMode = true;
43030b57cec5SDimitry Andric   bool ComplexMode = false;
4304349cc55cSDimitry Andric   FloatModeKind ExplicitType = FloatModeKind::NoFloat;
43050b57cec5SDimitry Andric   llvm::APInt VectorSize(64, 0);
43060b57cec5SDimitry Andric   if (Str.size() >= 4 && Str[0] == 'V') {
43070b57cec5SDimitry Andric     // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
43080b57cec5SDimitry Andric     size_t StrSize = Str.size();
43090b57cec5SDimitry Andric     size_t VectorStringLength = 0;
43100b57cec5SDimitry Andric     while ((VectorStringLength + 1) < StrSize &&
43110b57cec5SDimitry Andric            isdigit(Str[VectorStringLength + 1]))
43120b57cec5SDimitry Andric       ++VectorStringLength;
43130b57cec5SDimitry Andric     if (VectorStringLength &&
43140b57cec5SDimitry Andric         !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
43150b57cec5SDimitry Andric         VectorSize.isPowerOf2()) {
43160b57cec5SDimitry Andric       parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,
4317349cc55cSDimitry Andric                        IntegerMode, ComplexMode, ExplicitType);
43180b57cec5SDimitry Andric       // Avoid duplicate warning from template instantiation.
43190b57cec5SDimitry Andric       if (!InInstantiation)
43200b57cec5SDimitry Andric         Diag(AttrLoc, diag::warn_vector_mode_deprecated);
43210b57cec5SDimitry Andric     } else {
43220b57cec5SDimitry Andric       VectorSize = 0;
43230b57cec5SDimitry Andric     }
43240b57cec5SDimitry Andric   }
43250b57cec5SDimitry Andric 
43260b57cec5SDimitry Andric   if (!VectorSize)
43275ffd83dbSDimitry Andric     parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,
4328349cc55cSDimitry Andric                      ExplicitType);
43290b57cec5SDimitry Andric 
43300b57cec5SDimitry Andric   // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
43310b57cec5SDimitry Andric   // and friends, at least with glibc.
43320b57cec5SDimitry Andric   // FIXME: Make sure floating-point mappings are accurate
43330b57cec5SDimitry Andric   // FIXME: Support XF and TF types
43340b57cec5SDimitry Andric   if (!DestWidth) {
43350b57cec5SDimitry Andric     Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
43360b57cec5SDimitry Andric     return;
43370b57cec5SDimitry Andric   }
43380b57cec5SDimitry Andric 
43390b57cec5SDimitry Andric   QualType OldTy;
43400b57cec5SDimitry Andric   if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
43410b57cec5SDimitry Andric     OldTy = TD->getUnderlyingType();
43420b57cec5SDimitry Andric   else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
43430b57cec5SDimitry Andric     // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
43440b57cec5SDimitry Andric     // Try to get type from enum declaration, default to int.
43450b57cec5SDimitry Andric     OldTy = ED->getIntegerType();
43460b57cec5SDimitry Andric     if (OldTy.isNull())
43470b57cec5SDimitry Andric       OldTy = Context.IntTy;
43480b57cec5SDimitry Andric   } else
43490b57cec5SDimitry Andric     OldTy = cast<ValueDecl>(D)->getType();
43500b57cec5SDimitry Andric 
43510b57cec5SDimitry Andric   if (OldTy->isDependentType()) {
4352a7dea167SDimitry Andric     D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
43530b57cec5SDimitry Andric     return;
43540b57cec5SDimitry Andric   }
43550b57cec5SDimitry Andric 
43560b57cec5SDimitry Andric   // Base type can also be a vector type (see PR17453).
43570b57cec5SDimitry Andric   // Distinguish between base type and base element type.
43580b57cec5SDimitry Andric   QualType OldElemTy = OldTy;
43590b57cec5SDimitry Andric   if (const auto *VT = OldTy->getAs<VectorType>())
43600b57cec5SDimitry Andric     OldElemTy = VT->getElementType();
43610b57cec5SDimitry Andric 
43620b57cec5SDimitry Andric   // GCC allows 'mode' attribute on enumeration types (even incomplete), except
43630b57cec5SDimitry Andric   // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
43640b57cec5SDimitry Andric   // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
43650b57cec5SDimitry Andric   if ((isa<EnumDecl>(D) || OldElemTy->getAs<EnumType>()) &&
43660b57cec5SDimitry Andric       VectorSize.getBoolValue()) {
4367a7dea167SDimitry Andric     Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
43680b57cec5SDimitry Andric     return;
43690b57cec5SDimitry Andric   }
43705ffd83dbSDimitry Andric   bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
43710eae32dcSDimitry Andric                                 !OldElemTy->isBitIntType()) ||
43725ffd83dbSDimitry Andric                                OldElemTy->getAs<EnumType>();
43730b57cec5SDimitry Andric 
43740b57cec5SDimitry Andric   if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
43750b57cec5SDimitry Andric       !IntegralOrAnyEnumType)
43760b57cec5SDimitry Andric     Diag(AttrLoc, diag::err_mode_not_primitive);
43770b57cec5SDimitry Andric   else if (IntegerMode) {
43780b57cec5SDimitry Andric     if (!IntegralOrAnyEnumType)
43790b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_mode_wrong_type);
43800b57cec5SDimitry Andric   } else if (ComplexMode) {
43810b57cec5SDimitry Andric     if (!OldElemTy->isComplexType())
43820b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_mode_wrong_type);
43830b57cec5SDimitry Andric   } else {
43840b57cec5SDimitry Andric     if (!OldElemTy->isFloatingType())
43850b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_mode_wrong_type);
43860b57cec5SDimitry Andric   }
43870b57cec5SDimitry Andric 
43880b57cec5SDimitry Andric   QualType NewElemTy;
43890b57cec5SDimitry Andric 
43900b57cec5SDimitry Andric   if (IntegerMode)
43910b57cec5SDimitry Andric     NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
43920b57cec5SDimitry Andric                                               OldElemTy->isSignedIntegerType());
43930b57cec5SDimitry Andric   else
4394349cc55cSDimitry Andric     NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
43950b57cec5SDimitry Andric 
43960b57cec5SDimitry Andric   if (NewElemTy.isNull()) {
43970fca6ea1SDimitry Andric     // Only emit diagnostic on host for 128-bit mode attribute
43980fca6ea1SDimitry Andric     if (!(DestWidth == 128 && getLangOpts().CUDAIsDevice))
43990b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
44000b57cec5SDimitry Andric     return;
44010b57cec5SDimitry Andric   }
44020b57cec5SDimitry Andric 
44030b57cec5SDimitry Andric   if (ComplexMode) {
44040b57cec5SDimitry Andric     NewElemTy = Context.getComplexType(NewElemTy);
44050b57cec5SDimitry Andric   }
44060b57cec5SDimitry Andric 
44070b57cec5SDimitry Andric   QualType NewTy = NewElemTy;
44080b57cec5SDimitry Andric   if (VectorSize.getBoolValue()) {
44090b57cec5SDimitry Andric     NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(),
44105f757f3fSDimitry Andric                                   VectorKind::Generic);
44110b57cec5SDimitry Andric   } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
44120b57cec5SDimitry Andric     // Complex machine mode does not support base vector types.
44130b57cec5SDimitry Andric     if (ComplexMode) {
44140b57cec5SDimitry Andric       Diag(AttrLoc, diag::err_complex_mode_vector_type);
44150b57cec5SDimitry Andric       return;
44160b57cec5SDimitry Andric     }
44170b57cec5SDimitry Andric     unsigned NumElements = Context.getTypeSize(OldElemTy) *
44180b57cec5SDimitry Andric                            OldVT->getNumElements() /
44190b57cec5SDimitry Andric                            Context.getTypeSize(NewElemTy);
44200b57cec5SDimitry Andric     NewTy =
44210b57cec5SDimitry Andric         Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
44220b57cec5SDimitry Andric   }
44230b57cec5SDimitry Andric 
44240b57cec5SDimitry Andric   if (NewTy.isNull()) {
44250b57cec5SDimitry Andric     Diag(AttrLoc, diag::err_mode_wrong_type);
44260b57cec5SDimitry Andric     return;
44270b57cec5SDimitry Andric   }
44280b57cec5SDimitry Andric 
44290b57cec5SDimitry Andric   // Install the new type.
44300b57cec5SDimitry Andric   if (auto *TD = dyn_cast<TypedefNameDecl>(D))
44310b57cec5SDimitry Andric     TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
44320b57cec5SDimitry Andric   else if (auto *ED = dyn_cast<EnumDecl>(D))
44330b57cec5SDimitry Andric     ED->setIntegerType(NewTy);
44340b57cec5SDimitry Andric   else
44350b57cec5SDimitry Andric     cast<ValueDecl>(D)->setType(NewTy);
44360b57cec5SDimitry Andric 
4437a7dea167SDimitry Andric   D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
44380b57cec5SDimitry Andric }
44390b57cec5SDimitry Andric 
44400b57cec5SDimitry Andric static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4441a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
44420b57cec5SDimitry Andric }
44430b57cec5SDimitry Andric 
4444a7dea167SDimitry Andric AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
4445a7dea167SDimitry Andric                                               const AttributeCommonInfo &CI,
4446a7dea167SDimitry Andric                                               const IdentifierInfo *Ident) {
44470b57cec5SDimitry Andric   if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
4448a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
44490b57cec5SDimitry Andric     Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
44500b57cec5SDimitry Andric     return nullptr;
44510b57cec5SDimitry Andric   }
44520b57cec5SDimitry Andric 
44530b57cec5SDimitry Andric   if (D->hasAttr<AlwaysInlineAttr>())
44540b57cec5SDimitry Andric     return nullptr;
44550b57cec5SDimitry Andric 
4456a7dea167SDimitry Andric   return ::new (Context) AlwaysInlineAttr(Context, CI);
44570b57cec5SDimitry Andric }
44580b57cec5SDimitry Andric 
44590b57cec5SDimitry Andric InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
44600b57cec5SDimitry Andric                                                     const ParsedAttr &AL) {
44610b57cec5SDimitry Andric   if (const auto *VD = dyn_cast<VarDecl>(D)) {
44620b57cec5SDimitry Andric     // Attribute applies to Var but not any subclass of it (like ParmVar,
44630b57cec5SDimitry Andric     // ImplicitParm or VarTemplateSpecialization).
44640b57cec5SDimitry Andric     if (VD->getKind() != Decl::Var) {
44650b57cec5SDimitry Andric       Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
446606c3fb27SDimitry Andric           << AL << AL.isRegularKeywordAttribute()
446706c3fb27SDimitry Andric           << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
44680b57cec5SDimitry Andric                                       : ExpectedVariableOrFunction);
44690b57cec5SDimitry Andric       return nullptr;
44700b57cec5SDimitry Andric     }
44710b57cec5SDimitry Andric     // Attribute does not apply to non-static local variables.
44720b57cec5SDimitry Andric     if (VD->hasLocalStorage()) {
44730b57cec5SDimitry Andric       Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
44740b57cec5SDimitry Andric       return nullptr;
44750b57cec5SDimitry Andric     }
44760b57cec5SDimitry Andric   }
44770b57cec5SDimitry Andric 
4478a7dea167SDimitry Andric   return ::new (Context) InternalLinkageAttr(Context, AL);
44790b57cec5SDimitry Andric }
44800b57cec5SDimitry Andric InternalLinkageAttr *
44810b57cec5SDimitry Andric Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
44820b57cec5SDimitry Andric   if (const auto *VD = dyn_cast<VarDecl>(D)) {
44830b57cec5SDimitry Andric     // Attribute applies to Var but not any subclass of it (like ParmVar,
44840b57cec5SDimitry Andric     // ImplicitParm or VarTemplateSpecialization).
44850b57cec5SDimitry Andric     if (VD->getKind() != Decl::Var) {
44860b57cec5SDimitry Andric       Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)
448706c3fb27SDimitry Andric           << &AL << AL.isRegularKeywordAttribute()
448806c3fb27SDimitry Andric           << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
44890b57cec5SDimitry Andric                                       : ExpectedVariableOrFunction);
44900b57cec5SDimitry Andric       return nullptr;
44910b57cec5SDimitry Andric     }
44920b57cec5SDimitry Andric     // Attribute does not apply to non-static local variables.
44930b57cec5SDimitry Andric     if (VD->hasLocalStorage()) {
44940b57cec5SDimitry Andric       Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
44950b57cec5SDimitry Andric       return nullptr;
44960b57cec5SDimitry Andric     }
44970b57cec5SDimitry Andric   }
44980b57cec5SDimitry Andric 
4499a7dea167SDimitry Andric   return ::new (Context) InternalLinkageAttr(Context, AL);
45000b57cec5SDimitry Andric }
45010b57cec5SDimitry Andric 
4502a7dea167SDimitry Andric MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
45030b57cec5SDimitry Andric   if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
4504a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
45050b57cec5SDimitry Andric     Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
45060b57cec5SDimitry Andric     return nullptr;
45070b57cec5SDimitry Andric   }
45080b57cec5SDimitry Andric 
45090b57cec5SDimitry Andric   if (D->hasAttr<MinSizeAttr>())
45100b57cec5SDimitry Andric     return nullptr;
45110b57cec5SDimitry Andric 
4512a7dea167SDimitry Andric   return ::new (Context) MinSizeAttr(Context, CI);
45130b57cec5SDimitry Andric }
45140b57cec5SDimitry Andric 
4515a7dea167SDimitry Andric OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
4516a7dea167SDimitry Andric                                               const AttributeCommonInfo &CI) {
45170b57cec5SDimitry Andric   if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
45180b57cec5SDimitry Andric     Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
4519a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::note_conflicting_attribute);
45200b57cec5SDimitry Andric     D->dropAttr<AlwaysInlineAttr>();
45210b57cec5SDimitry Andric   }
45220b57cec5SDimitry Andric   if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
45230b57cec5SDimitry Andric     Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
4524a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::note_conflicting_attribute);
45250b57cec5SDimitry Andric     D->dropAttr<MinSizeAttr>();
45260b57cec5SDimitry Andric   }
45270b57cec5SDimitry Andric 
45280b57cec5SDimitry Andric   if (D->hasAttr<OptimizeNoneAttr>())
45290b57cec5SDimitry Andric     return nullptr;
45300b57cec5SDimitry Andric 
4531a7dea167SDimitry Andric   return ::new (Context) OptimizeNoneAttr(Context, CI);
45320b57cec5SDimitry Andric }
45330b57cec5SDimitry Andric 
45340b57cec5SDimitry Andric static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4535a7dea167SDimitry Andric   if (AlwaysInlineAttr *Inline =
4536a7dea167SDimitry Andric           S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
45370b57cec5SDimitry Andric     D->addAttr(Inline);
45380b57cec5SDimitry Andric }
45390b57cec5SDimitry Andric 
45400b57cec5SDimitry Andric static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4541a7dea167SDimitry Andric   if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
45420b57cec5SDimitry Andric     D->addAttr(MinSize);
45430b57cec5SDimitry Andric }
45440b57cec5SDimitry Andric 
45450b57cec5SDimitry Andric static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4546a7dea167SDimitry Andric   if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
45470b57cec5SDimitry Andric     D->addAttr(Optnone);
45480b57cec5SDimitry Andric }
45490b57cec5SDimitry Andric 
45500b57cec5SDimitry Andric static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
45510b57cec5SDimitry Andric   const auto *VD = cast<VarDecl>(D);
4552e8d8bef9SDimitry Andric   if (VD->hasLocalStorage()) {
4553e8d8bef9SDimitry Andric     S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
45540b57cec5SDimitry Andric     return;
45550b57cec5SDimitry Andric   }
4556fe6060f1SDimitry Andric   // constexpr variable may already get an implicit constant attr, which should
4557fe6060f1SDimitry Andric   // be replaced by the explicit constant attr.
4558fe6060f1SDimitry Andric   if (auto *A = D->getAttr<CUDAConstantAttr>()) {
4559fe6060f1SDimitry Andric     if (!A->isImplicit())
4560fe6060f1SDimitry Andric       return;
4561fe6060f1SDimitry Andric     D->dropAttr<CUDAConstantAttr>();
4562fe6060f1SDimitry Andric   }
4563a7dea167SDimitry Andric   D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
45640b57cec5SDimitry Andric }
45650b57cec5SDimitry Andric 
45660b57cec5SDimitry Andric static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
45670b57cec5SDimitry Andric   const auto *VD = cast<VarDecl>(D);
45680b57cec5SDimitry Andric   // extern __shared__ is only allowed on arrays with no length (e.g.
45690b57cec5SDimitry Andric   // "int x[]").
45700b57cec5SDimitry Andric   if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
45710b57cec5SDimitry Andric       !isa<IncompleteArrayType>(VD->getType())) {
45720b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;
45730b57cec5SDimitry Andric     return;
45740b57cec5SDimitry Andric   }
45750b57cec5SDimitry Andric   if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
45760fca6ea1SDimitry Andric       S.CUDA().DiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
45770fca6ea1SDimitry Andric           << llvm::to_underlying(S.CUDA().CurrentTarget()))
45780b57cec5SDimitry Andric     return;
4579a7dea167SDimitry Andric   D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
45800b57cec5SDimitry Andric }
45810b57cec5SDimitry Andric 
45820b57cec5SDimitry Andric static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
45830b57cec5SDimitry Andric   const auto *FD = cast<FunctionDecl>(D);
4584a7dea167SDimitry Andric   if (!FD->getReturnType()->isVoidType() &&
4585a7dea167SDimitry Andric       !FD->getReturnType()->getAs<AutoType>() &&
4586a7dea167SDimitry Andric       !FD->getReturnType()->isInstantiationDependentType()) {
45870b57cec5SDimitry Andric     SourceRange RTRange = FD->getReturnTypeSourceRange();
45880b57cec5SDimitry Andric     S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
45890b57cec5SDimitry Andric         << FD->getType()
45900b57cec5SDimitry Andric         << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
45910b57cec5SDimitry Andric                               : FixItHint());
45920b57cec5SDimitry Andric     return;
45930b57cec5SDimitry Andric   }
45940b57cec5SDimitry Andric   if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
45950b57cec5SDimitry Andric     if (Method->isInstance()) {
45960b57cec5SDimitry Andric       S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
45970b57cec5SDimitry Andric           << Method;
45980b57cec5SDimitry Andric       return;
45990b57cec5SDimitry Andric     }
46000b57cec5SDimitry Andric     S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;
46010b57cec5SDimitry Andric   }
46020b57cec5SDimitry Andric   // Only warn for "inline" when compiling for host, to cut down on noise.
46030b57cec5SDimitry Andric   if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
46040b57cec5SDimitry Andric     S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
46050b57cec5SDimitry Andric 
460606c3fb27SDimitry Andric   if (AL.getKind() == ParsedAttr::AT_NVPTXKernel)
460706c3fb27SDimitry Andric     D->addAttr(::new (S.Context) NVPTXKernelAttr(S.Context, AL));
460806c3fb27SDimitry Andric   else
4609a7dea167SDimitry Andric     D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
46105ffd83dbSDimitry Andric   // In host compilation the kernel is emitted as a stub function, which is
46115ffd83dbSDimitry Andric   // a helper function for launching the kernel. The instructions in the helper
46125ffd83dbSDimitry Andric   // function has nothing to do with the source code of the kernel. Do not emit
46135ffd83dbSDimitry Andric   // debug info for the stub function to avoid confusing the debugger.
46145ffd83dbSDimitry Andric   if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
46155ffd83dbSDimitry Andric     D->addAttr(NoDebugAttr::CreateImplicit(S.Context));
46160b57cec5SDimitry Andric }
46170b57cec5SDimitry Andric 
4618e8d8bef9SDimitry Andric static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4619e8d8bef9SDimitry Andric   if (const auto *VD = dyn_cast<VarDecl>(D)) {
4620e8d8bef9SDimitry Andric     if (VD->hasLocalStorage()) {
4621e8d8bef9SDimitry Andric       S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
4622e8d8bef9SDimitry Andric       return;
4623e8d8bef9SDimitry Andric     }
4624e8d8bef9SDimitry Andric   }
4625e8d8bef9SDimitry Andric 
4626e8d8bef9SDimitry Andric   if (auto *A = D->getAttr<CUDADeviceAttr>()) {
4627e8d8bef9SDimitry Andric     if (!A->isImplicit())
4628e8d8bef9SDimitry Andric       return;
4629e8d8bef9SDimitry Andric     D->dropAttr<CUDADeviceAttr>();
4630e8d8bef9SDimitry Andric   }
4631e8d8bef9SDimitry Andric   D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));
4632e8d8bef9SDimitry Andric }
4633e8d8bef9SDimitry Andric 
4634e8d8bef9SDimitry Andric static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4635e8d8bef9SDimitry Andric   if (const auto *VD = dyn_cast<VarDecl>(D)) {
4636e8d8bef9SDimitry Andric     if (VD->hasLocalStorage()) {
4637e8d8bef9SDimitry Andric       S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
4638e8d8bef9SDimitry Andric       return;
4639e8d8bef9SDimitry Andric     }
4640e8d8bef9SDimitry Andric   }
4641e8d8bef9SDimitry Andric   if (!D->hasAttr<HIPManagedAttr>())
4642e8d8bef9SDimitry Andric     D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));
4643e8d8bef9SDimitry Andric   if (!D->hasAttr<CUDADeviceAttr>())
4644e8d8bef9SDimitry Andric     D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));
4645e8d8bef9SDimitry Andric }
4646e8d8bef9SDimitry Andric 
46470b57cec5SDimitry Andric static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
46480b57cec5SDimitry Andric   const auto *Fn = cast<FunctionDecl>(D);
46490b57cec5SDimitry Andric   if (!Fn->isInlineSpecified()) {
46500b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
46510b57cec5SDimitry Andric     return;
46520b57cec5SDimitry Andric   }
46530b57cec5SDimitry Andric 
4654a7dea167SDimitry Andric   if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
4655a7dea167SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
4656a7dea167SDimitry Andric 
4657a7dea167SDimitry Andric   D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
46580b57cec5SDimitry Andric }
46590b57cec5SDimitry Andric 
46600b57cec5SDimitry Andric static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
46610b57cec5SDimitry Andric   if (hasDeclarator(D)) return;
46620b57cec5SDimitry Andric 
46630b57cec5SDimitry Andric   // Diagnostic is emitted elsewhere: here we store the (valid) AL
46640b57cec5SDimitry Andric   // in the Decl node for syntactic reasoning, e.g., pretty-printing.
46650b57cec5SDimitry Andric   CallingConv CC;
46660fca6ea1SDimitry Andric   if (S.CheckCallingConvAttr(
46670fca6ea1SDimitry Andric           AL, CC, /*FD*/ nullptr,
46680fca6ea1SDimitry Andric           S.CUDA().IdentifyTarget(dyn_cast<FunctionDecl>(D))))
46690b57cec5SDimitry Andric     return;
46700b57cec5SDimitry Andric 
46710b57cec5SDimitry Andric   if (!isa<ObjCMethodDecl>(D)) {
46720b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
467306c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
46740b57cec5SDimitry Andric     return;
46750b57cec5SDimitry Andric   }
46760b57cec5SDimitry Andric 
46770b57cec5SDimitry Andric   switch (AL.getKind()) {
46780b57cec5SDimitry Andric   case ParsedAttr::AT_FastCall:
4679a7dea167SDimitry Andric     D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
46800b57cec5SDimitry Andric     return;
46810b57cec5SDimitry Andric   case ParsedAttr::AT_StdCall:
4682a7dea167SDimitry Andric     D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
46830b57cec5SDimitry Andric     return;
46840b57cec5SDimitry Andric   case ParsedAttr::AT_ThisCall:
4685a7dea167SDimitry Andric     D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
46860b57cec5SDimitry Andric     return;
46870b57cec5SDimitry Andric   case ParsedAttr::AT_CDecl:
4688a7dea167SDimitry Andric     D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
46890b57cec5SDimitry Andric     return;
46900b57cec5SDimitry Andric   case ParsedAttr::AT_Pascal:
4691a7dea167SDimitry Andric     D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
46920b57cec5SDimitry Andric     return;
46930b57cec5SDimitry Andric   case ParsedAttr::AT_SwiftCall:
4694a7dea167SDimitry Andric     D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
46950b57cec5SDimitry Andric     return;
4696fe6060f1SDimitry Andric   case ParsedAttr::AT_SwiftAsyncCall:
4697fe6060f1SDimitry Andric     D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
4698fe6060f1SDimitry Andric     return;
46990b57cec5SDimitry Andric   case ParsedAttr::AT_VectorCall:
4700a7dea167SDimitry Andric     D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
47010b57cec5SDimitry Andric     return;
47020b57cec5SDimitry Andric   case ParsedAttr::AT_MSABI:
4703a7dea167SDimitry Andric     D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
47040b57cec5SDimitry Andric     return;
47050b57cec5SDimitry Andric   case ParsedAttr::AT_SysVABI:
4706a7dea167SDimitry Andric     D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
47070b57cec5SDimitry Andric     return;
47080b57cec5SDimitry Andric   case ParsedAttr::AT_RegCall:
4709a7dea167SDimitry Andric     D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
47100b57cec5SDimitry Andric     return;
47110b57cec5SDimitry Andric   case ParsedAttr::AT_Pcs: {
47120b57cec5SDimitry Andric     PcsAttr::PCSType PCS;
47130b57cec5SDimitry Andric     switch (CC) {
47140b57cec5SDimitry Andric     case CC_AAPCS:
47150b57cec5SDimitry Andric       PCS = PcsAttr::AAPCS;
47160b57cec5SDimitry Andric       break;
47170b57cec5SDimitry Andric     case CC_AAPCS_VFP:
47180b57cec5SDimitry Andric       PCS = PcsAttr::AAPCS_VFP;
47190b57cec5SDimitry Andric       break;
47200b57cec5SDimitry Andric     default:
47210b57cec5SDimitry Andric       llvm_unreachable("unexpected calling convention in pcs attribute");
47220b57cec5SDimitry Andric     }
47230b57cec5SDimitry Andric 
4724a7dea167SDimitry Andric     D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
47250b57cec5SDimitry Andric     return;
47260b57cec5SDimitry Andric   }
47270b57cec5SDimitry Andric   case ParsedAttr::AT_AArch64VectorPcs:
4728a7dea167SDimitry Andric     D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
47290b57cec5SDimitry Andric     return;
473081ad6265SDimitry Andric   case ParsedAttr::AT_AArch64SVEPcs:
473181ad6265SDimitry Andric     D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
473281ad6265SDimitry Andric     return;
473381ad6265SDimitry Andric   case ParsedAttr::AT_AMDGPUKernelCall:
473481ad6265SDimitry Andric     D->addAttr(::new (S.Context) AMDGPUKernelCallAttr(S.Context, AL));
473581ad6265SDimitry Andric     return;
47360b57cec5SDimitry Andric   case ParsedAttr::AT_IntelOclBicc:
4737a7dea167SDimitry Andric     D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
47380b57cec5SDimitry Andric     return;
47390b57cec5SDimitry Andric   case ParsedAttr::AT_PreserveMost:
4740a7dea167SDimitry Andric     D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
47410b57cec5SDimitry Andric     return;
47420b57cec5SDimitry Andric   case ParsedAttr::AT_PreserveAll:
4743a7dea167SDimitry Andric     D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
47440b57cec5SDimitry Andric     return;
47455f757f3fSDimitry Andric   case ParsedAttr::AT_M68kRTD:
47465f757f3fSDimitry Andric     D->addAttr(::new (S.Context) M68kRTDAttr(S.Context, AL));
47475f757f3fSDimitry Andric     return;
47480fca6ea1SDimitry Andric   case ParsedAttr::AT_PreserveNone:
47490fca6ea1SDimitry Andric     D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));
47500fca6ea1SDimitry Andric     return;
47510fca6ea1SDimitry Andric   case ParsedAttr::AT_RISCVVectorCC:
47520fca6ea1SDimitry Andric     D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
47530fca6ea1SDimitry Andric     return;
47540b57cec5SDimitry Andric   default:
47550b57cec5SDimitry Andric     llvm_unreachable("unexpected attribute kind");
47560b57cec5SDimitry Andric   }
47570b57cec5SDimitry Andric }
47580b57cec5SDimitry Andric 
47590b57cec5SDimitry Andric static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
47605f757f3fSDimitry Andric   if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
47615f757f3fSDimitry Andric     // Suppression attribute with GSL spelling requires at least 1 argument.
4762fe6060f1SDimitry Andric     if (!AL.checkAtLeastNumArgs(S, 1))
47630b57cec5SDimitry Andric       return;
47645f757f3fSDimitry Andric   }
47650b57cec5SDimitry Andric 
47660b57cec5SDimitry Andric   std::vector<StringRef> DiagnosticIdentifiers;
47670b57cec5SDimitry Andric   for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
47680b57cec5SDimitry Andric     StringRef RuleName;
47690b57cec5SDimitry Andric 
47700b57cec5SDimitry Andric     if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr))
47710b57cec5SDimitry Andric       return;
47720b57cec5SDimitry Andric 
47730b57cec5SDimitry Andric     DiagnosticIdentifiers.push_back(RuleName);
47740b57cec5SDimitry Andric   }
4775a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
4776a7dea167SDimitry Andric                  SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
4777a7dea167SDimitry Andric                               DiagnosticIdentifiers.size()));
4778a7dea167SDimitry Andric }
4779a7dea167SDimitry Andric 
4780a7dea167SDimitry Andric static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4781a7dea167SDimitry Andric   TypeSourceInfo *DerefTypeLoc = nullptr;
4782a7dea167SDimitry Andric   QualType ParmType;
4783a7dea167SDimitry Andric   if (AL.hasParsedType()) {
4784a7dea167SDimitry Andric     ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
4785a7dea167SDimitry Andric 
4786a7dea167SDimitry Andric     unsigned SelectIdx = ~0U;
4787480093f4SDimitry Andric     if (ParmType->isReferenceType())
4788a7dea167SDimitry Andric       SelectIdx = 0;
4789a7dea167SDimitry Andric     else if (ParmType->isArrayType())
4790480093f4SDimitry Andric       SelectIdx = 1;
4791a7dea167SDimitry Andric 
4792a7dea167SDimitry Andric     if (SelectIdx != ~0U) {
4793a7dea167SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
4794a7dea167SDimitry Andric           << SelectIdx << AL;
4795a7dea167SDimitry Andric       return;
4796a7dea167SDimitry Andric     }
4797a7dea167SDimitry Andric   }
4798a7dea167SDimitry Andric 
4799a7dea167SDimitry Andric   // To check if earlier decl attributes do not conflict the newly parsed ones
4800349cc55cSDimitry Andric   // we always add (and check) the attribute to the canonical decl. We need
4801fe6060f1SDimitry Andric   // to repeat the check for attribute mutual exclusion because we're attaching
4802fe6060f1SDimitry Andric   // all of the attributes to the canonical declaration rather than the current
4803fe6060f1SDimitry Andric   // declaration.
4804a7dea167SDimitry Andric   D = D->getCanonicalDecl();
4805a7dea167SDimitry Andric   if (AL.getKind() == ParsedAttr::AT_Owner) {
4806a7dea167SDimitry Andric     if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
4807a7dea167SDimitry Andric       return;
4808a7dea167SDimitry Andric     if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
4809a7dea167SDimitry Andric       const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
4810a7dea167SDimitry Andric                                           ? OAttr->getDerefType().getTypePtr()
4811a7dea167SDimitry Andric                                           : nullptr;
4812a7dea167SDimitry Andric       if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
4813a7dea167SDimitry Andric         S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
481406c3fb27SDimitry Andric             << AL << OAttr
481506c3fb27SDimitry Andric             << (AL.isRegularKeywordAttribute() ||
481606c3fb27SDimitry Andric                 OAttr->isRegularKeywordAttribute());
4817a7dea167SDimitry Andric         S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
4818a7dea167SDimitry Andric       }
4819a7dea167SDimitry Andric       return;
4820a7dea167SDimitry Andric     }
4821a7dea167SDimitry Andric     for (Decl *Redecl : D->redecls()) {
4822a7dea167SDimitry Andric       Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
4823a7dea167SDimitry Andric     }
4824a7dea167SDimitry Andric   } else {
4825a7dea167SDimitry Andric     if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
4826a7dea167SDimitry Andric       return;
4827a7dea167SDimitry Andric     if (const auto *PAttr = D->getAttr<PointerAttr>()) {
4828a7dea167SDimitry Andric       const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
4829a7dea167SDimitry Andric                                           ? PAttr->getDerefType().getTypePtr()
4830a7dea167SDimitry Andric                                           : nullptr;
4831a7dea167SDimitry Andric       if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
4832a7dea167SDimitry Andric         S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
483306c3fb27SDimitry Andric             << AL << PAttr
483406c3fb27SDimitry Andric             << (AL.isRegularKeywordAttribute() ||
483506c3fb27SDimitry Andric                 PAttr->isRegularKeywordAttribute());
4836a7dea167SDimitry Andric         S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
4837a7dea167SDimitry Andric       }
4838a7dea167SDimitry Andric       return;
4839a7dea167SDimitry Andric     }
4840a7dea167SDimitry Andric     for (Decl *Redecl : D->redecls()) {
4841a7dea167SDimitry Andric       Redecl->addAttr(::new (S.Context)
4842a7dea167SDimitry Andric                           PointerAttr(S.Context, AL, DerefTypeLoc));
4843a7dea167SDimitry Andric     }
4844a7dea167SDimitry Andric   }
48450b57cec5SDimitry Andric }
48460b57cec5SDimitry Andric 
484781ad6265SDimitry Andric static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
484881ad6265SDimitry Andric   if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))
484981ad6265SDimitry Andric     return;
485081ad6265SDimitry Andric   if (!D->hasAttr<RandomizeLayoutAttr>())
485181ad6265SDimitry Andric     D->addAttr(::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
485281ad6265SDimitry Andric }
485381ad6265SDimitry Andric 
485481ad6265SDimitry Andric static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,
485581ad6265SDimitry Andric                                         const ParsedAttr &AL) {
485681ad6265SDimitry Andric   if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))
485781ad6265SDimitry Andric     return;
485881ad6265SDimitry Andric   if (!D->hasAttr<NoRandomizeLayoutAttr>())
485981ad6265SDimitry Andric     D->addAttr(::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
486081ad6265SDimitry Andric }
486181ad6265SDimitry Andric 
48620b57cec5SDimitry Andric bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
48635f757f3fSDimitry Andric                                 const FunctionDecl *FD,
48645f757f3fSDimitry Andric                                 CUDAFunctionTarget CFT) {
48650b57cec5SDimitry Andric   if (Attrs.isInvalid())
48660b57cec5SDimitry Andric     return true;
48670b57cec5SDimitry Andric 
48680b57cec5SDimitry Andric   if (Attrs.hasProcessingCache()) {
48690b57cec5SDimitry Andric     CC = (CallingConv) Attrs.getProcessingCache();
48700b57cec5SDimitry Andric     return false;
48710b57cec5SDimitry Andric   }
48720b57cec5SDimitry Andric 
48730b57cec5SDimitry Andric   unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
4874fe6060f1SDimitry Andric   if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) {
48750b57cec5SDimitry Andric     Attrs.setInvalid();
48760b57cec5SDimitry Andric     return true;
48770b57cec5SDimitry Andric   }
48780b57cec5SDimitry Andric 
48790b57cec5SDimitry Andric   // TODO: diagnose uses of these conventions on the wrong target.
48800b57cec5SDimitry Andric   switch (Attrs.getKind()) {
48810b57cec5SDimitry Andric   case ParsedAttr::AT_CDecl:
48820b57cec5SDimitry Andric     CC = CC_C;
48830b57cec5SDimitry Andric     break;
48840b57cec5SDimitry Andric   case ParsedAttr::AT_FastCall:
48850b57cec5SDimitry Andric     CC = CC_X86FastCall;
48860b57cec5SDimitry Andric     break;
48870b57cec5SDimitry Andric   case ParsedAttr::AT_StdCall:
48880b57cec5SDimitry Andric     CC = CC_X86StdCall;
48890b57cec5SDimitry Andric     break;
48900b57cec5SDimitry Andric   case ParsedAttr::AT_ThisCall:
48910b57cec5SDimitry Andric     CC = CC_X86ThisCall;
48920b57cec5SDimitry Andric     break;
48930b57cec5SDimitry Andric   case ParsedAttr::AT_Pascal:
48940b57cec5SDimitry Andric     CC = CC_X86Pascal;
48950b57cec5SDimitry Andric     break;
48960b57cec5SDimitry Andric   case ParsedAttr::AT_SwiftCall:
48970b57cec5SDimitry Andric     CC = CC_Swift;
48980b57cec5SDimitry Andric     break;
4899fe6060f1SDimitry Andric   case ParsedAttr::AT_SwiftAsyncCall:
4900fe6060f1SDimitry Andric     CC = CC_SwiftAsync;
4901fe6060f1SDimitry Andric     break;
49020b57cec5SDimitry Andric   case ParsedAttr::AT_VectorCall:
49030b57cec5SDimitry Andric     CC = CC_X86VectorCall;
49040b57cec5SDimitry Andric     break;
49050b57cec5SDimitry Andric   case ParsedAttr::AT_AArch64VectorPcs:
49060b57cec5SDimitry Andric     CC = CC_AArch64VectorCall;
49070b57cec5SDimitry Andric     break;
490881ad6265SDimitry Andric   case ParsedAttr::AT_AArch64SVEPcs:
490981ad6265SDimitry Andric     CC = CC_AArch64SVEPCS;
491081ad6265SDimitry Andric     break;
491181ad6265SDimitry Andric   case ParsedAttr::AT_AMDGPUKernelCall:
491281ad6265SDimitry Andric     CC = CC_AMDGPUKernelCall;
491381ad6265SDimitry Andric     break;
49140b57cec5SDimitry Andric   case ParsedAttr::AT_RegCall:
49150b57cec5SDimitry Andric     CC = CC_X86RegCall;
49160b57cec5SDimitry Andric     break;
49170b57cec5SDimitry Andric   case ParsedAttr::AT_MSABI:
49180b57cec5SDimitry Andric     CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
49190b57cec5SDimitry Andric                                                              CC_Win64;
49200b57cec5SDimitry Andric     break;
49210b57cec5SDimitry Andric   case ParsedAttr::AT_SysVABI:
49220b57cec5SDimitry Andric     CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
49230b57cec5SDimitry Andric                                                              CC_C;
49240b57cec5SDimitry Andric     break;
49250b57cec5SDimitry Andric   case ParsedAttr::AT_Pcs: {
49260b57cec5SDimitry Andric     StringRef StrRef;
49270b57cec5SDimitry Andric     if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) {
49280b57cec5SDimitry Andric       Attrs.setInvalid();
49290b57cec5SDimitry Andric       return true;
49300b57cec5SDimitry Andric     }
49310b57cec5SDimitry Andric     if (StrRef == "aapcs") {
49320b57cec5SDimitry Andric       CC = CC_AAPCS;
49330b57cec5SDimitry Andric       break;
49340b57cec5SDimitry Andric     } else if (StrRef == "aapcs-vfp") {
49350b57cec5SDimitry Andric       CC = CC_AAPCS_VFP;
49360b57cec5SDimitry Andric       break;
49370b57cec5SDimitry Andric     }
49380b57cec5SDimitry Andric 
49390b57cec5SDimitry Andric     Attrs.setInvalid();
49400b57cec5SDimitry Andric     Diag(Attrs.getLoc(), diag::err_invalid_pcs);
49410b57cec5SDimitry Andric     return true;
49420b57cec5SDimitry Andric   }
49430b57cec5SDimitry Andric   case ParsedAttr::AT_IntelOclBicc:
49440b57cec5SDimitry Andric     CC = CC_IntelOclBicc;
49450b57cec5SDimitry Andric     break;
49460b57cec5SDimitry Andric   case ParsedAttr::AT_PreserveMost:
49470b57cec5SDimitry Andric     CC = CC_PreserveMost;
49480b57cec5SDimitry Andric     break;
49490b57cec5SDimitry Andric   case ParsedAttr::AT_PreserveAll:
49500b57cec5SDimitry Andric     CC = CC_PreserveAll;
49510b57cec5SDimitry Andric     break;
49525f757f3fSDimitry Andric   case ParsedAttr::AT_M68kRTD:
49535f757f3fSDimitry Andric     CC = CC_M68kRTD;
49545f757f3fSDimitry Andric     break;
49550fca6ea1SDimitry Andric   case ParsedAttr::AT_PreserveNone:
49560fca6ea1SDimitry Andric     CC = CC_PreserveNone;
49570fca6ea1SDimitry Andric     break;
49580fca6ea1SDimitry Andric   case ParsedAttr::AT_RISCVVectorCC:
49590fca6ea1SDimitry Andric     CC = CC_RISCVVectorCall;
49600fca6ea1SDimitry Andric     break;
49610b57cec5SDimitry Andric   default: llvm_unreachable("unexpected attribute kind");
49620b57cec5SDimitry Andric   }
49630b57cec5SDimitry Andric 
49640b57cec5SDimitry Andric   TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
49650b57cec5SDimitry Andric   const TargetInfo &TI = Context.getTargetInfo();
49660b57cec5SDimitry Andric   // CUDA functions may have host and/or device attributes which indicate
49670b57cec5SDimitry Andric   // their targeted execution environment, therefore the calling convention
49680b57cec5SDimitry Andric   // of functions in CUDA should be checked against the target deduced based
49690b57cec5SDimitry Andric   // on their host/device attributes.
49700b57cec5SDimitry Andric   if (LangOpts.CUDA) {
49710b57cec5SDimitry Andric     auto *Aux = Context.getAuxTargetInfo();
49720fca6ea1SDimitry Andric     assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
49730fca6ea1SDimitry Andric     auto CudaTarget = FD ? CUDA().IdentifyTarget(FD) : CFT;
49740b57cec5SDimitry Andric     bool CheckHost = false, CheckDevice = false;
49750b57cec5SDimitry Andric     switch (CudaTarget) {
49760fca6ea1SDimitry Andric     case CUDAFunctionTarget::HostDevice:
49770b57cec5SDimitry Andric       CheckHost = true;
49780b57cec5SDimitry Andric       CheckDevice = true;
49790b57cec5SDimitry Andric       break;
49800fca6ea1SDimitry Andric     case CUDAFunctionTarget::Host:
49810b57cec5SDimitry Andric       CheckHost = true;
49820b57cec5SDimitry Andric       break;
49830fca6ea1SDimitry Andric     case CUDAFunctionTarget::Device:
49840fca6ea1SDimitry Andric     case CUDAFunctionTarget::Global:
49850b57cec5SDimitry Andric       CheckDevice = true;
49860b57cec5SDimitry Andric       break;
49870fca6ea1SDimitry Andric     case CUDAFunctionTarget::InvalidTarget:
49880b57cec5SDimitry Andric       llvm_unreachable("unexpected cuda target");
49890b57cec5SDimitry Andric     }
49900b57cec5SDimitry Andric     auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
49910b57cec5SDimitry Andric     auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
49920b57cec5SDimitry Andric     if (CheckHost && HostTI)
49930b57cec5SDimitry Andric       A = HostTI->checkCallingConvention(CC);
49940b57cec5SDimitry Andric     if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
49950b57cec5SDimitry Andric       A = DeviceTI->checkCallingConvention(CC);
49960b57cec5SDimitry Andric   } else {
49970b57cec5SDimitry Andric     A = TI.checkCallingConvention(CC);
49980b57cec5SDimitry Andric   }
49990b57cec5SDimitry Andric 
50000b57cec5SDimitry Andric   switch (A) {
50010b57cec5SDimitry Andric   case TargetInfo::CCCR_OK:
50020b57cec5SDimitry Andric     break;
50030b57cec5SDimitry Andric 
50040b57cec5SDimitry Andric   case TargetInfo::CCCR_Ignore:
50050b57cec5SDimitry Andric     // Treat an ignored convention as if it was an explicit C calling convention
50060b57cec5SDimitry Andric     // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
50070b57cec5SDimitry Andric     // that command line flags that change the default convention to
50080b57cec5SDimitry Andric     // __vectorcall don't affect declarations marked __stdcall.
50090b57cec5SDimitry Andric     CC = CC_C;
50100b57cec5SDimitry Andric     break;
50110b57cec5SDimitry Andric 
5012a7dea167SDimitry Andric   case TargetInfo::CCCR_Error:
5013a7dea167SDimitry Andric     Diag(Attrs.getLoc(), diag::error_cconv_unsupported)
5014a7dea167SDimitry Andric         << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5015a7dea167SDimitry Andric     break;
5016a7dea167SDimitry Andric 
50170b57cec5SDimitry Andric   case TargetInfo::CCCR_Warning: {
50180b57cec5SDimitry Andric     Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)
50190b57cec5SDimitry Andric         << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
50200b57cec5SDimitry Andric 
50210b57cec5SDimitry Andric     // This convention is not valid for the target. Use the default function or
50220b57cec5SDimitry Andric     // method calling convention.
50230b57cec5SDimitry Andric     bool IsCXXMethod = false, IsVariadic = false;
50240b57cec5SDimitry Andric     if (FD) {
50250b57cec5SDimitry Andric       IsCXXMethod = FD->isCXXInstanceMember();
50260b57cec5SDimitry Andric       IsVariadic = FD->isVariadic();
50270b57cec5SDimitry Andric     }
50280b57cec5SDimitry Andric     CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
50290b57cec5SDimitry Andric     break;
50300b57cec5SDimitry Andric   }
50310b57cec5SDimitry Andric   }
50320b57cec5SDimitry Andric 
50330b57cec5SDimitry Andric   Attrs.setProcessingCache((unsigned) CC);
50340b57cec5SDimitry Andric   return false;
50350b57cec5SDimitry Andric }
50360b57cec5SDimitry Andric 
50370b57cec5SDimitry Andric bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
50380b57cec5SDimitry Andric   if (AL.isInvalid())
50390b57cec5SDimitry Andric     return true;
50400b57cec5SDimitry Andric 
5041fe6060f1SDimitry Andric   if (!AL.checkExactlyNumArgs(*this, 1)) {
50420b57cec5SDimitry Andric     AL.setInvalid();
50430b57cec5SDimitry Andric     return true;
50440b57cec5SDimitry Andric   }
50450b57cec5SDimitry Andric 
50460b57cec5SDimitry Andric   uint32_t NP;
50470b57cec5SDimitry Andric   Expr *NumParamsExpr = AL.getArgAsExpr(0);
50480fca6ea1SDimitry Andric   if (!checkUInt32Argument(AL, NumParamsExpr, NP)) {
50490b57cec5SDimitry Andric     AL.setInvalid();
50500b57cec5SDimitry Andric     return true;
50510b57cec5SDimitry Andric   }
50520b57cec5SDimitry Andric 
50530b57cec5SDimitry Andric   if (Context.getTargetInfo().getRegParmMax() == 0) {
50540b57cec5SDimitry Andric     Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)
50550b57cec5SDimitry Andric       << NumParamsExpr->getSourceRange();
50560b57cec5SDimitry Andric     AL.setInvalid();
50570b57cec5SDimitry Andric     return true;
50580b57cec5SDimitry Andric   }
50590b57cec5SDimitry Andric 
50600b57cec5SDimitry Andric   numParams = NP;
50610b57cec5SDimitry Andric   if (numParams > Context.getTargetInfo().getRegParmMax()) {
50620b57cec5SDimitry Andric     Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)
50630b57cec5SDimitry Andric       << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
50640b57cec5SDimitry Andric     AL.setInvalid();
50650b57cec5SDimitry Andric     return true;
50660b57cec5SDimitry Andric   }
50670b57cec5SDimitry Andric 
50680b57cec5SDimitry Andric   return false;
50690b57cec5SDimitry Andric }
50700b57cec5SDimitry Andric 
50710fca6ea1SDimitry Andric // Helper to get OffloadArch.
50720fca6ea1SDimitry Andric static OffloadArch getOffloadArch(const TargetInfo &TI) {
50735f757f3fSDimitry Andric   if (!TI.getTriple().isNVPTX())
50740fca6ea1SDimitry Andric     llvm_unreachable("getOffloadArch is only valid for NVPTX triple");
50755f757f3fSDimitry Andric   auto &TO = TI.getTargetOpts();
50760fca6ea1SDimitry Andric   return StringToOffloadArch(TO.CPU);
50775f757f3fSDimitry Andric }
50785f757f3fSDimitry Andric 
50790b57cec5SDimitry Andric // Checks whether an argument of launch_bounds attribute is
50800b57cec5SDimitry Andric // acceptable, performs implicit conversion to Rvalue, and returns
50810b57cec5SDimitry Andric // non-nullptr Expr result on success. Otherwise, it returns nullptr
50820b57cec5SDimitry Andric // and may output an error.
50830b57cec5SDimitry Andric static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
50840b57cec5SDimitry Andric                                      const CUDALaunchBoundsAttr &AL,
50850b57cec5SDimitry Andric                                      const unsigned Idx) {
50860b57cec5SDimitry Andric   if (S.DiagnoseUnexpandedParameterPack(E))
50870b57cec5SDimitry Andric     return nullptr;
50880b57cec5SDimitry Andric 
50890b57cec5SDimitry Andric   // Accept template arguments for now as they depend on something else.
50900b57cec5SDimitry Andric   // We'll get to check them when they eventually get instantiated.
50910b57cec5SDimitry Andric   if (E->isValueDependent())
50920b57cec5SDimitry Andric     return E;
50930b57cec5SDimitry Andric 
5094bdd1243dSDimitry Andric   std::optional<llvm::APSInt> I = llvm::APSInt(64);
5095e8d8bef9SDimitry Andric   if (!(I = E->getIntegerConstantExpr(S.Context))) {
50960b57cec5SDimitry Andric     S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
50970b57cec5SDimitry Andric         << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
50980b57cec5SDimitry Andric     return nullptr;
50990b57cec5SDimitry Andric   }
51000b57cec5SDimitry Andric   // Make sure we can fit it in 32 bits.
5101e8d8bef9SDimitry Andric   if (!I->isIntN(32)) {
5102e8d8bef9SDimitry Andric     S.Diag(E->getExprLoc(), diag::err_ice_too_large)
5103fe6060f1SDimitry Andric         << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
51040b57cec5SDimitry Andric     return nullptr;
51050b57cec5SDimitry Andric   }
5106e8d8bef9SDimitry Andric   if (*I < 0)
51070b57cec5SDimitry Andric     S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
51080b57cec5SDimitry Andric         << &AL << Idx << E->getSourceRange();
51090b57cec5SDimitry Andric 
51100b57cec5SDimitry Andric   // We may need to perform implicit conversion of the argument.
51110b57cec5SDimitry Andric   InitializedEntity Entity = InitializedEntity::InitializeParameter(
51120b57cec5SDimitry Andric       S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
51130b57cec5SDimitry Andric   ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
51140b57cec5SDimitry Andric   assert(!ValArg.isInvalid() &&
51150b57cec5SDimitry Andric          "Unexpected PerformCopyInitialization() failure.");
51160b57cec5SDimitry Andric 
51170b57cec5SDimitry Andric   return ValArg.getAs<Expr>();
51180b57cec5SDimitry Andric }
51190b57cec5SDimitry Andric 
51205f757f3fSDimitry Andric CUDALaunchBoundsAttr *
51215f757f3fSDimitry Andric Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads,
51225f757f3fSDimitry Andric                              Expr *MinBlocks, Expr *MaxBlocks) {
51235f757f3fSDimitry Andric   CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
51240b57cec5SDimitry Andric   MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
51255f757f3fSDimitry Andric   if (!MaxThreads)
51265f757f3fSDimitry Andric     return nullptr;
51270b57cec5SDimitry Andric 
51280b57cec5SDimitry Andric   if (MinBlocks) {
51290b57cec5SDimitry Andric     MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);
51305f757f3fSDimitry Andric     if (!MinBlocks)
51315f757f3fSDimitry Andric       return nullptr;
51320b57cec5SDimitry Andric   }
51330b57cec5SDimitry Andric 
51345f757f3fSDimitry Andric   if (MaxBlocks) {
51355f757f3fSDimitry Andric     // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
51360fca6ea1SDimitry Andric     auto SM = getOffloadArch(Context.getTargetInfo());
51370fca6ea1SDimitry Andric     if (SM == OffloadArch::UNKNOWN || SM < OffloadArch::SM_90) {
51385f757f3fSDimitry Andric       Diag(MaxBlocks->getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90)
51390fca6ea1SDimitry Andric           << OffloadArchToString(SM) << CI << MaxBlocks->getSourceRange();
51405f757f3fSDimitry Andric       // Ignore it by setting MaxBlocks to null;
51415f757f3fSDimitry Andric       MaxBlocks = nullptr;
51425f757f3fSDimitry Andric     } else {
51435f757f3fSDimitry Andric       MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2);
51445f757f3fSDimitry Andric       if (!MaxBlocks)
51455f757f3fSDimitry Andric         return nullptr;
51465f757f3fSDimitry Andric     }
51475f757f3fSDimitry Andric   }
51485f757f3fSDimitry Andric 
51495f757f3fSDimitry Andric   return ::new (Context)
51505f757f3fSDimitry Andric       CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
51515f757f3fSDimitry Andric }
51525f757f3fSDimitry Andric 
51535f757f3fSDimitry Andric void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
51545f757f3fSDimitry Andric                                Expr *MaxThreads, Expr *MinBlocks,
51555f757f3fSDimitry Andric                                Expr *MaxBlocks) {
51565f757f3fSDimitry Andric   if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
51575f757f3fSDimitry Andric     D->addAttr(Attr);
51580b57cec5SDimitry Andric }
51590b57cec5SDimitry Andric 
51600b57cec5SDimitry Andric static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
51615f757f3fSDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
51620b57cec5SDimitry Andric     return;
51630b57cec5SDimitry Andric 
5164a7dea167SDimitry Andric   S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
51655f757f3fSDimitry Andric                         AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr,
51665f757f3fSDimitry Andric                         AL.getNumArgs() > 2 ? AL.getArgAsExpr(2) : nullptr);
51670b57cec5SDimitry Andric }
51680b57cec5SDimitry Andric 
51690b57cec5SDimitry Andric static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
51700b57cec5SDimitry Andric                                           const ParsedAttr &AL) {
51710b57cec5SDimitry Andric   if (!AL.isArgIdent(0)) {
51720b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
51730b57cec5SDimitry Andric         << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
51740b57cec5SDimitry Andric     return;
51750b57cec5SDimitry Andric   }
51760b57cec5SDimitry Andric 
51770b57cec5SDimitry Andric   ParamIdx ArgumentIdx;
51780fca6ea1SDimitry Andric   if (!S.checkFunctionOrMethodParameterIndex(D, AL, 2, AL.getArgAsExpr(1),
51790b57cec5SDimitry Andric                                              ArgumentIdx))
51800b57cec5SDimitry Andric     return;
51810b57cec5SDimitry Andric 
51820b57cec5SDimitry Andric   ParamIdx TypeTagIdx;
51830fca6ea1SDimitry Andric   if (!S.checkFunctionOrMethodParameterIndex(D, AL, 3, AL.getArgAsExpr(2),
51840b57cec5SDimitry Andric                                              TypeTagIdx))
51850b57cec5SDimitry Andric     return;
51860b57cec5SDimitry Andric 
5187a7dea167SDimitry Andric   bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
51880b57cec5SDimitry Andric   if (IsPointer) {
51890b57cec5SDimitry Andric     // Ensure that buffer has a pointer type.
51900b57cec5SDimitry Andric     unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
51910b57cec5SDimitry Andric     if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
51920b57cec5SDimitry Andric         !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())
51930b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;
51940b57cec5SDimitry Andric   }
51950b57cec5SDimitry Andric 
51960b57cec5SDimitry Andric   D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
5197a7dea167SDimitry Andric       S.Context, AL, AL.getArgAsIdent(0)->Ident, ArgumentIdx, TypeTagIdx,
5198a7dea167SDimitry Andric       IsPointer));
51990b57cec5SDimitry Andric }
52000b57cec5SDimitry Andric 
52010b57cec5SDimitry Andric static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
52020b57cec5SDimitry Andric                                          const ParsedAttr &AL) {
52030b57cec5SDimitry Andric   if (!AL.isArgIdent(0)) {
52040b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
52050b57cec5SDimitry Andric         << AL << 1 << AANT_ArgumentIdentifier;
52060b57cec5SDimitry Andric     return;
52070b57cec5SDimitry Andric   }
52080b57cec5SDimitry Andric 
5209fe6060f1SDimitry Andric   if (!AL.checkExactlyNumArgs(S, 1))
52100b57cec5SDimitry Andric     return;
52110b57cec5SDimitry Andric 
52120b57cec5SDimitry Andric   if (!isa<VarDecl>(D)) {
52130b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
521406c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << ExpectedVariable;
52150b57cec5SDimitry Andric     return;
52160b57cec5SDimitry Andric   }
52170b57cec5SDimitry Andric 
52180b57cec5SDimitry Andric   IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->Ident;
52190b57cec5SDimitry Andric   TypeSourceInfo *MatchingCTypeLoc = nullptr;
52200b57cec5SDimitry Andric   S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);
52210b57cec5SDimitry Andric   assert(MatchingCTypeLoc && "no type source info for attribute argument");
52220b57cec5SDimitry Andric 
5223a7dea167SDimitry Andric   D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
5224a7dea167SDimitry Andric       S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
5225a7dea167SDimitry Andric       AL.getMustBeNull()));
52260b57cec5SDimitry Andric }
52270b57cec5SDimitry Andric 
52280b57cec5SDimitry Andric static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
52290b57cec5SDimitry Andric   ParamIdx ArgCount;
52300b57cec5SDimitry Andric 
52310fca6ea1SDimitry Andric   if (!S.checkFunctionOrMethodParameterIndex(D, AL, 1, AL.getArgAsExpr(0),
52320b57cec5SDimitry Andric                                              ArgCount,
52330b57cec5SDimitry Andric                                              true /* CanIndexImplicitThis */))
52340b57cec5SDimitry Andric     return;
52350b57cec5SDimitry Andric 
52360b57cec5SDimitry Andric   // ArgCount isn't a parameter index [0;n), it's a count [1;n]
5237a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
5238a7dea167SDimitry Andric                  XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
52390b57cec5SDimitry Andric }
52400b57cec5SDimitry Andric 
5241480093f4SDimitry Andric static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
5242480093f4SDimitry Andric                                              const ParsedAttr &AL) {
52430fca6ea1SDimitry Andric   if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
52440fca6ea1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;
52450fca6ea1SDimitry Andric     return;
52460fca6ea1SDimitry Andric   }
5247480093f4SDimitry Andric   uint32_t Count = 0, Offset = 0;
52480fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Count, 0, true))
5249480093f4SDimitry Andric     return;
5250480093f4SDimitry Andric   if (AL.getNumArgs() == 2) {
5251480093f4SDimitry Andric     Expr *Arg = AL.getArgAsExpr(1);
52520fca6ea1SDimitry Andric     if (!S.checkUInt32Argument(AL, Arg, Offset, 1, true))
5253480093f4SDimitry Andric       return;
525455e4f9d5SDimitry Andric     if (Count < Offset) {
52550fca6ea1SDimitry Andric       S.Diag(S.getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
525655e4f9d5SDimitry Andric           << &AL << 0 << Count << Arg->getBeginLoc();
5257480093f4SDimitry Andric       return;
5258480093f4SDimitry Andric     }
5259480093f4SDimitry Andric   }
5260480093f4SDimitry Andric   D->addAttr(::new (S.Context)
5261480093f4SDimitry Andric                  PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));
5262480093f4SDimitry Andric }
5263480093f4SDimitry Andric 
52640fca6ea1SDimitry Andric static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5265fe6060f1SDimitry Andric   if (!AL.isArgIdent(0)) {
5266fe6060f1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5267fe6060f1SDimitry Andric         << AL << 1 << AANT_ArgumentIdentifier;
5268fe6060f1SDimitry Andric     return;
5269fe6060f1SDimitry Andric   }
5270fe6060f1SDimitry Andric 
5271fe6060f1SDimitry Andric   IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
5272fe6060f1SDimitry Andric   unsigned BuiltinID = Ident->getBuiltinID();
5273fe6060f1SDimitry Andric   StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
5274fe6060f1SDimitry Andric 
5275fe6060f1SDimitry Andric   bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
5276fe6060f1SDimitry Andric   bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
5277fe6060f1SDimitry Andric   bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
527881ad6265SDimitry Andric   bool IsHLSL = S.Context.getLangOpts().HLSL;
52790fca6ea1SDimitry Andric   if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||
52800fca6ea1SDimitry Andric       (IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&
52810fca6ea1SDimitry Andric        !S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||
52820fca6ea1SDimitry Andric       (IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||
528381ad6265SDimitry Andric       (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL)) {
5284fe6060f1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
5285fe6060f1SDimitry Andric     return;
5286fe6060f1SDimitry Andric   }
5287fe6060f1SDimitry Andric 
5288fe6060f1SDimitry Andric   D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
5289fe6060f1SDimitry Andric }
5290fe6060f1SDimitry Andric 
52910fca6ea1SDimitry Andric static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
52920fca6ea1SDimitry Andric   if (AL.isUsedAsTypeAttr())
52930fca6ea1SDimitry Andric     return;
52940fca6ea1SDimitry Andric 
52950fca6ea1SDimitry Andric   if (auto *CRD = dyn_cast<CXXRecordDecl>(D);
52960fca6ea1SDimitry Andric       !CRD || !(CRD->isClass() || CRD->isStruct())) {
52970fca6ea1SDimitry Andric     S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type_str)
52980fca6ea1SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << "classes";
52990fca6ea1SDimitry Andric     return;
53000fca6ea1SDimitry Andric   }
53010fca6ea1SDimitry Andric 
53020fca6ea1SDimitry Andric   handleSimpleAttribute<TypeNullableAttr>(S, D, AL);
53030fca6ea1SDimitry Andric }
53040fca6ea1SDimitry Andric 
53055f757f3fSDimitry Andric static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
53065f757f3fSDimitry Andric   if (!AL.hasParsedType()) {
53075f757f3fSDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
53085f757f3fSDimitry Andric     return;
53095f757f3fSDimitry Andric   }
53105f757f3fSDimitry Andric 
53115f757f3fSDimitry Andric   TypeSourceInfo *ParmTSI = nullptr;
53125f757f3fSDimitry Andric   QualType QT = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
53135f757f3fSDimitry Andric   assert(ParmTSI && "no type source info for attribute argument");
53145f757f3fSDimitry Andric   S.RequireCompleteType(ParmTSI->getTypeLoc().getBeginLoc(), QT,
53155f757f3fSDimitry Andric                         diag::err_incomplete_type);
53165f757f3fSDimitry Andric 
53175f757f3fSDimitry Andric   D->addAttr(::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
53185f757f3fSDimitry Andric }
53195f757f3fSDimitry Andric 
53200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
53210b57cec5SDimitry Andric // Microsoft specific attribute handlers.
53220b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
53230b57cec5SDimitry Andric 
5324a7dea167SDimitry Andric UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
53255ffd83dbSDimitry Andric                               StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
53260b57cec5SDimitry Andric   if (const auto *UA = D->getAttr<UuidAttr>()) {
53275ffd83dbSDimitry Andric     if (declaresSameEntity(UA->getGuidDecl(), GuidDecl))
53280b57cec5SDimitry Andric       return nullptr;
5329480093f4SDimitry Andric     if (!UA->getGuid().empty()) {
53300b57cec5SDimitry Andric       Diag(UA->getLocation(), diag::err_mismatched_uuid);
5331a7dea167SDimitry Andric       Diag(CI.getLoc(), diag::note_previous_uuid);
53320b57cec5SDimitry Andric       D->dropAttr<UuidAttr>();
53330b57cec5SDimitry Andric     }
5334480093f4SDimitry Andric   }
53350b57cec5SDimitry Andric 
53365ffd83dbSDimitry Andric   return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
53370b57cec5SDimitry Andric }
53380b57cec5SDimitry Andric 
53390b57cec5SDimitry Andric static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
53400b57cec5SDimitry Andric   if (!S.LangOpts.CPlusPlus) {
53410b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
53420b57cec5SDimitry Andric         << AL << AttributeLangSupport::C;
53430b57cec5SDimitry Andric     return;
53440b57cec5SDimitry Andric   }
53450b57cec5SDimitry Andric 
53465ffd83dbSDimitry Andric   StringRef OrigStrRef;
53470b57cec5SDimitry Andric   SourceLocation LiteralLoc;
53485ffd83dbSDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, OrigStrRef, &LiteralLoc))
53490b57cec5SDimitry Andric     return;
53500b57cec5SDimitry Andric 
53510b57cec5SDimitry Andric   // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
53520b57cec5SDimitry Andric   // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
53535ffd83dbSDimitry Andric   StringRef StrRef = OrigStrRef;
53540b57cec5SDimitry Andric   if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
53550b57cec5SDimitry Andric     StrRef = StrRef.drop_front().drop_back();
53560b57cec5SDimitry Andric 
53570b57cec5SDimitry Andric   // Validate GUID length.
53580b57cec5SDimitry Andric   if (StrRef.size() != 36) {
53590b57cec5SDimitry Andric     S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
53600b57cec5SDimitry Andric     return;
53610b57cec5SDimitry Andric   }
53620b57cec5SDimitry Andric 
53630b57cec5SDimitry Andric   for (unsigned i = 0; i < 36; ++i) {
53640b57cec5SDimitry Andric     if (i == 8 || i == 13 || i == 18 || i == 23) {
53650b57cec5SDimitry Andric       if (StrRef[i] != '-') {
53660b57cec5SDimitry Andric         S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
53670b57cec5SDimitry Andric         return;
53680b57cec5SDimitry Andric       }
53690b57cec5SDimitry Andric     } else if (!isHexDigit(StrRef[i])) {
53700b57cec5SDimitry Andric       S.Diag(LiteralLoc, diag::err_attribute_uuid_malformed_guid);
53710b57cec5SDimitry Andric       return;
53720b57cec5SDimitry Andric     }
53730b57cec5SDimitry Andric   }
53740b57cec5SDimitry Andric 
53755ffd83dbSDimitry Andric   // Convert to our parsed format and canonicalize.
53765ffd83dbSDimitry Andric   MSGuidDecl::Parts Parsed;
53775ffd83dbSDimitry Andric   StrRef.substr(0, 8).getAsInteger(16, Parsed.Part1);
53785ffd83dbSDimitry Andric   StrRef.substr(9, 4).getAsInteger(16, Parsed.Part2);
53795ffd83dbSDimitry Andric   StrRef.substr(14, 4).getAsInteger(16, Parsed.Part3);
53805ffd83dbSDimitry Andric   for (unsigned i = 0; i != 8; ++i)
53815ffd83dbSDimitry Andric     StrRef.substr(19 + 2 * i + (i >= 2 ? 1 : 0), 2)
53825ffd83dbSDimitry Andric         .getAsInteger(16, Parsed.Part4And5[i]);
53835ffd83dbSDimitry Andric   MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parsed);
53845ffd83dbSDimitry Andric 
53850b57cec5SDimitry Andric   // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
53860b57cec5SDimitry Andric   // the only thing in the [] list, the [] too), and add an insertion of
53870b57cec5SDimitry Andric   // __declspec(uuid(...)).  But sadly, neither the SourceLocs of the commas
53880b57cec5SDimitry Andric   // separating attributes nor of the [ and the ] are in the AST.
53890b57cec5SDimitry Andric   // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
53900b57cec5SDimitry Andric   // on cfe-dev.
53910b57cec5SDimitry Andric   if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
53920b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_atl_uuid_deprecated);
53930b57cec5SDimitry Andric 
53945ffd83dbSDimitry Andric   UuidAttr *UA = S.mergeUuidAttr(D, AL, OrigStrRef, Guid);
53950b57cec5SDimitry Andric   if (UA)
53960b57cec5SDimitry Andric     D->addAttr(UA);
53970b57cec5SDimitry Andric }
53980b57cec5SDimitry Andric 
53990b57cec5SDimitry Andric static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
54000b57cec5SDimitry Andric   if (!S.LangOpts.CPlusPlus) {
54010b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
54020b57cec5SDimitry Andric         << AL << AttributeLangSupport::C;
54030b57cec5SDimitry Andric     return;
54040b57cec5SDimitry Andric   }
54050b57cec5SDimitry Andric   MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
5406480093f4SDimitry Andric       D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());
54070b57cec5SDimitry Andric   if (IA) {
54080b57cec5SDimitry Andric     D->addAttr(IA);
54090b57cec5SDimitry Andric     S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D));
54100b57cec5SDimitry Andric   }
54110b57cec5SDimitry Andric }
54120b57cec5SDimitry Andric 
54130b57cec5SDimitry Andric static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
54140b57cec5SDimitry Andric   const auto *VD = cast<VarDecl>(D);
54150b57cec5SDimitry Andric   if (!S.Context.getTargetInfo().isTLSSupported()) {
54160b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_thread_unsupported);
54170b57cec5SDimitry Andric     return;
54180b57cec5SDimitry Andric   }
54190b57cec5SDimitry Andric   if (VD->getTSCSpec() != TSCS_unspecified) {
54200b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_declspec_thread_on_thread_variable);
54210b57cec5SDimitry Andric     return;
54220b57cec5SDimitry Andric   }
54230b57cec5SDimitry Andric   if (VD->hasLocalStorage()) {
54240b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
54250b57cec5SDimitry Andric     return;
54260b57cec5SDimitry Andric   }
5427a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ThreadAttr(S.Context, AL));
54280b57cec5SDimitry Andric }
54290b57cec5SDimitry Andric 
54305f757f3fSDimitry Andric static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
54315f757f3fSDimitry Andric   if (!S.getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2022_3)) {
54325f757f3fSDimitry Andric     S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
54335f757f3fSDimitry Andric         << AL << AL.getRange();
54345f757f3fSDimitry Andric     return;
54355f757f3fSDimitry Andric   }
54365f757f3fSDimitry Andric   auto *FD = cast<FunctionDecl>(D);
54375f757f3fSDimitry Andric   if (FD->isConstexprSpecified() || FD->isConsteval()) {
54385f757f3fSDimitry Andric     S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
54395f757f3fSDimitry Andric         << FD->isConsteval() << FD;
54405f757f3fSDimitry Andric     return;
54415f757f3fSDimitry Andric   }
54425f757f3fSDimitry Andric   if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
54435f757f3fSDimitry Andric     if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
54445f757f3fSDimitry Andric       S.Diag(AL.getLoc(), diag::err_ms_constexpr_cannot_be_applied)
54455f757f3fSDimitry Andric           << /*virtual*/ 2 << MD;
54465f757f3fSDimitry Andric       return;
54475f757f3fSDimitry Andric     }
54485f757f3fSDimitry Andric   }
54495f757f3fSDimitry Andric   D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));
54505f757f3fSDimitry Andric }
54515f757f3fSDimitry Andric 
54520b57cec5SDimitry Andric static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
54530b57cec5SDimitry Andric   SmallVector<StringRef, 4> Tags;
54540b57cec5SDimitry Andric   for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
54550b57cec5SDimitry Andric     StringRef Tag;
54560b57cec5SDimitry Andric     if (!S.checkStringLiteralArgumentAttr(AL, I, Tag))
54570b57cec5SDimitry Andric       return;
54580b57cec5SDimitry Andric     Tags.push_back(Tag);
54590b57cec5SDimitry Andric   }
54600b57cec5SDimitry Andric 
54610b57cec5SDimitry Andric   if (const auto *NS = dyn_cast<NamespaceDecl>(D)) {
54620b57cec5SDimitry Andric     if (!NS->isInline()) {
54630b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 0;
54640b57cec5SDimitry Andric       return;
54650b57cec5SDimitry Andric     }
54660b57cec5SDimitry Andric     if (NS->isAnonymousNamespace()) {
54670b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attr_abi_tag_namespace) << 1;
54680b57cec5SDimitry Andric       return;
54690b57cec5SDimitry Andric     }
54700b57cec5SDimitry Andric     if (AL.getNumArgs() == 0)
54710b57cec5SDimitry Andric       Tags.push_back(NS->getName());
5472fe6060f1SDimitry Andric   } else if (!AL.checkAtLeastNumArgs(S, 1))
54730b57cec5SDimitry Andric     return;
54740b57cec5SDimitry Andric 
54750b57cec5SDimitry Andric   // Store tags sorted and without duplicates.
54760b57cec5SDimitry Andric   llvm::sort(Tags);
54770b57cec5SDimitry Andric   Tags.erase(std::unique(Tags.begin(), Tags.end()), Tags.end());
54780b57cec5SDimitry Andric 
54790b57cec5SDimitry Andric   D->addAttr(::new (S.Context)
5480a7dea167SDimitry Andric                  AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
54810b57cec5SDimitry Andric }
54820b57cec5SDimitry Andric 
5483349cc55cSDimitry Andric static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
5484349cc55cSDimitry Andric   for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
5485349cc55cSDimitry Andric     if (I->getBTFDeclTag() == Tag)
5486349cc55cSDimitry Andric       return true;
5487349cc55cSDimitry Andric   }
5488349cc55cSDimitry Andric   return false;
5489349cc55cSDimitry Andric }
5490349cc55cSDimitry Andric 
5491349cc55cSDimitry Andric static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5492349cc55cSDimitry Andric   StringRef Str;
5493349cc55cSDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
5494349cc55cSDimitry Andric     return;
5495349cc55cSDimitry Andric   if (hasBTFDeclTagAttr(D, Str))
5496349cc55cSDimitry Andric     return;
5497349cc55cSDimitry Andric 
5498349cc55cSDimitry Andric   D->addAttr(::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
5499349cc55cSDimitry Andric }
5500349cc55cSDimitry Andric 
5501349cc55cSDimitry Andric BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
5502349cc55cSDimitry Andric   if (hasBTFDeclTagAttr(D, AL.getBTFDeclTag()))
5503349cc55cSDimitry Andric     return nullptr;
5504349cc55cSDimitry Andric   return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
5505349cc55cSDimitry Andric }
5506349cc55cSDimitry Andric 
55070b57cec5SDimitry Andric static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
55080b57cec5SDimitry Andric   // Dispatch the interrupt attribute based on the current target.
55090b57cec5SDimitry Andric   switch (S.Context.getTargetInfo().getTriple().getArch()) {
55100b57cec5SDimitry Andric   case llvm::Triple::msp430:
55110fca6ea1SDimitry Andric     S.MSP430().handleInterruptAttr(D, AL);
55120b57cec5SDimitry Andric     break;
55130b57cec5SDimitry Andric   case llvm::Triple::mipsel:
55140b57cec5SDimitry Andric   case llvm::Triple::mips:
55150fca6ea1SDimitry Andric     S.MIPS().handleInterruptAttr(D, AL);
55160b57cec5SDimitry Andric     break;
5517fe6060f1SDimitry Andric   case llvm::Triple::m68k:
55180fca6ea1SDimitry Andric     S.M68k().handleInterruptAttr(D, AL);
5519fe6060f1SDimitry Andric     break;
55200b57cec5SDimitry Andric   case llvm::Triple::x86:
55210b57cec5SDimitry Andric   case llvm::Triple::x86_64:
55220fca6ea1SDimitry Andric     S.X86().handleAnyInterruptAttr(D, AL);
55230b57cec5SDimitry Andric     break;
55240b57cec5SDimitry Andric   case llvm::Triple::avr:
55250fca6ea1SDimitry Andric     S.AVR().handleInterruptAttr(D, AL);
55260b57cec5SDimitry Andric     break;
55270b57cec5SDimitry Andric   case llvm::Triple::riscv32:
55280b57cec5SDimitry Andric   case llvm::Triple::riscv64:
55290fca6ea1SDimitry Andric     S.RISCV().handleInterruptAttr(D, AL);
55300b57cec5SDimitry Andric     break;
55310b57cec5SDimitry Andric   default:
55320fca6ea1SDimitry Andric     S.ARM().handleInterruptAttr(D, AL);
55330b57cec5SDimitry Andric     break;
55340b57cec5SDimitry Andric   }
55350b57cec5SDimitry Andric }
55360b57cec5SDimitry Andric 
55370b57cec5SDimitry Andric static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
55380b57cec5SDimitry Andric   uint32_t Version;
55390b57cec5SDimitry Andric   Expr *VersionExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
55400fca6ea1SDimitry Andric   if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(0), Version))
55410b57cec5SDimitry Andric     return;
55420b57cec5SDimitry Andric 
55430b57cec5SDimitry Andric   // TODO: Investigate what happens with the next major version of MSVC.
55440b57cec5SDimitry Andric   if (Version != LangOptions::MSVC2015 / 100) {
55450b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
55460b57cec5SDimitry Andric         << AL << Version << VersionExpr->getSourceRange();
55470b57cec5SDimitry Andric     return;
55480b57cec5SDimitry Andric   }
55490b57cec5SDimitry Andric 
55500b57cec5SDimitry Andric   // The attribute expects a "major" version number like 19, but new versions of
55510b57cec5SDimitry Andric   // MSVC have moved to updating the "minor", or less significant numbers, so we
55520b57cec5SDimitry Andric   // have to multiply by 100 now.
55530b57cec5SDimitry Andric   Version *= 100;
55540b57cec5SDimitry Andric 
5555a7dea167SDimitry Andric   D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
55560b57cec5SDimitry Andric }
55570b57cec5SDimitry Andric 
5558a7dea167SDimitry Andric DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,
5559a7dea167SDimitry Andric                                         const AttributeCommonInfo &CI) {
55600b57cec5SDimitry Andric   if (D->hasAttr<DLLExportAttr>()) {
5561a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'dllimport'";
55620b57cec5SDimitry Andric     return nullptr;
55630b57cec5SDimitry Andric   }
55640b57cec5SDimitry Andric 
55650b57cec5SDimitry Andric   if (D->hasAttr<DLLImportAttr>())
55660b57cec5SDimitry Andric     return nullptr;
55670b57cec5SDimitry Andric 
5568a7dea167SDimitry Andric   return ::new (Context) DLLImportAttr(Context, CI);
55690b57cec5SDimitry Andric }
55700b57cec5SDimitry Andric 
5571a7dea167SDimitry Andric DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
5572a7dea167SDimitry Andric                                         const AttributeCommonInfo &CI) {
55730b57cec5SDimitry Andric   if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
55740b57cec5SDimitry Andric     Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
55750b57cec5SDimitry Andric     D->dropAttr<DLLImportAttr>();
55760b57cec5SDimitry Andric   }
55770b57cec5SDimitry Andric 
55780b57cec5SDimitry Andric   if (D->hasAttr<DLLExportAttr>())
55790b57cec5SDimitry Andric     return nullptr;
55800b57cec5SDimitry Andric 
5581a7dea167SDimitry Andric   return ::new (Context) DLLExportAttr(Context, CI);
55820b57cec5SDimitry Andric }
55830b57cec5SDimitry Andric 
55840b57cec5SDimitry Andric static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
55850b57cec5SDimitry Andric   if (isa<ClassTemplatePartialSpecializationDecl>(D) &&
5586e8d8bef9SDimitry Andric       (S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
55870b57cec5SDimitry Andric     S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
55880b57cec5SDimitry Andric     return;
55890b57cec5SDimitry Andric   }
55900b57cec5SDimitry Andric 
55910b57cec5SDimitry Andric   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
55920b57cec5SDimitry Andric     if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
5593e8d8bef9SDimitry Andric         !(S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
55940b57cec5SDimitry Andric       // MinGW doesn't allow dllimport on inline functions.
55950b57cec5SDimitry Andric       S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
55960b57cec5SDimitry Andric           << A;
55970b57cec5SDimitry Andric       return;
55980b57cec5SDimitry Andric     }
55990b57cec5SDimitry Andric   }
56000b57cec5SDimitry Andric 
56010b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
5602e8d8bef9SDimitry Andric     if ((S.Context.getTargetInfo().shouldDLLImportComdatSymbols()) &&
56030b57cec5SDimitry Andric         MD->getParent()->isLambda()) {
56040b57cec5SDimitry Andric       S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
56050b57cec5SDimitry Andric       return;
56060b57cec5SDimitry Andric     }
56070b57cec5SDimitry Andric   }
56080b57cec5SDimitry Andric 
56090b57cec5SDimitry Andric   Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
5610a7dea167SDimitry Andric                       ? (Attr *)S.mergeDLLExportAttr(D, A)
5611a7dea167SDimitry Andric                       : (Attr *)S.mergeDLLImportAttr(D, A);
56120b57cec5SDimitry Andric   if (NewAttr)
56130b57cec5SDimitry Andric     D->addAttr(NewAttr);
56140b57cec5SDimitry Andric }
56150b57cec5SDimitry Andric 
56160b57cec5SDimitry Andric MSInheritanceAttr *
5617a7dea167SDimitry Andric Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
5618a7dea167SDimitry Andric                              bool BestCase,
5619480093f4SDimitry Andric                              MSInheritanceModel Model) {
56200b57cec5SDimitry Andric   if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
5621480093f4SDimitry Andric     if (IA->getInheritanceModel() == Model)
56220b57cec5SDimitry Andric       return nullptr;
56230b57cec5SDimitry Andric     Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
56240b57cec5SDimitry Andric         << 1 /*previous declaration*/;
5625a7dea167SDimitry Andric     Diag(CI.getLoc(), diag::note_previous_ms_inheritance);
56260b57cec5SDimitry Andric     D->dropAttr<MSInheritanceAttr>();
56270b57cec5SDimitry Andric   }
56280b57cec5SDimitry Andric 
56290b57cec5SDimitry Andric   auto *RD = cast<CXXRecordDecl>(D);
56300b57cec5SDimitry Andric   if (RD->hasDefinition()) {
5631a7dea167SDimitry Andric     if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
5632480093f4SDimitry Andric                                            Model)) {
56330b57cec5SDimitry Andric       return nullptr;
56340b57cec5SDimitry Andric     }
56350b57cec5SDimitry Andric   } else {
56360b57cec5SDimitry Andric     if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {
5637a7dea167SDimitry Andric       Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
56380b57cec5SDimitry Andric           << 1 /*partial specialization*/;
56390b57cec5SDimitry Andric       return nullptr;
56400b57cec5SDimitry Andric     }
56410b57cec5SDimitry Andric     if (RD->getDescribedClassTemplate()) {
5642a7dea167SDimitry Andric       Diag(CI.getLoc(), diag::warn_ignored_ms_inheritance)
56430b57cec5SDimitry Andric           << 0 /*primary template*/;
56440b57cec5SDimitry Andric       return nullptr;
56450b57cec5SDimitry Andric     }
56460b57cec5SDimitry Andric   }
56470b57cec5SDimitry Andric 
5648a7dea167SDimitry Andric   return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
56490b57cec5SDimitry Andric }
56500b57cec5SDimitry Andric 
56510b57cec5SDimitry Andric static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
56520b57cec5SDimitry Andric   // The capability attributes take a single string parameter for the name of
56530b57cec5SDimitry Andric   // the capability they represent. The lockable attribute does not take any
56540b57cec5SDimitry Andric   // parameters. However, semantically, both attributes represent the same
56550b57cec5SDimitry Andric   // concept, and so they use the same semantic attribute. Eventually, the
56560b57cec5SDimitry Andric   // lockable attribute will be removed.
56570b57cec5SDimitry Andric   //
56580b57cec5SDimitry Andric   // For backward compatibility, any capability which has no specified string
56590b57cec5SDimitry Andric   // literal will be considered a "mutex."
56600b57cec5SDimitry Andric   StringRef N("mutex");
56610b57cec5SDimitry Andric   SourceLocation LiteralLoc;
56620b57cec5SDimitry Andric   if (AL.getKind() == ParsedAttr::AT_Capability &&
56630b57cec5SDimitry Andric       !S.checkStringLiteralArgumentAttr(AL, 0, N, &LiteralLoc))
56640b57cec5SDimitry Andric     return;
56650b57cec5SDimitry Andric 
5666a7dea167SDimitry Andric   D->addAttr(::new (S.Context) CapabilityAttr(S.Context, AL, N));
56670b57cec5SDimitry Andric }
56680b57cec5SDimitry Andric 
56690b57cec5SDimitry Andric static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
56700b57cec5SDimitry Andric   SmallVector<Expr*, 1> Args;
56710b57cec5SDimitry Andric   if (!checkLockFunAttrCommon(S, D, AL, Args))
56720b57cec5SDimitry Andric     return;
56730b57cec5SDimitry Andric 
5674a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
5675a7dea167SDimitry Andric                  AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
56760b57cec5SDimitry Andric }
56770b57cec5SDimitry Andric 
56780b57cec5SDimitry Andric static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
56790b57cec5SDimitry Andric                                         const ParsedAttr &AL) {
56800b57cec5SDimitry Andric   SmallVector<Expr*, 1> Args;
56810b57cec5SDimitry Andric   if (!checkLockFunAttrCommon(S, D, AL, Args))
56820b57cec5SDimitry Andric     return;
56830b57cec5SDimitry Andric 
5684a7dea167SDimitry Andric   D->addAttr(::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
5685a7dea167SDimitry Andric                                                      Args.size()));
56860b57cec5SDimitry Andric }
56870b57cec5SDimitry Andric 
56880b57cec5SDimitry Andric static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
56890b57cec5SDimitry Andric                                            const ParsedAttr &AL) {
56900b57cec5SDimitry Andric   SmallVector<Expr*, 2> Args;
56910b57cec5SDimitry Andric   if (!checkTryLockFunAttrCommon(S, D, AL, Args))
56920b57cec5SDimitry Andric     return;
56930b57cec5SDimitry Andric 
5694a7dea167SDimitry Andric   D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(
5695a7dea167SDimitry Andric       S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
56960b57cec5SDimitry Andric }
56970b57cec5SDimitry Andric 
56980b57cec5SDimitry Andric static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
56990b57cec5SDimitry Andric                                         const ParsedAttr &AL) {
57000b57cec5SDimitry Andric   // Check that all arguments are lockable objects.
57010b57cec5SDimitry Andric   SmallVector<Expr *, 1> Args;
57020b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, true);
57030b57cec5SDimitry Andric 
5704a7dea167SDimitry Andric   D->addAttr(::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
5705a7dea167SDimitry Andric                                                      Args.size()));
57060b57cec5SDimitry Andric }
57070b57cec5SDimitry Andric 
57080b57cec5SDimitry Andric static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
57090b57cec5SDimitry Andric                                          const ParsedAttr &AL) {
5710fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
57110b57cec5SDimitry Andric     return;
57120b57cec5SDimitry Andric 
57130b57cec5SDimitry Andric   // check that all arguments are lockable objects
57140b57cec5SDimitry Andric   SmallVector<Expr*, 1> Args;
57150b57cec5SDimitry Andric   checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
57160b57cec5SDimitry Andric   if (Args.empty())
57170b57cec5SDimitry Andric     return;
57180b57cec5SDimitry Andric 
57190b57cec5SDimitry Andric   RequiresCapabilityAttr *RCA = ::new (S.Context)
5720a7dea167SDimitry Andric       RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
57210b57cec5SDimitry Andric 
57220b57cec5SDimitry Andric   D->addAttr(RCA);
57230b57cec5SDimitry Andric }
57240b57cec5SDimitry Andric 
57250b57cec5SDimitry Andric static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
57260b57cec5SDimitry Andric   if (const auto *NSD = dyn_cast<NamespaceDecl>(D)) {
57270b57cec5SDimitry Andric     if (NSD->isAnonymousNamespace()) {
57280b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_deprecated_anonymous_namespace);
57290b57cec5SDimitry Andric       // Do not want to attach the attribute to the namespace because that will
57300b57cec5SDimitry Andric       // cause confusing diagnostic reports for uses of declarations within the
57310b57cec5SDimitry Andric       // namespace.
57320b57cec5SDimitry Andric       return;
57330b57cec5SDimitry Andric     }
5734fe6060f1SDimitry Andric   } else if (isa<UsingDecl, UnresolvedUsingTypenameDecl,
5735fe6060f1SDimitry Andric                  UnresolvedUsingValueDecl>(D)) {
5736fe6060f1SDimitry Andric     S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
5737fe6060f1SDimitry Andric         << AL;
5738fe6060f1SDimitry Andric     return;
57390b57cec5SDimitry Andric   }
57400b57cec5SDimitry Andric 
57410b57cec5SDimitry Andric   // Handle the cases where the attribute has a text message.
57420b57cec5SDimitry Andric   StringRef Str, Replacement;
57430b57cec5SDimitry Andric   if (AL.isArgExpr(0) && AL.getArgAsExpr(0) &&
57440b57cec5SDimitry Andric       !S.checkStringLiteralArgumentAttr(AL, 0, Str))
57450b57cec5SDimitry Andric     return;
57460b57cec5SDimitry Andric 
5747fe6060f1SDimitry Andric   // Support a single optional message only for Declspec and [[]] spellings.
5748fe6060f1SDimitry Andric   if (AL.isDeclspecAttribute() || AL.isStandardAttributeSyntax())
5749fe6060f1SDimitry Andric     AL.checkAtMostNumArgs(S, 1);
57500b57cec5SDimitry Andric   else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) &&
57510b57cec5SDimitry Andric            !S.checkStringLiteralArgumentAttr(AL, 1, Replacement))
57520b57cec5SDimitry Andric     return;
57530b57cec5SDimitry Andric 
57540b57cec5SDimitry Andric   if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
57550b57cec5SDimitry Andric     S.Diag(AL.getLoc(), diag::ext_cxx14_attr) << AL;
57560b57cec5SDimitry Andric 
5757a7dea167SDimitry Andric   D->addAttr(::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
57580b57cec5SDimitry Andric }
57590b57cec5SDimitry Andric 
57600b57cec5SDimitry Andric static bool isGlobalVar(const Decl *D) {
57610b57cec5SDimitry Andric   if (const auto *S = dyn_cast<VarDecl>(D))
57620b57cec5SDimitry Andric     return S->hasGlobalStorage();
57630b57cec5SDimitry Andric   return false;
57640b57cec5SDimitry Andric }
57650b57cec5SDimitry Andric 
576681ad6265SDimitry Andric static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
576781ad6265SDimitry Andric   return Sanitizer == "address" || Sanitizer == "hwaddress" ||
576881ad6265SDimitry Andric          Sanitizer == "memtag";
576981ad6265SDimitry Andric }
577081ad6265SDimitry Andric 
57710b57cec5SDimitry Andric static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5772fe6060f1SDimitry Andric   if (!AL.checkAtLeastNumArgs(S, 1))
57730b57cec5SDimitry Andric     return;
57740b57cec5SDimitry Andric 
57750b57cec5SDimitry Andric   std::vector<StringRef> Sanitizers;
57760b57cec5SDimitry Andric 
57770b57cec5SDimitry Andric   for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
57780b57cec5SDimitry Andric     StringRef SanitizerName;
57790b57cec5SDimitry Andric     SourceLocation LiteralLoc;
57800b57cec5SDimitry Andric 
57810b57cec5SDimitry Andric     if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc))
57820b57cec5SDimitry Andric       return;
57830b57cec5SDimitry Andric 
57840b57cec5SDimitry Andric     if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
5785fe6060f1SDimitry Andric             SanitizerMask() &&
5786fe6060f1SDimitry Andric         SanitizerName != "coverage")
57870b57cec5SDimitry Andric       S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
578881ad6265SDimitry Andric     else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))
5789bdd1243dSDimitry Andric       S.Diag(D->getLocation(), diag::warn_attribute_type_not_supported_global)
5790bdd1243dSDimitry Andric           << AL << SanitizerName;
57910b57cec5SDimitry Andric     Sanitizers.push_back(SanitizerName);
57920b57cec5SDimitry Andric   }
57930b57cec5SDimitry Andric 
5794a7dea167SDimitry Andric   D->addAttr(::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
5795a7dea167SDimitry Andric                                               Sanitizers.size()));
57960b57cec5SDimitry Andric }
57970b57cec5SDimitry Andric 
57980b57cec5SDimitry Andric static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
57990b57cec5SDimitry Andric                                          const ParsedAttr &AL) {
5800a7dea167SDimitry Andric   StringRef AttrName = AL.getAttrName()->getName();
58010b57cec5SDimitry Andric   normalizeName(AttrName);
58020b57cec5SDimitry Andric   StringRef SanitizerName = llvm::StringSwitch<StringRef>(AttrName)
58030b57cec5SDimitry Andric                                 .Case("no_address_safety_analysis", "address")
58040b57cec5SDimitry Andric                                 .Case("no_sanitize_address", "address")
58050b57cec5SDimitry Andric                                 .Case("no_sanitize_thread", "thread")
58060b57cec5SDimitry Andric                                 .Case("no_sanitize_memory", "memory");
58070b57cec5SDimitry Andric   if (isGlobalVar(D) && SanitizerName != "address")
58080b57cec5SDimitry Andric     S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
580906c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
58100b57cec5SDimitry Andric 
58110b57cec5SDimitry Andric   // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
58120b57cec5SDimitry Andric   // NoSanitizeAttr object; but we need to calculate the correct spelling list
58130b57cec5SDimitry Andric   // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
58140b57cec5SDimitry Andric   // has the same spellings as the index for NoSanitizeAttr. We don't have a
58150b57cec5SDimitry Andric   // general way to "translate" between the two, so this hack attempts to work
5816349cc55cSDimitry Andric   // around the issue with hard-coded indices. This is critical for calling
58170b57cec5SDimitry Andric   // getSpelling() or prettyPrint() on the resulting semantic attribute object
58180b57cec5SDimitry Andric   // without failing assertions.
58190b57cec5SDimitry Andric   unsigned TranslatedSpellingIndex = 0;
5820fe6060f1SDimitry Andric   if (AL.isStandardAttributeSyntax())
58210b57cec5SDimitry Andric     TranslatedSpellingIndex = 1;
58220b57cec5SDimitry Andric 
5823a7dea167SDimitry Andric   AttributeCommonInfo Info = AL;
5824a7dea167SDimitry Andric   Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
5825a7dea167SDimitry Andric   D->addAttr(::new (S.Context)
5826a7dea167SDimitry Andric                  NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
58270b57cec5SDimitry Andric }
58280b57cec5SDimitry Andric 
58290b57cec5SDimitry Andric static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
58300b57cec5SDimitry Andric   if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
58310b57cec5SDimitry Andric     D->addAttr(Internal);
58320b57cec5SDimitry Andric }
58330b57cec5SDimitry Andric 
583481ad6265SDimitry Andric static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
583581ad6265SDimitry Andric   // Check that the argument is a string literal.
583681ad6265SDimitry Andric   StringRef KindStr;
583781ad6265SDimitry Andric   SourceLocation LiteralLoc;
583881ad6265SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
583981ad6265SDimitry Andric     return;
584081ad6265SDimitry Andric 
584181ad6265SDimitry Andric   ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
584281ad6265SDimitry Andric   if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(KindStr, Kind)) {
584381ad6265SDimitry Andric     S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
584481ad6265SDimitry Andric         << AL << KindStr;
584581ad6265SDimitry Andric     return;
584681ad6265SDimitry Andric   }
584781ad6265SDimitry Andric 
584881ad6265SDimitry Andric   D->dropAttr<ZeroCallUsedRegsAttr>();
584981ad6265SDimitry Andric   D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
585081ad6265SDimitry Andric }
585181ad6265SDimitry Andric 
58520fca6ea1SDimitry Andric static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
58530fca6ea1SDimitry Andric   auto *FD = dyn_cast<FieldDecl>(D);
58540fca6ea1SDimitry Andric   assert(FD);
58550fca6ea1SDimitry Andric 
58560fca6ea1SDimitry Andric   auto *CountExpr = AL.getArgAsExpr(0);
58570fca6ea1SDimitry Andric   if (!CountExpr)
5858297eecfbSDimitry Andric     return;
5859297eecfbSDimitry Andric 
58600fca6ea1SDimitry Andric   bool CountInBytes;
58610fca6ea1SDimitry Andric   bool OrNull;
58620fca6ea1SDimitry Andric   switch (AL.getKind()) {
58630fca6ea1SDimitry Andric   case ParsedAttr::AT_CountedBy:
58640fca6ea1SDimitry Andric     CountInBytes = false;
58650fca6ea1SDimitry Andric     OrNull = false;
5866297eecfbSDimitry Andric     break;
58670fca6ea1SDimitry Andric   case ParsedAttr::AT_CountedByOrNull:
58680fca6ea1SDimitry Andric     CountInBytes = false;
58690fca6ea1SDimitry Andric     OrNull = true;
58700fca6ea1SDimitry Andric     break;
58710fca6ea1SDimitry Andric   case ParsedAttr::AT_SizedBy:
58720fca6ea1SDimitry Andric     CountInBytes = true;
58730fca6ea1SDimitry Andric     OrNull = false;
58740fca6ea1SDimitry Andric     break;
58750fca6ea1SDimitry Andric   case ParsedAttr::AT_SizedByOrNull:
58760fca6ea1SDimitry Andric     CountInBytes = true;
58770fca6ea1SDimitry Andric     OrNull = true;
58780fca6ea1SDimitry Andric     break;
58790fca6ea1SDimitry Andric   default:
58800fca6ea1SDimitry Andric     llvm_unreachable("unexpected counted_by family attribute");
5881297eecfbSDimitry Andric   }
5882297eecfbSDimitry Andric 
58830fca6ea1SDimitry Andric   llvm::SmallVector<TypeCoupledDeclRefInfo, 1> Decls;
58840fca6ea1SDimitry Andric   if (S.CheckCountedByAttrOnField(FD, CountExpr, Decls, CountInBytes, OrNull))
58850fca6ea1SDimitry Andric     return;
5886297eecfbSDimitry Andric 
58870fca6ea1SDimitry Andric   QualType CAT = S.BuildCountAttributedArrayOrPointerType(
58880fca6ea1SDimitry Andric       FD->getType(), CountExpr, CountInBytes, OrNull);
58890fca6ea1SDimitry Andric   FD->setType(CAT);
5890297eecfbSDimitry Andric }
5891297eecfbSDimitry Andric 
5892753f127fSDimitry Andric static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,
5893753f127fSDimitry Andric                                            const ParsedAttr &AL) {
5894753f127fSDimitry Andric   StringRef KindStr;
5895753f127fSDimitry Andric   SourceLocation LiteralLoc;
5896753f127fSDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, KindStr, &LiteralLoc))
5897753f127fSDimitry Andric     return;
5898753f127fSDimitry Andric 
5899753f127fSDimitry Andric   FunctionReturnThunksAttr::Kind Kind;
5900753f127fSDimitry Andric   if (!FunctionReturnThunksAttr::ConvertStrToKind(KindStr, Kind)) {
5901753f127fSDimitry Andric     S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported)
5902753f127fSDimitry Andric         << AL << KindStr;
5903753f127fSDimitry Andric     return;
5904753f127fSDimitry Andric   }
5905753f127fSDimitry Andric   // FIXME: it would be good to better handle attribute merging rather than
5906753f127fSDimitry Andric   // silently replacing the existing attribute, so long as it does not break
5907753f127fSDimitry Andric   // the expected codegen tests.
5908753f127fSDimitry Andric   D->dropAttr<FunctionReturnThunksAttr>();
5909753f127fSDimitry Andric   D->addAttr(FunctionReturnThunksAttr::Create(S.Context, Kind, AL));
5910753f127fSDimitry Andric }
5911753f127fSDimitry Andric 
591206c3fb27SDimitry Andric static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D,
591306c3fb27SDimitry Andric                                                    const ParsedAttr &AL) {
591406c3fb27SDimitry Andric   assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
591506c3fb27SDimitry Andric   handleSimpleAttribute<AvailableOnlyInDefaultEvalMethodAttr>(S, D, AL);
591606c3fb27SDimitry Andric }
591706c3fb27SDimitry Andric 
591806c3fb27SDimitry Andric static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
591906c3fb27SDimitry Andric   auto *VDecl = dyn_cast<VarDecl>(D);
592006c3fb27SDimitry Andric   if (VDecl && !VDecl->isFunctionPointerType()) {
592106c3fb27SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_ignored_non_function_pointer)
592206c3fb27SDimitry Andric         << AL << VDecl;
592306c3fb27SDimitry Andric     return;
592406c3fb27SDimitry Andric   }
592506c3fb27SDimitry Andric   D->addAttr(NoMergeAttr::Create(S.Context, AL));
592606c3fb27SDimitry Andric }
592706c3fb27SDimitry Andric 
59285f757f3fSDimitry Andric static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
59295f757f3fSDimitry Andric   D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
59305f757f3fSDimitry Andric }
59315f757f3fSDimitry Andric 
59320b57cec5SDimitry Andric static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
59330b57cec5SDimitry Andric   if (!cast<VarDecl>(D)->hasGlobalStorage()) {
59340b57cec5SDimitry Andric     S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
59350b57cec5SDimitry Andric         << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
59360b57cec5SDimitry Andric     return;
59370b57cec5SDimitry Andric   }
59380b57cec5SDimitry Andric 
59390b57cec5SDimitry Andric   if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
5940fe6060f1SDimitry Andric     handleSimpleAttribute<AlwaysDestroyAttr>(S, D, A);
59410b57cec5SDimitry Andric   else
5942fe6060f1SDimitry Andric     handleSimpleAttribute<NoDestroyAttr>(S, D, A);
59430b57cec5SDimitry Andric }
59440b57cec5SDimitry Andric 
59450b57cec5SDimitry Andric static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
59460b57cec5SDimitry Andric   assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
59470b57cec5SDimitry Andric          "uninitialized is only valid on automatic duration variables");
5948a7dea167SDimitry Andric   D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
59490b57cec5SDimitry Andric }
59500b57cec5SDimitry Andric 
59510b57cec5SDimitry Andric static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
59520b57cec5SDimitry Andric   // Check that the return type is a `typedef int kern_return_t` or a typedef
59530b57cec5SDimitry Andric   // around it, because otherwise MIG convention checks make no sense.
59540b57cec5SDimitry Andric   // BlockDecl doesn't store a return type, so it's annoying to check,
59550b57cec5SDimitry Andric   // so let's skip it for now.
59560b57cec5SDimitry Andric   if (!isa<BlockDecl>(D)) {
59570b57cec5SDimitry Andric     QualType T = getFunctionOrMethodResultType(D);
59580b57cec5SDimitry Andric     bool IsKernReturnT = false;
59590b57cec5SDimitry Andric     while (const auto *TT = T->getAs<TypedefType>()) {
59600b57cec5SDimitry Andric       IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
59610b57cec5SDimitry Andric       T = TT->desugar();
59620b57cec5SDimitry Andric     }
59630b57cec5SDimitry Andric     if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
59640b57cec5SDimitry Andric       S.Diag(D->getBeginLoc(),
59650b57cec5SDimitry Andric              diag::warn_mig_server_routine_does_not_return_kern_return_t);
59660b57cec5SDimitry Andric       return;
59670b57cec5SDimitry Andric     }
59680b57cec5SDimitry Andric   }
59690b57cec5SDimitry Andric 
59700b57cec5SDimitry Andric   handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL);
59710b57cec5SDimitry Andric }
59720b57cec5SDimitry Andric 
59730b57cec5SDimitry Andric static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
59740b57cec5SDimitry Andric   // Warn if the return type is not a pointer or reference type.
59750b57cec5SDimitry Andric   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
59760b57cec5SDimitry Andric     QualType RetTy = FD->getReturnType();
59770b57cec5SDimitry Andric     if (!RetTy->isPointerType() && !RetTy->isReferenceType()) {
59780b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)
59790b57cec5SDimitry Andric           << AL.getRange() << RetTy;
59800b57cec5SDimitry Andric       return;
59810b57cec5SDimitry Andric     }
59820b57cec5SDimitry Andric   }
59830b57cec5SDimitry Andric 
59840b57cec5SDimitry Andric   handleSimpleAttribute<MSAllocatorAttr>(S, D, AL);
59850b57cec5SDimitry Andric }
59860b57cec5SDimitry Andric 
59875ffd83dbSDimitry Andric static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5988480093f4SDimitry Andric   if (AL.isUsedAsTypeAttr())
5989480093f4SDimitry Andric     return;
5990480093f4SDimitry Andric   // Warn if the parameter is definitely not an output parameter.
5991480093f4SDimitry Andric   if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
5992480093f4SDimitry Andric     if (PVD->getType()->isIntegerType()) {
5993480093f4SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)
5994480093f4SDimitry Andric           << AL.getRange();
5995480093f4SDimitry Andric       return;
5996480093f4SDimitry Andric     }
5997480093f4SDimitry Andric   }
5998480093f4SDimitry Andric   StringRef Argument;
5999480093f4SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
6000480093f4SDimitry Andric     return;
6001480093f4SDimitry Andric   D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));
6002480093f4SDimitry Andric }
6003480093f4SDimitry Andric 
6004480093f4SDimitry Andric template<typename Attr>
6005480093f4SDimitry Andric static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6006480093f4SDimitry Andric   StringRef Argument;
6007480093f4SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
6008480093f4SDimitry Andric     return;
6009480093f4SDimitry Andric   D->addAttr(Attr::Create(S.Context, Argument, AL));
6010480093f4SDimitry Andric }
6011480093f4SDimitry Andric 
601206c3fb27SDimitry Andric template<typename Attr>
601306c3fb27SDimitry Andric static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
601406c3fb27SDimitry Andric   D->addAttr(Attr::Create(S.Context, AL));
601506c3fb27SDimitry Andric }
601606c3fb27SDimitry Andric 
6017480093f4SDimitry Andric static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6018480093f4SDimitry Andric   // The guard attribute takes a single identifier argument.
6019480093f4SDimitry Andric 
6020480093f4SDimitry Andric   if (!AL.isArgIdent(0)) {
6021480093f4SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
6022480093f4SDimitry Andric         << AL << AANT_ArgumentIdentifier;
6023480093f4SDimitry Andric     return;
6024480093f4SDimitry Andric   }
6025480093f4SDimitry Andric 
6026480093f4SDimitry Andric   CFGuardAttr::GuardArg Arg;
6027480093f4SDimitry Andric   IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
6028480093f4SDimitry Andric   if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {
6029480093f4SDimitry Andric     S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
6030480093f4SDimitry Andric     return;
6031480093f4SDimitry Andric   }
6032480093f4SDimitry Andric 
6033480093f4SDimitry Andric   D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
6034480093f4SDimitry Andric }
6035480093f4SDimitry Andric 
6036e8d8bef9SDimitry Andric 
6037e8d8bef9SDimitry Andric template <typename AttrTy>
6038e8d8bef9SDimitry Andric static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
6039e8d8bef9SDimitry Andric   auto Attrs = D->specific_attrs<AttrTy>();
6040e8d8bef9SDimitry Andric   auto I = llvm::find_if(Attrs,
6041e8d8bef9SDimitry Andric                          [Name](const AttrTy *A) {
6042e8d8bef9SDimitry Andric                            return A->getTCBName() == Name;
6043e8d8bef9SDimitry Andric                          });
6044e8d8bef9SDimitry Andric   return I == Attrs.end() ? nullptr : *I;
6045e8d8bef9SDimitry Andric }
6046e8d8bef9SDimitry Andric 
6047e8d8bef9SDimitry Andric template <typename AttrTy, typename ConflictingAttrTy>
6048e8d8bef9SDimitry Andric static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6049e8d8bef9SDimitry Andric   StringRef Argument;
6050e8d8bef9SDimitry Andric   if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
6051e8d8bef9SDimitry Andric     return;
6052e8d8bef9SDimitry Andric 
6053e8d8bef9SDimitry Andric   // A function cannot be have both regular and leaf membership in the same TCB.
6054e8d8bef9SDimitry Andric   if (const ConflictingAttrTy *ConflictingAttr =
6055e8d8bef9SDimitry Andric       findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {
6056e8d8bef9SDimitry Andric     // We could attach a note to the other attribute but in this case
6057e8d8bef9SDimitry Andric     // there's no need given how the two are very close to each other.
6058e8d8bef9SDimitry Andric     S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)
6059e8d8bef9SDimitry Andric       << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
6060e8d8bef9SDimitry Andric       << Argument;
6061e8d8bef9SDimitry Andric 
6062e8d8bef9SDimitry Andric     // Error recovery: drop the non-leaf attribute so that to suppress
6063e8d8bef9SDimitry Andric     // all future warnings caused by erroneous attributes. The leaf attribute
6064e8d8bef9SDimitry Andric     // needs to be kept because it can only suppresses warnings, not cause them.
6065e8d8bef9SDimitry Andric     D->dropAttr<EnforceTCBAttr>();
6066e8d8bef9SDimitry Andric     return;
6067e8d8bef9SDimitry Andric   }
6068e8d8bef9SDimitry Andric 
6069e8d8bef9SDimitry Andric   D->addAttr(AttrTy::Create(S.Context, Argument, AL));
6070e8d8bef9SDimitry Andric }
6071e8d8bef9SDimitry Andric 
6072e8d8bef9SDimitry Andric template <typename AttrTy, typename ConflictingAttrTy>
6073e8d8bef9SDimitry Andric static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
6074e8d8bef9SDimitry Andric   // Check if the new redeclaration has different leaf-ness in the same TCB.
6075e8d8bef9SDimitry Andric   StringRef TCBName = AL.getTCBName();
6076e8d8bef9SDimitry Andric   if (const ConflictingAttrTy *ConflictingAttr =
6077e8d8bef9SDimitry Andric       findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {
6078e8d8bef9SDimitry Andric     S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
6079e8d8bef9SDimitry Andric       << ConflictingAttr->getAttrName()->getName()
6080e8d8bef9SDimitry Andric       << AL.getAttrName()->getName() << TCBName;
6081e8d8bef9SDimitry Andric 
6082e8d8bef9SDimitry Andric     // Add a note so that the user could easily find the conflicting attribute.
6083e8d8bef9SDimitry Andric     S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
6084e8d8bef9SDimitry Andric 
6085e8d8bef9SDimitry Andric     // More error recovery.
6086e8d8bef9SDimitry Andric     D->dropAttr<EnforceTCBAttr>();
6087e8d8bef9SDimitry Andric     return nullptr;
6088e8d8bef9SDimitry Andric   }
6089e8d8bef9SDimitry Andric 
6090e8d8bef9SDimitry Andric   ASTContext &Context = S.getASTContext();
6091e8d8bef9SDimitry Andric   return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
6092e8d8bef9SDimitry Andric }
6093e8d8bef9SDimitry Andric 
6094e8d8bef9SDimitry Andric EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
6095e8d8bef9SDimitry Andric   return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(
6096e8d8bef9SDimitry Andric       *this, D, AL);
6097e8d8bef9SDimitry Andric }
6098e8d8bef9SDimitry Andric 
6099e8d8bef9SDimitry Andric EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr(
6100e8d8bef9SDimitry Andric     Decl *D, const EnforceTCBLeafAttr &AL) {
6101e8d8bef9SDimitry Andric   return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(
6102e8d8bef9SDimitry Andric       *this, D, AL);
6103e8d8bef9SDimitry Andric }
6104e8d8bef9SDimitry Andric 
61050fca6ea1SDimitry Andric static void handleVTablePointerAuthentication(Sema &S, Decl *D,
61060fca6ea1SDimitry Andric                                               const ParsedAttr &AL) {
61070fca6ea1SDimitry Andric   CXXRecordDecl *Decl = cast<CXXRecordDecl>(D);
61080fca6ea1SDimitry Andric   const uint32_t NumArgs = AL.getNumArgs();
61090fca6ea1SDimitry Andric   if (NumArgs > 4) {
61100fca6ea1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;
61110fca6ea1SDimitry Andric     AL.setInvalid();
61120fca6ea1SDimitry Andric   }
61130fca6ea1SDimitry Andric 
61140fca6ea1SDimitry Andric   if (NumArgs == 0) {
61150fca6ea1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL;
61160fca6ea1SDimitry Andric     AL.setInvalid();
61170fca6ea1SDimitry Andric     return;
61180fca6ea1SDimitry Andric   }
61190fca6ea1SDimitry Andric 
61200fca6ea1SDimitry Andric   if (D->getAttr<VTablePointerAuthenticationAttr>()) {
61210fca6ea1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_duplicated_vtable_pointer_auth) << Decl;
61220fca6ea1SDimitry Andric     AL.setInvalid();
61230fca6ea1SDimitry Andric   }
61240fca6ea1SDimitry Andric 
61250fca6ea1SDimitry Andric   auto KeyType = VTablePointerAuthenticationAttr::VPtrAuthKeyType::DefaultKey;
61260fca6ea1SDimitry Andric   if (AL.isArgIdent(0)) {
61270fca6ea1SDimitry Andric     IdentifierLoc *IL = AL.getArgAsIdent(0);
61280fca6ea1SDimitry Andric     if (!VTablePointerAuthenticationAttr::ConvertStrToVPtrAuthKeyType(
61290fca6ea1SDimitry Andric             IL->Ident->getName(), KeyType)) {
61300fca6ea1SDimitry Andric       S.Diag(IL->Loc, diag::err_invalid_authentication_key) << IL->Ident;
61310fca6ea1SDimitry Andric       AL.setInvalid();
61320fca6ea1SDimitry Andric     }
61330fca6ea1SDimitry Andric     if (KeyType == VTablePointerAuthenticationAttr::DefaultKey &&
61340fca6ea1SDimitry Andric         !S.getLangOpts().PointerAuthCalls) {
61350fca6ea1SDimitry Andric       S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 0;
61360fca6ea1SDimitry Andric       AL.setInvalid();
61370fca6ea1SDimitry Andric     }
61380fca6ea1SDimitry Andric   } else {
61390fca6ea1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
61400fca6ea1SDimitry Andric         << AL << AANT_ArgumentIdentifier;
61410fca6ea1SDimitry Andric     return;
61420fca6ea1SDimitry Andric   }
61430fca6ea1SDimitry Andric 
61440fca6ea1SDimitry Andric   auto AddressDiversityMode = VTablePointerAuthenticationAttr::
61450fca6ea1SDimitry Andric       AddressDiscriminationMode::DefaultAddressDiscrimination;
61460fca6ea1SDimitry Andric   if (AL.getNumArgs() > 1) {
61470fca6ea1SDimitry Andric     if (AL.isArgIdent(1)) {
61480fca6ea1SDimitry Andric       IdentifierLoc *IL = AL.getArgAsIdent(1);
61490fca6ea1SDimitry Andric       if (!VTablePointerAuthenticationAttr::
61500fca6ea1SDimitry Andric               ConvertStrToAddressDiscriminationMode(IL->Ident->getName(),
61510fca6ea1SDimitry Andric                                                     AddressDiversityMode)) {
61520fca6ea1SDimitry Andric         S.Diag(IL->Loc, diag::err_invalid_address_discrimination) << IL->Ident;
61530fca6ea1SDimitry Andric         AL.setInvalid();
61540fca6ea1SDimitry Andric       }
61550fca6ea1SDimitry Andric       if (AddressDiversityMode ==
61560fca6ea1SDimitry Andric               VTablePointerAuthenticationAttr::DefaultAddressDiscrimination &&
61570fca6ea1SDimitry Andric           !S.getLangOpts().PointerAuthCalls) {
61580fca6ea1SDimitry Andric         S.Diag(IL->Loc, diag::err_no_default_vtable_pointer_auth) << 1;
61590fca6ea1SDimitry Andric         AL.setInvalid();
61600fca6ea1SDimitry Andric       }
61610fca6ea1SDimitry Andric     } else {
61620fca6ea1SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
61630fca6ea1SDimitry Andric           << AL << AANT_ArgumentIdentifier;
61640fca6ea1SDimitry Andric     }
61650fca6ea1SDimitry Andric   }
61660fca6ea1SDimitry Andric 
61670fca6ea1SDimitry Andric   auto ED = VTablePointerAuthenticationAttr::ExtraDiscrimination::
61680fca6ea1SDimitry Andric       DefaultExtraDiscrimination;
61690fca6ea1SDimitry Andric   if (AL.getNumArgs() > 2) {
61700fca6ea1SDimitry Andric     if (AL.isArgIdent(2)) {
61710fca6ea1SDimitry Andric       IdentifierLoc *IL = AL.getArgAsIdent(2);
61720fca6ea1SDimitry Andric       if (!VTablePointerAuthenticationAttr::ConvertStrToExtraDiscrimination(
61730fca6ea1SDimitry Andric               IL->Ident->getName(), ED)) {
61740fca6ea1SDimitry Andric         S.Diag(IL->Loc, diag::err_invalid_extra_discrimination) << IL->Ident;
61750fca6ea1SDimitry Andric         AL.setInvalid();
61760fca6ea1SDimitry Andric       }
61770fca6ea1SDimitry Andric       if (ED == VTablePointerAuthenticationAttr::DefaultExtraDiscrimination &&
61780fca6ea1SDimitry Andric           !S.getLangOpts().PointerAuthCalls) {
61790fca6ea1SDimitry Andric         S.Diag(AL.getLoc(), diag::err_no_default_vtable_pointer_auth) << 2;
61800fca6ea1SDimitry Andric         AL.setInvalid();
61810fca6ea1SDimitry Andric       }
61820fca6ea1SDimitry Andric     } else {
61830fca6ea1SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
61840fca6ea1SDimitry Andric           << AL << AANT_ArgumentIdentifier;
61850fca6ea1SDimitry Andric     }
61860fca6ea1SDimitry Andric   }
61870fca6ea1SDimitry Andric 
61880fca6ea1SDimitry Andric   uint32_t CustomDiscriminationValue = 0;
61890fca6ea1SDimitry Andric   if (ED == VTablePointerAuthenticationAttr::CustomDiscrimination) {
61900fca6ea1SDimitry Andric     if (NumArgs < 4) {
61910fca6ea1SDimitry Andric       S.Diag(AL.getLoc(), diag::err_missing_custom_discrimination) << AL << 4;
61920fca6ea1SDimitry Andric       AL.setInvalid();
61930fca6ea1SDimitry Andric       return;
61940fca6ea1SDimitry Andric     }
61950fca6ea1SDimitry Andric     if (NumArgs > 4) {
61960fca6ea1SDimitry Andric       S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 4;
61970fca6ea1SDimitry Andric       AL.setInvalid();
61980fca6ea1SDimitry Andric     }
61990fca6ea1SDimitry Andric 
62000fca6ea1SDimitry Andric     if (!AL.isArgExpr(3) || !S.checkUInt32Argument(AL, AL.getArgAsExpr(3),
62010fca6ea1SDimitry Andric                                                    CustomDiscriminationValue)) {
62020fca6ea1SDimitry Andric       S.Diag(AL.getLoc(), diag::err_invalid_custom_discrimination);
62030fca6ea1SDimitry Andric       AL.setInvalid();
62040fca6ea1SDimitry Andric     }
62050fca6ea1SDimitry Andric   } else if (NumArgs > 3) {
62060fca6ea1SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 3;
62070fca6ea1SDimitry Andric     AL.setInvalid();
62080fca6ea1SDimitry Andric   }
62090fca6ea1SDimitry Andric 
62100fca6ea1SDimitry Andric   Decl->addAttr(::new (S.Context) VTablePointerAuthenticationAttr(
62110fca6ea1SDimitry Andric       S.Context, AL, KeyType, AddressDiversityMode, ED,
62120fca6ea1SDimitry Andric       CustomDiscriminationValue));
62130fca6ea1SDimitry Andric }
62140fca6ea1SDimitry Andric 
62150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
62160b57cec5SDimitry Andric // Top Level Sema Entry Points
62170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
62180b57cec5SDimitry Andric 
621981ad6265SDimitry Andric // Returns true if the attribute must delay setting its arguments until after
622081ad6265SDimitry Andric // template instantiation, and false otherwise.
622181ad6265SDimitry Andric static bool MustDelayAttributeArguments(const ParsedAttr &AL) {
622281ad6265SDimitry Andric   // Only attributes that accept expression parameter packs can delay arguments.
622381ad6265SDimitry Andric   if (!AL.acceptsExprPack())
622481ad6265SDimitry Andric     return false;
622581ad6265SDimitry Andric 
622681ad6265SDimitry Andric   bool AttrHasVariadicArg = AL.hasVariadicArg();
622781ad6265SDimitry Andric   unsigned AttrNumArgs = AL.getNumArgMembers();
622881ad6265SDimitry Andric   for (size_t I = 0; I < std::min(AL.getNumArgs(), AttrNumArgs); ++I) {
622981ad6265SDimitry Andric     bool IsLastAttrArg = I == (AttrNumArgs - 1);
623081ad6265SDimitry Andric     // If the argument is the last argument and it is variadic it can contain
623181ad6265SDimitry Andric     // any expression.
623281ad6265SDimitry Andric     if (IsLastAttrArg && AttrHasVariadicArg)
623381ad6265SDimitry Andric       return false;
623481ad6265SDimitry Andric     Expr *E = AL.getArgAsExpr(I);
623581ad6265SDimitry Andric     bool ArgMemberCanHoldExpr = AL.isParamExpr(I);
623681ad6265SDimitry Andric     // If the expression is a pack expansion then arguments must be delayed
623781ad6265SDimitry Andric     // unless the argument is an expression and it is the last argument of the
623881ad6265SDimitry Andric     // attribute.
623981ad6265SDimitry Andric     if (isa<PackExpansionExpr>(E))
624081ad6265SDimitry Andric       return !(IsLastAttrArg && ArgMemberCanHoldExpr);
624181ad6265SDimitry Andric     // Last case is if the expression is value dependent then it must delay
624281ad6265SDimitry Andric     // arguments unless the corresponding argument is able to hold the
624381ad6265SDimitry Andric     // expression.
624481ad6265SDimitry Andric     if (E->isValueDependent() && !ArgMemberCanHoldExpr)
624581ad6265SDimitry Andric       return true;
624681ad6265SDimitry Andric   }
624781ad6265SDimitry Andric   return false;
624881ad6265SDimitry Andric }
624981ad6265SDimitry Andric 
62500b57cec5SDimitry Andric /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
62510b57cec5SDimitry Andric /// the attribute applies to decls.  If the attribute is a type attribute, just
62520b57cec5SDimitry Andric /// silently ignore it if a GNU attribute.
625381ad6265SDimitry Andric static void
625481ad6265SDimitry Andric ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
625581ad6265SDimitry Andric                      const Sema::ProcessDeclAttributeOptions &Options) {
62560b57cec5SDimitry Andric   if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
62570b57cec5SDimitry Andric     return;
62580b57cec5SDimitry Andric 
62590b57cec5SDimitry Andric   // Ignore C++11 attributes on declarator chunks: they appertain to the type
62600fca6ea1SDimitry Andric   // instead. Note, isCXX11Attribute() will look at whether the attribute is
62610fca6ea1SDimitry Andric   // [[]] or alignas, while isC23Attribute() will only look at [[]]. This is
62620fca6ea1SDimitry Andric   // important for ensuring that alignas in C23 is properly handled on a
62630fca6ea1SDimitry Andric   // structure member declaration because it is a type-specifier-qualifier in
62640fca6ea1SDimitry Andric   // C but still applies to the declaration rather than the type.
62650fca6ea1SDimitry Andric   if ((S.getLangOpts().CPlusPlus ? AL.isCXX11Attribute()
62660fca6ea1SDimitry Andric                                  : AL.isC23Attribute()) &&
62670fca6ea1SDimitry Andric       !Options.IncludeCXX11Attributes)
62680b57cec5SDimitry Andric     return;
62690b57cec5SDimitry Andric 
62700b57cec5SDimitry Andric   // Unknown attributes are automatically warned on. Target-specific attributes
62710b57cec5SDimitry Andric   // which do not apply to the current target architecture are treated as
62720b57cec5SDimitry Andric   // though they were unknown attributes.
62730b57cec5SDimitry Andric   if (AL.getKind() == ParsedAttr::UnknownAttribute ||
62740b57cec5SDimitry Andric       !AL.existsInTarget(S.Context.getTargetInfo())) {
62750b57cec5SDimitry Andric     S.Diag(AL.getLoc(),
627606c3fb27SDimitry Andric            AL.isRegularKeywordAttribute()
627706c3fb27SDimitry Andric                ? (unsigned)diag::err_keyword_not_supported_on_target
627806c3fb27SDimitry Andric            : AL.isDeclspecAttribute()
62790b57cec5SDimitry Andric                ? (unsigned)diag::warn_unhandled_ms_attribute_ignored
62800b57cec5SDimitry Andric                : (unsigned)diag::warn_unknown_attribute_ignored)
6281e8d8bef9SDimitry Andric         << AL << AL.getRange();
62820b57cec5SDimitry Andric     return;
62830b57cec5SDimitry Andric   }
62840b57cec5SDimitry Andric 
628581ad6265SDimitry Andric   // Check if argument population must delayed to after template instantiation.
628681ad6265SDimitry Andric   bool MustDelayArgs = MustDelayAttributeArguments(AL);
628781ad6265SDimitry Andric 
628881ad6265SDimitry Andric   // Argument number check must be skipped if arguments are delayed.
628981ad6265SDimitry Andric   if (S.checkCommonAttributeFeatures(D, AL, MustDelayArgs))
62900b57cec5SDimitry Andric     return;
62910b57cec5SDimitry Andric 
629281ad6265SDimitry Andric   if (MustDelayArgs) {
629381ad6265SDimitry Andric     AL.handleAttrWithDelayedArgs(S, D);
629481ad6265SDimitry Andric     return;
629581ad6265SDimitry Andric   }
629681ad6265SDimitry Andric 
62970b57cec5SDimitry Andric   switch (AL.getKind()) {
62980b57cec5SDimitry Andric   default:
62995ffd83dbSDimitry Andric     if (AL.getInfo().handleDeclAttribute(S, D, AL) != ParsedAttrInfo::NotHandled)
63005ffd83dbSDimitry Andric       break;
63010b57cec5SDimitry Andric     if (!AL.isStmtAttr()) {
63020b57cec5SDimitry Andric       assert(AL.isTypeAttr() && "Non-type attribute not handled");
630381ad6265SDimitry Andric     }
630481ad6265SDimitry Andric     if (AL.isTypeAttr()) {
630581ad6265SDimitry Andric       if (Options.IgnoreTypeAttributes)
63060b57cec5SDimitry Andric         break;
630706c3fb27SDimitry Andric       if (!AL.isStandardAttributeSyntax() && !AL.isRegularKeywordAttribute()) {
630881ad6265SDimitry Andric         // Non-[[]] type attributes are handled in processTypeAttrs(); silently
630981ad6265SDimitry Andric         // move on.
631081ad6265SDimitry Andric         break;
631181ad6265SDimitry Andric       }
631281ad6265SDimitry Andric 
631381ad6265SDimitry Andric       // According to the C and C++ standards, we should never see a
631481ad6265SDimitry Andric       // [[]] type attribute on a declaration. However, we have in the past
631581ad6265SDimitry Andric       // allowed some type attributes to "slide" to the `DeclSpec`, so we need
631681ad6265SDimitry Andric       // to continue to support this legacy behavior. We only do this, however,
631781ad6265SDimitry Andric       // if
631881ad6265SDimitry Andric       // - we actually have a `DeclSpec`, i.e. if we're looking at a
631981ad6265SDimitry Andric       //   `DeclaratorDecl`, or
632081ad6265SDimitry Andric       // - we are looking at an alias-declaration, where historically we have
632181ad6265SDimitry Andric       //   allowed type attributes after the identifier to slide to the type.
632281ad6265SDimitry Andric       if (AL.slidesFromDeclToDeclSpecLegacyBehavior() &&
632381ad6265SDimitry Andric           isa<DeclaratorDecl, TypeAliasDecl>(D)) {
632481ad6265SDimitry Andric         // Suggest moving the attribute to the type instead, but only for our
632581ad6265SDimitry Andric         // own vendor attributes; moving other vendors' attributes might hurt
632681ad6265SDimitry Andric         // portability.
632781ad6265SDimitry Andric         if (AL.isClangScope()) {
632881ad6265SDimitry Andric           S.Diag(AL.getLoc(), diag::warn_type_attribute_deprecated_on_decl)
632981ad6265SDimitry Andric               << AL << D->getLocation();
633081ad6265SDimitry Andric         }
633181ad6265SDimitry Andric 
633281ad6265SDimitry Andric         // Allow this type attribute to be handled in processTypeAttrs();
633381ad6265SDimitry Andric         // silently move on.
633481ad6265SDimitry Andric         break;
633581ad6265SDimitry Andric       }
633681ad6265SDimitry Andric 
633781ad6265SDimitry Andric       if (AL.getKind() == ParsedAttr::AT_Regparm) {
633881ad6265SDimitry Andric         // `regparm` is a special case: It's a type attribute but we still want
633981ad6265SDimitry Andric         // to treat it as if it had been written on the declaration because that
634081ad6265SDimitry Andric         // way we'll be able to handle it directly in `processTypeAttr()`.
634181ad6265SDimitry Andric         // If we treated `regparm` it as if it had been written on the
634281ad6265SDimitry Andric         // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
634381ad6265SDimitry Andric         // would try to move it to the declarator, but that doesn't work: We
634481ad6265SDimitry Andric         // can't remove the attribute from the list of declaration attributes
634581ad6265SDimitry Andric         // because it might be needed by other declarators in the same
634681ad6265SDimitry Andric         // declaration.
634781ad6265SDimitry Andric         break;
634881ad6265SDimitry Andric       }
634981ad6265SDimitry Andric 
635081ad6265SDimitry Andric       if (AL.getKind() == ParsedAttr::AT_VectorSize) {
635181ad6265SDimitry Andric         // `vector_size` is a special case: It's a type attribute semantically,
635281ad6265SDimitry Andric         // but GCC expects the [[]] syntax to be written on the declaration (and
635381ad6265SDimitry Andric         // warns that the attribute has no effect if it is placed on the
635481ad6265SDimitry Andric         // decl-specifier-seq).
635581ad6265SDimitry Andric         // Silently move on and allow the attribute to be handled in
635681ad6265SDimitry Andric         // processTypeAttr().
635781ad6265SDimitry Andric         break;
635881ad6265SDimitry Andric       }
635981ad6265SDimitry Andric 
636081ad6265SDimitry Andric       if (AL.getKind() == ParsedAttr::AT_NoDeref) {
636181ad6265SDimitry Andric         // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
636281ad6265SDimitry Andric         // See https://github.com/llvm/llvm-project/issues/55790 for details.
636381ad6265SDimitry Andric         // We allow processTypeAttrs() to emit a warning and silently move on.
636481ad6265SDimitry Andric         break;
636581ad6265SDimitry Andric       }
63660b57cec5SDimitry Andric     }
6367fe6060f1SDimitry Andric     // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
6368fe6060f1SDimitry Andric     // statement attribute is not written on a declaration, but this code is
636981ad6265SDimitry Andric     // needed for type attributes as well as statement attributes in Attr.td
637081ad6265SDimitry Andric     // that do not list any subjects.
637181ad6265SDimitry Andric     S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)
637206c3fb27SDimitry Andric         << AL << AL.isRegularKeywordAttribute() << D->getLocation();
63730b57cec5SDimitry Andric     break;
63740b57cec5SDimitry Andric   case ParsedAttr::AT_Interrupt:
63750b57cec5SDimitry Andric     handleInterruptAttr(S, D, AL);
63760b57cec5SDimitry Andric     break;
63770b57cec5SDimitry Andric   case ParsedAttr::AT_X86ForceAlignArgPointer:
63780fca6ea1SDimitry Andric     S.X86().handleForceAlignArgPointerAttr(D, AL);
63790b57cec5SDimitry Andric     break;
6380bdd1243dSDimitry Andric   case ParsedAttr::AT_ReadOnlyPlacement:
6381bdd1243dSDimitry Andric     handleSimpleAttribute<ReadOnlyPlacementAttr>(S, D, AL);
6382bdd1243dSDimitry Andric     break;
63830b57cec5SDimitry Andric   case ParsedAttr::AT_DLLExport:
63840b57cec5SDimitry Andric   case ParsedAttr::AT_DLLImport:
63850b57cec5SDimitry Andric     handleDLLAttr(S, D, AL);
63860b57cec5SDimitry Andric     break;
63870b57cec5SDimitry Andric   case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
63880fca6ea1SDimitry Andric     S.AMDGPU().handleAMDGPUFlatWorkGroupSizeAttr(D, AL);
63890b57cec5SDimitry Andric     break;
63900b57cec5SDimitry Andric   case ParsedAttr::AT_AMDGPUWavesPerEU:
63910fca6ea1SDimitry Andric     S.AMDGPU().handleAMDGPUWavesPerEUAttr(D, AL);
63920b57cec5SDimitry Andric     break;
63930b57cec5SDimitry Andric   case ParsedAttr::AT_AMDGPUNumSGPR:
63940fca6ea1SDimitry Andric     S.AMDGPU().handleAMDGPUNumSGPRAttr(D, AL);
63950b57cec5SDimitry Andric     break;
63960b57cec5SDimitry Andric   case ParsedAttr::AT_AMDGPUNumVGPR:
63970fca6ea1SDimitry Andric     S.AMDGPU().handleAMDGPUNumVGPRAttr(D, AL);
63980fca6ea1SDimitry Andric     break;
63990fca6ea1SDimitry Andric   case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
64000fca6ea1SDimitry Andric     S.AMDGPU().handleAMDGPUMaxNumWorkGroupsAttr(D, AL);
64010b57cec5SDimitry Andric     break;
64020b57cec5SDimitry Andric   case ParsedAttr::AT_AVRSignal:
64030fca6ea1SDimitry Andric     S.AVR().handleSignalAttr(D, AL);
64040b57cec5SDimitry Andric     break;
6405480093f4SDimitry Andric   case ParsedAttr::AT_BPFPreserveAccessIndex:
64060fca6ea1SDimitry Andric     S.BPF().handlePreserveAccessIndexAttr(D, AL);
6407480093f4SDimitry Andric     break;
64085f757f3fSDimitry Andric   case ParsedAttr::AT_BPFPreserveStaticOffset:
64095f757f3fSDimitry Andric     handleSimpleAttribute<BPFPreserveStaticOffsetAttr>(S, D, AL);
64105f757f3fSDimitry Andric     break;
6411349cc55cSDimitry Andric   case ParsedAttr::AT_BTFDeclTag:
6412349cc55cSDimitry Andric     handleBTFDeclTagAttr(S, D, AL);
6413349cc55cSDimitry Andric     break;
6414480093f4SDimitry Andric   case ParsedAttr::AT_WebAssemblyExportName:
64150fca6ea1SDimitry Andric     S.Wasm().handleWebAssemblyExportNameAttr(D, AL);
6416480093f4SDimitry Andric     break;
64170b57cec5SDimitry Andric   case ParsedAttr::AT_WebAssemblyImportModule:
64180fca6ea1SDimitry Andric     S.Wasm().handleWebAssemblyImportModuleAttr(D, AL);
64190b57cec5SDimitry Andric     break;
64200b57cec5SDimitry Andric   case ParsedAttr::AT_WebAssemblyImportName:
64210fca6ea1SDimitry Andric     S.Wasm().handleWebAssemblyImportNameAttr(D, AL);
64220b57cec5SDimitry Andric     break;
64230b57cec5SDimitry Andric   case ParsedAttr::AT_IBOutlet:
64240fca6ea1SDimitry Andric     S.ObjC().handleIBOutlet(D, AL);
64250b57cec5SDimitry Andric     break;
64260b57cec5SDimitry Andric   case ParsedAttr::AT_IBOutletCollection:
64270fca6ea1SDimitry Andric     S.ObjC().handleIBOutletCollection(D, AL);
64280b57cec5SDimitry Andric     break;
64290b57cec5SDimitry Andric   case ParsedAttr::AT_IFunc:
64300b57cec5SDimitry Andric     handleIFuncAttr(S, D, AL);
64310b57cec5SDimitry Andric     break;
64320b57cec5SDimitry Andric   case ParsedAttr::AT_Alias:
64330b57cec5SDimitry Andric     handleAliasAttr(S, D, AL);
64340b57cec5SDimitry Andric     break;
64350b57cec5SDimitry Andric   case ParsedAttr::AT_Aligned:
64360b57cec5SDimitry Andric     handleAlignedAttr(S, D, AL);
64370b57cec5SDimitry Andric     break;
64380b57cec5SDimitry Andric   case ParsedAttr::AT_AlignValue:
64390b57cec5SDimitry Andric     handleAlignValueAttr(S, D, AL);
64400b57cec5SDimitry Andric     break;
64410b57cec5SDimitry Andric   case ParsedAttr::AT_AllocSize:
64420b57cec5SDimitry Andric     handleAllocSizeAttr(S, D, AL);
64430b57cec5SDimitry Andric     break;
64440b57cec5SDimitry Andric   case ParsedAttr::AT_AlwaysInline:
64450b57cec5SDimitry Andric     handleAlwaysInlineAttr(S, D, AL);
64460b57cec5SDimitry Andric     break;
64470b57cec5SDimitry Andric   case ParsedAttr::AT_AnalyzerNoReturn:
64480b57cec5SDimitry Andric     handleAnalyzerNoReturnAttr(S, D, AL);
64490b57cec5SDimitry Andric     break;
64500b57cec5SDimitry Andric   case ParsedAttr::AT_TLSModel:
64510b57cec5SDimitry Andric     handleTLSModelAttr(S, D, AL);
64520b57cec5SDimitry Andric     break;
64530b57cec5SDimitry Andric   case ParsedAttr::AT_Annotate:
64540b57cec5SDimitry Andric     handleAnnotateAttr(S, D, AL);
64550b57cec5SDimitry Andric     break;
64560b57cec5SDimitry Andric   case ParsedAttr::AT_Availability:
64570b57cec5SDimitry Andric     handleAvailabilityAttr(S, D, AL);
64580b57cec5SDimitry Andric     break;
64590b57cec5SDimitry Andric   case ParsedAttr::AT_CarriesDependency:
64600b57cec5SDimitry Andric     handleDependencyAttr(S, scope, D, AL);
64610b57cec5SDimitry Andric     break;
64620b57cec5SDimitry Andric   case ParsedAttr::AT_CPUDispatch:
64630b57cec5SDimitry Andric   case ParsedAttr::AT_CPUSpecific:
64640b57cec5SDimitry Andric     handleCPUSpecificAttr(S, D, AL);
64650b57cec5SDimitry Andric     break;
64660b57cec5SDimitry Andric   case ParsedAttr::AT_Common:
64670b57cec5SDimitry Andric     handleCommonAttr(S, D, AL);
64680b57cec5SDimitry Andric     break;
64690b57cec5SDimitry Andric   case ParsedAttr::AT_CUDAConstant:
64700b57cec5SDimitry Andric     handleConstantAttr(S, D, AL);
64710b57cec5SDimitry Andric     break;
64720b57cec5SDimitry Andric   case ParsedAttr::AT_PassObjectSize:
64730b57cec5SDimitry Andric     handlePassObjectSizeAttr(S, D, AL);
64740b57cec5SDimitry Andric     break;
64750b57cec5SDimitry Andric   case ParsedAttr::AT_Constructor:
64760b57cec5SDimitry Andric       handleConstructorAttr(S, D, AL);
64770b57cec5SDimitry Andric     break;
64780b57cec5SDimitry Andric   case ParsedAttr::AT_Deprecated:
64790b57cec5SDimitry Andric     handleDeprecatedAttr(S, D, AL);
64800b57cec5SDimitry Andric     break;
64810b57cec5SDimitry Andric   case ParsedAttr::AT_Destructor:
64820b57cec5SDimitry Andric       handleDestructorAttr(S, D, AL);
64830b57cec5SDimitry Andric     break;
64840b57cec5SDimitry Andric   case ParsedAttr::AT_EnableIf:
64850b57cec5SDimitry Andric     handleEnableIfAttr(S, D, AL);
64860b57cec5SDimitry Andric     break;
6487349cc55cSDimitry Andric   case ParsedAttr::AT_Error:
6488349cc55cSDimitry Andric     handleErrorAttr(S, D, AL);
6489349cc55cSDimitry Andric     break;
64900fca6ea1SDimitry Andric   case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
64910fca6ea1SDimitry Andric     handleExcludeFromExplicitInstantiationAttr(S, D, AL);
64920fca6ea1SDimitry Andric     break;
64930b57cec5SDimitry Andric   case ParsedAttr::AT_DiagnoseIf:
64940b57cec5SDimitry Andric     handleDiagnoseIfAttr(S, D, AL);
64950b57cec5SDimitry Andric     break;
64960eae32dcSDimitry Andric   case ParsedAttr::AT_DiagnoseAsBuiltin:
64970eae32dcSDimitry Andric     handleDiagnoseAsBuiltinAttr(S, D, AL);
64980eae32dcSDimitry Andric     break;
6499480093f4SDimitry Andric   case ParsedAttr::AT_NoBuiltin:
6500480093f4SDimitry Andric     handleNoBuiltinAttr(S, D, AL);
6501480093f4SDimitry Andric     break;
65020b57cec5SDimitry Andric   case ParsedAttr::AT_ExtVectorType:
65030b57cec5SDimitry Andric     handleExtVectorTypeAttr(S, D, AL);
65040b57cec5SDimitry Andric     break;
65050b57cec5SDimitry Andric   case ParsedAttr::AT_ExternalSourceSymbol:
65060b57cec5SDimitry Andric     handleExternalSourceSymbolAttr(S, D, AL);
65070b57cec5SDimitry Andric     break;
65080b57cec5SDimitry Andric   case ParsedAttr::AT_MinSize:
65090b57cec5SDimitry Andric     handleMinSizeAttr(S, D, AL);
65100b57cec5SDimitry Andric     break;
65110b57cec5SDimitry Andric   case ParsedAttr::AT_OptimizeNone:
65120b57cec5SDimitry Andric     handleOptimizeNoneAttr(S, D, AL);
65130b57cec5SDimitry Andric     break;
65140b57cec5SDimitry Andric   case ParsedAttr::AT_EnumExtensibility:
65150b57cec5SDimitry Andric     handleEnumExtensibilityAttr(S, D, AL);
65160b57cec5SDimitry Andric     break;
6517480093f4SDimitry Andric   case ParsedAttr::AT_SYCLKernel:
65180fca6ea1SDimitry Andric     S.SYCL().handleKernelAttr(D, AL);
6519480093f4SDimitry Andric     break;
652004eeddc0SDimitry Andric   case ParsedAttr::AT_SYCLSpecialClass:
652104eeddc0SDimitry Andric     handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, AL);
652204eeddc0SDimitry Andric     break;
65230b57cec5SDimitry Andric   case ParsedAttr::AT_Format:
65240b57cec5SDimitry Andric     handleFormatAttr(S, D, AL);
65250b57cec5SDimitry Andric     break;
65260b57cec5SDimitry Andric   case ParsedAttr::AT_FormatArg:
65270b57cec5SDimitry Andric     handleFormatArgAttr(S, D, AL);
65280b57cec5SDimitry Andric     break;
65290b57cec5SDimitry Andric   case ParsedAttr::AT_Callback:
65300b57cec5SDimitry Andric     handleCallbackAttr(S, D, AL);
65310b57cec5SDimitry Andric     break;
6532e8d8bef9SDimitry Andric   case ParsedAttr::AT_CalledOnce:
6533e8d8bef9SDimitry Andric     handleCalledOnceAttr(S, D, AL);
6534e8d8bef9SDimitry Andric     break;
653506c3fb27SDimitry Andric   case ParsedAttr::AT_NVPTXKernel:
65360b57cec5SDimitry Andric   case ParsedAttr::AT_CUDAGlobal:
65370b57cec5SDimitry Andric     handleGlobalAttr(S, D, AL);
65380b57cec5SDimitry Andric     break;
65390b57cec5SDimitry Andric   case ParsedAttr::AT_CUDADevice:
6540e8d8bef9SDimitry Andric     handleDeviceAttr(S, D, AL);
65410b57cec5SDimitry Andric     break;
6542e8d8bef9SDimitry Andric   case ParsedAttr::AT_HIPManaged:
6543e8d8bef9SDimitry Andric     handleManagedAttr(S, D, AL);
6544e8d8bef9SDimitry Andric     break;
65450b57cec5SDimitry Andric   case ParsedAttr::AT_GNUInline:
65460b57cec5SDimitry Andric     handleGNUInlineAttr(S, D, AL);
65470b57cec5SDimitry Andric     break;
65480b57cec5SDimitry Andric   case ParsedAttr::AT_CUDALaunchBounds:
65490b57cec5SDimitry Andric     handleLaunchBoundsAttr(S, D, AL);
65500b57cec5SDimitry Andric     break;
65510b57cec5SDimitry Andric   case ParsedAttr::AT_Restrict:
65520b57cec5SDimitry Andric     handleRestrictAttr(S, D, AL);
65530b57cec5SDimitry Andric     break;
65540b57cec5SDimitry Andric   case ParsedAttr::AT_Mode:
65550b57cec5SDimitry Andric     handleModeAttr(S, D, AL);
65560b57cec5SDimitry Andric     break;
65570b57cec5SDimitry Andric   case ParsedAttr::AT_NonNull:
65580b57cec5SDimitry Andric     if (auto *PVD = dyn_cast<ParmVarDecl>(D))
65590b57cec5SDimitry Andric       handleNonNullAttrParameter(S, PVD, AL);
65600b57cec5SDimitry Andric     else
65610b57cec5SDimitry Andric       handleNonNullAttr(S, D, AL);
65620b57cec5SDimitry Andric     break;
65630b57cec5SDimitry Andric   case ParsedAttr::AT_ReturnsNonNull:
65640b57cec5SDimitry Andric     handleReturnsNonNullAttr(S, D, AL);
65650b57cec5SDimitry Andric     break;
65660b57cec5SDimitry Andric   case ParsedAttr::AT_NoEscape:
65670b57cec5SDimitry Andric     handleNoEscapeAttr(S, D, AL);
65680b57cec5SDimitry Andric     break;
6569bdd1243dSDimitry Andric   case ParsedAttr::AT_MaybeUndef:
6570bdd1243dSDimitry Andric     handleSimpleAttribute<MaybeUndefAttr>(S, D, AL);
6571bdd1243dSDimitry Andric     break;
65720b57cec5SDimitry Andric   case ParsedAttr::AT_AssumeAligned:
65730b57cec5SDimitry Andric     handleAssumeAlignedAttr(S, D, AL);
65740b57cec5SDimitry Andric     break;
65750b57cec5SDimitry Andric   case ParsedAttr::AT_AllocAlign:
65760b57cec5SDimitry Andric     handleAllocAlignAttr(S, D, AL);
65770b57cec5SDimitry Andric     break;
65780b57cec5SDimitry Andric   case ParsedAttr::AT_Ownership:
65790b57cec5SDimitry Andric     handleOwnershipAttr(S, D, AL);
65800b57cec5SDimitry Andric     break;
65810b57cec5SDimitry Andric   case ParsedAttr::AT_Naked:
65820b57cec5SDimitry Andric     handleNakedAttr(S, D, AL);
65830b57cec5SDimitry Andric     break;
65840b57cec5SDimitry Andric   case ParsedAttr::AT_NoReturn:
65850b57cec5SDimitry Andric     handleNoReturnAttr(S, D, AL);
65860b57cec5SDimitry Andric     break;
658781ad6265SDimitry Andric   case ParsedAttr::AT_CXX11NoReturn:
658881ad6265SDimitry Andric     handleStandardNoReturnAttr(S, D, AL);
658981ad6265SDimitry Andric     break;
65900b57cec5SDimitry Andric   case ParsedAttr::AT_AnyX86NoCfCheck:
65910b57cec5SDimitry Andric     handleNoCfCheckAttr(S, D, AL);
65920b57cec5SDimitry Andric     break;
65930b57cec5SDimitry Andric   case ParsedAttr::AT_NoThrow:
65940b57cec5SDimitry Andric     if (!AL.isUsedAsTypeAttr())
65950b57cec5SDimitry Andric       handleSimpleAttribute<NoThrowAttr>(S, D, AL);
65960b57cec5SDimitry Andric     break;
65970b57cec5SDimitry Andric   case ParsedAttr::AT_CUDAShared:
65980b57cec5SDimitry Andric     handleSharedAttr(S, D, AL);
65990b57cec5SDimitry Andric     break;
66000b57cec5SDimitry Andric   case ParsedAttr::AT_VecReturn:
66010b57cec5SDimitry Andric     handleVecReturnAttr(S, D, AL);
66020b57cec5SDimitry Andric     break;
66030b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCOwnership:
66040fca6ea1SDimitry Andric     S.ObjC().handleOwnershipAttr(D, AL);
66050b57cec5SDimitry Andric     break;
66060b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCPreciseLifetime:
66070fca6ea1SDimitry Andric     S.ObjC().handlePreciseLifetimeAttr(D, AL);
66080b57cec5SDimitry Andric     break;
66090b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCReturnsInnerPointer:
66100fca6ea1SDimitry Andric     S.ObjC().handleReturnsInnerPointerAttr(D, AL);
66110b57cec5SDimitry Andric     break;
66120b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCRequiresSuper:
66130fca6ea1SDimitry Andric     S.ObjC().handleRequiresSuperAttr(D, AL);
66140b57cec5SDimitry Andric     break;
66150b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCBridge:
66160fca6ea1SDimitry Andric     S.ObjC().handleBridgeAttr(D, AL);
66170b57cec5SDimitry Andric     break;
66180b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCBridgeMutable:
66190fca6ea1SDimitry Andric     S.ObjC().handleBridgeMutableAttr(D, AL);
66200b57cec5SDimitry Andric     break;
66210b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCBridgeRelated:
66220fca6ea1SDimitry Andric     S.ObjC().handleBridgeRelatedAttr(D, AL);
66230b57cec5SDimitry Andric     break;
66240b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCDesignatedInitializer:
66250fca6ea1SDimitry Andric     S.ObjC().handleDesignatedInitializer(D, AL);
66260b57cec5SDimitry Andric     break;
66270b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCRuntimeName:
66280fca6ea1SDimitry Andric     S.ObjC().handleRuntimeName(D, AL);
66290b57cec5SDimitry Andric     break;
66300b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCBoxable:
66310fca6ea1SDimitry Andric     S.ObjC().handleBoxable(D, AL);
66320b57cec5SDimitry Andric     break;
6633e8d8bef9SDimitry Andric   case ParsedAttr::AT_NSErrorDomain:
66340fca6ea1SDimitry Andric     S.ObjC().handleNSErrorDomain(D, AL);
6635e8d8bef9SDimitry Andric     break;
66360b57cec5SDimitry Andric   case ParsedAttr::AT_CFConsumed:
66370b57cec5SDimitry Andric   case ParsedAttr::AT_NSConsumed:
66380b57cec5SDimitry Andric   case ParsedAttr::AT_OSConsumed:
66390fca6ea1SDimitry Andric     S.ObjC().AddXConsumedAttr(D, AL,
66400fca6ea1SDimitry Andric                               S.ObjC().parsedAttrToRetainOwnershipKind(AL),
66410b57cec5SDimitry Andric                               /*IsTemplateInstantiation=*/false);
66420b57cec5SDimitry Andric     break;
66430b57cec5SDimitry Andric   case ParsedAttr::AT_OSReturnsRetainedOnZero:
66440b57cec5SDimitry Andric     handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
66450fca6ea1SDimitry Andric         S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),
66460b57cec5SDimitry Andric         diag::warn_ns_attribute_wrong_parameter_type,
66470b57cec5SDimitry Andric         /*Extra Args=*/AL, /*pointer-to-OSObject-pointer*/ 3, AL.getRange());
66480b57cec5SDimitry Andric     break;
66490b57cec5SDimitry Andric   case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
66500b57cec5SDimitry Andric     handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnNonZeroAttr>(
66510fca6ea1SDimitry Andric         S, D, AL, S.ObjC().isValidOSObjectOutParameter(D),
66520b57cec5SDimitry Andric         diag::warn_ns_attribute_wrong_parameter_type,
66530b57cec5SDimitry Andric         /*Extra Args=*/AL, /*pointer-to-OSObject-poointer*/ 3, AL.getRange());
66540b57cec5SDimitry Andric     break;
66550b57cec5SDimitry Andric   case ParsedAttr::AT_NSReturnsAutoreleased:
66560b57cec5SDimitry Andric   case ParsedAttr::AT_NSReturnsNotRetained:
66570b57cec5SDimitry Andric   case ParsedAttr::AT_NSReturnsRetained:
66580b57cec5SDimitry Andric   case ParsedAttr::AT_CFReturnsNotRetained:
66590b57cec5SDimitry Andric   case ParsedAttr::AT_CFReturnsRetained:
66600b57cec5SDimitry Andric   case ParsedAttr::AT_OSReturnsNotRetained:
66610b57cec5SDimitry Andric   case ParsedAttr::AT_OSReturnsRetained:
66620fca6ea1SDimitry Andric     S.ObjC().handleXReturnsXRetainedAttr(D, AL);
66630b57cec5SDimitry Andric     break;
66640b57cec5SDimitry Andric   case ParsedAttr::AT_WorkGroupSizeHint:
66650b57cec5SDimitry Andric     handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);
66660b57cec5SDimitry Andric     break;
66670b57cec5SDimitry Andric   case ParsedAttr::AT_ReqdWorkGroupSize:
66680b57cec5SDimitry Andric     handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);
66690b57cec5SDimitry Andric     break;
66700b57cec5SDimitry Andric   case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
66710fca6ea1SDimitry Andric     S.OpenCL().handleSubGroupSize(D, AL);
66720b57cec5SDimitry Andric     break;
66730b57cec5SDimitry Andric   case ParsedAttr::AT_VecTypeHint:
66740b57cec5SDimitry Andric     handleVecTypeHint(S, D, AL);
66750b57cec5SDimitry Andric     break;
66760b57cec5SDimitry Andric   case ParsedAttr::AT_InitPriority:
66770b57cec5SDimitry Andric       handleInitPriorityAttr(S, D, AL);
66780b57cec5SDimitry Andric     break;
66790b57cec5SDimitry Andric   case ParsedAttr::AT_Packed:
66800b57cec5SDimitry Andric     handlePackedAttr(S, D, AL);
66810b57cec5SDimitry Andric     break;
6682e8d8bef9SDimitry Andric   case ParsedAttr::AT_PreferredName:
6683e8d8bef9SDimitry Andric     handlePreferredName(S, D, AL);
6684e8d8bef9SDimitry Andric     break;
66850b57cec5SDimitry Andric   case ParsedAttr::AT_Section:
66860b57cec5SDimitry Andric     handleSectionAttr(S, D, AL);
66870b57cec5SDimitry Andric     break;
66881db9f3b2SDimitry Andric   case ParsedAttr::AT_CodeModel:
66891db9f3b2SDimitry Andric     handleCodeModelAttr(S, D, AL);
66901db9f3b2SDimitry Andric     break;
669181ad6265SDimitry Andric   case ParsedAttr::AT_RandomizeLayout:
669281ad6265SDimitry Andric     handleRandomizeLayoutAttr(S, D, AL);
669381ad6265SDimitry Andric     break;
669481ad6265SDimitry Andric   case ParsedAttr::AT_NoRandomizeLayout:
669581ad6265SDimitry Andric     handleNoRandomizeLayoutAttr(S, D, AL);
669681ad6265SDimitry Andric     break;
66970b57cec5SDimitry Andric   case ParsedAttr::AT_CodeSeg:
66980b57cec5SDimitry Andric     handleCodeSegAttr(S, D, AL);
66990b57cec5SDimitry Andric     break;
67000b57cec5SDimitry Andric   case ParsedAttr::AT_Target:
67010b57cec5SDimitry Andric     handleTargetAttr(S, D, AL);
67020b57cec5SDimitry Andric     break;
6703bdd1243dSDimitry Andric   case ParsedAttr::AT_TargetVersion:
6704bdd1243dSDimitry Andric     handleTargetVersionAttr(S, D, AL);
6705bdd1243dSDimitry Andric     break;
67064824e7fdSDimitry Andric   case ParsedAttr::AT_TargetClones:
67074824e7fdSDimitry Andric     handleTargetClonesAttr(S, D, AL);
67084824e7fdSDimitry Andric     break;
67090b57cec5SDimitry Andric   case ParsedAttr::AT_MinVectorWidth:
67100b57cec5SDimitry Andric     handleMinVectorWidthAttr(S, D, AL);
67110b57cec5SDimitry Andric     break;
67120b57cec5SDimitry Andric   case ParsedAttr::AT_Unavailable:
67130b57cec5SDimitry Andric     handleAttrWithMessage<UnavailableAttr>(S, D, AL);
67140b57cec5SDimitry Andric     break;
67150fca6ea1SDimitry Andric   case ParsedAttr::AT_OMPAssume:
67160fca6ea1SDimitry Andric     S.OpenMP().handleOMPAssumeAttr(D, AL);
6717e8d8bef9SDimitry Andric     break;
6718480093f4SDimitry Andric   case ParsedAttr::AT_ObjCDirect:
67190fca6ea1SDimitry Andric     S.ObjC().handleDirectAttr(D, AL);
6720480093f4SDimitry Andric     break;
6721480093f4SDimitry Andric   case ParsedAttr::AT_ObjCDirectMembers:
67220fca6ea1SDimitry Andric     S.ObjC().handleDirectMembersAttr(D, AL);
6723480093f4SDimitry Andric     handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
6724480093f4SDimitry Andric     break;
67250b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCExplicitProtocolImpl:
67260fca6ea1SDimitry Andric     S.ObjC().handleSuppresProtocolAttr(D, AL);
67270b57cec5SDimitry Andric     break;
67280b57cec5SDimitry Andric   case ParsedAttr::AT_Unused:
67290b57cec5SDimitry Andric     handleUnusedAttr(S, D, AL);
67300b57cec5SDimitry Andric     break;
67310b57cec5SDimitry Andric   case ParsedAttr::AT_Visibility:
67320b57cec5SDimitry Andric     handleVisibilityAttr(S, D, AL, false);
67330b57cec5SDimitry Andric     break;
67340b57cec5SDimitry Andric   case ParsedAttr::AT_TypeVisibility:
67350b57cec5SDimitry Andric     handleVisibilityAttr(S, D, AL, true);
67360b57cec5SDimitry Andric     break;
67370b57cec5SDimitry Andric   case ParsedAttr::AT_WarnUnusedResult:
67380b57cec5SDimitry Andric     handleWarnUnusedResult(S, D, AL);
67390b57cec5SDimitry Andric     break;
67400b57cec5SDimitry Andric   case ParsedAttr::AT_WeakRef:
67410b57cec5SDimitry Andric     handleWeakRefAttr(S, D, AL);
67420b57cec5SDimitry Andric     break;
67430b57cec5SDimitry Andric   case ParsedAttr::AT_WeakImport:
67440b57cec5SDimitry Andric     handleWeakImportAttr(S, D, AL);
67450b57cec5SDimitry Andric     break;
67460b57cec5SDimitry Andric   case ParsedAttr::AT_TransparentUnion:
67470b57cec5SDimitry Andric     handleTransparentUnionAttr(S, D, AL);
67480b57cec5SDimitry Andric     break;
67490b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCMethodFamily:
67500fca6ea1SDimitry Andric     S.ObjC().handleMethodFamilyAttr(D, AL);
67510b57cec5SDimitry Andric     break;
67520b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCNSObject:
67530fca6ea1SDimitry Andric     S.ObjC().handleNSObject(D, AL);
67540b57cec5SDimitry Andric     break;
67550b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCIndependentClass:
67560fca6ea1SDimitry Andric     S.ObjC().handleIndependentClass(D, AL);
67570b57cec5SDimitry Andric     break;
67580b57cec5SDimitry Andric   case ParsedAttr::AT_Blocks:
67590fca6ea1SDimitry Andric     S.ObjC().handleBlocksAttr(D, AL);
67600b57cec5SDimitry Andric     break;
67610b57cec5SDimitry Andric   case ParsedAttr::AT_Sentinel:
67620b57cec5SDimitry Andric     handleSentinelAttr(S, D, AL);
67630b57cec5SDimitry Andric     break;
67640b57cec5SDimitry Andric   case ParsedAttr::AT_Cleanup:
67650b57cec5SDimitry Andric     handleCleanupAttr(S, D, AL);
67660b57cec5SDimitry Andric     break;
67670b57cec5SDimitry Andric   case ParsedAttr::AT_NoDebug:
67680b57cec5SDimitry Andric     handleNoDebugAttr(S, D, AL);
67690b57cec5SDimitry Andric     break;
67705ffd83dbSDimitry Andric   case ParsedAttr::AT_CmseNSEntry:
67710fca6ea1SDimitry Andric     S.ARM().handleCmseNSEntryAttr(D, AL);
6772a7dea167SDimitry Andric     break;
67730b57cec5SDimitry Andric   case ParsedAttr::AT_StdCall:
67740b57cec5SDimitry Andric   case ParsedAttr::AT_CDecl:
67750b57cec5SDimitry Andric   case ParsedAttr::AT_FastCall:
67760b57cec5SDimitry Andric   case ParsedAttr::AT_ThisCall:
67770b57cec5SDimitry Andric   case ParsedAttr::AT_Pascal:
67780b57cec5SDimitry Andric   case ParsedAttr::AT_RegCall:
67790b57cec5SDimitry Andric   case ParsedAttr::AT_SwiftCall:
6780fe6060f1SDimitry Andric   case ParsedAttr::AT_SwiftAsyncCall:
67810b57cec5SDimitry Andric   case ParsedAttr::AT_VectorCall:
67820b57cec5SDimitry Andric   case ParsedAttr::AT_MSABI:
67830b57cec5SDimitry Andric   case ParsedAttr::AT_SysVABI:
67840b57cec5SDimitry Andric   case ParsedAttr::AT_Pcs:
67850b57cec5SDimitry Andric   case ParsedAttr::AT_IntelOclBicc:
67860b57cec5SDimitry Andric   case ParsedAttr::AT_PreserveMost:
67870b57cec5SDimitry Andric   case ParsedAttr::AT_PreserveAll:
67880b57cec5SDimitry Andric   case ParsedAttr::AT_AArch64VectorPcs:
678981ad6265SDimitry Andric   case ParsedAttr::AT_AArch64SVEPcs:
679081ad6265SDimitry Andric   case ParsedAttr::AT_AMDGPUKernelCall:
67915f757f3fSDimitry Andric   case ParsedAttr::AT_M68kRTD:
67920fca6ea1SDimitry Andric   case ParsedAttr::AT_PreserveNone:
67930fca6ea1SDimitry Andric   case ParsedAttr::AT_RISCVVectorCC:
67940b57cec5SDimitry Andric     handleCallConvAttr(S, D, AL);
67950b57cec5SDimitry Andric     break;
67960b57cec5SDimitry Andric   case ParsedAttr::AT_Suppress:
67970b57cec5SDimitry Andric     handleSuppressAttr(S, D, AL);
67980b57cec5SDimitry Andric     break;
6799a7dea167SDimitry Andric   case ParsedAttr::AT_Owner:
6800a7dea167SDimitry Andric   case ParsedAttr::AT_Pointer:
6801a7dea167SDimitry Andric     handleLifetimeCategoryAttr(S, D, AL);
6802a7dea167SDimitry Andric     break;
68030b57cec5SDimitry Andric   case ParsedAttr::AT_OpenCLAccess:
68040fca6ea1SDimitry Andric     S.OpenCL().handleAccessAttr(D, AL);
68050b57cec5SDimitry Andric     break;
68060b57cec5SDimitry Andric   case ParsedAttr::AT_OpenCLNoSVM:
68070fca6ea1SDimitry Andric     S.OpenCL().handleNoSVMAttr(D, AL);
68080b57cec5SDimitry Andric     break;
68090b57cec5SDimitry Andric   case ParsedAttr::AT_SwiftContext:
68100fca6ea1SDimitry Andric     S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftContext);
68110b57cec5SDimitry Andric     break;
6812fe6060f1SDimitry Andric   case ParsedAttr::AT_SwiftAsyncContext:
68130fca6ea1SDimitry Andric     S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftAsyncContext);
6814fe6060f1SDimitry Andric     break;
68150b57cec5SDimitry Andric   case ParsedAttr::AT_SwiftErrorResult:
68160fca6ea1SDimitry Andric     S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftErrorResult);
68170b57cec5SDimitry Andric     break;
68180b57cec5SDimitry Andric   case ParsedAttr::AT_SwiftIndirectResult:
68190fca6ea1SDimitry Andric     S.Swift().AddParameterABIAttr(D, AL, ParameterABI::SwiftIndirectResult);
68200b57cec5SDimitry Andric     break;
68210b57cec5SDimitry Andric   case ParsedAttr::AT_InternalLinkage:
68220b57cec5SDimitry Andric     handleInternalLinkageAttr(S, D, AL);
68230b57cec5SDimitry Andric     break;
682481ad6265SDimitry Andric   case ParsedAttr::AT_ZeroCallUsedRegs:
682581ad6265SDimitry Andric     handleZeroCallUsedRegsAttr(S, D, AL);
682681ad6265SDimitry Andric     break;
6827753f127fSDimitry Andric   case ParsedAttr::AT_FunctionReturnThunks:
6828753f127fSDimitry Andric     handleFunctionReturnThunksAttr(S, D, AL);
6829753f127fSDimitry Andric     break;
683006c3fb27SDimitry Andric   case ParsedAttr::AT_NoMerge:
683106c3fb27SDimitry Andric     handleNoMergeAttr(S, D, AL);
683206c3fb27SDimitry Andric     break;
68335f757f3fSDimitry Andric   case ParsedAttr::AT_NoUniqueAddress:
68345f757f3fSDimitry Andric     handleNoUniqueAddressAttr(S, D, AL);
68355f757f3fSDimitry Andric     break;
683606c3fb27SDimitry Andric 
683706c3fb27SDimitry Andric   case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
683806c3fb27SDimitry Andric     handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
683906c3fb27SDimitry Andric     break;
68400b57cec5SDimitry Andric 
6841297eecfbSDimitry Andric   case ParsedAttr::AT_CountedBy:
68420fca6ea1SDimitry Andric   case ParsedAttr::AT_CountedByOrNull:
68430fca6ea1SDimitry Andric   case ParsedAttr::AT_SizedBy:
68440fca6ea1SDimitry Andric   case ParsedAttr::AT_SizedByOrNull:
68450fca6ea1SDimitry Andric     handleCountedByAttrField(S, D, AL);
6846297eecfbSDimitry Andric     break;
6847297eecfbSDimitry Andric 
68480b57cec5SDimitry Andric   // Microsoft attributes:
68490b57cec5SDimitry Andric   case ParsedAttr::AT_LayoutVersion:
68500b57cec5SDimitry Andric     handleLayoutVersion(S, D, AL);
68510b57cec5SDimitry Andric     break;
68520b57cec5SDimitry Andric   case ParsedAttr::AT_Uuid:
68530b57cec5SDimitry Andric     handleUuidAttr(S, D, AL);
68540b57cec5SDimitry Andric     break;
68550b57cec5SDimitry Andric   case ParsedAttr::AT_MSInheritance:
68560b57cec5SDimitry Andric     handleMSInheritanceAttr(S, D, AL);
68570b57cec5SDimitry Andric     break;
68580b57cec5SDimitry Andric   case ParsedAttr::AT_Thread:
68590b57cec5SDimitry Andric     handleDeclspecThreadAttr(S, D, AL);
68600b57cec5SDimitry Andric     break;
68615f757f3fSDimitry Andric   case ParsedAttr::AT_MSConstexpr:
68625f757f3fSDimitry Andric     handleMSConstexprAttr(S, D, AL);
68635f757f3fSDimitry Andric     break;
6864*52418fc2SDimitry Andric   case ParsedAttr::AT_HybridPatchable:
6865*52418fc2SDimitry Andric     handleSimpleAttribute<HybridPatchableAttr>(S, D, AL);
6866*52418fc2SDimitry Andric     break;
68670b57cec5SDimitry Andric 
686881ad6265SDimitry Andric   // HLSL attributes:
686981ad6265SDimitry Andric   case ParsedAttr::AT_HLSLNumThreads:
68700fca6ea1SDimitry Andric     S.HLSL().handleNumThreadsAttr(D, AL);
687181ad6265SDimitry Andric     break;
687281ad6265SDimitry Andric   case ParsedAttr::AT_HLSLSV_GroupIndex:
68735f757f3fSDimitry Andric     handleSimpleAttribute<HLSLSV_GroupIndexAttr>(S, D, AL);
687481ad6265SDimitry Andric     break;
6875bdd1243dSDimitry Andric   case ParsedAttr::AT_HLSLSV_DispatchThreadID:
68760fca6ea1SDimitry Andric     S.HLSL().handleSV_DispatchThreadIDAttr(D, AL);
68770fca6ea1SDimitry Andric     break;
68780fca6ea1SDimitry Andric   case ParsedAttr::AT_HLSLPackOffset:
68790fca6ea1SDimitry Andric     S.HLSL().handlePackOffsetAttr(D, AL);
6880bdd1243dSDimitry Andric     break;
688181ad6265SDimitry Andric   case ParsedAttr::AT_HLSLShader:
68820fca6ea1SDimitry Andric     S.HLSL().handleShaderAttr(D, AL);
688381ad6265SDimitry Andric     break;
6884bdd1243dSDimitry Andric   case ParsedAttr::AT_HLSLResourceBinding:
68850fca6ea1SDimitry Andric     S.HLSL().handleResourceBindingAttr(D, AL);
68860fca6ea1SDimitry Andric     break;
68870fca6ea1SDimitry Andric   case ParsedAttr::AT_HLSLResourceClass:
68880fca6ea1SDimitry Andric     S.HLSL().handleResourceClassAttr(D, AL);
6889bdd1243dSDimitry Andric     break;
68905f757f3fSDimitry Andric   case ParsedAttr::AT_HLSLParamModifier:
68910fca6ea1SDimitry Andric     S.HLSL().handleParamModifierAttr(D, AL);
68925f757f3fSDimitry Andric     break;
689381ad6265SDimitry Andric 
68940b57cec5SDimitry Andric   case ParsedAttr::AT_AbiTag:
68950b57cec5SDimitry Andric     handleAbiTagAttr(S, D, AL);
68960b57cec5SDimitry Andric     break;
6897480093f4SDimitry Andric   case ParsedAttr::AT_CFGuard:
6898480093f4SDimitry Andric     handleCFGuardAttr(S, D, AL);
6899480093f4SDimitry Andric     break;
69000b57cec5SDimitry Andric 
69010b57cec5SDimitry Andric   // Thread safety attributes:
69020b57cec5SDimitry Andric   case ParsedAttr::AT_AssertExclusiveLock:
69030b57cec5SDimitry Andric     handleAssertExclusiveLockAttr(S, D, AL);
69040b57cec5SDimitry Andric     break;
69050b57cec5SDimitry Andric   case ParsedAttr::AT_AssertSharedLock:
69060b57cec5SDimitry Andric     handleAssertSharedLockAttr(S, D, AL);
69070b57cec5SDimitry Andric     break;
69080b57cec5SDimitry Andric   case ParsedAttr::AT_PtGuardedVar:
69090b57cec5SDimitry Andric     handlePtGuardedVarAttr(S, D, AL);
69100b57cec5SDimitry Andric     break;
69110b57cec5SDimitry Andric   case ParsedAttr::AT_NoSanitize:
69120b57cec5SDimitry Andric     handleNoSanitizeAttr(S, D, AL);
69130b57cec5SDimitry Andric     break;
69140b57cec5SDimitry Andric   case ParsedAttr::AT_NoSanitizeSpecific:
69150b57cec5SDimitry Andric     handleNoSanitizeSpecificAttr(S, D, AL);
69160b57cec5SDimitry Andric     break;
69170b57cec5SDimitry Andric   case ParsedAttr::AT_GuardedBy:
69180b57cec5SDimitry Andric     handleGuardedByAttr(S, D, AL);
69190b57cec5SDimitry Andric     break;
69200b57cec5SDimitry Andric   case ParsedAttr::AT_PtGuardedBy:
69210b57cec5SDimitry Andric     handlePtGuardedByAttr(S, D, AL);
69220b57cec5SDimitry Andric     break;
69230b57cec5SDimitry Andric   case ParsedAttr::AT_ExclusiveTrylockFunction:
69240b57cec5SDimitry Andric     handleExclusiveTrylockFunctionAttr(S, D, AL);
69250b57cec5SDimitry Andric     break;
69260b57cec5SDimitry Andric   case ParsedAttr::AT_LockReturned:
69270b57cec5SDimitry Andric     handleLockReturnedAttr(S, D, AL);
69280b57cec5SDimitry Andric     break;
69290b57cec5SDimitry Andric   case ParsedAttr::AT_LocksExcluded:
69300b57cec5SDimitry Andric     handleLocksExcludedAttr(S, D, AL);
69310b57cec5SDimitry Andric     break;
69320b57cec5SDimitry Andric   case ParsedAttr::AT_SharedTrylockFunction:
69330b57cec5SDimitry Andric     handleSharedTrylockFunctionAttr(S, D, AL);
69340b57cec5SDimitry Andric     break;
69350b57cec5SDimitry Andric   case ParsedAttr::AT_AcquiredBefore:
69360b57cec5SDimitry Andric     handleAcquiredBeforeAttr(S, D, AL);
69370b57cec5SDimitry Andric     break;
69380b57cec5SDimitry Andric   case ParsedAttr::AT_AcquiredAfter:
69390b57cec5SDimitry Andric     handleAcquiredAfterAttr(S, D, AL);
69400b57cec5SDimitry Andric     break;
69410b57cec5SDimitry Andric 
69420b57cec5SDimitry Andric   // Capability analysis attributes.
69430b57cec5SDimitry Andric   case ParsedAttr::AT_Capability:
69440b57cec5SDimitry Andric   case ParsedAttr::AT_Lockable:
69450b57cec5SDimitry Andric     handleCapabilityAttr(S, D, AL);
69460b57cec5SDimitry Andric     break;
69470b57cec5SDimitry Andric   case ParsedAttr::AT_RequiresCapability:
69480b57cec5SDimitry Andric     handleRequiresCapabilityAttr(S, D, AL);
69490b57cec5SDimitry Andric     break;
69500b57cec5SDimitry Andric 
69510b57cec5SDimitry Andric   case ParsedAttr::AT_AssertCapability:
69520b57cec5SDimitry Andric     handleAssertCapabilityAttr(S, D, AL);
69530b57cec5SDimitry Andric     break;
69540b57cec5SDimitry Andric   case ParsedAttr::AT_AcquireCapability:
69550b57cec5SDimitry Andric     handleAcquireCapabilityAttr(S, D, AL);
69560b57cec5SDimitry Andric     break;
69570b57cec5SDimitry Andric   case ParsedAttr::AT_ReleaseCapability:
69580b57cec5SDimitry Andric     handleReleaseCapabilityAttr(S, D, AL);
69590b57cec5SDimitry Andric     break;
69600b57cec5SDimitry Andric   case ParsedAttr::AT_TryAcquireCapability:
69610b57cec5SDimitry Andric     handleTryAcquireCapabilityAttr(S, D, AL);
69620b57cec5SDimitry Andric     break;
69630b57cec5SDimitry Andric 
69640b57cec5SDimitry Andric   // Consumed analysis attributes.
69650b57cec5SDimitry Andric   case ParsedAttr::AT_Consumable:
69660b57cec5SDimitry Andric     handleConsumableAttr(S, D, AL);
69670b57cec5SDimitry Andric     break;
69680b57cec5SDimitry Andric   case ParsedAttr::AT_CallableWhen:
69690b57cec5SDimitry Andric     handleCallableWhenAttr(S, D, AL);
69700b57cec5SDimitry Andric     break;
69710b57cec5SDimitry Andric   case ParsedAttr::AT_ParamTypestate:
69720b57cec5SDimitry Andric     handleParamTypestateAttr(S, D, AL);
69730b57cec5SDimitry Andric     break;
69740b57cec5SDimitry Andric   case ParsedAttr::AT_ReturnTypestate:
69750b57cec5SDimitry Andric     handleReturnTypestateAttr(S, D, AL);
69760b57cec5SDimitry Andric     break;
69770b57cec5SDimitry Andric   case ParsedAttr::AT_SetTypestate:
69780b57cec5SDimitry Andric     handleSetTypestateAttr(S, D, AL);
69790b57cec5SDimitry Andric     break;
69800b57cec5SDimitry Andric   case ParsedAttr::AT_TestTypestate:
69810b57cec5SDimitry Andric     handleTestTypestateAttr(S, D, AL);
69820b57cec5SDimitry Andric     break;
69830b57cec5SDimitry Andric 
69840b57cec5SDimitry Andric   // Type safety attributes.
69850b57cec5SDimitry Andric   case ParsedAttr::AT_ArgumentWithTypeTag:
69860b57cec5SDimitry Andric     handleArgumentWithTypeTagAttr(S, D, AL);
69870b57cec5SDimitry Andric     break;
69880b57cec5SDimitry Andric   case ParsedAttr::AT_TypeTagForDatatype:
69890b57cec5SDimitry Andric     handleTypeTagForDatatypeAttr(S, D, AL);
69900b57cec5SDimitry Andric     break;
69915ffd83dbSDimitry Andric 
6992e8d8bef9SDimitry Andric   // Swift attributes.
6993e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftAsyncName:
69940fca6ea1SDimitry Andric     S.Swift().handleAsyncName(D, AL);
6995e8d8bef9SDimitry Andric     break;
6996e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftAttr:
69970fca6ea1SDimitry Andric     S.Swift().handleAttrAttr(D, AL);
6998e8d8bef9SDimitry Andric     break;
6999e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftBridge:
70000fca6ea1SDimitry Andric     S.Swift().handleBridge(D, AL);
7001e8d8bef9SDimitry Andric     break;
7002e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftError:
70030fca6ea1SDimitry Andric     S.Swift().handleError(D, AL);
7004e8d8bef9SDimitry Andric     break;
7005e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftName:
70060fca6ea1SDimitry Andric     S.Swift().handleName(D, AL);
7007e8d8bef9SDimitry Andric     break;
7008e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftNewType:
70090fca6ea1SDimitry Andric     S.Swift().handleNewType(D, AL);
7010e8d8bef9SDimitry Andric     break;
7011e8d8bef9SDimitry Andric   case ParsedAttr::AT_SwiftAsync:
70120fca6ea1SDimitry Andric     S.Swift().handleAsyncAttr(D, AL);
7013e8d8bef9SDimitry Andric     break;
7014fe6060f1SDimitry Andric   case ParsedAttr::AT_SwiftAsyncError:
70150fca6ea1SDimitry Andric     S.Swift().handleAsyncError(D, AL);
7016fe6060f1SDimitry Andric     break;
7017e8d8bef9SDimitry Andric 
70180b57cec5SDimitry Andric   // XRay attributes.
70190b57cec5SDimitry Andric   case ParsedAttr::AT_XRayLogArgs:
70200b57cec5SDimitry Andric     handleXRayLogArgsAttr(S, D, AL);
70210b57cec5SDimitry Andric     break;
70220b57cec5SDimitry Andric 
7023480093f4SDimitry Andric   case ParsedAttr::AT_PatchableFunctionEntry:
7024480093f4SDimitry Andric     handlePatchableFunctionEntryAttr(S, D, AL);
7025480093f4SDimitry Andric     break;
7026480093f4SDimitry Andric 
70270b57cec5SDimitry Andric   case ParsedAttr::AT_AlwaysDestroy:
70280b57cec5SDimitry Andric   case ParsedAttr::AT_NoDestroy:
70290b57cec5SDimitry Andric     handleDestroyAttr(S, D, AL);
70300b57cec5SDimitry Andric     break;
70310b57cec5SDimitry Andric 
70320b57cec5SDimitry Andric   case ParsedAttr::AT_Uninitialized:
70330b57cec5SDimitry Andric     handleUninitializedAttr(S, D, AL);
70340b57cec5SDimitry Andric     break;
70350b57cec5SDimitry Andric 
70360b57cec5SDimitry Andric   case ParsedAttr::AT_ObjCExternallyRetained:
70370fca6ea1SDimitry Andric     S.ObjC().handleExternallyRetainedAttr(D, AL);
70380b57cec5SDimitry Andric     break;
70390b57cec5SDimitry Andric 
70400b57cec5SDimitry Andric   case ParsedAttr::AT_MIGServerRoutine:
70410b57cec5SDimitry Andric     handleMIGServerRoutineAttr(S, D, AL);
70420b57cec5SDimitry Andric     break;
70430b57cec5SDimitry Andric 
70440b57cec5SDimitry Andric   case ParsedAttr::AT_MSAllocator:
70450b57cec5SDimitry Andric     handleMSAllocatorAttr(S, D, AL);
70460b57cec5SDimitry Andric     break;
7047480093f4SDimitry Andric 
70485ffd83dbSDimitry Andric   case ParsedAttr::AT_ArmBuiltinAlias:
70490fca6ea1SDimitry Andric     S.ARM().handleBuiltinAliasAttr(D, AL);
7050480093f4SDimitry Andric     break;
7051480093f4SDimitry Andric 
70525f757f3fSDimitry Andric   case ParsedAttr::AT_ArmLocallyStreaming:
70535f757f3fSDimitry Andric     handleSimpleAttribute<ArmLocallyStreamingAttr>(S, D, AL);
70545f757f3fSDimitry Andric     break;
70555f757f3fSDimitry Andric 
70567a6dacacSDimitry Andric   case ParsedAttr::AT_ArmNew:
70570fca6ea1SDimitry Andric     S.ARM().handleNewAttr(D, AL);
70585f757f3fSDimitry Andric     break;
70595f757f3fSDimitry Andric 
7060480093f4SDimitry Andric   case ParsedAttr::AT_AcquireHandle:
70615ffd83dbSDimitry Andric     handleAcquireHandleAttr(S, D, AL);
7062480093f4SDimitry Andric     break;
7063480093f4SDimitry Andric 
7064480093f4SDimitry Andric   case ParsedAttr::AT_ReleaseHandle:
7065480093f4SDimitry Andric     handleHandleAttr<ReleaseHandleAttr>(S, D, AL);
7066480093f4SDimitry Andric     break;
7067480093f4SDimitry Andric 
706806c3fb27SDimitry Andric   case ParsedAttr::AT_UnsafeBufferUsage:
706906c3fb27SDimitry Andric     handleUnsafeBufferUsage<UnsafeBufferUsageAttr>(S, D, AL);
707006c3fb27SDimitry Andric     break;
707106c3fb27SDimitry Andric 
7072480093f4SDimitry Andric   case ParsedAttr::AT_UseHandle:
7073480093f4SDimitry Andric     handleHandleAttr<UseHandleAttr>(S, D, AL);
7074480093f4SDimitry Andric     break;
7075e8d8bef9SDimitry Andric 
7076e8d8bef9SDimitry Andric   case ParsedAttr::AT_EnforceTCB:
7077e8d8bef9SDimitry Andric     handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);
7078e8d8bef9SDimitry Andric     break;
7079e8d8bef9SDimitry Andric 
7080e8d8bef9SDimitry Andric   case ParsedAttr::AT_EnforceTCBLeaf:
7081e8d8bef9SDimitry Andric     handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
7082e8d8bef9SDimitry Andric     break;
7083fe6060f1SDimitry Andric 
7084fe6060f1SDimitry Andric   case ParsedAttr::AT_BuiltinAlias:
7085fe6060f1SDimitry Andric     handleBuiltinAliasAttr(S, D, AL);
7086fe6060f1SDimitry Andric     break;
7087fe6060f1SDimitry Andric 
70885f757f3fSDimitry Andric   case ParsedAttr::AT_PreferredType:
70895f757f3fSDimitry Andric     handlePreferredTypeAttr(S, D, AL);
70905f757f3fSDimitry Andric     break;
70915f757f3fSDimitry Andric 
7092fe6060f1SDimitry Andric   case ParsedAttr::AT_UsingIfExists:
7093fe6060f1SDimitry Andric     handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
7094fe6060f1SDimitry Andric     break;
70950fca6ea1SDimitry Andric 
70960fca6ea1SDimitry Andric   case ParsedAttr::AT_TypeNullable:
70970fca6ea1SDimitry Andric     handleNullableTypeAttr(S, D, AL);
70980fca6ea1SDimitry Andric     break;
70990fca6ea1SDimitry Andric 
71000fca6ea1SDimitry Andric   case ParsedAttr::AT_VTablePointerAuthentication:
71010fca6ea1SDimitry Andric     handleVTablePointerAuthentication(S, D, AL);
71020fca6ea1SDimitry Andric     break;
71030b57cec5SDimitry Andric   }
71040b57cec5SDimitry Andric }
71050b57cec5SDimitry Andric 
710681ad6265SDimitry Andric void Sema::ProcessDeclAttributeList(
710781ad6265SDimitry Andric     Scope *S, Decl *D, const ParsedAttributesView &AttrList,
710881ad6265SDimitry Andric     const ProcessDeclAttributeOptions &Options) {
71090b57cec5SDimitry Andric   if (AttrList.empty())
71100b57cec5SDimitry Andric     return;
71110b57cec5SDimitry Andric 
71120b57cec5SDimitry Andric   for (const ParsedAttr &AL : AttrList)
711381ad6265SDimitry Andric     ProcessDeclAttribute(*this, S, D, AL, Options);
71140b57cec5SDimitry Andric 
71150b57cec5SDimitry Andric   // FIXME: We should be able to handle these cases in TableGen.
71160b57cec5SDimitry Andric   // GCC accepts
71170b57cec5SDimitry Andric   // static int a9 __attribute__((weakref));
71180b57cec5SDimitry Andric   // but that looks really pointless. We reject it.
71190b57cec5SDimitry Andric   if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
71200b57cec5SDimitry Andric     Diag(AttrList.begin()->getLoc(), diag::err_attribute_weakref_without_alias)
71210b57cec5SDimitry Andric         << cast<NamedDecl>(D);
71220b57cec5SDimitry Andric     D->dropAttr<WeakRefAttr>();
71230b57cec5SDimitry Andric     return;
71240b57cec5SDimitry Andric   }
71250b57cec5SDimitry Andric 
71260b57cec5SDimitry Andric   // FIXME: We should be able to handle this in TableGen as well. It would be
71270b57cec5SDimitry Andric   // good to have a way to specify "these attributes must appear as a group",
71280b57cec5SDimitry Andric   // for these. Additionally, it would be good to have a way to specify "these
71290b57cec5SDimitry Andric   // attribute must never appear as a group" for attributes like cold and hot.
71300b57cec5SDimitry Andric   if (!D->hasAttr<OpenCLKernelAttr>()) {
71310b57cec5SDimitry Andric     // These attributes cannot be applied to a non-kernel function.
71320b57cec5SDimitry Andric     if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
71330b57cec5SDimitry Andric       // FIXME: This emits a different error message than
71340b57cec5SDimitry Andric       // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
71350b57cec5SDimitry Andric       Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
71360b57cec5SDimitry Andric       D->setInvalidDecl();
71370b57cec5SDimitry Andric     } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
71380b57cec5SDimitry Andric       Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
71390b57cec5SDimitry Andric       D->setInvalidDecl();
71400b57cec5SDimitry Andric     } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
71410b57cec5SDimitry Andric       Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
71420b57cec5SDimitry Andric       D->setInvalidDecl();
71430b57cec5SDimitry Andric     } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
71440b57cec5SDimitry Andric       Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
71450b57cec5SDimitry Andric       D->setInvalidDecl();
71460b57cec5SDimitry Andric     } else if (!D->hasAttr<CUDAGlobalAttr>()) {
71470b57cec5SDimitry Andric       if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
71480b57cec5SDimitry Andric         Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
714906c3fb27SDimitry Andric             << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
71500b57cec5SDimitry Andric         D->setInvalidDecl();
71510b57cec5SDimitry Andric       } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
71520b57cec5SDimitry Andric         Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
715306c3fb27SDimitry Andric             << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
71540b57cec5SDimitry Andric         D->setInvalidDecl();
71550b57cec5SDimitry Andric       } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
71560b57cec5SDimitry Andric         Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
715706c3fb27SDimitry Andric             << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
71580b57cec5SDimitry Andric         D->setInvalidDecl();
71590b57cec5SDimitry Andric       } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
71600b57cec5SDimitry Andric         Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
716106c3fb27SDimitry Andric             << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
71620b57cec5SDimitry Andric         D->setInvalidDecl();
71630b57cec5SDimitry Andric       }
71640b57cec5SDimitry Andric     }
71650b57cec5SDimitry Andric   }
71660b57cec5SDimitry Andric 
71670b57cec5SDimitry Andric   // Do this check after processing D's attributes because the attribute
71680b57cec5SDimitry Andric   // objc_method_family can change whether the given method is in the init
71690b57cec5SDimitry Andric   // family, and it can be applied after objc_designated_initializer. This is a
71700b57cec5SDimitry Andric   // bit of a hack, but we need it to be compatible with versions of clang that
71710b57cec5SDimitry Andric   // processed the attribute list in the wrong order.
71720b57cec5SDimitry Andric   if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
71730b57cec5SDimitry Andric       cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
71740b57cec5SDimitry Andric     Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
71750b57cec5SDimitry Andric     D->dropAttr<ObjCDesignatedInitializerAttr>();
71760b57cec5SDimitry Andric   }
71770b57cec5SDimitry Andric }
71780b57cec5SDimitry Andric 
71790b57cec5SDimitry Andric void Sema::ProcessDeclAttributeDelayed(Decl *D,
71800b57cec5SDimitry Andric                                        const ParsedAttributesView &AttrList) {
71810b57cec5SDimitry Andric   for (const ParsedAttr &AL : AttrList)
71820b57cec5SDimitry Andric     if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
71830b57cec5SDimitry Andric       handleTransparentUnionAttr(*this, D, AL);
71840b57cec5SDimitry Andric       break;
71850b57cec5SDimitry Andric     }
7186480093f4SDimitry Andric 
7187480093f4SDimitry Andric   // For BPFPreserveAccessIndexAttr, we want to populate the attributes
7188480093f4SDimitry Andric   // to fields and inner records as well.
7189480093f4SDimitry Andric   if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
71900fca6ea1SDimitry Andric     BPF().handlePreserveAIRecord(cast<RecordDecl>(D));
71910b57cec5SDimitry Andric }
71920b57cec5SDimitry Andric 
71930b57cec5SDimitry Andric bool Sema::ProcessAccessDeclAttributeList(
71940b57cec5SDimitry Andric     AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
71950b57cec5SDimitry Andric   for (const ParsedAttr &AL : AttrList) {
71960b57cec5SDimitry Andric     if (AL.getKind() == ParsedAttr::AT_Annotate) {
719781ad6265SDimitry Andric       ProcessDeclAttribute(*this, nullptr, ASDecl, AL,
719881ad6265SDimitry Andric                            ProcessDeclAttributeOptions());
71990b57cec5SDimitry Andric     } else {
72000b57cec5SDimitry Andric       Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
72010b57cec5SDimitry Andric       return true;
72020b57cec5SDimitry Andric     }
72030b57cec5SDimitry Andric   }
72040b57cec5SDimitry Andric   return false;
72050b57cec5SDimitry Andric }
72060b57cec5SDimitry Andric 
72070b57cec5SDimitry Andric /// checkUnusedDeclAttributes - Check a list of attributes to see if it
72080b57cec5SDimitry Andric /// contains any decl attributes that we should warn about.
72090b57cec5SDimitry Andric static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) {
72100b57cec5SDimitry Andric   for (const ParsedAttr &AL : A) {
72110b57cec5SDimitry Andric     // Only warn if the attribute is an unignored, non-type attribute.
72120b57cec5SDimitry Andric     if (AL.isUsedAsTypeAttr() || AL.isInvalid())
72130b57cec5SDimitry Andric       continue;
72140b57cec5SDimitry Andric     if (AL.getKind() == ParsedAttr::IgnoredAttribute)
72150b57cec5SDimitry Andric       continue;
72160b57cec5SDimitry Andric 
72170b57cec5SDimitry Andric     if (AL.getKind() == ParsedAttr::UnknownAttribute) {
72180b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
72190b57cec5SDimitry Andric           << AL << AL.getRange();
72200b57cec5SDimitry Andric     } else {
72210b57cec5SDimitry Andric       S.Diag(AL.getLoc(), diag::warn_attribute_not_on_decl) << AL
72220b57cec5SDimitry Andric                                                             << AL.getRange();
72230b57cec5SDimitry Andric     }
72240b57cec5SDimitry Andric   }
72250b57cec5SDimitry Andric }
72260b57cec5SDimitry Andric 
72270b57cec5SDimitry Andric void Sema::checkUnusedDeclAttributes(Declarator &D) {
722881ad6265SDimitry Andric   ::checkUnusedDeclAttributes(*this, D.getDeclarationAttributes());
72290b57cec5SDimitry Andric   ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes());
72300b57cec5SDimitry Andric   ::checkUnusedDeclAttributes(*this, D.getAttributes());
72310b57cec5SDimitry Andric   for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
72320b57cec5SDimitry Andric     ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs());
72330b57cec5SDimitry Andric }
72340b57cec5SDimitry Andric 
723581ad6265SDimitry Andric NamedDecl *Sema::DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,
72360b57cec5SDimitry Andric                                      SourceLocation Loc) {
72370b57cec5SDimitry Andric   assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
72380b57cec5SDimitry Andric   NamedDecl *NewD = nullptr;
72390b57cec5SDimitry Andric   if (auto *FD = dyn_cast<FunctionDecl>(ND)) {
72400b57cec5SDimitry Andric     FunctionDecl *NewFD;
72410b57cec5SDimitry Andric     // FIXME: Missing call to CheckFunctionDeclaration().
72420b57cec5SDimitry Andric     // FIXME: Mangling?
72430b57cec5SDimitry Andric     // FIXME: Is the qualifier info correct?
72440b57cec5SDimitry Andric     // FIXME: Is the DeclContext correct?
72450b57cec5SDimitry Andric     NewFD = FunctionDecl::Create(
72460b57cec5SDimitry Andric         FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
72470b57cec5SDimitry Andric         DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None,
7248349cc55cSDimitry Andric         getCurFPFeatures().isFPConstrained(), false /*isInlineSpecified*/,
7249349cc55cSDimitry Andric         FD->hasPrototype(), ConstexprSpecKind::Unspecified,
7250349cc55cSDimitry Andric         FD->getTrailingRequiresClause());
72510b57cec5SDimitry Andric     NewD = NewFD;
72520b57cec5SDimitry Andric 
72530b57cec5SDimitry Andric     if (FD->getQualifier())
72540b57cec5SDimitry Andric       NewFD->setQualifierInfo(FD->getQualifierLoc());
72550b57cec5SDimitry Andric 
72560b57cec5SDimitry Andric     // Fake up parameter variables; they are declared as if this were
72570b57cec5SDimitry Andric     // a typedef.
72580b57cec5SDimitry Andric     QualType FDTy = FD->getType();
72590b57cec5SDimitry Andric     if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
72600b57cec5SDimitry Andric       SmallVector<ParmVarDecl*, 16> Params;
72610b57cec5SDimitry Andric       for (const auto &AI : FT->param_types()) {
72620b57cec5SDimitry Andric         ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
72630b57cec5SDimitry Andric         Param->setScopeInfo(0, Params.size());
72640b57cec5SDimitry Andric         Params.push_back(Param);
72650b57cec5SDimitry Andric       }
72660b57cec5SDimitry Andric       NewFD->setParams(Params);
72670b57cec5SDimitry Andric     }
72680b57cec5SDimitry Andric   } else if (auto *VD = dyn_cast<VarDecl>(ND)) {
72690b57cec5SDimitry Andric     NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
72700b57cec5SDimitry Andric                            VD->getInnerLocStart(), VD->getLocation(), II,
72710b57cec5SDimitry Andric                            VD->getType(), VD->getTypeSourceInfo(),
72720b57cec5SDimitry Andric                            VD->getStorageClass());
72730b57cec5SDimitry Andric     if (VD->getQualifier())
72740b57cec5SDimitry Andric       cast<VarDecl>(NewD)->setQualifierInfo(VD->getQualifierLoc());
72750b57cec5SDimitry Andric   }
72760b57cec5SDimitry Andric   return NewD;
72770b57cec5SDimitry Andric }
72780b57cec5SDimitry Andric 
727981ad6265SDimitry Andric void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W) {
72800b57cec5SDimitry Andric   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
72810b57cec5SDimitry Andric     IdentifierInfo *NDId = ND->getIdentifier();
72820b57cec5SDimitry Andric     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
7283a7dea167SDimitry Andric     NewD->addAttr(
7284a7dea167SDimitry Andric         AliasAttr::CreateImplicit(Context, NDId->getName(), W.getLocation()));
728506c3fb27SDimitry Andric     NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
72860b57cec5SDimitry Andric     WeakTopLevelDecl.push_back(NewD);
72870b57cec5SDimitry Andric     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
72880b57cec5SDimitry Andric     // to insert Decl at TU scope, sorry.
72890b57cec5SDimitry Andric     DeclContext *SavedContext = CurContext;
72900b57cec5SDimitry Andric     CurContext = Context.getTranslationUnitDecl();
72910b57cec5SDimitry Andric     NewD->setDeclContext(CurContext);
72920b57cec5SDimitry Andric     NewD->setLexicalDeclContext(CurContext);
72930b57cec5SDimitry Andric     PushOnScopeChains(NewD, S);
72940b57cec5SDimitry Andric     CurContext = SavedContext;
72950b57cec5SDimitry Andric   } else { // just add weak to existing
729606c3fb27SDimitry Andric     ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
72970b57cec5SDimitry Andric   }
72980b57cec5SDimitry Andric }
72990b57cec5SDimitry Andric 
73000b57cec5SDimitry Andric void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
73010b57cec5SDimitry Andric   // It's valid to "forward-declare" #pragma weak, in which case we
73020b57cec5SDimitry Andric   // have to do this.
73030b57cec5SDimitry Andric   LoadExternalWeakUndeclaredIdentifiers();
730481ad6265SDimitry Andric   if (WeakUndeclaredIdentifiers.empty())
730581ad6265SDimitry Andric     return;
73060b57cec5SDimitry Andric   NamedDecl *ND = nullptr;
73070b57cec5SDimitry Andric   if (auto *VD = dyn_cast<VarDecl>(D))
73080b57cec5SDimitry Andric     if (VD->isExternC())
73090b57cec5SDimitry Andric       ND = VD;
73100b57cec5SDimitry Andric   if (auto *FD = dyn_cast<FunctionDecl>(D))
73110b57cec5SDimitry Andric     if (FD->isExternC())
73120b57cec5SDimitry Andric       ND = FD;
731381ad6265SDimitry Andric   if (!ND)
731481ad6265SDimitry Andric     return;
73150b57cec5SDimitry Andric   if (IdentifierInfo *Id = ND->getIdentifier()) {
73160b57cec5SDimitry Andric     auto I = WeakUndeclaredIdentifiers.find(Id);
73170b57cec5SDimitry Andric     if (I != WeakUndeclaredIdentifiers.end()) {
731881ad6265SDimitry Andric       auto &WeakInfos = I->second;
731981ad6265SDimitry Andric       for (const auto &W : WeakInfos)
73200b57cec5SDimitry Andric         DeclApplyPragmaWeak(S, ND, W);
732181ad6265SDimitry Andric       std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
732281ad6265SDimitry Andric       WeakInfos.swap(EmptyWeakInfos);
73230b57cec5SDimitry Andric     }
73240b57cec5SDimitry Andric   }
73250b57cec5SDimitry Andric }
73260b57cec5SDimitry Andric 
73270b57cec5SDimitry Andric /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
73280b57cec5SDimitry Andric /// it, apply them to D.  This is a bit tricky because PD can have attributes
73290b57cec5SDimitry Andric /// specified in many different places, and we need to find and apply them all.
73300b57cec5SDimitry Andric void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
733181ad6265SDimitry Andric   // Ordering of attributes can be important, so we take care to process
733281ad6265SDimitry Andric   // attributes in the order in which they appeared in the source code.
733381ad6265SDimitry Andric 
73340fca6ea1SDimitry Andric   auto ProcessAttributesWithSliding =
73350fca6ea1SDimitry Andric       [&](const ParsedAttributesView &Src,
73360fca6ea1SDimitry Andric           const ProcessDeclAttributeOptions &Options) {
733781ad6265SDimitry Andric         ParsedAttributesView NonSlidingAttrs;
73380fca6ea1SDimitry Andric         for (ParsedAttr &AL : Src) {
73390fca6ea1SDimitry Andric           // FIXME: this sliding is specific to standard attributes and should
73400fca6ea1SDimitry Andric           // eventually be deprecated and removed as those are not intended to
73410fca6ea1SDimitry Andric           // slide to anything.
73420fca6ea1SDimitry Andric           if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) &&
73430fca6ea1SDimitry Andric               AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
73440fca6ea1SDimitry Andric             // Skip processing the attribute, but do check if it appertains to
73450fca6ea1SDimitry Andric             // the declaration. This is needed for the `MatrixType` attribute,
73460fca6ea1SDimitry Andric             // which, despite being a type attribute, defines a `SubjectList`
73470fca6ea1SDimitry Andric             // that only allows it to be used on typedef declarations.
734881ad6265SDimitry Andric             AL.diagnoseAppertainsTo(*this, D);
734981ad6265SDimitry Andric           } else {
735081ad6265SDimitry Andric             NonSlidingAttrs.addAtEnd(&AL);
735181ad6265SDimitry Andric           }
735281ad6265SDimitry Andric         }
73530fca6ea1SDimitry Andric         ProcessDeclAttributeList(S, D, NonSlidingAttrs, Options);
73540fca6ea1SDimitry Andric       };
73550fca6ea1SDimitry Andric 
73560fca6ea1SDimitry Andric   // First, process attributes that appeared on the declaration itself (but
73570fca6ea1SDimitry Andric   // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
73580fca6ea1SDimitry Andric   ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {});
735981ad6265SDimitry Andric 
73600b57cec5SDimitry Andric   // Apply decl attributes from the DeclSpec if present.
73610fca6ea1SDimitry Andric   ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(),
736281ad6265SDimitry Andric                                ProcessDeclAttributeOptions()
736381ad6265SDimitry Andric                                    .WithIncludeCXX11Attributes(false)
736481ad6265SDimitry Andric                                    .WithIgnoreTypeAttributes(true));
73650b57cec5SDimitry Andric 
73660b57cec5SDimitry Andric   // Walk the declarator structure, applying decl attributes that were in a type
73670b57cec5SDimitry Andric   // position to the decl itself.  This handles cases like:
73680b57cec5SDimitry Andric   //   int *__attr__(x)** D;
73690b57cec5SDimitry Andric   // when X is a decl attribute.
737081ad6265SDimitry Andric   for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
73710b57cec5SDimitry Andric     ProcessDeclAttributeList(S, D, PD.getTypeObject(i).getAttrs(),
737281ad6265SDimitry Andric                              ProcessDeclAttributeOptions()
737381ad6265SDimitry Andric                                  .WithIncludeCXX11Attributes(false)
737481ad6265SDimitry Andric                                  .WithIgnoreTypeAttributes(true));
737581ad6265SDimitry Andric   }
73760b57cec5SDimitry Andric 
73770b57cec5SDimitry Andric   // Finally, apply any attributes on the decl itself.
73780b57cec5SDimitry Andric   ProcessDeclAttributeList(S, D, PD.getAttributes());
73790b57cec5SDimitry Andric 
73800b57cec5SDimitry Andric   // Apply additional attributes specified by '#pragma clang attribute'.
73810b57cec5SDimitry Andric   AddPragmaAttributes(S, D);
73820fca6ea1SDimitry Andric 
73830fca6ea1SDimitry Andric   // Look for API notes that map to attributes.
73840fca6ea1SDimitry Andric   ProcessAPINotes(D);
73850b57cec5SDimitry Andric }
73860b57cec5SDimitry Andric 
73870b57cec5SDimitry Andric /// Is the given declaration allowed to use a forbidden type?
73880b57cec5SDimitry Andric /// If so, it'll still be annotated with an attribute that makes it
73890b57cec5SDimitry Andric /// illegal to actually use.
73900b57cec5SDimitry Andric static bool isForbiddenTypeAllowed(Sema &S, Decl *D,
73910b57cec5SDimitry Andric                                    const DelayedDiagnostic &diag,
73920b57cec5SDimitry Andric                                    UnavailableAttr::ImplicitReason &reason) {
73930b57cec5SDimitry Andric   // Private ivars are always okay.  Unfortunately, people don't
73940b57cec5SDimitry Andric   // always properly make their ivars private, even in system headers.
73950b57cec5SDimitry Andric   // Plus we need to make fields okay, too.
73960b57cec5SDimitry Andric   if (!isa<FieldDecl>(D) && !isa<ObjCPropertyDecl>(D) &&
73970b57cec5SDimitry Andric       !isa<FunctionDecl>(D))
73980b57cec5SDimitry Andric     return false;
73990b57cec5SDimitry Andric 
74000b57cec5SDimitry Andric   // Silently accept unsupported uses of __weak in both user and system
74010b57cec5SDimitry Andric   // declarations when it's been disabled, for ease of integration with
74020b57cec5SDimitry Andric   // -fno-objc-arc files.  We do have to take some care against attempts
74030b57cec5SDimitry Andric   // to define such things;  for now, we've only done that for ivars
74040b57cec5SDimitry Andric   // and properties.
74050b57cec5SDimitry Andric   if ((isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) {
74060b57cec5SDimitry Andric     if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
74070b57cec5SDimitry Andric         diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
74080b57cec5SDimitry Andric       reason = UnavailableAttr::IR_ForbiddenWeak;
74090b57cec5SDimitry Andric       return true;
74100b57cec5SDimitry Andric     }
74110b57cec5SDimitry Andric   }
74120b57cec5SDimitry Andric 
74130b57cec5SDimitry Andric   // Allow all sorts of things in system headers.
74140b57cec5SDimitry Andric   if (S.Context.getSourceManager().isInSystemHeader(D->getLocation())) {
74150b57cec5SDimitry Andric     // Currently, all the failures dealt with this way are due to ARC
74160b57cec5SDimitry Andric     // restrictions.
74170b57cec5SDimitry Andric     reason = UnavailableAttr::IR_ARCForbiddenType;
74180b57cec5SDimitry Andric     return true;
74190b57cec5SDimitry Andric   }
74200b57cec5SDimitry Andric 
74210b57cec5SDimitry Andric   return false;
74220b57cec5SDimitry Andric }
74230b57cec5SDimitry Andric 
74240b57cec5SDimitry Andric /// Handle a delayed forbidden-type diagnostic.
74250b57cec5SDimitry Andric static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD,
74260b57cec5SDimitry Andric                                        Decl *D) {
74270b57cec5SDimitry Andric   auto Reason = UnavailableAttr::IR_None;
74280b57cec5SDimitry Andric   if (D && isForbiddenTypeAllowed(S, D, DD, Reason)) {
74290b57cec5SDimitry Andric     assert(Reason && "didn't set reason?");
74300b57cec5SDimitry Andric     D->addAttr(UnavailableAttr::CreateImplicit(S.Context, "", Reason, DD.Loc));
74310b57cec5SDimitry Andric     return;
74320b57cec5SDimitry Andric   }
74330b57cec5SDimitry Andric   if (S.getLangOpts().ObjCAutoRefCount)
74340b57cec5SDimitry Andric     if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
74350b57cec5SDimitry Andric       // FIXME: we may want to suppress diagnostics for all
74360b57cec5SDimitry Andric       // kind of forbidden type messages on unavailable functions.
74370b57cec5SDimitry Andric       if (FD->hasAttr<UnavailableAttr>() &&
74380b57cec5SDimitry Andric           DD.getForbiddenTypeDiagnostic() ==
74390b57cec5SDimitry Andric               diag::err_arc_array_param_no_ownership) {
74400b57cec5SDimitry Andric         DD.Triggered = true;
74410b57cec5SDimitry Andric         return;
74420b57cec5SDimitry Andric       }
74430b57cec5SDimitry Andric     }
74440b57cec5SDimitry Andric 
74450b57cec5SDimitry Andric   S.Diag(DD.Loc, DD.getForbiddenTypeDiagnostic())
74460b57cec5SDimitry Andric       << DD.getForbiddenTypeOperand() << DD.getForbiddenTypeArgument();
74470b57cec5SDimitry Andric   DD.Triggered = true;
74480b57cec5SDimitry Andric }
74490b57cec5SDimitry Andric 
74500b57cec5SDimitry Andric 
74510b57cec5SDimitry Andric void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
74520b57cec5SDimitry Andric   assert(DelayedDiagnostics.getCurrentPool());
74530b57cec5SDimitry Andric   DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
74540b57cec5SDimitry Andric   DelayedDiagnostics.popWithoutEmitting(state);
74550b57cec5SDimitry Andric 
74560b57cec5SDimitry Andric   // When delaying diagnostics to run in the context of a parsed
74570b57cec5SDimitry Andric   // declaration, we only want to actually emit anything if parsing
74580b57cec5SDimitry Andric   // succeeds.
74590b57cec5SDimitry Andric   if (!decl) return;
74600b57cec5SDimitry Andric 
74610b57cec5SDimitry Andric   // We emit all the active diagnostics in this pool or any of its
74620b57cec5SDimitry Andric   // parents.  In general, we'll get one pool for the decl spec
74630b57cec5SDimitry Andric   // and a child pool for each declarator; in a decl group like:
74640b57cec5SDimitry Andric   //   deprecated_typedef foo, *bar, baz();
74650b57cec5SDimitry Andric   // only the declarator pops will be passed decls.  This is correct;
74660b57cec5SDimitry Andric   // we really do need to consider delayed diagnostics from the decl spec
74670b57cec5SDimitry Andric   // for each of the different declarations.
74680b57cec5SDimitry Andric   const DelayedDiagnosticPool *pool = &poppedPool;
74690b57cec5SDimitry Andric   do {
74700b57cec5SDimitry Andric     bool AnyAccessFailures = false;
74710b57cec5SDimitry Andric     for (DelayedDiagnosticPool::pool_iterator
74720b57cec5SDimitry Andric            i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
74730b57cec5SDimitry Andric       // This const_cast is a bit lame.  Really, Triggered should be mutable.
74740b57cec5SDimitry Andric       DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
74750b57cec5SDimitry Andric       if (diag.Triggered)
74760b57cec5SDimitry Andric         continue;
74770b57cec5SDimitry Andric 
74780b57cec5SDimitry Andric       switch (diag.Kind) {
74790b57cec5SDimitry Andric       case DelayedDiagnostic::Availability:
74800b57cec5SDimitry Andric         // Don't bother giving deprecation/unavailable diagnostics if
74810b57cec5SDimitry Andric         // the decl is invalid.
74820b57cec5SDimitry Andric         if (!decl->isInvalidDecl())
74835ffd83dbSDimitry Andric           handleDelayedAvailabilityCheck(diag, decl);
74840b57cec5SDimitry Andric         break;
74850b57cec5SDimitry Andric 
74860b57cec5SDimitry Andric       case DelayedDiagnostic::Access:
74870b57cec5SDimitry Andric         // Only produce one access control diagnostic for a structured binding
74880b57cec5SDimitry Andric         // declaration: we don't need to tell the user that all the fields are
74890b57cec5SDimitry Andric         // inaccessible one at a time.
74900b57cec5SDimitry Andric         if (AnyAccessFailures && isa<DecompositionDecl>(decl))
74910b57cec5SDimitry Andric           continue;
74920b57cec5SDimitry Andric         HandleDelayedAccessCheck(diag, decl);
74930b57cec5SDimitry Andric         if (diag.Triggered)
74940b57cec5SDimitry Andric           AnyAccessFailures = true;
74950b57cec5SDimitry Andric         break;
74960b57cec5SDimitry Andric 
74970b57cec5SDimitry Andric       case DelayedDiagnostic::ForbiddenType:
74980b57cec5SDimitry Andric         handleDelayedForbiddenType(*this, diag, decl);
74990b57cec5SDimitry Andric         break;
75000b57cec5SDimitry Andric       }
75010b57cec5SDimitry Andric     }
75020b57cec5SDimitry Andric   } while ((pool = pool->getParent()));
75030b57cec5SDimitry Andric }
75040b57cec5SDimitry Andric 
75050b57cec5SDimitry Andric void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
75060b57cec5SDimitry Andric   DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
75070b57cec5SDimitry Andric   assert(curPool && "re-emitting in undelayed context not supported");
75080b57cec5SDimitry Andric   curPool->steal(pool);
75090b57cec5SDimitry Andric }
7510