Fix PR6473.
Clang's support for weakref is now better than llvm-gcc's :-) We don't introduce a new symbol and we correctly mark undefined references weak only if there is no definition or regular undefined references in the same file. llvm-svn: 97733
This commit is contained in:
@@ -619,9 +619,41 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::Constant *CodeGenModule::GetWeakRefReference(const ValueDecl *VD) {
|
||||
const AliasAttr *AA = VD->getAttr<AliasAttr>();
|
||||
assert(AA && "No alias?");
|
||||
|
||||
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(VD->getType());
|
||||
|
||||
// Unique the name through the identifier table.
|
||||
const char *AliaseeName =
|
||||
getContext().Idents.get(AA->getAliasee()).getNameStart();
|
||||
|
||||
// See if there is already something with the target's name in the module.
|
||||
llvm::GlobalValue *Entry = GlobalDeclMap[AliaseeName];
|
||||
|
||||
llvm::Constant *Aliasee;
|
||||
if (isa<llvm::FunctionType>(DeclTy))
|
||||
Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl());
|
||||
else
|
||||
Aliasee = GetOrCreateLLVMGlobal(AliaseeName,
|
||||
llvm::PointerType::getUnqual(DeclTy), 0);
|
||||
if (!Entry) {
|
||||
llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
|
||||
F->setLinkage(llvm::Function::ExternalWeakLinkage);
|
||||
WeakRefReferences.insert(F);
|
||||
}
|
||||
|
||||
return Aliasee;
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitGlobal(GlobalDecl GD) {
|
||||
const ValueDecl *Global = cast<ValueDecl>(GD.getDecl());
|
||||
|
||||
// Weak references don't produce any output by themselves.
|
||||
if (Global->hasAttr<WeakRefAttr>())
|
||||
return;
|
||||
|
||||
// If this is an alias definition (which otherwise looks like a declaration)
|
||||
// emit it now.
|
||||
if (Global->hasAttr<AliasAttr>())
|
||||
@@ -708,6 +740,14 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
|
||||
// Lookup the entry, lazily creating it if necessary.
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
if (Entry) {
|
||||
if (WeakRefReferences.count(Entry)) {
|
||||
const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl());
|
||||
if (FD && !FD->hasAttr<WeakAttr>())
|
||||
Entry->setLinkage(llvm::Function::ExternalLinkage);
|
||||
|
||||
WeakRefReferences.erase(Entry);
|
||||
}
|
||||
|
||||
if (Entry->getType()->getElementType() == Ty)
|
||||
return Entry;
|
||||
|
||||
@@ -817,6 +857,13 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
|
||||
// Lookup the entry, lazily creating it if necessary.
|
||||
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
|
||||
if (Entry) {
|
||||
if (WeakRefReferences.count(Entry)) {
|
||||
if (D && !D->hasAttr<WeakAttr>())
|
||||
Entry->setLinkage(llvm::Function::ExternalLinkage);
|
||||
|
||||
WeakRefReferences.erase(Entry);
|
||||
}
|
||||
|
||||
if (Entry->getType() == Ty)
|
||||
return Entry;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user