llvm.org GIT mirror llvm / 4c61bbe
llvm-cov: clang-format the GCOV files (NFC) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226952 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Bogner 5 years ago
2 changed file(s) with 200 addition(s) and 153 deletion(s). Raw diff Collapse all Expand all
2828 class FileInfo;
2929
3030 namespace GCOV {
31 enum GCOVVersion {
32 V402,
33 V404
34 };
31 enum GCOVVersion { V402, V404 };
3532 } // end GCOV namespace
3633
3734 /// GCOVOptions - A struct for passing gcov options between functions.
5552 class GCOVBuffer {
5653 public:
5754 GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
58
55
5956 /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
6057 bool readGCNOFormat() {
6158 StringRef File = Buffer->getBuffer().slice(0, 4);
8077
8178 /// readGCOVVersion - Read GCOV version.
8279 bool readGCOVVersion(GCOV::GCOVVersion &Version) {
83 StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4);
80 StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor + 4);
8481 if (VersionStr == "*204") {
8582 Cursor += 4;
8683 Version = GCOV::V402;
9895 /// readFunctionTag - If cursor points to a function tag then increment the
9996 /// cursor and return true otherwise return false.
10097 bool readFunctionTag() {
101 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
102 if (Tag.empty() ||
103 Tag[0] != '\0' || Tag[1] != '\0' ||
104 Tag[2] != '\0' || Tag[3] != '\1') {
98 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
99 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
100 Tag[3] != '\1') {
105101 return false;
106102 }
107103 Cursor += 4;
111107 /// readBlockTag - If cursor points to a block tag then increment the
112108 /// cursor and return true otherwise return false.
113109 bool readBlockTag() {
114 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
115 if (Tag.empty() ||
116 Tag[0] != '\0' || Tag[1] != '\0' ||
117 Tag[2] != '\x41' || Tag[3] != '\x01') {
110 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
111 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x41' ||
112 Tag[3] != '\x01') {
118113 return false;
119114 }
120115 Cursor += 4;
124119 /// readEdgeTag - If cursor points to an edge tag then increment the
125120 /// cursor and return true otherwise return false.
126121 bool readEdgeTag() {
127 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
128 if (Tag.empty() ||
129 Tag[0] != '\0' || Tag[1] != '\0' ||
130 Tag[2] != '\x43' || Tag[3] != '\x01') {
122 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
123 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x43' ||
124 Tag[3] != '\x01') {
131125 return false;
132126 }
133127 Cursor += 4;
137131 /// readLineTag - If cursor points to a line tag then increment the
138132 /// cursor and return true otherwise return false.
139133 bool readLineTag() {
140 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
141 if (Tag.empty() ||
142 Tag[0] != '\0' || Tag[1] != '\0' ||
143 Tag[2] != '\x45' || Tag[3] != '\x01') {
134 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
135 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x45' ||
136 Tag[3] != '\x01') {
144137 return false;
145138 }
146139 Cursor += 4;
150143 /// readArcTag - If cursor points to an gcda arc tag then increment the
151144 /// cursor and return true otherwise return false.
152145 bool readArcTag() {
153 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
154 if (Tag.empty() ||
155 Tag[0] != '\0' || Tag[1] != '\0' ||
156 Tag[2] != '\xa1' || Tag[3] != '\1') {
146 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
147 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\xa1' ||
148 Tag[3] != '\1') {
157149 return false;
158150 }
159151 Cursor += 4;
163155 /// readObjectTag - If cursor points to an object summary tag then increment
164156 /// the cursor and return true otherwise return false.
165157 bool readObjectTag() {
166 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
167 if (Tag.empty() ||
168 Tag[0] != '\0' || Tag[1] != '\0' ||
169 Tag[2] != '\0' || Tag[3] != '\xa1') {
158 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
159 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
160 Tag[3] != '\xa1') {
170161 return false;
171162 }
172163 Cursor += 4;
176167 /// readProgramTag - If cursor points to a program summary tag then increment
177168 /// the cursor and return true otherwise return false.
178169 bool readProgramTag() {
179 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
180 if (Tag.empty() ||
181 Tag[0] != '\0' || Tag[1] != '\0' ||
182 Tag[2] != '\0' || Tag[3] != '\xa3') {
170 StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
171 if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
172 Tag[3] != '\xa3') {
183173 return false;
184174 }
185175 Cursor += 4;
187177 }
188178
189179 bool readInt(uint32_t &Val) {
190 if (Buffer->getBuffer().size() < Cursor+4) {
191 errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n";
192 return false;
193 }
194 StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
180 if (Buffer->getBuffer().size() < Cursor + 4) {
181 errs() << "Unexpected end of memory buffer: " << Cursor + 4 << ".\n";
182 return false;
183 }
184 StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor + 4);
195185 Cursor += 4;
196186 Val = *(const uint32_t *)(Str.data());
197187 return true;
199189
200190 bool readInt64(uint64_t &Val) {
201191 uint32_t Lo, Hi;
202 if (!readInt(Lo) || !readInt(Hi)) return false;
192 if (!readInt(Lo) || !readInt(Hi))
193 return false;
203194 Val = ((uint64_t)Hi << 32) | Lo;
204195 return true;
205196 }
209200 // Keep reading until we find a non-zero length. This emulates gcov's
210201 // behaviour, which appears to do the same.
211202 while (Len == 0)
212 if (!readInt(Len)) return false;
203 if (!readInt(Len))
204 return false;
213205 Len *= 4;
214 if (Buffer->getBuffer().size() < Cursor+Len) {
215 errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n";
216 return false;
217 }
218 Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first;
206 if (Buffer->getBuffer().size() < Cursor + Len) {
207 errs() << "Unexpected end of memory buffer: " << Cursor + Len << ".\n";
208 return false;
209 }
210 Str = Buffer->getBuffer().slice(Cursor, Cursor + Len).split('\0').first;
219211 Cursor += Len;
220212 return true;
221213 }
222214
223215 uint64_t getCursor() const { return Cursor; }
224 void advanceCursor(uint32_t n) { Cursor += n*4; }
216 void advanceCursor(uint32_t n) { Cursor += n * 4; }
217
225218 private:
226219 MemoryBuffer *Buffer;
227220 uint64_t Cursor;
231224 /// (.gcno and .gcda).
232225 class GCOVFile {
233226 public:
234 GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
235 ProgramCount(0) {}
227 GCOVFile()
228 : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
229 ProgramCount(0) {}
236230 bool readGCNO(GCOVBuffer &Buffer);
237231 bool readGCDA(GCOVBuffer &Buffer);
238232 uint32_t getChecksum() const { return Checksum; }
239233 void dump() const;
240234 void collectLineCounts(FileInfo &FI);
235
241236 private:
242237 bool GCNOInitialized;
243238 GCOV::GCOVVersion Version;
260255 class GCOVFunction {
261256 public:
262257 typedef SmallVectorImpl>::const_iterator
263 BlockIterator;
258 BlockIterator;
264259
265260 GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
266261 bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
276271
277272 void dump() const;
278273 void collectLineCounts(FileInfo &FI);
274
279275 private:
280276 GCOVFile &Parent;
281277 uint32_t Ident;
290286 /// GCOVBlock - Collects block information.
291287 class GCOVBlock {
292288 struct EdgeWeight {
293 EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {}
289 EdgeWeight(GCOVBlock *D) : Dst(D), Count(0) {}
294290
295291 GCOVBlock *Dst;
296292 uint64_t Count;
301297 return E1->Dst.Number < E2->Dst.Number;
302298 }
303299 };
300
304301 public:
305302 typedef SmallVectorImpl::const_iterator EdgeIterator;
306303
307 GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0),
308 DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {}
304 GCOVBlock(GCOVFunction &P, uint32_t N)
305 : Parent(P), Number(N), Counter(0), DstEdgesAreSorted(true), SrcEdges(),
306 DstEdges(), Lines() {}
309307 ~GCOVBlock();
310308 const GCOVFunction &getParent() const { return Parent; }
311309 void addLine(uint32_t N) { Lines.push_back(N); }
335333
336334 void dump() const;
337335 void collectLineCounts(FileInfo &FI);
336
338337 private:
339338 GCOVFunction &Parent;
340339 uint32_t Number;
346345 };
347346
348347 class FileInfo {
349 // It is unlikely--but possible--for multiple functions to be on the same line.
350 // Therefore this typedef allows LineData.Functions to store multiple functions
348 // It is unlikely--but possible--for multiple functions to be on the same
349 // line.
350 // Therefore this typedef allows LineData.Functions to store multiple
351 // functions
351352 // per instance. This is rare, however, so optimize for the common case.
352353 typedef SmallVector FunctionVector;
353354 typedef DenseMap FunctionLines;
362363 };
363364
364365 struct GCOVCoverage {
365 GCOVCoverage(StringRef Name) :
366 Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0),
367 BranchesTaken(0) {}
366 GCOVCoverage(StringRef Name)
367 : Name(Name), LogicalLines(0), LinesExec(0), Branches(0),
368 BranchesExec(0), BranchesTaken(0) {}
368369
369370 StringRef Name;
370371
375376 uint32_t BranchesExec;
376377 uint32_t BranchesTaken;
377378 };
379
378380 public:
379 FileInfo(const GCOVOptions &Options) :
380 Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
381 FileInfo(const GCOVOptions &Options)
382 : Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
381383
382384 void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
383385 if (Line > LineInfo[Filename].LastLine)
384386 LineInfo[Filename].LastLine = Line;
385 LineInfo[Filename].Blocks[Line-1].push_back(Block);
387 LineInfo[Filename].Blocks[Line - 1].push_back(Block);
386388 }
387389 void addFunctionLine(StringRef Filename, uint32_t Line,
388390 const GCOVFunction *Function) {
389391 if (Line > LineInfo[Filename].LastLine)
390392 LineInfo[Filename].LastLine = Line;
391 LineInfo[Filename].Functions[Line-1].push_back(Function);
393 LineInfo[Filename].Functions[Line - 1].push_back(Function);
392394 }
393395 void setRunCount(uint32_t Runs) { RunCount = Runs; }
394396 void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
397399 private:
398400 std::string getCoveragePath(StringRef Filename, StringRef MainFilename);
399401 std::unique_ptr openCoveragePath(StringRef CoveragePath);
400 void printFunctionSummary(raw_ostream &OS,
401 const FunctionVector &Funcs) const;
402 void printFunctionSummary(raw_ostream &OS, const FunctionVector &Funcs) const;
402403 void printBlockInfo(raw_ostream &OS, const GCOVBlock &Block,
403404 uint32_t LineIndex, uint32_t &BlockNo) const;
404405 void printBranchInfo(raw_ostream &OS, const GCOVBlock &Block,
415416 uint32_t RunCount;
416417 uint32_t ProgramCount;
417418
418 typedef SmallVector, 4>
419 FileCoverageList;
419 typedef SmallVector, 4> FileCoverageList;
420420 typedef MapVector FuncCoverageMap;
421421
422422 FileCoverageList FileCoverages;
423423 FuncCoverageMap FuncCoverages;
424424 };
425
426425 }
427426
428427 #endif
2727
2828 /// readGCNO - Read GCNO buffer.
2929 bool GCOVFile::readGCNO(GCOVBuffer &Buffer) {
30 if (!Buffer.readGCNOFormat()) return false;
31 if (!Buffer.readGCOVVersion(Version)) return false;
32
33 if (!Buffer.readInt(Checksum)) return false;
30 if (!Buffer.readGCNOFormat())
31 return false;
32 if (!Buffer.readGCOVVersion(Version))
33 return false;
34
35 if (!Buffer.readInt(Checksum))
36 return false;
3437 while (true) {
35 if (!Buffer.readFunctionTag()) break;
38 if (!Buffer.readFunctionTag())
39 break;
3640 auto GFun = make_unique(*this);
3741 if (!GFun->readGCNO(Buffer, Version))
3842 return false;
4751 /// called after readGCNO().
4852 bool GCOVFile::readGCDA(GCOVBuffer &Buffer) {
4953 assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()");
50 if (!Buffer.readGCDAFormat()) return false;
54 if (!Buffer.readGCDAFormat())
55 return false;
5156 GCOV::GCOVVersion GCDAVersion;
52 if (!Buffer.readGCOVVersion(GCDAVersion)) return false;
57 if (!Buffer.readGCOVVersion(GCDAVersion))
58 return false;
5359 if (Version != GCDAVersion) {
5460 errs() << "GCOV versions do not match.\n";
5561 return false;
5662 }
5763
5864 uint32_t GCDAChecksum;
59 if (!Buffer.readInt(GCDAChecksum)) return false;
65 if (!Buffer.readInt(GCDAChecksum))
66 return false;
6067 if (Checksum != GCDAChecksum) {
61 errs() << "File checksums do not match: " << Checksum << " != "
62 << GCDAChecksum << ".\n";
68 errs() << "File checksums do not match: " << Checksum
69 << " != " << GCDAChecksum << ".\n";
6370 return false;
6471 }
6572 for (size_t i = 0, e = Functions.size(); i < e; ++i) {
7380 if (Buffer.readObjectTag()) {
7481 uint32_t Length;
7582 uint32_t Dummy;
76 if (!Buffer.readInt(Length)) return false;
77 if (!Buffer.readInt(Dummy)) return false; // checksum
78 if (!Buffer.readInt(Dummy)) return false; // num
79 if (!Buffer.readInt(RunCount)) return false;
80 Buffer.advanceCursor(Length-3);
83 if (!Buffer.readInt(Length))
84 return false;
85 if (!Buffer.readInt(Dummy))
86 return false; // checksum
87 if (!Buffer.readInt(Dummy))
88 return false; // num
89 if (!Buffer.readInt(RunCount))
90 return false;
91 Buffer.advanceCursor(Length - 3);
8192 }
8293 while (Buffer.readProgramTag()) {
8394 uint32_t Length;
84 if (!Buffer.readInt(Length)) return false;
95 if (!Buffer.readInt(Length))
96 return false;
8597 Buffer.advanceCursor(Length);
8698 ++ProgramCount;
8799 }
111123 /// occurs.
112124 bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
113125 uint32_t Dummy;
114 if (!Buff.readInt(Dummy)) return false; // Function header length
115 if (!Buff.readInt(Ident)) return false;
116 if (!Buff.readInt(Checksum)) return false;
126 if (!Buff.readInt(Dummy))
127 return false; // Function header length
128 if (!Buff.readInt(Ident))
129 return false;
130 if (!Buff.readInt(Checksum))
131 return false;
117132 if (Version != GCOV::V402) {
118133 uint32_t CfgChecksum;
119 if (!Buff.readInt(CfgChecksum)) return false;
134 if (!Buff.readInt(CfgChecksum))
135 return false;
120136 if (Parent.getChecksum() != CfgChecksum) {
121137 errs() << "File checksums do not match: " << Parent.getChecksum()
122138 << " != " << CfgChecksum << " in (" << Name << ").\n";
123139 return false;
124140 }
125141 }
126 if (!Buff.readString(Name)) return false;
127 if (!Buff.readString(Filename)) return false;
128 if (!Buff.readInt(LineNumber)) return false;
142 if (!Buff.readString(Name))
143 return false;
144 if (!Buff.readString(Filename))
145 return false;
146 if (!Buff.readInt(LineNumber))
147 return false;
129148
130149 // read blocks.
131150 if (!Buff.readBlockTag()) {
133152 return false;
134153 }
135154 uint32_t BlockCount;
136 if (!Buff.readInt(BlockCount)) return false;
155 if (!Buff.readInt(BlockCount))
156 return false;
137157 for (uint32_t i = 0, e = BlockCount; i != e; ++i) {
138 if (!Buff.readInt(Dummy)) return false; // Block flags;
158 if (!Buff.readInt(Dummy))
159 return false; // Block flags;
139160 Blocks.push_back(make_unique(*this, i));
140161 }
141162
142163 // read edges.
143164 while (Buff.readEdgeTag()) {
144165 uint32_t EdgeCount;
145 if (!Buff.readInt(EdgeCount)) return false;
166 if (!Buff.readInt(EdgeCount))
167 return false;
146168 EdgeCount = (EdgeCount - 1) / 2;
147169 uint32_t BlockNo;
148 if (!Buff.readInt(BlockNo)) return false;
170 if (!Buff.readInt(BlockNo))
171 return false;
149172 if (BlockNo >= BlockCount) {
150173 errs() << "Unexpected block number: " << BlockNo << " (in " << Name
151174 << ").\n";
153176 }
154177 for (uint32_t i = 0, e = EdgeCount; i != e; ++i) {
155178 uint32_t Dst;
156 if (!Buff.readInt(Dst)) return false;
179 if (!Buff.readInt(Dst))
180 return false;
157181 Edges.push_back(make_unique(*Blocks[BlockNo], *Blocks[Dst]));
158182 GCOVEdge *Edge = Edges.back().get();
159183 Blocks[BlockNo]->addDstEdge(Edge);
160184 Blocks[Dst]->addSrcEdge(Edge);
161 if (!Buff.readInt(Dummy)) return false; // Edge flag
185 if (!Buff.readInt(Dummy))
186 return false; // Edge flag
162187 }
163188 }
164189
166191 while (Buff.readLineTag()) {
167192 uint32_t LineTableLength;
168193 // Read the length of this line table.
169 if (!Buff.readInt(LineTableLength)) return false;
170 uint32_t EndPos = Buff.getCursor() + LineTableLength*4;
194 if (!Buff.readInt(LineTableLength))
195 return false;
196 uint32_t EndPos = Buff.getCursor() + LineTableLength * 4;
171197 uint32_t BlockNo;
172198 // Read the block number this table is associated with.
173 if (!Buff.readInt(BlockNo)) return false;
199 if (!Buff.readInt(BlockNo))
200 return false;
174201 if (BlockNo >= BlockCount) {
175202 errs() << "Unexpected block number: " << BlockNo << " (in " << Name
176203 << ").\n";
179206 GCOVBlock &Block = *Blocks[BlockNo];
180207 // Read the word that pads the beginning of the line table. This may be a
181208 // flag of some sort, but seems to always be zero.
182 if (!Buff.readInt(Dummy)) return false;
209 if (!Buff.readInt(Dummy))
210 return false;
183211
184212 // Line information starts here and continues up until the last word.
185213 if (Buff.getCursor() != (EndPos - sizeof(uint32_t))) {
186214 StringRef F;
187215 // Read the source file name.
188 if (!Buff.readString(F)) return false;
216 if (!Buff.readString(F))
217 return false;
189218 if (Filename != F) {
190219 errs() << "Multiple sources for a single basic block: " << Filename
191220 << " != " << F << " (in " << Name << ").\n";
194223 // Read lines up to, but not including, the null terminator.
195224 while (Buff.getCursor() < (EndPos - 2 * sizeof(uint32_t))) {
196225 uint32_t Line;
197 if (!Buff.readInt(Line)) return false;
226 if (!Buff.readInt(Line))
227 return false;
198228 // Line 0 means this instruction was injected by the compiler. Skip it.
199 if (!Line) continue;
229 if (!Line)
230 continue;
200231 Block.addLine(Line);
201232 }
202233 // Read the null terminator.
203 if (!Buff.readInt(Dummy)) return false;
234 if (!Buff.readInt(Dummy))
235 return false;
204236 }
205237 // The last word is either a flag or padding, it isn't clear which. Skip
206238 // over it.
207 if (!Buff.readInt(Dummy)) return false;
239 if (!Buff.readInt(Dummy))
240 return false;
208241 }
209242 return true;
210243 }
213246 /// occurs.
214247 bool GCOVFunction::readGCDA(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
215248 uint32_t Dummy;
216 if (!Buff.readInt(Dummy)) return false; // Function header length
249 if (!Buff.readInt(Dummy))
250 return false; // Function header length
217251
218252 uint32_t GCDAIdent;
219 if (!Buff.readInt(GCDAIdent)) return false;
253 if (!Buff.readInt(GCDAIdent))
254 return false;
220255 if (Ident != GCDAIdent) {
221 errs() << "Function identifiers do not match: " << Ident << " != "
222 << GCDAIdent << " (in " << Name << ").\n";
256 errs() << "Function identifiers do not match: " << Ident
257 << " != " << GCDAIdent << " (in " << Name << ").\n";
223258 return false;
224259 }
225260
226261 uint32_t GCDAChecksum;
227 if (!Buff.readInt(GCDAChecksum)) return false;
262 if (!Buff.readInt(GCDAChecksum))
263 return false;
228264 if (Checksum != GCDAChecksum) {
229 errs() << "Function checksums do not match: " << Checksum << " != "
230 << GCDAChecksum << " (in " << Name << ").\n";
265 errs() << "Function checksums do not match: " << Checksum
266 << " != " << GCDAChecksum << " (in " << Name << ").\n";
231267 return false;
232268 }
233269
234270 uint32_t CfgChecksum;
235271 if (Version != GCOV::V402) {
236 if (!Buff.readInt(CfgChecksum)) return false;
272 if (!Buff.readInt(CfgChecksum))
273 return false;
237274 if (Parent.getChecksum() != CfgChecksum) {
238275 errs() << "File checksums do not match: " << Parent.getChecksum()
239276 << " != " << CfgChecksum << " (in " << Name << ").\n";
242279 }
243280
244281 StringRef GCDAName;
245 if (!Buff.readString(GCDAName)) return false;
282 if (!Buff.readString(GCDAName))
283 return false;
246284 if (Name != GCDAName) {
247285 errs() << "Function names do not match: " << Name << " != " << GCDAName
248286 << ".\n";
255293 }
256294
257295 uint32_t Count;
258 if (!Buff.readInt(Count)) return false;
296 if (!Buff.readInt(Count))
297 return false;
259298 Count /= 2;
260299
261300 // This for loop adds the counts for each block. A second nested loop is
262301 // required to combine the edge counts that are contained in the GCDA file.
263302 for (uint32_t BlockNo = 0; Count > 0; ++BlockNo) {
264303 // The last block is always reserved for exit block
265 if (BlockNo >= Blocks.size()-1) {
304 if (BlockNo >= Blocks.size() - 1) {
266305 errs() << "Unexpected number of edges (in " << Name << ").\n";
267306 return false;
268307 }
269308 GCOVBlock &Block = *Blocks[BlockNo];
270309 for (size_t EdgeNo = 0, End = Block.getNumDstEdges(); EdgeNo < End;
271 ++EdgeNo) {
310 ++EdgeNo) {
272311 if (Count == 0) {
273312 errs() << "Unexpected number of edges (in " << Name << ").\n";
274313 return false;
275314 }
276315 uint64_t ArcCount;
277 if (!Buff.readInt64(ArcCount)) return false;
316 if (!Buff.readInt64(ArcCount))
317 return false;
278318 Block.addCount(EdgeNo, ArcCount);
279319 --Count;
280320 }
348388 /// collectLineCounts - Collect line counts. This must be used after
349389 /// reading .gcno and .gcda files.
350390 void GCOVBlock::collectLineCounts(FileInfo &FI) {
351 for (SmallVectorImpl::iterator I = Lines.begin(),
352 E = Lines.end(); I != E; ++I)
391 for (auto I = Lines.begin(), E = Lines.end(); I != E; ++I)
353392 FI.addBlockLine(Parent.getFilename(), *I, this);
354393 }
355394
375414 if (!Lines.empty()) {
376415 dbgs() << "\tLines : ";
377416 for (SmallVectorImpl::const_iterator I = Lines.begin(),
378 E = Lines.end(); I != E; ++I)
417 E = Lines.end();
418 I != E; ++I)
379419 dbgs() << (*I) << ",";
380420 dbgs() << "\n";
381421 }
388428 static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) {
389429 if (!Numerator)
390430 return 0;
391 return Numerator/Divisor;
431 return Numerator / Divisor;
392432 }
393433
394434 // This custom division function mimics gcov's branch ouputs:
400440 if (Numerator == Divisor)
401441 return 100;
402442
403 uint8_t Res = (Numerator*100+Divisor/2) / Divisor;
443 uint8_t Res = (Numerator * 100 + Divisor / 2) / Divisor;
404444 if (Res == 0)
405445 return 1;
406446 if (Res == 100)
409449 }
410450
411451 struct formatBranchInfo {
412 formatBranchInfo(const GCOVOptions &Options, uint64_t Count,
413 uint64_t Total) :
414 Options(Options), Count(Count), Total(Total) {}
452 formatBranchInfo(const GCOVOptions &Options, uint64_t Count, uint64_t Total)
453 : Options(Options), Count(Count), Total(Total) {}
415454
416455 void print(raw_ostream &OS) const {
417456 if (!Total)
436475 class LineConsumer {
437476 std::unique_ptr Buffer;
438477 StringRef Remaining;
478
439479 public:
440480 LineConsumer(StringRef Filename) {
441481 ErrorOr> BufferOrErr =
507547 if (Options.LongFileNames && !Filename.equals(MainFilename))
508548 CoveragePath =
509549 mangleCoveragePath(MainFilename, Options.PreservePaths) + "##";
510 CoveragePath +=
511 mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov";
550 CoveragePath += mangleCoveragePath(Filename, Options.PreservePaths) + ".gcov";
512551 return CoveragePath;
513552 }
514553
531570 void FileInfo::print(StringRef MainFilename, StringRef GCNOFile,
532571 StringRef GCDAFile) {
533572 for (StringMap::const_iterator I = LineInfo.begin(),
534 E = LineInfo.end(); I != E; ++I) {
573 E = LineInfo.end();
574 I != E; ++I) {
535575 StringRef Filename = I->first();
536576 auto AllLines = LineConsumer(Filename);
537577
547587
548588 const LineData &Line = I->second;
549589 GCOVCoverage FileCoverage(Filename);
550 for (uint32_t LineIndex = 0;
551 LineIndex < Line.LastLine || !AllLines.empty(); ++LineIndex) {
590 for (uint32_t LineIndex = 0; LineIndex < Line.LastLine || !AllLines.empty();
591 ++LineIndex) {
552592 if (Options.BranchInfo) {
553593 FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
554594 if (FuncsIt != Line.Functions.end())
567607 DenseMap LineExecs;
568608 uint64_t LineCount = 0;
569609 for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
570 I != E; ++I) {
610 I != E; ++I) {
571611 const GCOVBlock *Block = *I;
572612 if (Options.AllBlocks) {
573613 // Only take the highest block count for that line.
592632 // one of the blocks are executed.
593633 const GCOVFunction *Function = &Block->getParent();
594634 if (FuncCoverages.find(Function) == FuncCoverages.end()) {
595 std::pair
596 KeyValue(Function, GCOVCoverage(Function->getName()));
635 std::pair KeyValue(
636 Function, GCOVCoverage(Function->getName()));
597637 FuncCoverages.insert(KeyValue);
598638 }
599639 GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
626666 uint32_t BlockNo = 0;
627667 uint32_t EdgeNo = 0;
628668 for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
629 I != E; ++I) {
669 I != E; ++I) {
630670 const GCOVBlock *Block = *I;
631671
632672 // Only print block and branch information at the end of the block.
633 if (Block->getLastLine() != LineIndex+1)
673 if (Block->getLastLine() != LineIndex + 1)
634674 continue;
635675 if (Options.AllBlocks)
636676 printBlockInfo(OS, *Block, LineIndex, BlockNo);
658698 void FileInfo::printFunctionSummary(raw_ostream &OS,
659699 const FunctionVector &Funcs) const {
660700 for (FunctionVector::const_iterator I = Funcs.begin(), E = Funcs.end();
661 I != E; ++I) {
701 I != E; ++I) {
662702 const GCOVFunction *Func = *I;
663703 uint64_t EntryCount = Func->getEntryCount();
664704 uint32_t BlocksExec = 0;
665705 for (GCOVFunction::BlockIterator I = Func->block_begin(),
666 E = Func->block_end(); I != E; ++I) {
706 E = Func->block_end();
707 I != E; ++I) {
667708 const GCOVBlock &Block = **I;
668709 if (Block.getNumDstEdges() && Block.getCount())
669 ++BlocksExec;
710 ++BlocksExec;
670711 }
671712
672713 OS << "function " << Func->getName() << " called " << EntryCount
673 << " returned " << safeDiv(Func->getExitCount()*100, EntryCount)
714 << " returned " << safeDiv(Func->getExitCount() * 100, EntryCount)
674715 << "% blocks executed "
675 << safeDiv(BlocksExec*100, Func->getNumBlocks()-1) << "%\n";
716 << safeDiv(BlocksExec * 100, Func->getNumBlocks() - 1) << "%\n";
676717 }
677718 }
678719
683724 OS << " $$$$$:";
684725 else
685726 OS << format("%9" PRIu64 ":", Block.getCount());
686 OS << format("%5u-block %2u\n", LineIndex+1, BlockNo++);
727 OS << format("%5u-block %2u\n", LineIndex + 1, BlockNo++);
687728 }
688729
689730 /// printBranchInfo - Print conditional branch probabilities.
692733 SmallVector BranchCounts;
693734 uint64_t TotalCounts = 0;
694735 for (GCOVBlock::EdgeIterator I = Block.dst_begin(), E = Block.dst_end();
695 I != E; ++I) {
736 I != E; ++I) {
696737 const GCOVEdge *Edge = *I;
697738 BranchCounts.push_back(Edge->Count);
698739 TotalCounts += Edge->Count;
699 if (Block.getCount()) ++Coverage.BranchesExec;
700 if (Edge->Count) ++Coverage.BranchesTaken;
740 if (Block.getCount())
741 ++Coverage.BranchesExec;
742 if (Edge->Count)
743 ++Coverage.BranchesTaken;
701744 ++Coverage.Branches;
702745
703746 if (Options.FuncCoverage) {
704747 const GCOVFunction *Function = &Block.getParent();
705748 GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second;
706 if (Block.getCount()) ++FuncCoverage.BranchesExec;
707 if (Edge->Count) ++FuncCoverage.BranchesTaken;
749 if (Block.getCount())
750 ++FuncCoverage.BranchesExec;
751 if (Edge->Count)
752 ++FuncCoverage.BranchesTaken;
708753 ++FuncCoverage.Branches;
709754 }
710755 }
711756
712757 for (SmallVectorImpl::const_iterator I = BranchCounts.begin(),
713 E = BranchCounts.end(); I != E; ++I) {
758 E = BranchCounts.end();
759 I != E; ++I) {
714760 OS << format("branch %2u ", EdgeNo++)
715761 << formatBranchInfo(Options, *I, TotalCounts) << "\n";
716762 }
727773 // and printFileCoverage.
728774 void FileInfo::printCoverage(const GCOVCoverage &Coverage) const {
729775 outs() << format("Lines executed:%.2f%% of %u\n",
730 double(Coverage.LinesExec)*100/Coverage.LogicalLines,
776 double(Coverage.LinesExec) * 100 / Coverage.LogicalLines,
731777 Coverage.LogicalLines);
732778 if (Options.BranchInfo) {
733779 if (Coverage.Branches) {
734780 outs() << format("Branches executed:%.2f%% of %u\n",
735 double(Coverage.BranchesExec)*100/Coverage.Branches,
781 double(Coverage.BranchesExec) * 100 / Coverage.Branches,
736782 Coverage.Branches);
737783 outs() << format("Taken at least once:%.2f%% of %u\n",
738 double(Coverage.BranchesTaken)*100/Coverage.Branches,
784 double(Coverage.BranchesTaken) * 100 / Coverage.Branches,
739785 Coverage.Branches);
740786 } else {
741787 outs() << "No branches\n";
747793 // printFuncCoverage - Print per-function coverage info.
748794 void FileInfo::printFuncCoverage() const {
749795 for (FuncCoverageMap::const_iterator I = FuncCoverages.begin(),
750 E = FuncCoverages.end(); I != E; ++I) {
796 E = FuncCoverages.end();
797 I != E; ++I) {
751798 const GCOVCoverage &Coverage = I->second;
752799 outs() << "Function '" << Coverage.Name << "'\n";
753800 printCoverage(Coverage);
758805 // printFileCoverage - Print per-file coverage info.
759806 void FileInfo::printFileCoverage() const {
760807 for (FileCoverageList::const_iterator I = FileCoverages.begin(),
761 E = FileCoverages.end(); I != E; ++I) {
808 E = FileCoverages.end();
809 I != E; ++I) {
762810 const std::string &Filename = I->first;
763811 const GCOVCoverage &Coverage = I->second;
764812 outs() << "File '" << Coverage.Name << "'\n";