diff options
Diffstat (limited to 'llvm/tools/llvm-cov/SourceCoverageView.cpp')
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageView.cpp | 100 |
1 files changed, 53 insertions, 47 deletions
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp index d6de961c70b..6b7f50ffc7e 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp @@ -21,76 +21,70 @@ using namespace llvm; -std::string SourceCoverageView::formatCount(uint64_t N) { - std::string Number = utostr(N); - int Len = Number.size(); - if (Len <= 3) - return Number; - int IntLen = Len % 3 == 0 ? 3 : Len % 3; - std::string Result(Number.data(), IntLen); - if (IntLen != 3) { - Result.push_back('.'); - Result += Number.substr(IntLen, 3 - IntLen); - } - Result.push_back(" kMGTPEZY"[(Len - 1) / 3]); - return Result; -} - -void SourceCoverageView::StreamDestructor::operator()(raw_ostream *OS) const { +void CoveragePrinter::StreamDestructor::operator()(raw_ostream *OS) const { if (OS == &outs()) return; delete OS; } -/// \brief Create a file at ``Dir/ToplevelDir/@Path.Extension``. If -/// \p ToplevelDir is empty, its path component is skipped. -static Expected<SourceCoverageView::OwnedStream> -createFileInDirectory(StringRef Dir, StringRef ToplevelDir, StringRef Path, - StringRef Extension) { +std::string CoveragePrinter::getOutputPath(StringRef Path, StringRef Extension, + bool InToplevel) { assert(Extension.size() && "The file extension may not be empty"); - SmallString<256> FullPath(Dir); - if (!ToplevelDir.empty()) - sys::path::append(FullPath, ToplevelDir); + SmallString<256> FullPath(Opts.ShowOutputDirectory); + if (!InToplevel) + sys::path::append(FullPath, getCoverageDir()); auto PathBaseDir = sys::path::relative_path(sys::path::parent_path(Path)); sys::path::append(FullPath, PathBaseDir); - if (auto E = sys::fs::create_directories(FullPath)) - return errorCodeToError(E); - auto PathFilename = (sys::path::filename(Path) + "." + Extension).str(); sys::path::append(FullPath, PathFilename); - std::error_code E; - auto OS = SourceCoverageView::OwnedStream( - new raw_fd_ostream(FullPath, E, sys::fs::F_RW)); - if (E) - return errorCodeToError(E); - return std::move(OS); + return FullPath.str(); } -Expected<SourceCoverageView::OwnedStream> -SourceCoverageView::createOutputStream(const CoverageViewOptions &Opts, - StringRef Path, StringRef Extension, - bool InToplevel) { +Expected<CoveragePrinter::OwnedStream> +CoveragePrinter::createOutputStream(StringRef Path, StringRef Extension, + bool InToplevel) { if (!Opts.hasOutputDirectory()) return OwnedStream(&outs()); - return createFileInDirectory(Opts.ShowOutputDirectory, - InToplevel ? "" : "coverage", Path, Extension); + std::string FullPath = getOutputPath(Path, Extension, InToplevel); + + auto ParentDir = sys::path::parent_path(FullPath); + if (auto E = sys::fs::create_directories(ParentDir)) + return errorCodeToError(E); + + std::error_code E; + raw_ostream *RawStream = new raw_fd_ostream(FullPath, E, sys::fs::F_RW); + auto OS = CoveragePrinter::OwnedStream(RawStream); + if (E) + return errorCodeToError(E); + return std::move(OS); } -void SourceCoverageView::addExpansion( - const coverage::CounterMappingRegion &Region, - std::unique_ptr<SourceCoverageView> View) { - ExpansionSubViews.emplace_back(Region, std::move(View)); +std::unique_ptr<CoveragePrinter> +CoveragePrinter::create(const CoverageViewOptions &Opts) { + switch (Opts.Format) { + case CoverageViewOptions::OutputFormat::Text: + return llvm::make_unique<CoveragePrinterText>(Opts); + } } -void SourceCoverageView::addInstantiation( - StringRef FunctionName, unsigned Line, - std::unique_ptr<SourceCoverageView> View) { - InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View)); +std::string SourceCoverageView::formatCount(uint64_t N) { + std::string Number = utostr(N); + int Len = Number.size(); + if (Len <= 3) + return Number; + int IntLen = Len % 3 == 0 ? 3 : Len % 3; + std::string Result(Number.data(), IntLen); + if (IntLen != 3) { + Result.push_back('.'); + Result += Number.substr(IntLen, 3 - IntLen); + } + Result.push_back(" kMGTPEZY"[(Len - 1) / 3]); + return Result; } std::unique_ptr<SourceCoverageView> @@ -105,6 +99,18 @@ SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File, llvm_unreachable("Unknown coverage output format!"); } +void SourceCoverageView::addExpansion( + const coverage::CounterMappingRegion &Region, + std::unique_ptr<SourceCoverageView> View) { + ExpansionSubViews.emplace_back(Region, std::move(View)); +} + +void SourceCoverageView::addInstantiation( + StringRef FunctionName, unsigned Line, + std::unique_ptr<SourceCoverageView> View) { + InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View)); +} + void SourceCoverageView::print(raw_ostream &OS, bool WholeFile, bool ShowSourceName, unsigned ViewDepth) { if (ShowSourceName) |