mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 19:08:21 +08:00
[clang][DependencyScanning] Move driver-command logic for by-name scanning into DependencyScanningTool (#171238)
This is the second patch in a series that removes the dependency of clangDependencyScanning on clangDriver, splitting the work from #169964 into smaller changes (see comment linked below). This patch updates the by-name scanning interface in DependencyScanningWorker to accept only -cc1 command lines directly and moves the logic for handling driver-style command lines into DependencyScanningTool in clangTooling. Support for -cc1 command lines in by-name scanning is introduced in this patch. The next patch will update the remaining parts of DependencyScanningWorker to operate only on -cc1 command lines, allowing its dependency on clangDriver to be removed. https://github.com/llvm/llvm-project/pull/169964#pullrequestreview-3545879529
This commit is contained in:
committed by
GitHub
parent
eb501b211a
commit
ad2fca7513
@@ -17,6 +17,7 @@
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
|
||||
namespace clang {
|
||||
class DiagnosticConsumer;
|
||||
@@ -143,22 +144,11 @@ class CompilerInstanceWithContext {
|
||||
llvm::StringRef CWD;
|
||||
std::vector<std::string> CommandLine;
|
||||
|
||||
// Context - file systems
|
||||
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;
|
||||
|
||||
// Context - Diagnostics engine.
|
||||
std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS;
|
||||
// DiagConsumer may points to DiagPrinterWithOS->DiagPrinter, or a custom
|
||||
// DiagnosticConsumer passed in from initialize.
|
||||
DiagnosticConsumer *DiagConsumer = nullptr;
|
||||
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
|
||||
|
||||
// Context - compiler invocation
|
||||
// Compilation's command's arguments may be owned by Alloc when expanded from
|
||||
// response files, so we need to keep Alloc alive in the context.
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
std::unique_ptr<clang::driver::Driver> Driver;
|
||||
std::unique_ptr<clang::driver::Compilation> Compilation;
|
||||
std::unique_ptr<CompilerInvocation> OriginalInvocation;
|
||||
|
||||
// Context - output options
|
||||
@@ -180,15 +170,13 @@ public:
|
||||
: Worker(Worker), CWD(CWD), CommandLine(CMD) {};
|
||||
|
||||
// The three methods below returns false when they fail, with the detail
|
||||
// accumulated in DiagConsumer.
|
||||
bool initialize(DiagnosticConsumer *DC);
|
||||
// accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
|
||||
bool initialize(
|
||||
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
|
||||
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
|
||||
bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer,
|
||||
DependencyActionController &Controller);
|
||||
bool finalize();
|
||||
|
||||
// The method below turns the return status from the above methods
|
||||
// into an llvm::Error using a default DiagnosticConsumer.
|
||||
llvm::Error handleReturnStatus(bool Success);
|
||||
};
|
||||
} // namespace dependencies
|
||||
} // namespace clang
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/DependencyScanning/DependencyScannerImpl.h"
|
||||
#include "clang/DependencyScanning/DependencyScanningService.h"
|
||||
#include "clang/DependencyScanning/ModuleDepCollector.h"
|
||||
#include "clang/Frontend/PCHContainerOperations.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBufferRef.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
@@ -119,13 +121,28 @@ public:
|
||||
/// dependency scanning. They together enable the dependency scanning worker
|
||||
/// to more effectively perform scanning for a sequence of modules
|
||||
/// by name when the CWD and CommandLine do not change across the queries.
|
||||
/// The initialization function asks the client for a DiagnosticsConsumer
|
||||
/// that it direct the diagnostics to.
|
||||
|
||||
/// @brief Initializing the context and the compiler instance.
|
||||
/// @param CWD The current working directory used during the scan.
|
||||
/// @param CommandLine The commandline used for the scan.
|
||||
/// @return Error if the initializaiton fails.
|
||||
llvm::Error initializeCompilerInstanceWithContextOrError(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine);
|
||||
/// @return False if the initializaiton fails.
|
||||
bool initializeCompilerInstanceWithContext(StringRef CWD,
|
||||
ArrayRef<std::string> CommandLine,
|
||||
DiagnosticConsumer &DC);
|
||||
|
||||
/// @brief Initializing the context and the compiler instance.
|
||||
/// @param CWD The current working directory used during the scan.
|
||||
/// @param CommandLine The commandline used for the scan.
|
||||
/// @param DiagEngineWithCmdAndOpts Preconfigured diagnostics engine and
|
||||
/// options associated with the cc1 command line.
|
||||
/// @param FS The overlay file system to use for this compiler instance.
|
||||
/// @return False if the initializaiton fails.
|
||||
bool initializeCompilerInstanceWithContext(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine,
|
||||
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts,
|
||||
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS);
|
||||
|
||||
/// @brief Performaces dependency scanning for the module whose name is
|
||||
/// specified.
|
||||
@@ -133,28 +150,15 @@ public:
|
||||
/// scanned.
|
||||
/// @param Consumer The dependency consumer that stores the results.
|
||||
/// @param Controller The controller for the dependency scanning action.
|
||||
/// @return Error if the scanner incurs errors.
|
||||
llvm::Error computeDependenciesByNameWithContextOrError(
|
||||
StringRef ModuleName, DependencyConsumer &Consumer,
|
||||
DependencyActionController &Controller);
|
||||
|
||||
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
|
||||
/// @return Error if errors occur during finalization.
|
||||
llvm::Error finalizeCompilerInstanceWithContextOrError();
|
||||
|
||||
/// The three methods below provides the same functionality as the
|
||||
/// three methods above. Instead of returning `llvm::Error`s, these
|
||||
/// three methods return a flag to indicate if the call is successful.
|
||||
/// The initialization function asks the client for a DiagnosticsConsumer
|
||||
/// that it direct the diagnostics to.
|
||||
bool initializeCompilerInstanceWithContext(StringRef CWD,
|
||||
ArrayRef<std::string> CommandLine,
|
||||
DiagnosticConsumer *DC = nullptr);
|
||||
/// @return False if the scanner incurs errors.
|
||||
bool
|
||||
computeDependenciesByNameWithContext(StringRef ModuleName,
|
||||
DependencyConsumer &Consumer,
|
||||
DependencyActionController &Controller);
|
||||
bool finalizeCompilerInstance();
|
||||
|
||||
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
|
||||
/// @return False if errors occur during finalization.
|
||||
bool finalizeCompilerInstanceWithContext();
|
||||
|
||||
llvm::vfs::FileSystem &getVFS() const { return *DepFS; }
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H
|
||||
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNINGTOOL_H
|
||||
|
||||
#include "clang/DependencyScanning/DependencyScannerImpl.h"
|
||||
#include "clang/DependencyScanning/DependencyScanningService.h"
|
||||
#include "clang/DependencyScanning/DependencyScanningUtils.h"
|
||||
#include "clang/DependencyScanning/DependencyScanningWorker.h"
|
||||
@@ -119,9 +120,8 @@ public:
|
||||
/// @param CWD The current working directory used during the scan.
|
||||
/// @param CommandLine The commandline used for the scan.
|
||||
/// @return Error if the initializaiton fails.
|
||||
llvm::Error
|
||||
initializeCompilerInstanceWithContext(StringRef CWD,
|
||||
ArrayRef<std::string> CommandLine);
|
||||
llvm::Error initializeCompilerInstanceWithContextOrError(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine);
|
||||
|
||||
/// @brief Computes the dependeny for the module named ModuleName.
|
||||
/// @param ModuleName The name of the module for which this method computes
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
/// @return An instance of \c TranslationUnitDeps if the scan is successful.
|
||||
/// Otherwise it returns an error.
|
||||
llvm::Expected<dependencies::TranslationUnitDeps>
|
||||
computeDependenciesByNameWithContext(
|
||||
computeDependenciesByNameWithContextOrError(
|
||||
StringRef ModuleName,
|
||||
const llvm::DenseSet<dependencies::ModuleID> &AlreadySeen,
|
||||
dependencies::LookupModuleOutputCallback LookupModuleOutput);
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
/// diagnostics and deletes the compiler instance. Call this method
|
||||
/// once all names for a same commandline are scanned.
|
||||
/// @return Error if an error occured during finalization.
|
||||
llvm::Error finalizeCompilerInstanceWithContext();
|
||||
llvm::Error finalizeCompilerInstanceWithContextOrError();
|
||||
|
||||
llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
|
||||
|
||||
|
||||
@@ -713,38 +713,25 @@ bool DependencyScanningAction::runInvocation(
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool CompilerInstanceWithContext::initialize(DiagnosticConsumer *DC) {
|
||||
if (DC) {
|
||||
DiagConsumer = DC;
|
||||
} else {
|
||||
DiagPrinterWithOS =
|
||||
std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
|
||||
DiagConsumer = &DiagPrinterWithOS->DiagPrinter;
|
||||
}
|
||||
bool CompilerInstanceWithContext::initialize(
|
||||
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
|
||||
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
|
||||
assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
|
||||
DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
|
||||
DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
|
||||
|
||||
std::tie(OverlayFS, CommandLine) = initVFSForByNameScanning(
|
||||
Worker.DepFS, CommandLine, CWD, "ScanningByName");
|
||||
#ifndef NDEBUG
|
||||
assert(OverlayFS && "OverlayFS required!");
|
||||
bool SawDepFS = false;
|
||||
OverlayFS->visit([&](llvm::vfs::FileSystem &VFS) {
|
||||
SawDepFS |= &VFS == Worker.DepFS.get();
|
||||
});
|
||||
assert(SawDepFS && "OverlayFS not based on DepFS");
|
||||
#endif
|
||||
|
||||
DiagEngineWithCmdAndOpts = std::make_unique<DiagnosticsEngineWithDiagOpts>(
|
||||
CommandLine, OverlayFS, *DiagConsumer);
|
||||
|
||||
std::tie(Driver, Compilation) = buildCompilation(
|
||||
CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS, Alloc);
|
||||
|
||||
if (!Compilation)
|
||||
return false;
|
||||
|
||||
assert(Compilation->getJobs().size() &&
|
||||
"Must have a job list of non-zero size");
|
||||
const driver::Command &Command = *(Compilation->getJobs().begin());
|
||||
const auto &CommandArgs = Command.getArguments();
|
||||
assert(!CommandArgs.empty() && "Cannot have a command with 0 args");
|
||||
assert(StringRef(CommandArgs[0]) == "-cc1" && "Requires a cc1 job.");
|
||||
OriginalInvocation = std::make_unique<CompilerInvocation>();
|
||||
|
||||
if (!CompilerInvocation::CreateFromArgs(*OriginalInvocation, CommandArgs,
|
||||
*DiagEngineWithCmdAndOpts->DiagEngine,
|
||||
Command.getExecutable())) {
|
||||
OriginalInvocation = createCompilerInvocation(
|
||||
CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
|
||||
if (!OriginalInvocation) {
|
||||
DiagEngineWithCmdAndOpts->DiagEngine->Report(
|
||||
diag::err_fe_expected_compiler_job)
|
||||
<< llvm::join(CommandLine, " ");
|
||||
@@ -876,11 +863,3 @@ bool CompilerInstanceWithContext::finalize() {
|
||||
DiagConsumer->finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::Error CompilerInstanceWithContext::handleReturnStatus(bool Success) {
|
||||
assert(DiagPrinterWithOS && "Must use the default DiagnosticConsumer.");
|
||||
return Success ? llvm::Error::success()
|
||||
: llvm::make_error<llvm::StringError>(
|
||||
DiagPrinterWithOS->DiagnosticsOS.str(),
|
||||
llvm::inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
@@ -7,10 +7,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/DependencyScanning/DependencyScanningWorker.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/DependencyScanning/DependencyScannerImpl.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace dependencies;
|
||||
@@ -165,33 +168,29 @@ bool DependencyScanningWorker::computeDependencies(
|
||||
DC);
|
||||
}
|
||||
|
||||
llvm::Error
|
||||
DependencyScanningWorker::initializeCompilerInstanceWithContextOrError(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine) {
|
||||
bool Success = initializeCompilerInstanceWithContext(CWD, CommandLine);
|
||||
return CIWithContext->handleReturnStatus(Success);
|
||||
}
|
||||
bool DependencyScanningWorker::initializeCompilerInstanceWithContext(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine, DiagnosticConsumer &DC) {
|
||||
auto OverlayFSAndArgs =
|
||||
initVFSForByNameScanning(DepFS, CommandLine, CWD, "ScanningByName");
|
||||
auto &OverlayFS = OverlayFSAndArgs.first;
|
||||
const auto &ModifiedCommandLine = OverlayFSAndArgs.second;
|
||||
|
||||
llvm::Error
|
||||
DependencyScanningWorker::computeDependenciesByNameWithContextOrError(
|
||||
StringRef ModuleName, DependencyConsumer &Consumer,
|
||||
DependencyActionController &Controller) {
|
||||
bool Success =
|
||||
computeDependenciesByNameWithContext(ModuleName, Consumer, Controller);
|
||||
return CIWithContext->handleReturnStatus(Success);
|
||||
}
|
||||
auto DiagEngineWithCmdAndOpts =
|
||||
std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine,
|
||||
OverlayFS, DC);
|
||||
|
||||
llvm::Error
|
||||
DependencyScanningWorker::finalizeCompilerInstanceWithContextOrError() {
|
||||
bool Success = finalizeCompilerInstance();
|
||||
return CIWithContext->handleReturnStatus(Success);
|
||||
return initializeCompilerInstanceWithContext(
|
||||
CWD, ModifiedCommandLine, std::move(DiagEngineWithCmdAndOpts), OverlayFS);
|
||||
}
|
||||
|
||||
bool DependencyScanningWorker::initializeCompilerInstanceWithContext(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine, DiagnosticConsumer *DC) {
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine,
|
||||
std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
|
||||
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) {
|
||||
CIWithContext =
|
||||
std::make_unique<CompilerInstanceWithContext>(*this, CWD, CommandLine);
|
||||
return CIWithContext->initialize(DC);
|
||||
return CIWithContext->initialize(std::move(DiagEngineWithDiagOpts),
|
||||
OverlayFS);
|
||||
}
|
||||
|
||||
bool DependencyScanningWorker::computeDependenciesByNameWithContext(
|
||||
@@ -201,6 +200,6 @@ bool DependencyScanningWorker::computeDependenciesByNameWithContext(
|
||||
return CIWithContext->computeDependencies(ModuleName, Consumer, Controller);
|
||||
}
|
||||
|
||||
bool DependencyScanningWorker::finalizeCompilerInstance() {
|
||||
bool DependencyScanningWorker::finalizeCompilerInstanceWithContext() {
|
||||
return CIWithContext->finalize();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Tooling/DependencyScanningTool.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/DependencyScanning/DependencyScannerImpl.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
#include "clang/Frontend/Utils.h"
|
||||
#include <optional>
|
||||
|
||||
@@ -161,43 +164,112 @@ DependencyScanningTool::getModuleDependencies(
|
||||
StringRef ModuleName, ArrayRef<std::string> CommandLine, StringRef CWD,
|
||||
const llvm::DenseSet<ModuleID> &AlreadySeen,
|
||||
LookupModuleOutputCallback LookupModuleOutput) {
|
||||
FullDependencyConsumer Consumer(AlreadySeen);
|
||||
CallbackActionController Controller(LookupModuleOutput);
|
||||
if (auto Error =
|
||||
Worker.initializeCompilerInstanceWithContextOrError(CWD, CommandLine))
|
||||
return std::move(Error);
|
||||
initializeCompilerInstanceWithContextOrError(CWD, CommandLine))
|
||||
return Error;
|
||||
|
||||
auto Result = Worker.computeDependenciesByNameWithContextOrError(
|
||||
ModuleName, Consumer, Controller);
|
||||
auto Result = computeDependenciesByNameWithContextOrError(
|
||||
ModuleName, AlreadySeen, LookupModuleOutput);
|
||||
|
||||
if (auto Error = Worker.finalizeCompilerInstanceWithContextOrError())
|
||||
return std::move(Error);
|
||||
if (auto Error = finalizeCompilerInstanceWithContextOrError())
|
||||
return Error;
|
||||
|
||||
if (Result)
|
||||
return std::move(Result);
|
||||
|
||||
return Consumer.takeTranslationUnitDeps();
|
||||
return Result;
|
||||
}
|
||||
|
||||
llvm::Error DependencyScanningTool::initializeCompilerInstanceWithContext(
|
||||
/// Constructs the full -cc1 command line, including executable, for the given
|
||||
/// driver \c Cmd.
|
||||
static std::vector<std::string>
|
||||
buildCC1CommandLine(const driver::Command &Cmd) {
|
||||
const auto &Args = Cmd.getArguments();
|
||||
std::vector<std::string> Out;
|
||||
Out.reserve(Args.size() + 1);
|
||||
Out.emplace_back(Cmd.getExecutable());
|
||||
llvm::append_range(Out, Args);
|
||||
return Out;
|
||||
}
|
||||
|
||||
static std::optional<std::vector<std::string>> getFirstCC1CommandLine(
|
||||
ArrayRef<std::string> CommandLine, DiagnosticsEngine &Diags,
|
||||
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> ScanFS) {
|
||||
// Compilation holds a non-owning a reference to the Driver, hence we need to
|
||||
// keep the Driver alive when we use Compilation. Arguments to commands may be
|
||||
// owned by Alloc when expanded from response files.
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
const auto [Driver, Compilation] =
|
||||
buildCompilation(CommandLine, Diags, ScanFS, Alloc);
|
||||
if (!Compilation)
|
||||
return std::nullopt;
|
||||
|
||||
const auto IsClangCmd = [](const driver::Command &Cmd) {
|
||||
return StringRef(Cmd.getCreator().getName()) == "clang";
|
||||
};
|
||||
|
||||
const auto &Jobs = Compilation->getJobs();
|
||||
if (const auto It = llvm::find_if(Jobs, IsClangCmd); It != Jobs.end())
|
||||
return buildCC1CommandLine(*It);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static llvm::Error makeErrorFromDiagnosticsOS(
|
||||
TextDiagnosticsPrinterWithOutput &DiagPrinterWithOS) {
|
||||
return llvm::make_error<llvm::StringError>(
|
||||
DiagPrinterWithOS.DiagnosticsOS.str(), llvm::inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
llvm::Error
|
||||
DependencyScanningTool::initializeCompilerInstanceWithContextOrError(
|
||||
StringRef CWD, ArrayRef<std::string> CommandLine) {
|
||||
return Worker.initializeCompilerInstanceWithContextOrError(CWD, CommandLine);
|
||||
DiagPrinterWithOS =
|
||||
std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
|
||||
|
||||
if (CommandLine.size() >= 2 && CommandLine[1] == "-cc1") {
|
||||
// The input command line is already a -cc1 invocation; initialize the
|
||||
// compiler instance directly from it.
|
||||
if (Worker.initializeCompilerInstanceWithContext(
|
||||
CWD, CommandLine, DiagPrinterWithOS->DiagPrinter))
|
||||
return llvm::Error::success();
|
||||
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
|
||||
}
|
||||
|
||||
// The input command line is either a driver-style command line, or
|
||||
// ill-formed. In this case, we will first call the Driver to build a -cc1
|
||||
// command line for this compilation or diagnose any ill-formed input.
|
||||
auto OverlayFSAndArgs = initVFSForByNameScanning(
|
||||
&Worker.getVFS(), CommandLine, CWD, "ScanningByName");
|
||||
auto &OverlayFS = OverlayFSAndArgs.first;
|
||||
const auto &ModifiedCommandLine = OverlayFSAndArgs.second;
|
||||
|
||||
auto DiagEngineWithCmdAndOpts =
|
||||
std::make_unique<DiagnosticsEngineWithDiagOpts>(
|
||||
ModifiedCommandLine, OverlayFS, DiagPrinterWithOS->DiagPrinter);
|
||||
|
||||
const auto MaybeFirstCC1 = getFirstCC1CommandLine(
|
||||
ModifiedCommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS);
|
||||
if (!MaybeFirstCC1)
|
||||
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
|
||||
|
||||
if (Worker.initializeCompilerInstanceWithContext(
|
||||
CWD, *MaybeFirstCC1, std::move(DiagEngineWithCmdAndOpts), OverlayFS))
|
||||
return llvm::Error::success();
|
||||
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
|
||||
}
|
||||
|
||||
llvm::Expected<TranslationUnitDeps>
|
||||
DependencyScanningTool::computeDependenciesByNameWithContext(
|
||||
DependencyScanningTool::computeDependenciesByNameWithContextOrError(
|
||||
StringRef ModuleName, const llvm::DenseSet<ModuleID> &AlreadySeen,
|
||||
LookupModuleOutputCallback LookupModuleOutput) {
|
||||
FullDependencyConsumer Consumer(AlreadySeen);
|
||||
CallbackActionController Controller(LookupModuleOutput);
|
||||
llvm::Error Result = Worker.computeDependenciesByNameWithContextOrError(
|
||||
ModuleName, Consumer, Controller);
|
||||
if (Result)
|
||||
return std::move(Result);
|
||||
|
||||
return Consumer.takeTranslationUnitDeps();
|
||||
if (Worker.computeDependenciesByNameWithContext(ModuleName, Consumer,
|
||||
Controller))
|
||||
return Consumer.takeTranslationUnitDeps();
|
||||
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
|
||||
}
|
||||
|
||||
llvm::Error DependencyScanningTool::finalizeCompilerInstanceWithContext() {
|
||||
return Worker.finalizeCompilerInstanceWithContextOrError();
|
||||
llvm::Error
|
||||
DependencyScanningTool::finalizeCompilerInstanceWithContextOrError() {
|
||||
if (Worker.finalizeCompilerInstanceWithContext())
|
||||
return llvm::Error::success();
|
||||
return makeErrorFromDiagnosticsOS(*DiagPrinterWithOS);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,17 @@ module transitive { header "transitive.h" }
|
||||
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -module-names=root > %t/result.json
|
||||
// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
|
||||
|
||||
//--- cdb.cc1.json.template
|
||||
[{
|
||||
"file": "",
|
||||
"directory": "DIR",
|
||||
"command": "clang -cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -I DIR -x c"
|
||||
}]
|
||||
|
||||
// RUN: sed "s|DIR|%/t|g" %t/cdb.cc1.json.template > %t/cdb.cc1.json
|
||||
// RUN: clang-scan-deps -compilation-database %t/cdb.cc1.json -format experimental-full -module-names=root > %t/result.cc1.json
|
||||
// RUN: cat %t/result.cc1.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
|
||||
|
||||
// CHECK: {
|
||||
// CHECK-NEXT: "modules": [
|
||||
// CHECK-NEXT: {
|
||||
|
||||
@@ -33,6 +33,17 @@ module root1 { header "root1.h"}
|
||||
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -module-names=root,root1,direct > %t/result.json
|
||||
// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
|
||||
|
||||
//--- cdb.cc1.json.template
|
||||
[{
|
||||
"file": "",
|
||||
"directory": "DIR",
|
||||
"command": "clang -cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -I DIR -x c"
|
||||
}]
|
||||
|
||||
// RUN: sed "s|DIR|%/t|g" %t/cdb.cc1.json.template > %t/cdb.cc1.json
|
||||
// RUN: clang-scan-deps -compilation-database %t/cdb.cc1.json -format experimental-full -module-names=root,root1,direct > %t/result.cc1.json
|
||||
// RUN: cat %t/result.cc1.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s
|
||||
|
||||
// CHECK: {
|
||||
// CHECK-NEXT: "modules": [
|
||||
// CHECK-NEXT: {
|
||||
|
||||
@@ -1105,7 +1105,7 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
|
||||
HadErrors = true;
|
||||
} else {
|
||||
if (llvm::Error Err =
|
||||
WorkerTool.initializeCompilerInstanceWithContext(
|
||||
WorkerTool.initializeCompilerInstanceWithContextOrError(
|
||||
CWD, Input->CommandLine)) {
|
||||
handleErrorWithInfoString(
|
||||
"Compiler instance with context setup error", std::move(Err),
|
||||
@@ -1116,7 +1116,7 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
|
||||
|
||||
for (auto N : Names) {
|
||||
auto MaybeModuleDepsGraph =
|
||||
WorkerTool.computeDependenciesByNameWithContext(
|
||||
WorkerTool.computeDependenciesByNameWithContextOrError(
|
||||
N, AlreadySeenModules, LookupOutput);
|
||||
if (handleModuleResult(N, MaybeModuleDepsGraph, *FD, LocalIndex,
|
||||
DependencyOS, Errs)) {
|
||||
@@ -1126,7 +1126,7 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
|
||||
}
|
||||
|
||||
if (llvm::Error Err =
|
||||
WorkerTool.finalizeCompilerInstanceWithContext()) {
|
||||
WorkerTool.finalizeCompilerInstanceWithContextOrError()) {
|
||||
handleErrorWithInfoString(
|
||||
"Compiler instance with context finialization error",
|
||||
std::move(Err), DependencyOS, Errs);
|
||||
|
||||
Reference in New Issue
Block a user