@@ -73,7 +73,7 @@ void ThreadSafeDiagnosticCollector::handleDiagnostic(SourceManager &SM,
7373 }
7474}
7575
76- void DependencyScanDiagnosticCollector ::addDiagnostic (
76+ void DepScanInMemoryDiagnosticCollector ::addDiagnostic (
7777 SourceManager &SM, const DiagnosticInfo &Info) {
7878 // Determine what kind of diagnostic we're emitting.
7979 llvm::SourceMgr::DiagKind SMKind;
@@ -131,7 +131,7 @@ void DependencyScanDiagnosticCollector::addDiagnostic(
131131}
132132
133133swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput (
134- const DependencyScanDiagnosticCollector *diagnosticCollector) {
134+ const DepScanInMemoryDiagnosticCollector *diagnosticCollector) {
135135 auto collectedDiagnostics = diagnosticCollector->getDiagnostics ();
136136 auto numDiagnostics = collectedDiagnostics.size ();
137137 swiftscan_diagnostic_set_t *diagnosticOutput = new swiftscan_diagnostic_set_t ;
@@ -183,7 +183,7 @@ swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
183183// module dependnecies but captures the diagnostics emitted during the attempted
184184// scan query.
185185static swiftscan_dependency_graph_t generateHollowDiagnosticOutput (
186- const DependencyScanDiagnosticCollector &ScanDiagnosticConsumer) {
186+ const DepScanInMemoryDiagnosticCollector &ScanDiagnosticConsumer) {
187187 // Create a dependency graph instance
188188 swiftscan_dependency_graph_t hollowResult = new swiftscan_dependency_graph_s;
189189
@@ -254,7 +254,7 @@ static swiftscan_dependency_graph_t generateHollowDiagnosticOutput(
254254// imports but captures the diagnostics emitted during the attempted
255255// scan query.
256256static swiftscan_import_set_t generateHollowDiagnosticOutputImportSet (
257- const DependencyScanDiagnosticCollector &ScanDiagnosticConsumer) {
257+ const DepScanInMemoryDiagnosticCollector &ScanDiagnosticConsumer) {
258258 // Create an dependency graph instance
259259 swiftscan_import_set_t hollowResult = new swiftscan_import_set_s;
260260 hollowResult->imports = c_string_utils::create_empty_set ();
@@ -268,72 +268,57 @@ DependencyScanningTool::DependencyScanningTool()
268268 Alloc (), Saver(Alloc) {}
269269
270270llvm::ErrorOr<swiftscan_dependency_graph_t >
271- DependencyScanningTool::getDependencies (
272- ArrayRef<const char *> Command,
273- StringRef WorkingDirectory) {
274- // There may be errors as early as in instance initialization, so we must ensure
275- // we can catch those.
276- auto ScanDiagnosticConsumer =
277- std::make_shared<DependencyScanDiagnosticCollector>();
278-
271+ DependencyScanningTool::getDependencies (ArrayRef<const char *> Command,
272+ StringRef WorkingDirectory) {
279273 // The primary instance used to scan the query Swift source-code
280- auto QueryContextOrErr = initCompilerInstanceForScan (Command,
281- WorkingDirectory,
282- ScanDiagnosticConsumer);
283- if (QueryContextOrErr.getError ())
284- return generateHollowDiagnosticOutput (*ScanDiagnosticConsumer);
285-
286- auto QueryContext = std::move (*QueryContextOrErr);
274+ auto QueryContext = createScanQueryContext (Command, WorkingDirectory);
275+ if (QueryContext.ScanInstance .getError ())
276+ return generateHollowDiagnosticOutput (
277+ *QueryContext.InMemoryDiagnosticCollector );
278+ auto ScanInstance = QueryContext.ScanInstance ->get ();
287279
288280 // Local scan cache instance, wrapping the shared global cache.
289281 ModuleDependenciesCache cache (
290- QueryContext. ScanInstance ->getMainModule ()->getNameStr ().str (),
291- QueryContext. ScanInstance ->getInvocation ().getModuleScanningHash ());
282+ ScanInstance->getMainModule ()->getNameStr ().str (),
283+ ScanInstance->getInvocation ().getModuleScanningHash ());
292284 // Execute the scanning action, retrieving the in-memory result
293- auto DependenciesOrErr = performModuleScan (*ScanningService,
294- *QueryContext.ScanInstance .get (),
295- cache,
296- QueryContext.ScanDiagnostics .get ());
285+ auto DependenciesOrErr =
286+ performModuleScan (*ScanningService, cache, QueryContext);
287+
297288 if (DependenciesOrErr.getError ())
298- return generateHollowDiagnosticOutput (*ScanDiagnosticConsumer);
289+ return generateHollowDiagnosticOutput (
290+ *QueryContext.InMemoryDiagnosticCollector );
299291
300292 return std::move (*DependenciesOrErr);
301293}
302294
303295llvm::ErrorOr<swiftscan_import_set_t >
304296DependencyScanningTool::getImports (ArrayRef<const char *> Command,
305297 StringRef WorkingDirectory) {
306- // There may be errors as early as in instance initialization, so we must ensure
307- // we can catch those
308- auto ScanDiagnosticConsumer = std::make_shared<DependencyScanDiagnosticCollector>();
309298 // The primary instance used to scan the query Swift source-code
310- auto QueryContextOrErr = initCompilerInstanceForScan (Command,
311- WorkingDirectory,
312- ScanDiagnosticConsumer);
313- if (QueryContextOrErr.getError ())
314- return generateHollowDiagnosticOutputImportSet (*ScanDiagnosticConsumer);
315-
316- auto QueryContext = std::move (*QueryContextOrErr);
299+ auto QueryContext = createScanQueryContext (Command, WorkingDirectory);
300+ if (QueryContext.ScanInstance .getError ())
301+ return generateHollowDiagnosticOutputImportSet (
302+ *QueryContext.InMemoryDiagnosticCollector );
303+ auto ScanInstance = QueryContext.ScanInstance ->get ();
317304
318305 // Local scan cache instance, wrapping the shared global cache.
319306 ModuleDependenciesCache cache (
320- QueryContext. ScanInstance ->getMainModule ()->getNameStr ().str (),
321- QueryContext. ScanInstance ->getInvocation ().getModuleScanningHash ());
322- auto DependenciesOrErr = performModulePrescan (*ScanningService,
323- *QueryContext. ScanInstance . get (),
324- cache,
325- QueryContext. ScanDiagnostics . get ());
307+ ScanInstance->getMainModule ()->getNameStr ().str (),
308+ ScanInstance->getInvocation ().getModuleScanningHash ());
309+ // Execute the pre-scanning action, retrieving the in-memory result
310+ auto DependenciesOrErr =
311+ performModulePrescan (*ScanningService, cache, QueryContext);
312+
326313 if (DependenciesOrErr.getError ())
327- return generateHollowDiagnosticOutputImportSet (*ScanDiagnosticConsumer);
314+ return generateHollowDiagnosticOutputImportSet (
315+ *QueryContext.InMemoryDiagnosticCollector );
328316
329317 return std::move (*DependenciesOrErr);
330318}
331319
332- llvm::ErrorOr<ScanQueryInstance>
333- DependencyScanningTool::initCompilerInstanceForScan (
334- ArrayRef<const char *> CommandArgs,
335- StringRef WorkingDir,
336- std::shared_ptr<DependencyScanDiagnosticCollector> scannerDiagnosticsCollector) {
320+ ScanQueryContext DependencyScanningTool::createScanQueryContext (
321+ ArrayRef<const char *> CommandArgs, StringRef WorkingDir) {
337322 // The remainder of this method operates on shared state in the
338323 // scanning service
339324 llvm::sys::SmartScopedLock<true > Lock (DependencyScanningToolStateLock);
@@ -342,14 +327,20 @@ DependencyScanningTool::initCompilerInstanceForScan(
342327 // client-side API plumbing.
343328 llvm::sys::SmartScopedLock<true > TargetInfoLock (TargetInfoMutex);
344329
330+ // There may be errors as early as in instance initialization, so we must
331+ // ensure we can catch those
332+ auto ScannerDiagnosticsCollector =
333+ std::make_unique<DepScanInMemoryDiagnosticCollector>();
334+
345335 // State unique to an individual scan
346336 auto Instance = std::make_unique<CompilerInstance>();
347- Instance->addDiagnosticConsumer (scannerDiagnosticsCollector .get ());
337+ Instance->addDiagnosticConsumer (ScannerDiagnosticsCollector .get ());
348338
349339 // Basic error checking on the arguments
350340 if (CommandArgs.empty ()) {
351341 Instance->getDiags ().diagnose (SourceLoc (), diag::error_no_frontend_args);
352- return std::make_error_code (std::errc::invalid_argument);
342+ return ScanQueryContext{std::make_error_code (std::errc::invalid_argument),
343+ std::move (ScannerDiagnosticsCollector), nullptr };
353344 }
354345
355346 CompilerInvocation Invocation;
@@ -375,24 +366,39 @@ DependencyScanningTool::initCompilerInstanceForScan(
375366
376367 if (Invocation.parseArgs (Args, Instance->getDiags (),
377368 nullptr , WorkingDirectory, " /tmp/foo" )) {
378- return std::make_error_code (std::errc::invalid_argument);
369+ return ScanQueryContext{std::make_error_code (std::errc::invalid_argument),
370+ std::move (ScannerDiagnosticsCollector), nullptr };
379371 }
380372
381373 // Setup the instance
382374 std::string InstanceSetupError;
383- if (Instance->setup (Invocation, InstanceSetupError)) {
384- return std::make_error_code (std::errc::not_supported);
385- }
375+ if (Instance->setup (Invocation, InstanceSetupError))
376+ return ScanQueryContext{std::make_error_code (std::errc::not_supported),
377+ std::move (ScannerDiagnosticsCollector), nullptr };
378+
386379 Invocation.getFrontendOptions ().LLVMArgs .clear ();
387380
388381 // Setup the caching service after the instance finishes setup.
389382 if (ScanningService->setupCachingDependencyScanningService (*Instance))
390- return std::make_error_code (std::errc::invalid_argument);
383+ return ScanQueryContext{std::make_error_code (std::errc::invalid_argument),
384+ std::move (ScannerDiagnosticsCollector), nullptr };
391385
392386 (void )Instance->getMainModule ();
393387
394- return ScanQueryInstance{std::move (Instance),
395- scannerDiagnosticsCollector};
388+ auto SerializedDiagnosticsOutputPath =
389+ Instance->getInvocation ()
390+ .getSerializedDiagnosticsPathForAtMostOnePrimary ();
391+ std::unique_ptr<DiagnosticConsumer> SerailizedDiagnosticsConsumer;
392+ if (!SerializedDiagnosticsOutputPath.empty ()) {
393+ SerailizedDiagnosticsConsumer =
394+ swift::serialized_diagnostics::createThreadSafeConsumer (
395+ SerializedDiagnosticsOutputPath, false );
396+ Instance->addDiagnosticConsumer (SerailizedDiagnosticsConsumer.get ());
397+ }
398+
399+ return ScanQueryContext{std::move (Instance),
400+ std::move (ScannerDiagnosticsCollector),
401+ std::move (SerailizedDiagnosticsConsumer)};
396402}
397403
398404} // namespace dependencies
0 commit comments