Skip to content

Commit

Permalink
Retry: [llvm-cov] Add support for exporting coverage data to JSON
Browse files Browse the repository at this point in the history
This enables users to export coverage information as portable JSON for use by
analysis tools and storage in document based databases.

The export sub-command is invoked just like the others:

  llvm-cov export -instr-profile path/to/foo.profdata path/to/foo.binary

The resulting JSON contains a list of files and functions. Every file object
contains a list of segments, expansions, and a summary of the file's region,
function, and line coverage. Every function object contains the function's name
and regions. There is also a total summary for the entire object file.

Changes since the initial commit (r276813):

  - Fixed the regexes in the tests to handle Windows filepaths.

Patch by Eddie Hurtig!

Differential Revision: https://reviews.llvm.org/D22651

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276818 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
vedantk committed Jul 26, 2016
1 parent aaba6ed commit 53397d1
Show file tree
Hide file tree
Showing 17 changed files with 758 additions and 4 deletions.
29 changes: 29 additions & 0 deletions docs/CommandGuide/llvm-cov.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ COMMANDS
* :ref:`gcov <llvm-cov-gcov>`
* :ref:`show <llvm-cov-show>`
* :ref:`report <llvm-cov-report>`
* :ref:`export <llvm-cov-export>`

.. program:: llvm-cov gcov

Expand Down Expand Up @@ -315,3 +316,31 @@ OPTIONS
It is an error to specify an architecture that is not included in the
universal binary or to use an architecture that does not match a
non-universal binary.

EXPORT COMMAND
--------------

SYNOPSIS
^^^^^^^^

:program:`llvm-cov export` [*options*] -instr-profile *PROFILE* *BIN*

DESCRIPTION
^^^^^^^^^^^

The :program:`llvm-cov export` command exports regions, functions, expansions,
and summaries of the coverage of a binary *BIN* using the profile data
*PROFILE* as JSON.

For information on compiling programs for coverage and generating profile data,
see :ref:`llvm-cov-show`.

OPTIONS
^^^^^^^

.. option:: -arch=<name>

If the covered binary is a universal binary, select the architecture to use.
It is an error to specify an architecture that is not included in the
universal binary or to use an architecture that does not match a
non-universal binary.
38 changes: 38 additions & 0 deletions test/tools/llvm-cov/Inputs/binary-formats.canonical.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Metadata section
// CHECK: {"version":"1.0.0","type":"llvm.coverage.json.export","data":[

// Open Export
// CHECK-SAME: {"object":"{{[^"]+}}","files":[

// File Object
// CHECK-SAME: {"filename":"{{[^"]+}}binary-formats.c",
// CHECK-SAME: "segments":[
// CHECK-SAME: [4,40,100,1,1],[4,42,0,0,0]],
// CHECK-SAME: "expansions":[],

// Verify the Summary Section for the first file
// CHECK-SAME: "summary":{
// CHECK-SAME: "lines":{"count":1,"covered":1,"percent":100,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":1,"covered":1,"notcovered":0,"percent":100}}}

// Close Files Array
// CHECK-SAME: ],

// Functions List
// CHECK-SAME: "functions":[
// CHECK-SAME: {"name":"main","count":100,"regions":[
// CHECK-SAME: [4,40,4,42,100,0,0,0]
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{[^"]+}}binary-formats.c"]
// CHECK-SAME: }],


// Full Export Summary
// CHECK-SAME: "totals":{
// CHECK-SAME: "lines":{"count":1,"covered":1,"percent":100,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":1,"covered":1,"notcovered":0,"percent":100}}

// Close the export object, data array, and root object
// CHECK-SAME: }]}
53 changes: 53 additions & 0 deletions test/tools/llvm-cov/Inputs/highlightedRanges.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Metadata section
// CHECK: {"version":"1.0.0","type":"llvm.coverage.json.export","data":[

// Open Export
// CHECK-SAME: {"object":"{{[^"]+}}","files":[

// File Object
// CHECK-SAME: {"filename":"{{[^"]+}}showHighlightedRanges.cpp",
// CHECK-SAME: "segments":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}],
// CHECK-SAME: "expansions":[],

// Verify the Summary Section for the first file
// CHECK-SAME: "summary":{
// CHECK-SAME: "lines":{"count":40,"covered":26,"percent":65,"noncode":0},
// CHECK-SAME: "functions":{"count":4,"covered":4,"percent":100},
// CHECK-SAME: "regions":{"count":19,"covered":11,"notcovered":8,"percent":57}}}

// Close Files Array
// CHECK-SAME: ],

// Functions List
// CHECK-SAME: "functions":[
// CHECK-SAME: {"name":"_Z4funcv","count":1,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{[^"]+}}showHighlightedRanges.cpp"]
// CHECK-SAME: },
// CHECK-SAME: {"name":"_Z5func2i","count":1,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{[^"]+}}showHighlightedRanges.cpp"]
// CHECK-SAME: }
// CHECK-SAME: {"name":"_Z4testv","count":1,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{[^"]+}}showHighlightedRanges.cpp"]
// CHECK-SAME: }
// CHECK-SAME: {"name":"main","count":1,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{.*}}showHighlightedRanges.cpp"]
// CHECK-SAME: }],


// Full Export Summary
// CHECK-SAME: "totals":{
// CHECK-SAME: "lines":{"count":40,"covered":26,"percent":65,"noncode":0},
// CHECK-SAME: "functions":{"count":4,"covered":4,"percent":100},
// CHECK-SAME: "regions":{"count":19,"covered":11,"notcovered":8,"percent":57}}

// Close the export object, data array, and root object
// CHECK-SAME: }]}
38 changes: 38 additions & 0 deletions test/tools/llvm-cov/Inputs/lineExecutionCounts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Metadata section
// CHECK: {"version":"1.0.0","type":"llvm.coverage.json.export","data":[

// Open Export
// CHECK-SAME: {"object":"{{[^"]+}}","files":[

// File Object
// CHECK-SAME: {"filename":"{{[^"]+}}showLineExecutionCounts.cpp",
// CHECK-SAME: "segments":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}],
// CHECK-SAME: "expansions":[],

// Verify the Summary Section for the first file
// CHECK-SAME: "summary":{
// CHECK-SAME: "lines":{"count":20,"covered":16,"percent":80,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}}

// Close Files Array
// CHECK-SAME: ],

// Functions List
// CHECK-SAME: "functions":[
// CHECK-SAME: {"name":"main","count":161,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{[^"]+}}showLineExecutionCounts.cpp"]
// CHECK-SAME: }],


// Full Export Summary
// CHECK-SAME: "totals":{
// CHECK-SAME: "lines":{"count":20,"covered":16,"percent":80,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}

// Close the export object, data array, and root object
// CHECK-SAME: }]}
37 changes: 37 additions & 0 deletions test/tools/llvm-cov/Inputs/regionMarkers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Metadata section
// CHECK: {"version":"1.0.0","type":"llvm.coverage.json.export","data":[

// Open Export
// CHECK-SAME: {"object":"{{[^"]+}}","files":[

// File Object
// CHECK-SAME: {"filename":"{{[^"]+}}showRegionMarkers.cpp",
// CHECK-SAME: "segments":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}],
// CHECK-SAME: "expansions":[],

// Verify the Summary Section for the first file
// CHECK-SAME: "summary":{
// CHECK-SAME: "lines":{"count":21,"covered":17,"percent":80,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}

// Close Files Array
// CHECK-SAME: ],

// Functions List
// CHECK-SAME: "functions":[
// CHECK-SAME: {"name":"main","count":1111000,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":["{{[^"]+}}showRegionMarkers.cpp"]
// CHECK-SAME: }],

// Full Export Summary
// CHECK-SAME: "totals":{
// CHECK-SAME: "lines":{"count":21,"covered":17,"percent":80,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":10,"covered":7,"notcovered":3,"percent":70}}

// Close the export object, data array, and root object
// CHECK-SAME: }]}
51 changes: 51 additions & 0 deletions test/tools/llvm-cov/Inputs/showExpansions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Metadata section
// CHECK: {"version":"1.0.0","type":"llvm.coverage.json.export","data":[

// Open Export
// CHECK-SAME: {"object":"{{[^"]+}}","files":[

// File Object
// CHECK-SAME: {"filename":"{{[^"]+}}showExpansions.cpp",
// CHECK-SAME: "segments":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}],
// CHECK-SAME: "expansions":[
// CHECK-SAME: {"source_region":[24,5,24,17,100,0,1,1],
// CHECK-SAME: "target_regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],

// Yes, 4 of the same filename in a row
// CHECK-SAME: "filenames":[
// CHECK-SAME: "{{[^"]+}}showExpansions.cpp","{{[^"]+}}showExpansions.cpp",
// CHECK-SAME: "{{[^"]+}}showExpansions.cpp","{{[^"]+}}showExpansions.cpp"]
// CHECK-SAME: }],

// Verify the Summary Section for the first file
// CHECK-SAME: "summary":{
// CHECK-SAME: "lines":{"count":17,"covered":15,"percent":88,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":13,"covered":12,"notcovered":1,"percent":92}}

// Close Files Array
// CHECK-SAME: ],

// Functions List
// CHECK-SAME: "functions":[
// CHECK-SAME: {"name":"main","count":1,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}
// CHECK-SAME: ],
// CHECK-SAME: "filenames":[
// CHECK-SAME: "{{[^"]+}}showExpansions.cpp",
// CHECK-SAME: "{{[^"]+}}showExpansions.cpp",
// CHECK-SAME: "{{[^"]+}}showExpansions.cpp",
// CHECK-SAME: "{{[^"]+}}showExpansions.cpp"]
// CHECK-SAME: }],

// Full Export Summary
// CHECK-SAME: "totals":{
// CHECK-SAME: "lines":{"count":17,"covered":15,"percent":88,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":13,"covered":12,"notcovered":1,"percent":92}}

// Close the export object, data array, and root object
// CHECK-SAME: }]}
36 changes: 36 additions & 0 deletions test/tools/llvm-cov/Inputs/universal-binary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Metadata section
// CHECK: {"version":"1.0.0","type":"llvm.coverage.json.export","data":[

// Open Export
// CHECK-SAME: {"object":"{{[^"]+}}","files":[

// File Object
// CHECK-SAME: {"filename":"{{[^"]+}}universal-binary.c",
// CHECK-SAME: "segments":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}],
// CHECK-SAME: "expansions":[],

// Verify the Summary Section for the first file
// CHECK-SAME: "summary":{
// CHECK-SAME: "lines":{"count":1,"covered":1,"percent":100,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":1,"covered":1,"notcovered":0,"percent":100}}

// Close Files Array
// CHECK-SAME: ],

// Functions List
// CHECK-SAME: "functions":[
// CHECK-SAME: {"name":"main","count":100,"regions":[
// CHECK-SAME: {{(\[[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\],?)+}}],
// CHECK-SAME: "filenames":["{{[^"]+}}universal-binary.c"]
// CHECK-SAME: }],

// Full Export Summary
// CHECK-SAME: "totals":{
// CHECK-SAME: "lines":{"count":1,"covered":1,"percent":100,"noncode":0},
// CHECK-SAME: "functions":{"count":1,"covered":1,"percent":100},
// CHECK-SAME: "regions":{"count":1,"covered":1,"notcovered":0,"percent":100}

// Close the export object, data array, and root object
// CHECK-SAME: }]}
4 changes: 4 additions & 0 deletions test/tools/llvm-cov/binary-formats.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ int main(int argc, const char *argv[]) {}
// RUN: llvm-cov show %S/Inputs/binary-formats.macho32l -instr-profile %t.profdata -filename-equivalence %s | FileCheck %s
// RUN: llvm-cov show %S/Inputs/binary-formats.macho64l -instr-profile %t.profdata -filename-equivalence %s | FileCheck %s
// RUN: llvm-cov show %S/Inputs/binary-formats.macho32b -instr-profile %t.profdata -filename-equivalence %s | FileCheck %s

// RUN: llvm-cov export %S/Inputs/binary-formats.macho32l -instr-profile %t.profdata | FileCheck %S/Inputs/binary-formats.canonical.json
// RUN: llvm-cov export %S/Inputs/binary-formats.macho64l -instr-profile %t.profdata | FileCheck %S/Inputs/binary-formats.canonical.json
// RUN: llvm-cov export %S/Inputs/binary-formats.macho32b -instr-profile %t.profdata | FileCheck %S/Inputs/binary-formats.canonical.json
1 change: 1 addition & 0 deletions test/tools/llvm-cov/showExpansions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ int main(int argc, const char *argv[]) {
DO_SOMETHING(i); // CHECK-DAG: Expansion at line [[@LINE]], 5 -> 17
return 0;
}
// RUN: llvm-cov export %S/Inputs/showExpansions.covmapping -instr-profile %S/Inputs/showExpansions.profdata 2>&1 | FileCheck %S/Inputs/showExpansions.json
2 changes: 2 additions & 0 deletions test/tools/llvm-cov/showHighlightedRanges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ int main() {
func2(9);
return 0;
}

// RUN: llvm-cov export %S/Inputs/highlightedRanges.covmapping -instr-profile %S/Inputs/highlightedRanges.profdata 2>&1 | FileCheck %S/Inputs/highlightedRanges.json
2 changes: 2 additions & 0 deletions test/tools/llvm-cov/showLineExecutionCounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,5 @@ int main() { // TEXT: 161| [[@LINE]]|int main(
// HTML: <td class='covered-line'><pre>161</pre></td><td class='line-number'><a name='L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='code'><pre>}
// HTML-WHOLE-FILE: <td class='uncovered-line'></td><td class='line-number'><a name='L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='code'><pre>// after
// HTML-FILTER-NOT: <td class='uncovered-line'></td><td class='line-number'><a name='L[[@LINE-45]]'><pre>[[@LINE-45]]</pre></a></td><td class='code'><pre>// after

// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -name=main 2>/dev/null | FileCheck %S/Inputs/lineExecutionCounts.json
2 changes: 2 additions & 0 deletions test/tools/llvm-cov/showRegionMarkers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ int main() { // CHECK: Marker at [[@LINE]]:12 = 1.11M
}

// RUN: llvm-cov show %S/Inputs/regionMarkers.covmapping -instr-profile %t.profdata -show-regions -dump -filename-equivalence %s 2>&1 | FileCheck %s

// RUN: llvm-cov export %S/Inputs/regionMarkers.covmapping -instr-profile %t.profdata 2>&1 | FileCheck %S/Inputs/regionMarkers.json
2 changes: 2 additions & 0 deletions test/tools/llvm-cov/universal-binary.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ int main(int argc, const char *argv[]) {}

// RUN: llvm-profdata merge %S/Inputs/universal-binary.proftext -o %t.profdata
// RUN: llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch x86_64 | FileCheck %s
// RUN: llvm-cov export %S/Inputs/universal-binary -instr-profile %t.profdata -arch x86_64 2>&1 | FileCheck %S/Inputs/universal-binary.json


// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -filename-equivalence %s -arch i386 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s
// WRONG-ARCH: Failed to load coverage
Expand Down
1 change: 1 addition & 0 deletions tools/llvm-cov/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_llvm_tool(llvm-cov
llvm-cov.cpp
gcov.cpp
CodeCoverage.cpp
CoverageExporterJson.cpp
CoverageFilters.cpp
CoverageReport.cpp
CoverageSummaryInfo.cpp
Expand Down
Loading

0 comments on commit 53397d1

Please sign in to comment.