forked from OSchip/llvm-project
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
This commit is contained in:
parent
d9c90a7317
commit
99d2835099
|
@ -788,8 +788,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
||||||
|
|
||||||
llvm::GlobalValue *
|
llvm::GlobalValue *
|
||||||
CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
|
CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
|
||||||
const llvm::Type *Ty,
|
const llvm::Type *Ty) {
|
||||||
bool ReplaceExisting) {
|
|
||||||
bool DoSetAttributes = true;
|
bool DoSetAttributes = true;
|
||||||
if (!Ty) {
|
if (!Ty) {
|
||||||
Ty = getTypes().ConvertType(D->getType());
|
Ty = getTypes().ConvertType(D->getType());
|
||||||
|
@ -802,13 +801,10 @@ CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D,
|
||||||
DoSetAttributes = false;
|
DoSetAttributes = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char *Name = getMangledName(D);
|
llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
|
||||||
llvm::Function *F = getModule().getFunction(Name);
|
llvm::Function::ExternalLinkage,
|
||||||
if (ReplaceExisting || !F || !F->hasExternalLinkage())
|
getMangledName(D),
|
||||||
F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
|
&getModule());
|
||||||
llvm::Function::ExternalLinkage,
|
|
||||||
Name,
|
|
||||||
&getModule());
|
|
||||||
if (DoSetAttributes)
|
if (DoSetAttributes)
|
||||||
SetFunctionAttributes(D, F);
|
SetFunctionAttributes(D, F);
|
||||||
return F;
|
return F;
|
||||||
|
@ -842,33 +838,33 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) {
|
||||||
llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
|
llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)];
|
||||||
if (!Entry) {
|
if (!Entry) {
|
||||||
Entry = EmitForwardFunctionDefinition(D, Ty);
|
Entry = EmitForwardFunctionDefinition(D, Ty);
|
||||||
}
|
} else {
|
||||||
|
// If the types mismatch then we have to rewrite the definition.
|
||||||
// If the types mismatch then we have to rewrite the definition.
|
if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
|
||||||
if (Entry->getType() != llvm::PointerType::getUnqual(Ty)) {
|
// Otherwise, we have a definition after a prototype with the
|
||||||
// Otherwise, we have a definition after a prototype with the
|
// wrong type. F is the Function* for the one with the wrong
|
||||||
// wrong type. F is the Function* for the one with the wrong
|
// type, we must make a new Function* and update everything that
|
||||||
// type, we must make a new Function* and update everything that
|
// used F (a declaration) with the new Function* (which will be
|
||||||
// used F (a declaration) with the new Function* (which will be
|
// a definition).
|
||||||
// a definition).
|
//
|
||||||
//
|
// This happens if there is a prototype for a function
|
||||||
// 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()") and then a definition of a different type
|
// (e.g. "int f(int x)"). Start by making a new function of the
|
||||||
// (e.g. "int f(int x)"). Start by making a new function of the
|
// correct type, RAUW, then steal the name.
|
||||||
// correct type, RAUW, then steal the name.
|
llvm::GlobalValue *NewFn = EmitForwardFunctionDefinition(D, Ty);
|
||||||
llvm::GlobalValue *NewFn = EmitForwardFunctionDefinition(D, Ty, true);
|
NewFn->takeName(Entry);
|
||||||
NewFn->takeName(Entry);
|
|
||||||
|
// Replace uses of F with the Function we will endow with a body.
|
||||||
// Replace uses of F with the Function we will endow with a body.
|
llvm::Constant *NewPtrForOldDecl =
|
||||||
llvm::Constant *NewPtrForOldDecl =
|
llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
|
||||||
llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
|
Entry->replaceAllUsesWith(NewPtrForOldDecl);
|
||||||
Entry->replaceAllUsesWith(NewPtrForOldDecl);
|
|
||||||
|
// Ok, delete the old function now, which is dead.
|
||||||
// Ok, delete the old function now, which is dead.
|
assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
|
||||||
assert(Entry->isDeclaration() && "Shouldn't replace non-declaration");
|
Entry->eraseFromParent();
|
||||||
Entry->eraseFromParent();
|
|
||||||
|
Entry = NewFn;
|
||||||
Entry = NewFn;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function *Fn = cast<llvm::Function>(Entry);
|
llvm::Function *Fn = cast<llvm::Function>(Entry);
|
||||||
|
|
|
@ -312,17 +312,14 @@ private:
|
||||||
|
|
||||||
void EmitGlobalDefinition(const ValueDecl *D);
|
void EmitGlobalDefinition(const ValueDecl *D);
|
||||||
|
|
||||||
/// EmitForwardFunctionDefinition - Create a new function for the given decl
|
/// EmitForwardFunctionDefinition - Create a new function for the
|
||||||
/// and set attributes as appropriate if ReplaceExisting is true, or if the
|
/// given decl and set attributes as appropriate.
|
||||||
/// same named declaration doesn't already exist in the module table,
|
|
||||||
/// otherwise return the existing function from the module table.
|
|
||||||
///
|
///
|
||||||
/// \arg Ty - If non-null the LLVM function type to use for the decl; it is
|
/// \arg Ty - If non-null the LLVM function type to use for the
|
||||||
/// the callers responsibility to make sure this is compatible with the
|
/// decl; it is the callers responsibility to make sure this is
|
||||||
/// correct type.
|
/// compatible with the correct type.
|
||||||
llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D,
|
llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D,
|
||||||
const llvm::Type *Ty,
|
const llvm::Type *Ty);
|
||||||
bool ReplaceExisting=false);
|
|
||||||
|
|
||||||
void EmitGlobalFunctionDefinition(const FunctionDecl *D);
|
void EmitGlobalFunctionDefinition(const FunctionDecl *D);
|
||||||
void EmitGlobalVarDefinition(const VarDecl *D);
|
void EmitGlobalVarDefinition(const VarDecl *D);
|
||||||
|
@ -340,19 +337,19 @@ private:
|
||||||
void EmitAliases(void);
|
void EmitAliases(void);
|
||||||
void EmitAnnotations(void);
|
void EmitAnnotations(void);
|
||||||
|
|
||||||
/// EmitDeferred - Emit any needed decls for which code generation was
|
/// EmitDeferred - Emit any needed decls for which code generation
|
||||||
/// deferred.
|
/// was deferred.
|
||||||
void EmitDeferred(void);
|
void EmitDeferred(void);
|
||||||
|
|
||||||
/// EmitLLVMUsed - Emit the llvm.used metadata used to force references to
|
/// EmitLLVMUsed - Emit the llvm.used metadata used to force
|
||||||
/// global which may otherwise be optimized out.
|
/// references to global which may otherwise be optimized out.
|
||||||
void EmitLLVMUsed(void);
|
void EmitLLVMUsed(void);
|
||||||
|
|
||||||
void BindRuntimeGlobals();
|
void BindRuntimeGlobals();
|
||||||
|
|
||||||
/// MayDeferGeneration - Determine if the given decl can be emitted lazily;
|
/// MayDeferGeneration - Determine if the given decl can be emitted
|
||||||
/// this is only relevant for definitions. The given decl must be either a
|
/// lazily; this is only relevant for definitions. The given decl
|
||||||
/// function or var decl.
|
/// must be either a function or var decl.
|
||||||
bool MayDeferGeneration(const ValueDecl *D);
|
bool MayDeferGeneration(const ValueDecl *D);
|
||||||
};
|
};
|
||||||
} // end namespace CodeGen
|
} // end namespace CodeGen
|
||||||
|
|
Loading…
Reference in New Issue