Skip to content

Commit e076b56

Browse files
committed
Addressing code review comments.
1 parent 554613b commit e076b56

File tree

4 files changed

+110
-114
lines changed

4 files changed

+110
-114
lines changed

clang/lib/Tooling/DependencyScanning/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,5 @@ add_clang_library(clangDependencyScanning
2424
clangFrontend
2525
clangLex
2626
clangSerialization
27-
clangTooling
2827
${LLVM_PTHREAD_LIB}
2928
)

clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -334,22 +334,9 @@ class ScanningDependencyDirectivesGetter : public DependencyDirectivesGetter {
334334
return DepFS->getDirectiveTokens(File.getName());
335335
}
336336
};
337-
} // namespace
338-
339-
std::unique_ptr<DiagnosticOptions>
340-
clang::tooling::dependencies::createDiagOptions(
341-
const std::vector<std::string> &CommandLine) {
342-
std::vector<const char *> CLI;
343-
for (const std::string &Arg : CommandLine)
344-
CLI.push_back(Arg.c_str());
345-
auto DiagOpts = CreateAndPopulateDiagOpts(CLI);
346-
sanitizeDiagOpts(*DiagOpts);
347-
return DiagOpts;
348-
}
349337

350338
/// Sanitize diagnostic options for dependency scan.
351-
void clang::tooling::dependencies::sanitizeDiagOpts(
352-
DiagnosticOptions &DiagOpts) {
339+
void sanitizeDiagOpts(DiagnosticOptions &DiagOpts) {
353340
// Don't print 'X warnings and Y errors generated'.
354341
DiagOpts.ShowCarets = false;
355342
// Don't write out diagnostic file.
@@ -368,6 +355,31 @@ void clang::tooling::dependencies::sanitizeDiagOpts(
368355
.Default(true);
369356
});
370357
}
358+
} // namespace
359+
360+
std::unique_ptr<DiagnosticOptions>
361+
clang::tooling::dependencies::createDiagOptions(
362+
const std::vector<std::string> &CommandLine) {
363+
std::vector<const char *> CLI;
364+
for (const std::string &Arg : CommandLine)
365+
CLI.push_back(Arg.c_str());
366+
auto DiagOpts = CreateAndPopulateDiagOpts(CLI);
367+
sanitizeDiagOpts(*DiagOpts);
368+
return DiagOpts;
369+
}
370+
371+
clang::tooling::dependencies::DignosticsEngineWithCCommandLineAndDiagOpts::
372+
DignosticsEngineWithCCommandLineAndDiagOpts(
373+
const std::vector<std::string> CommandLine,
374+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC)
375+
: CCommandLine(CommandLine.size(), nullptr) {
376+
llvm::transform(CommandLine, CCommandLine.begin(),
377+
[](const std::string &Str) { return Str.c_str(); });
378+
DiagOpts = CreateAndPopulateDiagOpts(CCommandLine);
379+
sanitizeDiagOpts(*DiagOpts);
380+
DiagEngine = CompilerInstance::createDiagnostics(*FS, *DiagOpts, &DC,
381+
/*ShouldOwnClient=*/false);
382+
}
371383

372384
std::pair<std::unique_ptr<driver::Driver>, std::unique_ptr<driver::Compilation>>
373385
clang::tooling::dependencies::buildCompilation(
@@ -395,7 +407,7 @@ clang::tooling::dependencies::buildCompilation(
395407
}
396408

397409
std::unique_ptr<driver::Compilation> Compilation(
398-
Driver->BuildCompilation(llvm::ArrayRef(Argv)));
410+
Driver->BuildCompilation(Argv));
399411
if (!Compilation)
400412
return std::make_pair(nullptr, nullptr);
401413

@@ -405,45 +417,37 @@ clang::tooling::dependencies::buildCompilation(
405417
return std::make_pair(std::move(Driver), std::move(Compilation));
406418
}
407419

408-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
409-
clang::tooling::dependencies::initVFSForTUBufferScanning(
410-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
411-
std::optional<std::vector<std::string>> &ModifiedCommandLine,
420+
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
421+
clang::tooling::dependencies::initVFSForTUBuferScanning(
422+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
412423
const std::vector<std::string> &CommandLine, StringRef WorkingDirectory,
413-
std::optional<llvm::MemoryBufferRef> TUBuffer) {
424+
llvm::MemoryBufferRef TUBuffer) {
414425
// Reset what might have been modified in the previous worker invocation.
415426
BaseFS->setCurrentWorkingDirectory(WorkingDirectory);
416427

417-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> ModifiedFS;
418-
if (TUBuffer) {
419-
auto OverlayFS =
420-
llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(BaseFS);
421-
auto InMemoryFS =
422-
llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
423-
InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory);
424-
auto InputPath = TUBuffer->getBufferIdentifier();
425-
InMemoryFS->addFile(
426-
InputPath, 0,
427-
llvm::MemoryBuffer::getMemBufferCopy(TUBuffer->getBuffer()));
428-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay =
429-
InMemoryFS;
430-
431-
OverlayFS->pushOverlay(InMemoryOverlay);
432-
ModifiedFS = OverlayFS;
433-
ModifiedCommandLine = CommandLine;
434-
ModifiedCommandLine->emplace_back(InputPath);
435-
436-
return ModifiedFS;
437-
}
428+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> ModifiedFS;
429+
auto OverlayFS =
430+
llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(BaseFS);
431+
auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
432+
InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory);
433+
auto InputPath = TUBuffer.getBufferIdentifier();
434+
InMemoryFS->addFile(
435+
InputPath, 0, llvm::MemoryBuffer::getMemBufferCopy(TUBuffer.getBuffer()));
436+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay = InMemoryFS;
437+
438+
OverlayFS->pushOverlay(InMemoryOverlay);
439+
ModifiedFS = OverlayFS;
440+
auto ModifiedCommandLine = CommandLine;
441+
ModifiedCommandLine.emplace_back(InputPath);
438442

439-
return BaseFS;
443+
return std::make_pair(ModifiedFS, ModifiedCommandLine);
440444
}
441445

442-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
446+
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
443447
clang::tooling::dependencies::initVFSForByNameScanning(
444-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
445-
std::vector<std::string> &CommandLine, StringRef WorkingDirectory,
446-
StringRef FakeFileNamePrefix) {
448+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
449+
const std::vector<std::string> &CommandLine, StringRef WorkingDirectory,
450+
StringRef ModuleName) {
447451
// Reset what might have been modified in the previous worker invocation.
448452
BaseFS->setCurrentWorkingDirectory(WorkingDirectory);
449453

@@ -456,16 +460,16 @@ clang::tooling::dependencies::initVFSForByNameScanning(
456460
InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory);
457461
SmallString<128> FakeInputPath;
458462
// TODO: We should retry the creation if the path already exists.
459-
llvm::sys::fs::createUniquePath(FakeFileNamePrefix + "-%%%%%%%%.input",
460-
FakeInputPath,
463+
llvm::sys::fs::createUniquePath(ModuleName + "-%%%%%%%%.input", FakeInputPath,
461464
/*MakeAbsolute=*/false);
462465
InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer(""));
463-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay = InMemoryFS;
466+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay = InMemoryFS;
464467
OverlayFS->pushOverlay(InMemoryOverlay);
465468

466-
CommandLine.emplace_back(FakeInputPath);
469+
auto ModifiedCommandLine = CommandLine;
470+
ModifiedCommandLine.emplace_back(FakeInputPath);
467471

468-
return OverlayFS;
472+
return std::make_pair(OverlayFS, ModifiedCommandLine);
469473
}
470474

471475
std::unique_ptr<CompilerInvocation>
@@ -487,7 +491,7 @@ bool clang::tooling::dependencies::initializeScanCompilerInstance(
487491
CompilerInstance &ScanInstance,
488492
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
489493
DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service,
490-
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS) {
494+
IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS) {
491495
ScanInstance.setBuildingModule(false);
492496

493497
ScanInstance.createVirtualFileSystem(FS, DiagConsumer);
@@ -554,7 +558,7 @@ bool clang::tooling::dependencies::initializeScanCompilerInstance(
554558
}
555559

556560
llvm::SmallVector<StringRef> clang::tooling::dependencies::computeStableDirs(
557-
CompilerInstance &ScanInstance) {
561+
const CompilerInstance &ScanInstance) {
558562
// Create a collection of stable directories derived from the ScanInstance
559563
// for determining whether module dependencies would fully resolve from
560564
// those directories.
@@ -600,7 +604,7 @@ void clang::tooling::dependencies::initializeModuleDepCollector(
600604
// and thus won't write out the extra '.d' files to disk.
601605
auto Opts = std::make_unique<DependencyOutputOptions>();
602606

603-
// We rely on the behaviour that that ScanInstance's Invocation instance's
607+
// We rely on the behaviour that the ScanInstance's Invocation instance's
604608
// dependency output opts are cleared here.
605609
// TODO: we will need to preserve and recover the original dependency output
606610
// opts if we want to reuse ScanInstance.

clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,28 @@ class DependencyScanningAction {
7474
bool DiagConsumerFinished = false;
7575
};
7676

77-
// Helper functions
77+
// Helper functions and data types.
7878
std::unique_ptr<DiagnosticOptions>
7979
createDiagOptions(const std::vector<std::string> &CommandLine);
80-
void sanitizeDiagOpts(DiagnosticOptions &DiagOpts);
80+
81+
struct DignosticsEngineWithCCommandLineAndDiagOpts {
82+
// We need to bound the lifetime of the CCommandLine and the DiagOpts
83+
// used to create the DiganosticsEngine with the DiagnosticsEngine itself.
84+
std::vector<const char *> CCommandLine;
85+
std::unique_ptr<DiagnosticOptions> DiagOpts;
86+
IntrusiveRefCntPtr<DiagnosticsEngine> DiagEngine;
87+
88+
DignosticsEngineWithCCommandLineAndDiagOpts(
89+
const std::vector<std::string> CommandLine,
90+
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC);
91+
};
8192

8293
struct TextDiagnosticsPrinterWithOutput {
94+
// We need to bound the lifetime of the data that supports the DiagPrinter
95+
// with it together so they have the same lifetime.
8396
std::string DiagnosticOutput;
8497
llvm::raw_string_ostream DiagnosticsOS;
85-
std::unique_ptr<clang::DiagnosticOptions> DiagOpts;
98+
std::unique_ptr<DiagnosticOptions> DiagOpts;
8699
TextDiagnosticPrinter DiagPrinter;
87100

88101
TextDiagnosticsPrinterWithOutput(const std::vector<std::string> &CommandLine)
@@ -99,25 +112,25 @@ std::unique_ptr<CompilerInvocation>
99112
createCompilerInvocation(const std::vector<std::string> &CommandLine,
100113
DiagnosticsEngine &Diags);
101114

102-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> initVFSForTUBufferScanning(
103-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
104-
std::optional<std::vector<std::string>> &ModifiedCommandLine,
105-
const std::vector<std::string> &CommandLine, StringRef WorkingDirectory,
106-
std::optional<llvm::MemoryBufferRef> TUBuffer);
115+
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
116+
initVFSForTUBuferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
117+
const std::vector<std::string> &CommandLine,
118+
StringRef WorkingDirectory,
119+
llvm::MemoryBufferRef TUBuffer);
107120

108-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
121+
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
109122
initVFSForByNameScanning(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
110-
std::vector<std::string> &CommandLine,
111-
StringRef WorkingDirectory,
112-
StringRef FakeFileNamePrefix);
123+
const std::vector<std::string> &CommandLine,
124+
StringRef WorkingDirectory, StringRef ModuleName);
113125

114126
bool initializeScanCompilerInstance(
115127
CompilerInstance &ScanInstance,
116128
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
117129
DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service,
118130
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS);
119131

120-
llvm::SmallVector<StringRef> computeStableDirs(CompilerInstance &ScanInstance);
132+
llvm::SmallVector<StringRef>
133+
computeStableDirs(const CompilerInstance &ScanInstance);
121134

122135
std::optional<PrebuiltModulesAttrsMap>
123136
computePrebuiltModulesASTMap(CompilerInstance &ScanInstance,

clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,9 @@
88

99
#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
1010
#include "DependencyScannerImpl.h"
11-
#include "clang/Basic/DiagnosticDriver.h"
1211
#include "clang/Basic/DiagnosticFrontend.h"
13-
#include "clang/Basic/DiagnosticSerialization.h"
14-
#include "clang/Driver/Compilation.h"
1512
#include "clang/Driver/Driver.h"
16-
#include "clang/Driver/Job.h"
1713
#include "clang/Driver/Tool.h"
18-
#include "clang/Frontend/CompilerInstance.h"
19-
#include "clang/Frontend/CompilerInvocation.h"
20-
#include "clang/Frontend/FrontendActions.h"
21-
#include "clang/Frontend/TextDiagnosticPrinter.h"
22-
#include "clang/Frontend/Utils.h"
23-
#include "clang/Lex/PreprocessorOptions.h"
24-
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
25-
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
26-
#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h"
27-
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
28-
#include "llvm/ADT/IntrusiveRefCntPtr.h"
29-
#include "llvm/Support/Allocator.h"
30-
#include "llvm/Support/Error.h"
31-
#include "llvm/Support/MemoryBuffer.h"
32-
#include "llvm/TargetParser/Host.h"
33-
#include <optional>
3414

3515
using namespace clang;
3616
using namespace tooling;
@@ -97,7 +77,7 @@ static bool forEachDriverJob(
9777
ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags,
9878
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
9979
llvm::function_ref<bool(const driver::Command &Cmd)> Callback) {
100-
// Compilation owns a reference to the Driver, hence we need to
80+
// Compilation holds a non-owning a reference to the Driver, hence we need to
10181
// keep the Driver alive when we use Compilation.
10282
auto [Driver, Compilation] = buildCompilation(ArgStrs, Diags, FS);
10383
if (!Compilation)
@@ -133,24 +113,20 @@ bool DependencyScanningWorker::scanDependencies(
133113
DependencyConsumer &Consumer, DependencyActionController &Controller,
134114
DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
135115
std::optional<StringRef> ModuleName) {
136-
std::vector<const char *> CCommandLine(CommandLine.size(), nullptr);
137-
llvm::transform(CommandLine, CCommandLine.begin(),
138-
[](const std::string &Str) { return Str.c_str(); });
139-
auto DiagOpts = CreateAndPopulateDiagOpts(CCommandLine);
140-
sanitizeDiagOpts(*DiagOpts);
141-
auto Diags = CompilerInstance::createDiagnostics(*FS, *DiagOpts, &DC,
142-
/*ShouldOwnClient=*/false);
143-
116+
DignosticsEngineWithCCommandLineAndDiagOpts DiagEngineWithCmdAndOpts(
117+
CommandLine, FS, DC);
144118
DependencyScanningAction Action(Service, WorkingDirectory, Consumer,
145119
Controller, DepFS, ModuleName);
146120

147121
bool Success = false;
148122
if (CommandLine[1] == "-cc1") {
149-
Success = createAndRunToolInvocation(CommandLine, Action, FS,
150-
PCHContainerOps, *Diags, Consumer);
123+
Success = createAndRunToolInvocation(
124+
CommandLine, Action, FS, PCHContainerOps,
125+
*DiagEngineWithCmdAndOpts.DiagEngine, Consumer);
151126
} else {
152127
Success = forEachDriverJob(
153-
CommandLine, *Diags, FS, [&](const driver::Command &Cmd) {
128+
CommandLine, *DiagEngineWithCmdAndOpts.DiagEngine, FS,
129+
[&](const driver::Command &Cmd) {
154130
if (StringRef(Cmd.getCreator().getName()) != "clang") {
155131
// Non-clang command. Just pass through to the dependency
156132
// consumer.
@@ -169,13 +145,15 @@ bool DependencyScanningWorker::scanDependencies(
169145
// system to ensure that any file system requests that
170146
// are made by the driver do not go through the
171147
// dependency scanning filesystem.
172-
return createAndRunToolInvocation(std::move(Argv), Action, FS,
173-
PCHContainerOps, *Diags, Consumer);
148+
return createAndRunToolInvocation(
149+
std::move(Argv), Action, FS, PCHContainerOps,
150+
*DiagEngineWithCmdAndOpts.DiagEngine, Consumer);
174151
});
175152
}
176153

177154
if (Success && !Action.hasScanned())
178-
Diags->Report(diag::err_fe_expected_compiler_job)
155+
DiagEngineWithCmdAndOpts.DiagEngine->Report(
156+
diag::err_fe_expected_compiler_job)
179157
<< llvm::join(CommandLine, " ");
180158

181159
// Ensure finish() is called even if we never reached ExecuteAction().
@@ -189,23 +167,25 @@ bool DependencyScanningWorker::computeDependencies(
189167
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
190168
DependencyConsumer &Consumer, DependencyActionController &Controller,
191169
DiagnosticConsumer &DC, std::optional<llvm::MemoryBufferRef> TUBuffer) {
192-
std::optional<std::vector<std::string>> ModifiedCommandLine;
193-
auto FinalFS = initVFSForTUBufferScanning(
194-
BaseFS, ModifiedCommandLine, CommandLine, WorkingDirectory, TUBuffer);
195-
const std::vector<std::string> &FinalCommandLine =
196-
ModifiedCommandLine ? *ModifiedCommandLine : CommandLine;
197-
198-
return scanDependencies(WorkingDirectory, FinalCommandLine, Consumer,
199-
Controller, DC, FinalFS, /*ModuleName=*/std::nullopt);
170+
if (TUBuffer) {
171+
auto [FinalFS, FinalCommandLine] = initVFSForTUBuferScanning(
172+
BaseFS, CommandLine, WorkingDirectory, *TUBuffer);
173+
return scanDependencies(WorkingDirectory, FinalCommandLine, Consumer,
174+
Controller, DC, FinalFS,
175+
/*ModuleName=*/std::nullopt);
176+
} else {
177+
BaseFS->setCurrentWorkingDirectory(WorkingDirectory);
178+
return scanDependencies(WorkingDirectory, CommandLine, Consumer, Controller,
179+
DC, BaseFS, /*ModuleName=*/std::nullopt);
180+
}
200181
}
201182

202183
bool DependencyScanningWorker::computeDependencies(
203184
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
204185
DependencyConsumer &Consumer, DependencyActionController &Controller,
205186
DiagnosticConsumer &DC, StringRef ModuleName) {
206-
auto ModifiedCommandLine = CommandLine;
207-
auto OverlayFS = initVFSForByNameScanning(BaseFS, ModifiedCommandLine,
208-
WorkingDirectory, ModuleName);
187+
auto [OverlayFS, ModifiedCommandLine] = initVFSForByNameScanning(
188+
BaseFS, CommandLine, WorkingDirectory, ModuleName);
209189

210190
return scanDependencies(WorkingDirectory, ModifiedCommandLine, Consumer,
211191
Controller, DC, OverlayFS, ModuleName);

0 commit comments

Comments
 (0)