comparison gen/classes.cpp @ 809:69a5e4a6fc0f

Changed some hardcoded offset/alignment for classes in DMD, broke offsets for 64bits. Changed ClassInfo generation to no longer access the default initializer of ClassInfo, fixes problems with index mismatch.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 30 Nov 2008 20:22:09 +0100
parents 96b404ba7eb0
children 6c2ff06c4201
comparison
equal deleted inserted replaced
808:4ad1e7b10378 809:69a5e4a6fc0f
73 irstruct->types.push_back( inter->type->ir.type->get() ); 73 irstruct->types.push_back( inter->type->ir.type->get() );
74 // set and increment index 74 // set and increment index
75 iri->index = irstruct->index++; 75 iri->index = irstruct->index++;
76 } 76 }
77 77
78 //////////////////////////////////////////////////////////////////////////////////////////
79
78 static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd) 80 static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
79 { 81 {
80 Logger::println("Adding data from class: %s", cd->toChars()); 82 Logger::println("Adding data from class: %s", cd->toChars());
81 LOG_SCOPE; 83 LOG_SCOPE;
82 84
441 size_t nfields = cd->fields.dim; 443 size_t nfields = cd->fields.dim;
442 444
443 std::vector<VarDeclaration*> defVars; 445 std::vector<VarDeclaration*> defVars;
444 defVars.reserve(nfields); 446 defVars.reserve(nfields);
445 447
446 size_t lastoffset = offsetbegin; // vtbl,monitor 448 size_t lastoffset = offsetbegin;
447 size_t lastsize = 0; 449 size_t lastsize = 0;
448 450
449 // find fields that contribute to default 451 // find fields that contribute to default
450 for (size_t i=0; i<nfields; i++) 452 for (size_t i=0; i<nfields; i++)
451 { 453 {
453 // only add vars that don't overlap 455 // only add vars that don't overlap
454 size_t offset = var->offset; 456 size_t offset = var->offset;
455 size_t size = var->type->size(); 457 size_t size = var->type->size();
456 if (offset >= lastoffset+lastsize) 458 if (offset >= lastoffset+lastsize)
457 { 459 {
458 Logger::println(" added"); 460 Logger::println(" added %s", var->toChars());
459 lastoffset = offset; 461 lastoffset = offset;
460 lastsize = size; 462 lastsize = size;
461 defVars.push_back(var); 463 defVars.push_back(var);
462 } 464 }
463 } 465 else
466 {
467 Logger::println(" skipped %s", var->toChars());
468 }
469 }
470
471 // reset offsets, we're going from beginning again
472 lastoffset = offsetbegin;
473 lastsize = 0;
464 474
465 // go through the default vars and build the default constant initializer 475 // go through the default vars and build the default constant initializer
466 // adding zeros along the way to live up to alignment expectations 476 // adding zeros along the way to live up to alignment expectations
467 size_t nvars = defVars.size(); 477 size_t nvars = defVars.size();
468 for (size_t i=0; i<nvars; i++) 478 for (size_t i=0; i<nvars; i++)
758 768
759 static void DefineInterfaceInfos(IrStruct* irstruct) 769 static void DefineInterfaceInfos(IrStruct* irstruct)
760 { 770 {
761 // always do interface info array when possible 771 // always do interface info array when possible
762 std::vector<LLConstant*> infoInits; 772 std::vector<LLConstant*> infoInits;
763 infoInits.reserve(irstruct->interfaceVec.size()); 773
764 774 size_t n = irstruct->interfaceVec.size();
765 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 775 infoInits.reserve(n);
766 { 776
767 IrInterface* iri = *i; 777 for (size_t i=0; i < n; i++)
778 {
779 IrInterface* iri = irstruct->interfaceVec[i];
768 assert(iri->infoInit); 780 assert(iri->infoInit);
769 infoInits.push_back(iri->infoInit); 781 infoInits.push_back(iri->infoInit);
770 } 782 }
771 783
772 // set initializer 784 // set initializer
832 assert(irstruct->init); 844 assert(irstruct->init);
833 assert(irstruct->constInit); 845 assert(irstruct->constInit);
834 assert(irstruct->vtbl); 846 assert(irstruct->vtbl);
835 assert(irstruct->constVtbl); 847 assert(irstruct->constVtbl);
836 848
837 if (Logger::enabled()) 849 // if (Logger::enabled())
838 { 850 // {
839 Logger::cout() << "initZ: " << *irstruct->init << std::endl; 851 // Logger::cout() << "initZ: " << *irstruct->init << std::endl;
840 Logger::cout() << "cinitZ: " << *irstruct->constInit << std::endl; 852 // Logger::cout() << "cinitZ: " << *irstruct->constInit << std::endl;
841 Logger::cout() << "vtblZ: " << *irstruct->vtbl << std::endl; 853 // Logger::cout() << "vtblZ: " << *irstruct->vtbl << std::endl;
842 Logger::cout() << "cvtblZ: " << *irstruct->constVtbl << std::endl; 854 // Logger::cout() << "cvtblZ: " << *irstruct->constVtbl << std::endl;
843 } 855 // }
844 856
845 // set initializers 857 // set initializers
846 irstruct->init->setInitializer(irstruct->constInit); 858 irstruct->init->setInitializer(irstruct->constInit);
847 irstruct->vtbl->setInitializer(irstruct->constVtbl); 859 irstruct->vtbl->setInitializer(irstruct->constVtbl);
848 860
1182 return new DImValue(_to, ret); 1194 return new DImValue(_to, ret);
1183 } 1195 }
1184 1196
1185 ////////////////////////////////////////////////////////////////////////////////////////// 1197 //////////////////////////////////////////////////////////////////////////////////////////
1186 1198
1187 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx)
1188 {
1189 // start at the bottom of the inheritance chain
1190 if (cd->baseClass != 0) {
1191 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx);
1192 if (o != (unsigned)-1)
1193 return o;
1194 }
1195
1196 // check this class
1197 unsigned i;
1198 for (i=0; i<cd->fields.dim; ++i) {
1199 VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
1200 if (os == vd->offset)
1201 return i+idx;
1202 }
1203 idx += i;
1204
1205 return (unsigned)-1;
1206 }
1207
1208 //////////////////////////////////////////////////////////////////////////////////////////
1209
1210 LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) 1199 LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
1211 { 1200 {
1212 Logger::println("indexing class field %s:", vd->toPrettyChars()); 1201 Logger::println("indexing class field %s:", vd->toPrettyChars());
1213 LOG_SCOPE; 1202 LOG_SCOPE;
1214 1203
1253 1242
1254 ////////////////////////////////////////////////////////////////////////////////////////// 1243 //////////////////////////////////////////////////////////////////////////////////////////
1255 1244
1256 LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) 1245 LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
1257 { 1246 {
1258 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); 1247 // sanity checks
1259 assert(fdecl->vtblIndex > 0); 1248 assert(fdecl->isVirtual());
1249 assert(fdecl->vtblIndex > 0); // 0 is always ClassInfo/Interface*
1260 assert(inst->getType()->toBasetype()->ty == Tclass); 1250 assert(inst->getType()->toBasetype()->ty == Tclass);
1261 1251
1252 // get instance
1262 LLValue* vthis = inst->getRVal(); 1253 LLValue* vthis = inst->getRVal();
1263 if (Logger::enabled()) 1254 if (Logger::enabled())
1264 Logger::cout() << "vthis: " << *vthis << '\n'; 1255 Logger::cout() << "vthis: " << *vthis << '\n';
1265 1256
1266 LLValue* funcval = vthis; 1257 LLValue* funcval = vthis;
1267 if (!fdecl->isMember2()->isInterfaceDeclaration()) 1258 // get the vtbl for objects
1259 if (!fdecl->isMember()->isInterfaceDeclaration())
1268 funcval = DtoGEPi(funcval, 0, 0, "tmp"); 1260 funcval = DtoGEPi(funcval, 0, 0, "tmp");
1261 // load vtbl ptr
1269 funcval = DtoLoad(funcval); 1262 funcval = DtoLoad(funcval);
1263 // index vtbl
1270 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toChars()); 1264 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toChars());
1265 // load funcptr
1271 funcval = DtoLoad(funcval); 1266 funcval = DtoLoad(funcval);
1272 1267
1273 if (Logger::enabled()) 1268 if (Logger::enabled())
1274 Logger::cout() << "funcval: " << *funcval << '\n'; 1269 Logger::cout() << "funcval: " << *funcval << '\n';
1275 1270
1271 // cast to final funcptr type
1276 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); 1272 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
1277 if (Logger::enabled()) 1273 if (Logger::enabled())
1278 Logger::cout() << "funcval casted: " << *funcval << '\n'; 1274 Logger::cout() << "funcval casted: " << *funcval << '\n';
1279 1275
1280 return funcval; 1276 return funcval;
1290 irstruct->classInfoDeclared = true; 1286 irstruct->classInfoDeclared = true;
1291 1287
1292 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); 1288 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
1293 LOG_SCOPE; 1289 LOG_SCOPE;
1294 1290
1291 // resovle ClassInfo
1295 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1292 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1296 DtoResolveClass(cinfo); 1293 DtoResolveClass(cinfo);
1297 1294
1295 // do the mangle
1298 std::string gname("_D"); 1296 std::string gname("_D");
1299 gname.append(cd->mangle()); 1297 gname.append(cd->mangle());
1300 if (!cd->isInterfaceDeclaration()) 1298 if (!cd->isInterfaceDeclaration())
1301 gname.append("7__ClassZ"); 1299 gname.append("7__ClassZ");
1302 else 1300 else
1303 gname.append("11__InterfaceZ"); 1301 gname.append("11__InterfaceZ");
1304 1302
1303 // create global
1305 irstruct->classInfo = new llvm::GlobalVariable(irstruct->classInfoOpaque.get(), false, DtoLinkage(cd), NULL, gname, gIR->module); 1304 irstruct->classInfo = new llvm::GlobalVariable(irstruct->classInfoOpaque.get(), false, DtoLinkage(cd), NULL, gname, gIR->module);
1306 } 1305 }
1307 1306
1307 //////////////////////////////////////////////////////////////////////////////////////////
1308
1309 // build a single element for the OffsetInfo[] of ClassInfo
1308 static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd) 1310 static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
1309 { 1311 {
1310 std::vector<const LLType*> types; 1312 std::vector<LLConstant*> inits(2);
1311 std::vector<LLConstant*> inits; 1313
1312 1314 // size_t offset;
1313 types.push_back(DtoSize_t()); 1315 //
1314
1315 assert(vd->ir.irField); 1316 assert(vd->ir.irField);
1317 // grab the offset from llvm and the formal class type
1316 size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index); 1318 size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index);
1319 // offset nested struct/union fields
1317 offset += vd->ir.irField->unionOffset; 1320 offset += vd->ir.irField->unionOffset;
1318 inits.push_back(DtoConstSize_t(offset)); 1321
1319 1322 // assert that it matches DMD
1320 LLConstant* c = DtoTypeInfoOf(vd->type, true); 1323 Logger::println("offsets: %lu vs %u", offset, vd->offset);
1321 const LLType* tiTy = c->getType(); 1324 assert(offset == vd->offset);
1322 //Logger::cout() << "tiTy = " << *tiTy << '\n'; 1325
1323 1326 inits[0] = DtoConstSize_t(offset);
1324 types.push_back(tiTy); 1327
1325 inits.push_back(c); 1328 // TypeInfo ti;
1326 1329 inits[1] = DtoTypeInfoOf(vd->type, true);
1327 const llvm::StructType* sTy = llvm::StructType::get(types); 1330
1328 return llvm::ConstantStruct::get(sTy, inits); 1331 // done
1329 } 1332 return llvm::ConstantStruct::get(inits);
1330 1333 }
1331 static LLConstant* build_offti_array(ClassDeclaration* cd, LLConstant* init) 1334
1332 { 1335 static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
1333 const llvm::StructType* initTy = isaStruct(init->getType()); 1336 {
1334 assert(initTy); 1337 IrStruct* irstruct = cd->ir.irStruct;
1335 1338
1336 std::vector<LLConstant*> arrayInits; 1339 size_t nvars = irstruct->varDecls.size();
1337 1340 std::vector<LLConstant*> arrayInits(nvars);
1338 VarDeclaration** fields = &cd->ir.irStruct->varDecls[0];
1339 size_t nvars = cd->ir.irStruct->varDecls.size();
1340 1341
1341 for (size_t i=0; i<nvars; i++) 1342 for (size_t i=0; i<nvars; i++)
1342 { 1343 {
1343 LLConstant* c = build_offti_entry(cd, fields[i]); 1344 arrayInits[i] = build_offti_entry(cd, irstruct->varDecls[i]);
1344 assert(c); 1345 }
1345 arrayInits.push_back(c); 1346
1346 } 1347 LLConstant* size = DtoConstSize_t(nvars);
1347
1348 size_t ninits = arrayInits.size();
1349 LLConstant* size = DtoConstSize_t(ninits);
1350 LLConstant* ptr; 1348 LLConstant* ptr;
1351 1349
1352 if (ninits > 0) { 1350 if (nvars == 0)
1353 // OffsetTypeInfo type 1351 return LLConstant::getNullValue( arrayT );
1354 std::vector<const LLType*> elemtypes; 1352
1355 elemtypes.push_back(DtoSize_t()); 1353 // array type
1356 const LLType* tiTy = getPtrToType(Type::typeinfo->type->ir.type->get()); 1354 const llvm::ArrayType* arrTy = llvm::ArrayType::get(arrayInits[0]->getType(), nvars);
1357 elemtypes.push_back(tiTy); 1355 LLConstant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
1358 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); 1356
1359 1357 // mangle
1360 // array type 1358 std::string name(cd->type->vtinfo->toChars());
1361 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); 1359 name.append("__OffsetTypeInfos");
1362 LLConstant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); 1360
1363 1361 // create symbol
1364 std::string name(cd->type->vtinfo->toChars()); 1362 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module);
1365 name.append("__OffsetTypeInfos"); 1363 ptr = DtoBitCast(gvar, getPtrToType(arrTy->getElementType()));
1366
1367 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module);
1368 ptr = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(sTy));
1369 }
1370 else {
1371 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
1372 }
1373 1364
1374 return DtoConstSlice(size, ptr); 1365 return DtoConstSlice(size, ptr);
1375 } 1366 }
1376 1367
1377 static LLConstant* build_class_dtor(ClassDeclaration* cd) 1368 static LLConstant* build_class_dtor(ClassDeclaration* cd)
1444 1435
1445 assert(cd->type->ty == Tclass); 1436 assert(cd->type->ty == Tclass);
1446 assert(ir->classInfo); 1437 assert(ir->classInfo);
1447 1438
1448 TypeClass* cdty = (TypeClass*)cd->type; 1439 TypeClass* cdty = (TypeClass*)cd->type;
1449 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1440 if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
1441 {
1450 assert(ir->init); 1442 assert(ir->init);
1451 assert(ir->constInit); 1443 assert(ir->constInit);
1452 assert(ir->vtbl); 1444 assert(ir->vtbl);
1453 assert(ir->constVtbl); 1445 assert(ir->constVtbl);
1454 } 1446 }
1458 1450
1459 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1451 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1460 DtoForceConstInitDsymbol(cinfo); 1452 DtoForceConstInitDsymbol(cinfo);
1461 assert(cinfo->ir.irStruct->constInit); 1453 assert(cinfo->ir.irStruct->constInit);
1462 1454
1463 // def init constant
1464 LLConstant* defc = cinfo->ir.irStruct->constInit;
1465 assert(defc);
1466
1467 LLConstant* c; 1455 LLConstant* c;
1468 1456
1457 const LLType* voidPtr = getVoidPtrType();
1458 const LLType* voidPtrPtr = getPtrToType(voidPtr);
1459
1469 // own vtable 1460 // own vtable
1470 c = defc->getOperand(0); 1461 c = cinfo->ir.irStruct->vtbl;
1471 assert(c); 1462 assert(c);
1472 inits.push_back(c); 1463 inits.push_back(c);
1473 1464
1474 // monitor 1465 // monitor
1475 c = defc->getOperand(1); 1466 c = LLConstant::getNullValue(voidPtr);
1476 inits.push_back(c); 1467 inits.push_back(c);
1477 1468
1478 // byte[] init 1469 // byte[] init
1479 const LLType* byteptrty = getPtrToType(LLType::Int8Ty); 1470 if (cd->isInterfaceDeclaration())
1480 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1471 c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(voidPtr));
1481 c = defc->getOperand(2); 1472 else
1482 } 1473 {
1483 else { 1474 c = DtoBitCast(ir->init, voidPtr);
1484 c = llvm::ConstantExpr::getBitCast(ir->init, byteptrty);
1485 //Logger::cout() << *ir->constInit->getType() << std::endl; 1475 //Logger::cout() << *ir->constInit->getType() << std::endl;
1486 size_t initsz = getABITypeSize(ir->constInit->getType()); 1476 size_t initsz = getABITypeSize(ir->constInit->getType());
1487 c = DtoConstSlice(DtoConstSize_t(initsz), c); 1477 c = DtoConstSlice(DtoConstSize_t(initsz), c);
1488 } 1478 }
1489 inits.push_back(c); 1479 inits.push_back(c);
1499 } 1489 }
1500 c = DtoConstString(name); 1490 c = DtoConstString(name);
1501 inits.push_back(c); 1491 inits.push_back(c);
1502 1492
1503 // vtbl array 1493 // vtbl array
1504 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1494 if (cd->isInterfaceDeclaration())
1505 c = defc->getOperand(4); 1495 c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(getPtrToType(voidPtr)));
1506 }
1507 else { 1496 else {
1508 const LLType* byteptrptrty = getPtrToType(byteptrty); 1497 c = DtoBitCast(ir->vtbl, voidPtrPtr);
1509 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); 1498 c = DtoConstSlice(DtoConstSize_t(cd->vtbl.dim), c);
1510
1511 assert(ir->constVtbl);
1512 size_t vtblsz = ir->constVtbl->getNumOperands();
1513 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
1514 } 1499 }
1515 inits.push_back(c); 1500 inits.push_back(c);
1516 1501
1517 // interfaces array 1502 // interfaces array
1518 IrStruct* irstruct = cd->ir.irStruct; 1503 VarDeclaration* intersVar = (VarDeclaration*)cinfo->fields.data[3];
1519 if (!irstruct->interfaceInfos) { 1504 const LLType* intersTy = DtoType(intersVar->type);
1520 c = defc->getOperand(5); 1505 if (!ir->interfaceInfos)
1521 } 1506 c = LLConstant::getNullValue(intersTy);
1522 else { 1507 else {
1523 const LLType* t = defc->getOperand(5)->getType()->getContainedType(1); 1508 const LLType* t = intersTy->getContainedType(1); // .ptr
1524 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); 1509 c = DtoBitCast(ir->interfaceInfos, t);
1525 size_t iisz = irstruct->interfaceVec.size(); 1510 size_t iisz = ir->interfaceVec.size();
1526 c = DtoConstSlice(DtoConstSize_t(iisz), c); 1511 c = DtoConstSlice(DtoConstSize_t(iisz), c);
1527 } 1512 }
1528 inits.push_back(c); 1513 inits.push_back(c);
1529 1514
1530 // base classinfo 1515 // base classinfo
1531 if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1516 // interfaces never get a base , just the interfaces[]
1517 if (cd->baseClass && !cd->isInterfaceDeclaration()) {
1532 DtoDeclareClassInfo(cd->baseClass); 1518 DtoDeclareClassInfo(cd->baseClass);
1533 c = cd->baseClass->ir.irStruct->classInfo; 1519 c = cd->baseClass->ir.irStruct->classInfo;
1534 assert(c); 1520 assert(c);
1535 inits.push_back(c); 1521 inits.push_back(c);
1536 } 1522 }
1537 else { 1523 else {
1538 // null 1524 // null
1539 c = defc->getOperand(6); 1525 c = LLConstant::getNullValue(DtoType(cinfo->type));
1540 inits.push_back(c); 1526 inits.push_back(c);
1541 } 1527 }
1542 1528
1543 // destructor 1529 // destructor
1544 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1530 if (cd->isInterfaceDeclaration())
1545 c = defc->getOperand(7); 1531 c = LLConstant::getNullValue(voidPtr);
1546 } 1532 else
1547 else {
1548 c = build_class_dtor(cd); 1533 c = build_class_dtor(cd);
1549 }
1550 inits.push_back(c); 1534 inits.push_back(c);
1551 1535
1552 // invariant 1536 // invariant
1553 if (cd->inv) { 1537 VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6];
1538 const LLType* invTy = DtoType(invVar->type);
1539 if (cd->inv)
1540 {
1554 DtoForceDeclareDsymbol(cd->inv); 1541 DtoForceDeclareDsymbol(cd->inv);
1555 c = cd->inv->ir.irFunc->func; 1542 c = cd->inv->ir.irFunc->func;
1556 c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(8)->getType()); 1543 c = DtoBitCast(c, invTy);
1557 } 1544 }
1558 else { 1545 else
1559 c = defc->getOperand(8); 1546 c = LLConstant::getNullValue(invTy);
1560 }
1561 inits.push_back(c); 1547 inits.push_back(c);
1562 1548
1563 // uint flags 1549 // uint flags
1564 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1550 if (cd->isInterfaceDeclaration())
1565 c = defc->getOperand(9); 1551 c = DtoConstUint(0);
1566 }
1567 else { 1552 else {
1568 unsigned flags = build_classinfo_flags(cd); 1553 unsigned flags = build_classinfo_flags(cd);
1569 c = DtoConstUint(flags); 1554 c = DtoConstUint(flags);
1570 } 1555 }
1571 inits.push_back(c); 1556 inits.push_back(c);
1572 1557
1573 // deallocator 1558 // deallocator
1574 if (cd->aggDelete) { 1559 if (cd->aggDelete)
1560 {
1575 DtoForceDeclareDsymbol(cd->aggDelete); 1561 DtoForceDeclareDsymbol(cd->aggDelete);
1576 c = cd->aggDelete->ir.irFunc->func; 1562 c = cd->aggDelete->ir.irFunc->func;
1577 c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(10)->getType()); 1563 c = DtoBitCast(c, voidPtr);
1578 } 1564 }
1579 else { 1565 else
1580 c = defc->getOperand(10); 1566 c = LLConstant::getNullValue(voidPtr);
1581 }
1582 inits.push_back(c); 1567 inits.push_back(c);
1583 1568
1584 // offset typeinfo 1569 // offset typeinfo
1585 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1570 VarDeclaration* offTiVar = (VarDeclaration*)cinfo->fields.data[9];
1586 c = defc->getOperand(11); 1571 const LLType* offTiTy = DtoType(offTiVar->type);
1587 } 1572 if (cd->isInterfaceDeclaration())
1588 else { 1573 c = LLConstant::getNullValue(offTiTy);
1589 c = build_offti_array(cd, defc->getOperand(11)); 1574 else
1590 } 1575 c = build_offti_array(cd, offTiTy);
1591 inits.push_back(c); 1576 inits.push_back(c);
1592 1577
1593 // default constructor 1578 // default constructor
1594 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1579 if (cd->defaultCtor)
1580 {
1595 DtoForceDeclareDsymbol(cd->defaultCtor); 1581 DtoForceDeclareDsymbol(cd->defaultCtor);
1596 c = isaConstant(cd->defaultCtor->ir.irFunc->func); 1582 c = isaConstant(cd->defaultCtor->ir.irFunc->func);
1597 const LLType* toTy = defc->getOperand(12)->getType(); 1583 c = DtoBitCast(c, voidPtr);
1598 c = llvm::ConstantExpr::getBitCast(c, toTy); 1584 }
1599 } 1585 else
1600 else { 1586 c = LLConstant::getNullValue(voidPtr);
1601 c = defc->getOperand(12);
1602 }
1603 inits.push_back(c); 1587 inits.push_back(c);
1604 1588
1605 #if DMDV2 1589 #if DMDV2
1606 1590
1607 // xgetMembers 1591 // xgetMembers
1608 c = defc->getOperand(13); 1592 VarDeclaration* xgetVar = (VarDeclaration*)cinfo->fields.data[11];
1609 inits.push_back(c); 1593 const LLType* xgetTy = DtoType(xgetVar->type);
1594
1595 // FIXME: fill it out!
1596 inits.push_back( LLConstant::getNullValue(xgetTy) );
1610 1597
1611 #else 1598 #else
1612 #endif 1599 #endif
1613 1600
1614 /*size_t n = inits.size(); 1601 /*size_t n = inits.size();