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:
David Nadlinger 2012-12-20 21:30:29 +01:00
parent 464c695814
commit a3a511ca55
9 changed files with 170 additions and 156 deletions

View file

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

View file

@ -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());

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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