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:
Rafael Espindola
2010-03-04 18:17:24 +00:00
parent 334db0ce7f
commit 2e42fec3a0
6 changed files with 174 additions and 6 deletions

View File

@@ -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;