diff --git a/compiler/src/dmd/dimport.d b/compiler/src/dmd/dimport.d index 2efdd31bbba0..0626c5a8fba7 100644 --- a/compiler/src/dmd/dimport.d +++ b/compiler/src/dmd/dimport.d @@ -41,6 +41,8 @@ extern (C++) final class Import : Dsymbol // corresponding AliasDeclarations for alias=name pairs AliasDeclarations aliasdecls; + bool forceCodegen; // whether codegen should be forced for the imported module + extern (D) this(const ref Loc loc, Identifier[] packages, Identifier id, Identifier aliasId, int isstatic) { Identifier selectIdent() diff --git a/compiler/src/dmd/dmodule.d b/compiler/src/dmd/dmodule.d index a1a337bd3a52..f512d4e67b44 100644 --- a/compiler/src/dmd/dmodule.d +++ b/compiler/src/dmd/dmodule.d @@ -362,6 +362,7 @@ extern (C++) final class Module : Package Package pkg; // if isPackageFile is true, the Package that contains this package.d Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; + bool forceCodegen; // if codegen should take place for this module, even if it normally wouldn't private ThreeState selfimports; private ThreeState rootimports; Dsymbol[void*] tagSymTab; /// ImportC: tag symbols that conflict with other symbols used as the index diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index 65a1b0436502..c9780447666c 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -7020,8 +7020,16 @@ extern (D) bool load(Import imp, Scope* sc) dst.insert(imp.id, imp.mod); } } - if (imp.mod && !imp.mod.importedFrom) - imp.mod.importedFrom = sc ? sc._module.importedFrom : Module.rootModule; + if (imp.mod) + { + if (imp.forceCodegen) + imp.mod.forceCodegen = true; + // if codegen is forced, promote imp.mod to a root module, so that codegen takes place + if (imp.mod.forceCodegen) + imp.mod.importedFrom = imp.mod; + else if (!imp.mod.importedFrom) + imp.mod.importedFrom = sc ? sc._module.importedFrom : Module.rootModule; + } if (!imp.pkg) { if (imp.mod && imp.mod.isPackageFile) diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index a208add26a6f..65ed0b545a2b 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -7032,6 +7032,7 @@ class Import final : public Dsymbol Module* mod; Package* pkg; Array aliasdecls; + bool forceCodegen; const char* kind() const override; Visibility visible() override; Import* syntaxCopy(Dsymbol* s) override; @@ -7086,6 +7087,7 @@ class Module final : public Package Package* pkg; Array contentImportedFiles; int32_t needmoduleinfo; + bool forceCodegen; private: ThreeState selfimports; ThreeState rootimports; diff --git a/compiler/src/dmd/main.d b/compiler/src/dmd/main.d index 0485b191aa5c..0f5323779a2d 100644 --- a/compiler/src/dmd/main.d +++ b/compiler/src/dmd/main.d @@ -577,6 +577,22 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params) } } Module.runDeferredSemantic3(); + + // Ensure codegen is performed for modules where codegen is forced + for (size_t i = 0; i < Module.amodules.length; ++i) + { + auto m = Module.amodules[i]; + if (m.forceCodegen && m.semanticRun != PASS.semantic3done) + { + assert(m.isRoot()); + if (params.v.verbose) + message("semantic3 %s", m.toChars()); + m.semantic3(null); + modules.push(m); + } + } + Module.runDeferredSemantic3(); + if (global.errors) removeHdrFilesAndFail(params, modules);