@@ -1150,29 +1150,16 @@ static Language getLanguageFromOptions(const LangOptions &LangOpts) {
1150
1150
return LangOpts.CPlusPlus ? Language::CXX : Language::C;
1151
1151
}
1152
1152
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) {
1176
1163
// Construct a compiler invocation for creating this module.
1177
1164
auto Invocation =
1178
1165
std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation ());
@@ -1226,8 +1213,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
1226
1213
// module. Since we're sharing an in-memory module cache,
1227
1214
// CompilerInstance::CompilerInstance is responsible for finalizing the
1228
1215
// 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
+
1231
1221
auto &Inv = *Invocation;
1232
1222
Instance.setInvocation (std::move (Invocation));
1233
1223
@@ -1267,12 +1257,32 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
1267
1257
Instance.setModuleDepCollector (ImportingInstance.getModuleDepCollector ());
1268
1258
Inv.getDependencyOutputOpts () = DependencyOutputOptions ();
1269
1259
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
+
1270
1282
ImportingInstance.getDiagnostics ().Report (ImportLoc,
1271
1283
diag::remark_module_build)
1272
1284
<< ModuleName << ModuleFileName;
1273
1285
1274
- PreBuildStep (Instance);
1275
-
1276
1286
// Execute the action to actually build the module in-place. Use a separate
1277
1287
// thread so that we get a stack large enough.
1278
1288
bool Crashed = !llvm::CrashRecoveryContext ().RunSafelyOnThread (
@@ -1282,14 +1292,12 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
1282
1292
},
1283
1293
DesiredStackSize);
1284
1294
1285
- PostBuildStep (Instance);
1286
-
1287
1295
ImportingInstance.getDiagnostics ().Report (ImportLoc,
1288
1296
diag::remark_module_build_done)
1289
1297
<< ModuleName;
1290
1298
1291
1299
// Propagate the statistics to the parent FileManager.
1292
- if (!FrontendOpts .ModulesShareFileManager )
1300
+ if (!ImportingInstance. getFrontendOpts () .ModulesShareFileManager )
1293
1301
ImportingInstance.getFileManager ().AddStats (Instance.getFileManager ());
1294
1302
1295
1303
if (Crashed) {
@@ -1302,6 +1310,12 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
1302
1310
Instance.clearOutputFiles (/* EraseFiles=*/ true );
1303
1311
}
1304
1312
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
+
1305
1319
// If \p AllowPCMWithCompilerErrors is set return 'success' even if errors
1306
1320
// occurred.
1307
1321
return !Instance.getDiagnostics ().hasErrorOccurred () ||
@@ -1321,20 +1335,24 @@ static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File,
1321
1335
return FileMgr.getOptionalFileRef (PublicFilename);
1322
1336
}
1323
1337
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
+
1330
1348
InputKind IK (getLanguageFromOptions (ImportingInstance.getLangOpts ()),
1331
1349
InputKind::ModuleMap);
1332
1350
1333
1351
// 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 ();
1336
1354
SourceManager &SourceMgr = ImportingInstance.getSourceManager ();
1337
- bool Result;
1355
+
1338
1356
if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID (Module);
1339
1357
ModuleMapFID.isValid ()) {
1340
1358
// We want to use the top-level module map. If we don't, the compiling
@@ -1368,44 +1386,36 @@ static bool compileModule(CompilerInstance &ImportingInstance,
1368
1386
bool IsSystem = isSystem (SLoc.getFile ().getFileCharacteristic ());
1369
1387
1370
1388
// Use the module map where this module resides.
1371
- Result = compileModuleImpl (
1372
- ImportingInstance, ImportLoc, Module-> getTopLevelModuleName () ,
1389
+ return createCompilerInstanceForModuleCompileImpl (
1390
+ ImportingInstance, ImportLoc, ModuleName ,
1373
1391
FrontendInputFile (ModuleMapFilePath, IK, IsSystem),
1374
1392
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
- });
1400
1393
}
1401
1394
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));
1407
1417
1408
- return Result ;
1418
+ return Instance ;
1409
1419
}
1410
1420
1411
1421
// / Read the AST right after compiling the module.
@@ -1455,8 +1465,12 @@ static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance,
1455
1465
SourceLocation ModuleNameLoc,
1456
1466
Module *Module,
1457
1467
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)) {
1460
1474
ImportingInstance.getDiagnostics ().Report (ModuleNameLoc,
1461
1475
diag::err_module_not_built)
1462
1476
<< Module->Name << SourceRange (ImportLoc, ModuleNameLoc);
@@ -2232,25 +2246,26 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,
2232
2246
2233
2247
std::string NullTerminatedSource (Source.str ());
2234
2248
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);
2242
2251
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));
2246
2258
2247
- auto PostBuildStep = [this ](CompilerInstance &Other) {
2248
- BuiltModules = std::move (Other.BuiltModules );
2249
- };
2259
+ Other->BuiltModules = std::move (BuiltModules);
2260
+ Other->DeleteBuiltModules = false ;
2250
2261
2251
2262
// 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) {
2254
2269
BuiltModules[std::string (ModuleName)] = std::string (ModuleFileName);
2255
2270
llvm::sys::RemoveFileOnSignal (ModuleFileName);
2256
2271
}
0 commit comments