1 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE 2 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-hint-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED 3 // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -fno-inline -emit-llvm -disable-llvm-optzns -o - | FileCheck %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