SBValue.cpp revision e179a5840a49167964ca768a13c252c58c9cffcc
1//===-- SBValue.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 "lldb/API/SBValue.h" 11#include "lldb/API/SBStream.h" 12 13#include "lldb/Core/DataExtractor.h" 14#include "lldb/Core/Log.h" 15#include "lldb/Core/Module.h" 16#include "lldb/Core/Stream.h" 17#include "lldb/Core/StreamFile.h" 18#include "lldb/Core/Value.h" 19#include "lldb/Core/ValueObject.h" 20#include "lldb/Symbol/Block.h" 21#include "lldb/Symbol/ObjectFile.h" 22#include "lldb/Symbol/Variable.h" 23#include "lldb/Target/ExecutionContext.h" 24#include "lldb/Target/Process.h" 25#include "lldb/Target/StackFrame.h" 26#include "lldb/Target/Target.h" 27#include "lldb/Target/Thread.h" 28 29#include "lldb/API/SBProcess.h" 30#include "lldb/API/SBTarget.h" 31#include "lldb/API/SBThread.h" 32#include "lldb/API/SBFrame.h" 33#include "lldb/API/SBDebugger.h" 34 35using namespace lldb; 36using namespace lldb_private; 37 38SBValue::SBValue () : 39 m_opaque_sp () 40{ 41} 42 43SBValue::SBValue (const lldb::ValueObjectSP &value_sp) : 44 m_opaque_sp (value_sp) 45{ 46} 47 48SBValue::SBValue(const SBValue &rhs) : 49 m_opaque_sp (rhs.m_opaque_sp) 50{ 51} 52 53const SBValue & 54SBValue::operator = (const SBValue &rhs) 55{ 56 if (this != &rhs) 57 m_opaque_sp = rhs.m_opaque_sp; 58 return *this; 59} 60 61SBValue::~SBValue() 62{ 63} 64 65bool 66SBValue::IsValid () const 67{ 68 // If this function ever changes to anything that does more than just 69 // check if the opaque shared pointer is non NULL, then we need to update 70 // all "if (m_opaque_sp)" code in this file. 71 return m_opaque_sp.get() != NULL; 72} 73 74SBError 75SBValue::GetError() 76{ 77 SBError sb_error; 78 79 if (m_opaque_sp.get()) 80 sb_error.SetError(m_opaque_sp->GetError()); 81 82 return sb_error; 83} 84 85const char * 86SBValue::GetName() 87{ 88 89 const char *name = NULL; 90 if (m_opaque_sp) 91 name = m_opaque_sp->GetName().GetCString(); 92 93 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 94 if (log) 95 { 96 if (name) 97 log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name); 98 else 99 log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get(), name); 100 } 101 102 return name; 103} 104 105const char * 106SBValue::GetTypeName () 107{ 108 const char *name = NULL; 109 if (m_opaque_sp) 110 name = m_opaque_sp->GetTypeName().GetCString(); 111 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 112 if (log) 113 { 114 if (name) 115 log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name); 116 else 117 log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get()); 118 } 119 120 return name; 121} 122 123size_t 124SBValue::GetByteSize () 125{ 126 size_t result = 0; 127 128 if (m_opaque_sp) 129 result = m_opaque_sp->GetByteSize(); 130 131 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 132 if (log) 133 log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result); 134 135 return result; 136} 137 138bool 139SBValue::IsInScope (const SBFrame &sb_frame) 140{ 141 bool result = false; 142 143 if (m_opaque_sp) 144 { 145 StackFrame *frame = sb_frame.get(); 146 if (frame) 147 { 148 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 149 result = m_opaque_sp->IsInScope (frame); 150 } 151 } 152 153 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 154 if (log) 155 log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result); 156 157 return result; 158} 159 160const char * 161SBValue::GetValue (const SBFrame &sb_frame) 162{ 163 const char *cstr = NULL; 164 if (m_opaque_sp) 165 { 166 StackFrame *frame = sb_frame.get(); 167 if (frame) 168 { 169 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 170 cstr = m_opaque_sp->GetValueAsCString (frame); 171 } 172 } 173 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 174 if (log) 175 { 176 if (cstr) 177 log->Printf ("SBValue(%p)::GetValue (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr); 178 else 179 log->Printf ("SBValue(%p)::GetValue (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get()); 180 } 181 182 return cstr; 183} 184 185ValueType 186SBValue::GetValueType () 187{ 188 ValueType result = eValueTypeInvalid; 189 if (m_opaque_sp) 190 result = m_opaque_sp->GetValueType(); 191 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 192 if (log) 193 { 194 switch (result) 195 { 196 case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break; 197 case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break; 198 case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break; 199 case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break; 200 case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break; 201 case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break; 202 case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break; 203 case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break; 204 default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break; 205 } 206 } 207 return result; 208} 209 210const char * 211SBValue::GetObjectDescription (const SBFrame &sb_frame) 212{ 213 const char *cstr = NULL; 214 if ( m_opaque_sp) 215 { 216 StackFrame *frame = sb_frame.get(); 217 if (frame) 218 { 219 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 220 cstr = m_opaque_sp->GetObjectDescription (frame); 221 } 222 } 223 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 224 if (log) 225 { 226 if (cstr) 227 log->Printf ("SBValue(%p)::GetObjectDescription (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr); 228 else 229 log->Printf ("SBValue(%p)::GetObjectDescription (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get()); 230 } 231 return cstr; 232} 233 234bool 235SBValue::GetValueDidChange (const SBFrame &sb_frame) 236{ 237 bool result = false; 238 if (m_opaque_sp) 239 { 240 StackFrame *frame = sb_frame.get(); 241 if (frame) 242 { 243 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 244 result = m_opaque_sp->GetValueDidChange (frame); 245 } 246 } 247 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 248 if (log) 249 log->Printf ("SBValue(%p)::GetValueDidChange (SBFrame(%p)) => %i", m_opaque_sp.get(), sb_frame.get(), result); 250 251 return result; 252} 253 254const char * 255SBValue::GetSummary (const SBFrame &sb_frame) 256{ 257 const char *cstr = NULL; 258 if (m_opaque_sp) 259 { 260 StackFrame *frame = sb_frame.get(); 261 if (frame) 262 { 263 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 264 cstr = m_opaque_sp->GetSummaryAsCString(frame); 265 } 266 } 267 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 268 if (log) 269 { 270 if (cstr) 271 log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr); 272 else 273 log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get()); 274 } 275 return cstr; 276} 277 278const char * 279SBValue::GetLocation (const SBFrame &sb_frame) 280{ 281 const char *cstr = NULL; 282 if (m_opaque_sp) 283 { 284 StackFrame *frame = sb_frame.get(); 285 if (frame) 286 { 287 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 288 cstr = m_opaque_sp->GetLocationAsCString(frame); 289 } 290 } 291 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 292 if (log) 293 { 294 if (cstr) 295 log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr); 296 else 297 log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get()); 298 } 299 return cstr; 300} 301 302bool 303SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str) 304{ 305 bool success = false; 306 if (m_opaque_sp) 307 { 308 StackFrame *frame = sb_frame.get(); 309 if (frame) 310 { 311 Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex()); 312 success = m_opaque_sp->SetValueFromCString (frame, value_str); 313 } 314 } 315 return success; 316} 317 318SBValue 319SBValue::GetChildAtIndex (uint32_t idx) 320{ 321 lldb::ValueObjectSP child_sp; 322 323 if (m_opaque_sp) 324 { 325 child_sp = m_opaque_sp->GetChildAtIndex (idx, true); 326 } 327 328 SBValue sb_value (child_sp); 329 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 330 if (log) 331 log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); 332 333 return sb_value; 334} 335 336uint32_t 337SBValue::GetIndexOfChildWithName (const char *name) 338{ 339 uint32_t idx = UINT32_MAX; 340 if (m_opaque_sp) 341 idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); 342 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 343 if (log) 344 { 345 if (idx == UINT32_MAX) 346 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx); 347 else 348 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); 349 } 350 return idx; 351} 352 353SBValue 354SBValue::GetChildMemberWithName (const char *name) 355{ 356 lldb::ValueObjectSP child_sp; 357 const ConstString str_name (name); 358 359 if (m_opaque_sp) 360 { 361 child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); 362 } 363 364 SBValue sb_value (child_sp); 365 366 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 367 if (log) 368 log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); 369 370 return sb_value; 371} 372 373 374uint32_t 375SBValue::GetNumChildren () 376{ 377 uint32_t num_children = 0; 378 379 if (m_opaque_sp) 380 num_children = m_opaque_sp->GetNumChildren(); 381 382 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 383 if (log) 384 log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); 385 386 return num_children; 387} 388 389 390SBValue 391SBValue::Dereference () 392{ 393 SBValue sb_value; 394 if (m_opaque_sp) 395 { 396 Error error; 397 sb_value = m_opaque_sp->Dereference (error); 398 } 399 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 400 if (log) 401 log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 402 403 return sb_value; 404} 405 406bool 407SBValue::TypeIsPointerType () 408{ 409 bool is_ptr_type = false; 410 411 if (m_opaque_sp) 412 is_ptr_type = m_opaque_sp->IsPointerType(); 413 414 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 415 if (log) 416 log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); 417 418 419 return is_ptr_type; 420} 421 422void * 423SBValue::GetOpaqueType() 424{ 425 if (m_opaque_sp) 426 return m_opaque_sp->GetClangType(); 427 return NULL; 428} 429 430// Mimic shared pointer... 431lldb_private::ValueObject * 432SBValue::get() const 433{ 434 return m_opaque_sp.get(); 435} 436 437lldb_private::ValueObject * 438SBValue::operator->() const 439{ 440 return m_opaque_sp.get(); 441} 442 443lldb::ValueObjectSP & 444SBValue::operator*() 445{ 446 return m_opaque_sp; 447} 448 449const lldb::ValueObjectSP & 450SBValue::operator*() const 451{ 452 return m_opaque_sp; 453} 454 455bool 456SBValue::GetExpressionPath (SBStream &description) 457{ 458 if (m_opaque_sp) 459 { 460 m_opaque_sp->GetExpressionPath (description.ref()); 461 return true; 462 } 463 return false; 464} 465 466bool 467SBValue::GetDescription (SBStream &description) 468{ 469 if (m_opaque_sp) 470 { 471 // Don't call all these APIs and cause more logging! 472// const char *name = GetName(); 473// const char *type_name = GetTypeName (); 474// size_t byte_size = GetByteSize (); 475// uint32_t num_children = GetNumChildren (); 476// bool is_stale = ValueIsStale (); 477// description.Printf ("name: '%s', type: %s, size: %d", (name != NULL ? name : "<unknown name>"), 478// (type_name != NULL ? type_name : "<unknown type name>"), (int) byte_size); 479// if (num_children > 0) 480// description.Printf (", num_children: %d", num_children); 481// 482// if (is_stale) 483// description.Printf (" [value is stale]"); 484 485 description.Printf ("name: '%s'", m_opaque_sp->GetName().GetCString()); 486 } 487 else 488 description.Printf ("No value"); 489 490 return true; 491} 492 493lldb::Format 494SBValue::GetFormat () const 495{ 496 if (m_opaque_sp) 497 return m_opaque_sp->GetFormat(); 498 return eFormatDefault; 499} 500 501void 502SBValue::SetFormat (lldb::Format format) 503{ 504 if (m_opaque_sp) 505 m_opaque_sp->SetFormat(format); 506} 507 508