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