Skip to content

Commit eafd515

Browse files
authored
[clang][deps] Support single-file mode for all formats (llvm#88764)
The `clang-scan-deps` tool can be used for fast scanning of batches of compilation commands passed in via the `-compilation-database` option. This gets awkward in our tests where we have to resort to using `.in`/`.template` JSON files and running them through `sed` in order to embed LIT's `%t` variable into them. However, most of our tests only need to pass single compilation command, so this dance is entirely unnecessary. This patch makes sure the existing "per-file" mode (where the compilation command is passed in-line after the `--` argument) works for all output formats, not only `P1689`.
1 parent e6ecff8 commit eafd515

File tree

2 files changed

+23
-52
lines changed

2 files changed

+23
-52
lines changed

clang/test/ClangScanDeps/error.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,10 @@
11
// RUN: rm -rf %t
22
// RUN: split-file %s %t
33

4-
//--- missing_tu.json.in
5-
[{
6-
"directory": "DIR",
7-
"command": "clang -fsyntax-only DIR/missing_tu.c",
8-
"file": "DIR/missing_tu.c"
9-
}]
10-
//--- missing_header.json.in
11-
[{
12-
"directory": "DIR",
13-
"command": "clang -fsyntax-only DIR/missing_header.c",
14-
"file": "DIR/missing_header.c"
15-
}]
164
//--- missing_header.c
175
#include "missing.h"
186

19-
// RUN: sed -e "s|DIR|%/t|g" %t/missing_tu.json.in > %t/missing_tu.json
20-
// RUN: not clang-scan-deps -compilation-database %t/missing_tu.json 2>%t/missing_tu.errs
7+
// RUN: not clang-scan-deps -- %clang -c %t/missing_tu.c 2>%t/missing_tu.errs
218
// RUN: echo EOF >> %t/missing_tu.errs
229
// RUN: cat %t/missing_tu.errs | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-MISSING-TU -DPREFIX=%/t
2310
// CHECK-MISSING-TU: Error while scanning dependencies for [[PREFIX]]/missing_tu.c
@@ -26,8 +13,7 @@
2613
// CHECK-MISSING-TU-NEXT: error:
2714
// CHECK-MISSING-TU-NEXT: EOF
2815

29-
// RUN: sed -e "s|DIR|%/t|g" %t/missing_header.json.in > %t/missing_header.json
30-
// RUN: not clang-scan-deps -compilation-database %t/missing_header.json 2>%t/missing_header.errs
16+
// RUN: not clang-scan-deps -- %clang -c %t/missing_header.c 2>%t/missing_header.errs
3117
// RUN: echo EOF >> %t/missing_header.errs
3218
// RUN: cat %t/missing_header.errs | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-MISSING-HEADER -DPREFIX=%/t
3319
// CHECK-MISSING-HEADER: Error while scanning dependencies for [[PREFIX]]/missing_header.c

clang/tools/clang-scan-deps/ClangScanDeps.cpp

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ static bool RoundTripArgs = DoRoundTripDefault;
9898
static void ParseArgs(int argc, char **argv) {
9999
ScanDepsOptTable Tbl;
100100
llvm::StringRef ToolName = argv[0];
101-
llvm::BumpPtrAllocator A;
102-
llvm::StringSaver Saver{A};
101+
llvm::BumpPtrAllocator Alloc;
102+
llvm::StringSaver Saver{Alloc};
103103
llvm::opt::InputArgList Args =
104104
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
105105
llvm::errs() << Msg << '\n';
@@ -186,14 +186,8 @@ static void ParseArgs(int argc, char **argv) {
186186
}
187187
}
188188

189-
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_compilation_database_EQ)) {
189+
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_compilation_database_EQ))
190190
CompilationDB = A->getValue();
191-
} else if (Format != ScanningOutputFormat::P1689) {
192-
llvm::errs() << ToolName
193-
<< ": for the --compiilation-database option: must be "
194-
"specified at least once!";
195-
std::exit(1);
196-
}
197191

198192
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_name_EQ))
199193
ModuleName = A->getValue();
@@ -225,9 +219,8 @@ static void ParseArgs(int argc, char **argv) {
225219

226220
RoundTripArgs = Args.hasArg(OPT_round_trip_args);
227221

228-
if (auto *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
229-
CommandLine.insert(CommandLine.end(), A->getValues().begin(),
230-
A->getValues().end());
222+
if (const llvm::opt::Arg *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
223+
CommandLine.assign(A->getValues().begin(), A->getValues().end());
231224
}
232225

233226
class SharedStream {
@@ -694,38 +687,28 @@ static std::string getModuleCachePath(ArrayRef<std::string> Args) {
694687
return std::string(Path);
695688
}
696689

697-
// getCompilationDataBase - If -compilation-database is set, load the
698-
// compilation database from the specified file. Otherwise if the we're
699-
// generating P1689 format, trying to generate the compilation database
700-
// form specified command line after the positional parameter "--".
690+
/// Attempts to construct the compilation database from '-compilation-database'
691+
/// or from the arguments following the positional '--'.
701692
static std::unique_ptr<tooling::CompilationDatabase>
702-
getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
693+
getCompilationDatabase(int argc, char **argv, std::string &ErrorMessage) {
703694
ParseArgs(argc, argv);
704695

696+
if (!(CommandLine.empty() ^ CompilationDB.empty())) {
697+
llvm::errs() << "The compilation command line must be provided either via "
698+
"'-compilation-database' or after '--'.";
699+
return nullptr;
700+
}
701+
705702
if (!CompilationDB.empty())
706703
return tooling::JSONCompilationDatabase::loadFromFile(
707704
CompilationDB, ErrorMessage,
708705
tooling::JSONCommandLineSyntax::AutoDetect);
709706

710-
if (Format != ScanningOutputFormat::P1689) {
711-
llvm::errs() << "the --compilation-database option: must be specified at "
712-
"least once!";
713-
return nullptr;
714-
}
715-
716-
// Trying to get the input file, the output file and the command line options
717-
// from the positional parameter "--".
718-
char **DoubleDash = std::find(argv, argv + argc, StringRef("--"));
719-
if (DoubleDash == argv + argc) {
720-
llvm::errs() << "The command line arguments is required after '--' in "
721-
"P1689 per file mode.";
722-
return nullptr;
723-
}
724-
725707
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
726708
CompilerInstance::createDiagnostics(new DiagnosticOptions);
727709
driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
728710
*Diags);
711+
TheDriver.setCheckInputsExist(false);
729712
std::unique_ptr<driver::Compilation> C(
730713
TheDriver.BuildCompilation(CommandLine));
731714
if (!C || C->getJobs().empty())
@@ -740,7 +723,8 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
740723

741724
FrontendOptions &FEOpts = CI->getFrontendOpts();
742725
if (FEOpts.Inputs.size() != 1) {
743-
llvm::errs() << "Only one input file is allowed in P1689 per file mode.";
726+
llvm::errs()
727+
<< "Exactly one input file is required in the per-file mode ('--').\n";
744728
return nullptr;
745729
}
746730

@@ -749,8 +733,9 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
749733
auto LastCmd = C->getJobs().end();
750734
LastCmd--;
751735
if (LastCmd->getOutputFilenames().size() != 1) {
752-
llvm::errs() << "The command line should provide exactly one output file "
753-
"in P1689 per file mode.\n";
736+
llvm::errs()
737+
<< "Exactly one output file is required in the per-file mode ('--').\n";
738+
return nullptr;
754739
}
755740
StringRef OutputFile = LastCmd->getOutputFilenames().front();
756741

@@ -790,7 +775,7 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
790775
int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
791776
std::string ErrorMessage;
792777
std::unique_ptr<tooling::CompilationDatabase> Compilations =
793-
getCompilationDataBase(argc, argv, ErrorMessage);
778+
getCompilationDatabase(argc, argv, ErrorMessage);
794779
if (!Compilations) {
795780
llvm::errs() << ErrorMessage << "\n";
796781
return 1;

0 commit comments

Comments
 (0)