1*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=limited %s -o - | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Li // Run again with -gline-tables-only and verify we don't crash. We won't output
4*67e74705SXin Li // type info at all.
5*67e74705SXin Li // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=line-tables-only %s -o - | FileCheck %s -check-prefix LINES-ONLY
6*67e74705SXin Li
7*67e74705SXin Li // LINES-ONLY-NOT: !DICompositeType(tag: DW_TAG_structure_type
8*67e74705SXin Li
9*67e74705SXin Li // "h" is at the top because it's in the compile unit's retainedTypes: list.
10*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "h<int>"
11*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
12*67e74705SXin Li // CHECK-SAME: ){{$}}
13*67e74705SXin Li
14*67e74705SXin Li template <typename T>
15*67e74705SXin Li struct a {
16*67e74705SXin Li };
17*67e74705SXin Li extern template class a<int>;
18*67e74705SXin Li // CHECK-NOT: DICompositeType(tag: DW_TAG_structure_type, name: "a<int>"
19*67e74705SXin Li
20*67e74705SXin Li template <typename T>
21*67e74705SXin Li struct b {
22*67e74705SXin Li };
23*67e74705SXin Li extern template class b<int>;
24*67e74705SXin Li b<int> bi;
25*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b<int>"
26*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
27*67e74705SXin Li // CHECK-SAME: ){{$}}
28*67e74705SXin Li
29*67e74705SXin Li template <typename T>
30*67e74705SXin Li struct c {
fc31*67e74705SXin Li void f() {}
32*67e74705SXin Li };
33*67e74705SXin Li extern template class c<int>;
34*67e74705SXin Li c<int> ci;
35*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "c<int>"
36*67e74705SXin Li // CHECK-SAME: DIFlagFwdDecl
37*67e74705SXin Li
38*67e74705SXin Li template <typename T>
39*67e74705SXin Li struct d {
40*67e74705SXin Li void f();
41*67e74705SXin Li };
42*67e74705SXin Li extern template class d<int>;
43*67e74705SXin Li d<int> di;
44*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "d<int>"
45*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
46*67e74705SXin Li // CHECK-SAME: ){{$}}
47*67e74705SXin Li
48*67e74705SXin Li template <typename T>
49*67e74705SXin Li struct e {
50*67e74705SXin Li void f();
51*67e74705SXin Li };
52*67e74705SXin Li template <typename T>
f()53*67e74705SXin Li void e<T>::f() {
54*67e74705SXin Li }
55*67e74705SXin Li extern template class e<int>;
56*67e74705SXin Li e<int> ei;
57*67e74705SXin Li // There's no guarantee that the out of line definition will appear before the
58*67e74705SXin Li // explicit template instantiation definition, so conservatively emit the type
59*67e74705SXin Li // definition here.
60*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "e<int>"
61*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
62*67e74705SXin Li // CHECK-SAME: ){{$}}
63*67e74705SXin Li
64*67e74705SXin Li template <typename T>
65*67e74705SXin Li struct f {
66*67e74705SXin Li void g();
67*67e74705SXin Li };
68*67e74705SXin Li extern template class f<int>;
69*67e74705SXin Li template <typename T>
g()70*67e74705SXin Li void f<T>::g() {
71*67e74705SXin Li }
72*67e74705SXin Li f<int> fi;
73*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "f<int>"
74*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
75*67e74705SXin Li // CHECK-SAME: ){{$}}
76*67e74705SXin Li
77*67e74705SXin Li template <typename T>
78*67e74705SXin Li struct g {
79*67e74705SXin Li void f();
80*67e74705SXin Li };
81*67e74705SXin Li template <>
82*67e74705SXin Li void g<int>::f();
83*67e74705SXin Li extern template class g<int>;
84*67e74705SXin Li g<int> gi;
85*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "g<int>"
86*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
87*67e74705SXin Li // CHECK-SAME: ){{$}}
88*67e74705SXin Li
89*67e74705SXin Li template <typename T>
90*67e74705SXin Li struct h {
91*67e74705SXin Li };
92*67e74705SXin Li template class h<int>;
93*67e74705SXin Li
94*67e74705SXin Li template <typename T>
95*67e74705SXin Li struct i {
fi96*67e74705SXin Li void f() {}
97*67e74705SXin Li };
98*67e74705SXin Li template<> void i<int>::f();
99*67e74705SXin Li extern template class i<int>;
100*67e74705SXin Li i<int> ii;
101*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "i<int>"
102*67e74705SXin Li // CHECK-NOT: DIFlagFwdDecl
103*67e74705SXin Li // CHECK-SAME: ){{$}}
104*67e74705SXin Li
105*67e74705SXin Li template <typename T1, typename T2 = T1>
106*67e74705SXin Li struct j {
107*67e74705SXin Li };
108*67e74705SXin Li extern template class j<int>;
109*67e74705SXin Li j<int> jj;
110*67e74705SXin Li // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "j<int, int>"
111*67e74705SXin Li
112*67e74705SXin Li template <typename T>
113*67e74705SXin Li struct k {
114*67e74705SXin Li };
115*67e74705SXin Li template <>
116*67e74705SXin Li struct k<int>;
117*67e74705SXin Li template struct k<int>;
118*67e74705SXin Li // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "k<int>"
119