| 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 { |
| 7 | A() {} |
| 8 | A(const A&) {} |
| 9 | A& operator=(const A&) { return *this; } |
| 10 | ~A() {} |
| 11 | }; |
| 12 | |
| 13 | struct B { |
| 14 | A member; |
| 15 | int implicitFunction(int a) { return a + a; } |
| 16 | inline int explicitFunction(int a); |
| 17 | int noHintFunction(int a); |
| 18 | __attribute__((optnone)) int optNoneFunction(int a) { return a + a; } |
| 19 | template<int N> int implicitTplFunction(int a) { return N + a; } |
| 20 | 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 | |
| 25 | int B::explicitFunction(int a) { return a + a; } |
| 26 | // CHECK: @_ZN1B14noHintFunctionEi({{.*}}) [[NOHINT_ATTR:#[0-9]+]] |
| 27 | int B::noHintFunction(int a) { return a + a; } |
| 28 | |
| 29 | // CHECK: @_ZN1B19implicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]] |
| 30 | template<> int B::implicitTplFunction<0>(int a) { return a + a; } |
| 31 | // CHECK: @_ZN1B19explicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]] |
| 32 | template<> int B::explicitTplFunction<0>(int a) { return a + a; } |
| 33 | // CHECK: @_ZN1B17noHintTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]] |
| 34 | template<> int B::noHintTplFunction<0>(int a) { return a + a; } |
| 35 | template<> inline int B::implicitTplFunction<1>(int a) { return a; } |
| 36 | template<> inline int B::explicitTplFunction<1>(int a) { return a; } |
| 37 | template<> inline int B::noHintTplFunction<1>(int a) { return a; } |
| 38 | template<int N> int B::noHintTplFunction(int a) { return N + a; } |
| 39 | template<int N> inline int B::explicitRedeclTplFunction(int a) { return N + a; } |
| 40 | |
| 41 | constexpr int constexprFunction(int a) { return a + a; } |
| 42 | |
| 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 | |