1 //===-- OptionValue.cpp ---------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/OptionValue.h"
10 #include "lldb/Interpreter/OptionValues.h"
11 #include "lldb/Utility/StringList.h"
16 using namespace lldb_private
;
18 OptionValue::OptionValue(const OptionValue
&other
) {
19 std::lock_guard
<std::mutex
> lock(other
.m_mutex
);
21 m_parent_wp
= other
.m_parent_wp
;
22 m_callback
= other
.m_callback
;
23 m_value_was_set
= other
.m_value_was_set
;
27 OptionValue
& OptionValue::operator=(const OptionValue
&other
) {
28 std::scoped_lock
<std::mutex
, std::mutex
> lock(m_mutex
, other
.m_mutex
);
30 m_parent_wp
= other
.m_parent_wp
;
31 m_callback
= other
.m_callback
;
32 m_value_was_set
= other
.m_value_was_set
;
37 Status
OptionValue::SetSubValue(const ExecutionContext
*exe_ctx
,
38 VarSetOperationType op
, llvm::StringRef name
,
39 llvm::StringRef value
) {
41 error
.SetErrorString("SetSubValue is not supported");
45 OptionValueBoolean
*OptionValue::GetAsBoolean() {
46 if (GetType() == OptionValue::eTypeBoolean
)
47 return static_cast<OptionValueBoolean
*>(this);
51 const OptionValueBoolean
*OptionValue::GetAsBoolean() const {
52 if (GetType() == OptionValue::eTypeBoolean
)
53 return static_cast<const OptionValueBoolean
*>(this);
57 const OptionValueChar
*OptionValue::GetAsChar() const {
58 if (GetType() == OptionValue::eTypeChar
)
59 return static_cast<const OptionValueChar
*>(this);
63 OptionValueChar
*OptionValue::GetAsChar() {
64 if (GetType() == OptionValue::eTypeChar
)
65 return static_cast<OptionValueChar
*>(this);
69 OptionValueFileSpec
*OptionValue::GetAsFileSpec() {
70 if (GetType() == OptionValue::eTypeFileSpec
)
71 return static_cast<OptionValueFileSpec
*>(this);
75 const OptionValueFileSpec
*OptionValue::GetAsFileSpec() const {
76 if (GetType() == OptionValue::eTypeFileSpec
)
77 return static_cast<const OptionValueFileSpec
*>(this);
81 OptionValueFileSpecList
*OptionValue::GetAsFileSpecList() {
82 if (GetType() == OptionValue::eTypeFileSpecList
)
83 return static_cast<OptionValueFileSpecList
*>(this);
87 const OptionValueFileSpecList
*OptionValue::GetAsFileSpecList() const {
88 if (GetType() == OptionValue::eTypeFileSpecList
)
89 return static_cast<const OptionValueFileSpecList
*>(this);
93 OptionValueArch
*OptionValue::GetAsArch() {
94 if (GetType() == OptionValue::eTypeArch
)
95 return static_cast<OptionValueArch
*>(this);
99 const OptionValueArch
*OptionValue::GetAsArch() const {
100 if (GetType() == OptionValue::eTypeArch
)
101 return static_cast<const OptionValueArch
*>(this);
105 OptionValueArray
*OptionValue::GetAsArray() {
106 if (GetType() == OptionValue::eTypeArray
)
107 return static_cast<OptionValueArray
*>(this);
111 const OptionValueArray
*OptionValue::GetAsArray() const {
112 if (GetType() == OptionValue::eTypeArray
)
113 return static_cast<const OptionValueArray
*>(this);
117 OptionValueArgs
*OptionValue::GetAsArgs() {
118 if (GetType() == OptionValue::eTypeArgs
)
119 return static_cast<OptionValueArgs
*>(this);
123 const OptionValueArgs
*OptionValue::GetAsArgs() const {
124 if (GetType() == OptionValue::eTypeArgs
)
125 return static_cast<const OptionValueArgs
*>(this);
129 OptionValueDictionary
*OptionValue::GetAsDictionary() {
130 if (GetType() == OptionValue::eTypeDictionary
)
131 return static_cast<OptionValueDictionary
*>(this);
135 const OptionValueDictionary
*OptionValue::GetAsDictionary() const {
136 if (GetType() == OptionValue::eTypeDictionary
)
137 return static_cast<const OptionValueDictionary
*>(this);
141 OptionValueEnumeration
*OptionValue::GetAsEnumeration() {
142 if (GetType() == OptionValue::eTypeEnum
)
143 return static_cast<OptionValueEnumeration
*>(this);
147 const OptionValueEnumeration
*OptionValue::GetAsEnumeration() const {
148 if (GetType() == OptionValue::eTypeEnum
)
149 return static_cast<const OptionValueEnumeration
*>(this);
153 OptionValueFormat
*OptionValue::GetAsFormat() {
154 if (GetType() == OptionValue::eTypeFormat
)
155 return static_cast<OptionValueFormat
*>(this);
159 const OptionValueFormat
*OptionValue::GetAsFormat() const {
160 if (GetType() == OptionValue::eTypeFormat
)
161 return static_cast<const OptionValueFormat
*>(this);
165 OptionValueLanguage
*OptionValue::GetAsLanguage() {
166 if (GetType() == OptionValue::eTypeLanguage
)
167 return static_cast<OptionValueLanguage
*>(this);
171 const OptionValueLanguage
*OptionValue::GetAsLanguage() const {
172 if (GetType() == OptionValue::eTypeLanguage
)
173 return static_cast<const OptionValueLanguage
*>(this);
177 OptionValueFormatEntity
*OptionValue::GetAsFormatEntity() {
178 if (GetType() == OptionValue::eTypeFormatEntity
)
179 return static_cast<OptionValueFormatEntity
*>(this);
183 const OptionValueFormatEntity
*OptionValue::GetAsFormatEntity() const {
184 if (GetType() == OptionValue::eTypeFormatEntity
)
185 return static_cast<const OptionValueFormatEntity
*>(this);
189 OptionValuePathMappings
*OptionValue::GetAsPathMappings() {
190 if (GetType() == OptionValue::eTypePathMap
)
191 return static_cast<OptionValuePathMappings
*>(this);
195 const OptionValuePathMappings
*OptionValue::GetAsPathMappings() const {
196 if (GetType() == OptionValue::eTypePathMap
)
197 return static_cast<const OptionValuePathMappings
*>(this);
201 OptionValueProperties
*OptionValue::GetAsProperties() {
202 if (GetType() == OptionValue::eTypeProperties
)
203 return static_cast<OptionValueProperties
*>(this);
207 const OptionValueProperties
*OptionValue::GetAsProperties() const {
208 if (GetType() == OptionValue::eTypeProperties
)
209 return static_cast<const OptionValueProperties
*>(this);
213 OptionValueRegex
*OptionValue::GetAsRegex() {
214 if (GetType() == OptionValue::eTypeRegex
)
215 return static_cast<OptionValueRegex
*>(this);
219 const OptionValueRegex
*OptionValue::GetAsRegex() const {
220 if (GetType() == OptionValue::eTypeRegex
)
221 return static_cast<const OptionValueRegex
*>(this);
225 OptionValueSInt64
*OptionValue::GetAsSInt64() {
226 if (GetType() == OptionValue::eTypeSInt64
)
227 return static_cast<OptionValueSInt64
*>(this);
231 const OptionValueSInt64
*OptionValue::GetAsSInt64() const {
232 if (GetType() == OptionValue::eTypeSInt64
)
233 return static_cast<const OptionValueSInt64
*>(this);
237 OptionValueString
*OptionValue::GetAsString() {
238 if (GetType() == OptionValue::eTypeString
)
239 return static_cast<OptionValueString
*>(this);
243 const OptionValueString
*OptionValue::GetAsString() const {
244 if (GetType() == OptionValue::eTypeString
)
245 return static_cast<const OptionValueString
*>(this);
249 OptionValueUInt64
*OptionValue::GetAsUInt64() {
250 if (GetType() == OptionValue::eTypeUInt64
)
251 return static_cast<OptionValueUInt64
*>(this);
255 const OptionValueUInt64
*OptionValue::GetAsUInt64() const {
256 if (GetType() == OptionValue::eTypeUInt64
)
257 return static_cast<const OptionValueUInt64
*>(this);
261 OptionValueUUID
*OptionValue::GetAsUUID() {
262 if (GetType() == OptionValue::eTypeUUID
)
263 return static_cast<OptionValueUUID
*>(this);
267 const OptionValueUUID
*OptionValue::GetAsUUID() const {
268 if (GetType() == OptionValue::eTypeUUID
)
269 return static_cast<const OptionValueUUID
*>(this);
273 std::optional
<bool> OptionValue::GetBooleanValue() const {
274 std::lock_guard
<std::mutex
> lock(m_mutex
);
275 if (const OptionValueBoolean
*option_value
= GetAsBoolean())
276 return option_value
->GetCurrentValue();
280 bool OptionValue::SetBooleanValue(bool new_value
) {
281 std::lock_guard
<std::mutex
> lock(m_mutex
);
282 if (OptionValueBoolean
*option_value
= GetAsBoolean()) {
283 option_value
->SetCurrentValue(new_value
);
289 std::optional
<char> OptionValue::GetCharValue() const {
290 std::lock_guard
<std::mutex
> lock(m_mutex
);
291 if (const OptionValueChar
*option_value
= GetAsChar())
292 return option_value
->GetCurrentValue();
296 bool OptionValue::SetCharValue(char new_value
) {
297 std::lock_guard
<std::mutex
> lock(m_mutex
);
298 if (OptionValueChar
*option_value
= GetAsChar()) {
299 option_value
->SetCurrentValue(new_value
);
305 std::optional
<int64_t> OptionValue::GetEnumerationValue() const {
306 std::lock_guard
<std::mutex
> lock(m_mutex
);
307 if (const OptionValueEnumeration
*option_value
= GetAsEnumeration())
308 return option_value
->GetCurrentValue();
312 bool OptionValue::SetEnumerationValue(int64_t value
) {
313 std::lock_guard
<std::mutex
> lock(m_mutex
);
314 if (OptionValueEnumeration
*option_value
= GetAsEnumeration()) {
315 option_value
->SetCurrentValue(value
);
321 std::optional
<FileSpec
> OptionValue::GetFileSpecValue() const {
322 std::lock_guard
<std::mutex
> lock(m_mutex
);
323 if (const OptionValueFileSpec
*option_value
= GetAsFileSpec())
324 return option_value
->GetCurrentValue();
328 bool OptionValue::SetFileSpecValue(FileSpec file_spec
) {
329 std::lock_guard
<std::mutex
> lock(m_mutex
);
330 if (OptionValueFileSpec
*option_value
= GetAsFileSpec()) {
331 option_value
->SetCurrentValue(file_spec
, false);
337 bool OptionValue::AppendFileSpecValue(FileSpec file_spec
) {
338 std::lock_guard
<std::mutex
> lock(m_mutex
);
339 if (OptionValueFileSpecList
*option_value
= GetAsFileSpecList()) {
340 option_value
->AppendCurrentValue(file_spec
);
346 std::optional
<FileSpecList
> OptionValue::GetFileSpecListValue() const {
347 std::lock_guard
<std::mutex
> lock(m_mutex
);
348 if (const OptionValueFileSpecList
*option_value
= GetAsFileSpecList())
349 return option_value
->GetCurrentValue();
353 std::optional
<lldb::Format
> OptionValue::GetFormatValue() const {
354 std::lock_guard
<std::mutex
> lock(m_mutex
);
355 if (const OptionValueFormat
*option_value
= GetAsFormat())
356 return option_value
->GetCurrentValue();
360 bool OptionValue::SetFormatValue(lldb::Format new_value
) {
361 std::lock_guard
<std::mutex
> lock(m_mutex
);
362 if (OptionValueFormat
*option_value
= GetAsFormat()) {
363 option_value
->SetCurrentValue(new_value
);
369 std::optional
<lldb::LanguageType
> OptionValue::GetLanguageValue() const {
370 std::lock_guard
<std::mutex
> lock(m_mutex
);
371 if (const OptionValueLanguage
*option_value
= GetAsLanguage())
372 return option_value
->GetCurrentValue();
376 bool OptionValue::SetLanguageValue(lldb::LanguageType new_language
) {
377 std::lock_guard
<std::mutex
> lock(m_mutex
);
378 if (OptionValueLanguage
*option_value
= GetAsLanguage()) {
379 option_value
->SetCurrentValue(new_language
);
385 const FormatEntity::Entry
*OptionValue::GetFormatEntity() const {
386 std::lock_guard
<std::mutex
> lock(m_mutex
);
387 if (const OptionValueFormatEntity
*option_value
= GetAsFormatEntity())
388 return &option_value
->GetCurrentValue();
392 const RegularExpression
*OptionValue::GetRegexValue() const {
393 std::lock_guard
<std::mutex
> lock(m_mutex
);
394 if (const OptionValueRegex
*option_value
= GetAsRegex())
395 return option_value
->GetCurrentValue();
399 std::optional
<int64_t> OptionValue::GetSInt64Value() const {
400 std::lock_guard
<std::mutex
> lock(m_mutex
);
401 if (const OptionValueSInt64
*option_value
= GetAsSInt64())
402 return option_value
->GetCurrentValue();
406 bool OptionValue::SetSInt64Value(int64_t new_value
) {
407 std::lock_guard
<std::mutex
> lock(m_mutex
);
408 if (OptionValueSInt64
*option_value
= GetAsSInt64()) {
409 option_value
->SetCurrentValue(new_value
);
415 std::optional
<llvm::StringRef
> OptionValue::GetStringValue() const {
416 std::lock_guard
<std::mutex
> lock(m_mutex
);
417 if (const OptionValueString
*option_value
= GetAsString())
418 return option_value
->GetCurrentValueAsRef();
422 bool OptionValue::SetStringValue(llvm::StringRef new_value
) {
423 std::lock_guard
<std::mutex
> lock(m_mutex
);
424 if (OptionValueString
*option_value
= GetAsString()) {
425 option_value
->SetCurrentValue(new_value
);
431 std::optional
<uint64_t> OptionValue::GetUInt64Value() const {
432 std::lock_guard
<std::mutex
> lock(m_mutex
);
433 if (const OptionValueUInt64
*option_value
= GetAsUInt64())
434 return option_value
->GetCurrentValue();
438 bool OptionValue::SetUInt64Value(uint64_t new_value
) {
439 std::lock_guard
<std::mutex
> lock(m_mutex
);
440 if (OptionValueUInt64
*option_value
= GetAsUInt64()) {
441 option_value
->SetCurrentValue(new_value
);
447 std::optional
<UUID
> OptionValue::GetUUIDValue() const {
448 std::lock_guard
<std::mutex
> lock(m_mutex
);
449 if (const OptionValueUUID
*option_value
= GetAsUUID())
450 return option_value
->GetCurrentValue();
454 bool OptionValue::SetUUIDValue(const UUID
&uuid
) {
455 std::lock_guard
<std::mutex
> lock(m_mutex
);
456 if (OptionValueUUID
*option_value
= GetAsUUID()) {
457 option_value
->SetCurrentValue(uuid
);
463 std::optional
<ArchSpec
> OptionValue::GetArchSpecValue() const {
464 std::lock_guard
<std::mutex
> lock(m_mutex
);
465 if (const OptionValueArch
*option_value
= GetAsArch())
466 return option_value
->GetCurrentValue();
470 bool OptionValue::SetArchSpecValue(ArchSpec arch_spec
) {
471 std::lock_guard
<std::mutex
> lock(m_mutex
);
472 if (OptionValueArch
*option_value
= GetAsArch()) {
473 option_value
->SetCurrentValue(arch_spec
, false);
479 const char *OptionValue::GetBuiltinTypeAsCString(Type t
) {
493 case eTypeDictionary
:
497 case eTypeFileLineColumn
:
498 return "file:line:column specifier";
501 case eTypeFileSpecList
:
505 case eTypeFormatEntity
:
506 return "format-string";
511 case eTypeProperties
:
527 lldb::OptionValueSP
OptionValue::CreateValueFromCStringForTypeMask(
528 const char *value_cstr
, uint32_t type_mask
, Status
&error
) {
529 // If only 1 bit is set in the type mask for a dictionary or array then we
530 // know how to decode a value from a cstring
531 lldb::OptionValueSP value_sp
;
533 case 1u << eTypeArch
:
534 value_sp
= std::make_shared
<OptionValueArch
>();
536 case 1u << eTypeBoolean
:
537 value_sp
= std::make_shared
<OptionValueBoolean
>(false);
539 case 1u << eTypeChar
:
540 value_sp
= std::make_shared
<OptionValueChar
>('\0');
542 case 1u << eTypeFileSpec
:
543 value_sp
= std::make_shared
<OptionValueFileSpec
>();
545 case 1u << eTypeFormat
:
546 value_sp
= std::make_shared
<OptionValueFormat
>(eFormatInvalid
);
548 case 1u << eTypeFormatEntity
:
549 value_sp
= std::make_shared
<OptionValueFormatEntity
>(nullptr);
551 case 1u << eTypeLanguage
:
552 value_sp
= std::make_shared
<OptionValueLanguage
>(eLanguageTypeUnknown
);
554 case 1u << eTypeSInt64
:
555 value_sp
= std::make_shared
<OptionValueSInt64
>();
557 case 1u << eTypeString
:
558 value_sp
= std::make_shared
<OptionValueString
>();
560 case 1u << eTypeUInt64
:
561 value_sp
= std::make_shared
<OptionValueUInt64
>();
563 case 1u << eTypeUUID
:
564 value_sp
= std::make_shared
<OptionValueUUID
>();
569 error
= value_sp
->SetValueFromString(value_cstr
, eVarSetOperationAssign
);
571 error
.SetErrorString("unsupported type mask");
575 bool OptionValue::DumpQualifiedName(Stream
&strm
) const {
576 bool dumped_something
= false;
577 lldb::OptionValueSP
m_parent_sp(m_parent_wp
.lock());
579 if (m_parent_sp
->DumpQualifiedName(strm
))
580 dumped_something
= true;
582 llvm::StringRef
name(GetName());
584 if (dumped_something
)
587 dumped_something
= true;
590 return dumped_something
;
593 OptionValueSP
OptionValue::DeepCopy(const OptionValueSP
&new_parent
) const {
594 auto clone
= Clone();
595 clone
->SetParent(new_parent
);
599 void OptionValue::AutoComplete(CommandInterpreter
&interpreter
,
600 CompletionRequest
&request
) {}
602 Status
OptionValue::SetValueFromString(llvm::StringRef value
,
603 VarSetOperationType op
) {
606 case eVarSetOperationReplace
:
607 error
.SetErrorStringWithFormat(
608 "%s objects do not support the 'replace' operation",
611 case eVarSetOperationInsertBefore
:
612 error
.SetErrorStringWithFormat(
613 "%s objects do not support the 'insert-before' operation",
616 case eVarSetOperationInsertAfter
:
617 error
.SetErrorStringWithFormat(
618 "%s objects do not support the 'insert-after' operation",
621 case eVarSetOperationRemove
:
622 error
.SetErrorStringWithFormat(
623 "%s objects do not support the 'remove' operation", GetTypeAsCString());
625 case eVarSetOperationAppend
:
626 error
.SetErrorStringWithFormat(
627 "%s objects do not support the 'append' operation", GetTypeAsCString());
629 case eVarSetOperationClear
:
630 error
.SetErrorStringWithFormat(
631 "%s objects do not support the 'clear' operation", GetTypeAsCString());
633 case eVarSetOperationAssign
:
634 error
.SetErrorStringWithFormat(
635 "%s objects do not support the 'assign' operation", GetTypeAsCString());
637 case eVarSetOperationInvalid
:
638 error
.SetErrorStringWithFormat("invalid operation performed on a %s object",