diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -542,6 +542,9 @@ class NamespaceDecl : public NamedDecl, public DeclContext, public Redeclarable { + + enum Flags : unsigned { F_Inline = 1 << 0, F_Nested = 1 << 1 }; + /// The starting location of the source range, pointing /// to either the namespace or the inline keyword. SourceLocation LocStart; @@ -553,11 +556,12 @@ /// this namespace or to the first namespace in the chain (the latter case /// only when this is not the first in the chain), along with a /// boolean value indicating whether this is an inline namespace. - llvm::PointerIntPair AnonOrFirstNamespaceAndInline; + llvm::PointerIntPair + AnonOrFirstNamespaceAndFlags; NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, NamespaceDecl *PrevDecl); + IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); using redeclarable_base = Redeclarable; @@ -569,10 +573,10 @@ friend class ASTDeclReader; friend class ASTDeclWriter; - static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, - bool Inline, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - NamespaceDecl *PrevDecl); + static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, bool Inline, + SourceLocation StartLoc, SourceLocation IdLoc, + IdentifierInfo *Id, NamespaceDecl *PrevDecl, + bool Nested); static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -601,12 +605,33 @@ /// Returns true if this is an inline namespace declaration. bool isInline() const { - return AnonOrFirstNamespaceAndInline.getInt(); + return AnonOrFirstNamespaceAndFlags.getInt() & F_Inline; } /// Set whether this is an inline namespace declaration. void setInline(bool Inline) { - AnonOrFirstNamespaceAndInline.setInt(Inline); + unsigned F = AnonOrFirstNamespaceAndFlags.getInt(); + if (Inline) + AnonOrFirstNamespaceAndFlags.setInt(F | F_Inline); + else + AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Inline); + } + + /// Returns true if this is a nested namespace declaration. + /// \code + /// namespace outer::nested { } + /// \endcode + bool isNested() const { + return AnonOrFirstNamespaceAndFlags.getInt() & F_Nested; + } + + /// Set whether this is a nested namespace declaration. + void setNested(bool Nested) { + unsigned F = AnonOrFirstNamespaceAndFlags.getInt(); + if (Nested) + AnonOrFirstNamespaceAndFlags.setInt(F | F_Nested); + else + AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Nested); } /// Returns true if the inline qualifier for \c Name is redundant. @@ -635,11 +660,11 @@ /// Retrieve the anonymous namespace nested inside this namespace, /// if any. NamespaceDecl *getAnonymousNamespace() const { - return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer(); + return getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.getPointer(); } void setAnonymousNamespace(NamespaceDecl *D) { - getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D); + getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.setPointer(D); } /// Retrieves the canonical declaration of this namespace. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6027,7 +6027,7 @@ SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, const ParsedAttributesView &AttrList, - UsingDirectiveDecl *&UsingDecl); + UsingDirectiveDecl *&UsingDecl, bool IsNested); void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); NamespaceDecl *getStdNamespace() const; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8767,7 +8767,7 @@ const_cast(*Context), Context->getTranslationUnitDecl(), /*Inline*/ false, SourceLocation(), SourceLocation(), &Context->Idents.get("std"), - /*PrevDecl*/ nullptr); + /*PrevDecl*/ nullptr, /*Nested*/ false); NS->setImplicit(); VaListTagDecl->setDeclContext(NS); } @@ -8954,9 +8954,9 @@ NamespaceDecl *NS; NS = NamespaceDecl::Create(const_cast(*Context), Context->getTranslationUnitDecl(), - /*Inline*/false, SourceLocation(), + /*Inline*/ false, SourceLocation(), SourceLocation(), &Context->Idents.get("std"), - /*PrevDecl*/ nullptr); + /*PrevDecl*/ nullptr, /*Nested*/ false); NS->setImplicit(); VaListDecl->setDeclContext(NS); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2412,10 +2412,10 @@ // Create the "to" namespace, if needed. NamespaceDecl *ToNamespace = MergeWithNamespace; if (!ToNamespace) { - if (GetImportedOrCreateDecl( - ToNamespace, D, Importer.getToContext(), DC, D->isInline(), - *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(), - /*PrevDecl=*/nullptr)) + if (GetImportedOrCreateDecl(ToNamespace, D, Importer.getToContext(), DC, + D->isInline(), *BeginLocOrErr, Loc, + Name.getAsIdentifierInfo(), + /*PrevDecl=*/nullptr, D->isNested())) return ToNamespace; ToNamespace->setRBraceLoc(*RBraceLocOrErr); ToNamespace->setLexicalDeclContext(LexicalDC); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2880,41 +2880,43 @@ NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, NamespaceDecl *PrevDecl) + IdentifierInfo *Id, NamespaceDecl *PrevDecl, + bool Nested) : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace), redeclarable_base(C), LocStart(StartLoc), - AnonOrFirstNamespaceAndInline(nullptr, Inline) { + AnonOrFirstNamespaceAndFlags(nullptr, + F_Inline * Inline | F_Nested * Nested) { setPreviousDecl(PrevDecl); if (PrevDecl) - AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace()); + AnonOrFirstNamespaceAndFlags.setPointer(PrevDecl->getOriginalNamespace()); } NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, - NamespaceDecl *PrevDecl) { - return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, - PrevDecl); + NamespaceDecl *PrevDecl, bool Nested) { + return new (C, DC) + NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), - SourceLocation(), nullptr, nullptr); + SourceLocation(), nullptr, nullptr, false); } NamespaceDecl *NamespaceDecl::getOriginalNamespace() { if (isFirstDecl()) return this; - return AnonOrFirstNamespaceAndInline.getPointer(); + return AnonOrFirstNamespaceAndFlags.getPointer(); } const NamespaceDecl *NamespaceDecl::getOriginalNamespace() const { if (isFirstDecl()) return this; - return AnonOrFirstNamespaceAndInline.getPointer(); + return AnonOrFirstNamespaceAndFlags.getPointer(); } bool NamespaceDecl::isOriginalNamespace() const { return isFirstDecl(); } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -604,7 +604,7 @@ getASTContext(), getASTContext().getTranslationUnitDecl(), /*Inline*/ false, SourceLocation(), SourceLocation(), &getASTContext().Idents.get("std"), - /*PrevDecl*/ nullptr); + /*PrevDecl*/ nullptr, /*Nested*/ false); StdNamespace->setImplicit(); } return StdNamespace; diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -794,6 +794,7 @@ void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) { VisitNamedDecl(ND); attributeOnlyIfTrue("isInline", ND->isInline()); + attributeOnlyIfTrue("isNested", ND->isNested()); if (!ND->isOriginalNamespace()) JOS.attribute("originalNamespace", createBareDeclRef(ND->getOriginalNamespace())); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1931,6 +1931,8 @@ dumpName(D); if (D->isInline()) OS << " inline"; + if (D->isNested()) + OS << " nested"; if (!D->isOriginalNamespace()) dumpDeclRef(D->getOriginalNamespace(), "original"); } diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -227,7 +227,7 @@ UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr; Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident, - T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); + T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, false); PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl, NamespaceLoc, "parsing namespace"); @@ -274,7 +274,7 @@ Decl *NamespcDecl = Actions.ActOnStartNamespaceDef( getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc, InnerNSs[index].IdentLoc, InnerNSs[index].Ident, - Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl); + Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, true); assert(!ImplicitUsingDirectiveDecl && "nested namespace definition cannot define anonymous namespace"); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -381,9 +381,9 @@ NamespaceDecl *PrevDecl = nullptr; if (S.LookupQualifiedName(Result, AST.getTranslationUnitDecl())) PrevDecl = Result.getAsSingle(); - HLSLNamespace = NamespaceDecl::Create(AST, AST.getTranslationUnitDecl(), - false, SourceLocation(), - SourceLocation(), &HLSL, PrevDecl); + HLSLNamespace = NamespaceDecl::Create( + AST, AST.getTranslationUnitDecl(), false, SourceLocation(), + SourceLocation(), &HLSL, PrevDecl, false); HLSLNamespace->setImplicit(true); HLSLNamespace->setHasExternalLexicalStorage(); AST.getTranslationUnitDecl()->addDecl(HLSLNamespace); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11157,10 +11157,13 @@ /// ActOnStartNamespaceDef - This is called at the start of a namespace /// definition. -Decl *Sema::ActOnStartNamespaceDef( - Scope *NamespcScope, SourceLocation InlineLoc, SourceLocation NamespaceLoc, - SourceLocation IdentLoc, IdentifierInfo *II, SourceLocation LBrace, - const ParsedAttributesView &AttrList, UsingDirectiveDecl *&UD) { +Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope, + SourceLocation InlineLoc, + SourceLocation NamespaceLoc, + SourceLocation IdentLoc, IdentifierInfo *II, + SourceLocation LBrace, + const ParsedAttributesView &AttrList, + UsingDirectiveDecl *&UD, bool IsNested) { SourceLocation StartLoc = InlineLoc.isValid() ? InlineLoc : NamespaceLoc; // For anonymous namespace, take the location of the left brace. SourceLocation Loc = II ? IdentLoc : LBrace; @@ -11230,8 +11233,8 @@ &IsInline, PrevNS); } - NamespaceDecl *Namespc = NamespaceDecl::Create(Context, CurContext, IsInline, - StartLoc, Loc, II, PrevNS); + NamespaceDecl *Namespc = NamespaceDecl::Create( + Context, CurContext, IsInline, StartLoc, Loc, II, PrevNS, IsNested); if (IsInvalid) Namespc->setInvalidDecl(); @@ -11492,12 +11495,11 @@ NamespaceDecl *Sema::getOrCreateStdNamespace() { if (!StdNamespace) { // The "std" namespace has not yet been defined, so build one implicitly. - StdNamespace = NamespaceDecl::Create(Context, - Context.getTranslationUnitDecl(), - /*Inline=*/false, - SourceLocation(), SourceLocation(), - &PP.getIdentifierTable().get("std"), - /*PrevDecl=*/nullptr); + StdNamespace = NamespaceDecl::Create( + Context, Context.getTranslationUnitDecl(), + /*Inline=*/false, SourceLocation(), SourceLocation(), + &PP.getIdentifierTable().get("std"), + /*PrevDecl=*/nullptr, /*Nested=*/false); getStdNamespace()->setImplicit(true); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1745,6 +1745,7 @@ RedeclarableResult Redecl = VisitRedeclarable(D); VisitNamedDecl(D); D->setInline(Record.readInt()); + D->setNested(Record.readInt()); D->LocStart = readSourceLocation(); D->RBraceLoc = readSourceLocation(); @@ -1758,7 +1759,7 @@ } else { // Link this namespace back to the first declaration, which has already // been deserialized. - D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl()); + D->AnonOrFirstNamespaceAndFlags.setPointer(D->getFirstDecl()); } mergeRedeclarable(D, Redecl); @@ -2784,8 +2785,8 @@ // We cannot have loaded any redeclarations of this declaration yet, so // there's nothing else that needs to be updated. if (auto *Namespace = dyn_cast(D)) - Namespace->AnonOrFirstNamespaceAndInline.setPointer( - assert_cast(ExistingCanon)); + Namespace->AnonOrFirstNamespaceAndFlags.setPointer( + assert_cast(ExistingCanon)); // When we merge a template, merge its pattern. if (auto *DTemplate = dyn_cast(D)) diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1252,6 +1252,7 @@ VisitRedeclarable(D); VisitNamedDecl(D); Record.push_back(D->isInline()); + Record.push_back(D->isNested()); Record.AddSourceLocation(D->getBeginLoc()); Record.AddSourceLocation(D->getRBraceLoc()); diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -1,806 +1,823 @@ -// Test without serialization: -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions \ -// RUN: -ast-dump -ast-dump-filter Test %s \ -// RUN: | FileCheck --strict-whitespace %s -// -// Test with serialization: FIXME: Find why the outputs differs and fix it! -// : %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -emit-pch -o %t %s -// : %clang_cc1 -x c++ -std=c++11 -triple x86_64-linux-gnu -fms-extensions -include-pch %t \ -// : -ast-dump-all -ast-dump-filter Test /dev/null \ -// : | sed -e "s/ //" -e "s/ imported//" \ -// : | FileCheck --strict-whitespace %s - -class testEnumDecl { - enum class TestEnumDeclScoped; - enum TestEnumDeclFixed : int; -}; -// CHECK: EnumDecl{{.*}} class TestEnumDeclScoped 'int' -// CHECK: EnumDecl{{.*}} TestEnumDeclFixed 'int' - -class testFieldDecl { - int TestFieldDeclInit = 0; -}; -// CHECK: FieldDecl{{.*}} TestFieldDeclInit 'int' -// CHECK-NEXT: IntegerLiteral - -namespace testVarDeclNRVO { - class A { }; - A foo() { - A TestVarDeclNRVO; - return TestVarDeclNRVO; - } -} -// CHECK: VarDecl{{.*}} TestVarDeclNRVO 'A':'testVarDeclNRVO::A' nrvo - -void testParmVarDeclInit(int TestParmVarDeclInit = 0); -// CHECK: ParmVarDecl{{.*}} TestParmVarDeclInit 'int' -// CHECK-NEXT: IntegerLiteral{{.*}} - -namespace TestNamespaceDecl { - int i; -} -// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl -// CHECK-NEXT: VarDecl - -namespace TestNamespaceDecl { - int j; -} -// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl -// CHECK-NEXT: original Namespace -// CHECK-NEXT: VarDecl - -inline namespace TestNamespaceDeclInline { -} -// CHECK: NamespaceDecl{{.*}} TestNamespaceDeclInline inline - -namespace testUsingDirectiveDecl { - namespace A { - } -} -namespace TestUsingDirectiveDecl { - using namespace testUsingDirectiveDecl::A; -} -// CHECK: NamespaceDecl{{.*}} TestUsingDirectiveDecl -// CHECK-NEXT: UsingDirectiveDecl{{.*}} Namespace{{.*}} 'A' - -namespace testNamespaceAlias { - namespace A { - } -} -namespace TestNamespaceAlias = testNamespaceAlias::A; -// CHECK: NamespaceAliasDecl{{.*}} TestNamespaceAlias -// CHECK-NEXT: Namespace{{.*}} 'A' - -using TestTypeAliasDecl = int; -// CHECK: TypeAliasDecl{{.*}} TestTypeAliasDecl 'int' - -namespace testTypeAliasTemplateDecl { - template class A; - template using TestTypeAliasTemplateDecl = A; -} -// CHECK: TypeAliasTemplateDecl{{.*}} TestTypeAliasTemplateDecl -// CHECK-NEXT: TemplateTypeParmDecl -// CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A' - -namespace testCXXRecordDecl { - class TestEmpty {}; -// CHECK: CXXRecordDecl{{.*}} class TestEmpty -// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init -// CHECK-NEXT: DefaultConstructor exists trivial constexpr -// CHECK-NEXT: CopyConstructor simple trivial has_const_param -// CHECK-NEXT: MoveConstructor exists simple trivial -// CHECK-NEXT: CopyAssignment simple trivial has_const_param -// CHECK-NEXT: MoveAssignment exists simple trivial -// CHECK-NEXT: Destructor simple irrelevant trivial - - class A { }; - class B { }; - class TestCXXRecordDecl : virtual A, public B { - int i; - }; -} -// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl -// CHECK-NEXT: DefinitionData{{$}} -// CHECK-NEXT: DefaultConstructor exists non_trivial -// CHECK-NEXT: CopyConstructor simple non_trivial has_const_param -// CHECK-NEXT: MoveConstructor exists simple non_trivial -// CHECK-NEXT: CopyAssignment simple non_trivial has_const_param -// CHECK-NEXT: MoveAssignment exists simple non_trivial -// CHECK-NEXT: Destructor simple irrelevant trivial -// CHECK-NEXT: virtual private 'A':'testCXXRecordDecl::A' -// CHECK-NEXT: public 'B':'testCXXRecordDecl::B' -// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl -// CHECK-NEXT: FieldDecl - -template -class TestCXXRecordDeclPack : public T... { -}; -// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack -// CHECK: public 'T'... -// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack - -thread_local int TestThreadLocalInt; -// CHECK: TestThreadLocalInt {{.*}} tls_dynamic - -class testCXXMethodDecl { - virtual void TestCXXMethodDeclPure() = 0; - void TestCXXMethodDeclDelete() = delete; - void TestCXXMethodDeclThrow() throw(); - void TestCXXMethodDeclThrowType() throw(int); -}; -// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPure 'void ()' virtual pure -// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclDelete 'void ()' delete -// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrow 'void () throw()' -// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrowType 'void () throw(int)' - -namespace testCXXConstructorDecl { - class A { }; - class TestCXXConstructorDecl : public A { - int I; - TestCXXConstructorDecl(A &a, int i) : A(a), I(i) { } - TestCXXConstructorDecl(A &a) : TestCXXConstructorDecl(a, 0) { } - }; -} -// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}' -// CHECK-NEXT: ParmVarDecl{{.*}} a -// CHECK-NEXT: ParmVarDecl{{.*}} i -// CHECK-NEXT: CXXCtorInitializer{{.*}}A -// CHECK-NEXT: Expr -// CHECK: CXXCtorInitializer{{.*}}I -// CHECK-NEXT: Expr -// CHECK: CompoundStmt -// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}' -// CHECK-NEXT: ParmVarDecl{{.*}} a -// CHECK-NEXT: CXXCtorInitializer{{.*}}TestCXXConstructorDecl -// CHECK-NEXT: CXXConstructExpr{{.*}}TestCXXConstructorDecl - -class TestCXXDestructorDecl { - ~TestCXXDestructorDecl() { } -}; -// CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void () noexcept' -// CHECK-NEXT: CompoundStmt - -// Test that the range of a defaulted members is computed correctly. -class TestMemberRanges { -public: - TestMemberRanges() = default; - TestMemberRanges(const TestMemberRanges &Other) = default; - TestMemberRanges(TestMemberRanges &&Other) = default; - ~TestMemberRanges() = default; - TestMemberRanges &operator=(const TestMemberRanges &Other) = default; - TestMemberRanges &operator=(TestMemberRanges &&Other) = default; -}; -void SomeFunction() { - TestMemberRanges A; - TestMemberRanges B(A); - B = A; - A = static_cast(B); - TestMemberRanges C(static_cast(A)); -} -// CHECK: CXXConstructorDecl{{.*}} -// CHECK: CXXConstructorDecl{{.*}} -// CHECK: CXXConstructorDecl{{.*}} -// CHECK: CXXDestructorDecl{{.*}} -// CHECK: CXXMethodDecl{{.*}} -// CHECK: CXXMethodDecl{{.*}} - -class TestCXXConversionDecl { - operator int() { return 0; } -}; -// CHECK: CXXConversionDecl{{.*}} operator int 'int ()' -// CHECK-NEXT: CompoundStmt - -namespace TestStaticAssertDecl { - static_assert(true, "msg"); -} -// CHECK: NamespaceDecl{{.*}} TestStaticAssertDecl -// CHECK-NEXT: StaticAssertDecl{{.*> .*$}} -// CHECK-NEXT: CXXBoolLiteralExpr -// CHECK-NEXT: StringLiteral - -namespace testFunctionTemplateDecl { - class A { }; - class B { }; - class C { }; - class D { }; - template void TestFunctionTemplate(T) { } - - // implicit instantiation - void bar(A a) { TestFunctionTemplate(a); } - - // explicit specialization - template<> void TestFunctionTemplate(B); - - // explicit instantiation declaration - extern template void TestFunctionTemplate(C); - - // explicit instantiation definition - template void TestFunctionTemplate(D); -} - // CHECK: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-14]]:3, col:55> col:29 TestFunctionTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T - // CHECK-NEXT: |-FunctionDecl 0x{{.+}} col:29 TestFunctionTemplate 'void (T)' - // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} col:51 'T' - // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} - // CHECK-NEXT: |-FunctionDecl 0x{{.+}} col:29 used TestFunctionTemplate 'void (testFunctionTemplateDecl::A)' - // CHECK-NEXT: | |-TemplateArgument type 'testFunctionTemplateDecl::A' - // CHECK-NEXT: | | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::A' - // CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'A' - // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} col:51 'testFunctionTemplateDecl::A':'testFunctionTemplateDecl::A' - // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} - // CHECK-NEXT: |-Function 0x{{.+}} 'TestFunctionTemplate' 'void (B)' - // CHECK-NEXT: |-FunctionDecl 0x{{.+}} col:29 TestFunctionTemplate 'void (testFunctionTemplateDecl::C)' - // CHECK-NEXT: | |-TemplateArgument type 'testFunctionTemplateDecl::C' - // CHECK-NEXT: | | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::C' - // CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'C' - // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:51 'testFunctionTemplateDecl::C':'testFunctionTemplateDecl::C' - // CHECK-NEXT: `-FunctionDecl 0x{{.+}} col:29 TestFunctionTemplate 'void (testFunctionTemplateDecl::D)' - // CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::D' - // CHECK-NEXT: | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::D' - // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'D' - // CHECK-NEXT: |-ParmVarDecl 0x{{.+}} col:51 'testFunctionTemplateDecl::D':'testFunctionTemplateDecl::D' - // CHECK-NEXT: `-CompoundStmt 0x{{.+}} - - // CHECK: FunctionDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-32]]:3, col:41> col:19 TestFunctionTemplate 'void (B)' - // CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::B' - // CHECK-NEXT: | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::B' - // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'B' - // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:41 'B':'testFunctionTemplateDecl::B' - - -namespace testClassTemplateDecl { - class A { }; - class B { }; - class C { }; - class D { }; - - template class TestClassTemplate { - public: - TestClassTemplate(); - ~TestClassTemplate(); - int j(); - int i; - }; - - // implicit instantiation - TestClassTemplate a; - - // explicit specialization - template<> class TestClassTemplate { - int j; - }; - - // explicit instantiation declaration - extern template class TestClassTemplate; - - // explicit instantiation definition - template class TestClassTemplate; - - // partial explicit specialization - template class TestClassTemplatePartial { - int i; - }; - template class TestClassTemplatePartial { - int j; - }; - - template struct TestTemplateDefaultType; - template struct TestTemplateDefaultType { }; - - template struct TestTemplateDefaultNonType; - template struct TestTemplateDefaultNonType { }; - - template class TT = TestClassTemplate> struct TestTemplateTemplateDefaultType; - template class TT> struct TestTemplateTemplateDefaultType { }; -} - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-40]]:3, line:[[@LINE-34]]:3> line:[[@LINE-40]]:30 TestClassTemplate -// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} line:[[@LINE-42]]:30 class TestClassTemplate definition -// CHECK-NEXT: | |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init -// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided -// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | | |-MoveConstructor -// CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | | |-MoveAssignment -// CHECK-NEXT: | | `-Destructor -// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} col:30 implicit referenced class TestClassTemplate -// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: | |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' -// CHECK-NEXT: | |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' -// CHECK-NEXT: | |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: | `-FieldDecl 0x{{.+}} col:9 i 'int' -// CHECK-NEXT: |-ClassTemplateSpecializationDecl 0x{{.+}} line:[[@LINE-56]]:30 class TestClassTemplate definition -// CHECK-NEXT: | |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init -// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided -// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param -// CHECK-NEXT: | | |-MoveConstructor -// CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | | |-MoveAssignment -// CHECK-NEXT: | | `-Destructor non_trivial user_declared -// CHECK-NEXT: | |-TemplateArgument type 'testClassTemplateDecl::A' -// CHECK-NEXT: | | `-RecordType 0{{.+}} 'testClassTemplateDecl::A' -// CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'A' -// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: | |-CXXConstructorDecl 0x{{.+}} col:5 used TestClassTemplate 'void ()' -// CHECK-NEXT: | |-CXXDestructorDecl 0x{{.+}} col:5 used ~TestClassTemplate 'void () noexcept' -// CHECK-NEXT: | |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: | |-FieldDecl 0x{{.+}} col:9 i 'int' -// CHECK-NEXT: | `-CXXConstructorDecl 0x{{.+}} col:30 implicit constexpr TestClassTemplate 'void (const testClassTemplateDecl::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} -// CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:30 'const testClassTemplateDecl::TestClassTemplate &' -// CHECK-NEXT: |-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' -// CHECK-NEXT: |-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' -// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' - -// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-67]]:3, line:[[@LINE-65]]:3> line:[[@LINE-67]]:20 class TestClassTemplate definition -// CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivial literal -// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit -// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit -// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::B' -// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::B' -// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'B' -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:20 implicit class TestClassTemplate -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' - -// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:{{.*}}:3, col:44> col:25 class TestClassTemplate definition -// CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init -// CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment -// CHECK-NEXT: | `-Destructor non_trivial user_declared -// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::C' -// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::C' -// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'C' -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' -// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} -// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' - -// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-91]]:3, col:37> col:18 class TestClassTemplate definition -// CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init -// CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment -// CHECK-NEXT: | `-Destructor non_trivial user_declared -// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D' -// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::D' -// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'D' -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' -// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} -// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-106]]:3, line:[[@LINE-104]]:3> line:[[@LINE-106]]:44 TestClassTemplatePartial -// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 -// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:34 typename depth 0 index 1 T2 -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} line:[[@LINE-109]]:44 class TestClassTemplatePartial definition -// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal -// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit -// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:44 implicit class TestClassTemplatePartial -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' - -// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-117]]:3, line:[[@LINE-115]]:3> line:[[@LINE-117]]:31 class TestClassTemplatePartial definition -// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal -// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit -// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit -// CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0' -// CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0 -// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::A' -// CHECK-NEXT: | `-RecordType 0x{{.+}} 'testClassTemplateDecl::A' -// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' -// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T1 -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplatePartial -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-130]]:3, col:37> col:37 TestTemplateDefaultType -// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T -// CHECK-NEXT: | `-TemplateArgument type 'int' -// CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int' -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:37 struct TestTemplateDefaultType - -// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-135]]:3, col:57> col:31 TestTemplateDefaultType -// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T -// CHECK-NEXT: | `-TemplateArgument type 'int' -// CHECK-NEXT: | |-inherited from TemplateTypeParm 0x{{.+}} 'T' -// CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int' -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 struct TestTemplateDefaultType definition -// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init -// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit -// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:31 implicit struct TestTemplateDefaultType - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-148]]:3, col:31> col:31 TestTemplateDefaultNonType -// CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} col:16 'int' depth 0 index 0 I -// CHECK-NEXT: | `-TemplateArgument expr -// CHECK-NEXT: | `-ConstantExpr 0x{{.+}} 'int' -// CHECK-NEXT: | |-value: Int 42 -// CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} 'int' 42 -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:31 struct TestTemplateDefaultNonType - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:{{.*}}:3, col:68> col:68 TestTemplateTemplateDefaultType -// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} col:37 depth 0 index 0 TT -// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} col:29 typename depth 1 index 0 -// CHECK-NEXT: | `-TemplateArgument template TestClassTemplate -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:68 struct TestTemplateTemplateDefaultType - -// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:{{.*}}:3, col:82> col:48 TestTemplateTemplateDefaultType -// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} col:37 depth 0 index 0 TT -// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} col:29 typename depth 1 index 0 -// CHECK-NEXT: | `-TemplateArgument template TestClassTemplate -// CHECK-NEXT: | `-inherited from TemplateTemplateParm 0x{{.+}} 'TT' -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:48 struct TestTemplateTemplateDefaultType definition -// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init -// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param -// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit -// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:48 implicit struct TestTemplateTemplateDefaultType - - -// PR15220 dump instantiation only once -namespace testCanonicalTemplate { - class A {}; - - template void TestFunctionTemplate(T); - template void TestFunctionTemplate(T); - void bar(A a) { TestFunctionTemplate(a); } - // CHECK: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-3]]:3, col:51> col:29 TestFunctionTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T - // CHECK-NEXT: |-FunctionDecl 0x{{.*}} col:29 TestFunctionTemplate 'void (T)' - // CHECK-NEXT: | `-ParmVarDecl 0x{{.*}} col:51 'T' - // CHECK-NEXT: `-FunctionDecl 0x{{.*}} col:29 used TestFunctionTemplate 'void (testCanonicalTemplate::A)' - // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' - // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' - // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' - // CHECK-NEXT: `-ParmVarDecl 0x{{.*}} col:51 'testCanonicalTemplate::A':'testCanonicalTemplate::A' - - // CHECK: FunctionTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-12]]:3, col:51> col:29 TestFunctionTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T - // CHECK-NEXT: |-FunctionDecl{{.*}} 0x{{.+}} prev 0x{{.+}} col:29 TestFunctionTemplate 'void (T)' - // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:51 'T' - // CHECK-NEXT: `-Function 0x{{.+}} 'TestFunctionTemplate' 'void (testCanonicalTemplate::A)' - // CHECK-NOT: TemplateArgument - - template class TestClassTemplate { - template friend class TestClassTemplate; - }; - TestClassTemplate a; - // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-4]]:3, line:[[@LINE-2]]:3> line:[[@LINE-4]]:31 TestClassTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} line:[[@LINE-6]]:31 class TestClassTemplate definition - // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init - // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr - // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param - // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param - // CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit - // CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit - // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplate - // CHECK-NEXT: | `-FriendDecl 0x{{.+}} col:40 - // CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} parent 0x{{.+}} col:40 TestClassTemplate - // CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} col:23 typename depth 1 index 0 T2 - // CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} col:40 class TestClassTemplate - // CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} line:[[@LINE-19]]:31 class TestClassTemplate definition - // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init - // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr - // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param - // CHECK-NEXT: | |-MoveConstructor exists simple trivial - // CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param - // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit - // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit - // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' - // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' - // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplate - // CHECK-NEXT: |-FriendDecl 0x{{.+}} col:40 - // CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:40 TestClassTemplate - // CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} col:23 typename depth 0 index 0 T2 - // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:40 class TestClassTemplate - // CHECK-NEXT: | `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' - // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit used constexpr TestClassTemplate 'void () noexcept' inline default trivial - // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} - // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit constexpr TestClassTemplate 'void (const testCanonicalTemplate::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} - // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:31 'const testCanonicalTemplate::TestClassTemplate &' - // CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} col:31 implicit constexpr TestClassTemplate 'void (testCanonicalTemplate::TestClassTemplate &&)' inline default trivial noexcept-unevaluated 0x{{.+}} - // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:31 'testCanonicalTemplate::TestClassTemplate &&' - - - template class TestClassTemplate2; - template class TestClassTemplate2; - template class TestClassTemplate2 { - }; - TestClassTemplate2 a2; - // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-5]]:3, col:31> col:31 TestClassTemplate2 - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 class TestClassTemplate2 - // CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} line:[[@LINE-6]]:31 class TestClassTemplate2 definition - // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init - // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr - // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param - // CHECK-NEXT: | |-MoveConstructor exists simple trivial - // CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param - // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit - // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit - // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' - // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' - // CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A' - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplate2 - // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit used constexpr TestClassTemplate2 'void () noexcept' inline default trivial - // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} - // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:31 implicit constexpr TestClassTemplate2 'void (const testCanonicalTemplate::TestClassTemplate2 &)' inline default trivial noexcept-unevaluated 0x{{.+}} - // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} col:31 'const testCanonicalTemplate::TestClassTemplate2 &' - // CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} col:31 implicit constexpr TestClassTemplate2 'void (testCanonicalTemplate::TestClassTemplate2 &&)' inline default trivial noexcept-unevaluated 0x{{.+}} - // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:31 'testCanonicalTemplate::TestClassTemplate2 &&' - - // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-26]]:3, col:31> col:31 TestClassTemplate2 - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 class TestClassTemplate2 - // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate2' - - // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-30]]:3, line:[[@LINE-29]]:3> line:[[@LINE-30]]:31 TestClassTemplate2 - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 - // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} line:[[@LINE-32]]:31 class TestClassTemplate2 definition - // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init - // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr - // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param - // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param - // CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit - // CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit - // CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplate2 - // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate2' - - struct S { - template static const T TestVarTemplate; // declaration of a static data member template - }; - template - const T S::TestVarTemplate = { }; // definition of a static data member template - - void f() - { - int i = S::TestVarTemplate; - int j = S::TestVarTemplate; - } - - // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-11]]:7, col:43> col:43 TestVarTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:25 referenced typename depth 0 index 0 T - // CHECK-NEXT: |-VarDecl 0x{{.+}} col:43 TestVarTemplate 'const T' static - // CHECK-NEXT: |-VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:14 referenced TestVarTemplate 'const int':'const int' cinit - // CHECK-NEXT: | |-TemplateArgument type 'int' - // CHECK-NEXT: | | `-BuiltinType 0x{{.+}} 'int' - // CHECK-NEXT: | `-InitListExpr 0x{{.+}} 'int':'int' - // CHECK-NEXT: `-VarTemplateSpecializationDecl 0x{{.+}} col:43 referenced TestVarTemplate 'const int':'const int' static - // CHECK-NEXT: `-TemplateArgument type 'int' - - // CHECK: VarTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-21]]:28, col:43> col:43 referenced TestVarTemplate 'const int':'const int' static - // CHECK-NEXT:`-TemplateArgument type 'int' - // CHECK-NEXT: `-BuiltinType 0x{{.+}} 'int' - - // CHECK: VarTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-23]]:3, line:[[@LINE-22]]:34> col:14 TestVarTemplate - // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T - // CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} col:14 TestVarTemplate 'const T' cinit - // CHECK-NEXT: | `-InitListExpr 0x{{.+}} 'void' - // CHECK-NEXT: |-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int':'const int' - // CHECK-NEXT: `-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int':'const int' - - // CHECK: VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-29]]:3, col:34> col:14 referenced TestVarTemplate 'const int':'const int' cinit - // CHECK-NEXT: |-TemplateArgument type 'int' - // CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int' - // CHECK-NEXT: `-InitListExpr 0x{{.+}} 'int':'int' -} - -template -class TestClassScopeFunctionSpecialization { - template void foo(U a) { } - template<> void foo(int a) { } -}; -// CHECK: ClassScopeFunctionSpecializationDecl -// CHECK-NEXT: CXXMethod{{.*}} foo 'void (int)' -// CHECK-NEXT: ParmVarDecl -// CHECK-NEXT: CompoundStmt -// CHECK-NEXT: TemplateArgument{{.*}} 'int' - -namespace TestTemplateTypeParmDecl { - template void foo(); -} -// CHECK: NamespaceDecl{{.*}} TestTemplateTypeParmDecl -// CHECK-NEXT: FunctionTemplateDecl -// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename depth 0 index 0 ... T -// CHECK-NEXT: TemplateTypeParmDecl{{.*}} class depth 0 index 1 U -// CHECK-NEXT: TemplateArgument type 'int' - -namespace TestNonTypeTemplateParmDecl { - template void foo(); -} -// CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl -// CHECK-NEXT: FunctionTemplateDecl -// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I -// CHECK-NEXT: TemplateArgument expr -// CHECK-NEXT: ConstantExpr{{.*}} 'int' -// CHECK-NEXT: value: Int 1 -// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 -// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J - -namespace TestTemplateTemplateParmDecl { - template class A; - template