blob: 7c0757b2829a0b385f89c45683ac4df26c548091 [file] [log] [blame]
Rafael Espindola838dc592013-01-12 06:42:30 +00001// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -fvisibility-inlines-hidden -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
John McCall479edbc2010-10-28 18:10:36 +00002
3// The trickery with optimization in the run line is to get IR
4// generation to emit available_externally function bodies, but not
5// actually inline them (and thus remove the emitted bodies).
6
Douglas Gregor7cf84d62010-06-15 17:05:35 +00007struct X0 {
8 void __attribute__((visibility("default"))) f1() { }
9 void f2() { }
10 void f3();
11 static void f5() { }
12 virtual void f6() { }
13};
14
15inline void X0::f3() { }
16
17template<typename T>
18struct X1 {
19 void __attribute__((visibility("default"))) f1() { }
20 void f2() { }
21 void f3();
22 void f4();
23 static void f5() { }
24 virtual void f6() { }
25};
26
27template<typename T>
28inline void X1<T>::f3() { }
29
30template<>
31inline void X1<int>::f4() { }
32
33struct __attribute__((visibility("default"))) X2 {
34 void f2() { }
35};
36
John McCall479edbc2010-10-28 18:10:36 +000037extern template struct X1<float>;
38
39void use(X0 *x0, X1<int> *x1, X2 *x2, X1<float> *x3) {
Stephen Lin93ab6bf2013-08-15 06:47:53 +000040 // CHECK-LABEL: define linkonce_odr void @_ZN2X02f1Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000041 x0->f1();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000042 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f2Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000043 x0->f2();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000044 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f3Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000045 x0->f3();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000046 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f5Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000047 X0::f5();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000048 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X02f6Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000049 x0->X0::f6();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000050 // CHECK-LABEL: define linkonce_odr void @_ZN2X1IiE2f1Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000051 x1->f1();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000052 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f2Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000053 x1->f2();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000054 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f3Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000055 x1->f3();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000056 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f4Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000057 x1->f4();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000058 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f5Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000059 X1<int>::f5();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000060 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X1IiE2f6Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000061 x1->X1::f6();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000062 // CHECK-LABEL: define linkonce_odr hidden void @_ZN2X22f2Ev
Douglas Gregor7cf84d62010-06-15 17:05:35 +000063 x2->f2();
Stephen Lin93ab6bf2013-08-15 06:47:53 +000064 // CHECK-LABEL: define available_externally void @_ZN2X1IfE2f2Ev
John McCall479edbc2010-10-28 18:10:36 +000065 x3->f2();
Douglas Gregor7cf84d62010-06-15 17:05:35 +000066}
John McCall66cbcf32010-11-01 01:29:57 +000067
68// rdar://problem/8614470
69namespace test1 {
70 struct __attribute__((visibility("default"))) A {
71 inline void foo();
72 ~A();
73 };
74
75 void test() {
76 A a;
77 a.foo();
78 }
79// CHECK: declare void @_ZN5test11A3fooEv
Eli Friedman065bb5e2011-06-15 18:37:44 +000080// CHECK: declare {{.*}} @_ZN5test11AD1Ev
John McCall66cbcf32010-11-01 01:29:57 +000081}
John McCall90f14502010-12-10 02:59:44 +000082
83// PR8713
84namespace test2 {
85 struct A {};
86 template <class T> class B {};
87 typedef B<A> arg;
88
89 namespace ns __attribute__((visibility("default"))) {
90 template <class T> inline void foo() {}
91 extern template void foo<arg>();
92 }
93
94 void test() {
95 ns::foo<arg>();
96 }
97
Stephen Lin93ab6bf2013-08-15 06:47:53 +000098 // CHECK-LABEL: define available_externally void @_ZN5test22ns3fooINS_1BINS_1AEEEEEvv()
John McCall90f14502010-12-10 02:59:44 +000099}
Rafael Espindolafedb6ec2011-12-27 21:15:28 +0000100
101namespace PR11642 {
102 template <typename T>
103 class Foo {
104 public:
105 T foo(T x) { return x; }
106 };
107 extern template class Foo<int>;
108 template class Foo<int>;
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000109 // CHECK-LABEL: define weak_odr i32 @_ZN7PR116423FooIiE3fooEi
Rafael Espindolafedb6ec2011-12-27 21:15:28 +0000110}
Rafael Espindolab04b7312012-07-13 14:25:36 +0000111
112// Test that clang implements the new gcc behaviour for inline functions.
113// GCC PR30066.
114namespace test3 {
115 inline void foo(void) {
116 }
117 template<typename T>
118 inline void zed() {
119 }
120 template void zed<float>();
121 void bar(void) {
122 foo();
123 zed<int>();
124 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000125 // CHECK-LABEL: define weak_odr void @_ZN5test33zedIfEEvv
126 // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test33fooEv
127 // CHECK-LABEL: define linkonce_odr hidden void @_ZN5test33zedIiEEvv
Rafael Espindolab04b7312012-07-13 14:25:36 +0000128}
Rafael Espindola0142f0c2012-10-11 16:32:25 +0000129
130namespace test4 {
131 extern inline __attribute__ ((__gnu_inline__))
132 void foo() {}
133 void bar() {
134 foo();
135 }
Stephen Lin93ab6bf2013-08-15 06:47:53 +0000136 // CHECK-LABEL: define available_externally void @_ZN5test43fooE
Rafael Espindola0142f0c2012-10-11 16:32:25 +0000137}
Rafael Espindola140aadf2012-12-25 07:31:49 +0000138
139namespace test5 {
140 // just don't crash.
141 template <int> inline void Op();
142 class UnaryInstruction {
143 UnaryInstruction() {
144 Op<0>();
145 }
146 };
147 template <int Idx_nocapture> void Op() {
148 }
149}
Rafael Espindola838dc592013-01-12 06:42:30 +0000150
151namespace test6 {
152 // just don't crash.
153 template <typename T>
154 void f(T x) {
155 }
156 struct C {
157 static void g() {
158 f([](){});
159 }
160 };
161 void g() {
162 C::g();
163 }
164}