Skip to content

Commit b3d7c45

Browse files
author
git apple-llvm automerger
committed
Merge commit 'ef51a35f8589' from swift/release/6.0 into stable/20230725
2 parents 9f21016 + ef51a35 commit b3d7c45

File tree

4 files changed

+81
-77
lines changed

4 files changed

+81
-77
lines changed

clang/test/ClangScanDeps/error.cpp

+18-23
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
1-
// RUN: rm -rf %t.dir
2-
// RUN: rm -rf %t.cdb
3-
// RUN: mkdir -p %t.dir
4-
// RUN: cp %s %t.dir/regular_cdb_input.cpp
5-
// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/regular_cdb.json > %t.cdb
6-
// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/regular_cdb_clangcl.json > %t_clangcl.cdb
7-
//
8-
// RUN: not clang-scan-deps -compilation-database %t.cdb -j 1 2>%t.dir/errs
9-
// RUN: echo EOF >> %t.dir/errs
10-
// RUN: FileCheck %s --input-file %t.dir/errs
11-
12-
// RUN: not clang-scan-deps -compilation-database %t_clangcl.cdb -j 1 2>%t.dir/errs_clangcl
13-
// RUN: echo EOF >> %t.dir/errs_clangcl
14-
// RUN: FileCheck %s --input-file %t.dir/errs_clangcl
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
153

4+
//--- missing_header.c
165
#include "missing.h"
176

18-
// CHECK: Error while scanning dependencies
19-
// CHECK-NEXT: error: no such file or directory:
20-
// CHECK-NEXT: error: no input files
21-
// CHECK-NEXT: error:
22-
// CHECK-NEXT: Error while scanning dependencies
23-
// CHECK-NEXT: fatal error: 'missing.h' file not found
24-
// CHECK-NEXT: Error while scanning dependencies
25-
// CHECK-NEXT: fatal error: 'missing.h' file not found
26-
// CHECK-NEXT: EOF
7+
// RUN: not clang-scan-deps -- %clang -c %t/missing_tu.c 2>%t/missing_tu.errs
8+
// RUN: echo EOF >> %t/missing_tu.errs
9+
// RUN: cat %t/missing_tu.errs | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-MISSING-TU -DPREFIX=%/t
10+
// CHECK-MISSING-TU: Error while scanning dependencies for [[PREFIX]]/missing_tu.c
11+
// CHECK-MISSING-TU-NEXT: error: no such file or directory: '[[PREFIX]]/missing_tu.c'
12+
// CHECK-MISSING-TU-NEXT: error: no input files
13+
// CHECK-MISSING-TU-NEXT: error:
14+
// CHECK-MISSING-TU-NEXT: EOF
15+
16+
// RUN: not clang-scan-deps -- %clang -c %t/missing_header.c 2>%t/missing_header.errs
17+
// RUN: echo EOF >> %t/missing_header.errs
18+
// RUN: cat %t/missing_header.errs | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-MISSING-HEADER -DPREFIX=%/t
19+
// CHECK-MISSING-HEADER: Error while scanning dependencies for [[PREFIX]]/missing_header.c
20+
// CHECK-MISSING-HEADER-NEXT: fatal error: 'missing.h' file not found
21+
// CHECK-MISSING-HEADER-NEXT: EOF

clang/test/ClangScanDeps/module-format.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// RUN: rm -f %t/cdb_pch.json
1717
// RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_pch.json > %t/cdb_pch.json
1818
// RUN: clang-scan-deps -compilation-database %t/cdb_pch.json -format experimental-full \
19-
// RUN: -module-files-dir %t/build > %t/result_pch.json
19+
// RUN: -module-files-dir %t/build -o %t/result_pch.json
2020

2121
// Explicitly build the PCH:
2222
//

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

+60-53
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ enum ResourceDirRecipeKind {
8181
RDRK_InvokeCompiler,
8282
};
8383

84+
static std::string OutputFileName = "-";
8485
static ScanningMode ScanMode = ScanningMode::DependencyDirectivesScan;
8586
static ScanningOutputFormat Format = ScanningOutputFormat::Make;
8687
static ScanningOptimizations OptimizeArgs;
@@ -115,8 +116,8 @@ static bool RoundTripArgs = DoRoundTripDefault;
115116
static void ParseArgs(int argc, char **argv) {
116117
ScanDepsOptTable Tbl;
117118
llvm::StringRef ToolName = argv[0];
118-
llvm::BumpPtrAllocator A;
119-
llvm::StringSaver Saver{A};
119+
llvm::BumpPtrAllocator Alloc;
120+
llvm::StringSaver Saver{Alloc};
120121
llvm::opt::InputArgList Args =
121122
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
122123
llvm::errs() << Msg << '\n';
@@ -196,6 +197,9 @@ static void ParseArgs(int argc, char **argv) {
196197
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_files_dir_EQ))
197198
ModuleFilesDir = A->getValue();
198199

200+
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_o))
201+
OutputFileName = A->getValue();
202+
199203
EagerLoadModules = Args.hasArg(OPT_eager_load_pcm);
200204

201205
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_j)) {
@@ -207,14 +211,8 @@ static void ParseArgs(int argc, char **argv) {
207211
}
208212
}
209213

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

219217
if (const llvm::opt::Arg *A = Args.getLastArg(OPT_module_name_EQ))
220218
ModuleName = A->getValue();
@@ -265,9 +263,8 @@ static void ParseArgs(int argc, char **argv) {
265263

266264
RoundTripArgs = Args.hasArg(OPT_round_trip_args);
267265

268-
if (auto *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
269-
CommandLine.insert(CommandLine.end(), A->getValues().begin(),
270-
A->getValues().end());
266+
if (const llvm::opt::Arg *A = Args.getLastArgNoClaim(OPT_DASH_DASH))
267+
CommandLine.assign(A->getValues().begin(), A->getValues().end());
271268
}
272269

273270
class SharedStream {
@@ -521,7 +518,7 @@ handleMakeDependencyToolResult(const std::string &Input,
521518

522519
static bool handleTreeDependencyToolResult(
523520
llvm::cas::ObjectStore &CAS, const std::string &Input,
524-
llvm::Expected<llvm::cas::ObjectProxy> &MaybeTree, SharedStream &OS,
521+
llvm::Expected<llvm::cas::ObjectProxy> &MaybeTree, llvm::raw_ostream &OS,
525522
SharedStream &Errs) {
526523
if (!MaybeTree) {
527524
llvm::handleAllErrors(
@@ -534,17 +531,15 @@ static bool handleTreeDependencyToolResult(
534531
});
535532
return true;
536533
}
537-
OS.applyLocked([&](llvm::raw_ostream &OS) {
538-
OS << "tree " << MaybeTree->getID() << " for '" << Input << "'\n";
539-
});
534+
OS << "tree " << MaybeTree->getID() << " for '" << Input << "'\n";
540535
return false;
541536
}
542537

543538
static bool
544539
handleIncludeTreeToolResult(llvm::cas::ObjectStore &CAS,
545540
const std::string &Input,
546541
Expected<cas::IncludeTreeRoot> &MaybeTree,
547-
SharedStream &OS, SharedStream &Errs) {
542+
llvm::raw_ostream &OS, SharedStream &Errs) {
548543
if (!MaybeTree) {
549544
llvm::handleAllErrors(
550545
MaybeTree.takeError(), [&Input, &Errs](llvm::StringError &Err) {
@@ -566,11 +561,9 @@ handleIncludeTreeToolResult(llvm::cas::ObjectStore &CAS,
566561
};
567562

568563
std::optional<llvm::Error> E;
569-
OS.applyLocked([&](llvm::raw_ostream &OS) {
570-
MaybeTree->getID().print(OS);
571-
OS << " - " << Input << "\n";
572-
E = MaybeTree->print(OS);
573-
});
564+
MaybeTree->getID().print(OS);
565+
OS << " - " << Input << "\n";
566+
E = MaybeTree->print(OS);
574567
if (*E)
575568
return printError(std::move(*E));
576569
return false;
@@ -689,6 +682,11 @@ class FullDeps {
689682
}
690683

691684
void printFullOutput(raw_ostream &OS) {
685+
// Skip sorting modules and constructing the JSON object if the output
686+
// cannot be observed anyway. This makes timings less noisy.
687+
if (&OS == &llvm::nulls())
688+
return;
689+
692690
// Sort the modules by name to get a deterministic order.
693691
std::vector<IndexedModuleID> ModuleIDs;
694692
for (auto &&M : Modules)
@@ -975,39 +973,29 @@ static std::string getModuleCachePath(ArrayRef<std::string> Args) {
975973
return std::string(Path);
976974
}
977975

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

983+
if (!(CommandLine.empty() ^ CompilationDB.empty())) {
984+
llvm::errs() << "The compilation command line must be provided either via "
985+
"'-compilation-database' or after '--'.";
986+
return nullptr;
987+
}
988+
987989
if (!CompilationDB.empty())
988990
return tooling::JSONCompilationDatabase::loadFromFile(
989991
CompilationDB, ErrorMessage,
990992
tooling::JSONCommandLineSyntax::AutoDetect);
991993

992-
if (Format != ScanningOutputFormat::P1689) {
993-
llvm::errs() << "the --compilation-database option: must be specified at "
994-
"least once!";
995-
return nullptr;
996-
}
997-
998-
// Trying to get the input file, the output file and the command line options
999-
// from the positional parameter "--".
1000-
char **DoubleDash = std::find(argv, argv + argc, StringRef("--"));
1001-
if (DoubleDash == argv + argc) {
1002-
llvm::errs() << "The command line arguments is required after '--' in "
1003-
"P1689 per file mode.";
1004-
return nullptr;
1005-
}
1006-
1007994
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
1008995
CompilerInstance::createDiagnostics(new DiagnosticOptions);
1009996
driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
1010997
*Diags);
998+
TheDriver.setCheckInputsExist(false);
1011999
std::unique_ptr<driver::Compilation> C(
10121000
TheDriver.BuildCompilation(CommandLine));
10131001
if (!C)
@@ -1022,7 +1010,8 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
10221010

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

@@ -1031,8 +1020,9 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
10311020
auto LastCmd = C->getJobs().end();
10321021
LastCmd--;
10331022
if (LastCmd->getOutputFilenames().size() != 1) {
1034-
llvm::errs() << "The command line should provide exactly one output file "
1035-
"in P1689 per file mode.\n";
1023+
llvm::errs()
1024+
<< "Exactly one output file is required in the per-file mode ('--').\n";
1025+
return nullptr;
10361026
}
10371027
StringRef OutputFile = LastCmd->getOutputFilenames().front();
10381028

@@ -1072,7 +1062,7 @@ getCompilationDataBase(int argc, char **argv, std::string &ErrorMessage) {
10721062
int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
10731063
std::string ErrorMessage;
10741064
std::unique_ptr<tooling::CompilationDatabase> Compilations =
1075-
getCompilationDataBase(argc, argv, ErrorMessage);
1065+
getCompilationDatabase(argc, argv, ErrorMessage);
10761066
if (!Compilations) {
10771067
llvm::errs() << ErrorMessage << "\n";
10781068
return 1;
@@ -1157,8 +1147,25 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
11571147
});
11581148

11591149
SharedStream Errs(llvm::errs());
1160-
// Print out the dependency results to STDOUT by default.
1161-
SharedStream DependencyOS(llvm::outs());
1150+
1151+
std::optional<llvm::raw_fd_ostream> FileOS;
1152+
llvm::raw_ostream &ThreadUnsafeDependencyOS = [&]() -> llvm::raw_ostream & {
1153+
if (OutputFileName == "-")
1154+
return llvm::outs();
1155+
1156+
if (OutputFileName == "/dev/null")
1157+
return llvm::nulls();
1158+
1159+
std::error_code EC;
1160+
FileOS.emplace(OutputFileName, EC);
1161+
if (EC) {
1162+
llvm::errs() << "Failed to open output file '" << OutputFileName
1163+
<< "': " << llvm::errorCodeToError(EC) << '\n';
1164+
std::exit(1);
1165+
}
1166+
return *FileOS;
1167+
}();
1168+
SharedStream DependencyOS(ThreadUnsafeDependencyOS);
11621169

11631170
auto DiagsConsumer = std::make_unique<TextDiagnosticPrinter>(
11641171
llvm::errs(), new DiagnosticOptions(), false);
@@ -1376,23 +1383,23 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {
13761383
if (Format == ScanningOutputFormat::Tree) {
13771384
for (auto &TreeResult : TreeResults) {
13781385
if (handleTreeDependencyToolResult(*CAS, TreeResult.Filename,
1379-
*TreeResult.MaybeTree, DependencyOS,
1380-
Errs))
1386+
*TreeResult.MaybeTree,
1387+
ThreadUnsafeDependencyOS, Errs))
13811388
HadErrors = true;
13821389
}
13831390
} else if (Format == ScanningOutputFormat::IncludeTree) {
13841391
for (auto &TreeResult : TreeResults) {
13851392
if (handleIncludeTreeToolResult(*CAS, TreeResult.Filename,
13861393
*TreeResult.MaybeIncludeTree,
1387-
DependencyOS, Errs))
1394+
ThreadUnsafeDependencyOS, Errs))
13881395
HadErrors = true;
13891396
}
13901397
} else if (Format == ScanningOutputFormat::Full ||
13911398
Format == ScanningOutputFormat::FullTree ||
13921399
Format == ScanningOutputFormat::FullIncludeTree) {
1393-
FD->printFullOutput(llvm::outs());
1400+
FD->printFullOutput(ThreadUnsafeDependencyOS);
13941401
} else if (Format == ScanningOutputFormat::P1689)
1395-
PD.printDependencies(llvm::outs());
1402+
PD.printDependencies(ThreadUnsafeDependencyOS);
13961403

13971404
return HadErrors;
13981405
}

clang/tools/clang-scan-deps/Opts.td

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ multiclass Eq<string name, string help> {
1111
def help : Flag<["--"], "help">, HelpText<"Display this help">;
1212
def version : Flag<["--"], "version">, HelpText<"Display the version">;
1313

14+
def o : Arg<"o", "Destination of the primary output">;
15+
1416
defm mode : Eq<"mode", "The preprocessing mode used to compute the dependencies">;
1517

1618
defm format : Eq<"format", "The output format for the dependencies">;

0 commit comments

Comments
 (0)