mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172025 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			227 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- llvm/Support/GCOV.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 and write coverage files that 
 | |
| // use 'gcov' format.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_SUPPORT_GCOV_H
 | |
| #define LLVM_SUPPORT_GCOV_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;
 | |
| 
 | |
| namespace GCOV {
 | |
|   enum GCOVFormat {
 | |
|     InvalidGCOV,
 | |
|     GCNO_402,
 | |
|     GCNO_404,
 | |
|     GCDA_402,
 | |
|     GCDA_404
 | |
|   };
 | |
| } // end GCOV namespace
 | |
| 
 | |
| /// 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.
 | |
|   GCOV::GCOVFormat readGCOVFormat() {
 | |
|     StringRef Magic = Buffer->getBuffer().slice(0, 12);
 | |
|     Cursor = 12;
 | |
|     if (Magic == "oncg*404MVLL")
 | |
|       return GCOV::GCNO_404;
 | |
|     else if (Magic == "oncg*204MVLL")
 | |
|       return GCOV::GCNO_402;
 | |
|     else if (Magic == "adcg*404MVLL")
 | |
|       return GCOV::GCDA_404;
 | |
|     else if (Magic == "adcg*204MVLL")
 | |
|       return GCOV::GCDA_402;
 | |
|     
 | |
|     Cursor = 0;
 | |
|     return GCOV::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 = *(const 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, GCOV::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
 |