diff options
-rw-r--r-- | lib/CodeGen/CGCall.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 52 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 68 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 3 |
4 files changed, 62 insertions, 68 deletions
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h index 78a83a8791..efeb6ee49f 100644 --- a/lib/CodeGen/CGCall.h +++ b/lib/CodeGen/CGCall.h @@ -32,6 +32,7 @@ namespace clang { class Decl; class FunctionDecl; class ObjCMethodDecl; + class VarDecl; namespace CodeGen { typedef llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrListType; @@ -40,6 +41,12 @@ namespace CodeGen { /// arguments in a call. typedef llvm::SmallVector<std::pair<RValue, QualType>, 16> CallArgList; + /// FunctionArgList - Type for representing both the decl and type + /// of parameters to a function. The decl must be either a + /// ParmVarDecl or ImplicitParamDecl. + typedef llvm::SmallVector<std::pair<const VarDecl*, QualType>, + 16> FunctionArgList; + /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. class CGFunctionInfo { diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 70c1993887..a3da59410d 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -102,53 +102,23 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { /// StartObjCMethod - Begin emission of an ObjCMethod. This generates /// the LLVM function and sets the other context used by /// CodeGenFunction. - -// FIXME: This should really be merged with GenerateCode. void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) { - CurFn = CGM.getObjCRuntime().GenerateMethod(OMD); + FunctionArgList Args; + llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD); - CGM.SetMethodAttributes(OMD, CurFn); - - llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); - - // Create a marker to make it easy to insert allocas into the entryblock - // later. Don't create this with the builder, because we don't want it - // folded. - llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty); - AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt", - EntryBB); + CGM.SetMethodAttributes(OMD, Fn); - FnRetTy = OMD->getResultType(); - CurFuncDecl = OMD; + Args.push_back(std::make_pair(OMD->getSelfDecl(), + OMD->getSelfDecl()->getType())); + Args.push_back(std::make_pair(OMD->getCmdDecl(), + OMD->getCmdDecl()->getType())); - ReturnBlock = llvm::BasicBlock::Create("return", CurFn); - ReturnValue = 0; - if (!FnRetTy->isVoidType()) - ReturnValue = CreateTempAlloca(ConvertType(FnRetTy), "retval"); - - Builder.SetInsertPoint(EntryBB); - - // Emit allocs for param decls. Give the LLVM Argument nodes names. - llvm::Function::arg_iterator AI = CurFn->arg_begin(); - - // Name the struct return argument. - if (hasAggregateLLVMType(OMD->getResultType())) { - AI->setName("agg.result"); - ++AI; + for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i) { + ParmVarDecl *IPD = OMD->getParamDecl(i); + Args.push_back(std::make_pair(IPD, IPD->getType())); } - // Add implicit parameters to the decl map. - EmitParmDecl(*OMD->getSelfDecl(), AI); - ++AI; - - EmitParmDecl(*OMD->getCmdDecl(), AI); - ++AI; - - for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) { - assert(AI != CurFn->arg_end() && "Argument mismatch!"); - EmitParmDecl(*OMD->getParamDecl(i), AI); - } - assert(AI == CurFn->arg_end() && "Argument mismatch"); + StartFunction(OMD, OMD->getResultType(), Fn, Args); } /// Generate an Objective-C method. An Objective-C method is a C function with diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index d2da71270e..a934e43e48 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -110,11 +110,11 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(!verifyFunction(*CurFn) && "Generated function is not well formed."); } -// FIXME: There is parallel code in StartObjCMethod. -void CodeGenFunction::GenerateCode(const FunctionDecl *FD, - llvm::Function *Fn) { - CurFuncDecl = FD; - FnRetTy = FD->getResultType(); +void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, + llvm::Function *Fn, + const FunctionArgList &Args) { + CurFuncDecl = D; + FnRetTy = RetTy; CurFn = Fn; assert(CurFn->isDeclaration() && "Function already has body?"); @@ -129,48 +129,62 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD, ReturnBlock = llvm::BasicBlock::Create("return", CurFn); ReturnValue = 0; - if (!FnRetTy->isVoidType()) - ReturnValue = CreateTempAlloca(ConvertType(FnRetTy), "retval"); + if (!RetTy->isVoidType()) + ReturnValue = CreateTempAlloca(ConvertType(RetTy), "retval"); Builder.SetInsertPoint(EntryBB); // Emit subprogram debug descriptor. - CGDebugInfo *DI = CGM.getDebugInfo(); - if (DI) { - CompoundStmt* body = dyn_cast<CompoundStmt>(FD->getBody()); - if (body && body->getLBracLoc().isValid()) { - DI->setLocation(body->getLBracLoc()); + // FIXME: The cast here is a huge hack. + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + if (CGDebugInfo *DI = CGM.getDebugInfo()) { + CompoundStmt* body = dyn_cast<CompoundStmt>(FD->getBody()); + if (body && body->getLBracLoc().isValid()) { + DI->setLocation(body->getLBracLoc()); + } + DI->EmitFunctionStart(FD, CurFn, Builder); } - DI->EmitFunctionStart(FD, CurFn, Builder); } // Emit allocs for param decls. Give the LLVM Argument nodes names. llvm::Function::arg_iterator AI = CurFn->arg_begin(); // Name the struct return argument. - if (hasAggregateLLVMType(FD->getResultType())) { + if (hasAggregateLLVMType(FnRetTy)) { AI->setName("agg.result"); ++AI; } + + for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); + i != e; ++i, ++AI) { + const VarDecl *Arg = i->first; + QualType T = i->second; + assert(AI != CurFn->arg_end() && "Argument mismatch!"); + llvm::Value* V = AI; + if (!getContext().typesAreCompatible(T, Arg->getType())) { + // This must be a promotion, for something like + // "void a(x) short x; {..." + V = EmitScalarConversion(V, T, Arg->getType()); + } + EmitParmDecl(*Arg, V); + } + assert(AI == CurFn->arg_end() && "Argument mismatch!"); +} +void CodeGenFunction::GenerateCode(const FunctionDecl *FD, + llvm::Function *Fn) { + FunctionArgList Args; if (FD->getNumParams()) { const FunctionTypeProto* FProto = FD->getType()->getAsFunctionTypeProto(); assert(FProto && "Function def must have prototype!"); - for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) { - assert(AI != CurFn->arg_end() && "Argument mismatch!"); - const ParmVarDecl* CurParam = FD->getParamDecl(i); - llvm::Value* V = AI; - if (!getContext().typesAreCompatible(FProto->getArgType(i), - CurParam->getType())) { - // This must be a promotion, for something like - // "void a(x) short x; {..." - V = EmitScalarConversion(V, FProto->getArgType(i), - CurParam->getType()); - } - EmitParmDecl(*CurParam, V); - } + + for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) + Args.push_back(std::make_pair(FD->getParamDecl(i), + FProto->getArgType(i))); } + StartFunction(FD, FD->getResultType(), Fn, Args); + EmitStmt(FD->getBody()); const CompoundStmt *S = dyn_cast<CompoundStmt>(FD->getBody()); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 6fad0486dd..cef6503eeb 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -133,6 +133,9 @@ public: void GenerateCode(const FunctionDecl *FD, llvm::Function *Fn); + void StartFunction(const Decl *D, QualType RetTy, + llvm::Function *Fn, + const FunctionArgList &Args); void FinishFunction(SourceLocation EndLoc=SourceLocation()); const llvm::Type *ConvertType(QualType T); |