@@ -314,7 +314,9 @@ class ModuleDecl
314314 // FIXME: Do we really need to bloat all modules with this?
315315 DebuggerClient *DebugClient = nullptr ;
316316
317- SmallVector<FileUnit *, 2 > Files;
317+ // / The list of files in the module. This is guaranteed to be set once module
318+ // / construction has completed. It must not be mutated afterwards.
319+ std::optional<SmallVector<FileUnit *, 2 >> Files;
318320
319321 llvm::SmallDenseMap<Identifier, SmallVector<OverlayFile *, 1 >>
320322 declaredCrossImports;
@@ -359,24 +361,55 @@ class ModuleDecl
359361 // / Used by the debugger to bypass resilient access to fields.
360362 bool BypassResilience = false ;
361363
362- ModuleDecl (Identifier name, ASTContext &ctx, ImplicitImportInfo importInfo);
364+ public:
365+ using PopulateFilesFn = llvm::function_ref<void (
366+ ModuleDecl *, llvm::function_ref<void (FileUnit *)>)>;
367+
368+ private:
369+ ModuleDecl (Identifier name, ASTContext &ctx, ImplicitImportInfo importInfo,
370+ PopulateFilesFn populateFiles, bool isMainModule);
363371
364372public:
365373 // / Creates a new module with a given \p name.
366374 // /
367375 // / \param importInfo Information about which modules should be implicitly
368376 // / imported by each file of this module.
369- static ModuleDecl *
370- create (Identifier name, ASTContext &ctx,
371- ImplicitImportInfo importInfo = ImplicitImportInfo()) {
372- return new (ctx) ModuleDecl (name, ctx, importInfo);
377+ // / \param populateFiles A function which populates the files for the module.
378+ // / Once called, the module's list of files may not change.
379+ static ModuleDecl *create (Identifier name, ASTContext &ctx,
380+ ImplicitImportInfo importInfo,
381+ PopulateFilesFn populateFiles) {
382+ return new (ctx) ModuleDecl (name, ctx, importInfo, populateFiles,
383+ /* isMainModule*/ false );
384+ }
385+
386+ // / Creates a new module with a given \p name.
387+ // /
388+ // / \param populateFiles A function which populates the files for the module.
389+ // / Once called, the module's list of files may not change.
390+ static ModuleDecl *create (Identifier name, ASTContext &ctx,
391+ PopulateFilesFn populateFiles) {
392+ return new (ctx) ModuleDecl (name, ctx, ImplicitImportInfo (), populateFiles,
393+ /* isMainModule*/ false );
373394 }
374395
396+ // / Creates a new main module with a given \p name. The main module is the
397+ // / module being built by the compiler, containing the primary source files.
398+ // /
399+ // / \param importInfo Information about which modules should be implicitly
400+ // / imported by each file of this module.
401+ // / \param populateFiles A function which populates the files for the module.
402+ // / Once called, the module's list of files may not change.
375403 static ModuleDecl *createMainModule (ASTContext &ctx, Identifier name,
376- ImplicitImportInfo iinfo) {
377- auto *Mod = ModuleDecl::create (name, ctx, iinfo);
378- Mod->Bits .ModuleDecl .IsMainModule = true ;
379- return Mod;
404+ ImplicitImportInfo iinfo,
405+ PopulateFilesFn populateFiles) {
406+ return new (ctx) ModuleDecl (name, ctx, iinfo, populateFiles,
407+ /* isMainModule*/ true );
408+ }
409+
410+ // / Creates an empty module with a given \p name.
411+ static ModuleDecl *createEmpty (Identifier name, ASTContext &ctx) {
412+ return create (name, ctx, ImplicitImportInfo (), [](auto , auto ) {});
380413 }
381414
382415 using Decl::getASTContext;
@@ -398,24 +431,11 @@ class ModuleDecl
398431 // / Only to be called by MemoryBufferSerializedModuleLoader.
399432 void setBypassResilience () { BypassResilience = true ; }
400433
401- ArrayRef<FileUnit *> getFiles () {
402- ASSERT (!Files.empty () || failedToLoad ());
403- return Files;
434+ ArrayRef<FileUnit *> getFiles () const {
435+ ASSERT (Files.has_value () &&
436+ " Attempting to query files before setting them" );
437+ return *Files;
404438 }
405- ArrayRef<const FileUnit *> getFiles () const {
406- return { Files.begin (), Files.size () };
407- }
408-
409- // / Add the given file to this module.
410- // /
411- // / FIXME: Remove this function from public view. Modules never need to add
412- // / files once they are created.
413- // /
414- // / \warning There are very few safe points to call this function once a
415- // / \c ModuleDecl has been created. If you find yourself needing to insert
416- // / a file in the middle of e.g. semantic analysis, use a \c
417- // / SynthesizedFileUnit instead.
418- void addFile (FileUnit &newFile);
419439
420440 // / Produces the source file that contains the given source location, or
421441 // / \c nullptr if the source location isn't in this module.
0 commit comments