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