mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
Refactoring: Introduce getIrType()
As *the* way to access the IrType associated with a Type via its `ctype` field. Most importantly, it makes sure all access is redirected to the *unqualified* type's `ctype`, which allows to get rid of the 'multiple types' workaround for aggregates in DtoType(). Those were e.g. hit for `shared struct SpinLock`, where the struct's type includes the `shared` modifier...
This commit is contained in:
parent
ab2ae5e0a2
commit
3f716ff75e
15 changed files with 117 additions and 115 deletions
|
@ -761,9 +761,8 @@ DISubroutineType DIBuilder::CreateFunctionType(Type *type) {
|
|||
|
||||
// The calling convention has to be recorded to distinguish
|
||||
// extern(D) functions from extern(C++) ones.
|
||||
DtoType(t);
|
||||
assert(t->ctype);
|
||||
unsigned CC = t->ctype->getIrFuncTy().reverseParams ? DW_CC_D_dmd : 0;
|
||||
unsigned CC =
|
||||
getIrType(t, true)->getIrFuncTy().reverseParams ? DW_CC_D_dmd : 0;
|
||||
|
||||
return DBuilder.createSubroutineType(paramsArray, DIFlags::FlagZero, CC);
|
||||
}
|
||||
|
|
|
@ -1806,9 +1806,9 @@ LLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad,
|
|||
// Look up field to index and any offset to apply.
|
||||
unsigned fieldIndex;
|
||||
unsigned byteOffset;
|
||||
assert(ad->type->ctype->isAggr());
|
||||
static_cast<IrTypeAggr *>(ad->type->ctype)
|
||||
->getMemberLocation(vd, fieldIndex, byteOffset);
|
||||
auto irTypeAggr = getIrType(ad->type)->isAggr();
|
||||
assert(irTypeAggr);
|
||||
irTypeAggr->getMemberLocation(vd, fieldIndex, byteOffset);
|
||||
|
||||
LLValue *val = DtoGEP(src, 0, fieldIndex);
|
||||
|
||||
|
@ -1828,9 +1828,9 @@ LLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad,
|
|||
unsigned getFieldGEPIndex(AggregateDeclaration *ad, VarDeclaration *vd) {
|
||||
unsigned fieldIndex;
|
||||
unsigned byteOffset;
|
||||
assert(ad->type->ctype->isAggr());
|
||||
static_cast<IrTypeAggr *>(ad->type->ctype)
|
||||
->getMemberLocation(vd, fieldIndex, byteOffset);
|
||||
auto irTypeAggr = getIrType(ad->type)->isAggr();
|
||||
assert(irTypeAggr);
|
||||
irTypeAggr->getMemberLocation(vd, fieldIndex, byteOffset);
|
||||
assert(byteOffset == 0 && "Cannot address field by a simple GEP.");
|
||||
return fieldIndex;
|
||||
}
|
||||
|
|
|
@ -258,9 +258,8 @@ struct LazyFunctionDeclarer {
|
|||
// the call to DtoType performs many actions such as rewriting the function
|
||||
// type and storing it in dty
|
||||
auto llfunctype = llvm::cast<llvm::FunctionType>(DtoType(dty));
|
||||
assert(dty->ctype);
|
||||
auto attrs =
|
||||
dty->ctype->getIrFuncTy().getParamAttrs(gABI->passThisBeforeSret(dty));
|
||||
auto attrs = getIrType(dty)->getIrFuncTy().getParamAttrs(
|
||||
gABI->passThisBeforeSret(dty));
|
||||
attrs.merge(attributes);
|
||||
|
||||
for (auto fname : mangledFunctionNames) {
|
||||
|
|
|
@ -40,10 +40,7 @@ IrFuncTy &DtoIrTypeFunction(DValue *fnval) {
|
|||
}
|
||||
}
|
||||
|
||||
Type *type = stripModifiers(fnval->type->toBasetype());
|
||||
DtoType(type);
|
||||
assert(type->ctype);
|
||||
return type->ctype->getIrFuncTy();
|
||||
return getIrType(fnval->type->toBasetype(), true)->getIrFuncTy();
|
||||
}
|
||||
|
||||
TypeFunction *DtoTypeFunction(DValue *fnval) {
|
||||
|
|
|
@ -289,7 +289,7 @@ public:
|
|||
static_cast<TypeClass *>(tb)->sym->isInterfaceDeclaration()) {
|
||||
assert(it->isBaseOf(cd, NULL));
|
||||
|
||||
IrTypeClass *typeclass = cd->type->ctype->isClass();
|
||||
IrTypeClass *typeclass = getIrType(cd->type)->isClass();
|
||||
|
||||
// find interface impl
|
||||
size_t i_index = typeclass->getInterfaceIndex(it);
|
||||
|
@ -565,7 +565,7 @@ public:
|
|||
IF_LOG Logger::cout() << "Using existing global: " << *result << '\n';
|
||||
} else {
|
||||
auto globalVar = new llvm::GlobalVariable(
|
||||
p->module, origClass->type->ctype->isClass()->getMemoryLLType(),
|
||||
p->module, getIrType(origClass->type)->isClass()->getMemoryLLType(),
|
||||
false, llvm::GlobalValue::InternalLinkage, nullptr, ".classref");
|
||||
p->setStructLiteralConstant(value, globalVar);
|
||||
|
||||
|
@ -615,10 +615,9 @@ public:
|
|||
if (InterfaceDeclaration *it = targetClass->isInterfaceDeclaration()) {
|
||||
assert(it->isBaseOf(origClass, NULL));
|
||||
|
||||
IrTypeClass *typeclass = origClass->type->ctype->isClass();
|
||||
|
||||
// find interface impl
|
||||
size_t i_index = typeclass->getInterfaceIndex(it);
|
||||
size_t i_index =
|
||||
getIrType(origClass->type)->isClass()->getInterfaceIndex(it);
|
||||
assert(i_index != ~0UL);
|
||||
|
||||
// offset pointer
|
||||
|
|
|
@ -124,32 +124,16 @@ LLType *DtoType(Type *t) {
|
|||
|
||||
// aggregates
|
||||
case Tstruct: {
|
||||
TypeStruct *ts = static_cast<TypeStruct *>(t);
|
||||
if (ts->sym->type->ty == Terror)
|
||||
auto sd = static_cast<TypeStruct *>(t)->sym;
|
||||
if (sd->type->ty == Terror)
|
||||
return getOpaqueErrorType();
|
||||
if (ts->sym->type->ctype) {
|
||||
// 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->ctype.
|
||||
IF_LOG Logger::cout()
|
||||
<< "Struct with multiple Types detected: " << ts->toChars() << " ("
|
||||
<< ts->sym->locToChars() << ")" << std::endl;
|
||||
return ts->sym->type->ctype->getLLType();
|
||||
}
|
||||
return IrTypeStruct::get(ts->sym)->getLLType();
|
||||
return IrTypeStruct::get(sd)->getLLType();
|
||||
}
|
||||
case Tclass: {
|
||||
TypeClass *tc = static_cast<TypeClass *>(t);
|
||||
if (tc->sym->type->ty == Terror)
|
||||
auto cd = static_cast<TypeClass *>(t)->sym;
|
||||
if (cd->type->ty == Terror)
|
||||
return getOpaqueErrorType();
|
||||
if (tc->sym->type->ctype) {
|
||||
// See Tstruct case.
|
||||
IF_LOG Logger::cout()
|
||||
<< "Class with multiple Types detected: " << tc->toChars() << " ("
|
||||
<< tc->sym->locToChars() << ")" << std::endl;
|
||||
return tc->sym->type->ctype->getLLType();
|
||||
}
|
||||
return IrTypeClass::get(tc->sym)->getLLType();
|
||||
return IrTypeClass::get(cd)->getLLType();
|
||||
}
|
||||
|
||||
// functions
|
||||
|
@ -182,9 +166,8 @@ LLType *DtoType(Type *t) {
|
|||
case Taarray:
|
||||
return getVoidPtrType();
|
||||
|
||||
case Tvector: {
|
||||
case Tvector:
|
||||
return IrTypeVector::get(t)->getLLType();
|
||||
}
|
||||
|
||||
default:
|
||||
llvm_unreachable("Unknown class of D Type!");
|
||||
|
|
|
@ -179,8 +179,7 @@ void TryCatchScope::emitCatchBodies(IRState &irs, llvm::Value *ehPtrSlot) {
|
|||
b.push(cpp_ti);
|
||||
|
||||
auto wrapperType = llvm::cast<llvm::StructType>(
|
||||
static_cast<IrTypeClass *>(cppTypeInfoPtrType->ctype)
|
||||
->getMemoryLLType());
|
||||
getIrType(cppTypeInfoPtrType)->isClass()->getMemoryLLType());
|
||||
auto wrapperInit = b.get_constant(wrapperType);
|
||||
|
||||
ci = defineGlobal(p.cd->loc, irs.module, wrapperMangle, wrapperInit,
|
||||
|
|
|
@ -35,7 +35,7 @@ llvm::StructType *IrAggr::getLLStructType() {
|
|||
return llStructType;
|
||||
|
||||
LLType *llType = DtoType(type);
|
||||
if (auto irClassType = type->ctype->isClass())
|
||||
if (auto irClassType = getIrType(type)->isClass())
|
||||
llType = irClassType->getMemoryLLType();
|
||||
|
||||
llStructType = llvm::dyn_cast<LLStructType>(llType);
|
||||
|
@ -223,7 +223,7 @@ IrAggr::createInitializerConstant(const VarInitMap &explicitInitializers) {
|
|||
}
|
||||
|
||||
// build constant
|
||||
const bool isPacked = static_cast<IrTypeAggr *>(type->ctype)->packed;
|
||||
const bool isPacked = getIrType(type)->isAggr()->packed;
|
||||
LLStructType *llType =
|
||||
isCompatible ? llStructType
|
||||
: LLStructType::get(gIR->context(), types, isPacked);
|
||||
|
|
|
@ -45,7 +45,7 @@ IrClass::IrClass(ClassDeclaration *cd) : IrAggr(cd) {
|
|||
addInterfaceVtbls(cd);
|
||||
|
||||
assert(interfacesWithVtbls.size() ==
|
||||
stripModifiers(type)->ctype->isClass()->getNumInterfaceVtbls() &&
|
||||
getIrType(type)->isClass()->getNumInterfaceVtbls() &&
|
||||
"inconsistent number of interface vtables in this class");
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ LLGlobalVariable *IrClass::getVtblSymbol(bool define) {
|
|||
if (!vtbl) {
|
||||
const auto irMangle = getIRMangledVTableSymbolName(aggrdecl);
|
||||
|
||||
LLType *vtblTy = stripModifiers(type)->ctype->isClass()->getVtblType();
|
||||
LLType *vtblTy = getIrType(type)->isClass()->getVtblType();
|
||||
|
||||
vtbl = declareGlobal(aggrdecl->loc, gIR->module, vtblTy, irMangle,
|
||||
/*isConstant=*/true);
|
||||
|
@ -91,9 +91,7 @@ LLGlobalVariable *IrClass::getClassInfoSymbol(bool define) {
|
|||
// The type is also ClassInfo for interfaces – the actual TypeInfo for them
|
||||
// is a TypeInfo_Interface instance that references __ClassZ in its "base"
|
||||
// member.
|
||||
Type *cinfoType = getClassInfoType();
|
||||
DtoType(cinfoType);
|
||||
IrTypeClass *tc = stripModifiers(cinfoType)->ctype->isClass();
|
||||
IrTypeClass *tc = getIrType(getClassInfoType(), true)->isClass();
|
||||
assert(tc && "invalid ClassInfo type");
|
||||
|
||||
// We need to keep the symbol mutable as the type is not declared as
|
||||
|
@ -152,7 +150,7 @@ LLGlobalVariable *IrClass::getInterfaceArraySymbol() {
|
|||
|
||||
ClassDeclaration *cd = aggrdecl->isClassDeclaration();
|
||||
|
||||
size_t n = stripModifiers(type)->ctype->isClass()->getNumInterfaceVtbls();
|
||||
size_t n = getIrType(type)->isClass()->getNumInterfaceVtbls();
|
||||
assert(n > 0 && "getting ClassInfo.interfaces storage symbol, but we "
|
||||
"don't implement any interfaces");
|
||||
|
||||
|
@ -657,7 +655,7 @@ LLConstant *IrClass::getInterfaceVtblInit(BaseClass *b,
|
|||
|
||||
void IrClass::defineInterfaceVtbls() {
|
||||
const size_t n = interfacesWithVtbls.size();
|
||||
assert(n == stripModifiers(type)->ctype->isClass()->getNumInterfaceVtbls() &&
|
||||
assert(n == getIrType(type)->isClass()->getNumInterfaceVtbls() &&
|
||||
"inconsistent number of interface vtables in this class");
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
|
@ -676,7 +674,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
|
|||
assert(cd);
|
||||
|
||||
size_t n = interfacesWithVtbls.size();
|
||||
assert(stripModifiers(type)->ctype->isClass()->getNumInterfaceVtbls() == n &&
|
||||
assert(getIrType(type)->isClass()->getNumInterfaceVtbls() == n &&
|
||||
"inconsistent number of interface vtables in this class");
|
||||
|
||||
Type *interfacesArrayType = getInterfacesArrayType();
|
||||
|
@ -710,7 +708,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
|
|||
|
||||
IrClass *irinter = getIrAggr(it->sym);
|
||||
assert(irinter && "interface has null IrStruct");
|
||||
IrTypeClass *itc = stripModifiers(irinter->type)->ctype->isClass();
|
||||
IrTypeClass *itc = getIrType(irinter->type)->isClass();
|
||||
assert(itc && "null interface IrTypeClass");
|
||||
|
||||
// classinfo
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
namespace {
|
||||
LLStructType* getTypeInfoStructMemType() {
|
||||
Type *t = getStructTypeInfoType();
|
||||
DtoType(t);
|
||||
IrTypeClass *tc = t->ctype->isClass();
|
||||
IrTypeClass *tc = getIrType(t, true)->isClass();
|
||||
assert(tc && "invalid TypeInfo_Struct type");
|
||||
|
||||
return llvm::cast<LLStructType>(tc->getMemoryLLType());
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
IrType::IrType(Type *dt, LLType *lt) : dtype(dt), type(lt) {
|
||||
assert(dt && "null D Type");
|
||||
assert(lt && "null LLVM Type");
|
||||
assert(!dt->ctype && "already has IrType");
|
||||
assert(!getIrType(dt) && "already has IrType");
|
||||
}
|
||||
|
||||
IrFuncTy &IrType::getIrFuncTy() {
|
||||
|
@ -37,7 +37,7 @@ IrTypeBasic::IrTypeBasic(Type *dt) : IrType(dt, basic2llvm(dt)) {}
|
|||
|
||||
IrTypeBasic *IrTypeBasic::get(Type *dt) {
|
||||
auto t = new IrTypeBasic(dt);
|
||||
dt->ctype = t;
|
||||
getIrType(dt) = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -136,9 +136,11 @@ llvm::Type *IrTypeBasic::basic2llvm(Type *t) {
|
|||
IrTypePointer::IrTypePointer(Type *dt, LLType *lt) : IrType(dt, lt) {}
|
||||
|
||||
IrTypePointer *IrTypePointer::get(Type *dt) {
|
||||
assert(!dt->ctype);
|
||||
assert((dt->ty == Tpointer || dt->ty == Tnull) && "not pointer/null type");
|
||||
|
||||
auto &ctype = getIrType(dt);
|
||||
assert(!ctype);
|
||||
|
||||
LLType *elemType;
|
||||
if (dt->ty == Tnull) {
|
||||
elemType = llvm::Type::getInt8Ty(getGlobalContext());
|
||||
|
@ -147,13 +149,13 @@ IrTypePointer *IrTypePointer::get(Type *dt) {
|
|||
|
||||
// DtoType could have already created the same type, e.g. for
|
||||
// dt == Node* in struct Node { Node* n; }.
|
||||
if (dt->ctype) {
|
||||
return dt->ctype->isPointer();
|
||||
if (ctype) {
|
||||
return ctype->isPointer();
|
||||
}
|
||||
}
|
||||
|
||||
auto t = new IrTypePointer(dt, llvm::PointerType::get(elemType, 0));
|
||||
dt->ctype = t;
|
||||
ctype = t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -162,20 +164,22 @@ IrTypePointer *IrTypePointer::get(Type *dt) {
|
|||
IrTypeSArray::IrTypeSArray(Type *dt, LLType *lt) : IrType(dt, lt) {}
|
||||
|
||||
IrTypeSArray *IrTypeSArray::get(Type *dt) {
|
||||
assert(!dt->ctype);
|
||||
assert(dt->ty == Tsarray && "not static array type");
|
||||
|
||||
auto &ctype = getIrType(dt);
|
||||
assert(!ctype);
|
||||
|
||||
LLType *elemType = DtoMemType(dt->nextOf());
|
||||
|
||||
// We might have already built the type during DtoMemType e.g. as part of a
|
||||
// forward reference in a struct.
|
||||
if (!dt->ctype) {
|
||||
if (!ctype) {
|
||||
TypeSArray *tsa = static_cast<TypeSArray *>(dt);
|
||||
uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
|
||||
dt->ctype = new IrTypeSArray(dt, llvm::ArrayType::get(elemType, dim));
|
||||
ctype = new IrTypeSArray(dt, llvm::ArrayType::get(elemType, dim));
|
||||
}
|
||||
|
||||
return dt->ctype->isSArray();
|
||||
return ctype->isSArray();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -183,20 +187,22 @@ IrTypeSArray *IrTypeSArray::get(Type *dt) {
|
|||
IrTypeArray::IrTypeArray(Type *dt, LLType *lt) : IrType(dt, lt) {}
|
||||
|
||||
IrTypeArray *IrTypeArray::get(Type *dt) {
|
||||
assert(!dt->ctype);
|
||||
assert(dt->ty == Tarray && "not dynamic array type");
|
||||
|
||||
auto &ctype = getIrType(dt);
|
||||
assert(!ctype);
|
||||
|
||||
LLType *elemType = DtoMemType(dt->nextOf());
|
||||
|
||||
// Could have already built the type as part of a struct forward reference,
|
||||
// just as for pointers.
|
||||
if (!dt->ctype) {
|
||||
if (!ctype) {
|
||||
llvm::Type *types[] = {DtoSize_t(), llvm::PointerType::get(elemType, 0)};
|
||||
LLType *at = llvm::StructType::get(getGlobalContext(), types, false);
|
||||
dt->ctype = new IrTypeArray(dt, at);
|
||||
ctype = new IrTypeArray(dt, at);
|
||||
}
|
||||
|
||||
return dt->ctype->isArray();
|
||||
return ctype->isArray();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -204,26 +210,40 @@ IrTypeArray *IrTypeArray::get(Type *dt) {
|
|||
IrTypeVector::IrTypeVector(Type *dt, llvm::Type *lt) : IrType(dt, lt) {}
|
||||
|
||||
IrTypeVector *IrTypeVector::get(Type *dt) {
|
||||
LLType *lt = vector2llvm(dt);
|
||||
TypeVector *tv = dt->isTypeVector();
|
||||
assert(tv && "not vector type");
|
||||
|
||||
auto &ctype = getIrType(dt);
|
||||
assert(!ctype);
|
||||
|
||||
TypeSArray *tsa = tv->basetype->isTypeSArray();
|
||||
assert(tsa);
|
||||
LLType *elemType = DtoMemType(tsa->next);
|
||||
|
||||
// Could have already built the type as part of a struct forward reference,
|
||||
// just as for pointers and arrays.
|
||||
if (!dt->ctype) {
|
||||
dt->ctype = new IrTypeVector(dt, lt);
|
||||
}
|
||||
return dt->ctype->isVector();
|
||||
}
|
||||
|
||||
llvm::Type *IrTypeVector::vector2llvm(Type *dt) {
|
||||
assert(dt->ty == Tvector && "not vector type");
|
||||
TypeVector *tv = static_cast<TypeVector *>(dt);
|
||||
assert(tv->basetype->ty == Tsarray);
|
||||
TypeSArray *tsa = static_cast<TypeSArray *>(tv->basetype);
|
||||
uint64_t dim = static_cast<uint64_t>(tsa->dim->toUInteger());
|
||||
LLType *elemType = DtoMemType(tsa->next);
|
||||
return llvm::VectorType::get(elemType, dim
|
||||
if (!ctype) {
|
||||
LLType *lt = llvm::VectorType::get(elemType, tsa->dim->toUInteger()
|
||||
#if LDC_LLVM_VER >= 1100
|
||||
,
|
||||
/*Scalable=*/false
|
||||
#endif
|
||||
);
|
||||
ctype = new IrTypeVector(dt, lt);
|
||||
}
|
||||
|
||||
return ctype->isVector();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrType *&getIrType(Type *t, bool create) {
|
||||
t = stripModifiers(t);
|
||||
|
||||
if (create) {
|
||||
DtoType(t);
|
||||
assert(t->ctype);
|
||||
}
|
||||
|
||||
return t->ctype;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,9 @@ public:
|
|||
protected:
|
||||
///
|
||||
explicit IrTypeVector(Type *dt, llvm::Type *lt);
|
||||
|
||||
static llvm::Type *vector2llvm(Type *dt);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Returns a reference to the IrType* associated with the specified D type.
|
||||
IrType *&getIrType(Type *t, bool create = false);
|
||||
|
|
|
@ -60,12 +60,13 @@ void IrTypeClass::addClassData(AggrTypeBuilder &builder,
|
|||
}
|
||||
|
||||
IrTypeClass *IrTypeClass::get(ClassDeclaration *cd) {
|
||||
const auto t = new IrTypeClass(cd);
|
||||
cd->type->ctype = t;
|
||||
|
||||
IF_LOG Logger::println("Building class type %s @ %s", cd->toPrettyChars(),
|
||||
cd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
const auto t = new IrTypeClass(cd);
|
||||
getIrType(cd->type) = t;
|
||||
|
||||
IF_LOG Logger::println("Instance size: %u", cd->structsize);
|
||||
|
||||
// This class may contain an align declaration. See GitHub #726.
|
||||
|
|
|
@ -19,20 +19,22 @@ IrTypeFunction::IrTypeFunction(Type *dt, llvm::Type *lt, IrFuncTy irFty_)
|
|||
: IrType(dt, lt), irFty(std::move(irFty_)) {}
|
||||
|
||||
IrTypeFunction *IrTypeFunction::get(Type *dt) {
|
||||
assert(!dt->ctype);
|
||||
assert(dt->ty == Tfunction);
|
||||
TypeFunction *tf = dt->isTypeFunction();
|
||||
assert(tf);
|
||||
|
||||
TypeFunction *tf = static_cast<TypeFunction *>(dt);
|
||||
auto &ctype = getIrType(tf);
|
||||
assert(!ctype);
|
||||
|
||||
IrFuncTy irFty(tf);
|
||||
llvm::Type *lt = DtoFunctionType(tf, irFty, nullptr, nullptr);
|
||||
|
||||
// Could have already built the type as part of a struct forward reference,
|
||||
// just as for pointers and arrays.
|
||||
if (!dt->ctype) {
|
||||
dt->ctype = new IrTypeFunction(dt, lt, irFty);
|
||||
if (!ctype) {
|
||||
ctype = new IrTypeFunction(dt, lt, irFty);
|
||||
}
|
||||
return dt->ctype->isFunction();
|
||||
|
||||
return ctype->isFunction();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -41,11 +43,12 @@ IrTypeDelegate::IrTypeDelegate(Type *dt, llvm::Type *lt, IrFuncTy irFty_)
|
|||
: IrType(dt, lt), irFty(std::move(irFty_)) {}
|
||||
|
||||
IrTypeDelegate *IrTypeDelegate::get(Type *t) {
|
||||
assert(!t->ctype);
|
||||
assert(t->ty == Tdelegate);
|
||||
assert(t->nextOf()->ty == Tfunction);
|
||||
TypeFunction *tf = t->nextOf()->isTypeFunction();
|
||||
assert(tf);
|
||||
|
||||
TypeFunction *tf = static_cast<TypeFunction *>(t->nextOf());
|
||||
auto &ctype = getIrType(t);
|
||||
assert(!ctype);
|
||||
|
||||
IrFuncTy irFty(tf);
|
||||
llvm::Type *ltf =
|
||||
|
@ -55,8 +58,9 @@ IrTypeDelegate *IrTypeDelegate::get(Type *t) {
|
|||
|
||||
// Could have already built the type as part of a struct forward reference,
|
||||
// just as for pointers and arrays.
|
||||
if (!t->ctype) {
|
||||
t->ctype = new IrTypeDelegate(t, lt, irFty);
|
||||
if (!ctype) {
|
||||
ctype = new IrTypeDelegate(t, lt, irFty);
|
||||
}
|
||||
return t->ctype->isDelegate();
|
||||
|
||||
return ctype->isDelegate();
|
||||
}
|
||||
|
|
|
@ -30,14 +30,15 @@ IrTypeStruct::IrTypeStruct(StructDeclaration *sd)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<IrTypeStruct*> IrTypeStruct::dcomputeTypes;
|
||||
std::vector<IrTypeStruct *> IrTypeStruct::dcomputeTypes;
|
||||
|
||||
/// Resets special DCompute structs so they get re-created
|
||||
/// with the proper address space when generating device code.
|
||||
void IrTypeStruct::resetDComputeTypes() {
|
||||
for(auto&& irTypeStruct : dcomputeTypes) {
|
||||
delete irTypeStruct->dtype->ctype;
|
||||
irTypeStruct->dtype->ctype = nullptr;
|
||||
for (auto irTypeStruct : dcomputeTypes) {
|
||||
auto &ctype = getIrType(irTypeStruct->dtype);
|
||||
delete ctype;
|
||||
ctype = nullptr;
|
||||
}
|
||||
|
||||
dcomputeTypes.clear();
|
||||
|
@ -46,13 +47,13 @@ void IrTypeStruct::resetDComputeTypes() {
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrTypeStruct *IrTypeStruct::get(StructDeclaration *sd) {
|
||||
auto t = new IrTypeStruct(sd);
|
||||
sd->type->ctype = t;
|
||||
|
||||
IF_LOG Logger::println("Building struct type %s @ %s", sd->toPrettyChars(),
|
||||
sd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
auto t = new IrTypeStruct(sd);
|
||||
getIrType(sd->type) = t;
|
||||
|
||||
// if it's a forward declaration, all bets are off, stick with the opaque
|
||||
if (sd->sizeok != SIZEOKdone) {
|
||||
return t;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue