Mercurial > projects > ldc
diff gen/toobj.cpp @ 116:fd7ad91fd713 trunk
[svn r120] ModuleInfo implementation is now almost complete.
Fixed some nasty static array-initializer bugs.
Fixed bug in DtoArrayLen and DtoArrayPtr for full slices of static arrays.
author | lindquist |
---|---|
date | Sun, 25 Nov 2007 18:55:52 +0100 |
parents | 5ba6d286c941 |
children | 56a21f3e5d3e |
line wrap: on
line diff
--- a/gen/toobj.cpp Sun Nov 25 03:58:55 2007 +0100 +++ b/gen/toobj.cpp Sun Nov 25 18:55:52 2007 +0100 @@ -106,36 +106,11 @@ } // main driver loop - for(;;) - { - Dsymbol* dsym; - if (!ir.resolveList.empty()) { - dsym = ir.resolveList.front(); - ir.resolveList.pop_front(); - DtoResolveDsymbol(dsym); - } - else if (!ir.declareList.empty()) { - dsym = ir.declareList.front(); - ir.declareList.pop_front(); - DtoDeclareDsymbol(dsym); - } - else if (!ir.constInitList.empty()) { - dsym = ir.constInitList.front(); - ir.constInitList.pop_front(); - DtoConstInitDsymbol(dsym); - } - else if (!ir.defineList.empty()) { - dsym = ir.defineList.front(); - ir.defineList.pop_front(); - DtoDefineDsymbol(dsym); - } - else { - break; - } - } - + DtoEmptyAllLists(); // generate ModuleInfo genmoduleinfo(); + // do this again as moduleinfo might have pulled something in! + DtoEmptyAllLists(); gTargetData = 0; @@ -181,6 +156,72 @@ /* ================================================================== */ +// build module ctor + +static llvm::Function* build_module_ctor() +{ + if (gIR->ctors.empty()) + return NULL; + + size_t n = gIR->ctors.size(); + if (n == 1) + return llvm::cast<llvm::Function>(gIR->ctors[0]->llvmValue); + + std::string name("_D"); + name.append(gIR->dmodule->mangle()); + name.append("6__ctorZ"); + + std::vector<const llvm::Type*> argsTy; + const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false); + llvm::Function* fn = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); + fn->setCallingConv(llvm::CallingConv::Fast); + + llvm::BasicBlock* bb = new llvm::BasicBlock("entry", fn); + LLVMBuilder builder(bb); + + for (size_t i=0; i<n; i++) { + llvm::Function* f = llvm::cast<llvm::Function>(gIR->ctors[i]->llvmValue); + llvm::CallInst* call = builder.CreateCall(f,""); + call->setCallingConv(llvm::CallingConv::Fast); + } + + builder.CreateRetVoid(); + return fn; +} + +// build module dtor + +static llvm::Function* build_module_dtor() +{ + if (gIR->dtors.empty()) + return NULL; + + size_t n = gIR->dtors.size(); + if (n == 1) + return llvm::cast<llvm::Function>(gIR->dtors[0]->llvmValue); + + std::string name("_D"); + name.append(gIR->dmodule->mangle()); + name.append("6__dtorZ"); + + std::vector<const llvm::Type*> argsTy; + const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false); + llvm::Function* fn = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module); + fn->setCallingConv(llvm::CallingConv::Fast); + + llvm::BasicBlock* bb = new llvm::BasicBlock("entry", fn); + LLVMBuilder builder(bb); + + for (size_t i=0; i<n; i++) { + llvm::Function* f = llvm::cast<llvm::Function>(gIR->dtors[i]->llvmValue); + llvm::CallInst* call = builder.CreateCall(f,""); + call->setCallingConv(llvm::CallingConv::Fast); + } + + builder.CreateRetVoid(); + return fn; +} + // Put out instance of ModuleInfo for this Module void Module::genmoduleinfo() @@ -198,139 +239,131 @@ // void *unitTest; // } - if (moduleinfo) { - Logger::println("moduleinfo"); - } - if (vmoduleinfo) { - Logger::println("vmoduleinfo"); - } - if (needModuleInfo()) { - Logger::attention("module info is needed but skipped"); - } + // resolve ModuleInfo + assert(moduleinfo); + DtoForceConstInitDsymbol(moduleinfo); + // moduleinfo llvm struct type + const llvm::StructType* moduleinfoTy = isaStruct(moduleinfo->type->llvmType->get()); - /* - Symbol *msym = toSymbol(); - unsigned offset; - unsigned sizeof_ModuleInfo = 12 * PTRSIZE; - - ////////////////////////////////////////////// - - csym->Sclass = SCglobal; - csym->Sfl = FLdata; + // classinfo llvm struct type + const llvm::StructType* classinfoTy = isaStruct(ClassDeclaration::classinfo->type->llvmType->get()); -// The layout is: -// { -// void **vptr; -// monitor_t monitor; -// char[] name; // class name -// ModuleInfo importedModules[]; -// ClassInfo localClasses[]; -// uint flags; // initialization state -// void *ctor; -// void *dtor; -// void *unitTest; -// } - dt_t *dt = NULL; + // initializer vector + std::vector<llvm::Constant*> initVec; + llvm::Constant* c = 0; + + // vtable + c = moduleinfo->llvmVtbl; + initVec.push_back(c); - if (moduleinfo) - dtxoff(&dt, moduleinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ModuleInfo - else - dtdword(&dt, 0); // BUG: should be an assert() - dtdword(&dt, 0); // monitor - - // name[] - char *name = toPrettyChars(); - size_t namelen = strlen(name); - dtdword(&dt, namelen); - dtabytes(&dt, TYnptr, 0, namelen + 1, name); + // monitor + c = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); + initVec.push_back(c); - ClassDeclarations aclasses; - int i; - - //printf("members->dim = %d\n", members->dim); - for (i = 0; i < members->dim; i++) - { - Dsymbol *member; - - member = (Dsymbol *)members->data[i]; - //printf("\tmember '%s'\n", member->toChars()); - member->addLocalClass(&aclasses); - } + // name + char *name = toPrettyChars(); + c = DtoConstString(name); + initVec.push_back(c); // importedModules[] int aimports_dim = aimports.dim; - for (i = 0; i < aimports.dim; i++) - { Module *m = (Module *)aimports.data[i]; - if (!m->needModuleInfo()) - aimports_dim--; + std::vector<llvm::Constant*> importInits; + for (size_t i = 0; i < aimports.dim; i++) + { + Module *m = (Module *)aimports.data[i]; + if (!m->needModuleInfo()) + aimports_dim--; + else { // declare + // create name + std::string m_name("_D"); + m_name.append(m->mangle()); + m_name.append("8__ModuleZ"); + llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name, gIR->module); + importInits.push_back(m_gvar); + } } - dtdword(&dt, aimports_dim); - if (aimports.dim) - dtxoff(&dt, csym, sizeof_ModuleInfo, TYnptr); + // has import array? + if (!importInits.empty()) { + const llvm::ArrayType* importArrTy = llvm::ArrayType::get(llvm::PointerType::get(moduleinfoTy), importInits.size()); + c = llvm::ConstantArray::get(importArrTy, importInits); + std::string m_name("_D"); + m_name.append(mangle()); + m_name.append("9__importsZ"); + llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(importArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module); + c = llvm::ConstantExpr::getBitCast(m_gvar, llvm::PointerType::get(importArrTy->getElementType())); + c = DtoConstSlice(DtoConstSize_t(importInits.size()), c); + } else - dtdword(&dt, 0); + c = moduleinfo->llvmInitZ->getOperand(3); + initVec.push_back(c); // localClasses[] - dtdword(&dt, aclasses.dim); - if (aclasses.dim) - dtxoff(&dt, csym, sizeof_ModuleInfo + aimports_dim * PTRSIZE, TYnptr); - else - dtdword(&dt, 0); - - if (needmoduleinfo) - dtdword(&dt, 0); // flags (4 means MIstandalone) - else - dtdword(&dt, 4); // flags (4 means MIstandalone) + ClassDeclarations aclasses; + //printf("members->dim = %d\n", members->dim); + for (size_t i = 0; i < members->dim; i++) + { + Dsymbol *member; - if (sctor) - dtxoff(&dt, sctor, 0, TYnptr); - else - dtdword(&dt, 0); - - if (sdtor) - dtxoff(&dt, sdtor, 0, TYnptr); - else - dtdword(&dt, 0); - - if (stest) - dtxoff(&dt, stest, 0, TYnptr); - else - dtdword(&dt, 0); - - ////////////////////////////////////////////// - - for (i = 0; i < aimports.dim; i++) + member = (Dsymbol *)members->data[i]; + //printf("\tmember '%s'\n", member->toChars()); + member->addLocalClass(&aclasses); + } + // fill inits + std::vector<llvm::Constant*> classInits; + for (size_t i = 0; i < aclasses.dim; i++) { - Module *m; + ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i]; + assert(cd->llvmClass); + classInits.push_back(cd->llvmClass); + } + // has class array? + if (!classInits.empty()) { + const llvm::ArrayType* classArrTy = llvm::ArrayType::get(llvm::PointerType::get(classinfoTy), classInits.size()); + c = llvm::ConstantArray::get(classArrTy, classInits); + std::string m_name("_D"); + m_name.append(mangle()); + m_name.append("9__classesZ"); + llvm::GlobalVariable* m_gvar = new llvm::GlobalVariable(classArrTy, true, llvm::GlobalValue::InternalLinkage, c, m_name, gIR->module); + c = llvm::ConstantExpr::getBitCast(m_gvar, llvm::PointerType::get(classArrTy->getElementType())); + c = DtoConstSlice(DtoConstSize_t(classInits.size()), c); + } + else + c = moduleinfo->llvmInitZ->getOperand(4); + initVec.push_back(c); - m = (Module *)aimports.data[i]; - if (m->needModuleInfo()) - { Symbol *s = m->toSymbol(); - s->Sflags |= SFLweak; - dtxoff(&dt, s, 0, TYnptr); - } - } - - for (i = 0; i < aclasses.dim; i++) - { - ClassDeclaration *cd; + // flags + if (needmoduleinfo) + c = DtoConstUint(0); // flags (4 means MIstandalone) + else + c = DtoConstUint(4); // flags (4 means MIstandalone) + initVec.push_back(c); - cd = (ClassDeclaration *)aclasses.data[i]; - dtxoff(&dt, cd->toSymbol(), 0, TYnptr); - } + // ctor + llvm::Function* fctor = build_module_ctor(); + c = fctor ? fctor : moduleinfo->llvmInitZ->getOperand(6); + initVec.push_back(c); + + // dtor + llvm::Function* fdtor = build_module_dtor(); + c = fdtor ? fdtor : moduleinfo->llvmInitZ->getOperand(7); + initVec.push_back(c); - csym->Sdt = dt; -#if ELFOBJ - // Cannot be CONST because the startup code sets flag bits in it - csym->Sseg = DATA; -#endif - outdata(csym); + // unitTest + c = moduleinfo->llvmInitZ->getOperand(8); + initVec.push_back(c); + + // create initializer + llvm::Constant* constMI = llvm::ConstantStruct::get(moduleinfoTy, initVec); - ////////////////////////////////////////////// + // create name + std::string MIname("_D"); + MIname.append(mangle()); + MIname.append("8__ModuleZ"); - obj_moduleinfo(msym); - */ + // declare + // flags will be modified at runtime so can't make it constant + llvm::GlobalVariable* gvar = new llvm::GlobalVariable(moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, constMI, MIname, gIR->module); } /* ================================================================== */