Path: blob/main/contrib/llvm-project/llvm/tools/llvm-cov/SourceCoverageView.h
35231 views
//===- SourceCoverageView.h - Code coverage view for source code ----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file This class implements rendering for code coverage of source code.9///10//===----------------------------------------------------------------------===//1112#ifndef LLVM_COV_SOURCECOVERAGEVIEW_H13#define LLVM_COV_SOURCECOVERAGEVIEW_H1415#include "CoverageViewOptions.h"16#include "CoverageSummaryInfo.h"17#include "llvm/ProfileData/Coverage/CoverageMapping.h"18#include "llvm/Support/MemoryBuffer.h"19#include <vector>2021namespace llvm {2223using namespace coverage;2425class CoverageFiltersMatchAll;26class SourceCoverageView;2728/// A view that represents a macro or include expansion.29struct ExpansionView {30CounterMappingRegion Region;31std::unique_ptr<SourceCoverageView> View;3233ExpansionView(const CounterMappingRegion &Region,34std::unique_ptr<SourceCoverageView> View)35: Region(Region), View(std::move(View)) {}36ExpansionView(ExpansionView &&RHS)37: Region(std::move(RHS.Region)), View(std::move(RHS.View)) {}38ExpansionView &operator=(ExpansionView &&RHS) {39Region = std::move(RHS.Region);40View = std::move(RHS.View);41return *this;42}4344unsigned getLine() const { return Region.LineStart; }45unsigned getStartCol() const { return Region.ColumnStart; }46unsigned getEndCol() const { return Region.ColumnEnd; }4748friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) {49return LHS.Region.startLoc() < RHS.Region.startLoc();50}51};5253/// A view that represents a function instantiation.54struct InstantiationView {55StringRef FunctionName;56unsigned Line;57std::unique_ptr<SourceCoverageView> View;5859InstantiationView(StringRef FunctionName, unsigned Line,60std::unique_ptr<SourceCoverageView> View)61: FunctionName(FunctionName), Line(Line), View(std::move(View)) {}6263friend bool operator<(const InstantiationView &LHS,64const InstantiationView &RHS) {65return LHS.Line < RHS.Line;66}67};6869/// A view that represents one or more branch regions on a given source line.70struct BranchView {71SmallVector<CountedRegion, 0> Regions;72unsigned Line;7374BranchView(unsigned Line, SmallVector<CountedRegion, 0> Regions)75: Regions(std::move(Regions)), Line(Line) {}7677unsigned getLine() const { return Line; }7879friend bool operator<(const BranchView &LHS, const BranchView &RHS) {80return LHS.Line < RHS.Line;81}82};8384/// A view that represents one or more MCDC regions on a given source line.85struct MCDCView {86SmallVector<MCDCRecord, 0> Records;87unsigned Line;8889MCDCView(unsigned Line, SmallVector<MCDCRecord, 0> Records)90: Records(std::move(Records)), Line(Line) {}9192unsigned getLine() const { return Line; }9394friend bool operator<(const MCDCView &LHS, const MCDCView &RHS) {95return LHS.Line < RHS.Line;96}97};9899/// A file manager that handles format-aware file creation.100class CoveragePrinter {101public:102struct StreamDestructor {103void operator()(raw_ostream *OS) const;104};105106using OwnedStream = std::unique_ptr<raw_ostream, StreamDestructor>;107108protected:109const CoverageViewOptions &Opts;110111CoveragePrinter(const CoverageViewOptions &Opts) : Opts(Opts) {}112113/// Return `OutputDir/ToplevelDir/Path.Extension`. If \p InToplevel is114/// true, skip the ToplevelDir component. If \p Relative is true, skip the115/// OutputDir component.116std::string getOutputPath(StringRef Path, StringRef Extension,117bool InToplevel, bool Relative = true) const;118119/// If directory output is enabled, create a file in that directory120/// at the path given by getOutputPath(). Otherwise, return stdout.121Expected<OwnedStream> createOutputStream(StringRef Path, StringRef Extension,122bool InToplevel) const;123124/// Return the sub-directory name for file coverage reports.125static StringRef getCoverageDir() { return "coverage"; }126127public:128static std::unique_ptr<CoveragePrinter>129create(const CoverageViewOptions &Opts);130131virtual ~CoveragePrinter() {}132133/// @name File Creation Interface134/// @{135136/// Create a file to print a coverage view into.137virtual Expected<OwnedStream> createViewFile(StringRef Path,138bool InToplevel) = 0;139140/// Close a file which has been used to print a coverage view.141virtual void closeViewFile(OwnedStream OS) = 0;142143/// Create an index which lists reports for the given source files.144virtual Error createIndexFile(ArrayRef<std::string> SourceFiles,145const CoverageMapping &Coverage,146const CoverageFiltersMatchAll &Filters) = 0;147148/// @}149};150151/// A code coverage view of a source file or function.152///153/// A source coverage view and its nested sub-views form a file-oriented154/// representation of code coverage data. This view can be printed out by a155/// renderer which implements the Rendering Interface.156class SourceCoverageView {157/// A function or file name.158StringRef SourceName;159160/// A memory buffer backing the source on display.161const MemoryBuffer &File;162163/// Various options to guide the coverage renderer.164const CoverageViewOptions &Options;165166/// Complete coverage information about the source on display.167CoverageData CoverageInfo;168169/// A container for all expansions (e.g macros) in the source on display.170std::vector<ExpansionView> ExpansionSubViews;171172/// A container for all branches in the source on display.173SmallVector<BranchView, 0> BranchSubViews;174175/// A container for all MCDC records in the source on display.176SmallVector<MCDCView, 0> MCDCSubViews;177178/// A container for all instantiations (e.g template functions) in the source179/// on display.180std::vector<InstantiationView> InstantiationSubViews;181182/// Get the first uncovered line number for the source file.183unsigned getFirstUncoveredLineNo();184185protected:186struct LineRef {187StringRef Line;188int64_t LineNo;189190LineRef(StringRef Line, int64_t LineNo) : Line(Line), LineNo(LineNo) {}191};192193using CoverageSegmentArray = ArrayRef<const CoverageSegment *>;194195/// @name Rendering Interface196/// @{197198/// Render a header for the view.199virtual void renderViewHeader(raw_ostream &OS) = 0;200201/// Render a footer for the view.202virtual void renderViewFooter(raw_ostream &OS) = 0;203204/// Render the source name for the view.205virtual void renderSourceName(raw_ostream &OS, bool WholeFile) = 0;206207/// Render the line prefix at the given \p ViewDepth.208virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0;209210/// Render the line suffix at the given \p ViewDepth.211virtual void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) = 0;212213/// Render a view divider at the given \p ViewDepth.214virtual void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) = 0;215216/// Render a source line with highlighting.217virtual void renderLine(raw_ostream &OS, LineRef L,218const LineCoverageStats &LCS, unsigned ExpansionCol,219unsigned ViewDepth) = 0;220221/// Render the line's execution count column.222virtual void renderLineCoverageColumn(raw_ostream &OS,223const LineCoverageStats &Line) = 0;224225/// Render the line number column.226virtual void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) = 0;227228/// Render all the region's execution counts on a line.229virtual void renderRegionMarkers(raw_ostream &OS,230const LineCoverageStats &Line,231unsigned ViewDepth) = 0;232233/// Render the site of an expansion.234virtual void renderExpansionSite(raw_ostream &OS, LineRef L,235const LineCoverageStats &LCS,236unsigned ExpansionCol,237unsigned ViewDepth) = 0;238239/// Render an expansion view and any nested views.240virtual void renderExpansionView(raw_ostream &OS, ExpansionView &ESV,241unsigned ViewDepth) = 0;242243/// Render an instantiation view and any nested views.244virtual void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV,245unsigned ViewDepth) = 0;246247/// Render a branch view and any nested views.248virtual void renderBranchView(raw_ostream &OS, BranchView &BRV,249unsigned ViewDepth) = 0;250251/// Render an MCDC view.252virtual void renderMCDCView(raw_ostream &OS, MCDCView &BRV,253unsigned ViewDepth) = 0;254255/// Render \p Title, a project title if one is available, and the256/// created time.257virtual void renderTitle(raw_ostream &OS, StringRef CellText) = 0;258259/// Render the table header for a given source file.260virtual void renderTableHeader(raw_ostream &OS, unsigned IndentLevel) = 0;261262/// @}263264/// Format a count using engineering notation with 3 significant265/// digits.266static std::string formatCount(uint64_t N);267268/// Check if region marker output is expected for a line.269bool shouldRenderRegionMarkers(const LineCoverageStats &LCS) const;270271/// Check if there are any sub-views attached to this view.272bool hasSubViews() const;273274SourceCoverageView(StringRef SourceName, const MemoryBuffer &File,275const CoverageViewOptions &Options,276CoverageData &&CoverageInfo)277: SourceName(SourceName), File(File), Options(Options),278CoverageInfo(std::move(CoverageInfo)) {}279280public:281static std::unique_ptr<SourceCoverageView>282create(StringRef SourceName, const MemoryBuffer &File,283const CoverageViewOptions &Options, CoverageData &&CoverageInfo);284285virtual ~SourceCoverageView() {}286287/// Return the source name formatted for the host OS.288std::string getSourceName() const;289290const CoverageViewOptions &getOptions() const { return Options; }291292/// Add an expansion subview to this view.293void addExpansion(const CounterMappingRegion &Region,294std::unique_ptr<SourceCoverageView> View);295296/// Add a function instantiation subview to this view.297void addInstantiation(StringRef FunctionName, unsigned Line,298std::unique_ptr<SourceCoverageView> View);299300/// Add a branch subview to this view.301void addBranch(unsigned Line, SmallVector<CountedRegion, 0> Regions);302303/// Add an MCDC subview to this view.304void addMCDCRecord(unsigned Line, SmallVector<MCDCRecord, 0> Records);305306/// Print the code coverage information for a specific portion of a307/// source file to the output stream.308void print(raw_ostream &OS, bool WholeFile, bool ShowSourceName,309bool ShowTitle, unsigned ViewDepth = 0);310};311312} // namespace llvm313314#endif // LLVM_COV_SOURCECOVERAGEVIEW_H315316317