[llvm-cov] Create an index of reports in -output-dir mode
This index lists the reports available in the 'coverage' sub-directory.
This will help navigate coverage output from large projects.
This commit factors the file creation code out of SourceCoverageView and
into CoveragePrinter.
llvm-svn: 274029
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp
index d6de961..6b7f50f 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp
@@ -21,6 +21,57 @@
using namespace llvm;
+void CoveragePrinter::StreamDestructor::operator()(raw_ostream *OS) const {
+ if (OS == &outs())
+ return;
+ delete OS;
+}
+
+std::string CoveragePrinter::getOutputPath(StringRef Path, StringRef Extension,
+ bool InToplevel) {
+ assert(Extension.size() && "The file extension may not be empty");
+
+ 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);
+
+ auto PathFilename = (sys::path::filename(Path) + "." + Extension).str();
+ sys::path::append(FullPath, PathFilename);
+
+ return FullPath.str();
+}
+
+Expected<CoveragePrinter::OwnedStream>
+CoveragePrinter::createOutputStream(StringRef Path, StringRef Extension,
+ bool InToplevel) {
+ if (!Opts.hasOutputDirectory())
+ return OwnedStream(&outs());
+
+ 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);
+}
+
+std::unique_ptr<CoveragePrinter>
+CoveragePrinter::create(const CoverageViewOptions &Opts) {
+ switch (Opts.Format) {
+ case CoverageViewOptions::OutputFormat::Text:
+ return llvm::make_unique<CoveragePrinterText>(Opts);
+ }
+}
+
std::string SourceCoverageView::formatCount(uint64_t N) {
std::string Number = utostr(N);
int Len = Number.size();
@@ -36,49 +87,16 @@
return Result;
}
-void SourceCoverageView::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) {
- assert(Extension.size() && "The file extension may not be empty");
-
- SmallString<256> FullPath(Dir);
- if (!ToplevelDir.empty())
- sys::path::append(FullPath, ToplevelDir);
-
- 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);
-}
-
-Expected<SourceCoverageView::OwnedStream>
-SourceCoverageView::createOutputStream(const CoverageViewOptions &Opts,
- StringRef Path, StringRef Extension,
- bool InToplevel) {
- if (!Opts.hasOutputDirectory())
- return OwnedStream(&outs());
-
- return createFileInDirectory(Opts.ShowOutputDirectory,
- InToplevel ? "" : "coverage", Path, Extension);
+std::unique_ptr<SourceCoverageView>
+SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File,
+ const CoverageViewOptions &Options,
+ coverage::CoverageData &&CoverageInfo) {
+ switch (Options.Format) {
+ case CoverageViewOptions::OutputFormat::Text:
+ return llvm::make_unique<SourceCoverageViewText>(SourceName, File, Options,
+ std::move(CoverageInfo));
+ }
+ llvm_unreachable("Unknown coverage output format!");
}
void SourceCoverageView::addExpansion(
@@ -93,18 +111,6 @@
InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View));
}
-std::unique_ptr<SourceCoverageView>
-SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File,
- const CoverageViewOptions &Options,
- coverage::CoverageData &&CoverageInfo) {
- switch (Options.Format) {
- case CoverageViewOptions::OutputFormat::Text:
- return llvm::make_unique<SourceCoverageViewText>(SourceName, File, Options,
- std::move(CoverageInfo));
- }
- llvm_unreachable("Unknown coverage output format!");
-}
-
void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
bool ShowSourceName, unsigned ViewDepth) {
if (ShowSourceName)