Skip to content

Commit f9bc227

Browse files
committed
[Dependency Scanning] Emit diagnostics from compilation instance initialization
1 parent c43fa37 commit f9bc227

File tree

5 files changed

+136
-90
lines changed

5 files changed

+136
-90
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
@@ -195,6 +195,8 @@ ModuleDependencyScanningWorker::ModuleDependencyScanningWorker(
195195
ScanASTContext.getModuleInterfaceChecker()),
196196
&DependencyTracker,
197197
ScanCompilerInvocation.getSearchPathOptions().ModuleLoadMode);
198+
199+
llvm::cl::ResetAllOptionOccurrences();
198200
}
199201

200202
ModuleDependencyVector

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -579,54 +579,26 @@ static void bridgeDependencyIDs(const ArrayRef<ModuleDependencyID> dependencies,
579579
}
580580
}
581581

582-
static swiftscan_diagnostic_set_t *mapCollectedDiagnosticsForOutput(
583-
const SourceManager &SM,
584-
const DependencyScanDiagnosticCollector *diagnosticCollector) {
585-
auto collectedDiagnostics = diagnosticCollector->getDiagnostics();
586-
auto numDiagnostics = collectedDiagnostics.size();
587-
swiftscan_diagnostic_set_t *diagnosticOutput = new swiftscan_diagnostic_set_t;
588-
diagnosticOutput->count = numDiagnostics;
589-
diagnosticOutput->diagnostics =
590-
new swiftscan_diagnostic_info_t[numDiagnostics];
591-
for (size_t i = 0; i < numDiagnostics; ++i) {
592-
const auto &Diagnostic = collectedDiagnostics[i];
593-
swiftscan_diagnostic_info_s *diagnosticInfo =
594-
new swiftscan_diagnostic_info_s;
595-
diagnosticInfo->message =
596-
swift::c_string_utils::create_clone(Diagnostic.Message.c_str());
597-
switch (Diagnostic.Severity) {
598-
case llvm::SourceMgr::DK_Error:
599-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_ERROR;
600-
break;
601-
case llvm::SourceMgr::DK_Warning:
602-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_WARNING;
603-
break;
604-
case llvm::SourceMgr::DK_Note:
605-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_NOTE;
606-
break;
607-
case llvm::SourceMgr::DK_Remark:
608-
diagnosticInfo->severity = SWIFTSCAN_DIAGNOSTIC_SEVERITY_REMARK;
609-
break;
610-
}
611-
612-
if (Diagnostic.ImportLocation.has_value()) {
613-
auto importLocation = Diagnostic.ImportLocation.value();
614-
swiftscan_source_location_s *sourceLoc = new swiftscan_source_location_s;
615-
if (importLocation.bufferIdentifier.empty())
616-
sourceLoc->buffer_identifier = swift::c_string_utils::create_null();
617-
else
618-
sourceLoc->buffer_identifier = swift::c_string_utils::create_clone(
619-
importLocation.bufferIdentifier.c_str());
620-
sourceLoc->line_number = importLocation.lineNumber;
621-
sourceLoc->column_number = importLocation.columnNumber;
622-
diagnosticInfo->source_location = sourceLoc;
623-
} else {
624-
diagnosticInfo->source_location = nullptr;
625-
}
626-
627-
diagnosticOutput->diagnostics[i] = diagnosticInfo;
582+
static swiftscan_macro_dependency_set_t *createMacroDependencySet(
583+
const std::map<std::string, MacroPluginDependency> &macroDeps) {
584+
swiftscan_macro_dependency_set_t *set = new swiftscan_macro_dependency_set_t;
585+
if (macroDeps.empty()) {
586+
set->count = 0;
587+
set->macro_dependencies = nullptr;
588+
return set;
589+
}
590+
set->count = macroDeps.size();
591+
set->macro_dependencies = new swiftscan_macro_dependency_t[set->count];
592+
unsigned SI = 0;
593+
for (auto &entry : macroDeps) {
594+
set->macro_dependencies[SI] = new swiftscan_macro_dependency_s;
595+
set->macro_dependencies[SI]->moduleName = create_clone(entry.first.c_str());
596+
set->macro_dependencies[SI]->libraryPath =
597+
create_clone(entry.second.LibraryPath.c_str());
598+
set->macro_dependencies[SI]->executablePath =
599+
create_clone(entry.second.ExecutablePath.c_str());
628600
}
629-
return diagnosticOutput;
601+
return set;
630602
}
631603

632604
static swiftscan_dependency_graph_t
@@ -811,8 +783,7 @@ generateFullDependencyGraph(const CompilerInstance &instance,
811783
result->dependencies = dependencySet;
812784
result->diagnostics =
813785
diagnosticCollector
814-
? mapCollectedDiagnosticsForOutput(instance.getSourceMgr(),
815-
diagnosticCollector)
786+
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
816787
: nullptr;
817788
return result;
818789
}
@@ -1484,13 +1455,11 @@ swift::dependencies::performModulePrescan(CompilerInstance &instance,
14841455
importSet->imports = create_set(importIdentifiers);
14851456
importSet->diagnostics =
14861457
diagnosticCollector
1487-
? mapCollectedDiagnosticsForOutput(instance.getSourceMgr(),
1488-
diagnosticCollector)
1458+
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
14891459
: nullptr;
14901460
importSet->diagnostics =
14911461
diagnosticCollector
1492-
? mapCollectedDiagnosticsForOutput(instance.getSourceMgr(),
1493-
diagnosticCollector)
1462+
? mapCollectedDiagnosticsForOutput(diagnosticCollector)
14941463
: nullptr;
14951464
return importSet;
14961465
}

tools/libSwiftScan/libSwiftScan.cpp

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

105105
void swiftscan_dependency_set_dispose(swiftscan_dependency_set_t *set) {
106-
for (size_t i = 0; i < set->count; ++i) {
107-
swiftscan_dependency_info_dispose(set->modules[i]);
106+
if (set) {
107+
for (size_t i = 0; i < set->count; ++i) {
108+
swiftscan_dependency_info_dispose(set->modules[i]);
109+
}
110+
delete[] set->modules;
111+
delete set;
108112
}
109-
delete[] set->modules;
110-
delete set;
111113
}
112114

113115
//=== Scanner Cache Operations --------------------------------------------===//
@@ -709,11 +711,13 @@ void swiftscan_diagnostic_dispose(swiftscan_diagnostic_info_t diagnostic) {
709711

710712
void
711713
swiftscan_diagnostics_set_dispose(swiftscan_diagnostic_set_t* diagnostics){
712-
for (size_t i = 0; i < diagnostics->count; ++i) {
713-
swiftscan_diagnostic_dispose(diagnostics->diagnostics[i]);
714+
if (diagnostics) {
715+
for (size_t i = 0; i < diagnostics->count; ++i) {
716+
swiftscan_diagnostic_dispose(diagnostics->diagnostics[i]);
717+
}
718+
delete[] diagnostics->diagnostics;
719+
delete diagnostics;
714720
}
715-
delete[] diagnostics->diagnostics;
716-
delete diagnostics;
717721
}
718722

719723
//=== Source Location -----------------------------------------------------===//

0 commit comments

Comments
 (0)