1 //===-- ValueObjectSyntheticFilter.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_VALUEOBJECTSYNTHETICFILTER_H 10 #define LLDB_CORE_VALUEOBJECTSYNTHETICFILTER_H 11 12 #include "lldb/Core/ValueObject.h" 13 #include "lldb/Symbol/CompilerType.h" 14 #include "lldb/Utility/ConstString.h" 15 #include "lldb/lldb-defines.h" 16 #include "lldb/lldb-enumerations.h" 17 #include "lldb/lldb-forward.h" 18 #include "lldb/lldb-private-enumerations.h" 19 20 #include <cstdint> 21 #include <memory> 22 #include <optional> 23 24 #include <cstddef> 25 26 namespace lldb_private { 27 class Declaration; 28 class Status; 29 class SyntheticChildrenFrontEnd; 30 31 /// A ValueObject that obtains its children from some source other than 32 /// real information. 33 /// This is currently used to implement Python-based children and filters but 34 /// you can bind it to any source of synthetic information and have it behave 35 /// accordingly. 36 class ValueObjectSynthetic : public ValueObject { 37 public: 38 ~ValueObjectSynthetic() override; 39 40 std::optional<uint64_t> GetByteSize() override; 41 42 ConstString GetTypeName() override; 43 44 ConstString GetQualifiedTypeName() override; 45 46 ConstString GetDisplayTypeName() override; 47 48 bool MightHaveChildren() override; 49 50 llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override; 51 52 lldb::ValueType GetValueType() const override; 53 54 lldb::ValueObjectSP GetChildAtIndex(uint32_t idx, 55 bool can_create = true) override; 56 57 lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name, 58 bool can_create = true) override; 59 60 size_t GetIndexOfChildWithName(llvm::StringRef name) override; 61 62 lldb::ValueObjectSP 63 GetDynamicValue(lldb::DynamicValueType valueType) override; 64 65 bool IsInScope() override; 66 HasSyntheticValue()67 bool HasSyntheticValue() override { return false; } 68 IsSynthetic()69 bool IsSynthetic() override { return true; } 70 CalculateSyntheticValue()71 void CalculateSyntheticValue() override {} 72 IsDynamic()73 bool IsDynamic() override { 74 return ((m_parent != nullptr) ? m_parent->IsDynamic() : false); 75 } 76 GetStaticValue()77 lldb::ValueObjectSP GetStaticValue() override { 78 return ((m_parent != nullptr) ? m_parent->GetStaticValue() : GetSP()); 79 } 80 GetDynamicValueType()81 virtual lldb::DynamicValueType GetDynamicValueType() { 82 return ((m_parent != nullptr) ? m_parent->GetDynamicValueType() 83 : lldb::eNoDynamicValues); 84 } 85 GetVariable()86 lldb::VariableSP GetVariable() override { 87 return m_parent != nullptr ? m_parent->GetVariable() : nullptr; 88 } 89 GetParent()90 ValueObject *GetParent() override { 91 return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr); 92 } 93 GetParent()94 const ValueObject *GetParent() const override { 95 return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr); 96 } 97 98 lldb::ValueObjectSP GetNonSyntheticValue() override; 99 100 bool CanProvideValue() override; 101 DoesProvideSyntheticValue()102 bool DoesProvideSyntheticValue() override { 103 return (UpdateValueIfNeeded(), m_provides_value == eLazyBoolYes); 104 } 105 GetIsConstant()106 bool GetIsConstant() const override { return false; } 107 108 bool SetValueFromCString(const char *value_str, Status &error) override; 109 110 void SetFormat(lldb::Format format) override; 111 112 lldb::LanguageType GetPreferredDisplayLanguage() override; 113 114 void SetPreferredDisplayLanguage(lldb::LanguageType); 115 116 bool IsSyntheticChildrenGenerated() override; 117 118 void SetSyntheticChildrenGenerated(bool b) override; 119 120 bool GetDeclaration(Declaration &decl) override; 121 122 uint64_t GetLanguageFlags() override; 123 124 void SetLanguageFlags(uint64_t flags) override; 125 126 protected: 127 bool UpdateValue() override; 128 CanUpdateWithInvalidExecutionContext()129 LazyBool CanUpdateWithInvalidExecutionContext() override { 130 return eLazyBoolYes; 131 } 132 133 CompilerType GetCompilerTypeImpl() override; 134 135 virtual void CreateSynthFilter(); 136 137 // we need to hold on to the SyntheticChildren because someone might delete 138 // the type binding while we are alive 139 lldb::SyntheticChildrenSP m_synth_sp; 140 std::unique_ptr<SyntheticChildrenFrontEnd> m_synth_filter_up; 141 142 typedef std::map<uint32_t, ValueObject *> ByIndexMap; 143 typedef std::map<const char *, uint32_t> NameToIndexMap; 144 typedef std::vector<lldb::ValueObjectSP> SyntheticChildrenCache; 145 146 typedef ByIndexMap::iterator ByIndexIterator; 147 typedef NameToIndexMap::iterator NameToIndexIterator; 148 149 std::mutex m_child_mutex; 150 /// Guarded by m_child_mutex; 151 ByIndexMap m_children_byindex; 152 /// Guarded by m_child_mutex; 153 NameToIndexMap m_name_toindex; 154 /// Guarded by m_child_mutex; 155 SyntheticChildrenCache m_synthetic_children_cache; 156 157 // FIXME: use the ValueObject's ChildrenManager instead of a special purpose 158 // solution. 159 uint32_t m_synthetic_children_count; 160 161 ConstString m_parent_type_name; 162 163 LazyBool m_might_have_children; 164 165 LazyBool m_provides_value; 166 167 private: 168 friend class ValueObject; 169 ValueObjectSynthetic(ValueObject &parent, lldb::SyntheticChildrenSP filter); 170 171 void CopyValueData(ValueObject *source); 172 173 ValueObjectSynthetic(const ValueObjectSynthetic &) = delete; 174 const ValueObjectSynthetic &operator=(const ValueObjectSynthetic &) = delete; 175 }; 176 177 } // namespace lldb_private 178 179 #endif // LLDB_CORE_VALUEOBJECTSYNTHETICFILTER_H 180