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() = default;
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 = false; // This can be used to see if a value has been
333                                 // set by a call to SetValueFromCString(). It is
334                                 // often handy to know if an option value was
335                                 // set from the command line or as a setting,
336                                 // versus if we just have the default value that
337                                 // was already populated in the option value.
338 };
339 
340 } // namespace lldb_private
341 
342 #endif // LLDB_INTERPRETER_OPTIONVALUE_H
343