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/ClangASTType.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
Value()35 Value::Value() :
36 m_value (),
37 m_vector (),
38 m_clang_type (),
39 m_context (NULL),
40 m_value_type (eValueTypeScalar),
41 m_context_type (eContextTypeInvalid),
42 m_data_buffer ()
43 {
44 }
45
Value(const Scalar & scalar)46 Value::Value(const Scalar& scalar) :
47 m_value (scalar),
48 m_vector (),
49 m_clang_type (),
50 m_context (NULL),
51 m_value_type (eValueTypeScalar),
52 m_context_type (eContextTypeInvalid),
53 m_data_buffer ()
54 {
55 }
56
57
Value(const void * bytes,int len)58 Value::Value(const void *bytes, int len) :
59 m_value (),
60 m_vector (),
61 m_clang_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
Value(const Value & v)70 Value::Value(const Value &v) :
71 m_value (v.m_value),
72 m_vector (v.m_vector),
73 m_clang_type (v.m_clang_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 &
operator =(const Value & rhs)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_clang_type = rhs.m_clang_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
SetBytes(const void * bytes,int len)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
AppendBytes(const void * bytes,int len)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
Dump(Stream * strm)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
GetValueType() const139 Value::GetValueType() const
140 {
141 return m_value_type;
142 }
143
144 AddressType
GetValueAddressType() const145 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 *
GetRegisterInfo() const160 Value::GetRegisterInfo() const
161 {
162 if (m_context_type == eContextTypeRegisterInfo)
163 return static_cast<RegisterInfo *> (m_context);
164 return NULL;
165 }
166
167 Type *
GetType()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
AppendDataToHostBuffer(const Value & rhs)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
ResizeData(size_t len)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
ValueOf(ExecutionContext * exe_ctx)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
GetValueByteSize(Error * error_ptr)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 ClangASTType &ast_type = GetClangType();
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 ClangASTType &
GetClangType()301 Value::GetClangType ()
302 {
303 if (!m_clang_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 clang type?
312
313 case eContextTypeLLDBType:
314 {
315 Type *lldb_type = GetType();
316 if (lldb_type)
317 m_clang_type = lldb_type->GetClangForwardType();
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_clang_type = variable_type->GetClangForwardType();
329 }
330 }
331 break;
332 }
333 }
334
335 return m_clang_type;
336 }
337
338 void
SetClangType(const ClangASTType & clang_type)339 Value::SetClangType (const ClangASTType &clang_type)
340 {
341 m_clang_type = clang_type;
342 }
343
344 lldb::Format
GetValueDefaultFormat()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 ClangASTType &ast_type = GetClangType();
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
GetData(DataExtractor & data)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
GetValueAsData(ExecutionContext * exe_ctx,DataExtractor & data,uint32_t data_offset,Module * module)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 ClangASTType &ast_type = GetClangType();
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 &
ResolveValue(ExecutionContext * exe_ctx)722 Value::ResolveValue(ExecutionContext *exe_ctx)
723 {
724 const ClangASTType &clang_type = GetClangType();
725 if (clang_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 (clang_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 *
GetVariable()773 Value::GetVariable()
774 {
775 if (m_context_type == eContextTypeVariable)
776 return static_cast<Variable *> (m_context);
777 return NULL;
778 }
779
780 void
Clear()781 Value::Clear()
782 {
783 m_value.Clear();
784 m_vector.Clear();
785 m_clang_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 *
GetValueTypeAsCString(ValueType value_type)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 *
GetContextTypeAsCString(ContextType context_type)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
ValueList(const ValueList & rhs)820 ValueList::ValueList (const ValueList &rhs)
821 {
822 m_values = rhs.m_values;
823 }
824
825 const ValueList &
operator =(const ValueList & rhs)826 ValueList::operator= (const ValueList &rhs)
827 {
828 m_values = rhs.m_values;
829 return *this;
830 }
831
832 void
PushValue(const Value & value)833 ValueList::PushValue (const Value &value)
834 {
835 m_values.push_back (value);
836 }
837
838 size_t
GetSize()839 ValueList::GetSize()
840 {
841 return m_values.size();
842 }
843
844 Value *
GetValueAtIndex(size_t idx)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
Clear()856 ValueList::Clear ()
857 {
858 m_values.clear();
859 }
860
861