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