1//===- CoverageReport.h - Code coverage report ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This class implements rendering of a code coverage report.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_COV_COVERAGEREPORT_H
14#define LLVM_COV_COVERAGEREPORT_H
15
16#include "CoverageFilters.h"
17#include "CoverageSummaryInfo.h"
18#include "CoverageViewOptions.h"
19#include <map>
20
21namespace llvm {
22
23class ThreadPoolInterface;
24
25/// Displays the code coverage report.
26class CoverageReport {
27 const CoverageViewOptions &Options;
28 const coverage::CoverageMapping &Coverage;
29
30 void render(const FileCoverageSummary &File, raw_ostream &OS) const;
31 void render(const FunctionCoverageSummary &Function, const DemangleCache &DC,
32 raw_ostream &OS) const;
33
34public:
35 CoverageReport(const CoverageViewOptions &Options,
36 const coverage::CoverageMapping &Coverage)
37 : Options(Options), Coverage(Coverage) {}
38
39 void renderFunctionReports(ArrayRef<std::string> Files,
40 const DemangleCache &DC, raw_ostream &OS);
41
42 /// Prepare file reports for the files specified in \p Files.
43 static std::vector<FileCoverageSummary>
44 prepareFileReports(const coverage::CoverageMapping &Coverage,
45 FileCoverageSummary &Totals, ArrayRef<std::string> Files,
46 const CoverageViewOptions &Options,
47 const CoverageFilter &Filters = CoverageFiltersMatchAll());
48
49 static void
50 prepareSingleFileReport(const StringRef Filename,
51 const coverage::CoverageMapping *Coverage,
52 const CoverageViewOptions &Options,
53 const unsigned LCP,
54 FileCoverageSummary *FileReport,
55 const CoverageFilter *Filters);
56
57 /// Render file reports for every unique file in the coverage mapping.
58 void renderFileReports(raw_ostream &OS,
59 const CoverageFilters &IgnoreFilenameFilters) const;
60
61 /// Render file reports for the files specified in \p Files.
62 void renderFileReports(raw_ostream &OS, ArrayRef<std::string> Files) const;
63
64 /// Render file reports for the files specified in \p Files and the functions
65 /// in \p Filters.
66 void renderFileReports(raw_ostream &OS, ArrayRef<std::string> Files,
67 const CoverageFiltersMatchAll &Filters) const;
68
69 /// Render file reports with given data.
70 void renderFileReports(raw_ostream &OS,
71 const std::vector<FileCoverageSummary> &FileReports,
72 const FileCoverageSummary &Totals,
73 bool ShowEmptyFiles) const;
74};
75
76/// Prepare reports for every non-trivial directories (which have more than 1
77/// source files) of the source files. This class uses template method pattern.
78class DirectoryCoverageReport {
79public:
80 DirectoryCoverageReport(
81 const CoverageViewOptions &Options,
82 const coverage::CoverageMapping &Coverage,
83 const CoverageFiltersMatchAll &Filters = CoverageFiltersMatchAll())
84 : Options(Options), Coverage(Coverage), Filters(Filters) {}
85
86 virtual ~DirectoryCoverageReport() = default;
87
88 /// Prepare file reports for each directory in \p SourceFiles. The total
89 /// report for all files is returned and its Name is set to the LCP of all
90 /// files. The size of \p SourceFiles must be greater than 1 or else the
91 /// behavior is undefined, in which case you should use
92 /// CoverageReport::prepareSingleFileReport instead. If an error occurs,
93 /// the recursion will stop immediately.
94 Expected<FileCoverageSummary>
95 prepareDirectoryReports(ArrayRef<std::string> SourceFiles);
96
97protected:
98 // These member variables below are used for avoiding being passed
99 // repeatedly in recursion.
100 const CoverageViewOptions &Options;
101 const coverage::CoverageMapping &Coverage;
102 const CoverageFiltersMatchAll &Filters;
103
104 /// For calling CoverageReport::prepareSingleFileReport asynchronously
105 /// in prepareSubDirectoryReports(). It's not intended to be modified by
106 /// generateSubDirectoryReport().
107 ThreadPoolInterface *TPool;
108
109 /// One report level may correspond to multiple directory levels as we omit
110 /// directories which have only one subentry. So we use this Stack to track
111 /// each report level's corresponding drectory level.
112 /// Each value in the stack is the LCP prefix length length of that report
113 /// level. LCPStack.front() is the root LCP. Current LCP is LCPStack.back().
114 SmallVector<unsigned, 32> LCPStack;
115
116 // Use std::map to sort table rows in order.
117 using SubFileReports = std::map<StringRef, FileCoverageSummary>;
118 using SubDirReports =
119 std::map<StringRef,
120 std::pair<FileCoverageSummary, SmallVector<StringRef, 0>>>;
121
122 /// This method is called when a report level is prepared during the
123 /// recursion. \p SubFiles are the reports for those files directly in the
124 /// current directory. \p SubDirs are the reports for subdirectories in
125 /// current directory. \p SubTotals is the sum of all, and its name is the
126 /// current LCP. Note that this method won't be called for trivial
127 /// directories.
128 virtual Error generateSubDirectoryReport(SubFileReports &&SubFiles,
129 SubDirReports &&SubDirs,
130 FileCoverageSummary &&SubTotals) = 0;
131
132private:
133 Error prepareSubDirectoryReports(const ArrayRef<StringRef> &Files,
134 FileCoverageSummary *Totals);
135};
136
137} // end namespace llvm
138
139#endif // LLVM_COV_COVERAGEREPORT_H
140