1 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-functions -emit-llvm -disable-llvm-passes -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=SUITABLE
2 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-hint-functions -emit-llvm -disable-llvm-passes -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=HINTED
3 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -fno-inline -emit-llvm -disable-llvm-passes -o - | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK --check-prefix=NOINLINE
4 
5 // Force non-trivial implicit constructors/destructors/operators for B by having explicit ones for A
6 struct A {
AA7   A() {}
AA8   A(const A&) {}
operator =A9   A& operator=(const A&) { return *this; }
~AA10   ~A() {}
11 };
12 
13 struct B {
14   A member;
implicitFunctionB15   int implicitFunction(int a) { return a + a; }
16   inline int explicitFunction(int a);
17   int noHintFunction(int a);
optNoneFunctionB18   __attribute__((optnone)) int optNoneFunction(int a) { return a + a; }
implicitTplFunctionB19   template<int N> int implicitTplFunction(int a) { return N + a; }
explicitTplFunctionB20   template<int N> inline int explicitTplFunction(int a) { return N + a; }
21   template<int N> int noHintTplFunction(int a);
22   template<int N> int explicitRedeclTplFunction(int a);
23 };
24 
explicitFunction(int a)25 int B::explicitFunction(int a) { return a + a; }
26 // CHECK: @_ZN1B14noHintFunctionEi({{.*}}) [[NOHINT_ATTR:#[0-9]+]]
noHintFunction(int a)27 int B::noHintFunction(int a) { return a + a; }
28 
29 // CHECK: @_ZN1B19implicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
implicitTplFunction(int a)30 template<> int B::implicitTplFunction<0>(int a) { return a + a; }
31 // CHECK: @_ZN1B19explicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
explicitTplFunction(int a)32 template<> int B::explicitTplFunction<0>(int a) { return a + a; }
33 // CHECK: @_ZN1B17noHintTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
noHintTplFunction(int a)34 template<> int B::noHintTplFunction<0>(int a) { return a + a; }
implicitTplFunction(int a)35 template<> inline int B::implicitTplFunction<1>(int a) { return a; }
explicitTplFunction(int a)36 template<> inline int B::explicitTplFunction<1>(int a) { return a; }
noHintTplFunction(int a)37 template<> inline int B::noHintTplFunction<1>(int a) { return a; }
noHintTplFunction(int a)38 template<int N> int B::noHintTplFunction(int a) { return N + a; }
explicitRedeclTplFunction(int a)39 template<int N> inline int B::explicitRedeclTplFunction(int a) { return N + a; }
40 
constexprFunction(int a)41 constexpr int constexprFunction(int a) { return a + a; }
42 
foo()43 void foo()
44 {
45 // CHECK: @_ZN1BC1Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR:#[0-9]+]]
46   B b1;
47 // CHECK: @_ZN1BC1ERKS_({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
48   B b2(b1);
49 // CHECK: @_ZN1BaSERKS_({{.*}}) [[IMPLICIT_CONSTR_ATTR]]
50   b2 = b1;
51 // CHECK: @_ZN1B16implicitFunctionEi({{.*}}) [[IMPLICIT_ATTR:#[0-9]+]]
52   b1.implicitFunction(1);
53 // CHECK: @_ZN1B16explicitFunctionEi({{.*}}) [[EXPLICIT_ATTR:#[0-9]+]]
54   b1.explicitFunction(2);
55   b1.noHintFunction(3);
56 // CHECK: @_ZN1B15optNoneFunctionEi({{.*}}) [[OPTNONE_ATTR:#[0-9]+]]
57   b1.optNoneFunction(4);
58 // CHECK: @_Z17constexprFunctioni({{.*}}) [[IMPLICIT_ATTR]]
59   constexprFunction(5);
60   b1.implicitTplFunction<0>(6);
61 // CHECK: @_ZN1B19implicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
62   b1.implicitTplFunction<1>(7);
63 // CHECK: @_ZN1B19implicitTplFunctionILi2EEEii({{.*}}) [[IMPLICIT_ATTR]]
64   b1.implicitTplFunction<2>(8);
65   b1.explicitTplFunction<0>(9);
66 // CHECK: @_ZN1B19explicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
67   b1.explicitTplFunction<1>(10);
68 // CHECK: @_ZN1B19explicitTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
69   b1.explicitTplFunction<2>(11);
70   b1.noHintTplFunction<0>(12);
71 // CHECK: @_ZN1B17noHintTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
72   b1.noHintTplFunction<1>(13);
73 // CHECK: @_ZN1B17noHintTplFunctionILi2EEEii({{.*}}) [[NOHINT_ATTR]]
74   b1.noHintTplFunction<2>(14);
75 // CHECK: @_ZN1B25explicitRedeclTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
76   b1.explicitRedeclTplFunction<2>(15);
77 // CHECK: @_ZN1BD2Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
78 }
79 
80 // SUITABLE-NOT: attributes [[NOHINT_ATTR]] = { {{.*}}noinline{{.*}} }
81 //   HINTED-DAG: attributes [[NOHINT_ATTR]] = { {{.*}}noinline{{.*}} }
82 // NOINLINE-DAG: attributes [[NOHINT_ATTR]] = { {{.*}}noinline{{.*}} }
83 
84 // SUITABLE-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
85 //   HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
86 // NOINLINE-DAG: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
87 
88 // SUITABLE-NOT: attributes [[IMPLICIT_CONSTR_ATTR]] = { {{.*}}noinline{{.*}} }
89 //   HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
90 // NOINLINE-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { {{.*}}noinline{{.*}} }
91 
92 // SUITABLE-NOT: attributes [[EXPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
93 //   HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
94 // NOINLINE-DAG: attributes [[EXPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
95 
96 // CHECK-DAG: attributes [[OPTNONE_ATTR]] = { {{.*}}noinline{{.*}} }
97