Started seperating type resolution from the rest of codegen again, the merge had too many regressions.

This commit is contained in:
Tomas Lindquist Olsen
2009-04-03 16:34:11 +02:00
parent 4df1f9be35
commit 9c4b2b4036
6 changed files with 349 additions and 32 deletions

View File

@@ -137,6 +137,10 @@ Type::Type(TY ty, Type *next)
#if IN_DMD
this->ctype = NULL;
#endif
#if IN_LLVM
this->irtype = NULL;
#endif
}
Type *Type::syntaxCopy()

View File

@@ -27,6 +27,8 @@
#include "../ir/irfuncty.h"
namespace llvm { class Type; }
struct Ir;
class IrType;
#endif
struct Scope;
@@ -281,6 +283,8 @@ struct Type : Object
// LDC
IrDType ir;
static Ir* sir;
IrType* irtype;
#endif
};

View File

@@ -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 @@ unsigned DtoShouldExtend(Type* type)
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 Timaginary64:
return LLType::DoubleTy;
case Tfloat80:
case Timaginary32:
case Timaginary64:
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: {

173
ir/irtype.cpp Normal file
View File

@@ -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);
}
//////////////////////////////////////////////////////////////////////////////

122
ir/irtype.h Normal file
View File

@@ -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

View File

@@ -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) {}