https://github.com/mizvekov created https://github.com/llvm/llvm-project/pull/199473
This makes these functions not always return the definition if any. The few users which depend on this are updated to fetch the definition themselves. Also fixes the VarDecl variant returning the queried declaration itself. >From ad0e4c07ddd19f37188a1a1bb5ff30d08168d5c7 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <[email protected]> Date: Sun, 24 May 2026 22:00:17 -0300 Subject: [PATCH] [clang] preserve exact redeclaration for getTemplateInstantiationPattern This makes these functions not always return the definition if any. The few users which depend on this are updated to fetch the definition themselves. Also fixes the VarDecl variant returning the queried declaration itself. --- clang/lib/AST/Decl.cpp | 35 ++++--------------- clang/lib/AST/DeclCXX.cpp | 13 ++----- clang/lib/Sema/SemaLookup.cpp | 10 +++--- .../StaticAnalyzer/Core/BugSuppression.cpp | 2 +- clang/test/AST/ast-dump-decl.cpp | 12 +++---- clang/test/AST/ast-dump-linkage-internal.cpp | 2 +- clang/test/AST/ast-dump-linkage.cpp | 2 +- clang/test/AST/ast-dump-templates-pattern.cpp | 19 +++++----- 8 files changed, 34 insertions(+), 61 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 535adcb2ae109..d660fa211db3d 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2666,14 +2666,6 @@ bool VarDecl::checkForConstantInitialization( return Eval->HasConstantInitialization; } -template<typename DeclT> -static DeclT *getDefinitionOrSelf(DeclT *D) { - assert(D); - if (auto *Def = D->getDefinition()) - return Def; - return D; -} - bool VarDecl::isEscapingByref() const { return hasAttr<BlocksAttr>() && NonParmVarDeclBits.EscapingByref; } @@ -2715,7 +2707,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { break; VTD = NewVTD; } - return getDefinitionOrSelf(VTD->getTemplatedDecl()); + return VTD->getTemplatedDecl(); } if (auto *VTPSD = From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) { @@ -2725,27 +2717,14 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { break; VTPSD = NewVTPSD; } - return getDefinitionOrSelf<VarDecl>(VTPSD); + return VTPSD; } } } - // If this is the pattern of a variable template, find where it was - // instantiated from. FIXME: Is this necessary? - if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) { - while (!VarTemplate->isMemberSpecialization()) { - auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate(); - if (!NewVT) - break; - VarTemplate = NewVT; - } - - return getDefinitionOrSelf(VarTemplate->getTemplatedDecl()); - } - if (VD == this) return nullptr; - return getDefinitionOrSelf(const_cast<VarDecl*>(VD)); + return const_cast<VarDecl *>(VD); } VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { @@ -4269,7 +4248,7 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { if (isGenericLambdaCallOperatorSpecialization( dyn_cast<CXXMethodDecl>(this))) { assert(getPrimaryTemplate() && "not a generic lambda call operator?"); - return getDefinitionOrSelf(getPrimaryTemplate()->getTemplatedDecl()); + return getPrimaryTemplate()->getTemplatedDecl(); } // Check for a declaration of this function that was instantiated from a @@ -4282,7 +4261,7 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { if (ForDefinition && !clang::isTemplateInstantiation(Info->getTemplateSpecializationKind())) return nullptr; - return getDefinitionOrSelf(cast<FunctionDecl>(Info->getInstantiatedFrom())); + return cast<FunctionDecl>(Info->getInstantiatedFrom()); } if (ForDefinition && @@ -4299,7 +4278,7 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { Primary = NewPrimary; } - return getDefinitionOrSelf(Primary->getTemplatedDecl()); + return Primary->getTemplatedDecl(); } return nullptr; @@ -5137,7 +5116,7 @@ EnumDecl *EnumDecl::getTemplateInstantiationPattern() const { EnumDecl *ED = getInstantiatedFromMemberEnum(); while (auto *NewED = ED->getInstantiatedFromMemberEnum()) ED = NewED; - return ::getDefinitionOrSelf(ED); + return ED; } } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 1a4753fc29b88..2a58313b699e2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2083,13 +2083,6 @@ CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { } const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { - auto GetDefinitionOrSelf = - [](const CXXRecordDecl *D) -> const CXXRecordDecl * { - if (auto *Def = D->getDefinition()) - return Def; - return D; - }; - // If it's a class template specialization, find the template or partial // specialization from which it was instantiated. if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) { @@ -2100,7 +2093,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { break; CTD = NewCTD; } - return GetDefinitionOrSelf(CTD->getTemplatedDecl()); + return CTD->getTemplatedDecl(); } if (auto *CTPSD = dyn_cast_if_present<ClassTemplatePartialSpecializationDecl *>( @@ -2110,7 +2103,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { break; CTPSD = NewCTPSD; } - return GetDefinitionOrSelf(CTPSD); + return CTPSD; } } @@ -2119,7 +2112,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { const CXXRecordDecl *RD = this; while (auto *NewRD = RD->getInstantiatedFromMemberClass()) RD = NewRD; - return GetDefinitionOrSelf(RD); + return RD; } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index e4e55bb7d0ac7..65b60964d1192 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1589,17 +1589,19 @@ static Module *getDefiningModule(Sema &S, Decl *Entity) { // If this function was instantiated from a template, the defining module is // the module containing the pattern. if (FunctionDecl *Pattern = FD->getTemplateInstantiationPattern()) - Entity = Pattern; + Entity = Pattern->getDefinition(); } else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Entity)) { if (CXXRecordDecl *Pattern = RD->getTemplateInstantiationPattern()) - Entity = Pattern; + Entity = Pattern->getDefinition(); } else if (EnumDecl *ED = dyn_cast<EnumDecl>(Entity)) { if (auto *Pattern = ED->getTemplateInstantiationPattern()) - Entity = Pattern; + Entity = Pattern->getDefinition(); } else if (VarDecl *VD = dyn_cast<VarDecl>(Entity)) { if (VarDecl *Pattern = VD->getTemplateInstantiationPattern()) - Entity = Pattern; + Entity = Pattern->getDefinition(); } + if (!Entity) + return nullptr; // Walk up to the containing context. That might also have been instantiated // from a template. diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp index b06026984775a..6c1a55f79b908 100644 --- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp @@ -246,7 +246,7 @@ preferTemplateDefinitionForTemplateSpecializations(const Decl *D) { // existing parent-chain walk find the suppression attribute. if (const auto *FD = dyn_cast<FunctionDecl>(D)) { if (const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern()) - return Pattern; + return Pattern->getDefinition(); } const auto *SpecializationDecl = dyn_cast<ClassTemplateSpecializationDecl>(D); diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp index 9b745642aedd0..15c2e4e07e95c 100644 --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -719,7 +719,7 @@ namespace testCanonicalTemplate { // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-11]]:7, col:43> col:43 TestVarTemplate external-linkage{{$}} // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:16, col:25> col:25 referenced typename depth 0 index 0 T{{$}} - // CHECK-NEXT: |-VarDecl 0x{{.+}} <col:28, col:43> col:43 TestVarTemplate 'const T' static instantiated_from 0x{{.+}}{{$}} + // CHECK-NEXT: |-VarDecl 0x{{.+}} <col:28, col:43> col:43 TestVarTemplate 'const T' static{{$}} // CHECK-NEXT: |-VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-12]]:3, line:[[@LINE-11]]:34> col:14 referenced TestVarTemplate 'const int' implicit_instantiation cinit instantiated_from 0x{{.+}}{{$}} // CHECK-NEXT: | |-NestedNameSpecifier TypeSpec 'S'{{$}} // CHECK-NEXT: | |-TemplateArgument type 'int'{{$}} @@ -734,7 +734,7 @@ namespace testCanonicalTemplate { // CHECK: VarTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-24]]:3, line:[[@LINE-23]]:34> col:14 TestVarTemplate external-linkage{{$}} // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <line:[[@LINE-25]]:12, col:21> col:21 referenced typename depth 0 index 0 T{{$}} - // CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-25]]:3, col:34> col:14 TestVarTemplate 'const T' cinit instantiated_from 0x{{.+}}{{$}} + // CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-25]]:3, col:34> col:14 TestVarTemplate 'const T' cinit{{$}} // CHECK-NEXT: | |-NestedNameSpecifier TypeSpec 'S'{{$}} // CHECK-NEXT: | `-InitListExpr 0x{{.+}} <col:32, col:34> 'void' explicit{{$}} // CHECK-NEXT: |-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int'{{$}} @@ -945,13 +945,13 @@ namespace TestConstexprVariableTemplateWithInitializer { template<typename T> constexpr T foo{}; // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-1]]:3, col:40> col:36 foo external-linkage{{$}} // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 referenced typename depth 0 index 0 T{{$}} - // CHECK-NEXT: `-VarDecl 0x{{.+}} <col:24, col:40> col:36 foo 'const T' constexpr listinit instantiated_from 0x{{.+}}{{$}} + // CHECK-NEXT: `-VarDecl 0x{{.+}} <col:24, col:40> col:36 foo 'const T' constexpr listinit{{$}} // CHECK-NEXT: `-InitListExpr 0x{{.+}} <col:39, col:40> 'void' explicit{{$}} template<typename T> constexpr int val{42}; // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-1]]:3, col:44> col:38 val external-linkage{{$}} // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T{{$}} - // CHECK-NEXT: `-VarDecl 0x{{.+}} <col:24, col:44> col:38 val 'const int' constexpr listinit instantiated_from 0x{{.+}}{{$}} + // CHECK-NEXT: `-VarDecl 0x{{.+}} <col:24, col:44> col:38 val 'const int' constexpr listinit{{$}} // CHECK-NEXT: |-value: Int 42{{$}} // CHECK-NEXT: `-InitListExpr 0x{{.+}} <col:41, col:44> 'int' explicit{{$}} @@ -964,13 +964,13 @@ namespace TestConstexprVariableTemplateWithInitializer { inline constexpr in_place_type_t<_Tp> in_place_type{}; // CHECK: -VarTemplateDecl 0x{{.+}} <line:[[@LINE-2]]:3, line:[[@LINE-1]]:55> col:41 in_place_type external-linkage{{$}} // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <line:[[@LINE-3]]:13, col:22> col:22 referenced typename depth 0 index 0 _Tp{{$}} - // CHECK-NEXT: `-VarDecl 0x{{.+}} <line:[[@LINE-3]]:3, col:55> col:41 in_place_type 'const in_place_type_t<_Tp>' inline constexpr listinit instantiated_from 0x{{.+}}{{$}} + // CHECK-NEXT: `-VarDecl 0x{{.+}} <line:[[@LINE-3]]:3, col:55> col:41 in_place_type 'const in_place_type_t<_Tp>' inline constexpr listinit{{$}} // CHECK-NEXT: `-InitListExpr 0x{{.+}} <col:54, col:55> 'void' explicit{{$}} template <typename T> constexpr T call_init(0); // CHECK: -VarTemplateDecl 0x{{.+}} <line:[[@LINE-1]]:3, col:48> col:37 call_init external-linkage{{$}} // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:13, col:22> col:22 referenced typename depth 0 index 0 T{{$}} - // CHECK-NEXT: `-VarDecl 0x{{.+}} <col:25, col:48> col:37 call_init 'const T' constexpr callinit instantiated_from 0x{{.+}}{{$}} + // CHECK-NEXT: `-VarDecl 0x{{.+}} <col:25, col:48> col:37 call_init 'const T' constexpr callinit{{$}} // CHECK-NEXT: `-ParenListExpr 0x{{.+}} <col:46, col:48> 'NULL TYPE'{{$}} // CHECK-NEXT: `-IntegerLiteral 0x{{.+}} <col:47> 'int' 0{{$}} } diff --git a/clang/test/AST/ast-dump-linkage-internal.cpp b/clang/test/AST/ast-dump-linkage-internal.cpp index 6b961301c4abb..1d88fe3a41d37 100644 --- a/clang/test/AST/ast-dump-linkage-internal.cpp +++ b/clang/test/AST/ast-dump-linkage-internal.cpp @@ -80,7 +80,7 @@ const int ConstInt = 0; template <typename T> T TemplatedVar = T{}; // CHECK: | |-VarTemplateDecl {{.*}} TemplatedVar internal-linkage -// CHECK: | | |-VarDecl {{.*}} TemplatedVar 'T' cinit instantiated_from 0x{{[0-9a-f]*}} +// CHECK: | | |-VarDecl {{.*}} TemplatedVar 'T' cinit // CHECK: | | `-VarTemplateSpecializationDecl {{.*}} used TemplatedVar 'int' implicit_instantiation cinit instantiated_from 0x{{[0-9a-f]*}} internal-linkage // FIXME: VarTemplateSpecializationDecl node is printed twice. diff --git a/clang/test/AST/ast-dump-linkage.cpp b/clang/test/AST/ast-dump-linkage.cpp index 18228eb4e8c21..b4ede9a522871 100644 --- a/clang/test/AST/ast-dump-linkage.cpp +++ b/clang/test/AST/ast-dump-linkage.cpp @@ -77,7 +77,7 @@ const int ConstInt = 0; template <typename T> T TemplatedVar = T{}; // CHECK: |-VarTemplateDecl {{.*}} TemplatedVar external-linkage -// CHECK: | |-VarDecl {{.*}} TemplatedVar 'T' cinit instantiated_from 0x{{[0-9a-f]*}} +// CHECK: | |-VarDecl {{.*}} TemplatedVar 'T' cinit // CHECK: | `-VarTemplateSpecializationDecl {{.*}} used TemplatedVar 'int' implicit_instantiation cinit instantiated_from 0x{{[0-9a-f]*}} external-linkage // FIXME: VarTemplateSpecializationDecl node is printed twice. diff --git a/clang/test/AST/ast-dump-templates-pattern.cpp b/clang/test/AST/ast-dump-templates-pattern.cpp index 6938f650cc50b..aec86664f9988 100644 --- a/clang/test/AST/ast-dump-templates-pattern.cpp +++ b/clang/test/AST/ast-dump-templates-pattern.cpp @@ -18,7 +18,7 @@ namespace TestClassRedecl { // CHECK: |-ClassTemplateDecl {{.+}} <line:[[@LINE-6]]:{{.+}} A external-linkage // CHECK: | |-CXXRecordDecl 0x[[TestClassRedecl_D2:[^ ]+]] prev 0x[[TestClassRedecl_D1]] {{.+}} struct A // CHECK: | `-ClassTemplateSpecialization 0x[[TestClassRedecl_S]] 'A' -// CHECK: |-ClassTemplateSpecializationDecl 0x[[TestClassRedecl_S]] <line:[[@LINE-8]]:{{.+}} struct A definition external-linkage instantiated_from 0x[[TestClassRedecl_D1]] explicit_instantiation_definition +// CHECK: |-ClassTemplateSpecializationDecl 0x[[TestClassRedecl_S]] <line:[[@LINE-8]]:{{.+}} struct A definition external-linkage instantiated_from 0x[[TestClassRedecl_D2]] explicit_instantiation_definition // CHECK: `-ExplicitInstantiationDecl {{.+}} <line:[[@LINE-9]]:{{.+}} 'A' // CHECK: |-ClassTemplateSpecialization 0x[[TestClassRedecl_S]] 'A' // CHECK: `-TemplateArgument {{.+}} type 'int' @@ -32,9 +32,9 @@ namespace TestFunctionRedecl { // CHECK-LABEL: Dumping TestFunctionRedecl: // CHECK: |-FunctionTemplateDecl 0x[[TestFunctionRedecl_T1:[^ ]+]] <line:[[@LINE-4]]:{{.+}} f external-linkage // CHECK: | |-FunctionDecl 0x[[TestFunctionRedecl_D1:[^ ]+]] {{.+}} f 'void ()' -// CHECK: | `-FunctionDecl 0x[[TestFunctionRedecl_S1:[^ ]+]] {{.+}} f 'void ()' explicit_instantiation_definition instantiated_from 0x[[TestFunctionRedecl_D1]] external-linkage +// CHECK: | `-FunctionDecl 0x[[TestFunctionRedecl_S1:[^ ]+]] {{.+}} f 'void ()' explicit_instantiation_definition instantiated_from 0x[[TestFunctionRedecl_D2:[^ ]+]] external-linkage // CHECK: |-FunctionTemplateDecl 0x[[TestFunctionRedecl_T2:[^ ]+]] prev 0x[[TestFunctionRedecl_T1]] <line:[[@LINE-6]]:{{.+}} f external-linkage -// CHECK: | |-FunctionDecl 0x[[TestFunctionRedecl_D2:[^ ]+]] prev 0x[[TestFunctionRedecl_D1]] {{.+}} f 'void ()' +// CHECK: | |-FunctionDecl 0x[[TestFunctionRedecl_D2]] prev 0x[[TestFunctionRedecl_D1]] {{.+}} f 'void ()' // CHECK: | `-Function 0x[[TestFunctionRedecl_S1]] 'f' 'void ()' // CHECK: `-ExplicitInstantiationDecl {{.+}} <line:[[@LINE-8]]:{{.+}} 'f' // CHECK: |-Function 0x[[TestFunctionRedecl_S1]] 'f' 'void ()' @@ -44,19 +44,18 @@ namespace TestFunctionRedecl { // CHECK: `-BuiltinType {{.+}} 'int' } -// FIXME: Bogus instantiated_from self-reference. namespace TestVariableRedecl { template <class T> T a = 0; template <class T> extern T a; template int a<int>; // CHECK-LABEL: Dumping TestVariableRedecl: // CHECK: |-VarTemplateDecl 0x[[TestVariableRedecl_T1:[^ ]+]] <line:[[@LINE-4]]:{{.+}} a external-linkage -// CHECK: | |-VarDecl 0x[[TestVariableRedecl_D1:[^ ]+]] {{.+}} a 'T' cinit instantiated_from 0x[[TestVariableRedecl_D1]] +// CHECK: | |-VarDecl 0x[[TestVariableRedecl_D1:[^ ]+]] {{.+}} a 'T' cinit{{$}} // CHECK: | `-VarTemplateSpecialization 0x[[TestVariableRedecl_S1:[^ ]+]] 'a' 'int' // CHECK: |-VarTemplateDecl 0x[[TestVariableRedecl_T2:[^ ]+]] prev 0x[[TestVariableRedecl_T1]] <line:[[@LINE-6]]:{{.+}} a external-linkage -// CHECK: | |-VarDecl 0x[[TestVariableRedecl_D2:[^ ]+]] prev 0x[[TestVariableRedecl_D1]] {{.+}} a 'T' extern instantiated_from 0x[[TestVariableRedecl_D1]] +// CHECK: | |-VarDecl 0x[[TestVariableRedecl_D2:[^ ]+]] prev 0x[[TestVariableRedecl_D1]] {{.+}} a 'T' extern{{$}} // CHECK: | `-VarTemplateSpecialization 0x[[TestVariableRedecl_S1]] 'a' 'int' -// CHECK: |-VarTemplateSpecializationDecl 0x[[TestVariableRedecl_S1]] {{.+}} a 'int' explicit_instantiation_definition cinit instantiated_from 0x[[TestVariableRedecl_D1]] external-linkage +// CHECK: |-VarTemplateSpecializationDecl 0x[[TestVariableRedecl_S1]] {{.+}} a 'int' explicit_instantiation_definition cinit instantiated_from 0x[[TestVariableRedecl_D2]] external-linkage // CHECK: `-ExplicitInstantiationDecl {{.+}} <line:[[@LINE-9]]:{{.+}} 'a' // CHECK: |-VarTemplateSpecialization 0x[[TestVariableRedecl_S1]] 'a' 'int' // CHECK: |-BuiltinTypeLoc {{.+}} 'int' @@ -76,16 +75,16 @@ namespace TestNestedClassRedecl { // CHECK: | |-CXXRecordDecl 0x[[TestNestedClassRedecl_A_D1:[^ ]+]] <{{.+}}line:[[@LINE-6]]:{{.+}}> line:[[@LINE-8]]:{{.+}} struct A definition // CHECK: | | `-ClassTemplateDecl 0x[[TestNestedClassRedecl_B_T1:[^ ]+]] <line:[[@LINE-8]]:{{.+}} B external-linkage // CHECK: | | `-CXXRecordDecl 0x[[TestNestedClassRedecl_B_D1:[^ ]+]] {{.+}} struct B -// CHECK: | `-ClassTemplateSpecializationDecl 0x[[TestNestedClassRedecl_A_S1:[^ ]+]] <line:[[@LINE-8]]:{{.+}} line:[[@LINE-11]]:{{.+}} struct A definition external-linkage instantiated_from 0x[[TestNestedClassRedecl_A_D1]] implicit_instantiation +// CHECK: | `-ClassTemplateSpecializationDecl 0x[[TestNestedClassRedecl_A_S1:[^ ]+]] <line:[[@LINE-8]]:{{.+}} line:[[@LINE-11]]:{{.+}} struct A definition external-linkage instantiated_from 0x[[TestNestedClassRedecl_A_D2:[^ ]+]] implicit_instantiation // CHECK: | `-ClassTemplateDecl 0x{{.+}} <line:[[@LINE-11]]:{{.+}} B external-linkage // CHECK: | |-CXXRecordDecl 0x{{.+}} struct B // CHECK: | `-ClassTemplateSpecialization 0x[[TestNestedClassRedecl_B_S1:[^ ]+]] 'B' // CHECK: |-ClassTemplateDecl 0x{{.+}} prev 0x[[TestNestedClassRedecl_A_T1]] <line:[[@LINE-12]]:{{.+}} A external-linkage -// CHECK: | |-CXXRecordDecl 0x[[TestNestedClassRedecl_A_D2:[^ ]+]] prev 0x[[TestNestedClassRedecl_A_D1]] {{.+}} struct A +// CHECK: | |-CXXRecordDecl 0x[[TestNestedClassRedecl_A_D2]] prev 0x[[TestNestedClassRedecl_A_D1]] {{.+}} struct A // CHECK: | `-ClassTemplateSpecialization 0x[[TestNestedClassRedecl_A_S1]] 'A' // CHECK: |-ClassTemplateDecl 0x{{.+}} parent 0x[[TestNestedClassRedecl_A_D1]] prev 0x[[TestNestedClassRedecl_B_T1]] <line:[[@LINE-14]]:{{.+}} B external-linkage // CHECK: | `-CXXRecordDecl 0x[[TestNestedClassRedecl_B_D2:[^ ]+]] parent 0x[[TestNestedClassRedecl_A_D1]] prev 0x[[TestNestedClassRedecl_B_D1]] {{.+}} struct B definition -// CHECK: |-ClassTemplateSpecializationDecl 0x[[TestNestedClassRedecl_B_S1]] parent 0x[[TestNestedClassRedecl_A_S1]] <line:[[@LINE-15]]:{{.+}} struct B definition external-linkage instantiated_from 0x[[TestNestedClassRedecl_B_D2]] explicit_instantiation_definition +// CHECK: |-ClassTemplateSpecializationDecl 0x[[TestNestedClassRedecl_B_S1]] parent 0x[[TestNestedClassRedecl_A_S1]] <line:[[@LINE-15]]:{{.+}} struct B definition external-linkage instantiated_from 0x[[TestNestedClassRedecl_B_D1]] explicit_instantiation_definition // CHECK: `-ExplicitInstantiationDecl {{.+}} <line:[[@LINE-16]]:{{.+}} 'B' // CHECK: |-NestedNameSpecifier TypeSpec {{.+}} // CHECK: |-ClassTemplateSpecialization 0x[[TestNestedClassRedecl_B_S1]] 'B' _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
