Mercurial > projects > ldc
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(); |