[clang] [clang] Instantiate attributes on other decl types (PR #115924)
Eric Astor via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 14 11:37:54 PST 2024
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924
>From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Tue, 12 Nov 2024 17:37:42 +0000
Subject: [PATCH 1/3] [clang] Instantiate attributes on other decl types
Start propagating attributes on (e.g.) labels inside of templated functions to their instances.
---
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +++++++++++++---
clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++--
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 5a001843e2ba46..bfc5913dbafd0f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -990,6 +990,7 @@ Decl *
TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) {
LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(),
D->getIdentifier());
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
return Inst;
}
@@ -1009,6 +1010,7 @@ TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->getQualifierLoc(),
D->getTargetNameLoc(),
D->getNamespace());
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
return Inst;
}
@@ -1095,15 +1097,21 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false);
- if (Typedef)
+ if (Typedef) {
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef, LateAttrs,
+ StartingScope);
Owner->addDecl(Typedef);
+ }
return Typedef;
}
Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {
Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true);
- if (Typedef)
+ if (Typedef) {
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef, LateAttrs,
+ StartingScope);
Owner->addDecl(Typedef);
+ }
return Typedef;
}
@@ -1160,8 +1168,10 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl(
Decl *
TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Decl *Inst = InstantiateTypeAliasTemplateDecl(D);
- if (Inst)
+ if (Inst) {
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
+ }
return Inst;
}
diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp
index f665b1ba491237..58266f947051c5 100644
--- a/clang/test/SemaCXX/attr-mode-tmpl.cpp
+++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp
@@ -9,7 +9,7 @@ void CheckEnumerations() {
// Check that non-vector 'mode' attribute is OK with enumeration types.
typedef T __attribute__((mode(QI))) T1;
typedef T T2 __attribute__((mode(HI)));
- typedef T __attribute__((mode(V8SI))) T3; // expected-error{{mode 'V8SI' is not supported for enumeration types}}
+ typedef T __attribute__((mode(V8SI))) T3; // expected-error2{{mode 'V8SI' is not supported for enumeration types}}
// expected-warning at -1{{specifying vector types with the 'mode' attribute is deprecated}}
typedef enum __attribute__((mode(HI))) { A4, B4 } T4;
@@ -62,7 +62,7 @@ struct TemplatedStruct {
// Check typedefs.
typedef T __attribute__((mode(DI))) T1;
- typedef T __attribute__((mode(V8DI))) T2; // expected-error{{mode 'V8DI' is not supported for enumeration types}}
+ typedef T __attribute__((mode(V8DI))) T2; // expected-error2{{mode 'V8DI' is not supported for enumeration types}}
// expected-warning at -1{{deprecated}}
// Check parameters.
>From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Thu, 14 Nov 2024 19:24:45 +0000
Subject: [PATCH 2/3] Include attributes on LabelStmts (forwarding from decls)
in AST dumps
We apply this to add a test of the new label attribute instantiation support.
---
clang/examples/Attribute/Attribute.cpp | 6 +++---
clang/include/clang/AST/ASTNodeTraverser.h | 5 +++++
clang/test/Frontend/plugin-attribute.cpp | 8 ++++++++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp
index 3b90724ad22205..59446a15a6925d 100644
--- a/clang/examples/Attribute/Attribute.cpp
+++ b/clang/examples/Attribute/Attribute.cpp
@@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo {
bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
const Decl *D) const override {
// This attribute appertains to functions only.
- if (!isa<FunctionDecl>(D)) {
+ if (!isa<FunctionDecl>(D) && !isa<LabelDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str)
- << Attr << Attr.isRegularKeywordAttribute() << "functions";
+ << Attr << Attr.isRegularKeywordAttribute() << "functions or labels";
return false;
}
return true;
@@ -52,7 +52,7 @@ struct ExampleAttrInfo : public ParsedAttrInfo {
AttrHandling handleDeclAttribute(Sema &S, Decl *D,
const ParsedAttr &Attr) const override {
// Check if the decl is at file scope.
- if (!D->getDeclContext()->isFileContext()) {
+ if (!D->getDeclContext()->isFileContext() && !isa<LabelDecl>(D)) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error,
"'example' attribute only allowed at file scope");
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index a443a88bab1f2d..876dcb647b27b4 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -800,6 +800,11 @@ class ASTNodeTraverser
Visit(A);
}
+ void VisitLabelStmt(const LabelStmt *Node) {
+ for (const auto *A : Node->getDecl()->getAttrs())
+ Visit(A);
+ }
+
void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
Visit(Node->getExceptionDecl());
}
diff --git a/clang/test/Frontend/plugin-attribute.cpp b/clang/test/Frontend/plugin-attribute.cpp
index 094ce9f5cbb85f..943ae3f95178d5 100644
--- a/clang/test/Frontend/plugin-attribute.cpp
+++ b/clang/test/Frontend/plugin-attribute.cpp
@@ -18,6 +18,9 @@ void fn2() __attribute__((example("somestring", 1, 2.0))) {
}
template <int N> void template_fn() __attribute__((example("template", N))) {
__attribute__((example("def", N + 1))) for (int i = 0; i < 9; ++i) {}
+ __attribute__((example("ghi", N + 2)))
+label1:
+ for (int i = 0; i < 9; ++i) {}
}
void fn3() { template_fn<5>(); }
// CHECK: -AttributedStmt 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}}
@@ -44,6 +47,11 @@ void fn3() { template_fn<5>(); }
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} 'int' 5
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 1
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
+// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "ghi"
+// CHECK: -BinaryOperator 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' '+'
+// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} 'int' 5
+// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 2
+// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "template"
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 5
>From 6ba54c4760f943402d3ae47282ebd1502e59afb9 Mon Sep 17 00:00:00 2001
From: Eric Astor <epastor at google.com>
Date: Thu, 14 Nov 2024 19:37:39 +0000
Subject: [PATCH 3/3] Scope this change back to just applying to LabelDecls
---
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index bfc5913dbafd0f..4529eb99377e78 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1010,7 +1010,6 @@ TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->getQualifierLoc(),
D->getTargetNameLoc(),
D->getNamespace());
- SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
return Inst;
}
@@ -1097,21 +1096,15 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false);
- if (Typedef) {
- SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef, LateAttrs,
- StartingScope);
+ if (Typedef)
Owner->addDecl(Typedef);
- }
return Typedef;
}
Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {
Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true);
- if (Typedef) {
- SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef, LateAttrs,
- StartingScope);
+ if (Typedef)
Owner->addDecl(Typedef);
- }
return Typedef;
}
@@ -1168,10 +1161,8 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl(
Decl *
TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Decl *Inst = InstantiateTypeAliasTemplateDecl(D);
- if (Inst) {
- SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
+ if (Inst)
Owner->addDecl(Inst);
- }
return Inst;
}
More information about the cfe-commits
mailing list