forked from OSchip/llvm-project
Factor CodeGenFunction::StartFunction out of GenerateCode and
StartObjCMethod. llvm-svn: 56030
This commit is contained in:
parent
b4c0295b8e
commit
bc915f4025
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue