summaryrefslogtreecommitdiff
path: root/lib/IR/GCOV.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2014-05-07 02:11:23 +0000
committerJustin Bogner <mail@justinbogner.com>2014-05-07 02:11:23 +0000
commitc92330c18ce2f7015f0db88e4bfce3d253fa3c57 (patch)
treeae700f9e5977fb7a1bc760e4f2746b9b2350379b /lib/IR/GCOV.cpp
parent56d05e468cdfd4ad195f264974f1b841bc4ca785 (diff)
downloadllvm-c92330c18ce2f7015f0db88e4bfce3d253fa3c57.tar.gz
llvm-c92330c18ce2f7015f0db88e4bfce3d253fa3c57.tar.bz2
llvm-c92330c18ce2f7015f0db88e4bfce3d253fa3c57.tar.xz
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
Diffstat (limited to 'lib/IR/GCOV.cpp')
-rw-r--r--lib/IR/GCOV.cpp42
1 files changed, 29 insertions, 13 deletions
diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp
index 05fe1e07df..7a89723d85 100644
--- a/lib/IR/GCOV.cpp
+++ b/lib/IR/GCOV.cpp
@@ -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;