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.
ASTRecordReader(ASTReader & Reader,ModuleFile & F)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).
isModule()55 bool isModule() const { return F->isModule(); }
56
57 /// Retrieve the AST context that this AST reader supplements.
getContext()58 ASTContext &getContext() { return Reader->getContext(); }
59
60 /// The current position in this record.
getIdx()61 unsigned getIdx() const { return Idx; }
62
63 /// The length of this record.
size()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.
back()70 uint64_t back() { return Record.back(); }
71
72 /// Returns the current value in this record, and advances to the
73 /// next value.
readInt()74 uint64_t readInt() { return Record[Idx++]; }
75
readIntArray(unsigned Len)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.
peekInt()83 uint64_t peekInt() { return Record[Idx]; }
84
85 /// Skips the specified number of values.
skipInts(unsigned N)86 void skipInts(unsigned N) { Idx += N; }
87
88 /// Retrieve the global submodule ID its local ID number.
89 serialization::SubmoduleID
getGlobalSubmoduleID(unsigned LocalID)90 getGlobalSubmoduleID(unsigned LocalID) {
91 return Reader->getGlobalSubmoduleID(*F, LocalID);
92 }
93
94 /// Retrieve the submodule that corresponds to a global submodule ID.
getSubmodule(serialization::SubmoduleID GlobalID)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.
readLexicalDeclContextStorage(uint64_t Offset,DeclContext * 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.
readVisibleDeclContextStorage(uint64_t Offset,serialization::DeclID ID)106 bool readVisibleDeclContextStorage(uint64_t Offset,
107 serialization::DeclID ID) {
108 return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
109 ID);
110 }
111
readExplicitSpec()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.
getGlobalBitOffset(uint64_t LocalOffset)125 uint64_t getGlobalBitOffset(uint64_t LocalOffset) {
126 return Reader->getGlobalBitOffset(*F, LocalOffset);
127 }
128
129 /// Reads a statement.
readStmt()130 Stmt *readStmt() { return Reader->ReadStmt(*F); }
readStmtRef()131 Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }
132
133 /// Reads an expression.
readExpr()134 Expr *readExpr() { return Reader->ReadExpr(*F); }
135
136 /// Reads a sub-statement operand during statement reading.
readSubStmt()137 Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
138
139 /// Reads a sub-expression operand during statement reading.
readSubExpr()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>
GetLocalDeclAs(uint32_t LocalID)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.
getGlobalTypeID(unsigned LocalID)168 serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
169 return Reader->getGlobalTypeID(*F, LocalID);
170 }
171
readQualifiers()172 Qualifiers readQualifiers() {
173 return Qualifiers::fromOpaqueValue(readInt());
174 }
175
176 /// Read a type from the current position in the record.
readType()177 QualType readType() {
178 return Reader->readType(*F, Record, Idx);
179 }
readQualType()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.
readDeclID()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.
readDecl()193 Decl *readDecl() {
194 return Reader->ReadDecl(*F, Record, Idx);
195 }
readDeclRef()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>
readDeclAs()206 T *readDeclAs() {
207 return Reader->ReadDeclAs<T>(*F, Record, Idx);
208 }
209
readIdentifier()210 IdentifierInfo *readIdentifier() {
211 return Reader->readIdentifier(*F, Record, Idx);
212 }
213
214 /// Read a selector from the Record, advancing Idx.
readSelector()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;
readTemplateArgument(bool Canonicalize)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
readCXXTemporary()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.
readBool()297 bool readBool() { return readInt() != 0; }
298
299 /// Read a 32-bit unsigned value; required to satisfy BasicReader.
readUInt32()300 uint32_t readUInt32() {
301 return uint32_t(readInt());
302 }
303
304 /// Read a 64-bit unsigned value; required to satisfy BasicReader.
readUInt64()305 uint64_t readUInt64() {
306 return readInt();
307 }
308
309 /// Read a string, advancing Idx.
readString()310 std::string readString() {
311 return Reader->ReadString(Record, Idx);
312 }
313
314 /// Read a path, advancing Idx.
readPath()315 std::string readPath() {
316 return Reader->ReadPath(*F, Record, Idx);
317 }
318
319 /// Read a version tuple, advancing Idx.
readVersionTuple()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.
readBTFTypeTagAttr()331 BTFTypeTagAttr *readBTFTypeTagAttr() {
332 return cast<BTFTypeTagAttr>(readAttr());
333 }
334
335 /// Reads a token out of a record, advancing Idx.
readToken()336 Token readToken() {
337 return Reader->ReadToken(*F, Record, Idx);
338 }
339
recordSwitchCaseID(SwitchCase * SC,unsigned ID)340 void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
341 Reader->RecordSwitchCaseID(SC, ID);
342 }
343
344 /// Retrieve the switch-case statement with the given ID.
getSwitchCaseWithID(unsigned 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 {
SavedStreamPositionSavedStreamPosition353 explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
354 : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
355
~SavedStreamPositionSavedStreamPosition356 ~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
Error(const char * Msg)368 inline void PCHValidator::Error(const char *Msg) {
369 Reader.Error(Msg);
370 }
371
372 } // namespace clang
373
374 #endif
375