From 1ce90d889a2664dd8dd4cd5e6410a96f3595f33a Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Thu, 22 Sep 2016 21:49:43 +0000 Subject: [PATCH] [llvm-cov] Add the ability to specify directories of input source files We've supported restricting coverage reports to a set of files for a long time. Add support for being able to restrict by entire directories. I suppose this supersedes D20803. llvm-svn: 282202 --- llvm/test/tools/llvm-cov/scan-directory.test | 9 ++++ llvm/tools/llvm-cov/CodeCoverage.cpp | 66 +++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 llvm/test/tools/llvm-cov/scan-directory.test diff --git a/llvm/test/tools/llvm-cov/scan-directory.test b/llvm/test/tools/llvm-cov/scan-directory.test new file mode 100644 index 0000000..9bacfc2 --- /dev/null +++ b/llvm/test/tools/llvm-cov/scan-directory.test @@ -0,0 +1,9 @@ +RUN: mkdir -p %t/a/b/ +RUN: echo "" > %t/a/b/c.tmp +RUN: echo "" > %t/a/d.tmp + +RUN: llvm-cov show /dev/null -instr-profile /dev/null -dump-collected-paths %t | FileCheck %s +RUN: llvm-cov show /dev/null -instr-profile /dev/null -dump-collected-paths %t/a/b/c.tmp %t/a/d.tmp | FileCheck %s + +CHECK-DAG: {{.*}}c.tmp +CHECK-DAG: {{.*}}d.tmp diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 8c9da11..c16bfcc 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -64,6 +64,10 @@ public: /// \brief Copy \p Path into the list of input source files. void addCollectedPath(const std::string &Path); + /// \brief If \p Path is a regular file, collect the path. If it's a + /// directory, recursively collect all of the paths within the directory. + void collectPaths(const std::string &Path); + /// \brief Return a memory buffer for the given source file. ErrorOr getSourceFile(StringRef SourceFile); @@ -152,10 +156,49 @@ void CodeCoverageTool::warning(const Twine &Message, StringRef Whence) { } void CodeCoverageTool::addCollectedPath(const std::string &Path) { - CollectedPaths.push_back(Path); + if (CompareFilenamesOnly) { + CollectedPaths.push_back(Path); + } else { + SmallString<128> EffectivePath(Path); + if (std::error_code EC = sys::fs::make_absolute(EffectivePath)) { + error(EC.message(), Path); + return; + } + sys::path::remove_dots(EffectivePath, /*remove_dot_dots=*/true); + CollectedPaths.push_back(EffectivePath.str()); + } + SourceFiles.emplace_back(CollectedPaths.back()); } +void CodeCoverageTool::collectPaths(const std::string &Path) { + llvm::sys::fs::file_status Status; + llvm::sys::fs::status(Path, Status); + if (!llvm::sys::fs::exists(Status)) { + if (CompareFilenamesOnly) + addCollectedPath(Path); + else + error("Missing source file", Path); + return; + } + + if (llvm::sys::fs::is_regular_file(Status)) { + addCollectedPath(Path); + return; + } + + if (llvm::sys::fs::is_directory(Status)) { + std::error_code EC; + for (llvm::sys::fs::recursive_directory_iterator F(Path, EC), E; + F != E && !EC; F.increment(EC)) { + if (llvm::sys::fs::is_regular_file(F->path())) + addCollectedPath(F->path()); + } + if (EC) + warning(EC.message(), Path); + } +} + ErrorOr CodeCoverageTool::getSourceFile(StringRef SourceFile) { // If we've remapped filenames, look up the real location for this file. @@ -391,6 +434,10 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { cl::list InputSourceFiles( cl::Positional, cl::desc(""), cl::ZeroOrMore); + cl::opt DebugDumpCollectedPaths( + "dump-collected-paths", cl::Optional, cl::Hidden, + cl::desc("Show the collected paths to source files")); + cl::opt PGOFilename( "instr-profile", cl::Required, cl::location(this->PGOFilename), cl::desc( @@ -535,16 +582,15 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { } CoverageArch = Arch; - for (const auto &File : InputSourceFiles) { - SmallString<128> Path(File); - if (!CompareFilenamesOnly) { - if (std::error_code EC = sys::fs::make_absolute(Path)) { - error(EC.message(), File); - return 1; - } - } - addCollectedPath(Path.str()); + for (const std::string &File : InputSourceFiles) + collectPaths(File); + + if (DebugDumpCollectedPaths) { + for (StringRef SF : SourceFiles) + outs() << SF << '\n'; + ::exit(0); } + return 0; }; -- 2.7.4