diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 41784cbb8131..16ba94791fad 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/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(Ty), - llvm::Function::ExternalLinkage, - Name, - &getModule()); + llvm::Function *F = llvm::Function::Create(cast(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(Entry); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 039579ffc5a9..c3a84af0c5be 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/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