1 //===-- SBValue.cpp ---------------------------------------------*- 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 #include "lldb/API/SBValue.h" 10 11 #include "lldb/API/SBDeclaration.h" 12 #include "lldb/API/SBStream.h" 13 #include "lldb/API/SBTypeFilter.h" 14 #include "lldb/API/SBTypeFormat.h" 15 #include "lldb/API/SBTypeSummary.h" 16 #include "lldb/API/SBTypeSynthetic.h" 17 18 #include "lldb/Breakpoint/Watchpoint.h" 19 #include "lldb/Core/Module.h" 20 #include "lldb/Core/Section.h" 21 #include "lldb/Core/StreamFile.h" 22 #include "lldb/Core/Value.h" 23 #include "lldb/Core/ValueObject.h" 24 #include "lldb/Core/ValueObjectConstResult.h" 25 #include "lldb/DataFormatters/DataVisualization.h" 26 #include "lldb/Symbol/Block.h" 27 #include "lldb/Symbol/Declaration.h" 28 #include "lldb/Symbol/ObjectFile.h" 29 #include "lldb/Symbol/Type.h" 30 #include "lldb/Symbol/Variable.h" 31 #include "lldb/Symbol/VariableList.h" 32 #include "lldb/Target/ExecutionContext.h" 33 #include "lldb/Target/Process.h" 34 #include "lldb/Target/StackFrame.h" 35 #include "lldb/Target/Target.h" 36 #include "lldb/Target/Thread.h" 37 #include "lldb/Utility/DataExtractor.h" 38 #include "lldb/Utility/Log.h" 39 #include "lldb/Utility/Scalar.h" 40 #include "lldb/Utility/Stream.h" 41 42 #include "lldb/API/SBDebugger.h" 43 #include "lldb/API/SBExpressionOptions.h" 44 #include "lldb/API/SBFrame.h" 45 #include "lldb/API/SBProcess.h" 46 #include "lldb/API/SBTarget.h" 47 #include "lldb/API/SBThread.h" 48 49 using namespace lldb; 50 using namespace lldb_private; 51 52 class ValueImpl { 53 public: 54 ValueImpl() {} 55 56 ValueImpl(lldb::ValueObjectSP in_valobj_sp, 57 lldb::DynamicValueType use_dynamic, bool use_synthetic, 58 const char *name = NULL) 59 : m_valobj_sp(), m_use_dynamic(use_dynamic), 60 m_use_synthetic(use_synthetic), m_name(name) { 61 if (in_valobj_sp) { 62 if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable( 63 lldb::eNoDynamicValues, false))) { 64 if (!m_name.IsEmpty()) 65 m_valobj_sp->SetName(m_name); 66 } 67 } 68 } 69 70 ValueImpl(const ValueImpl &rhs) 71 : m_valobj_sp(rhs.m_valobj_sp), m_use_dynamic(rhs.m_use_dynamic), 72 m_use_synthetic(rhs.m_use_synthetic), m_name(rhs.m_name) {} 73 74 ValueImpl &operator=(const ValueImpl &rhs) { 75 if (this != &rhs) { 76 m_valobj_sp = rhs.m_valobj_sp; 77 m_use_dynamic = rhs.m_use_dynamic; 78 m_use_synthetic = rhs.m_use_synthetic; 79 m_name = rhs.m_name; 80 } 81 return *this; 82 } 83 84 bool IsValid() { 85 if (m_valobj_sp.get() == NULL) 86 return false; 87 else { 88 // FIXME: This check is necessary but not sufficient. We for sure don't 89 // want to touch SBValues whose owning 90 // targets have gone away. This check is a little weak in that it 91 // enforces that restriction when you call IsValid, but since IsValid 92 // doesn't lock the target, you have no guarantee that the SBValue won't 93 // go invalid after you call this... Also, an SBValue could depend on 94 // data from one of the modules in the target, and those could go away 95 // independently of the target, for instance if a module is unloaded. 96 // But right now, neither SBValues nor ValueObjects know which modules 97 // they depend on. So I have no good way to make that check without 98 // tracking that in all the ValueObject subclasses. 99 TargetSP target_sp = m_valobj_sp->GetTargetSP(); 100 return target_sp && target_sp->IsValid(); 101 } 102 } 103 104 lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; } 105 106 lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker, 107 std::unique_lock<std::recursive_mutex> &lock, 108 Status &error) { 109 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 110 if (!m_valobj_sp) { 111 error.SetErrorString("invalid value object"); 112 return m_valobj_sp; 113 } 114 115 lldb::ValueObjectSP value_sp = m_valobj_sp; 116 117 Target *target = value_sp->GetTargetSP().get(); 118 if (!target) 119 return ValueObjectSP(); 120 121 lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); 122 123 ProcessSP process_sp(value_sp->GetProcessSP()); 124 if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) { 125 // We don't allow people to play around with ValueObject if the process 126 // is running. If you want to look at values, pause the process, then 127 // look. 128 if (log) 129 log->Printf("SBValue(%p)::GetSP() => error: process is running", 130 static_cast<void *>(value_sp.get())); 131 error.SetErrorString("process must be stopped."); 132 return ValueObjectSP(); 133 } 134 135 if (m_use_dynamic != eNoDynamicValues) { 136 ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic); 137 if (dynamic_sp) 138 value_sp = dynamic_sp; 139 } 140 141 if (m_use_synthetic) { 142 ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(m_use_synthetic); 143 if (synthetic_sp) 144 value_sp = synthetic_sp; 145 } 146 147 if (!value_sp) 148 error.SetErrorString("invalid value object"); 149 if (!m_name.IsEmpty()) 150 value_sp->SetName(m_name); 151 152 return value_sp; 153 } 154 155 void SetUseDynamic(lldb::DynamicValueType use_dynamic) { 156 m_use_dynamic = use_dynamic; 157 } 158 159 void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; } 160 161 lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; } 162 163 bool GetUseSynthetic() { return m_use_synthetic; } 164 165 // All the derived values that we would make from the m_valobj_sp will share 166 // the ExecutionContext with m_valobj_sp, so we don't need to do the 167 // calculations in GetSP to return the Target, Process, Thread or Frame. It 168 // is convenient to provide simple accessors for these, which I do here. 169 TargetSP GetTargetSP() { 170 if (m_valobj_sp) 171 return m_valobj_sp->GetTargetSP(); 172 else 173 return TargetSP(); 174 } 175 176 ProcessSP GetProcessSP() { 177 if (m_valobj_sp) 178 return m_valobj_sp->GetProcessSP(); 179 else 180 return ProcessSP(); 181 } 182 183 ThreadSP GetThreadSP() { 184 if (m_valobj_sp) 185 return m_valobj_sp->GetThreadSP(); 186 else 187 return ThreadSP(); 188 } 189 190 StackFrameSP GetFrameSP() { 191 if (m_valobj_sp) 192 return m_valobj_sp->GetFrameSP(); 193 else 194 return StackFrameSP(); 195 } 196 197 private: 198 lldb::ValueObjectSP m_valobj_sp; 199 lldb::DynamicValueType m_use_dynamic; 200 bool m_use_synthetic; 201 ConstString m_name; 202 }; 203 204 class ValueLocker { 205 public: 206 ValueLocker() {} 207 208 ValueObjectSP GetLockedSP(ValueImpl &in_value) { 209 return in_value.GetSP(m_stop_locker, m_lock, m_lock_error); 210 } 211 212 Status &GetError() { return m_lock_error; } 213 214 private: 215 Process::StopLocker m_stop_locker; 216 std::unique_lock<std::recursive_mutex> m_lock; 217 Status m_lock_error; 218 }; 219 220 SBValue::SBValue() : m_opaque_sp() {} 221 222 SBValue::SBValue(const lldb::ValueObjectSP &value_sp) { SetSP(value_sp); } 223 224 SBValue::SBValue(const SBValue &rhs) { SetSP(rhs.m_opaque_sp); } 225 226 SBValue &SBValue::operator=(const SBValue &rhs) { 227 if (this != &rhs) { 228 SetSP(rhs.m_opaque_sp); 229 } 230 return *this; 231 } 232 233 SBValue::~SBValue() {} 234 235 bool SBValue::IsValid() { 236 // If this function ever changes to anything that does more than just check 237 // if the opaque shared pointer is non NULL, then we need to update all "if 238 // (m_opaque_sp)" code in this file. 239 return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid() && 240 m_opaque_sp->GetRootSP().get() != NULL; 241 } 242 243 void SBValue::Clear() { m_opaque_sp.reset(); } 244 245 SBError SBValue::GetError() { 246 SBError sb_error; 247 248 ValueLocker locker; 249 lldb::ValueObjectSP value_sp(GetSP(locker)); 250 if (value_sp) 251 sb_error.SetError(value_sp->GetError()); 252 else 253 sb_error.SetErrorStringWithFormat("error: %s", 254 locker.GetError().AsCString()); 255 256 return sb_error; 257 } 258 259 user_id_t SBValue::GetID() { 260 ValueLocker locker; 261 lldb::ValueObjectSP value_sp(GetSP(locker)); 262 if (value_sp) 263 return value_sp->GetID(); 264 return LLDB_INVALID_UID; 265 } 266 267 const char *SBValue::GetName() { 268 const char *name = NULL; 269 ValueLocker locker; 270 lldb::ValueObjectSP value_sp(GetSP(locker)); 271 if (value_sp) 272 name = value_sp->GetName().GetCString(); 273 274 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 275 if (log) { 276 if (name) 277 log->Printf("SBValue(%p)::GetName () => \"%s\"", 278 static_cast<void *>(value_sp.get()), name); 279 else 280 log->Printf("SBValue(%p)::GetName () => NULL", 281 static_cast<void *>(value_sp.get())); 282 } 283 284 return name; 285 } 286 287 const char *SBValue::GetTypeName() { 288 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 289 const char *name = NULL; 290 ValueLocker locker; 291 lldb::ValueObjectSP value_sp(GetSP(locker)); 292 if (value_sp) { 293 name = value_sp->GetQualifiedTypeName().GetCString(); 294 } 295 296 if (log) { 297 if (name) 298 log->Printf("SBValue(%p)::GetTypeName () => \"%s\"", 299 static_cast<void *>(value_sp.get()), name); 300 else 301 log->Printf("SBValue(%p)::GetTypeName () => NULL", 302 static_cast<void *>(value_sp.get())); 303 } 304 305 return name; 306 } 307 308 const char *SBValue::GetDisplayTypeName() { 309 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 310 const char *name = NULL; 311 ValueLocker locker; 312 lldb::ValueObjectSP value_sp(GetSP(locker)); 313 if (value_sp) { 314 name = value_sp->GetDisplayTypeName().GetCString(); 315 } 316 317 if (log) { 318 if (name) 319 log->Printf("SBValue(%p)::GetTypeName () => \"%s\"", 320 static_cast<void *>(value_sp.get()), name); 321 else 322 log->Printf("SBValue(%p)::GetTypeName () => NULL", 323 static_cast<void *>(value_sp.get())); 324 } 325 326 return name; 327 } 328 329 size_t SBValue::GetByteSize() { 330 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 331 size_t result = 0; 332 333 ValueLocker locker; 334 lldb::ValueObjectSP value_sp(GetSP(locker)); 335 if (value_sp) { 336 result = value_sp->GetByteSize(); 337 } 338 339 if (log) 340 log->Printf("SBValue(%p)::GetByteSize () => %" PRIu64, 341 static_cast<void *>(value_sp.get()), 342 static_cast<uint64_t>(result)); 343 344 return result; 345 } 346 347 bool SBValue::IsInScope() { 348 bool result = false; 349 350 ValueLocker locker; 351 lldb::ValueObjectSP value_sp(GetSP(locker)); 352 if (value_sp) { 353 result = value_sp->IsInScope(); 354 } 355 356 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 357 if (log) 358 log->Printf("SBValue(%p)::IsInScope () => %i", 359 static_cast<void *>(value_sp.get()), result); 360 361 return result; 362 } 363 364 const char *SBValue::GetValue() { 365 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 366 367 const char *cstr = NULL; 368 ValueLocker locker; 369 lldb::ValueObjectSP value_sp(GetSP(locker)); 370 if (value_sp) { 371 cstr = value_sp->GetValueAsCString(); 372 } 373 if (log) { 374 if (cstr) 375 log->Printf("SBValue(%p)::GetValue() => \"%s\"", 376 static_cast<void *>(value_sp.get()), cstr); 377 else 378 log->Printf("SBValue(%p)::GetValue() => NULL", 379 static_cast<void *>(value_sp.get())); 380 } 381 382 return cstr; 383 } 384 385 ValueType SBValue::GetValueType() { 386 ValueType result = eValueTypeInvalid; 387 ValueLocker locker; 388 lldb::ValueObjectSP value_sp(GetSP(locker)); 389 if (value_sp) 390 result = value_sp->GetValueType(); 391 392 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 393 if (log) { 394 switch (result) { 395 case eValueTypeInvalid: 396 log->Printf("SBValue(%p)::GetValueType () => eValueTypeInvalid", 397 static_cast<void *>(value_sp.get())); 398 break; 399 case eValueTypeVariableGlobal: 400 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", 401 static_cast<void *>(value_sp.get())); 402 break; 403 case eValueTypeVariableStatic: 404 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", 405 static_cast<void *>(value_sp.get())); 406 break; 407 case eValueTypeVariableArgument: 408 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", 409 static_cast<void *>(value_sp.get())); 410 break; 411 case eValueTypeVariableLocal: 412 log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", 413 static_cast<void *>(value_sp.get())); 414 break; 415 case eValueTypeRegister: 416 log->Printf("SBValue(%p)::GetValueType () => eValueTypeRegister", 417 static_cast<void *>(value_sp.get())); 418 break; 419 case eValueTypeRegisterSet: 420 log->Printf("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", 421 static_cast<void *>(value_sp.get())); 422 break; 423 case eValueTypeConstResult: 424 log->Printf("SBValue(%p)::GetValueType () => eValueTypeConstResult", 425 static_cast<void *>(value_sp.get())); 426 break; 427 case eValueTypeVariableThreadLocal: 428 log->Printf( 429 "SBValue(%p)::GetValueType () => eValueTypeVariableThreadLocal", 430 static_cast<void *>(value_sp.get())); 431 break; 432 } 433 } 434 return result; 435 } 436 437 const char *SBValue::GetObjectDescription() { 438 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 439 const char *cstr = NULL; 440 ValueLocker locker; 441 lldb::ValueObjectSP value_sp(GetSP(locker)); 442 if (value_sp) { 443 cstr = value_sp->GetObjectDescription(); 444 } 445 if (log) { 446 if (cstr) 447 log->Printf("SBValue(%p)::GetObjectDescription() => \"%s\"", 448 static_cast<void *>(value_sp.get()), cstr); 449 else 450 log->Printf("SBValue(%p)::GetObjectDescription() => NULL", 451 static_cast<void *>(value_sp.get())); 452 } 453 return cstr; 454 } 455 456 const char *SBValue::GetTypeValidatorResult() { 457 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 458 const char *cstr = NULL; 459 ValueLocker locker; 460 lldb::ValueObjectSP value_sp(GetSP(locker)); 461 if (value_sp) { 462 const auto &validation(value_sp->GetValidationStatus()); 463 if (TypeValidatorResult::Failure == validation.first) { 464 if (validation.second.empty()) 465 cstr = "unknown error"; 466 else 467 cstr = validation.second.c_str(); 468 } 469 } 470 if (log) { 471 if (cstr) 472 log->Printf("SBValue(%p)::GetTypeValidatorResult() => \"%s\"", 473 static_cast<void *>(value_sp.get()), cstr); 474 else 475 log->Printf("SBValue(%p)::GetTypeValidatorResult() => NULL", 476 static_cast<void *>(value_sp.get())); 477 } 478 return cstr; 479 } 480 481 SBType SBValue::GetType() { 482 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 483 SBType sb_type; 484 ValueLocker locker; 485 lldb::ValueObjectSP value_sp(GetSP(locker)); 486 TypeImplSP type_sp; 487 if (value_sp) { 488 type_sp.reset(new TypeImpl(value_sp->GetTypeImpl())); 489 sb_type.SetSP(type_sp); 490 } 491 if (log) { 492 if (type_sp) 493 log->Printf("SBValue(%p)::GetType => SBType(%p)", 494 static_cast<void *>(value_sp.get()), 495 static_cast<void *>(type_sp.get())); 496 else 497 log->Printf("SBValue(%p)::GetType => NULL", 498 static_cast<void *>(value_sp.get())); 499 } 500 return sb_type; 501 } 502 503 bool SBValue::GetValueDidChange() { 504 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 505 bool result = false; 506 ValueLocker locker; 507 lldb::ValueObjectSP value_sp(GetSP(locker)); 508 if (value_sp) { 509 if (value_sp->UpdateValueIfNeeded(false)) 510 result = value_sp->GetValueDidChange(); 511 } 512 if (log) 513 log->Printf("SBValue(%p)::GetValueDidChange() => %i", 514 static_cast<void *>(value_sp.get()), result); 515 516 return result; 517 } 518 519 const char *SBValue::GetSummary() { 520 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 521 const char *cstr = NULL; 522 ValueLocker locker; 523 lldb::ValueObjectSP value_sp(GetSP(locker)); 524 if (value_sp) { 525 cstr = value_sp->GetSummaryAsCString(); 526 } 527 if (log) { 528 if (cstr) 529 log->Printf("SBValue(%p)::GetSummary() => \"%s\"", 530 static_cast<void *>(value_sp.get()), cstr); 531 else 532 log->Printf("SBValue(%p)::GetSummary() => NULL", 533 static_cast<void *>(value_sp.get())); 534 } 535 return cstr; 536 } 537 538 const char *SBValue::GetSummary(lldb::SBStream &stream, 539 lldb::SBTypeSummaryOptions &options) { 540 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 541 ValueLocker locker; 542 lldb::ValueObjectSP value_sp(GetSP(locker)); 543 if (value_sp) { 544 std::string buffer; 545 if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty()) 546 stream.Printf("%s", buffer.c_str()); 547 } 548 const char *cstr = stream.GetData(); 549 if (log) { 550 if (cstr) 551 log->Printf("SBValue(%p)::GetSummary() => \"%s\"", 552 static_cast<void *>(value_sp.get()), cstr); 553 else 554 log->Printf("SBValue(%p)::GetSummary() => NULL", 555 static_cast<void *>(value_sp.get())); 556 } 557 return cstr; 558 } 559 560 const char *SBValue::GetLocation() { 561 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 562 const char *cstr = NULL; 563 ValueLocker locker; 564 lldb::ValueObjectSP value_sp(GetSP(locker)); 565 if (value_sp) { 566 cstr = value_sp->GetLocationAsCString(); 567 } 568 if (log) { 569 if (cstr) 570 log->Printf("SBValue(%p)::GetLocation() => \"%s\"", 571 static_cast<void *>(value_sp.get()), cstr); 572 else 573 log->Printf("SBValue(%p)::GetLocation() => NULL", 574 static_cast<void *>(value_sp.get())); 575 } 576 return cstr; 577 } 578 579 // Deprecated - use the one that takes an lldb::SBError 580 bool SBValue::SetValueFromCString(const char *value_str) { 581 lldb::SBError dummy; 582 return SetValueFromCString(value_str, dummy); 583 } 584 585 bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) { 586 bool success = false; 587 ValueLocker locker; 588 lldb::ValueObjectSP value_sp(GetSP(locker)); 589 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 590 if (value_sp) { 591 success = value_sp->SetValueFromCString(value_str, error.ref()); 592 } else 593 error.SetErrorStringWithFormat("Could not get value: %s", 594 locker.GetError().AsCString()); 595 596 if (log) 597 log->Printf("SBValue(%p)::SetValueFromCString(\"%s\") => %i", 598 static_cast<void *>(value_sp.get()), value_str, success); 599 600 return success; 601 } 602 603 lldb::SBTypeFormat SBValue::GetTypeFormat() { 604 lldb::SBTypeFormat format; 605 ValueLocker locker; 606 lldb::ValueObjectSP value_sp(GetSP(locker)); 607 if (value_sp) { 608 if (value_sp->UpdateValueIfNeeded(true)) { 609 lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat(); 610 if (format_sp) 611 format.SetSP(format_sp); 612 } 613 } 614 return format; 615 } 616 617 lldb::SBTypeSummary SBValue::GetTypeSummary() { 618 lldb::SBTypeSummary summary; 619 ValueLocker locker; 620 lldb::ValueObjectSP value_sp(GetSP(locker)); 621 if (value_sp) { 622 if (value_sp->UpdateValueIfNeeded(true)) { 623 lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat(); 624 if (summary_sp) 625 summary.SetSP(summary_sp); 626 } 627 } 628 return summary; 629 } 630 631 lldb::SBTypeFilter SBValue::GetTypeFilter() { 632 lldb::SBTypeFilter filter; 633 ValueLocker locker; 634 lldb::ValueObjectSP value_sp(GetSP(locker)); 635 if (value_sp) { 636 if (value_sp->UpdateValueIfNeeded(true)) { 637 lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren(); 638 639 if (synthetic_sp && !synthetic_sp->IsScripted()) { 640 TypeFilterImplSP filter_sp = 641 std::static_pointer_cast<TypeFilterImpl>(synthetic_sp); 642 filter.SetSP(filter_sp); 643 } 644 } 645 } 646 return filter; 647 } 648 649 #ifndef LLDB_DISABLE_PYTHON 650 lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() { 651 lldb::SBTypeSynthetic synthetic; 652 ValueLocker locker; 653 lldb::ValueObjectSP value_sp(GetSP(locker)); 654 if (value_sp) { 655 if (value_sp->UpdateValueIfNeeded(true)) { 656 lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren(); 657 658 if (children_sp && children_sp->IsScripted()) { 659 ScriptedSyntheticChildrenSP synth_sp = 660 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 661 synthetic.SetSP(synth_sp); 662 } 663 } 664 } 665 return synthetic; 666 } 667 #endif 668 669 lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset, 670 SBType type) { 671 lldb::SBValue sb_value; 672 ValueLocker locker; 673 lldb::ValueObjectSP value_sp(GetSP(locker)); 674 lldb::ValueObjectSP new_value_sp; 675 if (value_sp) { 676 TypeImplSP type_sp(type.GetSP()); 677 if (type.IsValid()) { 678 sb_value.SetSP(value_sp->GetSyntheticChildAtOffset( 679 offset, type_sp->GetCompilerType(false), true), 680 GetPreferDynamicValue(), GetPreferSyntheticValue(), name); 681 } 682 } 683 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 684 if (log) { 685 if (new_value_sp) 686 log->Printf("SBValue(%p)::CreateChildAtOffset => \"%s\"", 687 static_cast<void *>(value_sp.get()), 688 new_value_sp->GetName().AsCString()); 689 else 690 log->Printf("SBValue(%p)::CreateChildAtOffset => NULL", 691 static_cast<void *>(value_sp.get())); 692 } 693 return sb_value; 694 } 695 696 lldb::SBValue SBValue::Cast(SBType type) { 697 lldb::SBValue sb_value; 698 ValueLocker locker; 699 lldb::ValueObjectSP value_sp(GetSP(locker)); 700 TypeImplSP type_sp(type.GetSP()); 701 if (value_sp && type_sp) 702 sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)), 703 GetPreferDynamicValue(), GetPreferSyntheticValue()); 704 return sb_value; 705 } 706 707 lldb::SBValue SBValue::CreateValueFromExpression(const char *name, 708 const char *expression) { 709 SBExpressionOptions options; 710 options.ref().SetKeepInMemory(true); 711 return CreateValueFromExpression(name, expression, options); 712 } 713 714 lldb::SBValue SBValue::CreateValueFromExpression(const char *name, 715 const char *expression, 716 SBExpressionOptions &options) { 717 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 718 lldb::SBValue sb_value; 719 ValueLocker locker; 720 lldb::ValueObjectSP value_sp(GetSP(locker)); 721 lldb::ValueObjectSP new_value_sp; 722 if (value_sp) { 723 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 724 new_value_sp = ValueObject::CreateValueObjectFromExpression( 725 name, expression, exe_ctx, options.ref()); 726 if (new_value_sp) 727 new_value_sp->SetName(ConstString(name)); 728 } 729 sb_value.SetSP(new_value_sp); 730 if (log) { 731 if (new_value_sp) 732 log->Printf("SBValue(%p)::CreateValueFromExpression(name=\"%s\", " 733 "expression=\"%s\") => SBValue (%p)", 734 static_cast<void *>(value_sp.get()), name, expression, 735 static_cast<void *>(new_value_sp.get())); 736 else 737 log->Printf("SBValue(%p)::CreateValueFromExpression(name=\"%s\", " 738 "expression=\"%s\") => NULL", 739 static_cast<void *>(value_sp.get()), name, expression); 740 } 741 return sb_value; 742 } 743 744 lldb::SBValue SBValue::CreateValueFromAddress(const char *name, 745 lldb::addr_t address, 746 SBType sb_type) { 747 lldb::SBValue sb_value; 748 ValueLocker locker; 749 lldb::ValueObjectSP value_sp(GetSP(locker)); 750 lldb::ValueObjectSP new_value_sp; 751 lldb::TypeImplSP type_impl_sp(sb_type.GetSP()); 752 if (value_sp && type_impl_sp) { 753 CompilerType ast_type(type_impl_sp->GetCompilerType(true)); 754 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 755 new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address, 756 exe_ctx, ast_type); 757 } 758 sb_value.SetSP(new_value_sp); 759 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 760 if (log) { 761 if (new_value_sp) 762 log->Printf("SBValue(%p)::CreateValueFromAddress => \"%s\"", 763 static_cast<void *>(value_sp.get()), 764 new_value_sp->GetName().AsCString()); 765 else 766 log->Printf("SBValue(%p)::CreateValueFromAddress => NULL", 767 static_cast<void *>(value_sp.get())); 768 } 769 return sb_value; 770 } 771 772 lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data, 773 SBType sb_type) { 774 lldb::SBValue sb_value; 775 lldb::ValueObjectSP new_value_sp; 776 ValueLocker locker; 777 lldb::ValueObjectSP value_sp(GetSP(locker)); 778 lldb::TypeImplSP type_impl_sp(sb_type.GetSP()); 779 if (value_sp && type_impl_sp) { 780 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 781 new_value_sp = ValueObject::CreateValueObjectFromData( 782 name, **data, exe_ctx, type_impl_sp->GetCompilerType(true)); 783 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); 784 } 785 sb_value.SetSP(new_value_sp); 786 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 787 if (log) { 788 if (new_value_sp) 789 log->Printf("SBValue(%p)::CreateValueFromData => \"%s\"", 790 static_cast<void *>(value_sp.get()), 791 new_value_sp->GetName().AsCString()); 792 else 793 log->Printf("SBValue(%p)::CreateValueFromData => NULL", 794 static_cast<void *>(value_sp.get())); 795 } 796 return sb_value; 797 } 798 799 SBValue SBValue::GetChildAtIndex(uint32_t idx) { 800 const bool can_create_synthetic = false; 801 lldb::DynamicValueType use_dynamic = eNoDynamicValues; 802 TargetSP target_sp; 803 if (m_opaque_sp) 804 target_sp = m_opaque_sp->GetTargetSP(); 805 806 if (target_sp) 807 use_dynamic = target_sp->GetPreferDynamicValue(); 808 809 return GetChildAtIndex(idx, use_dynamic, can_create_synthetic); 810 } 811 812 SBValue SBValue::GetChildAtIndex(uint32_t idx, 813 lldb::DynamicValueType use_dynamic, 814 bool can_create_synthetic) { 815 lldb::ValueObjectSP child_sp; 816 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 817 818 ValueLocker locker; 819 lldb::ValueObjectSP value_sp(GetSP(locker)); 820 if (value_sp) { 821 const bool can_create = true; 822 child_sp = value_sp->GetChildAtIndex(idx, can_create); 823 if (can_create_synthetic && !child_sp) { 824 child_sp = value_sp->GetSyntheticArrayMember(idx, can_create); 825 } 826 } 827 828 SBValue sb_value; 829 sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue()); 830 if (log) 831 log->Printf("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", 832 static_cast<void *>(value_sp.get()), idx, 833 static_cast<void *>(value_sp.get())); 834 835 return sb_value; 836 } 837 838 uint32_t SBValue::GetIndexOfChildWithName(const char *name) { 839 uint32_t idx = UINT32_MAX; 840 ValueLocker locker; 841 lldb::ValueObjectSP value_sp(GetSP(locker)); 842 if (value_sp) { 843 idx = value_sp->GetIndexOfChildWithName(ConstString(name)); 844 } 845 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 846 if (log) { 847 if (idx == UINT32_MAX) 848 log->Printf( 849 "SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", 850 static_cast<void *>(value_sp.get()), name); 851 else 852 log->Printf("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", 853 static_cast<void *>(value_sp.get()), name, idx); 854 } 855 return idx; 856 } 857 858 SBValue SBValue::GetChildMemberWithName(const char *name) { 859 lldb::DynamicValueType use_dynamic_value = eNoDynamicValues; 860 TargetSP target_sp; 861 if (m_opaque_sp) 862 target_sp = m_opaque_sp->GetTargetSP(); 863 864 if (target_sp) 865 use_dynamic_value = target_sp->GetPreferDynamicValue(); 866 return GetChildMemberWithName(name, use_dynamic_value); 867 } 868 869 SBValue 870 SBValue::GetChildMemberWithName(const char *name, 871 lldb::DynamicValueType use_dynamic_value) { 872 lldb::ValueObjectSP child_sp; 873 const ConstString str_name(name); 874 875 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 876 877 ValueLocker locker; 878 lldb::ValueObjectSP value_sp(GetSP(locker)); 879 if (value_sp) { 880 child_sp = value_sp->GetChildMemberWithName(str_name, true); 881 } 882 883 SBValue sb_value; 884 sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); 885 886 if (log) 887 log->Printf( 888 "SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", 889 static_cast<void *>(value_sp.get()), name, 890 static_cast<void *>(value_sp.get())); 891 892 return sb_value; 893 } 894 895 lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) { 896 SBValue value_sb; 897 if (IsValid()) { 898 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic, 899 m_opaque_sp->GetUseSynthetic())); 900 value_sb.SetSP(proxy_sp); 901 } 902 return value_sb; 903 } 904 905 lldb::SBValue SBValue::GetStaticValue() { 906 SBValue value_sb; 907 if (IsValid()) { 908 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), 909 eNoDynamicValues, 910 m_opaque_sp->GetUseSynthetic())); 911 value_sb.SetSP(proxy_sp); 912 } 913 return value_sb; 914 } 915 916 lldb::SBValue SBValue::GetNonSyntheticValue() { 917 SBValue value_sb; 918 if (IsValid()) { 919 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), 920 m_opaque_sp->GetUseDynamic(), false)); 921 value_sb.SetSP(proxy_sp); 922 } 923 return value_sb; 924 } 925 926 lldb::DynamicValueType SBValue::GetPreferDynamicValue() { 927 if (!IsValid()) 928 return eNoDynamicValues; 929 return m_opaque_sp->GetUseDynamic(); 930 } 931 932 void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) { 933 if (IsValid()) 934 return m_opaque_sp->SetUseDynamic(use_dynamic); 935 } 936 937 bool SBValue::GetPreferSyntheticValue() { 938 if (!IsValid()) 939 return false; 940 return m_opaque_sp->GetUseSynthetic(); 941 } 942 943 void SBValue::SetPreferSyntheticValue(bool use_synthetic) { 944 if (IsValid()) 945 return m_opaque_sp->SetUseSynthetic(use_synthetic); 946 } 947 948 bool SBValue::IsDynamic() { 949 ValueLocker locker; 950 lldb::ValueObjectSP value_sp(GetSP(locker)); 951 if (value_sp) 952 return value_sp->IsDynamic(); 953 return false; 954 } 955 956 bool SBValue::IsSynthetic() { 957 ValueLocker locker; 958 lldb::ValueObjectSP value_sp(GetSP(locker)); 959 if (value_sp) 960 return value_sp->IsSynthetic(); 961 return false; 962 } 963 964 bool SBValue::IsSyntheticChildrenGenerated() { 965 ValueLocker locker; 966 lldb::ValueObjectSP value_sp(GetSP(locker)); 967 if (value_sp) 968 return value_sp->IsSyntheticChildrenGenerated(); 969 return false; 970 } 971 972 void SBValue::SetSyntheticChildrenGenerated(bool is) { 973 ValueLocker locker; 974 lldb::ValueObjectSP value_sp(GetSP(locker)); 975 if (value_sp) 976 return value_sp->SetSyntheticChildrenGenerated(is); 977 } 978 979 lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) { 980 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 981 lldb::ValueObjectSP child_sp; 982 ValueLocker locker; 983 lldb::ValueObjectSP value_sp(GetSP(locker)); 984 if (value_sp) { 985 // using default values for all the fancy options, just do it if you can 986 child_sp = value_sp->GetValueForExpressionPath(expr_path); 987 } 988 989 SBValue sb_value; 990 sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue()); 991 992 if (log) 993 log->Printf("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => " 994 "SBValue(%p)", 995 static_cast<void *>(value_sp.get()), expr_path, 996 static_cast<void *>(value_sp.get())); 997 998 return sb_value; 999 } 1000 1001 int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) { 1002 error.Clear(); 1003 ValueLocker locker; 1004 lldb::ValueObjectSP value_sp(GetSP(locker)); 1005 if (value_sp) { 1006 bool success = true; 1007 uint64_t ret_val = fail_value; 1008 ret_val = value_sp->GetValueAsSigned(fail_value, &success); 1009 if (!success) 1010 error.SetErrorString("could not resolve value"); 1011 return ret_val; 1012 } else 1013 error.SetErrorStringWithFormat("could not get SBValue: %s", 1014 locker.GetError().AsCString()); 1015 1016 return fail_value; 1017 } 1018 1019 uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) { 1020 error.Clear(); 1021 ValueLocker locker; 1022 lldb::ValueObjectSP value_sp(GetSP(locker)); 1023 if (value_sp) { 1024 bool success = true; 1025 uint64_t ret_val = fail_value; 1026 ret_val = value_sp->GetValueAsUnsigned(fail_value, &success); 1027 if (!success) 1028 error.SetErrorString("could not resolve value"); 1029 return ret_val; 1030 } else 1031 error.SetErrorStringWithFormat("could not get SBValue: %s", 1032 locker.GetError().AsCString()); 1033 1034 return fail_value; 1035 } 1036 1037 int64_t SBValue::GetValueAsSigned(int64_t fail_value) { 1038 ValueLocker locker; 1039 lldb::ValueObjectSP value_sp(GetSP(locker)); 1040 if (value_sp) { 1041 return value_sp->GetValueAsSigned(fail_value); 1042 } 1043 return fail_value; 1044 } 1045 1046 uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) { 1047 ValueLocker locker; 1048 lldb::ValueObjectSP value_sp(GetSP(locker)); 1049 if (value_sp) { 1050 return value_sp->GetValueAsUnsigned(fail_value); 1051 } 1052 return fail_value; 1053 } 1054 1055 bool SBValue::MightHaveChildren() { 1056 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1057 bool has_children = false; 1058 ValueLocker locker; 1059 lldb::ValueObjectSP value_sp(GetSP(locker)); 1060 if (value_sp) 1061 has_children = value_sp->MightHaveChildren(); 1062 1063 if (log) 1064 log->Printf("SBValue(%p)::MightHaveChildren() => %i", 1065 static_cast<void *>(value_sp.get()), has_children); 1066 return has_children; 1067 } 1068 1069 bool SBValue::IsRuntimeSupportValue() { 1070 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1071 bool is_support = false; 1072 ValueLocker locker; 1073 lldb::ValueObjectSP value_sp(GetSP(locker)); 1074 if (value_sp) 1075 is_support = value_sp->IsRuntimeSupportValue(); 1076 1077 if (log) 1078 log->Printf("SBValue(%p)::IsRuntimeSupportValue() => %i", 1079 static_cast<void *>(value_sp.get()), is_support); 1080 return is_support; 1081 } 1082 1083 uint32_t SBValue::GetNumChildren() { return GetNumChildren(UINT32_MAX); } 1084 1085 uint32_t SBValue::GetNumChildren(uint32_t max) { 1086 uint32_t num_children = 0; 1087 1088 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1089 ValueLocker locker; 1090 lldb::ValueObjectSP value_sp(GetSP(locker)); 1091 if (value_sp) 1092 num_children = value_sp->GetNumChildren(max); 1093 1094 if (log) 1095 log->Printf("SBValue(%p)::GetNumChildren (%u) => %u", 1096 static_cast<void *>(value_sp.get()), max, num_children); 1097 1098 return num_children; 1099 } 1100 1101 SBValue SBValue::Dereference() { 1102 SBValue sb_value; 1103 ValueLocker locker; 1104 lldb::ValueObjectSP value_sp(GetSP(locker)); 1105 if (value_sp) { 1106 Status error; 1107 sb_value = value_sp->Dereference(error); 1108 } 1109 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1110 if (log) 1111 log->Printf("SBValue(%p)::Dereference () => SBValue(%p)", 1112 static_cast<void *>(value_sp.get()), 1113 static_cast<void *>(value_sp.get())); 1114 1115 return sb_value; 1116 } 1117 1118 // Deprecated - please use GetType().IsPointerType() instead. 1119 bool SBValue::TypeIsPointerType() { return GetType().IsPointerType(); } 1120 1121 void *SBValue::GetOpaqueType() { 1122 ValueLocker locker; 1123 lldb::ValueObjectSP value_sp(GetSP(locker)); 1124 if (value_sp) 1125 return value_sp->GetCompilerType().GetOpaqueQualType(); 1126 return NULL; 1127 } 1128 1129 lldb::SBTarget SBValue::GetTarget() { 1130 SBTarget sb_target; 1131 TargetSP target_sp; 1132 if (m_opaque_sp) { 1133 target_sp = m_opaque_sp->GetTargetSP(); 1134 sb_target.SetSP(target_sp); 1135 } 1136 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1137 if (log) { 1138 if (target_sp.get() == NULL) 1139 log->Printf("SBValue(%p)::GetTarget () => NULL", 1140 static_cast<void *>(m_opaque_sp.get())); 1141 else 1142 log->Printf("SBValue(%p)::GetTarget () => %p", 1143 static_cast<void *>(m_opaque_sp.get()), 1144 static_cast<void *>(target_sp.get())); 1145 } 1146 return sb_target; 1147 } 1148 1149 lldb::SBProcess SBValue::GetProcess() { 1150 SBProcess sb_process; 1151 ProcessSP process_sp; 1152 if (m_opaque_sp) { 1153 process_sp = m_opaque_sp->GetProcessSP(); 1154 sb_process.SetSP(process_sp); 1155 } 1156 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1157 if (log) { 1158 if (process_sp.get() == NULL) 1159 log->Printf("SBValue(%p)::GetProcess () => NULL", 1160 static_cast<void *>(m_opaque_sp.get())); 1161 else 1162 log->Printf("SBValue(%p)::GetProcess () => %p", 1163 static_cast<void *>(m_opaque_sp.get()), 1164 static_cast<void *>(process_sp.get())); 1165 } 1166 return sb_process; 1167 } 1168 1169 lldb::SBThread SBValue::GetThread() { 1170 SBThread sb_thread; 1171 ThreadSP thread_sp; 1172 if (m_opaque_sp) { 1173 thread_sp = m_opaque_sp->GetThreadSP(); 1174 sb_thread.SetThread(thread_sp); 1175 } 1176 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1177 if (log) { 1178 if (thread_sp.get() == NULL) 1179 log->Printf("SBValue(%p)::GetThread () => NULL", 1180 static_cast<void *>(m_opaque_sp.get())); 1181 else 1182 log->Printf("SBValue(%p)::GetThread () => %p", 1183 static_cast<void *>(m_opaque_sp.get()), 1184 static_cast<void *>(thread_sp.get())); 1185 } 1186 return sb_thread; 1187 } 1188 1189 lldb::SBFrame SBValue::GetFrame() { 1190 SBFrame sb_frame; 1191 StackFrameSP frame_sp; 1192 if (m_opaque_sp) { 1193 frame_sp = m_opaque_sp->GetFrameSP(); 1194 sb_frame.SetFrameSP(frame_sp); 1195 } 1196 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1197 if (log) { 1198 if (frame_sp.get() == NULL) 1199 log->Printf("SBValue(%p)::GetFrame () => NULL", 1200 static_cast<void *>(m_opaque_sp.get())); 1201 else 1202 log->Printf("SBValue(%p)::GetFrame () => %p", 1203 static_cast<void *>(m_opaque_sp.get()), 1204 static_cast<void *>(frame_sp.get())); 1205 } 1206 return sb_frame; 1207 } 1208 1209 lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const { 1210 if (!m_opaque_sp || !m_opaque_sp->IsValid()) { 1211 locker.GetError().SetErrorString("No value"); 1212 return ValueObjectSP(); 1213 } 1214 return locker.GetLockedSP(*m_opaque_sp.get()); 1215 } 1216 1217 lldb::ValueObjectSP SBValue::GetSP() const { 1218 ValueLocker locker; 1219 return GetSP(locker); 1220 } 1221 1222 void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; } 1223 1224 void SBValue::SetSP(const lldb::ValueObjectSP &sp) { 1225 if (sp) { 1226 lldb::TargetSP target_sp(sp->GetTargetSP()); 1227 if (target_sp) { 1228 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); 1229 bool use_synthetic = 1230 target_sp->TargetProperties::GetEnableSyntheticValue(); 1231 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); 1232 } else 1233 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true)); 1234 } else 1235 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false)); 1236 } 1237 1238 void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1239 lldb::DynamicValueType use_dynamic) { 1240 if (sp) { 1241 lldb::TargetSP target_sp(sp->GetTargetSP()); 1242 if (target_sp) { 1243 bool use_synthetic = 1244 target_sp->TargetProperties::GetEnableSyntheticValue(); 1245 SetSP(sp, use_dynamic, use_synthetic); 1246 } else 1247 SetSP(sp, use_dynamic, true); 1248 } else 1249 SetSP(sp, use_dynamic, false); 1250 } 1251 1252 void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) { 1253 if (sp) { 1254 lldb::TargetSP target_sp(sp->GetTargetSP()); 1255 if (target_sp) { 1256 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); 1257 SetSP(sp, use_dynamic, use_synthetic); 1258 } else 1259 SetSP(sp, eNoDynamicValues, use_synthetic); 1260 } else 1261 SetSP(sp, eNoDynamicValues, use_synthetic); 1262 } 1263 1264 void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1265 lldb::DynamicValueType use_dynamic, bool use_synthetic) { 1266 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); 1267 } 1268 1269 void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1270 lldb::DynamicValueType use_dynamic, bool use_synthetic, 1271 const char *name) { 1272 m_opaque_sp = 1273 ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name)); 1274 } 1275 1276 bool SBValue::GetExpressionPath(SBStream &description) { 1277 ValueLocker locker; 1278 lldb::ValueObjectSP value_sp(GetSP(locker)); 1279 if (value_sp) { 1280 value_sp->GetExpressionPath(description.ref(), false); 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 bool SBValue::GetExpressionPath(SBStream &description, 1287 bool qualify_cxx_base_classes) { 1288 ValueLocker locker; 1289 lldb::ValueObjectSP value_sp(GetSP(locker)); 1290 if (value_sp) { 1291 value_sp->GetExpressionPath(description.ref(), qualify_cxx_base_classes); 1292 return true; 1293 } 1294 return false; 1295 } 1296 1297 bool SBValue::GetDescription(SBStream &description) { 1298 Stream &strm = description.ref(); 1299 1300 ValueLocker locker; 1301 lldb::ValueObjectSP value_sp(GetSP(locker)); 1302 if (value_sp) 1303 value_sp->Dump(strm); 1304 else 1305 strm.PutCString("No value"); 1306 1307 return true; 1308 } 1309 1310 lldb::Format SBValue::GetFormat() { 1311 ValueLocker locker; 1312 lldb::ValueObjectSP value_sp(GetSP(locker)); 1313 if (value_sp) 1314 return value_sp->GetFormat(); 1315 return eFormatDefault; 1316 } 1317 1318 void SBValue::SetFormat(lldb::Format format) { 1319 ValueLocker locker; 1320 lldb::ValueObjectSP value_sp(GetSP(locker)); 1321 if (value_sp) 1322 value_sp->SetFormat(format); 1323 } 1324 1325 lldb::SBValue SBValue::AddressOf() { 1326 SBValue sb_value; 1327 ValueLocker locker; 1328 lldb::ValueObjectSP value_sp(GetSP(locker)); 1329 if (value_sp) { 1330 Status error; 1331 sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(), 1332 GetPreferSyntheticValue()); 1333 } 1334 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1335 if (log) 1336 log->Printf("SBValue(%p)::AddressOf () => SBValue(%p)", 1337 static_cast<void *>(value_sp.get()), 1338 static_cast<void *>(value_sp.get())); 1339 1340 return sb_value; 1341 } 1342 1343 lldb::addr_t SBValue::GetLoadAddress() { 1344 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1345 ValueLocker locker; 1346 lldb::ValueObjectSP value_sp(GetSP(locker)); 1347 if (value_sp) { 1348 TargetSP target_sp(value_sp->GetTargetSP()); 1349 if (target_sp) { 1350 const bool scalar_is_load_address = true; 1351 AddressType addr_type; 1352 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1353 if (addr_type == eAddressTypeFile) { 1354 ModuleSP module_sp(value_sp->GetModule()); 1355 if (!module_sp) 1356 value = LLDB_INVALID_ADDRESS; 1357 else { 1358 Address addr; 1359 module_sp->ResolveFileAddress(value, addr); 1360 value = addr.GetLoadAddress(target_sp.get()); 1361 } 1362 } else if (addr_type == eAddressTypeHost || 1363 addr_type == eAddressTypeInvalid) 1364 value = LLDB_INVALID_ADDRESS; 1365 } 1366 } 1367 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1368 if (log) 1369 log->Printf("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")", 1370 static_cast<void *>(value_sp.get()), value); 1371 1372 return value; 1373 } 1374 1375 lldb::SBAddress SBValue::GetAddress() { 1376 Address addr; 1377 ValueLocker locker; 1378 lldb::ValueObjectSP value_sp(GetSP(locker)); 1379 if (value_sp) { 1380 TargetSP target_sp(value_sp->GetTargetSP()); 1381 if (target_sp) { 1382 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1383 const bool scalar_is_load_address = true; 1384 AddressType addr_type; 1385 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1386 if (addr_type == eAddressTypeFile) { 1387 ModuleSP module_sp(value_sp->GetModule()); 1388 if (module_sp) 1389 module_sp->ResolveFileAddress(value, addr); 1390 } else if (addr_type == eAddressTypeLoad) { 1391 // no need to check the return value on this.. if it can actually do 1392 // the resolve addr will be in the form (section,offset), otherwise it 1393 // will simply be returned as (NULL, value) 1394 addr.SetLoadAddress(value, target_sp.get()); 1395 } 1396 } 1397 } 1398 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1399 if (log) 1400 log->Printf("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", 1401 static_cast<void *>(value_sp.get()), 1402 (addr.GetSection() ? addr.GetSection()->GetName().GetCString() 1403 : "NULL"), 1404 addr.GetOffset()); 1405 return SBAddress(new Address(addr)); 1406 } 1407 1408 lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) { 1409 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1410 lldb::SBData sb_data; 1411 ValueLocker locker; 1412 lldb::ValueObjectSP value_sp(GetSP(locker)); 1413 if (value_sp) { 1414 TargetSP target_sp(value_sp->GetTargetSP()); 1415 if (target_sp) { 1416 DataExtractorSP data_sp(new DataExtractor()); 1417 value_sp->GetPointeeData(*data_sp, item_idx, item_count); 1418 if (data_sp->GetByteSize() > 0) 1419 *sb_data = data_sp; 1420 } 1421 } 1422 if (log) 1423 log->Printf("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", 1424 static_cast<void *>(value_sp.get()), item_idx, item_count, 1425 static_cast<void *>(sb_data.get())); 1426 1427 return sb_data; 1428 } 1429 1430 lldb::SBData SBValue::GetData() { 1431 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1432 lldb::SBData sb_data; 1433 ValueLocker locker; 1434 lldb::ValueObjectSP value_sp(GetSP(locker)); 1435 if (value_sp) { 1436 DataExtractorSP data_sp(new DataExtractor()); 1437 Status error; 1438 value_sp->GetData(*data_sp, error); 1439 if (error.Success()) 1440 *sb_data = data_sp; 1441 } 1442 if (log) 1443 log->Printf("SBValue(%p)::GetData () => SBData(%p)", 1444 static_cast<void *>(value_sp.get()), 1445 static_cast<void *>(sb_data.get())); 1446 1447 return sb_data; 1448 } 1449 1450 bool SBValue::SetData(lldb::SBData &data, SBError &error) { 1451 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1452 ValueLocker locker; 1453 lldb::ValueObjectSP value_sp(GetSP(locker)); 1454 bool ret = true; 1455 1456 if (value_sp) { 1457 DataExtractor *data_extractor = data.get(); 1458 1459 if (!data_extractor) { 1460 if (log) 1461 log->Printf("SBValue(%p)::SetData() => error: no data to set", 1462 static_cast<void *>(value_sp.get())); 1463 1464 error.SetErrorString("No data to set"); 1465 ret = false; 1466 } else { 1467 Status set_error; 1468 1469 value_sp->SetData(*data_extractor, set_error); 1470 1471 if (!set_error.Success()) { 1472 error.SetErrorStringWithFormat("Couldn't set data: %s", 1473 set_error.AsCString()); 1474 ret = false; 1475 } 1476 } 1477 } else { 1478 error.SetErrorStringWithFormat( 1479 "Couldn't set data: could not get SBValue: %s", 1480 locker.GetError().AsCString()); 1481 ret = false; 1482 } 1483 1484 if (log) 1485 log->Printf("SBValue(%p)::SetData (%p) => %s", 1486 static_cast<void *>(value_sp.get()), 1487 static_cast<void *>(data.get()), ret ? "true" : "false"); 1488 return ret; 1489 } 1490 1491 lldb::SBDeclaration SBValue::GetDeclaration() { 1492 ValueLocker locker; 1493 lldb::ValueObjectSP value_sp(GetSP(locker)); 1494 SBDeclaration decl_sb; 1495 if (value_sp) { 1496 Declaration decl; 1497 if (value_sp->GetDeclaration(decl)) 1498 decl_sb.SetDeclaration(decl); 1499 } 1500 return decl_sb; 1501 } 1502 1503 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write, 1504 SBError &error) { 1505 SBWatchpoint sb_watchpoint; 1506 1507 // If the SBValue is not valid, there's no point in even trying to watch it. 1508 ValueLocker locker; 1509 lldb::ValueObjectSP value_sp(GetSP(locker)); 1510 TargetSP target_sp(GetTarget().GetSP()); 1511 if (value_sp && target_sp) { 1512 // Read and Write cannot both be false. 1513 if (!read && !write) 1514 return sb_watchpoint; 1515 1516 // If the value is not in scope, don't try and watch and invalid value 1517 if (!IsInScope()) 1518 return sb_watchpoint; 1519 1520 addr_t addr = GetLoadAddress(); 1521 if (addr == LLDB_INVALID_ADDRESS) 1522 return sb_watchpoint; 1523 size_t byte_size = GetByteSize(); 1524 if (byte_size == 0) 1525 return sb_watchpoint; 1526 1527 uint32_t watch_type = 0; 1528 if (read) 1529 watch_type |= LLDB_WATCH_TYPE_READ; 1530 if (write) 1531 watch_type |= LLDB_WATCH_TYPE_WRITE; 1532 1533 Status rc; 1534 CompilerType type(value_sp->GetCompilerType()); 1535 WatchpointSP watchpoint_sp = 1536 target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); 1537 error.SetError(rc); 1538 1539 if (watchpoint_sp) { 1540 sb_watchpoint.SetSP(watchpoint_sp); 1541 Declaration decl; 1542 if (value_sp->GetDeclaration(decl)) { 1543 if (decl.GetFile()) { 1544 StreamString ss; 1545 // True to show fullpath for declaration file. 1546 decl.DumpStopContext(&ss, true); 1547 watchpoint_sp->SetDeclInfo(ss.GetString()); 1548 } 1549 } 1550 } 1551 } else if (target_sp) { 1552 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1553 if (log) 1554 log->Printf("SBValue(%p)::Watch() => error getting SBValue: %s", 1555 static_cast<void *>(value_sp.get()), 1556 locker.GetError().AsCString()); 1557 1558 error.SetErrorStringWithFormat("could not get SBValue: %s", 1559 locker.GetError().AsCString()); 1560 } else { 1561 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1562 if (log) 1563 log->Printf("SBValue(%p)::Watch() => error getting SBValue: no target", 1564 static_cast<void *>(value_sp.get())); 1565 error.SetErrorString("could not set watchpoint, a target is required"); 1566 } 1567 1568 return sb_watchpoint; 1569 } 1570 1571 // FIXME: Remove this method impl (as well as the decl in .h) once it is no 1572 // longer needed. 1573 // Backward compatibility fix in the interim. 1574 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, 1575 bool write) { 1576 SBError error; 1577 return Watch(resolve_location, read, write, error); 1578 } 1579 1580 lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read, 1581 bool write, SBError &error) { 1582 SBWatchpoint sb_watchpoint; 1583 if (IsInScope() && GetType().IsPointerType()) 1584 sb_watchpoint = Dereference().Watch(resolve_location, read, write, error); 1585 return sb_watchpoint; 1586 } 1587 1588 lldb::SBValue SBValue::Persist() { 1589 ValueLocker locker; 1590 lldb::ValueObjectSP value_sp(GetSP(locker)); 1591 SBValue persisted_sb; 1592 if (value_sp) { 1593 persisted_sb.SetSP(value_sp->Persist()); 1594 } 1595 return persisted_sb; 1596 } 1597