1//===- ASTRecordReader.h - Helper classes for reading 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 classes that are useful in the implementation of
10// the ASTReader.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H
15#define LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H
16
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/AbstractBasicReader.h"
19#include "clang/Lex/Token.h"
20#include "clang/Serialization/ASTReader.h"
21#include "clang/Serialization/SourceLocationEncoding.h"
22#include "llvm/ADT/APFloat.h"
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/APSInt.h"
25
26namespace clang {
27class OpenACCClause;
28class OMPTraitInfo;
29class OMPChildren;
30
31/// An object for streaming information from a record.
32class ASTRecordReader
33 : public serialization::DataStreamBasicReader<ASTRecordReader> {
34 using ModuleFile = serialization::ModuleFile;
35 using LocSeq = SourceLocationSequence;
36
37 ASTReader *Reader;
38 ModuleFile *F;
39 unsigned Idx = 0;
40 ASTReader::RecordData Record;
41
42 using RecordData = ASTReader::RecordData;
43 using RecordDataImpl = ASTReader::RecordDataImpl;
44
45public:
46 /// Construct an ASTRecordReader that uses the default encoding scheme.
47 ASTRecordReader(ASTReader &Reader, ModuleFile &F)
48 : DataStreamBasicReader(Reader.getContext()), Reader(&Reader), F(&F) {}
49
50 /// Reads a record with id AbbrevID from Cursor, resetting the
51 /// internal state.
52 Expected<unsigned> readRecord(llvm::BitstreamCursor &Cursor,
53 unsigned AbbrevID);
54
55 /// Is this a module file for a module (rather than a PCH or similar).
56 bool isModule() const { return F->isModule(); }
57
58 /// Retrieve the AST context that this AST reader supplements.
59 ASTContext &getContext() { return Reader->getContext(); }
60
61 /// The current position in this record.
62 unsigned getIdx() const { return Idx; }
63
64 /// The length of this record.
65 size_t size() const { return Record.size(); }
66
67 /// An arbitrary index in this record.
68 const uint64_t &operator[](size_t N) { return Record[N]; }
69
70 /// Returns the last value in this record.
71 uint64_t back() { return Record.back(); }
72
73 /// Returns the current value in this record, and advances to the
74 /// next value.
75 uint64_t readInt() { return Record[Idx++]; }
76
77 ArrayRef<uint64_t> readIntArray(unsigned Len) {
78 auto Array = llvm::ArrayRef(Record).slice(N: Idx, M: Len);
79 Idx += Len;
80 return Array;
81 }
82
83 /// Returns the current value in this record, without advancing.
84 uint64_t peekInt() { return Record[Idx]; }
85
86 /// Skips the specified number of values.
87 void skipInts(unsigned N) { Idx += N; }
88
89 /// Retrieve the global submodule ID its local ID number.
90 serialization::SubmoduleID
91 getGlobalSubmoduleID(unsigned LocalID) {
92 return Reader->getGlobalSubmoduleID(M&: *F, LocalID);
93 }
94
95 /// Retrieve the submodule that corresponds to a global submodule ID.
96 Module *getSubmodule(serialization::SubmoduleID GlobalID) {
97 return Reader->getSubmodule(GlobalID);
98 }
99
100 /// Read the record that describes the lexical contents of a DC.
101 bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) {
102 return Reader->ReadLexicalDeclContextStorage(M&: *F, Cursor&: F->DeclsCursor, Offset,
103 DC);
104 }
105
106 ExplicitSpecifier readExplicitSpec() {
107 uint64_t Kind = readInt();
108 bool HasExpr = Kind & 0x1;
109 Kind = Kind >> 1;
110 return ExplicitSpecifier(HasExpr ? readExpr() : nullptr,
111 static_cast<ExplicitSpecKind>(Kind));
112 }
113
114 /// Read information about an exception specification (inherited).
115 //FunctionProtoType::ExceptionSpecInfo
116 //readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage);
117
118 /// Get the global offset corresponding to a local offset.
119 uint64_t getGlobalBitOffset(uint64_t LocalOffset) {
120 return Reader->getGlobalBitOffset(M&: *F, LocalOffset);
121 }
122
123 /// Reads a statement.
124 Stmt *readStmt() { return Reader->ReadStmt(F&: *F); }
125 Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }
126
127 /// Reads an expression.
128 Expr *readExpr() { return Reader->ReadExpr(F&: *F); }
129
130 /// Reads a sub-statement operand during statement reading.
131 Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
132
133 /// Reads a sub-expression operand during statement reading.
134 Expr *readSubExpr() { return Reader->ReadSubExpr(); }
135
136 /// Reads a declaration with the given local ID in the given module.
137 ///
138 /// \returns The requested declaration, casted to the given return type.
139 template <typename T> T *GetLocalDeclAs(serialization::LocalDeclID LocalID) {
140 return cast_or_null<T>(Reader->GetLocalDecl(F&: *F, LocalID));
141 }
142
143 /// Reads a TemplateArgumentLocInfo appropriate for the
144 /// given TemplateArgument kind, advancing Idx.
145 TemplateArgumentLocInfo
146 readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind);
147
148 /// Reads a TemplateArgumentLoc, advancing Idx.
149 TemplateArgumentLoc readTemplateArgumentLoc();
150
151 void readTemplateArgumentListInfo(TemplateArgumentListInfo &Result);
152
153 const ASTTemplateArgumentListInfo*
154 readASTTemplateArgumentListInfo();
155
156 // Reads a concept reference from the given record.
157 ConceptReference *readConceptReference();
158
159 /// Reads a declarator info from the given record, advancing Idx.
160 TypeSourceInfo *readTypeSourceInfo();
161
162 /// Reads the location information for a type.
163 void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr);
164
165 /// Map a local type ID within a given AST file to a global type ID.
166 serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
167 return Reader->getGlobalTypeID(F&: *F, LocalID);
168 }
169
170 Qualifiers readQualifiers() {
171 return Qualifiers::fromOpaqueValue(opaque: readInt());
172 }
173
174 /// Read a type from the current position in the record.
175 QualType readType() {
176 return Reader->readType(F&: *F, Record, Idx);
177 }
178 QualType readQualType() {
179 return readType();
180 }
181
182 /// Reads a declaration ID from the given position in this record.
183 ///
184 /// \returns The declaration ID read from the record, adjusted to a global ID.
185 serialization::GlobalDeclID readDeclID() {
186 return Reader->ReadDeclID(F&: *F, Record, Idx);
187 }
188
189 /// Reads a declaration from the given position in a record in the
190 /// given module, advancing Idx.
191 Decl *readDecl() {
192 return Reader->ReadDecl(F&: *F, R: Record, I&: Idx);
193 }
194 Decl *readDeclRef() {
195 return readDecl();
196 }
197
198 /// Reads a declaration from the given position in the record,
199 /// advancing Idx.
200 ///
201 /// \returns The declaration read from this location, casted to the given
202 /// result type.
203 template<typename T>
204 T *readDeclAs() {
205 return Reader->ReadDeclAs<T>(*F, Record, Idx);
206 }
207
208 IdentifierInfo *readIdentifier() {
209 return Reader->readIdentifier(M&: *F, Record, Idx);
210 }
211
212 /// Read a selector from the Record, advancing Idx.
213 Selector readSelector() {
214 return Reader->ReadSelector(M&: *F, Record, Idx);
215 }
216
217 TypeCoupledDeclRefInfo readTypeCoupledDeclRefInfo();
218
219 /// Read a declaration name, advancing Idx.
220 // DeclarationName readDeclarationName(); (inherited)
221 DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name);
222 DeclarationNameInfo readDeclarationNameInfo();
223
224 void readQualifierInfo(QualifierInfo &Info);
225
226 /// Return a nested name specifier, advancing Idx.
227 // NestedNameSpecifier *readNestedNameSpecifier(); (inherited)
228
229 NestedNameSpecifierLoc readNestedNameSpecifierLoc();
230
231 /// Read a template name, advancing Idx.
232 // TemplateName readTemplateName(); (inherited)
233
234 /// Read a template argument, advancing Idx. (inherited)
235 // TemplateArgument readTemplateArgument();
236 using DataStreamBasicReader::readTemplateArgument;
237 TemplateArgument readTemplateArgument(bool Canonicalize) {
238 TemplateArgument Arg = readTemplateArgument();
239 if (Canonicalize) {
240 Arg = getContext().getCanonicalTemplateArgument(Arg);
241 }
242 return Arg;
243 }
244
245 /// Read a template parameter list, advancing Idx.
246 TemplateParameterList *readTemplateParameterList();
247
248 /// Read a template argument array, advancing Idx.
249 void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
250 bool Canonicalize = false);
251
252 /// Read a UnresolvedSet structure, advancing Idx.
253 void readUnresolvedSet(LazyASTUnresolvedSet &Set);
254
255 /// Read a C++ base specifier, advancing Idx.
256 CXXBaseSpecifier readCXXBaseSpecifier();
257
258 /// Read a CXXCtorInitializer array, advancing Idx.
259 CXXCtorInitializer **readCXXCtorInitializers();
260
261 CXXTemporary *readCXXTemporary() {
262 return Reader->ReadCXXTemporary(F&: *F, Record, Idx);
263 }
264
265 /// Read an OMPTraitInfo object, advancing Idx.
266 OMPTraitInfo *readOMPTraitInfo();
267
268 /// Read an OpenMP clause, advancing Idx.
269 OMPClause *readOMPClause();
270
271 /// Read an OpenMP children, advancing Idx.
272 void readOMPChildren(OMPChildren *Data);
273
274 /// Read an OpenACC clause, advancing Idx.
275 OpenACCClause *readOpenACCClause();
276
277 /// Read a list of OpenACC clauses into the passed SmallVector.
278 void readOpenACCClauseList(MutableArrayRef<const OpenACCClause *> Clauses);
279
280 /// Read a source location, advancing Idx.
281 SourceLocation readSourceLocation(LocSeq *Seq = nullptr) {
282 return Reader->ReadSourceLocation(ModuleFile&: *F, Record, Idx, Seq);
283 }
284
285 /// Read a source range, advancing Idx.
286 SourceRange readSourceRange(LocSeq *Seq = nullptr) {
287 return Reader->ReadSourceRange(F&: *F, Record, Idx, Seq);
288 }
289
290 /// Read an arbitrary constant value, advancing Idx.
291 // APValue readAPValue(); (inherited)
292
293 /// Read an integral value, advancing Idx.
294 // llvm::APInt readAPInt(); (inherited)
295
296 /// Read a signed integral value, advancing Idx.
297 // llvm::APSInt readAPSInt(); (inherited)
298
299 /// Read a floating-point value, advancing Idx.
300 llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem);
301
302 /// Read a boolean value, advancing Idx.
303 bool readBool() { return readInt() != 0; }
304
305 /// Read a 32-bit unsigned value; required to satisfy BasicReader.
306 uint32_t readUInt32() {
307 return uint32_t(readInt());
308 }
309
310 /// Read a 64-bit unsigned value; required to satisfy BasicReader.
311 uint64_t readUInt64() {
312 return readInt();
313 }
314
315 /// Read a string, advancing Idx.
316 std::string readString() {
317 return Reader->ReadString(Record, Idx);
318 }
319
320 /// Read a path, advancing Idx.
321 std::string readPath() {
322 return Reader->ReadPath(F&: *F, Record, Idx);
323 }
324
325 /// Read a version tuple, advancing Idx.
326 VersionTuple readVersionTuple() {
327 return ASTReader::ReadVersionTuple(Record, Idx);
328 }
329
330 /// Reads one attribute from the current stream position, advancing Idx.
331 Attr *readAttr();
332
333 /// Reads attributes from the current stream position, advancing Idx.
334 void readAttributes(AttrVec &Attrs);
335
336 /// Read an BTFTypeTagAttr object.
337 BTFTypeTagAttr *readBTFTypeTagAttr() {
338 return cast<BTFTypeTagAttr>(Val: readAttr());
339 }
340
341 /// Reads a token out of a record, advancing Idx.
342 Token readToken() {
343 return Reader->ReadToken(M&: *F, Record, Idx);
344 }
345
346 void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
347 Reader->RecordSwitchCaseID(SC, ID);
348 }
349
350 /// Retrieve the switch-case statement with the given ID.
351 SwitchCase *getSwitchCaseWithID(unsigned ID) {
352 return Reader->getSwitchCaseWithID(ID);
353 }
354};
355
356/// Helper class that saves the current stream position and
357/// then restores it when destroyed.
358struct SavedStreamPosition {
359 explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
360 : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
361
362 ~SavedStreamPosition() {
363 if (llvm::Error Err = Cursor.JumpToBit(BitNo: Offset))
364 llvm::report_fatal_error(
365 reason: llvm::Twine("Cursor should always be able to go back, failed: ") +
366 toString(E: std::move(Err)));
367 }
368
369private:
370 llvm::BitstreamCursor &Cursor;
371 uint64_t Offset;
372};
373
374} // namespace clang
375
376#endif
377

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