mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-14 20:03:14 +01:00
Started seperating type resolution from the rest of codegen again, the merge had too many regressions.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
173
ir/irtype.cpp
Normal 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
122
ir/irtype.h
Normal 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
|
||||
13
tests/mini/compile_delegate.d
Normal file
13
tests/mini/compile_delegate.d
Normal 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) {}
|
||||
Reference in New Issue
Block a user