Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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 OMPTraitInfo; |
||
28 | class OMPChildren; |
||
29 | |||
30 | /// An object for streaming information from a record. |
||
31 | class ASTRecordReader |
||
32 | : public serialization::DataStreamBasicReader<ASTRecordReader> { |
||
33 | using ModuleFile = serialization::ModuleFile; |
||
34 | using LocSeq = SourceLocationSequence; |
||
35 | |||
36 | ASTReader *Reader; |
||
37 | ModuleFile *F; |
||
38 | unsigned Idx = 0; |
||
39 | ASTReader::RecordData Record; |
||
40 | |||
41 | using RecordData = ASTReader::RecordData; |
||
42 | using RecordDataImpl = ASTReader::RecordDataImpl; |
||
43 | |||
44 | public: |
||
45 | /// Construct an ASTRecordReader that uses the default encoding scheme. |
||
46 | ASTRecordReader(ASTReader &Reader, ModuleFile &F) |
||
47 | : DataStreamBasicReader(Reader.getContext()), Reader(&Reader), F(&F) {} |
||
48 | |||
49 | /// Reads a record with id AbbrevID from Cursor, resetting the |
||
50 | /// internal state. |
||
51 | Expected<unsigned> readRecord(llvm::BitstreamCursor &Cursor, |
||
52 | unsigned AbbrevID); |
||
53 | |||
54 | /// Is this a module file for a module (rather than a PCH or similar). |
||
55 | bool isModule() const { return F->isModule(); } |
||
56 | |||
57 | /// Retrieve the AST context that this AST reader supplements. |
||
58 | ASTContext &getContext() { return Reader->getContext(); } |
||
59 | |||
60 | /// The current position in this record. |
||
61 | unsigned getIdx() const { return Idx; } |
||
62 | |||
63 | /// The length of this record. |
||
64 | size_t size() const { return Record.size(); } |
||
65 | |||
66 | /// An arbitrary index in this record. |
||
67 | const uint64_t &operator[](size_t N) { return Record[N]; } |
||
68 | |||
69 | /// Returns the last value in this record. |
||
70 | uint64_t back() { return Record.back(); } |
||
71 | |||
72 | /// Returns the current value in this record, and advances to the |
||
73 | /// next value. |
||
74 | uint64_t readInt() { return Record[Idx++]; } |
||
75 | |||
76 | ArrayRef<uint64_t> readIntArray(unsigned Len) { |
||
77 | auto Array = llvm::ArrayRef(Record).slice(Idx, Len); |
||
78 | Idx += Len; |
||
79 | return Array; |
||
80 | } |
||
81 | |||
82 | /// Returns the current value in this record, without advancing. |
||
83 | uint64_t peekInt() { return Record[Idx]; } |
||
84 | |||
85 | /// Skips the specified number of values. |
||
86 | void skipInts(unsigned N) { Idx += N; } |
||
87 | |||
88 | /// Retrieve the global submodule ID its local ID number. |
||
89 | serialization::SubmoduleID |
||
90 | getGlobalSubmoduleID(unsigned LocalID) { |
||
91 | return Reader->getGlobalSubmoduleID(*F, LocalID); |
||
92 | } |
||
93 | |||
94 | /// Retrieve the submodule that corresponds to a global submodule ID. |
||
95 | Module *getSubmodule(serialization::SubmoduleID GlobalID) { |
||
96 | return Reader->getSubmodule(GlobalID); |
||
97 | } |
||
98 | |||
99 | /// Read the record that describes the lexical contents of a DC. |
||
100 | bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) { |
||
101 | return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset, |
||
102 | DC); |
||
103 | } |
||
104 | |||
105 | /// Read the record that describes the visible contents of a DC. |
||
106 | bool readVisibleDeclContextStorage(uint64_t Offset, |
||
107 | serialization::DeclID ID) { |
||
108 | return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset, |
||
109 | ID); |
||
110 | } |
||
111 | |||
112 | ExplicitSpecifier readExplicitSpec() { |
||
113 | uint64_t Kind = readInt(); |
||
114 | bool HasExpr = Kind & 0x1; |
||
115 | Kind = Kind >> 1; |
||
116 | return ExplicitSpecifier(HasExpr ? readExpr() : nullptr, |
||
117 | static_cast<ExplicitSpecKind>(Kind)); |
||
118 | } |
||
119 | |||
120 | /// Read information about an exception specification (inherited). |
||
121 | //FunctionProtoType::ExceptionSpecInfo |
||
122 | //readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage); |
||
123 | |||
124 | /// Get the global offset corresponding to a local offset. |
||
125 | uint64_t getGlobalBitOffset(uint64_t LocalOffset) { |
||
126 | return Reader->getGlobalBitOffset(*F, LocalOffset); |
||
127 | } |
||
128 | |||
129 | /// Reads a statement. |
||
130 | Stmt *readStmt() { return Reader->ReadStmt(*F); } |
||
131 | Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ } |
||
132 | |||
133 | /// Reads an expression. |
||
134 | Expr *readExpr() { return Reader->ReadExpr(*F); } |
||
135 | |||
136 | /// Reads a sub-statement operand during statement reading. |
||
137 | Stmt *readSubStmt() { return Reader->ReadSubStmt(); } |
||
138 | |||
139 | /// Reads a sub-expression operand during statement reading. |
||
140 | Expr *readSubExpr() { return Reader->ReadSubExpr(); } |
||
141 | |||
142 | /// Reads a declaration with the given local ID in the given module. |
||
143 | /// |
||
144 | /// \returns The requested declaration, casted to the given return type. |
||
145 | template<typename T> |
||
146 | T *GetLocalDeclAs(uint32_t LocalID) { |
||
147 | return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); |
||
148 | } |
||
149 | |||
150 | /// Reads a TemplateArgumentLocInfo appropriate for the |
||
151 | /// given TemplateArgument kind, advancing Idx. |
||
152 | TemplateArgumentLocInfo |
||
153 | readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind); |
||
154 | |||
155 | /// Reads a TemplateArgumentLoc, advancing Idx. |
||
156 | TemplateArgumentLoc readTemplateArgumentLoc(); |
||
157 | |||
158 | const ASTTemplateArgumentListInfo* |
||
159 | readASTTemplateArgumentListInfo(); |
||
160 | |||
161 | /// Reads a declarator info from the given record, advancing Idx. |
||
162 | TypeSourceInfo *readTypeSourceInfo(); |
||
163 | |||
164 | /// Reads the location information for a type. |
||
165 | void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr); |
||
166 | |||
167 | /// Map a local type ID within a given AST file to a global type ID. |
||
168 | serialization::TypeID getGlobalTypeID(unsigned LocalID) const { |
||
169 | return Reader->getGlobalTypeID(*F, LocalID); |
||
170 | } |
||
171 | |||
172 | Qualifiers readQualifiers() { |
||
173 | return Qualifiers::fromOpaqueValue(readInt()); |
||
174 | } |
||
175 | |||
176 | /// Read a type from the current position in the record. |
||
177 | QualType readType() { |
||
178 | return Reader->readType(*F, Record, Idx); |
||
179 | } |
||
180 | QualType readQualType() { |
||
181 | return readType(); |
||
182 | } |
||
183 | |||
184 | /// Reads a declaration ID from the given position in this record. |
||
185 | /// |
||
186 | /// \returns The declaration ID read from the record, adjusted to a global ID. |
||
187 | serialization::DeclID readDeclID() { |
||
188 | return Reader->ReadDeclID(*F, Record, Idx); |
||
189 | } |
||
190 | |||
191 | /// Reads a declaration from the given position in a record in the |
||
192 | /// given module, advancing Idx. |
||
193 | Decl *readDecl() { |
||
194 | return Reader->ReadDecl(*F, Record, Idx); |
||
195 | } |
||
196 | Decl *readDeclRef() { |
||
197 | return readDecl(); |
||
198 | } |
||
199 | |||
200 | /// Reads a declaration from the given position in the record, |
||
201 | /// advancing Idx. |
||
202 | /// |
||
203 | /// \returns The declaration read from this location, casted to the given |
||
204 | /// result type. |
||
205 | template<typename T> |
||
206 | T *readDeclAs() { |
||
207 | return Reader->ReadDeclAs<T>(*F, Record, Idx); |
||
208 | } |
||
209 | |||
210 | IdentifierInfo *readIdentifier() { |
||
211 | return Reader->readIdentifier(*F, Record, Idx); |
||
212 | } |
||
213 | |||
214 | /// Read a selector from the Record, advancing Idx. |
||
215 | Selector readSelector() { |
||
216 | return Reader->ReadSelector(*F, Record, Idx); |
||
217 | } |
||
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, 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 a source location, advancing Idx. |
||
275 | SourceLocation readSourceLocation(LocSeq *Seq = nullptr) { |
||
276 | return Reader->ReadSourceLocation(*F, Record, Idx, Seq); |
||
277 | } |
||
278 | |||
279 | /// Read a source range, advancing Idx. |
||
280 | SourceRange readSourceRange(LocSeq *Seq = nullptr) { |
||
281 | return Reader->ReadSourceRange(*F, Record, Idx, Seq); |
||
282 | } |
||
283 | |||
284 | /// Read an arbitrary constant value, advancing Idx. |
||
285 | // APValue readAPValue(); (inherited) |
||
286 | |||
287 | /// Read an integral value, advancing Idx. |
||
288 | // llvm::APInt readAPInt(); (inherited) |
||
289 | |||
290 | /// Read a signed integral value, advancing Idx. |
||
291 | // llvm::APSInt readAPSInt(); (inherited) |
||
292 | |||
293 | /// Read a floating-point value, advancing Idx. |
||
294 | llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem); |
||
295 | |||
296 | /// Read a boolean value, advancing Idx. |
||
297 | bool readBool() { return readInt() != 0; } |
||
298 | |||
299 | /// Read a 32-bit unsigned value; required to satisfy BasicReader. |
||
300 | uint32_t readUInt32() { |
||
301 | return uint32_t(readInt()); |
||
302 | } |
||
303 | |||
304 | /// Read a 64-bit unsigned value; required to satisfy BasicReader. |
||
305 | uint64_t readUInt64() { |
||
306 | return readInt(); |
||
307 | } |
||
308 | |||
309 | /// Read a string, advancing Idx. |
||
310 | std::string readString() { |
||
311 | return Reader->ReadString(Record, Idx); |
||
312 | } |
||
313 | |||
314 | /// Read a path, advancing Idx. |
||
315 | std::string readPath() { |
||
316 | return Reader->ReadPath(*F, Record, Idx); |
||
317 | } |
||
318 | |||
319 | /// Read a version tuple, advancing Idx. |
||
320 | VersionTuple readVersionTuple() { |
||
321 | return ASTReader::ReadVersionTuple(Record, Idx); |
||
322 | } |
||
323 | |||
324 | /// Reads one attribute from the current stream position, advancing Idx. |
||
325 | Attr *readAttr(); |
||
326 | |||
327 | /// Reads attributes from the current stream position, advancing Idx. |
||
328 | void readAttributes(AttrVec &Attrs); |
||
329 | |||
330 | /// Read an BTFTypeTagAttr object. |
||
331 | BTFTypeTagAttr *readBTFTypeTagAttr() { |
||
332 | return cast<BTFTypeTagAttr>(readAttr()); |
||
333 | } |
||
334 | |||
335 | /// Reads a token out of a record, advancing Idx. |
||
336 | Token readToken() { |
||
337 | return Reader->ReadToken(*F, Record, Idx); |
||
338 | } |
||
339 | |||
340 | void recordSwitchCaseID(SwitchCase *SC, unsigned ID) { |
||
341 | Reader->RecordSwitchCaseID(SC, ID); |
||
342 | } |
||
343 | |||
344 | /// Retrieve the switch-case statement with the given ID. |
||
345 | SwitchCase *getSwitchCaseWithID(unsigned ID) { |
||
346 | return Reader->getSwitchCaseWithID(ID); |
||
347 | } |
||
348 | }; |
||
349 | |||
350 | /// Helper class that saves the current stream position and |
||
351 | /// then restores it when destroyed. |
||
352 | struct SavedStreamPosition { |
||
353 | explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) |
||
354 | : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} |
||
355 | |||
356 | ~SavedStreamPosition() { |
||
357 | if (llvm::Error Err = Cursor.JumpToBit(Offset)) |
||
358 | llvm::report_fatal_error( |
||
359 | llvm::Twine("Cursor should always be able to go back, failed: ") + |
||
360 | toString(std::move(Err))); |
||
361 | } |
||
362 | |||
363 | private: |
||
364 | llvm::BitstreamCursor &Cursor; |
||
365 | uint64_t Offset; |
||
366 | }; |
||
367 | |||
368 | inline void PCHValidator::Error(const char *Msg) { |
||
369 | Reader.Error(Msg); |
||
370 | } |
||
371 | |||
372 | } // namespace clang |
||
373 | |||
374 | #endif |