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
) {
40 return Status::FromErrorString("SetSubValue is not supported");
43 OptionValueBoolean
*OptionValue::GetAsBoolean() {
44 if (GetType() == OptionValue::eTypeBoolean
)
45 return static_cast<OptionValueBoolean
*>(this);
49 const OptionValueBoolean
*OptionValue::GetAsBoolean() const {
50 if (GetType() == OptionValue::eTypeBoolean
)
51 return static_cast<const OptionValueBoolean
*>(this);
55 const OptionValueChar
*OptionValue::GetAsChar() const {
56 if (GetType() == OptionValue::eTypeChar
)
57 return static_cast<const OptionValueChar
*>(this);
61 OptionValueChar
*OptionValue::GetAsChar() {
62 if (GetType() == OptionValue::eTypeChar
)
63 return static_cast<OptionValueChar
*>(this);
67 OptionValueFileSpec
*OptionValue::GetAsFileSpec() {
68 if (GetType() == OptionValue::eTypeFileSpec
)
69 return static_cast<OptionValueFileSpec
*>(this);
73 const OptionValueFileSpec
*OptionValue::GetAsFileSpec() const {
74 if (GetType() == OptionValue::eTypeFileSpec
)
75 return static_cast<const OptionValueFileSpec
*>(this);
79 OptionValueFileSpecList
*OptionValue::GetAsFileSpecList() {
80 if (GetType() == OptionValue::eTypeFileSpecList
)
81 return static_cast<OptionValueFileSpecList
*>(this);
85 const OptionValueFileSpecList
*OptionValue::GetAsFileSpecList() const {
86 if (GetType() == OptionValue::eTypeFileSpecList
)
87 return static_cast<const OptionValueFileSpecList
*>(this);
91 OptionValueArch
*OptionValue::GetAsArch() {
92 if (GetType() == OptionValue::eTypeArch
)
93 return static_cast<OptionValueArch
*>(this);
97 const OptionValueArch
*OptionValue::GetAsArch() const {
98 if (GetType() == OptionValue::eTypeArch
)
99 return static_cast<const OptionValueArch
*>(this);
103 OptionValueArray
*OptionValue::GetAsArray() {
104 if (GetType() == OptionValue::eTypeArray
)
105 return static_cast<OptionValueArray
*>(this);
109 const OptionValueArray
*OptionValue::GetAsArray() const {
110 if (GetType() == OptionValue::eTypeArray
)
111 return static_cast<const OptionValueArray
*>(this);
115 OptionValueArgs
*OptionValue::GetAsArgs() {
116 if (GetType() == OptionValue::eTypeArgs
)
117 return static_cast<OptionValueArgs
*>(this);
121 const OptionValueArgs
*OptionValue::GetAsArgs() const {
122 if (GetType() == OptionValue::eTypeArgs
)
123 return static_cast<const OptionValueArgs
*>(this);
127 OptionValueDictionary
*OptionValue::GetAsDictionary() {
128 if (GetType() == OptionValue::eTypeDictionary
)
129 return static_cast<OptionValueDictionary
*>(this);
133 const OptionValueDictionary
*OptionValue::GetAsDictionary() const {
134 if (GetType() == OptionValue::eTypeDictionary
)
135 return static_cast<const OptionValueDictionary
*>(this);
139 OptionValueEnumeration
*OptionValue::GetAsEnumeration() {
140 if (GetType() == OptionValue::eTypeEnum
)
141 return static_cast<OptionValueEnumeration
*>(this);
145 const OptionValueEnumeration
*OptionValue::GetAsEnumeration() const {
146 if (GetType() == OptionValue::eTypeEnum
)
147 return static_cast<const OptionValueEnumeration
*>(this);
151 OptionValueFormat
*OptionValue::GetAsFormat() {
152 if (GetType() == OptionValue::eTypeFormat
)
153 return static_cast<OptionValueFormat
*>(this);
157 const OptionValueFormat
*OptionValue::GetAsFormat() const {
158 if (GetType() == OptionValue::eTypeFormat
)
159 return static_cast<const OptionValueFormat
*>(this);
163 OptionValueLanguage
*OptionValue::GetAsLanguage() {
164 if (GetType() == OptionValue::eTypeLanguage
)
165 return static_cast<OptionValueLanguage
*>(this);
169 const OptionValueLanguage
*OptionValue::GetAsLanguage() const {
170 if (GetType() == OptionValue::eTypeLanguage
)
171 return static_cast<const OptionValueLanguage
*>(this);
175 OptionValueFormatEntity
*OptionValue::GetAsFormatEntity() {
176 if (GetType() == OptionValue::eTypeFormatEntity
)
177 return static_cast<OptionValueFormatEntity
*>(this);
181 const OptionValueFormatEntity
*OptionValue::GetAsFormatEntity() const {
182 if (GetType() == OptionValue::eTypeFormatEntity
)
183 return static_cast<const OptionValueFormatEntity
*>(this);
187 OptionValuePathMappings
*OptionValue::GetAsPathMappings() {
188 if (GetType() == OptionValue::eTypePathMap
)
189 return static_cast<OptionValuePathMappings
*>(this);
193 const OptionValuePathMappings
*OptionValue::GetAsPathMappings() const {
194 if (GetType() == OptionValue::eTypePathMap
)
195 return static_cast<const OptionValuePathMappings
*>(this);
199 OptionValueProperties
*OptionValue::GetAsProperties() {
200 if (GetType() == OptionValue::eTypeProperties
)
201 return static_cast<OptionValueProperties
*>(this);
205 const OptionValueProperties
*OptionValue::GetAsProperties() const {
206 if (GetType() == OptionValue::eTypeProperties
)
207 return static_cast<const OptionValueProperties
*>(this);
211 OptionValueRegex
*OptionValue::GetAsRegex() {
212 if (GetType() == OptionValue::eTypeRegex
)
213 return static_cast<OptionValueRegex
*>(this);
217 const OptionValueRegex
*OptionValue::GetAsRegex() const {
218 if (GetType() == OptionValue::eTypeRegex
)
219 return static_cast<const OptionValueRegex
*>(this);
223 OptionValueSInt64
*OptionValue::GetAsSInt64() {
224 if (GetType() == OptionValue::eTypeSInt64
)
225 return static_cast<OptionValueSInt64
*>(this);
229 const OptionValueSInt64
*OptionValue::GetAsSInt64() const {
230 if (GetType() == OptionValue::eTypeSInt64
)
231 return static_cast<const OptionValueSInt64
*>(this);
235 OptionValueString
*OptionValue::GetAsString() {
236 if (GetType() == OptionValue::eTypeString
)
237 return static_cast<OptionValueString
*>(this);
241 const OptionValueString
*OptionValue::GetAsString() const {
242 if (GetType() == OptionValue::eTypeString
)
243 return static_cast<const OptionValueString
*>(this);
247 OptionValueUInt64
*OptionValue::GetAsUInt64() {
248 if (GetType() == OptionValue::eTypeUInt64
)
249 return static_cast<OptionValueUInt64
*>(this);
253 const OptionValueUInt64
*OptionValue::GetAsUInt64() const {
254 if (GetType() == OptionValue::eTypeUInt64
)
255 return static_cast<const OptionValueUInt64
*>(this);
259 OptionValueUUID
*OptionValue::GetAsUUID() {
260 if (GetType() == OptionValue::eTypeUUID
)
261 return static_cast<OptionValueUUID
*>(this);
265 const OptionValueUUID
*OptionValue::GetAsUUID() const {
266 if (GetType() == OptionValue::eTypeUUID
)
267 return static_cast<const OptionValueUUID
*>(this);
271 std::optional
<bool> OptionValue::GetBooleanValue() const {
272 std::lock_guard
<std::mutex
> lock(m_mutex
);
273 if (const OptionValueBoolean
*option_value
= GetAsBoolean())
274 return option_value
->GetCurrentValue();
278 bool OptionValue::SetBooleanValue(bool new_value
) {
279 std::lock_guard
<std::mutex
> lock(m_mutex
);
280 if (OptionValueBoolean
*option_value
= GetAsBoolean()) {
281 option_value
->SetCurrentValue(new_value
);
287 std::optional
<char> OptionValue::GetCharValue() const {
288 std::lock_guard
<std::mutex
> lock(m_mutex
);
289 if (const OptionValueChar
*option_value
= GetAsChar())
290 return option_value
->GetCurrentValue();
294 bool OptionValue::SetCharValue(char new_value
) {
295 std::lock_guard
<std::mutex
> lock(m_mutex
);
296 if (OptionValueChar
*option_value
= GetAsChar()) {
297 option_value
->SetCurrentValue(new_value
);
303 std::optional
<int64_t> OptionValue::GetEnumerationValue() const {
304 std::lock_guard
<std::mutex
> lock(m_mutex
);
305 if (const OptionValueEnumeration
*option_value
= GetAsEnumeration())
306 return option_value
->GetCurrentValue();
310 bool OptionValue::SetEnumerationValue(int64_t value
) {
311 std::lock_guard
<std::mutex
> lock(m_mutex
);
312 if (OptionValueEnumeration
*option_value
= GetAsEnumeration()) {
313 option_value
->SetCurrentValue(value
);
319 std::optional
<FileSpec
> OptionValue::GetFileSpecValue() const {
320 std::lock_guard
<std::mutex
> lock(m_mutex
);
321 if (const OptionValueFileSpec
*option_value
= GetAsFileSpec())
322 return option_value
->GetCurrentValue();
326 bool OptionValue::SetFileSpecValue(FileSpec file_spec
) {
327 std::lock_guard
<std::mutex
> lock(m_mutex
);
328 if (OptionValueFileSpec
*option_value
= GetAsFileSpec()) {
329 option_value
->SetCurrentValue(file_spec
, false);
335 bool OptionValue::AppendFileSpecValue(FileSpec file_spec
) {
336 std::lock_guard
<std::mutex
> lock(m_mutex
);
337 if (OptionValueFileSpecList
*option_value
= GetAsFileSpecList()) {
338 option_value
->AppendCurrentValue(file_spec
);
344 std::optional
<FileSpecList
> OptionValue::GetFileSpecListValue() const {
345 std::lock_guard
<std::mutex
> lock(m_mutex
);
346 if (const OptionValueFileSpecList
*option_value
= GetAsFileSpecList())
347 return option_value
->GetCurrentValue();
351 std::optional
<lldb::Format
> OptionValue::GetFormatValue() const {
352 std::lock_guard
<std::mutex
> lock(m_mutex
);
353 if (const OptionValueFormat
*option_value
= GetAsFormat())
354 return option_value
->GetCurrentValue();
358 bool OptionValue::SetFormatValue(lldb::Format new_value
) {
359 std::lock_guard
<std::mutex
> lock(m_mutex
);
360 if (OptionValueFormat
*option_value
= GetAsFormat()) {
361 option_value
->SetCurrentValue(new_value
);
367 std::optional
<lldb::LanguageType
> OptionValue::GetLanguageValue() const {
368 std::lock_guard
<std::mutex
> lock(m_mutex
);
369 if (const OptionValueLanguage
*option_value
= GetAsLanguage())
370 return option_value
->GetCurrentValue();
374 bool OptionValue::SetLanguageValue(lldb::LanguageType new_language
) {
375 std::lock_guard
<std::mutex
> lock(m_mutex
);
376 if (OptionValueLanguage
*option_value
= GetAsLanguage()) {
377 option_value
->SetCurrentValue(new_language
);
383 const FormatEntity::Entry
*OptionValue::GetFormatEntity() const {
384 std::lock_guard
<std::mutex
> lock(m_mutex
);
385 if (const OptionValueFormatEntity
*option_value
= GetAsFormatEntity())
386 return &option_value
->GetCurrentValue();
390 const RegularExpression
*OptionValue::GetRegexValue() const {
391 std::lock_guard
<std::mutex
> lock(m_mutex
);
392 if (const OptionValueRegex
*option_value
= GetAsRegex())
393 return option_value
->GetCurrentValue();
397 std::optional
<int64_t> OptionValue::GetSInt64Value() const {
398 std::lock_guard
<std::mutex
> lock(m_mutex
);
399 if (const OptionValueSInt64
*option_value
= GetAsSInt64())
400 return option_value
->GetCurrentValue();
404 bool OptionValue::SetSInt64Value(int64_t new_value
) {
405 std::lock_guard
<std::mutex
> lock(m_mutex
);
406 if (OptionValueSInt64
*option_value
= GetAsSInt64()) {
407 option_value
->SetCurrentValue(new_value
);
413 std::optional
<llvm::StringRef
> OptionValue::GetStringValue() const {
414 std::lock_guard
<std::mutex
> lock(m_mutex
);
415 if (const OptionValueString
*option_value
= GetAsString())
416 return option_value
->GetCurrentValueAsRef();
420 bool OptionValue::SetStringValue(llvm::StringRef new_value
) {
421 std::lock_guard
<std::mutex
> lock(m_mutex
);
422 if (OptionValueString
*option_value
= GetAsString()) {
423 option_value
->SetCurrentValue(new_value
);
429 std::optional
<uint64_t> OptionValue::GetUInt64Value() const {
430 std::lock_guard
<std::mutex
> lock(m_mutex
);
431 if (const OptionValueUInt64
*option_value
= GetAsUInt64())
432 return option_value
->GetCurrentValue();
436 bool OptionValue::SetUInt64Value(uint64_t new_value
) {
437 std::lock_guard
<std::mutex
> lock(m_mutex
);
438 if (OptionValueUInt64
*option_value
= GetAsUInt64()) {
439 option_value
->SetCurrentValue(new_value
);
445 std::optional
<UUID
> OptionValue::GetUUIDValue() const {
446 std::lock_guard
<std::mutex
> lock(m_mutex
);
447 if (const OptionValueUUID
*option_value
= GetAsUUID())
448 return option_value
->GetCurrentValue();
452 bool OptionValue::SetUUIDValue(const UUID
&uuid
) {
453 std::lock_guard
<std::mutex
> lock(m_mutex
);
454 if (OptionValueUUID
*option_value
= GetAsUUID()) {
455 option_value
->SetCurrentValue(uuid
);
461 std::optional
<ArchSpec
> OptionValue::GetArchSpecValue() const {
462 std::lock_guard
<std::mutex
> lock(m_mutex
);
463 if (const OptionValueArch
*option_value
= GetAsArch())
464 return option_value
->GetCurrentValue();
468 bool OptionValue::SetArchSpecValue(ArchSpec arch_spec
) {
469 std::lock_guard
<std::mutex
> lock(m_mutex
);
470 if (OptionValueArch
*option_value
= GetAsArch()) {
471 option_value
->SetCurrentValue(arch_spec
, false);
477 const char *OptionValue::GetBuiltinTypeAsCString(Type t
) {
491 case eTypeDictionary
:
495 case eTypeFileLineColumn
:
496 return "file:line:column specifier";
499 case eTypeFileSpecList
:
503 case eTypeFormatEntity
:
504 return "format-string";
509 case eTypeProperties
:
525 lldb::OptionValueSP
OptionValue::CreateValueFromCStringForTypeMask(
526 const char *value_cstr
, uint32_t type_mask
, Status
&error
) {
527 // If only 1 bit is set in the type mask for a dictionary or array then we
528 // know how to decode a value from a cstring
529 lldb::OptionValueSP value_sp
;
531 case 1u << eTypeArch
:
532 value_sp
= std::make_shared
<OptionValueArch
>();
534 case 1u << eTypeBoolean
:
535 value_sp
= std::make_shared
<OptionValueBoolean
>(false);
537 case 1u << eTypeChar
:
538 value_sp
= std::make_shared
<OptionValueChar
>('\0');
540 case 1u << eTypeFileSpec
:
541 value_sp
= std::make_shared
<OptionValueFileSpec
>();
543 case 1u << eTypeFormat
:
544 value_sp
= std::make_shared
<OptionValueFormat
>(eFormatInvalid
);
546 case 1u << eTypeFormatEntity
:
547 value_sp
= std::make_shared
<OptionValueFormatEntity
>(nullptr);
549 case 1u << eTypeLanguage
:
550 value_sp
= std::make_shared
<OptionValueLanguage
>(eLanguageTypeUnknown
);
552 case 1u << eTypeSInt64
:
553 value_sp
= std::make_shared
<OptionValueSInt64
>();
555 case 1u << eTypeString
:
556 value_sp
= std::make_shared
<OptionValueString
>();
558 case 1u << eTypeUInt64
:
559 value_sp
= std::make_shared
<OptionValueUInt64
>();
561 case 1u << eTypeUUID
:
562 value_sp
= std::make_shared
<OptionValueUUID
>();
567 error
= value_sp
->SetValueFromString(value_cstr
, eVarSetOperationAssign
);
569 error
= Status::FromErrorString("unsupported type mask");
573 bool OptionValue::DumpQualifiedName(Stream
&strm
) const {
574 bool dumped_something
= false;
575 lldb::OptionValueSP
m_parent_sp(m_parent_wp
.lock());
577 if (m_parent_sp
->DumpQualifiedName(strm
))
578 dumped_something
= true;
580 llvm::StringRef
name(GetName());
582 if (dumped_something
)
585 dumped_something
= true;
588 return dumped_something
;
591 OptionValueSP
OptionValue::DeepCopy(const OptionValueSP
&new_parent
) const {
592 auto clone
= Clone();
593 clone
->SetParent(new_parent
);
597 void OptionValue::AutoComplete(CommandInterpreter
&interpreter
,
598 CompletionRequest
&request
) {}
600 Status
OptionValue::SetValueFromString(llvm::StringRef value
,
601 VarSetOperationType op
) {
604 case eVarSetOperationReplace
:
605 error
= Status::FromErrorStringWithFormat(
606 "%s objects do not support the 'replace' operation",
609 case eVarSetOperationInsertBefore
:
610 error
= Status::FromErrorStringWithFormat(
611 "%s objects do not support the 'insert-before' operation",
614 case eVarSetOperationInsertAfter
:
615 error
= Status::FromErrorStringWithFormat(
616 "%s objects do not support the 'insert-after' operation",
619 case eVarSetOperationRemove
:
620 error
= Status::FromErrorStringWithFormat(
621 "%s objects do not support the 'remove' operation", GetTypeAsCString());
623 case eVarSetOperationAppend
:
624 error
= Status::FromErrorStringWithFormat(
625 "%s objects do not support the 'append' operation", GetTypeAsCString());
627 case eVarSetOperationClear
:
628 error
= Status::FromErrorStringWithFormat(
629 "%s objects do not support the 'clear' operation", GetTypeAsCString());
631 case eVarSetOperationAssign
:
632 error
= Status::FromErrorStringWithFormat(
633 "%s objects do not support the 'assign' operation", GetTypeAsCString());
635 case eVarSetOperationInvalid
:
636 error
= Status::FromErrorStringWithFormat(
637 "invalid operation performed on a %s object", GetTypeAsCString());