Skip to content
Snippets Groups Projects
Commit 99d28350 authored by Daniel Dunbar's avatar Daniel Dunbar
Browse files

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).

llvm-svn: 66512
parent d9c90a73
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment