blob: 22b4e8fb1dec725ee4fafae455d4dca7757cffc6 [file] [edit]
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++20 -ast-dump=json %s | FileCheck --check-prefix=JSON %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++20 -ast-print %s > %t
// RUN: FileCheck < %t %s -check-prefix=CHECK1
// RUN: FileCheck < %t %s -check-prefix=CHECK2
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++20 -ast-dump %s | FileCheck --check-prefix=DUMP %s
// Test with serialization:
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++20 -emit-pch -o %t %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -x c++ -std=c++20 -include-pch %t \
// RUN: -ast-dump-all /dev/null \
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN: | FileCheck --strict-whitespace --check-prefix=DUMP %s
template <int X, typename Y, int Z = 5>
struct foo {
int constant;
foo() {}
Y getSum() { return Y(X + Z); }
};
template <int A, typename B>
B bar() {
return B(A);
}
void baz() {
int x = bar<5, int>();
int y = foo<5, int>().getSum();
double z = foo<2, double, 3>().getSum();
}
// Template definition - foo
// CHECK1: template <int X, typename Y, int Z = 5> struct foo {
// CHECK2: template <int X, typename Y, int Z = 5> struct foo {
// Template instantiation - foo
// Since the order of instantiation may vary during runs, run FileCheck twice
// to make sure each instantiation is in the correct spot.
// CHECK1: template<> struct foo<5, int, 5> {
// CHECK2: template<> struct foo<2, double, 3> {
// Template definition - bar
// CHECK1: template <int A, typename B> B bar()
// CHECK2: template <int A, typename B> B bar()
// Template instantiation - bar
// CHECK1: template<> int bar<5, int>()
// CHECK2: template<> int bar<5, int>()
// CHECK1-LABEL: template <typename ...T> struct A {
// CHECK1-NEXT: template <T ...x[3]> struct B {
template <typename ...T> struct A {
template <T ...x[3]> struct B {};
};
// CHECK1-LABEL: template <typename ...T> void f() {
// CHECK1-NEXT: A<T[3]...> a;
template <typename ...T> void f() {
A<T[3]...> a;
}
namespace test2 {
void func(int);
void func(float);
template<typename T>
void tmpl() {
func(T());
}
// DUMP: UnresolvedLookupExpr {{.*}} <col:3> '<overloaded function type>' lvalue (ADL) = 'func'
// JSON-LABEL: "name": "test2",
// JSON: "kind": "UnresolvedLookupExpr",
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: },
// JSON-NEXT: "end": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "<overloaded function type>"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "lvalue",
// JSON-NEXT: "usesADL": true,
// JSON-NEXT: "name": "func",
}
namespace test3 {
template<typename T> struct A {};
template<typename T> A(T) -> A<int>;
// CHECK1: template <typename T> A(T) -> A<int>;
}
namespace test4 {
template <unsigned X, auto A>
struct foo {
static void fn();
};
// Prints using an "integral" template argument. Test that this correctly
// includes the type for the auto argument and omits it for the fixed
// type/unsigned argument (see
// TemplateParameterList::shouldIncludeTypeForArgument)
// CHECK1: {{^ }}template<> struct foo<0, 0L> {
// CHECK1: {{^ }}void test(){{ }}{
// CHECK1: {{^ }}foo<0, 0 + 0L>::fn();
void test() {
foo<0, 0 + 0L>::fn();
}
// Prints using an "expression" template argument. This renders based on the way
// the user wrote the arguments (including that + expression) - so it's not
// powered by the shouldIncludeTypeForArgument functionality.
// Not sure if this it's intentional that these two specializations are rendered
// differently in this way.
// CHECK1: {{^ }}template<> struct foo<1, 0 + 0L> {
template struct foo<1, 0 + 0L>;
}
namespace test5 {
template<long> void f() {}
void (*p)() = f<0>;
template<unsigned = 0> void f() {}
void (*q)() = f<>;
// Not perfect - this code in the dump would be ambiguous, but it's the best we
// can do to differentiate these two implicit specializations.
// CHECK1: template<> void f<0L>()
// CHECK1: template<> void f<0U>()
}
namespace test6 {
template <class D>
constexpr bool C = true;
template <class Key>
void func() {
C<Key>;
// DUMP: UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'C'
// DUMP-NEXT: `-TemplateArgument type 'Key'
// DUMP-NEXT: `-TemplateTypeParmType {{.*}} 'Key' dependent depth 0 index 0
// DUMP-NEXT: `-TemplateTypeParm {{.*}} 'Key'
// JSON-LABEL: "name": "test6",
// JSON: "kind": "UnresolvedLookupExpr",
// JSON: "type": {
// JSON-NEXT: "qualType": "<dependent type>"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "lvalue",
// JSON-NEXT: "usesADL": false,
// JSON-NEXT: "name": "C",
// JSON-NEXT: "lookups": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "VarTemplateDecl",
// JSON-NEXT: "name": "C"
// JSON-NEXT: }
// JSON-NEXT: ],
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "Key"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "TemplateTypeParmType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "Key"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0,
// JSON-NEXT: "decl": {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON-NEXT: "name": "Key"
// JSON-NEXT: }
}
}
namespace test7 {
template <template<class> class TT> struct A {};
template <class...> class B {};
template struct A<B>;
// DUMP-LABEL: NamespaceDecl {{.*}} test7 external-linkage{{$}}
// DUMP: ClassTemplateDecl 0x{{.+}} A external-linkage{{$}}
// DUMP-NEXT: |-TemplateTemplateParmDecl
// DUMP-NEXT: | `-TemplateTypeParmDecl
// DUMP-NEXT: |-CXXRecordDecl 0x[[TEST7_PAT:[^ ]+]] {{.+}} struct A definition
// DUMP: ClassTemplateSpecializationDecl {{.*}} struct A definition external-linkage instantiated_from 0x[[TEST7_PAT]] explicit_instantiation_definition strict-pack-match{{$}}
// JSON-LABEL: "name": "test7",
// JSON: "kind": "ClassTemplateSpecializationDecl",
// JSON: "name": "A",
// JSON-NEXT: "tagUsed": "struct",
// JSON-NEXT: "completeDefinition": true,
// JSON-NEXT: "strict-pack-match": true,
} // namespce test7
namespace test8 {
template<_Complex int x>
struct pr126341;
template<>
struct pr126341<{1, 2}>;
// DUMP-LABEL: NamespaceDecl {{.*}} test8 external-linkage{{$}}
// DUMP-NEXT: |-ClassTemplateDecl {{.*}} pr126341
// DUMP: `-ClassTemplateSpecializationDecl {{.*}} pr126341
// DUMP: `-TemplateArgument structural value '1+2i'
// JSON-LABEL: "name": "test8",
// JSON: "kind": "ClassTemplateSpecializationDecl",
// JSON: "name": "pr126341",
// JSON-NEXT: "tagUsed": "struct",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "value": "1+2i"
} // namespace test8
namespace TestMemberPointerPartialSpec {
template <class> struct A;
template <class T1, class T2> struct A<T1 T2::*>;
// DUMP-LABEL: NamespaceDecl {{.+}} TestMemberPointerPartialSpec external-linkage{{$}}
// DUMP: ClassTemplatePartialSpecializationDecl {{.*}} struct A
// DUMP-NEXT: |-TemplateArgument type 'type-parameter-0-0 type-parameter-0-1::*'
// DUMP-NEXT: | `-MemberPointerType {{.+}} 'type-parameter-0-0 type-parameter-0-1::*' dependent
// DUMP-NEXT: | |-TemplateTypeParmType {{.+}} 'type-parameter-0-1' dependent depth 0 index 1
// DUMP-NEXT: | `-TemplateTypeParmType {{.+}} 'type-parameter-0-0' dependent depth 0 index 0
// JSON-LABEL: "name": "TestMemberPointerPartialSpec",
// JSON: "kind": "ClassTemplatePartialSpecializationDecl"
// JSON: "name": "A",
// JSON-NEXT: "tagUsed": "struct",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0 type-parameter-0-1::*"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "MemberPointerType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0 type-parameter-0-1::*"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "isData": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "TemplateTypeParmType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-1"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 1,
// JSON-NEXT: "decl": {
// JSON-NEXT: "id": "0x0"
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "TemplateTypeParmType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0,
// JSON-NEXT: "decl": {
// JSON-NEXT: "id": "0x0"
// JSON-NEXT: }
} // namespace TestMemberPointerPartialSpec
namespace TestDependentMemberPointer {
template <class U> struct A {
using X = int U::*;
using Y = int U::test::*;
using Z = int U::template V<int>::*;
};
// DUMP-LABEL: NamespaceDecl {{.+}} TestDependentMemberPointer external-linkage{{$}}
// DUMP: |-TypeAliasDecl {{.+}} X 'int U::*'{{$}}
// DUMP-NEXT: | `-MemberPointerType {{.+}} 'int U::*' dependent
// DUMP-NEXT: | |-TemplateTypeParmType {{.+}} 'U' dependent depth 0 index 0
// DUMP-NEXT: | | `-TemplateTypeParm {{.+}} 'U'
// DUMP-NEXT: | `-BuiltinType {{.+}} 'int'
// DUMP-NEXT: |-TypeAliasDecl {{.+}} Y 'int U::test::*'{{$}}
// DUMP-NEXT: | `-MemberPointerType {{.+}} 'int U::test::*' dependent
// DUMP-NEXT: | |-DependentNameType {{.+}} 'U::test' dependent
// DUMP-NEXT: | `-BuiltinType {{.+}} 'int'
// DUMP-NEXT: `-TypeAliasDecl {{.+}} Z 'int U::template V<int>::*'{{$}}
// DUMP-NEXT: `-MemberPointerType {{.+}} 'int U::template V<int>::*' dependent
// DUMP-NEXT: |-TemplateSpecializationType {{.+}} 'U::template V<int>' dependent
// DUMP-NEXT: | |-name: 'U::template V':'type-parameter-0-0::template V' dependent
// DUMP-NEXT: | | `-NestedNameSpecifier TypeSpec 'U'
// DUMP-NEXT: | `-TemplateArgument type 'int'
// DUMP-NEXT: `-BuiltinType {{.+}} 'int'
// JSON-LABEL: "name": "TestDependentMemberPointer"
// JSON: "kind": "TypeAliasDecl",
// JSON: "name": "X",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int U::*"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "MemberPointerType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int U::*"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "isData": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateTypeParmType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "U"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0,
// JSON-NEXT: "decl": {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON-NEXT: "name": "U"
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "BuiltinType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON: "kind": "TypeAliasDecl",
// JSON: "name": "Y",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int U::test::*"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "MemberPointerType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int U::test::*"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "isData": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "DependentNameType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "U::test"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "BuiltinType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON: "kind": "TypeAliasDecl",
// JSON: "name": "Z",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int U::template V<int>::*"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "MemberPointerType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int U::template V<int>::*"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "isData": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "U::template V<int>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "templateName": "U::template V",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "BuiltinType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "BuiltinType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: }
// JSON-NEXT: }
} // namespace TestDependentMemberPointer
namespace TestPartialSpecNTTP {
// DUMP-LABEL: NamespaceDecl {{.+}} TestPartialSpecNTTP external-linkage{{$}}
// JSON-LABEL: "name": "TestPartialSpecNTTP"
template <class TA1, bool TA2> struct Template1 {};
template <class TB1, bool TB2> struct Template2 {};
template <class U1, bool U2, bool U3>
struct Template2<Template1<U1, U2>, U3> {};
// DUMP: ClassTemplatePartialSpecializationDecl {{.+}} struct Template2
// DUMP: |-TemplateArgument type 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>'
// DUMP-NEXT: | `-TemplateSpecializationType {{.+}} 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>' dependent
// DUMP-NEXT: | |-name: 'TestPartialSpecNTTP::Template1'
// DUMP-NEXT: | | `-ClassTemplateDecl {{.+}} Template1
// DUMP-NEXT: | |-TemplateArgument type 'type-parameter-0-0'
// DUMP-NEXT: | | `-TemplateTypeParmType {{.+}} 'type-parameter-0-0' dependent depth 0 index 0
// DUMP-NEXT: | `-TemplateArgument expr canonical 'value-parameter-0-1'
// DUMP-NEXT: | `-DeclRefExpr {{.+}} 'bool' NonTypeTemplateParm {{.+}} 'U2' 'bool'
// DUMP-NEXT: |-TemplateArgument expr canonical 'value-parameter-0-2'
// DUMP-NEXT: | `-DeclRefExpr {{.+}} 'bool' NonTypeTemplateParm {{.+}} 'U3' 'bool'
// DUMP-NEXT: |-TemplateTypeParmDecl {{.+}} referenced class depth 0 index 0 U1
// DUMP-NEXT: |-NonTypeTemplateParmDecl {{.+}} referenced 'bool' depth 0 index 1 U2
// DUMP-NEXT: |-NonTypeTemplateParmDecl {{.+}} referenced 'bool' depth 0 index 2 U3
// DUMP-NEXT: `-CXXRecordDecl {{.+}} implicit struct Template2
// JSON: "kind": "ClassTemplatePartialSpecializationDecl",
// JSON: "name": "Template2",
// JSON: "tagUsed": "struct",
// JSON: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "templateName": "TestPartialSpecNTTP::Template1",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateTypeParmType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0,
// JSON-NEXT: "decl": {
// JSON-NEXT: "id": "0x0"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "isExpr": true,
// JSON-NEXT: "isCanonical": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "prvalue",
// JSON-NEXT: "referencedDecl": {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "name": "U2",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON: "kind": "TemplateArgument",
// JSON-NEXT: "isExpr": true,
// JSON-NEXT: "isCanonical": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "prvalue",
// JSON-NEXT: "referencedDecl": {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "name": "U3",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON: "isReferenced": true,
// JSON-NEXT: "name": "U1",
// JSON-NEXT: "tagUsed": "class",
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON: "isReferenced": true,
// JSON-NEXT: "name": "U2",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 1
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON: "isReferenced": true,
// JSON-NEXT: "name": "U3",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 2
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON: "isImplicit": true,
// JSON-NEXT: "name": "Template2",
// JSON-NEXT: "tagUsed": "struct"
// JSON-NEXT: }
// JSON-NEXT: ]
template <typename U1, bool U3, bool U2>
struct Template2<Template1<U1, U2>, U3> {};
// DUMP: ClassTemplatePartialSpecializationDecl {{.+}} struct Template2 definition external-linkage explicit_specialization
// DUMP: |-TemplateArgument type 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>'
// DUMP-NEXT: | `-TemplateSpecializationType {{.+}} 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>' dependent
// DUMP-NEXT: | |-name: 'TestPartialSpecNTTP::Template1'
// DUMP-NEXT: | | `-ClassTemplateDecl {{.+}} Template1
// DUMP-NEXT: | |-TemplateArgument type 'type-parameter-0-0'
// DUMP-NEXT: | | `-TemplateTypeParmType {{.+}} 'type-parameter-0-0' dependent depth 0 index 0
// DUMP-NEXT: | `-TemplateArgument expr canonical 'value-parameter-0-2'
// DUMP-NEXT: | `-DeclRefExpr {{.+}} 'bool' NonTypeTemplateParm {{.+}} 'U2' 'bool'
// DUMP-NEXT: |-TemplateArgument expr canonical 'value-parameter-0-1'
// DUMP-NEXT: | `-DeclRefExpr {{.+}} 'bool' NonTypeTemplateParm {{.+}} 'U3' 'bool'
// DUMP-NEXT: |-TemplateTypeParmDecl {{.+}} referenced typename depth 0 index 0 U1
// DUMP-NEXT: |-NonTypeTemplateParmDecl {{.+}} referenced 'bool' depth 0 index 1 U3
// DUMP-NEXT: |-NonTypeTemplateParmDecl {{.+}} referenced 'bool' depth 0 index 2 U2
// DUMP-NEXT: `-CXXRecordDecl {{.+}} implicit struct Template2
// JSON: "kind": "ClassTemplatePartialSpecializationDecl",
// JSON: "name": "Template2",
// JSON: "tagUsed": "struct",
// JSON: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "templateName": "TestPartialSpecNTTP::Template1",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateTypeParmType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "type-parameter-0-0"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0,
// JSON-NEXT: "decl": {
// JSON-NEXT: "id": "0x0"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "isExpr": true,
// JSON-NEXT: "isCanonical": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "prvalue",
// JSON-NEXT: "referencedDecl": {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "name": "U2",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON: "kind": "TemplateArgument",
// JSON-NEXT: "isExpr": true,
// JSON-NEXT: "isCanonical": true,
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "prvalue",
// JSON-NEXT: "referencedDecl": {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "name": "U3",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON: "isReferenced": true,
// JSON-NEXT: "name": "U1",
// JSON-NEXT: "tagUsed": "typename",
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 0
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON: "isReferenced": true,
// JSON-NEXT: "name": "U3",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 1
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON: "isReferenced": true,
// JSON-NEXT: "name": "U2",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "bool"
// JSON-NEXT: },
// JSON-NEXT: "depth": 0,
// JSON-NEXT: "index": 2
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.+}},
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON: "isImplicit": true,
// JSON-NEXT: "name": "Template2",
// JSON-NEXT: "tagUsed": "struct"
// JSON-NEXT: }
// JSON-NEXT: ]
} // namespace TestPartialSpecNTTP
namespace GH153540 {
// DUMP-LABEL: NamespaceDecl {{.*}} GH153540 external-linkage{{$}}
// JSON-LABEL: "name": "GH153540",
namespace N {
template<typename T> struct S { S(T); };
}
void f() {
N::S(0);
}
// DUMP: FunctionDecl {{.*}} f 'void ()'
// DUMP-NEXT: CompoundStmt
// DUMP-NEXT: CXXFunctionalCastExpr {{.*}} 'N::S<int>':'GH153540::N::S<int>'
// DUMP-NEXT: CXXConstructExpr {{.*}} <col:5, col:11> 'N::S<int>':'GH153540::N::S<int>' 'void (int)'
// JSON: "kind": "FunctionDecl",
// JSON: "name": "f",
// JSON-NEXT: "mangledName": {{.*}},
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "void ()"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "CompoundStmt",
// JSON: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "CXXFunctionalCastExpr",
// JSON: "type": {
// JSON-NEXT: "desugaredQualType": "GH153540::N::S<int>",
// JSON-NEXT: "qualType": "N::S<int>"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "prvalue",
// JSON-NEXT: "castKind": "ConstructorConversion",
// JSON-NEXT: "conversionFunc": {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "CXXConstructorDecl",
// JSON-NEXT: "name": "S",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "void (int)"
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "CXXConstructExpr",
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "col": 5,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: },
// JSON-NEXT: "end": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "col": 11,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "type": {
// JSON-NEXT: "desugaredQualType": "GH153540::N::S<int>",
// JSON-NEXT: "qualType": "N::S<int>"
// JSON-NEXT: },
// JSON-NEXT: "valueCategory": "prvalue",
// JSON-NEXT: "ctorType": {
// JSON-NEXT: "qualType": "void (int)"
// JSON-NEXT: },
} // namespace GH153540
namespace AliasDependentTemplateSpecializationType {
// DUMP-LABEL: NamespaceDecl {{.*}} AliasDependentTemplateSpecializationType external-linkage{{$}}
// JSON-LABEL: "name": "AliasDependentTemplateSpecializationType",
template<template<class> class TT> using T1 = TT<int>;
template<class T> using T2 = T1<T::template X>;
// DUMP: TypeAliasDecl {{.*}} T2 'T1<T::template X>':'T::template X<int>'
// DUMP-NEXT: `-TemplateSpecializationType {{.*}} 'T1<T::template X>' sugar dependent alias
// DUMP-NEXT: |-name: 'T1':'AliasDependentTemplateSpecializationType::T1' qualified
// DUMP-NEXT: | `-TypeAliasTemplateDecl {{.*}} T1
// DUMP-NEXT: |-TemplateArgument template 'T::template X':'type-parameter-0-0::template X' dependent
// DUMP-NEXT: | `-NestedNameSpecifier TypeSpec 'T'
// DUMP-NEXT: `-TemplateSpecializationType {{.*}} 'T::template X<int>' dependent
// DUMP-NEXT: |-name: 'T::template X':'type-parameter-0-0::template X' subst index 0 final
// DUMP-NEXT: | |-parameter: TemplateTemplateParmDecl {{.*}} depth 0 index 0 TT
// DUMP-NEXT: | |-associated TypeAliasTemplate {{.*}} 'T1'
// DUMP-NEXT: | `-replacement: 'T::template X':'type-parameter-0-0::template X' dependent
// DUMP-NEXT: | `-NestedNameSpecifier TypeSpec 'T'
// DUMP-NEXT: `-TemplateArgument type 'int'
// DUMP-NEXT: `-BuiltinType {{.*}} 'int'
// FIXME: a non-trivial amount of data present in textual dump is nowhere
// to be found in JSON dump, because JSON dumper cannot dump the data
// inside TemplateNames.
// JSON: "kind": "TypeAliasTemplateDecl"
// JSON: "name": "T2",
// JSON: "kind": "TypeAliasDecl",
// JSON: "name": "T2",
// JSON-NEXT: "type": {
// JSON-NEXT: "desugaredQualType": "T::template X<int>",
// JSON-NEXT: "qualType": "T1<T::template X>"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "T1<T::template X>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "isAlias": true,
// JSON-NEXT: "templateName": "T1",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument"
// JSON-NEXT: },
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "T::template X<int>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
// JSON-NEXT: "templateName": "T::template X",
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": {{.*}},
// JSON-NEXT: "kind": "BuiltinType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
// JSON-NEXT: }
} // namespace
namespace TestAbbreviatedTemplateDecls {
// DUMP-LABEL: NamespaceDecl {{.*}} TestAbbreviatedTemplateDecls external-linkage{{$}}
// JSON-LABEL: "name": "TestAbbreviatedTemplateDecls",
void abbreviated(auto);
template<class T>
void mixed(T, auto);
// DUMP: FunctionTemplateDecl {{.*}} <line:[[@LINE-4]]:3, col:24> col:8 abbreviated
// DUMP: FunctionTemplateDecl {{.*}} <line:[[@LINE-4]]:3, line:[[@LINE-3]]:21> col:8 mixed
// JSON: "kind": "FunctionTemplateDecl",
// JSON-NEXT: "loc": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "line": [[#@LINE-10]],
// JSON-NEXT: "col": 8,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: },
// JSON-NEXT: "end": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "col": 24,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "name": "abbreviated",
// JSON: "kind": "FunctionTemplateDecl",
// JSON-NEXT: "loc": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "line": {{.*}},
// JSON-NEXT: "col": 8,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "line": [[#@LINE-37]],
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: },
// JSON-NEXT: "end": {
// JSON-NEXT: "offset": {{.*}},
// JSON-NEXT: "line": [[#@LINE-42]],
// JSON-NEXT: "col": 21,
// JSON-NEXT: "tokLen": {{.*}}
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "name": "mixed",
} // namespace TestAbbreviatedTemplateDecls