We would previously fail to emit a definition of bar() for the following code:
struct __declspec(dllexport) S {
void foo() {
t->bar();
}
struct T {
void bar() {}
};
T *t;
};
Note that foo() is an exported method, but bar() is not. However, foo() refers
to bar() so we need to emit its definition. We would previously fail to
realise that bar() is used.
By deferring the method definitions until the end of the top level declaration,
we can simply call EmitTopLevelDecl on them and rely on the usual mechanisms
to decide whether the method should be emitted or not.
Differential Revision: http://reviews.llvm.org/D4038
llvm-svn: 210356
28 lines
874 B
C++
28 lines
874 B
C++
// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
|
|
|
|
// <rdar://problem/8684363>: clang++ not respecting __attribute__((used)) on destructors
|
|
struct X0 {
|
|
// CHECK: define linkonce_odr {{.*}} @_ZN2X0C1Ev
|
|
__attribute__((used)) X0() {}
|
|
// CHECK: define linkonce_odr {{.*}} @_ZN2X0D1Ev
|
|
__attribute__((used)) ~X0() {}
|
|
};
|
|
|
|
// PR19743: not emitting __attribute__((used)) inline methods in nested classes.
|
|
struct X1 {
|
|
struct Nested {
|
|
// CHECK: define linkonce_odr {{.*}} @_ZN2X16Nested1fEv
|
|
void __attribute__((used)) f() {}
|
|
};
|
|
};
|
|
|
|
struct X2 {
|
|
// We must delay emission of bar() until foo() has had its body parsed,
|
|
// otherwise foo() would not be emitted.
|
|
void __attribute__((used)) bar() { foo(); }
|
|
void foo() { }
|
|
|
|
// CHECK: define linkonce_odr {{.*}} @_ZN2X23barEv
|
|
// CHECK: define linkonce_odr {{.*}} @_ZN2X23fooEv
|
|
};
|