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