aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp842
1 files changed, 477 insertions, 365 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 30d08b3d4ac0..bb4ce8d4962e 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -23,6 +23,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/DarwinSDKInfo.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetBuiltins.h"
@@ -40,6 +41,8 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Assumptions.h"
+#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
@@ -153,7 +156,8 @@ static bool isInstanceMethod(const Decl *D) {
return false;
}
-static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
+static inline bool isNSStringType(QualType T, ASTContext &Ctx,
+ bool AllowNSAttributedString = false) {
const auto *PT = T->getAs<ObjCObjectPointerType>();
if (!PT)
return false;
@@ -164,6 +168,9 @@ static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
IdentifierInfo* ClsName = Cls->getIdentifier();
+ if (AllowNSAttributedString &&
+ ClsName == &Ctx.Idents.get("NSAttributedString"))
+ return true;
// FIXME: Should we walk the chain of classes?
return ClsName == &Ctx.Idents.get("NSString") ||
ClsName == &Ctx.Idents.get("NSMutableString");
@@ -190,44 +197,6 @@ static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
return AL.getNumArgs() + AL.hasParsedType();
}
-template <typename Compare>
-static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL,
- unsigned Num, unsigned Diag,
- Compare Comp) {
- if (Comp(getNumAttributeArgs(AL), Num)) {
- S.Diag(AL.getLoc(), Diag) << AL << Num;
- return false;
- }
-
- return true;
-}
-
-/// Check if the attribute has exactly as many args as Num. May
-/// output an error.
-static bool checkAttributeNumArgs(Sema &S, const ParsedAttr &AL, unsigned Num) {
- return checkAttributeNumArgsImpl(S, AL, Num,
- diag::err_attribute_wrong_number_arguments,
- std::not_equal_to<unsigned>());
-}
-
-/// Check if the attribute has at least as many args as Num. May
-/// output an error.
-static bool checkAttributeAtLeastNumArgs(Sema &S, const ParsedAttr &AL,
- unsigned Num) {
- return checkAttributeNumArgsImpl(S, AL, Num,
- diag::err_attribute_too_few_arguments,
- std::less<unsigned>());
-}
-
-/// Check if the attribute has at most as many args as Num. May
-/// output an error.
-static bool checkAttributeAtMostNumArgs(Sema &S, const ParsedAttr &AL,
- unsigned Num) {
- return checkAttributeNumArgsImpl(S, AL, Num,
- diag::err_attribute_too_many_arguments,
- std::greater<unsigned>());
-}
-
/// A helper function to provide Attribute Location for the Attr types
/// AND the ParsedAttr.
template <typename AttrInfo>
@@ -261,7 +230,7 @@ static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
if (!I->isIntN(32)) {
S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
- << I->toString(10, false) << 32 << /* Unsigned */ 1;
+ << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
return false;
}
@@ -289,7 +258,7 @@ static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Ex
llvm::APSInt I(32); // for toString
I = UVal;
S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
- << I.toString(10, false) << 32 << /* Unsigned */ 0;
+ << toString(I, 10, false) << 32 << /* Unsigned */ 0;
return false;
}
@@ -423,10 +392,10 @@ appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
std::forward<DiagnosticArgs>(ExtraArgs)...);
}
-/// Add an attribute {@code AttrType} to declaration {@code D}, provided that
-/// {@code PassesCheck} is true.
-/// Otherwise, emit diagnostic {@code DiagID}, passing in all parameters
-/// specified in {@code ExtraArgs}.
+/// Add an attribute @c AttrType to declaration @c D, provided that
+/// @c PassesCheck is true.
+/// Otherwise, emit diagnostic @c DiagID, passing in all parameters
+/// specified in @c ExtraArgs.
template <typename AttrType, typename... DiagnosticArgs>
static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
const AttributeCommonInfo &CI,
@@ -440,24 +409,6 @@ static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
handleSimpleAttribute<AttrType>(S, D, CI);
}
-template <typename AttrType>
-static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
- const ParsedAttr &AL) {
- handleSimpleAttribute<AttrType>(S, D, AL);
-}
-
-/// Applies the given attribute to the Decl so long as the Decl doesn't
-/// already have one of the given incompatible attributes.
-template <typename AttrType, typename IncompatibleAttrType,
- typename... IncompatibleAttrTypes>
-static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
- const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
- return;
- handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
- AL);
-}
-
/// Check if the passed-in expression is of type int or bool.
static bool isIntOrBool(Expr *Exp) {
QualType QT = Exp->getType();
@@ -546,16 +497,9 @@ static bool checkRecordDeclForAttr(const RecordDecl *RD) {
// Else check if any base classes have the attribute.
if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
- CXXBasePaths BPaths(false, false);
- if (CRD->lookupInBases(
- [](const CXXBaseSpecifier *BS, CXXBasePath &) {
- const auto &Ty = *BS->getType();
- // If it's type-dependent, we assume it could have the attribute.
- if (Ty.isDependentType())
- return true;
- return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
- },
- BPaths, true))
+ if (!CRD->forallBases([](const CXXRecordDecl *Base) {
+ return !Base->hasAttr<AttrType>();
+ }))
return true;
}
return false;
@@ -770,7 +714,7 @@ static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
SmallVectorImpl<Expr *> &Args) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return false;
// Check that this attribute only applies to lockable types.
@@ -846,32 +790,33 @@ static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
///
/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
template <typename AttrInfo>
-static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
- const AttrInfo &AI, unsigned AttrArgNo) {
+static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
+ unsigned AttrArgNo) {
assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
ParamIdx Idx;
- if (!checkFunctionOrMethodParameterIndex(S, FD, AI, AttrArgNo + 1, AttrArg,
+ if (!checkFunctionOrMethodParameterIndex(S, D, AI, AttrArgNo + 1, AttrArg,
Idx))
return false;
- const ParmVarDecl *Param = FD->getParamDecl(Idx.getASTIndex());
- if (!Param->getType()->isIntegerType() && !Param->getType()->isCharType()) {
+ QualType ParamTy = getFunctionOrMethodParamType(D, Idx.getASTIndex());
+ if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {
SourceLocation SrcLoc = AttrArg->getBeginLoc();
S.Diag(SrcLoc, diag::err_attribute_integers_only)
- << AI << Param->getSourceRange();
+ << AI << getFunctionOrMethodParamRange(D, Idx.getASTIndex());
return false;
}
return true;
}
static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
- !checkAttributeAtMostNumArgs(S, AL, 2))
+ if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
return;
- const auto *FD = cast<FunctionDecl>(D);
- if (!FD->getReturnType()->isPointerType()) {
+ assert(isFunctionOrMethod(D) && hasFunctionProto(D));
+
+ QualType RetTy = getFunctionOrMethodResultType(D);
+ if (!RetTy->isPointerType()) {
S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
return;
}
@@ -881,7 +826,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Parameter indices are 1-indexed, hence Index=1
if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
return;
- if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/0))
+ if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/0))
return;
ParamIdx SizeArgNo(SizeArgNoVal, D);
@@ -892,7 +837,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Parameter indices are 1-based, hence Index=2
if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
return;
- if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/1))
+ if (!checkParamIsIntegerType(S, D, AL, /*AttrArgNo=*/1))
return;
NumberArgNo = ParamIdx(Val, D);
}
@@ -903,7 +848,7 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
SmallVectorImpl<Expr *> &Args) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return false;
if (!isIntOrBool(AL.getArgAsExpr(0))) {
@@ -950,7 +895,7 @@ static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return;
// check that all arguments are lockable objects
@@ -1192,7 +1137,7 @@ static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
}
static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return;
if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
@@ -1991,6 +1936,12 @@ static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
+ if (S.Context.getTargetInfo().getTriple().isOSAIX() &&
+ Model != "global-dynamic") {
+ S.Diag(LiteralLoc, diag::err_aix_attr_unsupported_tls_model) << Model;
+ return;
+ }
+
D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
}
@@ -2015,7 +1966,7 @@ static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
}
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return;
SmallVector<IdentifierInfo *, 8> CPUs;
@@ -2062,8 +2013,7 @@ static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
- if (CommonAttr *CA = S.mergeCommonAttr(D, AL))
- D->addAttr(CA);
+ D->addAttr(::new (S.Context) CommonAttr(S.Context, AL));
}
static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -2082,9 +2032,6 @@ static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, AL))
- return;
-
if (AL.isDeclspecAttribute()) {
const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
const auto &Arch = Triple.getArch();
@@ -2119,7 +2066,7 @@ static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
}
bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
- if (!checkAttributeNumArgs(*this, Attrs, 0)) {
+ if (!Attrs.checkExactlyNumArgs(*this, 0)) {
Attrs.setInvalid();
return true;
}
@@ -2147,7 +2094,7 @@ static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
ValueDecl *VD = dyn_cast<ValueDecl>(D);
if (!VD || (!VD->getType()->isBlockPointerType() &&
!VD->getType()->isFunctionPointerType())) {
- S.Diag(AL.getLoc(), AL.isCXX11Attribute()
+ S.Diag(AL.getLoc(), AL.isStandardAttributeSyntax()
? diag::err_attribute_wrong_decl_type
: diag::warn_attribute_wrong_decl_type)
<< AL << ExpectedFunctionMethodOrBlock;
@@ -2354,6 +2301,7 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(
case AMK_Override:
case AMK_ProtocolImplementation:
+ case AMK_OptionalProtocolImplementation:
OverrideOrImpl = true;
break;
}
@@ -2422,6 +2370,14 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(
diag::warn_mismatched_availability_override_unavail)
<< AvailabilityAttr::getPrettyPlatformName(Platform->getName())
<< (AMK == AMK_Override);
+ } else if (Which != 1 && AMK == AMK_OptionalProtocolImplementation) {
+ // Allow different 'introduced' / 'obsoleted' availability versions
+ // on a method that implements an optional protocol requirement. It
+ // makes less sense to allow this for 'deprecated' as the user can't
+ // see if the method is 'deprecated' as 'respondsToSelector' will
+ // still return true when the method is deprecated.
+ ++i;
+ continue;
} else {
Diag(OldAA->getLocation(),
diag::warn_mismatched_availability_override)
@@ -2491,7 +2447,14 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(
}
static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeNumArgs(S, AL, 1))
+ if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(
+ D)) {
+ S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
+ << AL;
+ return;
+ }
+
+ if (!AL.checkExactlyNumArgs(S, 1))
return;
IdentifierLoc *Platform = AL.getArgAsIdent(0);
@@ -2594,15 +2557,90 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (NewAttr)
D->addAttr(NewAttr);
}
+ } else if (S.Context.getTargetInfo().getTriple().getOS() ==
+ llvm::Triple::IOS &&
+ S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
+ auto GetSDKInfo = [&]() {
+ return S.getDarwinSDKInfoForAvailabilityChecking(AL.getRange().getBegin(),
+ "macOS");
+ };
+
+ // Transcribe "ios" to "maccatalyst" (and add a new attribute).
+ IdentifierInfo *NewII = nullptr;
+ if (II->getName() == "ios")
+ NewII = &S.Context.Idents.get("maccatalyst");
+ else if (II->getName() == "ios_app_extension")
+ NewII = &S.Context.Idents.get("maccatalyst_app_extension");
+ if (NewII) {
+ auto MinMacCatalystVersion = [](const VersionTuple &V) {
+ if (V.empty())
+ return V;
+ if (V.getMajor() < 13 ||
+ (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
+ return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
+ return V;
+ };
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL.getRange(), NewII, true /*Implicit*/,
+ MinMacCatalystVersion(Introduced.Version),
+ MinMacCatalystVersion(Deprecated.Version),
+ MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Str,
+ IsStrict, Replacement, Sema::AMK_None,
+ PriorityModifier + Sema::AP_InferredFromOtherPlatform);
+ if (NewAttr)
+ D->addAttr(NewAttr);
+ } else if (II->getName() == "macos" && GetSDKInfo() &&
+ (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
+ !Obsoleted.Version.empty())) {
+ if (const auto *MacOStoMacCatalystMapping =
+ GetSDKInfo()->getVersionMapping(
+ DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
+ // Infer Mac Catalyst availability from the macOS availability attribute
+ // if it has versioned availability. Don't infer 'unavailable'. This
+ // inferred availability has lower priority than the other availability
+ // attributes that are inferred from 'ios'.
+ NewII = &S.Context.Idents.get("maccatalyst");
+ auto RemapMacOSVersion =
+ [&](const VersionTuple &V) -> Optional<VersionTuple> {
+ if (V.empty())
+ return None;
+ // API_TO_BE_DEPRECATED is 100000.
+ if (V.getMajor() == 100000)
+ return VersionTuple(100000);
+ // The minimum iosmac version is 13.1
+ return MacOStoMacCatalystMapping->map(V, VersionTuple(13, 1), None);
+ };
+ Optional<VersionTuple> NewIntroduced =
+ RemapMacOSVersion(Introduced.Version),
+ NewDeprecated =
+ RemapMacOSVersion(Deprecated.Version),
+ NewObsoleted =
+ RemapMacOSVersion(Obsoleted.Version);
+ if (NewIntroduced || NewDeprecated || NewObsoleted) {
+ auto VersionOrEmptyVersion =
+ [](const Optional<VersionTuple> &V) -> VersionTuple {
+ return V ? *V : VersionTuple();
+ };
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL.getRange(), NewII, true /*Implicit*/,
+ VersionOrEmptyVersion(NewIntroduced),
+ VersionOrEmptyVersion(NewDeprecated),
+ VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Str,
+ IsStrict, Replacement, Sema::AMK_None,
+ PriorityModifier + Sema::AP_InferredFromOtherPlatform +
+ Sema::AP_InferredFromOtherPlatform);
+ if (NewAttr)
+ D->addAttr(NewAttr);
+ }
+ }
+ }
}
}
static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
return;
- assert(checkAttributeAtMostNumArgs(S, AL, 3) &&
- "Invalid number of arguments in an external_source_symbol attribute");
StringRef Language;
if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(0)))
@@ -2693,11 +2731,6 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
D->addAttr(newAttr);
}
-static void handleObjCNonRuntimeProtocolAttr(Sema &S, Decl *D,
- const ParsedAttr &AL) {
- handleSimpleAttribute<ObjCNonRuntimeProtocolAttr>(S, D, AL);
-}
-
static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// objc_direct cannot be set on methods declared in the context of a protocol
if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
@@ -2872,8 +2905,10 @@ static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
QualType Ty = V->getType();
if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
const FunctionType *FT = Ty->isFunctionPointerType()
- ? D->getFunctionType()
- : Ty->castAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
+ ? D->getFunctionType()
+ : Ty->castAs<BlockPointerType>()
+ ->getPointeeType()
+ ->castAs<FunctionType>();
if (!cast<FunctionProtoType>(FT)->isVariadic()) {
int m = Ty->isFunctionPointerType() ? 0 : 1;
S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
@@ -2906,7 +2941,7 @@ static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
}
StringRef Str;
- if ((AL.isCXX11Attribute() || AL.isC2xAttribute()) && !AL.getScopeName()) {
+ if (AL.isStandardAttributeSyntax() && !AL.getScopeName()) {
// The standard attribute cannot be applied to variable declarations such
// as a function pointer.
if (isa<VarDecl>(D))
@@ -3051,11 +3086,31 @@ SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
return ::new (Context) SectionAttr(Context, CI, Name);
}
+/// Used to implement to perform semantic checking on
+/// attribute((section("foo"))) specifiers.
+///
+/// In this case, "foo" is passed in to be checked. If the section
+/// specifier is invalid, return an Error that indicates the problem.
+///
+/// This is a simple quality of implementation feature to catch errors
+/// and give good diagnostics in cases when the assembler or code generator
+/// would otherwise reject the section specifier.
+llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
+ if (!Context.getTargetInfo().getTriple().isOSDarwin())
+ return llvm::Error::success();
+
+ // Let MCSectionMachO validate this.
+ StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ bool HasTAA;
+ return llvm::MCSectionMachO::ParseSectionSpecifier(SecName, Segment, Section,
+ TAA, HasTAA, StubSize);
+}
+
bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
- std::string Error = Context.getTargetInfo().isValidSectionSpecifier(SecName);
- if (!Error.empty()) {
- Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target) << Error
- << 1 /*'section'*/;
+ if (llvm::Error E = isValidSectionSpecifier(SecName)) {
+ Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
+ << toString(std::move(E)) << 1 /*'section'*/;
return false;
}
return true;
@@ -3072,14 +3127,6 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!S.checkSectionName(LiteralLoc, Str))
return;
- // If the target wants to validate the section specifier, make it happen.
- std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(Str);
- if (!Error.empty()) {
- S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
- << Error;
- return;
- }
-
SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
if (NewAttr) {
D->addAttr(NewAttr);
@@ -3095,11 +3142,9 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// `#pragma code_seg("segname")` uses checkSectionName() instead.
static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
StringRef CodeSegName) {
- std::string Error =
- S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName);
- if (!Error.empty()) {
+ if (llvm::Error E = S.isValidSectionSpecifier(CodeSegName)) {
S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
- << Error << 0 /*'code-seg'*/;
+ << toString(std::move(E)) << 0 /*'code-seg'*/;
return false;
}
@@ -3328,7 +3373,7 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
Ty = getFunctionOrMethodResultType(D);
- if (!isNSStringType(Ty, S.Context) &&
+ if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true) &&
!isCFStringType(Ty, S.Context) &&
(!Ty->isPointerType() ||
!Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
@@ -3504,7 +3549,7 @@ static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
} else if (Kind == NSStringFormat) {
// FIXME: do we need to check if the type is NSString*? What are the
// semantics?
- if (!isNSStringType(Ty, S.Context)) {
+ if (!isNSStringType(Ty, S.Context, /*AllowNSAttributedString=*/true)) {
S.Diag(AL.getLoc(), diag::err_format_attribute_not)
<< "an NSString" << IdxExpr->getSourceRange()
<< getFunctionOrMethodParamRange(D, ArgIdx);
@@ -3802,11 +3847,11 @@ void Sema::AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,
E = ImplicitCastExpr::Create(Context,
Context.getPointerType(E->getType()),
clang::CK_FunctionToPointerDecay, E, nullptr,
- VK_RValue, FPOptionsOverride());
+ VK_PRValue, FPOptionsOverride());
if (E->isLValue())
E = ImplicitCastExpr::Create(Context, E->getType().getNonReferenceType(),
clang::CK_LValueToRValue, E, nullptr,
- VK_RValue, FPOptionsOverride());
+ VK_PRValue, FPOptionsOverride());
Expr::EvalResult Eval;
Notes.clear();
@@ -3986,6 +4031,12 @@ void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
return;
uint64_t AlignVal = Alignment.getZExtValue();
+ // 16 byte ByVal alignment not due to a vector member is not honoured by XL
+ // on AIX. Emit a warning here that users are generating binary incompatible
+ // code to be safe.
+ if (AlignVal >= 16 && isa<FieldDecl>(D) &&
+ Context.getTargetInfo().getTriple().isOSAIX())
+ Diag(AttrLoc, diag::warn_not_xl_compatible) << E->getSourceRange();
// C++11 [dcl.align]p2:
// -- if the constant expression evaluates to zero, the alignment
@@ -4350,20 +4401,6 @@ AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
return ::new (Context) AlwaysInlineAttr(Context, CI);
}
-CommonAttr *Sema::mergeCommonAttr(Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, AL))
- return nullptr;
-
- return ::new (Context) CommonAttr(Context, AL);
-}
-
-CommonAttr *Sema::mergeCommonAttr(Decl *D, const CommonAttr &AL) {
- if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, AL))
- return nullptr;
-
- return ::new (Context) CommonAttr(Context, AL);
-}
-
InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
const ParsedAttr &AL) {
if (const auto *VD = dyn_cast<VarDecl>(D)) {
@@ -4382,9 +4419,6 @@ InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
}
}
- if (checkAttrMutualExclusion<CommonAttr>(*this, D, AL))
- return nullptr;
-
return ::new (Context) InternalLinkageAttr(Context, AL);
}
InternalLinkageAttr *
@@ -4405,9 +4439,6 @@ Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
}
}
- if (checkAttrMutualExclusion<CommonAttr>(*this, D, AL))
- return nullptr;
-
return ::new (Context) InternalLinkageAttr(Context, AL);
}
@@ -4424,14 +4455,6 @@ MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
return ::new (Context) MinSizeAttr(Context, CI);
}
-NoSpeculativeLoadHardeningAttr *Sema::mergeNoSpeculativeLoadHardeningAttr(
- Decl *D, const NoSpeculativeLoadHardeningAttr &AL) {
- if (checkAttrMutualExclusion<SpeculativeLoadHardeningAttr>(*this, D, AL))
- return nullptr;
-
- return ::new (Context) NoSpeculativeLoadHardeningAttr(Context, AL);
-}
-
SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
StringRef Name) {
if (const auto *PrevSNA = D->getAttr<SwiftNameAttr>()) {
@@ -4465,18 +4488,7 @@ OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
return ::new (Context) OptimizeNoneAttr(Context, CI);
}
-SpeculativeLoadHardeningAttr *Sema::mergeSpeculativeLoadHardeningAttr(
- Decl *D, const SpeculativeLoadHardeningAttr &AL) {
- if (checkAttrMutualExclusion<NoSpeculativeLoadHardeningAttr>(*this, D, AL))
- return nullptr;
-
- return ::new (Context) SpeculativeLoadHardeningAttr(Context, AL);
-}
-
static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, AL))
- return;
-
if (AlwaysInlineAttr *Inline =
S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
D->addAttr(Inline);
@@ -4493,21 +4505,22 @@ static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<CUDASharedAttr>(S, D, AL) ||
- checkAttrMutualExclusion<HIPManagedAttr>(S, D, AL))
- return;
const auto *VD = cast<VarDecl>(D);
if (VD->hasLocalStorage()) {
S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
return;
}
+ // constexpr variable may already get an implicit constant attr, which should
+ // be replaced by the explicit constant attr.
+ if (auto *A = D->getAttr<CUDAConstantAttr>()) {
+ if (!A->isImplicit())
+ return;
+ D->dropAttr<CUDAConstantAttr>();
+ }
D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
}
static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<CUDAConstantAttr>(S, D, AL) ||
- checkAttrMutualExclusion<HIPManagedAttr>(S, D, AL))
- return;
const auto *VD = cast<VarDecl>(D);
// extern __shared__ is only allowed on arrays with no length (e.g.
// "int x[]").
@@ -4524,10 +4537,6 @@ static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<CUDADeviceAttr>(S, D, AL) ||
- checkAttrMutualExclusion<CUDAHostAttr>(S, D, AL)) {
- return;
- }
const auto *FD = cast<FunctionDecl>(D);
if (!FD->getReturnType()->isVoidType() &&
!FD->getReturnType()->getAs<AutoType>() &&
@@ -4561,10 +4570,6 @@ static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<CUDAGlobalAttr>(S, D, AL)) {
- return;
- }
-
if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasLocalStorage()) {
S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
@@ -4581,11 +4586,6 @@ static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (checkAttrMutualExclusion<CUDAConstantAttr>(S, D, AL) ||
- checkAttrMutualExclusion<CUDASharedAttr>(S, D, AL)) {
- return;
- }
-
if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasLocalStorage()) {
S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
@@ -4645,6 +4645,9 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
case ParsedAttr::AT_SwiftCall:
D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
return;
+ case ParsedAttr::AT_SwiftAsyncCall:
+ D->addAttr(::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
+ return;
case ParsedAttr::AT_VectorCall:
D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
return;
@@ -4691,7 +4694,7 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return;
std::vector<StringRef> DiagnosticIdentifiers;
@@ -4730,7 +4733,10 @@ static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
// To check if earlier decl attributes do not conflict the newly parsed ones
- // we always add (and check) the attribute to the cannonical decl.
+ // we always add (and check) the attribute to the cannonical decl. We need
+ // to repeat the check for attribute mutual exclusion because we're attaching
+ // all of the attributes to the canonical declaration rather than the current
+ // declaration.
D = D->getCanonicalDecl();
if (AL.getKind() == ParsedAttr::AT_Owner) {
if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
@@ -4781,7 +4787,7 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
}
unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
- if (!checkAttributeNumArgs(*this, Attrs, ReqArgs)) {
+ if (!Attrs.checkExactlyNumArgs(*this, ReqArgs)) {
Attrs.setInvalid();
return true;
}
@@ -4806,6 +4812,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
case ParsedAttr::AT_SwiftCall:
CC = CC_Swift;
break;
+ case ParsedAttr::AT_SwiftAsyncCall:
+ CC = CC_SwiftAsync;
+ break;
case ParsedAttr::AT_VectorCall:
CC = CC_X86VectorCall;
break;
@@ -4984,6 +4993,14 @@ void Sema::AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
return;
+ case ParameterABI::SwiftAsyncContext:
+ if (!isValidSwiftContextType(type)) {
+ Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
+ << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
+ }
+ D->addAttr(::new (Context) SwiftAsyncContextAttr(Context, CI));
+ return;
+
case ParameterABI::SwiftErrorResult:
if (!isValidSwiftErrorResultType(type)) {
Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
@@ -5009,7 +5026,7 @@ bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
if (AL.isInvalid())
return true;
- if (!checkAttributeNumArgs(*this, AL, 1)) {
+ if (!AL.checkExactlyNumArgs(*this, 1)) {
AL.setInvalid();
return true;
}
@@ -5063,7 +5080,7 @@ static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
// Make sure we can fit it in 32 bits.
if (!I->isIntN(32)) {
S.Diag(E->getExprLoc(), diag::err_ice_too_large)
- << I->toString(10, false) << 32 << /* Unsigned */ 1;
+ << toString(*I, 10, false) << 32 << /* Unsigned */ 1;
return nullptr;
}
if (*I < 0)
@@ -5098,8 +5115,7 @@ void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
}
static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
- !checkAttributeAtMostNumArgs(S, AL, 2))
+ if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
return;
S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
@@ -5146,7 +5162,7 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
return;
}
- if (!checkAttributeNumArgs(S, AL, 1))
+ if (!AL.checkExactlyNumArgs(S, 1))
return;
if (!isa<VarDecl>(D)) {
@@ -5237,15 +5253,12 @@ static bool ArmCdeAliasValid(unsigned BuiltinID, StringRef AliasName) {
return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
}
-static bool ArmSveAliasValid(unsigned BuiltinID, StringRef AliasName) {
- switch (BuiltinID) {
- default:
- return false;
-#define GET_SVE_BUILTINS
-#define BUILTIN(name, types, attr) case SVE::BI##name:
-#include "clang/Basic/arm_sve_builtins.inc"
- return true;
- }
+static bool ArmSveAliasValid(ASTContext &Context, unsigned BuiltinID,
+ StringRef AliasName) {
+ if (Context.BuiltinInfo.isAuxBuiltinID(BuiltinID))
+ BuiltinID = Context.BuiltinInfo.getAuxBuiltinID(BuiltinID);
+ return BuiltinID >= AArch64::FirstSVEBuiltin &&
+ BuiltinID <= AArch64::LastSVEBuiltin;
}
static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -5260,7 +5273,7 @@ static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
- if ((IsAArch64 && !ArmSveAliasValid(BuiltinID, AliasName)) ||
+ if ((IsAArch64 && !ArmSveAliasValid(S.Context, BuiltinID, AliasName)) ||
(!IsAArch64 && !ArmMveAliasValid(BuiltinID, AliasName) &&
!ArmCdeAliasValid(BuiltinID, AliasName))) {
S.Diag(AL.getLoc(), diag::err_attribute_arm_builtin_alias);
@@ -5270,6 +5283,38 @@ static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(::new (S.Context) ArmBuiltinAliasAttr(S.Context, AL, Ident));
}
+static bool RISCVAliasValid(unsigned BuiltinID, StringRef AliasName) {
+ return BuiltinID >= Builtin::FirstTSBuiltin &&
+ BuiltinID < RISCV::LastTSBuiltin;
+}
+
+static void handleBuiltinAliasAttr(Sema &S, Decl *D,
+ const ParsedAttr &AL) {
+ if (!AL.isArgIdent(0)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
+ << AL << 1 << AANT_ArgumentIdentifier;
+ return;
+ }
+
+ IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
+ unsigned BuiltinID = Ident->getBuiltinID();
+ StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
+
+ bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
+ bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
+ bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
+ if ((IsAArch64 && !ArmSveAliasValid(S.Context, BuiltinID, AliasName)) ||
+ (IsARM && !ArmMveAliasValid(BuiltinID, AliasName) &&
+ !ArmCdeAliasValid(BuiltinID, AliasName)) ||
+ (IsRISCV && !RISCVAliasValid(BuiltinID, AliasName)) ||
+ (!IsAArch64 && !IsARM && !IsRISCV)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_builtin_alias) << AL;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
+}
+
//===----------------------------------------------------------------------===//
// Checker-specific attribute handlers.
//===----------------------------------------------------------------------===//
@@ -5751,9 +5796,11 @@ static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!S.checkStringLiteralArgumentAttr(AL, 0, BT))
return;
- // Don't duplicate annotations that are already set.
- if (D->hasAttr<SwiftBridgeAttr>()) {
- S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
+ // Warn about duplicate attributes if they have different arguments, but drop
+ // any duplicate attributes regardless.
+ if (const auto *Other = D->getAttr<SwiftBridgeAttr>()) {
+ if (Other->getSwiftType() != BT)
+ S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
return;
}
@@ -5856,6 +5903,125 @@ static void handleSwiftError(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(::new (S.Context) SwiftErrorAttr(S.Context, AL, Convention));
}
+static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D,
+ const SwiftAsyncErrorAttr *ErrorAttr,
+ const SwiftAsyncAttr *AsyncAttr) {
+ if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {
+ if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {
+ S.Diag(AsyncAttr->getLocation(),
+ diag::err_swift_async_error_without_swift_async)
+ << AsyncAttr << isa<ObjCMethodDecl>(D);
+ }
+ return;
+ }
+
+ const ParmVarDecl *HandlerParam = getFunctionOrMethodParam(
+ D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
+ // handleSwiftAsyncAttr already verified the type is correct, so no need to
+ // double-check it here.
+ const auto *FuncTy = HandlerParam->getType()
+ ->castAs<BlockPointerType>()
+ ->getPointeeType()
+ ->getAs<FunctionProtoType>();
+ ArrayRef<QualType> BlockParams;
+ if (FuncTy)
+ BlockParams = FuncTy->getParamTypes();
+
+ switch (ErrorAttr->getConvention()) {
+ case SwiftAsyncErrorAttr::ZeroArgument:
+ case SwiftAsyncErrorAttr::NonZeroArgument: {
+ uint32_t ParamIdx = ErrorAttr->getHandlerParamIdx();
+ if (ParamIdx == 0 || ParamIdx > BlockParams.size()) {
+ S.Diag(ErrorAttr->getLocation(),
+ diag::err_attribute_argument_out_of_bounds) << ErrorAttr << 2;
+ return;
+ }
+ QualType ErrorParam = BlockParams[ParamIdx - 1];
+ if (!ErrorParam->isIntegralType(S.Context)) {
+ StringRef ConvStr =
+ ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
+ ? "zero_argument"
+ : "nonzero_argument";
+ S.Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
+ << ErrorAttr << ConvStr << ParamIdx << ErrorParam;
+ return;
+ }
+ break;
+ }
+ case SwiftAsyncErrorAttr::NonNullError: {
+ bool AnyErrorParams = false;
+ for (QualType Param : BlockParams) {
+ // Check for NSError *.
+ if (const auto *ObjCPtrTy = Param->getAs<ObjCObjectPointerType>()) {
+ if (const auto *ID = ObjCPtrTy->getInterfaceDecl()) {
+ if (ID->getIdentifier() == S.getNSErrorIdent()) {
+ AnyErrorParams = true;
+ break;
+ }
+ }
+ }
+ // Check for CFError *.
+ if (const auto *PtrTy = Param->getAs<PointerType>()) {
+ if (const auto *RT = PtrTy->getPointeeType()->getAs<RecordType>()) {
+ if (S.isCFError(RT->getDecl())) {
+ AnyErrorParams = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!AnyErrorParams) {
+ S.Diag(ErrorAttr->getLocation(),
+ diag::err_swift_async_error_no_error_parameter)
+ << ErrorAttr << isa<ObjCMethodDecl>(D);
+ return;
+ }
+ break;
+ }
+ case SwiftAsyncErrorAttr::None:
+ break;
+ }
+}
+
+static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) {
+ IdentifierLoc *IDLoc = AL.getArgAsIdent(0);
+ SwiftAsyncErrorAttr::ConventionKind ConvKind;
+ if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(IDLoc->Ident->getName(),
+ ConvKind)) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
+ << AL << IDLoc->Ident;
+ return;
+ }
+
+ uint32_t ParamIdx = 0;
+ switch (ConvKind) {
+ case SwiftAsyncErrorAttr::ZeroArgument:
+ case SwiftAsyncErrorAttr::NonZeroArgument: {
+ if (!AL.checkExactlyNumArgs(S, 2))
+ return;
+
+ Expr *IdxExpr = AL.getArgAsExpr(1);
+ if (!checkUInt32Argument(S, AL, IdxExpr, ParamIdx))
+ return;
+ break;
+ }
+ case SwiftAsyncErrorAttr::NonNullError:
+ case SwiftAsyncErrorAttr::None: {
+ if (!AL.checkExactlyNumArgs(S, 1))
+ return;
+ break;
+ }
+ }
+
+ auto *ErrorAttr =
+ ::new (S.Context) SwiftAsyncErrorAttr(S.Context, AL, ConvKind, ParamIdx);
+ D->addAttr(ErrorAttr);
+
+ if (auto *AsyncAttr = D->getAttr<SwiftAsyncAttr>())
+ checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
+}
+
// For a function, this will validate a compound Swift name, e.g.
// <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, and
// the function will output the number of parameter names, and whether this is a
@@ -6168,7 +6334,7 @@ static void handleSwiftAsyncName(Sema &S, Decl *D, const ParsedAttr &AL) {
static void handleSwiftNewType(Sema &S, Decl *D, const ParsedAttr &AL) {
// Make sure that there is an identifier as the annotation's single argument.
- if (!checkAttributeNumArgs(S, AL, 1))
+ if (!AL.checkExactlyNumArgs(S, 1))
return;
if (!AL.isArgIdent(0)) {
@@ -6210,11 +6376,11 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
ParamIdx Idx;
if (Kind == SwiftAsyncAttr::None) {
// If this is 'none', then there shouldn't be any additional arguments.
- if (!checkAttributeNumArgs(S, AL, 1))
+ if (!AL.checkExactlyNumArgs(S, 1))
return;
} else {
// Non-none swift_async requires a completion handler index argument.
- if (!checkAttributeNumArgs(S, AL, 2))
+ if (!AL.checkExactlyNumArgs(S, 2))
return;
Expr *HandlerIdx = AL.getArgAsExpr(1);
@@ -6231,8 +6397,8 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
QualType BlockTy =
- CompletionBlockType->getAs<BlockPointerType>()->getPointeeType();
- if (!BlockTy->getAs<FunctionType>()->getReturnType()->isVoidType()) {
+ CompletionBlockType->castAs<BlockPointerType>()->getPointeeType();
+ if (!BlockTy->castAs<FunctionType>()->getReturnType()->isVoidType()) {
S.Diag(CompletionBlock->getLocation(),
diag::err_swift_async_bad_block_type)
<< CompletionBlock->getType();
@@ -6240,7 +6406,12 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
}
- D->addAttr(::new (S.Context) SwiftAsyncAttr(S.Context, AL, Kind, Idx));
+ auto *AsyncAttr =
+ ::new (S.Context) SwiftAsyncAttr(S.Context, AL, Kind, Idx);
+ D->addAttr(AsyncAttr);
+
+ if (auto *ErrorAttr = D->getAttr<SwiftAsyncErrorAttr>())
+ checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
}
//===----------------------------------------------------------------------===//
@@ -6373,7 +6544,7 @@ static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
if (AL.getNumArgs() == 0)
Tags.push_back(NS->getName());
- } else if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ } else if (!AL.checkAtLeastNumArgs(S, 1))
return;
// Store tags sorted and without duplicates.
@@ -6431,7 +6602,7 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
// The attribute takes one integer argument.
- if (!checkAttributeNumArgs(S, AL, 1))
+ if (!AL.checkExactlyNumArgs(S, 1))
return;
if (!AL.isArgExpr(0)) {
@@ -6503,6 +6674,8 @@ static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
+ // We still have to do this manually because the Interrupt attributes are
+ // a bit special due to sharing their spellings across targets.
if (checkAttrMutualExclusion<Mips16Attr>(S, D, AL))
return;
@@ -6516,6 +6689,39 @@ static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(::new (S.Context) MipsInterruptAttr(S.Context, AL, Kind));
}
+static void handleM68kInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!AL.checkExactlyNumArgs(S, 1))
+ return;
+
+ if (!AL.isArgExpr(0)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+ << AL << AANT_ArgumentIntegerConstant;
+ return;
+ }
+
+ // FIXME: Check for decl - it should be void ()(void).
+
+ Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
+ auto MaybeNumParams = NumParamsExpr->getIntegerConstantExpr(S.Context);
+ if (!MaybeNumParams) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+ << AL << AANT_ArgumentIntegerConstant
+ << NumParamsExpr->getSourceRange();
+ return;
+ }
+
+ unsigned Num = MaybeNumParams->getLimitedValue(255);
+ if ((Num & 1) || Num > 30) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+ << AL << (int)MaybeNumParams->getSExtValue()
+ << NumParamsExpr->getSourceRange();
+ return;
+ }
+
+ D->addAttr(::new (S.Context) M68kInterruptAttr(S.Context, AL, Num));
+ D->addAttr(UsedAttr::CreateImplicit(S.Context));
+}
+
static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Semantic checks for a function with the 'interrupt' attribute.
// a) Must be a function.
@@ -6587,7 +6793,7 @@ static void handleAVRInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
- if (!checkAttributeNumArgs(S, AL, 0))
+ if (!AL.checkExactlyNumArgs(S, 0))
return;
handleSimpleAttribute<AVRInterruptAttr>(S, D, AL);
@@ -6600,7 +6806,7 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
- if (!checkAttributeNumArgs(S, AL, 0))
+ if (!AL.checkExactlyNumArgs(S, 0))
return;
handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
@@ -6731,7 +6937,7 @@ static void handleRISCVInterruptAttr(Sema &S, Decl *D,
}
// Check the attribute argument. Argument is optional.
- if (!checkAttributeAtMostNumArgs(S, AL, 1))
+ if (!AL.checkAtMostNumArgs(S, 1))
return;
StringRef Str;
@@ -6788,6 +6994,9 @@ static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
case llvm::Triple::mips:
handleMipsInterruptAttr(S, D, AL);
break;
+ case llvm::Triple::m68k:
+ handleM68kInterruptAttr(S, D, AL);
+ break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
handleAnyX86InterruptAttr(S, D, AL);
@@ -6901,8 +7110,7 @@ void Sema::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI,
}
static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
- !checkAttributeAtMostNumArgs(S, AL, 2))
+ if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2))
return;
Expr *MinExpr = AL.getArgAsExpr(0);
@@ -7125,7 +7333,7 @@ static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return;
// check that all arguments are lockable objects
@@ -7149,6 +7357,11 @@ static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// namespace.
return;
}
+ } else if (isa<UsingDecl, UnresolvedUsingTypenameDecl,
+ UnresolvedUsingValueDecl>(D)) {
+ S.Diag(AL.getRange().getBegin(), diag::warn_deprecated_ignored_on_using)
+ << AL;
+ return;
}
// Handle the cases where the attribute has a text message.
@@ -7157,9 +7370,9 @@ static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
!S.checkStringLiteralArgumentAttr(AL, 0, Str))
return;
- // Only support a single optional message for Declspec and CXX11.
- if (AL.isDeclspecAttribute() || AL.isCXX11Attribute())
- checkAttributeAtMostNumArgs(S, AL, 1);
+ // Support a single optional message only for Declspec and [[]] spellings.
+ if (AL.isDeclspecAttribute() || AL.isStandardAttributeSyntax())
+ AL.checkAtMostNumArgs(S, 1);
else if (AL.isArgExpr(1) && AL.getArgAsExpr(1) &&
!S.checkStringLiteralArgumentAttr(AL, 1, Replacement))
return;
@@ -7177,7 +7390,7 @@ static bool isGlobalVar(const Decl *D) {
}
static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- if (!checkAttributeAtLeastNumArgs(S, AL, 1))
+ if (!AL.checkAtLeastNumArgs(S, 1))
return;
std::vector<StringRef> Sanitizers;
@@ -7190,7 +7403,8 @@ static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
- SanitizerMask())
+ SanitizerMask() &&
+ SanitizerName != "coverage")
S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
else if (isGlobalVar(D) && SanitizerName != "address")
S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
@@ -7224,7 +7438,7 @@ static void handleNoSanitizeSpecificAttr(Sema &S, Decl *D,
// getSpelling() or prettyPrint() on the resulting semantic attribute object
// without failing assertions.
unsigned TranslatedSpellingIndex = 0;
- if (AL.isC2xAttribute() || AL.isCXX11Attribute())
+ if (AL.isStandardAttributeSyntax())
TranslatedSpellingIndex = 1;
AttributeCommonInfo Info = AL;
@@ -7247,49 +7461,6 @@ static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< "2.0";
}
-/// Handles semantic checking for features that are common to all attributes,
-/// such as checking whether a parameter was properly specified, or the correct
-/// number of arguments were passed, etc.
-static bool handleCommonAttributeFeatures(Sema &S, Decl *D,
- const ParsedAttr &AL) {
- // Several attributes carry different semantics than the parsing requires, so
- // those are opted out of the common argument checks.
- //
- // We also bail on unknown and ignored attributes because those are handled
- // as part of the target-specific handling logic.
- if (AL.getKind() == ParsedAttr::UnknownAttribute)
- return false;
- // Check whether the attribute requires specific language extensions to be
- // enabled.
- if (!AL.diagnoseLangOpts(S))
- return true;
- // Check whether the attribute appertains to the given subject.
- if (!AL.diagnoseAppertainsTo(S, D))
- return true;
- if (AL.hasCustomParsing())
- return false;
-
- if (AL.getMinArgs() == AL.getMaxArgs()) {
- // If there are no optional arguments, then checking for the argument count
- // is trivial.
- if (!checkAttributeNumArgs(S, AL, AL.getMinArgs()))
- return true;
- } else {
- // There are optional arguments, so checking is slightly more involved.
- if (AL.getMinArgs() &&
- !checkAttributeAtLeastNumArgs(S, AL, AL.getMinArgs()))
- return true;
- else if (!AL.hasVariadicArg() && AL.getMaxArgs() &&
- !checkAttributeAtMostNumArgs(S, AL, AL.getMaxArgs()))
- return true;
- }
-
- if (S.CheckAttrTarget(AL))
- return true;
-
- return false;
-}
-
static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (D->isInvalidDecl())
return;
@@ -7308,16 +7479,24 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
}
- // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that an
- // image object can be read and written.
- // OpenCL v2.0 s6.13.6 - A kernel cannot read from and write to the same pipe
- // object. Using the read_write (or __read_write) qualifier with the pipe
- // qualifier is a compilation error.
+ // OpenCL v2.0 s6.6 - read_write can be used for image types to specify that
+ // an image object can be read and written. OpenCL v2.0 s6.13.6 - A kernel
+ // cannot read from and write to the same pipe object. Using the read_write
+ // (or __read_write) qualifier with the pipe qualifier is a compilation error.
+ // OpenCL v3.0 s6.8 - For OpenCL C 2.0, or with the
+ // __opencl_c_read_write_images feature, image objects specified as arguments
+ // to a kernel can additionally be declared to be read-write.
+ // C++ for OpenCL inherits rule from OpenCL C v2.0.
if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) {
const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
if (AL.getAttrName()->getName().find("read_write") != StringRef::npos) {
+ bool ReadWriteImagesUnsupportedForOCLC =
+ (S.getLangOpts().OpenCLVersion < 200) ||
+ (S.getLangOpts().OpenCLVersion == 300 &&
+ !S.getOpenCLOptions().isSupported("__opencl_c_read_write_images",
+ S.getLangOpts()));
if ((!S.getLangOpts().OpenCLCPlusPlus &&
- S.getLangOpts().OpenCLVersion < 200) ||
+ ReadWriteImagesUnsupportedForOCLC) ||
DeclTy->isPipeType()) {
S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write)
<< AL << PDecl->getType() << DeclTy->isImageType();
@@ -7377,9 +7556,9 @@ static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
}
if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
- handleSimpleAttributeWithExclusions<AlwaysDestroyAttr, NoDestroyAttr>(S, D, A);
+ handleSimpleAttribute<AlwaysDestroyAttr>(S, D, A);
else
- handleSimpleAttributeWithExclusions<NoDestroyAttr, AlwaysDestroyAttr>(S, D, A);
+ handleSimpleAttribute<NoDestroyAttr>(S, D, A);
}
static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -7643,7 +7822,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
return;
}
- if (handleCommonAttributeFeatures(S, D, AL))
+ if (S.checkCommonAttributeFeatures(D, AL))
return;
switch (AL.getKind()) {
@@ -7655,6 +7834,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
assert(AL.isTypeAttr() && "Non-type attribute not handled");
break;
}
+ // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
+ // statement attribute is not written on a declaration, but this code is
+ // needed for attributes in Attr.td that do not list any subjects.
S.Diag(AL.getLoc(), diag::err_stmt_attribute_invalid_on_decl)
<< AL << D->getLocation();
break;
@@ -7668,21 +7850,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_DLLImport:
handleDLLAttr(S, D, AL);
break;
- case ParsedAttr::AT_Mips16:
- handleSimpleAttributeWithExclusions<Mips16Attr, MicroMipsAttr,
- MipsInterruptAttr>(S, D, AL);
- break;
- case ParsedAttr::AT_MicroMips:
- handleSimpleAttributeWithExclusions<MicroMipsAttr, Mips16Attr>(S, D, AL);
- break;
- case ParsedAttr::AT_MipsLongCall:
- handleSimpleAttributeWithExclusions<MipsLongCallAttr, MipsShortCallAttr>(
- S, D, AL);
- break;
- case ParsedAttr::AT_MipsShortCall:
- handleSimpleAttributeWithExclusions<MipsShortCallAttr, MipsLongCallAttr>(
- S, D, AL);
- break;
case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
handleAMDGPUFlatWorkGroupSizeAttr(S, D, AL);
break;
@@ -7816,22 +7983,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_CUDADevice:
handleDeviceAttr(S, D, AL);
break;
- case ParsedAttr::AT_CUDAHost:
- handleSimpleAttributeWithExclusions<CUDAHostAttr, CUDAGlobalAttr>(S, D, AL);
- break;
case ParsedAttr::AT_HIPManaged:
handleManagedAttr(S, D, AL);
break;
- case ParsedAttr::AT_CUDADeviceBuiltinSurfaceType:
- handleSimpleAttributeWithExclusions<CUDADeviceBuiltinSurfaceTypeAttr,
- CUDADeviceBuiltinTextureTypeAttr>(S, D,
- AL);
- break;
- case ParsedAttr::AT_CUDADeviceBuiltinTextureType:
- handleSimpleAttributeWithExclusions<CUDADeviceBuiltinTextureTypeAttr,
- CUDADeviceBuiltinSurfaceTypeAttr>(S, D,
- AL);
- break;
case ParsedAttr::AT_GNUInline:
handleGNUInlineAttr(S, D, AL);
break;
@@ -7865,12 +8019,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Ownership:
handleOwnershipAttr(S, D, AL);
break;
- case ParsedAttr::AT_Cold:
- handleSimpleAttributeWithExclusions<ColdAttr, HotAttr>(S, D, AL);
- break;
- case ParsedAttr::AT_Hot:
- handleSimpleAttributeWithExclusions<HotAttr, ColdAttr>(S, D, AL);
- break;
case ParsedAttr::AT_Naked:
handleNakedAttr(S, D, AL);
break;
@@ -7880,9 +8028,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AnyX86NoCfCheck:
handleNoCfCheckAttr(S, D, AL);
break;
- case ParsedAttr::AT_Leaf:
- handleSimpleAttribute<LeafAttr>(S, D, AL);
- break;
case ParsedAttr::AT_NoThrow:
if (!AL.isUsedAsTypeAttr())
handleSimpleAttribute<NoThrowAttr>(S, D, AL);
@@ -7926,14 +8071,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_NSErrorDomain:
handleNSErrorDomain(S, D, AL);
break;
- case ParsedAttr::AT_CFAuditedTransfer:
- handleSimpleAttributeWithExclusions<CFAuditedTransferAttr,
- CFUnknownTransferAttr>(S, D, AL);
- break;
- case ParsedAttr::AT_CFUnknownTransfer:
- handleSimpleAttributeWithExclusions<CFUnknownTransferAttr,
- CFAuditedTransferAttr>(S, D, AL);
- break;
case ParsedAttr::AT_CFConsumed:
case ParsedAttr::AT_NSConsumed:
case ParsedAttr::AT_OSConsumed:
@@ -7974,10 +8111,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleVecTypeHint(S, D, AL);
break;
case ParsedAttr::AT_InitPriority:
- if (S.Context.getTargetInfo().getTriple().isOSAIX())
- llvm::report_fatal_error(
- "'init_priority' attribute is not yet supported on AIX");
- else
handleInitPriorityAttr(S, D, AL);
break;
case ParsedAttr::AT_Packed:
@@ -7989,15 +8122,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Section:
handleSectionAttr(S, D, AL);
break;
- case ParsedAttr::AT_SpeculativeLoadHardening:
- handleSimpleAttributeWithExclusions<SpeculativeLoadHardeningAttr,
- NoSpeculativeLoadHardeningAttr>(S, D,
- AL);
- break;
- case ParsedAttr::AT_NoSpeculativeLoadHardening:
- handleSimpleAttributeWithExclusions<NoSpeculativeLoadHardeningAttr,
- SpeculativeLoadHardeningAttr>(S, D, AL);
- break;
case ParsedAttr::AT_CodeSeg:
handleCodeSegAttr(S, D, AL);
break;
@@ -8016,9 +8140,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_ObjCDirect:
handleObjCDirectAttr(S, D, AL);
break;
- case ParsedAttr::AT_ObjCNonRuntimeProtocol:
- handleObjCNonRuntimeProtocolAttr(S, D, AL);
- break;
case ParsedAttr::AT_ObjCDirectMembers:
handleObjCDirectMembersAttr(S, D, AL);
handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
@@ -8029,17 +8150,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Unused:
handleUnusedAttr(S, D, AL);
break;
- case ParsedAttr::AT_NotTailCalled:
- handleSimpleAttributeWithExclusions<NotTailCalledAttr, AlwaysInlineAttr>(
- S, D, AL);
- break;
- case ParsedAttr::AT_DisableTailCalls:
- handleSimpleAttributeWithExclusions<DisableTailCallsAttr, NakedAttr>(S, D,
- AL);
- break;
- case ParsedAttr::AT_NoMerge:
- handleSimpleAttribute<NoMergeAttr>(S, D, AL);
- break;
case ParsedAttr::AT_Visibility:
handleVisibilityAttr(S, D, AL, false);
break;
@@ -8089,6 +8199,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Pascal:
case ParsedAttr::AT_RegCall:
case ParsedAttr::AT_SwiftCall:
+ case ParsedAttr::AT_SwiftAsyncCall:
case ParsedAttr::AT_VectorCall:
case ParsedAttr::AT_MSABI:
case ParsedAttr::AT_SysVABI:
@@ -8115,6 +8226,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_SwiftContext:
S.AddParameterABIAttr(D, AL, ParameterABI::SwiftContext);
break;
+ case ParsedAttr::AT_SwiftAsyncContext:
+ S.AddParameterABIAttr(D, AL, ParameterABI::SwiftAsyncContext);
+ break;
case ParsedAttr::AT_SwiftErrorResult:
S.AddParameterABIAttr(D, AL, ParameterABI::SwiftErrorResult);
break;
@@ -8247,9 +8361,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_SwiftBridge:
handleSwiftBridge(S, D, AL);
break;
- case ParsedAttr::AT_SwiftBridgedTypedef:
- handleSimpleAttribute<SwiftBridgedTypedefAttr>(S, D, AL);
- break;
case ParsedAttr::AT_SwiftError:
handleSwiftError(S, D, AL);
break;
@@ -8259,15 +8370,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_SwiftNewType:
handleSwiftNewType(S, D, AL);
break;
- case ParsedAttr::AT_SwiftObjCMembers:
- handleSimpleAttribute<SwiftObjCMembersAttr>(S, D, AL);
- break;
- case ParsedAttr::AT_SwiftPrivate:
- handleSimpleAttribute<SwiftPrivateAttr>(S, D, AL);
- break;
case ParsedAttr::AT_SwiftAsync:
handleSwiftAsyncAttr(S, D, AL);
break;
+ case ParsedAttr::AT_SwiftAsyncError:
+ handleSwiftAsyncError(S, D, AL);
+ break;
// XRay attributes.
case ParsedAttr::AT_XRayLogArgs:
@@ -8287,10 +8395,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleUninitializedAttr(S, D, AL);
break;
- case ParsedAttr::AT_LoaderUninitialized:
- handleSimpleAttribute<LoaderUninitializedAttr>(S, D, AL);
- break;
-
case ParsedAttr::AT_ObjCExternallyRetained:
handleObjCExternallyRetainedAttr(S, D, AL);
break;
@@ -8326,6 +8430,14 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_EnforceTCBLeaf:
handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
break;
+
+ case ParsedAttr::AT_BuiltinAlias:
+ handleBuiltinAliasAttr(S, D, AL);
+ break;
+
+ case ParsedAttr::AT_UsingIfExists:
+ handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
+ break;
}
}