//===------------------------- MemberPointer.h ------------------*- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H
#define LLVM_CLANG_AST_INTERP_MEMBER_POINTER_H

#include "Pointer.h"
#include <optional>

namespace clang {
class ASTContext;
namespace interp {

class Context;
class FunctionPointer;

class MemberPointer final {
private:
  Pointer Base;
  const ValueDecl *Dcl = nullptr;
  int32_t PtrOffset = 0;

  MemberPointer(Pointer Base, const ValueDecl *Dcl, int32_t PtrOffset)
      : Base(Base), Dcl(Dcl), PtrOffset(PtrOffset) {}

public:
  MemberPointer() = default;
  MemberPointer(Pointer Base, const ValueDecl *Dcl) : Base(Base), Dcl(Dcl) {}
  MemberPointer(uint32_t Address, const Descriptor *D) {
    // We only reach this for Address == 0, when creating a null member pointer.
    assert(Address == 0);
  }

  MemberPointer(const ValueDecl *D) : Dcl(D) {
    assert((isa<FieldDecl, IndirectFieldDecl, CXXMethodDecl>(D)));
  }

  uint64_t getIntegerRepresentation() const {
    assert(
        false &&
        "getIntegerRepresentation() shouldn't be reachable for MemberPointers");
    return 17;
  }

  std::optional<Pointer> toPointer(const Context &Ctx) const;

  FunctionPointer toFunctionPointer(const Context &Ctx) const;

  bool isBaseCastPossible() const {
    if (PtrOffset < 0)
      return true;
    return static_cast<uint64_t>(PtrOffset) <= Base.getByteOffset();
  }

  Pointer getBase() const {
    if (PtrOffset < 0)
      return Base.atField(-PtrOffset);
    return Base.atFieldSub(PtrOffset);
  }
  bool isMemberFunctionPointer() const {
    return isa_and_nonnull<CXXMethodDecl>(Dcl);
  }
  const CXXMethodDecl *getMemberFunction() const {
    return dyn_cast_if_present<CXXMethodDecl>(Dcl);
  }
  const FieldDecl *getField() const {
    return dyn_cast_if_present<FieldDecl>(Dcl);
  }

  bool hasDecl() const { return Dcl; }
  const ValueDecl *getDecl() const { return Dcl; }

  MemberPointer atInstanceBase(unsigned Offset) const {
    if (Base.isZero())
      return MemberPointer(Base, Dcl, Offset);
    return MemberPointer(this->Base, Dcl, Offset + PtrOffset);
  }

  MemberPointer takeInstance(Pointer Instance) const {
    assert(this->Base.isZero());
    return MemberPointer(Instance, this->Dcl, this->PtrOffset);
  }

  APValue toAPValue(const ASTContext &) const;

  bool isZero() const { return Base.isZero() && !Dcl; }
  bool hasBase() const { return !Base.isZero(); }
  bool isWeak() const {
    if (const auto *MF = getMemberFunction())
      return MF->isWeak();
    return false;
  }

  void print(llvm::raw_ostream &OS) const {
    OS << "MemberPtr(" << Base << " " << (const void *)Dcl << " + " << PtrOffset
       << ")";
  }

  std::string toDiagnosticString(const ASTContext &Ctx) const {
    return toAPValue(Ctx).getAsString(Ctx, Dcl->getType());
  }

  ComparisonCategoryResult compare(const MemberPointer &RHS) const {
    if (this->Dcl == RHS.Dcl)
      return ComparisonCategoryResult::Equal;
    return ComparisonCategoryResult::Unordered;
  }
};

inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MemberPointer FP) {
  FP.print(OS);
  return OS;
}

} // namespace interp
} // namespace clang

#endif
