Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:50

0001 //===-- OptionValue.h -------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_INTERPRETER_OPTIONVALUE_H
0010 #define LLDB_INTERPRETER_OPTIONVALUE_H
0011 
0012 #include "lldb/Core/FormatEntity.h"
0013 #include "lldb/Utility/ArchSpec.h"
0014 #include "lldb/Utility/Cloneable.h"
0015 #include "lldb/Utility/CompletionRequest.h"
0016 #include "lldb/Utility/ConstString.h"
0017 #include "lldb/Utility/FileSpec.h"
0018 #include "lldb/Utility/FileSpecList.h"
0019 #include "lldb/Utility/Status.h"
0020 #include "lldb/Utility/StringList.h"
0021 #include "lldb/Utility/UUID.h"
0022 #include "lldb/lldb-defines.h"
0023 #include "lldb/lldb-private-enumerations.h"
0024 #include "lldb/lldb-private-interfaces.h"
0025 #include "llvm/Support/JSON.h"
0026 #include <mutex>
0027 
0028 namespace lldb_private {
0029 
0030 // OptionValue
0031 class OptionValue {
0032 public:
0033   enum Type {
0034     eTypeInvalid = 0,
0035     eTypeArch,
0036     eTypeArgs,
0037     eTypeArray,
0038     eTypeBoolean,
0039     eTypeChar,
0040     eTypeDictionary,
0041     eTypeEnum,
0042     eTypeFileLineColumn,
0043     eTypeFileSpec,
0044     eTypeFileSpecList,
0045     eTypeFormat,
0046     eTypeLanguage,
0047     eTypePathMap,
0048     eTypeProperties,
0049     eTypeRegex,
0050     eTypeSInt64,
0051     eTypeString,
0052     eTypeUInt64,
0053     eTypeUUID,
0054     eTypeFormatEntity
0055   };
0056 
0057   enum {
0058     eDumpOptionName = (1u << 0),
0059     eDumpOptionType = (1u << 1),
0060     eDumpOptionValue = (1u << 2),
0061     eDumpOptionDescription = (1u << 3),
0062     eDumpOptionRaw = (1u << 4),
0063     eDumpOptionCommand = (1u << 5),
0064     eDumpGroupValue = (eDumpOptionName | eDumpOptionType | eDumpOptionValue),
0065     eDumpGroupHelp =
0066         (eDumpOptionName | eDumpOptionType | eDumpOptionDescription),
0067     eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue)
0068   };
0069 
0070   OptionValue() = default;
0071 
0072   virtual ~OptionValue() = default;
0073 
0074   OptionValue(const OptionValue &other);
0075   
0076   OptionValue& operator=(const OptionValue &other);
0077 
0078   // Subclasses should override these functions
0079   virtual Type GetType() const = 0;
0080 
0081   // If this value is always hidden, the avoid showing any info on this value,
0082   // just show the info for the child values.
0083   virtual bool ValueIsTransparent() const {
0084     return GetType() == eTypeProperties;
0085   }
0086 
0087   virtual const char *GetTypeAsCString() const {
0088     return GetBuiltinTypeAsCString(GetType());
0089   }
0090 
0091   static const char *GetBuiltinTypeAsCString(Type t);
0092 
0093   virtual void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
0094                          uint32_t dump_mask) = 0;
0095 
0096   // TODO: make this function pure virtual after implementing it in all
0097   // child classes.
0098   virtual llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) {
0099     // Return nullptr which will create a llvm::json::Value() that is a NULL
0100     // value. No setting should ever really have a NULL value in JSON. This
0101     // indicates an error occurred and if/when we add a FromJSON() it will know
0102     // to fail if someone tries to set it with a NULL JSON value.
0103     return nullptr;
0104   }
0105 
0106   virtual Status
0107   SetValueFromString(llvm::StringRef value,
0108                      VarSetOperationType op = eVarSetOperationAssign);
0109 
0110   virtual void Clear() = 0;
0111 
0112   virtual lldb::OptionValueSP
0113   DeepCopy(const lldb::OptionValueSP &new_parent) const;
0114 
0115   virtual void AutoComplete(CommandInterpreter &interpreter,
0116                             CompletionRequest &request);
0117 
0118   // Subclasses can override these functions
0119   virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx,
0120                                           llvm::StringRef name,
0121                                           Status &error) const {
0122     error = Status::FromErrorStringWithFormatv("'{0}' is not a valid subvalue",
0123                                                name);
0124     return lldb::OptionValueSP();
0125   }
0126 
0127   virtual Status SetSubValue(const ExecutionContext *exe_ctx,
0128                              VarSetOperationType op, llvm::StringRef name,
0129                              llvm::StringRef value);
0130 
0131   virtual bool IsAggregateValue() const { return false; }
0132 
0133   virtual llvm::StringRef GetName() const { return llvm::StringRef(); }
0134 
0135   virtual bool DumpQualifiedName(Stream &strm) const;
0136 
0137   // Subclasses should NOT override these functions as they use the above
0138   // functions to implement functionality
0139   uint32_t GetTypeAsMask() { return 1u << GetType(); }
0140 
0141   static uint32_t ConvertTypeToMask(OptionValue::Type type) {
0142     return 1u << type;
0143   }
0144 
0145   static OptionValue::Type ConvertTypeMaskToType(uint32_t type_mask) {
0146     // If only one bit is set, then return an appropriate enumeration
0147     switch (type_mask) {
0148     case 1u << eTypeArch:
0149       return eTypeArch;
0150     case 1u << eTypeArgs:
0151       return eTypeArgs;
0152     case 1u << eTypeArray:
0153       return eTypeArray;
0154     case 1u << eTypeBoolean:
0155       return eTypeBoolean;
0156     case 1u << eTypeChar:
0157       return eTypeChar;
0158     case 1u << eTypeDictionary:
0159       return eTypeDictionary;
0160     case 1u << eTypeEnum:
0161       return eTypeEnum;
0162     case 1u << eTypeFileLineColumn:
0163       return eTypeFileLineColumn;
0164     case 1u << eTypeFileSpec:
0165       return eTypeFileSpec;
0166     case 1u << eTypeFileSpecList:
0167       return eTypeFileSpecList;
0168     case 1u << eTypeFormat:
0169       return eTypeFormat;
0170     case 1u << eTypeLanguage:
0171       return eTypeLanguage;
0172     case 1u << eTypePathMap:
0173       return eTypePathMap;
0174     case 1u << eTypeProperties:
0175       return eTypeProperties;
0176     case 1u << eTypeRegex:
0177       return eTypeRegex;
0178     case 1u << eTypeSInt64:
0179       return eTypeSInt64;
0180     case 1u << eTypeString:
0181       return eTypeString;
0182     case 1u << eTypeUInt64:
0183       return eTypeUInt64;
0184     case 1u << eTypeUUID:
0185       return eTypeUUID;
0186     }
0187     // Else return invalid
0188     return eTypeInvalid;
0189   }
0190 
0191   static lldb::OptionValueSP
0192   CreateValueFromCStringForTypeMask(const char *value_cstr, uint32_t type_mask,
0193                                     Status &error);
0194 
0195   OptionValueArch *GetAsArch();
0196   const OptionValueArch *GetAsArch() const;
0197 
0198   OptionValueArray *GetAsArray();
0199   const OptionValueArray *GetAsArray() const;
0200 
0201   OptionValueArgs *GetAsArgs();
0202   const OptionValueArgs *GetAsArgs() const;
0203 
0204   OptionValueBoolean *GetAsBoolean();
0205   const OptionValueBoolean *GetAsBoolean() const;
0206 
0207   OptionValueChar *GetAsChar();
0208   const OptionValueChar *GetAsChar() const;
0209 
0210   OptionValueDictionary *GetAsDictionary();
0211   const OptionValueDictionary *GetAsDictionary() const;
0212 
0213   OptionValueEnumeration *GetAsEnumeration();
0214   const OptionValueEnumeration *GetAsEnumeration() const;
0215 
0216   OptionValueFileSpec *GetAsFileSpec();
0217   const OptionValueFileSpec *GetAsFileSpec() const;
0218 
0219   OptionValueFileSpecList *GetAsFileSpecList();
0220   const OptionValueFileSpecList *GetAsFileSpecList() const;
0221 
0222   OptionValueFormat *GetAsFormat();
0223   const OptionValueFormat *GetAsFormat() const;
0224 
0225   OptionValueLanguage *GetAsLanguage();
0226   const OptionValueLanguage *GetAsLanguage() const;
0227 
0228   OptionValuePathMappings *GetAsPathMappings();
0229   const OptionValuePathMappings *GetAsPathMappings() const;
0230 
0231   OptionValueProperties *GetAsProperties();
0232   const OptionValueProperties *GetAsProperties() const;
0233 
0234   OptionValueRegex *GetAsRegex();
0235   const OptionValueRegex *GetAsRegex() const;
0236 
0237   OptionValueSInt64 *GetAsSInt64();
0238   const OptionValueSInt64 *GetAsSInt64() const;
0239 
0240   OptionValueString *GetAsString();
0241   const OptionValueString *GetAsString() const;
0242 
0243   OptionValueUInt64 *GetAsUInt64();
0244   const OptionValueUInt64 *GetAsUInt64() const;
0245 
0246   OptionValueUUID *GetAsUUID();
0247   const OptionValueUUID *GetAsUUID() const;
0248 
0249   OptionValueFormatEntity *GetAsFormatEntity();
0250   const OptionValueFormatEntity *GetAsFormatEntity() const;
0251 
0252   bool AppendFileSpecValue(FileSpec file_spec);
0253 
0254   bool OptionWasSet() const { return m_value_was_set; }
0255 
0256   void SetOptionWasSet() { m_value_was_set = true; }
0257 
0258   void SetParent(const lldb::OptionValueSP &parent_sp) {
0259     m_parent_wp = parent_sp;
0260   }
0261 
0262   lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); }
0263 
0264   void SetValueChangedCallback(std::function<void()> callback) {
0265     m_callback = std::move(callback);
0266   }
0267 
0268   void NotifyValueChanged() {
0269     if (m_callback)
0270       m_callback();
0271   }
0272 
0273   template <typename T, std::enable_if_t<!std::is_pointer_v<T>, bool> = true>
0274   std::optional<T> GetValueAs() const {
0275     if constexpr (std::is_same_v<T, uint64_t>)
0276       return GetUInt64Value();
0277     if constexpr (std::is_same_v<T, int64_t>)
0278       return GetSInt64Value();
0279     if constexpr (std::is_same_v<T, bool>)
0280       return GetBooleanValue();
0281     if constexpr (std::is_same_v<T, char>)
0282       return GetCharValue();
0283     if constexpr (std::is_same_v<T, lldb::Format>)
0284       return GetFormatValue();
0285     if constexpr (std::is_same_v<T, FileSpec>)
0286       return GetFileSpecValue();
0287     if constexpr (std::is_same_v<T, FileSpecList>)
0288       return GetFileSpecListValue();
0289     if constexpr (std::is_same_v<T, lldb::LanguageType>)
0290       return GetLanguageValue();
0291     if constexpr (std::is_same_v<T, llvm::StringRef>)
0292       return GetStringValue();
0293     if constexpr (std::is_same_v<T, ArchSpec>)
0294       return GetArchSpecValue();
0295     if constexpr (std::is_enum_v<T>)
0296       if (std::optional<int64_t> value = GetEnumerationValue())
0297         return static_cast<T>(*value);
0298     return {};
0299   }
0300 
0301   template <typename T,
0302             typename U = typename std::remove_const<
0303                 typename std::remove_pointer<T>::type>::type,
0304             std::enable_if_t<std::is_pointer_v<T>, bool> = true>
0305   T GetValueAs() const {
0306     if constexpr (std::is_same_v<U, FormatEntity::Entry>)
0307       return GetFormatEntity();
0308     if constexpr (std::is_same_v<U, RegularExpression>)
0309       return GetRegexValue();
0310     return {};
0311   }
0312 
0313   bool SetValueAs(bool v) { return SetBooleanValue(v); }
0314 
0315   bool SetValueAs(char v) { return SetCharValue(v); }
0316 
0317   bool SetValueAs(uint64_t v) { return SetUInt64Value(v); }
0318 
0319   bool SetValueAs(int64_t v) { return SetSInt64Value(v); }
0320 
0321   bool SetValueAs(UUID v) { return SetUUIDValue(v); }
0322 
0323   bool SetValueAs(llvm::StringRef v) { return SetStringValue(v); }
0324 
0325   bool SetValueAs(lldb::LanguageType v) { return SetLanguageValue(v); }
0326 
0327   bool SetValueAs(lldb::Format v) { return SetFormatValue(v); }
0328 
0329   bool SetValueAs(FileSpec v) { return SetFileSpecValue(v); }
0330 
0331   bool SetValueAs(ArchSpec v) { return SetArchSpecValue(v); }
0332 
0333   template <typename T, std::enable_if_t<std::is_enum_v<T>, bool> = true>
0334   bool SetValueAs(T t) {
0335     return SetEnumerationValue(t);
0336   }
0337 
0338 protected:
0339   using TopmostBase = OptionValue;
0340 
0341   // Must be overriden by a derived class for correct downcasting the result of
0342   // DeepCopy to it. Inherit from Cloneable to avoid doing this manually.
0343   virtual lldb::OptionValueSP Clone() const = 0;
0344 
0345   lldb::OptionValueWP m_parent_wp;
0346   std::function<void()> m_callback;
0347   bool m_value_was_set = false; // This can be used to see if a value has been
0348                                 // set by a call to SetValueFromCString(). It is
0349                                 // often handy to know if an option value was
0350                                 // set from the command line or as a setting,
0351                                 // versus if we just have the default value that
0352                                 // was already populated in the option value.
0353 private:
0354   std::optional<ArchSpec> GetArchSpecValue() const;
0355   bool SetArchSpecValue(ArchSpec arch_spec);
0356 
0357   std::optional<bool> GetBooleanValue() const;
0358   bool SetBooleanValue(bool new_value);
0359 
0360   std::optional<char> GetCharValue() const;
0361   bool SetCharValue(char new_value);
0362 
0363   std::optional<int64_t> GetEnumerationValue() const;
0364   bool SetEnumerationValue(int64_t value);
0365 
0366   std::optional<FileSpec> GetFileSpecValue() const;
0367   bool SetFileSpecValue(FileSpec file_spec);
0368 
0369   std::optional<FileSpecList> GetFileSpecListValue() const;
0370 
0371   std::optional<int64_t> GetSInt64Value() const;
0372   bool SetSInt64Value(int64_t new_value);
0373 
0374   std::optional<uint64_t> GetUInt64Value() const;
0375   bool SetUInt64Value(uint64_t new_value);
0376 
0377   std::optional<lldb::Format> GetFormatValue() const;
0378   bool SetFormatValue(lldb::Format new_value);
0379 
0380   std::optional<lldb::LanguageType> GetLanguageValue() const;
0381   bool SetLanguageValue(lldb::LanguageType new_language);
0382 
0383   std::optional<llvm::StringRef> GetStringValue() const;
0384   bool SetStringValue(llvm::StringRef new_value);
0385 
0386   std::optional<UUID> GetUUIDValue() const;
0387   bool SetUUIDValue(const UUID &uuid);
0388 
0389   const FormatEntity::Entry *GetFormatEntity() const;
0390   const RegularExpression *GetRegexValue() const;
0391   
0392   mutable std::mutex m_mutex;
0393 };
0394 
0395 } // namespace lldb_private
0396 
0397 #endif // LLDB_INTERPRETER_OPTIONVALUE_H