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.
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).
52   bool isModule() const { return F->isModule(); }
53 
54   /// Retrieve the AST context that this AST reader supplements.
55   ASTContext &getContext() { return Reader->getContext(); }
56 
57   /// The current position in this record.
58   unsigned getIdx() const { return Idx; }
59 
60   /// The length of this record.
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.
67   uint64_t back() { return Record.back(); }
68 
69   /// Returns the current value in this record, and advances to the
70   /// next value.
71   uint64_t readInt() { return Record[Idx++]; }
72 
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.
80   uint64_t peekInt() { return Record[Idx]; }
81 
82   /// Skips the specified number of values.
83   void skipInts(unsigned N) { Idx += N; }
84 
85   /// Retrieve the global submodule ID its local ID number.
86   serialization::SubmoduleID
87   getGlobalSubmoduleID(unsigned LocalID) {
88     return Reader->getGlobalSubmoduleID(*F, LocalID);
89   }
90 
91   /// Retrieve the submodule that corresponds to a global submodule ID.
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.
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.
103   bool readVisibleDeclContextStorage(uint64_t Offset,
104                                      serialization::DeclID ID) {
105     return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
106                                                  ID);
107   }
108 
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.
122   uint64_t getGlobalBitOffset(uint64_t LocalOffset) {
123     return Reader->getGlobalBitOffset(*F, LocalOffset);
124   }
125 
126   /// Reads a statement.
127   Stmt *readStmt() { return Reader->ReadStmt(*F); }
128   Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }
129 
130   /// Reads an expression.
131   Expr *readExpr() { return Reader->ReadExpr(*F); }
132 
133   /// Reads a sub-statement operand during statement reading.
134   Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
135 
136   /// Reads a sub-expression operand during statement reading.
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>
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.
166   serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
167     return Reader->getGlobalTypeID(*F, LocalID);
168   }
169 
170   Qualifiers readQualifiers() {
171     return Qualifiers::fromOpaqueValue(readInt());
172   }
173 
174   /// Read a type from the current position in the record.
175   QualType readType() {
176     return Reader->readType(*F, Record, Idx);
177   }
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.
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.
191   Decl *readDecl() {
192     return Reader->ReadDecl(*F, Record, Idx);
193   }
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>
204   T *readDeclAs() {
205     return Reader->ReadDeclAs<T>(*F, Record, Idx);
206   }
207 
208   IdentifierInfo *readIdentifier() {
209     return Reader->readIdentifier(*F, Record, Idx);
210   }
211 
212   /// Read a selector from the Record, advancing Idx.
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;
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 
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.
270   SourceLocation readSourceLocation() {
271     return Reader->ReadSourceLocation(*F, Record, Idx);
272   }
273 
274   /// Read a source range, advancing Idx.
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.
292   bool readBool() { return readInt() != 0; }
293 
294   /// Read a 32-bit unsigned value; required to satisfy BasicReader.
295   uint32_t readUInt32() {
296     return uint32_t(readInt());
297   }
298 
299   /// Read a 64-bit unsigned value; required to satisfy BasicReader.
300   uint64_t readUInt64() {
301     return readInt();
302   }
303 
304   /// Read a string, advancing Idx.
305   std::string readString() {
306     return Reader->ReadString(Record, Idx);
307   }
308 
309   /// Read a path, advancing Idx.
310   std::string readPath() {
311     return Reader->ReadPath(*F, Record, Idx);
312   }
313 
314   /// Read a version tuple, advancing Idx.
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.
326   Token readToken() {
327     return Reader->ReadToken(*F, Record, Idx);
328   }
329 
330   void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
331     Reader->RecordSwitchCaseID(SC, ID);
332   }
333 
334   /// Retrieve the switch-case statement with the given 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 {
343   explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
344       : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
345 
346   ~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 
358 inline void PCHValidator::Error(const char *Msg) {
359   Reader.Error(Msg);
360 }
361 
362 } // namespace clang
363 
364 #endif
365