diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-06 09:23:02 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-06 09:23:02 +0000 |
commit | d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (patch) | |
tree | 7e0a88c3c6cb70271946aaa95a231b3da55d9f91 /lib/CodeGen/CodeGenModule.cpp | |
parent | df90325d4c0a65ee64d2dae3ed9b5b34f7418533 (diff) | |
download | FreeBSD-src-d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9.zip FreeBSD-src-d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9.tar.gz |
Update clang to r97873.
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 91c7322..d6a56da 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -33,6 +33,7 @@ #include "llvm/Module.h" #include "llvm/Intrinsics.h" #include "llvm/LLVMContext.h" +#include "llvm/ADT/Triple.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -89,6 +90,10 @@ void CodeGenModule::Release() { EmitLLVMUsed(); } +bool CodeGenModule::isTargetDarwin() const { + return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin; +} + /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified stmt yet. void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, @@ -619,9 +624,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 +745,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; @@ -753,17 +798,17 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, // synthesized. else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { if (CD->isImplicit()) { - assert (CD->isUsed()); + assert(CD->isUsed() && "Sema doesn't consider constructor as used."); DeferredDeclsToEmit.push_back(D); } } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { if (DD->isImplicit()) { - assert (DD->isUsed()); + assert(DD->isUsed() && "Sema doesn't consider destructor as used."); DeferredDeclsToEmit.push_back(D); } } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { if (MD->isCopyAssignment() && MD->isImplicit()) { - assert (MD->isUsed()); + assert(MD->isUsed() && "Sema doesn't consider CopyAssignment as used."); DeferredDeclsToEmit.push_back(D); } } @@ -817,6 +862,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; @@ -1203,7 +1255,7 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD); - + getMangleContext().mangleInitDiscriminator(); // Get or create the prototype for the function. llvm::Constant *Entry = GetAddrOfFunction(GD, Ty); |