Skip to content

Commit 4fc9d01

Browse files
authored
Merge pull request #40107 from ahoppen/pr/load-stdlib-in-setup
[Frontend] Load standard libarary in CompilerInstance::setup
2 parents 088c540 + 22f67e8 commit 4fc9d01

35 files changed

+317
-175
lines changed

include/swift/Frontend/Frontend.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,9 @@ class CompilerInvocation {
351351
if (FrontendOpts.InputMode == FrontendOptions::ParseInputMode::SIL) {
352352
return ImplicitStdlibKind::None;
353353
}
354+
if (FrontendOpts.InputsAndOutputs.shouldTreatAsLLVM()) {
355+
return ImplicitStdlibKind::None;
356+
}
354357
if (getParseStdlib()) {
355358
return ImplicitStdlibKind::Builtin;
356359
}
@@ -572,7 +575,7 @@ class CompilerInstance {
572575
}
573576

574577
/// Returns true if there was an error during setup.
575-
bool setup(const CompilerInvocation &Invocation);
578+
bool setup(const CompilerInvocation &Invocation, std::string &Error);
576579

577580
const CompilerInvocation &getInvocation() const { return Invocation; }
578581

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;

include/swift/IDE/Utils.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/Effects.h"
2121
#include "swift/AST/Module.h"
2222
#include "swift/AST/ASTPrinter.h"
23+
#include "swift/Frontend/FrontendOptions.h"
2324
#include "swift/IDE/SourceEntityWalker.h"
2425
#include "swift/Parse/Token.h"
2526
#include "llvm/ADT/StringRef.h"
@@ -85,7 +86,8 @@ SourceCompleteResult isSourceInputComplete(StringRef Text, SourceFileKind SFKind
8586

8687
bool initCompilerInvocation(
8788
CompilerInvocation &Invocation, ArrayRef<const char *> OrigArgs,
88-
DiagnosticEngine &Diags, StringRef UnresolvedPrimaryFile,
89+
FrontendOptions::ActionType Action, DiagnosticEngine &Diags,
90+
StringRef UnresolvedPrimaryFile,
8991
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
9092
const std::string &runtimeResourcePath,
9193
const std::string &diagnosticDocumentationPath, time_t sessionTimestamp,

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.

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1682,7 +1682,8 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
16821682

16831683
ForwardingDiagnosticConsumer FDC(*Diags);
16841684
subInstance.addDiagnosticConsumer(&FDC);
1685-
if (subInstance.setup(subInvocation)) {
1685+
std::string InstanceSetupError;
1686+
if (subInstance.setup(subInvocation, InstanceSetupError)) {
16861687
return std::make_error_code(std::errc::not_supported);
16871688
}
16881689

lib/FrontendTool/FrontendTool.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,17 +1254,6 @@ static bool performCompile(CompilerInstance &Instance,
12541254
if (opts.InputsAndOutputs.shouldTreatAsLLVM())
12551255
return compileLLVMIR(Instance);
12561256

1257-
// If we aren't in a parse-only context and expect an implicit stdlib import,
1258-
// load in the standard library. If we either fail to find it or encounter an
1259-
// error while loading it, bail early. Continuing the compilation will at best
1260-
// trigger a bunch of other errors due to the stdlib being missing, or at
1261-
// worst crash downstream as many call sites don't currently handle a missing
1262-
// stdlib.
1263-
if (FrontendOptions::doesActionRequireSwiftStandardLibrary(Action)) {
1264-
if (Instance.loadStdlibIfNeeded())
1265-
return true;
1266-
}
1267-
12681257
assert([&]() -> bool {
12691258
if (FrontendOptions::shouldActionOnlyParse(Action)) {
12701259
// Parsing gets triggered lazily, but let's make sure we have the right
@@ -2044,7 +2033,8 @@ int swift::performFrontend(ArrayRef<const char *> Args,
20442033
const DiagnosticOptions &diagOpts = Invocation.getDiagnosticOptions();
20452034
bool verifierEnabled = diagOpts.VerifyMode != DiagnosticOptions::NoVerify;
20462035

2047-
if (Instance->setup(Invocation)) {
2036+
std::string InstanceSetupError;
2037+
if (Instance->setup(Invocation, InstanceSetupError)) {
20482038
return finishDiagProcessing(1, /*verifierEnabled*/ false);
20492039
}
20502040

lib/IDE/CompletionInstance.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -561,23 +561,15 @@ void CompletionInstance::performNewOperation(
561561

562562
Invocation.setCodeCompletionPoint(completionBuffer, Offset);
563563

564-
if (CI.setup(Invocation)) {
564+
std::string InstanceSetupError;
565+
if (CI.setup(Invocation, InstanceSetupError)) {
565566
Callback(CancellableResult<CompletionInstanceResult>::failure(
566-
"failed to setup compiler instance"));
567+
InstanceSetupError));
567568
return;
568569
}
569570
CI.getASTContext().CancellationFlag = CancellationFlag;
570571
registerIDERequestFunctions(CI.getASTContext().evaluator);
571572

572-
// If we're expecting a standard library, but there either isn't one, or it
573-
// failed to load, let's bail early and hand back an empty completion
574-
// result to avoid any downstream crashes.
575-
if (CI.loadStdlibIfNeeded()) {
576-
Callback(CancellableResult<CompletionInstanceResult>::failure(
577-
"failed to load the standard library"));
578-
return;
579-
}
580-
581573
CI.performParseAndResolveImportsOnly();
582574

583575
bool DidFindCodeCompletionToken = CI.getCodeCompletionFile()

lib/IDE/Refactoring.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,8 +1200,9 @@ getNotableRegions(StringRef SourceText, unsigned NameOffset, StringRef Name,
12001200
Invocation.getLangOptions().DisablePoundIfEvaluation = true;
12011201

12021202
auto Instance = std::make_unique<swift::CompilerInstance>();
1203-
if (Instance->setup(Invocation))
1204-
llvm_unreachable("Failed setup");
1203+
std::string InstanceSetupError;
1204+
if (Instance->setup(Invocation, InstanceSetupError))
1205+
llvm_unreachable(InstanceSetupError.c_str());
12051206

12061207
unsigned BufferId = Instance->getPrimarySourceFile()->getBufferID().getValue();
12071208
SourceManager &SM = Instance->getSourceMgr();

lib/IDE/Utils.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ class StreamDiagConsumer : public DiagnosticConsumer {
273273

274274
bool ide::initCompilerInvocation(
275275
CompilerInvocation &Invocation, ArrayRef<const char *> OrigArgs,
276-
DiagnosticEngine &Diags, StringRef UnresolvedPrimaryFile,
276+
FrontendOptions::ActionType Action, DiagnosticEngine &Diags,
277+
StringRef UnresolvedPrimaryFile,
277278
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
278279
const std::string &runtimeResourcePath,
279280
const std::string &diagnosticDocumentationPath, time_t sessionTimestamp,

lib/Migrator/Migrator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ Migrator::performAFixItMigration(version::Version SwiftLanguageVersion) {
152152
// rdar://78576743 - Reset LLVM global state for command-line arguments set
153153
// by prior calls to setup.
154154
llvm::cl::ResetAllOptionOccurrences();
155-
if (Instance->setup(Invocation)) {
155+
std::string InstanceSetupError;
156+
if (Instance->setup(Invocation, InstanceSetupError)) {
156157
return nullptr;
157158
}
158159

test/SourceKit/CodeComplete/complete_without_stdlib.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ class Str {
1616
// RUN: -req=complete -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk == \
1717
// RUN: -req=complete -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk 2>&1 | %FileCheck %s
1818

19-
// CHECK: error response (Request Failed): failed to load the standard library
19+
// CHECK: error response (Request Failed): Loading the standard library failed

0 commit comments

Comments
 (0)