//===-- 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/Cloneable.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-private-interfaces.h" #include "llvm/Support/JSON.h" 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; // 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, bool will_modify, Status &error) const { error.SetErrorStringWithFormat("'%s' is not a value subvalue", name.str().c_str()); 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 ConstString GetName() const { return ConstString(); } 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); // Get this value as a uint64_t value if it is encoded as a boolean, uint64_t // or int64_t. Other types will cause "fail_value" to be returned uint64_t GetUInt64Value(uint64_t fail_value, bool *success_ptr); OptionValueArch *GetAsArch(); const OptionValueArch *GetAsArch() const; OptionValueArray *GetAsArray(); const OptionValueArray *GetAsArray() const; OptionValueArgs *GetAsArgs(); const OptionValueArgs *GetAsArgs() const; OptionValueBoolean *GetAsBoolean(); OptionValueChar *GetAsChar(); const OptionValueBoolean *GetAsBoolean() const; 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 GetBooleanValue(bool fail_value = false) const; bool SetBooleanValue(bool new_value); char GetCharValue(char fail_value) const; char SetCharValue(char new_value); int64_t GetEnumerationValue(int64_t fail_value = -1) const; bool SetEnumerationValue(int64_t value); FileSpec GetFileSpecValue() const; bool SetFileSpecValue(const FileSpec &file_spec); FileSpecList GetFileSpecListValue() const; lldb::Format GetFormatValue(lldb::Format fail_value = lldb::eFormatDefault) const; bool SetFormatValue(lldb::Format new_value); lldb::LanguageType GetLanguageValue( lldb::LanguageType fail_value = lldb::eLanguageTypeUnknown) const; bool SetLanguageValue(lldb::LanguageType new_language); const FormatEntity::Entry *GetFormatEntity() const; const RegularExpression *GetRegexValue() const; int64_t GetSInt64Value(int64_t fail_value = 0) const; bool SetSInt64Value(int64_t new_value); llvm::StringRef GetStringValue(llvm::StringRef fail_value) const; llvm::StringRef GetStringValue() const { return GetStringValue(llvm::StringRef()); } bool SetStringValue(llvm::StringRef new_value); uint64_t GetUInt64Value(uint64_t fail_value = 0) const; bool SetUInt64Value(uint64_t new_value); UUID GetUUIDValue() const; bool SetUUIDValue(const UUID &uuid); 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 callback) { m_callback = std::move(callback); } void NotifyValueChanged() { if (m_callback) m_callback(); } 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 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. }; } // namespace lldb_private #endif // LLDB_INTERPRETER_OPTIONVALUE_H