| //===- ASTRecordReader.h - Helper classes for reading AST -------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines classes that are useful in the implementation of |
| // the ASTReader. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H |
| #define LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H |
| |
| #include "clang/AST/ASTContext.h" |
| #include "clang/AST/AbstractBasicReader.h" |
| #include "clang/Lex/Token.h" |
| #include "clang/Serialization/ASTReader.h" |
| #include "llvm/ADT/APFloat.h" |
| #include "llvm/ADT/APInt.h" |
| #include "llvm/ADT/APSInt.h" |
| |
| namespace clang { |
| class OMPTraitInfo; |
| class OMPChildren; |
| |
| /// An object for streaming information from a record. |
| class ASTRecordReader |
| : public serialization::DataStreamBasicReader<ASTRecordReader> { |
| using ModuleFile = serialization::ModuleFile; |
| |
| ASTReader *Reader; |
| ModuleFile *F; |
| unsigned Idx = 0; |
| ASTReader::RecordData Record; |
| |
| using RecordData = ASTReader::RecordData; |
| using RecordDataImpl = ASTReader::RecordDataImpl; |
| |
| public: |
| /// Construct an ASTRecordReader that uses the default encoding scheme. |
| ASTRecordReader(ASTReader &Reader, ModuleFile &F) |
| : DataStreamBasicReader(Reader.getContext()), Reader(&Reader), F(&F) {} |
| |
| /// Reads a record with id AbbrevID from Cursor, resetting the |
| /// internal state. |
| Expected<unsigned> readRecord(llvm::BitstreamCursor &Cursor, |
| unsigned AbbrevID); |
| |
| /// Is this a module file for a module (rather than a PCH or similar). |
| bool isModule() const { return F->isModule(); } |
| |
| /// Retrieve the AST context that this AST reader supplements. |
| ASTContext &getContext() { return Reader->getContext(); } |
| |
| /// The current position in this record. |
| unsigned getIdx() const { return Idx; } |
| |
| /// The length of this record. |
| size_t size() const { return Record.size(); } |
| |
| /// An arbitrary index in this record. |
| const uint64_t &operator[](size_t N) { return Record[N]; } |
| |
| /// Returns the last value in this record. |
| uint64_t back() { return Record.back(); } |
| |
| /// Returns the current value in this record, and advances to the |
| /// next value. |
| uint64_t readInt() { return Record[Idx++]; } |
| |
| ArrayRef<uint64_t> readIntArray(unsigned Len) { |
| auto Array = llvm::makeArrayRef(Record).slice(Idx, Len); |
| Idx += Len; |
| return Array; |
| } |
| |
| /// Returns the current value in this record, without advancing. |
| uint64_t peekInt() { return Record[Idx]; } |
| |
| /// Skips the specified number of values. |
| void skipInts(unsigned N) { Idx += N; } |
| |
| /// Retrieve the global submodule ID its local ID number. |
| serialization::SubmoduleID |
| getGlobalSubmoduleID(unsigned LocalID) { |
| return Reader->getGlobalSubmoduleID(*F, LocalID); |
| } |
| |
| /// Retrieve the submodule that corresponds to a global submodule ID. |
| Module *getSubmodule(serialization::SubmoduleID GlobalID) { |
| return Reader->getSubmodule(GlobalID); |
| } |
| |
| /// Read the record that describes the lexical contents of a DC. |
| bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) { |
| return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset, |
| DC); |
| } |
| |
| /// Read the record that describes the visible contents of a DC. |
| bool readVisibleDeclContextStorage(uint64_t Offset, |
| serialization::DeclID ID) { |
| return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset, |
| ID); |
| } |
| |
| ExplicitSpecifier readExplicitSpec() { |
| uint64_t Kind = readInt(); |
| bool HasExpr = Kind & 0x1; |
| Kind = Kind >> 1; |
| return ExplicitSpecifier(HasExpr ? readExpr() : nullptr, |
| static_cast<ExplicitSpecKind>(Kind)); |
| } |
| |
| /// Read information about an exception specification (inherited). |
| //FunctionProtoType::ExceptionSpecInfo |
| //readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage); |
| |
| /// Get the global offset corresponding to a local offset. |
| uint64_t getGlobalBitOffset(uint64_t LocalOffset) { |
| return Reader->getGlobalBitOffset(*F, LocalOffset); |
| } |
| |
| /// Reads a statement. |
| Stmt *readStmt() { return Reader->ReadStmt(*F); } |
| Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ } |
| |
| /// Reads an expression. |
| Expr *readExpr() { return Reader->ReadExpr(*F); } |
| |
| /// Reads a sub-statement operand during statement reading. |
| Stmt *readSubStmt() { return Reader->ReadSubStmt(); } |
| |
| /// Reads a sub-expression operand during statement reading. |
| Expr *readSubExpr() { return Reader->ReadSubExpr(); } |
| |
| /// Reads a declaration with the given local ID in the given module. |
| /// |
| /// \returns The requested declaration, casted to the given return type. |
| template<typename T> |
| T *GetLocalDeclAs(uint32_t LocalID) { |
| return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); |
| } |
| |
| /// Reads a TemplateArgumentLocInfo appropriate for the |
| /// given TemplateArgument kind, advancing Idx. |
| TemplateArgumentLocInfo |
| readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind); |
| |
| /// Reads a TemplateArgumentLoc, advancing Idx. |
| TemplateArgumentLoc readTemplateArgumentLoc(); |
| |
| const ASTTemplateArgumentListInfo* |
| readASTTemplateArgumentListInfo(); |
| |
| /// Reads a declarator info from the given record, advancing Idx. |
| TypeSourceInfo *readTypeSourceInfo(); |
| |
| /// Reads the location information for a type. |
| void readTypeLoc(TypeLoc TL); |
| |
| |
| /// Map a local type ID within a given AST file to a global type ID. |
| serialization::TypeID getGlobalTypeID(unsigned LocalID) const { |
| return Reader->getGlobalTypeID(*F, LocalID); |
| } |
| |
| Qualifiers readQualifiers() { |
| return Qualifiers::fromOpaqueValue(readInt()); |
| } |
| |
| /// Read a type from the current position in the record. |
| QualType readType() { |
| return Reader->readType(*F, Record, Idx); |
| } |
| QualType readQualType() { |
| return readType(); |
| } |
| |
| /// Reads a declaration ID from the given position in this record. |
| /// |
| /// \returns The declaration ID read from the record, adjusted to a global ID. |
| serialization::DeclID readDeclID() { |
| return Reader->ReadDeclID(*F, Record, Idx); |
| } |
| |
| /// Reads a declaration from the given position in a record in the |
| /// given module, advancing Idx. |
| Decl *readDecl() { |
| return Reader->ReadDecl(*F, Record, Idx); |
| } |
| Decl *readDeclRef() { |
| return readDecl(); |
| } |
| |
| /// Reads a declaration from the given position in the record, |
| /// advancing Idx. |
| /// |
| /// \returns The declaration read from this location, casted to the given |
| /// result type. |
| template<typename T> |
| T *readDeclAs() { |
| return Reader->ReadDeclAs<T>(*F, Record, Idx); |
| } |
| |
| IdentifierInfo *readIdentifier() { |
| return Reader->readIdentifier(*F, Record, Idx); |
| } |
| |
| /// Read a selector from the Record, advancing Idx. |
| Selector readSelector() { |
| return Reader->ReadSelector(*F, Record, Idx); |
| } |
| |
| /// Read a declaration name, advancing Idx. |
| // DeclarationName readDeclarationName(); (inherited) |
| DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name); |
| DeclarationNameInfo readDeclarationNameInfo(); |
| |
| void readQualifierInfo(QualifierInfo &Info); |
| |
| /// Return a nested name specifier, advancing Idx. |
| // NestedNameSpecifier *readNestedNameSpecifier(); (inherited) |
| |
| NestedNameSpecifierLoc readNestedNameSpecifierLoc(); |
| |
| /// Read a template name, advancing Idx. |
| // TemplateName readTemplateName(); (inherited) |
| |
| /// Read a template argument, advancing Idx. (inherited) |
| // TemplateArgument readTemplateArgument(); |
| using DataStreamBasicReader::readTemplateArgument; |
| TemplateArgument readTemplateArgument(bool Canonicalize) { |
| TemplateArgument Arg = readTemplateArgument(); |
| if (Canonicalize) { |
| Arg = getContext().getCanonicalTemplateArgument(Arg); |
| } |
| return Arg; |
| } |
| |
| /// Read a template parameter list, advancing Idx. |
| TemplateParameterList *readTemplateParameterList(); |
| |
| /// Read a template argument array, advancing Idx. |
| void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, |
| bool Canonicalize = false); |
| |
| /// Read a UnresolvedSet structure, advancing Idx. |
| void readUnresolvedSet(LazyASTUnresolvedSet &Set); |
| |
| /// Read a C++ base specifier, advancing Idx. |
| CXXBaseSpecifier readCXXBaseSpecifier(); |
| |
| /// Read a CXXCtorInitializer array, advancing Idx. |
| CXXCtorInitializer **readCXXCtorInitializers(); |
| |
| CXXTemporary *readCXXTemporary() { |
| return Reader->ReadCXXTemporary(*F, Record, Idx); |
| } |
| |
| /// Read an OMPTraitInfo object, advancing Idx. |
| OMPTraitInfo *readOMPTraitInfo(); |
| |
| /// Read an OpenMP clause, advancing Idx. |
| OMPClause *readOMPClause(); |
| |
| /// Read an OpenMP children, advancing Idx. |
| void readOMPChildren(OMPChildren *Data); |
| |
| /// Read a source location, advancing Idx. |
| SourceLocation readSourceLocation() { |
| return Reader->ReadSourceLocation(*F, Record, Idx); |
| } |
| |
| /// Read a source range, advancing Idx. |
| SourceRange readSourceRange() { |
| return Reader->ReadSourceRange(*F, Record, Idx); |
| } |
| |
| /// Read an arbitrary constant value, advancing Idx. |
| // APValue readAPValue(); (inherited) |
| |
| /// Read an integral value, advancing Idx. |
| // llvm::APInt readAPInt(); (inherited) |
| |
| /// Read a signed integral value, advancing Idx. |
| // llvm::APSInt readAPSInt(); (inherited) |
| |
| /// Read a floating-point value, advancing Idx. |
| llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem); |
| |
| /// Read a boolean value, advancing Idx. |
| bool readBool() { return readInt() != 0; } |
| |
| /// Read a 32-bit unsigned value; required to satisfy BasicReader. |
| uint32_t readUInt32() { |
| return uint32_t(readInt()); |
| } |
| |
| /// Read a 64-bit unsigned value; required to satisfy BasicReader. |
| uint64_t readUInt64() { |
| return readInt(); |
| } |
| |
| /// Read a string, advancing Idx. |
| std::string readString() { |
| return Reader->ReadString(Record, Idx); |
| } |
| |
| /// Read a path, advancing Idx. |
| std::string readPath() { |
| return Reader->ReadPath(*F, Record, Idx); |
| } |
| |
| /// Read a version tuple, advancing Idx. |
| VersionTuple readVersionTuple() { |
| return ASTReader::ReadVersionTuple(Record, Idx); |
| } |
| |
| /// Reads one attribute from the current stream position, advancing Idx. |
| Attr *readAttr(); |
| |
| /// Reads attributes from the current stream position, advancing Idx. |
| void readAttributes(AttrVec &Attrs); |
| |
| /// Reads a token out of a record, advancing Idx. |
| Token readToken() { |
| return Reader->ReadToken(*F, Record, Idx); |
| } |
| |
| void recordSwitchCaseID(SwitchCase *SC, unsigned ID) { |
| Reader->RecordSwitchCaseID(SC, ID); |
| } |
| |
| /// Retrieve the switch-case statement with the given ID. |
| SwitchCase *getSwitchCaseWithID(unsigned ID) { |
| return Reader->getSwitchCaseWithID(ID); |
| } |
| }; |
| |
| /// Helper class that saves the current stream position and |
| /// then restores it when destroyed. |
| struct SavedStreamPosition { |
| explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) |
| : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} |
| |
| ~SavedStreamPosition() { |
| if (llvm::Error Err = Cursor.JumpToBit(Offset)) |
| llvm::report_fatal_error( |
| "Cursor should always be able to go back, failed: " + |
| toString(std::move(Err))); |
| } |
| |
| private: |
| llvm::BitstreamCursor &Cursor; |
| uint64_t Offset; |
| }; |
| |
| inline void PCHValidator::Error(const char *Msg) { |
| Reader.Error(Msg); |
| } |
| |
| } // namespace clang |
| |
| #endif |