# HG changeset patch # User Christian Kamm # Date 1236432330 -3600 # Node ID dc608dc330812b91f0eecba5bb81d696b8410c24 # Parent 32ead42679d1740571ebf2be14c27b5f724bc4a0 Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the same LDC call. diff -r 32ead42679d1 -r dc608dc33081 CMakeLists.txt --- a/CMakeLists.txt Fri Mar 06 21:15:13 2009 +0100 +++ b/CMakeLists.txt Sat Mar 07 14:25:30 2009 +0100 @@ -80,6 +80,7 @@ idgen impcnvgen PROPERTIES LINKER_LANGUAGE CXX RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${DMDFE_PATH} + COMPILE_FLAGS ${LLVM_CXXFLAGS} ) get_target_property(IDGEN_LOC idgen LOCATION) get_target_property(IMPCNVGEN_LOC impcnvgen LOCATION) diff -r 32ead42679d1 -r dc608dc33081 dmd/mtype.c --- a/dmd/mtype.c Fri Mar 06 21:15:13 2009 +0100 +++ b/dmd/mtype.c Sat Mar 07 14:25:30 2009 +0100 @@ -2659,9 +2659,6 @@ this->varargs = varargs; this->linkage = linkage; this->inuse = 0; - - // LDC - this->fty = NULL; } Type *TypeFunction::syntaxCopy() diff -r 32ead42679d1 -r dc608dc33081 dmd/mtype.h --- a/dmd/mtype.h Fri Mar 06 21:15:13 2009 +0100 +++ b/dmd/mtype.h Sat Mar 07 14:25:30 2009 +0100 @@ -23,8 +23,8 @@ // llvm #include "../ir/irtype.h" +#include "../ir/irfuncty.h" namespace llvm { class Type; } -struct IrFuncTy; struct Scope; struct Identifier; @@ -437,7 +437,7 @@ unsigned totym(); // LDC - IrFuncTy* fty; + IrFuncTy fty; }; struct TypeDelegate : Type diff -r 32ead42679d1 -r dc608dc33081 gen/abi-x86-64.cpp --- a/gen/abi-x86-64.cpp Fri Mar 06 21:15:13 2009 +0100 +++ b/gen/abi-x86-64.cpp Sat Mar 07 14:25:30 2009 +0100 @@ -647,20 +647,20 @@ if (tf->linkage != LINKd) { // TODO: See if this is correct for more than just extern(C). - IrFuncTy* fty = tf->fty; + IrFuncTy& fty = tf->fty; - if (!fty->arg_sret) { + if (!fty.arg_sret) { Logger::println("x86-64 ABI: Transforming return type"); - Type* rt = fty->ret->type->toBasetype(); + Type* rt = fty.ret->type->toBasetype(); if (rt != Type::tvoid) - fixup(*fty->ret); + fixup(*fty.ret); } Logger::println("x86-64 ABI: Transforming arguments"); LOG_SCOPE; - for (IrFuncTy::ArgIter I = fty->args.begin(), E = fty->args.end(); I != E; ++I) { + for (IrFuncTy::ArgIter I = fty.args.begin(), E = fty.args.end(); I != E; ++I) { IrFuncTyArg& arg = **I; if (Logger::enabled()) diff -r 32ead42679d1 -r dc608dc33081 gen/abi.cpp --- a/gen/abi.cpp Fri Mar 06 21:15:13 2009 +0100 +++ b/gen/abi.cpp Sat Mar 07 14:25:30 2009 +0100 @@ -167,8 +167,8 @@ void rewriteFunctionType(TypeFunction* tf) { - IrFuncTy* fty = tf->fty; - Type* rt = fty->ret->type->toBasetype(); + IrFuncTy& fty = tf->fty; + Type* rt = fty.ret->type->toBasetype(); // extern(D) if (tf->linkage == LINKd) @@ -179,31 +179,31 @@ if (rt->iscomplex()) { Logger::println("Rewriting complex return value"); - fty->ret->rewrite = &swapComplex; + fty.ret->rewrite = &swapComplex; } // IMPLICIT PARAMETERS // mark this/nested params inreg - if (fty->arg_this) + if (fty.arg_this) { Logger::println("Putting 'this' in register"); - fty->arg_this->attrs = llvm::Attribute::InReg; + fty.arg_this->attrs = llvm::Attribute::InReg; } - else if (fty->arg_nest) + else if (fty.arg_nest) { Logger::println("Putting context ptr in register"); - fty->arg_nest->attrs = llvm::Attribute::InReg; + fty.arg_nest->attrs = llvm::Attribute::InReg; } // otherwise try to mark the last param inreg - else if (!fty->arg_sret && !fty->args.empty()) + else if (!fty.arg_sret && !fty.args.empty()) { // The last parameter is passed in EAX rather than being pushed on the stack if the following conditions are met: // * It fits in EAX. // * It is not a 3 byte struct. // * It is not a floating point type. - IrFuncTyArg* last = fty->args.back(); + IrFuncTyArg* last = fty.args.back(); Type* lastTy = last->type->toBasetype(); unsigned sz = lastTy->size(); @@ -234,9 +234,9 @@ // reverse parameter order // for non variadics - if (!fty->args.empty() && tf->varargs != 1) + if (!fty.args.empty() && tf->varargs != 1) { - fty->reverseParams = true; + fty.reverseParams = true; } } @@ -248,8 +248,8 @@ // cfloat -> i64 if (tf->next->toBasetype() == Type::tcomplex32) { - fty->ret->rewrite = &cfloatToInt; - fty->ret->ltype = LLType::Int64Ty; + fty.ret->rewrite = &cfloatToInt; + fty.ret->ltype = LLType::Int64Ty; } // IMPLICIT PARAMETERS diff -r 32ead42679d1 -r dc608dc33081 gen/functions.cpp --- a/gen/functions.cpp Fri Mar 06 21:15:13 2009 +0100 +++ b/gen/functions.cpp Sat Mar 07 14:25:30 2009 +0100 @@ -33,16 +33,15 @@ // already built ? if (type->ir.type != NULL) { - assert(f->fty != NULL); + //assert(f->fty != NULL); return llvm::cast(type->ir.type->get()); } // Tell the ABI we're resolving a new function type gABI->newFunctionType(f); - // create new ir funcTy - assert(f->fty == NULL); - f->fty = new IrFuncTy(); + // start new ir funcTy + f->fty.reset(); // llvm idx counter size_t lidx = 0; @@ -50,7 +49,7 @@ // main needs a little special handling if (ismain) { - f->fty->ret = new IrFuncTyArg(Type::tint32, false); + f->fty.ret = new IrFuncTyArg(Type::tint32, false); } // sane return value else @@ -60,7 +59,7 @@ // sret return if (gABI->returnInArg(f)) { - f->fty->arg_sret = new IrFuncTyArg(rt, true, llvm::Attribute::StructRet); + f->fty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attribute::StructRet); rt = Type::tvoid; lidx++; } @@ -69,7 +68,7 @@ { a = se; } - f->fty->ret = new IrFuncTyArg(rt, false, a); + f->fty.ret = new IrFuncTyArg(rt, false, a); } lidx++; @@ -77,14 +76,14 @@ if (thistype) { bool toref = (thistype->toBasetype()->ty == Tstruct); - f->fty->arg_this = new IrFuncTyArg(thistype, toref); + f->fty.arg_this = new IrFuncTyArg(thistype, toref); lidx++; } // and nested functions else if (nesttype) { - f->fty->arg_nest = new IrFuncTyArg(nesttype, false); + f->fty.arg_nest = new IrFuncTyArg(nesttype, false); lidx++; } @@ -98,16 +97,16 @@ if (f->varargs == 1) { // _arguments - f->fty->arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false); + f->fty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false); lidx++; // _argptr - f->fty->arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false); + f->fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false); lidx++; } } else if (f->linkage == LINKc) { - f->fty->c_vararg = true; + f->fty.c_vararg = true; } else { @@ -122,7 +121,7 @@ if (ismain && nargs == 0) { Type* mainargs = Type::tchar->arrayOf()->arrayOf(); - f->fty->args.push_back(new IrFuncTyArg(mainargs, false)); + f->fty.args.push_back(new IrFuncTyArg(mainargs, false)); lidx++; } // add explicit parameters @@ -157,7 +156,7 @@ a |= DtoShouldExtend(argtype); } - f->fty->args.push_back(new IrFuncTyArg(argtype, byref, a)); + f->fty.args.push_back(new IrFuncTyArg(argtype, byref, a)); lidx++; } @@ -171,26 +170,26 @@ std::vector argtypes; argtypes.reserve(lidx); - if (f->fty->arg_sret) argtypes.push_back(f->fty->arg_sret->ltype); - if (f->fty->arg_this) argtypes.push_back(f->fty->arg_this->ltype); - if (f->fty->arg_nest) argtypes.push_back(f->fty->arg_nest->ltype); - if (f->fty->arg_arguments) argtypes.push_back(f->fty->arg_arguments->ltype); - if (f->fty->arg_argptr) argtypes.push_back(f->fty->arg_argptr->ltype); + if (f->fty.arg_sret) argtypes.push_back(f->fty.arg_sret->ltype); + if (f->fty.arg_this) argtypes.push_back(f->fty.arg_this->ltype); + if (f->fty.arg_nest) argtypes.push_back(f->fty.arg_nest->ltype); + if (f->fty.arg_arguments) argtypes.push_back(f->fty.arg_arguments->ltype); + if (f->fty.arg_argptr) argtypes.push_back(f->fty.arg_argptr->ltype); size_t beg = argtypes.size(); - size_t nargs2 = f->fty->args.size(); + size_t nargs2 = f->fty.args.size(); for (size_t i = 0; i < nargs2; i++) { - argtypes.push_back(f->fty->args[i]->ltype); + argtypes.push_back(f->fty.args[i]->ltype); } // reverse params? - if (f->fty->reverseParams && nargs2 > 1) + if (f->fty.reverseParams && nargs2 > 1) { std::reverse(argtypes.begin() + beg, argtypes.end()); } - llvm::FunctionType* functype = llvm::FunctionType::get(f->fty->ret->ltype, argtypes, f->fty->c_vararg); + llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg); f->ir.type = new llvm::PATypeHolder(functype); Logger::cout() << "Final function type: " << *functype << "\n"; @@ -211,17 +210,16 @@ const llvm::FunctionType* fty = 0; // create new ir funcTy - assert(f->fty == NULL); - f->fty = new IrFuncTy(); - f->fty->ret = new IrFuncTyArg(Type::tvoid, false); + f->fty.reset(); + f->fty.ret = new IrFuncTyArg(Type::tvoid, false); - f->fty->args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false)); + f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false)); if (fdecl->llvmInternal == LLVMva_start) fty = GET_INTRINSIC_DECL(vastart)->getFunctionType(); else if (fdecl->llvmInternal == LLVMva_copy) { fty = GET_INTRINSIC_DECL(vacopy)->getFunctionType(); - f->fty->args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false)); + f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false)); } else if (fdecl->llvmInternal == LLVMva_end) fty = GET_INTRINSIC_DECL(vaend)->getFunctionType(); @@ -359,10 +357,10 @@ // handle implicit args #define ADD_PA(X) \ - if (f->fty->X) { \ - if (f->fty->X->attrs) { \ + if (f->fty.X) { \ + if (f->fty.X->attrs) { \ PAWI.Index = idx; \ - PAWI.Attrs = f->fty->X->attrs; \ + PAWI.Attrs = f->fty.X->attrs; \ attrs.push_back(PAWI); \ } \ idx++; \ @@ -386,11 +384,11 @@ Argument* fnarg = Argument::getNth(f->parameters, k); assert(fnarg); - attrptr[k] = f->fty->args[k]->attrs; + attrptr[k] = f->fty.args[k]->attrs; } // reverse params? - if (f->fty->reverseParams) + if (f->fty.reverseParams) { std::reverse(attrptr.begin(), attrptr.end()); } @@ -500,26 +498,26 @@ // name parameters llvm::Function::arg_iterator iarg = func->arg_begin(); - if (f->fty->arg_sret) { + if (f->fty.arg_sret) { iarg->setName(".sret_arg"); fdecl->ir.irFunc->retArg = iarg; ++iarg; } - if (f->fty->arg_this) { + if (f->fty.arg_this) { iarg->setName(".this_arg"); fdecl->ir.irFunc->thisArg = iarg; assert(fdecl->ir.irFunc->thisArg); ++iarg; } - else if (f->fty->arg_nest) { + else if (f->fty.arg_nest) { iarg->setName(".nest_arg"); fdecl->ir.irFunc->nestArg = iarg; assert(fdecl->ir.irFunc->nestArg); ++iarg; } - if (f->fty->arg_argptr) { + if (f->fty.arg_argptr) { iarg->setName("._arguments"); fdecl->ir.irFunc->_arguments = iarg; ++iarg; @@ -535,7 +533,7 @@ if (fdecl->parameters && fdecl->parameters->dim > k) { Dsymbol* argsym; - if (f->fty->reverseParams) + if (f->fty.reverseParams) argsym = (Dsymbol*)fdecl->parameters->data[fdecl->parameters->dim-k-1]; else argsym = (Dsymbol*)fdecl->parameters->data[k]; @@ -655,7 +653,7 @@ } // give the 'this' argument storage and debug info - if (f->fty->arg_this) + if (f->fty.arg_this) { LLValue* thisvar = irfunction->thisArg; assert(thisvar); @@ -685,7 +683,7 @@ // and debug info if (fd->parameters) { - size_t n = f->fty->args.size(); + size_t n = f->fty.args.size(); assert(n == fd->parameters->dim); for (int i=0; i < n; ++i) { @@ -708,7 +706,7 @@ bool refout = vd->storage_class & (STCref | STCout); bool lazy = vd->storage_class & STClazy; - if (!refout && (!f->fty->args[i]->byref || lazy)) + if (!refout && (!f->fty.args[i]->byref || lazy)) { // alloca a stack slot for this first class value arg const LLType* argt; @@ -720,7 +718,7 @@ // let the abi transform the argument back first DImValue arg_dval(vd->type, irloc->value); - f->fty->getParam(vd->type, i, &arg_dval, mem); + f->fty.getParam(vd->type, i, &arg_dval, mem); // set the arg var value to the alloca irloc->value = mem; diff -r 32ead42679d1 -r dc608dc33081 gen/statements.cpp --- a/gen/statements.cpp Fri Mar 06 21:15:13 2009 +0100 +++ b/gen/statements.cpp Sat Mar 07 14:25:30 2009 +0100 @@ -92,7 +92,7 @@ if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); // do abi specific transformations on the return value - LLValue* v = p->func()->type->fty->putRet(exp->type, exp->toElem(p)); + LLValue* v = p->func()->type->fty.putRet(exp->type, exp->toElem(p)); if (Logger::enabled()) Logger::cout() << "return value is '" <<*v << "'\n"; diff -r 32ead42679d1 -r dc608dc33081 gen/tocall.cpp --- a/gen/tocall.cpp Fri Mar 06 21:15:13 2009 +0100 +++ b/gen/tocall.cpp Sat Mar 07 14:25:30 2009 +0100 @@ -201,11 +201,11 @@ DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); args.push_back(argval->getRVal()); - if (tf->fty->args[i]->attrs) + if (tf->fty.args[i]->attrs) { llvm::AttributeWithIndex Attr; Attr.Index = argidx; - Attr.Attrs = tf->fty->args[i]->attrs; + Attr.Attrs = tf->fty.args[i]->attrs; attrs.push_back(Attr); } @@ -239,10 +239,10 @@ TypeFunction* tf = DtoTypeFunction(fnval); // misc - bool retinptr = tf->fty->arg_sret; - bool thiscall = tf->fty->arg_this; + bool retinptr = tf->fty.arg_sret; + bool thiscall = tf->fty.arg_this; bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); - bool nestedcall = tf->fty->arg_nest; + bool nestedcall = tf->fty.arg_nest; bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); unsigned callconv = DtoCallingConv(loc, tf->linkage); @@ -267,16 +267,16 @@ llvm::AttributeWithIndex Attr; // return attrs - if (tf->fty->ret->attrs) + if (tf->fty.ret->attrs) { Attr.Index = 0; - Attr.Attrs = tf->fty->ret->attrs; + Attr.Attrs = tf->fty.ret->attrs; attrs.push_back(Attr); } // handle implicit arguments std::vector args; - args.reserve(tf->fty->args.size()); + args.reserve(tf->fty.args.size()); // return in hidden ptr is first if (retinptr) @@ -332,16 +332,16 @@ } // add attributes for context argument - if (tf->fty->arg_this && tf->fty->arg_this->attrs) + if (tf->fty.arg_this && tf->fty.arg_this->attrs) { Attr.Index = retinptr ? 2 : 1; - Attr.Attrs = tf->fty->arg_this->attrs; + Attr.Attrs = tf->fty.arg_this->attrs; attrs.push_back(Attr); } - else if (tf->fty->arg_nest && tf->fty->arg_nest->attrs) + else if (tf->fty.arg_nest && tf->fty.arg_nest->attrs) { Attr.Index = retinptr ? 2 : 1; - Attr.Attrs = tf->fty->arg_nest->attrs; + Attr.Attrs = tf->fty.arg_nest->attrs; attrs.push_back(Attr); } } @@ -402,14 +402,14 @@ } // give the ABI a say - LLValue* arg = tf->fty->putParam(argval->getType(), i, argval); + LLValue* arg = tf->fty.putParam(argval->getType(), i, argval); if (Logger::enabled()) { Logger::cout() << "Argument after ABI: " << *arg << '\n'; Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n'; } - int j = tf->fty->reverseParams ? beg + n - i - 1 : beg + i; + int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i; // Hack around LDC assuming structs are in memory: // If the function wants a struct, and the argument value is a @@ -434,14 +434,14 @@ } // param attrs - attrptr[i] = tf->fty->args[i]->attrs; + attrptr[i] = tf->fty.args[i]->attrs; ++argiter; args.push_back(arg); } // reverse the relevant params as well as the param attrs - if (tf->fty->reverseParams) + if (tf->fty.reverseParams) { std::reverse(args.begin() + beg, args.end()); std::reverse(attrptr.begin(), attrptr.end()); @@ -507,7 +507,7 @@ { // do abi specific return value fixups DImValue dretval(tf->next, retllval); - retllval = tf->fty->getRet(tf->next, &dretval); + retllval = tf->fty.getRet(tf->next, &dretval); } // Hack around LDC assuming structs are in memory: diff -r 32ead42679d1 -r dc608dc33081 ir/irfunction.cpp --- a/ir/irfunction.cpp Fri Mar 06 21:15:13 2009 +0100 +++ b/ir/irfunction.cpp Sat Mar 07 14:25:30 2009 +0100 @@ -5,6 +5,7 @@ #include "gen/dvalue.h" #include "gen/logger.h" #include "ir/irfunction.h" +#include "ir/irfuncty.h" #include @@ -21,6 +22,10 @@ rewrite = NULL; } +bool IrFuncTyArg::isInReg() const { return (attrs & llvm::Attribute::InReg) != 0; } +bool IrFuncTyArg::isSRet() const { return (attrs & llvm::Attribute::StructRet) != 0; } +bool IrFuncTyArg::isByVal() const { return (attrs & llvm::Attribute::ByVal) != 0; } + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// diff -r 32ead42679d1 -r dc608dc33081 ir/irfunction.h --- a/ir/irfunction.h Fri Mar 06 21:15:13 2009 +0100 +++ b/ir/irfunction.h Sat Mar 07 14:25:30 2009 +0100 @@ -9,90 +9,6 @@ #include #include -struct ABIRewrite; - -// represents a function type argument -// both explicit and implicit as well as return values -struct IrFuncTyArg : IrBase -{ - /** This is the original D type as the frontend knows it - * May NOT be rewritten!!! */ - Type* type; - - /// This is the final LLVM Type used for the parameter/return value type - const llvm::Type* ltype; - - /** These are the final LLVM attributes used for the function. - * Must be valid for the LLVM Type and byref setting */ - unsigned attrs; - - /** 'true' if the final LLVM argument is a LLVM reference type. - * Must be true when the D Type is a value type, but the final - * LLVM Type is a reference type! */ - bool byref; - - /** Pointer to the ABIRewrite structure needed to rewrite LLVM ValueS - * to match the final LLVM Type when passing arguments and getting - * return values */ - ABIRewrite* rewrite; - - /// Helper to check if the 'inreg' attribute is set - bool isInReg() const { return (attrs & llvm::Attribute::InReg) != 0; } - /// Helper to check if the 'sret' attribute is set - bool isSRet() const { return (attrs & llvm::Attribute::StructRet) != 0; } - /// Helper to check if the 'byval' attribute is set - bool isByVal() const { return (attrs & llvm::Attribute::ByVal) != 0; } - - /** @param t D type of argument/return value as known by the frontend - * @param byref Initial value for the 'byref' field. If true the initial - * LLVM Type will be of DtoType(type->pointerTo()), instead - * of just DtoType(type) */ - IrFuncTyArg(Type* t, bool byref, unsigned a = 0); -}; - -// represents a function type -struct IrFuncTy : IrBase -{ - // return value - IrFuncTyArg* ret; - - // null if not applicable - IrFuncTyArg* arg_sret; - IrFuncTyArg* arg_this; - IrFuncTyArg* arg_nest; - IrFuncTyArg* arg_arguments; - IrFuncTyArg* arg_argptr; - - // normal explicit arguments - typedef LLSmallVector ArgList; - typedef ArgList::iterator ArgIter; - ArgList args; - - // C varargs - bool c_vararg; - - // range of normal parameters to reverse - bool reverseParams; - - IrFuncTy() - : ret(NULL), - arg_sret(NULL), - arg_this(NULL), - arg_nest(NULL), - arg_arguments(NULL), - arg_argptr(NULL), - c_vararg(false), - reverseParams(false) - {} - - llvm::Value* putRet(Type* dty, DValue* dval); - llvm::Value* getRet(Type* dty, DValue* dval); - - llvm::Value* putParam(Type* dty, int idx, DValue* dval); - llvm::Value* getParam(Type* dty, int idx, DValue* dval); - void getParam(Type* dty, int idx, DValue* dval, llvm::Value* lval); -}; - // represents a function struct IrFunction : IrBase { diff -r 32ead42679d1 -r dc608dc33081 ir/irfuncty.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ir/irfuncty.h Sat Mar 07 14:25:30 2009 +0100 @@ -0,0 +1,108 @@ +#ifndef LDC_IR_IRFUNCTY_H +#define LDC_IR_IRFUNCTY_H + +#include "ir/ir.h" +#include "llvm/ADT/SmallVector.h" + +#include + +struct ABIRewrite; +namespace llvm { + class Type; + class Value; + class Instruction; + class Function; +} + +// represents a function type argument +// both explicit and implicit as well as return values +struct IrFuncTyArg : IrBase +{ + /** This is the original D type as the frontend knows it + * May NOT be rewritten!!! */ + Type* type; + + /// This is the final LLVM Type used for the parameter/return value type + const llvm::Type* ltype; + + /** These are the final LLVM attributes used for the function. + * Must be valid for the LLVM Type and byref setting */ + unsigned attrs; + + /** 'true' if the final LLVM argument is a LLVM reference type. + * Must be true when the D Type is a value type, but the final + * LLVM Type is a reference type! */ + bool byref; + + /** Pointer to the ABIRewrite structure needed to rewrite LLVM ValueS + * to match the final LLVM Type when passing arguments and getting + * return values */ + ABIRewrite* rewrite; + + /// Helper to check if the 'inreg' attribute is set + bool isInReg() const; + /// Helper to check if the 'sret' attribute is set + bool isSRet() const; + /// Helper to check if the 'byval' attribute is set + bool isByVal() const; + + /** @param t D type of argument/return value as known by the frontend + * @param byref Initial value for the 'byref' field. If true the initial + * LLVM Type will be of DtoType(type->pointerTo()), instead + * of just DtoType(type) */ + IrFuncTyArg(Type* t, bool byref, unsigned a = 0); +}; + +// represents a function type +struct IrFuncTy : IrBase +{ + // return value + IrFuncTyArg* ret; + + // null if not applicable + IrFuncTyArg* arg_sret; + IrFuncTyArg* arg_this; + IrFuncTyArg* arg_nest; + IrFuncTyArg* arg_arguments; + IrFuncTyArg* arg_argptr; + + // normal explicit arguments +// typedef llvm::SmallVector ArgList; + typedef std::vector ArgList; + typedef ArgList::iterator ArgIter; + ArgList args; + + // C varargs + bool c_vararg; + + // range of normal parameters to reverse + bool reverseParams; + + IrFuncTy() + : ret(NULL), + arg_sret(NULL), + arg_this(NULL), + arg_nest(NULL), + arg_arguments(NULL), + arg_argptr(NULL), + c_vararg(false), + reverseParams(false) + {} + + void reset() { + ret = NULL; + arg_sret = arg_this = arg_nest = arg_arguments = arg_argptr = NULL; + args.clear(); + c_vararg = false; + reverseParams = false; + } + + llvm::Value* putRet(Type* dty, DValue* dval); + llvm::Value* getRet(Type* dty, DValue* dval); + + llvm::Value* putParam(Type* dty, int idx, DValue* dval); + llvm::Value* getParam(Type* dty, int idx, DValue* dval); + void getParam(Type* dty, int idx, DValue* dval, llvm::Value* lval); +}; + +#endif diff -r 32ead42679d1 -r dc608dc33081 ir/irlandingpad.h --- a/ir/irlandingpad.h Fri Mar 06 21:15:13 2009 +0100 +++ b/ir/irlandingpad.h Sat Mar 07 14:25:30 2009 +0100 @@ -7,6 +7,13 @@ #include #include +namespace llvm { + class Type; + class Value; + class BasicBlock; + class Function; +} + // only to be used within IRLandingPad // holds information about a single catch or finally struct IRLandingPadInfo @@ -57,7 +64,7 @@ llvm::BasicBlock* get(); // creates or gets storage for exception object - LLValue* getExceptionStorage(); + llvm::Value* getExceptionStorage(); private: // constructs the landing pad from infos @@ -77,7 +84,7 @@ std::map catchToInt; // storage for the catch variable - LLValue* catch_var; + llvm::Value* catch_var; }; #endif