//===-- ValueObject.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 LLDB_CORE_VALUEOBJECT_H
#define LLDB_CORE_VALUEOBJECT_H

#include "lldb/Core/Value.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/SharedCluster.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-types.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"

#include <functional>
#include <initializer_list>
#include <map>
#include <mutex>
#include <string>
#include <utility>

#include <stddef.h>
#include <stdint.h>

namespace lldb_private {
class Declaration;
class DumpValueObjectOptions;
class EvaluateExpressionOptions;
class ExecutionContextScope;
class Log;
class Scalar;
class Stream;
class SymbolContextScope;
class TypeFormatImpl;
class TypeSummaryImpl;
class TypeSummaryOptions;

/// ValueObject:
///
/// This abstract class provides an interface to a particular value, be it a
/// register, a local or global variable,
/// that is evaluated in some particular scope.  The ValueObject also has the
/// capability of being the "child" of
/// some other variable object, and in turn of having children.
/// If a ValueObject is a root variable object - having no parent - then it must
/// be constructed with respect to some
/// particular ExecutionContextScope.  If it is a child, it inherits the
/// ExecutionContextScope from its parent.
/// The ValueObject will update itself if necessary before fetching its value,
/// summary, object description, etc.
/// But it will always update itself in the ExecutionContextScope with which it
/// was originally created.

/// A brief note on life cycle management for ValueObjects.  This is a little
/// tricky because a ValueObject can contain
/// various other ValueObjects - the Dynamic Value, its children, the
/// dereference value, etc.  Any one of these can be
/// handed out as a shared pointer, but for that contained value object to be
/// valid, the root object and potentially other
/// of the value objects need to stay around.
/// We solve this problem by handing out shared pointers to the Value Object and
/// any of its dependents using a shared
/// ClusterManager.  This treats each shared pointer handed out for the entire
/// cluster as a reference to the whole
/// cluster.  The whole cluster will stay around until the last reference is
/// released.
///
/// The ValueObject mostly handle this automatically, if a value object is made
/// with a Parent ValueObject, then it adds
/// itself to the ClusterManager of the parent.

/// It does mean that external to the ValueObjects we should only ever make
/// available ValueObjectSP's, never ValueObjects
/// or pointers to them.  So all the "Root level" ValueObject derived
/// constructors should be private, and
/// should implement a Create function that new's up object and returns a Shared
/// Pointer that it gets from the GetSP() method.
///
/// However, if you are making an derived ValueObject that will be contained in
/// a parent value object, you should just
/// hold onto a pointer to it internally, and by virtue of passing the parent
/// ValueObject into its constructor, it will
/// be added to the ClusterManager for the parent.  Then if you ever hand out a
/// Shared Pointer to the contained ValueObject,
/// just do so by calling GetSP() on the contained object.

class ValueObject {
public:
  enum GetExpressionPathFormat {
    eGetExpressionPathFormatDereferencePointers = 1,
    eGetExpressionPathFormatHonorPointers
  };

  enum ValueObjectRepresentationStyle {
    eValueObjectRepresentationStyleValue = 1,
    eValueObjectRepresentationStyleSummary,
    eValueObjectRepresentationStyleLanguageSpecific,
    eValueObjectRepresentationStyleLocation,
    eValueObjectRepresentationStyleChildrenCount,
    eValueObjectRepresentationStyleType,
    eValueObjectRepresentationStyleName,
    eValueObjectRepresentationStyleExpressionPath
  };

  enum ExpressionPathScanEndReason {
    /// Out of data to parse.
    eExpressionPathScanEndReasonEndOfString = 1,
    /// Child element not found.
    eExpressionPathScanEndReasonNoSuchChild,
    /// (Synthetic) child  element not found.
    eExpressionPathScanEndReasonNoSuchSyntheticChild,
    /// [] only allowed for arrays.
    eExpressionPathScanEndReasonEmptyRangeNotAllowed,
    /// . used when -> should be used.
    eExpressionPathScanEndReasonDotInsteadOfArrow,
    /// -> used when . should be used.
    eExpressionPathScanEndReasonArrowInsteadOfDot,
    /// ObjC ivar expansion not allowed.
    eExpressionPathScanEndReasonFragileIVarNotAllowed,
    /// [] not allowed by options.
    eExpressionPathScanEndReasonRangeOperatorNotAllowed,
    /// [] not valid on objects  other than scalars, pointers or arrays.
    eExpressionPathScanEndReasonRangeOperatorInvalid,
    /// [] is good for arrays,  but I cannot parse it.
    eExpressionPathScanEndReasonArrayRangeOperatorMet,
    /// [] is good for bitfields, but I cannot parse after it.
    eExpressionPathScanEndReasonBitfieldRangeOperatorMet,
    /// Something is malformed in he expression.
    eExpressionPathScanEndReasonUnexpectedSymbol,
    /// Impossible to apply &  operator.
    eExpressionPathScanEndReasonTakingAddressFailed,
    /// Impossible to apply *  operator.
    eExpressionPathScanEndReasonDereferencingFailed,
    /// [] was expanded into a  VOList.
    eExpressionPathScanEndReasonRangeOperatorExpanded,
    /// getting the synthetic children failed.
    eExpressionPathScanEndReasonSyntheticValueMissing,
    eExpressionPathScanEndReasonUnknown = 0xFFFF
  };

  enum ExpressionPathEndResultType {
    /// Anything but...
    eExpressionPathEndResultTypePlain = 1,
    /// A bitfield.
    eExpressionPathEndResultTypeBitfield,
    /// A range [low-high].
    eExpressionPathEndResultTypeBoundedRange,
    /// A range [].
    eExpressionPathEndResultTypeUnboundedRange,
    /// Several items in a VOList.
    eExpressionPathEndResultTypeValueObjectList,
    eExpressionPathEndResultTypeInvalid = 0xFFFF
  };

  enum ExpressionPathAftermath {
    /// Just return it.
    eExpressionPathAftermathNothing = 1,
    /// Dereference the target.
    eExpressionPathAftermathDereference,
    /// Take target's address.
    eExpressionPathAftermathTakeAddress
  };

  enum ClearUserVisibleDataItems {
    eClearUserVisibleDataItemsNothing = 1u << 0,
    eClearUserVisibleDataItemsValue = 1u << 1,
    eClearUserVisibleDataItemsSummary = 1u << 2,
    eClearUserVisibleDataItemsLocation = 1u << 3,
    eClearUserVisibleDataItemsDescription = 1u << 4,
    eClearUserVisibleDataItemsSyntheticChildren = 1u << 5,
    eClearUserVisibleDataItemsAllStrings =
        eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary |
        eClearUserVisibleDataItemsLocation |
        eClearUserVisibleDataItemsDescription,
    eClearUserVisibleDataItemsAll = 0xFFFF
  };

  struct GetValueForExpressionPathOptions {
    enum class SyntheticChildrenTraversal {
      None,
      ToSynthetic,
      FromSynthetic,
      Both
    };

    bool m_check_dot_vs_arrow_syntax;
    bool m_no_fragile_ivar;
    bool m_allow_bitfields_syntax;
    SyntheticChildrenTraversal m_synthetic_children_traversal;

    GetValueForExpressionPathOptions(
        bool dot = false, bool no_ivar = false, bool bitfield = true,
        SyntheticChildrenTraversal synth_traverse =
            SyntheticChildrenTraversal::ToSynthetic)
        : m_check_dot_vs_arrow_syntax(dot), m_no_fragile_ivar(no_ivar),
          m_allow_bitfields_syntax(bitfield),
          m_synthetic_children_traversal(synth_traverse) {}

    GetValueForExpressionPathOptions &DoCheckDotVsArrowSyntax() {
      m_check_dot_vs_arrow_syntax = true;
      return *this;
    }

    GetValueForExpressionPathOptions &DontCheckDotVsArrowSyntax() {
      m_check_dot_vs_arrow_syntax = false;
      return *this;
    }

    GetValueForExpressionPathOptions &DoAllowFragileIVar() {
      m_no_fragile_ivar = false;
      return *this;
    }

    GetValueForExpressionPathOptions &DontAllowFragileIVar() {
      m_no_fragile_ivar = true;
      return *this;
    }

    GetValueForExpressionPathOptions &DoAllowBitfieldSyntax() {
      m_allow_bitfields_syntax = true;
      return *this;
    }

    GetValueForExpressionPathOptions &DontAllowBitfieldSyntax() {
      m_allow_bitfields_syntax = false;
      return *this;
    }

    GetValueForExpressionPathOptions &
    SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse) {
      m_synthetic_children_traversal = traverse;
      return *this;
    }

    static const GetValueForExpressionPathOptions DefaultOptions() {
      static GetValueForExpressionPathOptions g_default_options;

      return g_default_options;
    }
  };

  class EvaluationPoint {
  public:
    EvaluationPoint();

    EvaluationPoint(ExecutionContextScope *exe_scope,
                    bool use_selected = false);

    EvaluationPoint(const EvaluationPoint &rhs);

    ~EvaluationPoint();

    const ExecutionContextRef &GetExecutionContextRef() const {
      return m_exe_ctx_ref;
    }

    void SetIsConstant() {
      SetUpdated();
      m_mod_id.SetInvalid();
    }

    bool IsConstant() const { return !m_mod_id.IsValid(); }

    ProcessModID GetModID() const { return m_mod_id; }

    void SetUpdateID(ProcessModID new_id) { m_mod_id = new_id; }

    void SetNeedsUpdate() { m_needs_update = true; }

    void SetUpdated();

    bool NeedsUpdating(bool accept_invalid_exe_ctx) {
      SyncWithProcessState(accept_invalid_exe_ctx);
      return m_needs_update;
    }

    bool IsValid() {
      const bool accept_invalid_exe_ctx = false;
      if (!m_mod_id.IsValid())
        return false;
      else if (SyncWithProcessState(accept_invalid_exe_ctx)) {
        if (!m_mod_id.IsValid())
          return false;
      }
      return true;
    }

    void SetInvalid() {
      // Use the stop id to mark us as invalid, leave the thread id and the
      // stack id around for logging and history purposes.
      m_mod_id.SetInvalid();

      // Can't update an invalid state.
      m_needs_update = false;
    }

  private:
    bool SyncWithProcessState(bool accept_invalid_exe_ctx);

    ProcessModID m_mod_id; // This is the stop id when this ValueObject was last
                           // evaluated.
    ExecutionContextRef m_exe_ctx_ref;
    bool m_needs_update;
  };

  virtual ~ValueObject();

  const EvaluationPoint &GetUpdatePoint() const { return m_update_point; }

  EvaluationPoint &GetUpdatePoint() { return m_update_point; }

  const ExecutionContextRef &GetExecutionContextRef() const {
    return m_update_point.GetExecutionContextRef();
  }

  lldb::TargetSP GetTargetSP() const {
    return m_update_point.GetExecutionContextRef().GetTargetSP();
  }

  lldb::ProcessSP GetProcessSP() const {
    return m_update_point.GetExecutionContextRef().GetProcessSP();
  }

  lldb::ThreadSP GetThreadSP() const {
    return m_update_point.GetExecutionContextRef().GetThreadSP();
  }

  lldb::StackFrameSP GetFrameSP() const {
    return m_update_point.GetExecutionContextRef().GetFrameSP();
  }

  void SetNeedsUpdate();

  CompilerType GetCompilerType() { return MaybeCalculateCompleteType(); }

  // this vends a TypeImpl that is useful at the SB API layer
  virtual TypeImpl GetTypeImpl() { return TypeImpl(GetCompilerType()); }

  virtual bool CanProvideValue();

  // Subclasses must implement the functions below.
  virtual llvm::Optional<uint64_t> GetByteSize() = 0;

  virtual lldb::ValueType GetValueType() const = 0;

  // Subclasses can implement the functions below.
  virtual ConstString GetTypeName() { return GetCompilerType().GetTypeName(); }

  virtual ConstString GetDisplayTypeName() { return GetTypeName(); }

  virtual ConstString GetQualifiedTypeName() {
    return GetCompilerType().GetTypeName();
  }

  virtual lldb::LanguageType GetObjectRuntimeLanguage() {
    return GetCompilerType().GetMinimumLanguage();
  }

  virtual uint32_t
  GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) {
    return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
  }

  virtual bool IsPointerType() { return GetCompilerType().IsPointerType(); }

  virtual bool IsArrayType() { return GetCompilerType().IsArrayType(); }

  virtual bool IsScalarType() { return GetCompilerType().IsScalarType(); }

  virtual bool IsPointerOrReferenceType() {
    return GetCompilerType().IsPointerOrReferenceType();
  }

  virtual bool IsPossibleDynamicType();

  bool IsNilReference();

  bool IsUninitializedReference();

  virtual bool IsBaseClass() { return false; }

  bool IsBaseClass(uint32_t &depth);

  virtual bool IsDereferenceOfParent() { return false; }

  bool IsIntegerType(bool &is_signed) {
    return GetCompilerType().IsIntegerType(is_signed);
  }

  virtual void GetExpressionPath(
      Stream &s,
      GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers);

  lldb::ValueObjectSP GetValueForExpressionPath(
      llvm::StringRef expression,
      ExpressionPathScanEndReason *reason_to_stop = nullptr,
      ExpressionPathEndResultType *final_value_type = nullptr,
      const GetValueForExpressionPathOptions &options =
          GetValueForExpressionPathOptions::DefaultOptions(),
      ExpressionPathAftermath *final_task_on_target = nullptr);

  virtual bool IsInScope() { return true; }

  virtual lldb::offset_t GetByteOffset() { return 0; }

  virtual uint32_t GetBitfieldBitSize() { return 0; }

  virtual uint32_t GetBitfieldBitOffset() { return 0; }

  bool IsBitfield() {
    return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0);
  }

  virtual bool IsArrayItemForPointer() {
    return m_flags.m_is_array_item_for_pointer;
  }

  virtual const char *GetValueAsCString();

  virtual bool GetValueAsCString(const lldb_private::TypeFormatImpl &format,
                                 std::string &destination);

  bool GetValueAsCString(lldb::Format format, std::string &destination);

  virtual uint64_t GetValueAsUnsigned(uint64_t fail_value,
                                      bool *success = nullptr);

  virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = nullptr);

  virtual bool SetValueFromCString(const char *value_str, Status &error);

  /// Return the module associated with this value object in case the value is
  /// from an executable file and might have its data in sections of the file.
  /// This can be used for variables.
  virtual lldb::ModuleSP GetModule();

  ValueObject *GetRoot();

  /// Given a ValueObject, loop over itself and its parent, and its parent's
  /// parent, .. until either the given callback returns false, or you end up at
  /// a null pointer
  ValueObject *FollowParentChain(std::function<bool(ValueObject *)>);

  virtual bool GetDeclaration(Declaration &decl);

  // The functions below should NOT be modified by subclasses
  const Status &GetError();

  ConstString GetName() const { return m_name; }

  /// Returns a unique id for this ValueObject.
  lldb::user_id_t GetID() const { return m_id.GetID(); }

  virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create);

  // this will always create the children if necessary
  lldb::ValueObjectSP GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
                                          size_t *index_of_error = nullptr);

  lldb::ValueObjectSP
  GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t, bool>> idxs,
                      size_t *index_of_error = nullptr);

  // this will always create the children if necessary
  lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
                                         ConstString *name_of_error = nullptr);

  lldb::ValueObjectSP
  GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString, bool>> names,
                     ConstString *name_of_error = nullptr);

  virtual lldb::ValueObjectSP GetChildMemberWithName(ConstString name,
                                                     bool can_create);

  virtual size_t GetIndexOfChildWithName(ConstString name);

  size_t GetNumChildren(uint32_t max = UINT32_MAX);

  const Value &GetValue() const { return m_value; }

  Value &GetValue() { return m_value; }

  virtual bool ResolveValue(Scalar &scalar);

  // return 'false' whenever you set the error, otherwise callers may assume
  // true means everything is OK - this will break breakpoint conditions among
  // potentially a few others
  virtual bool IsLogicalTrue(Status &error);

  virtual const char *GetLocationAsCString() {
    return GetLocationAsCStringImpl(m_value, m_data);
  }

  const char *
  GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown);

  bool
  GetSummaryAsCString(TypeSummaryImpl *summary_ptr, std::string &destination,
                      lldb::LanguageType lang = lldb::eLanguageTypeUnknown);

  bool GetSummaryAsCString(std::string &destination,
                           const TypeSummaryOptions &options);

  bool GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
                           std::string &destination,
                           const TypeSummaryOptions &options);

  const char *GetObjectDescription();

  bool HasSpecialPrintableRepresentation(
      ValueObjectRepresentationStyle val_obj_display,
      lldb::Format custom_format);

  enum class PrintableRepresentationSpecialCases : bool {
    eDisable = false,
    eAllow = true
  };

  bool
  DumpPrintableRepresentation(Stream &s,
                              ValueObjectRepresentationStyle val_obj_display =
                                  eValueObjectRepresentationStyleSummary,
                              lldb::Format custom_format = lldb::eFormatInvalid,
                              PrintableRepresentationSpecialCases special =
                                  PrintableRepresentationSpecialCases::eAllow,
                              bool do_dump_error = true);
  bool GetValueIsValid() const { return m_flags.m_value_is_valid; }

  // If you call this on a newly created ValueObject, it will always return
  // false.
  bool GetValueDidChange() { return m_flags.m_value_did_change; }

  bool UpdateValueIfNeeded(bool update_format = true);

  bool UpdateFormatsIfNeeded();

  lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(this); }

  /// Change the name of the current ValueObject. Should *not* be used from a
  /// synthetic child provider as it would change the name of the non synthetic
  /// child as well.
  void SetName(ConstString name) { m_name = name; }

  virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
                                    AddressType *address_type = nullptr);

  lldb::addr_t GetPointerValue(AddressType *address_type = nullptr);

  lldb::ValueObjectSP GetSyntheticChild(ConstString key) const;

  lldb::ValueObjectSP GetSyntheticArrayMember(size_t index, bool can_create);

  lldb::ValueObjectSP GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
                                                bool can_create);

  lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression,
                                                      bool can_create);

  virtual lldb::ValueObjectSP
  GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type,
                            bool can_create,
                            ConstString name_const_str = ConstString());

  virtual lldb::ValueObjectSP
  GetSyntheticBase(uint32_t offset, const CompilerType &type, bool can_create,
                   ConstString name_const_str = ConstString());

  virtual lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType);

  lldb::DynamicValueType GetDynamicValueType();

  virtual lldb::ValueObjectSP GetStaticValue() { return GetSP(); }

  virtual lldb::ValueObjectSP GetNonSyntheticValue() { return GetSP(); }

  lldb::ValueObjectSP GetSyntheticValue();

  virtual bool HasSyntheticValue();

  virtual bool IsSynthetic() { return false; }

  lldb::ValueObjectSP
  GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue,
                                        bool synthValue);

  virtual lldb::ValueObjectSP CreateConstantValue(ConstString name);

  virtual lldb::ValueObjectSP Dereference(Status &error);

  /// Creates a copy of the ValueObject with a new name and setting the current
  /// ValueObject as its parent. It should be used when we want to change the
  /// name of a ValueObject without modifying the actual ValueObject itself
  /// (e.g. sythetic child provider).
  virtual lldb::ValueObjectSP Clone(ConstString new_name);

  virtual lldb::ValueObjectSP AddressOf(Status &error);

  virtual lldb::addr_t GetLiveAddress() { return LLDB_INVALID_ADDRESS; }

  virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
                              AddressType address_type = eAddressTypeLoad) {}

  virtual lldb::ValueObjectSP Cast(const CompilerType &compiler_type);

  virtual lldb::ValueObjectSP CastPointerType(const char *name,
                                              CompilerType &ast_type);

  virtual lldb::ValueObjectSP CastPointerType(const char *name,
                                              lldb::TypeSP &type_sp);

  // The backing bits of this value object were updated, clear any descriptive
  // string, so we know we have to refetch them.
  virtual void ValueUpdated() {
    ClearUserVisibleData(eClearUserVisibleDataItemsValue |
                         eClearUserVisibleDataItemsSummary |
                         eClearUserVisibleDataItemsDescription);
  }

  virtual bool IsDynamic() { return false; }

  virtual bool DoesProvideSyntheticValue() { return false; }

  virtual bool IsSyntheticChildrenGenerated() {
    return m_flags.m_is_synthetic_children_generated;
  }

  virtual void SetSyntheticChildrenGenerated(bool b) {
    m_flags.m_is_synthetic_children_generated = b;
  }

  virtual SymbolContextScope *GetSymbolContextScope();

  void Dump(Stream &s);

  void Dump(Stream &s, const DumpValueObjectOptions &options);

  static lldb::ValueObjectSP
  CreateValueObjectFromExpression(llvm::StringRef name,
                                  llvm::StringRef expression,
                                  const ExecutionContext &exe_ctx);

  static lldb::ValueObjectSP
  CreateValueObjectFromExpression(llvm::StringRef name,
                                  llvm::StringRef expression,
                                  const ExecutionContext &exe_ctx,
                                  const EvaluateExpressionOptions &options);

  static lldb::ValueObjectSP
  CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
                               const ExecutionContext &exe_ctx,
                               CompilerType type);

  static lldb::ValueObjectSP
  CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
                            const ExecutionContext &exe_ctx, CompilerType type);

  lldb::ValueObjectSP Persist();

  /// Returns true if this is a char* or a char[] if it is a char* and
  /// check_pointer is true, it also checks that the pointer is valid.
  bool IsCStringContainer(bool check_pointer = false);

  std::pair<size_t, bool>
  ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
                    uint32_t max_length = 0, bool honor_array = true,
                    lldb::Format item_format = lldb::eFormatCharArray);

  virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
                                uint32_t item_count = 1);

  virtual uint64_t GetData(DataExtractor &data, Status &error);

  virtual bool SetData(DataExtractor &data, Status &error);

  virtual bool GetIsConstant() const { return m_update_point.IsConstant(); }

  bool NeedsUpdating() {
    const bool accept_invalid_exe_ctx =
        (CanUpdateWithInvalidExecutionContext() == eLazyBoolYes);
    return m_update_point.NeedsUpdating(accept_invalid_exe_ctx);
  }

  void SetIsConstant() { m_update_point.SetIsConstant(); }

  lldb::Format GetFormat() const;

  virtual void SetFormat(lldb::Format format) {
    if (format != m_format)
      ClearUserVisibleData(eClearUserVisibleDataItemsValue);
    m_format = format;
  }

  virtual lldb::LanguageType GetPreferredDisplayLanguage();

  void SetPreferredDisplayLanguage(lldb::LanguageType lt) {
    m_preferred_display_language = lt;
  }

  lldb::TypeSummaryImplSP GetSummaryFormat() {
    UpdateFormatsIfNeeded();
    return m_type_summary_sp;
  }

  void SetSummaryFormat(lldb::TypeSummaryImplSP format) {
    m_type_summary_sp = std::move(format);
    ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
  }

  void SetValueFormat(lldb::TypeFormatImplSP format) {
    m_type_format_sp = std::move(format);
    ClearUserVisibleData(eClearUserVisibleDataItemsValue);
  }

  lldb::TypeFormatImplSP GetValueFormat() {
    UpdateFormatsIfNeeded();
    return m_type_format_sp;
  }

  void SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp) {
    if (synth_sp.get() == m_synthetic_children_sp.get())
      return;
    ClearUserVisibleData(eClearUserVisibleDataItemsSyntheticChildren);
    m_synthetic_children_sp = synth_sp;
  }

  lldb::SyntheticChildrenSP GetSyntheticChildren() {
    UpdateFormatsIfNeeded();
    return m_synthetic_children_sp;
  }

  // Use GetParent for display purposes, but if you want to tell the parent to
  // update itself then use m_parent.  The ValueObjectDynamicValue's parent is
  // not the correct parent for displaying, they are really siblings, so for
  // display it needs to route through to its grandparent.
  virtual ValueObject *GetParent() { return m_parent; }

  virtual const ValueObject *GetParent() const { return m_parent; }

  ValueObject *GetNonBaseClassParent();

  void SetAddressTypeOfChildren(AddressType at) {
    m_address_type_of_ptr_or_ref_children = at;
  }

  AddressType GetAddressTypeOfChildren();

  void SetHasCompleteType() {
    m_flags.m_did_calculate_complete_objc_class_type = true;
  }

  /// Find out if a ValueObject might have children.
  ///
  /// This call is much more efficient than CalculateNumChildren() as
  /// it doesn't need to complete the underlying type. This is designed
  /// to be used in a UI environment in order to detect if the
  /// disclosure triangle should be displayed or not.
  ///
  /// This function returns true for class, union, structure,
  /// pointers, references, arrays and more. Again, it does so without
  /// doing any expensive type completion.
  ///
  /// \return
  ///     Returns \b true if the ValueObject might have children, or \b
  ///     false otherwise.
  virtual bool MightHaveChildren();

  virtual lldb::VariableSP GetVariable() { return nullptr; }

  virtual bool IsRuntimeSupportValue();

  virtual uint64_t GetLanguageFlags() { return m_language_flags; }

  virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }

protected:
  typedef ClusterManager<ValueObject> ValueObjectManager;

  class ChildrenManager {
  public:
    ChildrenManager() : m_mutex(), m_children(), m_children_count(0) {}

    bool HasChildAtIndex(size_t idx) {
      std::lock_guard<std::recursive_mutex> guard(m_mutex);
      return (m_children.find(idx) != m_children.end());
    }

    ValueObject *GetChildAtIndex(size_t idx) {
      std::lock_guard<std::recursive_mutex> guard(m_mutex);
      const auto iter = m_children.find(idx);
      return ((iter == m_children.end()) ? nullptr : iter->second);
    }

    void SetChildAtIndex(size_t idx, ValueObject *valobj) {
      // we do not need to be mutex-protected to make a pair
      ChildrenPair pair(idx, valobj);
      std::lock_guard<std::recursive_mutex> guard(m_mutex);
      m_children.insert(pair);
    }

    void SetChildrenCount(size_t count) { Clear(count); }

    size_t GetChildrenCount() { return m_children_count; }

    void Clear(size_t new_count = 0) {
      std::lock_guard<std::recursive_mutex> guard(m_mutex);
      m_children_count = new_count;
      m_children.clear();
    }

  private:
    typedef std::map<size_t, ValueObject *> ChildrenMap;
    typedef ChildrenMap::iterator ChildrenIterator;
    typedef ChildrenMap::value_type ChildrenPair;
    std::recursive_mutex m_mutex;
    ChildrenMap m_children;
    size_t m_children_count;
  };

  // Classes that inherit from ValueObject can see and modify these

  /// The parent value object, or nullptr if this has no parent.
  ValueObject *m_parent = nullptr;
  /// The root of the hierarchy for this ValueObject (or nullptr if never
  /// calculated).
  ValueObject *m_root = nullptr;
  /// Stores both the stop id and the full context at which this value was last
  /// updated.  When we are asked to update the value object, we check whether
  /// the context & stop id are the same before updating.
  EvaluationPoint m_update_point;
  /// The name of this object.
  ConstString m_name;
  /// A data extractor that can be used to extract the value.
  DataExtractor m_data;
  Value m_value;
  /// An error object that can describe any errors that occur when updating
  /// values.
  Status m_error;
  /// Cached value string that will get cleared if/when the value is updated.
  std::string m_value_str;
  /// Cached old value string from the last time the value was gotten
  std::string m_old_value_str;
  /// Cached location string that will get cleared if/when the value is updated.
  std::string m_location_str;
  /// Cached summary string that will get cleared if/when the value is updated.
  std::string m_summary_str;
  /// Cached result of the "object printer". This differs from the summary
  /// in that the summary is consed up by us, the object_desc_string is builtin.
  std::string m_object_desc_str;
  /// If the type of the value object should be overridden, the type to impose.
  CompilerType m_override_type;

  /// This object is managed by the root object (any ValueObject that gets
  /// created without a parent.) The manager gets passed through all the
  /// generations of dependent objects, and will keep the whole cluster of
  /// objects alive as long as a shared pointer to any of them has been handed
  /// out. Shared pointers to value objects must always be made with the GetSP
  /// method.
  ValueObjectManager *m_manager = nullptr;

  ChildrenManager m_children;
  std::map<ConstString, ValueObject *> m_synthetic_children;

  ValueObject *m_dynamic_value = nullptr;
  ValueObject *m_synthetic_value = nullptr;
  ValueObject *m_deref_valobj = nullptr;

  /// We have to hold onto a shared  pointer to this one because it is created
  /// as an independent ValueObjectConstResult, which isn't managed by us.
  lldb::ValueObjectSP m_addr_of_valobj_sp;

  lldb::Format m_format = lldb::eFormatDefault;
  lldb::Format m_last_format = lldb::eFormatDefault;
  uint32_t m_last_format_mgr_revision = 0;
  lldb::TypeSummaryImplSP m_type_summary_sp;
  lldb::TypeFormatImplSP m_type_format_sp;
  lldb::SyntheticChildrenSP m_synthetic_children_sp;
  ProcessModID m_user_id_of_forced_summary;
  AddressType m_address_type_of_ptr_or_ref_children = eAddressTypeInvalid;

  llvm::SmallVector<uint8_t, 16> m_value_checksum;

  lldb::LanguageType m_preferred_display_language = lldb::eLanguageTypeUnknown;

  uint64_t m_language_flags = 0;

  /// Unique identifier for every value object.
  UserID m_id;

  // Utility class for initializing all bitfields in ValueObject's constructors.
  // FIXME: This could be done via default initializers once we have C++20.
  struct Bitflags {
    bool m_value_is_valid : 1, m_value_did_change : 1,
        m_children_count_valid : 1, m_old_value_valid : 1,
        m_is_deref_of_parent : 1, m_is_array_item_for_pointer : 1,
        m_is_bitfield_for_scalar : 1, m_is_child_at_offset : 1,
        m_is_getting_summary : 1, m_did_calculate_complete_objc_class_type : 1,
        m_is_synthetic_children_generated : 1;
    Bitflags() {
      m_value_is_valid = false;
      m_value_did_change = false;
      m_children_count_valid = false;
      m_old_value_valid = false;
      m_is_deref_of_parent = false;
      m_is_array_item_for_pointer = false;
      m_is_bitfield_for_scalar = false;
      m_is_child_at_offset = false;
      m_is_getting_summary = false;
      m_did_calculate_complete_objc_class_type = false;
      m_is_synthetic_children_generated = false;
    }
  } m_flags;

  friend class ValueObjectChild;
  friend class ExpressionVariable;     // For SetName
  friend class Target;                 // For SetName
  friend class ValueObjectConstResultImpl;
  friend class ValueObjectSynthetic; // For ClearUserVisibleData

  /// Use this constructor to create a "root variable object".  The ValueObject
  /// will be locked to this context through-out its lifespan.
  ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager,
              AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad);

  /// Use this constructor to create a ValueObject owned by another ValueObject.
  /// It will inherit the ExecutionContext of its parent.
  ValueObject(ValueObject &parent);

  ValueObjectManager *GetManager() { return m_manager; }

  virtual bool UpdateValue() = 0;

  virtual LazyBool CanUpdateWithInvalidExecutionContext() {
    return eLazyBoolCalculate;
  }

  virtual void CalculateDynamicValue(lldb::DynamicValueType use_dynamic);

  virtual lldb::DynamicValueType GetDynamicValueTypeImpl() {
    return lldb::eNoDynamicValues;
  }

  virtual bool HasDynamicValueTypeInfo() { return false; }

  virtual void CalculateSyntheticValue();

  /// Should only be called by ValueObject::GetChildAtIndex().
  ///
  /// \return A ValueObject managed by this ValueObject's manager.
  virtual ValueObject *CreateChildAtIndex(size_t idx,
                                          bool synthetic_array_member,
                                          int32_t synthetic_index);

  /// Should only be called by ValueObject::GetNumChildren().
  virtual size_t CalculateNumChildren(uint32_t max = UINT32_MAX) = 0;

  void SetNumChildren(size_t num_children);

  void SetValueDidChange(bool value_changed) {
    m_flags.m_value_did_change = value_changed;
  }

  void SetValueIsValid(bool valid) { m_flags.m_value_is_valid = valid; }

  void ClearUserVisibleData(
      uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings);

  void AddSyntheticChild(ConstString key, ValueObject *valobj);

  DataExtractor &GetDataExtractor();

  void ClearDynamicTypeInformation();

  // Subclasses must implement the functions below.

  virtual CompilerType GetCompilerTypeImpl() = 0;

  const char *GetLocationAsCStringImpl(const Value &value,
                                       const DataExtractor &data);

  bool IsChecksumEmpty() { return m_value_checksum.empty(); }

  void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType);

protected:
  virtual void DoUpdateChildrenAddressType(ValueObject &valobj) { return; };

private:
  virtual CompilerType MaybeCalculateCompleteType();
  void UpdateChildrenAddressType() {
    GetRoot()->DoUpdateChildrenAddressType(*this);
  }

  lldb::ValueObjectSP GetValueForExpressionPath_Impl(
      llvm::StringRef expression_cstr,
      ExpressionPathScanEndReason *reason_to_stop,
      ExpressionPathEndResultType *final_value_type,
      const GetValueForExpressionPathOptions &options,
      ExpressionPathAftermath *final_task_on_target);

  ValueObject(const ValueObject &) = delete;
  const ValueObject &operator=(const ValueObject &) = delete;
};

} // namespace lldb_private

#endif // LLDB_CORE_VALUEOBJECT_H
