forked from OSchip/llvm-project
[clang][deps] Split translation units into individual -cc1 or other commands
Instead of trying to "fix" the original driver invocation by appending arguments to it, split it into multiple commands, and for each -cc1 command use a CompilerInvocation to give precise control over the invocation. This change should make it easier to (in the future) canonicalize the command-line (e.g. to improve hits in something like ccache), apply optimizations, or start supporting multi-arch builds, which would require different modules for each arch. In the long run it may make sense to treat the TU commands as a dependency graph, each with their own dependencies on modules or earlier TU commands, but for now they are simply a list that is executed in order, and the dependencies are simply duplicated. Since we currently only support single-arch builds, there is no parallelism available in the execution. Differential Revision: https://reviews.llvm.org/D132405
This commit is contained in:
parent
260fb2bc3f
commit
f80a0ea760
|
@ -49,8 +49,16 @@ struct FullDependencies {
|
|||
/// determined that the differences are benign for this compilation.
|
||||
std::vector<ModuleID> ClangModuleDeps;
|
||||
|
||||
/// The command line of the TU (excluding the compiler executable).
|
||||
std::vector<std::string> CommandLine;
|
||||
/// The sequence of commands required to build the translation unit. Commands
|
||||
/// should be executed in order.
|
||||
///
|
||||
/// FIXME: If we add support for multi-arch builds in clang-scan-deps, we
|
||||
/// should make the dependencies between commands explicit to enable parallel
|
||||
/// builds of each architecture.
|
||||
std::vector<Command> Commands;
|
||||
|
||||
/// Deprecated driver command-line. This will be removed in a future version.
|
||||
std::vector<std::string> DriverCommandLine;
|
||||
};
|
||||
|
||||
struct FullDependenciesResult {
|
||||
|
@ -99,6 +107,12 @@ public:
|
|||
LookupModuleOutputCallback LookupModuleOutput,
|
||||
llvm::Optional<StringRef> ModuleName = None);
|
||||
|
||||
llvm::Expected<FullDependenciesResult> getFullDependenciesLegacyDriverCommand(
|
||||
const std::vector<std::string> &CommandLine, StringRef CWD,
|
||||
const llvm::StringSet<> &AlreadySeen,
|
||||
LookupModuleOutputCallback LookupModuleOutput,
|
||||
llvm::Optional<StringRef> ModuleName = None);
|
||||
|
||||
private:
|
||||
DependencyScanningWorker Worker;
|
||||
};
|
||||
|
@ -111,6 +125,10 @@ public:
|
|||
: AlreadySeen(AlreadySeen), LookupModuleOutput(LookupModuleOutput),
|
||||
EagerLoadModules(EagerLoadModules) {}
|
||||
|
||||
void handleBuildCommand(Command Cmd) override {
|
||||
Commands.push_back(std::move(Cmd));
|
||||
}
|
||||
|
||||
void handleDependencyOutputOpts(const DependencyOutputOptions &) override {}
|
||||
|
||||
void handleFileDependency(StringRef File) override {
|
||||
|
@ -134,14 +152,17 @@ public:
|
|||
return LookupModuleOutput(ID, Kind);
|
||||
}
|
||||
|
||||
FullDependenciesResult getFullDependencies(
|
||||
FullDependenciesResult getFullDependenciesLegacyDriverCommand(
|
||||
const std::vector<std::string> &OriginalCommandLine) const;
|
||||
|
||||
FullDependenciesResult takeFullDependencies();
|
||||
|
||||
private:
|
||||
std::vector<std::string> Dependencies;
|
||||
std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
|
||||
llvm::MapVector<std::string, ModuleDeps, llvm::StringMap<unsigned>>
|
||||
ClangModuleDeps;
|
||||
std::vector<Command> Commands;
|
||||
std::string ContextHash;
|
||||
std::vector<std::string> OutputPaths;
|
||||
const llvm::StringSet<> &AlreadySeen;
|
||||
|
|
|
@ -28,10 +28,20 @@ namespace dependencies {
|
|||
|
||||
class DependencyScanningWorkerFilesystem;
|
||||
|
||||
/// A command-line tool invocation that is part of building a TU.
|
||||
///
|
||||
/// \see FullDependencies::Commands.
|
||||
struct Command {
|
||||
std::string Executable;
|
||||
std::vector<std::string> Arguments;
|
||||
};
|
||||
|
||||
class DependencyConsumer {
|
||||
public:
|
||||
virtual ~DependencyConsumer() {}
|
||||
|
||||
virtual void handleBuildCommand(Command Cmd) = 0;
|
||||
|
||||
virtual void
|
||||
handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0;
|
||||
|
||||
|
|
|
@ -181,12 +181,16 @@ class ModuleDepCollector final : public DependencyCollector {
|
|||
public:
|
||||
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
|
||||
CompilerInstance &ScanInstance, DependencyConsumer &C,
|
||||
CompilerInvocation &&OriginalCI, bool OptimizeArgs,
|
||||
CompilerInvocation OriginalCI, bool OptimizeArgs,
|
||||
bool EagerLoadModules);
|
||||
|
||||
void attachToPreprocessor(Preprocessor &PP) override;
|
||||
void attachToASTReader(ASTReader &R) override;
|
||||
|
||||
/// Apply any changes implied by the discovered dependencies to the given
|
||||
/// invocation, (e.g. disable implicit modules, add explicit module paths).
|
||||
void applyDiscoveredDependencies(CompilerInvocation &CI);
|
||||
|
||||
private:
|
||||
friend ModuleDepCollectorPP;
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
|
|||
/// Prints out all of the gathered dependencies into a string.
|
||||
class MakeDependencyPrinterConsumer : public DependencyConsumer {
|
||||
public:
|
||||
void handleBuildCommand(Command) override {}
|
||||
|
||||
void
|
||||
handleDependencyOutputOpts(const DependencyOutputOptions &Opts) override {
|
||||
this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
|
||||
|
@ -120,14 +122,53 @@ DependencyScanningTool::getFullDependencies(
|
|||
Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName);
|
||||
if (Result)
|
||||
return std::move(Result);
|
||||
return Consumer.getFullDependencies(CommandLine);
|
||||
return Consumer.takeFullDependencies();
|
||||
}
|
||||
|
||||
FullDependenciesResult FullDependencyConsumer::getFullDependencies(
|
||||
llvm::Expected<FullDependenciesResult>
|
||||
DependencyScanningTool::getFullDependenciesLegacyDriverCommand(
|
||||
const std::vector<std::string> &CommandLine, StringRef CWD,
|
||||
const llvm::StringSet<> &AlreadySeen,
|
||||
LookupModuleOutputCallback LookupModuleOutput,
|
||||
llvm::Optional<StringRef> ModuleName) {
|
||||
FullDependencyConsumer Consumer(AlreadySeen, LookupModuleOutput,
|
||||
Worker.shouldEagerLoadModules());
|
||||
llvm::Error Result =
|
||||
Worker.computeDependencies(CWD, CommandLine, Consumer, ModuleName);
|
||||
if (Result)
|
||||
return std::move(Result);
|
||||
return Consumer.getFullDependenciesLegacyDriverCommand(CommandLine);
|
||||
}
|
||||
|
||||
FullDependenciesResult FullDependencyConsumer::takeFullDependencies() {
|
||||
FullDependenciesResult FDR;
|
||||
FullDependencies &FD = FDR.FullDeps;
|
||||
|
||||
FD.ID.ContextHash = std::move(ContextHash);
|
||||
FD.FileDeps = std::move(Dependencies);
|
||||
FD.PrebuiltModuleDeps = std::move(PrebuiltModuleDeps);
|
||||
FD.Commands = std::move(Commands);
|
||||
|
||||
for (auto &&M : ClangModuleDeps) {
|
||||
auto &MD = M.second;
|
||||
if (MD.ImportedByMainFile)
|
||||
FD.ClangModuleDeps.push_back(MD.ID);
|
||||
// TODO: Avoid handleModuleDependency even being called for modules
|
||||
// we've already seen.
|
||||
if (AlreadySeen.count(M.first))
|
||||
continue;
|
||||
FDR.DiscoveredModules.push_back(std::move(MD));
|
||||
}
|
||||
|
||||
return FDR;
|
||||
}
|
||||
|
||||
FullDependenciesResult
|
||||
FullDependencyConsumer::getFullDependenciesLegacyDriverCommand(
|
||||
const std::vector<std::string> &OriginalCommandLine) const {
|
||||
FullDependencies FD;
|
||||
|
||||
FD.CommandLine = makeTUCommandLineWithoutPaths(
|
||||
FD.DriverCommandLine = makeTUCommandLineWithoutPaths(
|
||||
ArrayRef<std::string>(OriginalCommandLine).slice(1));
|
||||
|
||||
FD.ID.ContextHash = std::move(ContextHash);
|
||||
|
@ -135,7 +176,7 @@ FullDependenciesResult FullDependencyConsumer::getFullDependencies(
|
|||
FD.FileDeps.assign(Dependencies.begin(), Dependencies.end());
|
||||
|
||||
for (const PrebuiltModuleDep &PMD : PrebuiltModuleDeps)
|
||||
FD.CommandLine.push_back("-fmodule-file=" + PMD.PCMFile);
|
||||
FD.DriverCommandLine.push_back("-fmodule-file=" + PMD.PCMFile);
|
||||
|
||||
for (auto &&M : ClangModuleDeps) {
|
||||
auto &MD = M.second;
|
||||
|
@ -143,11 +184,12 @@ FullDependenciesResult FullDependencyConsumer::getFullDependencies(
|
|||
FD.ClangModuleDeps.push_back(MD.ID);
|
||||
auto PCMPath = LookupModuleOutput(MD.ID, ModuleOutputKind::ModuleFile);
|
||||
if (EagerLoadModules) {
|
||||
FD.CommandLine.push_back("-fmodule-file=" + PCMPath);
|
||||
FD.DriverCommandLine.push_back("-fmodule-file=" + PCMPath);
|
||||
} else {
|
||||
FD.CommandLine.push_back("-fmodule-map-file=" + MD.ClangModuleMapFile);
|
||||
FD.CommandLine.push_back("-fmodule-file=" + MD.ID.ModuleName + "=" +
|
||||
PCMPath);
|
||||
FD.DriverCommandLine.push_back("-fmodule-map-file=" +
|
||||
MD.ClangModuleMapFile);
|
||||
FD.DriverCommandLine.push_back("-fmodule-file=" + MD.ID.ModuleName +
|
||||
"=" + PCMPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
|
||||
#include "clang/Basic/DiagnosticFrontend.h"
|
||||
#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/Job.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Frontend/FrontendActions.h"
|
||||
|
@ -17,6 +22,7 @@
|
|||
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
|
||||
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
|
||||
#include "clang/Tooling/Tooling.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace tooling;
|
||||
|
@ -156,6 +162,17 @@ public:
|
|||
// Restore the value of DisableFree, which may be modified by Tooling.
|
||||
OriginalInvocation.getFrontendOpts().DisableFree = DisableFree;
|
||||
|
||||
if (Scanned) {
|
||||
// Scanning runs once for the first -cc1 invocation in a chain of driver
|
||||
// jobs. For any dependent jobs, reuse the scanning result and just
|
||||
// update the LastCC1Arguments to correspond to the new invocation.
|
||||
// FIXME: to support multi-arch builds, each arch requires a separate scan
|
||||
setLastCC1Arguments(std::move(OriginalInvocation));
|
||||
return true;
|
||||
}
|
||||
|
||||
Scanned = true;
|
||||
|
||||
// Create a compiler instance to handle the actual work.
|
||||
CompilerInstance ScanInstance(std::move(PCHContainerOps));
|
||||
ScanInstance.setInvocation(std::move(Invocation));
|
||||
|
@ -230,9 +247,10 @@ public:
|
|||
std::move(Opts), WorkingDirectory, Consumer));
|
||||
break;
|
||||
case ScanningOutputFormat::Full:
|
||||
ScanInstance.addDependencyCollector(std::make_shared<ModuleDepCollector>(
|
||||
std::move(Opts), ScanInstance, Consumer,
|
||||
std::move(OriginalInvocation), OptimizeArgs, EagerLoadModules));
|
||||
MDC = std::make_shared<ModuleDepCollector>(
|
||||
std::move(Opts), ScanInstance, Consumer, OriginalInvocation,
|
||||
OptimizeArgs, EagerLoadModules);
|
||||
ScanInstance.addDependencyCollector(MDC);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -253,9 +271,31 @@ public:
|
|||
const bool Result = ScanInstance.ExecuteAction(*Action);
|
||||
if (!DepFS)
|
||||
FileMgr->clearStatCache();
|
||||
|
||||
if (Result)
|
||||
setLastCC1Arguments(std::move(OriginalInvocation));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool hasScanned() const { return Scanned; }
|
||||
|
||||
/// Take the cc1 arguments corresponding to the most recent invocation used
|
||||
/// with this action. Any modifications implied by the discovered dependencies
|
||||
/// will have already been applied.
|
||||
std::vector<std::string> takeLastCC1Arguments() {
|
||||
std::vector<std::string> Result;
|
||||
std::swap(Result, LastCC1Arguments); // Reset LastCC1Arguments to empty.
|
||||
return Result;
|
||||
}
|
||||
|
||||
private:
|
||||
void setLastCC1Arguments(CompilerInvocation &&CI) {
|
||||
if (MDC)
|
||||
MDC->applyDiscoveredDependencies(CI);
|
||||
LastCC1Arguments = CI.getCC1CommandLine();
|
||||
}
|
||||
|
||||
private:
|
||||
StringRef WorkingDirectory;
|
||||
DependencyConsumer &Consumer;
|
||||
|
@ -265,6 +305,9 @@ private:
|
|||
bool EagerLoadModules;
|
||||
bool DisableFree;
|
||||
llvm::Optional<StringRef> ModuleName;
|
||||
std::shared_ptr<ModuleDepCollector> MDC;
|
||||
std::vector<std::string> LastCC1Arguments;
|
||||
bool Scanned = false;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -313,6 +356,36 @@ runWithDiags(DiagnosticOptions *DiagOpts,
|
|||
llvm::inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
static bool forEachDriverJob(
|
||||
ArrayRef<std::string> Args, DiagnosticsEngine &Diags, FileManager &FM,
|
||||
llvm::function_ref<bool(const driver::Command &Cmd)> Callback) {
|
||||
std::unique_ptr<driver::Driver> Driver = std::make_unique<driver::Driver>(
|
||||
Args[0], llvm::sys::getDefaultTargetTriple(), Diags,
|
||||
"clang LLVM compiler", &FM.getVirtualFileSystem());
|
||||
Driver->setTitle("clang_based_tool");
|
||||
|
||||
std::vector<const char *> Argv;
|
||||
for (const std::string &Arg : Args)
|
||||
Argv.push_back(Arg.c_str());
|
||||
|
||||
// The "input file not found" diagnostics from the driver are useful.
|
||||
// The driver is only aware of the VFS working directory, but some clients
|
||||
// change this at the FileManager level instead.
|
||||
// In this case the checks have false positives, so skip them.
|
||||
if (!FM.getFileSystemOpts().WorkingDir.empty())
|
||||
Driver->setCheckInputsExist(false);
|
||||
const std::unique_ptr<driver::Compilation> Compilation(
|
||||
Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
|
||||
if (!Compilation)
|
||||
return false;
|
||||
|
||||
for (const driver::Command &Job : Compilation->getJobs()) {
|
||||
if (!Callback(Job))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::Error DependencyScanningWorker::computeDependencies(
|
||||
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
|
||||
DependencyConsumer &Consumer, llvm::Optional<StringRef> ModuleName) {
|
||||
|
@ -338,25 +411,60 @@ llvm::Error DependencyScanningWorker::computeDependencies(
|
|||
llvm::transform(CommandLine, FinalCCommandLine.begin(),
|
||||
[](const std::string &Str) { return Str.c_str(); });
|
||||
|
||||
return runWithDiags(CreateAndPopulateDiagOpts(FinalCCommandLine).release(),
|
||||
[&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) {
|
||||
// DisableFree is modified by Tooling for running
|
||||
// in-process; preserve the original value, which is
|
||||
// always true for a driver invocation.
|
||||
bool DisableFree = true;
|
||||
DependencyScanningAction Action(
|
||||
WorkingDirectory, Consumer, DepFS, Format,
|
||||
OptimizeArgs, EagerLoadModules, DisableFree,
|
||||
ModuleName);
|
||||
// Create an invocation that uses the underlying file
|
||||
// system to ensure that any file system requests that
|
||||
// are made by the driver do not go through the
|
||||
// dependency scanning filesystem.
|
||||
ToolInvocation Invocation(FinalCommandLine, &Action,
|
||||
CurrentFiles.get(),
|
||||
PCHContainerOps);
|
||||
Invocation.setDiagnosticConsumer(&DC);
|
||||
Invocation.setDiagnosticOptions(&DiagOpts);
|
||||
return Invocation.run();
|
||||
});
|
||||
return runWithDiags(
|
||||
CreateAndPopulateDiagOpts(FinalCCommandLine).release(),
|
||||
[&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) {
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
|
||||
CompilerInstance::createDiagnostics(&DiagOpts, &DC, false);
|
||||
// Although `Diagnostics` are used only for command-line parsing, the
|
||||
// custom `DiagConsumer` might expect a `SourceManager` to be present.
|
||||
SourceManager SrcMgr(*Diags, *CurrentFiles);
|
||||
Diags->setSourceManager(&SrcMgr);
|
||||
// DisableFree is modified by Tooling for running
|
||||
// in-process; preserve the original value, which is
|
||||
// always true for a driver invocation.
|
||||
bool DisableFree = true;
|
||||
DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS,
|
||||
Format, OptimizeArgs, EagerLoadModules,
|
||||
DisableFree, ModuleName);
|
||||
bool Success = forEachDriverJob(
|
||||
FinalCommandLine, *Diags, *CurrentFiles,
|
||||
[&](const driver::Command &Cmd) {
|
||||
if (StringRef(Cmd.getCreator().getName()) != "clang") {
|
||||
// Non-clang command. Just pass through to the dependency
|
||||
// consumer.
|
||||
Consumer.handleBuildCommand(
|
||||
{Cmd.getExecutable(),
|
||||
{Cmd.getArguments().begin(), Cmd.getArguments().end()}});
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> Argv;
|
||||
Argv.push_back(Cmd.getExecutable());
|
||||
Argv.insert(Argv.end(), Cmd.getArguments().begin(),
|
||||
Cmd.getArguments().end());
|
||||
|
||||
// Create an invocation that uses the underlying file
|
||||
// system to ensure that any file system requests that
|
||||
// are made by the driver do not go through the
|
||||
// dependency scanning filesystem.
|
||||
ToolInvocation Invocation(std::move(Argv), &Action,
|
||||
&*CurrentFiles, PCHContainerOps);
|
||||
Invocation.setDiagnosticConsumer(Diags->getClient());
|
||||
Invocation.setDiagnosticOptions(&Diags->getDiagnosticOptions());
|
||||
if (!Invocation.run())
|
||||
return false;
|
||||
|
||||
std::vector<std::string> Args = Action.takeLastCC1Arguments();
|
||||
Consumer.handleBuildCommand(
|
||||
{Cmd.getExecutable(), std::move(Args)});
|
||||
return true;
|
||||
});
|
||||
|
||||
if (Success && !Action.hasScanned()) {
|
||||
Diags->Report(diag::err_fe_expected_compiler_job)
|
||||
<< llvm::join(FinalCommandLine, " ");
|
||||
}
|
||||
return Success && Action.hasScanned();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -174,6 +174,34 @@ void ModuleDepCollector::addModuleFiles(
|
|||
}
|
||||
}
|
||||
|
||||
static bool needsModules(FrontendInputFile FIF) {
|
||||
switch (FIF.getKind().getLanguage()) {
|
||||
case Language::Unknown:
|
||||
case Language::Asm:
|
||||
case Language::LLVM_IR:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) {
|
||||
CI.clearImplicitModuleBuildOptions();
|
||||
|
||||
if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
|
||||
SmallVector<ModuleID> DirectDeps;
|
||||
for (const auto &KV : ModularDeps)
|
||||
if (KV.second->ImportedByMainFile)
|
||||
DirectDeps.push_back(KV.second->ID);
|
||||
|
||||
addModuleMapFiles(CI, DirectDeps);
|
||||
addModuleFiles(CI, DirectDeps);
|
||||
|
||||
for (const auto &KV : DirectPrebuiltModularDeps)
|
||||
CI.getFrontendOpts().ModuleFiles.push_back(KV.second.PCMFile);
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getModuleContextHash(const ModuleDeps &MD,
|
||||
const CompilerInvocation &CI,
|
||||
bool EagerLoadModules) {
|
||||
|
@ -508,7 +536,7 @@ void ModuleDepCollectorPP::addAffectingModule(
|
|||
ModuleDepCollector::ModuleDepCollector(
|
||||
std::unique_ptr<DependencyOutputOptions> Opts,
|
||||
CompilerInstance &ScanInstance, DependencyConsumer &C,
|
||||
CompilerInvocation &&OriginalCI, bool OptimizeArgs, bool EagerLoadModules)
|
||||
CompilerInvocation OriginalCI, bool OptimizeArgs, bool EagerLoadModules)
|
||||
: ScanInstance(ScanInstance), Consumer(C), Opts(std::move(Opts)),
|
||||
OriginalInvocation(std::move(OriginalCI)), OptimizeArgs(OptimizeArgs),
|
||||
EagerLoadModules(EagerLoadModules) {}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
// Test the deprecated version of the API that returns a driver command instead
|
||||
// of multiple -cc1 commands.
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json
|
||||
|
||||
// RUN: clang-scan-deps -compilation-database=%t/cdb.json -format experimental-full \
|
||||
// RUN: -deprecated-driver-command | sed 's:\\\\\?:/:g' | FileCheck %s
|
||||
|
||||
// CHECK: "command-line": [
|
||||
// CHECK: "-c"
|
||||
// CHECK: "{{.*}}tu.c"
|
||||
// CHECK: "-save-temps"
|
||||
// CHECK: "-fno-implicit-modules"
|
||||
// CHECK: "-fno-implicit-module-maps"
|
||||
// CHECK: ]
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK: "{{.*}}tu.c",
|
||||
// CHECK: "{{.*}}header.h"
|
||||
// CHECK: ]
|
||||
|
||||
//--- cdb.json.in
|
||||
[{
|
||||
"directory": "DIR",
|
||||
"command": "clang -c DIR/tu.c -save-temps",
|
||||
"file": "DIR/tu.c"
|
||||
}]
|
||||
|
||||
//--- header.h
|
||||
void bar(void);
|
||||
|
||||
//--- tu.c
|
||||
#include "header.h"
|
||||
|
||||
void foo(void) {
|
||||
bar();
|
||||
}
|
|
@ -28,7 +28,7 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:.*]],
|
||||
// CHECK: "clang-context-hash": "[[HASH_TU:.*]],
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_MOD]]",
|
||||
|
@ -36,13 +36,11 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-fno-implicit-modules"
|
||||
// CHECK: "-fno-implicit-module-maps"
|
||||
// CHECK-NOT: "-fimplicit-modules"
|
||||
// CHECK-NOT: "-fimplicit-module-maps"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -95,7 +95,7 @@ module X { header "X.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK: "clang-context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_X]]",
|
||||
|
@ -104,14 +104,13 @@ module X { header "X.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/test.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
|
||||
// CHECK: {
|
||||
// CHECK-NEXT: "modules": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
|
@ -149,7 +148,7 @@ module X { header "X.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK: "clang-context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "{{.*}}",
|
||||
|
@ -158,10 +157,8 @@ module X { header "X.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/test.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -38,10 +38,11 @@
|
|||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NOT: "-DFOO"
|
||||
// CHECK-NOT: "FOO"
|
||||
// CHECK: ]
|
||||
// CHECK: "input-file": "{{.*}}tu1.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_FOO]]"
|
||||
|
@ -49,11 +50,12 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-DFOO"
|
||||
// CHECK: "-D"
|
||||
// CHECK-NEXT: "FOO"
|
||||
// CHECK: ]
|
||||
// CHECK: "input-file": "{{.*}}tu2.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_NO_FOO]]"
|
||||
|
@ -61,8 +63,9 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-DFOO"
|
||||
// CHECK: "-fmodules-ignore-macro=FOO"
|
||||
// CHECK: "-D"
|
||||
// CHECK-NEXT: "FOO"
|
||||
// CHECK: ]
|
||||
// CHECK: "input-file": "{{.*}}tu3.c"
|
||||
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-MF"
|
||||
// CHECK: "-dependency-file"
|
||||
// CHECK: ]
|
||||
// CHECK: "input-file": "{{.*}}tu1.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH2]]"
|
||||
|
@ -48,6 +48,7 @@
|
|||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NOT: "-MF"
|
||||
// CHECK-NOT: "-dependency-file"
|
||||
// CHECK: ]
|
||||
// CHECK: "input-file": "{{.*}}tu2.c"
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
// CHECK: ]
|
||||
// CHECK: "input-file": "{{.*}}tu1.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH2]]"
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK: "clang-context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_MOD_A]]",
|
||||
|
@ -49,15 +49,13 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "modules": [
|
||||
|
||||
// CHECK: "modules": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-module-deps": [],
|
||||
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap",
|
||||
|
@ -79,7 +77,7 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK: "clang-context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NOT: "context-hash": "[[HASH_MOD_A]]",
|
||||
|
@ -88,10 +86,8 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -78,7 +78,7 @@ module Direct { header "direct.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK: "clang-context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "{{.*}}",
|
||||
|
@ -93,10 +93,8 @@ module Direct { header "direct.h" }
|
|||
// CHECK_EAGER-NOT: "-fmodule-map-file={{.*}}"
|
||||
// CHECK_EAGER: "-fmodule-file=[[PREFIX]]/{{.*}}/Direct-{{.*}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
|
@ -33,7 +33,7 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H2]]",
|
||||
|
@ -42,12 +42,10 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules-fmodule-name-no-module-built.m"
|
||||
// CHECK-NEXT: "[[PREFIX]]/Inputs/header3.h"
|
||||
// CHECK-NEXT: "[[PREFIX]]/Inputs/header.h"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules-fmodule-name-no-module-built.m"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -82,76 +82,96 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: "commands": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NOT: "-fimplicit-modules"
|
||||
// CHECK-NOT: "-fimplicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}"
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-fno-implicit-modules"
|
||||
// CHECK: "-fno-implicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: "commands": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NOT: "-fimplicit-modules"
|
||||
// CHECK-NOT: "-fimplicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}"
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-fno-implicit-modules"
|
||||
// CHECK: "-fno-implicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: "commands": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NOT: "-fimplicit-modules"
|
||||
// CHECK-NOT: "-fimplicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}"
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-fno-implicit-modules"
|
||||
// CHECK: "-fno-implicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU_DINCLUDE:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: "commands": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1_DINCLUDE]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU_DINCLUDE:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_H1_DINCLUDE]]",
|
||||
// CHECK-NEXT: "module-name": "header1"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NOT: "-fimplicit-modules"
|
||||
// CHECK-NOT: "-fimplicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1_DINCLUDE]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "executable": "{{.*}}clang{{.*}}"
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input2.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input2.cpp"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-fno-implicit-modules"
|
||||
// CHECK: "-fno-implicit-module-maps"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H1_DINCLUDE]]/header1-{{[A-Z0-9]+}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input2.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input2.cpp"
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -26,35 +26,35 @@ framework module FW_Private { umbrella header "FW_Private.h" }
|
|||
// CHECK: {
|
||||
// CHECK-NEXT: "modules": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-module-deps": [],
|
||||
// CHECK: "clang-module-deps": [],
|
||||
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap",
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Headers/FW.h",
|
||||
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap",
|
||||
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "name": "FW"
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-module-deps": [],
|
||||
// CHECK: },
|
||||
// CHECK: {
|
||||
// CHECK: "clang-module-deps": [],
|
||||
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap",
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.modulemap",
|
||||
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap",
|
||||
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/FW_Private.h"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "name": "FW_Private"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK: }
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK: "clang-context-hash": "{{.*}}",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "{{.*}}",
|
||||
|
@ -66,16 +66,14 @@ framework module FW_Private { umbrella header "FW_Private.h" }
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm"
|
||||
// CHECK: "-fmodule-file={{.*}}/FW-{{.*}}.pcm"
|
||||
// CHECK: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm"
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/tu.m"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.m"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// RUN: %deps-to-rsp %t/result.json --module-name=FW > %t/FW.cc1.rsp
|
||||
// RUN: %deps-to-rsp %t/result.json --module-name=FW_Private > %t/FW_Private.cc1.rsp
|
||||
|
|
|
@ -67,7 +67,7 @@ framework module FW_Private {
|
|||
// CHECK_TU-NEXT: ],
|
||||
// CHECK_TU-NEXT: "translation-units": [
|
||||
// CHECK_TU-NEXT: {
|
||||
// CHECK_TU-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK_TU: "clang-context-hash": "{{.*}}",
|
||||
// CHECK_TU-NEXT: "clang-module-deps": [
|
||||
// CHECK_TU-NEXT: {
|
||||
// CHECK_TU-NEXT: "context-hash": "{{.*}}",
|
||||
|
@ -82,14 +82,12 @@ framework module FW_Private {
|
|||
// CHECK_TU: "-fmodule-file={{.*}}/FW-{{.*}}.pcm"
|
||||
// CHECK_TU: "-fmodule-file={{.*}}/FW_Private-{{.*}}.pcm"
|
||||
// CHECK_TU: ],
|
||||
// CHECK_TU-NEXT: "file-deps": [
|
||||
// CHECK_TU: "file-deps": [
|
||||
// CHECK_TU-NEXT: "[[PREFIX]]/from_tu.m",
|
||||
// CHECK_TU-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/Two.h"
|
||||
// CHECK_TU-NEXT: ],
|
||||
// CHECK_TU-NEXT: "input-file": "[[PREFIX]]/from_tu.m"
|
||||
// CHECK_TU-NEXT: }
|
||||
// CHECK_TU-NEXT: ]
|
||||
// CHECK_TU-NEXT: }
|
||||
|
||||
// RUN: %deps-to-rsp %t/from_tu_result.json --module-name=FW > %t/FW.cc1.rsp
|
||||
// RUN: %deps-to-rsp %t/from_tu_result.json --module-name=FW_Private > %t/FW_Private.cc1.rsp
|
||||
|
@ -175,7 +173,7 @@ module Mod { header "Mod.h" }
|
|||
// CHECK_MODULE-NEXT: ],
|
||||
// CHECK_MODULE-NEXT: "translation-units": [
|
||||
// CHECK_MODULE-NEXT: {
|
||||
// CHECK_MODULE-NEXT: "clang-context-hash": "{{.*}}",
|
||||
// CHECK_MODULE: "clang-context-hash": "{{.*}}",
|
||||
// CHECK_MODULE-NEXT: "clang-module-deps": [
|
||||
// CHECK_MODULE-NEXT: {
|
||||
// CHECK_MODULE-NEXT: "context-hash": "{{.*}}",
|
||||
|
@ -184,13 +182,11 @@ module Mod { header "Mod.h" }
|
|||
// CHECK_MODULE-NEXT: ],
|
||||
// CHECK_MODULE-NEXT: "command-line": [
|
||||
// CHECK_MODULE: ],
|
||||
// CHECK_MODULE-NEXT: "file-deps": [
|
||||
// CHECK_MODULE: "file-deps": [
|
||||
// CHECK_MODULE-NEXT: "[[PREFIX]]/from_module.m"
|
||||
// CHECK_MODULE-NEXT: ],
|
||||
// CHECK_MODULE-NEXT: "input-file": "[[PREFIX]]/from_module.m"
|
||||
// CHECK_MODULE-NEXT: }
|
||||
// CHECK_MODULE-NEXT: ]
|
||||
// CHECK_MODULE-NEXT: }
|
||||
|
||||
// RUN: %deps-to-rsp %t/from_module_result.json --module-name=FW > %t/FW.cc1.rsp
|
||||
// RUN: %deps-to-rsp %t/from_module_result.json --module-name=FW_Private > %t/FW_Private.cc1.rsp
|
||||
|
|
|
@ -31,7 +31,7 @@ inferred a = 0;
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK: "clang-context-hash": "[[HASH_TU:[A-Z0-9]+]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_INFERRED]]",
|
||||
|
@ -40,10 +40,8 @@ inferred a = 0;
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/modules_cdb_input.cpp"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -52,7 +52,7 @@ module User [no_undeclared_includes] { header "user.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "{{.*}}"
|
||||
// CHECK: "clang-context-hash": "{{.*}}"
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "{{.*}}"
|
||||
|
@ -61,13 +61,11 @@ module User [no_undeclared_includes] { header "user.h" }
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK: ],
|
||||
// CHECK-NEXT: "file-deps": [
|
||||
// CHECK: "file-deps": [
|
||||
// CHECK-NEXT: "[[PREFIX]]/test.c"
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "input-file": "[[PREFIX]]/test.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// RUN: %deps-to-rsp %t/result.json --module-name=User > %t/User.cc1.rsp
|
||||
// RUN: %deps-to-rsp %t/result.json --tu-index=0 > %t/tu.rsp
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "translation-units": [
|
||||
// CHECK-PCH-NEXT: {
|
||||
// CHECK-PCH-NEXT: "clang-context-hash": "[[HASH_PCH:.*]]",
|
||||
// CHECK-PCH: "clang-context-hash": "[[HASH_PCH:.*]]",
|
||||
// CHECK-PCH-NEXT: "clang-module-deps": [
|
||||
// CHECK-PCH-NEXT: {
|
||||
// CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON]]",
|
||||
|
@ -45,13 +45,11 @@
|
|||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "command-line": [
|
||||
// CHECK-PCH: ],
|
||||
// CHECK-PCH-NEXT: "file-deps": [
|
||||
// CHECK-PCH: "file-deps": [
|
||||
// CHECK-PCH-NEXT: "[[PREFIX]]/pch.h"
|
||||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "input-file": "[[PREFIX]]/pch.h"
|
||||
// CHECK-PCH-NEXT: }
|
||||
// CHECK-PCH-NEXT: ]
|
||||
// CHECK-PCH-NEXT: }
|
||||
|
||||
// Explicitly build the PCH:
|
||||
//
|
||||
|
@ -85,7 +83,7 @@
|
|||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "translation-units": [
|
||||
// CHECK-TU-NEXT: {
|
||||
// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-TU: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-TU-NEXT: "clang-module-deps": [
|
||||
// CHECK-TU-NEXT: {
|
||||
// CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]"
|
||||
|
@ -94,14 +92,12 @@
|
|||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "command-line": [
|
||||
// CHECK-TU: ],
|
||||
// CHECK-TU-NEXT: "file-deps": [
|
||||
// CHECK-TU: "file-deps": [
|
||||
// CHECK-TU-NEXT: "[[PREFIX]]/tu.c",
|
||||
// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch"
|
||||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-TU-NEXT: }
|
||||
// CHECK-TU-NEXT: ]
|
||||
// CHECK-TU-NEXT: }
|
||||
|
||||
// Explicitly build the TU:
|
||||
//
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "translation-units": [
|
||||
// CHECK-PCH-NEXT: {
|
||||
// CHECK-PCH-NEXT: "clang-context-hash": "[[HASH_PCH:.*]]",
|
||||
// CHECK-PCH: "clang-context-hash": "[[HASH_PCH:.*]]",
|
||||
// CHECK-PCH-NEXT: "clang-module-deps": [
|
||||
// CHECK-PCH-NEXT: {
|
||||
// CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON]]",
|
||||
|
@ -41,13 +41,11 @@
|
|||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "command-line": [
|
||||
// CHECK-PCH: ],
|
||||
// CHECK-PCH-NEXT: "file-deps": [
|
||||
// CHECK-PCH: "file-deps": [
|
||||
// CHECK-PCH-NEXT: "[[PREFIX]]/pch.h"
|
||||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "input-file": "[[PREFIX]]/pch.h"
|
||||
// CHECK-PCH-NEXT: }
|
||||
// CHECK-PCH-NEXT: ]
|
||||
// CHECK-PCH-NEXT: }
|
||||
|
||||
// Explicitly build the PCH:
|
||||
//
|
||||
|
@ -82,7 +80,7 @@
|
|||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "translation-units": [
|
||||
// CHECK-TU-NEXT: {
|
||||
// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-TU: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-TU-NEXT: "clang-module-deps": [
|
||||
// CHECK-TU-NEXT: {
|
||||
// CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]"
|
||||
|
@ -91,14 +89,12 @@
|
|||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "command-line": [
|
||||
// CHECK-TU: ],
|
||||
// CHECK-TU-NEXT: "file-deps": [
|
||||
// CHECK-TU: "file-deps": [
|
||||
// CHECK-TU-NEXT: "[[PREFIX]]/tu.c",
|
||||
// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch"
|
||||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-TU-NEXT: }
|
||||
// CHECK-TU-NEXT: ]
|
||||
// CHECK-TU-NEXT: }
|
||||
|
||||
// Explicitly build the TU:
|
||||
//
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "translation-units": [
|
||||
// CHECK-PCH-NEXT: {
|
||||
// CHECK-PCH-NEXT: "clang-context-hash": "[[HASH_PCH:.*]]",
|
||||
// CHECK-PCH: "clang-context-hash": "[[HASH_PCH:.*]]",
|
||||
// CHECK-PCH-NEXT: "clang-module-deps": [
|
||||
// CHECK-PCH-NEXT: {
|
||||
// CHECK-PCH-NEXT: "context-hash": "[[HASH_MOD_COMMON_1]]",
|
||||
|
@ -74,13 +74,11 @@
|
|||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "command-line": [
|
||||
// CHECK-PCH: ],
|
||||
// CHECK-PCH-NEXT: "file-deps": [
|
||||
// CHECK-PCH: "file-deps": [
|
||||
// CHECK-PCH-NEXT: "[[PREFIX]]/pch.h"
|
||||
// CHECK-PCH-NEXT: ],
|
||||
// CHECK-PCH-NEXT: "input-file": "[[PREFIX]]/pch.h"
|
||||
// CHECK-PCH-NEXT: }
|
||||
// CHECK-PCH-NEXT: ]
|
||||
// CHECK-PCH-NEXT: }
|
||||
|
||||
// Explicitly build the PCH:
|
||||
//
|
||||
|
@ -118,7 +116,7 @@
|
|||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "translation-units": [
|
||||
// CHECK-TU-NEXT: {
|
||||
// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-TU: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-TU-NEXT: "clang-module-deps": [
|
||||
// CHECK-TU-NEXT: {
|
||||
// CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]",
|
||||
|
@ -127,14 +125,12 @@
|
|||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "command-line": [
|
||||
// CHECK-TU: ],
|
||||
// CHECK-TU-NEXT: "file-deps": [
|
||||
// CHECK-TU: "file-deps": [
|
||||
// CHECK-TU-NEXT: "[[PREFIX]]/tu.c",
|
||||
// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch"
|
||||
// CHECK-TU-NEXT: ],
|
||||
// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c"
|
||||
// CHECK-TU-NEXT: }
|
||||
// CHECK-TU-NEXT: ]
|
||||
// CHECK-TU-NEXT: }
|
||||
|
||||
// Explicitly build the TU:
|
||||
//
|
||||
|
@ -168,7 +164,7 @@
|
|||
// CHECK-TU-WITH-COMMON-NEXT: ],
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "translation-units": [
|
||||
// CHECK-TU-WITH-COMMON-NEXT: {
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "clang-context-hash": "[[HASH_TU_WITH_COMMON:.*]]",
|
||||
// CHECK-TU-WITH-COMMON: "clang-context-hash": "[[HASH_TU_WITH_COMMON:.*]]",
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "clang-module-deps": [
|
||||
// CHECK-TU-WITH-COMMON-NEXT: {
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "context-hash": "[[HASH_MOD_TU_WITH_COMMON]]",
|
||||
|
@ -178,14 +174,12 @@
|
|||
// CHECK-TU-WITH-COMMON-NEXT: "command-line": [
|
||||
// CHECK-TU-WITH-COMMON: "-fmodule-file=[[PREFIX]]/build/{{.*}}/ModCommon2-{{.*}}.pcm"
|
||||
// CHECK-TU-WITH-COMMON: ],
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "file-deps": [
|
||||
// CHECK-TU-WITH-COMMON: "file-deps": [
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/tu_with_common.c",
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/pch.h.gch"
|
||||
// CHECK-TU-WITH-COMMON-NEXT: ],
|
||||
// CHECK-TU-WITH-COMMON-NEXT: "input-file": "[[PREFIX]]/tu_with_common.c"
|
||||
// CHECK-TU-WITH-COMMON-NEXT: }
|
||||
// CHECK-TU-WITH-COMMON-NEXT: ]
|
||||
// CHECK-TU-WITH-COMMON-NEXT: }
|
||||
|
||||
// Explicitly build the TU that has common modules with the PCH:
|
||||
//
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
// Test scanning when the driver requires multiple jobs. E.g. with -save-temps
|
||||
// there will be separate -E, -emit-llvm-bc, -S, and -cc1as jobs, which should
|
||||
// each result in a "command" in the output.
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json
|
||||
|
||||
// RUN: clang-scan-deps -compilation-database %t/cdb.json -module-files-dir %t/modules \
|
||||
// RUN: -j 1 -format experimental-full -mode preprocess-dependency-directives \
|
||||
// RUN: > %t/deps.json
|
||||
|
||||
// RUN: cat %t/deps.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t
|
||||
|
||||
// Build the -save-temps + -fmodules case
|
||||
// RUN: %deps-to-rsp %t/deps.json --module-name=Mod > %t/Mod.rsp
|
||||
// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 0 > %t/tu-cpp.rsp
|
||||
// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 1 > %t/tu-emit-ir.rsp
|
||||
// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 2 > %t/tu-emit-asm.rsp
|
||||
// RUN: %deps-to-rsp %t/deps.json --tu-index 1 --tu-cmd-index 3 > %t/tu-cc1as.rsp
|
||||
// RUN: %clang @%t/Mod.rsp
|
||||
// RUN: %clang @%t/tu-cpp.rsp
|
||||
// RUN: ls %t/tu_save_temps_module.i
|
||||
// RUN: %clang @%t/tu-emit-ir.rsp
|
||||
// RUN: ls %t/tu_save_temps_module.bc
|
||||
// RUN: %clang @%t/tu-emit-asm.rsp
|
||||
// RUN: ls %t/tu_save_temps_module.s
|
||||
// RUN: %clang @%t/tu-cc1as.rsp
|
||||
// RUN: ls %t/tu_save_temps_module.o
|
||||
|
||||
|
||||
// CHECK: "modules": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "clang-modulemap-file": "[[PREFIX]]{{.}}module.modulemap"
|
||||
// CHECK: "name": "Mod"
|
||||
// CHECK: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "commands": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash":
|
||||
// CHECK-NEXT: "clang-module-deps": []
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-cc1"
|
||||
// CHECK: "-o"
|
||||
// CHECK-NEXT: "{{.*}}tu_no_integrated_cpp{{.*}}.i"
|
||||
// CHECK: "-E"
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: "executable": "clang_tool"
|
||||
// CHECK: "input-file": "[[PREFIX]]{{.}}tu_no_integrated_cpp.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash":
|
||||
// CHECK-NEXT: "clang-module-deps": []
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-cc1"
|
||||
// CHECK: "-o"
|
||||
// CHECK-NEXT: "{{.*}}tu_no_integrated_cpp.o"
|
||||
// CHECK: "-emit-obj"
|
||||
// CHECK: "{{.*}}tu_no_integrated_cpp{{.*}}.i"
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: "executable": "clang_tool"
|
||||
// CHECK: "input-file": "[[PREFIX]]{{.}}tu_no_integrated_cpp.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "commands": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "module-name": "Mod"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-cc1"
|
||||
// CHECK: "-o"
|
||||
// CHECK-NEXT: "{{.*}}tu_save_temps_module.i"
|
||||
// CHECK: "-E"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]{{.}}modules{{.*}}Mod-{{.*}}.pcm"
|
||||
// CHECK: "{{.*}}tu_save_temps_module.c"
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: "executable": "clang_tool"
|
||||
// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "module-name": "Mod"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-cc1"
|
||||
// CHECK: "-o"
|
||||
// CHECK-NEXT: "{{.*}}tu_save_temps_module.bc"
|
||||
// CHECK: "-emit-llvm-bc"
|
||||
// CHECK: "{{.*}}tu_save_temps_module.i"
|
||||
// CHECK: "-fmodule-file={{.*}}[[PREFIX]]{{.}}modules{{.*}}Mod-{{.*}}.pcm"
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: "executable": "clang_tool"
|
||||
// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "module-name": "Mod"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-cc1"
|
||||
// CHECK: "-o"
|
||||
// CHECK-NEXT: "{{.*}}tu_save_temps_module.s"
|
||||
// CHECK: "-S"
|
||||
// CHECK: "{{.*}}tu_save_temps_module.bc"
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: "executable": "clang_tool"
|
||||
// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK: "module-name": "Mod"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-cc1as"
|
||||
// CHECK: "-o"
|
||||
// CHECK-NEXT: "{{.*}}tu_save_temps_module.o"
|
||||
// CHECK: "{{.*}}tu_save_temps_module.s"
|
||||
// CHECK: ]
|
||||
// CHECK-NEXT: "executable": "clang_tool"
|
||||
// CHECK: "input-file": "[[PREFIX]]{{.}}tu_save_temps_module.c"
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
|
||||
//--- cdb.json.in
|
||||
[
|
||||
{
|
||||
"directory": "DIR"
|
||||
"command": "clang_tool -c DIR/tu_no_integrated_cpp.c -no-integrated-cpp -o DIR/tu_no_integrated_cpp.o"
|
||||
"file": "DIR/tu_no_integrated_cpp.c"
|
||||
},
|
||||
{
|
||||
"directory": "DIR"
|
||||
"command": "clang_tool -c DIR/tu_save_temps_module.c -save-temps=obj -o DIR/tu_save_temps_module.o -fmodules -fimplicit-modules -fimplicit-module-maps"
|
||||
"file": "DIR/tu_save_temps_module.c"
|
||||
}
|
||||
]
|
||||
|
||||
//--- plain_header.h
|
||||
void foo(void);
|
||||
|
||||
//--- module_header.h
|
||||
void bar(void);
|
||||
|
||||
//--- module.modulemap
|
||||
module Mod { header "module_header.h" }
|
||||
|
||||
//--- tu_no_integrated_cpp.c
|
||||
#include "plain_header.h"
|
||||
void tu_no_integrated_cpp(void) { foo(); }
|
||||
|
||||
//--- tu_save_temps_module.c
|
||||
#include "module_header.h"
|
||||
void tu_save_temps(void) { bar(); }
|
|
@ -61,7 +61,7 @@
|
|||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "translation-units": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK: "clang-context-hash": "[[HASH_TU:.*]]",
|
||||
// CHECK-NEXT: "clang-module-deps": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "context-hash": "[[HASH_MOD_HEADER]]",
|
||||
|
@ -73,13 +73,11 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: "command-line": [
|
||||
// CHECK-NEXT: "-fsyntax-only",
|
||||
// CHECK-NEXT: "-cc1",
|
||||
// CHECK-NOT: "-fmodules-cache-path=
|
||||
// CHECK-NOT: "-fmodules-validate-once-per-build-session"
|
||||
// CHECK-NOT: "-fbuild-session-timestamp=
|
||||
// CHECK-NOT: "-fbuild-session-file=
|
||||
// CHECK-NOT: "-fmodules-prune-interval=
|
||||
// CHECK-NOT: "-fmodules-prune-after=
|
||||
// CHECK: ],
|
||||
// CHECK: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
|
|
@ -182,6 +182,11 @@ llvm::cl::list<std::string> ModuleDepTargets(
|
|||
llvm::cl::desc("The names of dependency targets for the dependency file"),
|
||||
llvm::cl::cat(DependencyScannerCategory));
|
||||
|
||||
llvm::cl::opt<bool> DeprecatedDriverCommand(
|
||||
"deprecated-driver-command", llvm::cl::Optional,
|
||||
llvm::cl::desc("use a single driver command to build the tu (deprecated)"),
|
||||
llvm::cl::cat(DependencyScannerCategory));
|
||||
|
||||
enum ResourceDirRecipeKind {
|
||||
RDRK_ModifyCompilerPath,
|
||||
RDRK_InvokeCompiler,
|
||||
|
@ -256,7 +261,7 @@ class FullDeps {
|
|||
public:
|
||||
void mergeDeps(StringRef Input, FullDependenciesResult FDR,
|
||||
size_t InputIndex) {
|
||||
const FullDependencies &FD = FDR.FullDeps;
|
||||
FullDependencies &FD = FDR.FullDeps;
|
||||
|
||||
InputDeps ID;
|
||||
ID.FileName = std::string(Input);
|
||||
|
@ -274,7 +279,8 @@ public:
|
|||
Modules.insert(I, {{MD.ID, InputIndex}, std::move(MD)});
|
||||
}
|
||||
|
||||
ID.CommandLine = FD.CommandLine;
|
||||
ID.DriverCommandLine = std::move(FD.DriverCommandLine);
|
||||
ID.Commands = std::move(FD.Commands);
|
||||
Inputs.push_back(std::move(ID));
|
||||
}
|
||||
|
||||
|
@ -311,14 +317,33 @@ public:
|
|||
|
||||
Array TUs;
|
||||
for (auto &&I : Inputs) {
|
||||
Object O{
|
||||
{"input-file", I.FileName},
|
||||
{"clang-context-hash", I.ContextHash},
|
||||
{"file-deps", I.FileDeps},
|
||||
{"clang-module-deps", toJSONSorted(I.ModuleDeps)},
|
||||
{"command-line", I.CommandLine},
|
||||
};
|
||||
TUs.push_back(std::move(O));
|
||||
Array Commands;
|
||||
if (I.DriverCommandLine.empty()) {
|
||||
for (const auto &Cmd : I.Commands) {
|
||||
Object O{
|
||||
{"input-file", I.FileName},
|
||||
{"clang-context-hash", I.ContextHash},
|
||||
{"file-deps", I.FileDeps},
|
||||
{"clang-module-deps", toJSONSorted(I.ModuleDeps)},
|
||||
{"executable", Cmd.Executable},
|
||||
{"command-line", Cmd.Arguments},
|
||||
};
|
||||
Commands.push_back(std::move(O));
|
||||
}
|
||||
} else {
|
||||
Object O{
|
||||
{"input-file", I.FileName},
|
||||
{"clang-context-hash", I.ContextHash},
|
||||
{"file-deps", I.FileDeps},
|
||||
{"clang-module-deps", toJSONSorted(I.ModuleDeps)},
|
||||
{"executable", "clang"},
|
||||
{"command-line", I.DriverCommandLine},
|
||||
};
|
||||
Commands.push_back(std::move(O));
|
||||
}
|
||||
TUs.push_back(Object{
|
||||
{"commands", std::move(Commands)},
|
||||
});
|
||||
}
|
||||
|
||||
Object Output{
|
||||
|
@ -353,7 +378,8 @@ private:
|
|||
std::string ContextHash;
|
||||
std::vector<std::string> FileDeps;
|
||||
std::vector<ModuleID> ModuleDeps;
|
||||
std::vector<std::string> CommandLine;
|
||||
std::vector<std::string> DriverCommandLine;
|
||||
std::vector<Command> Commands;
|
||||
};
|
||||
|
||||
std::mutex Lock;
|
||||
|
@ -559,6 +585,14 @@ int main(int argc, const char **argv) {
|
|||
if (handleMakeDependencyToolResult(Filename, MaybeFile, DependencyOS,
|
||||
Errs))
|
||||
HadErrors = true;
|
||||
} else if (DeprecatedDriverCommand) {
|
||||
auto MaybeFullDeps =
|
||||
WorkerTools[I]->getFullDependenciesLegacyDriverCommand(
|
||||
Input->CommandLine, CWD, AlreadySeenModules, LookupOutput,
|
||||
MaybeModuleName);
|
||||
if (handleFullDependencyToolResult(Filename, MaybeFullDeps, FD,
|
||||
LocalIndex, DependencyOS, Errs))
|
||||
HadErrors = true;
|
||||
} else {
|
||||
auto MaybeFullDeps = WorkerTools[I]->getFullDependencies(
|
||||
Input->CommandLine, CWD, AlreadySeenModules, LookupOutput,
|
||||
|
|
|
@ -48,6 +48,9 @@ def main():
|
|||
type=str)
|
||||
action.add_argument("--tu-index", help="The index of the translation unit to get arguments for",
|
||||
type=int)
|
||||
parser.add_argument("--tu-cmd-index",
|
||||
help="The index of the command within the translation unit (default=0)",
|
||||
type=int, default=0)
|
||||
args = parser.parse_args()
|
||||
|
||||
full_deps = parseFullDeps(json.load(open(args.full_deps_file, 'r')))
|
||||
|
@ -58,7 +61,8 @@ def main():
|
|||
if args.module_name:
|
||||
cmd = findModule(args.module_name, full_deps)['command-line']
|
||||
elif args.tu_index != None:
|
||||
cmd = full_deps.translation_units[args.tu_index]['command-line']
|
||||
tu = full_deps.translation_units[args.tu_index]
|
||||
cmd = tu['commands'][args.tu_cmd_index]['command-line']
|
||||
|
||||
print(" ".join(map(quote, cmd)))
|
||||
except:
|
||||
|
|
Loading…
Reference in New Issue