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 | |
21 | namespace llvm { |
22 | |
23 | class ThreadPoolInterface; |
24 | |
25 | /// Displays the code coverage report. |
26 | class 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 | |
34 | public: |
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. |
78 | class DirectoryCoverageReport { |
79 | public: |
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 | |
97 | protected: |
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 | |
132 | private: |
133 | Error prepareSubDirectoryReports(const ArrayRef<StringRef> &Files, |
134 | FileCoverageSummary *Totals); |
135 | }; |
136 | |
137 | } // end namespace llvm |
138 | |
139 | #endif // LLVM_COV_COVERAGEREPORT_H |
140 | |