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