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: CoverageReport(const CoverageViewOptions & Options,const coverage::CoverageMapping & Coverage)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()) Options(Options)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