mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-12 13:55:57 +03: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:
parent
464c695814
commit
a3a511ca55
9 changed files with 170 additions and 156 deletions
|
@ -113,55 +113,65 @@ LLType* DtoType(Type* t)
|
||||||
case Twchar:
|
case Twchar:
|
||||||
case Tdchar:
|
case Tdchar:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypeBasic(t);
|
return IrTypeBasic::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pointers
|
// pointers
|
||||||
case Tnull:
|
case Tnull:
|
||||||
case Tpointer:
|
case Tpointer:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypePointer(t);
|
return IrTypePointer::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrays
|
// arrays
|
||||||
case Tarray:
|
case Tarray:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypeArray(t);
|
return IrTypeArray::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Tsarray:
|
case Tsarray:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypeSArray(t);
|
return IrTypeSArray::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// aggregates
|
// aggregates
|
||||||
case Tstruct: {
|
case Tstruct:
|
||||||
|
{
|
||||||
TypeStruct* ts = static_cast<TypeStruct*>(t);
|
TypeStruct* ts = static_cast<TypeStruct*>(t);
|
||||||
t->irtype = new IrTypeStruct(ts->sym);
|
if (ts->sym->type->irtype)
|
||||||
return t->irtype->buildType();
|
{
|
||||||
|
// 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);
|
TypeClass* tc = static_cast<TypeClass*>(t);
|
||||||
t->irtype = new IrTypeClass(tc->sym);
|
if (tc->sym->type->irtype)
|
||||||
return t->irtype->buildType();
|
{
|
||||||
|
// 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
|
// functions
|
||||||
case Tfunction:
|
case Tfunction:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypeFunction(t);
|
return IrTypeFunction::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delegates
|
// delegates
|
||||||
case Tdelegate:
|
case Tdelegate:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypeDelegate(t);
|
return IrTypeDelegate::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedefs
|
// typedefs
|
||||||
|
@ -183,8 +193,7 @@ LLType* DtoType(Type* t)
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
case Tvector:
|
case Tvector:
|
||||||
{
|
{
|
||||||
t->irtype = new IrTypeVector(t);
|
return IrTypeVector::get(t)->getLLType();
|
||||||
return t->irtype->buildType();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
|
#include "gen/tollvm.h"
|
||||||
#include "ir/irtype.h"
|
#include "ir/irtype.h"
|
||||||
|
|
||||||
// This code uses llvm::getGlobalContext() as these functions are invoked before gIR is set.
|
// 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)
|
IrType::IrType(Type* dt, LLType* lt)
|
||||||
: dtype(dt),
|
: dtype(dt),
|
||||||
type(lt)
|
type(lt)
|
||||||
{
|
{
|
||||||
assert(dt && "null D Type");
|
assert(dt && "null D Type");
|
||||||
assert(lt && "null LLVM Type");
|
assert(lt && "null LLVM Type");
|
||||||
#if 0
|
assert(!dt->irtype && "already has IrType");
|
||||||
// FIXME: For some reason the assert fails
|
|
||||||
assert(dt->irtype == NULL && "already has IrType");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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)
|
IrTypePointer::IrTypePointer(Type* dt, LLType* lt)
|
||||||
: IrType(dt, dt->ty == Tnull ? null2llvm(dt) : pointer2llvm(dt))
|
: 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");
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
LLType* elemType;
|
||||||
|
if (dt->ty == Tnull)
|
||||||
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()))
|
|
||||||
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
||||||
return llvm::PointerType::get(elemType, 0);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
elemType = DtoTypeNotVoid(dt->nextOf());
|
||||||
|
|
||||||
llvm::Type* IrTypePointer::null2llvm(Type* dt)
|
// DtoTypeNotVoid could have already created the same type, e.g. for
|
||||||
{
|
// dt == Node* in struct Node { Node* n; }.
|
||||||
assert(dt->ty == Tnull && "not null type");
|
if (dt->irtype)
|
||||||
LLType* elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
return dt->irtype->isPointer();
|
||||||
return llvm::PointerType::get(elemType, 0);
|
}
|
||||||
|
|
||||||
|
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");
|
assert(t->ty == Tsarray && "not static array type");
|
||||||
TypeSArray* tsa = static_cast<TypeSArray*>(t);
|
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());
|
LLType* elemType = DtoType(t->nextOf());
|
||||||
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
||||||
elemType = llvm::Type::getInt8Ty(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);
|
TypeVector* tv = static_cast<TypeVector*>(dt);
|
||||||
assert(tv->basetype->ty == Tsarray);
|
assert(tv->basetype->ty == Tsarray);
|
||||||
TypeSArray* tsa = static_cast<TypeSArray*>(tv->basetype);
|
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);
|
LLType* elemType = DtoType(tsa->next);
|
||||||
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
||||||
elemType = llvm::Type::getInt8Ty(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
|
// 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
|
// other codegen metadata (e.g. for vtbl resolution) to frontend Types.
|
||||||
// is an 1:1 correspondence between Type and IrType instances.
|
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
@ -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
|
class IrType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
IrType(Type* dt, llvm::Type* lt);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
virtual IrTypeAggr* isAggr() { return NULL; }
|
virtual IrTypeAggr* isAggr() { return NULL; }
|
||||||
///
|
///
|
||||||
|
@ -75,10 +78,10 @@ public:
|
||||||
///
|
///
|
||||||
virtual llvm::Type* getLLType() { return type; }
|
virtual llvm::Type* getLLType() { return type; }
|
||||||
|
|
||||||
///
|
|
||||||
virtual llvm::Type* buildType() = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
///
|
||||||
|
IrType(Type* dt, llvm::Type* lt);
|
||||||
|
|
||||||
///
|
///
|
||||||
Type* dtype;
|
Type* dtype;
|
||||||
|
|
||||||
|
@ -93,19 +96,18 @@ class IrTypeBasic : public IrType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeBasic(Type* dt);
|
static IrTypeBasic* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeBasic* isBasic() { return this; }
|
IrTypeBasic* isBasic() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
|
|
||||||
protected:
|
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:
|
public:
|
||||||
///
|
///
|
||||||
IrTypePointer(Type* dt);
|
static IrTypePointer* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypePointer* isPointer() { return this; }
|
IrTypePointer* isPointer() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
llvm::Type* pointer2llvm(Type* t);
|
IrTypePointer(Type* dt, LLType *lt);
|
||||||
///
|
|
||||||
llvm::Type* null2llvm(Type* t);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -137,20 +134,17 @@ class IrTypeSArray : public IrType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeSArray(Type* dt);
|
static IrTypeSArray* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeSArray* isSArray() { return this; }
|
IrTypeSArray* isSArray() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
|
|
||||||
protected:
|
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:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeArray(Type* dt);
|
static IrTypeArray* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeArray* isArray() { return this; }
|
IrTypeArray* isArray() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
llvm::Type* array2llvm(Type* t);
|
IrTypeArray(Type* dt);
|
||||||
|
///
|
||||||
|
static llvm::Type* array2llvm(Type* t);
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -181,17 +174,16 @@ class IrTypeVector : public IrType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeVector(Type* dt);
|
static IrTypeVector* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeVector* isVector() { return this; }
|
IrTypeVector* isVector() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
protected:
|
protected:
|
||||||
llvm::Type* vector2llvm(Type* dt);
|
///
|
||||||
/// Dimension.
|
IrTypeVector(Type* dt);
|
||||||
uint64_t dim;
|
|
||||||
|
static llvm::Type* vector2llvm(Type* dt);
|
||||||
};
|
};
|
||||||
#endif
|
#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());
|
IF_LOG Logger::println("Building class type %s @ %s", cd->toPrettyChars(), cd->loc.toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
IF_LOG Logger::println("Instance size: %u", cd->structsize);
|
IF_LOG Logger::println("Instance size: %u", cd->structsize);
|
||||||
|
@ -235,12 +238,12 @@ llvm::Type* IrTypeClass::buildType()
|
||||||
defaultTypes.reserve(32);
|
defaultTypes.reserve(32);
|
||||||
|
|
||||||
// add vtbl
|
// 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
|
// interfaces are just a vtable
|
||||||
if (cd->isInterfaceDeclaration())
|
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
|
// classes have monitor and fields
|
||||||
else
|
else
|
||||||
|
@ -253,7 +256,7 @@ llvm::Type* IrTypeClass::buildType()
|
||||||
size_t field_index = 2;
|
size_t field_index = 2;
|
||||||
|
|
||||||
// add data members recursively
|
// add data members recursively
|
||||||
addBaseClassData(defaultTypes, cd, offset, field_index);
|
t->addBaseClassData(defaultTypes, cd, offset, field_index);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// tail padding?
|
// tail padding?
|
||||||
|
@ -270,16 +273,16 @@ llvm::Type* IrTypeClass::buildType()
|
||||||
fatal();
|
fatal();
|
||||||
|
|
||||||
// set struct body
|
// set struct body
|
||||||
isaStruct(type)->setBody(defaultTypes, false);
|
isaStruct(t->type)->setBody(defaultTypes, false);
|
||||||
|
|
||||||
// VTBL
|
// VTBL
|
||||||
|
|
||||||
// set vtbl type body
|
// 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:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeClass(ClassDeclaration* cd);
|
static IrTypeClass* get(ClassDeclaration* cd);
|
||||||
|
|
||||||
///
|
///
|
||||||
virtual IrTypeClass* isClass() { return this; }
|
virtual IrTypeClass* isClass() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
|
|
||||||
///
|
///
|
||||||
llvm::Type* getLLType();
|
llvm::Type* getLLType();
|
||||||
|
|
||||||
|
@ -53,6 +50,9 @@ public:
|
||||||
unsigned getNumInterfaceVtbls() { return num_interface_vtbls; }
|
unsigned getNumInterfaceVtbls() { return num_interface_vtbls; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
///
|
||||||
|
IrTypeClass(ClassDeclaration* cd);
|
||||||
|
|
||||||
///
|
///
|
||||||
ClassDeclaration* cd;
|
ClassDeclaration* cd;
|
||||||
///
|
///
|
||||||
|
|
|
@ -16,47 +16,51 @@
|
||||||
|
|
||||||
#include "ir/irtypefunction.h"
|
#include "ir/irtypefunction.h"
|
||||||
|
|
||||||
IrTypeFunction::IrTypeFunction(Type* dt)
|
IrTypeFunction::IrTypeFunction(Type* dt, LLType* lt)
|
||||||
: IrType(dt, func2llvm(dt))
|
: 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)
|
// We can't get cycles here, but we can end up building the type as part of
|
||||||
{
|
// a class vtbl, ...
|
||||||
llvm::Type* T;
|
llvm::Type* lt;
|
||||||
TypeFunction* tf = static_cast<TypeFunction*>(dt);
|
TypeFunction* tf = static_cast<TypeFunction*>(dt);
|
||||||
if (tf->funcdecl)
|
if (tf->funcdecl)
|
||||||
T = DtoFunctionType(tf->funcdecl);
|
lt = DtoFunctionType(tf->funcdecl);
|
||||||
else
|
else
|
||||||
T = DtoFunctionType(tf,NULL,NULL);
|
lt = DtoFunctionType(tf,NULL,NULL);
|
||||||
return T;
|
|
||||||
|
if (!dt->irtype)
|
||||||
|
dt->irtype = new IrTypeFunction(dt, lt);
|
||||||
|
return dt->irtype->isFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
IrTypeDelegate::IrTypeDelegate(Type * dt)
|
IrTypeDelegate::IrTypeDelegate(Type * dt, LLType* lt)
|
||||||
: IrType(dt, delegate2llvm(dt))
|
: IrType(dt, lt)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Type* IrTypeDelegate::buildType()
|
IrTypeDelegate* IrTypeDelegate::get(Type* dt)
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
llvm::Type* IrTypeDelegate::delegate2llvm(Type* dt)
|
|
||||||
{
|
{
|
||||||
assert(dt->ty == Tdelegate);
|
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());
|
LLType* func = DtoFunctionType(dt->nextOf(), NULL, Type::tvoid->pointerTo());
|
||||||
llvm::SmallVector<LLType*, 2> types;
|
if (!dt->irtype)
|
||||||
types.push_back(getVoidPtrType());
|
{
|
||||||
types.push_back(getPtrToType(func));
|
llvm::SmallVector<LLType*, 2> types;
|
||||||
LLStructType* dgtype = LLStructType::get(gIR->context(), types);
|
types.push_back(getVoidPtrType());
|
||||||
return dgtype;
|
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:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeFunction(Type* dt);
|
static IrTypeFunction* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeFunction* isFunction() { return this; }
|
IrTypeFunction* isFunction() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
|
|
||||||
IrFuncTy* fty() { return irfty; }
|
IrFuncTy* fty() { return irfty; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
llvm::Type* func2llvm(Type* dt);
|
///
|
||||||
|
IrTypeFunction(Type* dt, llvm::Type* lt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrFuncTy* irfty;
|
IrFuncTy* irfty;
|
||||||
};
|
};
|
||||||
|
@ -44,15 +43,14 @@ class IrTypeDelegate : public IrType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeDelegate(Type* dt);
|
static IrTypeDelegate* get(Type* dt);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeDelegate* isDelegate() { return this; }
|
IrTypeDelegate* isDelegate() { return this; }
|
||||||
|
|
||||||
///
|
|
||||||
llvm::Type* buildType();
|
|
||||||
protected:
|
protected:
|
||||||
llvm::Type* delegate2llvm(Type* dt);
|
///
|
||||||
|
IrTypeDelegate(Type* dt, llvm::Type* lt);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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
|
// this is pretty much the exact same thing we need to do for fields in each
|
||||||
// base class of a class
|
// 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",
|
IF_LOG Logger::println("Building struct type %s @ %s",
|
||||||
sd->toPrettyChars(), sd->loc.toChars());
|
sd->toPrettyChars(), sd->loc.toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
// if it's a forward declaration, all bets are off, stick with the opaque
|
// if it's a forward declaration, all bets are off, stick with the opaque
|
||||||
if (sd->sizeok != 1)
|
if (sd->sizeok != 1)
|
||||||
return type;
|
return t;
|
||||||
|
|
||||||
// mirror the sd->fields array but only fill in contributors
|
// mirror the sd->fields array but only fill in contributors
|
||||||
size_t n = sd->fields.dim;
|
size_t n = sd->fields.dim;
|
||||||
LLSmallVector<VarDeclaration*, 16> data(n, NULL);
|
LLSmallVector<VarDeclaration*, 16> data(n, NULL);
|
||||||
default_fields.reserve(n);
|
t->default_fields.reserve(n);
|
||||||
|
|
||||||
// first fill in the fields with explicit initializers
|
// first fill in the fields with explicit initializers
|
||||||
VarDeclarationIter field_it(sd->fields);
|
VarDeclarationIter field_it(sd->fields);
|
||||||
|
@ -197,7 +200,7 @@ llvm::Type* IrTypeStruct::buildType()
|
||||||
assert(vd->offset >= offset);
|
assert(vd->offset >= offset);
|
||||||
|
|
||||||
// add to default field list
|
// add to default field list
|
||||||
default_fields.push_back(vd);
|
t->default_fields.push_back(vd);
|
||||||
|
|
||||||
// get next aligned offset for this type
|
// get next aligned offset for this type
|
||||||
size_t alignedoffset = offset;
|
size_t alignedoffset = offset;
|
||||||
|
@ -229,11 +232,11 @@ llvm::Type* IrTypeStruct::buildType()
|
||||||
}
|
}
|
||||||
|
|
||||||
// set struct body
|
// 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
|
class IrTypeAggr : public IrType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
|
||||||
IrTypeAggr(AggregateDeclaration* ad);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeAggr* isAggr() { return this; }
|
IrTypeAggr* isAggr() { return this; }
|
||||||
|
|
||||||
|
@ -44,6 +41,9 @@ public:
|
||||||
iterator def_end() { return default_fields.end(); }
|
iterator def_end() { return default_fields.end(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
///
|
||||||
|
IrTypeAggr(AggregateDeclaration* ad);
|
||||||
|
|
||||||
/// AggregateDeclaration this type represents.
|
/// AggregateDeclaration this type represents.
|
||||||
AggregateDeclaration* aggr;
|
AggregateDeclaration* aggr;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ class IrTypeStruct : public IrTypeAggr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
IrTypeStruct(StructDeclaration* sd);
|
static IrTypeStruct* get(StructDeclaration* sd);
|
||||||
|
|
||||||
///
|
///
|
||||||
IrTypeStruct* isStruct() { return this; }
|
IrTypeStruct* isStruct() { return this; }
|
||||||
|
@ -70,6 +70,9 @@ public:
|
||||||
llvm::Type* buildType();
|
llvm::Type* buildType();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
///
|
||||||
|
IrTypeStruct(StructDeclaration* sd);
|
||||||
|
|
||||||
/// StructDeclaration this type represents.
|
/// StructDeclaration this type represents.
|
||||||
StructDeclaration* sd;
|
StructDeclaration* sd;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue