forked from OSchip/llvm-project
Use aliases for more constructors and destructors.
With this patch we produce alias for cases like template<typename T> struct foobar { foobar() { } }; template struct foobar<void>; It is safe to use aliases to weak symbols, as long and the alias itself is also weak. llvm-svn: 192300
This commit is contained in:
parent
ee863cedc2
commit
a25c79e704
|
@ -108,32 +108,17 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
|||
// support aliases with that linkage, fail.
|
||||
llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
|
||||
|
||||
switch (Linkage) {
|
||||
// We can definitely emit aliases to definitions with external linkage.
|
||||
case llvm::GlobalValue::ExternalLinkage:
|
||||
case llvm::GlobalValue::ExternalWeakLinkage:
|
||||
break;
|
||||
|
||||
// Same with local linkage.
|
||||
case llvm::GlobalValue::InternalLinkage:
|
||||
case llvm::GlobalValue::PrivateLinkage:
|
||||
case llvm::GlobalValue::LinkerPrivateLinkage:
|
||||
break;
|
||||
|
||||
// We should try to support linkonce linkages.
|
||||
case llvm::GlobalValue::LinkOnceAnyLinkage:
|
||||
case llvm::GlobalValue::LinkOnceODRLinkage:
|
||||
// We can't use an alias if the linkage is not valid for one.
|
||||
if (!llvm::GlobalAlias::isValidLinkage(Linkage))
|
||||
return true;
|
||||
|
||||
// Other linkages will probably never be supported.
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes TargetLinkage
|
||||
= getFunctionLinkage(TargetDecl);
|
||||
|
||||
if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
|
||||
// Don't create an strong alias to a linker weak symbol. If the linker
|
||||
// decides to drop the symbol, the alias would become undefined.
|
||||
if (llvm::GlobalValue::isWeakForLinker(TargetLinkage) &&
|
||||
!llvm::GlobalValue::isWeakForLinker(Linkage))
|
||||
return true;
|
||||
|
||||
// Derive the type for the alias.
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
// CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
|
||||
// CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
|
||||
|
||||
// CHECK: @_ZN6test106foobarIvEC1Ev = alias weak_odr void (%"struct.test10::foobar"*)* @_ZN6test106foobarIvEC2Ev
|
||||
|
||||
// CHECK: @_ZN6test116foobarIvEC1Ev = alias linkonce_odr void (%"struct.test11::foobar"*)* @_ZN6test116foobarIvEC2Ev
|
||||
|
||||
// CHECK: @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
|
||||
// CHECK: @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
|
||||
// CHECK: @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
|
||||
|
||||
// CHECK: @_ZN6PR752617allocator_derivedD1Ev = alias linkonce_odr void (%"struct.PR7526::allocator_derived"*)* @_ZN6PR752617allocator_derivedD2Ev
|
||||
|
||||
struct A {
|
||||
int a;
|
||||
|
||||
|
@ -44,9 +50,6 @@ namespace PR7526 {
|
|||
// CHECK: call void @__cxa_call_unexpected
|
||||
allocator::~allocator() throw() { foo(); }
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev(%"struct.PR7526::allocator_derived"* %this) unnamed_addr
|
||||
// CHECK-NOT: call void @__cxa_call_unexpected
|
||||
// CHECK: }
|
||||
void foo() {
|
||||
allocator_derived ad;
|
||||
}
|
||||
|
@ -419,3 +422,25 @@ namespace test9 {
|
|||
// CHECK: ret void
|
||||
|
||||
// CHECK: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}}
|
||||
|
||||
|
||||
namespace test10 {
|
||||
template<typename T>
|
||||
struct foobar {
|
||||
foobar() {
|
||||
}
|
||||
};
|
||||
|
||||
template struct foobar<void>;
|
||||
}
|
||||
|
||||
namespace test11 {
|
||||
void g();
|
||||
template<typename T>
|
||||
struct foobar {
|
||||
foobar() {
|
||||
g();
|
||||
}
|
||||
};
|
||||
foobar<void> x;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue