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 
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 
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 
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 
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 &
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
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 void
176 Value::ResizeData(size_t len)
177 {
178     m_value_type = eValueTypeHostAddress;
179     m_data_buffer.SetByteSize(len);
180     m_value = (uintptr_t)m_data_buffer.GetBytes();
181 }
182 
183 bool
184 Value::ValueOf(ExecutionContext *exe_ctx)
185 {
186     switch (m_context_type)
187     {
188     case eContextTypeInvalid:
189     case eContextTypeRegisterInfo:      // RegisterInfo *
190     case eContextTypeLLDBType:          // Type *
191         break;
192 
193     case eContextTypeVariable:          // Variable *
194         ResolveValue(exe_ctx);
195         return true;
196     }
197     return false;
198 }
199 
200 uint64_t
201 Value::GetValueByteSize (Error *error_ptr)
202 {
203     uint64_t byte_size = 0;
204 
205     switch (m_context_type)
206     {
207     case eContextTypeRegisterInfo:     // RegisterInfo *
208         if (GetRegisterInfo())
209             byte_size = GetRegisterInfo()->byte_size;
210         break;
211 
212     case eContextTypeInvalid:
213     case eContextTypeLLDBType:         // Type *
214     case eContextTypeVariable:         // Variable *
215         {
216             const ClangASTType &ast_type = GetClangType();
217             if (ast_type.IsValid())
218                 byte_size = ast_type.GetByteSize();
219         }
220         break;
221     }
222 
223     if (error_ptr)
224     {
225         if (byte_size == 0)
226         {
227             if (error_ptr->Success())
228                 error_ptr->SetErrorString("Unable to determine byte size.");
229         }
230         else
231         {
232             error_ptr->Clear();
233         }
234     }
235     return byte_size;
236 }
237 
238 const ClangASTType &
239 Value::GetClangType ()
240 {
241     if (!m_clang_type.IsValid())
242     {
243         switch (m_context_type)
244         {
245         case eContextTypeInvalid:
246             break;
247 
248         case eContextTypeRegisterInfo:
249             break;    // TODO: Eventually convert into a clang type?
250 
251         case eContextTypeLLDBType:
252             {
253                 Type *lldb_type = GetType();
254                 if (lldb_type)
255                     m_clang_type = lldb_type->GetClangForwardType();
256             }
257             break;
258 
259         case eContextTypeVariable:
260             {
261                 Variable *variable = GetVariable();
262                 if (variable)
263                 {
264                     Type *variable_type = variable->GetType();
265                     if (variable_type)
266                         m_clang_type = variable_type->GetClangForwardType();
267                 }
268             }
269             break;
270         }
271     }
272 
273     return m_clang_type;
274 }
275 
276 void
277 Value::SetClangType (const ClangASTType &clang_type)
278 {
279     m_clang_type = clang_type;
280 }
281 
282 lldb::Format
283 Value::GetValueDefaultFormat ()
284 {
285     switch (m_context_type)
286     {
287     case eContextTypeRegisterInfo:
288         if (GetRegisterInfo())
289             return GetRegisterInfo()->format;
290         break;
291 
292     case eContextTypeInvalid:
293     case eContextTypeLLDBType:
294     case eContextTypeVariable:
295         {
296             const ClangASTType &ast_type = GetClangType();
297             if (ast_type.IsValid())
298                 return ast_type.GetFormat();
299         }
300         break;
301 
302     }
303 
304     // Return a good default in case we can't figure anything out
305     return eFormatHex;
306 }
307 
308 bool
309 Value::GetData (DataExtractor &data)
310 {
311     switch (m_value_type)
312     {
313     default:
314         break;
315 
316     case eValueTypeScalar:
317         if (m_value.GetData (data))
318             return true;
319         break;
320 
321     case eValueTypeLoadAddress:
322     case eValueTypeFileAddress:
323     case eValueTypeHostAddress:
324         if (m_data_buffer.GetByteSize())
325         {
326             data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder());
327             return true;
328         }
329         break;
330     }
331 
332     return false;
333 
334 }
335 
336 Error
337 Value::GetValueAsData (ExecutionContext *exe_ctx,
338                        DataExtractor &data,
339                        uint32_t data_offset,
340                        Module *module)
341 {
342     data.Clear();
343 
344     Error error;
345     lldb::addr_t address = LLDB_INVALID_ADDRESS;
346     AddressType address_type = eAddressTypeFile;
347     Address file_so_addr;
348     const ClangASTType &ast_type = GetClangType();
349     switch (m_value_type)
350     {
351     case eValueTypeVector:
352         if (ast_type.IsValid())
353             data.SetAddressByteSize (ast_type.GetPointerByteSize());
354         else
355             data.SetAddressByteSize(sizeof(void *));
356         data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
357         break;
358 
359     case eValueTypeScalar:
360         {
361             data.SetByteOrder (lldb::endian::InlHostByteOrder());
362             if (ast_type.IsValid())
363                 data.SetAddressByteSize (ast_type.GetPointerByteSize());
364             else
365                 data.SetAddressByteSize(sizeof(void *));
366 
367             uint32_t limit_byte_size = UINT32_MAX;
368 
369             if (ast_type.IsValid() && ast_type.IsScalarType())
370             {
371                 uint64_t type_encoding_count = 0;
372                 lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count);
373 
374                 if (type_encoding == eEncodingUint || type_encoding == eEncodingSint)
375                     limit_byte_size = ast_type.GetByteSize();
376             }
377 
378             if (m_value.GetData (data, limit_byte_size))
379                 return error;   // Success;
380 
381             error.SetErrorStringWithFormat("extracting data from value failed");
382             break;
383         }
384     case eValueTypeLoadAddress:
385         if (exe_ctx == NULL)
386         {
387             error.SetErrorString ("can't read load address (no execution context)");
388         }
389         else
390         {
391             Process *process = exe_ctx->GetProcessPtr();
392             if (process == NULL || !process->IsAlive())
393             {
394                 Target *target = exe_ctx->GetTargetPtr();
395                 if (target)
396                 {
397                     // Allow expressions to run and evaluate things when the target
398                     // has memory sections loaded. This allows you to use "target modules load"
399                     // to load your executable and any shared libraries, then execute
400                     // commands where you can look at types in data sections.
401                     const SectionLoadList &target_sections = target->GetSectionLoadList();
402                     if (!target_sections.IsEmpty())
403                     {
404                         address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
405                         if (target_sections.ResolveLoadAddress(address, file_so_addr))
406                         {
407                             address_type = eAddressTypeLoad;
408                             data.SetByteOrder(target->GetArchitecture().GetByteOrder());
409                             data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
410                         }
411                         else
412                             address = LLDB_INVALID_ADDRESS;
413                     }
414 //                    else
415 //                    {
416 //                        ModuleSP exe_module_sp (target->GetExecutableModule());
417 //                        if (exe_module_sp)
418 //                        {
419 //                            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
420 //                            if (address != LLDB_INVALID_ADDRESS)
421 //                            {
422 //                                if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
423 //                                {
424 //                                    data.SetByteOrder(target->GetArchitecture().GetByteOrder());
425 //                                    data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
426 //                                    address_type = eAddressTypeFile;
427 //                                }
428 //                                else
429 //                                {
430 //                                    address = LLDB_INVALID_ADDRESS;
431 //                                }
432 //                            }
433 //                        }
434 //                    }
435                 }
436                 else
437                 {
438                     error.SetErrorString ("can't read load address (invalid process)");
439                 }
440             }
441             else
442             {
443                 address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
444                 address_type = eAddressTypeLoad;
445                 data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
446                 data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
447             }
448         }
449         break;
450 
451     case eValueTypeFileAddress:
452         if (exe_ctx == NULL)
453         {
454             error.SetErrorString ("can't read file address (no execution context)");
455         }
456         else if (exe_ctx->GetTargetPtr() == NULL)
457         {
458             error.SetErrorString ("can't read file address (invalid target)");
459         }
460         else
461         {
462             address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
463             if (address == LLDB_INVALID_ADDRESS)
464             {
465                 error.SetErrorString ("invalid file address");
466             }
467             else
468             {
469                 if (module == NULL)
470                 {
471                     // The only thing we can currently lock down to a module so that
472                     // we can resolve a file address, is a variable.
473                     Variable *variable = GetVariable();
474                     if (variable)
475                     {
476                         SymbolContext var_sc;
477                         variable->CalculateSymbolContext(&var_sc);
478                         module = var_sc.module_sp.get();
479                     }
480                 }
481 
482                 if (module)
483                 {
484                     bool resolved = false;
485                     ObjectFile *objfile = module->GetObjectFile();
486                     if (objfile)
487                     {
488                         Address so_addr(address, objfile->GetSectionList());
489                         addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
490                         bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
491                             ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
492                             : false;
493                         // Don't use the load address if the process has exited.
494                         if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
495                         {
496                             resolved = true;
497                             address = load_address;
498                             address_type = eAddressTypeLoad;
499                             data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
500                             data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
501                         }
502                         else
503                         {
504                             if (so_addr.IsSectionOffset())
505                             {
506                                 resolved = true;
507                                 file_so_addr = so_addr;
508                                 data.SetByteOrder(objfile->GetByteOrder());
509                                 data.SetAddressByteSize(objfile->GetAddressByteSize());
510                             }
511                         }
512                     }
513                     if (!resolved)
514                     {
515                         Variable *variable = GetVariable();
516 
517                         if (module)
518                         {
519                             if (variable)
520                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s",
521                                                                 address,
522                                                                 variable->GetName().AsCString(""),
523                                                                 module->GetFileSpec().GetPath().c_str());
524                             else
525                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s",
526                                                                 address,
527                                                                 module->GetFileSpec().GetPath().c_str());
528                         }
529                         else
530                         {
531                             if (variable)
532                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'",
533                                                                 address,
534                                                                 variable->GetName().AsCString(""));
535                             else
536                                 error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address);
537                         }
538                     }
539                 }
540                 else
541                 {
542                     // Can't convert a file address to anything valid without more
543                     // context (which Module it came from)
544                     error.SetErrorString ("can't read memory from file address without more context");
545                 }
546             }
547         }
548         break;
549 
550     case eValueTypeHostAddress:
551         address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
552         address_type = eAddressTypeHost;
553         if (exe_ctx)
554         {
555             Target *target = exe_ctx->GetTargetPtr();
556             if (target)
557             {
558                 data.SetByteOrder(target->GetArchitecture().GetByteOrder());
559                 data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
560                 break;
561             }
562         }
563         // fallback to host settings
564         data.SetByteOrder(lldb::endian::InlHostByteOrder());
565         data.SetAddressByteSize(sizeof(void *));
566         break;
567     }
568 
569     // Bail if we encountered any errors
570     if (error.Fail())
571         return error;
572 
573     if (address == LLDB_INVALID_ADDRESS)
574     {
575         error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
576         return error;
577     }
578 
579     // If we got here, we need to read the value from memory
580     size_t byte_size = GetValueByteSize (&error);
581 
582     // Bail if we encountered any errors getting the byte size
583     if (error.Fail())
584         return error;
585 
586     // Make sure we have enough room within "data", and if we don't make
587     // something large enough that does
588     if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
589     {
590         DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
591         data.SetData(data_sp);
592     }
593 
594     uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
595     if (dst != NULL)
596     {
597         if (address_type == eAddressTypeHost)
598         {
599             // The address is an address in this process, so just copy it.
600             if (address == 0)
601             {
602                 error.SetErrorStringWithFormat("trying to read from host address of 0.");
603                 return error;
604             }
605             memcpy (dst, (uint8_t*)NULL + address, byte_size);
606         }
607         else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
608         {
609             if (file_so_addr.IsValid())
610             {
611                 // We have a file address that we were able to translate into a
612                 // section offset address so we might be able to read this from
613                 // the object files if we don't have a live process. Lets always
614                 // try and read from the process if we have one though since we
615                 // want to read the actual value by setting "prefer_file_cache"
616                 // to false.
617                 const bool prefer_file_cache = false;
618                 if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
619                 {
620                     error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address);
621                 }
622             }
623             else
624             {
625                 // The execution context might have a NULL process, but it
626                 // might have a valid process in the exe_ctx->target, so use
627                 // the ExecutionContext::GetProcess accessor to ensure we
628                 // get the process if there is one.
629                 Process *process = exe_ctx->GetProcessPtr();
630 
631                 if (process)
632                 {
633                     const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
634                     if (bytes_read != byte_size)
635                         error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
636                                                        (uint64_t)address,
637                                                        (uint32_t)bytes_read,
638                                                        (uint32_t)byte_size);
639                 }
640                 else
641                 {
642                     error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address);
643                 }
644             }
645         }
646         else
647         {
648             error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
649         }
650     }
651     else
652     {
653         error.SetErrorStringWithFormat ("out of memory");
654     }
655 
656     return error;
657 }
658 
659 Scalar &
660 Value::ResolveValue(ExecutionContext *exe_ctx)
661 {
662     const ClangASTType &clang_type = GetClangType();
663     if (clang_type.IsValid())
664     {
665         switch (m_value_type)
666         {
667         case eValueTypeScalar:               // raw scalar value
668             break;
669 
670         default:
671         case eValueTypeFileAddress:
672         case eValueTypeLoadAddress:          // load address value
673         case eValueTypeHostAddress:          // host address value (for memory in the process that is using liblldb)
674             {
675                 DataExtractor data;
676                 lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
677                 Error error (GetValueAsData (exe_ctx, data, 0, NULL));
678                 if (error.Success())
679                 {
680                     Scalar scalar;
681                     if (clang_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar))
682                     {
683                         m_value = scalar;
684                         m_value_type = eValueTypeScalar;
685                     }
686                     else
687                     {
688                         if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
689                         {
690                             m_value.Clear();
691                             m_value_type = eValueTypeScalar;
692                         }
693                     }
694                 }
695                 else
696                 {
697                     if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
698                     {
699                         m_value.Clear();
700                         m_value_type = eValueTypeScalar;
701                     }
702                 }
703             }
704             break;
705         }
706     }
707     return m_value;
708 }
709 
710 Variable *
711 Value::GetVariable()
712 {
713     if (m_context_type == eContextTypeVariable)
714         return static_cast<Variable *> (m_context);
715     return NULL;
716 }
717 
718 void
719 Value::Clear()
720 {
721     m_value.Clear();
722     m_vector.Clear();
723     m_clang_type.Clear();
724     m_value_type = eValueTypeScalar;
725     m_context = NULL;
726     m_context_type = eContextTypeInvalid;
727     m_data_buffer.Clear();
728 }
729 
730 
731 const char *
732 Value::GetValueTypeAsCString (ValueType value_type)
733 {
734     switch (value_type)
735     {
736     case eValueTypeScalar:      return "scalar";
737     case eValueTypeVector:      return "vector";
738     case eValueTypeFileAddress: return "file address";
739     case eValueTypeLoadAddress: return "load address";
740     case eValueTypeHostAddress: return "host address";
741     };
742     return "???";
743 }
744 
745 const char *
746 Value::GetContextTypeAsCString (ContextType context_type)
747 {
748     switch (context_type)
749     {
750     case eContextTypeInvalid:       return "invalid";
751     case eContextTypeRegisterInfo:  return "RegisterInfo *";
752     case eContextTypeLLDBType:      return "Type *";
753     case eContextTypeVariable:      return "Variable *";
754     };
755     return "???";
756 }
757 
758 ValueList::ValueList (const ValueList &rhs)
759 {
760     m_values = rhs.m_values;
761 }
762 
763 const ValueList &
764 ValueList::operator= (const ValueList &rhs)
765 {
766     m_values = rhs.m_values;
767     return *this;
768 }
769 
770 void
771 ValueList::PushValue (const Value &value)
772 {
773     m_values.push_back (value);
774 }
775 
776 size_t
777 ValueList::GetSize()
778 {
779     return m_values.size();
780 }
781 
782 Value *
783 ValueList::GetValueAtIndex (size_t idx)
784 {
785     if (idx < GetSize())
786     {
787         return &(m_values[idx]);
788     }
789     else
790         return NULL;
791 }
792 
793 void
794 ValueList::Clear ()
795 {
796     m_values.clear();
797 }
798 
799