Mercurial > projects > ldc
comparison gen/classes.cpp @ 812:6c2ff06c4201
Fixed a nasty bug with how interface vtables for class initializers were output, causing some class fields to be skipped.
Fixed a problem in definition of ClassInfos where an invalid constant was potentially used. This needs to be looked into proper as it might happen again in the future.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Mon, 01 Dec 2008 04:37:54 +0100 |
parents | 69a5e4a6fc0f |
children | 7d16ce7ad19d |
comparison
equal
deleted
inserted
replaced
811:8e6135be6999 | 812:6c2ff06c4201 |
---|---|
433 if (cd->baseClass) | 433 if (cd->baseClass) |
434 { | 434 { |
435 offsetbegin = init_class_initializer(inits, target, cd->baseClass, offsetbegin); | 435 offsetbegin = init_class_initializer(inits, target, cd->baseClass, offsetbegin); |
436 } | 436 } |
437 | 437 |
438 Logger::println("adding data of %s to %s", cd->toChars(), target->toChars()); | 438 Logger::println("adding data of %s to %s starting at %lu", cd->toChars(), target->toChars(), offsetbegin); |
439 LOG_SCOPE; | 439 LOG_SCOPE; |
440 | 440 |
441 // add default fields | 441 // add default fields |
442 VarDeclaration** fields = (VarDeclaration**)cd->fields.data; | 442 VarDeclaration** fields = (VarDeclaration**)cd->fields.data; |
443 size_t nfields = cd->fields.dim; | 443 size_t nfields = cd->fields.dim; |
462 lastsize = size; | 462 lastsize = size; |
463 defVars.push_back(var); | 463 defVars.push_back(var); |
464 } | 464 } |
465 else | 465 else |
466 { | 466 { |
467 Logger::println(" skipped %s", var->toChars()); | 467 Logger::println(" skipped %s at offset %u, current pos is %lu", var->toChars(), var->offset, lastoffset+lastsize); |
468 } | 468 } |
469 } | 469 } |
470 | 470 |
471 // reset offsets, we're going from beginning again | 471 // reset offsets, we're going from beginning again |
472 lastoffset = offsetbegin; | 472 lastoffset = offsetbegin; |
517 if (iri->vtbl) | 517 if (iri->vtbl) |
518 inits.push_back(iri->vtbl); | 518 inits.push_back(iri->vtbl); |
519 else // abstract impl | 519 else // abstract impl |
520 inits.push_back(getNullPtr(getVoidPtrType())); | 520 inits.push_back(getNullPtr(getVoidPtrType())); |
521 | 521 |
522 lastoffset += PTRSIZE; | 522 lastoffset += lastsize; |
523 lastsize = PTRSIZE; | 523 lastsize = PTRSIZE; |
524 } | 524 } |
525 | 525 |
526 // return next offset | 526 // return next offset |
527 return lastoffset + lastsize; | 527 return lastoffset + lastsize; |
747 | 747 |
748 // build interface vtables | 748 // build interface vtables |
749 init_class_interface_vtbl_initializers(cd); | 749 init_class_interface_vtbl_initializers(cd); |
750 | 750 |
751 // build constant from inits | 751 // build constant from inits |
752 assert(!irstruct->constInit); | |
752 irstruct->constInit = LLConstantStruct::get(inits); // classes are never packed | 753 irstruct->constInit = LLConstantStruct::get(inits); // classes are never packed |
753 | 754 |
754 // refine __initZ global type to the one of the initializer | 755 // refine __initZ global type to the one of the initializer |
755 llvm::cast<llvm::OpaqueType>(irstruct->initOpaque.get())->refineAbstractTypeTo(irstruct->constInit->getType()); | 756 llvm::cast<llvm::OpaqueType>(irstruct->initOpaque.get())->refineAbstractTypeTo(irstruct->constInit->getType()); |
756 | 757 |
1435 | 1436 |
1436 assert(cd->type->ty == Tclass); | 1437 assert(cd->type->ty == Tclass); |
1437 assert(ir->classInfo); | 1438 assert(ir->classInfo); |
1438 | 1439 |
1439 TypeClass* cdty = (TypeClass*)cd->type; | 1440 TypeClass* cdty = (TypeClass*)cd->type; |
1440 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) | 1441 if (!cd->isInterfaceDeclaration()) |
1441 { | 1442 { |
1442 assert(ir->init); | 1443 assert(ir->init); |
1443 assert(ir->constInit); | 1444 assert(ir->constInit); |
1444 assert(ir->vtbl); | 1445 assert(ir->vtbl); |
1445 assert(ir->constVtbl); | 1446 assert(ir->constVtbl); |
1448 // holds the list of initializers for llvm | 1449 // holds the list of initializers for llvm |
1449 std::vector<LLConstant*> inits; | 1450 std::vector<LLConstant*> inits; |
1450 | 1451 |
1451 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | 1452 ClassDeclaration* cinfo = ClassDeclaration::classinfo; |
1452 DtoForceConstInitDsymbol(cinfo); | 1453 DtoForceConstInitDsymbol(cinfo); |
1453 assert(cinfo->ir.irStruct->constInit); | |
1454 | 1454 |
1455 LLConstant* c; | 1455 LLConstant* c; |
1456 | 1456 |
1457 const LLType* voidPtr = getVoidPtrType(); | 1457 const LLType* voidPtr = getVoidPtrType(); |
1458 const LLType* voidPtrPtr = getPtrToType(voidPtr); | 1458 const LLType* voidPtrPtr = getPtrToType(voidPtr); |
1471 c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(voidPtr)); | 1471 c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(voidPtr)); |
1472 else | 1472 else |
1473 { | 1473 { |
1474 c = DtoBitCast(ir->init, voidPtr); | 1474 c = DtoBitCast(ir->init, voidPtr); |
1475 //Logger::cout() << *ir->constInit->getType() << std::endl; | 1475 //Logger::cout() << *ir->constInit->getType() << std::endl; |
1476 size_t initsz = getABITypeSize(ir->constInit->getType()); | 1476 size_t initsz = getABITypeSize(ir->init->getType()->getContainedType(0)); |
1477 c = DtoConstSlice(DtoConstSize_t(initsz), c); | 1477 c = DtoConstSlice(DtoConstSize_t(initsz), c); |
1478 } | 1478 } |
1479 inits.push_back(c); | 1479 inits.push_back(c); |
1480 | 1480 |
1481 // class name | 1481 // class name |