xref: /aosp_15_r20/external/clang/test/CodeGenCXX/template-linkage.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li // CHECK: Outer5Inner{{.*}}localE6memberE = external global
4*67e74705SXin Li 
5*67e74705SXin Li template<typename T> struct A {
fA6*67e74705SXin Li   virtual void f(T) { }
gA7*67e74705SXin Li   inline void g() { }
8*67e74705SXin Li };
9*67e74705SXin Li 
10*67e74705SXin Li // Explicit instantiations have external linkage.
11*67e74705SXin Li 
12*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN1AIiE1gEv(
13*67e74705SXin Li template void A<int>::g();
14*67e74705SXin Li 
15*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN1AIfE1fEf(
16*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_ZN1AIfE1gEv(
17*67e74705SXin Li // FIXME: This should also emit the vtable.
18*67e74705SXin Li template struct A<float>;
19*67e74705SXin Li 
20*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_Z1fIiEvT_
f(T)21*67e74705SXin Li template <typename T> void f(T) { }
22*67e74705SXin Li template void f<int>(int);
23*67e74705SXin Li 
24*67e74705SXin Li // CHECK-LABEL: define weak_odr void @_Z1gIiEvT_
g(T)25*67e74705SXin Li template <typename T> inline void g(T) { }
26*67e74705SXin Li template void g<int>(int);
27*67e74705SXin Li 
28*67e74705SXin Li template<typename T>
29*67e74705SXin Li struct X0 {
~X0X030*67e74705SXin Li   virtual ~X0() { }
31*67e74705SXin Li };
32*67e74705SXin Li 
33*67e74705SXin Li template<typename T>
34*67e74705SXin Li struct X1 : X0<T> {
35*67e74705SXin Li   virtual void blarg();
36*67e74705SXin Li };
37*67e74705SXin Li 
blarg()38*67e74705SXin Li template<typename T> void X1<T>::blarg() { }
39*67e74705SXin Li 
40*67e74705SXin Li extern template struct X0<char>;
41*67e74705SXin Li extern template struct X1<char>;
42*67e74705SXin Li 
43*67e74705SXin Li // CHECK-LABEL: define linkonce_odr void @_ZN2X1IcED1Ev(%struct.X1* %this) unnamed_addr
test_X1()44*67e74705SXin Li void test_X1() {
45*67e74705SXin Li   X1<char> i1c;
46*67e74705SXin Li }
47*67e74705SXin Li 
48*67e74705SXin Li namespace PR14825 {
49*67e74705SXin Li struct Outer {
50*67e74705SXin Li   template <typename T> struct Inner {
51*67e74705SXin Li     static int member;
52*67e74705SXin Li   };
GetPR14825::Outer53*67e74705SXin Li   template <typename T> void Get() {
54*67e74705SXin Li     int m = Inner<T>::member;
55*67e74705SXin Li   }
56*67e74705SXin Li };
57*67e74705SXin Li 
test()58*67e74705SXin Li void test() {
59*67e74705SXin Li   struct local {};
60*67e74705SXin Li   Outer o;
61*67e74705SXin Li   typedef void (Outer::*mptr)();
62*67e74705SXin Li   mptr method = &Outer::Get<local>;
63*67e74705SXin Li }
64*67e74705SXin Li }
65