// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=limited %s -o - | FileCheck %s // Run again with -gline-tables-only and verify we don't crash. We won't output // type info at all. // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -debug-info-kind=line-tables-only %s -o - | FileCheck %s -check-prefix LINES-ONLY // LINES-ONLY-NOT: !DICompositeType(tag: DW_TAG_structure_type // "h" is at the top because it's in the compile unit's retainedTypes: list. // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "h<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T> struct a { }; extern template class a<int>; // CHECK-NOT: DICompositeType(tag: DW_TAG_structure_type, name: "a<int>" template <typename T> struct b { }; extern template class b<int>; b<int> bi; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T> struct c { void f() {} }; extern template class c<int>; c<int> ci; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "c<int>" // CHECK-SAME: DIFlagFwdDecl template <typename T> struct d { void f(); }; extern template class d<int>; d<int> di; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "d<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T> struct e { void f(); }; template <typename T> void e<T>::f() { } extern template class e<int>; e<int> ei; // There's no guarantee that the out of line definition will appear before the // explicit template instantiation definition, so conservatively emit the type // definition here. // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "e<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T> struct f { void g(); }; extern template class f<int>; template <typename T> void f<T>::g() { } f<int> fi; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "f<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T> struct g { void f(); }; template <> void g<int>::f(); extern template class g<int>; g<int> gi; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "g<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T> struct h { }; template class h<int>; template <typename T> struct i { void f() {} }; template<> void i<int>::f(); extern template class i<int>; i<int> ii; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "i<int>" // CHECK-NOT: DIFlagFwdDecl // CHECK-SAME: ){{$}} template <typename T1, typename T2 = T1> struct j { }; extern template class j<int>; j<int> jj; // CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "j<int, int>" template <typename T> struct k { }; template <> struct k<int>; template struct k<int>; // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "k<int>"