Mercurial > projects > ldc
comparison gen/classes.cpp @ 177:cea8dcfa76df trunk
[svn r193] Fixed: abstract classes implementing interfaces now output proper Interface info arrays. (null vtables).
Did a little renaming of delegate utils.
author | lindquist |
---|---|
date | Wed, 07 May 2008 04:45:51 +0200 |
parents | db9890b3fb64 |
children | 36044016709a |
comparison
equal
deleted
inserted
replaced
176:a074a5ff709c | 177:cea8dcfa76df |
---|---|
608 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); | 608 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); |
609 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); | 609 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); |
610 infoInits.push_back(c); | 610 infoInits.push_back(c); |
611 | 611 |
612 // offset | 612 // offset |
613 // generate target independent offset with constGEP | |
614 /*llvm::Value* cidx = DtoConstInt(iri->index); | |
615 Logger::cout() << "offset to interface in class type: " << *cd->type->ir.type->get() << '\n'; | |
616 size_t ioff = gTargetData->getIndexedOffset(cd->type->ir.type->get(), &cidx, 1); | |
617 infoInits.push_back(DtoConstUint(ioff));*/ | |
618 assert(iri->index >= 0); | 613 assert(iri->index >= 0); |
619 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); | 614 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); |
620 infoInits.push_back(DtoConstUint(ioff)); | 615 infoInits.push_back(DtoConstUint(ioff)); |
621 | 616 |
622 // create interface info initializer constant | 617 // create interface info initializer constant |
656 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); | 651 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); |
657 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); | 652 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); |
658 } | 653 } |
659 } | 654 } |
660 // we always generate interfaceinfos as best we can | 655 // we always generate interfaceinfos as best we can |
661 /*else | 656 else |
662 { | 657 { |
663 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) | 658 // TODO: this is duplicated code from right above... I'm just too lazy to generalise it right now :/ |
659 // create interface vtable const initalizers | |
660 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) | |
664 { | 661 { |
665 ClassDeclaration* id = i->first; | 662 IrInterface* iri = *i; |
663 BaseClass* b = iri->base; | |
664 | |
665 ClassDeclaration* id = iri->decl; | |
666 assert(id->type->ty == Tclass); | 666 assert(id->type->ty == Tclass); |
667 TypeClass* its = (TypeClass*)id->type; | 667 TypeClass* its = (TypeClass*)id->type; |
668 | |
669 IrInterface* iri = i->second; | |
670 BaseClass* b = iri->base; | |
671 | 668 |
672 // generate interface info initializer | 669 // generate interface info initializer |
673 std::vector<llvm::Constant*> infoInits; | 670 std::vector<llvm::Constant*> infoInits; |
674 | 671 |
675 // classinfo | 672 // classinfo |
681 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); | 678 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
682 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); | 679 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); |
683 infoInits.push_back(c); | 680 infoInits.push_back(c); |
684 | 681 |
685 // offset | 682 // offset |
686 infoInits.push_back(DtoConstInt(0)); | 683 assert(iri->index >= 0); |
684 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); | |
685 infoInits.push_back(DtoConstUint(ioff)); | |
687 | 686 |
688 // create interface info initializer constant | 687 // create interface info initializer constant |
689 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); | 688 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); |
690 } | 689 } |
691 }*/ | 690 } |
692 | 691 |
693 gIR->classes.pop_back(); | 692 gIR->classes.pop_back(); |
694 gIR->structs.pop_back(); | 693 gIR->structs.pop_back(); |
695 } | 694 } |
696 | 695 |
707 // get the struct (class) type | 706 // get the struct (class) type |
708 assert(cd->type->ty == Tclass); | 707 assert(cd->type->ty == Tclass); |
709 TypeClass* ts = (TypeClass*)cd->type; | 708 TypeClass* ts = (TypeClass*)cd->type; |
710 | 709 |
711 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { | 710 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { |
712 // interfaces don't have initializers | 711 |
712 // interfaces don't have static initializer/vtable | |
713 // neither do abstract classes | 713 // neither do abstract classes |
714 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) | 714 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) |
715 { | 715 { |
716 cd->ir.irStruct->init->setInitializer(cd->ir.irStruct->constInit); | 716 cd->ir.irStruct->init->setInitializer(cd->ir.irStruct->constInit); |
717 cd->ir.irStruct->vtbl->setInitializer(cd->ir.irStruct->constVtbl); | 717 cd->ir.irStruct->vtbl->setInitializer(cd->ir.irStruct->constVtbl); |
718 | 718 |
719 // initialize interface vtables | 719 // initialize interface vtables |
720 IrStruct* irstruct = cd->ir.irStruct; | 720 IrStruct* irstruct = cd->ir.irStruct; |
721 std::vector<llvm::Constant*> infoInits; | |
722 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) | 721 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) |
723 { | 722 { |
724 IrInterface* iri = *i; | 723 IrInterface* iri = *i; |
725 iri->vtbl->setInitializer(iri->vtblInit); | 724 iri->vtbl->setInitializer(iri->vtblInit); |
726 infoInits.push_back(iri->infoInit); | |
727 } | 725 } |
728 // initialize interface info array | 726 } |
729 if (!infoInits.empty()) | 727 |
730 { | 728 // always do interface info array when possible |
731 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); | 729 IrStruct* irstruct = cd->ir.irStruct; |
732 irstruct->interfaceInfos->setInitializer(arrInit); | 730 std::vector<llvm::Constant*> infoInits; |
733 } | 731 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) |
732 { | |
733 IrInterface* iri = *i; | |
734 infoInits.push_back(iri->infoInit); | |
735 } | |
736 // set initializer | |
737 if (!infoInits.empty()) | |
738 { | |
739 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); | |
740 irstruct->interfaceInfos->setInitializer(arrInit); | |
741 } | |
742 else | |
743 { | |
744 assert(irstruct->interfaceInfos == NULL); | |
734 } | 745 } |
735 | 746 |
736 // generate classinfo | 747 // generate classinfo |
737 DtoDefineClassInfo(cd); | 748 DtoDefineClassInfo(cd); |
738 } | 749 } |