@@ -1069,11 +1069,13 @@ static bool writeLdAddCFileIfNeeded(const CompilerInvocation &Invocation,
1069
1069
return false ;
1070
1070
}
1071
1071
1072
- static bool performCompileStepsPostSILGen (
1073
- CompilerInstance &Instance, const CompilerInvocation &Invocation,
1074
- std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
1075
- ModuleOrSourceFile MSF, const PrimarySpecificPaths &PSPs,
1076
- bool moduleIsPublic, int &ReturnValue, FrontendObserver *observer);
1072
+ static bool performCompileStepsPostSILGen (CompilerInstance &Instance,
1073
+ const CompilerInvocation &Invocation,
1074
+ std::unique_ptr<SILModule> SM,
1075
+ ModuleOrSourceFile MSF,
1076
+ const PrimarySpecificPaths &PSPs,
1077
+ bool moduleIsPublic, int &ReturnValue,
1078
+ FrontendObserver *observer);
1077
1079
1078
1080
static bool
1079
1081
performCompileStepsPostSema (const CompilerInvocation &Invocation,
@@ -1085,28 +1087,19 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
1085
1087
const PrimarySpecificPaths PSPs =
1086
1088
Instance.getPrimarySpecificPathsForAtMostOnePrimary ();
1087
1089
return performCompileStepsPostSILGen (Instance, Invocation, std::move (SM),
1088
- /* ASTGuaranteedToCorrespondToSIL=*/ false ,
1089
1090
mod, PSPs, moduleIsPublic,
1090
1091
ReturnValue, observer);
1091
1092
}
1092
1093
1093
1094
const SILOptions &SILOpts = Invocation.getSILOptions ();
1094
1095
const FrontendOptions &opts = Invocation.getFrontendOptions ();
1095
- auto fileIsSIB = [](const FileUnit *File) -> bool {
1096
- auto SASTF = dyn_cast<SerializedASTFile>(File);
1097
- return SASTF && SASTF->isSIB ();
1098
- };
1099
-
1100
1096
if (!opts.InputsAndOutputs .hasPrimaryInputs ()) {
1101
1097
// If there are no primary inputs the compiler is in WMO mode and builds one
1102
1098
// SILModule for the entire module.
1103
1099
auto SM = performSILGeneration (mod, Instance.getSILTypes (), SILOpts);
1104
1100
const PrimarySpecificPaths PSPs =
1105
1101
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode ();
1106
- bool astGuaranteedToCorrespondToSIL =
1107
- llvm::none_of (mod->getFiles (), fileIsSIB);
1108
1102
return performCompileStepsPostSILGen (Instance, Invocation, std::move (SM),
1109
- astGuaranteedToCorrespondToSIL,
1110
1103
mod, PSPs, moduleIsPublic,
1111
1104
ReturnValue, observer);
1112
1105
}
@@ -1120,7 +1113,6 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
1120
1113
const PrimarySpecificPaths PSPs =
1121
1114
Instance.getPrimarySpecificPathsForSourceFile (*PrimaryFile);
1122
1115
result |= performCompileStepsPostSILGen (Instance, Invocation, std::move (SM),
1123
- /* ASTGuaranteedToCorrespondToSIL*/ true ,
1124
1116
PrimaryFile, PSPs, moduleIsPublic,
1125
1117
ReturnValue, observer);
1126
1118
}
@@ -1139,7 +1131,6 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
1139
1131
const PrimarySpecificPaths &PSPs =
1140
1132
Instance.getPrimarySpecificPathsForPrimary (SASTF->getFilename ());
1141
1133
result |= performCompileStepsPostSILGen (Instance, Invocation, std::move (SM),
1142
- !fileIsSIB (SASTF),
1143
1134
mod, PSPs, moduleIsPublic,
1144
1135
ReturnValue, observer);
1145
1136
}
@@ -1422,44 +1413,76 @@ static bool processCommandLineAndRunImmediately(const CompilerInvocation &Invoca
1422
1413
1423
1414
static bool validateTBDIfNeeded (const CompilerInvocation &Invocation,
1424
1415
ModuleOrSourceFile MSF,
1425
- bool astGuaranteedToCorrespondToSIL,
1426
1416
const llvm::Module &IRModule) {
1427
- if (!astGuaranteedToCorrespondToSIL ||
1428
- ! inputFileKindCanHaveTBDValidated (Invocation. getInputKind ()))
1429
- return false ;
1430
-
1431
- if (Invocation. getSILOptions (). CrossModuleOptimization )
1432
- return false ;
1417
+ const auto mode = Invocation. getFrontendOptions (). ValidateTBDAgainstIR ;
1418
+ const bool canPerformTBDValidation = [&]() {
1419
+ // If the user has requested we skip validation, honor it.
1420
+ if (mode == FrontendOptions::TBDValidationMode::None) {
1421
+ return false ;
1422
+ }
1433
1423
1434
- const auto &frontendOpts = Invocation.getFrontendOptions ();
1435
- auto mode = frontendOpts.ValidateTBDAgainstIR ;
1436
- // Ensure all cases are covered by using a switch here.
1437
- switch (mode) {
1438
- case FrontendOptions::TBDValidationMode::Default:
1424
+ // Cross-module optimization does not yet support TBD validation.
1425
+ if (Invocation.getSILOptions ().CrossModuleOptimization ) {
1426
+ return false ;
1427
+ }
1428
+
1429
+ // If we can't validate the given input file, bail early. This covers cases
1430
+ // like passing raw SIL as a primary file.
1431
+ if (!inputFileKindCanHaveTBDValidated (Invocation.getInputKind ())) {
1432
+ return false ;
1433
+ }
1434
+
1435
+ // Modules with SIB files cannot be validated. This is because SIB files
1436
+ // may have serialized hand-crafted SIL definitions that are invisible to
1437
+ // TBDGen as it is an AST-only traversal.
1438
+ if (auto *mod = MSF.dyn_cast <ModuleDecl *>()) {
1439
+ return llvm::none_of (mod->getFiles (), [](const FileUnit *File) -> bool {
1440
+ auto SASTF = dyn_cast<SerializedASTFile>(File);
1441
+ return SASTF && SASTF->isSIB ();
1442
+ });
1443
+ }
1444
+
1445
+ // "Default" mode's behavior varies if using a debug compiler.
1446
+ if (mode == FrontendOptions::TBDValidationMode::Default) {
1439
1447
#ifndef NDEBUG
1440
- // With a debug compiler, we do some validation by default.
1441
- mode = FrontendOptions::TBDValidationMode::MissingFromTBD;
1442
- break ;
1448
+ // With a debug compiler, we do some validation by default.
1449
+ return true ;
1443
1450
#else
1444
- // Otherwise, the default is to do nothing.
1445
- LLVM_FALLTHROUGH ;
1451
+ // Otherwise, the default is to do nothing.
1452
+ return false ;
1446
1453
#endif
1447
- case FrontendOptions::TBDValidationMode::None:
1454
+ }
1455
+
1456
+
1457
+ return true ;
1458
+ }();
1459
+
1460
+ if (!canPerformTBDValidation) {
1448
1461
return false ;
1449
- case FrontendOptions::TBDValidationMode::All:
1450
- case FrontendOptions::TBDValidationMode::MissingFromTBD:
1451
- break ;
1452
1462
}
1453
1463
1454
- const bool allSymbols = mode == FrontendOptions::TBDValidationMode::All;
1455
- // We should ignore embeded symbols from external modules for validation.
1464
+ const bool diagnoseExtraSymbolsInTBD = [mode]() {
1465
+ switch (mode) {
1466
+ case FrontendOptions::TBDValidationMode::None:
1467
+ llvm_unreachable (" Handled Above!" );
1468
+ case FrontendOptions::TBDValidationMode::Default:
1469
+ case FrontendOptions::TBDValidationMode::MissingFromTBD:
1470
+ return false ;
1471
+ case FrontendOptions::TBDValidationMode::All:
1472
+ return true ;
1473
+ }
1474
+ }();
1475
+
1456
1476
TBDGenOptions Opts = Invocation.getTBDGenOptions ();
1477
+ // Ignore embedded symbols from external modules for validation to remove
1478
+ // noise from e.g. statically-linked libraries.
1457
1479
Opts.embedSymbolsFromModules .clear ();
1458
- return MSF.is <SourceFile *>()
1459
- ? validateTBD (MSF.get <SourceFile *>(), IRModule,
1460
- Opts, allSymbols)
1461
- : validateTBD (MSF.get <ModuleDecl *>(), IRModule,
1462
- Opts, allSymbols);
1480
+ if (auto *SF = MSF.dyn_cast <SourceFile *>()) {
1481
+ return validateTBD (SF, IRModule, Opts, diagnoseExtraSymbolsInTBD);
1482
+ } else {
1483
+ return validateTBD (MSF.get <ModuleDecl *>(), IRModule, Opts,
1484
+ diagnoseExtraSymbolsInTBD);
1485
+ }
1463
1486
}
1464
1487
1465
1488
enum class DeallocatableResources {
@@ -1547,11 +1570,13 @@ static void collectLinkerDirectives(const CompilerInvocation &Invocation,
1547
1570
enumeratePublicSymbols (MSF.get <ModuleDecl*>(), Symbols, tbdOpts);
1548
1571
}
1549
1572
1550
- static bool performCompileStepsPostSILGen (
1551
- CompilerInstance &Instance, const CompilerInvocation &Invocation,
1552
- std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
1553
- ModuleOrSourceFile MSF, const PrimarySpecificPaths &PSPs,
1554
- bool moduleIsPublic, int &ReturnValue, FrontendObserver *observer) {
1573
+ static bool performCompileStepsPostSILGen (CompilerInstance &Instance,
1574
+ const CompilerInvocation &Invocation,
1575
+ std::unique_ptr<SILModule> SM,
1576
+ ModuleOrSourceFile MSF,
1577
+ const PrimarySpecificPaths &PSPs,
1578
+ bool moduleIsPublic, int &ReturnValue,
1579
+ FrontendObserver *observer) {
1555
1580
1556
1581
FrontendOptions opts = Invocation.getFrontendOptions ();
1557
1582
FrontendOptions::ActionType Action = opts.RequestedAction ;
@@ -1690,8 +1715,7 @@ static bool performCompileStepsPostSILGen(
1690
1715
if (!IRModule)
1691
1716
return HadError;
1692
1717
1693
- if (validateTBDIfNeeded (Invocation, MSF, astGuaranteedToCorrespondToSIL,
1694
- *IRModule.getModule ()))
1718
+ if (validateTBDIfNeeded (Invocation, MSF, *IRModule.getModule ()))
1695
1719
return true ;
1696
1720
1697
1721
return generateCode (Invocation, Instance, OutputFilename,
0 commit comments