Skip to content

Commit 99dd142

Browse files
committed
[clang][DependencyScanning] Remove dependency on clangDriver from clangDependencyScanning
This follows PR llvm#169962 and removes the dependency on clangDriver from clangDependencyScanning. DependencyScanningWorker now only supports -cc1 command line inputs, and all functionality related to driver-level commands has been moved into clangTooling (DependencyScanningTool.cpp). Because DependencyScanningWorker now only accepts -cc1 inputs, this patch enables the use of -cc1 commands with the by-name scanning API introduced in llvm#164345. This is part of a broader effort to support driver-managed builds for compilations using C++ named modules and/or Clang modules. It is required for linking the dependency scanning tooling against the driver without introducing cyclic dependencies, which would otherwise cause build failures when dynamic linking is enabled. The RFC for this change can be found here: https://discourse.llvm.org/t/rfc-new-clangoptions-library-remove-dependency-on-clangdriver-from-clangfrontend-and-flangfrontend/88773?u=naveen-seth
1 parent b70be3d commit 99dd142

File tree

13 files changed

+478
-389
lines changed

13 files changed

+478
-389
lines changed

clang/include/clang/DependencyScanning/DependencyScannerImpl.h

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "clang/Frontend/CompilerInstance.h"
1717
#include "clang/Frontend/CompilerInvocation.h"
1818
#include "clang/Frontend/TextDiagnosticPrinter.h"
19-
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
2019

2120
namespace clang {
2221
class DiagnosticConsumer;
@@ -88,27 +87,10 @@ struct TextDiagnosticsPrinterWithOutput {
8887
DiagPrinter(DiagnosticsOS, *DiagOpts) {}
8988
};
9089

91-
std::pair<std::unique_ptr<driver::Driver>, std::unique_ptr<driver::Compilation>>
92-
buildCompilation(ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags,
93-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
94-
llvm::BumpPtrAllocator &Alloc);
95-
9690
std::unique_ptr<CompilerInvocation>
9791
createCompilerInvocation(ArrayRef<std::string> CommandLine,
9892
DiagnosticsEngine &Diags);
9993

100-
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
101-
initVFSForTUBufferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
102-
ArrayRef<std::string> CommandLine,
103-
StringRef WorkingDirectory,
104-
llvm::MemoryBufferRef TUBuffer);
105-
106-
std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
107-
std::vector<std::string>>
108-
initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
109-
ArrayRef<std::string> CommandLine,
110-
StringRef WorkingDirectory, StringRef ModuleName);
111-
11294
bool initializeScanCompilerInstance(
11395
CompilerInstance &ScanInstance,
11496
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
@@ -143,22 +125,11 @@ class CompilerInstanceWithContext {
143125
llvm::StringRef CWD;
144126
std::vector<std::string> CommandLine;
145127

146-
// Context - file systems
147-
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;
148-
149128
// Context - Diagnostics engine.
150-
std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS;
151-
// DiagConsumer may points to DiagPrinterWithOS->DiagPrinter, or a custom
152-
// DiagnosticConsumer passed in from initialize.
153129
DiagnosticConsumer *DiagConsumer = nullptr;
154130
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
155131

156132
// Context - compiler invocation
157-
// Compilation's command's arguments may be owned by Alloc when expanded from
158-
// response files, so we need to keep Alloc alive in the context.
159-
llvm::BumpPtrAllocator Alloc;
160-
std::unique_ptr<clang::driver::Driver> Driver;
161-
std::unique_ptr<clang::driver::Compilation> Compilation;
162133
std::unique_ptr<CompilerInvocation> OriginalInvocation;
163134

164135
// Context - output options
@@ -180,15 +151,13 @@ class CompilerInstanceWithContext {
180151
: Worker(Worker), CWD(CWD), CommandLine(CMD) {};
181152

182153
// The three methods below returns false when they fail, with the detail
183-
// accumulated in DiagConsumer.
184-
bool initialize(DiagnosticConsumer *DC);
154+
// accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
155+
bool initialize(
156+
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
157+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
185158
bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer,
186159
DependencyActionController &Controller);
187160
bool finalize();
188-
189-
// The method below turns the return status from the above methods
190-
// into an llvm::Error using a default DiagnosticConsumer.
191-
llvm::Error handleReturnStatus(bool Success);
192161
};
193162
} // namespace dependencies
194163
} // namespace clang

clang/include/clang/DependencyScanning/DependencyScanningWorker.h

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H
1010
#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H
1111

12+
#include "clang/Basic/Diagnostic.h"
1213
#include "clang/Basic/DiagnosticOptions.h"
1314
#include "clang/Basic/FileManager.h"
1415
#include "clang/Basic/LLVM.h"
16+
#include "clang/DependencyScanning/DependencyScannerImpl.h"
1517
#include "clang/DependencyScanning/DependencyScanningService.h"
1618
#include "clang/DependencyScanning/ModuleDepCollector.h"
1719
#include "clang/Frontend/PCHContainerOperations.h"
@@ -91,70 +93,72 @@ class DependencyScanningWorker {
9193

9294
~DependencyScanningWorker();
9395

94-
/// Run the dependency scanning tool for a given clang driver command-line,
95-
/// and report the discovered dependencies to the provided consumer. If
96-
/// TUBuffer is not nullopt, it is used as TU input for the dependency
97-
/// scanning. Otherwise, the input should be included as part of the
98-
/// command-line.
96+
/// Run the dependency scanning tool for a given clang -cc1 command-line,
97+
/// and report the discovered dependencies to the provided consumer.
9998
///
100-
/// \returns false if clang errors occurred (with diagnostics reported to
99+
/// @return false if clang errors occurred (with diagnostics reported to
101100
/// \c DiagConsumer), true otherwise.
102101
bool computeDependencies(
103102
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
104103
DependencyConsumer &DepConsumer, DependencyActionController &Controller,
105104
DiagnosticConsumer &DiagConsumer,
106-
std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt);
105+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> ScanFS = nullptr);
107106

108-
/// Run the dependency scanning tool for a given clang driver command-line
109-
/// for a specific translation unit via file system or memory buffer.
107+
/// Run the dependency scanning tool for all given clang -cc1 command-lines,
108+
/// and report the discovered dependencies to the provided consumer.
110109
///
111-
/// \returns A \c StringError with the diagnostic output if clang errors
112-
/// occurred, success otherwise.
113-
llvm::Error computeDependencies(
114-
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
110+
/// \returns false if clang errors occurred (with diagnostics reported to
111+
/// \c Diags), true otherwise.
112+
bool computeDependencies(
113+
StringRef WorkingDirectory,
114+
ArrayRef<std::vector<std::string>> CommandLines,
115115
DependencyConsumer &Consumer, DependencyActionController &Controller,
116-
std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt);
116+
DiagnosticsEngine &Diags,
117+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> ScanFS = nullptr);
117118

118119
/// The three method below implements a new interface for by name
119120
/// dependency scanning. They together enable the dependency scanning worker
120121
/// to more effectively perform scanning for a sequence of modules
121122
/// by name when the CWD and CommandLine do not change across the queries.
123+
/// The initialization function asks the client for a DiagnosticsConsumer
124+
/// that it direct the diagnostics to.
122125

123126
/// @brief Initializing the context and the compiler instance.
124127
/// @param CWD The current working directory used during the scan.
125128
/// @param CommandLine The commandline used for the scan.
126-
/// @return Error if the initializaiton fails.
127-
llvm::Error initializeCompilerInstanceWithContextOrError(
128-
StringRef CWD, const std::vector<std::string> &CommandLine);
129+
/// @return False if the initializaiton fails.
130+
bool initializeCompilerInstanceWithContext(StringRef CWD,
131+
ArrayRef<std::string> CommandLine,
132+
DiagnosticConsumer &DC);
133+
134+
/// @brief Initializing the context and the compiler instance.
135+
/// @param CWD The current working directory used during the scan.
136+
/// @param CommandLine The commandline used for the scan.
137+
/// @param DiagEngineWithCmdAndOpts Preconfigured diagnostics engine and
138+
/// options associated with the cc1 command line.
139+
/// @param FS The file system (typically an overlay) to use for this compiler
140+
/// instance.
141+
/// @return False if the initializaiton fails.
142+
bool initializeCompilerInstanceWithContext(
143+
StringRef CWD, ArrayRef<std::string> CommandLine,
144+
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts,
145+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
129146

130147
/// @brief Performaces dependency scanning for the module whose name is
131148
/// specified.
132149
/// @param ModuleName The name of the module whose dependency will be
133150
/// scanned.
134151
/// @param Consumer The dependency consumer that stores the results.
135152
/// @param Controller The controller for the dependency scanning action.
136-
/// @return Error if the scanner incurs errors.
137-
llvm::Error computeDependenciesByNameWithContextOrError(
138-
StringRef ModuleName, DependencyConsumer &Consumer,
139-
DependencyActionController &Controller);
140-
141-
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
142-
/// @return Error if errors occur during finalization.
143-
llvm::Error finalizeCompilerInstanceWithContextOrError();
144-
145-
/// The three methods below provides the same functionality as the
146-
/// three methods above. Instead of returning `llvm::Error`s, these
147-
/// three methods return a flag to indicate if the call is successful.
148-
/// The initialization function asks the client for a DiagnosticsConsumer
149-
/// that it direct the diagnostics to.
150-
bool initializeCompilerInstanceWithContext(
151-
StringRef CWD, const std::vector<std::string> &CommandLine,
152-
DiagnosticConsumer *DC = nullptr);
153+
/// @return False if the scanner incurs errors.
153154
bool
154155
computeDependenciesByNameWithContext(StringRef ModuleName,
155156
DependencyConsumer &Consumer,
156157
DependencyActionController &Controller);
157-
bool finalizeCompilerInstance();
158+
159+
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
160+
/// @return False if errors occur during finalization.
161+
bool finalizeCompilerInstanceWithContext();
158162

159163
llvm::vfs::FileSystem &getVFS() const { return *DepFS; }
160164

@@ -169,13 +173,21 @@ class DependencyScanningWorker {
169173
friend CompilerInstanceWithContext;
170174
std::unique_ptr<CompilerInstanceWithContext> CIWithContext;
171175

172-
/// Actually carries out the scan. If \c OverlayFS is provided, it must be
173-
/// based on top of DepFS.
174-
bool scanDependencies(
175-
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
176-
DependencyConsumer &Consumer, DependencyActionController &Controller,
177-
DiagnosticConsumer &DC,
178-
IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS = nullptr);
176+
/// Private helper functions to actually carry out the scan. If \c OverlayFS
177+
/// is provided, it must be based on top of DepFS.
178+
bool scanDependencies(StringRef WorkingDirectory,
179+
const std::vector<std::string> &CommandLine,
180+
DependencyConsumer &Consumer,
181+
DependencyActionController &Controller,
182+
DiagnosticConsumer &DC,
183+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
184+
185+
bool scanDependencies(StringRef WorkingDirectory,
186+
ArrayRef<std::vector<std::string>> CommandLine,
187+
DependencyConsumer &Consumer,
188+
DependencyActionController &Controller,
189+
DiagnosticsEngine &Diags,
190+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
179191
};
180192

181193
} // end namespace dependencies

clang/include/clang/Tooling/DependencyScanningTool.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H
1010
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H
1111

12+
#include "clang/DependencyScanning/DependencyScannerImpl.h"
1213
#include "clang/DependencyScanning/DependencyScanningService.h"
1314
#include "clang/DependencyScanning/DependencyScanningUtils.h"
1415
#include "clang/DependencyScanning/DependencyScanningWorker.h"
@@ -127,8 +128,8 @@ class DependencyScanningTool {
127128
/// @param CWD The current working directory used during the scan.
128129
/// @param CommandLine The commandline used for the scan.
129130
/// @return Error if the initializaiton fails.
130-
llvm::Error initializeCompilerInstanceWithContext(
131-
StringRef CWD, const std::vector<std::string> &CommandLine);
131+
llvm::Error initializeCompilerInstanceWithContextOrError(
132+
StringRef CWD, ArrayRef<std::string> CommandLine);
132133

133134
/// @brief Computes the dependeny for the module named ModuleName.
134135
/// @param ModuleName The name of the module for which this method computes
@@ -145,7 +146,7 @@ class DependencyScanningTool {
145146
/// @return An instance of \c TranslationUnitDeps if the scan is successful.
146147
/// Otherwise it returns an error.
147148
llvm::Expected<clang::dependencies::TranslationUnitDeps>
148-
computeDependenciesByNameWithContext(
149+
computeDependenciesByNameWithContextOrError(
149150
StringRef ModuleName,
150151
const llvm::DenseSet<clang::dependencies::ModuleID> &AlreadySeen,
151152
clang::dependencies::LookupModuleOutputCallback LookupModuleOutput);
@@ -154,7 +155,7 @@ class DependencyScanningTool {
154155
/// diagnostics and deletes the compiler instance. Call this method
155156
/// once all names for a same commandline are scanned.
156157
/// @return Error if an error occured during finalization.
157-
llvm::Error finalizeCompilerInstanceWithContext();
158+
llvm::Error finalizeCompilerInstanceWithContextOrError();
158159

159160
llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
160161

clang/lib/DependencyScanning/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ add_clang_library(clangDependencyScanning
1818
ClangDriverOptions
1919

2020
LINK_LIBS
21-
clangAST
2221
clangBasic
23-
clangDriver
2422
clangFrontend
2523
clangLex
2624
clangSerialization

0 commit comments

Comments
 (0)