Skip to content

Commit db3e9fc

Browse files
authored
Merge pull request swiftlang#31142 from CodaFi/TBD-TBD
[Frontend][NFC] Refactor validateTBDIfNeeded
2 parents 423713b + 446c6e6 commit db3e9fc

File tree

1 file changed

+75
-51
lines changed

1 file changed

+75
-51
lines changed

lib/FrontendTool/FrontendTool.cpp

Lines changed: 75 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,11 +1069,13 @@ static bool writeLdAddCFileIfNeeded(const CompilerInvocation &Invocation,
10691069
return false;
10701070
}
10711071

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);
10771079

10781080
static bool
10791081
performCompileStepsPostSema(const CompilerInvocation &Invocation,
@@ -1085,28 +1087,19 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
10851087
const PrimarySpecificPaths PSPs =
10861088
Instance.getPrimarySpecificPathsForAtMostOnePrimary();
10871089
return performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
1088-
/*ASTGuaranteedToCorrespondToSIL=*/false,
10891090
mod, PSPs, moduleIsPublic,
10901091
ReturnValue, observer);
10911092
}
10921093

10931094
const SILOptions &SILOpts = Invocation.getSILOptions();
10941095
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-
11001096
if (!opts.InputsAndOutputs.hasPrimaryInputs()) {
11011097
// If there are no primary inputs the compiler is in WMO mode and builds one
11021098
// SILModule for the entire module.
11031099
auto SM = performSILGeneration(mod, Instance.getSILTypes(), SILOpts);
11041100
const PrimarySpecificPaths PSPs =
11051101
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
1106-
bool astGuaranteedToCorrespondToSIL =
1107-
llvm::none_of(mod->getFiles(), fileIsSIB);
11081102
return performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
1109-
astGuaranteedToCorrespondToSIL,
11101103
mod, PSPs, moduleIsPublic,
11111104
ReturnValue, observer);
11121105
}
@@ -1120,7 +1113,6 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
11201113
const PrimarySpecificPaths PSPs =
11211114
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
11221115
result |= performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
1123-
/*ASTGuaranteedToCorrespondToSIL*/true,
11241116
PrimaryFile, PSPs, moduleIsPublic,
11251117
ReturnValue, observer);
11261118
}
@@ -1139,7 +1131,6 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
11391131
const PrimarySpecificPaths &PSPs =
11401132
Instance.getPrimarySpecificPathsForPrimary(SASTF->getFilename());
11411133
result |= performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
1142-
!fileIsSIB(SASTF),
11431134
mod, PSPs, moduleIsPublic,
11441135
ReturnValue, observer);
11451136
}
@@ -1422,44 +1413,76 @@ static bool processCommandLineAndRunImmediately(const CompilerInvocation &Invoca
14221413

14231414
static bool validateTBDIfNeeded(const CompilerInvocation &Invocation,
14241415
ModuleOrSourceFile MSF,
1425-
bool astGuaranteedToCorrespondToSIL,
14261416
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+
}
14331423

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) {
14391447
#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;
14431450
#else
1444-
// Otherwise, the default is to do nothing.
1445-
LLVM_FALLTHROUGH;
1451+
// Otherwise, the default is to do nothing.
1452+
return false;
14461453
#endif
1447-
case FrontendOptions::TBDValidationMode::None:
1454+
}
1455+
1456+
1457+
return true;
1458+
}();
1459+
1460+
if (!canPerformTBDValidation) {
14481461
return false;
1449-
case FrontendOptions::TBDValidationMode::All:
1450-
case FrontendOptions::TBDValidationMode::MissingFromTBD:
1451-
break;
14521462
}
14531463

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+
14561476
TBDGenOptions Opts = Invocation.getTBDGenOptions();
1477+
// Ignore embedded symbols from external modules for validation to remove
1478+
// noise from e.g. statically-linked libraries.
14571479
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+
}
14631486
}
14641487

14651488
enum class DeallocatableResources {
@@ -1547,11 +1570,13 @@ static void collectLinkerDirectives(const CompilerInvocation &Invocation,
15471570
enumeratePublicSymbols(MSF.get<ModuleDecl*>(), Symbols, tbdOpts);
15481571
}
15491572

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) {
15551580

15561581
FrontendOptions opts = Invocation.getFrontendOptions();
15571582
FrontendOptions::ActionType Action = opts.RequestedAction;
@@ -1690,8 +1715,7 @@ static bool performCompileStepsPostSILGen(
16901715
if (!IRModule)
16911716
return HadError;
16921717

1693-
if (validateTBDIfNeeded(Invocation, MSF, astGuaranteedToCorrespondToSIL,
1694-
*IRModule.getModule()))
1718+
if (validateTBDIfNeeded(Invocation, MSF, *IRModule.getModule()))
16951719
return true;
16961720

16971721
return generateCode(Invocation, Instance, OutputFilename,

0 commit comments

Comments
 (0)