From 5eaee5692cd499074b2eb064f42ea49e32b3e97d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 21 Mar 2009 08:38:50 +0000 Subject: [PATCH] code cleanups, rename EmitForwardFunctionDefinition -> CreateFunctionPrototypeIR, though my next patch will eliminate it entirely. llvm-svn: 67443 --- clang/lib/CodeGen/CodeGenModule.cpp | 85 +++++++++++++++-------------- clang/lib/CodeGen/CodeGenModule.h | 8 +-- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 97f989dbe381..d90165118365 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -782,10 +782,16 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { } } +/// CreateFunctionPrototypeIR - Create a new LLVM IR 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. llvm::GlobalValue * -CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D, - const llvm::Type *Ty) { - bool DoSetAttributes = true; +CodeGenModule::CreateFunctionPrototypeIR(const FunctionDecl *D, + const llvm::Type *Ty) { + bool ShouldSetAttributes = true; if (!Ty) { Ty = getTypes().ConvertType(D->getType()); if (!isa(Ty)) { @@ -794,31 +800,30 @@ CodeGenModule::EmitForwardFunctionDefinition(const FunctionDecl *D, // sure not to try to set attributes. Ty = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector(), false); - DoSetAttributes = false; + ShouldSetAttributes = false; } } llvm::Function *F = llvm::Function::Create(cast(Ty), llvm::Function::ExternalLinkage, getMangledName(D), &getModule()); - if (DoSetAttributes) + if (ShouldSetAttributes) SetFunctionAttributes(D, F); return F; } llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D) { - QualType ASTTy = D->getType(); - const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy); - const llvm::Type *PTy = llvm::PointerType::get(Ty, ASTTy.getAddressSpace()); - // Lookup the entry, lazily creating it if necessary. llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)]; if (!Entry) - return Entry = EmitForwardFunctionDefinition(D, 0); + return Entry = CreateFunctionPrototypeIR(D, 0); - if (Entry->getType() != PTy) - return llvm::ConstantExpr::getBitCast(Entry, PTy); - return Entry; + const llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType()); + if (Entry->getType()->getElementType() == Ty) + return Entry; + + const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty); + return llvm::ConstantExpr::getBitCast(Entry, PTy); } void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { @@ -830,39 +835,35 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { // to do unnecessary work). if (Ty->isVarArg() && Ty->getNumParams() == 0 && Ty->isVarArg()) Ty = llvm::FunctionType::get(Ty->getReturnType(), - std::vector(), - false); + std::vector(), false); llvm::GlobalValue *&Entry = GlobalDeclMap[getMangledName(D)]; if (!Entry) { - Entry = EmitForwardFunctionDefinition(D, Ty); - } else { + Entry = CreateFunctionPrototypeIR(D, Ty); + } else if (Entry->getType()->getElementType() != 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); - 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; - } + + // 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 = CreateFunctionPrototypeIR(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 0783d6521f3b..f35aa09fef89 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -315,14 +315,14 @@ private: void EmitGlobalDefinition(const ValueDecl *D); - /// EmitForwardFunctionDefinition - Create a new function for the - /// given decl and set attributes as appropriate. + /// CreateFunctionPrototypeIR - Create a new LLVM IR 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. - llvm::GlobalValue *EmitForwardFunctionDefinition(const FunctionDecl *D, - const llvm::Type *Ty); + llvm::GlobalValue *CreateFunctionPrototypeIR(const FunctionDecl *D, + const llvm::Type *Ty); void EmitGlobalFunctionDefinition(const FunctionDecl *D); void EmitGlobalVarDefinition(const VarDecl *D);