mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-18 01:17:46 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208149 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
56d05e468c
commit
c92330c18c
@ -356,8 +356,10 @@ class FileInfo {
|
||||
typedef DenseMap<uint32_t, BlockVector> BlockLines;
|
||||
|
||||
struct LineData {
|
||||
LineData() : LastLine(0) {}
|
||||
BlockLines Blocks;
|
||||
FunctionLines Functions;
|
||||
uint32_t LastLine;
|
||||
};
|
||||
|
||||
struct GCOVCoverage {
|
||||
@ -379,11 +381,15 @@ public:
|
||||
Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
|
||||
|
||||
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);
|
||||
}
|
||||
void addFunctionLine(StringRef Filename, uint32_t Line,
|
||||
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 setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
|
||||
|
@ -432,6 +432,30 @@ static raw_ostream &operator<<(raw_ostream &OS, const formatBranchInfo &FBI) {
|
||||
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
|
||||
/// translates "/" to "#", ".." to "^", and drops ".", to match gcov.
|
||||
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(),
|
||||
E = LineInfo.end(); I != E; ++I) {
|
||||
StringRef Filename = I->first();
|
||||
std::unique_ptr<MemoryBuffer> Buff;
|
||||
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
|
||||
errs() << Filename << ": " << ec.message() << "\n";
|
||||
return;
|
||||
}
|
||||
StringRef AllLines = Buff->getBuffer();
|
||||
auto AllLines = LineConsumer(Filename);
|
||||
|
||||
std::string CoveragePath = getCoveragePath(Filename, MainFilename);
|
||||
std::unique_ptr<raw_ostream> S = openCoveragePath(CoveragePath);
|
||||
@ -524,7 +543,8 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
||||
|
||||
const LineData &Line = I->second;
|
||||
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) {
|
||||
FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
|
||||
if (FuncsIt != Line.Functions.end())
|
||||
@ -535,9 +555,7 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
||||
if (BlocksIt == Line.Blocks.end()) {
|
||||
// No basic blocks are on this line. Not an executable line of code.
|
||||
OS << " -:";
|
||||
std::pair<StringRef, StringRef> P = AllLines.split('\n');
|
||||
OS << format("%5u:", LineIndex+1) << P.first << "\n";
|
||||
AllLines = P.second;
|
||||
AllLines.printNext(OS, LineIndex + 1);
|
||||
} else {
|
||||
const BlockVector &Blocks = BlocksIt->second;
|
||||
|
||||
@ -599,9 +617,7 @@ void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
|
||||
}
|
||||
++FileCoverage.LogicalLines;
|
||||
|
||||
std::pair<StringRef, StringRef> P = AllLines.split('\n');
|
||||
OS << format("%5u:", LineIndex+1) << P.first << "\n";
|
||||
AllLines = P.second;
|
||||
AllLines.printNext(OS, LineIndex + 1);
|
||||
|
||||
uint32_t BlockNo = 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
|
||||
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.
|
||||
RUN: mkdir -p %t/srcdir/nested_dir
|
||||
RUN: cp test.cpp test.h %t/srcdir
|
||||
|
Loading…
Reference in New Issue
Block a user