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//===----------------------------------------------------------------------===//
8
9#include "lldb/Interpreter/OptionValue.h"
10#include "lldb/Interpreter/OptionValues.h"
11#include "lldb/Utility/StringList.h"
12
13#include <memory>
14
15using namespace lldb;
16using namespace lldb_private;
17
18OptionValue::OptionValue(const OptionValue &other) {
19 std::lock_guard<std::mutex> lock(other.m_mutex);
20
21 m_parent_wp = other.m_parent_wp;
22 m_callback = other.m_callback;
23 m_value_was_set = other.m_value_was_set;
24
25}
26
27OptionValue& OptionValue::operator=(const OptionValue &other) {
28 std::scoped_lock<std::mutex, std::mutex> lock(m_mutex, other.m_mutex);
29
30 m_parent_wp = other.m_parent_wp;
31 m_callback = other.m_callback;
32 m_value_was_set = other.m_value_was_set;
33
34 return *this;
35}
36
37Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx,
38 VarSetOperationType op, llvm::StringRef name,
39 llvm::StringRef value) {
40 return Status::FromErrorString(str: "SetSubValue is not supported");
41}
42
43OptionValueBoolean *OptionValue::GetAsBoolean() {
44 if (GetType() == OptionValue::eTypeBoolean)
45 return static_cast<OptionValueBoolean *>(this);
46 return nullptr;
47}
48
49const OptionValueBoolean *OptionValue::GetAsBoolean() const {
50 if (GetType() == OptionValue::eTypeBoolean)
51 return static_cast<const OptionValueBoolean *>(this);
52 return nullptr;
53}
54
55const OptionValueChar *OptionValue::GetAsChar() const {
56 if (GetType() == OptionValue::eTypeChar)
57 return static_cast<const OptionValueChar *>(this);
58 return nullptr;
59}
60
61OptionValueChar *OptionValue::GetAsChar() {
62 if (GetType() == OptionValue::eTypeChar)
63 return static_cast<OptionValueChar *>(this);
64 return nullptr;
65}
66
67OptionValueFileSpec *OptionValue::GetAsFileSpec() {
68 if (GetType() == OptionValue::eTypeFileSpec)
69 return static_cast<OptionValueFileSpec *>(this);
70 return nullptr;
71}
72
73const OptionValueFileSpec *OptionValue::GetAsFileSpec() const {
74 if (GetType() == OptionValue::eTypeFileSpec)
75 return static_cast<const OptionValueFileSpec *>(this);
76 return nullptr;
77}
78
79OptionValueFileSpecList *OptionValue::GetAsFileSpecList() {
80 if (GetType() == OptionValue::eTypeFileSpecList)
81 return static_cast<OptionValueFileSpecList *>(this);
82 return nullptr;
83}
84
85const OptionValueFileSpecList *OptionValue::GetAsFileSpecList() const {
86 if (GetType() == OptionValue::eTypeFileSpecList)
87 return static_cast<const OptionValueFileSpecList *>(this);
88 return nullptr;
89}
90
91OptionValueArch *OptionValue::GetAsArch() {
92 if (GetType() == OptionValue::eTypeArch)
93 return static_cast<OptionValueArch *>(this);
94 return nullptr;
95}
96
97const OptionValueArch *OptionValue::GetAsArch() const {
98 if (GetType() == OptionValue::eTypeArch)
99 return static_cast<const OptionValueArch *>(this);
100 return nullptr;
101}
102
103OptionValueArray *OptionValue::GetAsArray() {
104 if (GetType() == OptionValue::eTypeArray)
105 return static_cast<OptionValueArray *>(this);
106 return nullptr;
107}
108
109const OptionValueArray *OptionValue::GetAsArray() const {
110 if (GetType() == OptionValue::eTypeArray)
111 return static_cast<const OptionValueArray *>(this);
112 return nullptr;
113}
114
115OptionValueArgs *OptionValue::GetAsArgs() {
116 if (GetType() == OptionValue::eTypeArgs)
117 return static_cast<OptionValueArgs *>(this);
118 return nullptr;
119}
120
121const OptionValueArgs *OptionValue::GetAsArgs() const {
122 if (GetType() == OptionValue::eTypeArgs)
123 return static_cast<const OptionValueArgs *>(this);
124 return nullptr;
125}
126
127OptionValueDictionary *OptionValue::GetAsDictionary() {
128 if (GetType() == OptionValue::eTypeDictionary)
129 return static_cast<OptionValueDictionary *>(this);
130 return nullptr;
131}
132
133const OptionValueDictionary *OptionValue::GetAsDictionary() const {
134 if (GetType() == OptionValue::eTypeDictionary)
135 return static_cast<const OptionValueDictionary *>(this);
136 return nullptr;
137}
138
139OptionValueEnumeration *OptionValue::GetAsEnumeration() {
140 if (GetType() == OptionValue::eTypeEnum)
141 return static_cast<OptionValueEnumeration *>(this);
142 return nullptr;
143}
144
145const OptionValueEnumeration *OptionValue::GetAsEnumeration() const {
146 if (GetType() == OptionValue::eTypeEnum)
147 return static_cast<const OptionValueEnumeration *>(this);
148 return nullptr;
149}
150
151OptionValueFormat *OptionValue::GetAsFormat() {
152 if (GetType() == OptionValue::eTypeFormat)
153 return static_cast<OptionValueFormat *>(this);
154 return nullptr;
155}
156
157const OptionValueFormat *OptionValue::GetAsFormat() const {
158 if (GetType() == OptionValue::eTypeFormat)
159 return static_cast<const OptionValueFormat *>(this);
160 return nullptr;
161}
162
163OptionValueLanguage *OptionValue::GetAsLanguage() {
164 if (GetType() == OptionValue::eTypeLanguage)
165 return static_cast<OptionValueLanguage *>(this);
166 return nullptr;
167}
168
169const OptionValueLanguage *OptionValue::GetAsLanguage() const {
170 if (GetType() == OptionValue::eTypeLanguage)
171 return static_cast<const OptionValueLanguage *>(this);
172 return nullptr;
173}
174
175OptionValueFormatEntity *OptionValue::GetAsFormatEntity() {
176 if (GetType() == OptionValue::eTypeFormatEntity)
177 return static_cast<OptionValueFormatEntity *>(this);
178 return nullptr;
179}
180
181const OptionValueFormatEntity *OptionValue::GetAsFormatEntity() const {
182 if (GetType() == OptionValue::eTypeFormatEntity)
183 return static_cast<const OptionValueFormatEntity *>(this);
184 return nullptr;
185}
186
187OptionValuePathMappings *OptionValue::GetAsPathMappings() {
188 if (GetType() == OptionValue::eTypePathMap)
189 return static_cast<OptionValuePathMappings *>(this);
190 return nullptr;
191}
192
193const OptionValuePathMappings *OptionValue::GetAsPathMappings() const {
194 if (GetType() == OptionValue::eTypePathMap)
195 return static_cast<const OptionValuePathMappings *>(this);
196 return nullptr;
197}
198
199OptionValueProperties *OptionValue::GetAsProperties() {
200 if (GetType() == OptionValue::eTypeProperties)
201 return static_cast<OptionValueProperties *>(this);
202 return nullptr;
203}
204
205const OptionValueProperties *OptionValue::GetAsProperties() const {
206 if (GetType() == OptionValue::eTypeProperties)
207 return static_cast<const OptionValueProperties *>(this);
208 return nullptr;
209}
210
211OptionValueRegex *OptionValue::GetAsRegex() {
212 if (GetType() == OptionValue::eTypeRegex)
213 return static_cast<OptionValueRegex *>(this);
214 return nullptr;
215}
216
217const OptionValueRegex *OptionValue::GetAsRegex() const {
218 if (GetType() == OptionValue::eTypeRegex)
219 return static_cast<const OptionValueRegex *>(this);
220 return nullptr;
221}
222
223OptionValueSInt64 *OptionValue::GetAsSInt64() {
224 if (GetType() == OptionValue::eTypeSInt64)
225 return static_cast<OptionValueSInt64 *>(this);
226 return nullptr;
227}
228
229const OptionValueSInt64 *OptionValue::GetAsSInt64() const {
230 if (GetType() == OptionValue::eTypeSInt64)
231 return static_cast<const OptionValueSInt64 *>(this);
232 return nullptr;
233}
234
235OptionValueString *OptionValue::GetAsString() {
236 if (GetType() == OptionValue::eTypeString)
237 return static_cast<OptionValueString *>(this);
238 return nullptr;
239}
240
241const OptionValueString *OptionValue::GetAsString() const {
242 if (GetType() == OptionValue::eTypeString)
243 return static_cast<const OptionValueString *>(this);
244 return nullptr;
245}
246
247OptionValueUInt64 *OptionValue::GetAsUInt64() {
248 if (GetType() == OptionValue::eTypeUInt64)
249 return static_cast<OptionValueUInt64 *>(this);
250 return nullptr;
251}
252
253const OptionValueUInt64 *OptionValue::GetAsUInt64() const {
254 if (GetType() == OptionValue::eTypeUInt64)
255 return static_cast<const OptionValueUInt64 *>(this);
256 return nullptr;
257}
258
259OptionValueUUID *OptionValue::GetAsUUID() {
260 if (GetType() == OptionValue::eTypeUUID)
261 return static_cast<OptionValueUUID *>(this);
262 return nullptr;
263}
264
265const OptionValueUUID *OptionValue::GetAsUUID() const {
266 if (GetType() == OptionValue::eTypeUUID)
267 return static_cast<const OptionValueUUID *>(this);
268 return nullptr;
269}
270
271std::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 {};
276}
277
278bool 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;
283 }
284 return false;
285}
286
287std::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 {};
292}
293
294bool 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;
299 }
300 return false;
301}
302
303std::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 {};
308}
309
310bool 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;
315 }
316 return false;
317}
318
319std::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 {};
324}
325
326bool OptionValue::SetFileSpecValue(FileSpec file_spec) {
327 std::lock_guard<std::mutex> lock(m_mutex);
328 if (OptionValueFileSpec *option_value = GetAsFileSpec()) {
329 option_value->SetCurrentValue(value: file_spec, set_value_was_set: false);
330 return true;
331 }
332 return false;
333}
334
335bool OptionValue::AppendFileSpecValue(FileSpec file_spec) {
336 std::lock_guard<std::mutex> lock(m_mutex);
337 if (OptionValueFileSpecList *option_value = GetAsFileSpecList()) {
338 option_value->AppendCurrentValue(value: file_spec);
339 return true;
340 }
341 return false;
342}
343
344std::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 {};
349}
350
351std::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 {};
356}
357
358bool 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;
363 }
364 return false;
365}
366
367std::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 {};
372}
373
374bool 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;
379 }
380 return false;
381}
382
383FormatEntity::Entry OptionValue::GetFormatEntityValue() const {
384 std::lock_guard<std::mutex> lock(m_mutex);
385 if (const OptionValueFormatEntity *option_value = GetAsFormatEntity())
386 return option_value->GetCurrentValue();
387 return {};
388}
389
390const 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;
395}
396
397std::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 {};
402}
403
404bool 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;
409 }
410 return false;
411}
412
413std::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 {};
418}
419
420bool 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;
425 }
426 return false;
427}
428
429std::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 {};
434}
435
436bool 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;
441 }
442 return false;
443}
444
445std::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 {};
450}
451
452bool 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;
457 }
458 return false;
459}
460
461std::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 {};
466}
467
468bool OptionValue::SetArchSpecValue(ArchSpec arch_spec) {
469 std::lock_guard<std::mutex> lock(m_mutex);
470 if (OptionValueArch *option_value = GetAsArch()) {
471 option_value->SetCurrentValue(value: arch_spec, set_value_was_set: false);
472 return true;
473 }
474 return false;
475}
476
477bool OptionValue::SetFormatEntityValue(const FormatEntity::Entry &entry) {
478 std::lock_guard<std::mutex> lock(m_mutex);
479 if (OptionValueFormatEntity *option_value = GetAsFormatEntity()) {
480 option_value->SetCurrentValue(entry);
481 return true;
482 }
483 return false;
484}
485
486const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
487 switch (t) {
488 case eTypeInvalid:
489 return "invalid";
490 case eTypeArch:
491 return "arch";
492 case eTypeArgs:
493 return "arguments";
494 case eTypeArray:
495 return "array";
496 case eTypeBoolean:
497 return "boolean";
498 case eTypeChar:
499 return "char";
500 case eTypeDictionary:
501 return "dictionary";
502 case eTypeEnum:
503 return "enum";
504 case eTypeFileLineColumn:
505 return "file:line:column specifier";
506 case eTypeFileSpec:
507 return "file";
508 case eTypeFileSpecList:
509 return "file-list";
510 case eTypeFormat:
511 return "format";
512 case eTypeFormatEntity:
513 return "format-string";
514 case eTypeLanguage:
515 return "language";
516 case eTypePathMap:
517 return "path-map";
518 case eTypeProperties:
519 return "properties";
520 case eTypeRegex:
521 return "regex";
522 case eTypeSInt64:
523 return "int";
524 case eTypeString:
525 return "string";
526 case eTypeUInt64:
527 return "unsigned";
528 case eTypeUUID:
529 return "uuid";
530 }
531 return nullptr;
532}
533
534lldb::OptionValueSP OptionValue::CreateValueFromCStringForTypeMask(
535 const char *value_cstr, uint32_t type_mask, Status &error) {
536 // If only 1 bit is set in the type mask for a dictionary or array then we
537 // know how to decode a value from a cstring
538 lldb::OptionValueSP value_sp;
539 switch (type_mask) {
540 case 1u << eTypeArch:
541 value_sp = std::make_shared<OptionValueArch>();
542 break;
543 case 1u << eTypeBoolean:
544 value_sp = std::make_shared<OptionValueBoolean>(args: false);
545 break;
546 case 1u << eTypeChar:
547 value_sp = std::make_shared<OptionValueChar>(args: '\0');
548 break;
549 case 1u << eTypeFileSpec:
550 value_sp = std::make_shared<OptionValueFileSpec>();
551 break;
552 case 1u << eTypeFormat:
553 value_sp = std::make_shared<OptionValueFormat>(args: eFormatInvalid);
554 break;
555 case 1u << eTypeFormatEntity:
556 value_sp = std::make_shared<OptionValueFormatEntity>(args: nullptr);
557 break;
558 case 1u << eTypeLanguage:
559 value_sp = std::make_shared<OptionValueLanguage>(args: eLanguageTypeUnknown);
560 break;
561 case 1u << eTypeSInt64:
562 value_sp = std::make_shared<OptionValueSInt64>();
563 break;
564 case 1u << eTypeString:
565 value_sp = std::make_shared<OptionValueString>();
566 break;
567 case 1u << eTypeUInt64:
568 value_sp = std::make_shared<OptionValueUInt64>();
569 break;
570 case 1u << eTypeUUID:
571 value_sp = std::make_shared<OptionValueUUID>();
572 break;
573 }
574
575 if (value_sp)
576 error = value_sp->SetValueFromString(value: value_cstr, op: eVarSetOperationAssign);
577 else
578 error = Status::FromErrorString(str: "unsupported type mask");
579 return value_sp;
580}
581
582bool OptionValue::DumpQualifiedName(Stream &strm) const {
583 bool dumped_something = false;
584 lldb::OptionValueSP m_parent_sp(m_parent_wp.lock());
585 if (m_parent_sp) {
586 if (m_parent_sp->DumpQualifiedName(strm))
587 dumped_something = true;
588 }
589 llvm::StringRef name(GetName());
590 if (!name.empty()) {
591 if (dumped_something)
592 strm.PutChar(ch: '.');
593 else
594 dumped_something = true;
595 strm << name;
596 }
597 return dumped_something;
598}
599
600OptionValueSP OptionValue::DeepCopy(const OptionValueSP &new_parent) const {
601 auto clone = Clone();
602 clone->SetParent(new_parent);
603 return clone;
604}
605
606void OptionValue::AutoComplete(CommandInterpreter &interpreter,
607 CompletionRequest &request) {}
608
609Status OptionValue::SetValueFromString(llvm::StringRef value,
610 VarSetOperationType op) {
611 Status error;
612 switch (op) {
613 case eVarSetOperationReplace:
614 error = Status::FromErrorStringWithFormat(
615 format: "%s objects do not support the 'replace' operation",
616 GetTypeAsCString());
617 break;
618 case eVarSetOperationInsertBefore:
619 error = Status::FromErrorStringWithFormat(
620 format: "%s objects do not support the 'insert-before' operation",
621 GetTypeAsCString());
622 break;
623 case eVarSetOperationInsertAfter:
624 error = Status::FromErrorStringWithFormat(
625 format: "%s objects do not support the 'insert-after' operation",
626 GetTypeAsCString());
627 break;
628 case eVarSetOperationRemove:
629 error = Status::FromErrorStringWithFormat(
630 format: "%s objects do not support the 'remove' operation", GetTypeAsCString());
631 break;
632 case eVarSetOperationAppend:
633 error = Status::FromErrorStringWithFormat(
634 format: "%s objects do not support the 'append' operation", GetTypeAsCString());
635 break;
636 case eVarSetOperationClear:
637 error = Status::FromErrorStringWithFormat(
638 format: "%s objects do not support the 'clear' operation", GetTypeAsCString());
639 break;
640 case eVarSetOperationAssign:
641 error = Status::FromErrorStringWithFormat(
642 format: "%s objects do not support the 'assign' operation", GetTypeAsCString());
643 break;
644 case eVarSetOperationInvalid:
645 error = Status::FromErrorStringWithFormat(
646 format: "invalid operation performed on a %s object", GetTypeAsCString());
647 break;
648 }
649 return error;
650}
651

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lldb/source/Interpreter/OptionValue.cpp