Factor CodeGenFunction::StartFunction out of GenerateCode and

StartObjCMethod.

llvm-svn: 56030
This commit is contained in:
Daniel Dunbar 2008-09-09 23:14:03 +00:00
parent b4c0295b8e
commit bc915f4025
4 changed files with 62 additions and 68 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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());

View File

@ -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);