LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) { auto linkage = (DtoIsTemplateInstance(sym) ? templateLinkage : LLGlobalValue::ExternalLinkage); // If @(ldc.attributes.weak) is applied, override the linkage to WeakAny if (hasWeakUDA(sym)) { linkage = LLGlobalValue::WeakAnyLinkage; } return {linkage, supportsCOMDAT()}; }
void RTTIBuilder::finalize(LLType *type, LLValue *value) { llvm::ArrayRef<LLConstant *> inits = llvm::makeArrayRef(this->inits); LLStructType *st = isaStruct(type); assert(st); // set struct body if (st->isOpaque()) { const int n = inits.size(); std::vector<LLType *> types; types.reserve(n); for (int i = 0; i < n; ++i) { types.push_back(inits[i]->getType()); } st->setBody(types); } // create the inititalizer LLConstant *tiInit = LLConstantStruct::get(st, inits); // set the initializer llvm::GlobalVariable *gvar = llvm::cast<llvm::GlobalVariable>(value); gvar->setInitializer(tiInit); setLinkage({TYPEINFO_LINKAGE_TYPE, supportsCOMDAT()}, gvar); }
LinkageWithCOMDAT DtoLinkage(Dsymbol* sym) { if (DtoIsTemplateInstance(sym)) return LinkageWithCOMDAT(templateLinkage, supportsCOMDAT()); return LinkageWithCOMDAT(llvm::GlobalValue::ExternalLinkage, false); }
llvm::GlobalVariable *genModuleInfo(Module *m) { // check declaration in object.d const auto moduleInfoType = getModuleInfoType(); const auto moduleInfoDecl = Module::moduleinfo; // The "new-style" ModuleInfo records are variable-length, with the presence // of the various fields indicated by a certain flag bit. The base struct // should consist only of the _flags/_index fields (the latter of which is // unused). if (moduleInfoDecl->structsize != 4 + 4) { m->error("Unexpected size of struct `object.ModuleInfo`; " "druntime version does not match compiler (see -v)"); fatal(); } // First, figure out which fields are present and set the flags accordingly. unsigned flags = MInew; const auto fctor = buildModuleCtor(m); if (fctor) { flags |= MItlsctor; } const auto fdtor = buildModuleDtor(m); if (fdtor) { flags |= MItlsdtor; } const auto fsharedctor = buildModuleSharedCtor(m); if (fsharedctor) { flags |= MIctor; } const auto fshareddtor = buildModuleSharedDtor(m); if (fshareddtor) { flags |= MIdtor; } #if 0 if (fgetmembers) flags |= MIxgetMembers; #endif const auto fictor = getIrModule(m)->coverageCtor; if (fictor) flags |= MIictor; const auto funittest = buildModuleUnittest(m); if (funittest) { flags |= MIunitTest; } size_t importedModulesCount; const auto importedModules = buildImportedModules(m, importedModulesCount); if (importedModules) { flags |= MIimportedModules; } size_t localClassesCount; const auto localClasses = buildLocalClasses(m, localClassesCount); if (localClasses) { flags |= MIlocalClasses; } if (!m->needmoduleinfo) { flags |= MIstandalone; } // Now, start building the initialiser for the ModuleInfo instance. RTTIBuilder b(moduleInfoType); b.push_uint(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); #endif if (fictor) { b.push(fictor); } if (funittest) { b.push(funittest); } if (importedModules) { b.push_size(importedModulesCount); b.push(importedModules); } if (localClasses) { b.push_size(localClassesCount); b.push(localClasses); } // Put out module name as a 0-terminated string. const char *name = m->toPrettyChars(); const size_t len = strlen(name) + 1; const auto it = llvm::IntegerType::getInt8Ty(gIR->context()); const auto at = llvm::ArrayType::get(it, len); b.push(toConstantArray(it, at, name, len, false)); // Create a global symbol with the above initialiser. LLGlobalVariable *moduleInfoSym = getIrModule(m)->moduleInfoSymbol(); b.finalize(moduleInfoSym); setLinkage({LLGlobalValue::ExternalLinkage, supportsCOMDAT()}, moduleInfoSym); return moduleInfoSym; }