1 | //===-- OptionValue.h -------------------------------------------*- C++ -*-===// |
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 | #ifndef LLDB_INTERPRETER_OPTIONVALUE_H |
10 | #define LLDB_INTERPRETER_OPTIONVALUE_H |
11 | |
12 | #include "lldb/Core/FormatEntity.h" |
13 | #include "lldb/Utility/Cloneable.h" |
14 | #include "lldb/Utility/CompletionRequest.h" |
15 | #include "lldb/Utility/ConstString.h" |
16 | #include "lldb/Utility/Status.h" |
17 | #include "lldb/lldb-defines.h" |
18 | #include "lldb/lldb-private-enumerations.h" |
19 | #include "lldb/lldb-private-interfaces.h" |
20 | |
21 | namespace lldb_private { |
22 | |
23 | // OptionValue |
24 | class OptionValue { |
25 | public: |
26 | enum Type { |
27 | eTypeInvalid = 0, |
28 | eTypeArch, |
29 | eTypeArgs, |
30 | eTypeArray, |
31 | eTypeBoolean, |
32 | eTypeChar, |
33 | eTypeDictionary, |
34 | eTypeEnum, |
35 | eTypeFileLineColumn, |
36 | eTypeFileSpec, |
37 | eTypeFileSpecList, |
38 | eTypeFormat, |
39 | eTypeLanguage, |
40 | eTypePathMap, |
41 | eTypeProperties, |
42 | eTypeRegex, |
43 | eTypeSInt64, |
44 | eTypeString, |
45 | eTypeUInt64, |
46 | eTypeUUID, |
47 | eTypeFormatEntity |
48 | }; |
49 | |
50 | enum { |
51 | eDumpOptionName = (1u << 0), |
52 | eDumpOptionType = (1u << 1), |
53 | eDumpOptionValue = (1u << 2), |
54 | eDumpOptionDescription = (1u << 3), |
55 | eDumpOptionRaw = (1u << 4), |
56 | eDumpOptionCommand = (1u << 5), |
57 | eDumpGroupValue = (eDumpOptionName | eDumpOptionType | eDumpOptionValue), |
58 | eDumpGroupHelp = |
59 | (eDumpOptionName | eDumpOptionType | eDumpOptionDescription), |
60 | eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue) |
61 | }; |
62 | |
63 | OptionValue() : m_value_was_set(false) {} |
64 | |
65 | virtual ~OptionValue() = default; |
66 | |
67 | // Subclasses should override these functions |
68 | virtual Type GetType() const = 0; |
69 | |
70 | // If this value is always hidden, the avoid showing any info on this value, |
71 | // just show the info for the child values. |
72 | virtual bool ValueIsTransparent() const { |
73 | return GetType() == eTypeProperties; |
74 | } |
75 | |
76 | virtual const char *GetTypeAsCString() const { |
77 | return GetBuiltinTypeAsCString(GetType()); |
78 | } |
79 | |
80 | static const char *GetBuiltinTypeAsCString(Type t); |
81 | |
82 | virtual void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, |
83 | uint32_t dump_mask) = 0; |
84 | |
85 | virtual Status |
86 | SetValueFromString(llvm::StringRef value, |
87 | VarSetOperationType op = eVarSetOperationAssign); |
88 | |
89 | virtual void Clear() = 0; |
90 | |
91 | virtual lldb::OptionValueSP |
92 | DeepCopy(const lldb::OptionValueSP &new_parent) const; |
93 | |
94 | virtual void AutoComplete(CommandInterpreter &interpreter, |
95 | CompletionRequest &request); |
96 | |
97 | // Subclasses can override these functions |
98 | virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, |
99 | llvm::StringRef name, |
100 | bool will_modify, |
101 | Status &error) const { |
102 | error.SetErrorStringWithFormat("'%s' is not a value subvalue" , name.str().c_str()); |
103 | return lldb::OptionValueSP(); |
104 | } |
105 | |
106 | virtual Status SetSubValue(const ExecutionContext *exe_ctx, |
107 | VarSetOperationType op, llvm::StringRef name, |
108 | llvm::StringRef value); |
109 | |
110 | virtual bool IsAggregateValue() const { return false; } |
111 | |
112 | virtual ConstString GetName() const { return ConstString(); } |
113 | |
114 | virtual bool DumpQualifiedName(Stream &strm) const; |
115 | |
116 | // Subclasses should NOT override these functions as they use the above |
117 | // functions to implement functionality |
118 | uint32_t GetTypeAsMask() { return 1u << GetType(); } |
119 | |
120 | static uint32_t ConvertTypeToMask(OptionValue::Type type) { |
121 | return 1u << type; |
122 | } |
123 | |
124 | static OptionValue::Type ConvertTypeMaskToType(uint32_t type_mask) { |
125 | // If only one bit is set, then return an appropriate enumeration |
126 | switch (type_mask) { |
127 | case 1u << eTypeArch: |
128 | return eTypeArch; |
129 | case 1u << eTypeArgs: |
130 | return eTypeArgs; |
131 | case 1u << eTypeArray: |
132 | return eTypeArray; |
133 | case 1u << eTypeBoolean: |
134 | return eTypeBoolean; |
135 | case 1u << eTypeChar: |
136 | return eTypeChar; |
137 | case 1u << eTypeDictionary: |
138 | return eTypeDictionary; |
139 | case 1u << eTypeEnum: |
140 | return eTypeEnum; |
141 | case 1u << eTypeFileLineColumn: |
142 | return eTypeFileLineColumn; |
143 | case 1u << eTypeFileSpec: |
144 | return eTypeFileSpec; |
145 | case 1u << eTypeFileSpecList: |
146 | return eTypeFileSpecList; |
147 | case 1u << eTypeFormat: |
148 | return eTypeFormat; |
149 | case 1u << eTypeLanguage: |
150 | return eTypeLanguage; |
151 | case 1u << eTypePathMap: |
152 | return eTypePathMap; |
153 | case 1u << eTypeProperties: |
154 | return eTypeProperties; |
155 | case 1u << eTypeRegex: |
156 | return eTypeRegex; |
157 | case 1u << eTypeSInt64: |
158 | return eTypeSInt64; |
159 | case 1u << eTypeString: |
160 | return eTypeString; |
161 | case 1u << eTypeUInt64: |
162 | return eTypeUInt64; |
163 | case 1u << eTypeUUID: |
164 | return eTypeUUID; |
165 | } |
166 | // Else return invalid |
167 | return eTypeInvalid; |
168 | } |
169 | |
170 | static lldb::OptionValueSP |
171 | CreateValueFromCStringForTypeMask(const char *value_cstr, uint32_t type_mask, |
172 | Status &error); |
173 | |
174 | // Get this value as a uint64_t value if it is encoded as a boolean, uint64_t |
175 | // or int64_t. Other types will cause "fail_value" to be returned |
176 | uint64_t GetUInt64Value(uint64_t fail_value, bool *success_ptr); |
177 | |
178 | OptionValueArch *GetAsArch(); |
179 | |
180 | const OptionValueArch *GetAsArch() const; |
181 | |
182 | OptionValueArray *GetAsArray(); |
183 | |
184 | const OptionValueArray *GetAsArray() const; |
185 | |
186 | OptionValueArgs *GetAsArgs(); |
187 | |
188 | const OptionValueArgs *GetAsArgs() const; |
189 | |
190 | OptionValueBoolean *GetAsBoolean(); |
191 | |
192 | OptionValueChar *GetAsChar(); |
193 | |
194 | const OptionValueBoolean *GetAsBoolean() const; |
195 | |
196 | const OptionValueChar *GetAsChar() const; |
197 | |
198 | OptionValueDictionary *GetAsDictionary(); |
199 | |
200 | const OptionValueDictionary *GetAsDictionary() const; |
201 | |
202 | OptionValueEnumeration *GetAsEnumeration(); |
203 | |
204 | const OptionValueEnumeration *GetAsEnumeration() const; |
205 | |
206 | OptionValueFileSpec *GetAsFileSpec(); |
207 | |
208 | const OptionValueFileSpec *GetAsFileSpec() const; |
209 | |
210 | OptionValueFileSpecList *GetAsFileSpecList(); |
211 | |
212 | const OptionValueFileSpecList *GetAsFileSpecList() const; |
213 | |
214 | OptionValueFormat *GetAsFormat(); |
215 | |
216 | const OptionValueFormat *GetAsFormat() const; |
217 | |
218 | OptionValueLanguage *GetAsLanguage(); |
219 | |
220 | const OptionValueLanguage *GetAsLanguage() const; |
221 | |
222 | OptionValuePathMappings *GetAsPathMappings(); |
223 | |
224 | const OptionValuePathMappings *GetAsPathMappings() const; |
225 | |
226 | OptionValueProperties *GetAsProperties(); |
227 | |
228 | const OptionValueProperties *GetAsProperties() const; |
229 | |
230 | OptionValueRegex *GetAsRegex(); |
231 | |
232 | const OptionValueRegex *GetAsRegex() const; |
233 | |
234 | OptionValueSInt64 *GetAsSInt64(); |
235 | |
236 | const OptionValueSInt64 *GetAsSInt64() const; |
237 | |
238 | OptionValueString *GetAsString(); |
239 | |
240 | const OptionValueString *GetAsString() const; |
241 | |
242 | OptionValueUInt64 *GetAsUInt64(); |
243 | |
244 | const OptionValueUInt64 *GetAsUInt64() const; |
245 | |
246 | OptionValueUUID *GetAsUUID(); |
247 | |
248 | const OptionValueUUID *GetAsUUID() const; |
249 | |
250 | OptionValueFormatEntity *GetAsFormatEntity(); |
251 | |
252 | const OptionValueFormatEntity *GetAsFormatEntity() const; |
253 | |
254 | bool GetBooleanValue(bool fail_value = false) const; |
255 | |
256 | bool SetBooleanValue(bool new_value); |
257 | |
258 | char GetCharValue(char fail_value) const; |
259 | |
260 | char SetCharValue(char new_value); |
261 | |
262 | int64_t GetEnumerationValue(int64_t fail_value = -1) const; |
263 | |
264 | bool SetEnumerationValue(int64_t value); |
265 | |
266 | FileSpec GetFileSpecValue() const; |
267 | |
268 | bool SetFileSpecValue(const FileSpec &file_spec); |
269 | |
270 | FileSpecList GetFileSpecListValue() const; |
271 | |
272 | lldb::Format |
273 | GetFormatValue(lldb::Format fail_value = lldb::eFormatDefault) const; |
274 | |
275 | bool SetFormatValue(lldb::Format new_value); |
276 | |
277 | lldb::LanguageType GetLanguageValue( |
278 | lldb::LanguageType fail_value = lldb::eLanguageTypeUnknown) const; |
279 | |
280 | bool SetLanguageValue(lldb::LanguageType new_language); |
281 | |
282 | const FormatEntity::Entry *GetFormatEntity() const; |
283 | |
284 | const RegularExpression *GetRegexValue() const; |
285 | |
286 | int64_t GetSInt64Value(int64_t fail_value = 0) const; |
287 | |
288 | bool SetSInt64Value(int64_t new_value); |
289 | |
290 | llvm::StringRef GetStringValue(llvm::StringRef fail_value) const; |
291 | llvm::StringRef GetStringValue() const { return GetStringValue(llvm::StringRef()); } |
292 | |
293 | bool SetStringValue(llvm::StringRef new_value); |
294 | |
295 | uint64_t GetUInt64Value(uint64_t fail_value = 0) const; |
296 | |
297 | bool SetUInt64Value(uint64_t new_value); |
298 | |
299 | UUID GetUUIDValue() const; |
300 | |
301 | bool SetUUIDValue(const UUID &uuid); |
302 | |
303 | bool OptionWasSet() const { return m_value_was_set; } |
304 | |
305 | void SetOptionWasSet() { m_value_was_set = true; } |
306 | |
307 | void SetParent(const lldb::OptionValueSP &parent_sp) { |
308 | m_parent_wp = parent_sp; |
309 | } |
310 | |
311 | lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); } |
312 | |
313 | void SetValueChangedCallback(std::function<void()> callback) { |
314 | assert(!m_callback); |
315 | m_callback = std::move(callback); |
316 | } |
317 | |
318 | void NotifyValueChanged() { |
319 | if (m_callback) |
320 | m_callback(); |
321 | } |
322 | |
323 | protected: |
324 | using TopmostBase = OptionValue; |
325 | |
326 | // Must be overriden by a derived class for correct downcasting the result of |
327 | // DeepCopy to it. Inherit from Cloneable to avoid doing this manually. |
328 | virtual lldb::OptionValueSP Clone() const = 0; |
329 | |
330 | lldb::OptionValueWP m_parent_wp; |
331 | std::function<void()> m_callback; |
332 | bool m_value_was_set; // This can be used to see if a value has been set |
333 | // by a call to SetValueFromCString(). It is often |
334 | // handy to know if an option value was set from the |
335 | // command line or as a setting, versus if we just have |
336 | // the default value that was already populated in the |
337 | // option value. |
338 | }; |
339 | |
340 | } // namespace lldb_private |
341 | |
342 | #endif // LLDB_INTERPRETER_OPTIONVALUE_H |
343 | |