Index: test/tools/llvm-cov/Inputs/cov_dir/main.cpp =================================================================== --- test/tools/llvm-cov/Inputs/cov_dir/main.cpp +++ test/tools/llvm-cov/Inputs/cov_dir/main.cpp @@ -0,0 +1,12 @@ +#include + +extern int f(int g); +int main(int argc, char **argv) { + int result = 0; + int a; + scanf("%d", &a); + result = f(a); + return result; + result = 10; + return 0; +} Index: test/tools/llvm-cov/Inputs/cov_dir/sub_dir/function.cpp =================================================================== --- test/tools/llvm-cov/Inputs/cov_dir/sub_dir/function.cpp +++ test/tools/llvm-cov/Inputs/cov_dir/sub_dir/function.cpp @@ -0,0 +1,5 @@ +int f(int g) { + return g + 2; + g += 4; + return g; +} Index: test/tools/llvm-cov/cov_dir.cpp =================================================================== --- test/tools/llvm-cov/cov_dir.cpp +++ test/tools/llvm-cov/cov_dir.cpp @@ -0,0 +1,13 @@ +// RUN: llvm-cov report %S/Inputs/cov_dir.covmapping -instr-profile %S/Inputs/cov_dir.profdata -filename-equivalence main.cpp function.cpp 2>&1 | FileCheck %s + +// CHECK: Name Regions Miss Cover Lines Miss Cover +// CHECK-NEXT: --- +// CHECK-NEXT: main 2 1 50.00% 8 2 75.00% +// CHECK-NEXT: --- +// CHECK-NEXT: TOTAL 2 1 50.00% 8 2 75.00% + +// CHECK: Name Regions Miss Cover Lines Miss Cover +// CHECK-NEXT: --- +// CHECK-NEXT: _Z1fi 2 1 50.00% 5 2 60.00% +// CHECK-NEXT: --- +// CHECK-NEXT: TOTAL 2 1 50.00% 5 2 60.00% Index: tools/llvm-cov/CodeCoverage.cpp =================================================================== --- tools/llvm-cov/CodeCoverage.cpp +++ tools/llvm-cov/CodeCoverage.cpp @@ -70,6 +70,9 @@ /// \brief Load the coverage mapping data. Return true if an error occured. std::unique_ptr load(); + /// \brief Collects all source files recursively inside the directory + void collectSourceFiles(StringRef Path); + int run(Command Cmd, int argc, const char **argv); typedef std::function CommandLineParserType; @@ -239,6 +242,36 @@ return Coverage; } +void CodeCoverageTool::collectSourceFiles(StringRef Path) { + if (CompareFilenamesOnly) { + SourceFiles.push_back(Path.str()); + return; + } + 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; +} + int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -362,7 +395,7 @@ errs() << "error: " << File << ": " << EC.message(); return 1; } - SourceFiles.push_back(Path.str()); + collectSourceFiles(Path.str()); } return 0; };