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