//===- 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/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 {

/// 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(uint32_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 OpenMP clause, advancing Idx.
  OMPClause *readOMPClause();

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

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