1 //===-- LibStdcpp.cpp ---------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "LibStdcpp.h" 11 12 #include "lldb/Core/DataBufferHeap.h" 13 #include "lldb/Core/Error.h" 14 #include "lldb/Core/Stream.h" 15 #include "lldb/Core/ValueObject.h" 16 #include "lldb/Core/ValueObjectConstResult.h" 17 #include "lldb/DataFormatters/VectorIterator.h" 18 #include "lldb/Host/Endian.h" 19 #include "lldb/Symbol/ClangASTContext.h" 20 #include "lldb/Target/Target.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 using namespace lldb_private::formatters; 25 26 class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd 27 { 28 public: 29 LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp); 30 31 size_t 32 CalculateNumChildren() override; 33 34 lldb::ValueObjectSP 35 GetChildAtIndex(size_t idx) override; 36 37 bool 38 Update() override; 39 40 bool 41 MightHaveChildren() override; 42 43 size_t 44 GetIndexOfChildWithName (const ConstString &name) override; 45 46 ~LibstdcppMapIteratorSyntheticFrontEnd() override; 47 48 private: 49 ExecutionContextRef m_exe_ctx_ref; 50 lldb::addr_t m_pair_address; 51 CompilerType m_pair_type; 52 EvaluateExpressionOptions m_options; 53 lldb::ValueObjectSP m_pair_sp; 54 }; 55 56 /* 57 (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = { 58 (_Base_ptr) _M_node = 0x0000000100103910 { 59 (std::_Rb_tree_color) _M_color = _S_black 60 (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0 61 (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000 62 (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000 63 } 64 } 65 */ 66 67 LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) : 68 SyntheticChildrenFrontEnd(*valobj_sp.get()), 69 m_exe_ctx_ref(), 70 m_pair_address(0), 71 m_pair_type(), 72 m_options(), 73 m_pair_sp() 74 { 75 if (valobj_sp) 76 Update(); 77 m_options.SetCoerceToId(false); 78 m_options.SetUnwindOnError(true); 79 m_options.SetKeepInMemory(true); 80 m_options.SetUseDynamic(lldb::eDynamicCanRunTarget); 81 } 82 83 bool 84 LibstdcppMapIteratorSyntheticFrontEnd::Update() 85 { 86 ValueObjectSP valobj_sp = m_backend.GetSP(); 87 if (!valobj_sp) 88 return false; 89 90 TargetSP target_sp(valobj_sp->GetTargetSP()); 91 92 if (!target_sp) 93 return false; 94 95 bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8); 96 97 if (!valobj_sp) 98 return false; 99 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 100 101 ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true)); 102 if (!_M_node_sp) 103 return false; 104 105 m_pair_address = _M_node_sp->GetValueAsUnsigned(0); 106 if (m_pair_address == 0) 107 return false; 108 109 m_pair_address += (is_64bit ? 32 : 16); 110 111 CompilerType my_type(valobj_sp->GetCompilerType()); 112 if (my_type.GetNumTemplateArguments() >= 1) 113 { 114 TemplateArgumentKind kind; 115 CompilerType pair_type = my_type.GetTemplateArgument(0, kind); 116 if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion) 117 return false; 118 m_pair_type = pair_type; 119 } 120 else 121 return false; 122 123 return true; 124 } 125 126 size_t 127 LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren () 128 { 129 return 2; 130 } 131 132 lldb::ValueObjectSP 133 LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) 134 { 135 if (m_pair_address != 0 && m_pair_type) 136 { 137 if (!m_pair_sp) 138 m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type); 139 if (m_pair_sp) 140 return m_pair_sp->GetChildAtIndex(idx, true); 141 } 142 return lldb::ValueObjectSP(); 143 } 144 145 bool 146 LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren () 147 { 148 return true; 149 } 150 151 size_t 152 LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 153 { 154 if (name == ConstString("first")) 155 return 0; 156 if (name == ConstString("second")) 157 return 1; 158 return UINT32_MAX; 159 } 160 161 LibstdcppMapIteratorSyntheticFrontEnd::~LibstdcppMapIteratorSyntheticFrontEnd () 162 {} 163 164 SyntheticChildrenFrontEnd* 165 lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 166 { 167 if (!valobj_sp) 168 return NULL; 169 return (new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp)); 170 } 171 172 /* 173 (lldb) fr var ibeg --ptr-depth 1 174 (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >) ibeg = { 175 _M_current = 0x00000001001037a0 { 176 *_M_current = 1 177 } 178 } 179 */ 180 181 SyntheticChildrenFrontEnd* 182 lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp) 183 { 184 static ConstString g_item_name; 185 if (!g_item_name) 186 g_item_name.SetCString("_M_current"); 187 if (!valobj_sp) 188 return NULL; 189 return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name)); 190 } 191 192 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp, 193 ConstString item_name) : 194 SyntheticChildrenFrontEnd(*valobj_sp.get()), 195 m_exe_ctx_ref(), 196 m_item_name(item_name), 197 m_item_sp() 198 { 199 if (valobj_sp) 200 Update(); 201 } 202 203 bool 204 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::Update() 205 { 206 m_item_sp.reset(); 207 208 ValueObjectSP valobj_sp = m_backend.GetSP(); 209 if (!valobj_sp) 210 return false; 211 212 if (!valobj_sp) 213 return false; 214 215 ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name,true)); 216 if (!item_ptr) 217 return false; 218 if (item_ptr->GetValueAsUnsigned(0) == 0) 219 return false; 220 Error err; 221 m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); 222 m_item_sp = CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, item_ptr->GetCompilerType().GetPointeeType()); 223 if (err.Fail()) 224 m_item_sp.reset(); 225 return false; 226 } 227 228 size_t 229 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::CalculateNumChildren () 230 { 231 return 1; 232 } 233 234 lldb::ValueObjectSP 235 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx) 236 { 237 if (idx == 0) 238 return m_item_sp; 239 return lldb::ValueObjectSP(); 240 } 241 242 bool 243 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::MightHaveChildren () 244 { 245 return true; 246 } 247 248 size_t 249 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name) 250 { 251 if (name == ConstString("item")) 252 return 0; 253 return UINT32_MAX; 254 } 255 256 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::~VectorIteratorSyntheticFrontEnd () 257 { 258 } 259