| // RUN: %clang_cc1 -std=c++11 -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -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 'class 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<typename T> class A; |
| template<typename T> using TestTypeAliasTemplateDecl = A<T>; |
| } |
| // CHECK: TypeAliasTemplateDecl{{.*}} TestTypeAliasTemplateDecl |
| // CHECK-NEXT: TemplateTypeParmDecl |
| // CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A<T>' |
| |
| namespace testCXXRecordDecl { |
| class A { }; |
| class B { }; |
| class TestCXXRecordDecl : virtual A, public B { |
| int i; |
| }; |
| } |
| // CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl |
| // CHECK-NEXT: virtual private 'class testCXXRecordDecl::A' |
| // CHECK-NEXT: public 'class testCXXRecordDecl::B' |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl |
| // CHECK-NEXT: FieldDecl |
| |
| template<class...T> |
| class TestCXXRecordDeclPack : public T... { |
| }; |
| // CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack |
| // CHECK-NEXT: public 'T'... |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack |
| |
| __module_private__ class TestCXXRecordDeclPrivate; |
| // CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPrivate __module_private__ |
| |
| class testCXXMethodDecl { |
| __module_private__ void TestCXXMethodDeclPrivate(); |
| virtual void TestCXXMethodDeclPure() = 0; |
| void TestCXXMethodDeclDelete() = delete; |
| void TestCXXMethodDeclThrow() throw(); |
| void TestCXXMethodDeclThrowType() throw(int); |
| }; |
| // CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPrivate 'void (void)' __module_private__ |
| // CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPure 'void (void)' virtual pure |
| // CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclDelete 'void (void)' delete |
| // CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrow 'void (void) throw()' |
| // CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrowType 'void (void) throw(int)' |
| |
| namespace testCXXConstructorDecl { |
| class A { }; |
| class TestCXXConstructorDecl : public A { |
| int I; |
| TestCXXConstructorDecl(A &a, int i) : A(a), I(i) { } |
| }; |
| } |
| // 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 |
| |
| class TestCXXDestructorDecl { |
| ~TestCXXDestructorDecl() { } |
| }; |
| // CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void (void) noexcept' |
| // CHECK-NEXT: CompoundStmt |
| |
| class TestCXXConversionDecl { |
| operator int() { return 0; } |
| }; |
| // CHECK: CXXConversionDecl{{.*}} operator int 'int (void)' |
| // 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<typename T> 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{{.*}} TestFunctionTemplate |
| // CHECK-NEXT: TemplateTypeParmDecl |
| // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)' |
| // CHECK-NEXT: ParmVarDecl{{.*}} 'T' |
| // CHECK-NEXT: CompoundStmt |
| // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A |
| // CHECK-NEXT: TemplateArgument |
| // CHECK-NEXT: ParmVarDecl |
| // CHECK-NEXT: CompoundStmt |
| // CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' {{.*}}B |
| // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}C |
| // CHECK-NEXT: TemplateArgument |
| // CHECK-NEXT: ParmVarDecl |
| // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}D |
| // CHECK-NEXT: TemplateArgument |
| // CHECK-NEXT: ParmVarDecl |
| // CHECK-NEXT: CompoundStmt |
| // CHECK: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}B |
| // CHECK-NEXT: TemplateArgument |
| // CHECK-NEXT: ParmVarDecl |
| |
| namespace testClassTemplateDecl { |
| class A { }; |
| class B { }; |
| class C { }; |
| class D { }; |
| |
| template<typename T> class TestClassTemplate { |
| int i; |
| }; |
| |
| // implicit instantiation |
| TestClassTemplate<A> a; |
| |
| // explicit specialization |
| template<> class TestClassTemplate<B> { |
| int j; |
| }; |
| |
| // explicit instantiation declaration |
| extern template class TestClassTemplate<C>; |
| |
| // explicit instantiation definition |
| template class TestClassTemplate<D>; |
| |
| // partial explicit specialization |
| template<typename T1, typename T2> class TestClassTemplatePartial { |
| int i; |
| }; |
| template<typename T1> class TestClassTemplatePartial<T1, A> { |
| int j; |
| }; |
| } |
| // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate |
| // CHECK-NEXT: TemplateTypeParmDecl |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: FieldDecl{{.*}} i |
| // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: TemplateArgument{{.*}}A |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: FieldDecl{{.*}} i |
| // CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' |
| // CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' |
| // CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' |
| |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: TemplateArgument{{.*}}B |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: FieldDecl{{.*}} j |
| |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: TemplateArgument{{.*}}C |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: FieldDecl{{.*}} i |
| |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: TemplateArgument{{.*}}D |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate |
| // CHECK-NEXT: FieldDecl{{.*}} i |
| |
| // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial |
| // CHECK-NEXT: TemplateArgument |
| // CHECK-NEXT: TemplateArgument{{.*}}A |
| // CHECK-NEXT: TemplateTypeParmDecl |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial |
| // CHECK-NEXT: FieldDecl{{.*}} j |
| |
| template <class T> |
| class TestClassScopeFunctionSpecialization { |
| template<class U> void foo(U a) { } |
| template<> void foo<int>(int a) { } |
| }; |
| // CHECK: ClassScopeFunctionSpecializationDecl |
| // CHECK-NEXT: CXXMethod{{.*}} 'foo' 'void (int)' |
| // CHECK-NEXT: TemplateArgument{{.*}} 'int' |
| |
| namespace TestTemplateTypeParmDecl { |
| template<typename ... T, class U = int> void foo(); |
| } |
| // CHECK: NamespaceDecl{{.*}} TestTemplateTypeParmDecl |
| // CHECK-NEXT: FunctionTemplateDecl |
| // CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename ... T |
| // CHECK-NEXT: TemplateTypeParmDecl{{.*}} class U 'int' |
| |
| namespace TestNonTypeTemplateParmDecl { |
| template<int I = 1, int ... J> void foo(); |
| } |
| // CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl |
| // CHECK-NEXT: FunctionTemplateDecl |
| // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' I |
| // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 |
| // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' ... J |
| |
| namespace TestTemplateTemplateParmDecl { |
| template<typename T> class A; |
| template <template <typename> class T = A, template <typename> class ... U> void foo(); |
| } |
| // CHECK: NamespaceDecl{{.*}} TestTemplateTemplateParmDecl |
| // CHECK: FunctionTemplateDecl |
| // CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T |
| // CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename |
| // CHECK-NEXT: TemplateArgument{{.*}} template A |
| // CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U |
| // CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename |
| |
| namespace TestTemplateArgument { |
| template<typename> class A { }; |
| template<template<typename> class ...> class B { }; |
| int foo(); |
| |
| template<typename> class testType { }; |
| template class testType<int>; |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class testType |
| // CHECK-NEXT: TemplateArgument{{.*}} type 'int' |
| |
| template<int fp(void)> class testDecl { }; |
| template class testDecl<foo>; |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl |
| // CHECK-NEXT: TemplateArgument{{.*}} decl |
| // CHECK-NEXT: Function{{.*}}foo |
| |
| template class testDecl<nullptr>; |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl |
| // CHECK-NEXT: TemplateArgument{{.*}} nullptr |
| |
| template<int> class testIntegral { }; |
| template class testIntegral<1>; |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral |
| // CHECK-NEXT: TemplateArgument{{.*}} integral 1 |
| |
| template<template<typename> class> class testTemplate { }; |
| template class testTemplate<A>; |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate |
| // CHECK-NEXT: TemplateArgument{{.*}} A |
| |
| template<template<typename> class ...T> class C { |
| B<T...> testTemplateExpansion; |
| }; |
| // FIXME: Need TemplateSpecializationType dumping to test TemplateExpansion. |
| |
| template<int, int = 0> class testExpr; |
| template<int I> class testExpr<I> { }; |
| // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr |
| // CHECK-NEXT: TemplateArgument{{.*}} expr |
| // CHECK-NEXT: DeclRefExpr{{.*}}I |
| |
| template<int, int ...> class testPack { }; |
| template class testPack<0, 1, 2>; |
| // CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack |
| // CHECK-NEXT: TemplateArgument{{.*}} integral 0 |
| // CHECK-NEXT: TemplateArgument{{.*}} pack |
| // CHECK-NEXT: TemplateArgument{{.*}} integral 1 |
| // CHECK-NEXT: TemplateArgument{{.*}} integral 2 |
| } |
| |
| namespace testUsingDecl { |
| int i; |
| } |
| namespace TestUsingDecl { |
| using testUsingDecl::i; |
| } |
| // CHECK: NamespaceDecl{{.*}} TestUsingDecl |
| // CHECK-NEXT: UsingDecl{{.*}} testUsingDecl::i |
| // CHECK-NEXT: UsingShadowDecl{{.*}} Var{{.*}} 'i' 'int' |
| |
| namespace testUnresolvedUsing { |
| class A { }; |
| template<class T> class B { |
| public: |
| A a; |
| }; |
| template<class T> class TestUnresolvedUsing : public B<T> { |
| using typename B<T>::a; |
| using B<T>::a; |
| }; |
| } |
| // CHECK: CXXRecordDecl{{.*}} TestUnresolvedUsing |
| // CHECK: UnresolvedUsingTypenameDecl{{.*}} B<T>::a |
| // CHECK: UnresolvedUsingValueDecl{{.*}} B<T>::a |
| |
| namespace TestLinkageSpecDecl { |
| extern "C" void test1(); |
| extern "C++" void test2(); |
| } |
| // CHECK: NamespaceDecl{{.*}} TestLinkageSpecDecl |
| // CHECK-NEXT: LinkageSpecDecl{{.*}} C |
| // CHECK-NEXT: FunctionDecl |
| // CHECK-NEXT: LinkageSpecDecl{{.*}} C++ |
| // CHECK-NEXT: FunctionDecl |
| |
| class TestAccessSpecDecl { |
| public: |
| private: |
| protected: |
| }; |
| // CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl |
| // CHECK-NEXT: CXXRecordDecl{{.*}} class TestAccessSpecDecl |
| // CHECK-NEXT: AccessSpecDecl{{.*}} public |
| // CHECK-NEXT: AccessSpecDecl{{.*}} private |
| // CHECK-NEXT: AccessSpecDecl{{.*}} protected |
| |
| template<typename T> class TestFriendDecl { |
| friend int foo(); |
| friend class A; |
| friend T; |
| }; |
| // CHECK: CXXRecord{{.*}} TestFriendDecl |
| // CHECK-NEXT: CXXRecord{{.*}} TestFriendDecl |
| // CHECK-NEXT: FriendDecl |
| // CHECK-NEXT: FunctionDecl{{.*}} foo |
| // CHECK-NEXT: FriendDecl{{.*}} 'class A':'class A' |
| // CHECK-NEXT: FriendDecl{{.*}} 'T' |
| |
| namespace TestFileScopeAsmDecl { |
| asm("ret"); |
| } |
| // CHECK: NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}} |
| // CHECK: FileScopeAsmDecl{{.*>$}} |
| // CHECK-NEXT: StringLiteral |