1 | //===-- ValueObject.h -------------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_CORE_VALUEOBJECT_H |
10 | #define LLDB_CORE_VALUEOBJECT_H |
11 | |
12 | #include "lldb/Core/Value.h" |
13 | #include "lldb/Symbol/CompilerType.h" |
14 | #include "lldb/Symbol/Type.h" |
15 | #include "lldb/Target/ExecutionContext.h" |
16 | #include "lldb/Target/Process.h" |
17 | #include "lldb/Utility/ConstString.h" |
18 | #include "lldb/Utility/DataExtractor.h" |
19 | #include "lldb/Utility/SharedCluster.h" |
20 | #include "lldb/Utility/Status.h" |
21 | #include "lldb/Utility/UserID.h" |
22 | #include "lldb/lldb-defines.h" |
23 | #include "lldb/lldb-enumerations.h" |
24 | #include "lldb/lldb-forward.h" |
25 | #include "lldb/lldb-private-enumerations.h" |
26 | #include "lldb/lldb-types.h" |
27 | |
28 | #include "llvm/ADT/ArrayRef.h" |
29 | #include "llvm/ADT/SmallVector.h" |
30 | #include "llvm/ADT/StringRef.h" |
31 | |
32 | #include <functional> |
33 | #include <initializer_list> |
34 | #include <map> |
35 | #include <mutex> |
36 | #include <optional> |
37 | #include <string> |
38 | #include <utility> |
39 | |
40 | #include <cstddef> |
41 | #include <cstdint> |
42 | |
43 | namespace lldb_private { |
44 | class Declaration; |
45 | class DumpValueObjectOptions; |
46 | class EvaluateExpressionOptions; |
47 | class ExecutionContextScope; |
48 | class Log; |
49 | class Scalar; |
50 | class Stream; |
51 | class SymbolContextScope; |
52 | class TypeFormatImpl; |
53 | class TypeSummaryImpl; |
54 | class TypeSummaryOptions; |
55 | |
56 | /// ValueObject: |
57 | /// |
58 | /// This abstract class provides an interface to a particular value, be it a |
59 | /// register, a local or global variable, |
60 | /// that is evaluated in some particular scope. The ValueObject also has the |
61 | /// capability of being the "child" of |
62 | /// some other variable object, and in turn of having children. |
63 | /// If a ValueObject is a root variable object - having no parent - then it must |
64 | /// be constructed with respect to some |
65 | /// particular ExecutionContextScope. If it is a child, it inherits the |
66 | /// ExecutionContextScope from its parent. |
67 | /// The ValueObject will update itself if necessary before fetching its value, |
68 | /// summary, object description, etc. |
69 | /// But it will always update itself in the ExecutionContextScope with which it |
70 | /// was originally created. |
71 | |
72 | /// A brief note on life cycle management for ValueObjects. This is a little |
73 | /// tricky because a ValueObject can contain |
74 | /// various other ValueObjects - the Dynamic Value, its children, the |
75 | /// dereference value, etc. Any one of these can be |
76 | /// handed out as a shared pointer, but for that contained value object to be |
77 | /// valid, the root object and potentially other |
78 | /// of the value objects need to stay around. |
79 | /// We solve this problem by handing out shared pointers to the Value Object and |
80 | /// any of its dependents using a shared |
81 | /// ClusterManager. This treats each shared pointer handed out for the entire |
82 | /// cluster as a reference to the whole |
83 | /// cluster. The whole cluster will stay around until the last reference is |
84 | /// released. |
85 | /// |
86 | /// The ValueObject mostly handle this automatically, if a value object is made |
87 | /// with a Parent ValueObject, then it adds |
88 | /// itself to the ClusterManager of the parent. |
89 | |
90 | /// It does mean that external to the ValueObjects we should only ever make |
91 | /// available ValueObjectSP's, never ValueObjects |
92 | /// or pointers to them. So all the "Root level" ValueObject derived |
93 | /// constructors should be private, and |
94 | /// should implement a Create function that new's up object and returns a Shared |
95 | /// Pointer that it gets from the GetSP() method. |
96 | /// |
97 | /// However, if you are making an derived ValueObject that will be contained in |
98 | /// a parent value object, you should just |
99 | /// hold onto a pointer to it internally, and by virtue of passing the parent |
100 | /// ValueObject into its constructor, it will |
101 | /// be added to the ClusterManager for the parent. Then if you ever hand out a |
102 | /// Shared Pointer to the contained ValueObject, |
103 | /// just do so by calling GetSP() on the contained object. |
104 | |
105 | class ValueObject { |
106 | public: |
107 | enum GetExpressionPathFormat { |
108 | eGetExpressionPathFormatDereferencePointers = 1, |
109 | eGetExpressionPathFormatHonorPointers |
110 | }; |
111 | |
112 | enum ValueObjectRepresentationStyle { |
113 | eValueObjectRepresentationStyleValue = 1, |
114 | eValueObjectRepresentationStyleSummary, |
115 | eValueObjectRepresentationStyleLanguageSpecific, |
116 | eValueObjectRepresentationStyleLocation, |
117 | eValueObjectRepresentationStyleChildrenCount, |
118 | eValueObjectRepresentationStyleType, |
119 | eValueObjectRepresentationStyleName, |
120 | eValueObjectRepresentationStyleExpressionPath |
121 | }; |
122 | |
123 | enum ExpressionPathScanEndReason { |
124 | /// Out of data to parse. |
125 | eExpressionPathScanEndReasonEndOfString = 1, |
126 | /// Child element not found. |
127 | eExpressionPathScanEndReasonNoSuchChild, |
128 | /// (Synthetic) child element not found. |
129 | eExpressionPathScanEndReasonNoSuchSyntheticChild, |
130 | /// [] only allowed for arrays. |
131 | eExpressionPathScanEndReasonEmptyRangeNotAllowed, |
132 | /// . used when -> should be used. |
133 | eExpressionPathScanEndReasonDotInsteadOfArrow, |
134 | /// -> used when . should be used. |
135 | eExpressionPathScanEndReasonArrowInsteadOfDot, |
136 | /// ObjC ivar expansion not allowed. |
137 | eExpressionPathScanEndReasonFragileIVarNotAllowed, |
138 | /// [] not allowed by options. |
139 | eExpressionPathScanEndReasonRangeOperatorNotAllowed, |
140 | /// [] not valid on objects other than scalars, pointers or arrays. |
141 | eExpressionPathScanEndReasonRangeOperatorInvalid, |
142 | /// [] is good for arrays, but I cannot parse it. |
143 | eExpressionPathScanEndReasonArrayRangeOperatorMet, |
144 | /// [] is good for bitfields, but I cannot parse after it. |
145 | eExpressionPathScanEndReasonBitfieldRangeOperatorMet, |
146 | /// Something is malformed in he expression. |
147 | eExpressionPathScanEndReasonUnexpectedSymbol, |
148 | /// Impossible to apply & operator. |
149 | eExpressionPathScanEndReasonTakingAddressFailed, |
150 | /// Impossible to apply * operator. |
151 | eExpressionPathScanEndReasonDereferencingFailed, |
152 | /// [] was expanded into a VOList. |
153 | eExpressionPathScanEndReasonRangeOperatorExpanded, |
154 | /// getting the synthetic children failed. |
155 | eExpressionPathScanEndReasonSyntheticValueMissing, |
156 | eExpressionPathScanEndReasonUnknown = 0xFFFF |
157 | }; |
158 | |
159 | enum ExpressionPathEndResultType { |
160 | /// Anything but... |
161 | eExpressionPathEndResultTypePlain = 1, |
162 | /// A bitfield. |
163 | eExpressionPathEndResultTypeBitfield, |
164 | /// A range [low-high]. |
165 | eExpressionPathEndResultTypeBoundedRange, |
166 | /// A range []. |
167 | eExpressionPathEndResultTypeUnboundedRange, |
168 | /// Several items in a VOList. |
169 | eExpressionPathEndResultTypeValueObjectList, |
170 | eExpressionPathEndResultTypeInvalid = 0xFFFF |
171 | }; |
172 | |
173 | enum ExpressionPathAftermath { |
174 | /// Just return it. |
175 | eExpressionPathAftermathNothing = 1, |
176 | /// Dereference the target. |
177 | eExpressionPathAftermathDereference, |
178 | /// Take target's address. |
179 | eExpressionPathAftermathTakeAddress |
180 | }; |
181 | |
182 | enum ClearUserVisibleDataItems { |
183 | eClearUserVisibleDataItemsNothing = 1u << 0, |
184 | eClearUserVisibleDataItemsValue = 1u << 1, |
185 | eClearUserVisibleDataItemsSummary = 1u << 2, |
186 | eClearUserVisibleDataItemsLocation = 1u << 3, |
187 | eClearUserVisibleDataItemsDescription = 1u << 4, |
188 | eClearUserVisibleDataItemsSyntheticChildren = 1u << 5, |
189 | eClearUserVisibleDataItemsAllStrings = |
190 | eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary | |
191 | eClearUserVisibleDataItemsLocation | |
192 | eClearUserVisibleDataItemsDescription, |
193 | eClearUserVisibleDataItemsAll = 0xFFFF |
194 | }; |
195 | |
196 | struct GetValueForExpressionPathOptions { |
197 | enum class SyntheticChildrenTraversal { |
198 | None, |
199 | ToSynthetic, |
200 | FromSynthetic, |
201 | Both |
202 | }; |
203 | |
204 | bool m_check_dot_vs_arrow_syntax; |
205 | bool m_no_fragile_ivar; |
206 | bool m_allow_bitfields_syntax; |
207 | SyntheticChildrenTraversal m_synthetic_children_traversal; |
208 | |
209 | GetValueForExpressionPathOptions( |
210 | bool dot = false, bool no_ivar = false, bool bitfield = true, |
211 | SyntheticChildrenTraversal synth_traverse = |
212 | SyntheticChildrenTraversal::ToSynthetic) |
213 | : m_check_dot_vs_arrow_syntax(dot), m_no_fragile_ivar(no_ivar), |
214 | m_allow_bitfields_syntax(bitfield), |
215 | m_synthetic_children_traversal(synth_traverse) {} |
216 | |
217 | GetValueForExpressionPathOptions &DoCheckDotVsArrowSyntax() { |
218 | m_check_dot_vs_arrow_syntax = true; |
219 | return *this; |
220 | } |
221 | |
222 | GetValueForExpressionPathOptions &DontCheckDotVsArrowSyntax() { |
223 | m_check_dot_vs_arrow_syntax = false; |
224 | return *this; |
225 | } |
226 | |
227 | GetValueForExpressionPathOptions &DoAllowFragileIVar() { |
228 | m_no_fragile_ivar = false; |
229 | return *this; |
230 | } |
231 | |
232 | GetValueForExpressionPathOptions &DontAllowFragileIVar() { |
233 | m_no_fragile_ivar = true; |
234 | return *this; |
235 | } |
236 | |
237 | GetValueForExpressionPathOptions &DoAllowBitfieldSyntax() { |
238 | m_allow_bitfields_syntax = true; |
239 | return *this; |
240 | } |
241 | |
242 | GetValueForExpressionPathOptions &DontAllowBitfieldSyntax() { |
243 | m_allow_bitfields_syntax = false; |
244 | return *this; |
245 | } |
246 | |
247 | GetValueForExpressionPathOptions & |
248 | SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse) { |
249 | m_synthetic_children_traversal = traverse; |
250 | return *this; |
251 | } |
252 | |
253 | static const GetValueForExpressionPathOptions DefaultOptions() { |
254 | static GetValueForExpressionPathOptions g_default_options; |
255 | |
256 | return g_default_options; |
257 | } |
258 | }; |
259 | |
260 | class EvaluationPoint { |
261 | public: |
262 | EvaluationPoint(); |
263 | |
264 | EvaluationPoint(ExecutionContextScope *exe_scope, |
265 | bool use_selected = false); |
266 | |
267 | EvaluationPoint(const EvaluationPoint &rhs); |
268 | |
269 | ~EvaluationPoint(); |
270 | |
271 | const ExecutionContextRef &GetExecutionContextRef() const { |
272 | return m_exe_ctx_ref; |
273 | } |
274 | |
275 | void SetIsConstant() { |
276 | SetUpdated(); |
277 | m_mod_id.SetInvalid(); |
278 | } |
279 | |
280 | bool IsConstant() const { return !m_mod_id.IsValid(); } |
281 | |
282 | ProcessModID GetModID() const { return m_mod_id; } |
283 | |
284 | void SetUpdateID(ProcessModID new_id) { m_mod_id = new_id; } |
285 | |
286 | void SetNeedsUpdate() { m_needs_update = true; } |
287 | |
288 | void SetUpdated(); |
289 | |
290 | bool NeedsUpdating(bool accept_invalid_exe_ctx) { |
291 | SyncWithProcessState(accept_invalid_exe_ctx); |
292 | return m_needs_update; |
293 | } |
294 | |
295 | bool IsValid() { |
296 | const bool accept_invalid_exe_ctx = false; |
297 | if (!m_mod_id.IsValid()) |
298 | return false; |
299 | else if (SyncWithProcessState(accept_invalid_exe_ctx)) { |
300 | if (!m_mod_id.IsValid()) |
301 | return false; |
302 | } |
303 | return true; |
304 | } |
305 | |
306 | void SetInvalid() { |
307 | // Use the stop id to mark us as invalid, leave the thread id and the |
308 | // stack id around for logging and history purposes. |
309 | m_mod_id.SetInvalid(); |
310 | |
311 | // Can't update an invalid state. |
312 | m_needs_update = false; |
313 | } |
314 | |
315 | private: |
316 | bool SyncWithProcessState(bool accept_invalid_exe_ctx); |
317 | |
318 | ProcessModID m_mod_id; // This is the stop id when this ValueObject was last |
319 | // evaluated. |
320 | ExecutionContextRef m_exe_ctx_ref; |
321 | bool m_needs_update = true; |
322 | }; |
323 | |
324 | virtual ~ValueObject(); |
325 | |
326 | const EvaluationPoint &GetUpdatePoint() const { return m_update_point; } |
327 | |
328 | EvaluationPoint &GetUpdatePoint() { return m_update_point; } |
329 | |
330 | const ExecutionContextRef &GetExecutionContextRef() const { |
331 | return m_update_point.GetExecutionContextRef(); |
332 | } |
333 | |
334 | lldb::TargetSP GetTargetSP() const { |
335 | return m_update_point.GetExecutionContextRef().GetTargetSP(); |
336 | } |
337 | |
338 | lldb::ProcessSP GetProcessSP() const { |
339 | return m_update_point.GetExecutionContextRef().GetProcessSP(); |
340 | } |
341 | |
342 | lldb::ThreadSP GetThreadSP() const { |
343 | return m_update_point.GetExecutionContextRef().GetThreadSP(); |
344 | } |
345 | |
346 | lldb::StackFrameSP GetFrameSP() const { |
347 | return m_update_point.GetExecutionContextRef().GetFrameSP(); |
348 | } |
349 | |
350 | void SetNeedsUpdate(); |
351 | |
352 | CompilerType GetCompilerType() { return MaybeCalculateCompleteType(); } |
353 | |
354 | // this vends a TypeImpl that is useful at the SB API layer |
355 | virtual TypeImpl GetTypeImpl() { return TypeImpl(GetCompilerType()); } |
356 | |
357 | virtual bool CanProvideValue(); |
358 | |
359 | // Subclasses must implement the functions below. |
360 | virtual std::optional<uint64_t> GetByteSize() = 0; |
361 | |
362 | virtual lldb::ValueType GetValueType() const = 0; |
363 | |
364 | // Subclasses can implement the functions below. |
365 | virtual ConstString GetTypeName() { return GetCompilerType().GetTypeName(); } |
366 | |
367 | virtual ConstString GetDisplayTypeName() { return GetTypeName(); } |
368 | |
369 | virtual ConstString GetQualifiedTypeName() { |
370 | return GetCompilerType().GetTypeName(); |
371 | } |
372 | |
373 | lldb::LanguageType GetObjectRuntimeLanguage() { |
374 | return GetCompilerType().GetMinimumLanguage(); |
375 | } |
376 | |
377 | uint32_t |
378 | GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) { |
379 | return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type); |
380 | } |
381 | |
382 | bool IsPointerType() { return GetCompilerType().IsPointerType(); } |
383 | |
384 | bool IsArrayType() { return GetCompilerType().IsArrayType(); } |
385 | |
386 | bool IsScalarType() { return GetCompilerType().IsScalarType(); } |
387 | |
388 | bool IsPointerOrReferenceType() { |
389 | return GetCompilerType().IsPointerOrReferenceType(); |
390 | } |
391 | |
392 | bool IsPossibleDynamicType(); |
393 | |
394 | bool IsNilReference(); |
395 | |
396 | bool IsUninitializedReference(); |
397 | |
398 | virtual bool IsBaseClass() { return false; } |
399 | |
400 | bool IsBaseClass(uint32_t &depth); |
401 | |
402 | virtual bool IsDereferenceOfParent() { return false; } |
403 | |
404 | bool IsIntegerType(bool &is_signed) { |
405 | return GetCompilerType().IsIntegerType(is_signed); |
406 | } |
407 | |
408 | virtual void GetExpressionPath( |
409 | Stream &s, |
410 | GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers); |
411 | |
412 | lldb::ValueObjectSP GetValueForExpressionPath( |
413 | llvm::StringRef expression, |
414 | ExpressionPathScanEndReason *reason_to_stop = nullptr, |
415 | ExpressionPathEndResultType *final_value_type = nullptr, |
416 | const GetValueForExpressionPathOptions &options = |
417 | GetValueForExpressionPathOptions::DefaultOptions(), |
418 | ExpressionPathAftermath *final_task_on_target = nullptr); |
419 | |
420 | virtual bool IsInScope() { return true; } |
421 | |
422 | virtual lldb::offset_t GetByteOffset() { return 0; } |
423 | |
424 | virtual uint32_t GetBitfieldBitSize() { return 0; } |
425 | |
426 | virtual uint32_t GetBitfieldBitOffset() { return 0; } |
427 | |
428 | bool IsBitfield() { |
429 | return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0); |
430 | } |
431 | |
432 | virtual const char *GetValueAsCString(); |
433 | |
434 | virtual bool GetValueAsCString(const lldb_private::TypeFormatImpl &format, |
435 | std::string &destination); |
436 | |
437 | bool GetValueAsCString(lldb::Format format, std::string &destination); |
438 | |
439 | virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, |
440 | bool *success = nullptr); |
441 | |
442 | virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = nullptr); |
443 | |
444 | virtual bool SetValueFromCString(const char *value_str, Status &error); |
445 | |
446 | /// Return the module associated with this value object in case the value is |
447 | /// from an executable file and might have its data in sections of the file. |
448 | /// This can be used for variables. |
449 | virtual lldb::ModuleSP GetModule(); |
450 | |
451 | ValueObject *GetRoot(); |
452 | |
453 | /// Given a ValueObject, loop over itself and its parent, and its parent's |
454 | /// parent, .. until either the given callback returns false, or you end up at |
455 | /// a null pointer |
456 | ValueObject *FollowParentChain(std::function<bool(ValueObject *)>); |
457 | |
458 | virtual bool GetDeclaration(Declaration &decl); |
459 | |
460 | // The functions below should NOT be modified by subclasses |
461 | const Status &GetError(); |
462 | |
463 | ConstString GetName() const { return m_name; } |
464 | |
465 | /// Returns a unique id for this ValueObject. |
466 | lldb::user_id_t GetID() const { return m_id.GetID(); } |
467 | |
468 | virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, |
469 | bool can_create = true); |
470 | |
471 | // The method always creates missing children in the path, if necessary. |
472 | lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<llvm::StringRef> names); |
473 | |
474 | virtual lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, |
475 | bool can_create = true); |
476 | |
477 | virtual size_t GetIndexOfChildWithName(llvm::StringRef name); |
478 | |
479 | size_t GetNumChildren(uint32_t max = UINT32_MAX); |
480 | |
481 | const Value &GetValue() const { return m_value; } |
482 | |
483 | Value &GetValue() { return m_value; } |
484 | |
485 | virtual bool ResolveValue(Scalar &scalar); |
486 | |
487 | // return 'false' whenever you set the error, otherwise callers may assume |
488 | // true means everything is OK - this will break breakpoint conditions among |
489 | // potentially a few others |
490 | virtual bool IsLogicalTrue(Status &error); |
491 | |
492 | virtual const char *GetLocationAsCString() { |
493 | return GetLocationAsCStringImpl(value: m_value, data: m_data); |
494 | } |
495 | |
496 | const char * |
497 | GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown); |
498 | |
499 | bool |
500 | GetSummaryAsCString(TypeSummaryImpl *summary_ptr, std::string &destination, |
501 | lldb::LanguageType lang = lldb::eLanguageTypeUnknown); |
502 | |
503 | bool GetSummaryAsCString(std::string &destination, |
504 | const TypeSummaryOptions &options); |
505 | |
506 | bool GetSummaryAsCString(TypeSummaryImpl *summary_ptr, |
507 | std::string &destination, |
508 | const TypeSummaryOptions &options); |
509 | |
510 | const char *GetObjectDescription(); |
511 | |
512 | bool HasSpecialPrintableRepresentation( |
513 | ValueObjectRepresentationStyle val_obj_display, |
514 | lldb::Format custom_format); |
515 | |
516 | enum class PrintableRepresentationSpecialCases : bool { |
517 | eDisable = false, |
518 | eAllow = true |
519 | }; |
520 | |
521 | bool |
522 | DumpPrintableRepresentation(Stream &s, |
523 | ValueObjectRepresentationStyle val_obj_display = |
524 | eValueObjectRepresentationStyleSummary, |
525 | lldb::Format custom_format = lldb::eFormatInvalid, |
526 | PrintableRepresentationSpecialCases special = |
527 | PrintableRepresentationSpecialCases::eAllow, |
528 | bool do_dump_error = true); |
529 | bool GetValueIsValid() const { return m_flags.m_value_is_valid; } |
530 | |
531 | // If you call this on a newly created ValueObject, it will always return |
532 | // false. |
533 | bool GetValueDidChange() { return m_flags.m_value_did_change; } |
534 | |
535 | bool UpdateValueIfNeeded(bool update_format = true); |
536 | |
537 | bool UpdateFormatsIfNeeded(); |
538 | |
539 | lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(desired_object: this); } |
540 | |
541 | /// Change the name of the current ValueObject. Should *not* be used from a |
542 | /// synthetic child provider as it would change the name of the non synthetic |
543 | /// child as well. |
544 | void SetName(ConstString name) { m_name = name; } |
545 | |
546 | virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true, |
547 | AddressType *address_type = nullptr); |
548 | |
549 | lldb::addr_t GetPointerValue(AddressType *address_type = nullptr); |
550 | |
551 | lldb::ValueObjectSP GetSyntheticChild(ConstString key) const; |
552 | |
553 | lldb::ValueObjectSP GetSyntheticArrayMember(size_t index, bool can_create); |
554 | |
555 | lldb::ValueObjectSP GetSyntheticBitFieldChild(uint32_t from, uint32_t to, |
556 | bool can_create); |
557 | |
558 | lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression, |
559 | bool can_create); |
560 | |
561 | virtual lldb::ValueObjectSP |
562 | GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type, |
563 | bool can_create, |
564 | ConstString name_const_str = ConstString()); |
565 | |
566 | virtual lldb::ValueObjectSP |
567 | GetSyntheticBase(uint32_t offset, const CompilerType &type, bool can_create, |
568 | ConstString name_const_str = ConstString()); |
569 | |
570 | virtual lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType); |
571 | |
572 | lldb::DynamicValueType GetDynamicValueType(); |
573 | |
574 | virtual lldb::ValueObjectSP GetStaticValue() { return GetSP(); } |
575 | |
576 | virtual lldb::ValueObjectSP GetNonSyntheticValue() { return GetSP(); } |
577 | |
578 | lldb::ValueObjectSP GetSyntheticValue(); |
579 | |
580 | virtual bool HasSyntheticValue(); |
581 | |
582 | virtual bool IsSynthetic() { return false; } |
583 | |
584 | lldb::ValueObjectSP |
585 | GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue, |
586 | bool synthValue); |
587 | |
588 | virtual lldb::ValueObjectSP CreateConstantValue(ConstString name); |
589 | |
590 | virtual lldb::ValueObjectSP Dereference(Status &error); |
591 | |
592 | /// Creates a copy of the ValueObject with a new name and setting the current |
593 | /// ValueObject as its parent. It should be used when we want to change the |
594 | /// name of a ValueObject without modifying the actual ValueObject itself |
595 | /// (e.g. sythetic child provider). |
596 | virtual lldb::ValueObjectSP Clone(ConstString new_name); |
597 | |
598 | virtual lldb::ValueObjectSP AddressOf(Status &error); |
599 | |
600 | virtual lldb::addr_t GetLiveAddress() { return LLDB_INVALID_ADDRESS; } |
601 | |
602 | virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS, |
603 | AddressType address_type = eAddressTypeLoad) {} |
604 | |
605 | lldb::ValueObjectSP Cast(const CompilerType &compiler_type); |
606 | |
607 | virtual lldb::ValueObjectSP DoCast(const CompilerType &compiler_type); |
608 | |
609 | virtual lldb::ValueObjectSP CastPointerType(const char *name, |
610 | CompilerType &ast_type); |
611 | |
612 | virtual lldb::ValueObjectSP CastPointerType(const char *name, |
613 | lldb::TypeSP &type_sp); |
614 | |
615 | /// If this object represents a C++ class with a vtable, return an object |
616 | /// that represents the virtual function table. If the object isn't a class |
617 | /// with a vtable, return a valid ValueObject with the error set correctly. |
618 | lldb::ValueObjectSP GetVTable(); |
619 | // The backing bits of this value object were updated, clear any descriptive |
620 | // string, so we know we have to refetch them. |
621 | void ValueUpdated() { |
622 | ClearUserVisibleData(items: eClearUserVisibleDataItemsValue | |
623 | eClearUserVisibleDataItemsSummary | |
624 | eClearUserVisibleDataItemsDescription); |
625 | } |
626 | |
627 | virtual bool IsDynamic() { return false; } |
628 | |
629 | virtual bool DoesProvideSyntheticValue() { return false; } |
630 | |
631 | virtual bool IsSyntheticChildrenGenerated() { |
632 | return m_flags.m_is_synthetic_children_generated; |
633 | } |
634 | |
635 | virtual void SetSyntheticChildrenGenerated(bool b) { |
636 | m_flags.m_is_synthetic_children_generated = b; |
637 | } |
638 | |
639 | virtual SymbolContextScope *GetSymbolContextScope(); |
640 | |
641 | void Dump(Stream &s); |
642 | |
643 | void Dump(Stream &s, const DumpValueObjectOptions &options); |
644 | |
645 | static lldb::ValueObjectSP |
646 | CreateValueObjectFromExpression(llvm::StringRef name, |
647 | llvm::StringRef expression, |
648 | const ExecutionContext &exe_ctx); |
649 | |
650 | static lldb::ValueObjectSP |
651 | CreateValueObjectFromExpression(llvm::StringRef name, |
652 | llvm::StringRef expression, |
653 | const ExecutionContext &exe_ctx, |
654 | const EvaluateExpressionOptions &options); |
655 | |
656 | static lldb::ValueObjectSP |
657 | CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, |
658 | const ExecutionContext &exe_ctx, |
659 | CompilerType type); |
660 | |
661 | static lldb::ValueObjectSP |
662 | (llvm::StringRef name, const DataExtractor &data, |
663 | const ExecutionContext &exe_ctx, CompilerType type); |
664 | |
665 | lldb::ValueObjectSP Persist(); |
666 | |
667 | /// Returns true if this is a char* or a char[] if it is a char* and |
668 | /// check_pointer is true, it also checks that the pointer is valid. |
669 | bool IsCStringContainer(bool check_pointer = false); |
670 | |
671 | std::pair<size_t, bool> |
672 | ReadPointedString(lldb::WritableDataBufferSP &buffer_sp, Status &error, |
673 | bool honor_array); |
674 | |
675 | virtual size_t (DataExtractor &data, uint32_t item_idx = 0, |
676 | uint32_t item_count = 1); |
677 | |
678 | virtual uint64_t (DataExtractor &data, Status &error); |
679 | |
680 | virtual bool (DataExtractor &data, Status &error); |
681 | |
682 | virtual bool GetIsConstant() const { return m_update_point.IsConstant(); } |
683 | |
684 | bool NeedsUpdating() { |
685 | const bool accept_invalid_exe_ctx = |
686 | (CanUpdateWithInvalidExecutionContext() == eLazyBoolYes); |
687 | return m_update_point.NeedsUpdating(accept_invalid_exe_ctx); |
688 | } |
689 | |
690 | void SetIsConstant() { m_update_point.SetIsConstant(); } |
691 | |
692 | lldb::Format GetFormat() const; |
693 | |
694 | virtual void SetFormat(lldb::Format format) { |
695 | if (format != m_format) |
696 | ClearUserVisibleData(items: eClearUserVisibleDataItemsValue); |
697 | m_format = format; |
698 | } |
699 | |
700 | virtual lldb::LanguageType GetPreferredDisplayLanguage(); |
701 | |
702 | void SetPreferredDisplayLanguage(lldb::LanguageType lt) { |
703 | m_preferred_display_language = lt; |
704 | } |
705 | |
706 | lldb::TypeSummaryImplSP GetSummaryFormat() { |
707 | UpdateFormatsIfNeeded(); |
708 | return m_type_summary_sp; |
709 | } |
710 | |
711 | void SetSummaryFormat(lldb::TypeSummaryImplSP format) { |
712 | m_type_summary_sp = std::move(format); |
713 | ClearUserVisibleData(items: eClearUserVisibleDataItemsSummary); |
714 | } |
715 | |
716 | void SetValueFormat(lldb::TypeFormatImplSP format) { |
717 | m_type_format_sp = std::move(format); |
718 | ClearUserVisibleData(items: eClearUserVisibleDataItemsValue); |
719 | } |
720 | |
721 | lldb::TypeFormatImplSP GetValueFormat() { |
722 | UpdateFormatsIfNeeded(); |
723 | return m_type_format_sp; |
724 | } |
725 | |
726 | void SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp) { |
727 | if (synth_sp.get() == m_synthetic_children_sp.get()) |
728 | return; |
729 | ClearUserVisibleData(items: eClearUserVisibleDataItemsSyntheticChildren); |
730 | m_synthetic_children_sp = synth_sp; |
731 | } |
732 | |
733 | lldb::SyntheticChildrenSP GetSyntheticChildren() { |
734 | UpdateFormatsIfNeeded(); |
735 | return m_synthetic_children_sp; |
736 | } |
737 | |
738 | // Use GetParent for display purposes, but if you want to tell the parent to |
739 | // update itself then use m_parent. The ValueObjectDynamicValue's parent is |
740 | // not the correct parent for displaying, they are really siblings, so for |
741 | // display it needs to route through to its grandparent. |
742 | virtual ValueObject *GetParent() { return m_parent; } |
743 | |
744 | virtual const ValueObject *GetParent() const { return m_parent; } |
745 | |
746 | ValueObject *GetNonBaseClassParent(); |
747 | |
748 | void SetAddressTypeOfChildren(AddressType at) { |
749 | m_address_type_of_ptr_or_ref_children = at; |
750 | } |
751 | |
752 | AddressType GetAddressTypeOfChildren(); |
753 | |
754 | void SetHasCompleteType() { |
755 | m_flags.m_did_calculate_complete_objc_class_type = true; |
756 | } |
757 | |
758 | /// Find out if a ValueObject might have children. |
759 | /// |
760 | /// This call is much more efficient than CalculateNumChildren() as |
761 | /// it doesn't need to complete the underlying type. This is designed |
762 | /// to be used in a UI environment in order to detect if the |
763 | /// disclosure triangle should be displayed or not. |
764 | /// |
765 | /// This function returns true for class, union, structure, |
766 | /// pointers, references, arrays and more. Again, it does so without |
767 | /// doing any expensive type completion. |
768 | /// |
769 | /// \return |
770 | /// Returns \b true if the ValueObject might have children, or \b |
771 | /// false otherwise. |
772 | virtual bool MightHaveChildren(); |
773 | |
774 | virtual lldb::VariableSP GetVariable() { return nullptr; } |
775 | |
776 | virtual bool IsRuntimeSupportValue(); |
777 | |
778 | virtual uint64_t GetLanguageFlags() { return m_language_flags; } |
779 | |
780 | virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; } |
781 | |
782 | protected: |
783 | typedef ClusterManager<ValueObject> ValueObjectManager; |
784 | |
785 | class ChildrenManager { |
786 | public: |
787 | ChildrenManager() = default; |
788 | |
789 | bool HasChildAtIndex(size_t idx) { |
790 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
791 | return (m_children.find(x: idx) != m_children.end()); |
792 | } |
793 | |
794 | ValueObject *GetChildAtIndex(size_t idx) { |
795 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
796 | const auto iter = m_children.find(x: idx); |
797 | return ((iter == m_children.end()) ? nullptr : iter->second); |
798 | } |
799 | |
800 | void SetChildAtIndex(size_t idx, ValueObject *valobj) { |
801 | // we do not need to be mutex-protected to make a pair |
802 | ChildrenPair pair(idx, valobj); |
803 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
804 | m_children.insert(x&: pair); |
805 | } |
806 | |
807 | void SetChildrenCount(size_t count) { Clear(new_count: count); } |
808 | |
809 | size_t GetChildrenCount() { return m_children_count; } |
810 | |
811 | void Clear(size_t new_count = 0) { |
812 | std::lock_guard<std::recursive_mutex> guard(m_mutex); |
813 | m_children_count = new_count; |
814 | m_children.clear(); |
815 | } |
816 | |
817 | private: |
818 | typedef std::map<size_t, ValueObject *> ChildrenMap; |
819 | typedef ChildrenMap::iterator ChildrenIterator; |
820 | typedef ChildrenMap::value_type ChildrenPair; |
821 | std::recursive_mutex m_mutex; |
822 | ChildrenMap m_children; |
823 | size_t m_children_count = 0; |
824 | }; |
825 | |
826 | // Classes that inherit from ValueObject can see and modify these |
827 | |
828 | /// The parent value object, or nullptr if this has no parent. |
829 | ValueObject *m_parent = nullptr; |
830 | /// The root of the hierarchy for this ValueObject (or nullptr if never |
831 | /// calculated). |
832 | ValueObject *m_root = nullptr; |
833 | /// Stores both the stop id and the full context at which this value was last |
834 | /// updated. When we are asked to update the value object, we check whether |
835 | /// the context & stop id are the same before updating. |
836 | EvaluationPoint m_update_point; |
837 | /// The name of this object. |
838 | ConstString m_name; |
839 | /// A data extractor that can be used to extract the value. |
840 | DataExtractor m_data; |
841 | Value m_value; |
842 | /// An error object that can describe any errors that occur when updating |
843 | /// values. |
844 | Status m_error; |
845 | /// Cached value string that will get cleared if/when the value is updated. |
846 | std::string m_value_str; |
847 | /// Cached old value string from the last time the value was gotten |
848 | std::string m_old_value_str; |
849 | /// Cached location string that will get cleared if/when the value is updated. |
850 | std::string m_location_str; |
851 | /// Cached summary string that will get cleared if/when the value is updated. |
852 | std::string m_summary_str; |
853 | /// Cached result of the "object printer". This differs from the summary |
854 | /// in that the summary is consed up by us, the object_desc_string is builtin. |
855 | std::string m_object_desc_str; |
856 | /// If the type of the value object should be overridden, the type to impose. |
857 | CompilerType m_override_type; |
858 | |
859 | /// This object is managed by the root object (any ValueObject that gets |
860 | /// created without a parent.) The manager gets passed through all the |
861 | /// generations of dependent objects, and will keep the whole cluster of |
862 | /// objects alive as long as a shared pointer to any of them has been handed |
863 | /// out. Shared pointers to value objects must always be made with the GetSP |
864 | /// method. |
865 | ValueObjectManager *m_manager = nullptr; |
866 | |
867 | ChildrenManager m_children; |
868 | std::map<ConstString, ValueObject *> m_synthetic_children; |
869 | |
870 | ValueObject *m_dynamic_value = nullptr; |
871 | ValueObject *m_synthetic_value = nullptr; |
872 | ValueObject *m_deref_valobj = nullptr; |
873 | |
874 | /// We have to hold onto a shared pointer to this one because it is created |
875 | /// as an independent ValueObjectConstResult, which isn't managed by us. |
876 | lldb::ValueObjectSP m_addr_of_valobj_sp; |
877 | |
878 | lldb::Format m_format = lldb::eFormatDefault; |
879 | lldb::Format m_last_format = lldb::eFormatDefault; |
880 | uint32_t m_last_format_mgr_revision = 0; |
881 | lldb::TypeSummaryImplSP m_type_summary_sp; |
882 | lldb::TypeFormatImplSP m_type_format_sp; |
883 | lldb::SyntheticChildrenSP m_synthetic_children_sp; |
884 | ProcessModID m_user_id_of_forced_summary; |
885 | AddressType m_address_type_of_ptr_or_ref_children = eAddressTypeInvalid; |
886 | |
887 | llvm::SmallVector<uint8_t, 16> m_value_checksum; |
888 | |
889 | lldb::LanguageType m_preferred_display_language = lldb::eLanguageTypeUnknown; |
890 | |
891 | uint64_t m_language_flags = 0; |
892 | |
893 | /// Unique identifier for every value object. |
894 | UserID m_id; |
895 | |
896 | // Utility class for initializing all bitfields in ValueObject's constructors. |
897 | // FIXME: This could be done via default initializers once we have C++20. |
898 | struct Bitflags { |
899 | bool m_value_is_valid : 1, m_value_did_change : 1, |
900 | m_children_count_valid : 1, m_old_value_valid : 1, |
901 | m_is_deref_of_parent : 1, m_is_array_item_for_pointer : 1, |
902 | m_is_bitfield_for_scalar : 1, m_is_child_at_offset : 1, |
903 | m_is_getting_summary : 1, m_did_calculate_complete_objc_class_type : 1, |
904 | m_is_synthetic_children_generated : 1; |
905 | Bitflags() { |
906 | m_value_is_valid = false; |
907 | m_value_did_change = false; |
908 | m_children_count_valid = false; |
909 | m_old_value_valid = false; |
910 | m_is_deref_of_parent = false; |
911 | m_is_array_item_for_pointer = false; |
912 | m_is_bitfield_for_scalar = false; |
913 | m_is_child_at_offset = false; |
914 | m_is_getting_summary = false; |
915 | m_did_calculate_complete_objc_class_type = false; |
916 | m_is_synthetic_children_generated = false; |
917 | } |
918 | } m_flags; |
919 | |
920 | friend class ValueObjectChild; |
921 | friend class ExpressionVariable; // For SetName |
922 | friend class Target; // For SetName |
923 | friend class ValueObjectConstResultImpl; |
924 | friend class ValueObjectSynthetic; // For ClearUserVisibleData |
925 | |
926 | /// Use this constructor to create a "root variable object". The ValueObject |
927 | /// will be locked to this context through-out its lifespan. |
928 | ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager, |
929 | AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad); |
930 | |
931 | /// Use this constructor to create a ValueObject owned by another ValueObject. |
932 | /// It will inherit the ExecutionContext of its parent. |
933 | ValueObject(ValueObject &parent); |
934 | |
935 | ValueObjectManager *GetManager() { return m_manager; } |
936 | |
937 | virtual bool UpdateValue() = 0; |
938 | |
939 | virtual LazyBool CanUpdateWithInvalidExecutionContext() { |
940 | return eLazyBoolCalculate; |
941 | } |
942 | |
943 | virtual void CalculateDynamicValue(lldb::DynamicValueType use_dynamic); |
944 | |
945 | virtual lldb::DynamicValueType GetDynamicValueTypeImpl() { |
946 | return lldb::eNoDynamicValues; |
947 | } |
948 | |
949 | virtual bool HasDynamicValueTypeInfo() { return false; } |
950 | |
951 | virtual void CalculateSyntheticValue(); |
952 | |
953 | /// Should only be called by ValueObject::GetChildAtIndex(). |
954 | /// |
955 | /// \return A ValueObject managed by this ValueObject's manager. |
956 | virtual ValueObject *CreateChildAtIndex(size_t idx, |
957 | bool synthetic_array_member, |
958 | int32_t synthetic_index); |
959 | |
960 | /// Should only be called by ValueObject::GetNumChildren(). |
961 | virtual size_t CalculateNumChildren(uint32_t max = UINT32_MAX) = 0; |
962 | |
963 | void SetNumChildren(size_t num_children); |
964 | |
965 | void SetValueDidChange(bool value_changed) { |
966 | m_flags.m_value_did_change = value_changed; |
967 | } |
968 | |
969 | void SetValueIsValid(bool valid) { m_flags.m_value_is_valid = valid; } |
970 | |
971 | void ClearUserVisibleData( |
972 | uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings); |
973 | |
974 | void AddSyntheticChild(ConstString key, ValueObject *valobj); |
975 | |
976 | DataExtractor &(); |
977 | |
978 | void ClearDynamicTypeInformation(); |
979 | |
980 | // Subclasses must implement the functions below. |
981 | |
982 | virtual CompilerType GetCompilerTypeImpl() = 0; |
983 | |
984 | const char *(const Value &value, |
985 | const DataExtractor &data); |
986 | |
987 | bool IsChecksumEmpty() { return m_value_checksum.empty(); } |
988 | |
989 | void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType); |
990 | |
991 | protected: |
992 | virtual void DoUpdateChildrenAddressType(ValueObject &valobj){}; |
993 | |
994 | private: |
995 | virtual CompilerType MaybeCalculateCompleteType(); |
996 | void UpdateChildrenAddressType() { |
997 | GetRoot()->DoUpdateChildrenAddressType(valobj&: *this); |
998 | } |
999 | |
1000 | lldb::ValueObjectSP GetValueForExpressionPath_Impl( |
1001 | llvm::StringRef expression_cstr, |
1002 | ExpressionPathScanEndReason *reason_to_stop, |
1003 | ExpressionPathEndResultType *final_value_type, |
1004 | const GetValueForExpressionPathOptions &options, |
1005 | ExpressionPathAftermath *final_task_on_target); |
1006 | |
1007 | ValueObject(const ValueObject &) = delete; |
1008 | const ValueObject &operator=(const ValueObject &) = delete; |
1009 | }; |
1010 | |
1011 | } // namespace lldb_private |
1012 | |
1013 | #endif // LLDB_CORE_VALUEOBJECT_H |
1014 | |