void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses) { Dsymbols *d = include(NULL, NULL); if (d) { for (size_t i = 0; i < d->dim; i++) { Dsymbol *s = (*d)[i]; s->addLocalClass(aclasses); } } }
void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses) { Array *d = include(NULL, NULL); if (d) { for (unsigned i = 0; i < d->dim; i++) { Dsymbol *s = (Dsymbol *)d->data[i]; s->addLocalClass(aclasses); } } }
void genModuleInfo(Module *m) { //printf("Module::genmoduleinfo() %s\n", m->toChars()); if (!Module::moduleinfo) { ObjectNotFound(Id::ModuleInfo); } Symbol *msym = toSymbol(m); ////////////////////////////////////////////// m->csym->Sclass = SCglobal; m->csym->Sfl = FLdata; dt_t *dt = NULL; ClassDeclarations aclasses; //printf("members->dim = %d\n", members->dim); for (size_t i = 0; i < m->members->dim; i++) { Dsymbol *member = (*m->members)[i]; //printf("\tmember '%s'\n", member->toChars()); member->addLocalClass(&aclasses); } // importedModules[] size_t aimports_dim = m->aimports.dim; for (size_t i = 0; i < m->aimports.dim; i++) { Module *mod = m->aimports[i]; if (!mod->needmoduleinfo) aimports_dim--; } FuncDeclaration *sgetmembers = m->findGetMembers(); // These must match the values in druntime/src/object_.d #define MIstandalone 0x4 #define MItlsctor 0x8 #define MItlsdtor 0x10 #define MIctor 0x20 #define MIdtor 0x40 #define MIxgetMembers 0x80 #define MIictor 0x100 #define MIunitTest 0x200 #define MIimportedModules 0x400 #define MIlocalClasses 0x800 #define MIname 0x1000 unsigned flags = 0; if (!m->needmoduleinfo) flags |= MIstandalone; if (m->sctor) flags |= MItlsctor; if (m->sdtor) flags |= MItlsdtor; if (m->ssharedctor) flags |= MIctor; if (m->sshareddtor) flags |= MIdtor; if (sgetmembers) flags |= MIxgetMembers; if (m->sictor) flags |= MIictor; if (m->stest) flags |= MIunitTest; if (aimports_dim) flags |= MIimportedModules; if (aclasses.dim) flags |= MIlocalClasses; flags |= MIname; dtdword(&dt, flags); // _flags dtdword(&dt, 0); // _index if (flags & MItlsctor) dtxoff(&dt, m->sctor, 0, TYnptr); if (flags & MItlsdtor) dtxoff(&dt, m->sdtor, 0, TYnptr); if (flags & MIctor) dtxoff(&dt, m->ssharedctor, 0, TYnptr); if (flags & MIdtor) dtxoff(&dt, m->sshareddtor, 0, TYnptr); if (flags & MIxgetMembers) dtxoff(&dt, toSymbol(sgetmembers), 0, TYnptr); if (flags & MIictor) dtxoff(&dt, m->sictor, 0, TYnptr); if (flags & MIunitTest) dtxoff(&dt, m->stest, 0, TYnptr); if (flags & MIimportedModules) { dtsize_t(&dt, aimports_dim); for (size_t i = 0; i < m->aimports.dim; i++) { Module *mod = m->aimports[i]; if (!mod->needmoduleinfo) continue; Symbol *s = toSymbol(mod); /* Weak references don't pull objects in from the library, * they resolve to 0 if not pulled in by something else. * Don't pull in a module just because it was imported. */ s->Sflags |= SFLweak; dtxoff(&dt, s, 0, TYnptr); } } if (flags & MIlocalClasses) { dtsize_t(&dt, aclasses.dim); for (size_t i = 0; i < aclasses.dim; i++) { ClassDeclaration *cd = aclasses[i]; dtxoff(&dt, toSymbol(cd), 0, TYnptr); } } if (flags & MIname) { // Put out module name as a 0-terminated string, to save bytes m->nameoffset = dt_size(dt); const char *name = m->toPrettyChars(); m->namelen = strlen(name); dtnbytes(&dt, m->namelen + 1, name); //printf("nameoffset = x%x\n", nameoffset); } objc_Module_genmoduleinfo_classes(); m->csym->Sdt = dt; out_readonly(m->csym); outdata(m->csym); ////////////////////////////////////////////// objmod->moduleinfo(msym); }
// Put out instance of ModuleInfo for this Module void Module::genmoduleinfo() { // resolve ModuleInfo if (!moduleinfo) { error("object.d is missing the ModuleInfo struct"); fatal(); } // check for patch else { unsigned sizeof_ModuleInfo = 16 * Target::ptrsize; if (sizeof_ModuleInfo != moduleinfo->structsize) { error("object.d ModuleInfo class is incorrect"); fatal(); } } // use the RTTIBuilder RTTIBuilder b(moduleinfo); // some types LLType* moduleinfoTy = moduleinfo->type->irtype->getLLType(); LLType* classinfoTy = ClassDeclaration::classinfo->type->irtype->getLLType(); // importedModules[] std::vector<LLConstant*> importInits; LLConstant* importedModules = 0; llvm::ArrayType* importedModulesTy = 0; for (size_t i = 0; i < aimports.dim; i++) { Module *m = static_cast<Module *>(aimports.data[i]); if (!m->needModuleInfo() || m == this) continue; // declare the imported module info std::string m_name("_D"); m_name.append(m->mangle()); m_name.append("12__ModuleInfoZ"); llvm::GlobalVariable* m_gvar = gIR->module->getGlobalVariable(m_name); if (!m_gvar) m_gvar = new llvm::GlobalVariable(*gIR->module, moduleinfoTy, false, llvm::GlobalValue::ExternalLinkage, NULL, m_name); importInits.push_back(m_gvar); } // has import array? if (!importInits.empty()) { importedModulesTy = llvm::ArrayType::get(getPtrToType(moduleinfoTy), importInits.size()); importedModules = LLConstantArray::get(importedModulesTy, importInits); } // localClasses[] LLConstant* localClasses = 0; llvm::ArrayType* localClassesTy = 0; ClassDeclarations aclasses; //printf("members->dim = %d\n", members->dim); for (size_t i = 0; i < members->dim; i++) { Dsymbol *member; member = static_cast<Dsymbol *>(members->data[i]); //printf("\tmember '%s'\n", member->toChars()); member->addLocalClass(&aclasses); } // fill inits std::vector<LLConstant*> classInits; for (size_t i = 0; i < aclasses.dim; i++) { ClassDeclaration* cd = static_cast<ClassDeclaration*>(aclasses.data[i]); cd->codegen(Type::sir); if (cd->isInterfaceDeclaration()) { Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars()); continue; } else if (cd->sizeok != 1) { Logger::println("skipping opaque class declaration '%s' in moduleinfo", cd->toPrettyChars()); continue; } Logger::println("class: %s", cd->toPrettyChars()); LLConstant *c = DtoBitCast(cd->ir.irAggr->getClassInfoSymbol(), classinfoTy); classInits.push_back(c); } // has class array? if (!classInits.empty()) { localClassesTy = llvm::ArrayType::get(classinfoTy, classInits.size()); localClasses = LLConstantArray::get(localClassesTy, classInits); } // These must match the values in druntime/src/object_.d #define MIstandalone 4 #define MItlsctor 8 #define MItlsdtor 0x10 #define MIctor 0x20 #define MIdtor 0x40 #define MIxgetMembers 0x80 #define MIictor 0x100 #define MIunitTest 0x200 #define MIimportedModules 0x400 #define MIlocalClasses 0x800 #define MInew 0x80000000 // it's the "new" layout llvm::Function* fsharedctor = build_module_shared_ctor(); llvm::Function* fshareddtor = build_module_shared_dtor(); llvm::Function* funittest = build_module_unittest(); llvm::Function* fctor = build_module_ctor(); llvm::Function* fdtor = build_module_dtor(); unsigned flags = MInew; if (fctor) flags |= MItlsctor; if (fdtor) flags |= MItlsdtor; if (fsharedctor) flags |= MIctor; if (fshareddtor) flags |= MIdtor; #if 0 if (fgetmembers) flags |= MIxgetMembers; if (fictor) flags |= MIictor; #endif if (funittest) flags |= MIunitTest; if (importedModules) flags |= MIimportedModules; if (localClasses) flags |= MIlocalClasses; if (!needmoduleinfo) flags |= MIstandalone; b.push_uint(flags); // flags b.push_uint(0); // index if (fctor) b.push(fctor); if (fdtor) b.push(fdtor); if (fsharedctor) b.push(fsharedctor); if (fshareddtor) b.push(fshareddtor); #if 0 if (fgetmembers) b.push(fgetmembers); if (fictor) b.push(fictor); #endif if (funittest) b.push(funittest); if (importedModules) { b.push_size(importInits.size()); b.push(importedModules); } if (localClasses) { b.push_size(classInits.size()); b.push(localClasses); } // Put out module name as a 0-terminated string. const char *name = toPrettyChars(); const size_t len = strlen(name) + 1; llvm::IntegerType *it = llvm::IntegerType::getInt8Ty(gIR->context()); llvm::ArrayType *at = llvm::ArrayType::get(it, len); b.push(toConstantArray(it, at, name, len, false)); // create and set initializer b.finalize(moduleInfoType, moduleInfoSymbol()); // build the modulereference and ctor for registering it LLFunction* mictor = build_module_reference_and_ctor(moduleInfoSymbol()); AppendFunctionToLLVMGlobalCtorsDtors(mictor, 65535, true); }