[lldb] Create a property to store the REPL language

Until the introduction of the C++ REPL, there was always a single REPL
language. Several places relied on this assumption through
repl_languages.GetSingularLanguage. Now that this is no longer the case,
we need a way to specify a selected/preferred REPL language. This patch
does that with the help of a debugger property, taking inspiration from
how we store the scripting language.

Differential revision: https://reviews.llvm.org/D116697
This commit is contained in:
Jonas Devlieghere 2022-01-05 14:42:21 -08:00
parent 2819e5de42
commit 46a28a954e
10 changed files with 81 additions and 12 deletions

View File

@ -306,6 +306,10 @@ public:
void SetScriptLanguage(lldb::ScriptLanguage script_lang);
lldb::LanguageType GetREPLLanguage() const;
void SetREPLLanguage(lldb::LanguageType repl_lang);
bool GetCloseInputOnEOF() const;
void SetCloseInputOnEOF(bool b);

View File

@ -306,6 +306,10 @@ public:
bool SetScriptLanguage(lldb::ScriptLanguage script_lang);
lldb::LanguageType GetREPLLanguage() const;
bool SetREPLLanguage(lldb::LanguageType repl_lang);
uint32_t GetTerminalWidth() const;
bool SetTerminalWidth(uint32_t term_width);

View File

@ -114,6 +114,9 @@ public:
GetPropertyAtIndexAsOptionValueLanguage(const ExecutionContext *exe_ctx,
uint32_t idx) const;
bool SetPropertyAtIndexAsLanguage(const ExecutionContext *exe_ctx,
uint32_t idx, lldb::LanguageType lang);
bool GetPropertyAtIndexAsArgs(const ExecutionContext *exe_ctx, uint32_t idx,
Args &args) const;

View File

@ -1425,6 +1425,22 @@ void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) {
}
}
LanguageType SBDebugger::GetREPLLanguage() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::LanguageType, SBDebugger,
GetREPLLanguage);
return (m_opaque_sp ? m_opaque_sp->GetREPLLanguage() : eLanguageTypeUnknown);
}
void SBDebugger::SetREPLLanguage(LanguageType repl_lang) {
LLDB_RECORD_METHOD(void, SBDebugger, SetREPLLanguage, (lldb::LanguageType),
repl_lang);
if (m_opaque_sp) {
m_opaque_sp->SetREPLLanguage(repl_lang);
}
}
bool SBDebugger::SetUseExternalEditor(bool value) {
LLDB_RECORD_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool), value);
@ -1870,6 +1886,9 @@ template <> void RegisterMethods<SBDebugger>(Registry &R) {
GetScriptLanguage, ());
LLDB_REGISTER_METHOD(void, SBDebugger, SetScriptLanguage,
(lldb::ScriptLanguage));
LLDB_REGISTER_METHOD_CONST(lldb::LanguageType, SBDebugger, GetREPLLanguage,
());
LLDB_REGISTER_METHOD(void, SBDebugger, SetREPLLanguage, (lldb::LanguageType));
LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool));
LLDB_REGISTER_METHOD(bool, SBDebugger, GetUseExternalEditor, ());
LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseColor, (bool));

View File

@ -62,6 +62,10 @@ let Definition = "debugger" in {
DefaultEnumValue<"eScriptLanguagePython">,
EnumValues<"OptionEnumValues(g_language_enumerators)">,
Desc<"The script language to be used for evaluating user-written scripts.">;
def REPLLanguage: Property<"repl-lang", "Language">,
Global,
DefaultEnumValue<"eLanguageTypeUnknown">,
Desc<"The language to use for the REPL.">;
def StopDisassemblyCount: Property<"stop-disassembly-count", "SInt64">,
Global,
DefaultUnsignedValue<4>,

View File

@ -25,6 +25,7 @@
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Interpreter/OptionValueLanguage.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/OptionValueSInt64.h"
#include "lldb/Interpreter/OptionValueString.h"
@ -324,6 +325,20 @@ bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
script_lang);
}
lldb::LanguageType Debugger::GetREPLLanguage() const {
const uint32_t idx = ePropertyREPLLanguage;
OptionValueLanguage *value =
m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage(nullptr, idx);
if (value)
return value->GetCurrentValue();
return LanguageType();
}
bool Debugger::SetREPLLanguage(lldb::LanguageType repl_lang) {
const uint32_t idx = ePropertyREPLLanguage;
return m_collection_sp->SetPropertyAtIndexAsLanguage(nullptr, idx, repl_lang);
}
uint32_t Debugger::GetTerminalWidth() const {
const uint32_t idx = ePropertyTerminalWidth;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
@ -1753,17 +1768,20 @@ Status Debugger::RunREPL(LanguageType language, const char *repl_options) {
Status err;
FileSpec repl_executable;
if (language == eLanguageTypeUnknown)
language = GetREPLLanguage();
if (language == eLanguageTypeUnknown) {
LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
if (auto single_lang = repl_languages.GetSingularLanguage()) {
language = *single_lang;
} else if (repl_languages.Empty()) {
err.SetErrorStringWithFormat(
err.SetErrorString(
"LLDB isn't configured with REPL support for any languages.");
return err;
} else {
err.SetErrorStringWithFormat(
err.SetErrorString(
"Multiple possible REPL languages. Please specify a language.");
return err;
}

View File

@ -2259,13 +2259,15 @@ static void GetHomeInitFile(llvm::SmallVectorImpl<char> &init_file,
FileSystem::Instance().Resolve(init_file);
}
static void GetHomeREPLInitFile(llvm::SmallVectorImpl<char> &init_file) {
LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
LanguageType language = eLanguageTypeUnknown;
if (auto main_repl_language = repl_languages.GetSingularLanguage())
language = *main_repl_language;
else
return;
static void GetHomeREPLInitFile(llvm::SmallVectorImpl<char> &init_file,
LanguageType language) {
if (language == eLanguageTypeUnknown) {
LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
if (auto main_repl_language = repl_languages.GetSingularLanguage())
language = *main_repl_language;
else
return;
}
std::string init_file_name =
(llvm::Twine(".lldbinit-") +
@ -2355,7 +2357,7 @@ void CommandInterpreter::SourceInitFileHome(CommandReturnObject &result,
llvm::SmallString<128> init_file;
if (is_repl)
GetHomeREPLInitFile(init_file);
GetHomeREPLInitFile(init_file, GetDebugger().GetREPLLanguage());
if (init_file.empty())
GetHomeInitFile(init_file);

View File

@ -226,6 +226,17 @@ OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage(
return nullptr;
}
bool OptionValueProperties::SetPropertyAtIndexAsLanguage(
const ExecutionContext *exe_ctx, uint32_t idx, const LanguageType lang) {
const Property *property = GetPropertyAtIndex(exe_ctx, true, idx);
if (property) {
OptionValue *value = property->GetValue().get();
if (value)
return value->SetLanguageValue(lang);
}
return false;
}
bool OptionValueProperties::GetPropertyAtIndexAsArgs(
const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const {
const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);

View File

@ -212,17 +212,20 @@ const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }
lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language,
const char *repl_options, bool can_create) {
if (language == eLanguageTypeUnknown)
language = m_debugger.GetREPLLanguage();
if (language == eLanguageTypeUnknown) {
LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
if (auto single_lang = repl_languages.GetSingularLanguage()) {
language = *single_lang;
} else if (repl_languages.Empty()) {
err.SetErrorStringWithFormat(
err.SetErrorString(
"LLDB isn't configured with REPL support for any languages.");
return REPLSP();
} else {
err.SetErrorStringWithFormat(
err.SetErrorString(
"Multiple possible REPL languages. Please specify a language.");
return REPLSP();
}

View File

@ -296,6 +296,7 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
arg_value);
return error;
}
m_debugger.SetREPLLanguage(m_option_data.m_repl_lang);
}
if (args.hasArg(OPT_repl)) {