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