@@ -1150,29 +1150,16 @@ static Language getLanguageFromOptions(const LangOptions &LangOpts) {
11501150 return LangOpts.CPlusPlus ? Language::CXX : Language::C;
11511151}
11521152
1153- // / Compile a module file for the given module, using the options
1154- // / provided by the importing compiler instance. Returns true if the module
1155- // / was built without errors.
1156- static bool
1157- compileModuleImpl (CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
1158- StringRef ModuleName, FrontendInputFile Input,
1159- StringRef OriginalModuleMapFile, StringRef ModuleFileName,
1160- llvm::function_ref<void (CompilerInstance &)> PreBuildStep =
1161- [](CompilerInstance &) {},
1162- llvm::function_ref<void (CompilerInstance &)> PostBuildStep =
1163- [](CompilerInstance &) {}) {
1164- llvm::TimeTraceScope TimeScope (" Module Compile" , ModuleName);
1165-
1166- // Never compile a module that's already finalized - this would cause the
1167- // existing module to be freed, causing crashes if it is later referenced
1168- if (ImportingInstance.getModuleCache ().getInMemoryModuleCache ().isPCMFinal (
1169- ModuleFileName)) {
1170- ImportingInstance.getDiagnostics ().Report (
1171- ImportLoc, diag::err_module_rebuild_finalized)
1172- << ModuleName;
1173- return false ;
1174- }
1175-
1153+ // / Creates a \c CompilerInstance for compiling a module.
1154+ // /
1155+ // / This expects a properly initialized \c FrontendInputFile.
1156+ static std::unique_ptr<CompilerInstance>
1157+ createCompilerInstanceForModuleCompileImpl (CompilerInstance &ImportingInstance,
1158+ SourceLocation ImportLoc,
1159+ StringRef ModuleName,
1160+ FrontendInputFile Input,
1161+ StringRef OriginalModuleMapFile,
1162+ StringRef ModuleFileName) {
11761163 // Construct a compiler invocation for creating this module.
11771164 auto Invocation =
11781165 std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation ());
@@ -1226,8 +1213,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
12261213 // module. Since we're sharing an in-memory module cache,
12271214 // CompilerInstance::CompilerInstance is responsible for finalizing the
12281215 // buffers to prevent use-after-frees.
1229- CompilerInstance Instance (ImportingInstance.getPCHContainerOperations (),
1230- &ImportingInstance.getModuleCache ());
1216+ auto InstancePtr = std::make_unique<CompilerInstance>(
1217+ ImportingInstance.getPCHContainerOperations (),
1218+ &ImportingInstance.getModuleCache ());
1219+ auto &Instance = *InstancePtr;
1220+
12311221 auto &Inv = *Invocation;
12321222 Instance.setInvocation (std::move (Invocation));
12331223
@@ -1267,12 +1257,32 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
12671257 Instance.setModuleDepCollector (ImportingInstance.getModuleDepCollector ());
12681258 Inv.getDependencyOutputOpts () = DependencyOutputOptions ();
12691259
1260+ return InstancePtr;
1261+ }
1262+
1263+ // / Compile a module file for the given module, using the options
1264+ // / provided by the importing compiler instance. Returns true if the module
1265+ // / was built without errors.
1266+ static bool compileModule (CompilerInstance &ImportingInstance,
1267+ SourceLocation ImportLoc, StringRef ModuleName,
1268+ StringRef ModuleFileName,
1269+ CompilerInstance &Instance) {
1270+ llvm::TimeTraceScope TimeScope (" Module Compile" , ModuleName);
1271+
1272+ // Never compile a module that's already finalized - this would cause the
1273+ // existing module to be freed, causing crashes if it is later referenced
1274+ if (ImportingInstance.getModuleCache ().getInMemoryModuleCache ().isPCMFinal (
1275+ ModuleFileName)) {
1276+ ImportingInstance.getDiagnostics ().Report (
1277+ ImportLoc, diag::err_module_rebuild_finalized)
1278+ << ModuleName;
1279+ return false ;
1280+ }
1281+
12701282 ImportingInstance.getDiagnostics ().Report (ImportLoc,
12711283 diag::remark_module_build)
12721284 << ModuleName << ModuleFileName;
12731285
1274- PreBuildStep (Instance);
1275-
12761286 // Execute the action to actually build the module in-place. Use a separate
12771287 // thread so that we get a stack large enough.
12781288 bool Crashed = !llvm::CrashRecoveryContext ().RunSafelyOnThread (
@@ -1282,14 +1292,12 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
12821292 },
12831293 DesiredStackSize);
12841294
1285- PostBuildStep (Instance);
1286-
12871295 ImportingInstance.getDiagnostics ().Report (ImportLoc,
12881296 diag::remark_module_build_done)
12891297 << ModuleName;
12901298
12911299 // Propagate the statistics to the parent FileManager.
1292- if (!FrontendOpts .ModulesShareFileManager )
1300+ if (!ImportingInstance. getFrontendOpts () .ModulesShareFileManager )
12931301 ImportingInstance.getFileManager ().AddStats (Instance.getFileManager ());
12941302
12951303 if (Crashed) {
@@ -1302,6 +1310,12 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
13021310 Instance.clearOutputFiles (/* EraseFiles=*/ true );
13031311 }
13041312
1313+ // We've rebuilt a module. If we're allowed to generate or update the global
1314+ // module index, record that fact in the importing compiler instance.
1315+ if (ImportingInstance.getFrontendOpts ().GenerateGlobalModuleIndex ) {
1316+ ImportingInstance.setBuildGlobalModuleIndex (true );
1317+ }
1318+
13051319 // If \p AllowPCMWithCompilerErrors is set return 'success' even if errors
13061320 // occurred.
13071321 return !Instance.getDiagnostics ().hasErrorOccurred () ||
@@ -1321,20 +1335,24 @@ static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File,
13211335 return FileMgr.getOptionalFileRef (PublicFilename);
13221336}
13231337
1324- // / Compile a module file for the given module in a separate compiler instance,
1325- // / using the options provided by the importing compiler instance. Returns true
1326- // / if the module was built without errors.
1327- static bool compileModule (CompilerInstance &ImportingInstance,
1328- SourceLocation ImportLoc, Module *Module,
1329- StringRef ModuleFileName) {
1338+ // / Creates a \c CompilerInstance for compiling a module.
1339+ // /
1340+ // / This takes care of creating appropriate \c FrontendInputFile for
1341+ // / public/private frameworks, inferred modules and such.
1342+ static std::unique_ptr<CompilerInstance>
1343+ createCompilerInstanceForModuleCompile (CompilerInstance &ImportingInstance,
1344+ SourceLocation ImportLoc, Module *Module,
1345+ StringRef ModuleFileName) {
1346+ StringRef ModuleName = Module->getTopLevelModuleName ();
1347+
13301348 InputKind IK (getLanguageFromOptions (ImportingInstance.getLangOpts ()),
13311349 InputKind::ModuleMap);
13321350
13331351 // Get or create the module map that we'll use to build this module.
1334- ModuleMap &ModMap
1335- = ImportingInstance.getPreprocessor ().getHeaderSearchInfo ().getModuleMap ();
1352+ ModuleMap &ModMap =
1353+ ImportingInstance.getPreprocessor ().getHeaderSearchInfo ().getModuleMap ();
13361354 SourceManager &SourceMgr = ImportingInstance.getSourceManager ();
1337- bool Result;
1355+
13381356 if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID (Module);
13391357 ModuleMapFID.isValid ()) {
13401358 // We want to use the top-level module map. If we don't, the compiling
@@ -1368,44 +1386,36 @@ static bool compileModule(CompilerInstance &ImportingInstance,
13681386 bool IsSystem = isSystem (SLoc.getFile ().getFileCharacteristic ());
13691387
13701388 // Use the module map where this module resides.
1371- Result = compileModuleImpl (
1372- ImportingInstance, ImportLoc, Module-> getTopLevelModuleName () ,
1389+ return createCompilerInstanceForModuleCompileImpl (
1390+ ImportingInstance, ImportLoc, ModuleName ,
13731391 FrontendInputFile (ModuleMapFilePath, IK, IsSystem),
13741392 ModMap.getModuleMapFileForUniquing (Module)->getName (), ModuleFileName);
1375- } else {
1376- // FIXME: We only need to fake up an input file here as a way of
1377- // transporting the module's directory to the module map parser. We should
1378- // be able to do that more directly, and parse from a memory buffer without
1379- // inventing this file.
1380- SmallString<128 > FakeModuleMapFile (Module->Directory ->getName ());
1381- llvm::sys::path::append (FakeModuleMapFile, " __inferred_module.map" );
1382-
1383- std::string InferredModuleMapContent;
1384- llvm::raw_string_ostream OS (InferredModuleMapContent);
1385- Module->print (OS);
1386-
1387- Result = compileModuleImpl (
1388- ImportingInstance, ImportLoc, Module->getTopLevelModuleName (),
1389- FrontendInputFile (FakeModuleMapFile, IK, +Module->IsSystem ),
1390- ModMap.getModuleMapFileForUniquing (Module)->getName (),
1391- ModuleFileName,
1392- [&](CompilerInstance &Instance) {
1393- std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1394- llvm::MemoryBuffer::getMemBuffer (InferredModuleMapContent);
1395- FileEntryRef ModuleMapFile = Instance.getFileManager ().getVirtualFileRef (
1396- FakeModuleMapFile, InferredModuleMapContent.size (), 0 );
1397- Instance.getSourceManager ().overrideFileContents (
1398- ModuleMapFile, std::move (ModuleMapBuffer));
1399- });
14001393 }
14011394
1402- // We've rebuilt a module. If we're allowed to generate or update the global
1403- // module index, record that fact in the importing compiler instance.
1404- if (ImportingInstance.getFrontendOpts ().GenerateGlobalModuleIndex ) {
1405- ImportingInstance.setBuildGlobalModuleIndex (true );
1406- }
1395+ // FIXME: We only need to fake up an input file here as a way of
1396+ // transporting the module's directory to the module map parser. We should
1397+ // be able to do that more directly, and parse from a memory buffer without
1398+ // inventing this file.
1399+ SmallString<128 > FakeModuleMapFile (Module->Directory ->getName ());
1400+ llvm::sys::path::append (FakeModuleMapFile, " __inferred_module.map" );
1401+
1402+ std::string InferredModuleMapContent;
1403+ llvm::raw_string_ostream OS (InferredModuleMapContent);
1404+ Module->print (OS);
1405+
1406+ auto Instance = createCompilerInstanceForModuleCompileImpl (
1407+ ImportingInstance, ImportLoc, ModuleName,
1408+ FrontendInputFile (FakeModuleMapFile, IK, +Module->IsSystem ),
1409+ ModMap.getModuleMapFileForUniquing (Module)->getName (), ModuleFileName);
1410+
1411+ std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1412+ llvm::MemoryBuffer::getMemBufferCopy (InferredModuleMapContent);
1413+ FileEntryRef ModuleMapFile = Instance->getFileManager ().getVirtualFileRef (
1414+ FakeModuleMapFile, InferredModuleMapContent.size (), 0 );
1415+ Instance->getSourceManager ().overrideFileContents (ModuleMapFile,
1416+ std::move (ModuleMapBuffer));
14071417
1408- return Result ;
1418+ return Instance ;
14091419}
14101420
14111421// / Read the AST right after compiling the module.
@@ -1455,8 +1465,12 @@ static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance,
14551465 SourceLocation ModuleNameLoc,
14561466 Module *Module,
14571467 StringRef ModuleFileName) {
1458- if (!compileModule (ImportingInstance, ModuleNameLoc, Module,
1459- ModuleFileName)) {
1468+ auto Instance = createCompilerInstanceForModuleCompile (
1469+ ImportingInstance, ModuleNameLoc, Module, ModuleFileName);
1470+
1471+ if (!compileModule (ImportingInstance, ModuleNameLoc,
1472+ Module->getTopLevelModuleName (), ModuleFileName,
1473+ *Instance)) {
14601474 ImportingInstance.getDiagnostics ().Report (ModuleNameLoc,
14611475 diag::err_module_not_built)
14621476 << Module->Name << SourceRange (ImportLoc, ModuleNameLoc);
@@ -2232,25 +2246,26 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,
22322246
22332247 std::string NullTerminatedSource (Source.str ());
22342248
2235- auto PreBuildStep = [&](CompilerInstance &Other) {
2236- // Create a virtual file containing our desired source.
2237- // FIXME: We shouldn't need to do this.
2238- FileEntryRef ModuleMapFile = Other.getFileManager ().getVirtualFileRef (
2239- ModuleMapFileName, NullTerminatedSource.size (), 0 );
2240- Other.getSourceManager ().overrideFileContents (
2241- ModuleMapFile, llvm::MemoryBuffer::getMemBuffer (NullTerminatedSource));
2249+ auto Other = createCompilerInstanceForModuleCompileImpl (
2250+ *this , ImportLoc, ModuleName, Input, StringRef (), ModuleFileName);
22422251
2243- Other.BuiltModules = std::move (BuiltModules);
2244- Other.DeleteBuiltModules = false ;
2245- };
2252+ // Create a virtual file containing our desired source.
2253+ // FIXME: We shouldn't need to do this.
2254+ FileEntryRef ModuleMapFile = Other->getFileManager ().getVirtualFileRef (
2255+ ModuleMapFileName, NullTerminatedSource.size (), 0 );
2256+ Other->getSourceManager ().overrideFileContents (
2257+ ModuleMapFile, llvm::MemoryBuffer::getMemBuffer (NullTerminatedSource));
22462258
2247- auto PostBuildStep = [this ](CompilerInstance &Other) {
2248- BuiltModules = std::move (Other.BuiltModules );
2249- };
2259+ Other->BuiltModules = std::move (BuiltModules);
2260+ Other->DeleteBuiltModules = false ;
22502261
22512262 // Build the module, inheriting any modules that we've built locally.
2252- if (compileModuleImpl (*this , ImportLoc, ModuleName, Input, StringRef (),
2253- ModuleFileName, PreBuildStep, PostBuildStep)) {
2263+ bool Success =
2264+ compileModule (*this , ImportLoc, ModuleName, ModuleFileName, *Other);
2265+
2266+ BuiltModules = std::move (Other->BuiltModules );
2267+
2268+ if (Success) {
22542269 BuiltModules[std::string (ModuleName)] = std::string (ModuleFileName);
22552270 llvm::sys::RemoveFileOnSignal (ModuleFileName);
22562271 }
0 commit comments