Mercurial > projects > ldc
comparison gen/classes.cpp @ 1383:f15a2d131ceb
Update !ClassInfo generation to use !RTTIBuilder, slight update of !RTTIBuilder .
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Sun, 17 May 2009 16:27:01 +0200 |
parents | 1fbdfec6ea0d |
children | 68a0e361fdce |
comparison
equal
deleted
inserted
replaced
1382:a0a4d4dac1a4 | 1383:f15a2d131ceb |
---|---|
3 #include "mtype.h" | 3 #include "mtype.h" |
4 #include "aggregate.h" | 4 #include "aggregate.h" |
5 #include "init.h" | 5 #include "init.h" |
6 #include "declaration.h" | 6 #include "declaration.h" |
7 | 7 |
8 #include "gen/dvalue.h" | |
8 #include "gen/irstate.h" | 9 #include "gen/irstate.h" |
10 | |
11 #include "gen/arrays.h" | |
12 #include "gen/classes.h" | |
13 #include "gen/functions.h" | |
14 #include "gen/llvmhelpers.h" | |
15 #include "gen/logger.h" | |
16 #include "gen/nested.h" | |
17 #include "gen/rttibuilder.h" | |
18 #include "gen/runtime.h" | |
19 #include "gen/structs.h" | |
9 #include "gen/tollvm.h" | 20 #include "gen/tollvm.h" |
10 #include "gen/llvmhelpers.h" | |
11 #include "gen/arrays.h" | |
12 #include "gen/logger.h" | |
13 #include "gen/classes.h" | |
14 #include "gen/structs.h" | |
15 #include "gen/functions.h" | |
16 #include "gen/runtime.h" | |
17 #include "gen/dvalue.h" | |
18 #include "gen/nested.h" | |
19 #include "gen/utils.h" | 21 #include "gen/utils.h" |
20 | 22 |
21 #include "ir/irstruct.h" | 23 #include "ir/irstruct.h" |
22 #include "ir/irtypeclass.h" | 24 #include "ir/irtypeclass.h" |
23 | 25 |
664 // } | 666 // } |
665 | 667 |
666 Logger::println("DtoDefineClassInfo(%s)", cd->toChars()); | 668 Logger::println("DtoDefineClassInfo(%s)", cd->toChars()); |
667 LOG_SCOPE; | 669 LOG_SCOPE; |
668 | 670 |
671 assert(cd->type->ty == Tclass); | |
672 TypeClass* cdty = (TypeClass*)cd->type; | |
673 | |
669 IrStruct* ir = cd->ir.irStruct; | 674 IrStruct* ir = cd->ir.irStruct; |
670 | 675 assert(ir); |
671 assert(cd->type->ty == Tclass); | |
672 | |
673 TypeClass* cdty = (TypeClass*)cd->type; | |
674 | |
675 // holds the list of initializers for llvm | |
676 std::vector<LLConstant*> inits; | |
677 | 676 |
678 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | 677 ClassDeclaration* cinfo = ClassDeclaration::classinfo; |
679 cinfo->codegen(Type::sir); | 678 |
679 // use the rtti builder | |
680 RTTIBuilder b(ClassDeclaration::classinfo); | |
680 | 681 |
681 LLConstant* c; | 682 LLConstant* c; |
682 | 683 |
683 const LLType* voidPtr = getVoidPtrType(); | 684 const LLType* voidPtr = getVoidPtrType(); |
684 const LLType* voidPtrPtr = getPtrToType(voidPtr); | 685 const LLType* voidPtrPtr = getPtrToType(voidPtr); |
685 | 686 |
686 // own vtable | |
687 c = cinfo->ir.irStruct->getVtblSymbol(); | |
688 inits.push_back(c); | |
689 | |
690 // monitor | |
691 c = LLConstant::getNullValue(voidPtr); | |
692 inits.push_back(c); | |
693 | |
694 // byte[] init | 687 // byte[] init |
695 if (cd->isInterfaceDeclaration()) | 688 if (cd->isInterfaceDeclaration()) |
696 c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(voidPtr)); | 689 { |
690 b.push_null_void_array(); | |
691 } | |
697 else | 692 else |
698 { | 693 { |
699 c = DtoBitCast(ir->getInitSymbol(), voidPtr); | 694 const LLType* cd_type = cdty->irtype->getPA(); |
700 //Logger::cout() << *ir->constInit->getType() << std::endl; | 695 size_t initsz = getTypePaddedSize(cd_type); |
701 size_t initsz = getTypePaddedSize(ir->getInitSymbol()->getType()->getContainedType(0)); | 696 b.push_void_array(initsz, ir->getInitSymbol()); |
702 c = DtoConstSlice(DtoConstSize_t(initsz), c); | 697 } |
703 } | |
704 inits.push_back(c); | |
705 | 698 |
706 // class name | 699 // class name |
707 // from dmd | 700 // code from dmd |
708 char *name = cd->ident->toChars(); | 701 char *name = cd->ident->toChars(); |
709 size_t namelen = strlen(name); | 702 size_t namelen = strlen(name); |
710 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) | 703 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) |
711 { | 704 { |
712 name = cd->toPrettyChars(); | 705 name = cd->toPrettyChars(); |
713 namelen = strlen(name); | 706 namelen = strlen(name); |
714 } | 707 } |
715 c = DtoConstString(name); | 708 b.push_string(name); |
716 inits.push_back(c); | |
717 | 709 |
718 // vtbl array | 710 // vtbl array |
719 if (cd->isInterfaceDeclaration()) | 711 if (cd->isInterfaceDeclaration()) |
720 c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(getPtrToType(voidPtr))); | 712 { |
721 else { | 713 b.push_array(0, getNullValue(voidPtrPtr)); |
714 } | |
715 else | |
716 { | |
722 c = DtoBitCast(ir->getVtblSymbol(), voidPtrPtr); | 717 c = DtoBitCast(ir->getVtblSymbol(), voidPtrPtr); |
723 c = DtoConstSlice(DtoConstSize_t(cd->vtbl.dim), c); | 718 b.push_array(cd->vtbl.dim, c); |
724 } | 719 } |
725 inits.push_back(c); | |
726 | 720 |
727 // interfaces array | 721 // interfaces array |
728 c = ir->getClassInfoInterfaces(); | 722 b.push(ir->getClassInfoInterfaces()); |
729 inits.push_back(c); | |
730 | 723 |
731 // base classinfo | 724 // base classinfo |
732 // interfaces never get a base , just the interfaces[] | 725 // interfaces never get a base , just the interfaces[] |
733 if (cd->baseClass && !cd->isInterfaceDeclaration()) { | 726 if (cd->baseClass && !cd->isInterfaceDeclaration()) |
734 c = cd->baseClass->ir.irStruct->getClassInfoSymbol(); | 727 b.push_classinfo(cd->baseClass); |
735 assert(c); | 728 else |
736 inits.push_back(c); | 729 b.push_null(cinfo->type); |
737 } | |
738 else { | |
739 // null | |
740 c = LLConstant::getNullValue(DtoType(cinfo->type)); | |
741 inits.push_back(c); | |
742 } | |
743 | 730 |
744 // destructor | 731 // destructor |
745 if (cd->isInterfaceDeclaration()) | 732 if (cd->isInterfaceDeclaration()) |
746 c = LLConstant::getNullValue(voidPtr); | 733 b.push_null_vp(); |
747 else | 734 else |
748 c = build_class_dtor(cd); | 735 b.push(build_class_dtor(cd)); |
749 inits.push_back(c); | |
750 | 736 |
751 // invariant | 737 // invariant |
752 VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6]; | 738 VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6]; |
753 const LLType* invTy = DtoType(invVar->type); | 739 b.push_funcptr(cd->inv, invVar->type); |
754 if (cd->inv) | |
755 { | |
756 cd->inv->codegen(Type::sir); | |
757 c = cd->inv->ir.irFunc->func; | |
758 c = DtoBitCast(c, invTy); | |
759 } | |
760 else | |
761 c = LLConstant::getNullValue(invTy); | |
762 inits.push_back(c); | |
763 | 740 |
764 // uint flags | 741 // uint flags |
765 if (cd->isInterfaceDeclaration()) | 742 if (cd->isInterfaceDeclaration()) |
766 c = DtoConstUint(0); | 743 b.push_uint(0); |
767 else { | 744 else |
768 unsigned flags = build_classinfo_flags(cd); | 745 b.push_uint(build_classinfo_flags(cd)); |
769 c = DtoConstUint(flags); | |
770 } | |
771 inits.push_back(c); | |
772 | 746 |
773 // deallocator | 747 // deallocator |
774 if (cd->aggDelete) | 748 b.push_funcptr(cd->aggDelete, Type::tvoid->pointerTo()); |
775 { | |
776 cd->aggDelete->codegen(Type::sir); | |
777 c = cd->aggDelete->ir.irFunc->func; | |
778 c = DtoBitCast(c, voidPtr); | |
779 } | |
780 else | |
781 c = LLConstant::getNullValue(voidPtr); | |
782 inits.push_back(c); | |
783 | 749 |
784 // offset typeinfo | 750 // offset typeinfo |
785 VarDeclaration* offTiVar = (VarDeclaration*)cinfo->fields.data[9]; | 751 VarDeclaration* offTiVar = (VarDeclaration*)cinfo->fields.data[9]; |
786 const LLType* offTiTy = DtoType(offTiVar->type); | |
787 | 752 |
788 #if GENERATE_OFFTI | 753 #if GENERATE_OFFTI |
789 | 754 |
790 if (cd->isInterfaceDeclaration()) | 755 if (cd->isInterfaceDeclaration()) |
791 c = LLConstant::getNullValue(offTiTy); | 756 b.push_null(offTiVar->type); |
792 else | 757 else |
793 c = build_offti_array(cd, offTiTy); | 758 b.push(build_offti_array(cd, DtoType(offTiVar->type))); |
794 | 759 |
795 #else // GENERATE_OFFTI | 760 #else // GENERATE_OFFTI |
796 | 761 |
797 c = LLConstant::getNullValue(offTiTy); | 762 b.push_null(offTiVar->type); |
798 | 763 |
799 #endif // GENERATE_OFFTI | 764 #endif // GENERATE_OFFTI |
800 | 765 |
801 inits.push_back(c); | |
802 | |
803 // default constructor | 766 // default constructor |
804 if (cd->defaultCtor) | 767 b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo()); |
805 { | |
806 cd->defaultCtor->codegen(Type::sir); | |
807 c = isaConstant(cd->defaultCtor->ir.irFunc->func); | |
808 c = DtoBitCast(c, voidPtr); | |
809 } | |
810 else | |
811 c = LLConstant::getNullValue(voidPtr); | |
812 inits.push_back(c); | |
813 | 768 |
814 // typeinfo - since 1.045 | 769 // typeinfo - since 1.045 |
815 inits.push_back(DtoTypeInfoOf(cd->type, true)); | 770 b.push_typeinfo(cd->type); |
816 | 771 |
817 #if DMDV2 | 772 #if DMDV2 |
818 | 773 |
819 // xgetMembers | 774 // xgetMembers |
820 VarDeclaration* xgetVar = (VarDeclaration*)cinfo->fields.data[11]; | 775 VarDeclaration* xgetVar = (VarDeclaration*)cinfo->fields.data[11]; |
821 const LLType* xgetTy = DtoType(xgetVar->type); | |
822 | 776 |
823 // FIXME: fill it out! | 777 // FIXME: fill it out! |
824 inits.push_back( LLConstant::getNullValue(xgetTy) ); | 778 b.push_null(xgetVar->type); |
779 | |
825 #endif | 780 #endif |
826 | 781 |
827 /*size_t n = inits.size(); | 782 /*size_t n = inits.size(); |
828 for (size_t i=0; i<n; ++i) | 783 for (size_t i=0; i<n; ++i) |
829 { | 784 { |
830 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | 785 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; |
831 }*/ | 786 }*/ |
832 | 787 |
833 // build the initializer | 788 // build the initializer |
834 LLConstant* finalinit = llvm::ConstantStruct::get(inits); | 789 LLConstant* finalinit = b.get_constant(); |
790 | |
835 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | 791 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; |
836 ir->constClassInfo = finalinit; | 792 ir->constClassInfo = finalinit; |
837 | 793 |
838 // sanity check | 794 // sanity check |
839 assert(finalinit->getType() == ir->classInfo->getType()->getContainedType(0) && | 795 assert(finalinit->getType() == ir->classInfo->getType()->getContainedType(0) && |
840 "__ClassZ initializer does not match the ClassInfo type"); | 796 "__ClassZ initializer does not match the ClassInfo type"); |
841 | |
842 | 797 |
843 // return initializer | 798 // return initializer |
844 return finalinit; | 799 return finalinit; |
845 } | 800 } |