SBValue.cpp revision daa6efe771f5f068e29328a774fa5bf2358ce14a
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/Breakpoint/Watchpoint.h" 14#include "lldb/Core/DataExtractor.h" 15#include "lldb/Core/Log.h" 16#include "lldb/Core/Module.h" 17#include "lldb/Core/Scalar.h" 18#include "lldb/Core/Stream.h" 19#include "lldb/Core/StreamFile.h" 20#include "lldb/Core/Value.h" 21#include "lldb/Core/ValueObject.h" 22#include "lldb/Core/ValueObjectConstResult.h" 23#include "lldb/Symbol/Block.h" 24#include "lldb/Symbol/ObjectFile.h" 25#include "lldb/Symbol/Variable.h" 26#include "lldb/Symbol/VariableList.h" 27#include "lldb/Target/ExecutionContext.h" 28#include "lldb/Target/Process.h" 29#include "lldb/Target/StackFrame.h" 30#include "lldb/Target/Target.h" 31#include "lldb/Target/Thread.h" 32 33#include "lldb/API/SBProcess.h" 34#include "lldb/API/SBTarget.h" 35#include "lldb/API/SBThread.h" 36#include "lldb/API/SBFrame.h" 37#include "lldb/API/SBDebugger.h" 38 39using namespace lldb; 40using namespace lldb_private; 41 42SBValue::SBValue () : 43 m_opaque_sp () 44{ 45} 46 47SBValue::SBValue (const lldb::ValueObjectSP &value_sp) : 48 m_opaque_sp (value_sp) 49{ 50} 51 52SBValue::SBValue(const SBValue &rhs) : 53 m_opaque_sp (rhs.m_opaque_sp) 54{ 55} 56 57SBValue & 58SBValue::operator = (const SBValue &rhs) 59{ 60 if (this != &rhs) 61 m_opaque_sp = rhs.m_opaque_sp; 62 return *this; 63} 64 65SBValue::~SBValue() 66{ 67} 68 69bool 70SBValue::IsValid () 71{ 72 // If this function ever changes to anything that does more than just 73 // check if the opaque shared pointer is non NULL, then we need to update 74 // all "if (m_opaque_sp)" code in this file. 75 return m_opaque_sp.get() != NULL; 76} 77 78void 79SBValue::Clear() 80{ 81 m_opaque_sp.reset(); 82} 83 84SBError 85SBValue::GetError() 86{ 87 SBError sb_error; 88 89 if (m_opaque_sp.get()) 90 sb_error.SetError(m_opaque_sp->GetError()); 91 92 return sb_error; 93} 94 95user_id_t 96SBValue::GetID() 97{ 98 if (m_opaque_sp) 99 return m_opaque_sp->GetID(); 100 return LLDB_INVALID_UID; 101} 102 103const char * 104SBValue::GetName() 105{ 106 107 const char *name = NULL; 108 if (m_opaque_sp) 109 name = m_opaque_sp->GetName().GetCString(); 110 111 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 112 if (log) 113 { 114 if (name) 115 log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name); 116 else 117 log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get()); 118 } 119 120 return name; 121} 122 123const char * 124SBValue::GetTypeName () 125{ 126 const char *name = NULL; 127 if (m_opaque_sp) 128 name = m_opaque_sp->GetTypeName().GetCString(); 129 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 130 if (log) 131 { 132 if (name) 133 log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name); 134 else 135 log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get()); 136 } 137 138 return name; 139} 140 141size_t 142SBValue::GetByteSize () 143{ 144 size_t result = 0; 145 146 if (m_opaque_sp) 147 result = m_opaque_sp->GetByteSize(); 148 149 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 150 if (log) 151 log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result); 152 153 return result; 154} 155 156bool 157SBValue::IsInScope () 158{ 159 bool result = false; 160 161 if (m_opaque_sp) 162 { 163 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 164 { 165 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 166 result = m_opaque_sp->IsInScope (); 167 } 168 } 169 170 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 171 if (log) 172 log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result); 173 174 return result; 175} 176 177const char * 178SBValue::GetValue () 179{ 180 const char *cstr = NULL; 181 if (m_opaque_sp) 182 { 183 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 184 { 185 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 186 cstr = m_opaque_sp->GetValueAsCString (); 187 } 188 } 189 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 190 if (log) 191 { 192 if (cstr) 193 log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr); 194 else 195 log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get()); 196 } 197 198 return cstr; 199} 200 201ValueType 202SBValue::GetValueType () 203{ 204 ValueType result = eValueTypeInvalid; 205 if (m_opaque_sp) 206 result = m_opaque_sp->GetValueType(); 207 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 208 if (log) 209 { 210 switch (result) 211 { 212 case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break; 213 case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break; 214 case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break; 215 case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break; 216 case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break; 217 case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break; 218 case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break; 219 case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break; 220 default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break; 221 } 222 } 223 return result; 224} 225 226const char * 227SBValue::GetObjectDescription () 228{ 229 const char *cstr = NULL; 230 if (m_opaque_sp) 231 { 232 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 233 { 234 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 235 cstr = m_opaque_sp->GetObjectDescription (); 236 } 237 } 238 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 239 if (log) 240 { 241 if (cstr) 242 log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr); 243 else 244 log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get()); 245 } 246 return cstr; 247} 248 249SBType 250SBValue::GetType() 251{ 252 SBType result; 253 if (m_opaque_sp) 254 { 255 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 256 { 257 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 258 result = SBType(ClangASTType (m_opaque_sp->GetClangAST(), m_opaque_sp->GetClangType())); 259 } 260 } 261 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 262 if (log) 263 { 264 if (result.IsValid()) 265 log->Printf ("SBValue(%p)::GetType => %p", m_opaque_sp.get(), &result); 266 else 267 log->Printf ("SBValue(%p)::GetType => NULL", m_opaque_sp.get()); 268 } 269 return result; 270} 271 272bool 273SBValue::GetValueDidChange () 274{ 275 bool result = false; 276 if (m_opaque_sp) 277 { 278 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 279 { 280 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 281 result = m_opaque_sp->GetValueDidChange (); 282 } 283 } 284 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 285 if (log) 286 log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result); 287 288 return result; 289} 290 291const char * 292SBValue::GetSummary () 293{ 294 const char *cstr = NULL; 295 if (m_opaque_sp) 296 { 297 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 298 { 299 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 300 cstr = m_opaque_sp->GetSummaryAsCString(); 301 } 302 } 303 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 304 if (log) 305 { 306 if (cstr) 307 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 308 else 309 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 310 } 311 return cstr; 312} 313 314const char * 315SBValue::GetLocation () 316{ 317 const char *cstr = NULL; 318 if (m_opaque_sp) 319 { 320 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 321 { 322 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 323 cstr = m_opaque_sp->GetLocationAsCString(); 324 } 325 } 326 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 327 if (log) 328 { 329 if (cstr) 330 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 331 else 332 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 333 } 334 return cstr; 335} 336 337bool 338SBValue::SetValueFromCString (const char *value_str) 339{ 340 bool success = false; 341 if (m_opaque_sp) 342 { 343 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 344 { 345 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 346 success = m_opaque_sp->SetValueFromCString (value_str); 347 } 348 } 349 return success; 350} 351 352lldb::SBValue 353SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) 354{ 355 lldb::SBValue result; 356 if (m_opaque_sp) 357 { 358 if (type.IsValid()) 359 { 360 result = SBValue(m_opaque_sp->GetSyntheticChildAtOffset(offset, type.m_opaque_sp->GetClangASTType(), true)); 361 result.m_opaque_sp->SetName(ConstString(name)); 362 } 363 } 364 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 365 if (log) 366 { 367 if (result.IsValid()) 368 log->Printf ("SBValue(%p)::GetChildAtOffset => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 369 else 370 log->Printf ("SBValue(%p)::GetChildAtOffset => NULL", m_opaque_sp.get()); 371 } 372 return result; 373} 374 375lldb::SBValue 376SBValue::Cast (SBType type) 377{ 378 return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type); 379} 380 381lldb::SBValue 382SBValue::CreateValueFromExpression (const char *name, const char* expression) 383{ 384 lldb::SBValue result; 385 if (m_opaque_sp) 386 { 387 ValueObjectSP result_valobj_sp; 388 m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression, 389 m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame(), 390 eExecutionPolicyOnlyWhenNeeded, 391 false, // coerce to id 392 true, // unwind on error 393 true, // keep in memory 394 eNoDynamicValues, 395 result_valobj_sp); 396 if (result_valobj_sp) 397 { 398 result_valobj_sp->SetName(ConstString(name)); 399 result = SBValue(result_valobj_sp); 400 } 401 } 402 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 403 if (log) 404 { 405 if (result.IsValid()) 406 log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 407 else 408 log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); 409 } 410 return result; 411} 412 413lldb::SBValue 414SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type) 415{ 416 lldb::SBValue result; 417 if (m_opaque_sp && type.IsValid() && type.GetPointerType().IsValid()) 418 { 419 SBType real_type(type.GetPointerType()); 420 421 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); 422 423 ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(), 424 real_type.m_opaque_sp->GetASTContext(), 425 real_type.m_opaque_sp->GetOpaqueQualType(), 426 ConstString(name), 427 buffer, 428 lldb::endian::InlHostByteOrder(), 429 GetTarget().GetProcess().GetAddressByteSize())); 430 431 ValueObjectSP result_valobj_sp; 432 433 ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); 434 if (ptr_result_valobj_sp) 435 { 436 Error err; 437 result_valobj_sp = ptr_result_valobj_sp->Dereference(err); 438 if (result_valobj_sp) 439 result_valobj_sp->SetName(ConstString(name)); 440 } 441 result = SBValue(result_valobj_sp); 442 } 443 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 444 if (log) 445 { 446 if (result.IsValid()) 447 log->Printf ("SBValue(%p)::GetChildFromAddress => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 448 else 449 log->Printf ("SBValue(%p)::GetChildFromAddress => NULL", m_opaque_sp.get()); 450 } 451 return result; 452} 453 454lldb::SBValue 455SBValue::CreateValueFromData (const char* name, SBData data, SBType type) 456{ 457 SBValue result; 458 459 AddressType addr_of_children_priv = eAddressTypeLoad; 460 461 if (m_opaque_sp) 462 { 463 ValueObjectSP valobj_sp; 464 valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(), 465 type.m_opaque_sp->GetASTContext() , 466 type.m_opaque_sp->GetOpaqueQualType(), 467 ConstString(name), 468 *data.m_opaque_sp, 469 LLDB_INVALID_ADDRESS); 470 valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv); 471 result = SBValue(valobj_sp); 472 } 473 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 474 if (log) 475 { 476 if (result.IsValid()) 477 log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp->GetName().AsCString()); 478 else 479 log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); 480 } 481 return result; 482} 483 484SBValue 485SBValue::GetChildAtIndex (uint32_t idx) 486{ 487 const bool can_create_synthetic = false; 488 lldb::DynamicValueType use_dynamic = eNoDynamicValues; 489 if (m_opaque_sp) 490 use_dynamic = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue(); 491 return GetChildAtIndex (idx, use_dynamic, can_create_synthetic); 492} 493 494SBValue 495SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic) 496{ 497 lldb::ValueObjectSP child_sp; 498 499 if (m_opaque_sp) 500 { 501 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 502 { 503 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 504 const bool can_create = true; 505 child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create); 506 if (can_create_synthetic && !child_sp) 507 { 508 if (m_opaque_sp->IsPointerType()) 509 { 510 child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create); 511 } 512 else if (m_opaque_sp->IsArrayType()) 513 { 514 child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create); 515 } 516 } 517 518 if (child_sp) 519 { 520 if (use_dynamic != lldb::eNoDynamicValues) 521 { 522 lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic)); 523 if (dynamic_sp) 524 child_sp = dynamic_sp; 525 } 526 } 527 } 528 } 529 530 SBValue sb_value (child_sp); 531 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 532 if (log) 533 log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); 534 535 return sb_value; 536} 537 538uint32_t 539SBValue::GetIndexOfChildWithName (const char *name) 540{ 541 uint32_t idx = UINT32_MAX; 542 if (m_opaque_sp) 543 { 544 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 545 { 546 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 547 548 idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); 549 } 550 } 551 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 552 if (log) 553 { 554 if (idx == UINT32_MAX) 555 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name); 556 else 557 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); 558 } 559 return idx; 560} 561 562SBValue 563SBValue::GetChildMemberWithName (const char *name) 564{ 565 if (m_opaque_sp) 566 { 567 lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetPreferDynamicValue(); 568 return GetChildMemberWithName (name, use_dynamic_value); 569 } 570 else 571 return GetChildMemberWithName (name, eNoDynamicValues); 572} 573 574SBValue 575SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) 576{ 577 lldb::ValueObjectSP child_sp; 578 const ConstString str_name (name); 579 580 581 if (m_opaque_sp) 582 { 583 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 584 { 585 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 586 child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); 587 if (use_dynamic_value != lldb::eNoDynamicValues) 588 { 589 if (child_sp) 590 { 591 lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); 592 if (dynamic_sp) 593 child_sp = dynamic_sp; 594 } 595 } 596 } 597 } 598 599 SBValue sb_value (child_sp); 600 601 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 602 if (log) 603 log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); 604 605 return sb_value; 606} 607 608lldb::SBValue 609SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic) 610{ 611 if (m_opaque_sp) 612 { 613 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 614 { 615 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 616 return SBValue (m_opaque_sp->GetDynamicValue(use_dynamic)); 617 } 618 } 619 620 return SBValue(); 621} 622 623lldb::SBValue 624SBValue::GetStaticValue () 625{ 626 if (m_opaque_sp) 627 { 628 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 629 { 630 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 631 return SBValue(m_opaque_sp->GetStaticValue()); 632 } 633 } 634 635 return SBValue(); 636} 637 638bool 639SBValue::IsDynamic() 640{ 641 if (m_opaque_sp) 642 { 643 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 644 { 645 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 646 return m_opaque_sp->IsDynamic(); 647 } 648 } 649 return false; 650} 651 652lldb::SBValue 653SBValue::GetValueForExpressionPath(const char* expr_path) 654{ 655 lldb::ValueObjectSP child_sp; 656 if (m_opaque_sp) 657 { 658 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 659 { 660 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 661 // using default values for all the fancy options, just do it if you can 662 child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path); 663 } 664 } 665 666 SBValue sb_value (child_sp); 667 668 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 669 if (log) 670 log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get()); 671 672 return sb_value; 673} 674 675int64_t 676SBValue::GetValueAsSigned(SBError& error, int64_t fail_value) 677{ 678 error.Clear(); 679 if (m_opaque_sp) 680 { 681 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 682 { 683 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 684 Scalar scalar; 685 if (m_opaque_sp->ResolveValue (scalar)) 686 return scalar.GetRawBits64(fail_value); 687 else 688 error.SetErrorString("could not get value"); 689 } 690 else 691 error.SetErrorString("could not get target"); 692 } 693 error.SetErrorString("invalid SBValue"); 694 return fail_value; 695} 696 697uint64_t 698SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value) 699{ 700 error.Clear(); 701 if (m_opaque_sp) 702 { 703 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 704 { 705 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 706 Scalar scalar; 707 if (m_opaque_sp->ResolveValue (scalar)) 708 return scalar.GetRawBits64(fail_value); 709 else 710 error.SetErrorString("could not get value"); 711 } 712 else 713 error.SetErrorString("could not get target"); 714 } 715 error.SetErrorString("invalid SBValue"); 716 return fail_value; 717} 718 719int64_t 720SBValue::GetValueAsSigned(int64_t fail_value) 721{ 722 if (m_opaque_sp) 723 { 724 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 725 { 726 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 727 Scalar scalar; 728 if (m_opaque_sp->ResolveValue (scalar)) 729 return scalar.GetRawBits64(fail_value); 730 } 731 } 732 return fail_value; 733} 734 735uint64_t 736SBValue::GetValueAsUnsigned(uint64_t fail_value) 737{ 738 if (m_opaque_sp) 739 { 740 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 741 { 742 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 743 Scalar scalar; 744 if (m_opaque_sp->ResolveValue (scalar)) 745 return scalar.GetRawBits64(fail_value); 746 } 747 } 748 return fail_value; 749} 750 751uint32_t 752SBValue::GetNumChildren () 753{ 754 uint32_t num_children = 0; 755 756 if (m_opaque_sp) 757 { 758 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 759 { 760 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 761 762 num_children = m_opaque_sp->GetNumChildren(); 763 } 764 } 765 766 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 767 if (log) 768 log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); 769 770 return num_children; 771} 772 773 774SBValue 775SBValue::Dereference () 776{ 777 SBValue sb_value; 778 if (m_opaque_sp) 779 { 780 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 781 { 782 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 783 784 Error error; 785 sb_value = m_opaque_sp->Dereference (error); 786 } 787 } 788 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 789 if (log) 790 log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 791 792 return sb_value; 793} 794 795bool 796SBValue::TypeIsPointerType () 797{ 798 bool is_ptr_type = false; 799 800 if (m_opaque_sp) 801 { 802 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 803 { 804 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 805 806 is_ptr_type = m_opaque_sp->IsPointerType(); 807 } 808 } 809 810 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 811 if (log) 812 log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); 813 814 815 return is_ptr_type; 816} 817 818void * 819SBValue::GetOpaqueType() 820{ 821 if (m_opaque_sp) 822 { 823 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 824 { 825 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); 826 827 return m_opaque_sp->GetClangType(); 828 } 829 } 830 return NULL; 831} 832 833lldb::SBTarget 834SBValue::GetTarget() 835{ 836 SBTarget result; 837 if (m_opaque_sp) 838 { 839 if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) 840 { 841 result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP())); 842 } 843 } 844 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 845 if (log) 846 { 847 if (result.get() == NULL) 848 log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); 849 else 850 log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get()); 851 } 852 return result; 853} 854 855lldb::SBProcess 856SBValue::GetProcess() 857{ 858 SBProcess result; 859 if (m_opaque_sp) 860 { 861 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 862 if (target) 863 { 864 result = SBProcess(lldb::ProcessSP(target->GetProcessSP())); 865 } 866 } 867 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 868 if (log) 869 { 870 if (result.get() == NULL) 871 log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get()); 872 else 873 log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), result.get()); 874 } 875 return result; 876} 877 878lldb::SBThread 879SBValue::GetThread() 880{ 881 SBThread result; 882 if (m_opaque_sp) 883 { 884 if (m_opaque_sp->GetExecutionContextScope()) 885 { 886 result = SBThread(m_opaque_sp->GetExecutionContextScope()->CalculateThread()->GetSP()); 887 } 888 } 889 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 890 if (log) 891 { 892 if (result.get() == NULL) 893 log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get()); 894 else 895 log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), result.get()); 896 } 897 return result; 898} 899 900lldb::SBFrame 901SBValue::GetFrame() 902{ 903 SBFrame result; 904 if (m_opaque_sp) 905 { 906 if (m_opaque_sp->GetExecutionContextScope()) 907 { 908 result.SetFrame (m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame()->GetSP()); 909 } 910 } 911 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 912 if (log) 913 { 914 if (result.get() == NULL) 915 log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get()); 916 else 917 log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), result.get()); 918 } 919 return result; 920} 921 922 923// Mimic shared pointer... 924lldb_private::ValueObject * 925SBValue::get() const 926{ 927 return m_opaque_sp.get(); 928} 929 930lldb_private::ValueObject * 931SBValue::operator->() const 932{ 933 return m_opaque_sp.get(); 934} 935 936lldb::ValueObjectSP & 937SBValue::operator*() 938{ 939 return m_opaque_sp; 940} 941 942const lldb::ValueObjectSP & 943SBValue::operator*() const 944{ 945 return m_opaque_sp; 946} 947 948bool 949SBValue::GetExpressionPath (SBStream &description) 950{ 951 if (m_opaque_sp) 952 { 953 m_opaque_sp->GetExpressionPath (description.ref(), false); 954 return true; 955 } 956 return false; 957} 958 959bool 960SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) 961{ 962 if (m_opaque_sp) 963 { 964 m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); 965 return true; 966 } 967 return false; 968} 969 970bool 971SBValue::GetDescription (SBStream &description) 972{ 973 Stream &strm = description.ref(); 974 975 if (m_opaque_sp) 976 { 977 ValueObject::DumpValueObject (strm, m_opaque_sp.get()); 978 } 979 else 980 strm.PutCString ("No value"); 981 982 return true; 983} 984 985lldb::Format 986SBValue::GetFormat () 987{ 988 if (m_opaque_sp) 989 return m_opaque_sp->GetFormat(); 990 return eFormatDefault; 991} 992 993void 994SBValue::SetFormat (lldb::Format format) 995{ 996 if (m_opaque_sp) 997 m_opaque_sp->SetFormat(format); 998} 999 1000lldb::SBValue 1001SBValue::AddressOf() 1002{ 1003 SBValue sb_value; 1004 if (m_opaque_sp) 1005 { 1006 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1007 if (target) 1008 { 1009 Mutex::Locker api_locker (target->GetAPIMutex()); 1010 Error error; 1011 sb_value = m_opaque_sp->AddressOf (error); 1012 } 1013 } 1014 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1015 if (log) 1016 log->Printf ("SBValue(%p)::GetPointerToObject () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 1017 1018 return sb_value; 1019} 1020 1021lldb::addr_t 1022SBValue::GetLoadAddress() 1023{ 1024 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1025 if (m_opaque_sp) 1026 { 1027 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1028 if (target) 1029 { 1030 Mutex::Locker api_locker (target->GetAPIMutex()); 1031 const bool scalar_is_load_address = true; 1032 AddressType addr_type; 1033 value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1034 if (addr_type == eAddressTypeFile) 1035 { 1036 Module* module = m_opaque_sp->GetModule(); 1037 if (!module) 1038 value = LLDB_INVALID_ADDRESS; 1039 else 1040 { 1041 Address addr; 1042 module->ResolveFileAddress(value, addr); 1043 value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get()); 1044 } 1045 } 1046 else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid) 1047 value = LLDB_INVALID_ADDRESS; 1048 } 1049 } 1050 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1051 if (log) 1052 log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value); 1053 1054 return value; 1055} 1056 1057lldb::SBAddress 1058SBValue::GetAddress() 1059{ 1060 Address addr; 1061 if (m_opaque_sp) 1062 { 1063 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1064 if (target) 1065 { 1066 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1067 Mutex::Locker api_locker (target->GetAPIMutex()); 1068 const bool scalar_is_load_address = true; 1069 AddressType addr_type; 1070 value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1071 if (addr_type == eAddressTypeFile) 1072 { 1073 Module* module = m_opaque_sp->GetModule(); 1074 if (module) 1075 module->ResolveFileAddress(value, addr); 1076 } 1077 else if (addr_type == eAddressTypeLoad) 1078 { 1079 // no need to check the return value on this.. if it can actually do the resolve 1080 // addr will be in the form (section,offset), otherwise it will simply be returned 1081 // as (NULL, value) 1082 addr.SetLoadAddress(value, target); 1083 } 1084 } 1085 } 1086 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1087 if (log) 1088 log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset()); 1089 return SBAddress(new Address(addr)); 1090} 1091 1092lldb::SBData 1093SBValue::GetPointeeData (uint32_t item_idx, 1094 uint32_t item_count) 1095{ 1096 lldb::SBData sb_data; 1097 if (m_opaque_sp) 1098 { 1099 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1100 if (target) 1101 { 1102 DataExtractorSP data_sp(new DataExtractor()); 1103 Mutex::Locker api_locker (target->GetAPIMutex()); 1104 m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count); 1105 if (data_sp->GetByteSize() > 0) 1106 *sb_data = data_sp; 1107 } 1108 } 1109 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1110 if (log) 1111 log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", 1112 m_opaque_sp.get(), 1113 item_idx, 1114 item_count, 1115 sb_data.get()); 1116 1117 return sb_data; 1118} 1119 1120lldb::SBData 1121SBValue::GetData () 1122{ 1123 lldb::SBData sb_data; 1124 if (m_opaque_sp) 1125 { 1126 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1127 if (target) 1128 { 1129 DataExtractorSP data_sp(new DataExtractor()); 1130 Mutex::Locker api_locker (target->GetAPIMutex()); 1131 m_opaque_sp->GetData(*data_sp); 1132 if (data_sp->GetByteSize() > 0) 1133 *sb_data = data_sp; 1134 } 1135 } 1136 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1137 if (log) 1138 log->Printf ("SBValue(%p)::GetData () => SBData(%p)", 1139 m_opaque_sp.get(), 1140 sb_data.get()); 1141 1142 return sb_data; 1143} 1144 1145lldb::SBWatchpoint 1146SBValue::Watch (bool resolve_location, bool read, bool write) 1147{ 1148 lldb::SBWatchpoint sb_watchpoint; 1149 if (!m_opaque_sp) 1150 return sb_watchpoint; 1151 1152 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1153 if (target) 1154 { 1155 Mutex::Locker api_locker (target->GetAPIMutex()); 1156 sb_watchpoint = WatchValue(read, write, false); 1157 } 1158 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1159 if (log) 1160 log->Printf ("SBValue(%p)::Watch (resolve_location=%i, read=%i, write=%i) => wp(%p)", 1161 m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get()); 1162 return sb_watchpoint; 1163} 1164 1165lldb::SBWatchpoint 1166SBValue::WatchPointee (bool resolve_location, bool read, bool write) 1167{ 1168 lldb::SBWatchpoint sb_watchpoint; 1169 if (!m_opaque_sp) 1170 return sb_watchpoint; 1171 1172 Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); 1173 if (target) 1174 { 1175 Mutex::Locker api_locker (target->GetAPIMutex()); 1176 sb_watchpoint = WatchValue(read, write, true); 1177 } 1178 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1179 if (log) 1180 log->Printf ("SBValue(%p)::WatchPointee (resolve_location=%i, read=%i, write=%i) => wp(%p)", 1181 m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get()); 1182 return sb_watchpoint; 1183} 1184 1185// Helper function for SBValue::Watch() and SBValue::WatchPointee(). 1186SBWatchpoint 1187SBValue::WatchValue(bool read, bool write, bool watch_pointee) 1188{ 1189 SBWatchpoint sb_wp_empty; 1190 1191 // If the SBValue is not valid, there's no point in even trying to watch it. 1192 if (!IsValid() || !GetFrame().IsValid()) 1193 return sb_wp_empty; 1194 1195 // Read and Write cannot both be false. 1196 if (!read && !write) 1197 return sb_wp_empty; 1198 1199 // If we are watching the pointee, check that the SBValue is a pointer type. 1200 if (watch_pointee && !GetType().IsPointerType()) 1201 return sb_wp_empty; 1202 1203 addr_t addr; 1204 size_t size; 1205 if (watch_pointee) { 1206 addr = GetValueAsUnsigned(LLDB_INVALID_ADDRESS); 1207 size = GetType().GetPointeeType().GetByteSize(); 1208 } else { 1209 addr = GetLoadAddress(); 1210 size = GetByteSize(); 1211 } 1212 1213 // Sanity check the address and the size before calling Target::CreateWatchpoint(). 1214 if (addr == LLDB_INVALID_ADDRESS || size == 0) 1215 return sb_wp_empty; 1216 1217 uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) | 1218 (write ? LLDB_WATCH_TYPE_WRITE : 0); 1219 WatchpointSP wp_sp = GetFrame().m_opaque_sp->GetThread().GetProcess().GetTarget(). 1220 CreateWatchpoint(addr, size, watch_type); 1221 1222 if (wp_sp) { 1223 // StackFrame::GetInScopeVariableList(true) to get file globals as well. 1224 VariableListSP var_list_sp(GetFrame().m_opaque_sp->GetInScopeVariableList(true)); 1225 VariableSP var_sp = var_list_sp->FindVariable(ConstString(GetName())); 1226 if (var_sp && var_sp->GetDeclaration().GetFile()) { 1227 StreamString ss; 1228 // True to show fullpath for declaration file. 1229 var_sp->GetDeclaration().DumpStopContext(&ss, true); 1230 wp_sp->SetDeclInfo(ss.GetString()); 1231 } 1232 } 1233 return wp_sp; 1234} 1235 1236