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