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

source code of clang/include/clang/Serialization/ASTRecordWriter.h