[6.2][Dependency Scanning] Give each scanner worker a unique Diagnostic Engine

Otherwise, when multiple workers encounter a diagnostic simultaneously we can encounter races which lead to corrupted diagnostic data or crashes

Resolves rdar://159598539
This commit is contained in:
Artem Chikin
2025-09-02 15:05:36 -07:00
parent d4c0b15956
commit 0fa722f41f
5 changed files with 105 additions and 10 deletions

View File

@@ -31,8 +31,23 @@ struct ScanQueryInstance {
std::shared_ptr<DependencyScanDiagnosticCollector> ScanDiagnostics;
};
/// Pure virtual Diagnostic consumer intended for collecting
/// emitted diagnostics in a thread-safe fashion
class ThreadSafeDiagnosticCollector : public DiagnosticConsumer {
private:
llvm::sys::SmartMutex<true> DiagnosticConsumerStateLock;
void handleDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) final;
protected:
virtual void addDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) = 0;
public:
ThreadSafeDiagnosticCollector() {}
bool finishProcessing() final { return false; }
};
/// Diagnostic consumer that simply collects the diagnostics emitted so-far
class DependencyScanDiagnosticCollector : public DiagnosticConsumer {
class DependencyScanDiagnosticCollector : public ThreadSafeDiagnosticCollector {
private:
struct ScannerDiagnosticInfo {
std::string Message;
@@ -40,12 +55,9 @@ private:
std::optional<ScannerImportStatementInfo::ImportDiagnosticLocationInfo> ImportLocation;
};
std::vector<ScannerDiagnosticInfo> Diagnostics;
llvm::sys::SmartMutex<true> ScanningDiagnosticConsumerStateLock;
void handleDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) override;
protected:
virtual void addDiagnostic(SourceManager &SM, const DiagnosticInfo &Info);
void addDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) override;
public:
friend DependencyScanningTool;

View File

@@ -83,6 +83,8 @@ private:
// Worker-specific instance of CompilerInvocation
std::unique_ptr<CompilerInvocation> workerCompilerInvocation;
// Worker-specific diagnostic engine
std::unique_ptr<DiagnosticEngine> workerDiagnosticEngine;
// Worker-specific instance of ASTContext
std::unique_ptr<ASTContext> workerASTContext;
// An AST delegate for interface scanning.