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.
|
||||
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) {}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
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::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,
|
||||
|
|
Loading…
Reference in New Issue