brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · b7fe82f Raw
192 lines · cpp
1// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-OPT2// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -std=c++1y -O3 -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OPT3// RUN: %clang_cc1 -emit-llvm -triple i686-pc-win32 -std=c++1y -o - %s | FileCheck %s --check-prefix=CHECK-MS4 5// This check logically is attached to 'template int S<int>::i;' below.6// CHECK: @_ZN1SIiE1iE = weak_odr global i327 8// This check is logically attached to 'template int ExportedStaticLocal::f<int>()' below.9// CHECK-OPT: @_ZZN19ExportedStaticLocal1fIiEEvvE1i = linkonce_odr global10 11template<typename T, typename U, typename Result>12struct plus {13  Result operator()(const T& t, const U& u) const;14};15 16template<typename T, typename U, typename Result>17Result plus<T, U, Result>::operator()(const T& t, const U& u) const {18  return t + u;19}20 21// CHECK-LABEL: define weak_odr noundef i32 @_ZNK4plusIillEclERKiRKl22template struct plus<int, long, long>;23 24namespace EarlyInstantiation {25  // Check that we emit definitions if we instantiate a function definition before26  // it gets explicitly instantiatied.27  template<typename T> struct S {28    constexpr int constexpr_function() { return 0; }29    auto deduced_return_type() { return 0; }30  };31 32  // From an implicit instantiation.33  constexpr int a = S<char>().constexpr_function();34  int b = S<char>().deduced_return_type();35 36  // From an explicit instantiation declaration.37  extern template struct S<int>;38  constexpr int c = S<int>().constexpr_function();39  int d = S<int>().deduced_return_type();40 41  // CHECK: define weak_odr noundef i32 @_ZN18EarlyInstantiation1SIcE18constexpr_functionEv(42  // CHECK: define weak_odr noundef i32 @_ZN18EarlyInstantiation1SIcE19deduced_return_typeEv(43  // CHECK: define weak_odr noundef i32 @_ZN18EarlyInstantiation1SIiE18constexpr_functionEv(44  // CHECK: define weak_odr noundef i32 @_ZN18EarlyInstantiation1SIiE19deduced_return_typeEv(45  template struct S<char>;46  template struct S<int>;47 48  template<typename T> constexpr int constexpr_function() { return 0; }49  template<typename T> auto deduced_return_type() { return 0; }50 51  // From an implicit instantiation.52  constexpr int e = constexpr_function<char>();53  int f = deduced_return_type<char>();54 55  // From an explicit instantiation declaration.56  extern template int constexpr_function<int>();57  extern template auto deduced_return_type<int>();58  constexpr int g = constexpr_function<int>();59  int h = deduced_return_type<int>();60 61  // The FIXMEs below are for PR19551.62  // CHECK: define weak_odr noundef i32 @_ZN18EarlyInstantiation18constexpr_functionIcEEiv(63  // FIXME: define weak_odr noundef i32 @_ZN18EarlyInstantiation19deduced_return_typeIcEEiv(64  // CHECK: define weak_odr noundef i32 @_ZN18EarlyInstantiation18constexpr_functionIiEEiv(65  // FIXME: define weak_odr noundef i32 @_ZN18EarlyInstantiation19deduced_return_typeIiEEiv(66  template int constexpr_function<char>();67  // FIXME template auto deduced_return_type<char>();68  template int constexpr_function<int>();69  // FIXME template auto deduced_return_type<int>();70}71 72namespace LateInstantiation {73  // Check that we downgrade the linkage to available_externally if we see an74  // explicit instantiation declaration after the function template is75  // instantiated.76  template<typename T> struct S { constexpr int f() { return 0; } };77  template<typename T> constexpr int f() { return 0; }78 79  // Trigger eager instantiation of the function definitions.80  int a, b = S<char>().f() + f<char>() + a;81  int c, d = S<int>().f() + f<int>() + a;82 83  // Don't allow some of those definitions to be emitted.84  extern template struct S<int>;85  extern template int f<int>();86 87  // Check that we declare, define, or provide an available-externally88  // definition as appropriate.89  // CHECK: define linkonce_odr noundef i32 @_ZN17LateInstantiation1SIcE1fEv(90  // CHECK: define linkonce_odr noundef i32 @_ZN17LateInstantiation1fIcEEiv(91  // CHECK-NO-OPT: declare noundef i32 @_ZN17LateInstantiation1SIiE1fEv(92  // CHECK-NO-OPT: declare noundef i32 @_ZN17LateInstantiation1fIiEEiv(93  // CHECK-OPT: define available_externally noundef i32 @_ZN17LateInstantiation1SIiE1fEv(94  // CHECK-OPT: define available_externally noundef i32 @_ZN17LateInstantiation1fIiEEiv(95}96 97namespace PR21718 {98// The linkage of a used constexpr member function can change from linkonce_odr99// to weak_odr after explicit instantiation without errors about defining the100// same function twice.101template <typename T>102struct S {103// CHECK-LABEL: define weak_odr noundef i32 @_ZN7PR217181SIiE1fEv104  __attribute__((used)) constexpr int f() { return 0; }105};106int g() { return S<int>().f(); }107template struct S<int>;108}109 110namespace NestedClasses {111  // Check how explicit instantiation of an outer class affects the inner class.112  template <typename T> struct Outer {113    struct Inner {114      void f() {}115    };116  };117 118  // Explicit instantiation definition of Outer causes explicit instantiation119  // definition of Inner.120  template struct Outer<int>;121  // CHECK: define weak_odr void @_ZN13NestedClasses5OuterIiE5Inner1fEv122  // CHECK-MS: define weak_odr dso_local x86_thiscallcc void @"?f@Inner@?$Outer@H@NestedClasses@@QAEXXZ"123 124  // Explicit instantiation declaration of Outer causes explicit instantiation125  // declaration of Inner, but not in MSVC mode.126  extern template struct Outer<char>;127  auto use = &Outer<char>::Inner::f;128  // CHECK: {{declare|define available_externally}} void @_ZN13NestedClasses5OuterIcE5Inner1fEv129  // CHECK-MS: define linkonce_odr dso_local x86_thiscallcc void @"?f@Inner@?$Outer@D@NestedClasses@@QAEXXZ"130}131 132// Check that we emit definitions from explicit instantiations even when they133// occur prior to the definition itself.134template <typename T> struct S {135  void f();136  static void g();137  static int i;138  struct S2 {139    void h();140  };141};142 143// CHECK-LABEL: define weak_odr void @_ZN1SIiE1fEv144template void S<int>::f();145 146// CHECK-LABEL: define weak_odr void @_ZN1SIiE1gEv147template void S<int>::g();148 149// See the check line at the top of the file.150template int S<int>::i;151 152// CHECK-LABEL: define weak_odr void @_ZN1SIiE2S21hEv153template void S<int>::S2::h();154 155template <typename T> void S<T>::f() {}156template <typename T> void S<T>::g() {}157template <typename T> int S<T>::i;158template <typename T> void S<T>::S2::h() {}159 160namespace ExportedStaticLocal {161void sink(int&);162template <typename T>163inline void f() {164  static int i;165  sink(i);166}167// See the check line at the top of the file.168extern template void f<int>();169void use() {170  f<int>();171}172}173 174namespace DefaultedMembers {175  struct B { B(); B(const B&); ~B(); };176  template<typename T> struct A : B {177    A() = default;178    ~A() = default;179  };180  extern template struct A<int>;181 182  // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2Ev183  // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiED2Ev184  A<int> ai;185 186  // CHECK-LABEL: define {{.*}} @_ZN16DefaultedMembers1AIiEC2ERKS1_187  A<int> ai2(ai);188 189  // CHECK-NOT: @_ZN16DefaultedMembers1AIcE190  template struct A<char>;191}192