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 }