mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
llvm-cov: Handle missing source files as GCOV does
If the source files referenced by a gcno file are missing, gcov outputs a coverage file where every line is simply /*EOF*/. This also occurs for lines in the coverage that are past the end of a file that is found. This change mimics gcov. llvm-svn: 208149
This commit is contained in:
parent
b8e01630df
commit
d56b21803f
@ -356,8 +356,10 @@ class FileInfo {
|
|||||||
typedef DenseMap<uint32_t, BlockVector> BlockLines;
|
typedef DenseMap<uint32_t, BlockVector> BlockLines;
|
||||||
|
|
||||||
struct LineData {
|
struct LineData {
|
||||||
|
LineData() : LastLine(0) {}
|
||||||
BlockLines Blocks;
|
BlockLines Blocks;
|
||||||
FunctionLines Functions;
|
FunctionLines Functions;
|
||||||
|
uint32_t LastLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GCOVCoverage {
|
struct GCOVCoverage {
|
||||||
@ -379,11 +381,15 @@ public:
|
|||||||
Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
|
Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
|
||||||
|
|
||||||
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
|
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
|
||||||
|
if (Line > LineInfo[Filename].LastLine)
|
||||||
|
LineInfo[Filename].LastLine = Line;
|
||||||
LineInfo[Filename].Blocks[Line-1].push_back(Block);
|
LineInfo[Filename].Blocks[Line-1].push_back(Block);
|
||||||
}
|
}
|
||||||
void addFunctionLine(StringRef Filename, uint32_t Line,
|
void addFunctionLine(StringRef Filename, uint32_t Line,
|
||||||
const GCOVFunction *Function) {
|
const GCOVFunction *Function) {
|
||||||
LineInfo[Filename].Functions[Line-1].push_back(Function);
|
if (Line > LineInfo[Filename].LastLine)
|
||||||
|
LineInfo[Filename].LastLine = Line;
|
||||||
|
LineInfo[Filename].Functions[Line-1].push_back(Function);
|
||||||
}
|
}
|
||||||
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; }
|
||||||
|
@ -432,6 +432,30 @@ static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) {
|
|||||||
return OS;
|
return OS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class LineConsumer {
|
||||||
|
std::unique_ptr<MemoryBuffer> Buffer;
|
||||||
|
StringRef Remaining;
|
||||||
|
public:
|
||||||
|
LineConsumer(StringRef Filename) {
|
||||||
|
if (error_code EC = MemoryBuffer::getFileOrSTDIN(Filename, Buffer)) {
|
||||||
|
errs() << Filename << ": " << EC.message() << "\n";
|
||||||
|
Remaining = "";
|
||||||
|
} else
|
||||||
|
Remaining = Buffer->getBuffer();
|
||||||
|
}
|
||||||
|
bool empty() { return Remaining.empty(); }
|
||||||
|
void printNext(raw_ostream &OS, uint32_t LineNum) {
|
||||||
|
StringRef Line;
|
||||||
|
if (empty())
|
||||||
|
Line = "/*EOF*/";
|
||||||
|
else
|
||||||
|
std::tie(Line, Remaining) = Remaining.split("\n");
|
||||||
|
OS << format("%5u:", LineNum) << Line << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert a path to a gcov filename. If PreservePaths is true, this
|
/// Convert a path to a gcov filename. If PreservePaths is true, this
|
||||||
/// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
|
/// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
|
||||||
static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
|
static std::string mangleCoveragePath(StringRef Filename, bool PreservePaths) {
|
||||||
@ -505,12 +529,7 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
|||||||
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();
|
||||||
std::unique_ptr<MemoryBuffer> Buff;
|
auto AllLines = LineConsumer(Filename);
|
||||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
|
|
||||||
errs() << Filename << ": " << ec.message() << "\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
StringRef AllLines = Buff->getBuffer();
|
|
||||||
|
|
||||||
std::string CoveragePath = getCoveragePath(Filename, MainFilename);
|
std::string CoveragePath = getCoveragePath(Filename, MainFilename);
|
||||||
std::unique_ptr<raw_ostream> S = openCoveragePath(CoveragePath);
|
std::unique_ptr<raw_ostream> S = openCoveragePath(CoveragePath);
|
||||||
@ -524,7 +543,8 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
|||||||
|
|
||||||
const LineData &Line = I->second;
|
const LineData &Line = I->second;
|
||||||
GCOVCoverage FileCoverage(Filename);
|
GCOVCoverage FileCoverage(Filename);
|
||||||
for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
|
for (uint32_t LineIndex = 0;
|
||||||
|
LineIndex < Line.LastLine || !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);
|
||||||
if (FuncsIt != Line.Functions.end())
|
if (FuncsIt != Line.Functions.end())
|
||||||
@ -535,9 +555,7 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
|||||||
if (BlocksIt == Line.Blocks.end()) {
|
if (BlocksIt == Line.Blocks.end()) {
|
||||||
// No basic blocks are on this line. Not an executable line of code.
|
// No basic blocks are on this line. Not an executable line of code.
|
||||||
OS << " -:";
|
OS << " -:";
|
||||||
std::pair<StringRef, StringRef> P = AllLines.split('\n');
|
AllLines.printNext(OS, LineIndex + 1);
|
||||||
OS << format("%5u:", LineIndex+1) << P.first << "\n";
|
|
||||||
AllLines = P.second;
|
|
||||||
} else {
|
} else {
|
||||||
const BlockVector &Blocks = BlocksIt->second;
|
const BlockVector &Blocks = BlocksIt->second;
|
||||||
|
|
||||||
@ -599,9 +617,7 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
|||||||
}
|
}
|
||||||
++FileCoverage.LogicalLines;
|
++FileCoverage.LogicalLines;
|
||||||
|
|
||||||
std::pair<StringRef, StringRef> P = AllLines.split('\n');
|
AllLines.printNext(OS, LineIndex + 1);
|
||||||
OS << format("%5u:", LineIndex+1) << P.first << "\n";
|
|
||||||
AllLines = P.second;
|
|
||||||
|
|
||||||
uint32_t BlockNo = 0;
|
uint32_t BlockNo = 0;
|
||||||
uint32_t EdgeNo = 0;
|
uint32_t EdgeNo = 0;
|
||||||
|
77
test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
Normal file
77
test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
-: 0:Source:srcdir/./nested_dir/../test.cpp
|
||||||
|
-: 0:Graph:test_paths.gcno
|
||||||
|
-: 0:Data:test_paths.gcda
|
||||||
|
-: 0:Runs:3
|
||||||
|
-: 0:Programs:1
|
||||||
|
-: 1:/*EOF*/
|
||||||
|
-: 2:/*EOF*/
|
||||||
|
-: 3:/*EOF*/
|
||||||
|
-: 4:/*EOF*/
|
||||||
|
-: 5:/*EOF*/
|
||||||
|
-: 6:/*EOF*/
|
||||||
|
-: 7:/*EOF*/
|
||||||
|
-: 8:/*EOF*/
|
||||||
|
-: 9:/*EOF*/
|
||||||
|
12884901888: 10:/*EOF*/
|
||||||
|
-: 11:/*EOF*/
|
||||||
|
#####: 12:/*EOF*/
|
||||||
|
-: 13:/*EOF*/
|
||||||
|
-: 14:/*EOF*/
|
||||||
|
#####: 15:/*EOF*/
|
||||||
|
-: 16:/*EOF*/
|
||||||
|
-: 17:/*EOF*/
|
||||||
|
-: 18:/*EOF*/
|
||||||
|
3: 19:/*EOF*/
|
||||||
|
3: 20:/*EOF*/
|
||||||
|
-: 21:/*EOF*/
|
||||||
|
-: 22:/*EOF*/
|
||||||
|
-: 23:/*EOF*/
|
||||||
|
#####: 24:/*EOF*/
|
||||||
|
#####: 25:/*EOF*/
|
||||||
|
-: 26:/*EOF*/
|
||||||
|
-: 27:/*EOF*/
|
||||||
|
12: 28:/*EOF*/
|
||||||
|
12: 29:/*EOF*/
|
||||||
|
12: 30:/*EOF*/
|
||||||
|
-: 31:/*EOF*/
|
||||||
|
-: 32:/*EOF*/
|
||||||
|
21: 33:/*EOF*/
|
||||||
|
36: 34:/*EOF*/
|
||||||
|
18: 35:/*EOF*/
|
||||||
|
3: 36:/*EOF*/
|
||||||
|
-: 37:/*EOF*/
|
||||||
|
-: 38:/*EOF*/
|
||||||
|
3: 39:/*EOF*/
|
||||||
|
-: 40:/*EOF*/
|
||||||
|
3: 41:/*EOF*/
|
||||||
|
3: 42:/*EOF*/
|
||||||
|
3: 43:/*EOF*/
|
||||||
|
3: 44:/*EOF*/
|
||||||
|
3: 45:/*EOF*/
|
||||||
|
3: 46:/*EOF*/
|
||||||
|
#####: 47:/*EOF*/
|
||||||
|
#####: 48:/*EOF*/
|
||||||
|
-: 49:/*EOF*/
|
||||||
|
-: 50:/*EOF*/
|
||||||
|
66: 51:/*EOF*/
|
||||||
|
30: 52:/*EOF*/
|
||||||
|
-: 53:/*EOF*/
|
||||||
|
6: 54:/*EOF*/
|
||||||
|
6: 55:/*EOF*/
|
||||||
|
-: 56:/*EOF*/
|
||||||
|
-: 57:/*EOF*/
|
||||||
|
3: 58:/*EOF*/
|
||||||
|
3: 59:/*EOF*/
|
||||||
|
-: 60:/*EOF*/
|
||||||
|
9: 61:/*EOF*/
|
||||||
|
9: 62:/*EOF*/
|
||||||
|
-: 63:/*EOF*/
|
||||||
|
12: 64:/*EOF*/
|
||||||
|
12: 65:/*EOF*/
|
||||||
|
30: 66:/*EOF*/
|
||||||
|
-: 67:/*EOF*/
|
||||||
|
3: 68:/*EOF*/
|
||||||
|
25769803782: 69:/*EOF*/
|
||||||
|
12884901888: 70:/*EOF*/
|
||||||
|
-: 71:/*EOF*/
|
||||||
|
3: 72:/*EOF*/
|
6
test/tools/llvm-cov/Inputs/test_missing.h.gcov
Normal file
6
test/tools/llvm-cov/Inputs/test_missing.h.gcov
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-: 0:Source:srcdir/./nested_dir/../test.h
|
||||||
|
-: 0:Graph:test_paths.gcno
|
||||||
|
-: 0:Data:test_paths.gcda
|
||||||
|
-: 0:Runs:3
|
||||||
|
-: 0:Programs:1
|
||||||
|
6: 1:/*EOF*/
|
8
test/tools/llvm-cov/Inputs/test_missing.output
Normal file
8
test/tools/llvm-cov/Inputs/test_missing.output
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
File 'srcdir/./nested_dir/../test.h'
|
||||||
|
Lines executed:100.00% of 1
|
||||||
|
srcdir/./nested_dir/../test.h:creating 'test.h.gcov'
|
||||||
|
|
||||||
|
File 'srcdir/./nested_dir/../test.cpp'
|
||||||
|
Lines executed:84.21% of 38
|
||||||
|
srcdir/./nested_dir/../test.cpp:creating 'test.cpp.gcov'
|
||||||
|
|
@ -34,6 +34,12 @@ RUN: diff -aub test_objdir.h.gcov test.h.gcov
|
|||||||
# With gcov output disabled
|
# With gcov output disabled
|
||||||
RUN: llvm-cov -n test.c | diff -u test_no_output.output -
|
RUN: llvm-cov -n test.c | diff -u test_no_output.output -
|
||||||
|
|
||||||
|
# Missing source files. This test is fragile, as it depends on being
|
||||||
|
# run before we copy some sources into place in the next test.
|
||||||
|
RUN: llvm-cov test_paths.cpp 2>/dev/null | diff -u test_missing.output -
|
||||||
|
RUN: diff -aub test_missing.cpp.gcov test.cpp.gcov
|
||||||
|
RUN: diff -aub test_missing.h.gcov test.h.gcov
|
||||||
|
|
||||||
# Preserve paths. This mangles the output filenames.
|
# Preserve paths. This mangles the output filenames.
|
||||||
RUN: mkdir -p %t/srcdir/nested_dir
|
RUN: mkdir -p %t/srcdir/nested_dir
|
||||||
RUN: cp test.cpp test.h %t/srcdir
|
RUN: cp test.cpp test.h %t/srcdir
|
||||||
|
Loading…
x
Reference in New Issue
Block a user