/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ASTRecordWriter.h - Helper classes for writing AST -------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file defines the ASTRecordWriter class, a helper class useful |
10 | | // when serializing AST. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H |
15 | | #define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H |
16 | | |
17 | | #include "clang/AST/AbstractBasicWriter.h" |
18 | | #include "clang/AST/OpenMPClause.h" |
19 | | #include "clang/Serialization/ASTWriter.h" |
20 | | |
21 | | namespace clang { |
22 | | |
23 | | class TypeLoc; |
24 | | |
25 | | /// An object for streaming information to a record. |
26 | | class ASTRecordWriter |
27 | | : public serialization::DataStreamBasicWriter<ASTRecordWriter> { |
28 | | ASTWriter *Writer; |
29 | | ASTWriter::RecordDataImpl *Record; |
30 | | |
31 | | /// Statements that we've encountered while serializing a |
32 | | /// declaration or type. |
33 | | SmallVector<Stmt *, 16> StmtsToEmit; |
34 | | |
35 | | /// Indices of record elements that describe offsets within the |
36 | | /// bitcode. These will be converted to offsets relative to the current |
37 | | /// record when emitted. |
38 | | SmallVector<unsigned, 8> OffsetIndices; |
39 | | |
40 | | /// Flush all of the statements and expressions that have |
41 | | /// been added to the queue via AddStmt(). |
42 | | void FlushStmts(); |
43 | | void FlushSubStmts(); |
44 | | |
45 | 9.86M | void PrepareToEmit(uint64_t MyOffset) { |
46 | | // Convert offsets into relative form. |
47 | 1.82M | for (unsigned I : OffsetIndices) { |
48 | 1.82M | auto &StoredOffset = (*Record)[I]; |
49 | 1.82M | assert(StoredOffset < MyOffset && "invalid offset"); |
50 | 1.82M | if (StoredOffset) |
51 | 569k | StoredOffset = MyOffset - StoredOffset; |
52 | 1.82M | } |
53 | 9.86M | OffsetIndices.clear(); |
54 | 9.86M | } |
55 | | |
56 | | public: |
57 | | /// Construct a ASTRecordWriter that uses the default encoding scheme. |
58 | | ASTRecordWriter(ASTWriter &W, ASTWriter::RecordDataImpl &Record) |
59 | 10.4M | : DataStreamBasicWriter(W.getASTContext()), Writer(&W), Record(&Record) {} |
60 | | |
61 | | /// Construct a ASTRecordWriter that uses the same encoding scheme as another |
62 | | /// ASTRecordWriter. |
63 | | ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record) |
64 | | : DataStreamBasicWriter(Parent.getASTContext()), Writer(Parent.Writer), |
65 | 77.0k | Record(&Record) {} |
66 | | |
67 | | /// Copying an ASTRecordWriter is almost certainly a bug. |
68 | | ASTRecordWriter(const ASTRecordWriter &) = delete; |
69 | | ASTRecordWriter &operator=(const ASTRecordWriter &) = delete; |
70 | | |
71 | | /// Extract the underlying record storage. |
72 | 0 | ASTWriter::RecordDataImpl &getRecordData() const { return *Record; } |
73 | | |
74 | | /// Minimal vector-like interface. |
75 | | /// @{ |
76 | 141M | void push_back(uint64_t N) { Record->push_back(N); } |
77 | | template<typename InputIterator> |
78 | 53.4k | void append(InputIterator begin, InputIterator end) { |
79 | 53.4k | Record->append(begin, end); |
80 | 53.4k | } |
81 | 0 | bool empty() const { return Record->empty(); } |
82 | 260k | size_t size() const { return Record->size(); } |
83 | 130k | uint64_t &operator[](size_t N) { return (*Record)[N]; } |
84 | | /// @} |
85 | | |
86 | | /// Emit the record to the stream, followed by its substatements, and |
87 | | /// return its offset. |
88 | | // FIXME: Allow record producers to suggest Abbrevs. |
89 | 4.94M | uint64_t Emit(unsigned Code, unsigned Abbrev = 0) { |
90 | 4.94M | uint64_t Offset = Writer->Stream.GetCurrentBitNo(); |
91 | 4.94M | PrepareToEmit(Offset); |
92 | 4.94M | Writer->Stream.EmitRecord(Code, *Record, Abbrev); |
93 | 4.94M | FlushStmts(); |
94 | 4.94M | return Offset; |
95 | 4.94M | } |
96 | | |
97 | | /// Emit the record to the stream, preceded by its substatements. |
98 | 4.92M | uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) { |
99 | 4.92M | FlushSubStmts(); |
100 | 4.92M | PrepareToEmit(Writer->Stream.GetCurrentBitNo()); |
101 | 4.92M | Writer->Stream.EmitRecord(Code, *Record, Abbrev); |
102 | 4.92M | return Writer->Stream.GetCurrentBitNo(); |
103 | 4.92M | } |
104 | | |
105 | | /// Add a bit offset into the record. This will be converted into an |
106 | | /// offset relative to the current record when emitted. |
107 | 1.82M | void AddOffset(uint64_t BitOffset) { |
108 | 1.82M | OffsetIndices.push_back(Record->size()); |
109 | 1.82M | Record->push_back(BitOffset); |
110 | 1.82M | } |
111 | | |
112 | | /// Add the given statement or expression to the queue of |
113 | | /// statements to emit. |
114 | | /// |
115 | | /// This routine should be used when emitting types and declarations |
116 | | /// that have expressions as part of their formulation. Once the |
117 | | /// type or declaration has been written, Emit() will write |
118 | | /// the corresponding statements just after the record. |
119 | 5.60M | void AddStmt(Stmt *S) { |
120 | 5.60M | StmtsToEmit.push_back(S); |
121 | 5.60M | } |
122 | 268k | void writeStmtRef(const Stmt *S) { |
123 | 268k | AddStmt(const_cast<Stmt*>(S)); |
124 | 268k | } |
125 | | |
126 | | /// Add a definition for the given function to the queue of statements |
127 | | /// to emit. |
128 | | void AddFunctionDefinition(const FunctionDecl *FD); |
129 | | |
130 | | /// Emit a source location. |
131 | 17.7M | void AddSourceLocation(SourceLocation Loc) { |
132 | 17.7M | return Writer->AddSourceLocation(Loc, *Record); |
133 | 17.7M | } |
134 | 5.70k | void writeSourceLocation(SourceLocation Loc) { |
135 | 5.70k | AddSourceLocation(Loc); |
136 | 5.70k | } |
137 | | |
138 | | /// Emit a source range. |
139 | 2.22M | void AddSourceRange(SourceRange Range) { |
140 | 2.22M | return Writer->AddSourceRange(Range, *Record); |
141 | 2.22M | } |
142 | | |
143 | 3.18M | void writeBool(bool Value) { |
144 | 3.18M | Record->push_back(Value); |
145 | 3.18M | } |
146 | | |
147 | 8.35M | void writeUInt32(uint32_t Value) { |
148 | 8.35M | Record->push_back(Value); |
149 | 8.35M | } |
150 | | |
151 | 627k | void writeUInt64(uint64_t Value) { |
152 | 627k | Record->push_back(Value); |
153 | 627k | } |
154 | | |
155 | | /// Emit an integral value. |
156 | 412k | void AddAPInt(const llvm::APInt &Value) { |
157 | 412k | writeAPInt(Value); |
158 | 412k | } |
159 | | |
160 | | /// Emit a signed integral value. |
161 | 175k | void AddAPSInt(const llvm::APSInt &Value) { |
162 | 175k | writeAPSInt(Value); |
163 | 175k | } |
164 | | |
165 | | /// Emit a floating-point value. |
166 | | void AddAPFloat(const llvm::APFloat &Value); |
167 | | |
168 | | /// Emit an APvalue. |
169 | 42 | void AddAPValue(const APValue &Value) { writeAPValue(Value); } |
170 | | |
171 | | /// Emit a reference to an identifier. |
172 | 6.06M | void AddIdentifierRef(const IdentifierInfo *II) { |
173 | 6.06M | return Writer->AddIdentifierRef(II, *Record); |
174 | 6.06M | } |
175 | 3.22M | void writeIdentifier(const IdentifierInfo *II) { |
176 | 3.22M | AddIdentifierRef(II); |
177 | 3.22M | } |
178 | | |
179 | | /// Emit a Selector (which is a smart pointer reference). |
180 | | void AddSelectorRef(Selector S); |
181 | 91.9k | void writeSelector(Selector sel) { |
182 | 91.9k | AddSelectorRef(sel); |
183 | 91.9k | } |
184 | | |
185 | | /// Emit a CXXTemporary. |
186 | | void AddCXXTemporary(const CXXTemporary *Temp); |
187 | | |
188 | | /// Emit a C++ base specifier. |
189 | | void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base); |
190 | | |
191 | | /// Emit a set of C++ base specifiers. |
192 | | void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases); |
193 | | |
194 | | /// Emit a reference to a type. |
195 | 13.7M | void AddTypeRef(QualType T) { |
196 | 13.7M | return Writer->AddTypeRef(T, *Record); |
197 | 13.7M | } |
198 | 2.65M | void writeQualType(QualType T) { |
199 | 2.65M | AddTypeRef(T); |
200 | 2.65M | } |
201 | | |
202 | | /// Emits a reference to a declarator info. |
203 | | void AddTypeSourceInfo(TypeSourceInfo *TInfo); |
204 | | |
205 | | /// Emits source location information for a type. Does not emit the type. |
206 | | void AddTypeLoc(TypeLoc TL); |
207 | | |
208 | | /// Emits a template argument location info. |
209 | | void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, |
210 | | const TemplateArgumentLocInfo &Arg); |
211 | | |
212 | | /// Emits a template argument location. |
213 | | void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg); |
214 | | |
215 | | /// Emits an AST template argument list info. |
216 | | void AddASTTemplateArgumentListInfo( |
217 | | const ASTTemplateArgumentListInfo *ASTTemplArgList); |
218 | | |
219 | | /// Emit a reference to a declaration. |
220 | 10.7M | void AddDeclRef(const Decl *D) { |
221 | 10.7M | return Writer->AddDeclRef(D, *Record); |
222 | 10.7M | } |
223 | 892k | void writeDeclRef(const Decl *D) { |
224 | 892k | AddDeclRef(D); |
225 | 892k | } |
226 | | |
227 | | /// Emit a declaration name. |
228 | 3.44M | void AddDeclarationName(DeclarationName Name) { |
229 | 3.44M | writeDeclarationName(Name); |
230 | 3.44M | } |
231 | | |
232 | | void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, |
233 | | DeclarationName Name); |
234 | | void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo); |
235 | | |
236 | | void AddQualifierInfo(const QualifierInfo &Info); |
237 | | |
238 | | /// Emit a nested name specifier. |
239 | 0 | void AddNestedNameSpecifier(NestedNameSpecifier *NNS) { |
240 | 0 | writeNestedNameSpecifier(NNS); |
241 | 0 | } |
242 | | |
243 | | /// Emit a nested name specifier with source-location information. |
244 | | void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); |
245 | | |
246 | | /// Emit a template name. |
247 | 0 | void AddTemplateName(TemplateName Name) { |
248 | 0 | writeTemplateName(Name); |
249 | 0 | } |
250 | | |
251 | | /// Emit a template argument. |
252 | 133k | void AddTemplateArgument(const TemplateArgument &Arg) { |
253 | 133k | writeTemplateArgument(Arg); |
254 | 133k | } |
255 | | |
256 | | /// Emit a template parameter list. |
257 | | void AddTemplateParameterList(const TemplateParameterList *TemplateParams); |
258 | | |
259 | | /// Emit a template argument list. |
260 | | void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs); |
261 | | |
262 | | /// Emit a UnresolvedSet structure. |
263 | | void AddUnresolvedSet(const ASTUnresolvedSet &Set); |
264 | | |
265 | | /// Emit a CXXCtorInitializer array. |
266 | | void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits); |
267 | | |
268 | | void AddCXXDefinitionData(const CXXRecordDecl *D); |
269 | | |
270 | | /// Emit information about the initializer of a VarDecl. |
271 | | void AddVarDeclInit(const VarDecl *VD); |
272 | | |
273 | | /// Write an OMPTraitInfo object. |
274 | | void writeOMPTraitInfo(const OMPTraitInfo *TI); |
275 | | |
276 | | void writeOMPClause(OMPClause *C); |
277 | | |
278 | | /// Writes data related to the OpenMP directives. |
279 | | void writeOMPChildren(OMPChildren *Data); |
280 | | |
281 | | /// Emit a string. |
282 | 669k | void AddString(StringRef Str) { |
283 | 669k | return Writer->AddString(Str, *Record); |
284 | 669k | } |
285 | | |
286 | | /// Emit a path. |
287 | 0 | void AddPath(StringRef Path) { |
288 | 0 | return Writer->AddPath(Path, *Record); |
289 | 0 | } |
290 | | |
291 | | /// Emit a version tuple. |
292 | 908k | void AddVersionTuple(const VersionTuple &Version) { |
293 | 908k | return Writer->AddVersionTuple(Version, *Record); |
294 | 908k | } |
295 | | |
296 | | // Emit an attribute. |
297 | | void AddAttr(const Attr *A); |
298 | | |
299 | | /// Emit a list of attributes. |
300 | | void AddAttributes(ArrayRef<const Attr*> Attrs); |
301 | | }; |
302 | | |
303 | | } // end namespace clang |
304 | | |
305 | | #endif |