mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +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
 |