[llvm] r208149 - llvm-cov: Handle missing source files as GCOV does

Justin Bogner mail at justinbogner.com
Tue May 6 19:11:24 PDT 2014


Author: bogner
Date: Tue May  6 21:11:23 2014
New Revision: 208149

URL: http://llvm.org/viewvc/llvm-project?rev=208149&view=rev
Log:
llvm-cov: Handle missing source files as GCOV does

If the source files referenced by a gcno file are missing, gcov
outputs a coverage file where every line is simply /*EOF*/.  This also
occurs for lines in the coverage that are past the end of a file that
is found.

This change mimics gcov.

Added:
    llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
    llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.h.gcov
    llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.output
Modified:
    llvm/trunk/include/llvm/Support/GCOV.h
    llvm/trunk/lib/IR/GCOV.cpp
    llvm/trunk/test/tools/llvm-cov/llvm-cov.test

Modified: llvm/trunk/include/llvm/Support/GCOV.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GCOV.h?rev=208149&r1=208148&r2=208149&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/GCOV.h (original)
+++ llvm/trunk/include/llvm/Support/GCOV.h Tue May  6 21:11:23 2014
@@ -356,8 +356,10 @@ class FileInfo {
   typedef DenseMap<uint32_t, BlockVector> BlockLines;
 
   struct LineData {
+    LineData() : LastLine(0) {}
     BlockLines Blocks;
     FunctionLines Functions;
+    uint32_t LastLine;
   };
 
   struct GCOVCoverage {
@@ -379,11 +381,15 @@ public:
     Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
 
   void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
+    if (Line > LineInfo[Filename].LastLine)
+      LineInfo[Filename].LastLine = Line;
     LineInfo[Filename].Blocks[Line-1].push_back(Block);
   }
   void addFunctionLine(StringRef Filename, uint32_t Line,
                        const GCOVFunction *Function) {
-    LineInfo[Filename].Functions[Line-1].push_back(Function);
+    if (Line > LineInfo[Filename].LastLine)
+      LineInfo[Filename].LastLine = Line;
+   LineInfo[Filename].Functions[Line-1].push_back(Function);
   }
   void setRunCount(uint32_t Runs) { RunCount = Runs; }
   void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }

Modified: llvm/trunk/lib/IR/GCOV.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/GCOV.cpp?rev=208149&r1=208148&r2=208149&view=diff
==============================================================================
--- llvm/trunk/lib/IR/GCOV.cpp (original)
+++ llvm/trunk/lib/IR/GCOV.cpp Tue May  6 21:11:23 2014
@@ -432,6 +432,30 @@ static raw_ostream &operator<<(raw_ostre
   return OS;
 }
 
+namespace {
+class LineConsumer {
+  std::unique_ptr<MemoryBuffer> Buffer;
+  StringRef Remaining;
+public:
+  LineConsumer(StringRef Filename) {
+    if (error_code EC = MemoryBuffer::getFileOrSTDIN(Filename, Buffer)) {
+      errs() << Filename << ": " << EC.message() << "\n";
+      Remaining = "";
+    } else
+      Remaining = Buffer->getBuffer();
+  }
+  bool empty() { return Remaining.empty(); }
+  void printNext(raw_ostream &OS, uint32_t LineNum) {
+    StringRef Line;
+    if (empty())
+      Line = "/*EOF*/";
+    else
+      std::tie(Line, Remaining) = Remaining.split("\n");
+    OS << format("%5u:", LineNum) << Line << "\n";
+  }
+};
+}
+
 /// Convert a path to a gcov filename. If PreservePaths is true, this
 /// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
 static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
@@ -505,12 +529,7 @@ void FileInfo::print(StringRef MainFilen
   for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
          E = LineInfo.end(); I != E; ++I) {
     StringRef Filename = I->first();
-    std::unique_ptr<MemoryBuffer> Buff;
-    if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
-      errs() << Filename << ": " << ec.message() << "\n";
-      return;
-    }
-    StringRef AllLines = Buff->getBuffer();
+    auto AllLines = LineConsumer(Filename);
 
     std::string CoveragePath = getCoveragePath(Filename, MainFilename);
     std::unique_ptr<raw_ostream> S = openCoveragePath(CoveragePath);
@@ -524,7 +543,8 @@ void FileInfo::print(StringRef MainFilen
 
     const LineData &Line = I->second;
     GCOVCoverage FileCoverage(Filename);
-    for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
+    for (uint32_t LineIndex = 0;
+         LineIndex < Line.LastLine || !AllLines.empty(); ++LineIndex) {
       if (Options.BranchInfo) {
         FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
         if (FuncsIt != Line.Functions.end())
@@ -535,9 +555,7 @@ void FileInfo::print(StringRef MainFilen
       if (BlocksIt == Line.Blocks.end()) {
         // No basic blocks are on this line. Not an executable line of code.
         OS << "        -:";
-        std::pair<StringRef, StringRef> P = AllLines.split('\n');
-        OS << format("%5u:", LineIndex+1) << P.first << "\n";
-        AllLines = P.second;
+        AllLines.printNext(OS, LineIndex + 1);
       } else {
         const BlockVector &Blocks = BlocksIt->second;
 
@@ -599,9 +617,7 @@ void FileInfo::print(StringRef MainFilen
         }
         ++FileCoverage.LogicalLines;
 
-        std::pair<StringRef, StringRef> P = AllLines.split('\n');
-        OS << format("%5u:", LineIndex+1) << P.first << "\n";
-        AllLines = P.second;
+        AllLines.printNext(OS, LineIndex + 1);
 
         uint32_t BlockNo = 0;
         uint32_t EdgeNo = 0;

Added: llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov?rev=208149&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov Tue May  6 21:11:23 2014
@@ -0,0 +1,77 @@
+        -:    0:Source:srcdir/./nested_dir/../test.cpp
+        -:    0:Graph:test_paths.gcno
+        -:    0:Data:test_paths.gcda
+        -:    0:Runs:3
+        -:    0:Programs:1
+        -:    1:/*EOF*/
+        -:    2:/*EOF*/
+        -:    3:/*EOF*/
+        -:    4:/*EOF*/
+        -:    5:/*EOF*/
+        -:    6:/*EOF*/
+        -:    7:/*EOF*/
+        -:    8:/*EOF*/
+        -:    9:/*EOF*/
+12884901888:   10:/*EOF*/
+        -:   11:/*EOF*/
+    #####:   12:/*EOF*/
+        -:   13:/*EOF*/
+        -:   14:/*EOF*/
+    #####:   15:/*EOF*/
+        -:   16:/*EOF*/
+        -:   17:/*EOF*/
+        -:   18:/*EOF*/
+        3:   19:/*EOF*/
+        3:   20:/*EOF*/
+        -:   21:/*EOF*/
+        -:   22:/*EOF*/
+        -:   23:/*EOF*/
+    #####:   24:/*EOF*/
+    #####:   25:/*EOF*/
+        -:   26:/*EOF*/
+        -:   27:/*EOF*/
+       12:   28:/*EOF*/
+       12:   29:/*EOF*/
+       12:   30:/*EOF*/
+        -:   31:/*EOF*/
+        -:   32:/*EOF*/
+       21:   33:/*EOF*/
+       36:   34:/*EOF*/
+       18:   35:/*EOF*/
+        3:   36:/*EOF*/
+        -:   37:/*EOF*/
+        -:   38:/*EOF*/
+        3:   39:/*EOF*/
+        -:   40:/*EOF*/
+        3:   41:/*EOF*/
+        3:   42:/*EOF*/
+        3:   43:/*EOF*/
+        3:   44:/*EOF*/
+        3:   45:/*EOF*/
+        3:   46:/*EOF*/
+    #####:   47:/*EOF*/
+    #####:   48:/*EOF*/
+        -:   49:/*EOF*/
+        -:   50:/*EOF*/
+       66:   51:/*EOF*/
+       30:   52:/*EOF*/
+        -:   53:/*EOF*/
+        6:   54:/*EOF*/
+        6:   55:/*EOF*/
+        -:   56:/*EOF*/
+        -:   57:/*EOF*/
+        3:   58:/*EOF*/
+        3:   59:/*EOF*/
+        -:   60:/*EOF*/
+        9:   61:/*EOF*/
+        9:   62:/*EOF*/
+        -:   63:/*EOF*/
+       12:   64:/*EOF*/
+       12:   65:/*EOF*/
+       30:   66:/*EOF*/
+        -:   67:/*EOF*/
+        3:   68:/*EOF*/
+25769803782:   69:/*EOF*/
+12884901888:   70:/*EOF*/
+        -:   71:/*EOF*/
+        3:   72:/*EOF*/

Added: llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.h.gcov
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.h.gcov?rev=208149&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.h.gcov (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.h.gcov Tue May  6 21:11:23 2014
@@ -0,0 +1,6 @@
+        -:    0:Source:srcdir/./nested_dir/../test.h
+        -:    0:Graph:test_paths.gcno
+        -:    0:Data:test_paths.gcda
+        -:    0:Runs:3
+        -:    0:Programs:1
+        6:    1:/*EOF*/

Added: llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.output
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.output?rev=208149&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.output (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/test_missing.output Tue May  6 21:11:23 2014
@@ -0,0 +1,8 @@
+File 'srcdir/./nested_dir/../test.h'
+Lines executed:100.00% of 1
+srcdir/./nested_dir/../test.h:creating 'test.h.gcov'
+
+File 'srcdir/./nested_dir/../test.cpp'
+Lines executed:84.21% of 38
+srcdir/./nested_dir/../test.cpp:creating 'test.cpp.gcov'
+

Modified: llvm/trunk/test/tools/llvm-cov/llvm-cov.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/llvm-cov.test?rev=208149&r1=208148&r2=208149&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/llvm-cov.test (original)
+++ llvm/trunk/test/tools/llvm-cov/llvm-cov.test Tue May  6 21:11:23 2014
@@ -34,6 +34,12 @@ RUN: diff -aub test_objdir.h.gcov test.h
 # With gcov output disabled
 RUN: llvm-cov -n test.c | diff -u test_no_output.output -
 
+# 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 test_paths.cpp 2>/dev/null | diff -u test_missing.output -
+RUN: diff -aub test_missing.cpp.gcov test.cpp.gcov
+RUN: diff -aub test_missing.h.gcov test.h.gcov
+
 # Preserve paths. This mangles the output filenames.
 RUN: mkdir -p %t/srcdir/nested_dir
 RUN: cp test.cpp test.h %t/srcdir





More information about the llvm-commits mailing list