Home | History | Annotate | Download | only in CodeGenCXX
      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