xref: /aosp_15_r20/external/clang/test/CodeGenCXX/linkage.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-optzns %s -o - | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li namespace test1 {
4*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_(
f(T)5*67e74705SXin Li   template <typename T> void f(T) {}
g()6*67e74705SXin Li   inline void *g() {
7*67e74705SXin Li     struct S {
8*67e74705SXin Li     } s;
9*67e74705SXin Li     return reinterpret_cast<void *>(f<S>);
10*67e74705SXin Li   }
h()11*67e74705SXin Li   void *h() { return g(); }
12*67e74705SXin Li }
13*67e74705SXin Li 
14*67e74705SXin Li namespace test2 {
15*67e74705SXin Li   // CHECK-DAG: define internal void @_ZN5test21fIZNS_L1gEvE1SEEvT_(
f(T)16*67e74705SXin Li   template <typename T> void f(T) {}
g()17*67e74705SXin Li   static inline void *g() {
18*67e74705SXin Li     struct S {
19*67e74705SXin Li     } s;
20*67e74705SXin Li     return reinterpret_cast<void *>(f<S>);
21*67e74705SXin Li   }
h()22*67e74705SXin Li   void *h() { return g(); }
23*67e74705SXin Li }
24*67e74705SXin Li 
25*67e74705SXin Li namespace test3 {
26*67e74705SXin Li   // CHECK-DAG: define internal void @_ZN5test31fIZNS_1gEvE1SEEvT_(
f(T)27*67e74705SXin Li   template <typename T> void f(T) {}
g()28*67e74705SXin Li   void *g() {
29*67e74705SXin Li     struct S {
30*67e74705SXin Li     } s;
31*67e74705SXin Li     return reinterpret_cast<void *>(f<S>);
32*67e74705SXin Li   }
h()33*67e74705SXin Li   void *h() { return g(); }
34*67e74705SXin Li }
35*67e74705SXin Li 
36*67e74705SXin Li namespace test4 {
37*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN5test41fIZNS_1gILi1EEEPvvE1SEEvT_(
f(T)38*67e74705SXin Li   template <typename T> void f(T) {}
g()39*67e74705SXin Li   template <int N> inline void *g() {
40*67e74705SXin Li     struct S {
41*67e74705SXin Li     } s;
42*67e74705SXin Li     return reinterpret_cast<void *>(f<S>);
43*67e74705SXin Li   }
44*67e74705SXin Li   extern template void *g<1>();
45*67e74705SXin Li   template void *g<1>();
46*67e74705SXin Li }
47*67e74705SXin Li 
48*67e74705SXin Li namespace test5 {
49*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN5test51fIZNS_1gILi1EEEPvvE1SEEvT_(
f(T)50*67e74705SXin Li   template <typename T> void f(T) {}
g()51*67e74705SXin Li   template <int N> inline void *g() {
52*67e74705SXin Li     struct S {
53*67e74705SXin Li     } s;
54*67e74705SXin Li     return reinterpret_cast<void *>(f<S>);
55*67e74705SXin Li   }
56*67e74705SXin Li   extern template void *g<1>();
h()57*67e74705SXin Li   void *h() { return g<1>(); }
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li namespace test6 {
61*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN5test61fIZZNS_1gEvEN1S1hEvE1TEEvv(
f()62*67e74705SXin Li   template <typename T> void f() {}
63*67e74705SXin Li 
g()64*67e74705SXin Li   inline void *g() {
65*67e74705SXin Li     struct S {
66*67e74705SXin Li       void *h() {
67*67e74705SXin Li         struct T {
68*67e74705SXin Li         };
69*67e74705SXin Li         return (void *)f<T>;
70*67e74705SXin Li       }
71*67e74705SXin Li     } s;
72*67e74705SXin Li     return s.h();
73*67e74705SXin Li   }
74*67e74705SXin Li 
h()75*67e74705SXin Li   void *h() { return g(); }
76*67e74705SXin Li }
77*67e74705SXin Li 
78*67e74705SXin Li namespace test7 {
79*67e74705SXin Li   // CHECK-DAG: define internal void @_ZN5test71fIZZNS_1gEvEN1S1hEvE1TEEvv(
f()80*67e74705SXin Li   template <typename T> void f() {}
81*67e74705SXin Li 
g()82*67e74705SXin Li   void *g() {
83*67e74705SXin Li     struct S {
84*67e74705SXin Li       void *h() {
85*67e74705SXin Li         struct T {
86*67e74705SXin Li         };
87*67e74705SXin Li         return (void *)f<T>;
88*67e74705SXin Li       }
89*67e74705SXin Li     } s;
90*67e74705SXin Li     return s.h();
91*67e74705SXin Li   }
92*67e74705SXin Li 
h()93*67e74705SXin Li   void *h() { return g(); }
94*67e74705SXin Li }
95*67e74705SXin Li 
96*67e74705SXin Li namespace test8 {
97*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN5test81fIZNS_1gEvE1SEEvT_(
f(T)98*67e74705SXin Li   template <typename T> void f(T) {}
g()99*67e74705SXin Li   inline void *g() {
100*67e74705SXin Li     enum S {
101*67e74705SXin Li     };
102*67e74705SXin Li     return reinterpret_cast<void *>(f<S>);
103*67e74705SXin Li   }
h()104*67e74705SXin Li   void *h() { return g(); }
105*67e74705SXin Li }
106*67e74705SXin Li 
107*67e74705SXin Li namespace test9 {
108*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN5test91fIPZNS_1gEvE1SEEvT_(
f(T)109*67e74705SXin Li   template <typename T> void f(T) {}
g()110*67e74705SXin Li   inline void *g() {
111*67e74705SXin Li     struct S {
112*67e74705SXin Li     } s;
113*67e74705SXin Li     return reinterpret_cast<void *>(f<S*>);
114*67e74705SXin Li   }
h()115*67e74705SXin Li   void *h() { return g(); }
116*67e74705SXin Li }
117*67e74705SXin Li 
118*67e74705SXin Li namespace test10 {
119*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN6test101fIPFZNS_1gEvE1SvEEEvT_(
f(T)120*67e74705SXin Li   template <typename T> void f(T) {}
g()121*67e74705SXin Li   inline void *g() {
122*67e74705SXin Li     struct S {
123*67e74705SXin Li     } s;
124*67e74705SXin Li     typedef S(*ftype)();
125*67e74705SXin Li     return reinterpret_cast<void *>(f<ftype>);
126*67e74705SXin Li   }
h()127*67e74705SXin Li   void *h() { return g(); }
128*67e74705SXin Li }
129*67e74705SXin Li 
130*67e74705SXin Li namespace test11 {
131*67e74705SXin Li   // CHECK-DAG: define internal void @_ZN6test111fIPFZNS_1gEvE1SPNS_12_GLOBAL__N_11IEEEEvT_(
132*67e74705SXin Li   namespace {
133*67e74705SXin Li     struct I {
134*67e74705SXin Li     };
135*67e74705SXin Li   }
136*67e74705SXin Li 
f(T)137*67e74705SXin Li   template <typename T> void f(T) {}
g()138*67e74705SXin Li   inline void *g() {
139*67e74705SXin Li     struct S {
140*67e74705SXin Li     };
141*67e74705SXin Li     typedef S(*ftype)(I * x);
142*67e74705SXin Li     return reinterpret_cast<void *>(f<ftype>);
143*67e74705SXin Li   }
h()144*67e74705SXin Li   void *h() { return g(); }
145*67e74705SXin Li }
146*67e74705SXin Li 
147*67e74705SXin Li namespace test12 {
148*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN6test123fooIZNS_3barIZNS_3zedEvE2S2EEPvvE2S1EEvv
foo()149*67e74705SXin Li   template <typename T> void foo() {}
bar()150*67e74705SXin Li   template <typename T> inline void *bar() {
151*67e74705SXin Li     enum S1 {
152*67e74705SXin Li     };
153*67e74705SXin Li     return reinterpret_cast<void *>(foo<S1>);
154*67e74705SXin Li   }
zed()155*67e74705SXin Li   inline void *zed() {
156*67e74705SXin Li     enum S2 {
157*67e74705SXin Li     };
158*67e74705SXin Li     return reinterpret_cast<void *>(bar<S2>);
159*67e74705SXin Li   }
h()160*67e74705SXin Li   void *h() { return zed(); }
161*67e74705SXin Li }
162*67e74705SXin Li 
163*67e74705SXin Li namespace test13 {
164*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZZN6test133fooEvEN1S3barEv(
foo()165*67e74705SXin Li   inline void *foo() {
166*67e74705SXin Li     struct S {
167*67e74705SXin Li       static void bar() {}
168*67e74705SXin Li     };
169*67e74705SXin Li     return (void *)S::bar;
170*67e74705SXin Li   }
zed()171*67e74705SXin Li   void *zed() { return foo(); }
172*67e74705SXin Li }
173*67e74705SXin Li 
174*67e74705SXin Li namespace test14 {
175*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN6test143fooIZNS_1fEvE1SE3barILPS1_0EEEvv(
176*67e74705SXin Li   template <typename T> struct foo {
bartest14::foo177*67e74705SXin Li     template <T *P> static void bar() {}
gtest14::foo178*67e74705SXin Li     static void *g() { return (void *)bar<nullptr>; }
179*67e74705SXin Li   };
f()180*67e74705SXin Li   inline void *f() {
181*67e74705SXin Li     struct S {
182*67e74705SXin Li     };
183*67e74705SXin Li     return foo<S>::g();
184*67e74705SXin Li   }
h()185*67e74705SXin Li   void h() { f(); }
186*67e74705SXin Li }
187*67e74705SXin Li 
188*67e74705SXin Li namespace test15 {
189*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN6test153zedIZNS_3fooIiEEPvvE3barEEvv(
zed()190*67e74705SXin Li   template <class T> void zed() {}
foo()191*67e74705SXin Li   template <class T> void *foo() {
192*67e74705SXin Li     class bar {
193*67e74705SXin Li     };
194*67e74705SXin Li     return reinterpret_cast<void *>(zed<bar>);
195*67e74705SXin Li   }
test()196*67e74705SXin Li   void test() { foo<int>(); }
197*67e74705SXin Li }
198*67e74705SXin Li 
199*67e74705SXin Li namespace test16 {
200*67e74705SXin Li   // CHECK-DAG: define linkonce_odr void @_ZN6test163zedIZNS_3fooIiE3barEvE1SEEvv(
zed()201*67e74705SXin Li   template <class T> void zed() {}
202*67e74705SXin Li   template <class T> struct foo {
203*67e74705SXin Li     static void *bar();
204*67e74705SXin Li   };
bar()205*67e74705SXin Li   template <class T> void *foo<T>::bar() {
206*67e74705SXin Li     class S {
207*67e74705SXin Li     };
208*67e74705SXin Li     return reinterpret_cast<void *>(zed<S>);
209*67e74705SXin Li   }
test()210*67e74705SXin Li   void *test() { return foo<int>::bar(); }
211*67e74705SXin Li }
212*67e74705SXin Li 
213*67e74705SXin Li namespace test17 {
214*67e74705SXin Li   // CHECK-DAG: @_ZZN6test173fooILi42EEEPivE3bar = linkonce_odr
215*67e74705SXin Li   // CHECK-DAG: define weak_odr i32* @_ZN6test173fooILi42EEEPiv(
216*67e74705SXin Li   template<int I>
foo()217*67e74705SXin Li   int *foo() {
218*67e74705SXin Li     static int bar;
219*67e74705SXin Li     return &bar;
220*67e74705SXin Li   }
221*67e74705SXin Li   template int *foo<42>();
222*67e74705SXin Li }
223*67e74705SXin Li 
224*67e74705SXin Li // PR18408
225*67e74705SXin Li namespace test18 {
226*67e74705SXin Li   template<template<typename> class> struct A {};
227*67e74705SXin Li   struct B { template<typename> struct C; };
f(A<B::C>)228*67e74705SXin Li   void f(A<B::C>) {}
229*67e74705SXin Li   // CHECK-DAG: define void @_ZN6test181fENS_1AINS_1B1CEEE(
230*67e74705SXin Li }
231