Skip to content

[clang][deps] Support single-file mode for all formats #88764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions clang/test/ClangScanDeps/error.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
// RUN: rm -rf %t
// RUN: split-file %s %t

//--- missing_tu.json.in
[{
"directory": "DIR",
"command": "clang -fsyntax-only DIR/missing_tu.c",
"file": "DIR/missing_tu.c"
}]
//--- missing_header.json.in
[{
"directory": "DIR",
"command": "clang -fsyntax-only DIR/missing_header.c",
"file": "DIR/missing_header.c"
}]
//--- missing_header.c
#include "missing.h"

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

// RUN: sed -e "s|DIR|%/t|g" %t/missing_header.json.in > %t/missing_header.json
// RUN: not clang-scan-deps -compilation-database %t/missing_header.json 2>%t/missing_header.errs
// RUN: not clang-scan-deps -- %clang -c %t/missing_header.c 2>%t/missing_header.errs
// RUN: echo EOF >> %t/missing_header.errs
// RUN: cat %t/missing_header.errs | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-MISSING-HEADER -DPREFIX=%/t
// CHECK-MISSING-HEADER: Error while scanning dependencies for [[PREFIX]]/missing_header.c
Expand Down
57 changes: 21 additions & 36 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ static bool RoundTripArgs = DoRoundTripDefault;
static void ParseArgs(int argc, char **argv) {
ScanDepsOptTable Tbl;
llvm::StringRef ToolName = argv[0];
llvm::BumpPtrAllocator A;
llvm::StringSaver Saver{A};
llvm::BumpPtrAllocator Alloc;
llvm::StringSaver Saver{Alloc};
llvm::opt::InputArgList Args =
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
llvm::errs() << Msg << '\n';
Expand Down Expand Up @@ -186,14 +186,8 @@ static void ParseArgs(int argc, char **argv) {
}
}

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

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

RoundTripArgs = Args.hasArg(OPT_round_trip_args);

if (auto *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
CommandLine.insert(CommandLine.end(), A->getValues().begin(),
A->getValues().end());
if (const llvm::opt::Arg *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
CommandLine.assign(A->getValues().begin(), A->getValues().end());
}

class SharedStream {
Expand Down Expand Up @@ -694,38 +687,28 @@ static std::string getModuleCachePath(ArrayRef<std::string> Args) {
return std::string(Path);
}

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

if (!(CommandLine.empty() ^ CompilationDB.empty())) {
llvm::errs() << "The compilation command line must be provided either via "
"'-compilation-database' or after '--'.";
return nullptr;
}

if (!CompilationDB.empty())
return tooling::JSONCompilationDatabase::loadFromFile(
CompilationDB, ErrorMessage,
tooling::JSONCommandLineSyntax::AutoDetect);

if (Format != ScanningOutputFormat::P1689) {
llvm::errs() << "the --compilation-database option: must be specified at "
"least once!";
return nullptr;
}

// Trying to get the input file, the output file and the command line options
// from the positional parameter "--".
char **DoubleDash = std::find(argv, argv + argc, StringRef("--"));
if (DoubleDash == argv + argc) {
llvm::errs() << "The command line arguments is required after '--' in "
"P1689 per file mode.";
return nullptr;
}

llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions);
driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
*Diags);
TheDriver.setCheckInputsExist(false);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is here because some tests rely on the fact that we fail later and print a specific error message if the main input file doesn't exist.

std::unique_ptr<driver::Compilation> C(
TheDriver.BuildCompilation(CommandLine));
if (!C || C->getJobs().empty())
Expand All @@ -740,7 +723,8 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {

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

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

Expand Down Expand Up @@ -790,7 +775,7 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
std::string ErrorMessage;
std::unique_ptr<tooling::CompilationDatabase> Compilations =
getCompilationDataBase(argc, argv, ErrorMessage);
getCompilationDatabase(argc, argv, ErrorMessage);
if (!Compilations) {
llvm::errs() << ErrorMessage << "\n";
return 1;
Expand Down