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 }