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