| // -fkeep-inline-functions has an effect without optimization, although it is | |
| // primarily useful with optimization enabled. | |
| // RUN: %clang_cc1 -O2 -fkeep-inline-functions -emit-llvm %s -o - -triple x86_64-unknown-linux-gnu | FileCheck %s | |
| // RUN: %clang_cc1 -O2 -fkeep-inline-functions -emit-llvm %s -o - -triple x86_64-pc-windows-msvc | FileCheck %s --check-prefix=MSVC | |
| // RUN: %clang_cc1 -O2 -fkeep-inline-functions -emit-llvm %s -o - -triple powerpc64-ibm-aix-xcoff | FileCheck %s | |
| // RUN: %clang_cc1 -O0 -fkeep-inline-functions -emit-llvm %s -o - -triple powerpc64-ibm-aix-xcoff | FileCheck %s | |
| // RUN: %clang_cc1 -O0 -mconstructor-aliases -fkeep-inline-functions -emit-llvm %s -o - -triple powerpc64-ibm-aix-xcoff | FileCheck %s --check-prefix=CONSTRUCTOR-ALIASES | |
| // -fkeep-inline-functions retains inline function definitions available in | |
| // this translation unit. Definitions emitted with available_externally | |
| // linkage are excluded. | |
| // Retained: | |
| // f1 explicit inline and referenced | |
| // f2 static inline | |
| // f3 constexpr (implicit inline) | |
| // f4 in-class member definition (implicit inline) | |
| // f7 explicit inline and unreferenced | |
| // f8 explicitly instantiated inline template | |
| // TestCtorDtor implicitly inline constructor/destructor variants. | |
| // Also exercises the GlobalDecl construction path in MustBeEmitted() for | |
| // constructors/destructors. Without the special handling, debug builds hit | |
| // the GlobalDecl(FunctionDecl*) assertion. | |
| // Not retained: | |
| // f5 non-inline | |
| // f6 GNU extern inline | |
| // f9 extern template specialization | |
| inline int f1(int x) { return x + 1; } | |
| static inline int f2(int x) { return x + 2; } | |
| constexpr int f3(int x) { return x + 3; } | |
| struct S { | |
| int f4() { return 4; } | |
| }; | |
| int f5(int x) { return x + 5; } | |
| __attribute__((gnu_inline)) inline int f6(int x) { return x + 6; } | |
| inline int f7(int x) { return x + 7; } | |
| template <typename T> inline T f8(T x) { return x + 8; } | |
| template int f8<int>(int); | |
| template <typename T> | |
| struct A { | |
| static int f9() { return 9; } | |
| }; | |
| extern template int A<int>::f9(); | |
| // Implicitly inline ctor and dtor intentionally unreferenced so | |
| // MustBeEmitted() is the sole mechanism that forces their emission. | |
| struct TestCtorDtor { | |
| TestCtorDtor() {} | |
| ~TestCtorDtor() {} | |
| }; | |
| int use(S s) { | |
| return f1(0) + f5(0) + f6(0) + A<int>::f9(); | |
| } | |
| // CHECK: @llvm{{(\.compiler)?}}.used = appending global [10 x ptr] | |
| // CHECK-DAG: define {{.*}}@_Z2f1i | |
| // CHECK-DAG: define internal {{.*}}@_ZL2f2i | |
| // CHECK-DAG: define {{.*}}@_Z2f3i | |
| // CHECK-DAG: define {{.*}}@_ZN1S2f4Ev | |
| // CHECK-DAG: define {{.*}}@_Z2f7i | |
| // CHECK-DAG: define {{.*}}@_Z2f8IiET_S0_ | |
| // CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorC1Ev | |
| // CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorD1Ev | |
| // CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorC2Ev | |
| // CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorD2Ev | |
| // FIXME: -mconstructor-aliases is enabled by default by the driver for this | |
| // target, but is not enabled by default for -cc1. With -mconstructor-aliases, | |
| // the C1/D1 constructor and destructor variants are not emitted as separate | |
| // definitions. | |
| // CONSTRUCTOR-ALIASES: @llvm{{(\.compiler)?}}.used = appending global [8 x ptr] | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_Z2f1i | |
| // CONSTRUCTOR-ALIASES-DAG: define internal {{.*}}@_ZL2f2i | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_Z2f3i | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_ZN1S2f4Ev | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_Z2f7i | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_Z2f8IiET_S0_ | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_ZN12TestCtorDtorC2Ev | |
| // CONSTRUCTOR-ALIASES-DAG: define {{.*}}@_ZN12TestCtorDtorD2Ev | |
| // MSVC: @llvm{{(\.compiler)?}}.used = appending global [8 x ptr] | |
| // MSVC-DAG: define {{.*}}@"?f1@@YAHH@Z" | |
| // MSVC-DAG: define internal {{.*}}@"?f2@@YAHH@Z" | |
| // MSVC-DAG: define {{.*}}@"?f3@@YAHH@Z" | |
| // MSVC-DAG: define {{.*}}@"?f4@S@@QEAAHXZ" | |
| // MSVC-DAG: define {{.*}}@"?f7@@YAHH@Z" | |
| // MSVC-DAG: define {{.*}}@"??$f8@H@@YAHH@Z" | |
| // MSVC-DAG: define {{.*}}@"??0TestCtorDtor@@QEAA@XZ" | |
| // MSVC-DAG: define {{.*}}@"??1TestCtorDtor@@QEAA@XZ" |