mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Refactored IrType construction to use static get() method.
This also allows us to enable the assert in IrType::IrType. Unfortunately, this is mostly a "peace of mind" commit, there doesn't seem to have been a bug actually caused by the transitory duplicate IrTypePointer/IrTypeStruct instances. The remaining xyz2llvm static methods are not exactly pretty, they should probably just be folded into get.
This commit is contained in:
@@ -113,55 +113,65 @@ LLType* DtoType(Type* t)
|
||||
case Twchar:
|
||||
case Tdchar:
|
||||
{
|
||||
t->irtype = new IrTypeBasic(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypeBasic::get(t)->getLLType();
|
||||
}
|
||||
|
||||
// pointers
|
||||
case Tnull:
|
||||
case Tpointer:
|
||||
{
|
||||
t->irtype = new IrTypePointer(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypePointer::get(t)->getLLType();
|
||||
}
|
||||
|
||||
// arrays
|
||||
case Tarray:
|
||||
{
|
||||
t->irtype = new IrTypeArray(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypeArray::get(t)->getLLType();
|
||||
}
|
||||
|
||||
case Tsarray:
|
||||
{
|
||||
t->irtype = new IrTypeSArray(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypeSArray::get(t)->getLLType();
|
||||
}
|
||||
|
||||
// aggregates
|
||||
case Tstruct: {
|
||||
case Tstruct:
|
||||
{
|
||||
TypeStruct* ts = static_cast<TypeStruct*>(t);
|
||||
t->irtype = new IrTypeStruct(ts->sym);
|
||||
return t->irtype->buildType();
|
||||
if (ts->sym->type->irtype)
|
||||
{
|
||||
// This should not happen, but the frontend seems to be buggy. Not
|
||||
// sure if this is the best way to handle the situation, but we
|
||||
// certainly don't want to override ts->sym->type->irtype.
|
||||
IF_LOG Logger::cout() << "Struct with multiple Types detected: " <<
|
||||
ts->toChars() << " (" << ts->sym->locToChars() << ")" << std::endl;
|
||||
return ts->sym->type->irtype->getLLType();
|
||||
}
|
||||
return IrTypeStruct::get(ts->sym)->getLLType();
|
||||
}
|
||||
case Tclass: {
|
||||
case Tclass:
|
||||
{
|
||||
TypeClass* tc = static_cast<TypeClass*>(t);
|
||||
t->irtype = new IrTypeClass(tc->sym);
|
||||
return t->irtype->buildType();
|
||||
if (tc->sym->type->irtype)
|
||||
{
|
||||
// See Tstruct case.
|
||||
IF_LOG Logger::cout() << "Class with multiple Types detected: " <<
|
||||
tc->toChars() << " (" << tc->sym->locToChars() << ")" << std::endl;
|
||||
return tc->sym->type->irtype->getLLType();
|
||||
}
|
||||
return IrTypeClass::get(tc->sym)->getLLType();
|
||||
}
|
||||
|
||||
// functions
|
||||
case Tfunction:
|
||||
{
|
||||
t->irtype = new IrTypeFunction(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypeFunction::get(t)->getLLType();
|
||||
}
|
||||
|
||||
// delegates
|
||||
case Tdelegate:
|
||||
{
|
||||
t->irtype = new IrTypeDelegate(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypeDelegate::get(t)->getLLType();
|
||||
}
|
||||
|
||||
// typedefs
|
||||
@@ -183,8 +193,7 @@ LLType* DtoType(Type* t)
|
||||
#if DMDV2
|
||||
case Tvector:
|
||||
{
|
||||
t->irtype = new IrTypeVector(t);
|
||||
return t->irtype->buildType();
|
||||
return IrTypeVector::get(t)->getLLType();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "mtype.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irtype.h"
|
||||
|
||||
// This code uses llvm::getGlobalContext() as these functions are invoked before gIR is set.
|
||||
@@ -20,21 +21,13 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern LLType* DtoType(Type* dt);
|
||||
extern LLIntegerType* DtoSize_t();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrType::IrType(Type* dt, LLType* lt)
|
||||
: dtype(dt),
|
||||
type(lt)
|
||||
{
|
||||
assert(dt && "null D Type");
|
||||
assert(lt && "null LLVM Type");
|
||||
#if 0
|
||||
// FIXME: For some reason the assert fails
|
||||
assert(dt->irtype == NULL && "already has IrType");
|
||||
#endif
|
||||
assert(!dt->irtype && "already has IrType");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -48,9 +41,11 @@ IrTypeBasic::IrTypeBasic(Type * dt)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type * IrTypeBasic::buildType()
|
||||
IrTypeBasic* IrTypeBasic::get(Type* dt)
|
||||
{
|
||||
return type;
|
||||
IrTypeBasic* t = new IrTypeBasic(dt);
|
||||
dt->irtype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -145,35 +140,36 @@ llvm::Type * IrTypeBasic::basic2llvm(Type* t)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrTypePointer::IrTypePointer(Type * dt)
|
||||
: IrType(dt, dt->ty == Tnull ? null2llvm(dt) : pointer2llvm(dt))
|
||||
IrTypePointer::IrTypePointer(Type* dt, LLType* lt)
|
||||
: IrType(dt, lt)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type * IrTypePointer::buildType()
|
||||
IrTypePointer* IrTypePointer::get(Type* dt)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
assert(!dt->irtype);
|
||||
assert((dt->ty == Tpointer || dt->ty == Tnull) && "not pointer/null type");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type * IrTypePointer::pointer2llvm(Type * dt)
|
||||
{
|
||||
assert(dt->ty == Tpointer && "not pointer type");
|
||||
|
||||
LLType* elemType = DtoType(dt->nextOf());
|
||||
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
||||
LLType* elemType;
|
||||
if (dt->ty == Tnull)
|
||||
{
|
||||
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
||||
return llvm::PointerType::get(elemType, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
elemType = DtoTypeNotVoid(dt->nextOf());
|
||||
|
||||
llvm::Type* IrTypePointer::null2llvm(Type* dt)
|
||||
{
|
||||
assert(dt->ty == Tnull && "not null type");
|
||||
LLType* elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
||||
return llvm::PointerType::get(elemType, 0);
|
||||
// DtoTypeNotVoid could have already created the same type, e.g. for
|
||||
// dt == Node* in struct Node { Node* n; }.
|
||||
if (dt->irtype)
|
||||
return dt->irtype->isPointer();
|
||||
}
|
||||
|
||||
IrTypePointer* t = new IrTypePointer(dt, llvm::PointerType::get(elemType, 0));
|
||||
dt->irtype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -187,9 +183,11 @@ IrTypeSArray::IrTypeSArray(Type * dt)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type * IrTypeSArray::buildType()
|
||||
IrTypeSArray* IrTypeSArray::get(Type* dt)
|
||||
{
|
||||
return type;
|
||||
IrTypeSArray* t = new IrTypeSArray(dt);
|
||||
dt->irtype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -198,7 +196,7 @@ llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
|
||||
{
|
||||
assert(t->ty == Tsarray && "not static array type");
|
||||
TypeSArray* tsa = static_cast<TypeSArray*>(t);
|
||||
dim = static_cast<uint64_t>(tsa->dim->toUInteger());
|
||||
uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
|
||||
LLType* elemType = DtoType(t->nextOf());
|
||||
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
||||
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
||||
@@ -216,9 +214,11 @@ IrTypeArray::IrTypeArray(Type * dt)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type * IrTypeArray::buildType()
|
||||
IrTypeArray* IrTypeArray::get(Type* dt)
|
||||
{
|
||||
return type;
|
||||
IrTypeArray* t = new IrTypeArray(dt);
|
||||
dt->irtype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -255,9 +255,11 @@ IrTypeVector::IrTypeVector(Type* dt)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type* IrTypeVector::buildType()
|
||||
IrTypeVector* IrTypeVector::get(Type* dt)
|
||||
{
|
||||
return type;
|
||||
IrTypeVector* t = new IrTypeVector(dt);
|
||||
dt->irtype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -268,7 +270,7 @@ llvm::Type* IrTypeVector::vector2llvm(Type* dt)
|
||||
TypeVector* tv = static_cast<TypeVector*>(dt);
|
||||
assert(tv->basetype->ty == Tsarray);
|
||||
TypeSArray* tsa = static_cast<TypeSArray*>(tv->basetype);
|
||||
dim = static_cast<uint64_t>(tsa->dim->toUInteger());
|
||||
uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
|
||||
LLType* elemType = DtoType(tsa->next);
|
||||
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
||||
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
||||
|
||||
72
ir/irtype.h
72
ir/irtype.h
@@ -8,8 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The types derived from IrType are used to attach LLVM type information and
|
||||
// other codegen metadata (e.g. for vtbl resolution) to frontend Types. There
|
||||
// is an 1:1 correspondence between Type and IrType instances.
|
||||
// other codegen metadata (e.g. for vtbl resolution) to frontend Types.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -40,13 +39,17 @@ class IrTypeVector;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Base class for IrTypeS.
|
||||
/// Code generation state/metadata for D types. The mapping from IrType to
|
||||
/// Type is injective but not surjective.
|
||||
///
|
||||
/// Derived classes should be created using their static get() methods, which
|
||||
/// makes sure that uniqueness is preserved in the face of forward references.
|
||||
/// Note that the get() methods expect the IrType of the passed type/symbol to
|
||||
/// be not yet set. This could be altered to just return the existing IrType
|
||||
/// in order to bring the API entirely in line with the LLVM type get() methods.
|
||||
class IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrType(Type* dt, llvm::Type* lt);
|
||||
|
||||
///
|
||||
virtual IrTypeAggr* isAggr() { return NULL; }
|
||||
///
|
||||
@@ -75,10 +78,10 @@ public:
|
||||
///
|
||||
virtual llvm::Type* getLLType() { return type; }
|
||||
|
||||
///
|
||||
virtual llvm::Type* buildType() = 0;
|
||||
|
||||
protected:
|
||||
///
|
||||
IrType(Type* dt, llvm::Type* lt);
|
||||
|
||||
///
|
||||
Type* dtype;
|
||||
|
||||
@@ -93,19 +96,18 @@ class IrTypeBasic : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeBasic(Type* dt);
|
||||
static IrTypeBasic* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypeBasic* isBasic() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
|
||||
protected:
|
||||
///
|
||||
LLType* getComplexType(llvm::LLVMContext& ctx, LLType* type);
|
||||
IrTypeBasic(Type* dt);
|
||||
///
|
||||
llvm::Type* basic2llvm(Type* t);
|
||||
static LLType* getComplexType(llvm::LLVMContext& ctx, LLType* type);
|
||||
///
|
||||
static llvm::Type* basic2llvm(Type* t);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -115,19 +117,14 @@ class IrTypePointer : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypePointer(Type* dt);
|
||||
static IrTypePointer* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypePointer* isPointer() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
|
||||
protected:
|
||||
///
|
||||
llvm::Type* pointer2llvm(Type* t);
|
||||
///
|
||||
llvm::Type* null2llvm(Type* t);
|
||||
IrTypePointer(Type* dt, LLType *lt);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -137,20 +134,17 @@ class IrTypeSArray : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeSArray(Type* dt);
|
||||
static IrTypeSArray* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypeSArray* isSArray() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
|
||||
protected:
|
||||
///
|
||||
llvm::Type* sarray2llvm(Type* t);
|
||||
IrTypeSArray(Type* dt);
|
||||
|
||||
/// Dimension.
|
||||
uint64_t dim;
|
||||
///
|
||||
static llvm::Type* sarray2llvm(Type* t);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -160,17 +154,16 @@ class IrTypeArray : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeArray(Type* dt);
|
||||
static IrTypeArray* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypeArray* isArray() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
|
||||
protected:
|
||||
///
|
||||
llvm::Type* array2llvm(Type* t);
|
||||
IrTypeArray(Type* dt);
|
||||
///
|
||||
static llvm::Type* array2llvm(Type* t);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -181,17 +174,16 @@ class IrTypeVector : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeVector(Type* dt);
|
||||
static IrTypeVector* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypeVector* isVector() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
protected:
|
||||
llvm::Type* vector2llvm(Type* dt);
|
||||
/// Dimension.
|
||||
uint64_t dim;
|
||||
///
|
||||
IrTypeVector(Type* dt);
|
||||
|
||||
static llvm::Type* vector2llvm(Type* dt);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -222,8 +222,11 @@ void IrTypeClass::addBaseClassData(
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type* IrTypeClass::buildType()
|
||||
IrTypeClass* IrTypeClass::get(ClassDeclaration* cd)
|
||||
{
|
||||
IrTypeClass* t = new IrTypeClass(cd);
|
||||
cd->type->irtype = t;
|
||||
|
||||
IF_LOG Logger::println("Building class type %s @ %s", cd->toPrettyChars(), cd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
IF_LOG Logger::println("Instance size: %u", cd->structsize);
|
||||
@@ -235,12 +238,12 @@ llvm::Type* IrTypeClass::buildType()
|
||||
defaultTypes.reserve(32);
|
||||
|
||||
// add vtbl
|
||||
defaultTypes.push_back(llvm::PointerType::get(vtbl_type, 0));
|
||||
defaultTypes.push_back(llvm::PointerType::get(t->vtbl_type, 0));
|
||||
|
||||
// interfaces are just a vtable
|
||||
if (cd->isInterfaceDeclaration())
|
||||
{
|
||||
num_interface_vtbls = cd->vtblInterfaces ? cd->vtblInterfaces->dim : 0;
|
||||
t->num_interface_vtbls = cd->vtblInterfaces ? cd->vtblInterfaces->dim : 0;
|
||||
}
|
||||
// classes have monitor and fields
|
||||
else
|
||||
@@ -253,7 +256,7 @@ llvm::Type* IrTypeClass::buildType()
|
||||
size_t field_index = 2;
|
||||
|
||||
// add data members recursively
|
||||
addBaseClassData(defaultTypes, cd, offset, field_index);
|
||||
t->addBaseClassData(defaultTypes, cd, offset, field_index);
|
||||
|
||||
#if 1
|
||||
// tail padding?
|
||||
@@ -270,16 +273,16 @@ llvm::Type* IrTypeClass::buildType()
|
||||
fatal();
|
||||
|
||||
// set struct body
|
||||
isaStruct(type)->setBody(defaultTypes, false);
|
||||
isaStruct(t->type)->setBody(defaultTypes, false);
|
||||
|
||||
// VTBL
|
||||
|
||||
// set vtbl type body
|
||||
vtbl_type->setBody(buildVtblType(ClassDeclaration::classinfo->type, &cd->vtbl));
|
||||
t->vtbl_type->setBody(t->buildVtblType(ClassDeclaration::classinfo->type, &cd->vtbl));
|
||||
|
||||
IF_LOG Logger::cout() << "class type: " << *type << std::endl;
|
||||
IF_LOG Logger::cout() << "class type: " << *t->type << std::endl;
|
||||
|
||||
return getLLType();
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -22,14 +22,11 @@ class IrTypeClass : public IrTypeAggr
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeClass(ClassDeclaration* cd);
|
||||
static IrTypeClass* get(ClassDeclaration* cd);
|
||||
|
||||
///
|
||||
virtual IrTypeClass* isClass() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
|
||||
///
|
||||
llvm::Type* getLLType();
|
||||
|
||||
@@ -53,6 +50,9 @@ public:
|
||||
unsigned getNumInterfaceVtbls() { return num_interface_vtbls; }
|
||||
|
||||
protected:
|
||||
///
|
||||
IrTypeClass(ClassDeclaration* cd);
|
||||
|
||||
///
|
||||
ClassDeclaration* cd;
|
||||
///
|
||||
|
||||
@@ -16,47 +16,51 @@
|
||||
|
||||
#include "ir/irtypefunction.h"
|
||||
|
||||
IrTypeFunction::IrTypeFunction(Type* dt)
|
||||
: IrType(dt, func2llvm(dt))
|
||||
IrTypeFunction::IrTypeFunction(Type* dt, LLType* lt)
|
||||
: IrType(dt, lt)
|
||||
{
|
||||
irfty = NULL;
|
||||
}
|
||||
|
||||
llvm::Type * IrTypeFunction::buildType()
|
||||
IrTypeFunction* IrTypeFunction::get(Type* dt)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
assert(dt->ty == Tfunction);
|
||||
|
||||
llvm::Type* IrTypeFunction::func2llvm(Type* dt)
|
||||
{
|
||||
llvm::Type* T;
|
||||
// We can't get cycles here, but we can end up building the type as part of
|
||||
// a class vtbl, ...
|
||||
llvm::Type* lt;
|
||||
TypeFunction* tf = static_cast<TypeFunction*>(dt);
|
||||
if (tf->funcdecl)
|
||||
T = DtoFunctionType(tf->funcdecl);
|
||||
lt = DtoFunctionType(tf->funcdecl);
|
||||
else
|
||||
T = DtoFunctionType(tf,NULL,NULL);
|
||||
return T;
|
||||
lt = DtoFunctionType(tf,NULL,NULL);
|
||||
|
||||
if (!dt->irtype)
|
||||
dt->irtype = new IrTypeFunction(dt, lt);
|
||||
return dt->irtype->isFunction();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrTypeDelegate::IrTypeDelegate(Type * dt)
|
||||
: IrType(dt, delegate2llvm(dt))
|
||||
IrTypeDelegate::IrTypeDelegate(Type * dt, LLType* lt)
|
||||
: IrType(dt, lt)
|
||||
{
|
||||
}
|
||||
|
||||
llvm::Type* IrTypeDelegate::buildType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
llvm::Type* IrTypeDelegate::delegate2llvm(Type* dt)
|
||||
IrTypeDelegate* IrTypeDelegate::get(Type* dt)
|
||||
{
|
||||
assert(dt->ty == Tdelegate);
|
||||
|
||||
// We can't get cycles here, but we can end up building the type as part of
|
||||
// a class vtbl, ...
|
||||
LLType* func = DtoFunctionType(dt->nextOf(), NULL, Type::tvoid->pointerTo());
|
||||
llvm::SmallVector<LLType*, 2> types;
|
||||
types.push_back(getVoidPtrType());
|
||||
types.push_back(getPtrToType(func));
|
||||
LLStructType* dgtype = LLStructType::get(gIR->context(), types);
|
||||
return dgtype;
|
||||
if (!dt->irtype)
|
||||
{
|
||||
llvm::SmallVector<LLType*, 2> types;
|
||||
types.push_back(getVoidPtrType());
|
||||
types.push_back(getPtrToType(func));
|
||||
LLStructType* lt = LLStructType::get(gIR->context(), types);
|
||||
dt->irtype = new IrTypeDelegate(dt, lt);
|
||||
}
|
||||
|
||||
return dt->irtype->isDelegate();
|
||||
}
|
||||
|
||||
@@ -23,18 +23,17 @@ class IrTypeFunction : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeFunction(Type* dt);
|
||||
static IrTypeFunction* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypeFunction* isFunction() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
|
||||
IrFuncTy* fty() { return irfty; }
|
||||
|
||||
protected:
|
||||
llvm::Type* func2llvm(Type* dt);
|
||||
///
|
||||
IrTypeFunction(Type* dt, llvm::Type* lt);
|
||||
|
||||
///
|
||||
IrFuncTy* irfty;
|
||||
};
|
||||
@@ -44,15 +43,14 @@ class IrTypeDelegate : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeDelegate(Type* dt);
|
||||
static IrTypeDelegate* get(Type* dt);
|
||||
|
||||
///
|
||||
IrTypeDelegate* isDelegate() { return this; }
|
||||
|
||||
///
|
||||
llvm::Type* buildType();
|
||||
protected:
|
||||
llvm::Type* delegate2llvm(Type* dt);
|
||||
///
|
||||
IrTypeDelegate(Type* dt, llvm::Type* lt);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -84,20 +84,23 @@ bool var_offset_sort_cb(const VarDeclaration* v1, const VarDeclaration* v2)
|
||||
// this is pretty much the exact same thing we need to do for fields in each
|
||||
// base class of a class
|
||||
|
||||
llvm::Type* IrTypeStruct::buildType()
|
||||
IrTypeStruct* IrTypeStruct::get(StructDeclaration* sd)
|
||||
{
|
||||
IrTypeStruct* t = new IrTypeStruct(sd);
|
||||
sd->type->irtype = t;
|
||||
|
||||
IF_LOG Logger::println("Building struct type %s @ %s",
|
||||
sd->toPrettyChars(), sd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// if it's a forward declaration, all bets are off, stick with the opaque
|
||||
if (sd->sizeok != 1)
|
||||
return type;
|
||||
return t;
|
||||
|
||||
// mirror the sd->fields array but only fill in contributors
|
||||
size_t n = sd->fields.dim;
|
||||
LLSmallVector<VarDeclaration*, 16> data(n, NULL);
|
||||
default_fields.reserve(n);
|
||||
t->default_fields.reserve(n);
|
||||
|
||||
// first fill in the fields with explicit initializers
|
||||
VarDeclarationIter field_it(sd->fields);
|
||||
@@ -197,7 +200,7 @@ llvm::Type* IrTypeStruct::buildType()
|
||||
assert(vd->offset >= offset);
|
||||
|
||||
// add to default field list
|
||||
default_fields.push_back(vd);
|
||||
t->default_fields.push_back(vd);
|
||||
|
||||
// get next aligned offset for this type
|
||||
size_t alignedoffset = offset;
|
||||
@@ -229,11 +232,11 @@ llvm::Type* IrTypeStruct::buildType()
|
||||
}
|
||||
|
||||
// set struct body
|
||||
isaStruct(type)->setBody(defaultTypes, packed);
|
||||
isaStruct(t->type)->setBody(defaultTypes, packed);
|
||||
|
||||
IF_LOG Logger::cout() << "final struct type: " << *type << std::endl;
|
||||
IF_LOG Logger::cout() << "final struct type: " << *t->type << std::endl;
|
||||
|
||||
return type;
|
||||
return t;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -28,9 +28,6 @@ struct TypeStruct;
|
||||
class IrTypeAggr : public IrType
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeAggr(AggregateDeclaration* ad);
|
||||
|
||||
///
|
||||
IrTypeAggr* isAggr() { return this; }
|
||||
|
||||
@@ -44,6 +41,9 @@ public:
|
||||
iterator def_end() { return default_fields.end(); }
|
||||
|
||||
protected:
|
||||
///
|
||||
IrTypeAggr(AggregateDeclaration* ad);
|
||||
|
||||
/// AggregateDeclaration this type represents.
|
||||
AggregateDeclaration* aggr;
|
||||
|
||||
@@ -61,7 +61,7 @@ class IrTypeStruct : public IrTypeAggr
|
||||
{
|
||||
public:
|
||||
///
|
||||
IrTypeStruct(StructDeclaration* sd);
|
||||
static IrTypeStruct* get(StructDeclaration* sd);
|
||||
|
||||
///
|
||||
IrTypeStruct* isStruct() { return this; }
|
||||
@@ -70,6 +70,9 @@ public:
|
||||
llvm::Type* buildType();
|
||||
|
||||
protected:
|
||||
///
|
||||
IrTypeStruct(StructDeclaration* sd);
|
||||
|
||||
/// StructDeclaration this type represents.
|
||||
StructDeclaration* sd;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user