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 }