This is an archive of the discontinued LLVM Phabricator instance.

Displaying coverage information for all source files present in a directory
Needs ReviewPublic

Authored by chakshugrover on May 30 2016, 11:50 PM.

Details

Reviewers
davidxl
bogner
vsk
Summary

The llvm-cov tool currently reads code coverage data files and displays the coverage information for a specified source file. This patch will enable us to provide it with a directory and it will display the information for all the source files inside that directory by iterating over all of them using directory_iterator.
It still works if you provide a single source file.

Diff Detail

Event Timeline

chakshugrover retitled this revision from to Displaying coverage information for all source files present in a directory.
chakshugrover updated this object.
chakshugrover added reviewers: davidxl, bogner, vsk.
chakshugrover added a subscriber: llvm-commits.
vsk edited edge metadata.May 31 2016, 8:35 AM

Thank you very much for doing this!

Logistics note: in the future, please upload a diff with more context (git diff -U1000 ...).

tools/llvm-cov/CodeCoverage.cpp
38

I don't think you need any of these #includes.

76

Please add a short, doxygen-style comment describing what walk does. Also: walk does not seem like a sufficiently descriptive name. Wdyt of e.g collectSourceFiles?

76

I think a StringRef would work better than a SmallString here.

248

Please use llvm::sys::fs::status.

249

nit, I prefer checking for the simplest/base case first. Start by handling llvm::sys::fs::is_regular_file(FS), followed by llvm::sys::fs::is_directory(FS), followed by the error case.

250

Please follow the existing error-reporting idiom in this file (e.g colored_ostream(), "error: Failed to ....").

257

Why not just call walk on File->path() directly? It should handle files, directories, and access errors correctly.

vsk added a comment.May 31 2016, 8:40 AM

One last note: you'll need to add a small test to test/tools/llvm-cov along with this patch.

davidxl added inline comments.May 31 2016, 8:57 AM
tools/llvm-cov/CodeCoverage.cpp
255

Can you just use recursive_directory_iterator?

chakshugrover edited edge metadata.

I have tried to incorporate all the comments.
The code is still not what i would like it to be!

I started with this

void CodeCoverageTool::collectSourceFiles(StringRef Path) {

llvm::sys::fs::file_status Status;
llvm::sys::fs::status(Path, Status);
if (llvm::sys::fs::exists(Status)) {
  // If it's a source file, collect it.
  if (llvm::sys::fs::is_regular_file(Status)) {
    SourceFiles.push_back(Path.str());
    return;
  }
  if (llvm::sys::fs::is_directory(Status)) {
    std::error_code EC;
    // Collect all source files within this directory by iterating
    // recursively.
    for (llvm::sys::fs::recursive_directory_iterator File(Path, EC), FileEnd;
         File != FileEnd && !EC; File.increment(EC)) {
      if (llvm::sys::fs::is_regular_file(File->path())) {
        SourceFiles.push_back(File->path());
      }
    }
    return;
  }
} else
  fprintf(stderr, "Error: Can't access: %s\n", Path.str().c_str());
return;

}

But the code above breaks the test case test/tools/llvm-cov/report.cpp. Please suggest how to go about it.
The script that it emitted works without any error if run from test/tools/llvm-cov/ directory but the test fails.

chakshugrover marked 6 inline comments as done.Jun 3 2016, 6:39 AM
chakshugrover added inline comments.
tools/llvm-cov/CodeCoverage.cpp
35

Removed

260

Please check the comment above.

vsk added a comment.Jun 3 2016, 9:52 AM

There shouldn't be a need to check in a binary profdata file.

test/tools/llvm-cov/cov_dir.cpp
2

Instead of checking in an executable, use llvm-cov convert-for-testing cov_dir_test -o cov_dir.covmapping and check in the covmapping.

tools/llvm-cov/CodeCoverage.cpp
73

nit, Please add a period.

269

You aren't checking whether this is a regular file, or if it exists. Could you extend the patch in your penultimate comment with extra error checking and report back on the exact failures you're seeing?

chakshugrover marked 5 inline comments as not done.

Sorry for the delay. Please review the updated collectSourceFiles function. I had to explicitly handle the case when -filename-equivalence option is passed.

I am facing issue in creating the test case. As absolute path of files being compiled gets hardcoded inside the covmapping, I had to use -filename-equivalence while passing file names. I couldn't find a way to pass a directory name while using this option such that my code actually gets tested.
Please suggest how should i proceed with the test case.

Had forgotten to add period.

vsk added a comment.Jun 16 2016, 10:34 AM

Meta: Please wait one week before pinging patches, see http://llvm.org/docs/DeveloperPolicy.html#code-reviews.

Your code isn't being tested because -filename-equivalence sets CompareFilenamesOnly: collectSourceFiles pushes back the directory path and returns immediately when this happens.

Please don't check in a profdata file or any source files. Add a hidden -dump-input-file-list cl::opt to CodeCoverageTool::run and write a test like this:

RUN: rm -rf %t
RUN: mkdir -p %t/a/b/
RUN: echo "" > %t/a/b/c.tmp
RUN: echo "" > %t/a/d.tmp
RUN: llvm-cov show %S/Inputs/directory-search.covmapping -instr-profile=/dev/null -dump-input-file-list | FileCheck %s
CHECK-DAG: {{.*}}c.tmp
CHECK-DAG: {{.*}}d.tmp

This tests the functionality you're adding, instead of testing e.g the coverage report format, which is unrelated.

Added the requested -dump-input-file-list cl::opt to CodeCoverageTool::run and completed test case.
Sorry for the delay. This is the first time I am trying to write a test case.

vsk added inline comments.Jul 5 2016, 5:45 PM
test/tools/llvm-cov/cov_dir.cpp
6

It might make more sense to pass "/dev/null" for the covmapping file, since it ultimately isn't used. Also, please add another RUN line to test your code with -filename-equivalence turned on.

tools/llvm-cov/CodeCoverage.cpp
96

Does this really need to live here? Why not just deal with it in parseCommandLineArgs?

257

Why are we skipping the recursive directory traversal if -filename-equivalence is turned on?

279

Drop the redundant return statement here.

282

Use the error method instead of fprintf.

356

You're only handling this argument when running the "show" sub-command. It would be better to handle it in commandLineParser.

480

In llvm, this is typically written using a range-based for, e.g: for (StringRef SF : SourceFiles).

481

I think this file uses the llvm namespace, so you should be able to drop the llvm::.

DumpInputFileList is handled in commandLineParser itself. I make an early exit from show and report subcommands if this option is enabled ( hence the need of bool DumpFileNames in class CodeCoverageTool ). I skip the recursive directory traversal if -filename-equivalence is turned on as I believe that option is meant for a completely different purpose ( Treat source files (not directories) as equivalent to paths in the coverage data even when only the file names match )

chakshugrover added inline comments.Jul 20 2016, 5:57 AM
test/tools/llvm-cov/cov_dir.cpp
6

As the code is being tested already in multiple test cases such as report.cpp with -filename-equivalence turned on, I think writing another RUN line to check the same may be redundant.

vsk added a comment.Jul 20 2016, 10:53 AM

I skip the recursive directory traversal if -filename-equivalence is turned on as I believe that option is meant for a completely different purpose ( Treat source files (not directories) as equivalent to paths in the coverage data even when only the file names match )

I disagree. It should retain its original meaning while applying to all files within the directory.

test/tools/llvm-cov/cov_dir.cpp
6

I pointed this out in a comment further below, but: I think there is a bug in your patch which occurs when you turn on -filename-equivalence with recursive directory search. So, in this case, I don't think the extra test I suggested is redundant.

tools/llvm-cov/CodeCoverage.cpp
96

Instead of adding this to CodeCoverageTool, you can simply call exit(0) after you're finished printing the input file list in the command line arg parser.