summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-06 09:23:02 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-06 09:23:02 +0000
commitd2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (patch)
tree7e0a88c3c6cb70271946aaa95a231b3da55d9f91 /lib/CodeGen/CodeGenModule.cpp
parentdf90325d4c0a65ee64d2dae3ed9b5b34f7418533 (diff)
downloadFreeBSD-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.cpp60
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);
OpenPOWER on IntegriCloud