12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//===- SourceCoverageView.h - Code coverage view for source code ----------===// 22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 32228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// The LLVM Compiler Infrastructure 42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi// This file is distributed under the University of Illinois Open Source 62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// License. See LICENSE.TXT for details. 72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//===----------------------------------------------------------------------===// 92228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// This class implements rendering for code coverage of source code. 112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project// 122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//===----------------------------------------------------------------------===// 132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifndef LLVM_COV_SOURCECOVERAGEVIEW_H 152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define LLVM_COV_SOURCECOVERAGEVIEW_H 162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "CoverageViewOptions.h" 182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "llvm/ProfileData/CoverageMapping.h" 192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "llvm/Support/MemoryBuffer.h" 202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include <vector> 212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectnamespace llvm { 232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectclass SourceCoverageView; 252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// \brief A view that represents a macro or include expansion 272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstruct ExpansionView { 282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project coverage::CounterMappingRegion Region; 292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project std::unique_ptr<SourceCoverageView> View; 302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ExpansionView(const coverage::CounterMappingRegion &Region, 322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project std::unique_ptr<SourceCoverageView> View) 332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project : Region(Region), View(std::move(View)) {} 342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ExpansionView(ExpansionView &&RHS) 352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {} 362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ExpansionView &operator=(ExpansionView &&RHS) { 372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Region = std::move(RHS.Region); 382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project View = std::move(RHS.View); 392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return *this; 402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned getLine() const { return Region.LineStart; } 432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned getStartCol() const { return Region.ColumnStart; } 442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned getEndCol() const { return Region.ColumnEnd; } 452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) { 472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return LHS.Region.startLoc() < RHS.Region.startLoc(); 482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}; 502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// \brief A view that represents a function instantiation 522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstruct InstantiationView { 532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project StringRef FunctionName; 542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned Line; 552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project std::unique_ptr<SourceCoverageView> View; 562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project InstantiationView(StringRef FunctionName, unsigned Line, 582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project std::unique_ptr<SourceCoverageView> View) 592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project : FunctionName(FunctionName), Line(Line), View(std::move(View)) {} 602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project InstantiationView(InstantiationView &&RHS) 612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project : FunctionName(std::move(RHS.FunctionName)), Line(std::move(RHS.Line)), 622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project View(std::move(RHS.View)) {} 632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project InstantiationView &operator=(InstantiationView &&RHS) { 642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FunctionName = std::move(RHS.FunctionName); 652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Line = std::move(RHS.Line); 662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project View = std::move(RHS.View); 672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return *this; 682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project friend bool operator<(const InstantiationView &LHS, 712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const InstantiationView &RHS) { 722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return LHS.Line < RHS.Line; 732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}; 752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// \brief A code coverage view of a specific source file. 772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/// It can have embedded coverage views. 782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectclass SourceCoverageView { 792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprivate: 802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /// \brief Coverage information for a single line. 812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project struct LineCoverageInfo { 822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project uint64_t ExecutionCount; 832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned RegionCount; 842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bool Mapped; 852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project LineCoverageInfo() : ExecutionCount(0), RegionCount(0), Mapped(false) {} 872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bool isMapped() const { return Mapped; } 892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bool hasMultipleRegions() const { return RegionCount > 1; } 912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void addRegionStartCount(uint64_t Count) { 932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project // The max of all region starts is the most interesting value. 942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count); 952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ++RegionCount; 962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void addRegionCount(uint64_t Count) { 992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Mapped = true; 1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ExecutionCount = Count; 1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project }; 1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const MemoryBuffer &File; 1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const CoverageViewOptions &Options; 1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project coverage::CoverageData CoverageInfo; 1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project std::vector<ExpansionView> ExpansionSubViews; 1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project std::vector<InstantiationView> InstantiationSubViews; 1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /// \brief Render a source line with highlighting. 1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void renderLine(raw_ostream &OS, StringRef Line, int64_t LineNumber, 1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const coverage::CoverageSegment *WrappedSegment, 1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ArrayRef<const coverage::CoverageSegment *> Segments, 1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned ExpansionCol); 1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void renderIndent(raw_ostream &OS, unsigned Level); 1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void renderViewDivider(unsigned Offset, unsigned Length, raw_ostream &OS); 1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /// \brief Render the line's execution count column. 1213aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi void renderLineCoverageColumn(raw_ostream &OS, const LineCoverageInfo &Line); 1223aec97e388e29a1d03f0197b27b893bc6aaf8ac3Jean-Michel Trivi 1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /// \brief Render the line number column. 1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo); 1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /// \brief Render all the region's execution counts on a line. 1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project void 128 renderRegionMarkers(raw_ostream &OS, 129 ArrayRef<const coverage::CoverageSegment *> Segments); 130 131 static const unsigned LineCoverageColumnWidth = 7; 132 static const unsigned LineNumberColumnWidth = 5; 133 134public: 135 SourceCoverageView(const MemoryBuffer &File, 136 const CoverageViewOptions &Options, 137 coverage::CoverageData &&CoverageInfo) 138 : File(File), Options(Options), CoverageInfo(std::move(CoverageInfo)) {} 139 140 const CoverageViewOptions &getOptions() const { return Options; } 141 142 /// \brief Add an expansion subview to this view. 143 void addExpansion(const coverage::CounterMappingRegion &Region, 144 std::unique_ptr<SourceCoverageView> View) { 145 ExpansionSubViews.emplace_back(Region, std::move(View)); 146 } 147 148 /// \brief Add a function instantiation subview to this view. 149 void addInstantiation(StringRef FunctionName, unsigned Line, 150 std::unique_ptr<SourceCoverageView> View) { 151 InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View)); 152 } 153 154 /// \brief Print the code coverage information for a specific 155 /// portion of a source file to the output stream. 156 void render(raw_ostream &OS, bool WholeFile, unsigned IndentLevel = 0); 157}; 158 159} // namespace llvm 160 161#endif // LLVM_COV_SOURCECOVERAGEVIEW_H 162