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