Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / Interpreter / OptionValue.cpp
blobfe1d8829c5adf67e5eff196d1d7824799ed3d586
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 Status error;
41 error.SetErrorString("SetSubValue is not supported");
42 return error;
45 OptionValueBoolean *OptionValue::GetAsBoolean() {
46 if (GetType() == OptionValue::eTypeBoolean)
47 return static_cast<OptionValueBoolean *>(this);
48 return nullptr;
51 const OptionValueBoolean *OptionValue::GetAsBoolean() const {
52 if (GetType() == OptionValue::eTypeBoolean)
53 return static_cast<const OptionValueBoolean *>(this);
54 return nullptr;
57 const OptionValueChar *OptionValue::GetAsChar() const {
58 if (GetType() == OptionValue::eTypeChar)
59 return static_cast<const OptionValueChar *>(this);
60 return nullptr;
63 OptionValueChar *OptionValue::GetAsChar() {
64 if (GetType() == OptionValue::eTypeChar)
65 return static_cast<OptionValueChar *>(this);
66 return nullptr;
69 OptionValueFileSpec *OptionValue::GetAsFileSpec() {
70 if (GetType() == OptionValue::eTypeFileSpec)
71 return static_cast<OptionValueFileSpec *>(this);
72 return nullptr;
75 const OptionValueFileSpec *OptionValue::GetAsFileSpec() const {
76 if (GetType() == OptionValue::eTypeFileSpec)
77 return static_cast<const OptionValueFileSpec *>(this);
78 return nullptr;
81 OptionValueFileSpecList *OptionValue::GetAsFileSpecList() {
82 if (GetType() == OptionValue::eTypeFileSpecList)
83 return static_cast<OptionValueFileSpecList *>(this);
84 return nullptr;
87 const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const {
88 if (GetType() == OptionValue::eTypeFileSpecList)
89 return static_cast<const OptionValueFileSpecList *>(this);
90 return nullptr;
93 OptionValueArch *OptionValue::GetAsArch() {
94 if (GetType() == OptionValue::eTypeArch)
95 return static_cast<OptionValueArch *>(this);
96 return nullptr;
99 const OptionValueArch *OptionValue::GetAsArch() const {
100 if (GetType() == OptionValue::eTypeArch)
101 return static_cast<const OptionValueArch *>(this);
102 return nullptr;
105 OptionValueArray *OptionValue::GetAsArray() {
106 if (GetType() == OptionValue::eTypeArray)
107 return static_cast<OptionValueArray *>(this);
108 return nullptr;
111 const OptionValueArray *OptionValue::GetAsArray() const {
112 if (GetType() == OptionValue::eTypeArray)
113 return static_cast<const OptionValueArray *>(this);
114 return nullptr;
117 OptionValueArgs *OptionValue::GetAsArgs() {
118 if (GetType() == OptionValue::eTypeArgs)
119 return static_cast<OptionValueArgs *>(this);
120 return nullptr;
123 const OptionValueArgs *OptionValue::GetAsArgs() const {
124 if (GetType() == OptionValue::eTypeArgs)
125 return static_cast<const OptionValueArgs *>(this);
126 return nullptr;
129 OptionValueDictionary *OptionValue::GetAsDictionary() {
130 if (GetType() == OptionValue::eTypeDictionary)
131 return static_cast<OptionValueDictionary *>(this);
132 return nullptr;
135 const OptionValueDictionary *OptionValue::GetAsDictionary() const {
136 if (GetType() == OptionValue::eTypeDictionary)
137 return static_cast<const OptionValueDictionary *>(this);
138 return nullptr;
141 OptionValueEnumeration *OptionValue::GetAsEnumeration() {
142 if (GetType() == OptionValue::eTypeEnum)
143 return static_cast<OptionValueEnumeration *>(this);
144 return nullptr;
147 const OptionValueEnumeration *OptionValue::GetAsEnumeration() const {
148 if (GetType() == OptionValue::eTypeEnum)
149 return static_cast<const OptionValueEnumeration *>(this);
150 return nullptr;
153 OptionValueFormat *OptionValue::GetAsFormat() {
154 if (GetType() == OptionValue::eTypeFormat)
155 return static_cast<OptionValueFormat *>(this);
156 return nullptr;
159 const OptionValueFormat *OptionValue::GetAsFormat() const {
160 if (GetType() == OptionValue::eTypeFormat)
161 return static_cast<const OptionValueFormat *>(this);
162 return nullptr;
165 OptionValueLanguage *OptionValue::GetAsLanguage() {
166 if (GetType() == OptionValue::eTypeLanguage)
167 return static_cast<OptionValueLanguage *>(this);
168 return nullptr;
171 const OptionValueLanguage *OptionValue::GetAsLanguage() const {
172 if (GetType() == OptionValue::eTypeLanguage)
173 return static_cast<const OptionValueLanguage *>(this);
174 return nullptr;
177 OptionValueFormatEntity *OptionValue::GetAsFormatEntity() {
178 if (GetType() == OptionValue::eTypeFormatEntity)
179 return static_cast<OptionValueFormatEntity *>(this);
180 return nullptr;
183 const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const {
184 if (GetType() == OptionValue::eTypeFormatEntity)
185 return static_cast<const OptionValueFormatEntity *>(this);
186 return nullptr;
189 OptionValuePathMappings *OptionValue::GetAsPathMappings() {
190 if (GetType() == OptionValue::eTypePathMap)
191 return static_cast<OptionValuePathMappings *>(this);
192 return nullptr;
195 const OptionValuePathMappings *OptionValue::GetAsPathMappings() const {
196 if (GetType() == OptionValue::eTypePathMap)
197 return static_cast<const OptionValuePathMappings *>(this);
198 return nullptr;
201 OptionValueProperties *OptionValue::GetAsProperties() {
202 if (GetType() == OptionValue::eTypeProperties)
203 return static_cast<OptionValueProperties *>(this);
204 return nullptr;
207 const OptionValueProperties *OptionValue::GetAsProperties() const {
208 if (GetType() == OptionValue::eTypeProperties)
209 return static_cast<const OptionValueProperties *>(this);
210 return nullptr;
213 OptionValueRegex *OptionValue::GetAsRegex() {
214 if (GetType() == OptionValue::eTypeRegex)
215 return static_cast<OptionValueRegex *>(this);
216 return nullptr;
219 const OptionValueRegex *OptionValue::GetAsRegex() const {
220 if (GetType() == OptionValue::eTypeRegex)
221 return static_cast<const OptionValueRegex *>(this);
222 return nullptr;
225 OptionValueSInt64 *OptionValue::GetAsSInt64() {
226 if (GetType() == OptionValue::eTypeSInt64)
227 return static_cast<OptionValueSInt64 *>(this);
228 return nullptr;
231 const OptionValueSInt64 *OptionValue::GetAsSInt64() const {
232 if (GetType() == OptionValue::eTypeSInt64)
233 return static_cast<const OptionValueSInt64 *>(this);
234 return nullptr;
237 OptionValueString *OptionValue::GetAsString() {
238 if (GetType() == OptionValue::eTypeString)
239 return static_cast<OptionValueString *>(this);
240 return nullptr;
243 const OptionValueString *OptionValue::GetAsString() const {
244 if (GetType() == OptionValue::eTypeString)
245 return static_cast<const OptionValueString *>(this);
246 return nullptr;
249 OptionValueUInt64 *OptionValue::GetAsUInt64() {
250 if (GetType() == OptionValue::eTypeUInt64)
251 return static_cast<OptionValueUInt64 *>(this);
252 return nullptr;
255 const OptionValueUInt64 *OptionValue::GetAsUInt64() const {
256 if (GetType() == OptionValue::eTypeUInt64)
257 return static_cast<const OptionValueUInt64 *>(this);
258 return nullptr;
261 OptionValueUUID *OptionValue::GetAsUUID() {
262 if (GetType() == OptionValue::eTypeUUID)
263 return static_cast<OptionValueUUID *>(this);
264 return nullptr;
267 const OptionValueUUID *OptionValue::GetAsUUID() const {
268 if (GetType() == OptionValue::eTypeUUID)
269 return static_cast<const OptionValueUUID *>(this);
270 return nullptr;
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();
277 return {};
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);
284 return true;
286 return false;
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();
293 return {};
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);
300 return true;
302 return false;
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();
309 return {};
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);
316 return true;
318 return false;
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();
325 return {};
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);
332 return true;
334 return 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);
341 return true;
343 return false;
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();
350 return {};
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();
357 return {};
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);
364 return true;
366 return false;
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();
373 return {};
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);
380 return true;
382 return false;
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();
389 return nullptr;
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();
396 return nullptr;
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();
403 return {};
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);
410 return true;
412 return false;
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();
419 return {};
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);
426 return true;
428 return false;
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();
435 return {};
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);
442 return true;
444 return false;
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();
451 return {};
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);
458 return true;
460 return false;
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();
467 return {};
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);
474 return true;
476 return false;
479 const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
480 switch (t) {
481 case eTypeInvalid:
482 return "invalid";
483 case eTypeArch:
484 return "arch";
485 case eTypeArgs:
486 return "arguments";
487 case eTypeArray:
488 return "array";
489 case eTypeBoolean:
490 return "boolean";
491 case eTypeChar:
492 return "char";
493 case eTypeDictionary:
494 return "dictionary";
495 case eTypeEnum:
496 return "enum";
497 case eTypeFileLineColumn:
498 return "file:line:column specifier";
499 case eTypeFileSpec:
500 return "file";
501 case eTypeFileSpecList:
502 return "file-list";
503 case eTypeFormat:
504 return "format";
505 case eTypeFormatEntity:
506 return "format-string";
507 case eTypeLanguage:
508 return "language";
509 case eTypePathMap:
510 return "path-map";
511 case eTypeProperties:
512 return "properties";
513 case eTypeRegex:
514 return "regex";
515 case eTypeSInt64:
516 return "int";
517 case eTypeString:
518 return "string";
519 case eTypeUInt64:
520 return "unsigned";
521 case eTypeUUID:
522 return "uuid";
524 return nullptr;
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;
532 switch (type_mask) {
533 case 1u << eTypeArch:
534 value_sp = std::make_shared<OptionValueArch>();
535 break;
536 case 1u << eTypeBoolean:
537 value_sp = std::make_shared<OptionValueBoolean>(false);
538 break;
539 case 1u << eTypeChar:
540 value_sp = std::make_shared<OptionValueChar>('\0');
541 break;
542 case 1u << eTypeFileSpec:
543 value_sp = std::make_shared<OptionValueFileSpec>();
544 break;
545 case 1u << eTypeFormat:
546 value_sp = std::make_shared<OptionValueFormat>(eFormatInvalid);
547 break;
548 case 1u << eTypeFormatEntity:
549 value_sp = std::make_shared<OptionValueFormatEntity>(nullptr);
550 break;
551 case 1u << eTypeLanguage:
552 value_sp = std::make_shared<OptionValueLanguage>(eLanguageTypeUnknown);
553 break;
554 case 1u << eTypeSInt64:
555 value_sp = std::make_shared<OptionValueSInt64>();
556 break;
557 case 1u << eTypeString:
558 value_sp = std::make_shared<OptionValueString>();
559 break;
560 case 1u << eTypeUInt64:
561 value_sp = std::make_shared<OptionValueUInt64>();
562 break;
563 case 1u << eTypeUUID:
564 value_sp = std::make_shared<OptionValueUUID>();
565 break;
568 if (value_sp)
569 error = value_sp->SetValueFromString(value_cstr, eVarSetOperationAssign);
570 else
571 error.SetErrorString("unsupported type mask");
572 return value_sp;
575 bool OptionValue::DumpQualifiedName(Stream &strm) const {
576 bool dumped_something = false;
577 lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
578 if (m_parent_sp) {
579 if (m_parent_sp->DumpQualifiedName(strm))
580 dumped_something = true;
582 llvm::StringRef name(GetName());
583 if (!name.empty()) {
584 if (dumped_something)
585 strm.PutChar('.');
586 else
587 dumped_something = true;
588 strm << name;
590 return dumped_something;
593 OptionValueSP OptionValue::DeepCopy(const OptionValueSP &new_parent) const {
594 auto clone = Clone();
595 clone->SetParent(new_parent);
596 return clone;
599 void OptionValue::AutoComplete(CommandInterpreter &interpreter,
600 CompletionRequest &request) {}
602 Status OptionValue::SetValueFromString(llvm::StringRef value,
603 VarSetOperationType op) {
604 Status error;
605 switch (op) {
606 case eVarSetOperationReplace:
607 error.SetErrorStringWithFormat(
608 "%s objects do not support the 'replace' operation",
609 GetTypeAsCString());
610 break;
611 case eVarSetOperationInsertBefore:
612 error.SetErrorStringWithFormat(
613 "%s objects do not support the 'insert-before' operation",
614 GetTypeAsCString());
615 break;
616 case eVarSetOperationInsertAfter:
617 error.SetErrorStringWithFormat(
618 "%s objects do not support the 'insert-after' operation",
619 GetTypeAsCString());
620 break;
621 case eVarSetOperationRemove:
622 error.SetErrorStringWithFormat(
623 "%s objects do not support the 'remove' operation", GetTypeAsCString());
624 break;
625 case eVarSetOperationAppend:
626 error.SetErrorStringWithFormat(
627 "%s objects do not support the 'append' operation", GetTypeAsCString());
628 break;
629 case eVarSetOperationClear:
630 error.SetErrorStringWithFormat(
631 "%s objects do not support the 'clear' operation", GetTypeAsCString());
632 break;
633 case eVarSetOperationAssign:
634 error.SetErrorStringWithFormat(
635 "%s objects do not support the 'assign' operation", GetTypeAsCString());
636 break;
637 case eVarSetOperationInvalid:
638 error.SetErrorStringWithFormat("invalid operation performed on a %s object",
639 GetTypeAsCString());
640 break;
642 return error;