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.
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).
55   bool isModule() const { return F->isModule(); }
56 
57   /// Retrieve the AST context that this AST reader supplements.
58   ASTContext &getContext() { return Reader->getContext(); }
59 
60   /// The current position in this record.
61   unsigned getIdx() const { return Idx; }
62 
63   /// The length of this record.
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.
70   uint64_t back() { return Record.back(); }
71 
72   /// Returns the current value in this record, and advances to the
73   /// next value.
74   uint64_t readInt() { return Record[Idx++]; }
75 
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.
83   uint64_t peekInt() { return Record[Idx]; }
84 
85   /// Skips the specified number of values.
86   void skipInts(unsigned N) { Idx += N; }
87 
88   /// Retrieve the global submodule ID its local ID number.
89   serialization::SubmoduleID
90   getGlobalSubmoduleID(unsigned LocalID) {
91     return Reader->getGlobalSubmoduleID(*F, LocalID);
92   }
93 
94   /// Retrieve the submodule that corresponds to a global submodule ID.
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.
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.
106   bool readVisibleDeclContextStorage(uint64_t Offset,
107                                      serialization::DeclID ID) {
108     return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
109                                                  ID);
110   }
111 
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.
125   uint64_t getGlobalBitOffset(uint64_t LocalOffset) {
126     return Reader->getGlobalBitOffset(*F, LocalOffset);
127   }
128 
129   /// Reads a statement.
130   Stmt *readStmt() { return Reader->ReadStmt(*F); }
131   Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }
132 
133   /// Reads an expression.
134   Expr *readExpr() { return Reader->ReadExpr(*F); }
135 
136   /// Reads a sub-statement operand during statement reading.
137   Stmt *readSubStmt() { return Reader->ReadSubStmt(); }
138 
139   /// Reads a sub-expression operand during statement reading.
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>
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   void readTemplateArgumentListInfo(TemplateArgumentListInfo &Result);
159 
160   const ASTTemplateArgumentListInfo*
161   readASTTemplateArgumentListInfo();
162 
163   // Reads a concept reference from the given record.
164   ConceptReference *readConceptReference();
165 
166   /// Reads a declarator info from the given record, advancing Idx.
167   TypeSourceInfo *readTypeSourceInfo();
168 
169   /// Reads the location information for a type.
170   void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr);
171 
172   /// Map a local type ID within a given AST file to a global type ID.
173   serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
174     return Reader->getGlobalTypeID(*F, LocalID);
175   }
176 
177   Qualifiers readQualifiers() {
178     return Qualifiers::fromOpaqueValue(readInt());
179   }
180 
181   /// Read a type from the current position in the record.
182   QualType readType() {
183     return Reader->readType(*F, Record, Idx);
184   }
185   QualType readQualType() {
186     return readType();
187   }
188 
189   /// Reads a declaration ID from the given position in this record.
190   ///
191   /// \returns The declaration ID read from the record, adjusted to a global ID.
192   serialization::DeclID readDeclID() {
193     return Reader->ReadDeclID(*F, Record, Idx);
194   }
195 
196   /// Reads a declaration from the given position in a record in the
197   /// given module, advancing Idx.
198   Decl *readDecl() {
199     return Reader->ReadDecl(*F, Record, Idx);
200   }
201   Decl *readDeclRef() {
202     return readDecl();
203   }
204 
205   /// Reads a declaration from the given position in the record,
206   /// advancing Idx.
207   ///
208   /// \returns The declaration read from this location, casted to the given
209   /// result type.
210   template<typename T>
211   T *readDeclAs() {
212     return Reader->ReadDeclAs<T>(*F, Record, Idx);
213   }
214 
215   IdentifierInfo *readIdentifier() {
216     return Reader->readIdentifier(*F, Record, Idx);
217   }
218 
219   /// Read a selector from the Record, advancing Idx.
220   Selector readSelector() {
221     return Reader->ReadSelector(*F, Record, Idx);
222   }
223 
224   /// Read a declaration name, advancing Idx.
225   // DeclarationName readDeclarationName(); (inherited)
226   DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name);
227   DeclarationNameInfo readDeclarationNameInfo();
228 
229   void readQualifierInfo(QualifierInfo &Info);
230 
231   /// Return a nested name specifier, advancing Idx.
232   // NestedNameSpecifier *readNestedNameSpecifier(); (inherited)
233 
234   NestedNameSpecifierLoc readNestedNameSpecifierLoc();
235 
236   /// Read a template name, advancing Idx.
237   // TemplateName readTemplateName(); (inherited)
238 
239   /// Read a template argument, advancing Idx. (inherited)
240   // TemplateArgument readTemplateArgument();
241   using DataStreamBasicReader::readTemplateArgument;
242   TemplateArgument readTemplateArgument(bool Canonicalize) {
243     TemplateArgument Arg = readTemplateArgument();
244     if (Canonicalize) {
245       Arg = getContext().getCanonicalTemplateArgument(Arg);
246     }
247     return Arg;
248   }
249 
250   /// Read a template parameter list, advancing Idx.
251   TemplateParameterList *readTemplateParameterList();
252 
253   /// Read a template argument array, advancing Idx.
254   void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
255                                 bool Canonicalize = false);
256 
257   /// Read a UnresolvedSet structure, advancing Idx.
258   void readUnresolvedSet(LazyASTUnresolvedSet &Set);
259 
260   /// Read a C++ base specifier, advancing Idx.
261   CXXBaseSpecifier readCXXBaseSpecifier();
262 
263   /// Read a CXXCtorInitializer array, advancing Idx.
264   CXXCtorInitializer **readCXXCtorInitializers();
265 
266   CXXTemporary *readCXXTemporary() {
267     return Reader->ReadCXXTemporary(*F, Record, Idx);
268   }
269 
270   /// Read an OMPTraitInfo object, advancing Idx.
271   OMPTraitInfo *readOMPTraitInfo();
272 
273   /// Read an OpenMP clause, advancing Idx.
274   OMPClause *readOMPClause();
275 
276   /// Read an OpenMP children, advancing Idx.
277   void readOMPChildren(OMPChildren *Data);
278 
279   /// Read a source location, advancing Idx.
280   SourceLocation readSourceLocation(LocSeq *Seq = nullptr) {
281     return Reader->ReadSourceLocation(*F, Record, Idx, Seq);
282   }
283 
284   /// Read a source range, advancing Idx.
285   SourceRange readSourceRange(LocSeq *Seq = nullptr) {
286     return Reader->ReadSourceRange(*F, Record, Idx, Seq);
287   }
288 
289   /// Read an arbitrary constant value, advancing Idx.
290   // APValue readAPValue(); (inherited)
291 
292   /// Read an integral value, advancing Idx.
293   // llvm::APInt readAPInt(); (inherited)
294 
295   /// Read a signed integral value, advancing Idx.
296   // llvm::APSInt readAPSInt(); (inherited)
297 
298   /// Read a floating-point value, advancing Idx.
299   llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem);
300 
301   /// Read a boolean value, advancing Idx.
302   bool readBool() { return readInt() != 0; }
303 
304   /// Read a 32-bit unsigned value; required to satisfy BasicReader.
305   uint32_t readUInt32() {
306     return uint32_t(readInt());
307   }
308 
309   /// Read a 64-bit unsigned value; required to satisfy BasicReader.
310   uint64_t readUInt64() {
311     return readInt();
312   }
313 
314   /// Read a string, advancing Idx.
315   std::string readString() {
316     return Reader->ReadString(Record, Idx);
317   }
318 
319   /// Read a path, advancing Idx.
320   std::string readPath() {
321     return Reader->ReadPath(*F, Record, Idx);
322   }
323 
324   /// Read a version tuple, advancing Idx.
325   VersionTuple readVersionTuple() {
326     return ASTReader::ReadVersionTuple(Record, Idx);
327   }
328 
329   /// Reads one attribute from the current stream position, advancing Idx.
330   Attr *readAttr();
331 
332   /// Reads attributes from the current stream position, advancing Idx.
333   void readAttributes(AttrVec &Attrs);
334 
335   /// Read an BTFTypeTagAttr object.
336   BTFTypeTagAttr *readBTFTypeTagAttr() {
337     return cast<BTFTypeTagAttr>(readAttr());
338   }
339 
340   /// Reads a token out of a record, advancing Idx.
341   Token readToken() {
342     return Reader->ReadToken(*F, Record, Idx);
343   }
344 
345   void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
346     Reader->RecordSwitchCaseID(SC, ID);
347   }
348 
349   /// Retrieve the switch-case statement with the given ID.
350   SwitchCase *getSwitchCaseWithID(unsigned ID) {
351     return Reader->getSwitchCaseWithID(ID);
352   }
353 };
354 
355 /// Helper class that saves the current stream position and
356 /// then restores it when destroyed.
357 struct SavedStreamPosition {
358   explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
359       : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
360 
361   ~SavedStreamPosition() {
362     if (llvm::Error Err = Cursor.JumpToBit(Offset))
363       llvm::report_fatal_error(
364           llvm::Twine("Cursor should always be able to go back, failed: ") +
365           toString(std::move(Err)));
366   }
367 
368 private:
369   llvm::BitstreamCursor &Cursor;
370   uint64_t Offset;
371 };
372 
373 } // namespace clang
374 
375 #endif
376