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

source code of lldb/source/Core/Value.cpp