diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h index 1c0288574cc8..6c395c81c37b 100644 --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -88,6 +88,20 @@ public: lldb::OptionValuePropertiesSP GetSubProperty (const ExecutionContext *exe_ctx, const ConstString &name); + + // We sometimes need to introduce a setting to enable experimental features, + // but then we don't want the setting for these to cause errors when the setting + // goes away. Add a sub-topic of the settings using this experimental name, and + // two things will happen. One is that settings that don't find the name will not + // be treated as errors. Also, if you decide to keep the settings just move them into + // the containing properties, and we will auto-forward the experimental settings to the + // real one. + static const char * + GetExperimentalSettingsName(); + + static bool + IsSettingExperimental(const char *setting); + protected: lldb::OptionValuePropertiesSP m_collection_sp; }; diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index 837ff18721e2..718c12d21a65 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -108,3 +108,27 @@ Properties::GetSubProperty (const ExecutionContext *exe_ctx, return lldb::OptionValuePropertiesSP(); } +const char * +Properties::GetExperimentalSettingsName() +{ + return "experimental"; +} + +bool +Properties::IsSettingExperimental(const char *setting) +{ + if (setting == nullptr) + return false; + + const char *experimental = GetExperimentalSettingsName(); + char *dot_pos = strchr(setting, '.'); + if (dot_pos == nullptr) + return strcmp(experimental, setting) == 0; + else + { + size_t first_elem_len = dot_pos - setting; + return strncmp(experimental, setting, first_elem_len) == 0; + } + +} + diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp index a3c28f70270f..7024c3601d9f 100644 --- a/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -164,8 +164,23 @@ OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx, switch (sub_name[0]) { case '.': - return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error); - + { + lldb::OptionValueSP return_val_sp; + return_val_sp = value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error); + if (!return_val_sp) + { + if (Properties::IsSettingExperimental(sub_name + 1)) + { + size_t experimental_len = strlen(Properties::GetExperimentalSettingsName()); + if (*(sub_name + experimental_len + 1) == '.') + return_val_sp = value_sp->GetSubValue(exe_ctx, sub_name + experimental_len + 2, will_modify, error); + // It isn't an error if an experimental setting is not present. + if (!return_val_sp) + error.Clear(); + } + } + return return_val_sp; + } case '{': // Predicate matching for predicates like // "{}"