https://github.com/jansvoboda11 created https://github.com/llvm/llvm-project/pull/134887
This PR extracts the creation of `CompilerInstance` for compiling an implicitly-discovered module out of `compileModuleImpl()` into its own separate function and passes it into `compileModuleImpl()` from the outside. This makes the instance creation logic reusable (useful for my experiments) and also simplifies the API, removing the `PreBuildStep` and `PostBuildStep` hooks from `compileModuleImpl()`. >From a41ba702f42671f7e9c51c29a846a6c7c7324378 Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Mon, 7 Apr 2025 13:30:28 -0700 Subject: [PATCH 1/3] [clang] Extract `CompilerInstance` creation out of `compileModuleImpl()` --- clang/lib/Frontend/CompilerInstance.cpp | 68 +++++++++++++++---------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 9cab17ae70eeb..126398fd6e765 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1150,29 +1150,10 @@ static Language getLanguageFromOptions(const LangOptions &LangOpts) { return LangOpts.CPlusPlus ? Language::CXX : Language::C; } -/// Compile a module file for the given module, using the options -/// provided by the importing compiler instance. Returns true if the module -/// was built without errors. -static bool -compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, - StringRef ModuleName, FrontendInputFile Input, - StringRef OriginalModuleMapFile, StringRef ModuleFileName, - llvm::function_ref<void(CompilerInstance &)> PreBuildStep = - [](CompilerInstance &) {}, - llvm::function_ref<void(CompilerInstance &)> PostBuildStep = - [](CompilerInstance &) {}) { - llvm::TimeTraceScope TimeScope("Module Compile", ModuleName); - - // Never compile a module that's already finalized - this would cause the - // existing module to be freed, causing crashes if it is later referenced - if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal( - ModuleFileName)) { - ImportingInstance.getDiagnostics().Report( - ImportLoc, diag::err_module_rebuild_finalized) - << ModuleName; - return false; - } - +static std::unique_ptr<CompilerInstance> createCompilerInstanceForModuleCompile( + CompilerInstance &ImportingInstance, SourceLocation ImportLoc, + StringRef ModuleName, FrontendInputFile Input, + StringRef OriginalModuleMapFile, StringRef ModuleFileName) { // Construct a compiler invocation for creating this module. auto Invocation = std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation()); @@ -1226,8 +1207,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, // module. Since we're sharing an in-memory module cache, // CompilerInstance::CompilerInstance is responsible for finalizing the // buffers to prevent use-after-frees. - CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), - &ImportingInstance.getModuleCache()); + auto InstancePtr = std::make_unique<CompilerInstance>( + ImportingInstance.getPCHContainerOperations(), + &ImportingInstance.getModuleCache()); + auto &Instance = *InstancePtr; + auto &Inv = *Invocation; Instance.setInvocation(std::move(Invocation)); @@ -1267,6 +1251,38 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); Inv.getDependencyOutputOpts() = DependencyOutputOptions(); + return InstancePtr; +} + +/// Compile a module file for the given module, using the options +/// provided by the importing compiler instance. Returns true if the module +/// was built without errors. +static bool +compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, + StringRef ModuleName, FrontendInputFile Input, + StringRef OriginalModuleMapFile, StringRef ModuleFileName, + llvm::function_ref<void(CompilerInstance &)> PreBuildStep = + [](CompilerInstance &) {}, + llvm::function_ref<void(CompilerInstance &)> PostBuildStep = + [](CompilerInstance &) {}) { + llvm::TimeTraceScope TimeScope("Module Compile", ModuleName); + + // Never compile a module that's already finalized - this would cause the + // existing module to be freed, causing crashes if it is later referenced + if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal( + ModuleFileName)) { + ImportingInstance.getDiagnostics().Report( + ImportLoc, diag::err_module_rebuild_finalized) + << ModuleName; + return false; + } + + std::unique_ptr<CompilerInstance> InstancePtr = + createCompilerInstanceForModuleCompile( + ImportingInstance, ImportLoc, ModuleName, Input, + OriginalModuleMapFile, ModuleFileName); + CompilerInstance &Instance = *InstancePtr; + ImportingInstance.getDiagnostics().Report(ImportLoc, diag::remark_module_build) << ModuleName << ModuleFileName; @@ -1289,7 +1305,7 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, << ModuleName; // Propagate the statistics to the parent FileManager. - if (!FrontendOpts.ModulesShareFileManager) + if (ImportingInstance.getFileManagerPtr() != Instance.getFileManagerPtr()) ImportingInstance.getFileManager().AddStats(Instance.getFileManager()); if (Crashed) { >From e5f448d78557625d27d8194f88b24d15c2f9ed77 Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Mon, 7 Apr 2025 14:43:43 -0700 Subject: [PATCH 2/3] [clang] Pass `CompilerInstance` instance into `compileModuleImpl()` from the outside --- clang/lib/Frontend/CompilerInstance.cpp | 109 +++++++++++------------- 1 file changed, 50 insertions(+), 59 deletions(-) diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 126398fd6e765..5ebee46a1116d 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1257,38 +1257,16 @@ static std::unique_ptr<CompilerInstance> createCompilerInstanceForModuleCompile( /// Compile a module file for the given module, using the options /// provided by the importing compiler instance. Returns true if the module /// was built without errors. -static bool -compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, - StringRef ModuleName, FrontendInputFile Input, - StringRef OriginalModuleMapFile, StringRef ModuleFileName, - llvm::function_ref<void(CompilerInstance &)> PreBuildStep = - [](CompilerInstance &) {}, - llvm::function_ref<void(CompilerInstance &)> PostBuildStep = - [](CompilerInstance &) {}) { +static bool compileModuleImpl(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, StringRef ModuleName, + StringRef ModuleFileName, + CompilerInstance &Instance) { llvm::TimeTraceScope TimeScope("Module Compile", ModuleName); - // Never compile a module that's already finalized - this would cause the - // existing module to be freed, causing crashes if it is later referenced - if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal( - ModuleFileName)) { - ImportingInstance.getDiagnostics().Report( - ImportLoc, diag::err_module_rebuild_finalized) - << ModuleName; - return false; - } - - std::unique_ptr<CompilerInstance> InstancePtr = - createCompilerInstanceForModuleCompile( - ImportingInstance, ImportLoc, ModuleName, Input, - OriginalModuleMapFile, ModuleFileName); - CompilerInstance &Instance = *InstancePtr; - ImportingInstance.getDiagnostics().Report(ImportLoc, diag::remark_module_build) << ModuleName << ModuleFileName; - PreBuildStep(Instance); - // Execute the action to actually build the module in-place. Use a separate // thread so that we get a stack large enough. bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread( @@ -1298,8 +1276,6 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, }, DesiredStackSize); - PostBuildStep(Instance); - ImportingInstance.getDiagnostics().Report(ImportLoc, diag::remark_module_build_done) << ModuleName; @@ -1343,6 +1319,18 @@ static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, static bool compileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName) { + StringRef ModuleName = Module->getTopLevelModuleName(); + + // Never compile a module that's already finalized - this would cause the + // existing module to be freed, causing crashes if it is later referenced + if (ImportingInstance.getModuleCache().getInMemoryModuleCache().isPCMFinal( + ModuleFileName)) { + ImportingInstance.getDiagnostics().Report( + ImportLoc, diag::err_module_rebuild_finalized) + << ModuleName; + return false; + } + InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()), InputKind::ModuleMap); @@ -1350,7 +1338,8 @@ static bool compileModule(CompilerInstance &ImportingInstance, ModuleMap &ModMap = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); SourceManager &SourceMgr = ImportingInstance.getSourceManager(); - bool Result; + + std::unique_ptr<CompilerInstance> Instance; if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module); ModuleMapFID.isValid()) { // We want to use the top-level module map. If we don't, the compiling @@ -1384,8 +1373,8 @@ static bool compileModule(CompilerInstance &ImportingInstance, bool IsSystem = isSystem(SLoc.getFile().getFileCharacteristic()); // Use the module map where this module resides. - Result = compileModuleImpl( - ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), + Instance = createCompilerInstanceForModuleCompile( + ImportingInstance, ImportLoc, ModuleName, FrontendInputFile(ModuleMapFilePath, IK, IsSystem), ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); } else { @@ -1400,28 +1389,29 @@ static bool compileModule(CompilerInstance &ImportingInstance, llvm::raw_string_ostream OS(InferredModuleMapContent); Module->print(OS); - Result = compileModuleImpl( - ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), + Instance = createCompilerInstanceForModuleCompile( + ImportingInstance, ImportLoc, ModuleName, FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem), - ModMap.getModuleMapFileForUniquing(Module)->getName(), - ModuleFileName, - [&](CompilerInstance &Instance) { - std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = - llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); - FileEntryRef ModuleMapFile = Instance.getFileManager().getVirtualFileRef( - FakeModuleMapFile, InferredModuleMapContent.size(), 0); - Instance.getSourceManager().overrideFileContents( - ModuleMapFile, std::move(ModuleMapBuffer)); - }); + ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); + + std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = + llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent); + FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef( + FakeModuleMapFile, InferredModuleMapContent.size(), 0); + Instance->getSourceManager().overrideFileContents( + ModuleMapFile, std::move(ModuleMapBuffer)); } + bool Success = compileModuleImpl(ImportingInstance, ImportLoc, ModuleName, + ModuleFileName, *Instance); + // We've rebuilt a module. If we're allowed to generate or update the global // module index, record that fact in the importing compiler instance. if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { ImportingInstance.setBuildGlobalModuleIndex(true); } - return Result; + return Success; } /// Read the AST right after compiling the module. @@ -2248,25 +2238,26 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc, std::string NullTerminatedSource(Source.str()); - auto PreBuildStep = [&](CompilerInstance &Other) { - // Create a virtual file containing our desired source. - // FIXME: We shouldn't need to do this. - FileEntryRef ModuleMapFile = Other.getFileManager().getVirtualFileRef( - ModuleMapFileName, NullTerminatedSource.size(), 0); - Other.getSourceManager().overrideFileContents( - ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource)); + auto Other = createCompilerInstanceForModuleCompile( + *this, ImportLoc, ModuleName, Input, StringRef(), ModuleFileName); - Other.BuiltModules = std::move(BuiltModules); - Other.DeleteBuiltModules = false; - }; + // Create a virtual file containing our desired source. + // FIXME: We shouldn't need to do this. + FileEntryRef ModuleMapFile = Other->getFileManager().getVirtualFileRef( + ModuleMapFileName, NullTerminatedSource.size(), 0); + Other->getSourceManager().overrideFileContents( + ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource)); - auto PostBuildStep = [this](CompilerInstance &Other) { - BuiltModules = std::move(Other.BuiltModules); - }; + Other->BuiltModules = std::move(BuiltModules); + Other->DeleteBuiltModules = false; // Build the module, inheriting any modules that we've built locally. - if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(), - ModuleFileName, PreBuildStep, PostBuildStep)) { + bool Success = + compileModuleImpl(*this, ImportLoc, ModuleName, ModuleFileName, *Other); + + BuiltModules = std::move(Other->BuiltModules); + + if (Success) { BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName); llvm::sys::RemoveFileOnSignal(ModuleFileName); } >From 5bc798d2924d3c7f844d76c034f40901312ac379 Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Tue, 8 Apr 2025 10:24:00 -0700 Subject: [PATCH 3/3] [clang] Also extract the `FrontendInputFile` logic --- clang/lib/Frontend/CompilerInstance.cpp | 221 +++++++++++++----------- 1 file changed, 121 insertions(+), 100 deletions(-) diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 5ebee46a1116d..62fff9e2397a1 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1138,22 +1138,16 @@ void CompilerInstance::LoadRequestedPlugins() { } } -/// Determine the appropriate source input kind based on language -/// options. -static Language getLanguageFromOptions(const LangOptions &LangOpts) { - if (LangOpts.OpenCL) - return Language::OpenCL; - if (LangOpts.CUDA) - return Language::CUDA; - if (LangOpts.ObjC) - return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC; - return LangOpts.CPlusPlus ? Language::CXX : Language::C; -} - -static std::unique_ptr<CompilerInstance> createCompilerInstanceForModuleCompile( - CompilerInstance &ImportingInstance, SourceLocation ImportLoc, - StringRef ModuleName, FrontendInputFile Input, - StringRef OriginalModuleMapFile, StringRef ModuleFileName) { +/// Creates a \c CompilerInstance for compiling a module. +/// +/// This expects a properly initialized \c FrontendInputFile. +static std::unique_ptr<CompilerInstance> +createCompilerInstanceForModuleCompileImpl(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, + StringRef ModuleName, + FrontendInputFile Input, + StringRef OriginalModuleMapFile, + StringRef ModuleFileName) { // Construct a compiler invocation for creating this module. auto Invocation = std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation()); @@ -1254,6 +1248,114 @@ static std::unique_ptr<CompilerInstance> createCompilerInstanceForModuleCompile( return InstancePtr; } +/// Determine the appropriate source input kind based on language +/// options. +static Language getLanguageFromOptions(const LangOptions &LangOpts) { + if (LangOpts.OpenCL) + return Language::OpenCL; + if (LangOpts.CUDA) + return Language::CUDA; + if (LangOpts.ObjC) + return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC; + return LangOpts.CPlusPlus ? Language::CXX : Language::C; +} + +static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, + FileManager &FileMgr) { + StringRef Filename = llvm::sys::path::filename(File.getName()); + SmallString<128> PublicFilename(File.getDir().getName()); + if (Filename == "module_private.map") + llvm::sys::path::append(PublicFilename, "module.map"); + else if (Filename == "module.private.modulemap") + llvm::sys::path::append(PublicFilename, "module.modulemap"); + else + return std::nullopt; + return FileMgr.getOptionalFileRef(PublicFilename); +} + +/// Creates a \c CompilerInstance for compiling a module. +/// +/// This takes care of creating appropriate \c FrontendInputFile for +/// public/private frameworks, inferred modules and such. +static std::unique_ptr<CompilerInstance> +createCompilerInstanceForModuleCompile(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, Module *Module, + StringRef ModuleFileName) { + StringRef ModuleName = Module->getTopLevelModuleName(); + + InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()), + InputKind::ModuleMap); + + // Get or create the module map that we'll use to build this module. + ModuleMap &ModMap = + ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); + SourceManager &SourceMgr = ImportingInstance.getSourceManager(); + + if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module); + ModuleMapFID.isValid()) { + // We want to use the top-level module map. If we don't, the compiling + // instance may think the containing module map is a top-level one, while + // the importing instance knows it's included from a parent module map via + // the extern directive. This mismatch could bite us later. + SourceLocation Loc = SourceMgr.getIncludeLoc(ModuleMapFID); + while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) { + ModuleMapFID = SourceMgr.getFileID(Loc); + Loc = SourceMgr.getIncludeLoc(ModuleMapFID); + } + + OptionalFileEntryRef ModuleMapFile = + SourceMgr.getFileEntryRefForID(ModuleMapFID); + assert(ModuleMapFile && "Top-level module map with no FileID"); + + // Canonicalize compilation to start with the public module map. This is + // vital for submodules declarations in the private module maps to be + // correctly parsed when depending on a top level module in the public one. + if (OptionalFileEntryRef PublicMMFile = getPublicModuleMap( + *ModuleMapFile, ImportingInstance.getFileManager())) + ModuleMapFile = PublicMMFile; + + StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested(); + + // Use the systemness of the module map as parsed instead of using the + // IsSystem attribute of the module. If the module has [system] but the + // module map is not in a system path, then this would incorrectly parse + // any other modules in that module map as system too. + const SrcMgr::SLocEntry &SLoc = SourceMgr.getSLocEntry(ModuleMapFID); + bool IsSystem = isSystem(SLoc.getFile().getFileCharacteristic()); + + // Use the module map where this module resides. + return createCompilerInstanceForModuleCompileImpl( + ImportingInstance, ImportLoc, ModuleName, + FrontendInputFile(ModuleMapFilePath, IK, IsSystem), + ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); + } + + // FIXME: We only need to fake up an input file here as a way of + // transporting the module's directory to the module map parser. We should + // be able to do that more directly, and parse from a memory buffer without + // inventing this file. + SmallString<128> FakeModuleMapFile(Module->Directory->getName()); + llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); + + std::string InferredModuleMapContent; + llvm::raw_string_ostream OS(InferredModuleMapContent); + Module->print(OS); + + auto Instance = createCompilerInstanceForModuleCompileImpl( + ImportingInstance, ImportLoc, ModuleName, + FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem), + ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); + + std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = + llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent); + FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef( + FakeModuleMapFile, InferredModuleMapContent.size(), 0); + Instance->getSourceManager().overrideFileContents(ModuleMapFile, + std::move(ModuleMapBuffer)); + + return Instance; +} + /// Compile a module file for the given module, using the options /// provided by the importing compiler instance. Returns true if the module /// was built without errors. @@ -1300,19 +1402,6 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, Instance.getFrontendOpts().AllowPCMWithCompilerErrors; } -static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, - FileManager &FileMgr) { - StringRef Filename = llvm::sys::path::filename(File.getName()); - SmallString<128> PublicFilename(File.getDir().getName()); - if (Filename == "module_private.map") - llvm::sys::path::append(PublicFilename, "module.map"); - else if (Filename == "module.private.modulemap") - llvm::sys::path::append(PublicFilename, "module.modulemap"); - else - return std::nullopt; - return FileMgr.getOptionalFileRef(PublicFilename); -} - /// Compile a module file for the given module in a separate compiler instance, /// using the options provided by the importing compiler instance. Returns true /// if the module was built without errors. @@ -1331,76 +1420,8 @@ static bool compileModule(CompilerInstance &ImportingInstance, return false; } - InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()), - InputKind::ModuleMap); - - // Get or create the module map that we'll use to build this module. - ModuleMap &ModMap - = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - SourceManager &SourceMgr = ImportingInstance.getSourceManager(); - - std::unique_ptr<CompilerInstance> Instance; - if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module); - ModuleMapFID.isValid()) { - // We want to use the top-level module map. If we don't, the compiling - // instance may think the containing module map is a top-level one, while - // the importing instance knows it's included from a parent module map via - // the extern directive. This mismatch could bite us later. - SourceLocation Loc = SourceMgr.getIncludeLoc(ModuleMapFID); - while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) { - ModuleMapFID = SourceMgr.getFileID(Loc); - Loc = SourceMgr.getIncludeLoc(ModuleMapFID); - } - - OptionalFileEntryRef ModuleMapFile = - SourceMgr.getFileEntryRefForID(ModuleMapFID); - assert(ModuleMapFile && "Top-level module map with no FileID"); - - // Canonicalize compilation to start with the public module map. This is - // vital for submodules declarations in the private module maps to be - // correctly parsed when depending on a top level module in the public one. - if (OptionalFileEntryRef PublicMMFile = getPublicModuleMap( - *ModuleMapFile, ImportingInstance.getFileManager())) - ModuleMapFile = PublicMMFile; - - StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested(); - - // Use the systemness of the module map as parsed instead of using the - // IsSystem attribute of the module. If the module has [system] but the - // module map is not in a system path, then this would incorrectly parse - // any other modules in that module map as system too. - const SrcMgr::SLocEntry &SLoc = SourceMgr.getSLocEntry(ModuleMapFID); - bool IsSystem = isSystem(SLoc.getFile().getFileCharacteristic()); - - // Use the module map where this module resides. - Instance = createCompilerInstanceForModuleCompile( - ImportingInstance, ImportLoc, ModuleName, - FrontendInputFile(ModuleMapFilePath, IK, IsSystem), - ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); - } else { - // FIXME: We only need to fake up an input file here as a way of - // transporting the module's directory to the module map parser. We should - // be able to do that more directly, and parse from a memory buffer without - // inventing this file. - SmallString<128> FakeModuleMapFile(Module->Directory->getName()); - llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); - - std::string InferredModuleMapContent; - llvm::raw_string_ostream OS(InferredModuleMapContent); - Module->print(OS); - - Instance = createCompilerInstanceForModuleCompile( - ImportingInstance, ImportLoc, ModuleName, - FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem), - ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); - - std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = - llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent); - FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef( - FakeModuleMapFile, InferredModuleMapContent.size(), 0); - Instance->getSourceManager().overrideFileContents( - ModuleMapFile, std::move(ModuleMapBuffer)); - } + auto Instance = createCompilerInstanceForModuleCompile( + ImportingInstance, ImportLoc, Module, ModuleFileName); bool Success = compileModuleImpl(ImportingInstance, ImportLoc, ModuleName, ModuleFileName, *Instance); @@ -2238,7 +2259,7 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc, std::string NullTerminatedSource(Source.str()); - auto Other = createCompilerInstanceForModuleCompile( + auto Other = createCompilerInstanceForModuleCompileImpl( *this, ImportLoc, ModuleName, Input, StringRef(), ModuleFileName); // Create a virtual file containing our desired source. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits