diff --git a/dmd2/module.c b/dmd2/module.c index 135b8571..a957e11c 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -936,6 +936,28 @@ void Module::semantic(Scope* unused_sc) } #endif +#if IN_LLVM + // If this is a root module (i.e. one we generate an object file for), + // make sure all template instances created as part of semantic analysis + // of this module are actually emitted during codegen for this module, and + // not while generating another random module that happened to import a + // given module "first" (the frontend usually only sets importedFrom once). + // This is especially important for LDC, as we base the decision of whether + // to actually emit code for a declaration (mustDefineSymbol) on whether + // the module being codegen'ed is the module the symbol was defined in. + if (importedFrom == this) + { + for (size_t i = 0; i < members->dim; i++) + { + Import *s = (*members)[i]->isImport(); + if (s) + { + s->mod->updateImportedFrom(this); + } + } + } +#endif + // Do semantic() on members that don't depend on others for (size_t i = 0; i < members->dim; i++) { Dsymbol *s = (*members)[i]; @@ -1260,6 +1282,26 @@ int Module::selfImports() } +#if IN_LLVM +void Module::updateImportedFrom(Module *newRoot) +{ + // If this is also a root, there is nothing to do. + if (importedFrom == this || importedFrom == newRoot) + return; + + importedFrom = newRoot; + for (size_t i = 0; i < members->dim; i++) + { + Import *s = (*members)[i]->isImport(); + if (s) + { + s->mod->updateImportedFrom(newRoot); + } + } +} +#endif + + /* =========================== ModuleDeclaration ===================== */ ModuleDeclaration::ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe) diff --git a/dmd2/module.h b/dmd2/module.h index 71730021..f59285af 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -196,7 +196,10 @@ struct Module : Package void genmoduleinfo(); #if IN_LLVM - // LDC + /// Recursively sets the importedFrom field of any non-root modules + /// imported by this (including the module itself) to the given module. + void updateImportedFrom(Module *newRoot); + llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir); void buildTargetFiles(bool singleObj); File* buildFilePath(const char* forcename, const char* path, const char* ext);