Skip to content

Commit 1b870c7

Browse files
authored
Merge pull request #3258 from apple/jan_svoboda/cherry_pick
[clang][deps][tooling] Cherry-pick recent dependency scanning commits
2 parents 3fa6a67 + cf679e4 commit 1b870c7

File tree

21 files changed

+286
-231
lines changed

21 files changed

+286
-231
lines changed

clang/include/clang/Frontend/CompilerInvocation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class HeaderSearchOptions;
5151
class PreprocessorOptions;
5252
class TargetOptions;
5353

54+
// This lets us create the DiagnosticsEngine with a properly-filled-out
55+
// DiagnosticOptions instance.
56+
std::unique_ptr<DiagnosticOptions>
57+
CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv);
58+
5459
/// Fill out Opts based on the options given in Args.
5560
///
5661
/// Args must have been created from the OptTable returned by

clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ class DependencyScanningTool {
8383
/// \returns A \c StringError with the diagnostic output if clang errors
8484
/// occurred, dependency file contents otherwise.
8585
llvm::Expected<std::string>
86-
getDependencyFile(const tooling::CompilationDatabase &Compilations,
87-
StringRef CWD, llvm::Optional<StringRef> ModuleName = None);
86+
getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD,
87+
llvm::Optional<StringRef> ModuleName = None);
8888

8989
/// Collect the full module dependency graph for the input, ignoring any
9090
/// modules which have already been seen. If \p ModuleName isn't empty, this
@@ -99,7 +99,7 @@ class DependencyScanningTool {
9999
/// \returns a \c StringError with the diagnostic output if clang errors
100100
/// occurred, \c FullDependencies otherwise.
101101
llvm::Expected<FullDependenciesResult>
102-
getFullDependencies(const tooling::CompilationDatabase &Compilations,
102+
getFullDependencies(const std::vector<std::string> &CommandLine,
103103
StringRef CWD, const llvm::StringSet<> &AlreadySeen,
104104
llvm::Optional<StringRef> ModuleName = None);
105105

clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "clang/Basic/LLVM.h"
1515
#include "clang/Frontend/PCHContainerOperations.h"
1616
#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
17-
#include "clang/Tooling/CompilationDatabase.h"
1817
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
1918
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
2019
#include "llvm/Support/Error.h"
@@ -30,24 +29,6 @@ namespace dependencies {
3029

3130
class DependencyScanningWorkerFilesystem;
3231

33-
/// Compilation database that holds and reports a single compile command.
34-
class SingleCommandCompilationDatabase : public CompilationDatabase {
35-
CompileCommand Command;
36-
37-
public:
38-
SingleCommandCompilationDatabase(CompileCommand Cmd)
39-
: Command(std::move(Cmd)) {}
40-
41-
std::vector<CompileCommand>
42-
getCompileCommands(StringRef FilePath) const override {
43-
return {Command};
44-
}
45-
46-
std::vector<CompileCommand> getAllCompileCommands() const override {
47-
return {Command};
48-
}
49-
};
50-
5132
class DependencyConsumer {
5233
public:
5334
virtual ~DependencyConsumer() {}
@@ -74,28 +55,15 @@ class DependencyScanningWorker {
7455
public:
7556
DependencyScanningWorker(DependencyScanningService &Service);
7657

77-
/// Run the dependency scanning tool for a given clang driver invocation, and
78-
/// report the discovered dependencies to the provided consumer. If
79-
/// \p ModuleName isn't empty, this function reports the dependencies of
80-
/// module \p ModuleName.
81-
///
82-
/// \returns A \c StringError with the diagnostic output if clang errors
83-
/// occurred, success otherwise.
84-
llvm::Error computeDependenciesForClangInvocation(
85-
StringRef WorkingDirectory, ArrayRef<std::string> Arguments,
86-
DependencyConsumer &Consumer,
87-
llvm::Optional<StringRef> ModuleName = None);
88-
89-
/// Run the dependency scanning tool for a given clang driver invocation (as
90-
/// specified for the given Input in the CDB), and report the discovered
91-
/// dependencies to the provided consumer. If \p ModuleName isn't empty, this
92-
/// function reports the dependencies of module \p ModuleName.
58+
/// Run the dependency scanning tool for a given clang driver command-line,
59+
/// and report the discovered dependencies to the provided consumer. If \p
60+
/// ModuleName isn't empty, this function reports the dependencies of module
61+
/// \p ModuleName.
9362
///
9463
/// \returns A \c StringError with the diagnostic output if clang errors
9564
/// occurred, success otherwise.
96-
llvm::Error computeDependencies(const std::string &Input,
97-
StringRef WorkingDirectory,
98-
const CompilationDatabase &CDB,
65+
llvm::Error computeDependencies(StringRef WorkingDirectory,
66+
const std::vector<std::string> &CommandLine,
9967
DependencyConsumer &Consumer,
10068
llvm::Optional<StringRef> ModuleName = None);
10169

@@ -104,11 +72,13 @@ class DependencyScanningWorker {
10472
llvm::StringSet<> AlreadySeen;
10573

10674
private:
107-
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
10875
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
10976
std::unique_ptr<ExcludedPreprocessorDirectiveSkipMapping> PPSkipMappings;
11077

78+
/// The physical filesystem overlaid by `InMemoryFS`.
11179
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS;
80+
/// The in-memory filesystem laid on top the physical filesystem in `RealFS`.
81+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFS;
11282
/// The file system that is used by each worker when scanning for
11383
/// dependencies. This filesystem persists accross multiple compiler
11484
/// invocations.

clang/include/clang/Tooling/Tooling.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,17 @@ class ToolInvocation {
268268

269269
~ToolInvocation();
270270

271-
/// Set a \c DiagnosticConsumer to use during parsing.
271+
/// Set a \c DiagnosticConsumer to use during driver command-line parsing and
272+
/// the action invocation itself.
272273
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
273274
this->DiagConsumer = DiagConsumer;
274275
}
275276

277+
/// Set a \c DiagnosticOptions to use during driver command-line parsing.
278+
void setDiagnosticOptions(DiagnosticOptions *DiagOpts) {
279+
this->DiagOpts = DiagOpts;
280+
}
281+
276282
/// Run the clang invocation.
277283
///
278284
/// \returns True if there were no errors during execution.
@@ -290,6 +296,7 @@ class ToolInvocation {
290296
FileManager *Files;
291297
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
292298
DiagnosticConsumer *DiagConsumer = nullptr;
299+
DiagnosticOptions *DiagOpts = nullptr;
293300
};
294301

295302
/// Utility to run a FrontendAction over a set of files.

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,6 +2355,19 @@ void CompilerInvocation::GenerateDiagnosticArgs(
23552355
}
23562356
}
23572357

2358+
std::unique_ptr<DiagnosticOptions>
2359+
clang::CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv) {
2360+
auto DiagOpts = std::make_unique<DiagnosticOptions>();
2361+
unsigned MissingArgIndex, MissingArgCount;
2362+
InputArgList Args = getDriverOptTable().ParseArgs(
2363+
Argv.slice(1), MissingArgIndex, MissingArgCount);
2364+
// We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
2365+
// Any errors that would be diagnosed here will also be diagnosed later,
2366+
// when the DiagnosticsEngine actually exists.
2367+
(void)ParseDiagnosticArgs(*DiagOpts, Args);
2368+
return DiagOpts;
2369+
}
2370+
23582371
bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
23592372
DiagnosticsEngine *Diags,
23602373
bool DefaultDiagColor) {

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,10 @@ IncrementalCompilerBuilder::create(std::vector<const char *> &ClangArgv) {
147147
// Buffer diagnostics from argument parsing so that we can output them using a
148148
// well formed diagnostic object.
149149
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
150-
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
150+
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
151+
CreateAndPopulateDiagOpts(ClangArgv);
151152
TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
152153
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
153-
unsigned MissingArgIndex, MissingArgCount;
154-
const llvm::opt::OptTable &Opts = driver::getDriverOptTable();
155-
llvm::opt::InputArgList ParsedArgs =
156-
Opts.ParseArgs(ArrayRef<const char *>(ClangArgv).slice(1),
157-
MissingArgIndex, MissingArgCount);
158-
ParseDiagnosticArgs(*DiagOpts, ParsedArgs, &Diags);
159154

160155
driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0],
161156
llvm::sys::getProcessTriple(), Diags);

clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ DependencyScanningTool::DependencyScanningTool(
5050
: Worker(Service) {}
5151

5252
llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
53-
const tooling::CompilationDatabase &Compilations, StringRef CWD,
53+
const std::vector<std::string> &CommandLine, StringRef CWD,
5454
llvm::Optional<StringRef> ModuleName) {
5555
/// Prints out all of the gathered dependencies into a string.
5656
class MakeDependencyPrinterConsumer : public DependencyConsumer {
@@ -103,18 +103,9 @@ llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
103103
std::vector<std::string> Dependencies;
104104
};
105105

106-
// We expect a single command here because if a source file occurs multiple
107-
// times in the original CDB, then `computeDependencies` would run the
108-
// `DependencyScanningAction` once for every time the input occured in the
109-
// CDB. Instead we split up the CDB into single command chunks to avoid this
110-
// behavior.
111-
assert(Compilations.getAllCompileCommands().size() == 1 &&
112-
"Expected a compilation database with a single command!");
113-
std::string Input = Compilations.getAllCompileCommands().front().Filename;
114-
115106
MakeDependencyPrinterConsumer Consumer;
116-
auto Result = Worker.computeDependencies(Input, CWD, Compilations, Consumer,
117-
ModuleName);
107+
auto Result =
108+
Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName);
118109
if (Result)
119110
return std::move(Result);
120111
std::string Output;
@@ -124,7 +115,7 @@ llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
124115

125116
llvm::Expected<FullDependenciesResult>
126117
DependencyScanningTool::getFullDependencies(
127-
const tooling::CompilationDatabase &Compilations, StringRef CWD,
118+
const std::vector<std::string> &CommandLine, StringRef CWD,
128119
const llvm::StringSet<> &AlreadySeen,
129120
llvm::Optional<StringRef> ModuleName) {
130121
class FullDependencyPrinterConsumer : public DependencyConsumer {
@@ -189,18 +180,9 @@ DependencyScanningTool::getFullDependencies(
189180
const llvm::StringSet<> &AlreadySeen;
190181
};
191182

192-
// We expect a single command here because if a source file occurs multiple
193-
// times in the original CDB, then `computeDependencies` would run the
194-
// `DependencyScanningAction` once for every time the input occured in the
195-
// CDB. Instead we split up the CDB into single command chunks to avoid this
196-
// behavior.
197-
assert(Compilations.getAllCompileCommands().size() == 1 &&
198-
"Expected a compilation database with a single command!");
199-
std::string Input = Compilations.getAllCompileCommands().front().Filename;
200-
201183
FullDependencyPrinterConsumer Consumer(AlreadySeen);
202-
llvm::Error Result = Worker.computeDependencies(Input, CWD, Compilations,
203-
Consumer, ModuleName);
184+
llvm::Error Result =
185+
Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName);
204186
if (Result)
205187
return std::move(Result);
206188
return Consumer.getFullDependencies();

0 commit comments

Comments
 (0)