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