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.
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.
337 struct 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 
348 private:
349   llvm::BitstreamCursor &Cursor;
350   uint64_t Offset;
351 };
352 
353 inline void PCHValidator::Error(const char *Msg) {
354   Reader.Error(Msg);
355 }
356 
357 } // namespace clang
358 
359 #endif
360