[gcov] Implement --stdout -t
authorFangrui Song <maskray@google.com>
Mon, 11 May 2020 00:16:01 +0000 (17:16 -0700)
committerFangrui Song <maskray@google.com>
Mon, 11 May 2020 04:02:38 +0000 (21:02 -0700)
gcov by default prints to a .gcov file. With --stdout, stdout is used.
Some summary information is omitted. There is no separator for multiple
source files.

llvm/include/llvm/ProfileData/GCOV.h
llvm/lib/ProfileData/GCOV.cpp
llvm/test/tools/llvm-cov/llvm-cov.test
llvm/tools/llvm-cov/gcov.cpp

index 1aabf3b..467772b 100644 (file)
@@ -45,10 +45,11 @@ enum GCOVVersion { V402, V407, V800, V900 };
 
 /// A struct for passing gcov options between functions.
 struct Options {
-  Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N, bool X)
+  Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N,
+          bool T, bool X)
       : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
         PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N),
-        HashFilenames(X) {}
+        UseStdout(T), HashFilenames(X) {}
 
   bool AllBlocks;
   bool BranchInfo;
@@ -58,6 +59,7 @@ struct Options {
   bool UncondBranch;
   bool LongFileNames;
   bool NoOutput;
+  bool UseStdout;
   bool HashFilenames;
 };
 
index d969552..e8e0629 100644 (file)
@@ -650,9 +650,6 @@ std::string FileInfo::getCoveragePath(StringRef Filename,
 
 std::unique_ptr<raw_ostream>
 FileInfo::openCoveragePath(StringRef CoveragePath) {
-  if (Options.NoOutput)
-    return std::make_unique<raw_null_ostream>();
-
   std::error_code EC;
   auto OS =
       std::make_unique<raw_fd_ostream>(CoveragePath, EC, sys::fs::OF_Text);
@@ -676,8 +673,13 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
     auto AllLines = LineConsumer(Filename);
 
     std::string CoveragePath = getCoveragePath(Filename, MainFilename);
-    std::unique_ptr<raw_ostream> CovStream = openCoveragePath(CoveragePath);
-    raw_ostream &CovOS = *CovStream;
+    std::unique_ptr<raw_ostream> CovStream;
+    if (Options.NoOutput)
+      CovStream = std::make_unique<raw_null_ostream>();
+    else if (!Options.UseStdout)
+      CovStream = openCoveragePath(CoveragePath);
+    raw_ostream &CovOS =
+        !Options.NoOutput && Options.UseStdout ? llvm::outs() : *CovStream;
 
     CovOS << "        -:    0:Source:" << Filename << "\n";
     CovOS << "        -:    0:Graph:" << GCNOFile << "\n";
@@ -774,10 +776,12 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
     FileCoverages.push_back(std::make_pair(CoveragePath, FileCoverage));
   }
 
-  // FIXME: There is no way to detect calls given current instrumentation.
-  if (Options.FuncCoverage)
-    printFuncCoverage(InfoOS);
-  printFileCoverage(InfoOS);
+  if (!Options.UseStdout) {
+    // FIXME: There is no way to detect calls given current instrumentation.
+    if (Options.FuncCoverage)
+      printFuncCoverage(InfoOS);
+    printFileCoverage(InfoOS);
+  }
 }
 
 /// printFunctionSummary - Print function and block summary.
index 38fc065..c1d904e 100644 (file)
@@ -35,6 +35,12 @@ RUN: diff -aub test_objdir.h.gcov test.h.gcov
 # With gcov output disabled
 RUN: llvm-cov gcov -n test.c | diff -u test_no_output.output -
 
+# Print to stdout.
+RUN: llvm-cov gcov -t test.c > stdout
+RUN: llvm-cov gcov --stdout test.c | cmp stdout -
+RUN: cat test_no_options.h.gcov test_no_options.cpp.gcov | diff -u - stdout
+RUN: llvm-cov gcov -n -t test.c | count 0
+
 # Missing source files. This test is fragile, as it depends on being
 # run before we copy some sources into place in the next test.
 RUN: llvm-cov gcov test_paths.cpp 2>/dev/null | diff -u test_missing.output -
index f1bca90..bd3b6be 100644 (file)
@@ -119,6 +119,10 @@ int gcovMain(int argc, const char *argv[]) {
                               cl::desc("Preserve path components"));
   cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths));
 
+  cl::opt<bool> UseStdout("t", cl::Grouping, cl::init(false),
+                          cl::desc("Print to stdout"));
+  cl::alias UseStdoutA("stdout", cl::aliasopt(UseStdout));
+
   cl::opt<bool> UncondBranch("u", cl::Grouping, cl::init(false),
                              cl::desc("Display unconditional branch info "
                                       "(requires -b)"));
@@ -141,7 +145,7 @@ int gcovMain(int argc, const char *argv[]) {
 
   GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
                         PreservePaths, UncondBranch, LongNames, NoOutput,
-                        HashFilenames);
+                        UseStdout, HashFilenames);
 
   for (const auto &SourceFile : SourceFiles)
     reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,