[llvm] b2c32c9 - [llvm-cov gcov] Add -r (--relative-only) && -s (--source-prefix)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 13 14:54:43 PDT 2020
Author: Fangrui Song
Date: 2020-09-13T14:54:20-07:00
New Revision: b2c32c90bab09a6e2c1f370429db26017a182143
URL: https://github.com/llvm/llvm-project/commit/b2c32c90bab09a6e2c1f370429db26017a182143
DIFF: https://github.com/llvm/llvm-project/commit/b2c32c90bab09a6e2c1f370429db26017a182143.diff
LOG: [llvm-cov gcov] Add -r (--relative-only) && -s (--source-prefix)
gcov 4.7 introduced the two options.
https://sourceware.org/pipermail/gcc-patches/2011-November/328782.html
-r only dumps files with relative paths or absolute paths with the prefix
specified by -s. The two options are useful filtering out system header files.
Added:
llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda
llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno
llvm/test/tools/llvm-cov/gcov/relative-only.test
Modified:
llvm/include/llvm/ProfileData/GCOV.h
llvm/lib/ProfileData/GCOV.cpp
llvm/tools/llvm-cov/gcov.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h
index 3c6312f91674..56b512b6d606 100644
--- a/llvm/include/llvm/ProfileData/GCOV.h
+++ b/llvm/include/llvm/ProfileData/GCOV.h
@@ -48,10 +48,11 @@ enum GCOVVersion { V304, V407, V408, V800, V900 };
/// A struct for passing gcov options between functions.
struct Options {
Options(bool A, bool B, bool C, bool F, bool P, bool U, bool I, bool L,
- bool N, bool T, bool X)
+ bool N, bool R, bool T, bool X, std::string SourcePrefix)
: AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
PreservePaths(P), UncondBranch(U), Intermediate(I), LongFileNames(L),
- NoOutput(N), UseStdout(T), HashFilenames(X) {}
+ NoOutput(N), RelativeOnly(R), UseStdout(T), HashFilenames(X),
+ SourcePrefix(std::move(SourcePrefix)) {}
bool AllBlocks;
bool BranchInfo;
@@ -62,8 +63,10 @@ struct Options {
bool Intermediate;
bool LongFileNames;
bool NoOutput;
+ bool RelativeOnly;
bool UseStdout;
bool HashFilenames;
+ std::string SourcePrefix;
};
} // end namespace GCOV
@@ -341,9 +344,11 @@ struct GCOVCoverage {
struct SourceInfo {
StringRef filename;
+ SmallString<0> displayName;
std::string name;
std::vector<GCOVFunction *> functions;
GCOVCoverage coverage;
+ bool ignored = false;
SourceInfo(StringRef filename) : filename(filename) {}
};
diff --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index d4a4a8979e81..20118a0378b7 100644
--- a/llvm/lib/ProfileData/GCOV.cpp
+++ b/llvm/lib/ProfileData/GCOV.cpp
@@ -261,8 +261,24 @@ LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); }
/// reading .gcno and .gcda files.
void GCOVFile::collectLineCounts(FileInfo &fi) {
assert(fi.sources.empty());
- for (StringRef filename : filenames)
+ for (StringRef filename : filenames) {
fi.sources.emplace_back(filename);
+ SourceInfo &si = fi.sources.back();
+ si.displayName = si.filename;
+ if (!fi.Options.SourcePrefix.empty() &&
+ sys::path::replace_path_prefix(si.displayName, fi.Options.SourcePrefix,
+ "") &&
+ !si.displayName.empty()) {
+ // TODO replace_path_prefix may strip the prefix even if the remaining
+ // part does not start with a separator.
+ if (sys::path::is_separator(si.displayName[0]))
+ si.displayName.erase(si.displayName.begin());
+ else
+ si.displayName = si.filename;
+ }
+ if (fi.Options.RelativeOnly && sys::path::is_absolute(si.displayName))
+ si.ignored = true;
+ }
for (GCOVFunction &f : *this) {
f.collectLineCounts(fi);
fi.sources[f.srcIdx].functions.push_back(&f);
@@ -664,6 +680,10 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
llvm::sort(Filenames);
for (StringRef Filename : Filenames) {
+ SourceInfo &source = sources[file.filenameToIdx.find(Filename)->second];
+ if (source.ignored)
+ continue;
+
auto AllLines =
Options.Intermediate ? LineConsumer() : LineConsumer(Filename);
std::string CoveragePath = getCoveragePath(Filename, MainFilename);
@@ -675,7 +695,7 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
raw_ostream &CovOS =
!Options.NoOutput && Options.UseStdout ? llvm::outs() : *CovStream;
- CovOS << " -: 0:Source:" << Filename << "\n";
+ CovOS << " -: 0:Source:" << source.displayName << "\n";
CovOS << " -: 0:Graph:" << GCNOFile << "\n";
CovOS << " -: 0:Data:" << GCDAFile << "\n";
CovOS << " -: 0:Runs:" << RunCount << "\n";
@@ -683,7 +703,7 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
CovOS << " -: 0:Programs:" << ProgramCount << "\n";
const LineData &Line = LineInfo[Filename];
- GCOVCoverage FileCoverage(Filename);
+ GCOVCoverage FileCoverage(source.displayName);
for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
++LineIndex) {
if (Options.BranchInfo) {
@@ -767,7 +787,6 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
}
}
}
- SourceInfo &source = sources[file.filenameToIdx.find(Filename)->second];
source.name = CoveragePath;
source.coverage = FileCoverage;
}
@@ -928,6 +947,8 @@ void FileInfo::printFuncCoverage(raw_ostream &OS) const {
// printFileCoverage - Print per-file coverage info.
void FileInfo::printFileCoverage(raw_ostream &OS) const {
for (const SourceInfo &source : sources) {
+ if (source.ignored)
+ continue;
const GCOVCoverage &Coverage = source.coverage;
OS << "File '" << Coverage.Name << "'\n";
printCoverage(OS, Coverage);
diff --git a/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda
new file mode 100644
index 000000000000..806dc6a2aa0f
Binary files /dev/null and b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcda
diff er
diff --git a/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno
new file mode 100644
index 000000000000..1bd83064d67b
Binary files /dev/null and b/llvm/test/tools/llvm-cov/gcov/Inputs/abs-path.gcno
diff er
diff --git a/llvm/test/tools/llvm-cov/gcov/relative-only.test b/llvm/test/tools/llvm-cov/gcov/relative-only.test
new file mode 100644
index 000000000000..157441e7673f
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/gcov/relative-only.test
@@ -0,0 +1,37 @@
+# Test -r (--relative-only) and -s (--source-prefix).
+RUN: rm -rf %t && mkdir %t && cd %t
+RUN: cp %S/Inputs/abs-path.gcno %S/Inputs/abs-path.gcda .
+
+RUN: llvm-cov gcov abs-path.gcda | FileCheck %s
+RUN: rm abs-path.c.gcov a.h.gcov
+CHECK: File '/tmp/c/abs-path.c'
+CHECK: File '/tmp/h/a.h'
+
+# If there is no source file with a relative path, nothing is dumped.
+RUN: llvm-cov gcov -r abs-path.gcda 2>&1 | count 0
+RUN: llvm-cov gcov -r -s /t abs-path.gcda 2>&1 | count 0
+RUN: not ls abs-path.c.gcov 2> /dev/null
+
+# -s strips a prefix from filenames and can change filtering of -r.
+RUN: llvm-cov gcov -r -s /tmp abs-path.gcda | FileCheck %s --check-prefix=STRIP1 --match-full-lines --strict-whitespace
+RUN: FileCheck %s --check-prefix=STRIP1_C < abs-path.c.gcov
+RUN: FileCheck %s --check-prefix=STRIP1_H < a.h.gcov
+
+# Test full option names.
+RUN: llvm-cov gcov --relative-only --source-prefix=/tmp abs-path.gcda | FileCheck %s --check-prefix=STRIP1 --match-full-lines --strict-whitespace
+
+ STRIP1:File 'c/abs-path.c'
+ STRIP1-NEXT:Lines executed:100.00% of 1
+ STRIP1-NEXT:Creating 'abs-path.c.gcov'
+STRIP1-EMPTY:
+ STRIP1-NEXT:File 'h/a.h'
+ STRIP1-NEXT:Lines executed:0.00% of 1
+ STRIP1-NEXT:Creating 'a.h.gcov'
+
+STRIP1_C: 0:Source:c/abs-path.c
+STRIP1_H: 0:Source:h/a.h
+
+RUN: llvm-cov gcov -r -s /tmp/h abs-path.gcda | FileCheck %s --check-prefix=STRIP2
+
+STRIP2-NOT: File
+STRIP2: File 'a.h'
diff --git a/llvm/tools/llvm-cov/gcov.cpp b/llvm/tools/llvm-cov/gcov.cpp
index d99e792c68a9..858f4cee7904 100644
--- a/llvm/tools/llvm-cov/gcov.cpp
+++ b/llvm/tools/llvm-cov/gcov.cpp
@@ -131,6 +131,14 @@ int gcovMain(int argc, const char *argv[]) {
cl::desc("Preserve path components"));
cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths));
+ cl::opt<bool> RelativeOnly(
+ "r", cl::Grouping,
+ cl::desc("Only dump files with relative paths or absolute paths with the "
+ "prefix specified by -s"));
+ cl::alias RelativeOnlyA("relative-only", cl::aliasopt(RelativeOnly));
+ cl::opt<std::string> SourcePrefix("s", cl::desc("Source prefix to elide"));
+ cl::alias SourcePrefixA("source-prefix", cl::aliasopt(SourcePrefix));
+
cl::opt<bool> UseStdout("t", cl::Grouping, cl::init(false),
cl::desc("Print to stdout"));
cl::alias UseStdoutA("stdout", cl::aliasopt(UseStdout));
@@ -157,7 +165,8 @@ int gcovMain(int argc, const char *argv[]) {
GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
PreservePaths, UncondBranch, Intermediate, LongNames,
- NoOutput, UseStdout, HashFilenames);
+ NoOutput, RelativeOnly, UseStdout, HashFilenames,
+ SourcePrefix);
for (const auto &SourceFile : SourceFiles)
reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,
More information about the llvm-commits
mailing list