//===-- ValueObject.h -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ValueObject_h_
#define liblldb_ValueObject_h_

#include "lldb/Core/Value.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h" // for TypeImpl
#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"              // for LLDB_INVALID...
#include "lldb/lldb-enumerations.h"         // for DynamicValue...
#include "lldb/lldb-forward.h"              // for ValueObjectSP
#include "lldb/lldb-private-enumerations.h" // for AddressType
#include "lldb/lldb-types.h"                // for addr_t, offs...

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

#include <functional>
#include <initializer_list>
#include <map>
#include <mutex>   // for recursive_mutex
#include <string>  // for string
#include <utility> // for pair

#include <stddef.h> // for size_t
#include <stdint.h> // for uint32_t
namespace lldb_private {
class Declaration;
}
namespace lldb_private {
class DumpValueObjectOptions;
}
namespace lldb_private {
class EvaluateExpressionOptions;
}
namespace lldb_private {
class ExecutionContextScope;
}
namespace lldb_private {
class Log;
}
namespace lldb_private {
class Scalar;
}
namespace lldb_private {
class Stream;
}
namespace lldb_private {
class SymbolContextScope;
}
namespace lldb_private {
class TypeFormatImpl;
}
namespace lldb_private {
class TypeSummaryImpl;
}
namespace lldb_private {
class TypeSummaryOptions;
}
namespace lldb_private {

/// 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 UserID {
public:
  enum GetExpressionPathFormat {
    eGetExpressionPathFormatDereferencePointers = 1,
    eGetExpressionPathFormatHonorPointers
  };

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

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

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

  enum ExpressionPathAftermath {
    eExpressionPathAftermathNothing = 1, // just return it
    eExpressionPathAftermathDereference, // dereference the target
    eExpressionPathAftermathTakeAddress  // take target's address
  };

  enum ClearUserVisibleDataItems {
    eClearUserVisibleDataItemsNothing = 1u << 0,
    eClearUserVisibleDataItemsValue = 1u << 1,
    eClearUserVisibleDataItemsSummary = 1u << 2,
    eClearUserVisibleDataItemsLocation = 1u << 3,
    eClearUserVisibleDataItemsDescription = 1u << 4,
    eClearUserVisibleDataItemsSyntheticChildren = 1u << 5,
    eClearUserVisibleDataItemsValidator = 1u << 6,
    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;
    }

    // Set the EvaluationPoint to the values in exe_scope, Return true if the
    // Evaluation Point changed. Since the ExecutionContextScope is always
    // going to be valid currently, the Updated Context will also always be
    // valid.

    //        bool
    //        SetContext (ExecutionContextScope *exe_scope);

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

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

  virtual bool CanProvideValue();

  //------------------------------------------------------------------
  // Subclasses must implement the functions below.
  //------------------------------------------------------------------
  virtual uint64_t GetByteSize() = 0;

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

  //------------------------------------------------------------------
  // Subclasses can implement the functions below.
  //------------------------------------------------------------------
  virtual ConstString GetTypeName();

  virtual ConstString GetDisplayTypeName();

  virtual ConstString GetQualifiedTypeName();

  virtual lldb::LanguageType GetObjectRuntimeLanguage();

  virtual uint32_t
  GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr);

  virtual bool IsPointerType();

  virtual bool IsArrayType();

  virtual bool IsScalarType();

  virtual bool 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);

  virtual bool GetBaseClassPath(Stream &s);

  virtual void GetExpressionPath(
      Stream &s, bool qualify_cxx_base_classes,
      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_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();

  const ConstString &GetName() const;

  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(const ConstString &name,
                                                     bool can_create);

  virtual size_t GetIndexOfChildWithName(const ConstString &name);

  size_t GetNumChildren(uint32_t max = UINT32_MAX);

  const Value &GetValue() const;

  Value &GetValue();

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

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

  std::pair<TypeValidatorResult, std::string> GetValidationStatus();

  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;

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

  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(const ConstString &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(const 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();

  virtual lldb::ValueObjectSP GetNonSyntheticValue();

  lldb::ValueObjectSP GetSyntheticValue(bool use_synthetic = true);

  virtual bool HasSyntheticValue();

  virtual bool IsSynthetic() { return false; }

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

  virtual lldb::ValueObjectSP CreateConstantValue(const 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(const 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) {}

  // Find the address of the C++ vtable pointer
  virtual lldb::addr_t GetCPPVTableAddress(AddressType &address_type);

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

  virtual void SetSyntheticChildrenGenerated(bool 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);

  void LogValueObject(Log *log);

  void LogValueObject(Log *log, const DumpValueObjectOptions &options);

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

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

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

  lldb::TypeValidatorImplSP GetValidator() {
    UpdateFormatsIfNeeded();
    return m_type_validator_sp;
  }

  void SetValidator(lldb::TypeValidatorImplSP format) {
    m_type_validator_sp = format;
    ClearUserVisibleData(eClearUserVisibleDataItemsValidator);
  }

  void SetValueFormat(lldb::TypeFormatImplSP format) {
    m_type_format_sp = 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_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();

  virtual void SetLanguageFlags(uint64_t 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
  //------------------------------------------------------------------
  ValueObject
      *m_parent; // The parent value object, or nullptr if this has no parent
  ValueObject *m_root; // The root of the hierarchy for this ValueObject (or
                       // nullptr if never calculated)
  EvaluationPoint m_update_point; // 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.
  ConstString m_name; // The name of this object
  DataExtractor
      m_data; // A data extractor that can be used to extract the value.
  Value m_value;
  Status
      m_error; // An error object that can describe any errors that occur when
               // updating values.
  std::string m_value_str; // Cached value string that will get cleared if/when
                           // the value is updated.
  std::string m_old_value_str; // Cached old value string from the last time the
                               // value was gotten
  std::string m_location_str;  // Cached location string that will get cleared
                               // if/when the value is updated.
  std::string m_summary_str;   // Cached summary string that will get cleared
                               // if/when the value is updated.
  std::string m_object_desc_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.

  llvm::Optional<std::pair<TypeValidatorResult, std::string>>
      m_validation_result;

  CompilerType m_override_type; // If the type of the value object should be
                                // overridden, the type to impose.

  ValueObjectManager *m_manager; // 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.

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

  ValueObject *m_dynamic_value;
  ValueObject *m_synthetic_value;
  ValueObject *m_deref_valobj;

  lldb::ValueObjectSP m_addr_of_valobj_sp; // 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::Format m_format;
  lldb::Format m_last_format;
  uint32_t m_last_format_mgr_revision;
  lldb::TypeSummaryImplSP m_type_summary_sp;
  lldb::TypeFormatImplSP m_type_format_sp;
  lldb::SyntheticChildrenSP m_synthetic_children_sp;
  lldb::TypeValidatorImplSP m_type_validator_sp;
  ProcessModID m_user_id_of_forced_summary;
  AddressType m_address_type_of_ptr_or_ref_children;

  llvm::SmallVector<uint8_t, 16> m_value_checksum;

  lldb::LanguageType m_preferred_display_language;

  uint64_t m_language_flags;

  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;

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

  //------------------------------------------------------------------
  // Constructors and Destructors
  //------------------------------------------------------------------

  // Use the no-argument constructor to make a constant variable object (with
  // no ExecutionContextScope.)

  ValueObject();

  // 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,
              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(bool use_synthetic = true);

  // Should only be called by ValueObject::GetChildAtIndex() Returns 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);

  void SetValueIsValid(bool valid);

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

  void AddSyntheticChild(const 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();

  void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType);

private:
  virtual CompilerType MaybeCalculateCompleteType();

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

  DISALLOW_COPY_AND_ASSIGN(ValueObject);
};

//------------------------------------------------------------------------------
// A value object manager class that is seeded with the static variable value
// and it vends the user facing value object. If the type is dynamic it can
// vend the dynamic type. If this user type also has a synthetic type
// associated with it, it will vend the synthetic type. The class watches the
// process' stop
// ID and will update the user type when needed.
//------------------------------------------------------------------------------
class ValueObjectManager {
  // The root value object is the static typed variable object.
  lldb::ValueObjectSP m_root_valobj_sp;
  // The user value object is the value object the user wants to see.
  lldb::ValueObjectSP m_user_valobj_sp;
  lldb::DynamicValueType m_use_dynamic;
  uint32_t m_stop_id; // The stop ID that m_user_valobj_sp is valid for.
  bool m_use_synthetic;

public:
  ValueObjectManager() {}
  
  ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
                     lldb::DynamicValueType use_dynamic, bool use_synthetic);
  
  bool IsValid() const;
  
  lldb::ValueObjectSP GetRootSP() const { return m_root_valobj_sp; }
  
  // Gets the correct value object from the root object for a given process
  // stop ID. If dynamic values are enabled, or if synthetic children are
  // enabled, the value object that the user wants to see might change while
  // debugging.
  lldb::ValueObjectSP GetSP();
  
  void SetUseDynamic(lldb::DynamicValueType use_dynamic);
  void SetUseSynthetic(bool use_synthetic);
  lldb::DynamicValueType GetUseDynamic() const { return m_use_dynamic; }
  bool GetUseSynthetic() const { return m_use_synthetic; }
  lldb::TargetSP GetTargetSP() const;
  lldb::ProcessSP GetProcessSP() const;
  lldb::ThreadSP GetThreadSP() const;
  lldb::StackFrameSP GetFrameSP() const;
};

} // namespace lldb_private

#endif // liblldb_ValueObject_h_
