aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-cov/CoverageReport.h
blob: 60f751ca96752874b56aaf19443c821f73b86f89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//===- CoverageReport.h - Code coverage report ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This class implements rendering of a code coverage report.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_COV_COVERAGEREPORT_H
#define LLVM_COV_COVERAGEREPORT_H

#include "CoverageFilters.h"
#include "CoverageSummaryInfo.h"
#include "CoverageViewOptions.h"
#include <map>

namespace llvm {

class ThreadPool;

/// Displays the code coverage report.
class CoverageReport {
  const CoverageViewOptions &Options;
  const coverage::CoverageMapping &Coverage;

  void render(const FileCoverageSummary &File, raw_ostream &OS) const;
  void render(const FunctionCoverageSummary &Function, const DemangleCache &DC,
              raw_ostream &OS) const;

public:
  CoverageReport(const CoverageViewOptions &Options,
                 const coverage::CoverageMapping &Coverage)
      : Options(Options), Coverage(Coverage) {}

  void renderFunctionReports(ArrayRef<std::string> Files,
                             const DemangleCache &DC, raw_ostream &OS);

  /// Prepare file reports for the files specified in \p Files.
  static std::vector<FileCoverageSummary>
  prepareFileReports(const coverage::CoverageMapping &Coverage,
                     FileCoverageSummary &Totals, ArrayRef<std::string> Files,
                     const CoverageViewOptions &Options,
                     const CoverageFilter &Filters = CoverageFiltersMatchAll());

  static void
  prepareSingleFileReport(const StringRef Filename,
                          const coverage::CoverageMapping *Coverage,
                          const CoverageViewOptions &Options,
                          const unsigned LCP,
                          FileCoverageSummary *FileReport,
                          const CoverageFilter *Filters);

  /// Render file reports for every unique file in the coverage mapping.
  void renderFileReports(raw_ostream &OS,
                         const CoverageFilters &IgnoreFilenameFilters) const;

  /// Render file reports for the files specified in \p Files.
  void renderFileReports(raw_ostream &OS, ArrayRef<std::string> Files) const;

  /// Render file reports for the files specified in \p Files and the functions
  /// in \p Filters.
  void renderFileReports(raw_ostream &OS, ArrayRef<std::string> Files,
                         const CoverageFiltersMatchAll &Filters) const;

  /// Render file reports with given data.
  void renderFileReports(raw_ostream &OS,
                         const std::vector<FileCoverageSummary> &FileReports,
                         const FileCoverageSummary &Totals,
                         bool ShowEmptyFiles) const;
};

/// Prepare reports for every non-trivial directories (which have more than 1
/// source files) of the source files. This class uses template method pattern.
class DirectoryCoverageReport {
public:
  DirectoryCoverageReport(
      const CoverageViewOptions &Options,
      const coverage::CoverageMapping &Coverage,
      const CoverageFiltersMatchAll &Filters = CoverageFiltersMatchAll())
      : Options(Options), Coverage(Coverage), Filters(Filters) {}

  virtual ~DirectoryCoverageReport() = default;

  /// Prepare file reports for each directory in \p SourceFiles. The total
  /// report for all files is returned and its Name is set to the LCP of all
  /// files. The size of \p SourceFiles must be greater than 1 or else the
  /// behavior is undefined, in which case you should use
  /// CoverageReport::prepareSingleFileReport instead. If an error occurs,
  /// the recursion will stop immediately.
  Expected<FileCoverageSummary>
  prepareDirectoryReports(ArrayRef<std::string> SourceFiles);

protected:
  // These member variables below are used for avoiding being passed
  // repeatedly in recursion.
  const CoverageViewOptions &Options;
  const coverage::CoverageMapping &Coverage;
  const CoverageFiltersMatchAll &Filters;

  /// For calling CoverageReport::prepareSingleFileReport asynchronously
  /// in prepareSubDirectoryReports(). It's not intended to be modified by
  /// generateSubDirectoryReport().
  ThreadPool *TPool;

  /// One report level may correspond to multiple directory levels as we omit
  /// directories which have only one subentry. So we use this Stack to track
  /// each report level's corresponding drectory level.
  /// Each value in the stack is the LCP prefix length length of that report
  /// level. LCPStack.front() is the root LCP. Current LCP is LCPStack.back().
  SmallVector<unsigned, 32> LCPStack;

  // Use std::map to sort table rows in order.
  using SubFileReports = std::map<StringRef, FileCoverageSummary>;
  using SubDirReports =
      std::map<StringRef,
               std::pair<FileCoverageSummary, SmallVector<StringRef, 0>>>;

  /// This method is called when a report level is prepared during the
  /// recursion. \p SubFiles are the reports for those files directly in the
  /// current directory. \p SubDirs are the reports for subdirectories in
  /// current directory. \p SubTotals is the sum of all, and its name is the
  /// current LCP. Note that this method won't be called for trivial
  /// directories.
  virtual Error generateSubDirectoryReport(SubFileReports &&SubFiles,
                                           SubDirReports &&SubDirs,
                                           FileCoverageSummary &&SubTotals) = 0;

private:
  Error prepareSubDirectoryReports(const ArrayRef<StringRef> &Files,
                                   FileCoverageSummary *Totals);
};

} // end namespace llvm

#endif // LLVM_COV_COVERAGEREPORT_H