changeset 1192:3251ce06c820

Started seperating type resolution from the rest of codegen again, the merge had too many regressions.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Fri, 03 Apr 2009 16:34:11 +0200
parents d68796be59fd
children c271eca933fb
files dmd/mtype.c dmd/mtype.h gen/tollvm.cpp ir/irtype.cpp ir/irtype.h tests/mini/compile_delegate.d
diffstat 6 files changed, 349 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mtype.c	Fri Apr 03 14:54:17 2009 +0200
+++ b/dmd/mtype.c	Fri Apr 03 16:34:11 2009 +0200
@@ -137,6 +137,10 @@
 #if IN_DMD
     this->ctype = NULL;
 #endif
+
+#if IN_LLVM
+    this->irtype = NULL;
+#endif
 }
 
 Type *Type::syntaxCopy()
--- a/dmd/mtype.h	Fri Apr 03 14:54:17 2009 +0200
+++ b/dmd/mtype.h	Fri Apr 03 16:34:11 2009 +0200
@@ -27,6 +27,8 @@
 #include "../ir/irfuncty.h"
 namespace llvm { class Type; }
 struct Ir;
+
+class IrType;
 #endif
 
 struct Scope;
@@ -281,6 +283,8 @@
     // LDC
     IrDType ir;
     static Ir* sir;
+
+    IrType* irtype;
 #endif
 };
 
--- a/gen/tollvm.cpp	Fri Apr 03 14:54:17 2009 +0200
+++ b/gen/tollvm.cpp	Fri Apr 03 16:34:11 2009 +0200
@@ -22,6 +22,8 @@
 #include "gen/linkage.h"
 #include "gen/llvm-version.h"
 
+#include "ir/irtype.h"
+
 bool DtoIsPassedByRef(Type* type)
 {
     Type* typ = type->toBasetype();
@@ -50,63 +52,62 @@
 
 const LLType* DtoType(Type* t)
 {
+    if (t->irtype)
+    {
+        return t->irtype->get();
+    }
+
     assert(t);
     switch (t->ty)
     {
-    // integers
+    // basic types
+    case Tvoid:
     case Tint8:
     case Tuns8:
-    case Tchar:
-        return (const LLType*)LLType::Int8Ty;
     case Tint16:
     case Tuns16:
-    case Twchar:
-        return (const LLType*)LLType::Int16Ty;
     case Tint32:
     case Tuns32:
-    case Tdchar:
-        return (const LLType*)LLType::Int32Ty;
     case Tint64:
     case Tuns64:
-        return (const LLType*)LLType::Int64Ty;
-
-    case Tbool:
-        return (const LLType*)llvm::ConstantInt::getTrue()->getType();
-
-    // floats
     case Tfloat32:
-    case Timaginary32:
-        return LLType::FloatTy;
     case Tfloat64:
+    case Tfloat80:
+    case Timaginary32:
     case Timaginary64:
-        return LLType::DoubleTy;
-    case Tfloat80:
     case Timaginary80:
-        if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64)
-            return LLType::X86_FP80Ty;
-        else
-            return LLType::DoubleTy;
-
-    // complex
     case Tcomplex32:
     case Tcomplex64:
     case Tcomplex80:
-        return DtoComplexType(t);
+    //case Tbit:
+    case Tbool:
+    case Tchar:
+    case Twchar:
+    case Tdchar:
+    {
+        t->irtype = new IrTypeBasic(t);
+        return t->irtype->get();
+    }
 
     // pointers
     case Tpointer:
-        // getPtrToType checks for void itself
-        return getPtrToType(DtoType(t->nextOf()));
+    {
+        t->irtype = new IrTypePointer(t);
+        return t->irtype->get();
+    }
 
     // arrays
     case Tarray:
-        return DtoArrayType(t);
-    case Tsarray:
-        return DtoStaticArrayType(t);
+    {
+        t->irtype = new IrTypeArray(t);
+        return t->irtype->get();
+    }
 
-    // void
-    case Tvoid:
-        return LLType::VoidTy;
+    case Tsarray:
+    {
+        t->irtype = new IrTypeSArray(t);
+        return t->irtype->get();
+    }
 
     // aggregates
     case Tstruct:    {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irtype.cpp	Fri Apr 03 16:34:11 2009 +0200
@@ -0,0 +1,173 @@
+#include "llvm/DerivedTypes.h"
+#include "ir/irtype.h"
+
+#include "mars.h"
+#include "mtype.h"
+
+IrType::IrType(Type* dt, const llvm::Type* lt)
+:   dtype(dt),
+    pa(lt)
+{
+    assert(dt && "null D Type");
+    assert(lt && "null LLVM Type");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrTypeBasic::IrTypeBasic(Type * dt)
+: IrType(dt, basic2llvm(dt))
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+const llvm::Type * IrTypeBasic::basic2llvm(Type* t)
+{
+    const llvm::Type* t2;
+
+    switch(t->ty)
+    {
+    case Tvoid:
+        return llvm::Type::VoidTy;
+
+    case Tint8:
+    case Tuns8:
+    case Tchar:
+        return llvm::Type::Int8Ty;
+
+    case Tint16:
+    case Tuns16:
+    case Twchar:
+        return llvm::Type::Int16Ty;
+
+    case Tint32:
+    case Tuns32:
+    case Tdchar:
+        return llvm::Type::Int32Ty;
+
+    case Tint64:
+    case Tuns64:
+        return llvm::Type::Int64Ty;
+
+    /*
+    case Tint128:
+    case Tuns128:
+        return llvm::IntegerType::get(128);
+    */
+
+    case Tfloat32:
+    case Timaginary32:
+        return llvm::Type::FloatTy;
+
+    case Tfloat64:
+    case Timaginary64:
+        return llvm::Type::DoubleTy;
+
+    case Tfloat80:
+    case Timaginary80:
+        // only x86 has 80bit float
+        if (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64)
+            return llvm::Type::X86_FP80Ty;
+        // other platforms use 64bit reals
+        else
+            return llvm::Type::DoubleTy;
+
+    case Tcomplex32:
+        t2 = llvm::Type::FloatTy;
+        return llvm::StructType::get(t2, t2, NULL);
+
+    case Tcomplex64:
+        t2 = llvm::Type::DoubleTy;
+        return llvm::StructType::get(t2, t2, NULL);
+
+    case Tcomplex80:
+        t2 = (global.params.cpu == ARCHx86 || global.params.cpu == ARCHx86_64)
+            ? llvm::Type::X86_FP80Ty
+            : llvm::Type::DoubleTy;
+        return llvm::StructType::get(t2, t2, NULL);
+
+    case Tbool:
+        return llvm::Type::Int1Ty;
+    }
+
+    assert(0 && "not basic type");
+    return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrTypePointer::IrTypePointer(Type * dt)
+: IrType(dt, pointer2llvm(dt))
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern const llvm::Type* DtoType(Type* dt);
+
+const llvm::Type * IrTypePointer::pointer2llvm(Type * t)
+{
+    assert(t->ty == Tpointer && "not pointer type");
+
+    const llvm::Type* elemType = DtoType(t->nextOf());
+    if (elemType == llvm::Type::VoidTy)
+        elemType = llvm::Type::Int8Ty;
+    return llvm::PointerType::get(elemType, 0);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrTypeSArray::IrTypeSArray(Type * dt)
+: IrType(dt, sarray2llvm(dt))
+{
+    TypeSArray* tsa = (TypeSArray*)dt;
+    uint64_t d = (uint64_t)tsa->dim->toUInteger();
+    assert(d == dim);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+const llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
+{
+    assert(t->ty == Tsarray && "not static array type");
+
+    TypeSArray* tsa = (TypeSArray*)t;
+    dim = (uint64_t)tsa->dim->toUInteger();
+    const llvm::Type* elemType = DtoType(t->nextOf());
+    if (elemType == llvm::Type::VoidTy)
+        elemType = llvm::Type::Int8Ty;
+    return llvm::ArrayType::get(elemType, dim);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+IrTypeArray::IrTypeArray(Type * dt)
+: IrType(dt, array2llvm(dt))
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+extern const llvm::Type* DtoSize_t();
+
+const llvm::Type * IrTypeArray::array2llvm(Type * t)
+{
+    assert(t->ty == Tarray && "not dynamic array type");
+
+    const llvm::Type* elemType = DtoType(t->nextOf());
+    if (elemType == llvm::Type::VoidTy)
+        elemType = llvm::Type::Int8Ty;
+    elemType = llvm::PointerType::get(elemType, 0);
+    return llvm::StructType::get(DtoSize_t(), elemType, NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ir/irtype.h	Fri Apr 03 16:34:11 2009 +0200
@@ -0,0 +1,122 @@
+#ifndef __LDC_IR_IRTYPE_H__
+#define __LDC_IR_IRTYPE_H__
+
+#include "llvm/Type.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+// forward declarations
+
+struct Type;
+
+class IrTypeArray;
+class IrTypeBasic;
+class IrTypePointer;
+class IrTypeSArray;
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// Base class for IrTypeS.
+class IrType
+{
+public:
+    ///
+    IrType(Type* dt, const llvm::Type* lt);
+
+    ///
+    Type* getD()                    { return dtype; }
+
+    ///
+    const llvm::Type* get()         { return pa.get(); }
+
+    ///
+    virtual IrTypeArray* isArray()      { return NULL; }
+    ///
+    virtual IrTypeBasic* isBasic()      { return NULL; }
+    ///
+    virtual IrTypePointer* isPointer()  { return NULL; }
+    ///
+    virtual IrTypeSArray* isSArray()    { return NULL; }
+
+protected:
+    ///
+    Type* dtype;
+
+    /// LLVM type holder.
+    llvm::PATypeHolder pa;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// IrType for basic D types.
+class IrTypeBasic : public IrType
+{
+public:
+    ///
+    IrTypeBasic(Type* dt);
+
+    ///
+    IrTypeBasic* isBasic()          { return this; }
+
+protected:
+    ///
+    const llvm::Type* basic2llvm(Type* t);
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// IrType from pointers.
+class IrTypePointer : public IrType
+{
+public:
+    ///
+    IrTypePointer(Type* dt);
+
+    ///
+    IrTypePointer* isPointer()      { return this; }
+
+protected:
+    ///
+    const llvm::Type* pointer2llvm(Type* t);
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// IrType for static arrays
+class IrTypeSArray : public IrType
+{
+public:
+    ///
+    IrTypeSArray(Type* dt);
+
+    ///
+    IrTypeSArray* isSArray()  { return this; }
+
+protected:
+    ///
+    const llvm::Type* sarray2llvm(Type* t);
+
+    /// Dimension.
+    uint64_t dim;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// IrType for dynamic arrays
+class IrTypeArray : public IrType
+{
+public:
+    ///
+    IrTypeArray(Type* dt);
+
+    ///
+    IrTypeArray* isArray()  { return this; }
+
+protected:
+    ///
+    const llvm::Type* array2llvm(Type* t);
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/compile_delegate.d	Fri Apr 03 16:34:11 2009 +0200
@@ -0,0 +1,13 @@
+class A(T)
+{
+   void foo(void delegate (T) d) {}
+
+   void bar()
+   {
+     foo(delegate void (T t) {});
+   }
+}
+
+class B: A!(B) {}
+
+class C: A!(C) {}