summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDeclAttr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /clang/lib/Sema/SemaDeclAttr.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'clang/lib/Sema/SemaDeclAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp347
1 files changed, 327 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index b2be6245a814..5c51b0f9b8cb 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -23,6 +23,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
@@ -1068,6 +1069,56 @@ static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
}
+static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ static constexpr const StringRef kWildcard = "*";
+
+ llvm::SmallVector<StringRef, 16> Names;
+ bool HasWildcard = false;
+
+ const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
+ if (Name == kWildcard)
+ HasWildcard = true;
+ Names.push_back(Name);
+ };
+
+ // Add previously defined attributes.
+ if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
+ for (StringRef BuiltinName : NBA->builtinNames())
+ AddBuiltinName(BuiltinName);
+
+ // Add current attributes.
+ if (AL.getNumArgs() == 0)
+ AddBuiltinName(kWildcard);
+ else
+ for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
+ StringRef BuiltinName;
+ SourceLocation LiteralLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
+ return;
+
+ if (Builtin::Context::isBuiltinFunc(BuiltinName))
+ AddBuiltinName(BuiltinName);
+ else
+ S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
+ << BuiltinName << AL.getAttrName()->getName();
+ }
+
+ // Repeating the same attribute is fine.
+ llvm::sort(Names);
+ Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
+
+ // Empty no_builtin must be on its own.
+ if (HasWildcard && Names.size() > 1)
+ S.Diag(D->getLocation(),
+ diag::err_attribute_no_builtin_wildcard_or_builtin_name)
+ << AL.getAttrName()->getName();
+
+ if (D->hasAttr<NoBuiltinAttr>())
+ D->dropAttr<NoBuiltinAttr>();
+ D->addAttr(::new (S.Context)
+ NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
+}
+
static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (D->hasAttr<PassObjectSizeAttr>()) {
S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
@@ -2549,6 +2600,29 @@ static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
D->addAttr(newAttr);
}
+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())) {
+ S.Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
+ return;
+ }
+
+ if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
+ handleSimpleAttribute<ObjCDirectAttr>(S, D, AL);
+ } else {
+ S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
+ }
+}
+
+static void handleObjCDirectMembersAttr(Sema &S, Decl *D,
+ const ParsedAttr &AL) {
+ if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
+ handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
+ } else {
+ S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
+ }
+}
+
static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
const auto *M = cast<ObjCMethodDecl>(D);
if (!AL.isArgIdent(0)) {
@@ -2839,7 +2913,7 @@ static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
(ParmType->isBooleanType() ||
!ParmType->isIntegralType(S.getASTContext()))) {
- S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 3 << AL;
+ S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
return;
}
@@ -2972,7 +3046,7 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << Str;
- TargetAttr::ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr);
+ ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr);
if (!ParsedAttrs.Architecture.empty() &&
!Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture))
@@ -2990,6 +3064,19 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
<< Unsupported << None << CurFeature;
}
+ TargetInfo::BranchProtectionInfo BPI;
+ StringRef Error;
+ if (!ParsedAttrs.BranchProtection.empty() &&
+ !Context.getTargetInfo().validateBranchProtection(
+ ParsedAttrs.BranchProtection, BPI, Error)) {
+ if (Error.empty())
+ return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
+ << Unsupported << None << "branch-protection";
+ else
+ return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
+ << Error;
+ }
+
return false;
}
@@ -3798,7 +3885,7 @@ void Sema::CheckAlignasUnderalignment(Decl *D) {
bool Sema::checkMSInheritanceAttrOnDefinition(
CXXRecordDecl *RD, SourceRange Range, bool BestCase,
- MSInheritanceAttr::Spelling SemanticSpelling) {
+ MSInheritanceModel ExplicitModel) {
assert(RD->hasDefinition() && "RD has no definition!");
// We may not have seen base specifiers or any virtual methods yet. We will
@@ -3807,14 +3894,14 @@ bool Sema::checkMSInheritanceAttrOnDefinition(
return false;
// The unspecified model never matches what a definition could need.
- if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance)
+ if (ExplicitModel == MSInheritanceModel::Unspecified)
return false;
if (BestCase) {
- if (RD->calculateInheritanceModel() == SemanticSpelling)
+ if (RD->calculateInheritanceModel() == ExplicitModel)
return false;
} else {
- if (RD->calculateInheritanceModel() <= SemanticSpelling)
+ if (RD->calculateInheritanceModel() <= ExplicitModel)
return false;
}
@@ -4367,12 +4454,10 @@ static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
unsigned SelectIdx = ~0U;
- if (ParmType->isVoidType())
+ if (ParmType->isReferenceType())
SelectIdx = 0;
- else if (ParmType->isReferenceType())
- SelectIdx = 1;
else if (ParmType->isArrayType())
- SelectIdx = 2;
+ SelectIdx = 1;
if (SelectIdx != ~0U) {
S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
@@ -4830,6 +4915,54 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
}
+static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
+ const ParsedAttr &AL) {
+ uint32_t Count = 0, Offset = 0;
+ if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true))
+ return;
+ if (AL.getNumArgs() == 2) {
+ Expr *Arg = AL.getArgAsExpr(1);
+ if (!checkUInt32Argument(S, AL, Arg, Offset, 1, true))
+ return;
+ if (Offset) {
+ S.Diag(getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
+ << &AL << 0 << 0 << Arg->getBeginLoc();
+ return;
+ }
+ }
+ D->addAttr(::new (S.Context)
+ PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));
+}
+
+static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName) {
+ if (AliasName.startswith("__arm_"))
+ AliasName = AliasName.substr(6);
+ switch (BuiltinID) {
+#include "clang/Basic/arm_mve_builtin_aliases.inc"
+ default:
+ return false;
+ }
+}
+
+static void handleArmMveAliasAttr(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();
+
+ if (!ArmMveAliasValid(BuiltinID,
+ cast<FunctionDecl>(D)->getIdentifier()->getName())) {
+ S.Diag(AL.getLoc(), diag::err_attribute_arm_mve_alias);
+ return;
+ }
+
+ D->addAttr(::new (S.Context) ArmMveAliasAttr(S.Context, AL, Ident));
+}
+
//===----------------------------------------------------------------------===//
// Checker-specific attribute handlers.
//===----------------------------------------------------------------------===//
@@ -5278,9 +5411,11 @@ UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
if (const auto *UA = D->getAttr<UuidAttr>()) {
if (UA->getGuid().equals_lower(Uuid))
return nullptr;
- Diag(UA->getLocation(), diag::err_mismatched_uuid);
- Diag(CI.getLoc(), diag::note_previous_uuid);
- D->dropAttr<UuidAttr>();
+ if (!UA->getGuid().empty()) {
+ Diag(UA->getLocation(), diag::err_mismatched_uuid);
+ Diag(CI.getLoc(), diag::note_previous_uuid);
+ D->dropAttr<UuidAttr>();
+ }
}
return ::new (Context) UuidAttr(Context, CI, Uuid);
@@ -5342,8 +5477,7 @@ static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
- D, AL, /*BestCase=*/true,
- (MSInheritanceAttr::Spelling)AL.getSemanticSpelling());
+ D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling());
if (IA) {
D->addAttr(IA);
S.Consumer.AssignInheritanceModel(cast<CXXRecordDecl>(D));
@@ -5620,6 +5754,47 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
}
+static void handleBPFPreserveAIRecord(Sema &S, RecordDecl *RD) {
+ // Add preserve_access_index attribute to all fields and inner records.
+ for (auto D : RD->decls()) {
+ if (D->hasAttr<BPFPreserveAccessIndexAttr>())
+ continue;
+
+ D->addAttr(BPFPreserveAccessIndexAttr::CreateImplicit(S.Context));
+ if (auto *Rec = dyn_cast<RecordDecl>(D))
+ handleBPFPreserveAIRecord(S, Rec);
+ }
+}
+
+static void handleBPFPreserveAccessIndexAttr(Sema &S, Decl *D,
+ const ParsedAttr &AL) {
+ auto *Rec = cast<RecordDecl>(D);
+ handleBPFPreserveAIRecord(S, Rec);
+ Rec->addAttr(::new (S.Context) BPFPreserveAccessIndexAttr(S.Context, AL));
+}
+
+static void handleWebAssemblyExportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!isFunctionOrMethod(D)) {
+ S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+ << "'export_name'" << ExpectedFunction;
+ return;
+ }
+
+ auto *FD = cast<FunctionDecl>(D);
+ if (FD->isThisDeclarationADefinition()) {
+ S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+ return;
+ }
+
+ StringRef Str;
+ SourceLocation ArgLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
+ return;
+
+ D->addAttr(::new (S.Context) WebAssemblyExportNameAttr(S.Context, AL, Str));
+ D->addAttr(UsedAttr::CreateImplicit(S.Context));
+}
+
static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!isFunctionOrMethod(D)) {
S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
@@ -5977,9 +6152,9 @@ static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
MSInheritanceAttr *
Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
bool BestCase,
- MSInheritanceAttr::Spelling SemanticSpelling) {
+ MSInheritanceModel Model) {
if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
- if (IA->getSemanticSpelling() == SemanticSpelling)
+ if (IA->getInheritanceModel() == Model)
return nullptr;
Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
<< 1 /*previous declaration*/;
@@ -5990,7 +6165,7 @@ Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
auto *RD = cast<CXXRecordDecl>(D);
if (RD->hasDefinition()) {
if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
- SemanticSpelling)) {
+ Model)) {
return nullptr;
}
} else {
@@ -6278,6 +6453,45 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(::new (S.Context) OpenCLAccessAttr(S.Context, AL));
}
+static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // The 'sycl_kernel' attribute applies only to function templates.
+ const auto *FD = cast<FunctionDecl>(D);
+ const FunctionTemplateDecl *FT = FD->getDescribedFunctionTemplate();
+ assert(FT && "Function template is expected");
+
+ // Function template must have at least two template parameters.
+ const TemplateParameterList *TL = FT->getTemplateParameters();
+ if (TL->size() < 2) {
+ S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_template_params);
+ return;
+ }
+
+ // Template parameters must be typenames.
+ for (unsigned I = 0; I < 2; ++I) {
+ const NamedDecl *TParam = TL->getParam(I);
+ if (isa<NonTypeTemplateParmDecl>(TParam)) {
+ S.Diag(FT->getLocation(),
+ diag::warn_sycl_kernel_invalid_template_param_type);
+ return;
+ }
+ }
+
+ // Function must have at least one argument.
+ if (getFunctionOrMethodNumParams(D) != 1) {
+ S.Diag(FT->getLocation(), diag::warn_sycl_kernel_num_of_function_params);
+ return;
+ }
+
+ // Function must return void.
+ QualType RetTy = getFunctionOrMethodResultType(D);
+ if (!RetTy->isVoidType()) {
+ S.Diag(FT->getLocation(), diag::warn_sycl_kernel_return_type);
+ return;
+ }
+
+ handleSimpleAttribute<SYCLKernelAttr>(S, D, AL);
+}
+
static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
if (!cast<VarDecl>(D)->hasGlobalStorage()) {
S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var)
@@ -6406,6 +6620,50 @@ static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
handleSimpleAttribute<MSAllocatorAttr>(S, D, AL);
}
+static void handeAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (AL.isUsedAsTypeAttr())
+ return;
+ // Warn if the parameter is definitely not an output parameter.
+ if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
+ if (PVD->getType()->isIntegerType()) {
+ S.Diag(AL.getLoc(), diag::err_attribute_output_parameter)
+ << AL.getRange();
+ return;
+ }
+ }
+ StringRef Argument;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
+ return;
+ D->addAttr(AcquireHandleAttr::Create(S.Context, Argument, AL));
+}
+
+template<typename Attr>
+static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ StringRef Argument;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
+ return;
+ D->addAttr(Attr::Create(S.Context, Argument, AL));
+}
+
+static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // The guard attribute takes a single identifier argument.
+
+ if (!AL.isArgIdent(0)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+ << AL << AANT_ArgumentIdentifier;
+ return;
+ }
+
+ CFGuardAttr::GuardArg Arg;
+ IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
+ if (!CFGuardAttr::ConvertStrToGuardArg(II->getName(), Arg)) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
+}
+
//===----------------------------------------------------------------------===//
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
@@ -6496,6 +6754,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AVRSignal:
handleAVRSignalAttr(S, D, AL);
break;
+ case ParsedAttr::AT_BPFPreserveAccessIndex:
+ handleBPFPreserveAccessIndexAttr(S, D, AL);
+ break;
+ case ParsedAttr::AT_WebAssemblyExportName:
+ handleWebAssemblyExportNameAttr(S, D, AL);
+ break;
case ParsedAttr::AT_WebAssemblyImportModule:
handleWebAssemblyImportModuleAttr(S, D, AL);
break;
@@ -6578,6 +6842,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_DiagnoseIf:
handleDiagnoseIfAttr(S, D, AL);
break;
+ case ParsedAttr::AT_NoBuiltin:
+ handleNoBuiltinAttr(S, D, AL);
+ break;
case ParsedAttr::AT_ExtVectorType:
handleExtVectorTypeAttr(S, D, AL);
break;
@@ -6599,6 +6866,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_Flatten:
handleSimpleAttribute<FlattenAttr>(S, D, AL);
break;
+ case ParsedAttr::AT_SYCLKernel:
+ handleSYCLKernelAttr(S, D, AL);
+ break;
case ParsedAttr::AT_Format:
handleFormatAttr(S, D, AL);
break;
@@ -6826,6 +7096,13 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_ObjCRootClass:
handleSimpleAttribute<ObjCRootClassAttr>(S, D, AL);
break;
+ case ParsedAttr::AT_ObjCDirect:
+ handleObjCDirectAttr(S, D, AL);
+ break;
+ case ParsedAttr::AT_ObjCDirectMembers:
+ handleObjCDirectMembersAttr(S, D, AL);
+ handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
+ break;
case ParsedAttr::AT_ObjCNonLazyClass:
handleSimpleAttribute<ObjCNonLazyClassAttr>(S, D, AL);
break;
@@ -7015,6 +7292,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AbiTag:
handleAbiTagAttr(S, D, AL);
break;
+ case ParsedAttr::AT_CFGuard:
+ handleCFGuardAttr(S, D, AL);
+ break;
// Thread safety attributes:
case ParsedAttr::AT_AssertExclusiveLock:
@@ -7135,6 +7415,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleXRayLogArgsAttr(S, D, AL);
break;
+ case ParsedAttr::AT_PatchableFunctionEntry:
+ handlePatchableFunctionEntryAttr(S, D, AL);
+ break;
+
// Move semantics attribute.
case ParsedAttr::AT_Reinitializes:
handleSimpleAttribute<ReinitializesAttr>(S, D, AL);
@@ -7160,6 +7444,22 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_MSAllocator:
handleMSAllocatorAttr(S, D, AL);
break;
+
+ case ParsedAttr::AT_ArmMveAlias:
+ handleArmMveAliasAttr(S, D, AL);
+ break;
+
+ case ParsedAttr::AT_AcquireHandle:
+ handeAcquireHandleAttr(S, D, AL);
+ break;
+
+ case ParsedAttr::AT_ReleaseHandle:
+ handleHandleAttr<ReleaseHandleAttr>(S, D, AL);
+ break;
+
+ case ParsedAttr::AT_UseHandle:
+ handleHandleAttr<UseHandleAttr>(S, D, AL);
+ break;
}
}
@@ -7238,7 +7538,8 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
}
}
-// Helper for delayed processing TransparentUnion attribute.
+// Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr
+// attribute.
void Sema::ProcessDeclAttributeDelayed(Decl *D,
const ParsedAttributesView &AttrList) {
for (const ParsedAttr &AL : AttrList)
@@ -7246,6 +7547,11 @@ void Sema::ProcessDeclAttributeDelayed(Decl *D,
handleTransparentUnionAttr(*this, D, AL);
break;
}
+
+ // For BPFPreserveAccessIndexAttr, we want to populate the attributes
+ // to fields and inner records as well.
+ if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
+ handleBPFPreserveAIRecord(*this, cast<RecordDecl>(D));
}
// Annotation attributes are the only attributes allowed after an access
@@ -7308,7 +7614,8 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
NewFD = FunctionDecl::Create(
FD->getASTContext(), FD->getDeclContext(), Loc, Loc,
DeclarationName(II), FD->getType(), FD->getTypeSourceInfo(), SC_None,
- false /*isInlineSpecified*/, FD->hasPrototype(), CSK_unspecified);
+ false /*isInlineSpecified*/, FD->hasPrototype(), CSK_unspecified,
+ FD->getTrailingRequiresClause());
NewD = NewFD;
if (FD->getQualifier())