//===- 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 "clang/Serialization/SourceLocationEncoding.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;
  using LocSeq = SourceLocationSequence;

  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, LocSeq *Seq = nullptr);

  /// 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(LocSeq *Seq = nullptr) {
    return Reader->ReadSourceLocation(*F, Record, Idx, Seq);
  }

  /// Read a source range, advancing Idx.
  SourceRange readSourceRange(LocSeq *Seq = nullptr) {
    return Reader->ReadSourceRange(*F, Record, Idx, Seq);
  }

  /// 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);

  /// Read an BTFTypeTagAttr object.
  BTFTypeTagAttr *readBTFTypeTagAttr() {
    return cast<BTFTypeTagAttr>(readAttr());
  }

  /// 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(
          llvm::Twine("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
