diff options
Diffstat (limited to 'include/llvm/Support/GCOV.h')
-rw-r--r-- | include/llvm/Support/GCOV.h | 147 |
1 files changed, 79 insertions, 68 deletions
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index e378602..c2e34bd 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -19,6 +19,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -29,10 +30,7 @@ class GCOVBlock; class FileInfo; namespace GCOV { - enum GCOVVersion { - V402, - V404 - }; +enum GCOVVersion { V402, V404 }; } // end GCOV namespace /// GCOVOptions - A struct for passing gcov options between functions. @@ -56,7 +54,7 @@ struct GCOVOptions { class GCOVBuffer { public: GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {} - + /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer. bool readGCNOFormat() { StringRef File = Buffer->getBuffer().slice(0, 4); @@ -81,7 +79,7 @@ public: /// readGCOVVersion - Read GCOV version. bool readGCOVVersion(GCOV::GCOVVersion &Version) { - StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4); + StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor + 4); if (VersionStr == "*204") { Cursor += 4; Version = GCOV::V402; @@ -99,10 +97,9 @@ public: /// readFunctionTag - If cursor points to a function tag then increment the /// cursor and return true otherwise return false. bool readFunctionTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\0' || Tag[3] != '\1') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || + Tag[3] != '\1') { return false; } Cursor += 4; @@ -112,10 +109,9 @@ public: /// readBlockTag - If cursor points to a block tag then increment the /// cursor and return true otherwise return false. bool readBlockTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\x41' || Tag[3] != '\x01') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x41' || + Tag[3] != '\x01') { return false; } Cursor += 4; @@ -125,10 +121,9 @@ public: /// readEdgeTag - If cursor points to an edge tag then increment the /// cursor and return true otherwise return false. bool readEdgeTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\x43' || Tag[3] != '\x01') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x43' || + Tag[3] != '\x01') { return false; } Cursor += 4; @@ -138,10 +133,9 @@ public: /// readLineTag - If cursor points to a line tag then increment the /// cursor and return true otherwise return false. bool readLineTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\x45' || Tag[3] != '\x01') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x45' || + Tag[3] != '\x01') { return false; } Cursor += 4; @@ -151,10 +145,9 @@ public: /// readArcTag - If cursor points to an gcda arc tag then increment the /// cursor and return true otherwise return false. bool readArcTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\xa1' || Tag[3] != '\1') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\xa1' || + Tag[3] != '\1') { return false; } Cursor += 4; @@ -164,10 +157,9 @@ public: /// readObjectTag - If cursor points to an object summary tag then increment /// the cursor and return true otherwise return false. bool readObjectTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\0' || Tag[3] != '\xa1') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || + Tag[3] != '\xa1') { return false; } Cursor += 4; @@ -177,10 +169,9 @@ public: /// readProgramTag - If cursor points to a program summary tag then increment /// the cursor and return true otherwise return false. bool readProgramTag() { - StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || - Tag[0] != '\0' || Tag[1] != '\0' || - Tag[2] != '\0' || Tag[3] != '\xa3') { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4); + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || + Tag[3] != '\xa3') { return false; } Cursor += 4; @@ -188,11 +179,11 @@ public: } bool readInt(uint32_t &Val) { - if (Buffer->getBuffer().size() < Cursor+4) { - errs() << "Unexpected end of memory buffer: " << Cursor+4 << ".\n"; + if (Buffer->getBuffer().size() < Cursor + 4) { + errs() << "Unexpected end of memory buffer: " << Cursor + 4 << ".\n"; return false; } - StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4); + StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor + 4); Cursor += 4; Val = *(const uint32_t *)(Str.data()); return true; @@ -200,7 +191,8 @@ public: bool readInt64(uint64_t &Val) { uint32_t Lo, Hi; - if (!readInt(Lo) || !readInt(Hi)) return false; + if (!readInt(Lo) || !readInt(Hi)) + return false; Val = ((uint64_t)Hi << 32) | Lo; return true; } @@ -210,19 +202,21 @@ public: // Keep reading until we find a non-zero length. This emulates gcov's // behaviour, which appears to do the same. while (Len == 0) - if (!readInt(Len)) return false; + if (!readInt(Len)) + return false; Len *= 4; - if (Buffer->getBuffer().size() < Cursor+Len) { - errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n"; + if (Buffer->getBuffer().size() < Cursor + Len) { + errs() << "Unexpected end of memory buffer: " << Cursor + Len << ".\n"; return false; } - Str = Buffer->getBuffer().slice(Cursor, Cursor+Len).split('\0').first; + Str = Buffer->getBuffer().slice(Cursor, Cursor + Len).split('\0').first; Cursor += Len; return true; } uint64_t getCursor() const { return Cursor; } - void advanceCursor(uint32_t n) { Cursor += n*4; } + void advanceCursor(uint32_t n) { Cursor += n * 4; } + private: MemoryBuffer *Buffer; uint64_t Cursor; @@ -232,13 +226,15 @@ private: /// (.gcno and .gcda). class GCOVFile { public: - GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0), - ProgramCount(0) {} + GCOVFile() + : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0), + ProgramCount(0) {} bool readGCNO(GCOVBuffer &Buffer); bool readGCDA(GCOVBuffer &Buffer); uint32_t getChecksum() const { return Checksum; } void dump() const; void collectLineCounts(FileInfo &FI); + private: bool GCNOInitialized; GCOV::GCOVVersion Version; @@ -260,8 +256,8 @@ struct GCOVEdge { /// GCOVFunction - Collects function information. class GCOVFunction { public: - typedef SmallVectorImpl<std::unique_ptr<GCOVBlock>>::const_iterator - BlockIterator; + typedef pointee_iterator<SmallVectorImpl< + std::unique_ptr<GCOVBlock>>::const_iterator> BlockIterator; GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {} bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version); @@ -274,9 +270,13 @@ public: BlockIterator block_begin() const { return Blocks.begin(); } BlockIterator block_end() const { return Blocks.end(); } + iterator_range<BlockIterator> blocks() const { + return make_range(block_begin(), block_end()); + } void dump() const; void collectLineCounts(FileInfo &FI); + private: GCOVFile &Parent; uint32_t Ident; @@ -291,7 +291,7 @@ private: /// GCOVBlock - Collects block information. class GCOVBlock { struct EdgeWeight { - EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {} + EdgeWeight(GCOVBlock *D) : Dst(D), Count(0) {} GCOVBlock *Dst; uint64_t Count; @@ -302,11 +302,13 @@ class GCOVBlock { return E1->Dst.Number < E2->Dst.Number; } }; + public: typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator; - GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0), - DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {} + GCOVBlock(GCOVFunction &P, uint32_t N) + : Parent(P), Number(N), Counter(0), DstEdgesAreSorted(true), SrcEdges(), + DstEdges(), Lines() {} ~GCOVBlock(); const GCOVFunction &getParent() const { return Parent; } void addLine(uint32_t N) { Lines.push_back(N); } @@ -331,11 +333,19 @@ public: EdgeIterator src_begin() const { return SrcEdges.begin(); } EdgeIterator src_end() const { return SrcEdges.end(); } + iterator_range<EdgeIterator> srcs() const { + return make_range(src_begin(), src_end()); + } + EdgeIterator dst_begin() const { return DstEdges.begin(); } EdgeIterator dst_end() const { return DstEdges.end(); } + iterator_range<EdgeIterator> dsts() const { + return make_range(dst_begin(), dst_end()); + } void dump() const; void collectLineCounts(FileInfo &FI); + private: GCOVFunction &Parent; uint32_t Number; @@ -347,8 +357,10 @@ private: }; class FileInfo { - // It is unlikely--but possible--for multiple functions to be on the same line. - // Therefore this typedef allows LineData.Functions to store multiple functions + // It is unlikely--but possible--for multiple functions to be on the same + // line. + // Therefore this typedef allows LineData.Functions to store multiple + // functions // per instance. This is rare, however, so optimize for the common case. typedef SmallVector<const GCOVFunction *, 1> FunctionVector; typedef DenseMap<uint32_t, FunctionVector> FunctionLines; @@ -363,9 +375,9 @@ class FileInfo { }; struct GCOVCoverage { - GCOVCoverage(StringRef Name) : - Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0), - BranchesTaken(0) {} + GCOVCoverage(StringRef Name) + : Name(Name), LogicalLines(0), LinesExec(0), Branches(0), + BranchesExec(0), BranchesTaken(0) {} StringRef Name; @@ -376,30 +388,31 @@ class FileInfo { uint32_t BranchesExec; uint32_t BranchesTaken; }; + public: - FileInfo(const GCOVOptions &Options) : - Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {} + FileInfo(const GCOVOptions &Options) + : 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); + LineInfo[Filename].Blocks[Line - 1].push_back(Block); } void addFunctionLine(StringRef Filename, uint32_t Line, const GCOVFunction *Function) { if (Line > LineInfo[Filename].LastLine) LineInfo[Filename].LastLine = Line; - LineInfo[Filename].Functions[Line-1].push_back(Function); + LineInfo[Filename].Functions[Line - 1].push_back(Function); } void setRunCount(uint32_t Runs) { RunCount = Runs; } void setProgramCount(uint32_t Programs) { ProgramCount = Programs; } - void print(StringRef MainFilename, StringRef GCNOFile, StringRef GCDAFile); + void print(raw_ostream &OS, StringRef MainFilename, StringRef GCNOFile, + StringRef GCDAFile); private: std::string getCoveragePath(StringRef Filename, StringRef MainFilename); std::unique_ptr<raw_ostream> openCoveragePath(StringRef CoveragePath); - void printFunctionSummary(raw_ostream &OS, - const FunctionVector &Funcs) const; + void printFunctionSummary(raw_ostream &OS, const FunctionVector &Funcs) const; void printBlockInfo(raw_ostream &OS, const GCOVBlock &Block, uint32_t LineIndex, uint32_t &BlockNo) const; void printBranchInfo(raw_ostream &OS, const GCOVBlock &Block, @@ -407,23 +420,21 @@ private: void printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo, uint64_t Count) const; - void printCoverage(const GCOVCoverage &Coverage) const; - void printFuncCoverage() const; - void printFileCoverage() const; + void printCoverage(raw_ostream &OS, const GCOVCoverage &Coverage) const; + void printFuncCoverage(raw_ostream &OS) const; + void printFileCoverage(raw_ostream &OS) const; const GCOVOptions &Options; StringMap<LineData> LineInfo; uint32_t RunCount; uint32_t ProgramCount; - typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4> - FileCoverageList; + typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4> FileCoverageList; typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap; FileCoverageList FileCoverages; FuncCoverageMap FuncCoverages; }; - } #endif |