Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
5.8 KiB

  1. //===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This header provides the interface to read and write coverage files that
  11. // use 'gcov' format.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_SUPPORT_GCOV_H
  15. #define LLVM_SUPPORT_GCOV_H
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/ADT/StringMap.h"
  18. #include "llvm/Support/MemoryBuffer.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. namespace llvm {
  21. class GCOVFunction;
  22. class GCOVBlock;
  23. class GCOVLines;
  24. class FileInfo;
  25. namespace GCOV {
  26. enum GCOVFormat {
  27. InvalidGCOV,
  28. GCNO_402,
  29. GCNO_404,
  30. GCDA_402,
  31. GCDA_404
  32. };
  33. } // end GCOV namespace
  34. /// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
  35. /// read operations.
  36. class GCOVBuffer {
  37. public:
  38. GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {}
  39. /// readGCOVFormat - Read GCOV signature at the beginning of buffer.
  40. GCOV::GCOVFormat readGCOVFormat() {
  41. StringRef Magic = Buffer->getBuffer().slice(0, 12);
  42. Cursor = 12;
  43. if (Magic == "oncg*404MVLL")
  44. return GCOV::GCNO_404;
  45. else if (Magic == "oncg*204MVLL")
  46. return GCOV::GCNO_402;
  47. else if (Magic == "adcg*404MVLL")
  48. return GCOV::GCDA_404;
  49. else if (Magic == "adcg*204MVLL")
  50. return GCOV::GCDA_402;
  51. Cursor = 0;
  52. return GCOV::InvalidGCOV;
  53. }
  54. /// readFunctionTag - If cursor points to a function tag then increment the
  55. /// cursor and return true otherwise return false.
  56. bool readFunctionTag() {
  57. StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
  58. if (Tag.empty() ||
  59. Tag[0] != '\0' || Tag[1] != '\0' ||
  60. Tag[2] != '\0' || Tag[3] != '\1') {
  61. return false;
  62. }
  63. Cursor += 4;
  64. return true;
  65. }
  66. /// readBlockTag - If cursor points to a block tag then increment the
  67. /// cursor and return true otherwise return false.
  68. bool readBlockTag() {
  69. StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
  70. if (Tag.empty() ||
  71. Tag[0] != '\0' || Tag[1] != '\0' ||
  72. Tag[2] != '\x41' || Tag[3] != '\x01') {
  73. return false;
  74. }
  75. Cursor += 4;
  76. return true;
  77. }
  78. /// readEdgeTag - If cursor points to an edge tag then increment the
  79. /// cursor and return true otherwise return false.
  80. bool readEdgeTag() {
  81. StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
  82. if (Tag.empty() ||
  83. Tag[0] != '\0' || Tag[1] != '\0' ||
  84. Tag[2] != '\x43' || Tag[3] != '\x01') {
  85. return false;
  86. }
  87. Cursor += 4;
  88. return true;
  89. }
  90. /// readLineTag - If cursor points to a line tag then increment the
  91. /// cursor and return true otherwise return false.
  92. bool readLineTag() {
  93. StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
  94. if (Tag.empty() ||
  95. Tag[0] != '\0' || Tag[1] != '\0' ||
  96. Tag[2] != '\x45' || Tag[3] != '\x01') {
  97. return false;
  98. }
  99. Cursor += 4;
  100. return true;
  101. }
  102. /// readArcTag - If cursor points to an gcda arc tag then increment the
  103. /// cursor and return true otherwise return false.
  104. bool readArcTag() {
  105. StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
  106. if (Tag.empty() ||
  107. Tag[0] != '\0' || Tag[1] != '\0' ||
  108. Tag[2] != '\xa1' || Tag[3] != '\1') {
  109. return false;
  110. }
  111. Cursor += 4;
  112. return true;
  113. }
  114. uint32_t readInt() {
  115. uint32_t Result;
  116. StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
  117. assert (Str.empty() == false && "Unexpected memory buffer end!");
  118. Cursor += 4;
  119. Result = *(const uint32_t *)(Str.data());
  120. return Result;
  121. }
  122. uint64_t readInt64() {
  123. uint64_t Lo = readInt();
  124. uint64_t Hi = readInt();
  125. uint64_t Result = Lo | (Hi << 32);
  126. return Result;
  127. }
  128. StringRef readString() {
  129. uint32_t Len = readInt() * 4;
  130. StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len);
  131. Cursor += Len;
  132. return Str;
  133. }
  134. uint64_t getCursor() const { return Cursor; }
  135. private:
  136. MemoryBuffer *Buffer;
  137. uint64_t Cursor;
  138. };
  139. /// GCOVFile - Collects coverage information for one pair of coverage file
  140. /// (.gcno and .gcda).
  141. class GCOVFile {
  142. public:
  143. GCOVFile() {}
  144. ~GCOVFile();
  145. bool read(GCOVBuffer &Buffer);
  146. void dump();
  147. void collectLineCounts(FileInfo &FI);
  148. private:
  149. SmallVector<GCOVFunction *, 16> Functions;
  150. };
  151. /// GCOVFunction - Collects function information.
  152. class GCOVFunction {
  153. public:
  154. GCOVFunction() : Ident(0), LineNumber(0) {}
  155. ~GCOVFunction();
  156. bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format);
  157. void dump();
  158. void collectLineCounts(FileInfo &FI);
  159. private:
  160. uint32_t Ident;
  161. uint32_t LineNumber;
  162. StringRef Name;
  163. StringRef Filename;
  164. SmallVector<GCOVBlock *, 16> Blocks;
  165. };
  166. /// GCOVBlock - Collects block information.
  167. class GCOVBlock {
  168. public:
  169. GCOVBlock(uint32_t N) : Number(N), Counter(0) {}
  170. ~GCOVBlock();
  171. void addEdge(uint32_t N) { Edges.push_back(N); }
  172. void addLine(StringRef Filename, uint32_t LineNo);
  173. void addCount(uint64_t N) { Counter = N; }
  174. void dump();
  175. void collectLineCounts(FileInfo &FI);
  176. private:
  177. uint32_t Number;
  178. uint64_t Counter;
  179. SmallVector<uint32_t, 16> Edges;
  180. StringMap<GCOVLines *> Lines;
  181. };
  182. /// GCOVLines - A wrapper around a vector of int to keep track of line nos.
  183. class GCOVLines {
  184. public:
  185. ~GCOVLines() { Lines.clear(); }
  186. void add(uint32_t N) { Lines.push_back(N); }
  187. void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count);
  188. void dump();
  189. private:
  190. SmallVector<uint32_t, 4> Lines;
  191. };
  192. typedef SmallVector<uint32_t, 16> LineCounts;
  193. class FileInfo {
  194. public:
  195. void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count);
  196. void print();
  197. private:
  198. StringMap<LineCounts> LineInfo;
  199. };
  200. }
  201. #endif