1 //===-- Value.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/Core/Value.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/DataExtractor.h" 17 #include "lldb/Core/DataBufferHeap.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Core/Stream.h" 21 #include "lldb/Symbol/CompilerType.h" 22 #include "lldb/Symbol/ClangASTContext.h" 23 #include "lldb/Symbol/ObjectFile.h" 24 #include "lldb/Symbol/SymbolContext.h" 25 #include "lldb/Symbol/Type.h" 26 #include "lldb/Symbol/Variable.h" 27 #include "lldb/Target/ExecutionContext.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/SectionLoadList.h" 30 #include "lldb/Target/Target.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 Value::Value() : 36 m_value (), 37 m_vector (), 38 m_compiler_type (), 39 m_context (NULL), 40 m_value_type (eValueTypeScalar), 41 m_context_type (eContextTypeInvalid), 42 m_data_buffer () 43 { 44 } 45 46 Value::Value(const Scalar& scalar) : 47 m_value (scalar), 48 m_vector (), 49 m_compiler_type (), 50 m_context (NULL), 51 m_value_type (eValueTypeScalar), 52 m_context_type (eContextTypeInvalid), 53 m_data_buffer () 54 { 55 } 56 57 58 Value::Value(const void *bytes, int len) : 59 m_value (), 60 m_vector (), 61 m_compiler_type (), 62 m_context (NULL), 63 m_value_type (eValueTypeHostAddress), 64 m_context_type (eContextTypeInvalid), 65 m_data_buffer () 66 { 67 SetBytes(bytes, len); 68 } 69 70 Value::Value(const Value &v) : 71 m_value (v.m_value), 72 m_vector (v.m_vector), 73 m_compiler_type (v.m_compiler_type), 74 m_context (v.m_context), 75 m_value_type (v.m_value_type), 76 m_context_type (v.m_context_type), 77 m_data_buffer () 78 { 79 const uintptr_t rhs_value = (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS); 80 if ((rhs_value != 0) && (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())) 81 { 82 m_data_buffer.CopyData(v.m_data_buffer.GetBytes(), 83 v.m_data_buffer.GetByteSize()); 84 85 m_value = (uintptr_t)m_data_buffer.GetBytes(); 86 } 87 } 88 89 Value & 90 Value::operator=(const Value &rhs) 91 { 92 if (this != &rhs) 93 { 94 m_value = rhs.m_value; 95 m_vector = rhs.m_vector; 96 m_compiler_type = rhs.m_compiler_type; 97 m_context = rhs.m_context; 98 m_value_type = rhs.m_value_type; 99 m_context_type = rhs.m_context_type; 100 const uintptr_t rhs_value = (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS); 101 if ((rhs_value != 0) && (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())) 102 { 103 m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(), 104 rhs.m_data_buffer.GetByteSize()); 105 106 m_value = (uintptr_t)m_data_buffer.GetBytes(); 107 } 108 } 109 return *this; 110 } 111 112 void 113 Value::SetBytes (const void *bytes, int len) 114 { 115 m_value_type = eValueTypeHostAddress; 116 m_data_buffer.CopyData(bytes, len); 117 m_value = (uintptr_t)m_data_buffer.GetBytes(); 118 } 119 120 void 121 Value::AppendBytes (const void *bytes, int len) 122 { 123 m_value_type = eValueTypeHostAddress; 124 m_data_buffer.AppendData (bytes, len); 125 m_value = (uintptr_t)m_data_buffer.GetBytes(); 126 } 127 128 void 129 Value::Dump (Stream* strm) 130 { 131 m_value.GetValue (strm, true); 132 strm->Printf(", value_type = %s, context = %p, context_type = %s", 133 Value::GetValueTypeAsCString(m_value_type), 134 m_context, 135 Value::GetContextTypeAsCString(m_context_type)); 136 } 137 138 Value::ValueType 139 Value::GetValueType() const 140 { 141 return m_value_type; 142 } 143 144 AddressType 145 Value::GetValueAddressType () const 146 { 147 switch (m_value_type) 148 { 149 default: 150 case eValueTypeScalar: 151 break; 152 case eValueTypeLoadAddress: return eAddressTypeLoad; 153 case eValueTypeFileAddress: return eAddressTypeFile; 154 case eValueTypeHostAddress: return eAddressTypeHost; 155 } 156 return eAddressTypeInvalid; 157 } 158 159 RegisterInfo * 160 Value::GetRegisterInfo() const 161 { 162 if (m_context_type == eContextTypeRegisterInfo) 163 return static_cast<RegisterInfo *> (m_context); 164 return NULL; 165 } 166 167 Type * 168 Value::GetType() 169 { 170 if (m_context_type == eContextTypeLLDBType) 171 return static_cast<Type *> (m_context); 172 return NULL; 173 } 174 175 size_t 176 Value::AppendDataToHostBuffer (const Value &rhs) 177 { 178 size_t curr_size = m_data_buffer.GetByteSize(); 179 Error error; 180 switch (rhs.GetValueType()) 181 { 182 case eValueTypeScalar: 183 { 184 const size_t scalar_size = rhs.m_value.GetByteSize(); 185 if (scalar_size > 0) 186 { 187 const size_t new_size = curr_size + scalar_size; 188 if (ResizeData(new_size) == new_size) 189 { 190 rhs.m_value.GetAsMemoryData (m_data_buffer.GetBytes() + curr_size, 191 scalar_size, 192 endian::InlHostByteOrder(), 193 error); 194 return scalar_size; 195 } 196 } 197 } 198 break; 199 case eValueTypeVector: 200 { 201 const size_t vector_size = rhs.m_vector.length; 202 if (vector_size > 0) 203 { 204 const size_t new_size = curr_size + vector_size; 205 if (ResizeData(new_size) == new_size) 206 { 207 ::memcpy (m_data_buffer.GetBytes() + curr_size, 208 rhs.m_vector.bytes, 209 vector_size); 210 return vector_size; 211 } 212 } 213 } 214 break; 215 case eValueTypeFileAddress: 216 case eValueTypeLoadAddress: 217 case eValueTypeHostAddress: 218 { 219 const uint8_t *src = rhs.GetBuffer().GetBytes(); 220 const size_t src_len = rhs.GetBuffer().GetByteSize(); 221 if (src && src_len > 0) 222 { 223 const size_t new_size = curr_size + src_len; 224 if (ResizeData(new_size) == new_size) 225 { 226 ::memcpy (m_data_buffer.GetBytes() + curr_size, src, src_len); 227 return src_len; 228 } 229 } 230 } 231 break; 232 } 233 return 0; 234 } 235 236 size_t 237 Value::ResizeData(size_t len) 238 { 239 m_value_type = eValueTypeHostAddress; 240 m_data_buffer.SetByteSize(len); 241 m_value = (uintptr_t)m_data_buffer.GetBytes(); 242 return m_data_buffer.GetByteSize(); 243 } 244 245 bool 246 Value::ValueOf(ExecutionContext *exe_ctx) 247 { 248 switch (m_context_type) 249 { 250 case eContextTypeInvalid: 251 case eContextTypeRegisterInfo: // RegisterInfo * 252 case eContextTypeLLDBType: // Type * 253 break; 254 255 case eContextTypeVariable: // Variable * 256 ResolveValue(exe_ctx); 257 return true; 258 } 259 return false; 260 } 261 262 uint64_t 263 Value::GetValueByteSize (Error *error_ptr, ExecutionContext *exe_ctx) 264 { 265 uint64_t byte_size = 0; 266 267 switch (m_context_type) 268 { 269 case eContextTypeRegisterInfo: // RegisterInfo * 270 if (GetRegisterInfo()) 271 byte_size = GetRegisterInfo()->byte_size; 272 break; 273 274 case eContextTypeInvalid: 275 case eContextTypeLLDBType: // Type * 276 case eContextTypeVariable: // Variable * 277 { 278 const CompilerType &ast_type = GetCompilerType(); 279 if (ast_type.IsValid()) 280 byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); 281 } 282 break; 283 } 284 285 if (error_ptr) 286 { 287 if (byte_size == 0) 288 { 289 if (error_ptr->Success()) 290 error_ptr->SetErrorString("Unable to determine byte size."); 291 } 292 else 293 { 294 error_ptr->Clear(); 295 } 296 } 297 return byte_size; 298 } 299 300 const CompilerType & 301 Value::GetCompilerType () 302 { 303 if (!m_compiler_type.IsValid()) 304 { 305 switch (m_context_type) 306 { 307 case eContextTypeInvalid: 308 break; 309 310 case eContextTypeRegisterInfo: 311 break; // TODO: Eventually convert into a compiler type? 312 313 case eContextTypeLLDBType: 314 { 315 Type *lldb_type = GetType(); 316 if (lldb_type) 317 m_compiler_type = lldb_type->GetForwardCompilerType (); 318 } 319 break; 320 321 case eContextTypeVariable: 322 { 323 Variable *variable = GetVariable(); 324 if (variable) 325 { 326 Type *variable_type = variable->GetType(); 327 if (variable_type) 328 m_compiler_type = variable_type->GetForwardCompilerType (); 329 } 330 } 331 break; 332 } 333 } 334 335 return m_compiler_type; 336 } 337 338 void 339 Value::SetCompilerType (const CompilerType &compiler_type) 340 { 341 m_compiler_type = compiler_type; 342 } 343 344 lldb::Format 345 Value::GetValueDefaultFormat () 346 { 347 switch (m_context_type) 348 { 349 case eContextTypeRegisterInfo: 350 if (GetRegisterInfo()) 351 return GetRegisterInfo()->format; 352 break; 353 354 case eContextTypeInvalid: 355 case eContextTypeLLDBType: 356 case eContextTypeVariable: 357 { 358 const CompilerType &ast_type = GetCompilerType(); 359 if (ast_type.IsValid()) 360 return ast_type.GetFormat(); 361 } 362 break; 363 364 } 365 366 // Return a good default in case we can't figure anything out 367 return eFormatHex; 368 } 369 370 bool 371 Value::GetData (DataExtractor &data) 372 { 373 switch (m_value_type) 374 { 375 default: 376 break; 377 378 case eValueTypeScalar: 379 if (m_value.GetData (data)) 380 return true; 381 break; 382 383 case eValueTypeLoadAddress: 384 case eValueTypeFileAddress: 385 case eValueTypeHostAddress: 386 if (m_data_buffer.GetByteSize()) 387 { 388 data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder()); 389 return true; 390 } 391 break; 392 } 393 394 return false; 395 396 } 397 398 Error 399 Value::GetValueAsData (ExecutionContext *exe_ctx, 400 DataExtractor &data, 401 uint32_t data_offset, 402 Module *module) 403 { 404 data.Clear(); 405 406 Error error; 407 lldb::addr_t address = LLDB_INVALID_ADDRESS; 408 AddressType address_type = eAddressTypeFile; 409 Address file_so_addr; 410 const CompilerType &ast_type = GetCompilerType(); 411 switch (m_value_type) 412 { 413 case eValueTypeVector: 414 if (ast_type.IsValid()) 415 data.SetAddressByteSize (ast_type.GetPointerByteSize()); 416 else 417 data.SetAddressByteSize(sizeof(void *)); 418 data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order); 419 break; 420 421 case eValueTypeScalar: 422 { 423 data.SetByteOrder (endian::InlHostByteOrder()); 424 if (ast_type.IsValid()) 425 data.SetAddressByteSize (ast_type.GetPointerByteSize()); 426 else 427 data.SetAddressByteSize(sizeof(void *)); 428 429 uint32_t limit_byte_size = UINT32_MAX; 430 431 if (ast_type.IsValid()) 432 { 433 limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); 434 } 435 436 if (limit_byte_size <= m_value.GetByteSize()) 437 { 438 if (m_value.GetData (data, limit_byte_size)) 439 return error; // Success; 440 } 441 442 error.SetErrorStringWithFormat("extracting data from value failed"); 443 break; 444 } 445 case eValueTypeLoadAddress: 446 if (exe_ctx == NULL) 447 { 448 error.SetErrorString ("can't read load address (no execution context)"); 449 } 450 else 451 { 452 Process *process = exe_ctx->GetProcessPtr(); 453 if (process == NULL || !process->IsAlive()) 454 { 455 Target *target = exe_ctx->GetTargetPtr(); 456 if (target) 457 { 458 // Allow expressions to run and evaluate things when the target 459 // has memory sections loaded. This allows you to use "target modules load" 460 // to load your executable and any shared libraries, then execute 461 // commands where you can look at types in data sections. 462 const SectionLoadList &target_sections = target->GetSectionLoadList(); 463 if (!target_sections.IsEmpty()) 464 { 465 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 466 if (target_sections.ResolveLoadAddress(address, file_so_addr)) 467 { 468 address_type = eAddressTypeLoad; 469 data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 470 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 471 } 472 else 473 address = LLDB_INVALID_ADDRESS; 474 } 475 // else 476 // { 477 // ModuleSP exe_module_sp (target->GetExecutableModule()); 478 // if (exe_module_sp) 479 // { 480 // address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 481 // if (address != LLDB_INVALID_ADDRESS) 482 // { 483 // if (exe_module_sp->ResolveFileAddress(address, file_so_addr)) 484 // { 485 // data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 486 // data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 487 // address_type = eAddressTypeFile; 488 // } 489 // else 490 // { 491 // address = LLDB_INVALID_ADDRESS; 492 // } 493 // } 494 // } 495 // } 496 } 497 else 498 { 499 error.SetErrorString ("can't read load address (invalid process)"); 500 } 501 } 502 else 503 { 504 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 505 address_type = eAddressTypeLoad; 506 data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder()); 507 data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize()); 508 } 509 } 510 break; 511 512 case eValueTypeFileAddress: 513 if (exe_ctx == NULL) 514 { 515 error.SetErrorString ("can't read file address (no execution context)"); 516 } 517 else if (exe_ctx->GetTargetPtr() == NULL) 518 { 519 error.SetErrorString ("can't read file address (invalid target)"); 520 } 521 else 522 { 523 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 524 if (address == LLDB_INVALID_ADDRESS) 525 { 526 error.SetErrorString ("invalid file address"); 527 } 528 else 529 { 530 if (module == NULL) 531 { 532 // The only thing we can currently lock down to a module so that 533 // we can resolve a file address, is a variable. 534 Variable *variable = GetVariable(); 535 if (variable) 536 { 537 SymbolContext var_sc; 538 variable->CalculateSymbolContext(&var_sc); 539 module = var_sc.module_sp.get(); 540 } 541 } 542 543 if (module) 544 { 545 bool resolved = false; 546 ObjectFile *objfile = module->GetObjectFile(); 547 if (objfile) 548 { 549 Address so_addr(address, objfile->GetSectionList()); 550 addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr()); 551 bool process_launched_and_stopped = exe_ctx->GetProcessPtr() 552 ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */) 553 : false; 554 // Don't use the load address if the process has exited. 555 if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped) 556 { 557 resolved = true; 558 address = load_address; 559 address_type = eAddressTypeLoad; 560 data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder()); 561 data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize()); 562 } 563 else 564 { 565 if (so_addr.IsSectionOffset()) 566 { 567 resolved = true; 568 file_so_addr = so_addr; 569 data.SetByteOrder(objfile->GetByteOrder()); 570 data.SetAddressByteSize(objfile->GetAddressByteSize()); 571 } 572 } 573 } 574 if (!resolved) 575 { 576 Variable *variable = GetVariable(); 577 578 if (module) 579 { 580 if (variable) 581 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s", 582 address, 583 variable->GetName().AsCString(""), 584 module->GetFileSpec().GetPath().c_str()); 585 else 586 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s", 587 address, 588 module->GetFileSpec().GetPath().c_str()); 589 } 590 else 591 { 592 if (variable) 593 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'", 594 address, 595 variable->GetName().AsCString("")); 596 else 597 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address); 598 } 599 } 600 } 601 else 602 { 603 // Can't convert a file address to anything valid without more 604 // context (which Module it came from) 605 error.SetErrorString ("can't read memory from file address without more context"); 606 } 607 } 608 } 609 break; 610 611 case eValueTypeHostAddress: 612 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 613 address_type = eAddressTypeHost; 614 if (exe_ctx) 615 { 616 Target *target = exe_ctx->GetTargetPtr(); 617 if (target) 618 { 619 data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 620 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 621 break; 622 } 623 } 624 // fallback to host settings 625 data.SetByteOrder(endian::InlHostByteOrder()); 626 data.SetAddressByteSize(sizeof(void *)); 627 break; 628 } 629 630 // Bail if we encountered any errors 631 if (error.Fail()) 632 return error; 633 634 if (address == LLDB_INVALID_ADDRESS) 635 { 636 error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load"); 637 return error; 638 } 639 640 // If we got here, we need to read the value from memory 641 size_t byte_size = GetValueByteSize (&error, exe_ctx); 642 643 // Bail if we encountered any errors getting the byte size 644 if (error.Fail()) 645 return error; 646 647 // Make sure we have enough room within "data", and if we don't make 648 // something large enough that does 649 if (!data.ValidOffsetForDataOfSize (data_offset, byte_size)) 650 { 651 DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0')); 652 data.SetData(data_sp); 653 } 654 655 uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size)); 656 if (dst != NULL) 657 { 658 if (address_type == eAddressTypeHost) 659 { 660 // The address is an address in this process, so just copy it. 661 if (address == 0) 662 { 663 error.SetErrorStringWithFormat("trying to read from host address of 0."); 664 return error; 665 } 666 memcpy (dst, (uint8_t*)NULL + address, byte_size); 667 } 668 else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile)) 669 { 670 if (file_so_addr.IsValid()) 671 { 672 // We have a file address that we were able to translate into a 673 // section offset address so we might be able to read this from 674 // the object files if we don't have a live process. Lets always 675 // try and read from the process if we have one though since we 676 // want to read the actual value by setting "prefer_file_cache" 677 // to false. 678 const bool prefer_file_cache = false; 679 if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size) 680 { 681 error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address); 682 } 683 } 684 else 685 { 686 // The execution context might have a NULL process, but it 687 // might have a valid process in the exe_ctx->target, so use 688 // the ExecutionContext::GetProcess accessor to ensure we 689 // get the process if there is one. 690 Process *process = exe_ctx->GetProcessPtr(); 691 692 if (process) 693 { 694 const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error); 695 if (bytes_read != byte_size) 696 error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)", 697 (uint64_t)address, 698 (uint32_t)bytes_read, 699 (uint32_t)byte_size); 700 } 701 else 702 { 703 error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address); 704 } 705 } 706 } 707 else 708 { 709 error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type); 710 } 711 } 712 else 713 { 714 error.SetErrorStringWithFormat ("out of memory"); 715 } 716 717 return error; 718 } 719 720 Scalar & 721 Value::ResolveValue(ExecutionContext *exe_ctx) 722 { 723 const CompilerType &compiler_type = GetCompilerType(); 724 if (compiler_type.IsValid()) 725 { 726 switch (m_value_type) 727 { 728 case eValueTypeScalar: // raw scalar value 729 break; 730 731 default: 732 case eValueTypeFileAddress: 733 case eValueTypeLoadAddress: // load address value 734 case eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb) 735 { 736 DataExtractor data; 737 lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS); 738 Error error (GetValueAsData (exe_ctx, data, 0, NULL)); 739 if (error.Success()) 740 { 741 Scalar scalar; 742 if (compiler_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar)) 743 { 744 m_value = scalar; 745 m_value_type = eValueTypeScalar; 746 } 747 else 748 { 749 if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) 750 { 751 m_value.Clear(); 752 m_value_type = eValueTypeScalar; 753 } 754 } 755 } 756 else 757 { 758 if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) 759 { 760 m_value.Clear(); 761 m_value_type = eValueTypeScalar; 762 } 763 } 764 } 765 break; 766 } 767 } 768 return m_value; 769 } 770 771 Variable * 772 Value::GetVariable() 773 { 774 if (m_context_type == eContextTypeVariable) 775 return static_cast<Variable *> (m_context); 776 return NULL; 777 } 778 779 void 780 Value::Clear() 781 { 782 m_value.Clear(); 783 m_vector.Clear(); 784 m_compiler_type.Clear(); 785 m_value_type = eValueTypeScalar; 786 m_context = NULL; 787 m_context_type = eContextTypeInvalid; 788 m_data_buffer.Clear(); 789 } 790 791 792 const char * 793 Value::GetValueTypeAsCString (ValueType value_type) 794 { 795 switch (value_type) 796 { 797 case eValueTypeScalar: return "scalar"; 798 case eValueTypeVector: return "vector"; 799 case eValueTypeFileAddress: return "file address"; 800 case eValueTypeLoadAddress: return "load address"; 801 case eValueTypeHostAddress: return "host address"; 802 }; 803 return "???"; 804 } 805 806 const char * 807 Value::GetContextTypeAsCString (ContextType context_type) 808 { 809 switch (context_type) 810 { 811 case eContextTypeInvalid: return "invalid"; 812 case eContextTypeRegisterInfo: return "RegisterInfo *"; 813 case eContextTypeLLDBType: return "Type *"; 814 case eContextTypeVariable: return "Variable *"; 815 }; 816 return "???"; 817 } 818 819 ValueList::ValueList (const ValueList &rhs) 820 { 821 m_values = rhs.m_values; 822 } 823 824 const ValueList & 825 ValueList::operator= (const ValueList &rhs) 826 { 827 m_values = rhs.m_values; 828 return *this; 829 } 830 831 void 832 ValueList::PushValue (const Value &value) 833 { 834 m_values.push_back (value); 835 } 836 837 size_t 838 ValueList::GetSize() 839 { 840 return m_values.size(); 841 } 842 843 Value * 844 ValueList::GetValueAtIndex (size_t idx) 845 { 846 if (idx < GetSize()) 847 { 848 return &(m_values[idx]); 849 } 850 else 851 return NULL; 852 } 853 854 void 855 ValueList::Clear () 856 { 857 m_values.clear(); 858 } 859 860