Skip to content

Commit 63c3103

Browse files
committed
[Frontend] Load standard libarary in CompilerInstance::setup
Instead of checking that the stdlib can be loaded in a variety of places, check it when setting up the compiler instance. This required a couple more checks to avoid loading the stdlib in cases where it’s not needed. To be able to differentiate stdlib loading failures from other setup errors, make `CompilerInstance::setup` return an error message on failure via an inout parameter. Consume that error on the call side, replacing a previous, more generic error message, adding error handling where appropriate or ignoring the error message, depending on the context.
1 parent 5a6341b commit 63c3103

29 files changed

+224
-105
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,9 @@ class CompilerInvocation {
341341
if (FrontendOpts.InputMode == FrontendOptions::ParseInputMode::SIL) {
342342
return ImplicitStdlibKind::None;
343343
}
344+
if (FrontendOpts.InputsAndOutputs.shouldTreatAsLLVM()) {
345+
return ImplicitStdlibKind::None;
346+
}
344347
if (getParseStdlib()) {
345348
return ImplicitStdlibKind::Builtin;
346349
}
@@ -562,7 +565,7 @@ class CompilerInstance {
562565
}
563566

564567
/// Returns true if there was an error during setup.
565-
bool setup(const CompilerInvocation &Invocation);
568+
bool setup(const CompilerInvocation &Invocation, std::string &Error);
566569

567570
const CompilerInvocation &getInvocation() const { return Invocation; }
568571

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ struct ModuleInterfaceLoaderOptions {
313313
case FrontendOptions::ActionType::TypecheckModuleFromInterface:
314314
requestedAction = FrontendOptions::ActionType::Typecheck;
315315
break;
316+
case FrontendOptions::ActionType::ScanDependencies:
317+
requestedAction = Opts.RequestedAction;
318+
break;
316319
default:
317320
requestedAction = FrontendOptions::ActionType::EmitModuleOnly;
318321
break;

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,8 +2247,9 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx,
22472247
// The PrintDiags is only responsible compiler errors, we should remove the
22482248
// consumer immediately after importing is done.
22492249
SWIFT_DEFER { CI.getDiags().removeConsumer(PrintDiags); };
2250-
if (CI.setup(Invocation)) {
2251-
llvm::errs() << "Failed to setup the compiler instance\n";
2250+
std::string InstanceSetupError;
2251+
if (CI.setup(Invocation, InstanceSetupError)) {
2252+
llvm::errs() << InstanceSetupError << '\n';
22522253
return nullptr;
22532254
}
22542255

lib/DependencyScan/DependencyScanningTool.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,10 @@ DependencyScanningTool::initCompilerInstanceForScan(
194194
}
195195

196196
// Setup the instance
197-
Instance->setup(Invocation);
197+
std::string InstanceSetupError;
198+
if (Instance->setup(Invocation, InstanceSetupError)) {
199+
return std::make_error_code(std::errc::not_supported);
200+
}
198201
(void)Instance->getMainModule();
199202

200203
return Instance;

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,8 @@ forEachBatchEntry(CompilerInstance &invocationInstance,
10931093
SourceLoc(), diag::scanner_arguments_invalid, entry.arguments);
10941094
return true;
10951095
}
1096-
if (pInstance->setup(subInvok)) {
1096+
std::string InstanceSetupError;
1097+
if (pInstance->setup(subInvok, InstanceSetupError)) {
10971098
invocationInstance.getDiags().diagnose(
10981099
SourceLoc(), diag::scanner_arguments_invalid, entry.arguments);
10991100
return true;

lib/DriverTool/swift_api_digester_main.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1849,8 +1849,10 @@ static bool readBreakageAllowlist(SDKContext &Ctx, llvm::StringSet<> &lines,
18491849
CompilerInstance instance;
18501850
CompilerInvocation invok;
18511851
invok.setModuleName("ForClangImporter");
1852-
if (instance.setup(invok))
1852+
std::string InstanceSetupError;
1853+
if (instance.setup(invok, InstanceSetupError)) {
18531854
return 1;
1855+
}
18541856
auto importer = ClangImporter::create(instance.getASTContext());
18551857
SmallString<128> preprocessedFilePath;
18561858
if (auto error = llvm::sys::fs::createTemporaryFile(

lib/DriverTool/swift_api_extract_main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,9 @@ class SwiftAPIExtractInvocation {
197197
}
198198

199199
int extractAPI() {
200-
if (Instance.setup(Invocation)) {
201-
llvm::outs() << "Failed to setup compiler instance\n";
200+
std::string InstanceSetupError;
201+
if (Instance.setup(Invocation, InstanceSetupError)) {
202+
llvm::outs() << InstanceSetupError << '\n';
202203
return 1;
203204
}
204205

lib/DriverTool/swift_symbolgraph_extract_main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,9 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args,
182182
.Default(AccessLevel::Public);
183183
}
184184

185-
if (CI.setup(Invocation)) {
186-
llvm::outs() << "Failed to setup compiler instance\n";
185+
std::string InstanceSetupError;
186+
if (CI.setup(Invocation, InstanceSetupError)) {
187+
llvm::outs() << InstanceSetupError << '\n';
187188
return EXIT_FAILURE;
188189
}
189190

lib/Frontend/Frontend.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,30 +357,49 @@ void CompilerInstance::setupDependencyTrackerIfNeeded() {
357357
DepTracker = std::make_unique<DependencyTracker>(*collectionMode);
358358
}
359359

360-
bool CompilerInstance::setup(const CompilerInvocation &Invok) {
360+
bool CompilerInstance::setup(const CompilerInvocation &Invok,
361+
std::string &Error) {
361362
Invocation = Invok;
362363

363364
setupDependencyTrackerIfNeeded();
364365

365366
// If initializing the overlay file system fails there's no sense in
366367
// continuing because the compiler will read the wrong files.
367-
if (setUpVirtualFileSystemOverlays())
368+
if (setUpVirtualFileSystemOverlays()) {
369+
Error = "Setting up virtual file system overlays failed";
368370
return true;
371+
}
369372
setUpLLVMArguments();
370373
setUpDiagnosticOptions();
371374

372375
assert(Lexer::isIdentifier(Invocation.getModuleName()));
373376

374-
if (setUpInputs())
377+
if (setUpInputs()) {
378+
Error = "Setting up inputs failed";
375379
return true;
380+
}
376381

377-
if (setUpASTContextIfNeeded())
382+
if (setUpASTContextIfNeeded()) {
383+
Error = "Setting up ASTContext failed";
378384
return true;
385+
}
379386

380387
setupStatsReporter();
381388

382-
if (setupDiagnosticVerifierIfNeeded())
389+
if (setupDiagnosticVerifierIfNeeded()) {
390+
Error = "Setting up diagnostics verified failed";
383391
return true;
392+
}
393+
394+
// If we expect an implicit stdlib import, load in the standard library. If we
395+
// either fail to find it or encounter an error while loading it, bail early. Continuing will at best
396+
// trigger a bunch of other errors due to the stdlib being missing, or at
397+
// worst crash downstream as many call sites don't currently handle a missing
398+
// stdlib.
399+
if (loadStdlibIfNeeded()) {
400+
Error = "Loading the standard library failed";
401+
return true;
402+
}
384403

385404
return false;
386405
}
@@ -1101,6 +1120,10 @@ void CompilerInstance::performSema() {
11011120
}
11021121

11031122
bool CompilerInstance::loadStdlibIfNeeded() {
1123+
if (!FrontendOptions::doesActionRequireSwiftStandardLibrary(
1124+
Invocation.getFrontendOptions().RequestedAction)) {
1125+
return false;
1126+
}
11041127
// If we aren't expecting an implicit stdlib import, there's nothing to do.
11051128
if (getImplicitImportInfo().StdlibKind != ImplicitStdlibKind::Stdlib)
11061129
return false;

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,6 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
218218
InputInfo.getPrimarySpecificPaths().SupplementaryOutputs;
219219
StringRef OutPath = OutputInfo.ModuleOutputPath;
220220

221-
// Bail out if we're going to use the standard library but can't load it. If
222-
// we don't do this before we try to build the interface, we could end up
223-
// trying to rebuild a broken standard library dozens of times due to
224-
// multiple calls to `ASTContext::getStdlibModule()`.
225-
if (SubInstance.loadStdlibIfNeeded())
226-
return std::make_error_code(std::errc::not_supported);
227-
228221
// Build the .swiftmodule; this is a _very_ abridged version of the logic
229222
// in performCompile in libFrontendTool, specialized, to just the one
230223
// module-serialization task we're trying to do here.

0 commit comments

Comments
 (0)