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   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.
168   serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
169     return Reader->getGlobalTypeID(*F, LocalID);
170   }
171 
172   Qualifiers readQualifiers() {
173     return Qualifiers::fromOpaqueValue(readInt());
174   }
175 
176   /// Read a type from the current position in the record.
177   QualType readType() {
178     return Reader->readType(*F, Record, Idx);
179   }
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.
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.
193   Decl *readDecl() {
194     return Reader->ReadDecl(*F, Record, Idx);
195   }
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>
206   T *readDeclAs() {
207     return Reader->ReadDeclAs<T>(*F, Record, Idx);
208   }
209 
210   IdentifierInfo *readIdentifier() {
211     return Reader->readIdentifier(*F, Record, Idx);
212   }
213 
214   /// Read a selector from the Record, advancing Idx.
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;
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 
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.
297   bool readBool() { return readInt() != 0; }
298 
299   /// Read a 32-bit unsigned value; required to satisfy BasicReader.
300   uint32_t readUInt32() {
301     return uint32_t(readInt());
302   }
303 
304   /// Read a 64-bit unsigned value; required to satisfy BasicReader.
305   uint64_t readUInt64() {
306     return readInt();
307   }
308 
309   /// Read a string, advancing Idx.
310   std::string readString() {
311     return Reader->ReadString(Record, Idx);
312   }
313 
314   /// Read a path, advancing Idx.
315   std::string readPath() {
316     return Reader->ReadPath(*F, Record, Idx);
317   }
318 
319   /// Read a version tuple, advancing Idx.
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.
331   BTFTypeTagAttr *readBTFTypeTagAttr() {
332     return cast<BTFTypeTagAttr>(readAttr());
333   }
334 
335   /// Reads a token out of a record, advancing Idx.
336   Token readToken() {
337     return Reader->ReadToken(*F, Record, Idx);
338   }
339 
340   void recordSwitchCaseID(SwitchCase *SC, unsigned ID) {
341     Reader->RecordSwitchCaseID(SC, ID);
342   }
343 
344   /// Retrieve the switch-case statement with the given 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 {
353   explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
354       : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}
355 
356   ~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 
368 inline void PCHValidator::Error(const char *Msg) {
369   Reader.Error(Msg);
370 }
371 
372 } // namespace clang
373 
374 #endif
375