diff options
author | Puyan Lotfi <puyan@puyan.org> | 2019-06-17 22:46:54 +0000 |
---|---|---|
committer | Puyan Lotfi <puyan@puyan.org> | 2019-06-17 22:46:54 +0000 |
commit | d9cb70af7cf60498423d776efcca80e30a3e233a (patch) | |
tree | 47d179841d7311fb2bbf4df8a6bb9088c0aa54f7 /test/InterfaceStubs | |
parent | d8450eac7b8a65d2332a074d4fdafbf4738a0b6b (diff) | |
download | clang-d9cb70af7cf60498423d776efcca80e30a3e233a.tar.gz |
[clang-ifs] Clang Interface Stubs, first version.
Clang interface stubs (previously referred to as clang-ifsos) is a new frontend
action in clang that allows the generation of stub files that contain mangled
name info that can be used to produce a stub library. These stub libraries can
be useful for breaking up build dependencies and controlling access to a
library's internal symbols. Generation of these stubs can be invoked by:
clang -fvisibility=<visibility> -emit-interface-stubs \
-interface-stub-version=<interface format>
Notice that -fvisibility (along with use of visibility attributes) can be used
to control what symbols get generated. Currently the interface format is
experimental but there are a wide range of possibilities here.
Differential Revision: https://reviews.llvm.org/D60974
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@363626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/InterfaceStubs')
-rw-r--r-- | test/InterfaceStubs/bad-format.cpp | 7 | ||||
-rw-r--r-- | test/InterfaceStubs/class-template-specialization.cpp | 42 | ||||
-rw-r--r-- | test/InterfaceStubs/externstatic.c | 29 | ||||
-rw-r--r-- | test/InterfaceStubs/function-template-specialization.cpp | 41 | ||||
-rw-r--r-- | test/InterfaceStubs/hidden-class-inheritance.cpp | 153 | ||||
-rw-r--r-- | test/InterfaceStubs/inline.c | 67 | ||||
-rw-r--r-- | test/InterfaceStubs/inline.h | 4 | ||||
-rw-r--r-- | test/InterfaceStubs/object.cpp | 13 | ||||
-rw-r--r-- | test/InterfaceStubs/template-namespace-function.cpp | 31 | ||||
-rw-r--r-- | test/InterfaceStubs/virtual.cpp | 41 | ||||
-rw-r--r-- | test/InterfaceStubs/visibility.cpp | 45 | ||||
-rw-r--r-- | test/InterfaceStubs/weak.cpp | 27 |
12 files changed, 500 insertions, 0 deletions
diff --git a/test/InterfaceStubs/bad-format.cpp b/test/InterfaceStubs/bad-format.cpp new file mode 100644 index 0000000000..d40b1f965b --- /dev/null +++ b/test/InterfaceStubs/bad-format.cpp @@ -0,0 +1,7 @@ +// RUN: not %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=bar-format %s 2>&1 | FileCheck %s + +// CHECK: error: invalid value +// CHECK: '-interface-stub-version=<experimental-tapi-elf-v1 | +// CHECK: experimental-yaml-elf-v1>' in 'Must specify a valid interface +// CHECK: stub format type using diff --git a/test/InterfaceStubs/class-template-specialization.cpp b/test/InterfaceStubs/class-template-specialization.cpp new file mode 100644 index 0000000000..d1f1d067cc --- /dev/null +++ b/test/InterfaceStubs/class-template-specialization.cpp @@ -0,0 +1,42 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-TAPI %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-TAPI2 %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | \ +// RUN: llvm-readelf -s - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s + +// For the following: +// g() +// n::S<int>::S() +// n::S<int>::~S() +// n::S<int>::func() const +// n::S<int>::S(n::S<int> const&) + +// We expect these manglings: +// CHECK-TAPI: Symbols: +// CHECK-TAPI-NOT: _ZNK1n1SIiEclEv +// CHECK-TAPI2: Symbols: +// CHECK-TAPI2: _Z1g + +// CHECK-SYMBOLS-DAG: FUNC GLOBAL DEFAULT {{[0-9]}} _Z1g +// CHECK-SYMBOLS-DAG: FUNC WEAK HIDDEN {{[0-9]}} _ZNK1n1SIiEclEv + +namespace n { +template <typename T> +struct __attribute__((__visibility__("default"))) S { + S() = default; + ~S() = default; + int __attribute__((__visibility__(("default")))) func() const { + return 1844; + } + int __attribute__((__visibility__(("hidden")))) operator()() const { + return 1863; + } +}; +} // namespace n + +void g() { n::S<int>()(); } diff --git a/test/InterfaceStubs/externstatic.c b/test/InterfaceStubs/externstatic.c new file mode 100644 index 0000000000..9224581ee0 --- /dev/null +++ b/test/InterfaceStubs/externstatic.c @@ -0,0 +1,29 @@ +// RUN: %clang -DSTORAGE="extern" -target x86_64-unknown-linux-gnu -o - \ +// RUN: -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=c99 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-EXTERN %s +// RUN: %clang -DSTORAGE="extern" -target x86_64-linux-gnu -O0 -o - -c -std=c99 \ +// RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-EXTERN %s + +// RUN: %clang -DSTORAGE="extern" -target x86_64-unknown-linux-gnu -o - \ +// RUN: -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=c99 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-EXTERN2 %s +// RUN: %clang -DSTORAGE="extern" -target x86_64-linux-gnu -O0 -o - -c -std=c99 \ +// RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-EXTERN2 %s + +// RUN: %clang -DSTORAGE="static" -target x86_64-unknown-linux-gnu -o - \ +// RUN: -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=c99 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-STATIC %s +// RUN: %clang -DSTORAGE="static" -target x86_64-linux-gnu -O0 -o - -c -std=c99 \ +// RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-STATIC %s + +// CHECK-EXTERN-NOT: foo +// CHECK-STATIC-NOT: foo +// CHECK-STATIC-NOT: bar + +// We want to emit extern function symbols. +// CHECK-EXTERN2: bar +STORAGE int foo; +STORAGE int bar() { return 42; } diff --git a/test/InterfaceStubs/function-template-specialization.cpp b/test/InterfaceStubs/function-template-specialization.cpp new file mode 100644 index 0000000000..b6cf64c602 --- /dev/null +++ b/test/InterfaceStubs/function-template-specialization.cpp @@ -0,0 +1,41 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | FileCheck %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DUSE_TEMPLATE_FUNCTION=1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-USES-TEMPLATE-FUNCTION %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DSPECIALIZE_TEMPLATE_FUNCTION=1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-SPECIALIZES-TEMPLATE-FUNCTION %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: %s | llvm-nm - 2>&1 | FileCheck %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: -DUSE_TEMPLATE_FUNCTION=1 %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-USES-TEMPLATE-FUNCTION %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: -DSPECIALIZE_TEMPLATE_FUNCTION=1 %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SPECIALIZES-TEMPLATE-FUNCTION %s + +// CHECK-NOT: _Z16templateFunctionIiET_S0_ +// CHECK-USES-TEMPLATE-FUNCTION-DAG: _Z16templateFunctionIiET_S0_ +// CHECK-SPECIALIZES-TEMPLATE-FUNCTION-DAG: _Z16templateFunctionIiET_S0_ +template <typename T> +T templateFunction(T t) { return t; } + +#ifdef USE_TEMPLATE_FUNCTION +int FortyTwo = templateFunction<int>(42); +#endif + +#ifdef SPECIALIZE_TEMPLATE_FUNCTION +template <> +int templateFunction<int>(int t); +// TODO: Make it so that -emit-interface-stubs does not emit +// _Z16templateFunctionIiET_S0_ if there is no user of the specialization. +int foo() { return templateFunction(42); } +#endif diff --git a/test/InterfaceStubs/hidden-class-inheritance.cpp b/test/InterfaceStubs/hidden-class-inheritance.cpp new file mode 100644 index 0000000000..de4c2993c7 --- /dev/null +++ b/test/InterfaceStubs/hidden-class-inheritance.cpp @@ -0,0 +1,153 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DPARENT_CLASS_VISIBILITY="" -DCHILD_CLASS_VISIBILITY="" \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: FileCheck -check-prefix=CHECK-X %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: -DPARENT_CLASS_VISIBILITY="" -DCHILD_CLASS_VISIBILITY="" \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: llvm-readelf -s - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-X-RE %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DPARENT_CLASS_VISIBILITY=HIDDEN -DCHILD_CLASS_VISIBILITY="" \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: FileCheck -check-prefix=CHECK-HP %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DPARENT_CLASS_VISIBILITY=HIDDEN -DCHILD_CLASS_VISIBILITY="" \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: FileCheck -check-prefix=CHECK-HP2 %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: -DPARENT_CLASS_VISIBILITY=HIDDEN -DCHILD_CLASS_VISIBILITY="" \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: llvm-readelf -s - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-HP-RE %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DPARENT_CLASS_VISIBILITY="" -DCHILD_CLASS_VISIBILITY=HIDDEN \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: FileCheck -check-prefix=CHECK-HC %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DPARENT_CLASS_VISIBILITY="" -DCHILD_CLASS_VISIBILITY=HIDDEN \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: FileCheck -check-prefix=CHECK-HC2 %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: -DPARENT_CLASS_VISIBILITY="" -DCHILD_CLASS_VISIBILITY=HIDDEN \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: llvm-readelf -s - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-HC-RE %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -DPARENT_CLASS_VISIBILITY=HIDDEN -DCHILD_CLASS_VISIBILITY=HIDDEN \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: FileCheck -check-prefix=CHECK-HP-HC %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c \ +// RUN: -DPARENT_CLASS_VISIBILITY=HIDDEN -DCHILD_CLASS_VISIBILITY=HIDDEN \ +// RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ +// RUN: llvm-readelf -s - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-HP-HC-RE %s + +// CHECK-X-DAG: _ZN1CC2Ev +// CHECK-X-DAG: _ZN1CD0Ev +// CHECK-X-DAG: _ZN1CD2Ev +// CHECK-X-DAG: _ZN1SC2Ev +// CHECK-X-DAG: _ZN1SD0Ev +// CHECK-X-DAG: _ZN1SD2Ev +// CHECK-X-DAG: _ZN1C1mEv +// CHECK-X-DAG: _ZN1S1nEv + +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1C1mEv +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1CC2Ev +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1CD0Ev +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1CD2Ev +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1S1nEv +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1SC2Ev +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1SD0Ev +// CHECK-X-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1SD2Ev + +// CHECK-HP2-DAG: _ZN1CC2Ev +// CHECK-HP2-DAG: _ZN1CD0Ev +// CHECK-HP2-DAG: _ZN1CD2Ev +// CHECK-HP2-DAG: _ZN1C1mEv + +// CHECK-HP-NOT: _ZN1S1nEv +// CHECK-HP-NOT: _ZN1SC2Ev +// CHECK-HP-NOT: _ZN1SD0Ev +// CHECK-HP-NOT: _ZN1SD2Ev + +// CHECK-HP-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1C1mEv +// CHECK-HP-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1CC2Ev +// CHECK-HP-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1CD0Ev +// CHECK-HP-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1CD2Ev +// CHECK-HP-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1S1nEv +// CHECK-HP-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1SC2Ev +// CHECK-HP-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1SD0Ev +// CHECK-HP-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1SD2Ev + +// CHECK-HC2-DAG: _ZN1SC2Ev +// CHECK-HC2-DAG: _ZN1SD0Ev +// CHECK-HC2-DAG: _ZN1SD2Ev +// CHECK-HC2-DAG: _ZN1S1nEv + +// CHECK-HC-NOT: _ZN1C1mEv +// CHECK-HC-NOT: _ZN1CC2Ev +// CHECK-HC-NOT: _ZN1CD0Ev +// CHECK-HC-NOT: _ZN1CD2Ev + +// CHECK-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1C1mEv +// CHECK-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1CC2Ev +// CHECK-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1CD0Ev +// CHECK-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1CD2Ev +// CHECK-HC-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1S1nEv +// CHECK-HC-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1SC2Ev +// CHECK-HC-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1SD0Ev +// CHECK-HC-RE: FUNC WEAK DEFAULT {{[0-9]+}} _ZN1SD2Ev + +// CHECK-HP-HC-NOT: _ZN1CC2Ev +// CHECK-HP-HC-NOT: _ZN1CD0Ev +// CHECK-HP-HC-NOT: _ZN1CD2Ev +// CHECK-HP-HC-NOT: _ZN1SC2Ev +// CHECK-HP-HC-NOT: _ZN1SD0Ev +// CHECK-HP-HC-NOT: _ZN1SD2Ev +// CHECK-HP-HC-NOT: _ZN1C1mEv +// CHECK-HP-HC-NOT: _ZN1S1nEv + +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1C1mEv +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1CC2Ev +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1CD0Ev +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1CD2Ev +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1S1nEv +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1SC2Ev +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1SD0Ev +// CHECK-HP-HC-RE: FUNC WEAK HIDDEN {{[0-9]+}} _ZN1SD2Ev + +// TODO: clang+llvm does not materialize complete ctors and dtors for the +// Itanium abi. Figure out why and add the check-not for these: +// _ZN1CC1Ev +// _ZN1CD1Ev +// _ZN1SC1Ev +// _ZN1SD1Ev + +#define HIDDEN __attribute__((__visibility__("hidden"))) +#define DEFAULT __attribute__((__visibility__("default"))) + +struct PARENT_CLASS_VISIBILITY S { + virtual ~S() {} + virtual PARENT_METHOD_VISIBILITY void n() {} +}; + +class CHILD_CLASS_VISIBILITY C : public S { +public: + virtual CHILD_METHOD_VISIBILITY void m() {} +}; + +void f() { + C c; + c.m(); + c.n(); +} diff --git a/test/InterfaceStubs/inline.c b/test/InterfaceStubs/inline.c new file mode 100644 index 0000000000..c64771185f --- /dev/null +++ b/test/InterfaceStubs/inline.c @@ -0,0 +1,67 @@ +// RUN: %clang -DINLINE=inline -target x86_64-unknown-linux-gnu -o - \ +// RUN: -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=gnu89 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-GNU %s +// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -O0 -o - -c \ +// RUN: -std=gnu89 -xc %s | llvm-nm - | FileCheck -check-prefix=CHECK-GNU %s + +// RUN: %clang -DINLINE="__attribute__((always_inline))" \ +// RUN: -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-GNU %s +// RUN: %clang -DINLINE="__attribute__((always_inline))" \ +// RUN: -target x86_64-linux-gnu -O0 -o - -c -xc %s | \ +// RUN: llvm-nm - | FileCheck -check-prefix=CHECK-GNU %s + +// RUN: %clang -DINLINE=inline -target x86_64-unknown-linux-gnu -o - \ +// RUN: -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=c99 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-STD %s +// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -O0 -o - -c -std=c99 \ +// RUN: -xc %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-STD %s + +// RUN: %clang -DINLINE="__attribute__((noinline))" \ +// RUN: -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=c99 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-NOINLINE %s +// RUN: %clang -DINLINE="__attribute__((noinline))" -target x86_64-linux-gnu \ +// RUN: -O0 -o - -c -std=c99 -xc %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-NOINLINE %s + +// RUN: %clang -DINLINE="static" -target x86_64-unknown-linux-gnu -o - \ +// RUN: -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -std=c99 -xc %s | \ +// RUN: FileCheck -check-prefix=CHECK-STATIC %s +// RUN: %clang -DINLINE="static" -target x86_64-linux-gnu -O0 -o - -c \ +// RUN: -std=c99 -xc %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-STATIC %s + +// CHECK-GNU-DAG: foo +// CHECK-GNU-DAG: foo.var +// CHECK-NOINLINE-DAG: foo +// CHECK-NOINLINE-DAG: foo.var +// CHECK-STATIC-NOT: foo +// CHECK-STATIC-NOT: foo.var +// CHECK-STD-NOT: foo +#pragma clang diagnostic ignored "-Wstatic-local-in-inline" +INLINE int foo() { + static int var = 42; + return var; +} + +// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -o - \ +// RUN: -emit-interface-stubs -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -std=gnu89 -xc %s | FileCheck -check-prefix=CHECK-TAPI %s + +// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -o - \ +// RUN: -emit-interface-stubs -interface-stub-version=experimental-tapi-elf-v1 \ +// RUN: -std=gnu89 -xc %s | FileCheck -check-prefix=CHECK-SYMBOLS %s +// RUN: %clang -DINLINE=inline -target x86_64-linux-gnu -o - \ +// RUN: -c -std=gnu89 -xc %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s + +// CHECK-TAPI-DAG: foo: { Type: Func } +// CHECK-TAPI-DAG: foo.var: { Type: Object, Size: 4 } +// CHECK-SYMBOLS-DAG: foo +// CHECK-SYMBOLS-DAG: foo.var +#include "inline.h" diff --git a/test/InterfaceStubs/inline.h b/test/InterfaceStubs/inline.h new file mode 100644 index 0000000000..fe16519e94 --- /dev/null +++ b/test/InterfaceStubs/inline.h @@ -0,0 +1,4 @@ +INLINE int bar() { + static int var = 42; + return var; +} diff --git a/test/InterfaceStubs/object.cpp b/test/InterfaceStubs/object.cpp new file mode 100644 index 0000000000..68b5ee781c --- /dev/null +++ b/test/InterfaceStubs/object.cpp @@ -0,0 +1,13 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-TAPI %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s + +// CHECK-TAPI: data: { Type: Object, Size: 4 } +// CHECK-SYMBOLS: data +int data = 42; diff --git a/test/InterfaceStubs/template-namespace-function.cpp b/test/InterfaceStubs/template-namespace-function.cpp new file mode 100644 index 0000000000..879318122b --- /dev/null +++ b/test/InterfaceStubs/template-namespace-function.cpp @@ -0,0 +1,31 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s + +// CHECK: Symbols: +// CHECK-DAG: _ZN3qux3barEii: { Type: Func } +// CHECK-DAG: _ZN3baz3addIiEET_S1_S1_: { Type: Func } +// CHECK-DAG: _Z4fbarff: { Type: Func } +// CHECK-DAG: _ZN3baz3addIfEET_S1_S1_: { Type: Func } + +// Same symbols just different order. +// CHECK-SYMBOLS-DAG: _Z4fbarff +// CHECK-SYMBOLS-DAG: _ZN3baz3addIfEET_S1_S1_ +// CHECK-SYMBOLS-DAG: _ZN3baz3addIiEET_S1_S1_ +// CHECK-SYMBOLS-DAG: _ZN3qux3barEii + +namespace baz { +template <typename T> +T add(T a, T b) { + return a + b; +} +} // namespace baz + +namespace qux { +int bar(int a, int b) { return baz::add<int>(a, b); } +} // namespace qux + +float fbar(float a, float b) { return baz::add<float>(a, b); } diff --git a/test/InterfaceStubs/virtual.cpp b/test/InterfaceStubs/virtual.cpp new file mode 100644 index 0000000000..b861b7e802 --- /dev/null +++ b/test/InterfaceStubs/virtual.cpp @@ -0,0 +1,41 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-TAPI %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck -check-prefix=CHECK-TAPI2 %s +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | \ +// RUN: llvm-readelf -s - 2>&1 | FileCheck -check-prefix=CHECK-SYMBOLS %s + +#define HIDDEN __attribute__((__visibility__(("hidden")))) +#define DEFAULT __attribute__((__visibility__(("default")))) + +// CHECK-TAPI-NOT: _ZNK1Q5func1Ev +// CHECK-TAPI-NOT: _ZNK1Q5func2Ev +// CHECK-SYMBOLS-DAG: NOTYPE GLOBAL HIDDEN {{.*}} _ZNK1Q5func1Ev +// CHECK-SYMBOLS-DAG: NOTYPE GLOBAL DEFAULT {{.*}} _ZNK1Q5func2Ev +struct Q { + virtual HIDDEN int func1() const; + virtual DEFAULT int func2() const; +} q; + +// CHECK-TAPI-NOT: _ZNK1S5func1Ev +// CHECK-TAPI2-DAG: _ZNK1S5func2Ev +// CHECK-SYMBOLS-DAG: FUNC WEAK HIDDEN {{.*}} _ZNK1S5func1Ev +// CHECK-SYMBOLS-DAG: FUNC WEAK DEFAULT {{.*}} _ZNK1S5func2Ev +struct S { + virtual HIDDEN int func1() const { return 42; } + virtual DEFAULT int func2() const { return 42; } +} s; + +// CHECK-TAPI-NOT: _ZNK1R5func1Ev +// CHECK-TAPI-NOT: _ZNK1R5func2Ev +// CHECK-SYMBOLS-NOT: _ZNK1R5func1Ev +// CHECK-SYMBOLS-NOT: _ZNK1R5func2Ev +struct R { + virtual HIDDEN int func1() const = 0; + virtual DEFAULT int func2() const = 0; +}; + +int a = q.func1() + q.func2(); + diff --git a/test/InterfaceStubs/visibility.cpp b/test/InterfaceStubs/visibility.cpp new file mode 100644 index 0000000000..87ea7ea7bd --- /dev/null +++ b/test/InterfaceStubs/visibility.cpp @@ -0,0 +1,45 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 -fvisibility=hidden \ +// RUN: %s | FileCheck --check-prefix=CHECK-CMD-HIDDEN %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 -fvisibility=hidden \ +// RUN: %s | FileCheck --check-prefix=CHECK-CMD-HIDDEN %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck --check-prefix=CHECK-CMD %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 %s | \ +// RUN: FileCheck --check-prefix=CHECK-CMD %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck --check-prefix=CHECK-CMD2 %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 %s | \ +// RUN: FileCheck --check-prefix=CHECK-CMD2 %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | llvm-readelf -s - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s + +// Always Be Hidden: +// CHECK-CMD-HIDDEN-NOT: _Z6hiddenv +// CHECK-CMD2-NOT: _Z6hiddenv +__attribute__((visibility("hidden"))) void hidden() {} + +// Always Be Visible: +// CHECK-CMD-HIDDEN: _Z9nothiddenv +// CHECK-CMD-DAG: _Z9nothiddenv +__attribute__((visibility("default"))) void nothidden() {} + +// Do Whatever -fvisibility says: +// CHECK-CMD-HIDDEN-NOT: _Z10cmdVisiblev +// CHECK-CMD-DAG: _Z10cmdVisiblev +void cmdVisible() {} + +// CHECK-SYMBOLS-DAG: DEFAULT {{.*}} _Z10cmdVisiblev +// CHECK-SYMBOLS-DAG: HIDDEN {{.*}} _Z6hiddenv +// CHECK-SYMBOLS-DAG: DEFAULT {{.*}} _Z9nothiddenv diff --git a/test/InterfaceStubs/weak.cpp b/test/InterfaceStubs/weak.cpp new file mode 100644 index 0000000000..e089225b5d --- /dev/null +++ b/test/InterfaceStubs/weak.cpp @@ -0,0 +1,27 @@ +// RUN: %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-tapi-elf-v1 %s | \ +// RUN: FileCheck %s + +// RUN: %clang -target x86_64-linux-gnu -o - -emit-interface-stubs \ +// RUN: -interface-stub-version=experimental-yaml-elf-v1 %s | \ +// RUN: FileCheck --check-prefix=CHECK-YAML %s + +// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | llvm-nm - 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s + +// CHECK: Symbols: +// CHECK-DAG: _Z8weakFuncv: { Type: Func, Weak: true } +// CHECK-DAG: _Z10strongFuncv: { Type: Func } + +// CHECK-YAML: Symbols: +// CHECK-YAML-DAG: - Name: _Z8weakFuncv +// CHECK-YAML-DAG: Type: STT_FUNC +// CHECK-YAML-DAG: Binding: STB_WEAK +// CHECK-YAML-DAG: - Name: _Z10strongFuncv +// CHECK-YAML-DAG: Type: STT_FUNC +// CHECK-YAML-DAG: Binding: STB_GLOBAL + +// CHECK-SYMBOLS-DAG: _Z10strongFuncv +// CHECK-SYMBOLS-DAG: _Z8weakFuncv +__attribute__((weak)) void weakFunc() {} +int strongFunc() { return 42; } |