forked from OSchip/llvm-project
llvm-cov: Added -f option for function summaries.
Similar to the file summaries, the function summaries output line, branching and call statistics. The file summaries have been moved outside the initial loop so that all of the function summaries can be outputted before file summaries. Also updated test cases. llvm-svn: 197633
This commit is contained in:
parent
23f2fcaed8
commit
bb6a477131
|
@ -16,6 +16,7 @@
|
||||||
#define LLVM_SUPPORT_GCOV_H
|
#define LLVM_SUPPORT_GCOV_H
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/MapVector.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
|
@ -36,12 +37,14 @@ namespace GCOV {
|
||||||
|
|
||||||
/// GCOVOptions - A struct for passing gcov options between functions.
|
/// GCOVOptions - A struct for passing gcov options between functions.
|
||||||
struct GCOVOptions {
|
struct GCOVOptions {
|
||||||
GCOVOptions(bool A, bool B, bool C, bool U) :
|
GCOVOptions(bool A, bool B, bool C, bool F, bool U) :
|
||||||
AllBlocks(A), BranchInfo(B), BranchCount(C), UncondBranch(U) {}
|
AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), UncondBranch(U)
|
||||||
|
{}
|
||||||
|
|
||||||
bool AllBlocks;
|
bool AllBlocks;
|
||||||
bool BranchInfo;
|
bool BranchInfo;
|
||||||
bool BranchCount;
|
bool BranchCount;
|
||||||
|
bool FuncCoverage;
|
||||||
bool UncondBranch;
|
bool UncondBranch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -300,6 +303,7 @@ public:
|
||||||
GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
|
GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
|
||||||
DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
|
DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
|
||||||
~GCOVBlock();
|
~GCOVBlock();
|
||||||
|
const GCOVFunction &getParent() const { return Parent; }
|
||||||
void addLine(uint32_t N) { Lines.push_back(N); }
|
void addLine(uint32_t N) { Lines.push_back(N); }
|
||||||
uint32_t getLastLine() const { return Lines.back(); }
|
uint32_t getLastLine() const { return Lines.back(); }
|
||||||
void addCount(size_t DstEdgeNo, uint64_t N);
|
void addCount(size_t DstEdgeNo, uint64_t N);
|
||||||
|
@ -352,10 +356,12 @@ class FileInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GCOVCoverage {
|
struct GCOVCoverage {
|
||||||
GCOVCoverage() :
|
GCOVCoverage(StringRef Name) :
|
||||||
LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
|
Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
|
||||||
BranchesTaken(0) {}
|
BranchesTaken(0) {}
|
||||||
|
|
||||||
|
StringRef Name;
|
||||||
|
|
||||||
uint32_t LogicalLines;
|
uint32_t LogicalLines;
|
||||||
uint32_t LinesExec;
|
uint32_t LinesExec;
|
||||||
|
|
||||||
|
@ -376,22 +382,27 @@ public:
|
||||||
}
|
}
|
||||||
void setRunCount(uint32_t Runs) { RunCount = Runs; }
|
void setRunCount(uint32_t Runs) { RunCount = Runs; }
|
||||||
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
|
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
|
||||||
void print(StringRef GCNOFile, StringRef GCDAFile) const;
|
void print(StringRef GCNOFile, StringRef GCDAFile);
|
||||||
private:
|
private:
|
||||||
void printFunctionSummary(raw_fd_ostream &OS,
|
void printFunctionSummary(raw_fd_ostream &OS,
|
||||||
const FunctionVector &Funcs) const;
|
const FunctionVector &Funcs) const;
|
||||||
void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
||||||
uint32_t LineIndex, uint32_t &BlockNo) const;
|
uint32_t LineIndex, uint32_t &BlockNo) const;
|
||||||
void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
||||||
GCOVCoverage &Coverage, uint32_t &EdgeNo) const;
|
GCOVCoverage &Coverage, uint32_t &EdgeNo);
|
||||||
void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
|
void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
|
||||||
uint64_t Count) const;
|
uint64_t Count) const;
|
||||||
void printFileCoverage(StringRef Filename, GCOVCoverage &Coverage) const;
|
|
||||||
|
void printCoverage(const GCOVCoverage &Coverage) const;
|
||||||
|
void printFuncCoverage() const;
|
||||||
|
void printFileCoverage() const;
|
||||||
|
|
||||||
const GCOVOptions &Options;
|
const GCOVOptions &Options;
|
||||||
StringMap<LineData> LineInfo;
|
StringMap<LineData> LineInfo;
|
||||||
uint32_t RunCount;
|
uint32_t RunCount;
|
||||||
uint32_t ProgramCount;
|
uint32_t ProgramCount;
|
||||||
|
SmallVector<GCOVCoverage, 4> FileCoverages;
|
||||||
|
MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverages;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,7 +430,7 @@ static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// print - Print source files with collected line count information.
|
/// print - Print source files with collected line count information.
|
||||||
void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
|
void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) {
|
||||||
for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
|
for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
|
||||||
E = LineInfo.end(); I != E; ++I) {
|
E = LineInfo.end(); I != E; ++I) {
|
||||||
StringRef Filename = I->first();
|
StringRef Filename = I->first();
|
||||||
|
@ -454,7 +454,7 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
|
||||||
OS << " -: 0:Programs:" << ProgramCount << "\n";
|
OS << " -: 0:Programs:" << ProgramCount << "\n";
|
||||||
|
|
||||||
const LineData &Line = I->second;
|
const LineData &Line = I->second;
|
||||||
GCOVCoverage Coverage;
|
GCOVCoverage FileCoverage(Filename);
|
||||||
for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
|
for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
|
||||||
if (Options.BranchInfo) {
|
if (Options.BranchInfo) {
|
||||||
FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
|
FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
|
||||||
|
@ -473,6 +473,7 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
|
||||||
const BlockVector &Blocks = BlocksIt->second;
|
const BlockVector &Blocks = BlocksIt->second;
|
||||||
|
|
||||||
// Add up the block counts to form line counts.
|
// Add up the block counts to form line counts.
|
||||||
|
DenseMap<const GCOVFunction *, bool> LineExecs;
|
||||||
uint64_t LineCount = 0;
|
uint64_t LineCount = 0;
|
||||||
for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
|
for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
|
@ -485,15 +486,49 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
|
||||||
// Sum up all of the block counts.
|
// Sum up all of the block counts.
|
||||||
LineCount += Block->getCount();
|
LineCount += Block->getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Options.FuncCoverage) {
|
||||||
|
// This is a slightly convoluted way to most accurately gather line
|
||||||
|
// statistics for functions. Basically what is happening is that we
|
||||||
|
// don't want to count a single line with multiple blocks more than
|
||||||
|
// once. However, we also don't simply want to give the total line
|
||||||
|
// count to every function that starts on the line. Thus, what is
|
||||||
|
// happening here are two things:
|
||||||
|
// 1) Ensure that the number of logical lines is only incremented
|
||||||
|
// once per function.
|
||||||
|
// 2) If there are multiple blocks on the same line, ensure that the
|
||||||
|
// number of lines executed is incremented as long as at least
|
||||||
|
// one of the blocks are executed.
|
||||||
|
const GCOVFunction *Function = &Block->getParent();
|
||||||
|
if (FuncCoverages.find(Function) == FuncCoverages.end()) {
|
||||||
|
std::pair<const GCOVFunction *, GCOVCoverage>
|
||||||
|
KeyValue(Function, GCOVCoverage(Function->getName()));
|
||||||
|
FuncCoverages.insert(KeyValue);
|
||||||
|
}
|
||||||
|
GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
|
||||||
|
|
||||||
|
if (LineExecs.find(Function) == LineExecs.end()) {
|
||||||
|
if (Block->getCount()) {
|
||||||
|
++FuncCoverage.LinesExec;
|
||||||
|
LineExecs[Function] = true;
|
||||||
|
} else {
|
||||||
|
LineExecs[Function] = false;
|
||||||
|
}
|
||||||
|
++FuncCoverage.LogicalLines;
|
||||||
|
} else if (!LineExecs[Function] && Block->getCount()) {
|
||||||
|
++FuncCoverage.LinesExec;
|
||||||
|
LineExecs[Function] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LineCount == 0)
|
if (LineCount == 0)
|
||||||
OS << " #####:";
|
OS << " #####:";
|
||||||
else {
|
else {
|
||||||
OS << format("%9" PRIu64 ":", LineCount);
|
OS << format("%9" PRIu64 ":", LineCount);
|
||||||
++Coverage.LinesExec;
|
++FileCoverage.LinesExec;
|
||||||
}
|
}
|
||||||
++Coverage.LogicalLines;
|
++FileCoverage.LogicalLines;
|
||||||
|
|
||||||
std::pair<StringRef, StringRef> P = AllLines.split('\n');
|
std::pair<StringRef, StringRef> P = AllLines.split('\n');
|
||||||
OS << format("%5u:", LineIndex+1) << P.first << "\n";
|
OS << format("%5u:", LineIndex+1) << P.first << "\n";
|
||||||
|
@ -513,17 +548,20 @@ void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
|
||||||
if (Options.BranchInfo) {
|
if (Options.BranchInfo) {
|
||||||
size_t NumEdges = Block->getNumDstEdges();
|
size_t NumEdges = Block->getNumDstEdges();
|
||||||
if (NumEdges > 1)
|
if (NumEdges > 1)
|
||||||
printBranchInfo(OS, *Block, Coverage, EdgeNo);
|
printBranchInfo(OS, *Block, FileCoverage, EdgeNo);
|
||||||
else if (Options.UncondBranch && NumEdges == 1)
|
else if (Options.UncondBranch && NumEdges == 1)
|
||||||
printUncondBranchInfo(OS, EdgeNo, (*Block->dst_begin())->Count);
|
printUncondBranchInfo(OS, EdgeNo, (*Block->dst_begin())->Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FileCoverages.push_back(FileCoverage);
|
||||||
// FIXME: There is no way to detect calls given current instrumentation.
|
|
||||||
printFileCoverage(Filename, Coverage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: There is no way to detect calls given current instrumentation.
|
||||||
|
if (Options.FuncCoverage)
|
||||||
|
printFuncCoverage();
|
||||||
|
printFileCoverage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// printFunctionSummary - Print function and block summary.
|
/// printFunctionSummary - Print function and block summary.
|
||||||
|
@ -560,7 +598,7 @@ void FileInfo::printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
||||||
|
|
||||||
/// printBranchInfo - Print conditional branch probabilities.
|
/// printBranchInfo - Print conditional branch probabilities.
|
||||||
void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
||||||
GCOVCoverage &Coverage, uint32_t &EdgeNo) const {
|
GCOVCoverage &Coverage, uint32_t &EdgeNo) {
|
||||||
SmallVector<uint64_t, 16> BranchCounts;
|
SmallVector<uint64_t, 16> BranchCounts;
|
||||||
uint64_t TotalCounts = 0;
|
uint64_t TotalCounts = 0;
|
||||||
for (GCOVBlock::EdgeIterator I = Block.dst_begin(), E = Block.dst_end();
|
for (GCOVBlock::EdgeIterator I = Block.dst_begin(), E = Block.dst_end();
|
||||||
|
@ -571,6 +609,14 @@ void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
|
||||||
if (Block.getCount()) ++Coverage.BranchesExec;
|
if (Block.getCount()) ++Coverage.BranchesExec;
|
||||||
if (Edge->Count) ++Coverage.BranchesTaken;
|
if (Edge->Count) ++Coverage.BranchesTaken;
|
||||||
++Coverage.Branches;
|
++Coverage.Branches;
|
||||||
|
|
||||||
|
if (Options.FuncCoverage) {
|
||||||
|
const GCOVFunction *Function = &Block.getParent();
|
||||||
|
GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
|
||||||
|
if (Block.getCount()) ++FuncCoverage.BranchesExec;
|
||||||
|
if (Edge->Count) ++FuncCoverage.BranchesTaken;
|
||||||
|
++FuncCoverage.Branches;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SmallVectorImpl<uint64_t>::const_iterator I = BranchCounts.begin(),
|
for (SmallVectorImpl<uint64_t>::const_iterator I = BranchCounts.begin(),
|
||||||
|
@ -587,10 +633,9 @@ void FileInfo::printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
|
||||||
<< formatBranchInfo(Options, Count, Count) << "\n";
|
<< formatBranchInfo(Options, Count, Count) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// printFileCoverage - Print per-file coverage info.
|
// printCoverage - Print generic coverage info used by both printFuncCoverage
|
||||||
void FileInfo::printFileCoverage(StringRef Filename,
|
// and printFileCoverage.
|
||||||
GCOVCoverage &Coverage) const {
|
void FileInfo::printCoverage(const GCOVCoverage &Coverage) const {
|
||||||
outs() << "File '" << Filename << "'\n";
|
|
||||||
outs() << format("Lines executed:%.2lf%% of %u\n",
|
outs() << format("Lines executed:%.2lf%% of %u\n",
|
||||||
double(Coverage.LinesExec)*100/Coverage.LogicalLines,
|
double(Coverage.LinesExec)*100/Coverage.LogicalLines,
|
||||||
Coverage.LogicalLines);
|
Coverage.LogicalLines);
|
||||||
|
@ -607,6 +652,27 @@ void FileInfo::printFileCoverage(StringRef Filename,
|
||||||
}
|
}
|
||||||
outs() << "No calls\n"; // to be consistent with gcov
|
outs() << "No calls\n"; // to be consistent with gcov
|
||||||
}
|
}
|
||||||
outs() << Filename << ":creating '" << Filename << ".gcov'\n";
|
}
|
||||||
outs() << "\n";
|
|
||||||
|
// printFuncCoverage - Print per-function coverage info.
|
||||||
|
void FileInfo::printFuncCoverage() const {
|
||||||
|
for (MapVector<const GCOVFunction *, GCOVCoverage>::const_iterator I =
|
||||||
|
FuncCoverages.begin(), E = FuncCoverages.end(); I != E; ++I) {
|
||||||
|
const GCOVCoverage &Coverage = I->second;
|
||||||
|
outs() << "Function '" << Coverage.Name << "'\n";
|
||||||
|
printCoverage(Coverage);
|
||||||
|
outs() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// printFileCoverage - Print per-file coverage info.
|
||||||
|
void FileInfo::printFileCoverage() const {
|
||||||
|
for (SmallVectorImpl<GCOVCoverage>::const_iterator I =
|
||||||
|
FileCoverages.begin(), E = FileCoverages.end(); I != E; ++I) {
|
||||||
|
const GCOVCoverage &Coverage = *I;
|
||||||
|
outs() << "File '" << Coverage.Name << "'\n";
|
||||||
|
printCoverage(Coverage);
|
||||||
|
outs() << Coverage.Name << ":creating '" << Coverage.Name
|
||||||
|
<< ".gcov'\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
Function '_ZN1A1BEv'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_Z7uselessv'
|
||||||
|
Lines executed:0.00% of 1
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_Z12more_uselessv'
|
||||||
|
Lines executed:0.00% of 1
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_Z3foov'
|
||||||
|
Lines executed:100.00% of 2
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_Z3barv'
|
||||||
|
Lines executed:0.00% of 2
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_Z6assignii'
|
||||||
|
Lines executed:100.00% of 3
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_Z15initialize_gridv'
|
||||||
|
Lines executed:100.00% of 4
|
||||||
|
Branches executed:100.00% of 4
|
||||||
|
Taken at least once:100.00% of 4
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function 'main'
|
||||||
|
Lines executed:91.67% of 24
|
||||||
|
Branches executed:100.00% of 11
|
||||||
|
Taken at least once:81.82% of 11
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_ZN1AC1Ev'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
Function '_ZN1AC2Ev'
|
||||||
|
No executable lines
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
|
||||||
|
File 'test.cpp'
|
||||||
|
Lines executed:84.21% of 38
|
||||||
|
Branches executed:100.00% of 15
|
||||||
|
Taken at least once:86.67% of 15
|
||||||
|
No calls
|
||||||
|
test.cpp:creating 'test.cpp.gcov'
|
||||||
|
|
||||||
|
File './test.h'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
No branches
|
||||||
|
No calls
|
||||||
|
./test.h:creating 'test.h.gcov'
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
Function '_ZN1A1BEv'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
|
||||||
|
Function '_Z7uselessv'
|
||||||
|
Lines executed:0.00% of 1
|
||||||
|
|
||||||
|
Function '_Z12more_uselessv'
|
||||||
|
Lines executed:0.00% of 1
|
||||||
|
|
||||||
|
Function '_Z3foov'
|
||||||
|
Lines executed:100.00% of 2
|
||||||
|
|
||||||
|
Function '_Z3barv'
|
||||||
|
Lines executed:0.00% of 2
|
||||||
|
|
||||||
|
Function '_Z6assignii'
|
||||||
|
Lines executed:100.00% of 3
|
||||||
|
|
||||||
|
Function '_Z15initialize_gridv'
|
||||||
|
Lines executed:100.00% of 4
|
||||||
|
|
||||||
|
Function 'main'
|
||||||
|
Lines executed:91.67% of 24
|
||||||
|
|
||||||
|
Function '_ZN1AC1Ev'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
|
||||||
|
Function '_ZN1AC2Ev'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
|
||||||
|
File 'test.cpp'
|
||||||
|
Lines executed:84.21% of 38
|
||||||
|
test.cpp:creating 'test.cpp.gcov'
|
||||||
|
|
||||||
|
File './test.h'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
./test.h:creating './test.h.gcov'
|
||||||
|
|
|
@ -6,6 +6,7 @@ RUN: cd %t
|
||||||
RUN: cp %p/Inputs/test* .
|
RUN: cp %p/Inputs/test* .
|
||||||
|
|
||||||
RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda | diff test_no_options.output -
|
RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda | diff test_no_options.output -
|
||||||
|
RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -f | diff test_-f.output -
|
||||||
RUN: diff -aub test_no_options.cpp.gcov test.cpp.gcov
|
RUN: diff -aub test_no_options.cpp.gcov test.cpp.gcov
|
||||||
RUN: diff -aub test_no_options.h.gcov test.h.gcov
|
RUN: diff -aub test_no_options.h.gcov test.h.gcov
|
||||||
|
|
||||||
|
@ -14,6 +15,9 @@ RUN: diff -aub test_-a.cpp.gcov test.cpp.gcov
|
||||||
RUN: diff -aub test_-a.h.gcov test.h.gcov
|
RUN: diff -aub test_-a.h.gcov test.h.gcov
|
||||||
|
|
||||||
RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -a -b | diff test_-b.output -
|
RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -a -b | diff test_-b.output -
|
||||||
|
# This is expected to fail because gcov doesn't actually output real branch or
|
||||||
|
# call statistics on a per function basis.
|
||||||
|
RUN: llvm-cov -gcno=test.gcno -gcda=test.gcda -a -b -f | not diff test_-b_-f.output -
|
||||||
RUN: diff -aub test_-a_-b.cpp.gcov test.cpp.gcov
|
RUN: diff -aub test_-a_-b.cpp.gcov test.cpp.gcov
|
||||||
RUN: diff -aub test_-a_-b.h.gcov test.h.gcov
|
RUN: diff -aub test_-a_-b.h.gcov test.h.gcov
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,9 @@ static cl::opt<bool>
|
||||||
BranchCount("c", cl::init(false), cl::desc("display branch counts instead of \
|
BranchCount("c", cl::init(false), cl::desc("display branch counts instead of \
|
||||||
probabilities (requires -b)"));
|
probabilities (requires -b)"));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
FuncCoverage("f", cl::init(false), cl::desc("output function coverage"));
|
||||||
|
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
UncondBranch("u", cl::init(false), cl::desc("display unconditional branch info \
|
UncondBranch("u", cl::init(false), cl::desc("display unconditional branch info \
|
||||||
(requires -b)"));
|
(requires -b)"));
|
||||||
|
@ -84,7 +87,8 @@ int main(int argc, char **argv) {
|
||||||
if (DumpGCOV)
|
if (DumpGCOV)
|
||||||
GF.dump();
|
GF.dump();
|
||||||
|
|
||||||
GCOVOptions Options(AllBlocks, BranchInfo, BranchCount, UncondBranch);
|
GCOVOptions Options(AllBlocks, BranchInfo, BranchCount, FuncCoverage,
|
||||||
|
UncondBranch);
|
||||||
FileInfo FI(Options);
|
FileInfo FI(Options);
|
||||||
GF.collectLineCounts(FI);
|
GF.collectLineCounts(FI);
|
||||||
FI.print(InputGCNO, InputGCDA);
|
FI.print(InputGCNO, InputGCDA);
|
||||||
|
|
Loading…
Reference in New Issue