Author: Eric Astor Date: 2024-11-15T12:33:20-05:00 New Revision: e9e8f59dd4f88229b731a0b5951db176a03bd8c4
URL: https://github.com/llvm/llvm-project/commit/e9e8f59dd4f88229b731a0b5951db176a03bd8c4 DIFF: https://github.com/llvm/llvm-project/commit/e9e8f59dd4f88229b731a0b5951db176a03bd8c4.diff LOG: [clang] Instantiate attributes on LabelDecls (#115924) Start propagating attributes on (e.g.) labels inside of templated functions to their instances. Added: clang/test/SemaCXX/attr-annotate-ast.cpp Modified: clang/include/clang/AST/ASTNodeTraverser.h clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index a443a88bab1f2d..3d63d581a9be60 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -800,6 +800,13 @@ class ASTNodeTraverser Visit(A); } + void VisitLabelStmt(const LabelStmt *Node) { + if (Node->getDecl()->hasAttrs()) { + for (const auto *A : Node->getDecl()->getAttrs()) + Visit(A); + } + } + void VisitCXXCatchStmt(const CXXCatchStmt *Node) { Visit(Node->getExceptionDecl()); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..4529eb99377e78 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; } diff --git a/clang/test/SemaCXX/attr-annotate-ast.cpp b/clang/test/SemaCXX/attr-annotate-ast.cpp new file mode 100644 index 00000000000000..ad8e2c26e666fd --- /dev/null +++ b/clang/test/SemaCXX/attr-annotate-ast.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -std=gnu++20 -fsyntax-only -ast-dump %s | FileCheck %s + +void f() { + [[clang::annotate("decl", 1)]] int i = 0; + [[clang::annotate("stmt", 2)]] i += 1; +[[clang::annotate("label", 3)]] label1: + i += 2; +} + +// CHECK: -FunctionDecl {{.*}} f 'void ()' +// CHECK: -VarDecl {{.*}} used i 'int' +// CHECK: -AnnotateAttr {{.*}} "decl" +// CHECK: -IntegerLiteral {{.*}} 'int' 1 +// CHECK: -AttributedStmt +// CHECK: -AnnotateAttr {{.*}} "stmt" +// CHECK: -IntegerLiteral {{.*}} 'int' 2 +// CHECK: -LabelStmt {{.*}} 'label1' +// CHECK: -AnnotateAttr {{.*}} "label" +// CHECK: -IntegerLiteral {{.*}} 'int' 3 +// CHECK: -CompoundAssignOperator + +template <typename T> void g() { + [[clang::annotate("tmpl_decl", 4)]] T j = 0; + [[clang::annotate("tmpl_stmt", 5)]] j += 1; +[[clang::annotate("tmpl_label", 6)]] label2: + j += 2; +} + +// CHECK: -FunctionTemplateDecl {{.*}} g +// CHECK: -VarDecl {{.*}} referenced j 'T' +// CHECK: -AnnotateAttr {{.*}} "tmpl_decl" +// CHECK: -IntegerLiteral {{.*}} 'int' 4 +// CHECK: -AttributedStmt +// CHECK: -AnnotateAttr {{.*}} "tmpl_stmt" +// CHECK: -IntegerLiteral {{.*}} 'int' 5 +// CHECK: -LabelStmt {{.*}} 'label2' +// CHECK: -AnnotateAttr {{.*}} "tmpl_label" +// CHECK: -IntegerLiteral {{.*}} 'int' 6 +// CHECK: -CompoundAssignOperator + +void h() { + g<int>(); +} + +// CHECK: -FunctionDecl {{.*}} used g 'void ()' implicit_instantiation +// CHECK: -VarDecl {{.*}} used j 'int' +// CHECK: -AnnotateAttr {{.*}} "tmpl_decl" +// CHECK: -IntegerLiteral {{.*}} 'int' 4 +// CHECK: -AttributedStmt +// CHECK: -AnnotateAttr {{.*}} Implicit "tmpl_stmt" +// CHECK: -IntegerLiteral {{.*}} 'int' 5 +// CHECK: -LabelStmt {{.*}} 'label2' +// CHECK: -AnnotateAttr {{.*}} "tmpl_label" +// CHECK: -IntegerLiteral {{.*}} 'int' 6 +// CHECK: -CompoundAssignOperator _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits