xref: /freebsd/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/ASTReader.h"
21 #include "clang/Serialization/ASTWriter.h"
22 #include "clang/Serialization/SourceLocationEncoding.h"
23 
24 namespace clang {
25 
26 class OpenACCClause;
27 class TypeLoc;
28 
29 /// An object for streaming information to a record.
30 class ASTRecordWriter
31     : public serialization::DataStreamBasicWriter<ASTRecordWriter> {
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(ASTContext & Context,ASTWriter & W,ASTWriter::RecordDataImpl & Record)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.
ASTRecordWriter(ASTRecordWriter & Parent,ASTWriter::RecordDataImpl & Record)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.
getRecordData()78   ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
79 
80   /// Minimal vector-like interface.
81   /// @{
push_back(uint64_t N)82   void push_back(uint64_t N) { Record->push_back(N); }
83   template<typename InputIterator>
append(InputIterator begin,InputIterator end)84   void append(InputIterator begin, InputIterator end) {
85     Record->append(begin, end);
86   }
empty()87   bool empty() const { return Record->empty(); }
size()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.
AddOffset(uint64_t BitOffset)113   void AddOffset(uint64_t BitOffset) {
114     OffsetIndices.push_back(Record->size());
115     Record->push_back(BitOffset);
116   }
117 
AddLookupOffsets(const LookupBlockOffsets & Offsets)118   void AddLookupOffsets(const LookupBlockOffsets &Offsets) {
119     AddOffset(Offsets.LexicalOffset);
120     AddOffset(Offsets.VisibleOffset);
121     AddOffset(Offsets.ModuleLocalOffset);
122     AddOffset(Offsets.TULocalOffset);
123   }
124 
125   /// Add the given statement or expression to the queue of
126   /// statements to emit.
127   ///
128   /// This routine should be used when emitting types and declarations
129   /// that have expressions as part of their formulation. Once the
130   /// type or declaration has been written, Emit() will write
131   /// the corresponding statements just after the record.
AddStmt(Stmt * S)132   void AddStmt(Stmt *S) {
133     StmtsToEmit.push_back(S);
134   }
writeStmtRef(const Stmt * S)135   void writeStmtRef(const Stmt *S) {
136     AddStmt(const_cast<Stmt*>(S));
137   }
138 
writeAttr(const Attr * A)139   void writeAttr(const Attr *A) { AddAttr(A); }
140 
141   /// Write an BTFTypeTagAttr object.
writeBTFTypeTagAttr(const BTFTypeTagAttr * A)142   void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }
143 
144   /// Add a definition for the given function to the queue of statements
145   /// to emit.
146   void AddFunctionDefinition(const FunctionDecl *FD);
147 
148   /// Emit a source location.
AddSourceLocation(SourceLocation Loc)149   void AddSourceLocation(SourceLocation Loc) {
150     return Writer->AddSourceLocation(Loc, *Record);
151   }
writeSourceLocation(SourceLocation Loc)152   void writeSourceLocation(SourceLocation Loc) {
153     AddSourceLocation(Loc);
154   }
155 
writeTypeCoupledDeclRefInfo(TypeCoupledDeclRefInfo Info)156   void writeTypeCoupledDeclRefInfo(TypeCoupledDeclRefInfo Info) {
157     writeDeclRef(Info.getDecl());
158     writeBool(Info.isDeref());
159   }
160 
writeHLSLSpirvOperand(SpirvOperand Op)161   void writeHLSLSpirvOperand(SpirvOperand Op) {
162     QualType ResultType;
163     llvm::APInt Value;
164 
165     if (Op.isConstant() || Op.isType())
166       ResultType = Op.getResultType();
167     if (Op.isConstant() || Op.isLiteral())
168       Value = Op.getValue();
169 
170     Record->push_back(Op.getKind());
171     writeQualType(ResultType);
172     writeAPInt(Value);
173   }
174 
175   /// Emit a source range.
AddSourceRange(SourceRange Range)176   void AddSourceRange(SourceRange Range) {
177     return Writer->AddSourceRange(Range, *Record);
178   }
179 
writeBool(bool Value)180   void writeBool(bool Value) {
181     Record->push_back(Value);
182   }
183 
writeUInt32(uint32_t Value)184   void writeUInt32(uint32_t Value) {
185     Record->push_back(Value);
186   }
187 
writeUInt64(uint64_t Value)188   void writeUInt64(uint64_t Value) {
189     Record->push_back(Value);
190   }
191 
writeUnsignedOrNone(UnsignedOrNone Value)192   void writeUnsignedOrNone(UnsignedOrNone Value) {
193     Record->push_back(Value.toInternalRepresentation());
194   }
195 
196   /// Emit an integral value.
AddAPInt(const llvm::APInt & Value)197   void AddAPInt(const llvm::APInt &Value) {
198     writeAPInt(Value);
199   }
200 
201   /// Emit a signed integral value.
AddAPSInt(const llvm::APSInt & Value)202   void AddAPSInt(const llvm::APSInt &Value) {
203     writeAPSInt(Value);
204   }
205 
206   /// Emit a floating-point value.
207   void AddAPFloat(const llvm::APFloat &Value);
208 
209   /// Emit an APvalue.
AddAPValue(const APValue & Value)210   void AddAPValue(const APValue &Value) { writeAPValue(Value); }
211 
212   /// Emit a reference to an identifier.
AddIdentifierRef(const IdentifierInfo * II)213   void AddIdentifierRef(const IdentifierInfo *II) {
214     return Writer->AddIdentifierRef(II, *Record);
215   }
writeIdentifier(const IdentifierInfo * II)216   void writeIdentifier(const IdentifierInfo *II) {
217     AddIdentifierRef(II);
218   }
219 
220   /// Emit a Selector (which is a smart pointer reference).
221   void AddSelectorRef(Selector S);
writeSelector(Selector sel)222   void writeSelector(Selector sel) {
223     AddSelectorRef(sel);
224   }
225 
226   /// Emit a CXXTemporary.
227   void AddCXXTemporary(const CXXTemporary *Temp);
228 
229   /// Emit a C++ base specifier.
230   void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
231 
232   /// Emit a set of C++ base specifiers.
233   void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);
234 
235   /// Emit a reference to a type.
AddTypeRef(QualType T)236   void AddTypeRef(QualType T) {
237     return Writer->AddTypeRef(getASTContext(), T, *Record);
238   }
writeQualType(QualType T)239   void writeQualType(QualType T) {
240     AddTypeRef(T);
241   }
242 
243   /// Emits a reference to a declarator info.
244   void AddTypeSourceInfo(TypeSourceInfo *TInfo);
245 
246   /// Emits source location information for a type. Does not emit the type.
247   void AddTypeLoc(TypeLoc TL);
248 
249   /// Emits a template argument location info.
250   void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
251                                   const TemplateArgumentLocInfo &Arg);
252 
253   /// Emits a template argument location.
254   void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
255 
256   /// Emits an AST template argument list info.
257   void AddASTTemplateArgumentListInfo(
258       const ASTTemplateArgumentListInfo *ASTTemplArgList);
259 
260   // Emits a concept reference.
261   void AddConceptReference(const ConceptReference *CR);
262 
263   /// Emit a reference to a declaration.
AddDeclRef(const Decl * D)264   void AddDeclRef(const Decl *D) {
265     return Writer->AddDeclRef(D, *Record);
266   }
writeDeclRef(const Decl * D)267   void writeDeclRef(const Decl *D) {
268     AddDeclRef(D);
269   }
270 
271   /// Emit a declaration name.
AddDeclarationName(DeclarationName Name)272   void AddDeclarationName(DeclarationName Name) {
273     writeDeclarationName(Name);
274   }
275 
276   void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
277                              DeclarationName Name);
278   void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
279 
280   void AddQualifierInfo(const QualifierInfo &Info);
281 
282   /// Emit a nested name specifier.
AddNestedNameSpecifier(NestedNameSpecifier * NNS)283   void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
284     writeNestedNameSpecifier(NNS);
285   }
286 
287   /// Emit a nested name specifier with source-location information.
288   void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
289 
290   /// Emit a template name.
AddTemplateName(TemplateName Name)291   void AddTemplateName(TemplateName Name) {
292     writeTemplateName(Name);
293   }
294 
295   /// Emit a template argument.
AddTemplateArgument(const TemplateArgument & Arg)296   void AddTemplateArgument(const TemplateArgument &Arg) {
297     writeTemplateArgument(Arg);
298   }
299 
300   /// Emit a template parameter list.
301   void AddTemplateParameterList(const TemplateParameterList *TemplateParams);
302 
303   /// Emit a template argument list.
304   void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);
305 
306   /// Emit a UnresolvedSet structure.
307   void AddUnresolvedSet(const ASTUnresolvedSet &Set);
308 
309   /// Emit a CXXCtorInitializer array.
310   void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);
311 
312   void AddCXXDefinitionData(const CXXRecordDecl *D);
313 
314   /// Emit information about the initializer of a VarDecl.
315   void AddVarDeclInit(const VarDecl *VD);
316 
317   /// Write an OMPTraitInfo object.
318   void writeOMPTraitInfo(const OMPTraitInfo *TI);
319 
320   void writeOMPClause(OMPClause *C);
321 
322   /// Writes data related to the OpenMP directives.
323   void writeOMPChildren(OMPChildren *Data);
324 
325   void writeOpenACCVarList(const OpenACCClauseWithVarList *C);
326 
327   void writeOpenACCIntExprList(ArrayRef<Expr *> Exprs);
328 
329   /// Writes out a single OpenACC Clause.
330   void writeOpenACCClause(const OpenACCClause *C);
331 
332   /// Writes out a list of OpenACC clauses.
333   void writeOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses);
334 
335   void AddOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);
336 
337   /// Emit a string.
AddString(StringRef Str)338   void AddString(StringRef Str) {
339     return Writer->AddString(Str, *Record);
340   }
341 
342   /// Emit a path.
AddPath(StringRef Path)343   void AddPath(StringRef Path) {
344     return Writer->AddPath(Path, *Record);
345   }
346 
347   /// Emit a version tuple.
AddVersionTuple(const VersionTuple & Version)348   void AddVersionTuple(const VersionTuple &Version) {
349     return Writer->AddVersionTuple(Version, *Record);
350   }
351 
352   // Emit an attribute.
353   void AddAttr(const Attr *A);
354 
355   /// Emit a list of attributes.
356   void AddAttributes(ArrayRef<const Attr*> Attrs);
357 };
358 
359 } // end namespace clang
360 
361 #endif
362