Mercurial > projects > ldc
comparison gen/toobj.cpp @ 811:8e6135be6999
Fixed ModuleInfo generation to no longer use the ModuleInfo class' default initializer for types/defaults, it's unsafe as initializers don't necesarily match the "formal" type. There might be explicit padding.
Changed -g switch to emit DW_LANG_D debug info, make demangling work with a patched GDB, still more work to do for full support of D's Dwarf extensions.
Added getNullValue helper method.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Mon, 01 Dec 2008 02:10:16 +0100 |
parents | 67fcd9df8b79 |
children | 05f2651caa6c |
comparison
equal
deleted
inserted
replaced
810:67fcd9df8b79 | 811:8e6135be6999 |
---|---|
677 | 677 |
678 // Put out instance of ModuleInfo for this Module | 678 // Put out instance of ModuleInfo for this Module |
679 | 679 |
680 void Module::genmoduleinfo() | 680 void Module::genmoduleinfo() |
681 { | 681 { |
682 // The layout is: | 682 // The layout is: |
683 // { | 683 // { |
684 // void **vptr; | 684 // char[] name; |
685 // monitor_t monitor; | 685 // ModuleInfo[] importedModules; |
686 // char[] name; // class name | 686 // ClassInfo[] localClasses; |
687 // ModuleInfo importedModules[]; | 687 // uint flags; |
688 // ClassInfo localClasses[]; | 688 // |
689 // uint flags; // initialization state | 689 // void function() ctor; |
690 // void *ctor; | 690 // void function() dtor; |
691 // void *dtor; | 691 // void function() unitTest; |
692 // void *unitTest; | 692 // |
693 // } | 693 // void* xgetMembers; |
694 // void function() ictor; | |
695 // } | |
694 | 696 |
695 // resolve ModuleInfo | 697 // resolve ModuleInfo |
696 assert(moduleinfo); | 698 assert(moduleinfo); |
697 DtoForceConstInitDsymbol(moduleinfo); | 699 DtoForceConstInitDsymbol(moduleinfo); |
698 | 700 |
703 fatal(); | 705 fatal(); |
704 } | 706 } |
705 | 707 |
706 // moduleinfo llvm struct type | 708 // moduleinfo llvm struct type |
707 const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->ir.type->get()); | 709 const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->ir.type->get()); |
708 | |
709 // classinfo llvm struct type | 710 // classinfo llvm struct type |
710 const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->ir.type->get()); | 711 const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->ir.type->get()); |
711 | 712 |
712 // initializer vector | 713 // initializer vector |
713 std::vector<LLConstant*> initVec; | 714 std::vector<LLConstant*> initVec; |
731 std::vector<LLConstant*> importInits; | 732 std::vector<LLConstant*> importInits; |
732 for (size_t i = 0; i < aimports.dim; i++) | 733 for (size_t i = 0; i < aimports.dim; i++) |
733 { | 734 { |
734 Module *m = (Module *)aimports.data[i]; | 735 Module *m = (Module *)aimports.data[i]; |
735 if (!m->needModuleInfo()) | 736 if (!m->needModuleInfo()) |
736 aimports_dim--; | 737 continue; |
737 else { // declare | 738 |
738 // create name | 739 // declare the imported module info |
739 std::string m_name("_D"); | 740 std::string m_name("_D"); |
740 m_name.append(m->mangle()); | 741 m_name.append(m->mangle()); |
741 m_name.append("8__ModuleZ"); | 742 m_name.append("8__ModuleZ"); |
742 llvm::GlobalVariable* m_gvar = gIR->module->getGlobalVariable(m_name); | 743 llvm::GlobalVariable* m_gvar = gIR->module->getGlobalVariable(m_name); |
743 if (!m_gvar) m_gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name, gIR->module); | 744 if (!m_gvar) m_gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name, gIR->module); |
744 importInits.push_back(m_gvar); | 745 importInits.push_back(m_gvar); |
745 } | |
746 } | 746 } |
747 // has import array? | 747 // has import array? |
748 if (!importInits.empty()) | 748 if (!importInits.empty()) |
749 { | 749 { |
750 const llvm::ArrayType* importArrTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size()); | 750 const llvm::ArrayType* importArrTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size()); |
756 if (!m_gvar) m_gvar = new llvm::GlobalVariable(importArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module); | 756 if (!m_gvar) m_gvar = new llvm::GlobalVariable(importArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module); |
757 c = llvm::ConstantExpr::getBitCast(m_gvar, getPtrToType(importArrTy->getElementType())); | 757 c = llvm::ConstantExpr::getBitCast(m_gvar, getPtrToType(importArrTy->getElementType())); |
758 c = DtoConstSlice(DtoConstSize_t(importInits.size()), c); | 758 c = DtoConstSlice(DtoConstSize_t(importInits.size()), c); |
759 } | 759 } |
760 else | 760 else |
761 c = moduleinfo->ir.irStruct->constInit->getOperand(3); | 761 c = DtoConstSlice( DtoConstSize_t(0), getNullValue(getPtrToType(moduleinfoTy)) ); |
762 initVec.push_back(c); | 762 initVec.push_back(c); |
763 | 763 |
764 // localClasses[] | 764 // localClasses[] |
765 ClassDeclarations aclasses; | 765 ClassDeclarations aclasses; |
766 //printf("members->dim = %d\n", members->dim); | 766 //printf("members->dim = %d\n", members->dim); |
787 Logger::println("skipping opaque class declaration '%s' in moduleinfo", cd->toPrettyChars()); | 787 Logger::println("skipping opaque class declaration '%s' in moduleinfo", cd->toPrettyChars()); |
788 continue; | 788 continue; |
789 } | 789 } |
790 Logger::println("class: %s", cd->toPrettyChars()); | 790 Logger::println("class: %s", cd->toPrettyChars()); |
791 assert(cd->ir.irStruct->classInfo); | 791 assert(cd->ir.irStruct->classInfo); |
792 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->classInfo, getPtrToType(classinfoTy)); | 792 c = DtoBitCast(cd->ir.irStruct->classInfo, getPtrToType(classinfoTy)); |
793 classInits.push_back(c); | 793 classInits.push_back(c); |
794 } | 794 } |
795 // has class array? | 795 // has class array? |
796 if (!classInits.empty()) | 796 if (!classInits.empty()) |
797 { | 797 { |
800 std::string m_name("_D"); | 800 std::string m_name("_D"); |
801 m_name.append(mangle()); | 801 m_name.append(mangle()); |
802 m_name.append("9__classesZ"); | 802 m_name.append("9__classesZ"); |
803 assert(gIR->module->getGlobalVariable(m_name) == NULL); | 803 assert(gIR->module->getGlobalVariable(m_name) == NULL); |
804 llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(classArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module); | 804 llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(classArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module); |
805 c = llvm::ConstantExpr::getBitCast(m_gvar, getPtrToType(classArrTy->getElementType())); | 805 c = DtoBitCast(m_gvar, getPtrToType(classinfoTy)); |
806 c = DtoConstSlice(DtoConstSize_t(classInits.size()), c); | 806 c = DtoConstSlice(DtoConstSize_t(classInits.size()), c); |
807 } | 807 } |
808 else | 808 else |
809 c = moduleinfo->ir.irStruct->constInit->getOperand(4); | 809 c = DtoConstSlice( DtoConstSize_t(0), getNullValue(getPtrToType(classinfoTy)) ); |
810 initVec.push_back(c); | 810 initVec.push_back(c); |
811 | 811 |
812 // flags | 812 // flags |
813 c = DtoConstUint(0); | 813 c = DtoConstUint(0); |
814 if (!needmoduleinfo) | 814 if (!needmoduleinfo) |
815 c = DtoConstUint(4); // flags (4 means MIstandalone) | 815 c = DtoConstUint(4); // flags (4 means MIstandalone) |
816 initVec.push_back(c); | 816 initVec.push_back(c); |
817 | 817 |
818 // function pointer type for next three fields | |
819 const LLType* fnptrTy = getPtrToType(LLFunctionType::get(LLType::VoidTy, std::vector<const LLType*>(), false)); | |
820 | |
818 // ctor | 821 // ctor |
819 llvm::Function* fctor = build_module_ctor(); | 822 llvm::Function* fctor = build_module_ctor(); |
820 c = fctor ? fctor : moduleinfo->ir.irStruct->constInit->getOperand(6); | 823 c = fctor ? fctor : getNullValue(fnptrTy); |
821 initVec.push_back(c); | 824 initVec.push_back(c); |
822 | 825 |
823 // dtor | 826 // dtor |
824 llvm::Function* fdtor = build_module_dtor(); | 827 llvm::Function* fdtor = build_module_dtor(); |
825 c = fdtor ? fdtor : moduleinfo->ir.irStruct->constInit->getOperand(7); | 828 c = fdtor ? fdtor : getNullValue(fnptrTy); |
826 initVec.push_back(c); | 829 initVec.push_back(c); |
827 | 830 |
828 // unitTest | 831 // unitTest |
829 llvm::Function* unittest = build_module_unittest(); | 832 llvm::Function* unittest = build_module_unittest(); |
830 c = unittest ? unittest : moduleinfo->ir.irStruct->constInit->getOperand(8); | 833 c = unittest ? unittest : getNullValue(fnptrTy); |
831 initVec.push_back(c); | 834 initVec.push_back(c); |
832 | 835 |
833 // xgetMembers | 836 // xgetMembers |
834 c = moduleinfo->ir.irStruct->constInit->getOperand(9); | 837 c = getNullValue(getVoidPtrType()); |
835 initVec.push_back(c); | 838 initVec.push_back(c); |
836 | 839 |
837 // ictor | 840 // ictor |
838 c = moduleinfo->ir.irStruct->constInit->getOperand(10); | 841 c = getNullValue(fnptrTy); |
839 initVec.push_back(c); | 842 initVec.push_back(c); |
840 | 843 |
841 /*Logger::println("MODULE INFO INITIALIZERS"); | 844 /*Logger::println("MODULE INFO INITIALIZERS"); |
842 for (size_t i=0; i<initVec.size(); ++i) | 845 for (size_t i=0; i<initVec.size(); ++i) |
843 { | 846 { |