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
24namespace clang {
25
26/// An object for streaming information from a record.
27class 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
39public:
40  /// Construct an ASTRecordReader that uses the default encoding scheme.
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).
50  bool isModule() const { return F->isModule(); }
51
52  /// Retrieve the AST context that this AST reader supplements.
53  ASTContext &getContext() { return Reader->getContext(); }
54
55  /// The current position in this record.
56  unsigned getIdx() const { return Idx; }
57
58  /// The length of this record.
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.
65  uint64_t back() { return Record.back(); }
66
67  /// Returns the current value in this record, and advances to the
68  /// next value.
69  uint64_t readInt() { return Record[Idx++]; }
70
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.
78  uint64_t peekInt() { return Record[Idx]; }
79
80  /// Skips the specified number of values.
81  void skipInts(unsigned N) { Idx += N; }
82
83  /// Retrieve the global submodule ID its local ID number.
84  serialization::SubmoduleID
85  getGlobalSubmoduleID(unsigned LocalID) {
86    return Reader->getGlobalSubmoduleID(*F, LocalID);
87  }
88
89  /// Retrieve the submodule that corresponds to a global submodule ID.
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.
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.
101  bool readVisibleDeclContextStorage(uint64_t Offset,
102                                     serialization::DeclID ID) {
103    return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
104                                                 ID);
105  }
106
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.
120  uint64_t getGlobalBitOffset(uint32_t LocalOffset) {
121    return Reader->getGlobalBitOffset(*F, LocalOffset);
122  }
123
124  /// Reads a statement.
125  Stmt *readStmt() { return Reader->ReadStmt(*F); }
126  Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }
127
128  /// Reads an expression.
129  Expr *readExpr() { return Reader->ReadExpr(*F); }
130
131  /// Reads a sub-statement operand during statement reading.
132  Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
133
134  /// Reads a sub-expression operand during statement reading.
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>
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.
164  serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
165    return Reader->getGlobalTypeID(*F, LocalID);
166  }
167
168  Qualifiers readQualifiers() {
169    return Qualifiers::fromOpaqueValue(readInt());
170  }
171
172  /// Read a type from the current position in the record.
173  QualType readType() {
174    return Reader->readType(*F, Record, Idx);
175  }
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.
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.
189  Decl *readDecl() {
190    return Reader->ReadDecl(*F, Record, Idx);
191  }
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>
202  T *readDeclAs() {
203    return Reader->ReadDeclAs<T>(*F, Record, Idx);
204  }
205
206  IdentifierInfo *readIdentifier() {
207    return Reader->readIdentifier(*F, Record, Idx);
208  }
209
210  /// Read a selector from the Record, advancing Idx.
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;
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
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.
265  SourceLocation readSourceLocation() {
266    return Reader->ReadSourceLocation(*F, Record, Idx);
267  }
268
269  /// Read a source range, advancing Idx.
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.
287  bool readBool() { return readInt() != 0; }
288
289  /// Read a 32-bit unsigned value; required to satisfy BasicReader.
290  uint32_t readUInt32() {
291    return uint32_t(readInt());
292  }
293
294  /// Read a 64-bit unsigned value; required to satisfy BasicReader.
295  uint64_t readUInt64() {
296    return readInt();
297  }
298
299  /// Read a string, advancing Idx.
300  std::string readString() {
301    return Reader->ReadString(Record, Idx);
302  }
303
304  /// Read a path, advancing Idx.
305  std::string readPath() {
306    return Reader->ReadPath(*F, Record, Idx);
307  }
308
309  /// Read a version tuple, advancing Idx.
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.
321  Token readToken() {
322    return Reader->ReadToken(*F, Record, Idx);
323  }
324
325  void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
326    Reader->RecordSwitchCaseID(SC, ID);
327  }
328
329  /// Retrieve the switch-case statement with the given 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.
337struct SavedStreamPosition {
338  explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
339      : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
340
341  ~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
348private:
349  llvm::BitstreamCursor &Cursor;
350  uint64_t Offset;
351};
352
353inline void PCHValidator::Error(const char *Msg) {
354  Reader.Error(Msg);
355}
356
357} // namespace clang
358
359#endif
360