137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===- CodeCoverage.cpp - Coverage tool based on profiling instrumentation-===// 237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The LLVM Compiler Infrastructure 437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// This file is distributed under the University of Illinois Open Source 637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// License. See LICENSE.TXT for details. 737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===// 937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 1037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// The 'CodeCoverageTool' class implements a command line tool to analyze and 1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// report coverage information using the profiling instrumentation and code 1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// coverage mapping. 1337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// 1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//===----------------------------------------------------------------------===// 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "RenderingSupport.h" 1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "CoverageFilters.h" 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "CoverageReport.h" 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "CoverageViewOptions.h" 20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "SourceCoverageView.h" 2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ADT/SmallString.h" 22ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ADT/StringRef.h" 234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/Triple.h" 2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ProfileData/CoverageMapping.h" 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ProfileData/InstrProfReader.h" 2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/CommandLine.h" 2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/FileSystem.h" 2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Format.h" 29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/ManagedStatic.h" 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/Path.h" 3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/PrettyStackTrace.h" 324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/Process.h" 33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Signals.h" 3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include <functional> 3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include <system_error> 3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing namespace llvm; 3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing namespace coverage; 3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesnamespace { 4137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// \brief The implementation of the coverage tool. 4237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesclass CodeCoverageTool { 4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinespublic: 4437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines enum Command { 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief The show command. 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Show, 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief The report command. 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Report 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief Print the error message to the error output stream. 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void error(const Twine &Message, StringRef Whence = ""); 5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief Return a memory buffer for the given source file. 5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ErrorOr<const MemoryBuffer &> getSourceFile(StringRef SourceFile); 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief Create source views for the expansions of the view. 5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void attachExpansionSubViews(SourceCoverageView &View, 5937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ArrayRef<ExpansionRecord> Expansions, 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CoverageMapping &Coverage); 6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief Create the source view of a particular function. 6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<SourceCoverageView> 6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createFunctionView(const FunctionRecord &Function, CoverageMapping &Coverage); 6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief Create the main source view of a particular source file. 6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<SourceCoverageView> 6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines createSourceFileView(StringRef SourceFile, CoverageMapping &Coverage); 6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// \brief Load the coverage mapping data. Return true if an error occured. 7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<CoverageMapping> load(); 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int run(Command Cmd, int argc, const char **argv); 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines typedef std::function<int(int, const char **)> CommandLineParserType; 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int show(int argc, const char **argv, 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CommandLineParserType commandLineParser); 7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int report(int argc, const char **argv, 8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CommandLineParserType commandLineParser); 8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string ObjectFilename; 8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CoverageViewOptions ViewOpts; 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::string PGOFilename; 8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CoverageFiltersMatchAll Filters; 8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::vector<std::string> SourceFiles; 8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>> 8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LoadedSourceFiles; 9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool CompareFilenamesOnly; 9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringMap<std::string> RemappedFilenames; 924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar llvm::Triple::ArchType CoverageArch; 9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}; 9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid CodeCoverageTool::error(const Twine &Message, StringRef Whence) { 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "error: "; 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Whence.empty()) 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << Whence << ": "; 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << Message << "\n"; 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesErrorOr<const MemoryBuffer &> 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCodeCoverageTool::getSourceFile(StringRef SourceFile) { 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // If we've remapped filenames, look up the real location for this file. 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!RemappedFilenames.empty()) { 10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Loc = RemappedFilenames.find(SourceFile); 10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Loc != RemappedFilenames.end()) 10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceFile = Loc->second; 11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Files : LoadedSourceFiles) 11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (sys::fs::equivalent(SourceFile, Files.first)) 11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return *Files.second; 11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Buffer = MemoryBuffer::getFile(SourceFile); 11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (auto EC = Buffer.getError()) { 11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines error(EC.message(), SourceFile); 11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return EC; 11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LoadedSourceFiles.push_back( 12037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::make_pair(SourceFile, std::move(Buffer.get()))); 12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return *LoadedSourceFiles.back().second; 12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 12337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid 12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCodeCoverageTool::attachExpansionSubViews(SourceCoverageView &View, 12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ArrayRef<ExpansionRecord> Expansions, 12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CoverageMapping &Coverage) { 12837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!ViewOpts.ShowExpandedRegions) 12937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return; 13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Expansion : Expansions) { 13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion); 13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ExpansionCoverage.empty()) 13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SourceBuffer = getSourceFile(ExpansionCoverage.getFilename()); 13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!SourceBuffer) 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SubViewExpansions = ExpansionCoverage.getExpansions(); 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SubView = llvm::make_unique<SourceCoverageView>( 14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceBuffer.get(), ViewOpts, std::move(ExpansionCoverage)); 14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines attachExpansionSubViews(*SubView, SubViewExpansions, Coverage); 14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines View.addExpansion(Expansion.Region, std::move(SubView)); 14337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<SourceCoverageView> 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCodeCoverageTool::createFunctionView(const FunctionRecord &Function, 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CoverageMapping &Coverage) { 14937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto FunctionCoverage = Coverage.getCoverageForFunction(Function); 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (FunctionCoverage.empty()) 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 15237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SourceBuffer = getSourceFile(FunctionCoverage.getFilename()); 15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!SourceBuffer) 15437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 15537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 15637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Expansions = FunctionCoverage.getExpansions(); 15737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto View = llvm::make_unique<SourceCoverageView>( 15837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceBuffer.get(), ViewOpts, std::move(FunctionCoverage)); 15937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines attachExpansionSubViews(*View, Expansions, Coverage); 16037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 16137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return View; 16237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 16337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 16437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<SourceCoverageView> 16537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesCodeCoverageTool::createSourceFileView(StringRef SourceFile, 16637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CoverageMapping &Coverage) { 16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SourceBuffer = getSourceFile(SourceFile); 16837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!SourceBuffer) 16937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 17037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto FileCoverage = Coverage.getCoverageForFile(SourceFile); 17137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (FileCoverage.empty()) 17237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 17337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Expansions = FileCoverage.getExpansions(); 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto View = llvm::make_unique<SourceCoverageView>( 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceBuffer.get(), ViewOpts, std::move(FileCoverage)); 17737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines attachExpansionSubViews(*View, Expansions, Coverage); 17837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto Function : Coverage.getInstantiations(SourceFile)) { 18037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SubViewCoverage = Coverage.getCoverageForFunction(*Function); 18137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SubViewExpansions = SubViewCoverage.getExpansions(); 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto SubView = llvm::make_unique<SourceCoverageView>( 18337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceBuffer.get(), ViewOpts, std::move(SubViewCoverage)); 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines attachExpansionSubViews(*SubView, SubViewExpansions, Coverage); 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SubView) { 18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned FileID = Function->CountedRegions.front().FileID; 18837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned Line = 0; 18937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &CR : Function->CountedRegions) 19037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CR.FileID == FileID) 19137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Line = std::max(CR.LineEnd, Line); 19237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines View->addInstantiation(Function->Name, Line, std::move(SubView)); 19337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 19437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 19537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return View; 19637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 19737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 19837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstd::unique_ptr<CoverageMapping> CodeCoverageTool::load() { 1994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename, 2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CoverageArch); 20137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (std::error_code EC = CoverageOrErr.getError()) { 20237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines colored_ostream(errs(), raw_ostream::RED) 20337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "error: Failed to load coverage: " << EC.message(); 20437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "\n"; 20537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return nullptr; 20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Coverage = std::move(CoverageOrErr.get()); 20837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines unsigned Mismatched = Coverage->getMismatchedCount(); 20937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Mismatched) { 21037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines colored_ostream(errs(), raw_ostream::RED) 21137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "warning: " << Mismatched << " functions have mismatched data. "; 21237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "\n"; 21337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 21437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 21537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (CompareFilenamesOnly) { 21637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto CoveredFiles = Coverage.get()->getUniqueSourceFiles(); 21737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (auto &SF : SourceFiles) { 21837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StringRef SFBase = sys::path::filename(SF); 21937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &CF : CoveredFiles) 22037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SFBase == sys::path::filename(CF)) { 22137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RemappedFilenames[CF] = SF; 22237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SF = CF; 22337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 22437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 22537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 22637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 22737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 22837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Coverage; 22937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 23037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesint CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { 23237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Print a stack trace if we signal out. 23337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines sys::PrintStackTraceOnErrorSignal(); 23437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines PrettyStackTraceProgram X(argc, argv); 23537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 23637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 23737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<std::string, true> ObjectFilename( 23837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::Positional, cl::Required, cl::location(this->ObjectFilename), 23937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Covered executable or object file.")); 24037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::list<std::string> InputSourceFiles( 24237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::Positional, cl::desc("<Source files>"), cl::ZeroOrMore); 24337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 24437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<std::string, true> PGOFilename( 24537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "instr-profile", cl::Required, cl::location(this->PGOFilename), 24637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc( 24737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "File with the profile data obtained after an instrumented run")); 24837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::opt<std::string> Arch( 2504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "arch", cl::desc("architecture of the coverage mapping binary")); 2514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 25237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> DebugDump("dump", cl::Optional, 25337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show internal debug dump")); 25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> FilenameEquivalence( 25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "filename-equivalence", cl::Optional, 25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Treat source files as equivalent to paths in the coverage data " 25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "when the file names match, even if the full paths do not")); 25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::OptionCategory FilteringCategory("Function filtering options"); 26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 26237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::list<std::string> NameFilters( 26337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "name", cl::Optional, 26437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show code coverage only for functions with the given name"), 26537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::ZeroOrMore, cl::cat(FilteringCategory)); 26637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::list<std::string> NameRegexFilters( 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "name-regex", cl::Optional, 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show code coverage only for functions that match the given " 27037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "regular expression"), 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::ZeroOrMore, cl::cat(FilteringCategory)); 27237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 27337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<double> RegionCoverageLtFilter( 27437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "region-coverage-lt", cl::Optional, 27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show code coverage only for functions with region coverage " 27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "less than the given threshold"), 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(FilteringCategory)); 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 27937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<double> RegionCoverageGtFilter( 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "region-coverage-gt", cl::Optional, 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show code coverage only for functions with region coverage " 28237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "greater than the given threshold"), 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(FilteringCategory)); 28437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<double> LineCoverageLtFilter( 28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "line-coverage-lt", cl::Optional, 28737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show code coverage only for functions with line coverage less " 28837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "than the given threshold"), 28937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(FilteringCategory)); 29037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 29137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<double> LineCoverageGtFilter( 29237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "line-coverage-gt", cl::Optional, 29337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show code coverage only for functions with line coverage " 29437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "greater than the given threshold"), 29537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(FilteringCategory)); 29637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 2974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::opt<cl::boolOrDefault> UseColor( 2984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "use-color", cl::desc("Emit colored output (default=autodetect)"), 2994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init(cl::BOU_UNSET)); 3004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto commandLineParser = [&, this](int argc, const char **argv) -> int { 30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); 30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.Debug = DebugDump; 30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CompareFilenamesOnly = FilenameEquivalence; 30537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ViewOpts.Colors = UseColor == cl::BOU_UNSET 3074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ? sys::Process::StandardOutHasColors() 3084c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : UseColor == cl::BOU_TRUE; 3094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 31037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Create the function filters 31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!NameFilters.empty() || !NameRegexFilters.empty()) { 31237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto NameFilterer = new CoverageFilters; 31337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Name : NameFilters) 31437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines NameFilterer->push_back(llvm::make_unique<NameCoverageFilter>(Name)); 31537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Regex : NameRegexFilters) 31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines NameFilterer->push_back( 31737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::make_unique<NameRegexCoverageFilter>(Regex)); 31837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filters.push_back(std::unique_ptr<CoverageFilter>(NameFilterer)); 31937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RegionCoverageLtFilter.getNumOccurrences() || 32137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RegionCoverageGtFilter.getNumOccurrences() || 32237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LineCoverageLtFilter.getNumOccurrences() || 32337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LineCoverageGtFilter.getNumOccurrences()) { 32437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto StatFilterer = new CoverageFilters; 32537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RegionCoverageLtFilter.getNumOccurrences()) 32637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StatFilterer->push_back(llvm::make_unique<RegionCoverageFilter>( 32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RegionCoverageFilter::LessThan, RegionCoverageLtFilter)); 32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (RegionCoverageGtFilter.getNumOccurrences()) 32937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StatFilterer->push_back(llvm::make_unique<RegionCoverageFilter>( 33037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RegionCoverageFilter::GreaterThan, RegionCoverageGtFilter)); 33137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (LineCoverageLtFilter.getNumOccurrences()) 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StatFilterer->push_back(llvm::make_unique<LineCoverageFilter>( 33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines LineCoverageFilter::LessThan, LineCoverageLtFilter)); 33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (LineCoverageGtFilter.getNumOccurrences()) 33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines StatFilterer->push_back(llvm::make_unique<LineCoverageFilter>( 33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RegionCoverageFilter::GreaterThan, LineCoverageGtFilter)); 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer)); 33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Arch.empty()) 3414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CoverageArch = llvm::Triple::ArchType::UnknownArch; 3424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else { 3434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CoverageArch = Triple(Arch).getArch(); 3444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (CoverageArch == llvm::Triple::ArchType::UnknownArch) { 3454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << "error: Unknown architecture: " << Arch << "\n"; 3464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 1; 3474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 3484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 3494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &File : InputSourceFiles) { 35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SmallString<128> Path(File); 352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!CompareFilenamesOnly) 353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (std::error_code EC = sys::fs::make_absolute(Path)) { 354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines errs() << "error: " << File << ": " << EC.message(); 355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 1; 356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 35737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceFiles.push_back(Path.str()); 35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 0; 36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines }; 36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 36237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (Cmd) { 36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case Show: 36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return show(argc, argv, commandLineParser); 36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case Report: 36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return report(argc, argv, commandLineParser); 36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 0; 36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 37037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesint CodeCoverageTool::show(int argc, const char **argv, 37237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CommandLineParserType commandLineParser) { 37337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::OptionCategory ViewCategory("Viewing options"); 37537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 37637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> ShowLineExecutionCounts( 37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "show-line-counts", cl::Optional, 37837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show the execution counts for each line"), cl::init(true), 37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(ViewCategory)); 38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> ShowRegions( 38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "show-regions", cl::Optional, 38337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show the execution counts for each region"), 38437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(ViewCategory)); 38537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 38637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> ShowBestLineRegionsCounts( 38737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "show-line-counts-or-regions", cl::Optional, 38837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show the execution counts for each line, or the execution " 38937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "counts for each region on lines that have multiple regions"), 39037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(ViewCategory)); 39137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 39237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> ShowExpansions("show-expansions", cl::Optional, 39337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show expanded source regions"), 39437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(ViewCategory)); 39537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::opt<bool> ShowInstantiations("show-instantiations", cl::Optional, 39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Show function instantiations"), 39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::cat(ViewCategory)); 39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 40037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Err = commandLineParser(argc, argv); 40137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Err) 40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Err; 40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 40437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.ShowLineNumbers = true; 40537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 || 40637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines !ShowRegions || ShowBestLineRegionsCounts; 40737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.ShowRegionMarkers = ShowRegions || ShowBestLineRegionsCounts; 40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts; 40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.ShowExpandedRegions = ShowExpansions; 41037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.ShowFunctionInstantiations = ShowInstantiations; 41137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 41237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Coverage = load(); 41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Coverage) 41437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 1; 41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Filters.empty()) { 41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Show functions 41837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &Function : Coverage->getCoveredFunctions()) { 41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Filters.matches(Function)) 42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 42137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 42237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto mainView = createFunctionView(Function, *Coverage); 42337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!mainView) { 42437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.colored_ostream(outs(), raw_ostream::RED) 42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "warning: Could not read coverage for '" << Function.Name; 42637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines outs() << "\n"; 42737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 42937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.colored_ostream(outs(), raw_ostream::CYAN) << Function.Name 43037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << ":"; 43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines outs() << "\n"; 43237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines mainView->render(outs(), /*WholeFile=*/false); 43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines outs() << "\n"; 43437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 43537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 0; 43637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 43737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 43837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Show files 43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines bool ShowFilenames = SourceFiles.size() != 1; 44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SourceFiles.empty()) 44237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Get the source files from the function coverage mapping 44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (StringRef Filename : Coverage->getUniqueSourceFiles()) 44437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SourceFiles.push_back(Filename); 44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (const auto &SourceFile : SourceFiles) { 44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto mainView = createSourceFileView(SourceFile, *Coverage); 44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!mainView) { 44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.colored_ostream(outs(), raw_ostream::RED) 45037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "warning: The file '" << SourceFile << "' isn't covered."; 45137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines outs() << "\n"; 45237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines continue; 45337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (ShowFilenames) { 45637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ViewOpts.colored_ostream(outs(), raw_ostream::CYAN) << SourceFile << ":"; 45737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines outs() << "\n"; 45837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 45937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines mainView->render(outs(), /*Wholefile=*/true); 46037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (SourceFiles.size() > 1) 46137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines outs() << "\n"; 46237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 46337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 46437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 0; 46537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 46637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 46737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesint CodeCoverageTool::report(int argc, const char **argv, 46837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CommandLineParserType commandLineParser) { 46937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Err = commandLineParser(argc, argv); 47037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (Err) 47137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Err; 47237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 47337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto Coverage = load(); 47437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!Coverage) 47537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 1; 47637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 477ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CoverageReport Report(ViewOpts, std::move(Coverage)); 478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (SourceFiles.empty()) 47937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Report.renderFileReports(llvm::outs()); 480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Report.renderFunctionReports(SourceFiles, llvm::outs()); 48237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return 0; 48337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 48437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 48537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesint showMain(int argc, const char *argv[]) { 48637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CodeCoverageTool Tool; 48737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Tool.run(CodeCoverageTool::Show, argc, argv); 48837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 49037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesint reportMain(int argc, const char *argv[]) { 49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CodeCoverageTool Tool; 49237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return Tool.run(CodeCoverageTool::Report, argc, argv); 49337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 494