[llvm] r321815 - [llvm-cov] Refactor "export" command implementation and add support for SOURCES.
Max Moroz via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 4 11:33:29 PST 2018
Author: dor1s
Date: Thu Jan 4 11:33:29 2018
New Revision: 321815
URL: http://llvm.org/viewvc/llvm-project?rev=321815&view=rev
Log:
[llvm-cov] Refactor "export" command implementation and add support for SOURCES.
Summary: Define an interface for Exporter + split JSON exporter into .h and .cpp.
Reviewers: vsk, morehouse
Reviewed By: vsk
Subscribers: llvm-commits, Dor1s, kcc
Differential Revision: https://reviews.llvm.org/D41600
Added:
llvm/trunk/tools/llvm-cov/CoverageExporter.h
llvm/trunk/tools/llvm-cov/CoverageExporterJson.h
Modified:
llvm/trunk/docs/CommandGuide/llvm-cov.rst
llvm/trunk/test/tools/llvm-cov/sources-specified.test
llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp
llvm/trunk/tools/llvm-cov/CoverageReport.h
Modified: llvm/trunk/docs/CommandGuide/llvm-cov.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-cov.rst?rev=321815&r1=321814&r2=321815&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/llvm-cov.rst (original)
+++ llvm/trunk/docs/CommandGuide/llvm-cov.rst Thu Jan 4 11:33:29 2018
@@ -361,14 +361,15 @@ EXPORT COMMAND
SYNOPSIS
^^^^^^^^
-:program:`llvm-cov export` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]]
+:program:`llvm-cov export` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]] [*SOURCES*]
DESCRIPTION
^^^^^^^^^^^
The :program:`llvm-cov export` command exports regions, functions, expansions,
and summaries of the coverage of the binaries *BIN*,... using the profile data
-*PROFILE* as JSON.
+*PROFILE* as JSON. It can optionally be filtered to only export the coverage
+for the files listed in *SOURCES*.
For information on compiling programs for coverage and generating profile data,
see :ref:`llvm-cov-show`.
Modified: llvm/trunk/test/tools/llvm-cov/sources-specified.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/sources-specified.test?rev=321815&r1=321814&r2=321815&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/sources-specified.test (original)
+++ llvm/trunk/test/tools/llvm-cov/sources-specified.test Thu Jan 4 11:33:29 2018
@@ -20,6 +20,20 @@ SHOW: {{.*}}sources_specified{{.*}}
SHOW: {{.*}}sources_specified{{.*}}
SHOW: {{.*}}sources_specified{{.*}}
+
+# Test "export" command. Use a temp .json file as output is a single line.
+RUN: llvm-cov export -instr-profile %S/Inputs/sources_specified/main.profdata \
+RUN: -path-equivalence=/tmp,%S/Inputs \
+RUN: %S/Inputs/sources_specified/main.covmapping \
+RUN: %S/Inputs/sources_specified/main.cc %S/Inputs/sources_specified/extra \
+RUN: > %t.export.json
+
+RUN: not grep '"filename":"/tmp/sources_specified/abs.h"' %t.export.json
+RUN: grep '"filename":"/tmp/sources_specified/main.cc"' %t.export.json
+RUN: grep '"filename":"/tmp/sources_specified/extra/dec.h"' %t.export.json
+RUN: grep '"filename":"/tmp/sources_specified/extra/inc.h"' %t.export.json
+
+
Instructions for regenerating the test:
# cd %S/Inputs/sources_specified
Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=321815&r1=321814&r2=321815&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Thu Jan 4 11:33:29 2018
@@ -13,6 +13,7 @@
//
//===----------------------------------------------------------------------===//
+#include "CoverageExporterJson.h"
#include "CoverageFilters.h"
#include "CoverageReport.h"
#include "CoverageSummaryInfo.h"
@@ -113,14 +114,14 @@ private:
typedef llvm::function_ref<int(int, const char **)> CommandLineParserType;
- int show(int argc, const char **argv,
- CommandLineParserType commandLineParser);
-
- int report(int argc, const char **argv,
+ int doShow(int argc, const char **argv,
CommandLineParserType commandLineParser);
- int export_(int argc, const char **argv,
- CommandLineParserType commandLineParser);
+ int doReport(int argc, const char **argv,
+ CommandLineParserType commandLineParser);
+
+ int doExport(int argc, const char **argv,
+ CommandLineParserType commandLineParser);
std::vector<StringRef> ObjectFilenames;
CoverageViewOptions ViewOpts;
@@ -755,17 +756,17 @@ int CodeCoverageTool::run(Command Cmd, i
switch (Cmd) {
case Show:
- return show(argc, argv, commandLineParser);
+ return doShow(argc, argv, commandLineParser);
case Report:
- return report(argc, argv, commandLineParser);
+ return doReport(argc, argv, commandLineParser);
case Export:
- return export_(argc, argv, commandLineParser);
+ return doExport(argc, argv, commandLineParser);
}
return 0;
}
-int CodeCoverageTool::show(int argc, const char **argv,
- CommandLineParserType commandLineParser) {
+int CodeCoverageTool::doShow(int argc, const char **argv,
+ CommandLineParserType commandLineParser) {
cl::OptionCategory ViewCategory("Viewing options");
@@ -932,8 +933,8 @@ int CodeCoverageTool::show(int argc, con
return 0;
}
-int CodeCoverageTool::report(int argc, const char **argv,
- CommandLineParserType commandLineParser) {
+int CodeCoverageTool::doReport(int argc, const char **argv,
+ CommandLineParserType commandLineParser) {
cl::opt<bool> ShowFunctionSummaries(
"show-functions", cl::Optional, cl::init(false),
cl::desc("Show coverage summaries for each function"));
@@ -969,8 +970,8 @@ int CodeCoverageTool::report(int argc, c
return 0;
}
-int CodeCoverageTool::export_(int argc, const char **argv,
- CommandLineParserType commandLineParser) {
+int CodeCoverageTool::doExport(int argc, const char **argv,
+ CommandLineParserType commandLineParser) {
auto Err = commandLineParser(argc, argv);
if (Err)
@@ -987,7 +988,12 @@ int CodeCoverageTool::export_(int argc,
return 1;
}
- exportCoverageDataToJson(*Coverage.get(), ViewOpts, outs());
+ auto Exporter = CoverageExporterJson(*Coverage.get(), ViewOpts, outs());
+
+ if (SourceFiles.empty())
+ Exporter.renderRoot();
+ else
+ Exporter.renderRoot(SourceFiles);
return 0;
}
Added: llvm/trunk/tools/llvm-cov/CoverageExporter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageExporter.h?rev=321815&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageExporter.h (added)
+++ llvm/trunk/tools/llvm-cov/CoverageExporter.h Thu Jan 4 11:33:29 2018
@@ -0,0 +1,51 @@
+//===- CoverageExporter.h - Code coverage exporter ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines a code coverage exporter interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_COV_COVERAGEEXPORTER_H
+#define LLVM_COV_COVERAGEEXPORTER_H
+
+#include "CoverageSummaryInfo.h"
+#include "CoverageViewOptions.h"
+#include "llvm/ProfileData/Coverage/CoverageMapping.h"
+
+namespace llvm {
+
+/// \brief Exports the code coverage information.
+class CoverageExporter {
+protected:
+ /// \brief The full CoverageMapping object to export.
+ const coverage::CoverageMapping &Coverage;
+
+ /// \brief The options passed to the tool.
+ const CoverageViewOptions &Options;
+
+ /// \brief Output stream to print JSON to.
+ raw_ostream &OS;
+
+ CoverageExporter(const coverage::CoverageMapping &CoverageMapping,
+ const CoverageViewOptions &Options, raw_ostream &OS)
+ : Coverage(CoverageMapping), Options(Options), OS(OS) {}
+
+public:
+ virtual ~CoverageExporter(){};
+
+ /// \brief Render the CoverageMapping object.
+ virtual void renderRoot() = 0;
+
+ /// \brief Render the CoverageMapping object for specified source files.
+ virtual void renderRoot(const std::vector<std::string> &SourceFiles) = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_COV_COVERAGEEXPORTER_H
Modified: llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp?rev=321815&r1=321814&r2=321815&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CoverageExporterJson.cpp Thu Jan 4 11:33:29 2018
@@ -41,11 +41,8 @@
//
//===----------------------------------------------------------------------===//
+#include "CoverageExporterJson.h"
#include "CoverageReport.h"
-#include "CoverageSummaryInfo.h"
-#include "CoverageViewOptions.h"
-#include "llvm/ProfileData/Coverage/CoverageMapping.h"
-#include <stack>
/// \brief The semantic version combined as a string.
#define LLVM_COVERAGE_EXPORT_JSON_STR "2.0.0"
@@ -54,381 +51,328 @@
#define LLVM_COVERAGE_EXPORT_JSON_TYPE_STR "llvm.coverage.json.export"
using namespace llvm;
-using namespace coverage;
-class CoverageExporterJson {
- const CoverageViewOptions &Options;
-
- /// \brief Output stream to print JSON to.
- raw_ostream &OS;
-
- /// \brief The full CoverageMapping object to export.
- const CoverageMapping &Coverage;
-
- /// \brief States that the JSON rendering machine can be in.
- enum JsonState { None, NonEmptyElement, EmptyElement };
-
- /// \brief Tracks state of the JSON output.
- std::stack<JsonState> State;
-
- /// \brief Emit a serialized scalar.
- void emitSerialized(const int64_t Value) { OS << Value; }
-
- /// \brief Emit a serialized string.
- void emitSerialized(const std::string &Value) {
- OS << "\"";
- for (char C : Value) {
- if (C != '\\')
- OS << C;
- else
- OS << "\\\\";
- }
- OS << "\"";
- }
-
- /// \brief Emit a comma if there is a previous element to delimit.
- void emitComma() {
- if (State.top() == JsonState::NonEmptyElement) {
- OS << ",";
- } else if (State.top() == JsonState::EmptyElement) {
- State.pop();
- assert((State.size() >= 1) && "Closed too many JSON elements");
- State.push(JsonState::NonEmptyElement);
- }
- }
-
- /// \brief Emit a starting dictionary/object character.
- void emitDictStart() {
- emitComma();
- State.push(JsonState::EmptyElement);
- OS << "{";
- }
-
- /// \brief Emit a dictionary/object key but no value.
- void emitDictKey(const std::string &Key) {
- emitComma();
- emitSerialized(Key);
- OS << ":";
- State.pop();
- assert((State.size() >= 1) && "Closed too many JSON elements");
-
- // We do not want to emit a comma after this key.
- State.push(JsonState::EmptyElement);
- }
-
- /// \brief Emit a dictionary/object key/value pair.
- template <typename V>
- void emitDictElement(const std::string &Key, const V &Value) {
- emitComma();
- emitSerialized(Key);
- OS << ":";
- emitSerialized(Value);
- }
-
- /// \brief Emit a closing dictionary/object character.
- void emitDictEnd() {
- State.pop();
- assert((State.size() >= 1) && "Closed too many JSON elements");
- OS << "}";
- }
+CoverageExporterJson::CoverageExporterJson(
+ const coverage::CoverageMapping &CoverageMapping,
+ const CoverageViewOptions &Options, raw_ostream &OS)
+ : CoverageExporter(CoverageMapping, Options, OS) {
+ State.push(JsonState::None);
+}
- /// \brief Emit a starting array character.
- void emitArrayStart() {
- emitComma();
- State.push(JsonState::EmptyElement);
- OS << "[";
- }
+void CoverageExporterJson::emitSerialized(const int64_t Value) { OS << Value; }
- /// \brief Emit an array element.
- template <typename V> void emitArrayElement(const V &Value) {
- emitComma();
- emitSerialized(Value);
+void CoverageExporterJson::emitSerialized(const std::string &Value) {
+ OS << "\"";
+ for (char C : Value) {
+ if (C != '\\')
+ OS << C;
+ else
+ OS << "\\\\";
}
+ OS << "\"";
+}
- /// \brief emit a closing array character.
- void emitArrayEnd() {
+void CoverageExporterJson::emitComma() {
+ if (State.top() == JsonState::NonEmptyElement) {
+ OS << ",";
+ } else if (State.top() == JsonState::EmptyElement) {
State.pop();
assert((State.size() >= 1) && "Closed too many JSON elements");
- OS << "]";
+ State.push(JsonState::NonEmptyElement);
}
+}
- /// \brief Render the CoverageMapping object.
- void renderRoot() {
- // Start Root of JSON object.
- emitDictStart();
-
- emitDictElement("version", LLVM_COVERAGE_EXPORT_JSON_STR);
- emitDictElement("type", LLVM_COVERAGE_EXPORT_JSON_TYPE_STR);
- emitDictKey("data");
+void CoverageExporterJson::emitDictStart() {
+ emitComma();
+ State.push(JsonState::EmptyElement);
+ OS << "{";
+}
- // Start List of Exports.
- emitArrayStart();
+void CoverageExporterJson::emitDictKey(const std::string &Key) {
+ emitComma();
+ emitSerialized(Key);
+ OS << ":";
+ State.pop();
+ assert((State.size() >= 1) && "Closed too many JSON elements");
- // Start Export.
- emitDictStart();
+ // We do not want to emit a comma after this key.
+ State.push(JsonState::EmptyElement);
+}
- emitDictKey("files");
+void CoverageExporterJson::emitDictEnd() {
+ State.pop();
+ assert((State.size() >= 1) && "Closed too many JSON elements");
+ OS << "}";
+}
- FileCoverageSummary Totals = FileCoverageSummary("Totals");
- std::vector<std::string> SourceFiles;
- for (StringRef SF : Coverage.getUniqueSourceFiles())
- SourceFiles.emplace_back(SF);
- auto FileReports = CoverageReport::prepareFileReports(Coverage, Totals,
- SourceFiles, Options);
- renderFiles(SourceFiles, FileReports);
-
- // Skip functions-level information for summary-only export mode.
- if (!Options.ExportSummaryOnly) {
- emitDictKey("functions");
- renderFunctions(Coverage.getCoveredFunctions());
- }
+void CoverageExporterJson::emitArrayStart() {
+ emitComma();
+ State.push(JsonState::EmptyElement);
+ OS << "[";
+}
- emitDictKey("totals");
- renderSummary(Totals);
+void CoverageExporterJson::emitArrayEnd() {
+ State.pop();
+ assert((State.size() >= 1) && "Closed too many JSON elements");
+ OS << "]";
+}
- // End Export.
- emitDictEnd();
+void CoverageExporterJson::renderRoot() {
+ std::vector<std::string> SourceFiles;
+ for (StringRef SF : Coverage.getUniqueSourceFiles())
+ SourceFiles.emplace_back(SF);
+ renderRoot(SourceFiles);
+}
- // End List of Exports.
- emitArrayEnd();
+void CoverageExporterJson::renderRoot(
+ const std::vector<std::string> &SourceFiles) {
+ // Start Root of JSON object.
+ emitDictStart();
+
+ emitDictElement("version", LLVM_COVERAGE_EXPORT_JSON_STR);
+ emitDictElement("type", LLVM_COVERAGE_EXPORT_JSON_TYPE_STR);
+ emitDictKey("data");
+
+ // Start List of Exports.
+ emitArrayStart();
+
+ // Start Export.
+ emitDictStart();
+
+ emitDictKey("files");
+
+ FileCoverageSummary Totals = FileCoverageSummary("Totals");
+ auto FileReports = CoverageReport::prepareFileReports(Coverage, Totals,
+ SourceFiles, Options);
+ renderFiles(SourceFiles, FileReports);
- // End Root of JSON Object.
- emitDictEnd();
-
- assert((State.top() == JsonState::None) &&
- "All Elements In JSON were Closed");
+ // Skip functions-level information for summary-only export mode.
+ if (!Options.ExportSummaryOnly) {
+ emitDictKey("functions");
+ renderFunctions(Coverage.getCoveredFunctions());
}
- /// \brief Render an array of all the given functions.
- void
- renderFunctions(const iterator_range<FunctionRecordIterator> &Functions) {
- // Start List of Functions.
- emitArrayStart();
+ emitDictKey("totals");
+ renderSummary(Totals);
- for (const auto &Function : Functions) {
- // Start Function.
- emitDictStart();
+ // End Export.
+ emitDictEnd();
- emitDictElement("name", Function.Name);
- emitDictElement("count", Function.ExecutionCount);
- emitDictKey("regions");
+ // End List of Exports.
+ emitArrayEnd();
- renderRegions(Function.CountedRegions);
+ // End Root of JSON Object.
+ emitDictEnd();
- emitDictKey("filenames");
+ assert((State.top() == JsonState::None) &&
+ "All Elements In JSON were Closed");
+}
- // Start Filenames for Function.
- emitArrayStart();
+void CoverageExporterJson::renderFunctions(
+ const iterator_range<coverage::FunctionRecordIterator> &Functions) {
+ // Start List of Functions.
+ emitArrayStart();
- for (const auto &FileName : Function.Filenames)
- emitArrayElement(FileName);
+ for (const auto &Function : Functions) {
+ // Start Function.
+ emitDictStart();
- // End Filenames for Function.
- emitArrayEnd();
+ emitDictElement("name", Function.Name);
+ emitDictElement("count", Function.ExecutionCount);
+ emitDictKey("regions");
- // End Function.
- emitDictEnd();
- }
+ renderRegions(Function.CountedRegions);
- // End List of Functions.
- emitArrayEnd();
- }
+ emitDictKey("filenames");
- /// \brief Render an array of all the source files, also pass back a Summary.
- void renderFiles(ArrayRef<std::string> SourceFiles,
- ArrayRef<FileCoverageSummary> FileReports) {
- // Start List of Files.
+ // Start Filenames for Function.
emitArrayStart();
- for (unsigned I = 0, E = SourceFiles.size(); I < E; ++I) {
- // Render the file.
- auto FileCoverage = Coverage.getCoverageForFile(SourceFiles[I]);
- renderFile(FileCoverage, FileReports[I]);
- }
+ for (const auto &FileName : Function.Filenames)
+ emitArrayElement(FileName);
- // End List of Files.
+ // End Filenames for Function.
emitArrayEnd();
- }
- /// \brief Render a single file.
- void renderFile(const CoverageData &FileCoverage,
- const FileCoverageSummary &FileReport) {
- // Start File.
- emitDictStart();
-
- emitDictElement("filename", FileCoverage.getFilename());
-
- // Skip segments and expansions for summary-only export mode.
- if (!Options.ExportSummaryOnly) {
- emitDictKey("segments");
-
- // Start List of Segments.
- emitArrayStart();
-
- for (const auto &Segment : FileCoverage)
- renderSegment(Segment);
-
- // End List of Segments.
- emitArrayEnd();
-
- emitDictKey("expansions");
-
- // Start List of Expansions.
- emitArrayStart();
-
- for (const auto &Expansion : FileCoverage.getExpansions())
- renderExpansion(Expansion);
-
- // End List of Expansions.
- emitArrayEnd();
- }
-
- emitDictKey("summary");
- renderSummary(FileReport);
-
- // End File.
+ // End Function.
emitDictEnd();
}
- /// \brief Render a CoverageSegment.
- void renderSegment(const CoverageSegment &Segment) {
- // Start Segment.
- emitArrayStart();
-
- emitArrayElement(Segment.Line);
- emitArrayElement(Segment.Col);
- emitArrayElement(Segment.Count);
- emitArrayElement(Segment.HasCount);
- emitArrayElement(Segment.IsRegionEntry);
+ // End List of Functions.
+ emitArrayEnd();
+}
- // End Segment.
- emitArrayEnd();
+void CoverageExporterJson::renderFiles(
+ ArrayRef<std::string> SourceFiles,
+ ArrayRef<FileCoverageSummary> FileReports) {
+ // Start List of Files.
+ emitArrayStart();
+
+ for (unsigned I = 0, E = SourceFiles.size(); I < E; ++I) {
+ // Render the file.
+ auto FileCoverage = Coverage.getCoverageForFile(SourceFiles[I]);
+ renderFile(FileCoverage, FileReports[I]);
}
- /// \brief Render an ExpansionRecord.
- void renderExpansion(const ExpansionRecord &Expansion) {
- // Start Expansion.
- emitDictStart();
+ // End List of Files.
+ emitArrayEnd();
+}
- // Mark the beginning and end of this expansion in the source file.
- emitDictKey("source_region");
- renderRegion(Expansion.Region);
-
- // Enumerate the coverage information for the expansion.
- emitDictKey("target_regions");
- renderRegions(Expansion.Function.CountedRegions);
+void CoverageExporterJson::renderFile(
+ const coverage::CoverageData &FileCoverage,
+ const FileCoverageSummary &FileReport) {
+ // Start File.
+ emitDictStart();
+
+ emitDictElement("filename", FileCoverage.getFilename());
+
+ // Skip segments and expansions for summary-only export mode.
+ if (!Options.ExportSummaryOnly) {
+ emitDictKey("segments");
- emitDictKey("filenames");
- // Start List of Filenames to map the fileIDs.
+ // Start List of Segments.
emitArrayStart();
- for (const auto &Filename : Expansion.Function.Filenames)
- emitArrayElement(Filename);
- // End List of Filenames.
- emitArrayEnd();
- // End Expansion.
- emitDictEnd();
- }
-
- /// \brief Render a list of CountedRegions.
- void renderRegions(ArrayRef<CountedRegion> Regions) {
- // Start List of Regions.
- emitArrayStart();
+ for (const auto &Segment : FileCoverage)
+ renderSegment(Segment);
- for (const auto &Region : Regions)
- renderRegion(Region);
-
- // End List of Regions.
+ // End List of Segments.
emitArrayEnd();
- }
- /// \brief Render a single CountedRegion.
- void renderRegion(const CountedRegion &Region) {
- // Start CountedRegion.
+ emitDictKey("expansions");
+
+ // Start List of Expansions.
emitArrayStart();
- emitArrayElement(Region.LineStart);
- emitArrayElement(Region.ColumnStart);
- emitArrayElement(Region.LineEnd);
- emitArrayElement(Region.ColumnEnd);
- emitArrayElement(Region.ExecutionCount);
- emitArrayElement(Region.FileID);
- emitArrayElement(Region.ExpandedFileID);
- emitArrayElement(Region.Kind);
+ for (const auto &Expansion : FileCoverage.getExpansions())
+ renderExpansion(Expansion);
- // End CountedRegion.
+ // End List of Expansions.
emitArrayEnd();
}
- /// \brief Render a FileCoverageSummary.
- void renderSummary(const FileCoverageSummary &Summary) {
- // Start Summary for the file.
- emitDictStart();
+ emitDictKey("summary");
+ renderSummary(FileReport);
- emitDictKey("lines");
+ // End File.
+ emitDictEnd();
+}
- // Start Line Coverage Summary.
- emitDictStart();
- emitDictElement("count", Summary.LineCoverage.getNumLines());
- emitDictElement("covered", Summary.LineCoverage.getCovered());
- emitDictElement("percent", Summary.LineCoverage.getPercentCovered());
- // End Line Coverage Summary.
- emitDictEnd();
+void CoverageExporterJson::renderSegment(
+ const coverage::CoverageSegment &Segment) {
+ // Start Segment.
+ emitArrayStart();
+
+ emitArrayElement(Segment.Line);
+ emitArrayElement(Segment.Col);
+ emitArrayElement(Segment.Count);
+ emitArrayElement(Segment.HasCount);
+ emitArrayElement(Segment.IsRegionEntry);
- emitDictKey("functions");
+ // End Segment.
+ emitArrayEnd();
+}
- // Start Function Coverage Summary.
- emitDictStart();
- emitDictElement("count", Summary.FunctionCoverage.getNumFunctions());
- emitDictElement("covered", Summary.FunctionCoverage.getExecuted());
- emitDictElement("percent", Summary.FunctionCoverage.getPercentCovered());
- // End Function Coverage Summary.
- emitDictEnd();
+void CoverageExporterJson::renderExpansion(
+ const coverage::ExpansionRecord &Expansion) {
+ // Start Expansion.
+ emitDictStart();
+
+ // Mark the beginning and end of this expansion in the source file.
+ emitDictKey("source_region");
+ renderRegion(Expansion.Region);
+
+ // Enumerate the coverage information for the expansion.
+ emitDictKey("target_regions");
+ renderRegions(Expansion.Function.CountedRegions);
+
+ emitDictKey("filenames");
+ // Start List of Filenames to map the fileIDs.
+ emitArrayStart();
+ for (const auto &Filename : Expansion.Function.Filenames)
+ emitArrayElement(Filename);
+ // End List of Filenames.
+ emitArrayEnd();
- emitDictKey("instantiations");
+ // End Expansion.
+ emitDictEnd();
+}
- // Start Instantiation Coverage Summary.
- emitDictStart();
- emitDictElement("count", Summary.InstantiationCoverage.getNumFunctions());
- emitDictElement("covered", Summary.InstantiationCoverage.getExecuted());
- emitDictElement("percent",
- Summary.InstantiationCoverage.getPercentCovered());
- // End Function Coverage Summary.
- emitDictEnd();
+void CoverageExporterJson::renderRegions(
+ ArrayRef<coverage::CountedRegion> Regions) {
+ // Start List of Regions.
+ emitArrayStart();
- emitDictKey("regions");
+ for (const auto &Region : Regions)
+ renderRegion(Region);
- // Start Region Coverage Summary.
- emitDictStart();
- emitDictElement("count", Summary.RegionCoverage.getNumRegions());
- emitDictElement("covered", Summary.RegionCoverage.getCovered());
- emitDictElement("notcovered",
- Summary.RegionCoverage.getNumRegions() -
- Summary.RegionCoverage.getCovered());
- emitDictElement("percent", Summary.RegionCoverage.getPercentCovered());
- // End Region Coverage Summary.
- emitDictEnd();
+ // End List of Regions.
+ emitArrayEnd();
+}
- // End Summary for the file.
- emitDictEnd();
- }
+void CoverageExporterJson::renderRegion(const coverage::CountedRegion &Region) {
+ // Start CountedRegion.
+ emitArrayStart();
+
+ emitArrayElement(Region.LineStart);
+ emitArrayElement(Region.ColumnStart);
+ emitArrayElement(Region.LineEnd);
+ emitArrayElement(Region.ColumnEnd);
+ emitArrayElement(Region.ExecutionCount);
+ emitArrayElement(Region.FileID);
+ emitArrayElement(Region.ExpandedFileID);
+ emitArrayElement(Region.Kind);
-public:
- CoverageExporterJson(const CoverageMapping &CoverageMapping,
- const CoverageViewOptions &Options, raw_ostream &OS)
- : Options(Options), OS(OS), Coverage(CoverageMapping) {
- State.push(JsonState::None);
- }
+ // End CountedRegion.
+ emitArrayEnd();
+}
- /// \brief Print the CoverageMapping.
- void print() { renderRoot(); }
-};
-
-/// \brief Export the given CoverageMapping to a JSON Format.
-void exportCoverageDataToJson(const CoverageMapping &CoverageMapping,
- const CoverageViewOptions &Options,
- raw_ostream &OS) {
- auto Exporter = CoverageExporterJson(CoverageMapping, Options, OS);
+void CoverageExporterJson::renderSummary(const FileCoverageSummary &Summary) {
+ // Start Summary for the file.
+ emitDictStart();
+
+ emitDictKey("lines");
+
+ // Start Line Coverage Summary.
+ emitDictStart();
+ emitDictElement("count", Summary.LineCoverage.getNumLines());
+ emitDictElement("covered", Summary.LineCoverage.getCovered());
+ emitDictElement("percent", Summary.LineCoverage.getPercentCovered());
+ // End Line Coverage Summary.
+ emitDictEnd();
+
+ emitDictKey("functions");
+
+ // Start Function Coverage Summary.
+ emitDictStart();
+ emitDictElement("count", Summary.FunctionCoverage.getNumFunctions());
+ emitDictElement("covered", Summary.FunctionCoverage.getExecuted());
+ emitDictElement("percent", Summary.FunctionCoverage.getPercentCovered());
+ // End Function Coverage Summary.
+ emitDictEnd();
+
+ emitDictKey("instantiations");
+
+ // Start Instantiation Coverage Summary.
+ emitDictStart();
+ emitDictElement("count", Summary.InstantiationCoverage.getNumFunctions());
+ emitDictElement("covered", Summary.InstantiationCoverage.getExecuted());
+ emitDictElement("percent", Summary.InstantiationCoverage.getPercentCovered());
+ // End Function Coverage Summary.
+ emitDictEnd();
+
+ emitDictKey("regions");
+
+ // Start Region Coverage Summary.
+ emitDictStart();
+ emitDictElement("count", Summary.RegionCoverage.getNumRegions());
+ emitDictElement("covered", Summary.RegionCoverage.getCovered());
+ emitDictElement("notcovered", Summary.RegionCoverage.getNumRegions() -
+ Summary.RegionCoverage.getCovered());
+ emitDictElement("percent", Summary.RegionCoverage.getPercentCovered());
+ // End Region Coverage Summary.
+ emitDictEnd();
- Exporter.print();
+ // End Summary for the file.
+ emitDictEnd();
}
Added: llvm/trunk/tools/llvm-cov/CoverageExporterJson.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageExporterJson.h?rev=321815&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageExporterJson.h (added)
+++ llvm/trunk/tools/llvm-cov/CoverageExporterJson.h Thu Jan 4 11:33:29 2018
@@ -0,0 +1,108 @@
+//===- CoverageExporterJson.h - Code coverage JSON exporter ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements a code coverage exporter for JSON format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_COV_COVERAGEEXPORTERJSON_H
+#define LLVM_COV_COVERAGEEXPORTERJSON_H
+
+#include "CoverageExporter.h"
+#include <stack>
+
+namespace llvm {
+
+class CoverageExporterJson : public CoverageExporter {
+ /// \brief States that the JSON rendering machine can be in.
+ enum JsonState { None, NonEmptyElement, EmptyElement };
+
+ /// \brief Tracks state of the JSON output.
+ std::stack<JsonState> State;
+
+ /// \brief Emit a serialized scalar.
+ void emitSerialized(const int64_t Value);
+
+ /// \brief Emit a serialized string.
+ void emitSerialized(const std::string &Value);
+
+ /// \brief Emit a comma if there is a previous element to delimit.
+ void emitComma();
+
+ /// \brief Emit a starting dictionary/object character.
+ void emitDictStart();
+
+ /// \brief Emit a dictionary/object key but no value.
+ void emitDictKey(const std::string &Key);
+
+ /// \brief Emit a dictionary/object key/value pair.
+ template <typename V>
+ void emitDictElement(const std::string &Key, const V &Value) {
+ emitComma();
+ emitSerialized(Key);
+ OS << ":";
+ emitSerialized(Value);
+ }
+
+ /// \brief Emit a closing dictionary/object character.
+ void emitDictEnd();
+
+ /// \brief Emit a starting array character.
+ void emitArrayStart();
+
+ /// \brief Emit an array element.
+ template <typename V> void emitArrayElement(const V &Value) {
+ emitComma();
+ emitSerialized(Value);
+ }
+
+ /// \brief emit a closing array character.
+ void emitArrayEnd();
+
+ /// \brief Render an array of all the given functions.
+ void renderFunctions(
+ const iterator_range<coverage::FunctionRecordIterator> &Functions);
+
+ /// \brief Render an array of all the source files, also pass back a Summary.
+ void renderFiles(ArrayRef<std::string> SourceFiles,
+ ArrayRef<FileCoverageSummary> FileReports);
+
+ /// \brief Render a single file.
+ void renderFile(const coverage::CoverageData &FileCoverage,
+ const FileCoverageSummary &FileReport);
+
+ /// \brief Render a CoverageSegment.
+ void renderSegment(const coverage::CoverageSegment &Segment);
+
+ /// \brief Render an ExpansionRecord.
+ void renderExpansion(const coverage::ExpansionRecord &Expansion);
+
+ /// \brief Render a list of CountedRegions.
+ void renderRegions(ArrayRef<coverage::CountedRegion> Regions);
+
+ /// \brief Render a single CountedRegion.
+ void renderRegion(const coverage::CountedRegion &Region);
+
+ /// \brief Render a FileCoverageSummary.
+ void renderSummary(const FileCoverageSummary &Summary);
+
+public:
+ CoverageExporterJson(const coverage::CoverageMapping &CoverageMapping,
+ const CoverageViewOptions &Options, raw_ostream &OS);
+
+ /// \brief Render the CoverageMapping object.
+ void renderRoot() override;
+
+ /// \brief Render the CoverageMapping object for specified source files.
+ void renderRoot(const std::vector<std::string> &SourceFiles) override;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_COV_COVERAGEEXPORTERJSON_H
Modified: llvm/trunk/tools/llvm-cov/CoverageReport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CoverageReport.h?rev=321815&r1=321814&r2=321815&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CoverageReport.h (original)
+++ llvm/trunk/tools/llvm-cov/CoverageReport.h Thu Jan 4 11:33:29 2018
@@ -1,4 +1,4 @@
-//===- CoverageReport.h - Code coverage report ---------------------------===//
+//===- CoverageReport.h - Code coverage report ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
More information about the llvm-commits
mailing list