[NFC][Coroutines] Use structured binding with llvm::enumerate in CoroSplit (#116879)
[llvm-project.git] / lldb / source / Interpreter / OptionValue.cpp
blobb95f4fec3394999a45f10c5de1fe5ff042b045cc
1 //===-- OptionValue.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 //===----------------------------------------------------------------------===//
9 #include "lldb/Interpreter/OptionValue.h"
10 #include "lldb/Interpreter/OptionValues.h"
11 #include "lldb/Utility/StringList.h"
13 #include <memory>
15 using namespace lldb;
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;
34 return *this;
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);
46 return nullptr;
49 const OptionValueBoolean *OptionValue::GetAsBoolean() const {
50 if (GetType() == OptionValue::eTypeBoolean)
51 return static_cast<const OptionValueBoolean *>(this);
52 return nullptr;
55 const OptionValueChar *OptionValue::GetAsChar() const {
56 if (GetType() == OptionValue::eTypeChar)
57 return static_cast<const OptionValueChar *>(this);
58 return nullptr;
61 OptionValueChar *OptionValue::GetAsChar() {
62 if (GetType() == OptionValue::eTypeChar)
63 return static_cast<OptionValueChar *>(this);
64 return nullptr;
67 OptionValueFileSpec *OptionValue::GetAsFileSpec() {
68 if (GetType() == OptionValue::eTypeFileSpec)
69 return static_cast<OptionValueFileSpec *>(this);
70 return nullptr;
73 const OptionValueFileSpec *OptionValue::GetAsFileSpec() const {
74 if (GetType() == OptionValue::eTypeFileSpec)
75 return static_cast<const OptionValueFileSpec *>(this);
76 return nullptr;
79 OptionValueFileSpecList *OptionValue::GetAsFileSpecList() {
80 if (GetType() == OptionValue::eTypeFileSpecList)
81 return static_cast<OptionValueFileSpecList *>(this);
82 return nullptr;
85 const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const {
86 if (GetType() == OptionValue::eTypeFileSpecList)
87 return static_cast<const OptionValueFileSpecList *>(this);
88 return nullptr;
91 OptionValueArch *OptionValue::GetAsArch() {
92 if (GetType() == OptionValue::eTypeArch)
93 return static_cast<OptionValueArch *>(this);
94 return nullptr;
97 const OptionValueArch *OptionValue::GetAsArch() const {
98 if (GetType() == OptionValue::eTypeArch)
99 return static_cast<const OptionValueArch *>(this);
100 return nullptr;
103 OptionValueArray *OptionValue::GetAsArray() {
104 if (GetType() == OptionValue::eTypeArray)
105 return static_cast<OptionValueArray *>(this);
106 return nullptr;
109 const OptionValueArray *OptionValue::GetAsArray() const {
110 if (GetType() == OptionValue::eTypeArray)
111 return static_cast<const OptionValueArray *>(this);
112 return nullptr;
115 OptionValueArgs *OptionValue::GetAsArgs() {
116 if (GetType() == OptionValue::eTypeArgs)
117 return static_cast<OptionValueArgs *>(this);
118 return nullptr;
121 const OptionValueArgs *OptionValue::GetAsArgs() const {
122 if (GetType() == OptionValue::eTypeArgs)
123 return static_cast<const OptionValueArgs *>(this);
124 return nullptr;
127 OptionValueDictionary *OptionValue::GetAsDictionary() {
128 if (GetType() == OptionValue::eTypeDictionary)
129 return static_cast<OptionValueDictionary *>(this);
130 return nullptr;
133 const OptionValueDictionary *OptionValue::GetAsDictionary() const {
134 if (GetType() == OptionValue::eTypeDictionary)
135 return static_cast<const OptionValueDictionary *>(this);
136 return nullptr;
139 OptionValueEnumeration *OptionValue::GetAsEnumeration() {
140 if (GetType() == OptionValue::eTypeEnum)
141 return static_cast<OptionValueEnumeration *>(this);
142 return nullptr;
145 const OptionValueEnumeration *OptionValue::GetAsEnumeration() const {
146 if (GetType() == OptionValue::eTypeEnum)
147 return static_cast<const OptionValueEnumeration *>(this);
148 return nullptr;
151 OptionValueFormat *OptionValue::GetAsFormat() {
152 if (GetType() == OptionValue::eTypeFormat)
153 return static_cast<OptionValueFormat *>(this);
154 return nullptr;
157 const OptionValueFormat *OptionValue::GetAsFormat() const {
158 if (GetType() == OptionValue::eTypeFormat)
159 return static_cast<const OptionValueFormat *>(this);
160 return nullptr;
163 OptionValueLanguage *OptionValue::GetAsLanguage() {
164 if (GetType() == OptionValue::eTypeLanguage)
165 return static_cast<OptionValueLanguage *>(this);
166 return nullptr;
169 const OptionValueLanguage *OptionValue::GetAsLanguage() const {
170 if (GetType() == OptionValue::eTypeLanguage)
171 return static_cast<const OptionValueLanguage *>(this);
172 return nullptr;
175 OptionValueFormatEntity *OptionValue::GetAsFormatEntity() {
176 if (GetType() == OptionValue::eTypeFormatEntity)
177 return static_cast<OptionValueFormatEntity *>(this);
178 return nullptr;
181 const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const {
182 if (GetType() == OptionValue::eTypeFormatEntity)
183 return static_cast<const OptionValueFormatEntity *>(this);
184 return nullptr;
187 OptionValuePathMappings *OptionValue::GetAsPathMappings() {
188 if (GetType() == OptionValue::eTypePathMap)
189 return static_cast<OptionValuePathMappings *>(this);
190 return nullptr;
193 const OptionValuePathMappings *OptionValue::GetAsPathMappings() const {
194 if (GetType() == OptionValue::eTypePathMap)
195 return static_cast<const OptionValuePathMappings *>(this);
196 return nullptr;
199 OptionValueProperties *OptionValue::GetAsProperties() {
200 if (GetType() == OptionValue::eTypeProperties)
201 return static_cast<OptionValueProperties *>(this);
202 return nullptr;
205 const OptionValueProperties *OptionValue::GetAsProperties() const {
206 if (GetType() == OptionValue::eTypeProperties)
207 return static_cast<const OptionValueProperties *>(this);
208 return nullptr;
211 OptionValueRegex *OptionValue::GetAsRegex() {
212 if (GetType() == OptionValue::eTypeRegex)
213 return static_cast<OptionValueRegex *>(this);
214 return nullptr;
217 const OptionValueRegex *OptionValue::GetAsRegex() const {
218 if (GetType() == OptionValue::eTypeRegex)
219 return static_cast<const OptionValueRegex *>(this);
220 return nullptr;
223 OptionValueSInt64 *OptionValue::GetAsSInt64() {
224 if (GetType() == OptionValue::eTypeSInt64)
225 return static_cast<OptionValueSInt64 *>(this);
226 return nullptr;
229 const OptionValueSInt64 *OptionValue::GetAsSInt64() const {
230 if (GetType() == OptionValue::eTypeSInt64)
231 return static_cast<const OptionValueSInt64 *>(this);
232 return nullptr;
235 OptionValueString *OptionValue::GetAsString() {
236 if (GetType() == OptionValue::eTypeString)
237 return static_cast<OptionValueString *>(this);
238 return nullptr;
241 const OptionValueString *OptionValue::GetAsString() const {
242 if (GetType() == OptionValue::eTypeString)
243 return static_cast<const OptionValueString *>(this);
244 return nullptr;
247 OptionValueUInt64 *OptionValue::GetAsUInt64() {
248 if (GetType() == OptionValue::eTypeUInt64)
249 return static_cast<OptionValueUInt64 *>(this);
250 return nullptr;
253 const OptionValueUInt64 *OptionValue::GetAsUInt64() const {
254 if (GetType() == OptionValue::eTypeUInt64)
255 return static_cast<const OptionValueUInt64 *>(this);
256 return nullptr;
259 OptionValueUUID *OptionValue::GetAsUUID() {
260 if (GetType() == OptionValue::eTypeUUID)
261 return static_cast<OptionValueUUID *>(this);
262 return nullptr;
265 const OptionValueUUID *OptionValue::GetAsUUID() const {
266 if (GetType() == OptionValue::eTypeUUID)
267 return static_cast<const OptionValueUUID *>(this);
268 return nullptr;
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();
275 return {};
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);
282 return true;
284 return false;
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();
291 return {};
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);
298 return true;
300 return false;
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();
307 return {};
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);
314 return true;
316 return false;
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();
323 return {};
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);
330 return true;
332 return 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);
339 return true;
341 return false;
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();
348 return {};
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();
355 return {};
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);
362 return true;
364 return false;
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();
371 return {};
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);
378 return true;
380 return false;
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();
387 return nullptr;
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();
394 return nullptr;
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();
401 return {};
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);
408 return true;
410 return false;
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();
417 return {};
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);
424 return true;
426 return false;
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();
433 return {};
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);
440 return true;
442 return false;
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();
449 return {};
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);
456 return true;
458 return false;
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();
465 return {};
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);
472 return true;
474 return false;
477 const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
478 switch (t) {
479 case eTypeInvalid:
480 return "invalid";
481 case eTypeArch:
482 return "arch";
483 case eTypeArgs:
484 return "arguments";
485 case eTypeArray:
486 return "array";
487 case eTypeBoolean:
488 return "boolean";
489 case eTypeChar:
490 return "char";
491 case eTypeDictionary:
492 return "dictionary";
493 case eTypeEnum:
494 return "enum";
495 case eTypeFileLineColumn:
496 return "file:line:column specifier";
497 case eTypeFileSpec:
498 return "file";
499 case eTypeFileSpecList:
500 return "file-list";
501 case eTypeFormat:
502 return "format";
503 case eTypeFormatEntity:
504 return "format-string";
505 case eTypeLanguage:
506 return "language";
507 case eTypePathMap:
508 return "path-map";
509 case eTypeProperties:
510 return "properties";
511 case eTypeRegex:
512 return "regex";
513 case eTypeSInt64:
514 return "int";
515 case eTypeString:
516 return "string";
517 case eTypeUInt64:
518 return "unsigned";
519 case eTypeUUID:
520 return "uuid";
522 return nullptr;
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;
530 switch (type_mask) {
531 case 1u << eTypeArch:
532 value_sp = std::make_shared<OptionValueArch>();
533 break;
534 case 1u << eTypeBoolean:
535 value_sp = std::make_shared<OptionValueBoolean>(false);
536 break;
537 case 1u << eTypeChar:
538 value_sp = std::make_shared<OptionValueChar>('\0');
539 break;
540 case 1u << eTypeFileSpec:
541 value_sp = std::make_shared<OptionValueFileSpec>();
542 break;
543 case 1u << eTypeFormat:
544 value_sp = std::make_shared<OptionValueFormat>(eFormatInvalid);
545 break;
546 case 1u << eTypeFormatEntity:
547 value_sp = std::make_shared<OptionValueFormatEntity>(nullptr);
548 break;
549 case 1u << eTypeLanguage:
550 value_sp = std::make_shared<OptionValueLanguage>(eLanguageTypeUnknown);
551 break;
552 case 1u << eTypeSInt64:
553 value_sp = std::make_shared<OptionValueSInt64>();
554 break;
555 case 1u << eTypeString:
556 value_sp = std::make_shared<OptionValueString>();
557 break;
558 case 1u << eTypeUInt64:
559 value_sp = std::make_shared<OptionValueUInt64>();
560 break;
561 case 1u << eTypeUUID:
562 value_sp = std::make_shared<OptionValueUUID>();
563 break;
566 if (value_sp)
567 error = value_sp->SetValueFromString(value_cstr, eVarSetOperationAssign);
568 else
569 error = Status::FromErrorString("unsupported type mask");
570 return value_sp;
573 bool OptionValue::DumpQualifiedName(Stream &strm) const {
574 bool dumped_something = false;
575 lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
576 if (m_parent_sp) {
577 if (m_parent_sp->DumpQualifiedName(strm))
578 dumped_something = true;
580 llvm::StringRef name(GetName());
581 if (!name.empty()) {
582 if (dumped_something)
583 strm.PutChar('.');
584 else
585 dumped_something = true;
586 strm << name;
588 return dumped_something;
591 OptionValueSP OptionValue::DeepCopy(const OptionValueSP &new_parent) const {
592 auto clone = Clone();
593 clone->SetParent(new_parent);
594 return clone;
597 void OptionValue::AutoComplete(CommandInterpreter &interpreter,
598 CompletionRequest &request) {}
600 Status OptionValue::SetValueFromString(llvm::StringRef value,
601 VarSetOperationType op) {
602 Status error;
603 switch (op) {
604 case eVarSetOperationReplace:
605 error = Status::FromErrorStringWithFormat(
606 "%s objects do not support the 'replace' operation",
607 GetTypeAsCString());
608 break;
609 case eVarSetOperationInsertBefore:
610 error = Status::FromErrorStringWithFormat(
611 "%s objects do not support the 'insert-before' operation",
612 GetTypeAsCString());
613 break;
614 case eVarSetOperationInsertAfter:
615 error = Status::FromErrorStringWithFormat(
616 "%s objects do not support the 'insert-after' operation",
617 GetTypeAsCString());
618 break;
619 case eVarSetOperationRemove:
620 error = Status::FromErrorStringWithFormat(
621 "%s objects do not support the 'remove' operation", GetTypeAsCString());
622 break;
623 case eVarSetOperationAppend:
624 error = Status::FromErrorStringWithFormat(
625 "%s objects do not support the 'append' operation", GetTypeAsCString());
626 break;
627 case eVarSetOperationClear:
628 error = Status::FromErrorStringWithFormat(
629 "%s objects do not support the 'clear' operation", GetTypeAsCString());
630 break;
631 case eVarSetOperationAssign:
632 error = Status::FromErrorStringWithFormat(
633 "%s objects do not support the 'assign' operation", GetTypeAsCString());
634 break;
635 case eVarSetOperationInvalid:
636 error = Status::FromErrorStringWithFormat(
637 "invalid operation performed on a %s object", GetTypeAsCString());
638 break;
640 return error;