aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-03-09 23:53:08 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-03-09 23:53:08 +0000
commit42745815fa4e90bfb07e581d2e5152b2c2db08ff (patch)
treeef7baf6b3c967280a8bfab6bc08ce17c8ed77c7e
parent1a873ae65f8814eae6c9b8786f164ce70c645a21 (diff)
Backout r66408, we don't want handling of globals to rely on the
module symbol table. The root problem inspiring this was fixed in r66316 (and again in r66506). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66512 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenModule.cpp68
-rw-r--r--lib/CodeGen/CodeGenModule.h29
2 files changed, 45 insertions, 52 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 41784cbb81..16ba94791f 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -788,8 +788,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::GlobalValue *
CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
- const llvm::Type *Ty,
- bool ReplaceExisting) {
+ const llvm::Type *Ty) {
bool DoSetAttributes = true;
if (!Ty) {
Ty = getTypes().ConvertType(D->getType());
@@ -802,13 +801,10 @@ CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
DoSetAttributes = false;
}
}
- const char *Name = getMangledName(D);
- llvm::Function *F = getModule().getFunction(Name);
- if (ReplaceExisting || !F || !F->hasExternalLinkage())
- F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
- llvm::Function::ExternalLinkage,
- Name,
- &getModule());
+ llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
+ llvm::Function::ExternalLinkage,
+ getMangledName(D),
+ &getModule());
if (DoSetAttributes)
SetFunctionAttributes(D, F);
return F;
@@ -842,33 +838,33 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
if (!Entry) {
Entry = EmitForwardFunctionDefinition(D, Ty);
- }
-
- // If the types mismatch then we have to rewrite the definition.
- if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
- // Otherwise, we have a definition after a prototype with the
- // wrong type. F is the Function* for the one with the wrong
- // type, we must make a new Function* and update everything that
- // used F (a declaration) with the new Function* (which will be
- // a definition).
- //
- // This happens if there is a prototype for a function
- // (e.g. "int f()") and then a definition of a different type
- // (e.g. "int f(int x)"). Start by making a new function of the
- // correct type, RAUW, then steal the name.
- llvm::GlobalValue *NewFn = EmitForwardFunctionDefinition(D, Ty, true);
- NewFn->takeName(Entry);
-
- // Replace uses of F with the Function we will endow with a body.
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
- Entry->replaceAllUsesWith(NewPtrForOldDecl);
-
- // Ok, delete the old function now, which is dead.
- assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
- Entry->eraseFromParent();
-
- Entry = NewFn;
+ } else {
+ // If the types mismatch then we have to rewrite the definition.
+ if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
+ // Otherwise, we have a definition after a prototype with the
+ // wrong type. F is the Function* for the one with the wrong
+ // type, we must make a new Function* and update everything that
+ // used F (a declaration) with the new Function* (which will be
+ // a definition).
+ //
+ // This happens if there is a prototype for a function
+ // (e.g. "int f()") and then a definition of a different type
+ // (e.g. "int f(int x)"). Start by making a new function of the
+ // correct type, RAUW, then steal the name.
+ llvm::GlobalValue *NewFn = EmitForwardFunctionDefinition(D, Ty);
+ NewFn->takeName(Entry);
+
+ // Replace uses of F with the Function we will endow with a body.
+ llvm::Constant *NewPtrForOldDecl =
+ llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
+ Entry->replaceAllUsesWith(NewPtrForOldDecl);
+
+ // Ok, delete the old function now, which is dead.
+ assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
+ Entry->eraseFromParent();
+
+ Entry = NewFn;
+ }
}
llvm::Function *Fn = cast<llvm::Function>(Entry);
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 039579ffc5..c3a84af0c5 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -312,17 +312,14 @@ private:
void EmitGlobalDefinition(const ValueDecl *D);
- /// EmitForwardFunctionDefinition - Create a new function for the given decl
- /// and set attributes as appropriate if ReplaceExisting is true, or if the
- /// same named declaration doesn't already exist in the module table,
- /// otherwise return the existing function from the module table.
+ /// EmitForwardFunctionDefinition - Create a new function for the
+ /// given decl and set attributes as appropriate.
///
- /// \arg Ty - If non-null the LLVM function type to use for the decl; it is
- /// the callers responsibility to make sure this is compatible with the
- /// correct type.
+ /// \arg Ty - If non-null the LLVM function type to use for the
+ /// decl; it is the callers responsibility to make sure this is
+ /// compatible with the correct type.
llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D,
- const llvm::Type *Ty,
- bool ReplaceExisting=false);
+ const llvm::Type *Ty);
void EmitGlobalFunctionDefinition(const FunctionDecl *D);
void EmitGlobalVarDefinition(const VarDecl *D);
@@ -340,19 +337,19 @@ private:
void EmitAliases(void);
void EmitAnnotations(void);
- /// EmitDeferred - Emit any needed decls for which code generation was
- /// deferred.
+ /// EmitDeferred - Emit any needed decls for which code generation
+ /// was deferred.
void EmitDeferred(void);
- /// EmitLLVMUsed - Emit the llvm.used metadata used to force references to
- /// global which may otherwise be optimized out.
+ /// EmitLLVMUsed - Emit the llvm.used metadata used to force
+ /// references to global which may otherwise be optimized out.
void EmitLLVMUsed(void);
void BindRuntimeGlobals();
- /// MayDeferGeneration - Determine if the given decl can be emitted lazily;
- /// this is only relevant for definitions. The given decl must be either a
- /// function or var decl.
+ /// MayDeferGeneration - Determine if the given decl can be emitted
+ /// lazily; this is only relevant for definitions. The given decl
+ /// must be either a function or var decl.
bool MayDeferGeneration(const ValueDecl *D);
};
} // end namespace CodeGen