# HG changeset patch # User Tomas Lindquist Olsen # Date 1238769251 -7200 # Node ID 3251ce06c820ea618bce67a00d33db5229783978 # Parent d68796be59fdca00e8cb389fe4274909d0e069da Started seperating type resolution from the rest of codegen again, the merge had too many regressions. diff -r d68796be59fd -r 3251ce06c820 dmd/mtype.c --- 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() diff -r d68796be59fd -r 3251ce06c820 dmd/mtype.h --- 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 }; diff -r d68796be59fd -r 3251ce06c820 gen/tollvm.cpp --- 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: { diff -r d68796be59fd -r 3251ce06c820 ir/irtype.cpp --- /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); +} + +////////////////////////////////////////////////////////////////////////////// + diff -r d68796be59fd -r 3251ce06c820 ir/irtype.h --- /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 diff -r d68796be59fd -r 3251ce06c820 tests/mini/compile_delegate.d --- /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) {}