diff options
author | Devang Patel <dpatel@apple.com> | 2011-10-04 17:24:48 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2011-10-04 17:24:48 +0000 |
commit | 58c620024ad00eae80a766e8e2b3b1d9414dc4cf (patch) | |
tree | c9023032fb190a9acac8b12337d33bb510ee86f8 /tools/llvm-cov | |
parent | 1f121e844fad436b6fcf8981cc9297f7aad43125 (diff) |
Put GCOVFile and other related interface in a common header so that llvm-cov tool can share it with GCOV writer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141095 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-cov')
-rw-r--r-- | tools/llvm-cov/GCOVReader.cpp | 281 | ||||
-rw-r--r-- | tools/llvm-cov/GCOVReader.h | 224 | ||||
-rw-r--r-- | tools/llvm-cov/llvm-cov.cpp | 2 |
3 files changed, 1 insertions, 506 deletions
diff --git a/tools/llvm-cov/GCOVReader.cpp b/tools/llvm-cov/GCOVReader.cpp deleted file mode 100644 index 2b40a84f8e..0000000000 --- a/tools/llvm-cov/GCOVReader.cpp +++ /dev/null @@ -1,281 +0,0 @@ -//===- tools/llvm-cov/GCOVReader.cpp - LLVM coverage tool -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// GCOVReader implements the interface to read coverage files that use 'gcov' -// format. -// -//===----------------------------------------------------------------------===// - -#include "GCOVReader.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/MemoryObject.h" -#include "llvm/Support/system_error.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// GCOVFile implementation. - -/// ~GCOVFile - Delete GCOVFile and its content. -GCOVFile::~GCOVFile() { - DeleteContainerPointers(Functions); -} - -/// isGCDAFile - Return true if Format identifies a .gcda file. -static bool isGCDAFile(GCOVFormat Format) { - return Format == GCDA_402 || Format == GCDA_404; -} - -/// isGCNOFile - Return true if Format identifies a .gcno file. -static bool isGCNOFile(GCOVFormat Format) { - return Format == GCNO_402 || Format == GCNO_404; -} - -/// read - Read GCOV buffer. -bool GCOVFile::read(GCOVBuffer &Buffer) { - GCOVFormat Format = Buffer.readGCOVFormat(); - if (Format == InvalidGCOV) - return false; - - unsigned i = 0; - while (1) { - GCOVFunction *GFun = NULL; - if (isGCDAFile(Format)) { - // Use existing function while reading .gcda file. - assert (i < Functions.size() && ".gcda data does not match .gcno data"); - GFun = Functions[i]; - } else if (isGCNOFile(Format)){ - GFun = new GCOVFunction(); - Functions.push_back(GFun); - } - if (!GFun || !GFun->read(Buffer, Format)) - break; - ++i; - } - return true; -} - -/// dump - Dump GCOVFile content on standard out for debugging purposes. -void GCOVFile::dump() { - for (SmallVector<GCOVFunction *, 16>::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) - (*I)->dump(); -} - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVFile::collectLineCounts(FileInfo &FI) { - for (SmallVector<GCOVFunction *, 16>::iterator I = Functions.begin(), - E = Functions.end(); I != E; ++I) - (*I)->collectLineCounts(FI); - FI.print(); -} - -//===----------------------------------------------------------------------===// -// GCOVFunction implementation. - -/// ~GCOVFunction - Delete GCOVFunction and its content. -GCOVFunction::~GCOVFunction() { - DeleteContainerPointers(Blocks); -} - -/// read - Read a aunction from the buffer. Return false if buffer cursor -/// does not point to a function tag. -bool GCOVFunction::read(GCOVBuffer &Buff, GCOVFormat Format) { - if (!Buff.readFunctionTag()) - return false; - - Buff.readInt(); // Function header length - Ident = Buff.readInt(); - Buff.readInt(); // Checksum #1 - if (Format != GCNO_402) - Buff.readInt(); // Checksum #2 - - Name = Buff.readString(); - if (Format == GCNO_402 || Format == GCNO_404) - Filename = Buff.readString(); - - if (Format == GCDA_402 || Format == GCDA_404) { - Buff.readArcTag(); - uint32_t Count = Buff.readInt() / 2; - for (unsigned i = 0, e = Count; i != e; ++i) { - Blocks[i]->addCount(Buff.readInt64()); - } - return true;; - } - - LineNumber = Buff.readInt(); - - // read blocks. - assert (Buff.readBlockTag() && "Block Tag not found!"); - uint32_t BlockCount = Buff.readInt(); - for (int i = 0, e = BlockCount; i != e; ++i) { - Buff.readInt(); // Block flags; - Blocks.push_back(new GCOVBlock(i)); - } - - // read edges. - while (Buff.readEdgeTag()) { - uint32_t EdgeCount = (Buff.readInt() - 1) / 2; - uint32_t BlockNo = Buff.readInt(); - assert (BlockNo < BlockCount && "Unexpected Block number!"); - for (int i = 0, e = EdgeCount; i != e; ++i) { - Blocks[BlockNo]->addEdge(Buff.readInt()); - Buff.readInt(); // Edge flag - } - } - - // read line table. - while (Buff.readLineTag()) { - uint32_t LineTableLength = Buff.readInt(); - uint32_t Size = Buff.getCursor() + LineTableLength*4; - uint32_t BlockNo = Buff.readInt(); - assert (BlockNo < BlockCount && "Unexpected Block number!"); - GCOVBlock *Block = Blocks[BlockNo]; - Buff.readInt(); // flag - while (Buff.getCursor() != (Size - 4)) { - StringRef Filename = Buff.readString(); - if (Buff.getCursor() == (Size - 4)) break; - while (uint32_t L = Buff.readInt()) - Block->addLine(Filename, L); - } - Buff.readInt(); // flag - } - return true; -} - -/// dump - Dump GCOVFunction content on standard out for debugging purposes. -void GCOVFunction::dump() { - outs() << "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n"; - for (SmallVector<GCOVBlock *, 16>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - (*I)->dump(); -} - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVFunction::collectLineCounts(FileInfo &FI) { - for (SmallVector<GCOVBlock *, 16>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - (*I)->collectLineCounts(FI); -} - -//===----------------------------------------------------------------------===// -// GCOVBlock implementation. - -/// ~GCOVBlock - Delete GCOVBlock and its content. -GCOVBlock::~GCOVBlock() { - Edges.clear(); - DeleteContainerSeconds(Lines); -} - -void GCOVBlock::addLine(StringRef Filename, uint32_t LineNo) { - GCOVLines *&LinesForFile = Lines[Filename]; - if (!LinesForFile) - LinesForFile = new GCOVLines(); - LinesForFile->add(LineNo); -} - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVBlock::collectLineCounts(FileInfo &FI) { - for (StringMap<GCOVLines *>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - I->second->collectLineCounts(FI, I->first(), Counter); -} - -/// dump - Dump GCOVBlock content on standard out for debugging purposes. -void GCOVBlock::dump() { - outs() << "Block : " << Number << " Counter : " << Counter << "\n"; - if (!Edges.empty()) { - outs() << "\tEdges : "; - for (SmallVector<uint32_t, 16>::iterator I = Edges.begin(), E = Edges.end(); - I != E; ++I) - outs() << (*I) << ","; - outs() << "\n"; - } - if (!Lines.empty()) { - outs() << "\tLines : "; - for (StringMap<GCOVLines *>::iterator LI = Lines.begin(), - LE = Lines.end(); LI != LE; ++LI) { - outs() << LI->first() << " -> "; - LI->second->dump(); - outs() << "\n"; - } - } -} - -//===----------------------------------------------------------------------===// -// GCOVLines implementation. - -/// collectLineCounts - Collect line counts. This must be used after -/// reading .gcno and .gcda files. -void GCOVLines::collectLineCounts(FileInfo &FI, StringRef Filename, - uint32_t Count) { - for (SmallVector<uint32_t, 16>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - FI.addLineCount(Filename, *I, Count); -} - -/// dump - Dump GCOVLines content on standard out for debugging purposes. -void GCOVLines::dump() { - for (SmallVector<uint32_t, 16>::iterator I = Lines.begin(), - E = Lines.end(); I != E; ++I) - outs() << (*I) << ","; -} - -//===----------------------------------------------------------------------===// -// FileInfo implementation. - -/// addLineCount - Add line count for the given line number in a file. -void FileInfo::addLineCount(StringRef Filename, uint32_t Line, uint32_t Count) { - if (LineInfo.find(Filename) == LineInfo.end()) { - OwningPtr<MemoryBuffer> Buff; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << Filename << ": " << ec.message() << "\n"; - return; - } - StringRef AllLines = Buff.take()->getBuffer(); - LineCounts L(AllLines.count('\n')+2); - L[Line-1] = Count; - LineInfo[Filename] = L; - return; - } - LineCounts &L = LineInfo[Filename]; - L[Line-1] = Count; -} - -/// print - Print source files with collected line count information. -void FileInfo::print() { - for (StringMap<LineCounts>::iterator I = LineInfo.begin(), E = LineInfo.end(); - I != E; ++I) { - StringRef Filename = I->first(); - outs() << Filename << "\n"; - LineCounts &L = LineInfo[Filename]; - OwningPtr<MemoryBuffer> Buff; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << Filename << ": " << ec.message() << "\n"; - return; - } - StringRef AllLines = Buff.take()->getBuffer(); - for (unsigned i = 0, e = L.size(); i != e; ++i) { - if (L[i]) - outs() << L[i] << ":\t"; - else - outs() << " :\t"; - std::pair<StringRef, StringRef> P = AllLines.split('\n'); - if (AllLines != P.first) - outs() << P.first; - outs() << "\n"; - AllLines = P.second; - } - } -} - - diff --git a/tools/llvm-cov/GCOVReader.h b/tools/llvm-cov/GCOVReader.h deleted file mode 100644 index 98a556c78d..0000000000 --- a/tools/llvm-cov/GCOVReader.h +++ /dev/null @@ -1,224 +0,0 @@ -//===-- tools/llvm-cov/GCOVReader.h - LLVM coverage tool --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header provides the interface to read coverage files that use 'gcov' -// format. -// -//===----------------------------------------------------------------------===// - -#ifndef GCOVREADER_H -#define GCOVREADER_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvm { - -class GCOVFunction; -class GCOVBlock; -class GCOVLines; -class FileInfo; - -enum GCOVFormat { - InvalidGCOV, - GCNO_402, - GCNO_404, - GCDA_402, - GCDA_404 -}; - -/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific -/// read operations. -class GCOVBuffer { -public: - GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {} - - /// readGCOVFormat - Read GCOV signature at the beginning of buffer. - enum GCOVFormat readGCOVFormat() { - StringRef Magic = Buffer->getBuffer().slice(0, 12); - Cursor = 12; - if (Magic == "oncg*404MVLL") - return GCNO_404; - else if (Magic == "oncg*204MVLL") - return GCNO_402; - else if (Magic == "adcg*404MVLL") - return GCDA_404; - else if (Magic == "adcg*204MVLL") - return GCDA_402; - - Cursor = 0; - return InvalidGCOV; - } - - /// 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') { - return false; - } - Cursor += 4; - return true; - } - - /// 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') { - return false; - } - Cursor += 4; - return true; - } - - /// 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') { - return false; - } - Cursor += 4; - return true; - } - - /// 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') { - return false; - } - Cursor += 4; - return true; - } - - /// 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') { - return false; - } - Cursor += 4; - return true; - } - - uint32_t readInt() { - uint32_t Result; - StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4); - assert (Str.empty() == false && "Unexpected memory buffer end!"); - Cursor += 4; - Result = *(uint32_t *)(Str.data()); - return Result; - } - - uint64_t readInt64() { - uint64_t Lo = readInt(); - uint64_t Hi = readInt(); - uint64_t Result = Lo | (Hi << 32); - return Result; - } - - StringRef readString() { - uint32_t Len = readInt() * 4; - StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len); - Cursor += Len; - return Str; - } - - uint64_t getCursor() const { return Cursor; } -private: - MemoryBuffer *Buffer; - uint64_t Cursor; -}; - -/// GCOVFile - Collects coverage information for one pair of coverage file -/// (.gcno and .gcda). -class GCOVFile { -public: - GCOVFile() {} - ~GCOVFile(); - bool read(GCOVBuffer &Buffer); - void dump(); - void collectLineCounts(FileInfo &FI); -private: - SmallVector<GCOVFunction *, 16> Functions; -}; - -/// GCOVFunction - Collects function information. -class GCOVFunction { -public: - GCOVFunction() : Ident(0), LineNumber(0) {} - ~GCOVFunction(); - bool read(GCOVBuffer &Buffer, GCOVFormat Format); - void dump(); - void collectLineCounts(FileInfo &FI); -private: - uint32_t Ident; - uint32_t LineNumber; - StringRef Name; - StringRef Filename; - SmallVector<GCOVBlock *, 16> Blocks; -}; - -/// GCOVBlock - Collects block information. -class GCOVBlock { -public: - GCOVBlock(uint32_t N) : Number(N), Counter(0) {} - ~GCOVBlock(); - void addEdge(uint32_t N) { Edges.push_back(N); } - void addLine(StringRef Filename, uint32_t LineNo); - void addCount(uint64_t N) { Counter = N; } - void dump(); - void collectLineCounts(FileInfo &FI); -private: - uint32_t Number; - uint64_t Counter; - SmallVector<uint32_t, 16> Edges; - StringMap<GCOVLines *> Lines; -}; - -/// GCOVLines - A wrapper around a vector of int to keep track of line nos. -class GCOVLines { -public: - ~GCOVLines() { Lines.clear(); } - void add(uint32_t N) { Lines.push_back(N); } - void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count); - void dump(); - -private: - SmallVector<uint32_t, 4> Lines; -}; - -typedef SmallVector<uint32_t, 16> LineCounts; -class FileInfo { -public: - void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count); - void print(); -private: - StringMap<LineCounts> LineInfo; -}; - -} - -#endif diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index 5e4c1ec9de..7b21c5bae2 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "GCOVReader.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/GCOV.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryObject.h" #include "llvm/Support/PrettyStackTrace.h" |