forked from OSchip/llvm-project
[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.
This commit is contained in:
parent
cb3e1dd6c3
commit
b2c32c90ba
|
@ -48,10 +48,11 @@ enum GCOVVersion { V304, V407, V408, V800, V900 };
|
||||||
/// A struct for passing gcov options between functions.
|
/// A struct for passing gcov options between functions.
|
||||||
struct Options {
|
struct Options {
|
||||||
Options(bool A, bool B, bool C, bool F, bool P, bool U, bool I, bool L,
|
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),
|
: AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
|
||||||
PreservePaths(P), UncondBranch(U), Intermediate(I), LongFileNames(L),
|
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 AllBlocks;
|
||||||
bool BranchInfo;
|
bool BranchInfo;
|
||||||
|
@ -62,8 +63,10 @@ struct Options {
|
||||||
bool Intermediate;
|
bool Intermediate;
|
||||||
bool LongFileNames;
|
bool LongFileNames;
|
||||||
bool NoOutput;
|
bool NoOutput;
|
||||||
|
bool RelativeOnly;
|
||||||
bool UseStdout;
|
bool UseStdout;
|
||||||
bool HashFilenames;
|
bool HashFilenames;
|
||||||
|
std::string SourcePrefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace GCOV
|
} // end namespace GCOV
|
||||||
|
@ -341,9 +344,11 @@ struct GCOVCoverage {
|
||||||
|
|
||||||
struct SourceInfo {
|
struct SourceInfo {
|
||||||
StringRef filename;
|
StringRef filename;
|
||||||
|
SmallString<0> displayName;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<GCOVFunction *> functions;
|
std::vector<GCOVFunction *> functions;
|
||||||
GCOVCoverage coverage;
|
GCOVCoverage coverage;
|
||||||
|
bool ignored = false;
|
||||||
SourceInfo(StringRef filename) : filename(filename) {}
|
SourceInfo(StringRef filename) : filename(filename) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -261,8 +261,24 @@ LLVM_DUMP_METHOD void GCOVFile::dump() const { print(dbgs()); }
|
||||||
/// reading .gcno and .gcda files.
|
/// reading .gcno and .gcda files.
|
||||||
void GCOVFile::collectLineCounts(FileInfo &fi) {
|
void GCOVFile::collectLineCounts(FileInfo &fi) {
|
||||||
assert(fi.sources.empty());
|
assert(fi.sources.empty());
|
||||||
for (StringRef filename : filenames)
|
for (StringRef filename : filenames) {
|
||||||
fi.sources.emplace_back(filename);
|
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) {
|
for (GCOVFunction &f : *this) {
|
||||||
f.collectLineCounts(fi);
|
f.collectLineCounts(fi);
|
||||||
fi.sources[f.srcIdx].functions.push_back(&f);
|
fi.sources[f.srcIdx].functions.push_back(&f);
|
||||||
|
@ -664,6 +680,10 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
|
||||||
llvm::sort(Filenames);
|
llvm::sort(Filenames);
|
||||||
|
|
||||||
for (StringRef Filename : Filenames) {
|
for (StringRef Filename : Filenames) {
|
||||||
|
SourceInfo &source = sources[file.filenameToIdx.find(Filename)->second];
|
||||||
|
if (source.ignored)
|
||||||
|
continue;
|
||||||
|
|
||||||
auto AllLines =
|
auto AllLines =
|
||||||
Options.Intermediate ? LineConsumer() : LineConsumer(Filename);
|
Options.Intermediate ? LineConsumer() : LineConsumer(Filename);
|
||||||
std::string CoveragePath = getCoveragePath(Filename, MainFilename);
|
std::string CoveragePath = getCoveragePath(Filename, MainFilename);
|
||||||
|
@ -675,7 +695,7 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
|
||||||
raw_ostream &CovOS =
|
raw_ostream &CovOS =
|
||||||
!Options.NoOutput && Options.UseStdout ? llvm::outs() : *CovStream;
|
!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:Graph:" << GCNOFile << "\n";
|
||||||
CovOS << " -: 0:Data:" << GCDAFile << "\n";
|
CovOS << " -: 0:Data:" << GCDAFile << "\n";
|
||||||
CovOS << " -: 0:Runs:" << RunCount << "\n";
|
CovOS << " -: 0:Runs:" << RunCount << "\n";
|
||||||
|
@ -683,7 +703,7 @@ void FileInfo::print(raw_ostream &InfoOS, StringRef MainFilename,
|
||||||
CovOS << " -: 0:Programs:" << ProgramCount << "\n";
|
CovOS << " -: 0:Programs:" << ProgramCount << "\n";
|
||||||
|
|
||||||
const LineData &Line = LineInfo[Filename];
|
const LineData &Line = LineInfo[Filename];
|
||||||
GCOVCoverage FileCoverage(Filename);
|
GCOVCoverage FileCoverage(source.displayName);
|
||||||
for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
|
for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
|
||||||
++LineIndex) {
|
++LineIndex) {
|
||||||
if (Options.BranchInfo) {
|
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.name = CoveragePath;
|
||||||
source.coverage = FileCoverage;
|
source.coverage = FileCoverage;
|
||||||
}
|
}
|
||||||
|
@ -928,6 +947,8 @@ void FileInfo::printFuncCoverage(raw_ostream &OS) const {
|
||||||
// printFileCoverage - Print per-file coverage info.
|
// printFileCoverage - Print per-file coverage info.
|
||||||
void FileInfo::printFileCoverage(raw_ostream &OS) const {
|
void FileInfo::printFileCoverage(raw_ostream &OS) const {
|
||||||
for (const SourceInfo &source : sources) {
|
for (const SourceInfo &source : sources) {
|
||||||
|
if (source.ignored)
|
||||||
|
continue;
|
||||||
const GCOVCoverage &Coverage = source.coverage;
|
const GCOVCoverage &Coverage = source.coverage;
|
||||||
OS << "File '" << Coverage.Name << "'\n";
|
OS << "File '" << Coverage.Name << "'\n";
|
||||||
printCoverage(OS, Coverage);
|
printCoverage(OS, Coverage);
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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'
|
|
@ -131,6 +131,14 @@ int gcovMain(int argc, const char *argv[]) {
|
||||||
cl::desc("Preserve path components"));
|
cl::desc("Preserve path components"));
|
||||||
cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths));
|
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::opt<bool> UseStdout("t", cl::Grouping, cl::init(false),
|
||||||
cl::desc("Print to stdout"));
|
cl::desc("Print to stdout"));
|
||||||
cl::alias UseStdoutA("stdout", cl::aliasopt(UseStdout));
|
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,
|
GCOV::Options Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
|
||||||
PreservePaths, UncondBranch, Intermediate, LongNames,
|
PreservePaths, UncondBranch, Intermediate, LongNames,
|
||||||
NoOutput, UseStdout, HashFilenames);
|
NoOutput, RelativeOnly, UseStdout, HashFilenames,
|
||||||
|
SourcePrefix);
|
||||||
|
|
||||||
for (const auto &SourceFile : SourceFiles)
|
for (const auto &SourceFile : SourceFiles)
|
||||||
reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,
|
reportCoverage(SourceFile, ObjectDir, InputGCNO, InputGCDA, DumpGCOV,
|
||||||
|
|
Loading…
Reference in New Issue