diff options
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bc2bd6c882d..e6e9b1a595e 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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; |