From: Richard Smith Date: Fri, 22 Sep 2017 00:11:15 +0000 (+0000) Subject: Extend -ast-dump for CXXRecordDecl to dump the flags from the DefinitionData. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b5ac08821c0efb80531b9bcfdae8c2204e75ff9;p=clang Extend -ast-dump for CXXRecordDecl to dump the flags from the DefinitionData. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313943 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 1542f00ca7..e74aee0aaa 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -1376,6 +1376,128 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { if (!D->isCompleteDefinition()) return; + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "DefinitionData"; + } +#define FLAG(fn, name) if (D->fn()) OS << " " #name; + FLAG(isParsingBaseSpecifiers, parsing_base_specifiers); + + FLAG(isGenericLambda, generic); + FLAG(isLambda, lambda); + + FLAG(canPassInRegisters, pass_in_registers); + FLAG(isEmpty, empty); + FLAG(isAggregate, aggregate); + FLAG(isStandardLayout, standard_layout); + FLAG(isTriviallyCopyable, trivially_copyable); + FLAG(isPOD, pod); + FLAG(isTrivial, trivial); + FLAG(isPolymorphic, polymorphic); + FLAG(isAbstract, abstract); + FLAG(isLiteral, literal); + + FLAG(hasUserDeclaredConstructor, has_user_declared_ctor); + FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor); + FLAG(hasMutableFields, has_mutable_fields); + FLAG(hasVariantMembers, has_variant_members); + FLAG(allowConstDefaultInit, can_const_default_init); + + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "DefaultConstructor"; + } + FLAG(hasDefaultConstructor, exists); + FLAG(hasTrivialDefaultConstructor, trivial); + FLAG(hasNonTrivialDefaultConstructor, non_trivial); + FLAG(hasUserProvidedDefaultConstructor, user_provided); + FLAG(hasConstexprDefaultConstructor, constexpr); + FLAG(needsImplicitDefaultConstructor, needs_implicit); + FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr); + }); + + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "CopyConstructor"; + } + FLAG(hasSimpleCopyConstructor, simple); + FLAG(hasTrivialCopyConstructor, trivial); + FLAG(hasNonTrivialCopyConstructor, non_trivial); + FLAG(hasUserDeclaredCopyConstructor, user_declared); + FLAG(hasCopyConstructorWithConstParam, has_const_param); + FLAG(needsImplicitCopyConstructor, needs_implicit); + FLAG(needsOverloadResolutionForCopyConstructor, + needs_overload_resolution); + if (!D->needsOverloadResolutionForCopyConstructor()) + FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted); + FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param); + }); + + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "MoveConstructor"; + } + FLAG(hasMoveConstructor, exists); + FLAG(hasSimpleMoveConstructor, simple); + FLAG(hasTrivialMoveConstructor, trivial); + FLAG(hasNonTrivialMoveConstructor, non_trivial); + FLAG(hasUserDeclaredMoveConstructor, user_declared); + FLAG(needsImplicitMoveConstructor, needs_implicit); + FLAG(needsOverloadResolutionForMoveConstructor, + needs_overload_resolution); + if (!D->needsOverloadResolutionForMoveConstructor()) + FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted); + }); + + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "CopyAssignment"; + } + FLAG(hasTrivialCopyAssignment, trivial); + FLAG(hasNonTrivialCopyAssignment, non_trivial); + FLAG(hasCopyAssignmentWithConstParam, has_const_param); + FLAG(hasUserDeclaredCopyAssignment, user_declared); + FLAG(needsImplicitCopyAssignment, needs_implicit); + FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution); + FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param); + }); + + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "MoveAssignment"; + } + FLAG(hasMoveAssignment, exists); + FLAG(hasSimpleMoveAssignment, simple); + FLAG(hasTrivialMoveAssignment, trivial); + FLAG(hasNonTrivialMoveAssignment, non_trivial); + FLAG(hasUserDeclaredMoveAssignment, user_declared); + FLAG(needsImplicitMoveAssignment, needs_implicit); + FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution); + }); + + dumpChild([=] { + { + ColorScope Color(*this, DeclKindNameColor); + OS << "Destructor"; + } + FLAG(hasSimpleDestructor, simple); + FLAG(hasIrrelevantDestructor, irrelevant); + FLAG(hasTrivialDestructor, trivial); + FLAG(hasNonTrivialDestructor, non_trivial); + FLAG(hasUserDeclaredDestructor, user_declared); + FLAG(needsImplicitDestructor, needs_implicit); + FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution); + if (!D->needsOverloadResolutionForDestructor()) + FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted); + }); + }); + for (const auto &I : D->bases()) { dumpChild([=] { if (I.isVirtual()) diff --git a/test/Frontend/float16.cpp b/test/Frontend/float16.cpp index 31d24bfe54..febd6b8e36 100644 --- a/test/Frontend/float16.cpp +++ b/test/Frontend/float16.cpp @@ -111,7 +111,7 @@ public: }; //CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition -//CHECK-NEXT: | |-CXXRecordDecl {{.*}} implicit referenced class C1 +//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1 //CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16' //CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static //CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16' @@ -179,7 +179,7 @@ template struct S1 { //CHECK: |-ClassTemplateDecl {{.*}} S1 //CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C //CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition -//CHECK-NEXT: | | |-CXXRecordDecl {{.*}} implicit struct S1 +//CHECK: | | |-CXXRecordDecl {{.*}} implicit struct S1 //CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C' //CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1' diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp index a48261d367..0df8a5a2b8 100644 --- a/test/Misc/ast-dump-decl.cpp +++ b/test/Misc/ast-dump-decl.cpp @@ -73,6 +73,16 @@ namespace testTypeAliasTemplateDecl { // 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 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 { @@ -80,6 +90,13 @@ namespace testCXXRecordDecl { }; } // 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 non_trivial has_const_param +// CHECK-NEXT: MoveAssignment exists simple non_trivial +// CHECK-NEXT: Destructor simple irrelevant trivial // CHECK-NEXT: virtual private 'class testCXXRecordDecl::A' // CHECK-NEXT: public 'class testCXXRecordDecl::B' // CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl @@ -89,7 +106,7 @@ template class TestCXXRecordDeclPack : public T... { }; // CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack -// CHECK-NEXT: public 'T'... +// CHECK: public 'T'... // CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack thread_local int TestThreadLocalInt; @@ -250,14 +267,14 @@ namespace testClassTemplateDecl { // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate // CHECK-NEXT: TemplateTypeParmDecl // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate -// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: AccessSpecDecl{{.*}} public // CHECK-NEXT: CXXConstructorDecl{{.*}} // CHECK-NEXT: CXXDestructorDecl{{.*}} // CHECK-NEXT: CXXMethodDecl{{.*}} // CHECK-NEXT: FieldDecl{{.*}} i // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate -// CHECK-NEXT: TemplateArgument{{.*}}A +// CHECK: TemplateArgument{{.*}}A // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: AccessSpecDecl{{.*}} public // CHECK-NEXT: CXXConstructorDecl{{.*}} @@ -269,12 +286,13 @@ namespace testClassTemplateDecl { // CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate -// CHECK-NEXT: TemplateArgument{{.*}}B +// CHECK-NEXT: DefinitionData +// CHECK: TemplateArgument{{.*}}B // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: FieldDecl{{.*}} j // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate -// CHECK-NEXT: TemplateArgument{{.*}}C +// CHECK: TemplateArgument{{.*}}C // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: AccessSpecDecl{{.*}} public // CHECK-NEXT: CXXConstructorDecl{{.*}} @@ -283,7 +301,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: FieldDecl{{.*}} i // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate -// CHECK-NEXT: TemplateArgument{{.*}}D +// CHECK: TemplateArgument{{.*}}D // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: AccessSpecDecl{{.*}} public // CHECK-NEXT: CXXConstructorDecl{{.*}} @@ -292,7 +310,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: FieldDecl{{.*}} i // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial -// CHECK-NEXT: TemplateArgument +// CHECK: TemplateArgument // CHECK-NEXT: TemplateArgument{{.*}}A // CHECK-NEXT: TemplateTypeParmDecl // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial @@ -326,13 +344,13 @@ namespace testCanonicalTemplate { // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate // CHECK-NEXT: TemplateTypeParmDecl // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate - // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate + // CHECK: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: FriendDecl // CHECK-NEXT: ClassTemplateDecl{{.*}} TestClassTemplate // CHECK-NEXT: TemplateTypeParmDecl // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate - // CHECK-NEXT: TemplateArgument{{.*}}A + // CHECK: TemplateArgument{{.*}}A // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate } @@ -384,27 +402,27 @@ namespace TestTemplateArgument { template class testType { }; template class testType; // CHECK: ClassTemplateSpecializationDecl{{.*}} class testType - // CHECK-NEXT: TemplateArgument{{.*}} type 'int' + // CHECK: TemplateArgument{{.*}} type 'int' template class testDecl { }; template class testDecl; // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl - // CHECK-NEXT: TemplateArgument{{.*}} decl + // CHECK: TemplateArgument{{.*}} decl // CHECK-NEXT: Function{{.*}}foo template class testDecl; // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl - // CHECK-NEXT: TemplateArgument{{.*}} nullptr + // CHECK: TemplateArgument{{.*}} nullptr template class testIntegral { }; template class testIntegral<1>; // CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral - // CHECK-NEXT: TemplateArgument{{.*}} integral 1 + // CHECK: TemplateArgument{{.*}} integral 1 template class> class testTemplate { }; template class testTemplate; // CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate - // CHECK-NEXT: TemplateArgument{{.*}} A + // CHECK: TemplateArgument{{.*}} A template class ...T> class C { B testTemplateExpansion; @@ -414,13 +432,13 @@ namespace TestTemplateArgument { template class testExpr; template class testExpr { }; // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr - // CHECK-NEXT: TemplateArgument{{.*}} expr + // CHECK: TemplateArgument{{.*}} expr // CHECK-NEXT: DeclRefExpr{{.*}}I template class testPack { }; template class testPack<0, 1, 2>; // CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack - // CHECK-NEXT: TemplateArgument{{.*}} integral 0 + // CHECK: TemplateArgument{{.*}} integral 0 // CHECK-NEXT: TemplateArgument{{.*}} pack // CHECK-NEXT: TemplateArgument{{.*}} integral 1 // CHECK-NEXT: TemplateArgument{{.*}} integral 2 @@ -467,7 +485,7 @@ private: protected: }; // CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl -// CHECK-NEXT: CXXRecordDecl{{.*}} class TestAccessSpecDecl +// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl // CHECK-NEXT: AccessSpecDecl{{.*}} public // CHECK-NEXT: AccessSpecDecl{{.*}} private // CHECK-NEXT: AccessSpecDecl{{.*}} protected @@ -478,7 +496,7 @@ template class TestFriendDecl { friend T; }; // CHECK: CXXRecord{{.*}} TestFriendDecl -// CHECK-NEXT: CXXRecord{{.*}} TestFriendDecl +// CHECK: CXXRecord{{.*}} TestFriendDecl // CHECK-NEXT: FriendDecl // CHECK-NEXT: FunctionDecl{{.*}} foo // CHECK-NEXT: FriendDecl{{.*}} 'class A':'class A' diff --git a/test/Misc/ast-dump-invalid.cpp b/test/Misc/ast-dump-invalid.cpp index aa6cd52692..842b057a4a 100644 --- a/test/Misc/ast-dump-invalid.cpp +++ b/test/Misc/ast-dump-invalid.cpp @@ -51,7 +51,7 @@ double Str::foo1(double, invalid_type) } // CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl // CHECK-NEXT: |-CXXRecordDecl {{.*}} line:46:8 struct Str definition -// CHECK-NEXT: | |-CXXRecordDecl {{.*}} col:8 implicit struct Str +// CHECK: | |-CXXRecordDecl {{.*}} col:8 implicit struct Str // CHECK-NEXT: | `-CXXMethodDecl {{.*}} col:11 invalid foo1 'double (double, int)' // CHECK-NEXT: | |-ParmVarDecl {{.*}} col:22 'double' // CHECK-NEXT: | `-ParmVarDecl {{.*}} > col:36 invalid 'int' diff --git a/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp b/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp index b7741343ad..18dfb43a38 100644 --- a/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp +++ b/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp @@ -44,9 +44,9 @@ struct testStructRecord { int testStructRecordField; }; // CHECK-RECORD: CXXRecordDecl{{.*}} testStructRecord -// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-RECORD: AnnotateAttr{{.*}} "test" // CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testStructRecord -// CHECK-RECORD_UNLESS_IS_UNION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-RECORD_UNLESS_IS_UNION: AnnotateAttr{{.*}} "test" // CHECK-FIELD: FieldDecl{{.*}} testStructRecordField // CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test" @@ -54,9 +54,9 @@ class testClassRecord { int testClassRecordField; }; // CHECK-RECORD: CXXRecordDecl{{.*}} testClassRecord -// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-RECORD: AnnotateAttr{{.*}} "test" // CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testClassRecord -// CHECK-RECORD_UNLESS_IS_UNION-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-RECORD_UNLESS_IS_UNION: AnnotateAttr{{.*}} "test" // CHECK-FIELD: FieldDecl{{.*}} testClassRecordField // CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test" @@ -64,7 +64,7 @@ union testUnionRecord { int testUnionRecordField; }; // CHECK-RECORD: CXXRecordDecl{{.*}} testUnionRecord -// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test" +// CHECK-RECORD: AnnotateAttr{{.*}} "test" // CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testUnionRecord // CHECK-RECORD_UNLESS_IS_UNION-NOT: AnnotateAttr{{.*}} "test" // CHECK-FIELD: FieldDecl{{.*}} testUnionRecordField diff --git a/test/Misc/pragma-attribute-cxx.cpp b/test/Misc/pragma-attribute-cxx.cpp index c241c4e4bd..a8a3bdebc6 100644 --- a/test/Misc/pragma-attribute-cxx.cpp +++ b/test/Misc/pragma-attribute-cxx.cpp @@ -17,7 +17,7 @@ class testClass2 { testClass2 *operator -> (); }; // CHECK-LABEL: CXXRecordDecl{{.*}} testClass2 -// CHECK-NEXT: AnnotateAttr{{.*}} "test" +// CHECK: AnnotateAttr{{.*}} "test" // CHECK: CXXMethodDecl{{.*}} testMethod1 // CHECK-NEXT: ParmVarDecl{{.*}} param // CHECK-NEXT: AnnotateAttr{{.*}} "test" @@ -76,7 +76,7 @@ void testLambdaMethod() { // CHECK-LABEL: FunctionDecl{{.*}} testLambdaMethod // CHECK: LambdaExpr // CHECK-NEXT: CXXRecordDecl -// CHECK-NEXT: CXXMethodDecl{{.*}} operator() +// CHECK: CXXMethodDecl{{.*}} operator() // CHECK-NEXT: CompoundStmt // CHECK-NEXT: AnnotateAttr{{.*}} "test" diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp index 401b770490..25f8a99925 100644 --- a/test/Modules/cxx-templates.cpp +++ b/test/Modules/cxx-templates.cpp @@ -251,8 +251,22 @@ namespace Std { // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate // CHECK-DUMP-NEXT: TemplateArgument type 'char [2]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition +// CHECK-DUMP-NEXT: DefinitionData +// CHECK-DUMP-NEXT: DefaultConstructor +// CHECK-DUMP-NEXT: CopyConstructor +// CHECK-DUMP-NEXT: MoveConstructor +// CHECK-DUMP-NEXT: CopyAssignment +// CHECK-DUMP-NEXT: MoveAssignment +// CHECK-DUMP-NEXT: Destructor // CHECK-DUMP-NEXT: TemplateArgument type 'char [2]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate // CHECK-DUMP-NEXT: TemplateArgument type 'char [1]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition +// CHECK-DUMP-NEXT: DefinitionData +// CHECK-DUMP-NEXT: DefaultConstructor +// CHECK-DUMP-NEXT: CopyConstructor +// CHECK-DUMP-NEXT: MoveConstructor +// CHECK-DUMP-NEXT: CopyAssignment +// CHECK-DUMP-NEXT: MoveAssignment +// CHECK-DUMP-NEXT: Destructor // CHECK-DUMP-NEXT: TemplateArgument type 'char [1]' diff --git a/test/SemaTemplate/default-expr-arguments-3.cpp b/test/SemaTemplate/default-expr-arguments-3.cpp index 173609c045..4449eb7100 100644 --- a/test/SemaTemplate/default-expr-arguments-3.cpp +++ b/test/SemaTemplate/default-expr-arguments-3.cpp @@ -21,7 +21,7 @@ namespace PR28795 { } // CHECK: ClassTemplateSpecializationDecl {{.*}} struct class2 definition -// CHECK-NEXT: TemplateArgument type 'int' +// CHECK: TemplateArgument type 'int' // CHECK: LambdaExpr {{.*}} 'class (lambda at // CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit // CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo'