diff options
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h')
-rw-r--r-- | contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h new file mode 100644 index 000000000000..bfbdbead72c6 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/OptionValue.h @@ -0,0 +1,396 @@ +//===-- OptionValue.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_OPTIONVALUE_H +#define LLDB_INTERPRETER_OPTIONVALUE_H + +#include "lldb/Core/FormatEntity.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Cloneable.h" +#include "lldb/Utility/CompletionRequest.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/FileSpecList.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StringList.h" +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-private-interfaces.h" +#include "llvm/Support/JSON.h" +#include <mutex> + +namespace lldb_private { + +// OptionValue +class OptionValue { +public: + enum Type { + eTypeInvalid = 0, + eTypeArch, + eTypeArgs, + eTypeArray, + eTypeBoolean, + eTypeChar, + eTypeDictionary, + eTypeEnum, + eTypeFileLineColumn, + eTypeFileSpec, + eTypeFileSpecList, + eTypeFormat, + eTypeLanguage, + eTypePathMap, + eTypeProperties, + eTypeRegex, + eTypeSInt64, + eTypeString, + eTypeUInt64, + eTypeUUID, + eTypeFormatEntity + }; + + enum { + eDumpOptionName = (1u << 0), + eDumpOptionType = (1u << 1), + eDumpOptionValue = (1u << 2), + eDumpOptionDescription = (1u << 3), + eDumpOptionRaw = (1u << 4), + eDumpOptionCommand = (1u << 5), + eDumpGroupValue = (eDumpOptionName | eDumpOptionType | eDumpOptionValue), + eDumpGroupHelp = + (eDumpOptionName | eDumpOptionType | eDumpOptionDescription), + eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue) + }; + + OptionValue() = default; + + virtual ~OptionValue() = default; + + OptionValue(const OptionValue &other); + + OptionValue& operator=(const OptionValue &other); + + // Subclasses should override these functions + virtual Type GetType() const = 0; + + // If this value is always hidden, the avoid showing any info on this value, + // just show the info for the child values. + virtual bool ValueIsTransparent() const { + return GetType() == eTypeProperties; + } + + virtual const char *GetTypeAsCString() const { + return GetBuiltinTypeAsCString(GetType()); + } + + static const char *GetBuiltinTypeAsCString(Type t); + + virtual void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) = 0; + + // TODO: make this function pure virtual after implementing it in all + // child classes. + virtual llvm::json::Value ToJSON(const ExecutionContext *exe_ctx) { + // Return nullptr which will create a llvm::json::Value() that is a NULL + // value. No setting should ever really have a NULL value in JSON. This + // indicates an error occurred and if/when we add a FromJSON() it will know + // to fail if someone tries to set it with a NULL JSON value. + return nullptr; + } + + virtual Status + SetValueFromString(llvm::StringRef value, + VarSetOperationType op = eVarSetOperationAssign); + + virtual void Clear() = 0; + + virtual lldb::OptionValueSP + DeepCopy(const lldb::OptionValueSP &new_parent) const; + + virtual void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request); + + // Subclasses can override these functions + virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, + llvm::StringRef name, + Status &error) const { + error.SetErrorStringWithFormatv("'{0}' is not a valid subvalue", name); + return lldb::OptionValueSP(); + } + + virtual Status SetSubValue(const ExecutionContext *exe_ctx, + VarSetOperationType op, llvm::StringRef name, + llvm::StringRef value); + + virtual bool IsAggregateValue() const { return false; } + + virtual llvm::StringRef GetName() const { return llvm::StringRef(); } + + virtual bool DumpQualifiedName(Stream &strm) const; + + // Subclasses should NOT override these functions as they use the above + // functions to implement functionality + uint32_t GetTypeAsMask() { return 1u << GetType(); } + + static uint32_t ConvertTypeToMask(OptionValue::Type type) { + return 1u << type; + } + + static OptionValue::Type ConvertTypeMaskToType(uint32_t type_mask) { + // If only one bit is set, then return an appropriate enumeration + switch (type_mask) { + case 1u << eTypeArch: + return eTypeArch; + case 1u << eTypeArgs: + return eTypeArgs; + case 1u << eTypeArray: + return eTypeArray; + case 1u << eTypeBoolean: + return eTypeBoolean; + case 1u << eTypeChar: + return eTypeChar; + case 1u << eTypeDictionary: + return eTypeDictionary; + case 1u << eTypeEnum: + return eTypeEnum; + case 1u << eTypeFileLineColumn: + return eTypeFileLineColumn; + case 1u << eTypeFileSpec: + return eTypeFileSpec; + case 1u << eTypeFileSpecList: + return eTypeFileSpecList; + case 1u << eTypeFormat: + return eTypeFormat; + case 1u << eTypeLanguage: + return eTypeLanguage; + case 1u << eTypePathMap: + return eTypePathMap; + case 1u << eTypeProperties: + return eTypeProperties; + case 1u << eTypeRegex: + return eTypeRegex; + case 1u << eTypeSInt64: + return eTypeSInt64; + case 1u << eTypeString: + return eTypeString; + case 1u << eTypeUInt64: + return eTypeUInt64; + case 1u << eTypeUUID: + return eTypeUUID; + } + // Else return invalid + return eTypeInvalid; + } + + static lldb::OptionValueSP + CreateValueFromCStringForTypeMask(const char *value_cstr, uint32_t type_mask, + Status &error); + + OptionValueArch *GetAsArch(); + const OptionValueArch *GetAsArch() const; + + OptionValueArray *GetAsArray(); + const OptionValueArray *GetAsArray() const; + + OptionValueArgs *GetAsArgs(); + const OptionValueArgs *GetAsArgs() const; + + OptionValueBoolean *GetAsBoolean(); + const OptionValueBoolean *GetAsBoolean() const; + + OptionValueChar *GetAsChar(); + const OptionValueChar *GetAsChar() const; + + OptionValueDictionary *GetAsDictionary(); + const OptionValueDictionary *GetAsDictionary() const; + + OptionValueEnumeration *GetAsEnumeration(); + const OptionValueEnumeration *GetAsEnumeration() const; + + OptionValueFileSpec *GetAsFileSpec(); + const OptionValueFileSpec *GetAsFileSpec() const; + + OptionValueFileSpecList *GetAsFileSpecList(); + const OptionValueFileSpecList *GetAsFileSpecList() const; + + OptionValueFormat *GetAsFormat(); + const OptionValueFormat *GetAsFormat() const; + + OptionValueLanguage *GetAsLanguage(); + const OptionValueLanguage *GetAsLanguage() const; + + OptionValuePathMappings *GetAsPathMappings(); + const OptionValuePathMappings *GetAsPathMappings() const; + + OptionValueProperties *GetAsProperties(); + const OptionValueProperties *GetAsProperties() const; + + OptionValueRegex *GetAsRegex(); + const OptionValueRegex *GetAsRegex() const; + + OptionValueSInt64 *GetAsSInt64(); + const OptionValueSInt64 *GetAsSInt64() const; + + OptionValueString *GetAsString(); + const OptionValueString *GetAsString() const; + + OptionValueUInt64 *GetAsUInt64(); + const OptionValueUInt64 *GetAsUInt64() const; + + OptionValueUUID *GetAsUUID(); + const OptionValueUUID *GetAsUUID() const; + + OptionValueFormatEntity *GetAsFormatEntity(); + const OptionValueFormatEntity *GetAsFormatEntity() const; + + bool AppendFileSpecValue(FileSpec file_spec); + + bool OptionWasSet() const { return m_value_was_set; } + + void SetOptionWasSet() { m_value_was_set = true; } + + void SetParent(const lldb::OptionValueSP &parent_sp) { + m_parent_wp = parent_sp; + } + + lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); } + + void SetValueChangedCallback(std::function<void()> callback) { + m_callback = std::move(callback); + } + + void NotifyValueChanged() { + if (m_callback) + m_callback(); + } + + template <typename T, std::enable_if_t<!std::is_pointer_v<T>, bool> = true> + std::optional<T> GetValueAs() const { + if constexpr (std::is_same_v<T, uint64_t>) + return GetUInt64Value(); + if constexpr (std::is_same_v<T, int64_t>) + return GetSInt64Value(); + if constexpr (std::is_same_v<T, bool>) + return GetBooleanValue(); + if constexpr (std::is_same_v<T, char>) + return GetCharValue(); + if constexpr (std::is_same_v<T, lldb::Format>) + return GetFormatValue(); + if constexpr (std::is_same_v<T, FileSpec>) + return GetFileSpecValue(); + if constexpr (std::is_same_v<T, FileSpecList>) + return GetFileSpecListValue(); + if constexpr (std::is_same_v<T, lldb::LanguageType>) + return GetLanguageValue(); + if constexpr (std::is_same_v<T, llvm::StringRef>) + return GetStringValue(); + if constexpr (std::is_same_v<T, ArchSpec>) + return GetArchSpecValue(); + if constexpr (std::is_enum_v<T>) + if (std::optional<int64_t> value = GetEnumerationValue()) + return static_cast<T>(*value); + return {}; + } + + template <typename T, + typename U = typename std::remove_const< + typename std::remove_pointer<T>::type>::type, + std::enable_if_t<std::is_pointer_v<T>, bool> = true> + T GetValueAs() const { + if constexpr (std::is_same_v<U, FormatEntity::Entry>) + return GetFormatEntity(); + if constexpr (std::is_same_v<U, RegularExpression>) + return GetRegexValue(); + return {}; + } + + bool SetValueAs(bool v) { return SetBooleanValue(v); } + + bool SetValueAs(char v) { return SetCharValue(v); } + + bool SetValueAs(uint64_t v) { return SetUInt64Value(v); } + + bool SetValueAs(int64_t v) { return SetSInt64Value(v); } + + bool SetValueAs(UUID v) { return SetUUIDValue(v); } + + bool SetValueAs(llvm::StringRef v) { return SetStringValue(v); } + + bool SetValueAs(lldb::LanguageType v) { return SetLanguageValue(v); } + + bool SetValueAs(lldb::Format v) { return SetFormatValue(v); } + + bool SetValueAs(FileSpec v) { return SetFileSpecValue(v); } + + bool SetValueAs(ArchSpec v) { return SetArchSpecValue(v); } + + template <typename T, std::enable_if_t<std::is_enum_v<T>, bool> = true> + bool SetValueAs(T t) { + return SetEnumerationValue(t); + } + +protected: + using TopmostBase = OptionValue; + + // Must be overriden by a derived class for correct downcasting the result of + // DeepCopy to it. Inherit from Cloneable to avoid doing this manually. + virtual lldb::OptionValueSP Clone() const = 0; + + lldb::OptionValueWP m_parent_wp; + std::function<void()> m_callback; + bool m_value_was_set = false; // This can be used to see if a value has been + // set by a call to SetValueFromCString(). It is + // often handy to know if an option value was + // set from the command line or as a setting, + // versus if we just have the default value that + // was already populated in the option value. +private: + std::optional<ArchSpec> GetArchSpecValue() const; + bool SetArchSpecValue(ArchSpec arch_spec); + + std::optional<bool> GetBooleanValue() const; + bool SetBooleanValue(bool new_value); + + std::optional<char> GetCharValue() const; + bool SetCharValue(char new_value); + + std::optional<int64_t> GetEnumerationValue() const; + bool SetEnumerationValue(int64_t value); + + std::optional<FileSpec> GetFileSpecValue() const; + bool SetFileSpecValue(FileSpec file_spec); + + std::optional<FileSpecList> GetFileSpecListValue() const; + + std::optional<int64_t> GetSInt64Value() const; + bool SetSInt64Value(int64_t new_value); + + std::optional<uint64_t> GetUInt64Value() const; + bool SetUInt64Value(uint64_t new_value); + + std::optional<lldb::Format> GetFormatValue() const; + bool SetFormatValue(lldb::Format new_value); + + std::optional<lldb::LanguageType> GetLanguageValue() const; + bool SetLanguageValue(lldb::LanguageType new_language); + + std::optional<llvm::StringRef> GetStringValue() const; + bool SetStringValue(llvm::StringRef new_value); + + std::optional<UUID> GetUUIDValue() const; + bool SetUUIDValue(const UUID &uuid); + + const FormatEntity::Entry *GetFormatEntity() const; + const RegularExpression *GetRegexValue() const; + + mutable std::mutex m_mutex; +}; + +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_OPTIONVALUE_H |