changeset 1051:dc608dc33081

Make IrFuncTy a member of TypeFunction. Reset between modules compiled in the same LDC call.
author Christian Kamm <kamm incasoftware de>
date Sat, 07 Mar 2009 14:25:30 +0100
parents 32ead42679d1
children 12ea38902e83
files CMakeLists.txt dmd/mtype.c dmd/mtype.h gen/abi-x86-64.cpp gen/abi.cpp gen/functions.cpp gen/statements.cpp gen/tocall.cpp ir/irfunction.cpp ir/irfunction.h ir/irfuncty.h ir/irlandingpad.h
diffstat 12 files changed, 201 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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()
--- 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
--- 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())
--- 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
--- 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<llvm::FunctionType>(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<const LLType*> 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;
--- 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";
--- 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<LLValue*> 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:
--- 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 <sstream>
 
@@ -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; }
+
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
--- 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 <stack>
 #include <map>
 
-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<IrFuncTyArg*, 4> 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
 {
--- /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 <vector>
+
+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<IrFuncTyArg*, 4> ArgList;
+    typedef std::vector<IrFuncTyArg*> 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
--- 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 <deque>
 #include <stack>
 
+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<ClassDeclaration*, int> catchToInt;
 
     // storage for the catch variable
-    LLValue* catch_var;
+    llvm::Value* catch_var;
 };
 
 #endif