Skip to content

Commit e9e8f59

Browse files
authored
[clang] Instantiate attributes on LabelDecls (#115924)
Start propagating attributes on (e.g.) labels inside of templated functions to their instances.
1 parent 2d48489 commit e9e8f59

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

clang/include/clang/AST/ASTNodeTraverser.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,13 @@ class ASTNodeTraverser
800800
Visit(A);
801801
}
802802

803+
void VisitLabelStmt(const LabelStmt *Node) {
804+
if (Node->getDecl()->hasAttrs()) {
805+
for (const auto *A : Node->getDecl()->getAttrs())
806+
Visit(A);
807+
}
808+
}
809+
803810
void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
804811
Visit(Node->getExceptionDecl());
805812
}

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ Decl *
990990
TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) {
991991
LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(),
992992
D->getIdentifier());
993+
SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
993994
Owner->addDecl(Inst);
994995
return Inst;
995996
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %clang_cc1 -std=gnu++20 -fsyntax-only -ast-dump %s | FileCheck %s
2+
3+
void f() {
4+
[[clang::annotate("decl", 1)]] int i = 0;
5+
[[clang::annotate("stmt", 2)]] i += 1;
6+
[[clang::annotate("label", 3)]] label1:
7+
i += 2;
8+
}
9+
10+
// CHECK: -FunctionDecl {{.*}} f 'void ()'
11+
// CHECK: -VarDecl {{.*}} used i 'int'
12+
// CHECK: -AnnotateAttr {{.*}} "decl"
13+
// CHECK: -IntegerLiteral {{.*}} 'int' 1
14+
// CHECK: -AttributedStmt
15+
// CHECK: -AnnotateAttr {{.*}} "stmt"
16+
// CHECK: -IntegerLiteral {{.*}} 'int' 2
17+
// CHECK: -LabelStmt {{.*}} 'label1'
18+
// CHECK: -AnnotateAttr {{.*}} "label"
19+
// CHECK: -IntegerLiteral {{.*}} 'int' 3
20+
// CHECK: -CompoundAssignOperator
21+
22+
template <typename T> void g() {
23+
[[clang::annotate("tmpl_decl", 4)]] T j = 0;
24+
[[clang::annotate("tmpl_stmt", 5)]] j += 1;
25+
[[clang::annotate("tmpl_label", 6)]] label2:
26+
j += 2;
27+
}
28+
29+
// CHECK: -FunctionTemplateDecl {{.*}} g
30+
// CHECK: -VarDecl {{.*}} referenced j 'T'
31+
// CHECK: -AnnotateAttr {{.*}} "tmpl_decl"
32+
// CHECK: -IntegerLiteral {{.*}} 'int' 4
33+
// CHECK: -AttributedStmt
34+
// CHECK: -AnnotateAttr {{.*}} "tmpl_stmt"
35+
// CHECK: -IntegerLiteral {{.*}} 'int' 5
36+
// CHECK: -LabelStmt {{.*}} 'label2'
37+
// CHECK: -AnnotateAttr {{.*}} "tmpl_label"
38+
// CHECK: -IntegerLiteral {{.*}} 'int' 6
39+
// CHECK: -CompoundAssignOperator
40+
41+
void h() {
42+
g<int>();
43+
}
44+
45+
// CHECK: -FunctionDecl {{.*}} used g 'void ()' implicit_instantiation
46+
// CHECK: -VarDecl {{.*}} used j 'int'
47+
// CHECK: -AnnotateAttr {{.*}} "tmpl_decl"
48+
// CHECK: -IntegerLiteral {{.*}} 'int' 4
49+
// CHECK: -AttributedStmt
50+
// CHECK: -AnnotateAttr {{.*}} Implicit "tmpl_stmt"
51+
// CHECK: -IntegerLiteral {{.*}} 'int' 5
52+
// CHECK: -LabelStmt {{.*}} 'label2'
53+
// CHECK: -AnnotateAttr {{.*}} "tmpl_label"
54+
// CHECK: -IntegerLiteral {{.*}} 'int' 6
55+
// CHECK: -CompoundAssignOperator

0 commit comments

Comments
 (0)