xref: /openbsd-src/gnu/llvm/lldb/include/lldb/Core/ValueObject.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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