Mercurial > projects > ldc
comparison gen/toobj.cpp @ 797:340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Fixed function literals in static initializers.
Changed alignment of delegates from 2*PTRSIZE to just PTRSIZE.
Changed errors to go to stderr instead of stdout.
Fairly major rewriting of struct/union/class handling, STILL A BIT BUGGY !!!
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sat, 29 Nov 2008 21:25:43 +0100 |
parents | af04bbae8553 |
children | 67fcd9df8b79 |
comparison
equal
deleted
inserted
replaced
796:6e7a4c3b64d2 | 797:340acf1535d0 |
---|---|
75 Logger::println("Generating module: %s\n", (md ? md->toChars() : toChars())); | 75 Logger::println("Generating module: %s\n", (md ? md->toChars() : toChars())); |
76 LOG_SCOPE; | 76 LOG_SCOPE; |
77 | 77 |
78 //printf("codegen: %s\n", srcfile->toChars()); | 78 //printf("codegen: %s\n", srcfile->toChars()); |
79 | 79 |
80 assert(!global.errors); | |
81 | |
80 // start by deleting the old object file | 82 // start by deleting the old object file |
81 deleteObjFile(); | 83 deleteObjFile(); |
82 | 84 |
83 // create a new ir state | 85 // create a new ir state |
84 // TODO look at making the instance static and moving most functionality into IrModule where it belongs | 86 // TODO look at making the instance static and moving most functionality into IrModule where it belongs |
153 } | 155 } |
154 if (!ClassDeclaration::classinfo) { | 156 if (!ClassDeclaration::classinfo) { |
155 error("is missing 'class ClassInfo'"); | 157 error("is missing 'class ClassInfo'"); |
156 fatal(); | 158 fatal(); |
157 } | 159 } |
158 | |
159 // start out by providing opaque for the built-in class types | |
160 if (!ClassDeclaration::object->type->ir.type) | |
161 ClassDeclaration::object->type->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get()); | |
162 | |
163 if (!Type::typeinfo->type->ir.type) | |
164 Type::typeinfo->type->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get()); | |
165 | |
166 if (!ClassDeclaration::classinfo->type->ir.type) | |
167 ClassDeclaration::classinfo->type->ir.type = new llvm::PATypeHolder(llvm::OpaqueType::get()); | |
168 | 160 |
169 // process module members | 161 // process module members |
170 for (int k=0; k < members->dim; k++) { | 162 for (int k=0; k < members->dim; k++) { |
171 Dsymbol* dsym = (Dsymbol*)(members->data[k]); | 163 Dsymbol* dsym = (Dsymbol*)(members->data[k]); |
172 assert(dsym); | 164 assert(dsym); |
636 | 628 |
637 // provide the default initializer | 629 // provide the default initializer |
638 const LLStructType* modulerefTy = DtoModuleReferenceType(); | 630 const LLStructType* modulerefTy = DtoModuleReferenceType(); |
639 std::vector<LLConstant*> mrefvalues; | 631 std::vector<LLConstant*> mrefvalues; |
640 mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0))); | 632 mrefvalues.push_back(LLConstant::getNullValue(modulerefTy->getContainedType(0))); |
641 mrefvalues.push_back(moduleinfo); | 633 mrefvalues.push_back(llvm::ConstantExpr::getBitCast(moduleinfo, modulerefTy->getContainedType(1))); |
642 LLConstant* thismrefinit = LLConstantStruct::get(modulerefTy, mrefvalues); | 634 LLConstant* thismrefinit = LLConstantStruct::get(modulerefTy, mrefvalues); |
643 | 635 |
644 // create the ModuleReference node for this module | 636 // create the ModuleReference node for this module |
645 std::string thismrefname = "_D"; | 637 std::string thismrefname = "_D"; |
646 thismrefname += gIR->dmodule->mangle(); | 638 thismrefname += gIR->dmodule->mangle(); |
702 | 694 |
703 // resolve ModuleInfo | 695 // resolve ModuleInfo |
704 assert(moduleinfo); | 696 assert(moduleinfo); |
705 DtoForceConstInitDsymbol(moduleinfo); | 697 DtoForceConstInitDsymbol(moduleinfo); |
706 | 698 |
699 // check for patch | |
700 if (moduleinfo->ir.irStruct->constInit->getNumOperands() != 11) | |
701 { | |
702 error("unpatched object.d detected, ModuleInfo incorrect"); | |
703 fatal(); | |
704 } | |
705 | |
707 // moduleinfo llvm struct type | 706 // moduleinfo llvm struct type |
708 const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->ir.type->get()); | 707 const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->ir.type->get()); |
709 | 708 |
710 // classinfo llvm struct type | 709 // classinfo llvm struct type |
711 const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->ir.type->get()); | 710 const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->ir.type->get()); |
781 if (cd->isInterfaceDeclaration()) | 780 if (cd->isInterfaceDeclaration()) |
782 { | 781 { |
783 Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars()); | 782 Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars()); |
784 continue; | 783 continue; |
785 } | 784 } |
785 else if (cd->sizeok != 1) | |
786 { | |
787 Logger::println("skipping opaque class declaration '%s' in moduleinfo", cd->toPrettyChars()); | |
788 continue; | |
789 } | |
786 Logger::println("class: %s", cd->toPrettyChars()); | 790 Logger::println("class: %s", cd->toPrettyChars()); |
787 assert(cd->ir.irStruct->classInfo); | 791 assert(cd->ir.irStruct->classInfo); |
788 classInits.push_back(cd->ir.irStruct->classInfo); | 792 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->classInfo, getPtrToType(classinfoTy)); |
793 classInits.push_back(c); | |
789 } | 794 } |
790 // has class array? | 795 // has class array? |
791 if (!classInits.empty()) | 796 if (!classInits.empty()) |
792 { | 797 { |
793 const llvm::ArrayType* classArrTy = llvm::ArrayType::get(getPtrToType(classinfoTy), classInits.size()); | 798 const llvm::ArrayType* classArrTy = llvm::ArrayType::get(getPtrToType(classinfoTy), classInits.size()); |
840 if (initVec[i]->getType() != moduleinfoTy->getElementType(i)) | 845 if (initVec[i]->getType() != moduleinfoTy->getElementType(i)) |
841 assert(0); | 846 assert(0); |
842 }*/ | 847 }*/ |
843 | 848 |
844 // create initializer | 849 // create initializer |
845 LLConstant* constMI = llvm::ConstantStruct::get(moduleinfoTy, initVec); | 850 LLConstant* constMI = llvm::ConstantStruct::get(initVec); |
846 | 851 |
847 // create name | 852 // create name |
848 std::string MIname("_D"); | 853 std::string MIname("_D"); |
849 MIname.append(mangle()); | 854 MIname.append(mangle()); |
850 MIname.append("8__ModuleZ"); | 855 MIname.append("8__ModuleZ"); |
851 | 856 |
852 // declare | 857 // declare |
853 // flags will be modified at runtime so can't make it constant | 858 // flags will be modified at runtime so can't make it constant |
854 | 859 |
855 llvm::GlobalVariable* gvar = gIR->module->getGlobalVariable(MIname); | 860 llvm::GlobalVariable* gvar = gIR->module->getGlobalVariable(MIname); |
856 if (!gvar) gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module); | 861 if (!gvar) gvar = new llvm::GlobalVariable(constMI->getType(), false, llvm::GlobalValue::ExternalLinkage, NULL, MIname, gIR->module); |
862 else assert(gvar->getType()->getContainedType(0) == constMI->getType()); | |
857 gvar->setInitializer(constMI); | 863 gvar->setInitializer(constMI); |
858 | 864 |
859 // build the modulereference and ctor for registering it | 865 // build the modulereference and ctor for registering it |
860 LLFunction* mictor = build_module_reference_and_ctor(gvar); | 866 LLFunction* mictor = build_module_reference_and_ctor(gvar); |
861 | 867 |
986 // not sure why this is only needed for d2 | 992 // not sure why this is only needed for d2 |
987 bool _isconst = isConst() && init; | 993 bool _isconst = isConst() && init; |
988 #else | 994 #else |
989 bool _isconst = isConst(); | 995 bool _isconst = isConst(); |
990 #endif | 996 #endif |
991 if (parent && parent->isFuncDeclaration()) | 997 Dsymbol* par = toParent2(); |
998 if (par && par->isFuncDeclaration()) | |
992 { | 999 { |
993 static_local = true; | 1000 static_local = true; |
994 if (init && init->isExpInitializer()) { | 1001 if (init && init->isExpInitializer()) { |
995 _isconst = false; | 1002 _isconst = false; |
996 } | 1003 } |
1013 else | 1020 else |
1014 gIR->constInitList.push_back(this); | 1021 gIR->constInitList.push_back(this); |
1015 } | 1022 } |
1016 else | 1023 else |
1017 { | 1024 { |
1018 #if DMDV2 | 1025 // might already have its irField, as classes derive each other without getting copies of the VarDeclaration |
1019 #if 0 | |
1020 if (!ir.irField) | 1026 if (!ir.irField) |
1021 { | 1027 { |
1022 printf("dataseg: %d\n", isDataseg()); | 1028 assert(!ir.isSet()); |
1023 printf("parent: %s %s\n", parent->kind(), parent->toPrettyChars()); | 1029 ir.irField = new IrField(this); |
1024 printf("this: %s %s\n", this->kind(), this->toPrettyChars()); | 1030 } |
1025 } | 1031 IrStruct* irstruct = gIR->topstruct(); |
1026 #endif | 1032 irstruct->addVar(this); |
1027 #else | 1033 |
1028 assert(ir.irField != 0); | 1034 Logger::println("added offset %u", offset); |
1029 #endif | 1035 } |
1030 } | |
1031 Logger::println("VarDeclaration::toObjFile is done"); | |
1032 } | 1036 } |
1033 | 1037 |
1034 /* ================================================================== */ | 1038 /* ================================================================== */ |
1035 | 1039 |
1036 void TypedefDeclaration::toObjFile(int multiobj) | 1040 void TypedefDeclaration::toObjFile(int multiobj) |
1054 | 1058 |
1055 void FuncDeclaration::toObjFile(int multiobj) | 1059 void FuncDeclaration::toObjFile(int multiobj) |
1056 { | 1060 { |
1057 gIR->resolveList.push_back(this); | 1061 gIR->resolveList.push_back(this); |
1058 } | 1062 } |
1063 | |
1064 /* ================================================================== */ | |
1065 | |
1066 void AnonDeclaration::toObjFile(int multiobj) | |
1067 { | |
1068 Array *d = include(NULL, NULL); | |
1069 | |
1070 if (d) | |
1071 { | |
1072 // get real aggregate parent | |
1073 IrStruct* irstruct = gIR->topstruct(); | |
1074 | |
1075 // push a block on the stack | |
1076 irstruct->pushAnon(isunion); | |
1077 | |
1078 // go over children | |
1079 for (unsigned i = 0; i < d->dim; i++) | |
1080 { Dsymbol *s = (Dsymbol *)d->data[i]; | |
1081 s->toObjFile(multiobj); | |
1082 } | |
1083 | |
1084 // finish | |
1085 irstruct->popAnon(); | |
1086 } | |
1087 } |