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 lldb::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) 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(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 (lldb::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() && ast_type.IsScalarType()) 432 { 433 uint64_t type_encoding_count = 0; 434 lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count); 435 436 if (type_encoding == eEncodingUint || type_encoding == eEncodingSint) 437 limit_byte_size = ast_type.GetByteSize(nullptr); 438 } 439 440 if (m_value.GetData (data, limit_byte_size)) 441 return error; // Success; 442 443 error.SetErrorStringWithFormat("extracting data from value failed"); 444 break; 445 } 446 case eValueTypeLoadAddress: 447 if (exe_ctx == NULL) 448 { 449 error.SetErrorString ("can't read load address (no execution context)"); 450 } 451 else 452 { 453 Process *process = exe_ctx->GetProcessPtr(); 454 if (process == NULL || !process->IsAlive()) 455 { 456 Target *target = exe_ctx->GetTargetPtr(); 457 if (target) 458 { 459 // Allow expressions to run and evaluate things when the target 460 // has memory sections loaded. This allows you to use "target modules load" 461 // to load your executable and any shared libraries, then execute 462 // commands where you can look at types in data sections. 463 const SectionLoadList &target_sections = target->GetSectionLoadList(); 464 if (!target_sections.IsEmpty()) 465 { 466 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 467 if (target_sections.ResolveLoadAddress(address, file_so_addr)) 468 { 469 address_type = eAddressTypeLoad; 470 data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 471 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 472 } 473 else 474 address = LLDB_INVALID_ADDRESS; 475 } 476 // else 477 // { 478 // ModuleSP exe_module_sp (target->GetExecutableModule()); 479 // if (exe_module_sp) 480 // { 481 // address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 482 // if (address != LLDB_INVALID_ADDRESS) 483 // { 484 // if (exe_module_sp->ResolveFileAddress(address, file_so_addr)) 485 // { 486 // data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 487 // data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 488 // address_type = eAddressTypeFile; 489 // } 490 // else 491 // { 492 // address = LLDB_INVALID_ADDRESS; 493 // } 494 // } 495 // } 496 // } 497 } 498 else 499 { 500 error.SetErrorString ("can't read load address (invalid process)"); 501 } 502 } 503 else 504 { 505 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 506 address_type = eAddressTypeLoad; 507 data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder()); 508 data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize()); 509 } 510 } 511 break; 512 513 case eValueTypeFileAddress: 514 if (exe_ctx == NULL) 515 { 516 error.SetErrorString ("can't read file address (no execution context)"); 517 } 518 else if (exe_ctx->GetTargetPtr() == NULL) 519 { 520 error.SetErrorString ("can't read file address (invalid target)"); 521 } 522 else 523 { 524 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 525 if (address == LLDB_INVALID_ADDRESS) 526 { 527 error.SetErrorString ("invalid file address"); 528 } 529 else 530 { 531 if (module == NULL) 532 { 533 // The only thing we can currently lock down to a module so that 534 // we can resolve a file address, is a variable. 535 Variable *variable = GetVariable(); 536 if (variable) 537 { 538 SymbolContext var_sc; 539 variable->CalculateSymbolContext(&var_sc); 540 module = var_sc.module_sp.get(); 541 } 542 } 543 544 if (module) 545 { 546 bool resolved = false; 547 ObjectFile *objfile = module->GetObjectFile(); 548 if (objfile) 549 { 550 Address so_addr(address, objfile->GetSectionList()); 551 addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr()); 552 bool process_launched_and_stopped = exe_ctx->GetProcessPtr() 553 ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */) 554 : false; 555 // Don't use the load address if the process has exited. 556 if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped) 557 { 558 resolved = true; 559 address = load_address; 560 address_type = eAddressTypeLoad; 561 data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder()); 562 data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize()); 563 } 564 else 565 { 566 if (so_addr.IsSectionOffset()) 567 { 568 resolved = true; 569 file_so_addr = so_addr; 570 data.SetByteOrder(objfile->GetByteOrder()); 571 data.SetAddressByteSize(objfile->GetAddressByteSize()); 572 } 573 } 574 } 575 if (!resolved) 576 { 577 Variable *variable = GetVariable(); 578 579 if (module) 580 { 581 if (variable) 582 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s", 583 address, 584 variable->GetName().AsCString(""), 585 module->GetFileSpec().GetPath().c_str()); 586 else 587 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s", 588 address, 589 module->GetFileSpec().GetPath().c_str()); 590 } 591 else 592 { 593 if (variable) 594 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'", 595 address, 596 variable->GetName().AsCString("")); 597 else 598 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address); 599 } 600 } 601 } 602 else 603 { 604 // Can't convert a file address to anything valid without more 605 // context (which Module it came from) 606 error.SetErrorString ("can't read memory from file address without more context"); 607 } 608 } 609 } 610 break; 611 612 case eValueTypeHostAddress: 613 address = m_value.ULongLong(LLDB_INVALID_ADDRESS); 614 address_type = eAddressTypeHost; 615 if (exe_ctx) 616 { 617 Target *target = exe_ctx->GetTargetPtr(); 618 if (target) 619 { 620 data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 621 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 622 break; 623 } 624 } 625 // fallback to host settings 626 data.SetByteOrder(lldb::endian::InlHostByteOrder()); 627 data.SetAddressByteSize(sizeof(void *)); 628 break; 629 } 630 631 // Bail if we encountered any errors 632 if (error.Fail()) 633 return error; 634 635 if (address == LLDB_INVALID_ADDRESS) 636 { 637 error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load"); 638 return error; 639 } 640 641 // If we got here, we need to read the value from memory 642 size_t byte_size = GetValueByteSize (&error); 643 644 // Bail if we encountered any errors getting the byte size 645 if (error.Fail()) 646 return error; 647 648 // Make sure we have enough room within "data", and if we don't make 649 // something large enough that does 650 if (!data.ValidOffsetForDataOfSize (data_offset, byte_size)) 651 { 652 DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0')); 653 data.SetData(data_sp); 654 } 655 656 uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size)); 657 if (dst != NULL) 658 { 659 if (address_type == eAddressTypeHost) 660 { 661 // The address is an address in this process, so just copy it. 662 if (address == 0) 663 { 664 error.SetErrorStringWithFormat("trying to read from host address of 0."); 665 return error; 666 } 667 memcpy (dst, (uint8_t*)NULL + address, byte_size); 668 } 669 else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile)) 670 { 671 if (file_so_addr.IsValid()) 672 { 673 // We have a file address that we were able to translate into a 674 // section offset address so we might be able to read this from 675 // the object files if we don't have a live process. Lets always 676 // try and read from the process if we have one though since we 677 // want to read the actual value by setting "prefer_file_cache" 678 // to false. 679 const bool prefer_file_cache = false; 680 if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size) 681 { 682 error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address); 683 } 684 } 685 else 686 { 687 // The execution context might have a NULL process, but it 688 // might have a valid process in the exe_ctx->target, so use 689 // the ExecutionContext::GetProcess accessor to ensure we 690 // get the process if there is one. 691 Process *process = exe_ctx->GetProcessPtr(); 692 693 if (process) 694 { 695 const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error); 696 if (bytes_read != byte_size) 697 error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)", 698 (uint64_t)address, 699 (uint32_t)bytes_read, 700 (uint32_t)byte_size); 701 } 702 else 703 { 704 error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address); 705 } 706 } 707 } 708 else 709 { 710 error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type); 711 } 712 } 713 else 714 { 715 error.SetErrorStringWithFormat ("out of memory"); 716 } 717 718 return error; 719 } 720 721 Scalar & 722 Value::ResolveValue(ExecutionContext *exe_ctx) 723 { 724 const CompilerType &compiler_type = GetCompilerType(); 725 if (compiler_type.IsValid()) 726 { 727 switch (m_value_type) 728 { 729 case eValueTypeScalar: // raw scalar value 730 break; 731 732 default: 733 case eValueTypeFileAddress: 734 case eValueTypeLoadAddress: // load address value 735 case eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb) 736 { 737 DataExtractor data; 738 lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS); 739 Error error (GetValueAsData (exe_ctx, data, 0, NULL)); 740 if (error.Success()) 741 { 742 Scalar scalar; 743 if (compiler_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar)) 744 { 745 m_value = scalar; 746 m_value_type = eValueTypeScalar; 747 } 748 else 749 { 750 if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) 751 { 752 m_value.Clear(); 753 m_value_type = eValueTypeScalar; 754 } 755 } 756 } 757 else 758 { 759 if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) 760 { 761 m_value.Clear(); 762 m_value_type = eValueTypeScalar; 763 } 764 } 765 } 766 break; 767 } 768 } 769 return m_value; 770 } 771 772 Variable * 773 Value::GetVariable() 774 { 775 if (m_context_type == eContextTypeVariable) 776 return static_cast<Variable *> (m_context); 777 return NULL; 778 } 779 780 void 781 Value::Clear() 782 { 783 m_value.Clear(); 784 m_vector.Clear(); 785 m_compiler_type.Clear(); 786 m_value_type = eValueTypeScalar; 787 m_context = NULL; 788 m_context_type = eContextTypeInvalid; 789 m_data_buffer.Clear(); 790 } 791 792 793 const char * 794 Value::GetValueTypeAsCString (ValueType value_type) 795 { 796 switch (value_type) 797 { 798 case eValueTypeScalar: return "scalar"; 799 case eValueTypeVector: return "vector"; 800 case eValueTypeFileAddress: return "file address"; 801 case eValueTypeLoadAddress: return "load address"; 802 case eValueTypeHostAddress: return "host address"; 803 }; 804 return "???"; 805 } 806 807 const char * 808 Value::GetContextTypeAsCString (ContextType context_type) 809 { 810 switch (context_type) 811 { 812 case eContextTypeInvalid: return "invalid"; 813 case eContextTypeRegisterInfo: return "RegisterInfo *"; 814 case eContextTypeLLDBType: return "Type *"; 815 case eContextTypeVariable: return "Variable *"; 816 }; 817 return "???"; 818 } 819 820 ValueList::ValueList (const ValueList &rhs) 821 { 822 m_values = rhs.m_values; 823 } 824 825 const ValueList & 826 ValueList::operator= (const ValueList &rhs) 827 { 828 m_values = rhs.m_values; 829 return *this; 830 } 831 832 void 833 ValueList::PushValue (const Value &value) 834 { 835 m_values.push_back (value); 836 } 837 838 size_t 839 ValueList::GetSize() 840 { 841 return m_values.size(); 842 } 843 844 Value * 845 ValueList::GetValueAtIndex (size_t idx) 846 { 847 if (idx < GetSize()) 848 { 849 return &(m_values[idx]); 850 } 851 else 852 return NULL; 853 } 854 855 void 856 ValueList::Clear () 857 { 858 m_values.clear(); 859 } 860 861