Mercurial > projects > ldc
diff gen/classes.cpp @ 137:ce7b81fb957f trunk
[svn r141] fixed more problems with classinfo
moved more IR state out of the AST classes
author | lindquist |
---|---|
date | Fri, 18 Jan 2008 16:42:16 +0100 |
parents | 0e28624814e8 |
children | aeddd4d533b3 |
line wrap: on
line diff
--- a/gen/classes.cpp Thu Jan 17 03:15:12 2008 +0100 +++ b/gen/classes.cpp Fri Jan 18 16:42:16 2008 +0100 @@ -20,21 +20,54 @@ ////////////////////////////////////////////////////////////////////////////////////////// +static void LLVM_AddBaseClassInterfaces(ClassDeclaration* target, BaseClasses* bcs) +{ + // add base class data members first + for (int j=0; j<bcs->dim; j++) + { + BaseClass* bc = (BaseClass*)(bcs->data[j]); + + // resolve interfaces while we're at it + if (bc->base->isInterfaceDeclaration()) + { + Logger::println("adding interface '%s'", bc->base->toPrettyChars()); + IrInterface* iri = new IrInterface(bc, NULL); + target->irStruct->interfaces.insert(std::make_pair(bc->base, iri)); + if (!target->isAbstract()) { + // Fill in vtbl[] + bc->fillVtbl(target, &bc->vtbl, 0); + } + DtoResolveClass(bc->base); + } + + // base *classes* might add more interfaces? + LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + static void LLVM_AddBaseClassData(BaseClasses* bcs) { // add base class data members first for (int j=0; j<bcs->dim; j++) { BaseClass* bc = (BaseClass*)(bcs->data[j]); + + // interfaces never add data fields if (bc->base->isInterfaceDeclaration()) - continue; // interfaces only have methods + continue; + // recursively add baseclass data LLVM_AddBaseClassData(&bc->base->baseclasses); + Array* arr = &bc->base->fields; + if (arr->dim == 0) + continue; + Logger::println("Adding base class members of %s", bc->base->toChars()); LOG_SCOPE; - Array* arr = &bc->base->fields; for (int k=0; k < arr->dim; k++) { VarDeclaration* v = (VarDeclaration*)(arr->data[k]); v->toObjFile(); @@ -57,10 +90,10 @@ TypeClass* ts = (TypeClass*)cd->type; // make sure the IrStruct is created - IrStruct* irstruct = cd->llvmIrStruct; + IrStruct* irstruct = cd->irStruct; if (!irstruct) { irstruct = new IrStruct(ts); - cd->llvmIrStruct = irstruct; + cd->irStruct = irstruct; } // resolve the base class @@ -69,15 +102,18 @@ } // resolve interface vtables - if (cd->vtblInterfaces) { + /*if (cd->vtblInterfaces) { + Logger::println("Vtbl interfaces for '%s'", cd->toPrettyChars()); + LOG_SCOPE; for (int i=0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; ClassDeclaration *id = b->base; + Logger::println("Vtbl interface: '%s'", id->toPrettyChars()); DtoResolveClass(id); // Fill in vtbl[] b->fillVtbl(cd, &b->vtbl, 1); } - } + }*/ gIR->structs.push_back(irstruct); gIR->classes.push_back(cd); @@ -92,23 +128,7 @@ // add monitor fieldtypes.push_back(getPtrToType(llvm::Type::Int8Ty)); - // add interface vtables - if (cd->vtblInterfaces) - for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) - { - BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; - ClassDeclaration *id = b->base; - assert(id->type->ty == Tclass); - TypeClass* itc = (TypeClass*)id->type; - const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get()); - fieldtypes.push_back(ivtblTy); - - // add this interface to the map - IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get())); - irstruct->interfaces.insert(std::make_pair(id, iri)); - } - - // base classes first + // add base class data fields first LLVM_AddBaseClassData(&cd->baseclasses); // then add own members @@ -149,14 +169,14 @@ fieldpad += s - prevsize; prevsize = s; } - cd->llvmHasUnions = true; + cd->irStruct->hasUnions = true; i->second.var->irField->index = idx; } // intersecting offset? else if (i->first < (lastoffset + prevsize)) { size_t s = getABITypeSize(i->second.type); assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size - cd->llvmHasUnions = true; + cd->irStruct->hasUnions = true; i->second.var->irField->index = idx; i->second.var->irField->indexOffset = (i->first - lastoffset) / s; } @@ -190,21 +210,44 @@ } } - /* - // add field types - for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { - fieldtypes.push_back(i->second.type); + // populate interface map + { + Logger::println("Adding interfaces to '%s'", cd->toPrettyChars()); + LOG_SCOPE; + LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses); + Logger::println("%d interfaces added", cd->irStruct->interfaces.size()); } - */ + + // add interface vtables at the end + int interIdx = (int)fieldtypes.size(); + for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + { + ClassDeclaration* id = i->first; + IrInterface* iri = i->second; + // set vtbl type + TypeClass* itc = (TypeClass*)id->type; + const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get()); + fieldtypes.push_back(ivtblTy); + + // fix the interface vtable type + iri->vtblTy = isaStruct(itc->llvmVtblType->get()); + + // set index + iri->index = interIdx++; + } + Logger::println("%d interface vtables added", cd->irStruct->interfaces.size()); + + // create type const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); + // refine abstract types for stuff like: class C {C next;} assert(irstruct->recty != 0); - llvm::PATypeHolder& spa = irstruct->recty; llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); structtype = isaStruct(spa.get()); + // make it official if (!ts->llvmType) ts->llvmType = new llvm::PATypeHolder(structtype); else @@ -214,22 +257,8 @@ // name the type gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); - // build interface info type - std::vector<const llvm::Type*> infoTypes; - // ClassInfo classinfo - ClassDeclaration* cinfod = ClassDeclaration::classinfo; - DtoResolveClass(cinfod); - infoTypes.push_back(getPtrToType(cinfod->type->llvmType->get())); - // void*[] vtbl - std::vector<const llvm::Type*> infoVtbltypes; - infoVtbltypes.push_back(DtoSize_t()); - const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); - infoVtbltypes.push_back(byteptrptrty); - infoTypes.push_back(llvm::StructType::get(infoVtbltypes)); - // int offset - infoTypes.push_back(llvm::Type::Int32Ty); - // create type - const llvm::StructType* infoTy = llvm::StructType::get(infoTypes); + // get interface info type + const llvm::StructType* infoTy = DtoInterfaceInfoType(); // create vtable type llvm::GlobalVariable* svtblVar = 0; @@ -256,9 +285,8 @@ if (cd->isInterfaceDeclaration()) { cinfoty = infoTy; } - else if (cd != cinfod) { - DtoResolveClass(cinfod); - cinfoty = cinfod->type->llvmType->get(); + else if (cd != ClassDeclaration::classinfo) { + cinfoty = ClassDeclaration::classinfo->type->llvmType->get(); } else { // this is the ClassInfo class, the type is this type @@ -300,8 +328,8 @@ assert(cd->type->ty == Tclass); TypeClass* ts = (TypeClass*)cd->type; - assert(cd->llvmIrStruct); - IrStruct* irstruct = cd->llvmIrStruct; + assert(cd->irStruct); + IrStruct* irstruct = cd->irStruct; gIR->structs.push_back(irstruct); gIR->classes.push_back(cd); @@ -322,20 +350,20 @@ varname.append("6__vtblZ"); const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); - cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); + cd->irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); } // get interface info type const llvm::StructType* infoTy = DtoInterfaceInfoType(); // interface info array - if (cd->vtblInterfaces->dim > 0) { + if (!cd->irStruct->interfaces.empty()) { // symbol name std::string nam = "_D"; nam.append(cd->mangle()); nam.append("16__interfaceInfosZ"); // resolve array type - const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim); + const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->irStruct->interfaces.size()); // declare global irstruct->interfaceInfosTy = arrTy; irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); @@ -370,7 +398,7 @@ initname.append("6__initZ"); llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); - cd->llvmInit = initvar; + cd->irStruct->init = initvar; } gIR->classes.pop_back(); @@ -401,7 +429,7 @@ Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); LOG_SCOPE; - IrStruct* irstruct = cd->llvmIrStruct; + IrStruct* irstruct = cd->irStruct; gIR->structs.push_back(irstruct); gIR->classes.push_back(cd); @@ -436,16 +464,31 @@ } else { - assert(cd->llvmVtbl != 0); - fieldinits.push_back(cd->llvmVtbl); + assert(cd->irStruct->vtbl != 0); + fieldinits.push_back(cd->irStruct->vtbl); } // then comes monitor fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); - size_t dataoffset = 2; + // go through the field inits and build the default initializer + size_t nfi = irstruct->defaultFields.size(); + for (size_t i=0; i<nfi; ++i) { + llvm::Constant* c; + if (irstruct->defaultFields[i]) { + c = irstruct->defaultFields[i]->irField->constInit; + assert(c); + } + else { + const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2)); + assert(arrty); + std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); + c = llvm::ConstantArray::get(arrty, vals); + } + fieldinits.push_back(c); + } - // next comes interface vtables + // last comes interface vtables const llvm::StructType* infoTy = DtoInterfaceInfoType(); for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { @@ -453,48 +496,27 @@ iri->infoTy = infoTy; if (cd->isAbstract()) { - fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy)); + fieldinits.push_back(llvm::Constant::getNullValue(structtype->getElementType(iri->index))); } else { assert(iri->vtbl); fieldinits.push_back(iri->vtbl); - ++dataoffset; } } - /* - // rest - for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { - Logger::println("adding fieldinit for: %s", i->second.var->toChars()); - fieldinits.push_back(i->second.init); - } - */ - - // go through the field inits and build the default initializer - size_t nfi = irstruct->defaultFields.size(); - for (size_t i=0; i<nfi; ++i) { - llvm::Constant* c; - if (irstruct->defaultFields[i] != NULL) { - c = irstruct->defaultFields[i]->irField->constInit; - assert(c); - } - else { - const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+dataoffset)); - std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); - c = llvm::ConstantArray::get(arrty, vals); - } - fieldinits.push_back(c); - } - // generate initializer #if 0 - Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n'; - + //Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n'; + assert(fieldinits.size() == structtype->getNumElements()); for(size_t i=0; i<structtype->getNumElements(); ++i) { Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n'; + Logger::cout() << "i#" << i << " = " << *fieldinits[i] << '\n'; + assert(fieldinits[i]->getType() == structtype->getElementType(i)); } +#endif +#if 0 for(size_t i=0; i<fieldinits.size(); ++i) { Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n'; } @@ -502,10 +524,11 @@ llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); assert(_init); - cd->llvmConstInit = _init; + cd->irStruct->constInit = _init; // abstract classes have no static vtable - if (!cd->isAbstract()) + // neither do interfaces (on their own, the implementing class supplies the vtable) + if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { // generate vtable initializer std::vector<llvm::Constant*> sinits; @@ -526,8 +549,8 @@ sinits.push_back(c); } else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { - assert(cd->llvmClass); - llvm::Constant* c = cd->llvmClass; + assert(cd->irStruct->classInfo); + llvm::Constant* c = cd->irStruct->classInfo; sinits.push_back(c); } else @@ -546,11 +569,9 @@ #endif llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); - cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); + cd->irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); // create interface vtable const initalizers - int idx = 2; - int idxScale = PTRSIZE; for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { ClassDeclaration* id = i->first; @@ -566,8 +587,8 @@ std::vector<llvm::Constant*> infoInits; // classinfo - assert(id->llvmClass); - llvm::Constant* c = id->llvmClass; + assert(id->irStruct->classInfo); + llvm::Constant* c = id->irStruct->classInfo; infoInits.push_back(c); // vtbl @@ -577,7 +598,14 @@ infoInits.push_back(c); // offset - infoInits.push_back(DtoConstInt(idx*idxScale)); + // generate target independent offset with constGEP + /*llvm::Value* cidx = DtoConstInt(iri->index); + Logger::cout() << "offset to interface in class type: " << *cd->type->llvmType->get() << '\n'; + size_t ioff = gTargetData->getIndexedOffset(cd->type->llvmType->get(), &cidx, 1); + infoInits.push_back(DtoConstUint(ioff));*/ + assert(iri->index >= 0); + size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->llvmType->get()))->getElementOffset(iri->index); + infoInits.push_back(DtoConstUint(ioff)); // create interface info initializer constant iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); @@ -592,6 +620,7 @@ { Logger::println("interface vtbl const init nr. %d", k); Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k]; + assert(dsym); FuncDeclaration* fd = dsym->isFuncDeclaration(); assert(fd); DtoForceDeclareDsymbol(fd); @@ -603,7 +632,7 @@ iinits.push_back(c); } - #if 1 + #if 0 for (size_t x=0; x< iinits.size(); ++x) { Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n"; @@ -614,12 +643,10 @@ llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); - - idx++; } } // we always generate interfaceinfos as best we can - else + /*else { for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { @@ -634,8 +661,8 @@ std::vector<llvm::Constant*> infoInits; // classinfo - assert(id->llvmClass); - llvm::Constant* c = id->llvmClass; + assert(id->irStruct->classInfo); + llvm::Constant* c = id->irStruct->classInfo; infoInits.push_back(c); // vtbl @@ -649,7 +676,7 @@ // create interface info initializer constant iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); } - } + }*/ gIR->classes.pop_back(); gIR->structs.pop_back(); @@ -674,11 +701,11 @@ // neither do abstract classes if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { - cd->llvmInit->setInitializer(cd->llvmConstInit); - cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); + cd->irStruct->init->setInitializer(cd->irStruct->constInit); + cd->irStruct->vtbl->setInitializer(cd->irStruct->constVtbl); // initialize interface vtables - IrStruct* irstruct = cd->llvmIrStruct; + IrStruct* irstruct = cd->irStruct; std::vector<llvm::Constant*> infoInits; for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) { @@ -716,7 +743,7 @@ { llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); std::vector<llvm::Value*> args; - args.push_back(tc->sym->llvmClass); + args.push_back(tc->sym->irStruct->classInfo); mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); } @@ -731,7 +758,7 @@ LOG_SCOPE; DValue* thisval = newexp->thisexp->toElem(gIR); size_t idx = 2; - idx += tc->sym->llvmIrStruct->interfaces.size(); + idx += tc->sym->irStruct->interfaces.size(); llvm::Value* dst = thisval->getRVal(); llvm::Value* src = DtoGEPi(mem,0,idx,"tmp"); Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; @@ -743,7 +770,7 @@ Logger::println("Resolving nested context"); LOG_SCOPE; size_t idx = 2; - idx += tc->sym->llvmIrStruct->interfaces.size(); + idx += tc->sym->irStruct->interfaces.size(); llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar; if (!nest) nest = gIR->func()->decl->irFunc->thisVar; @@ -769,8 +796,8 @@ uint64_t n = getABITypeSize(tc->llvmType->get()) - presz; // set vtable field seperately, this might give better optimization - assert(tc->sym->llvmVtbl); - DtoStore(tc->sym->llvmVtbl, DtoGEPi(dst,0,0,"vtbl")); + assert(tc->sym->irStruct->vtbl); + DtoStore(tc->sym->irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); // monitor always defaults to zero llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor"); @@ -781,15 +808,15 @@ return; // copy the rest from the static initializer - assert(tc->sym->llvmInit); - assert(dst->getType() == tc->sym->llvmInit->getType()); + assert(tc->sym->irStruct->init); + assert(dst->getType() == tc->sym->irStruct->init->getType()); const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp"); dstarr = DtoBitCast(dstarr, arrty); - llvm::Value* srcarr = DtoGEPi(tc->sym->llvmInit,0,2,"tmp"); + llvm::Value* srcarr = DtoGEPi(tc->sym->irStruct->init,0,2,"tmp"); srcarr = DtoBitCast(srcarr, arrty); llvm::Function* fn = LLVM_DeclareMemCpy32(); @@ -912,8 +939,8 @@ // ClassInfo c TypeClass* to = (TypeClass*)DtoDType(_to); DtoForceDeclareDsymbol(to->sym); - assert(to->sym->llvmClass); - tmp = to->sym->llvmClass; + assert(to->sym->irStruct->classInfo); + tmp = to->sym->irStruct->classInfo; // unfortunately this is needed as the implementation of object differs somehow from the declaration // this could happen in user code as well :/ tmp = DtoBitCast(tmp, funcTy->getParamType(1)); @@ -978,8 +1005,8 @@ // ClassInfo c TypeClass* to = (TypeClass*)DtoDType(_to); DtoForceDeclareDsymbol(to->sym); - assert(to->sym->llvmClass); - tmp = to->sym->llvmClass; + assert(to->sym->irStruct->classInfo); + tmp = to->sym->irStruct->classInfo; // unfortunately this is needed as the implementation of object differs somehow from the declaration // this could happen in user code as well :/ tmp = DtoBitCast(tmp, funcTy->getParamType(1)); @@ -1045,13 +1072,13 @@ const llvm::Type* llt = getPtrToType(DtoType(t)); const llvm::Type* st = DtoType(cd->type); if (ptr->getType() != st) { - assert(cd->llvmHasUnions); + assert(cd->irStruct->hasUnions); ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); } - unsigned dataoffset = 2 + cd->vtblInterfaces->dim; + unsigned dataoffset = 2; - IrStruct* irstruct = cd->llvmIrStruct; + IrStruct* irstruct = cd->irStruct; for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { //for (unsigned i=0; i<cd->fields.dim; ++i) { //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; @@ -1134,8 +1161,8 @@ void DtoDeclareClassInfo(ClassDeclaration* cd) { - if (cd->llvmClassDeclared) return; - cd->llvmClassDeclared = true; + if (cd->irStruct->classDeclared) return; + cd->irStruct->classDeclared = true; Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); LOG_SCOPE; @@ -1152,7 +1179,7 @@ const llvm::Type* st = cinfo->type->llvmType->get(); - cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); + cd->irStruct->classInfo = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); } static llvm::Constant* build_offti_entry(VarDeclaration* vd) @@ -1325,21 +1352,21 @@ // void *defaultConstructor; // } - if (cd->llvmClassDefined) return; - cd->llvmClassDefined = true; + if (cd->irStruct->classDefined) return; + cd->irStruct->classDefined = true; Logger::println("DtoDefineClassInfo(%s)", cd->toChars()); LOG_SCOPE; assert(cd->type->ty == Tclass); - assert(cd->llvmClass); + assert(cd->irStruct->classInfo); TypeClass* cdty = (TypeClass*)cd->type; if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { - assert(cd->llvmInit); - assert(cd->llvmConstInit); - assert(cd->llvmVtbl); - assert(cd->llvmConstVtbl); + assert(cd->irStruct->init); + assert(cd->irStruct->constInit); + assert(cd->irStruct->vtbl); + assert(cd->irStruct->constVtbl); } // holds the list of initializers for llvm @@ -1347,28 +1374,28 @@ ClassDeclaration* cinfo = ClassDeclaration::classinfo; DtoForceConstInitDsymbol(cinfo); - assert(cinfo->llvmConstInit); + assert(cinfo->irStruct->constInit); llvm::Constant* c; // own vtable - c = cinfo->llvmConstInit->getOperand(0); + c = cinfo->irStruct->constInit->getOperand(0); assert(c); inits.push_back(c); // monitor - c = cinfo->llvmConstInit->getOperand(1); + c = cinfo->irStruct->constInit->getOperand(1); inits.push_back(c); // byte[] init const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty); if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->llvmConstInit->getOperand(2); + c = cinfo->irStruct->constInit->getOperand(2); } else { - c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty); - assert(!cd->llvmConstInit->getType()->isAbstract()); - size_t initsz = getABITypeSize(cd->llvmConstInit->getType()); + c = llvm::ConstantExpr::getBitCast(cd->irStruct->init, byteptrty); + assert(!cd->irStruct->constInit->getType()->isAbstract()); + size_t initsz = getABITypeSize(cd->irStruct->constInit->getType()); c = DtoConstSlice(DtoConstSize_t(initsz), c); } inits.push_back(c); @@ -1387,25 +1414,25 @@ // vtbl array if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->llvmConstInit->getOperand(4); + c = cinfo->irStruct->constInit->getOperand(4); } else { const llvm::Type* byteptrptrty = getPtrToType(byteptrty); - assert(!cd->llvmVtbl->getType()->isAbstract()); - c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty); - assert(!cd->llvmConstVtbl->getType()->isAbstract()); - size_t vtblsz = cd->llvmConstVtbl->getType()->getNumElements(); + assert(!cd->irStruct->vtbl->getType()->isAbstract()); + c = llvm::ConstantExpr::getBitCast(cd->irStruct->vtbl, byteptrptrty); + assert(!cd->irStruct->constVtbl->getType()->isAbstract()); + size_t vtblsz = cd->irStruct->constVtbl->getType()->getNumElements(); c = DtoConstSlice(DtoConstSize_t(vtblsz), c); } inits.push_back(c); // interfaces array - IrStruct* irstruct = cd->llvmIrStruct; + IrStruct* irstruct = cd->irStruct; if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { - c = cinfo->llvmConstInit->getOperand(5); + c = cinfo->irStruct->constInit->getOperand(5); } else { - const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1); + const llvm::Type* t = cinfo->irStruct->constInit->getOperand(5)->getType()->getContainedType(1); c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); size_t iisz = irstruct->interfaceInfosTy->getNumElements(); c = DtoConstSlice(DtoConstSize_t(iisz), c); @@ -1415,19 +1442,19 @@ // base classinfo if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { DtoDeclareClassInfo(cd->baseClass); - c = cd->baseClass->llvmClass; + c = cd->baseClass->irStruct->classInfo; assert(c); inits.push_back(c); } else { // null - c = cinfo->llvmConstInit->getOperand(6); + c = cinfo->irStruct->constInit->getOperand(6); inits.push_back(c); } // destructor if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->llvmConstInit->getOperand(7); + c = cinfo->irStruct->constInit->getOperand(7); } else { c = build_class_dtor(cd); @@ -1436,12 +1463,12 @@ // invariant // TODO - c = cinfo->llvmConstInit->getOperand(8); + c = cinfo->irStruct->constInit->getOperand(8); inits.push_back(c); // uint flags if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->llvmConstInit->getOperand(9); + c = cinfo->irStruct->constInit->getOperand(9); } else { uint flags = build_classinfo_flags(cd); @@ -1451,15 +1478,15 @@ // allocator // TODO - c = cinfo->llvmConstInit->getOperand(10); + c = cinfo->irStruct->constInit->getOperand(10); inits.push_back(c); // offset typeinfo if (cd->isInterfaceDeclaration() || cd->isAbstract()) { - c = cinfo->llvmConstInit->getOperand(11); + c = cinfo->irStruct->constInit->getOperand(11); } else { - c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11)); + c = build_offti_array(cd, cinfo->irStruct->constInit->getOperand(11)); } inits.push_back(c); @@ -1467,11 +1494,11 @@ if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { DtoForceDeclareDsymbol(cd->defaultCtor); c = isaConstant(cd->defaultCtor->irFunc->func); - const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType(); + const llvm::Type* toTy = cinfo->irStruct->constInit->getOperand(12)->getType(); c = llvm::ConstantExpr::getBitCast(c, toTy); } else { - c = cinfo->llvmConstInit->getOperand(12); + c = cinfo->irStruct->constInit->getOperand(12); } inits.push_back(c); @@ -1482,10 +1509,10 @@ }*/ // build the initializer - const llvm::StructType* st = isaStruct(cinfo->llvmConstInit->getType()); + const llvm::StructType* st = isaStruct(cinfo->irStruct->constInit->getType()); llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; - cd->llvmConstClass = finalinit; - cd->llvmClass->setInitializer(finalinit); + cd->irStruct->constClassInfo = finalinit; + cd->irStruct->classInfo->setInitializer(finalinit); }