1061da546Spatrick //===-- ValueObject.h -------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_CORE_VALUEOBJECT_H 10dda28197Spatrick #define LLDB_CORE_VALUEOBJECT_H 11061da546Spatrick 12061da546Spatrick #include "lldb/Core/Value.h" 13061da546Spatrick #include "lldb/Symbol/CompilerType.h" 14061da546Spatrick #include "lldb/Symbol/Type.h" 15061da546Spatrick #include "lldb/Target/ExecutionContext.h" 16061da546Spatrick #include "lldb/Target/Process.h" 17061da546Spatrick #include "lldb/Utility/ConstString.h" 18061da546Spatrick #include "lldb/Utility/DataExtractor.h" 19061da546Spatrick #include "lldb/Utility/SharedCluster.h" 20061da546Spatrick #include "lldb/Utility/Status.h" 21061da546Spatrick #include "lldb/Utility/UserID.h" 22061da546Spatrick #include "lldb/lldb-defines.h" 23061da546Spatrick #include "lldb/lldb-enumerations.h" 24061da546Spatrick #include "lldb/lldb-forward.h" 25061da546Spatrick #include "lldb/lldb-private-enumerations.h" 26061da546Spatrick #include "lldb/lldb-types.h" 27061da546Spatrick 28061da546Spatrick #include "llvm/ADT/ArrayRef.h" 29061da546Spatrick #include "llvm/ADT/SmallVector.h" 30061da546Spatrick #include "llvm/ADT/StringRef.h" 31061da546Spatrick 32061da546Spatrick #include <functional> 33061da546Spatrick #include <initializer_list> 34061da546Spatrick #include <map> 35061da546Spatrick #include <mutex> 36*f6aab3d8Srobert #include <optional> 37061da546Spatrick #include <string> 38061da546Spatrick #include <utility> 39061da546Spatrick 40be691f3bSpatrick #include <cstddef> 41be691f3bSpatrick #include <cstdint> 42061da546Spatrick 43061da546Spatrick namespace lldb_private { 44061da546Spatrick class Declaration; 45061da546Spatrick class DumpValueObjectOptions; 46061da546Spatrick class EvaluateExpressionOptions; 47061da546Spatrick class ExecutionContextScope; 48061da546Spatrick class Log; 49061da546Spatrick class Scalar; 50061da546Spatrick class Stream; 51061da546Spatrick class SymbolContextScope; 52061da546Spatrick class TypeFormatImpl; 53061da546Spatrick class TypeSummaryImpl; 54061da546Spatrick class TypeSummaryOptions; 55061da546Spatrick 56061da546Spatrick /// ValueObject: 57061da546Spatrick /// 58061da546Spatrick /// This abstract class provides an interface to a particular value, be it a 59061da546Spatrick /// register, a local or global variable, 60061da546Spatrick /// that is evaluated in some particular scope. The ValueObject also has the 61061da546Spatrick /// capability of being the "child" of 62061da546Spatrick /// some other variable object, and in turn of having children. 63061da546Spatrick /// If a ValueObject is a root variable object - having no parent - then it must 64061da546Spatrick /// be constructed with respect to some 65061da546Spatrick /// particular ExecutionContextScope. If it is a child, it inherits the 66061da546Spatrick /// ExecutionContextScope from its parent. 67061da546Spatrick /// The ValueObject will update itself if necessary before fetching its value, 68061da546Spatrick /// summary, object description, etc. 69061da546Spatrick /// But it will always update itself in the ExecutionContextScope with which it 70061da546Spatrick /// was originally created. 71061da546Spatrick 72061da546Spatrick /// A brief note on life cycle management for ValueObjects. This is a little 73061da546Spatrick /// tricky because a ValueObject can contain 74061da546Spatrick /// various other ValueObjects - the Dynamic Value, its children, the 75061da546Spatrick /// dereference value, etc. Any one of these can be 76061da546Spatrick /// handed out as a shared pointer, but for that contained value object to be 77061da546Spatrick /// valid, the root object and potentially other 78061da546Spatrick /// of the value objects need to stay around. 79061da546Spatrick /// We solve this problem by handing out shared pointers to the Value Object and 80061da546Spatrick /// any of its dependents using a shared 81061da546Spatrick /// ClusterManager. This treats each shared pointer handed out for the entire 82061da546Spatrick /// cluster as a reference to the whole 83061da546Spatrick /// cluster. The whole cluster will stay around until the last reference is 84061da546Spatrick /// released. 85061da546Spatrick /// 86061da546Spatrick /// The ValueObject mostly handle this automatically, if a value object is made 87061da546Spatrick /// with a Parent ValueObject, then it adds 88061da546Spatrick /// itself to the ClusterManager of the parent. 89061da546Spatrick 90061da546Spatrick /// It does mean that external to the ValueObjects we should only ever make 91061da546Spatrick /// available ValueObjectSP's, never ValueObjects 92061da546Spatrick /// or pointers to them. So all the "Root level" ValueObject derived 93061da546Spatrick /// constructors should be private, and 94061da546Spatrick /// should implement a Create function that new's up object and returns a Shared 95061da546Spatrick /// Pointer that it gets from the GetSP() method. 96061da546Spatrick /// 97061da546Spatrick /// However, if you are making an derived ValueObject that will be contained in 98061da546Spatrick /// a parent value object, you should just 99061da546Spatrick /// hold onto a pointer to it internally, and by virtue of passing the parent 100061da546Spatrick /// ValueObject into its constructor, it will 101061da546Spatrick /// be added to the ClusterManager for the parent. Then if you ever hand out a 102061da546Spatrick /// Shared Pointer to the contained ValueObject, 103061da546Spatrick /// just do so by calling GetSP() on the contained object. 104061da546Spatrick 105be691f3bSpatrick class ValueObject { 106061da546Spatrick public: 107061da546Spatrick enum GetExpressionPathFormat { 108061da546Spatrick eGetExpressionPathFormatDereferencePointers = 1, 109061da546Spatrick eGetExpressionPathFormatHonorPointers 110061da546Spatrick }; 111061da546Spatrick 112061da546Spatrick enum ValueObjectRepresentationStyle { 113061da546Spatrick eValueObjectRepresentationStyleValue = 1, 114061da546Spatrick eValueObjectRepresentationStyleSummary, 115061da546Spatrick eValueObjectRepresentationStyleLanguageSpecific, 116061da546Spatrick eValueObjectRepresentationStyleLocation, 117061da546Spatrick eValueObjectRepresentationStyleChildrenCount, 118061da546Spatrick eValueObjectRepresentationStyleType, 119061da546Spatrick eValueObjectRepresentationStyleName, 120061da546Spatrick eValueObjectRepresentationStyleExpressionPath 121061da546Spatrick }; 122061da546Spatrick 123061da546Spatrick enum ExpressionPathScanEndReason { 124be691f3bSpatrick /// Out of data to parse. 125be691f3bSpatrick eExpressionPathScanEndReasonEndOfString = 1, 126be691f3bSpatrick /// Child element not found. 127be691f3bSpatrick eExpressionPathScanEndReasonNoSuchChild, 128be691f3bSpatrick /// (Synthetic) child element not found. 129be691f3bSpatrick eExpressionPathScanEndReasonNoSuchSyntheticChild, 130be691f3bSpatrick /// [] only allowed for arrays. 131be691f3bSpatrick eExpressionPathScanEndReasonEmptyRangeNotAllowed, 132be691f3bSpatrick /// . used when -> should be used. 133be691f3bSpatrick eExpressionPathScanEndReasonDotInsteadOfArrow, 134be691f3bSpatrick /// -> used when . should be used. 135be691f3bSpatrick eExpressionPathScanEndReasonArrowInsteadOfDot, 136be691f3bSpatrick /// ObjC ivar expansion not allowed. 137be691f3bSpatrick eExpressionPathScanEndReasonFragileIVarNotAllowed, 138be691f3bSpatrick /// [] not allowed by options. 139be691f3bSpatrick eExpressionPathScanEndReasonRangeOperatorNotAllowed, 140be691f3bSpatrick /// [] not valid on objects other than scalars, pointers or arrays. 141be691f3bSpatrick eExpressionPathScanEndReasonRangeOperatorInvalid, 142be691f3bSpatrick /// [] is good for arrays, but I cannot parse it. 143be691f3bSpatrick eExpressionPathScanEndReasonArrayRangeOperatorMet, 144be691f3bSpatrick /// [] is good for bitfields, but I cannot parse after it. 145be691f3bSpatrick eExpressionPathScanEndReasonBitfieldRangeOperatorMet, 146be691f3bSpatrick /// Something is malformed in he expression. 147be691f3bSpatrick eExpressionPathScanEndReasonUnexpectedSymbol, 148be691f3bSpatrick /// Impossible to apply & operator. 149be691f3bSpatrick eExpressionPathScanEndReasonTakingAddressFailed, 150be691f3bSpatrick /// Impossible to apply * operator. 151be691f3bSpatrick eExpressionPathScanEndReasonDereferencingFailed, 152be691f3bSpatrick /// [] was expanded into a VOList. 153be691f3bSpatrick eExpressionPathScanEndReasonRangeOperatorExpanded, 154be691f3bSpatrick /// getting the synthetic children failed. 155be691f3bSpatrick eExpressionPathScanEndReasonSyntheticValueMissing, 156061da546Spatrick eExpressionPathScanEndReasonUnknown = 0xFFFF 157061da546Spatrick }; 158061da546Spatrick 159061da546Spatrick enum ExpressionPathEndResultType { 160be691f3bSpatrick /// Anything but... 161be691f3bSpatrick eExpressionPathEndResultTypePlain = 1, 162be691f3bSpatrick /// A bitfield. 163be691f3bSpatrick eExpressionPathEndResultTypeBitfield, 164be691f3bSpatrick /// A range [low-high]. 165be691f3bSpatrick eExpressionPathEndResultTypeBoundedRange, 166be691f3bSpatrick /// A range []. 167be691f3bSpatrick eExpressionPathEndResultTypeUnboundedRange, 168be691f3bSpatrick /// Several items in a VOList. 169be691f3bSpatrick eExpressionPathEndResultTypeValueObjectList, 170061da546Spatrick eExpressionPathEndResultTypeInvalid = 0xFFFF 171061da546Spatrick }; 172061da546Spatrick 173061da546Spatrick enum ExpressionPathAftermath { 174be691f3bSpatrick /// Just return it. 175be691f3bSpatrick eExpressionPathAftermathNothing = 1, 176be691f3bSpatrick /// Dereference the target. 177be691f3bSpatrick eExpressionPathAftermathDereference, 178be691f3bSpatrick /// Take target's address. 179be691f3bSpatrick eExpressionPathAftermathTakeAddress 180061da546Spatrick }; 181061da546Spatrick 182061da546Spatrick enum ClearUserVisibleDataItems { 183061da546Spatrick eClearUserVisibleDataItemsNothing = 1u << 0, 184061da546Spatrick eClearUserVisibleDataItemsValue = 1u << 1, 185061da546Spatrick eClearUserVisibleDataItemsSummary = 1u << 2, 186061da546Spatrick eClearUserVisibleDataItemsLocation = 1u << 3, 187061da546Spatrick eClearUserVisibleDataItemsDescription = 1u << 4, 188061da546Spatrick eClearUserVisibleDataItemsSyntheticChildren = 1u << 5, 189061da546Spatrick eClearUserVisibleDataItemsAllStrings = 190061da546Spatrick eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | 191061da546Spatrick eClearUserVisibleDataItemsLocation | 192061da546Spatrick eClearUserVisibleDataItemsDescription, 193061da546Spatrick eClearUserVisibleDataItemsAll = 0xFFFF 194061da546Spatrick }; 195061da546Spatrick 196061da546Spatrick struct GetValueForExpressionPathOptions { 197061da546Spatrick enum class SyntheticChildrenTraversal { 198061da546Spatrick None, 199061da546Spatrick ToSynthetic, 200061da546Spatrick FromSynthetic, 201061da546Spatrick Both 202061da546Spatrick }; 203061da546Spatrick 204061da546Spatrick bool m_check_dot_vs_arrow_syntax; 205061da546Spatrick bool m_no_fragile_ivar; 206061da546Spatrick bool m_allow_bitfields_syntax; 207061da546Spatrick SyntheticChildrenTraversal m_synthetic_children_traversal; 208061da546Spatrick 209061da546Spatrick GetValueForExpressionPathOptions( 210061da546Spatrick bool dot = false, bool no_ivar = false, bool bitfield = true, 211061da546Spatrick SyntheticChildrenTraversal synth_traverse = 212061da546Spatrick SyntheticChildrenTraversal::ToSynthetic) m_check_dot_vs_arrow_syntaxGetValueForExpressionPathOptions213061da546Spatrick : m_check_dot_vs_arrow_syntax(dot), m_no_fragile_ivar(no_ivar), 214061da546Spatrick m_allow_bitfields_syntax(bitfield), 215061da546Spatrick m_synthetic_children_traversal(synth_traverse) {} 216061da546Spatrick DoCheckDotVsArrowSyntaxGetValueForExpressionPathOptions217061da546Spatrick GetValueForExpressionPathOptions &DoCheckDotVsArrowSyntax() { 218061da546Spatrick m_check_dot_vs_arrow_syntax = true; 219061da546Spatrick return *this; 220061da546Spatrick } 221061da546Spatrick DontCheckDotVsArrowSyntaxGetValueForExpressionPathOptions222061da546Spatrick GetValueForExpressionPathOptions &DontCheckDotVsArrowSyntax() { 223061da546Spatrick m_check_dot_vs_arrow_syntax = false; 224061da546Spatrick return *this; 225061da546Spatrick } 226061da546Spatrick DoAllowFragileIVarGetValueForExpressionPathOptions227061da546Spatrick GetValueForExpressionPathOptions &DoAllowFragileIVar() { 228061da546Spatrick m_no_fragile_ivar = false; 229061da546Spatrick return *this; 230061da546Spatrick } 231061da546Spatrick DontAllowFragileIVarGetValueForExpressionPathOptions232061da546Spatrick GetValueForExpressionPathOptions &DontAllowFragileIVar() { 233061da546Spatrick m_no_fragile_ivar = true; 234061da546Spatrick return *this; 235061da546Spatrick } 236061da546Spatrick DoAllowBitfieldSyntaxGetValueForExpressionPathOptions237061da546Spatrick GetValueForExpressionPathOptions &DoAllowBitfieldSyntax() { 238061da546Spatrick m_allow_bitfields_syntax = true; 239061da546Spatrick return *this; 240061da546Spatrick } 241061da546Spatrick DontAllowBitfieldSyntaxGetValueForExpressionPathOptions242061da546Spatrick GetValueForExpressionPathOptions &DontAllowBitfieldSyntax() { 243061da546Spatrick m_allow_bitfields_syntax = false; 244061da546Spatrick return *this; 245061da546Spatrick } 246061da546Spatrick 247061da546Spatrick GetValueForExpressionPathOptions & SetSyntheticChildrenTraversalGetValueForExpressionPathOptions248061da546Spatrick SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse) { 249061da546Spatrick m_synthetic_children_traversal = traverse; 250061da546Spatrick return *this; 251061da546Spatrick } 252061da546Spatrick DefaultOptionsGetValueForExpressionPathOptions253061da546Spatrick static const GetValueForExpressionPathOptions DefaultOptions() { 254061da546Spatrick static GetValueForExpressionPathOptions g_default_options; 255061da546Spatrick 256061da546Spatrick return g_default_options; 257061da546Spatrick } 258061da546Spatrick }; 259061da546Spatrick 260061da546Spatrick class EvaluationPoint { 261061da546Spatrick public: 262061da546Spatrick EvaluationPoint(); 263061da546Spatrick 264061da546Spatrick EvaluationPoint(ExecutionContextScope *exe_scope, 265061da546Spatrick bool use_selected = false); 266061da546Spatrick 267061da546Spatrick EvaluationPoint(const EvaluationPoint &rhs); 268061da546Spatrick 269061da546Spatrick ~EvaluationPoint(); 270061da546Spatrick GetExecutionContextRef()271061da546Spatrick const ExecutionContextRef &GetExecutionContextRef() const { 272061da546Spatrick return m_exe_ctx_ref; 273061da546Spatrick } 274061da546Spatrick SetIsConstant()275061da546Spatrick void SetIsConstant() { 276061da546Spatrick SetUpdated(); 277061da546Spatrick m_mod_id.SetInvalid(); 278061da546Spatrick } 279061da546Spatrick IsConstant()280061da546Spatrick bool IsConstant() const { return !m_mod_id.IsValid(); } 281061da546Spatrick GetModID()282061da546Spatrick ProcessModID GetModID() const { return m_mod_id; } 283061da546Spatrick SetUpdateID(ProcessModID new_id)284061da546Spatrick void SetUpdateID(ProcessModID new_id) { m_mod_id = new_id; } 285061da546Spatrick SetNeedsUpdate()286061da546Spatrick void SetNeedsUpdate() { m_needs_update = true; } 287061da546Spatrick 288061da546Spatrick void SetUpdated(); 289061da546Spatrick NeedsUpdating(bool accept_invalid_exe_ctx)290061da546Spatrick bool NeedsUpdating(bool accept_invalid_exe_ctx) { 291061da546Spatrick SyncWithProcessState(accept_invalid_exe_ctx); 292061da546Spatrick return m_needs_update; 293061da546Spatrick } 294061da546Spatrick IsValid()295061da546Spatrick bool IsValid() { 296061da546Spatrick const bool accept_invalid_exe_ctx = false; 297061da546Spatrick if (!m_mod_id.IsValid()) 298061da546Spatrick return false; 299061da546Spatrick else if (SyncWithProcessState(accept_invalid_exe_ctx)) { 300061da546Spatrick if (!m_mod_id.IsValid()) 301061da546Spatrick return false; 302061da546Spatrick } 303061da546Spatrick return true; 304061da546Spatrick } 305061da546Spatrick SetInvalid()306061da546Spatrick void SetInvalid() { 307061da546Spatrick // Use the stop id to mark us as invalid, leave the thread id and the 308061da546Spatrick // stack id around for logging and history purposes. 309061da546Spatrick m_mod_id.SetInvalid(); 310061da546Spatrick 311061da546Spatrick // Can't update an invalid state. 312061da546Spatrick m_needs_update = false; 313061da546Spatrick } 314061da546Spatrick 315061da546Spatrick private: 316061da546Spatrick bool SyncWithProcessState(bool accept_invalid_exe_ctx); 317061da546Spatrick 318061da546Spatrick ProcessModID m_mod_id; // This is the stop id when this ValueObject was last 319061da546Spatrick // evaluated. 320061da546Spatrick ExecutionContextRef m_exe_ctx_ref; 321be691f3bSpatrick bool m_needs_update = true; 322061da546Spatrick }; 323061da546Spatrick 324061da546Spatrick virtual ~ValueObject(); 325061da546Spatrick GetUpdatePoint()326061da546Spatrick const EvaluationPoint &GetUpdatePoint() const { return m_update_point; } 327061da546Spatrick GetUpdatePoint()328061da546Spatrick EvaluationPoint &GetUpdatePoint() { return m_update_point; } 329061da546Spatrick GetExecutionContextRef()330061da546Spatrick const ExecutionContextRef &GetExecutionContextRef() const { 331061da546Spatrick return m_update_point.GetExecutionContextRef(); 332061da546Spatrick } 333061da546Spatrick GetTargetSP()334061da546Spatrick lldb::TargetSP GetTargetSP() const { 335061da546Spatrick return m_update_point.GetExecutionContextRef().GetTargetSP(); 336061da546Spatrick } 337061da546Spatrick GetProcessSP()338061da546Spatrick lldb::ProcessSP GetProcessSP() const { 339061da546Spatrick return m_update_point.GetExecutionContextRef().GetProcessSP(); 340061da546Spatrick } 341061da546Spatrick GetThreadSP()342061da546Spatrick lldb::ThreadSP GetThreadSP() const { 343061da546Spatrick return m_update_point.GetExecutionContextRef().GetThreadSP(); 344061da546Spatrick } 345061da546Spatrick GetFrameSP()346061da546Spatrick lldb::StackFrameSP GetFrameSP() const { 347061da546Spatrick return m_update_point.GetExecutionContextRef().GetFrameSP(); 348061da546Spatrick } 349061da546Spatrick 350061da546Spatrick void SetNeedsUpdate(); 351061da546Spatrick GetCompilerType()352be691f3bSpatrick CompilerType GetCompilerType() { return MaybeCalculateCompleteType(); } 353061da546Spatrick 354061da546Spatrick // this vends a TypeImpl that is useful at the SB API layer GetTypeImpl()355be691f3bSpatrick virtual TypeImpl GetTypeImpl() { return TypeImpl(GetCompilerType()); } 356061da546Spatrick 357061da546Spatrick virtual bool CanProvideValue(); 358061da546Spatrick 359061da546Spatrick // Subclasses must implement the functions below. 360*f6aab3d8Srobert virtual std::optional<uint64_t> GetByteSize() = 0; 361061da546Spatrick 362061da546Spatrick virtual lldb::ValueType GetValueType() const = 0; 363061da546Spatrick 364061da546Spatrick // Subclasses can implement the functions below. GetTypeName()365be691f3bSpatrick virtual ConstString GetTypeName() { return GetCompilerType().GetTypeName(); } 366061da546Spatrick GetDisplayTypeName()367be691f3bSpatrick virtual ConstString GetDisplayTypeName() { return GetTypeName(); } 368061da546Spatrick GetQualifiedTypeName()369be691f3bSpatrick virtual ConstString GetQualifiedTypeName() { 370be691f3bSpatrick return GetCompilerType().GetTypeName(); 371be691f3bSpatrick } 372061da546Spatrick GetObjectRuntimeLanguage()373be691f3bSpatrick virtual lldb::LanguageType GetObjectRuntimeLanguage() { 374be691f3bSpatrick return GetCompilerType().GetMinimumLanguage(); 375be691f3bSpatrick } 376061da546Spatrick 377061da546Spatrick virtual uint32_t 378be691f3bSpatrick GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) { 379be691f3bSpatrick return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type); 380be691f3bSpatrick } 381061da546Spatrick IsPointerType()382be691f3bSpatrick virtual bool IsPointerType() { return GetCompilerType().IsPointerType(); } 383061da546Spatrick IsArrayType()384be691f3bSpatrick virtual bool IsArrayType() { return GetCompilerType().IsArrayType(); } 385061da546Spatrick IsScalarType()386be691f3bSpatrick virtual bool IsScalarType() { return GetCompilerType().IsScalarType(); } 387061da546Spatrick IsPointerOrReferenceType()388be691f3bSpatrick virtual bool IsPointerOrReferenceType() { 389be691f3bSpatrick return GetCompilerType().IsPointerOrReferenceType(); 390be691f3bSpatrick } 391061da546Spatrick 392061da546Spatrick virtual bool IsPossibleDynamicType(); 393061da546Spatrick 394061da546Spatrick bool IsNilReference(); 395061da546Spatrick 396061da546Spatrick bool IsUninitializedReference(); 397061da546Spatrick IsBaseClass()398061da546Spatrick virtual bool IsBaseClass() { return false; } 399061da546Spatrick 400061da546Spatrick bool IsBaseClass(uint32_t &depth); 401061da546Spatrick IsDereferenceOfParent()402061da546Spatrick virtual bool IsDereferenceOfParent() { return false; } 403061da546Spatrick IsIntegerType(bool & is_signed)404be691f3bSpatrick bool IsIntegerType(bool &is_signed) { 405be691f3bSpatrick return GetCompilerType().IsIntegerType(is_signed); 406be691f3bSpatrick } 407061da546Spatrick 408061da546Spatrick virtual void GetExpressionPath( 409dda28197Spatrick Stream &s, 410061da546Spatrick GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers); 411061da546Spatrick 412061da546Spatrick lldb::ValueObjectSP GetValueForExpressionPath( 413061da546Spatrick llvm::StringRef expression, 414061da546Spatrick ExpressionPathScanEndReason *reason_to_stop = nullptr, 415061da546Spatrick ExpressionPathEndResultType *final_value_type = nullptr, 416061da546Spatrick const GetValueForExpressionPathOptions &options = 417061da546Spatrick GetValueForExpressionPathOptions::DefaultOptions(), 418061da546Spatrick ExpressionPathAftermath *final_task_on_target = nullptr); 419061da546Spatrick IsInScope()420061da546Spatrick virtual bool IsInScope() { return true; } 421061da546Spatrick GetByteOffset()422061da546Spatrick virtual lldb::offset_t GetByteOffset() { return 0; } 423061da546Spatrick GetBitfieldBitSize()424061da546Spatrick virtual uint32_t GetBitfieldBitSize() { return 0; } 425061da546Spatrick GetBitfieldBitOffset()426061da546Spatrick virtual uint32_t GetBitfieldBitOffset() { return 0; } 427061da546Spatrick IsBitfield()428061da546Spatrick bool IsBitfield() { 429061da546Spatrick return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0); 430061da546Spatrick } 431061da546Spatrick IsArrayItemForPointer()432be691f3bSpatrick virtual bool IsArrayItemForPointer() { 433be691f3bSpatrick return m_flags.m_is_array_item_for_pointer; 434be691f3bSpatrick } 435061da546Spatrick 436061da546Spatrick virtual const char *GetValueAsCString(); 437061da546Spatrick 438061da546Spatrick virtual bool GetValueAsCString(const lldb_private::TypeFormatImpl &format, 439061da546Spatrick std::string &destination); 440061da546Spatrick 441061da546Spatrick bool GetValueAsCString(lldb::Format format, std::string &destination); 442061da546Spatrick 443061da546Spatrick virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, 444061da546Spatrick bool *success = nullptr); 445061da546Spatrick 446061da546Spatrick virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = nullptr); 447061da546Spatrick 448061da546Spatrick virtual bool SetValueFromCString(const char *value_str, Status &error); 449061da546Spatrick 450be691f3bSpatrick /// Return the module associated with this value object in case the value is 451be691f3bSpatrick /// from an executable file and might have its data in sections of the file. 452be691f3bSpatrick /// This can be used for variables. 453061da546Spatrick virtual lldb::ModuleSP GetModule(); 454061da546Spatrick 455061da546Spatrick ValueObject *GetRoot(); 456061da546Spatrick 457be691f3bSpatrick /// Given a ValueObject, loop over itself and its parent, and its parent's 458be691f3bSpatrick /// parent, .. until either the given callback returns false, or you end up at 459be691f3bSpatrick /// a null pointer 460061da546Spatrick ValueObject *FollowParentChain(std::function<bool(ValueObject *)>); 461061da546Spatrick 462061da546Spatrick virtual bool GetDeclaration(Declaration &decl); 463061da546Spatrick 464061da546Spatrick // The functions below should NOT be modified by subclasses 465061da546Spatrick const Status &GetError(); 466061da546Spatrick GetName()467be691f3bSpatrick ConstString GetName() const { return m_name; } 468be691f3bSpatrick 469be691f3bSpatrick /// Returns a unique id for this ValueObject. GetID()470be691f3bSpatrick lldb::user_id_t GetID() const { return m_id.GetID(); } 471061da546Spatrick 472061da546Spatrick virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create); 473061da546Spatrick 474061da546Spatrick // this will always create the children if necessary 475061da546Spatrick lldb::ValueObjectSP GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs, 476061da546Spatrick size_t *index_of_error = nullptr); 477061da546Spatrick 478061da546Spatrick lldb::ValueObjectSP 479061da546Spatrick GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t, bool>> idxs, 480061da546Spatrick size_t *index_of_error = nullptr); 481061da546Spatrick 482061da546Spatrick // this will always create the children if necessary 483061da546Spatrick lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<ConstString> names, 484061da546Spatrick ConstString *name_of_error = nullptr); 485061da546Spatrick 486061da546Spatrick lldb::ValueObjectSP 487061da546Spatrick GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString, bool>> names, 488061da546Spatrick ConstString *name_of_error = nullptr); 489061da546Spatrick 490061da546Spatrick virtual lldb::ValueObjectSP GetChildMemberWithName(ConstString name, 491061da546Spatrick bool can_create); 492061da546Spatrick 493061da546Spatrick virtual size_t GetIndexOfChildWithName(ConstString name); 494061da546Spatrick 495061da546Spatrick size_t GetNumChildren(uint32_t max = UINT32_MAX); 496061da546Spatrick GetValue()497be691f3bSpatrick const Value &GetValue() const { return m_value; } 498061da546Spatrick GetValue()499be691f3bSpatrick Value &GetValue() { return m_value; } 500061da546Spatrick 501061da546Spatrick virtual bool ResolveValue(Scalar &scalar); 502061da546Spatrick 503061da546Spatrick // return 'false' whenever you set the error, otherwise callers may assume 504061da546Spatrick // true means everything is OK - this will break breakpoint conditions among 505061da546Spatrick // potentially a few others 506061da546Spatrick virtual bool IsLogicalTrue(Status &error); 507061da546Spatrick GetLocationAsCString()508be691f3bSpatrick virtual const char *GetLocationAsCString() { 509be691f3bSpatrick return GetLocationAsCStringImpl(m_value, m_data); 510be691f3bSpatrick } 511061da546Spatrick 512061da546Spatrick const char * 513061da546Spatrick GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown); 514061da546Spatrick 515061da546Spatrick bool 516061da546Spatrick GetSummaryAsCString(TypeSummaryImpl *summary_ptr, std::string &destination, 517061da546Spatrick lldb::LanguageType lang = lldb::eLanguageTypeUnknown); 518061da546Spatrick 519061da546Spatrick bool GetSummaryAsCString(std::string &destination, 520061da546Spatrick const TypeSummaryOptions &options); 521061da546Spatrick 522061da546Spatrick bool GetSummaryAsCString(TypeSummaryImpl *summary_ptr, 523061da546Spatrick std::string &destination, 524061da546Spatrick const TypeSummaryOptions &options); 525061da546Spatrick 526061da546Spatrick const char *GetObjectDescription(); 527061da546Spatrick 528061da546Spatrick bool HasSpecialPrintableRepresentation( 529061da546Spatrick ValueObjectRepresentationStyle val_obj_display, 530061da546Spatrick lldb::Format custom_format); 531061da546Spatrick 532061da546Spatrick enum class PrintableRepresentationSpecialCases : bool { 533061da546Spatrick eDisable = false, 534061da546Spatrick eAllow = true 535061da546Spatrick }; 536061da546Spatrick 537061da546Spatrick bool 538061da546Spatrick DumpPrintableRepresentation(Stream &s, 539061da546Spatrick ValueObjectRepresentationStyle val_obj_display = 540061da546Spatrick eValueObjectRepresentationStyleSummary, 541061da546Spatrick lldb::Format custom_format = lldb::eFormatInvalid, 542061da546Spatrick PrintableRepresentationSpecialCases special = 543061da546Spatrick PrintableRepresentationSpecialCases::eAllow, 544061da546Spatrick bool do_dump_error = true); GetValueIsValid()545be691f3bSpatrick bool GetValueIsValid() const { return m_flags.m_value_is_valid; } 546061da546Spatrick 547061da546Spatrick // If you call this on a newly created ValueObject, it will always return 548061da546Spatrick // false. GetValueDidChange()549be691f3bSpatrick bool GetValueDidChange() { return m_flags.m_value_did_change; } 550061da546Spatrick 551061da546Spatrick bool UpdateValueIfNeeded(bool update_format = true); 552061da546Spatrick 553061da546Spatrick bool UpdateFormatsIfNeeded(); 554061da546Spatrick GetSP()555061da546Spatrick lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(this); } 556061da546Spatrick 557be691f3bSpatrick /// Change the name of the current ValueObject. Should *not* be used from a 558be691f3bSpatrick /// synthetic child provider as it would change the name of the non synthetic 559be691f3bSpatrick /// child as well. SetName(ConstString name)560be691f3bSpatrick void SetName(ConstString name) { m_name = name; } 561061da546Spatrick 562061da546Spatrick virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true, 563061da546Spatrick AddressType *address_type = nullptr); 564061da546Spatrick 565061da546Spatrick lldb::addr_t GetPointerValue(AddressType *address_type = nullptr); 566061da546Spatrick 567061da546Spatrick lldb::ValueObjectSP GetSyntheticChild(ConstString key) const; 568061da546Spatrick 569061da546Spatrick lldb::ValueObjectSP GetSyntheticArrayMember(size_t index, bool can_create); 570061da546Spatrick 571061da546Spatrick lldb::ValueObjectSP GetSyntheticBitFieldChild(uint32_t from, uint32_t to, 572061da546Spatrick bool can_create); 573061da546Spatrick 574061da546Spatrick lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression, 575061da546Spatrick bool can_create); 576061da546Spatrick 577061da546Spatrick virtual lldb::ValueObjectSP 578061da546Spatrick GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type, 579061da546Spatrick bool can_create, 580061da546Spatrick ConstString name_const_str = ConstString()); 581061da546Spatrick 582061da546Spatrick virtual lldb::ValueObjectSP 583061da546Spatrick GetSyntheticBase(uint32_t offset, const CompilerType &type, bool can_create, 584061da546Spatrick ConstString name_const_str = ConstString()); 585061da546Spatrick 586061da546Spatrick virtual lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType); 587061da546Spatrick 588061da546Spatrick lldb::DynamicValueType GetDynamicValueType(); 589061da546Spatrick GetStaticValue()590be691f3bSpatrick virtual lldb::ValueObjectSP GetStaticValue() { return GetSP(); } 591061da546Spatrick GetNonSyntheticValue()592be691f3bSpatrick virtual lldb::ValueObjectSP GetNonSyntheticValue() { return GetSP(); } 593061da546Spatrick 594dda28197Spatrick lldb::ValueObjectSP GetSyntheticValue(); 595061da546Spatrick 596061da546Spatrick virtual bool HasSyntheticValue(); 597061da546Spatrick IsSynthetic()598061da546Spatrick virtual bool IsSynthetic() { return false; } 599061da546Spatrick 600061da546Spatrick lldb::ValueObjectSP 601061da546Spatrick GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue, 602061da546Spatrick bool synthValue); 603061da546Spatrick 604061da546Spatrick virtual lldb::ValueObjectSP CreateConstantValue(ConstString name); 605061da546Spatrick 606061da546Spatrick virtual lldb::ValueObjectSP Dereference(Status &error); 607061da546Spatrick 608be691f3bSpatrick /// Creates a copy of the ValueObject with a new name and setting the current 609be691f3bSpatrick /// ValueObject as its parent. It should be used when we want to change the 610be691f3bSpatrick /// name of a ValueObject without modifying the actual ValueObject itself 611be691f3bSpatrick /// (e.g. sythetic child provider). 612061da546Spatrick virtual lldb::ValueObjectSP Clone(ConstString new_name); 613061da546Spatrick 614061da546Spatrick virtual lldb::ValueObjectSP AddressOf(Status &error); 615061da546Spatrick GetLiveAddress()616061da546Spatrick virtual lldb::addr_t GetLiveAddress() { return LLDB_INVALID_ADDRESS; } 617061da546Spatrick 618061da546Spatrick virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS, 619061da546Spatrick AddressType address_type = eAddressTypeLoad) {} 620061da546Spatrick 621061da546Spatrick virtual lldb::ValueObjectSP Cast(const CompilerType &compiler_type); 622061da546Spatrick 623061da546Spatrick virtual lldb::ValueObjectSP CastPointerType(const char *name, 624061da546Spatrick CompilerType &ast_type); 625061da546Spatrick 626061da546Spatrick virtual lldb::ValueObjectSP CastPointerType(const char *name, 627061da546Spatrick lldb::TypeSP &type_sp); 628061da546Spatrick 629061da546Spatrick // The backing bits of this value object were updated, clear any descriptive 630be691f3bSpatrick // string, so we know we have to refetch them. ValueUpdated()631061da546Spatrick virtual void ValueUpdated() { 632061da546Spatrick ClearUserVisibleData(eClearUserVisibleDataItemsValue | 633061da546Spatrick eClearUserVisibleDataItemsSummary | 634061da546Spatrick eClearUserVisibleDataItemsDescription); 635061da546Spatrick } 636061da546Spatrick IsDynamic()637061da546Spatrick virtual bool IsDynamic() { return false; } 638061da546Spatrick DoesProvideSyntheticValue()639061da546Spatrick virtual bool DoesProvideSyntheticValue() { return false; } 640061da546Spatrick IsSyntheticChildrenGenerated()641be691f3bSpatrick virtual bool IsSyntheticChildrenGenerated() { 642be691f3bSpatrick return m_flags.m_is_synthetic_children_generated; 643be691f3bSpatrick } 644061da546Spatrick SetSyntheticChildrenGenerated(bool b)645be691f3bSpatrick virtual void SetSyntheticChildrenGenerated(bool b) { 646be691f3bSpatrick m_flags.m_is_synthetic_children_generated = b; 647be691f3bSpatrick } 648061da546Spatrick 649061da546Spatrick virtual SymbolContextScope *GetSymbolContextScope(); 650061da546Spatrick 651061da546Spatrick void Dump(Stream &s); 652061da546Spatrick 653061da546Spatrick void Dump(Stream &s, const DumpValueObjectOptions &options); 654061da546Spatrick 655061da546Spatrick static lldb::ValueObjectSP 656061da546Spatrick CreateValueObjectFromExpression(llvm::StringRef name, 657061da546Spatrick llvm::StringRef expression, 658061da546Spatrick const ExecutionContext &exe_ctx); 659061da546Spatrick 660061da546Spatrick static lldb::ValueObjectSP 661061da546Spatrick CreateValueObjectFromExpression(llvm::StringRef name, 662061da546Spatrick llvm::StringRef expression, 663061da546Spatrick const ExecutionContext &exe_ctx, 664061da546Spatrick const EvaluateExpressionOptions &options); 665061da546Spatrick 666061da546Spatrick static lldb::ValueObjectSP 667061da546Spatrick CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, 668061da546Spatrick const ExecutionContext &exe_ctx, 669061da546Spatrick CompilerType type); 670061da546Spatrick 671061da546Spatrick static lldb::ValueObjectSP 672061da546Spatrick CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, 673061da546Spatrick const ExecutionContext &exe_ctx, CompilerType type); 674061da546Spatrick 675061da546Spatrick lldb::ValueObjectSP Persist(); 676061da546Spatrick 677be691f3bSpatrick /// Returns true if this is a char* or a char[] if it is a char* and 678be691f3bSpatrick /// check_pointer is true, it also checks that the pointer is valid. 679061da546Spatrick bool IsCStringContainer(bool check_pointer = false); 680061da546Spatrick 681061da546Spatrick std::pair<size_t, bool> 682*f6aab3d8Srobert ReadPointedString(lldb::WritableDataBufferSP &buffer_sp, Status &error, 683061da546Spatrick uint32_t max_length = 0, bool honor_array = true, 684061da546Spatrick lldb::Format item_format = lldb::eFormatCharArray); 685061da546Spatrick 686061da546Spatrick virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0, 687061da546Spatrick uint32_t item_count = 1); 688061da546Spatrick 689061da546Spatrick virtual uint64_t GetData(DataExtractor &data, Status &error); 690061da546Spatrick 691061da546Spatrick virtual bool SetData(DataExtractor &data, Status &error); 692061da546Spatrick GetIsConstant()693061da546Spatrick virtual bool GetIsConstant() const { return m_update_point.IsConstant(); } 694061da546Spatrick NeedsUpdating()695061da546Spatrick bool NeedsUpdating() { 696061da546Spatrick const bool accept_invalid_exe_ctx = 697061da546Spatrick (CanUpdateWithInvalidExecutionContext() == eLazyBoolYes); 698061da546Spatrick return m_update_point.NeedsUpdating(accept_invalid_exe_ctx); 699061da546Spatrick } 700061da546Spatrick SetIsConstant()701061da546Spatrick void SetIsConstant() { m_update_point.SetIsConstant(); } 702061da546Spatrick 703061da546Spatrick lldb::Format GetFormat() const; 704061da546Spatrick SetFormat(lldb::Format format)705061da546Spatrick virtual void SetFormat(lldb::Format format) { 706061da546Spatrick if (format != m_format) 707061da546Spatrick ClearUserVisibleData(eClearUserVisibleDataItemsValue); 708061da546Spatrick m_format = format; 709061da546Spatrick } 710061da546Spatrick 711061da546Spatrick virtual lldb::LanguageType GetPreferredDisplayLanguage(); 712061da546Spatrick SetPreferredDisplayLanguage(lldb::LanguageType lt)713be691f3bSpatrick void SetPreferredDisplayLanguage(lldb::LanguageType lt) { 714be691f3bSpatrick m_preferred_display_language = lt; 715be691f3bSpatrick } 716061da546Spatrick GetSummaryFormat()717061da546Spatrick lldb::TypeSummaryImplSP GetSummaryFormat() { 718061da546Spatrick UpdateFormatsIfNeeded(); 719061da546Spatrick return m_type_summary_sp; 720061da546Spatrick } 721061da546Spatrick SetSummaryFormat(lldb::TypeSummaryImplSP format)722061da546Spatrick void SetSummaryFormat(lldb::TypeSummaryImplSP format) { 723be691f3bSpatrick m_type_summary_sp = std::move(format); 724061da546Spatrick ClearUserVisibleData(eClearUserVisibleDataItemsSummary); 725061da546Spatrick } 726061da546Spatrick SetValueFormat(lldb::TypeFormatImplSP format)727061da546Spatrick void SetValueFormat(lldb::TypeFormatImplSP format) { 728be691f3bSpatrick m_type_format_sp = std::move(format); 729061da546Spatrick ClearUserVisibleData(eClearUserVisibleDataItemsValue); 730061da546Spatrick } 731061da546Spatrick GetValueFormat()732061da546Spatrick lldb::TypeFormatImplSP GetValueFormat() { 733061da546Spatrick UpdateFormatsIfNeeded(); 734061da546Spatrick return m_type_format_sp; 735061da546Spatrick } 736061da546Spatrick SetSyntheticChildren(const lldb::SyntheticChildrenSP & synth_sp)737061da546Spatrick void SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp) { 738061da546Spatrick if (synth_sp.get() == m_synthetic_children_sp.get()) 739061da546Spatrick return; 740061da546Spatrick ClearUserVisibleData(eClearUserVisibleDataItemsSyntheticChildren); 741061da546Spatrick m_synthetic_children_sp = synth_sp; 742061da546Spatrick } 743061da546Spatrick GetSyntheticChildren()744061da546Spatrick lldb::SyntheticChildrenSP GetSyntheticChildren() { 745061da546Spatrick UpdateFormatsIfNeeded(); 746061da546Spatrick return m_synthetic_children_sp; 747061da546Spatrick } 748061da546Spatrick 749061da546Spatrick // Use GetParent for display purposes, but if you want to tell the parent to 750061da546Spatrick // update itself then use m_parent. The ValueObjectDynamicValue's parent is 751061da546Spatrick // not the correct parent for displaying, they are really siblings, so for 752061da546Spatrick // display it needs to route through to its grandparent. GetParent()753061da546Spatrick virtual ValueObject *GetParent() { return m_parent; } 754061da546Spatrick GetParent()755061da546Spatrick virtual const ValueObject *GetParent() const { return m_parent; } 756061da546Spatrick 757061da546Spatrick ValueObject *GetNonBaseClassParent(); 758061da546Spatrick SetAddressTypeOfChildren(AddressType at)759061da546Spatrick void SetAddressTypeOfChildren(AddressType at) { 760061da546Spatrick m_address_type_of_ptr_or_ref_children = at; 761061da546Spatrick } 762061da546Spatrick 763061da546Spatrick AddressType GetAddressTypeOfChildren(); 764061da546Spatrick SetHasCompleteType()765be691f3bSpatrick void SetHasCompleteType() { 766be691f3bSpatrick m_flags.m_did_calculate_complete_objc_class_type = true; 767be691f3bSpatrick } 768061da546Spatrick 769061da546Spatrick /// Find out if a ValueObject might have children. 770061da546Spatrick /// 771061da546Spatrick /// This call is much more efficient than CalculateNumChildren() as 772061da546Spatrick /// it doesn't need to complete the underlying type. This is designed 773061da546Spatrick /// to be used in a UI environment in order to detect if the 774061da546Spatrick /// disclosure triangle should be displayed or not. 775061da546Spatrick /// 776061da546Spatrick /// This function returns true for class, union, structure, 777061da546Spatrick /// pointers, references, arrays and more. Again, it does so without 778061da546Spatrick /// doing any expensive type completion. 779061da546Spatrick /// 780061da546Spatrick /// \return 781061da546Spatrick /// Returns \b true if the ValueObject might have children, or \b 782061da546Spatrick /// false otherwise. 783061da546Spatrick virtual bool MightHaveChildren(); 784061da546Spatrick GetVariable()785061da546Spatrick virtual lldb::VariableSP GetVariable() { return nullptr; } 786061da546Spatrick 787061da546Spatrick virtual bool IsRuntimeSupportValue(); 788061da546Spatrick GetLanguageFlags()789be691f3bSpatrick virtual uint64_t GetLanguageFlags() { return m_language_flags; } 790061da546Spatrick SetLanguageFlags(uint64_t flags)791be691f3bSpatrick virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; } 792061da546Spatrick 793061da546Spatrick protected: 794061da546Spatrick typedef ClusterManager<ValueObject> ValueObjectManager; 795061da546Spatrick 796061da546Spatrick class ChildrenManager { 797061da546Spatrick public: 798*f6aab3d8Srobert ChildrenManager() = default; 799061da546Spatrick HasChildAtIndex(size_t idx)800061da546Spatrick bool HasChildAtIndex(size_t idx) { 801061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex); 802061da546Spatrick return (m_children.find(idx) != m_children.end()); 803061da546Spatrick } 804061da546Spatrick GetChildAtIndex(size_t idx)805061da546Spatrick ValueObject *GetChildAtIndex(size_t idx) { 806061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex); 807061da546Spatrick const auto iter = m_children.find(idx); 808061da546Spatrick return ((iter == m_children.end()) ? nullptr : iter->second); 809061da546Spatrick } 810061da546Spatrick SetChildAtIndex(size_t idx,ValueObject * valobj)811061da546Spatrick void SetChildAtIndex(size_t idx, ValueObject *valobj) { 812061da546Spatrick // we do not need to be mutex-protected to make a pair 813061da546Spatrick ChildrenPair pair(idx, valobj); 814061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex); 815061da546Spatrick m_children.insert(pair); 816061da546Spatrick } 817061da546Spatrick SetChildrenCount(size_t count)818061da546Spatrick void SetChildrenCount(size_t count) { Clear(count); } 819061da546Spatrick GetChildrenCount()820061da546Spatrick size_t GetChildrenCount() { return m_children_count; } 821061da546Spatrick 822061da546Spatrick void Clear(size_t new_count = 0) { 823061da546Spatrick std::lock_guard<std::recursive_mutex> guard(m_mutex); 824061da546Spatrick m_children_count = new_count; 825061da546Spatrick m_children.clear(); 826061da546Spatrick } 827061da546Spatrick 828061da546Spatrick private: 829061da546Spatrick typedef std::map<size_t, ValueObject *> ChildrenMap; 830061da546Spatrick typedef ChildrenMap::iterator ChildrenIterator; 831061da546Spatrick typedef ChildrenMap::value_type ChildrenPair; 832061da546Spatrick std::recursive_mutex m_mutex; 833061da546Spatrick ChildrenMap m_children; 834be691f3bSpatrick size_t m_children_count = 0; 835061da546Spatrick }; 836061da546Spatrick 837061da546Spatrick // Classes that inherit from ValueObject can see and modify these 838be691f3bSpatrick 839be691f3bSpatrick /// The parent value object, or nullptr if this has no parent. 840be691f3bSpatrick ValueObject *m_parent = nullptr; 841be691f3bSpatrick /// The root of the hierarchy for this ValueObject (or nullptr if never 842be691f3bSpatrick /// calculated). 843be691f3bSpatrick ValueObject *m_root = nullptr; 844be691f3bSpatrick /// Stores both the stop id and the full context at which this value was last 845be691f3bSpatrick /// updated. When we are asked to update the value object, we check whether 846be691f3bSpatrick /// the context & stop id are the same before updating. 847be691f3bSpatrick EvaluationPoint m_update_point; 848be691f3bSpatrick /// The name of this object. 849be691f3bSpatrick ConstString m_name; 850be691f3bSpatrick /// A data extractor that can be used to extract the value. 851be691f3bSpatrick DataExtractor m_data; 852061da546Spatrick Value m_value; 853be691f3bSpatrick /// An error object that can describe any errors that occur when updating 854be691f3bSpatrick /// values. 855be691f3bSpatrick Status m_error; 856be691f3bSpatrick /// Cached value string that will get cleared if/when the value is updated. 857be691f3bSpatrick std::string m_value_str; 858be691f3bSpatrick /// Cached old value string from the last time the value was gotten 859be691f3bSpatrick std::string m_old_value_str; 860be691f3bSpatrick /// Cached location string that will get cleared if/when the value is updated. 861be691f3bSpatrick std::string m_location_str; 862be691f3bSpatrick /// Cached summary string that will get cleared if/when the value is updated. 863be691f3bSpatrick std::string m_summary_str; 864be691f3bSpatrick /// Cached result of the "object printer". This differs from the summary 865be691f3bSpatrick /// in that the summary is consed up by us, the object_desc_string is builtin. 866be691f3bSpatrick std::string m_object_desc_str; 867be691f3bSpatrick /// If the type of the value object should be overridden, the type to impose. 868be691f3bSpatrick CompilerType m_override_type; 869061da546Spatrick 870be691f3bSpatrick /// This object is managed by the root object (any ValueObject that gets 871be691f3bSpatrick /// created without a parent.) The manager gets passed through all the 872be691f3bSpatrick /// generations of dependent objects, and will keep the whole cluster of 873be691f3bSpatrick /// objects alive as long as a shared pointer to any of them has been handed 874be691f3bSpatrick /// out. Shared pointers to value objects must always be made with the GetSP 875be691f3bSpatrick /// method. 876be691f3bSpatrick ValueObjectManager *m_manager = nullptr; 877061da546Spatrick 878061da546Spatrick ChildrenManager m_children; 879061da546Spatrick std::map<ConstString, ValueObject *> m_synthetic_children; 880061da546Spatrick 881be691f3bSpatrick ValueObject *m_dynamic_value = nullptr; 882be691f3bSpatrick ValueObject *m_synthetic_value = nullptr; 883be691f3bSpatrick ValueObject *m_deref_valobj = nullptr; 884061da546Spatrick 885be691f3bSpatrick /// We have to hold onto a shared pointer to this one because it is created 886be691f3bSpatrick /// as an independent ValueObjectConstResult, which isn't managed by us. 887be691f3bSpatrick lldb::ValueObjectSP m_addr_of_valobj_sp; 888061da546Spatrick 889be691f3bSpatrick lldb::Format m_format = lldb::eFormatDefault; 890be691f3bSpatrick lldb::Format m_last_format = lldb::eFormatDefault; 891be691f3bSpatrick uint32_t m_last_format_mgr_revision = 0; 892061da546Spatrick lldb::TypeSummaryImplSP m_type_summary_sp; 893061da546Spatrick lldb::TypeFormatImplSP m_type_format_sp; 894061da546Spatrick lldb::SyntheticChildrenSP m_synthetic_children_sp; 895061da546Spatrick ProcessModID m_user_id_of_forced_summary; 896be691f3bSpatrick AddressType m_address_type_of_ptr_or_ref_children = eAddressTypeInvalid; 897061da546Spatrick 898061da546Spatrick llvm::SmallVector<uint8_t, 16> m_value_checksum; 899061da546Spatrick 900be691f3bSpatrick lldb::LanguageType m_preferred_display_language = lldb::eLanguageTypeUnknown; 901061da546Spatrick 902be691f3bSpatrick uint64_t m_language_flags = 0; 903061da546Spatrick 904be691f3bSpatrick /// Unique identifier for every value object. 905be691f3bSpatrick UserID m_id; 906be691f3bSpatrick 907be691f3bSpatrick // Utility class for initializing all bitfields in ValueObject's constructors. 908be691f3bSpatrick // FIXME: This could be done via default initializers once we have C++20. 909be691f3bSpatrick struct Bitflags { 910be691f3bSpatrick bool m_value_is_valid : 1, m_value_did_change : 1, 911be691f3bSpatrick m_children_count_valid : 1, m_old_value_valid : 1, 912be691f3bSpatrick m_is_deref_of_parent : 1, m_is_array_item_for_pointer : 1, 913be691f3bSpatrick m_is_bitfield_for_scalar : 1, m_is_child_at_offset : 1, 914be691f3bSpatrick m_is_getting_summary : 1, m_did_calculate_complete_objc_class_type : 1, 915061da546Spatrick m_is_synthetic_children_generated : 1; BitflagsBitflags916be691f3bSpatrick Bitflags() { 917be691f3bSpatrick m_value_is_valid = false; 918be691f3bSpatrick m_value_did_change = false; 919be691f3bSpatrick m_children_count_valid = false; 920be691f3bSpatrick m_old_value_valid = false; 921be691f3bSpatrick m_is_deref_of_parent = false; 922be691f3bSpatrick m_is_array_item_for_pointer = false; 923be691f3bSpatrick m_is_bitfield_for_scalar = false; 924be691f3bSpatrick m_is_child_at_offset = false; 925be691f3bSpatrick m_is_getting_summary = false; 926be691f3bSpatrick m_did_calculate_complete_objc_class_type = false; 927be691f3bSpatrick m_is_synthetic_children_generated = false; 928be691f3bSpatrick } 929be691f3bSpatrick } m_flags; 930061da546Spatrick 931061da546Spatrick friend class ValueObjectChild; 932061da546Spatrick friend class ExpressionVariable; // For SetName 933061da546Spatrick friend class Target; // For SetName 934061da546Spatrick friend class ValueObjectConstResultImpl; 935061da546Spatrick friend class ValueObjectSynthetic; // For ClearUserVisibleData 936061da546Spatrick 937be691f3bSpatrick /// Use this constructor to create a "root variable object". The ValueObject 938be691f3bSpatrick /// will be locked to this context through-out its lifespan. 939dda28197Spatrick ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, 940061da546Spatrick AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad); 941061da546Spatrick 942be691f3bSpatrick /// Use this constructor to create a ValueObject owned by another ValueObject. 943be691f3bSpatrick /// It will inherit the ExecutionContext of its parent. 944061da546Spatrick ValueObject(ValueObject &parent); 945061da546Spatrick GetManager()946061da546Spatrick ValueObjectManager *GetManager() { return m_manager; } 947061da546Spatrick 948061da546Spatrick virtual bool UpdateValue() = 0; 949061da546Spatrick CanUpdateWithInvalidExecutionContext()950061da546Spatrick virtual LazyBool CanUpdateWithInvalidExecutionContext() { 951061da546Spatrick return eLazyBoolCalculate; 952061da546Spatrick } 953061da546Spatrick 954061da546Spatrick virtual void CalculateDynamicValue(lldb::DynamicValueType use_dynamic); 955061da546Spatrick GetDynamicValueTypeImpl()956061da546Spatrick virtual lldb::DynamicValueType GetDynamicValueTypeImpl() { 957061da546Spatrick return lldb::eNoDynamicValues; 958061da546Spatrick } 959061da546Spatrick HasDynamicValueTypeInfo()960061da546Spatrick virtual bool HasDynamicValueTypeInfo() { return false; } 961061da546Spatrick 962dda28197Spatrick virtual void CalculateSyntheticValue(); 963061da546Spatrick 964be691f3bSpatrick /// Should only be called by ValueObject::GetChildAtIndex(). 965be691f3bSpatrick /// 966be691f3bSpatrick /// \return A ValueObject managed by this ValueObject's manager. 967061da546Spatrick virtual ValueObject *CreateChildAtIndex(size_t idx, 968061da546Spatrick bool synthetic_array_member, 969061da546Spatrick int32_t synthetic_index); 970061da546Spatrick 971be691f3bSpatrick /// Should only be called by ValueObject::GetNumChildren(). 972061da546Spatrick virtual size_t CalculateNumChildren(uint32_t max = UINT32_MAX) = 0; 973061da546Spatrick 974061da546Spatrick void SetNumChildren(size_t num_children); 975061da546Spatrick SetValueDidChange(bool value_changed)976be691f3bSpatrick void SetValueDidChange(bool value_changed) { 977be691f3bSpatrick m_flags.m_value_did_change = value_changed; 978be691f3bSpatrick } 979061da546Spatrick SetValueIsValid(bool valid)980be691f3bSpatrick void SetValueIsValid(bool valid) { m_flags.m_value_is_valid = valid; } 981061da546Spatrick 982061da546Spatrick void ClearUserVisibleData( 983061da546Spatrick uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings); 984061da546Spatrick 985061da546Spatrick void AddSyntheticChild(ConstString key, ValueObject *valobj); 986061da546Spatrick 987061da546Spatrick DataExtractor &GetDataExtractor(); 988061da546Spatrick 989061da546Spatrick void ClearDynamicTypeInformation(); 990061da546Spatrick 991061da546Spatrick // Subclasses must implement the functions below. 992061da546Spatrick 993061da546Spatrick virtual CompilerType GetCompilerTypeImpl() = 0; 994061da546Spatrick 995061da546Spatrick const char *GetLocationAsCStringImpl(const Value &value, 996061da546Spatrick const DataExtractor &data); 997061da546Spatrick IsChecksumEmpty()998be691f3bSpatrick bool IsChecksumEmpty() { return m_value_checksum.empty(); } 999061da546Spatrick 1000061da546Spatrick void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType); 1001061da546Spatrick 1002dda28197Spatrick protected: DoUpdateChildrenAddressType(ValueObject & valobj)1003*f6aab3d8Srobert virtual void DoUpdateChildrenAddressType(ValueObject &valobj){}; 1004dda28197Spatrick 1005061da546Spatrick private: 1006061da546Spatrick virtual CompilerType MaybeCalculateCompleteType(); UpdateChildrenAddressType()1007dda28197Spatrick void UpdateChildrenAddressType() { 1008dda28197Spatrick GetRoot()->DoUpdateChildrenAddressType(*this); 1009dda28197Spatrick } 1010061da546Spatrick 1011061da546Spatrick lldb::ValueObjectSP GetValueForExpressionPath_Impl( 1012061da546Spatrick llvm::StringRef expression_cstr, 1013061da546Spatrick ExpressionPathScanEndReason *reason_to_stop, 1014061da546Spatrick ExpressionPathEndResultType *final_value_type, 1015061da546Spatrick const GetValueForExpressionPathOptions &options, 1016061da546Spatrick ExpressionPathAftermath *final_task_on_target); 1017061da546Spatrick 1018dda28197Spatrick ValueObject(const ValueObject &) = delete; 1019dda28197Spatrick const ValueObject &operator=(const ValueObject &) = delete; 1020061da546Spatrick }; 1021061da546Spatrick 1022061da546Spatrick } // namespace lldb_private 1023061da546Spatrick 1024dda28197Spatrick #endif // LLDB_CORE_VALUEOBJECT_H 1025