brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · efbbb0c Raw
85 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -O0 -o - %s | FileCheck %s2 3// Test that we do not assume that entities marked with the4// exclude_from_explicit_instantiation attribute are instantiated5// in another TU when an extern template instantiation declaration6// is present. We test that by making sure that definitions are7// generated in this TU despite there being an extern template8// instantiation declaration, which is normally not the case.9 10#define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation))11 12template <class T>13struct Foo {14  EXCLUDE_FROM_EXPLICIT_INSTANTIATION        inline void non_static_member_function1();15  EXCLUDE_FROM_EXPLICIT_INSTANTIATION               void non_static_member_function2();16 17  EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1();18  EXCLUDE_FROM_EXPLICIT_INSTANTIATION static        void static_member_function2();19 20  EXCLUDE_FROM_EXPLICIT_INSTANTIATION static        int static_data_member;21 22  struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 {23    static void static_member_function() { }24  };25 26  struct member_class2 {27    EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() { }28  };29};30 31template <class T> inline void Foo<T>::non_static_member_function1() { }32template <class T>        void Foo<T>::non_static_member_function2() { }33 34template <class T> inline void Foo<T>::static_member_function1() { }35template <class T>        void Foo<T>::static_member_function2() { }36 37template <class T>        int Foo<T>::static_data_member = 0;38 39extern template struct Foo<int>;40 41void use() {42  Foo<int> f;43 44  // An inline non-static member function marked with the attribute is not45  // part of the extern template declaration, so a definition must be emitted46  // in this TU.47  // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE27non_static_member_function1Ev48  f.non_static_member_function1();49 50  // A non-inline non-static member function marked with the attribute is51  // not part of the extern template declaration, so a definition must be52  // emitted in this TU.53  // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE27non_static_member_function2Ev54  f.non_static_member_function2();55 56  // An inline static member function marked with the attribute is not57  // part of the extern template declaration, so a definition must be58  // emitted in this TU.59  // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE23static_member_function1Ev60  Foo<int>::static_member_function1();61 62  // A non-inline static member function marked with the attribute is not63  // part of the extern template declaration, so a definition must be64  // emitted in this TU.65  // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE23static_member_function2Ev66  Foo<int>::static_member_function2();67 68  // A static data member marked with the attribute is not part of the69  // extern template declaration, so a definition must be emitted in this TU.70  // CHECK-DAG: @_ZN3FooIiE18static_data_memberE = linkonce_odr global71  int& odr_use = Foo<int>::static_data_member;72 73  // A member class marked with the attribute is not part of the extern74  // template declaration (it is not recursively instantiated), so its member75  // functions must be emitted in this TU.76  // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE13member_class122static_member_functionEv77  Foo<int>::member_class1::static_member_function();78 79  // A member function marked with the attribute in a member class is not80  // part of the extern template declaration of the parent class template, so81  // it must be emitted in this TU.82  // CHECK-DAG: define linkonce_odr void @_ZN3FooIiE13member_class222static_member_functionEv83  Foo<int>::member_class2::static_member_function();84}85