//===-- 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_GCOV_H
#define LLVM_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;

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
