llvm-cov: add code coverage tool that's based on coverage mapping format and clang's pgo.

This commit expands llvm-cov's functionality by adding support for a new code coverage
tool that uses LLVM's coverage mapping format and clang's instrumentation based profiling.
The gcov compatible tool can be invoked by supplying the 'gcov' command as the first argument,
or by modifying the tool's name to end with 'gcov'.

Differential Revision: http://reviews.llvm.org/D4445

llvm-svn: 216300
diff --git a/llvm/test/tools/llvm-cov/Inputs/README b/llvm/test/tools/llvm-cov/Inputs/README
index 2cfb191..3773ba3 100644
--- a/llvm/test/tools/llvm-cov/Inputs/README
+++ b/llvm/test/tools/llvm-cov/Inputs/README
@@ -1,7 +1,21 @@
 These inputs were pre-generated to allow for easier testing of llvm-cov.
 
-test.gcno and test.gcda were create by running clang:
-  clang++ -g -ftest-coverage -fprofile-arcs test.cpp
+The files used to test the gcov compatible code coverage tool were generated
+using the following method:
 
-test.cpp.gcov was created by running gcov 4.2.1:
-  gcov test.cpp
+  test.gcno and test.gcda were create by running clang:
+    clang++ -g -ftest-coverage -fprofile-arcs test.cpp
+
+  test.cpp.gcov was created by running gcov 4.2.1:
+    gcov test.cpp
+
+The 'covmapping' files that are used to test llvm-cov contain raw sections
+with the coverage mapping data generated by the compiler and linker. They are
+created by running clang and llvm-cov:
+  clang++ -fprofile-instr-generate -fcoverage-mapping -o test test.cpp
+  llvm-cov convert-for-testing -o test.covmapping test
+
+The 'profdata' files were generated by running an instrumented version of the
+program and merging the raw profile data using llvm-profdata.
+  ./test
+  llvm-profdata merge -o test.profdata default.profraw
diff --git a/llvm/test/tools/llvm-cov/Inputs/highlightedRanges.covmapping b/llvm/test/tools/llvm-cov/Inputs/highlightedRanges.covmapping
new file mode 100644
index 0000000..20eb0d7
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/highlightedRanges.covmapping
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/highlightedRanges.profdata b/llvm/test/tools/llvm-cov/Inputs/highlightedRanges.profdata
new file mode 100644
index 0000000..b465b00
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/highlightedRanges.profdata
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping b/llvm/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping
new file mode 100644
index 0000000..5cfa169
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/lineExecutionCounts.covmapping
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/lineExecutionCounts.profdata b/llvm/test/tools/llvm-cov/Inputs/lineExecutionCounts.profdata
new file mode 100644
index 0000000..8712227
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/lineExecutionCounts.profdata
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/regionMarkers.covmapping b/llvm/test/tools/llvm-cov/Inputs/regionMarkers.covmapping
new file mode 100644
index 0000000..3ebcb07
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/regionMarkers.covmapping
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/regionMarkers.profdata b/llvm/test/tools/llvm-cov/Inputs/regionMarkers.profdata
new file mode 100644
index 0000000..8712227
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/regionMarkers.profdata
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/showHighlightedRanges.cpp b/llvm/test/tools/llvm-cov/showHighlightedRanges.cpp
new file mode 100644
index 0000000..7c38fff
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/showHighlightedRanges.cpp
@@ -0,0 +1,45 @@
+// RUN: llvm-cov show %S/Inputs/highlightedRanges.covmapping -instr-profile %S/Inputs/highlightedRanges.profdata -dump -filename-equivalence %s | FileCheck %s
+
+void func() {
+  return;
+  int i = 0;                     // CHECK: Highlighted line [[@LINE]], 3 -> 12
+}
+
+void func2(int x) {
+  if(x > 5) {
+    while(x >= 9) {
+      return;
+      --x;                       // CHECK: Highlighted line [[@LINE]], 7 -> 10
+    }
+    int i = 0;                   // CHECK: Highlighted line [[@LINE]], 5 -> 14
+  }
+}
+
+void test() {
+  int x = 0;
+
+  if (x) {                       // CHECK: Highlighted line [[@LINE]], 10 -> ?
+    x = 0;                       // CHECK: Highlighted line [[@LINE]], 1 -> ?
+  } else {                       // CHECK: Highlighted line [[@LINE]], 1 -> 4
+    x = 1;
+  }
+
+                                  // CHECK: Highlighted line [[@LINE+1]], 26 -> 29
+  for (int i = 0; i < 0; ++i) {   // CHECK: Highlighted line [[@LINE]], 31 -> ?
+    x = 1;                        // CHECK: Highlighted line [[@LINE]], 1 -> ?
+  }                               // CHECK: Highlighted line [[@LINE]], 1 -> 4
+
+  x = x < 10 ? x +
+               1
+             : x - 1;             // CHECK: Highlighted line [[@LINE]], 16 -> 21
+  x = x > 10 ? x +                // CHECK: Highlighted line [[@LINE]], 16 -> ?
+               1                  // CHECK: Highlighted line [[@LINE]], 1 -> 17
+             : x - 1;
+}
+
+int main() {
+  test();
+  func();
+  func2(9);
+  return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
new file mode 100644
index 0000000..abcf5a3
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
@@ -0,0 +1,22 @@
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %S/Inputs/lineExecutionCounts.profdata -no-colors -filename-equivalence %s | FileCheck %s
+
+int main() {                             // CHECK:   1| [[@LINE]]|int main(
+  int x = 0;                             // CHECK:   1| [[@LINE]]|  int x
+                                         // CHECK:   1| [[@LINE]]|
+  if (x) {                               // CHECK:   0| [[@LINE]]|  if (x)
+    x = 0;                               // CHECK:   0| [[@LINE]]|    x = 0
+  } else {                               // CHECK:   1| [[@LINE]]|  } else
+    x = 1;                               // CHECK:   1| [[@LINE]]|    x = 1
+  }                                      // CHECK:   1| [[@LINE]]|  }
+                                         // CHECK:   1| [[@LINE]]|
+  for (int i = 0; i < 100; ++i) {        // CHECK: 100| [[@LINE]]|  for (
+    x = 1;                               // CHECK: 100| [[@LINE]]|    x = 1
+  }                                      // CHECK: 100| [[@LINE]]|  }
+                                         // CHECK:   1| [[@LINE]]|
+  x = x < 10 ? x + 1 : x - 1;            // CHECK:   0| [[@LINE]]|  x =
+  x = x > 10 ?                           // CHECK:   1| [[@LINE]]|  x =
+        x - 1:                           // CHECK:   0| [[@LINE]]|        x
+        x + 1;                           // CHECK:   1| [[@LINE]]|        x
+                                         // CHECK:   1| [[@LINE]]|
+  return 0;                              // CHECK:   1| [[@LINE]]|  return
+}                                        // CHECK:   1| [[@LINE]]|}
diff --git a/llvm/test/tools/llvm-cov/showRegionMarkers.cpp b/llvm/test/tools/llvm-cov/showRegionMarkers.cpp
new file mode 100644
index 0000000..9866144
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/showRegionMarkers.cpp
@@ -0,0 +1,23 @@
+// RUN: llvm-cov show %S/Inputs/regionMarkers.covmapping -instr-profile %S/Inputs/regionMarkers.profdata -show-regions -dump -filename-equivalence %s | FileCheck %s
+
+int main() {                      // CHECK: Marker at [[@LINE]]:12 = 1
+  int x = 0;
+
+  if (x) {                        // CHECK: Marker at [[@LINE]]:10 = 0
+    x = 0;
+  } else {                        // CHECK: Marker at [[@LINE]]:10 = 1
+    x = 1;
+  }
+                                  // CHECK: Marker at [[@LINE+2]]:19 = 101
+                                  // CHECK: Marker at [[@LINE+1]]:28 = 100
+  for (int i = 0; i < 100; ++i) { // CHECK: Marker at [[@LINE]]:33 = 100
+    x = 1;
+  }
+                                  // CHECK: Marker at [[@LINE+1]]:16 = 1
+  x = x < 10 ? x + 1 : x - 1;     // CHECK: Marker at [[@LINE]]:24 = 0
+  x = x > 10 ?
+        x - 1:                    // CHECK: Marker at [[@LINE]]:9 = 0
+        x + 1;                    // CHECK: Marker at [[@LINE]]:9 = 1
+
+  return 0;
+}