Skip to content

Commit 4b7bf3a

Browse files
committed
[Dependency Scanning] Emit diagnostics from compilation instance initialization
1 parent 55d4a56 commit 4b7bf3a

File tree

5 files changed

+117
-93
lines changed

5 files changed

+117
-93
lines changed

include/swift/DependencyScan/DependencyScanningTool.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class DependencyScanDiagnosticCollector;
2828

2929
struct ScanQueryInstance {
3030
std::unique_ptr<CompilerInstance> ScanInstance;
31-
std::unique_ptr<DependencyScanDiagnosticCollector> ScanDiagnostics;
31+
std::shared_ptr<DependencyScanDiagnosticCollector> ScanDiagnostics;
3232
};
3333

3434
/// Diagnostic consumer that simply collects the diagnostics emitted so-far
@@ -124,15 +124,10 @@ class DependencyScanningTool {
124124
/// that will be used for this scan.
125125
llvm::ErrorOr<ScanQueryInstance>
126126
initCompilerInstanceForScan(ArrayRef<const char *> Command,
127-
StringRef WorkingDirectory);
127+
StringRef WorkingDirectory,
128+
std::shared_ptr<DependencyScanDiagnosticCollector> scannerDiagnosticsCollector);
128129

129130
private:
130-
/// Using the specified invocation command, initialize the scanner instance
131-
/// for this scan. Returns the `CompilerInstance` that will be used.
132-
llvm::ErrorOr<ScanQueryInstance>
133-
initScannerForAction(ArrayRef<const char *> Command,
134-
StringRef WorkingDirectory);
135-
136131
/// Shared cache of module dependencies, re-used by individual full-scan queries
137132
/// during the lifetime of this Tool.
138133
std::unique_ptr<SwiftDependencyScanningService> ScanningService;
@@ -150,6 +145,8 @@ class DependencyScanningTool {
150145
llvm::StringSaver Saver;
151146
};
152147

148+
swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(const DependencyScanDiagnosticCollector *diagnosticCollector);
149+
153150
} // end namespace dependencies
154151
} // end namespace swift
155152

lib/DependencyScan/DependencyScanningTool.cpp

Lines changed: 95 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,55 @@ void LockingDependencyScanDiagnosticCollector::addDiagnostic(
140140
DependencyScanDiagnosticCollector::addDiagnostic(SM, Info);
141141
}
142142

143+
swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
144+
const DependencyScanDiagnosticCollector *diagnosticCollector) {
145+
auto collectedDiagnostics = diagnosticCollector->getDiagnostics();
146+
auto numDiagnostics = collectedDiagnostics.size();
147+
swiftscan_diagnostic_set_t *diagnosticOutput = new swiftscan_diagnostic_set_t;
148+
diagnosticOutput->count = numDiagnostics;
149+
diagnosticOutput->diagnostics =
150+
new swiftscan_diagnostic_info_t[numDiagnostics];
151+
for (size_t i = 0; i < numDiagnostics; ++i) {
152+
const auto &Diagnostic = collectedDiagnostics[i];
153+
swiftscan_diagnostic_info_s *diagnosticInfo =
154+
new swiftscan_diagnostic_info_s;
155+
diagnosticInfo->message =
156+
swift::c_string_utils::create_clone(Diagnostic.Message.c_str());
157+
switch (Diagnostic.Severity) {
158+
case llvm::SourceMgr::DK_Error:
159+
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_ERROR;
160+
break;
161+
case llvm::SourceMgr::DK_Warning:
162+
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_WARNING;
163+
break;
164+
case llvm::SourceMgr::DK_Note:
165+
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_NOTE;
166+
break;
167+
case llvm::SourceMgr::DK_Remark:
168+
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_REMARK;
169+
break;
170+
}
171+
172+
if (Diagnostic.ImportLocation.has_value()) {
173+
auto importLocation = Diagnostic.ImportLocation.value();
174+
swiftscan_source_location_s *sourceLoc = new swiftscan_source_location_s;
175+
if (importLocation.bufferIdentifier.empty())
176+
sourceLoc->buffer_identifier = swift::c_string_utils::create_null();
177+
else
178+
sourceLoc->buffer_identifier = swift::c_string_utils::create_clone(
179+
importLocation.bufferIdentifier.c_str());
180+
sourceLoc->line_number = importLocation.lineNumber;
181+
sourceLoc->column_number = importLocation.columnNumber;
182+
diagnosticInfo->source_location = sourceLoc;
183+
} else {
184+
diagnosticInfo->source_location = nullptr;
185+
}
186+
187+
diagnosticOutput->diagnostics[i] = diagnosticInfo;
188+
}
189+
return diagnosticOutput;
190+
}
191+
143192
DependencyScanningTool::DependencyScanningTool()
144193
: ScanningService(std::make_unique<SwiftDependencyScanningService>()),
145194
VersionedPCMInstanceCacheCache(
@@ -148,12 +197,25 @@ DependencyScanningTool::DependencyScanningTool()
148197

149198
llvm::ErrorOr<swiftscan_dependency_graph_t>
150199
DependencyScanningTool::getDependencies(
151-
ArrayRef<const char *> Command, const llvm::StringSet<> &PlaceholderModules,
200+
ArrayRef<const char *> Command,
201+
const llvm::StringSet<> &PlaceholderModules,
152202
StringRef WorkingDirectory) {
203+
// There may be errors as early as in instance initialization, so we must ensure
204+
// we can catch those.
205+
auto ScanDiagnosticConsumer = std::make_shared<DependencyScanDiagnosticCollector>();
206+
auto produceDiagnosticStateOnFailure = [&ScanDiagnosticConsumer]() {
207+
swiftscan_dependency_graph_t result = new swiftscan_dependency_graph_s;
208+
result->diagnostics = mapCollectedDiagnosticsForOutput(ScanDiagnosticConsumer.get());
209+
return result;
210+
};
211+
153212
// The primary instance used to scan the query Swift source-code
154-
auto QueryContextOrErr = initScannerForAction(Command, WorkingDirectory);
155-
if (std::error_code EC = QueryContextOrErr.getError())
156-
return EC;
213+
auto QueryContextOrErr = initCompilerInstanceForScan(Command,
214+
WorkingDirectory,
215+
ScanDiagnosticConsumer);
216+
if (QueryContextOrErr.getError())
217+
return produceDiagnosticStateOnFailure();
218+
157219
auto QueryContext = std::move(*QueryContextOrErr);
158220

159221
// Local scan cache instance, wrapping the shared global cache.
@@ -166,19 +228,26 @@ DependencyScanningTool::getDependencies(
166228
QueryContext.ScanDiagnostics.get(),
167229
cache);
168230
if (DependenciesOrErr.getError())
169-
return std::make_error_code(std::errc::not_supported);
170-
auto Dependencies = std::move(*DependenciesOrErr);
231+
return produceDiagnosticStateOnFailure();
171232

172-
return Dependencies;
233+
return std::move(*DependenciesOrErr);;
173234
}
174235

175236
llvm::ErrorOr<swiftscan_import_set_t>
176237
DependencyScanningTool::getImports(ArrayRef<const char *> Command,
177238
StringRef WorkingDirectory) {
239+
// There may be errors as early as in instance initialization, so we must ensure
240+
// we can catch those
241+
auto ScanDiagnosticConsumer = std::make_shared<DependencyScanDiagnosticCollector>();
178242
// The primary instance used to scan the query Swift source-code
179-
auto QueryContextOrErr = initScannerForAction(Command, WorkingDirectory);
180-
if (std::error_code EC = QueryContextOrErr.getError())
181-
return EC;
243+
auto QueryContextOrErr = initCompilerInstanceForScan(Command,
244+
WorkingDirectory,
245+
ScanDiagnosticConsumer);
246+
if (QueryContextOrErr.getError()) {
247+
swiftscan_import_set_t result = new swiftscan_import_set_s;
248+
result->diagnostics = mapCollectedDiagnosticsForOutput(ScanDiagnosticConsumer.get());
249+
return result;
250+
}
182251
auto QueryContext = std::move(*QueryContextOrErr);
183252

184253
// Local scan cache instance, wrapping the shared global cache.
@@ -202,10 +271,14 @@ DependencyScanningTool::getDependencies(
202271
const std::vector<BatchScanInput> &BatchInput,
203272
const llvm::StringSet<> &PlaceholderModules, StringRef WorkingDirectory) {
204273
// The primary instance used to scan Swift modules
205-
auto QueryContextOrErr = initScannerForAction(Command, WorkingDirectory);
274+
auto ScanDiagnosticConsumer = std::make_shared<DependencyScanDiagnosticCollector>();
275+
auto QueryContextOrErr = initCompilerInstanceForScan(Command,
276+
WorkingDirectory,
277+
ScanDiagnosticConsumer);
206278
if (std::error_code EC = QueryContextOrErr.getError())
207279
return std::vector<llvm::ErrorOr<swiftscan_dependency_graph_t>>(
208280
BatchInput.size(), std::make_error_code(std::errc::invalid_argument));
281+
209282
auto QueryContext = std::move(*QueryContextOrErr);
210283

211284
// Local scan cache instance, wrapping the shared global cache.
@@ -264,26 +337,26 @@ void DependencyScanningTool::resetDiagnostics() {
264337
}
265338

266339
llvm::ErrorOr<ScanQueryInstance>
267-
DependencyScanningTool::initScannerForAction(
268-
ArrayRef<const char *> Command, StringRef WorkingDirectory) {
340+
DependencyScanningTool::initCompilerInstanceForScan(
341+
ArrayRef<const char *> CommandArgs,
342+
StringRef WorkingDir,
343+
std::shared_ptr<DependencyScanDiagnosticCollector> scannerDiagnosticsCollector) {
269344
// The remainder of this method operates on shared state in the
270345
// scanning service and global LLVM state with:
271346
// llvm::cl::ResetAllOptionOccurrences
272347
llvm::sys::SmartScopedLock<true> Lock(DependencyScanningToolStateLock);
273-
return initCompilerInstanceForScan(Command, WorkingDirectory);
274-
}
348+
// FIXME: Instead, target-info and supported-features queries must use
349+
// `DependencyScanningToolStateLock`, but this currently requires further
350+
// client-side API plumbing.
351+
llvm::sys::SmartScopedLock<true> TargetInfoLock(TargetInfoMutex);
275352

276-
llvm::ErrorOr<ScanQueryInstance>
277-
DependencyScanningTool::initCompilerInstanceForScan(
278-
ArrayRef<const char *> CommandArgs, StringRef WorkingDir) {
279353
// State unique to an individual scan
280354
auto Instance = std::make_unique<CompilerInstance>();
281-
auto ScanDiagnosticConsumer = std::make_unique<DependencyScanDiagnosticCollector>();
282355

283356
// FIXME: The shared CDC must be deprecated once all clients have switched
284357
// to using per-scan diagnostic output embedded in the `swiftscan_dependency_graph_s`
285358
Instance->addDiagnosticConsumer(&CDC);
286-
Instance->addDiagnosticConsumer(ScanDiagnosticConsumer.get());
359+
Instance->addDiagnosticConsumer(scannerDiagnosticsCollector.get());
287360

288361
// Basic error checking on the arguments
289362
if (CommandArgs.empty()) {
@@ -327,6 +400,7 @@ DependencyScanningTool::initCompilerInstanceForScan(
327400
if (Instance->setup(Invocation, InstanceSetupError)) {
328401
return std::make_error_code(std::errc::not_supported);
329402
}
403+
Invocation.getFrontendOptions().LLVMArgs.clear();
330404

331405
// Setup the caching service after the instance finishes setup.
332406
if (ScanningService->setupCachingDependencyScanningService(*Instance))
@@ -335,7 +409,7 @@ DependencyScanningTool::initCompilerInstanceForScan(
335409
(void)Instance->getMainModule();
336410

337411
return ScanQueryInstance{std::move(Instance),
338-
std::move(ScanDiagnosticConsumer)};
412+
scannerDiagnosticsCollector};
339413
}
340414

341415
} // namespace dependencies

lib/DependencyScan/ModuleDependencyScanner.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
207207
ScanASTContext.getModuleInterfaceChecker()),
208208
&DependencyTracker,
209209
ScanCompilerInvocation.getSearchPathOptions().ModuleLoadMode);
210+
211+
llvm::cl::ResetAllOptionOccurrences();
210212
}
211213

212214
ModuleDependencyVector

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -589,56 +589,6 @@ static void bridgeDependencyIDs(const ArrayRef<ModuleDependencyID> dependencies,
589589
}
590590
}
591591

592-
static swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
593-
const SourceManager &SM,
594-
const DependencyScanDiagnosticCollector *diagnosticCollector) {
595-
auto collectedDiagnostics = diagnosticCollector->getDiagnostics();
596-
auto numDiagnostics = collectedDiagnostics.size();
597-
swiftscan_diagnostic_set_t *diagnosticOutput = new swiftscan_diagnostic_set_t;
598-
diagnosticOutput->count = numDiagnostics;
599-
diagnosticOutput->diagnostics =
600-
new swiftscan_diagnostic_info_t[numDiagnostics];
601-
for (size_t i = 0; i < numDiagnostics; ++i) {
602-
const auto &Diagnostic = collectedDiagnostics[i];
603-
swiftscan_diagnostic_info_s *diagnosticInfo =
604-
new swiftscan_diagnostic_info_s;
605-
diagnosticInfo->message =
606-
swift::c_string_utils::create_clone(Diagnostic.Message.c_str());
607-
switch (Diagnostic.Severity) {
608-
case llvm::SourceMgr::DK_Error:
609-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_ERROR;
610-
break;
611-
case llvm::SourceMgr::DK_Warning:
612-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_WARNING;
613-
break;
614-
case llvm::SourceMgr::DK_Note:
615-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_NOTE;
616-
break;
617-
case llvm::SourceMgr::DK_Remark:
618-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_REMARK;
619-
break;
620-
}
621-
622-
if (Diagnostic.ImportLocation.has_value()) {
623-
auto importLocation = Diagnostic.ImportLocation.value();
624-
swiftscan_source_location_s *sourceLoc = new swiftscan_source_location_s;
625-
if (importLocation.bufferIdentifier.empty())
626-
sourceLoc->buffer_identifier = swift::c_string_utils::create_null();
627-
else
628-
sourceLoc->buffer_identifier = swift::c_string_utils::create_clone(
629-
importLocation.bufferIdentifier.c_str());
630-
sourceLoc->line_number = importLocation.lineNumber;
631-
sourceLoc->column_number = importLocation.columnNumber;
632-
diagnosticInfo->source_location = sourceLoc;
633-
} else {
634-
diagnosticInfo->source_location = nullptr;
635-
}
636-
637-
diagnosticOutput->diagnostics[i] = diagnosticInfo;
638-
}
639-
return diagnosticOutput;
640-
}
641-
642592
static swiftscan_macro_dependency_set_t *createMacroDependencySet(
643593
const std::map<std::string, MacroPluginDependency> &macroDeps) {
644594
swiftscan_macro_dependency_set_t *set = new swiftscan_macro_dependency_set_t;
@@ -867,8 +817,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
867817
result->dependencies = dependencySet;
868818
result->diagnostics =
869819
diagnosticCollector
870-
? mapCollectedDiagnosticsForOutput(instance.getSourceMgr(),
871-
diagnosticCollector)
820+
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
872821
: nullptr;
873822
return result;
874823
}
@@ -1574,13 +1523,11 @@ swift::dependencies::performModulePrescan(CompilerInstance &instance,
15741523
importSet->imports = create_set(importIdentifiers);
15751524
importSet->diagnostics =
15761525
diagnosticCollector
1577-
? mapCollectedDiagnosticsForOutput(instance.getSourceMgr(),
1578-
diagnosticCollector)
1526+
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
15791527
: nullptr;
15801528
importSet->diagnostics =
15811529
diagnosticCollector
1582-
? mapCollectedDiagnosticsForOutput(instance.getSourceMgr(),
1583-
diagnosticCollector)
1530+
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
15841531
: nullptr;
15851532
return importSet;
15861533
}

tools/libSwiftScan/libSwiftScan.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,13 @@ void swiftscan_dependency_info_dispose(swiftscan_dependency_info_t info) {
126126
}
127127

128128
void swiftscan_dependency_set_dispose(swiftscan_dependency_set_t *set) {
129-
for (size_t i = 0; i < set->count; ++i) {
130-
swiftscan_dependency_info_dispose(set->modules[i]);
129+
if (set) {
130+
for (size_t i = 0; i < set->count; ++i) {
131+
swiftscan_dependency_info_dispose(set->modules[i]);
132+
}
133+
delete[] set->modules;
134+
delete set;
131135
}
132-
delete[] set->modules;
133-
delete set;
134136
}
135137

136138
//=== Scanner Cache Operations --------------------------------------------===//
@@ -753,11 +755,13 @@ void swiftscan_diagnostic_dispose(swiftscan_diagnostic_info_t diagnostic) {
753755

754756
void
755757
swiftscan_diagnostics_set_dispose(swiftscan_diagnostic_set_t* diagnostics){
756-
for (size_t i = 0; i < diagnostics->count; ++i) {
757-
swiftscan_diagnostic_dispose(diagnostics->diagnostics[i]);
758+
if (diagnostics) {
759+
for (size_t i = 0; i < diagnostics->count; ++i) {
760+
swiftscan_diagnostic_dispose(diagnostics->diagnostics[i]);
761+
}
762+
delete[] diagnostics->diagnostics;
763+
delete diagnostics;
758764
}
759-
delete[] diagnostics->diagnostics;
760-
delete diagnostics;
761765
}
762766

763767
//=== Source Location -----------------------------------------------------===//

0 commit comments

Comments
 (0)