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 | |
26 | namespace clang { |
27 | class OpenACCClause; |
28 | class OMPTraitInfo; |
29 | class OMPChildren; |
30 | |
31 | /// An object for streaming information from a record. |
32 | class 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 | |
45 | public: |
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. |
358 | struct 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 | |
369 | private: |
370 | llvm::BitstreamCursor &Cursor; |
371 | uint64_t Offset; |
372 | }; |
373 | |
374 | } // namespace clang |
375 | |
376 | #endif |
377 | |