| //===-- ClangREPL.cpp -----------------------------------------------------===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ClangREPL.h" |
| #include "lldb/Core/Debugger.h" |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Expression/ExpressionVariable.h" |
| |
| using namespace lldb_private; |
| |
| LLDB_PLUGIN_DEFINE(ClangREPL) |
| |
| ClangREPL::ClangREPL(lldb::LanguageType language, Target &target) |
| : REPL(eKindClang, target), m_language(language), |
| m_implicit_expr_result_regex("\\$[0-9]+") {} |
| |
| ClangREPL::~ClangREPL() {} |
| |
| void ClangREPL::Initialize() { |
| LanguageSet languages; |
| // FIXME: There isn't a way to ask CPlusPlusLanguage and ObjCLanguage for |
| // a list of languages they support. |
| languages.Insert(lldb::LanguageType::eLanguageTypeC); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC89); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC99); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC11); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_03); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_11); |
| languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_14); |
| languages.Insert(lldb::LanguageType::eLanguageTypeObjC); |
| languages.Insert(lldb::LanguageType::eLanguageTypeObjC_plus_plus); |
| PluginManager::RegisterPlugin(GetPluginNameStatic(), "C language REPL", |
| &CreateInstance, languages); |
| } |
| |
| void ClangREPL::Terminate() { |
| PluginManager::UnregisterPlugin(&CreateInstance); |
| } |
| |
| lldb::REPLSP ClangREPL::CreateInstance(Status &error, |
| lldb::LanguageType language, |
| Debugger *debugger, Target *target, |
| const char *repl_options) { |
| // Creating a dummy target if only a debugger is given isn't implemented yet. |
| if (!target) { |
| error.SetErrorString("must have a target to create a REPL"); |
| return nullptr; |
| } |
| lldb::REPLSP result = std::make_shared<ClangREPL>(language, *target); |
| target->SetREPL(language, result); |
| error = Status(); |
| return result; |
| } |
| |
| Status ClangREPL::DoInitialization() { return Status(); } |
| |
| ConstString ClangREPL::GetSourceFileBasename() { |
| return ConstString("repl.c"); |
| } |
| |
| const char *ClangREPL::GetAutoIndentCharacters() { return " "; } |
| |
| bool ClangREPL::SourceIsComplete(const std::string &source) { |
| // FIXME: There isn't a good way to know if the input source is complete or |
| // not, so just say that every single REPL line is ready to be parsed. |
| return !source.empty(); |
| } |
| |
| lldb::offset_t ClangREPL::GetDesiredIndentation(const StringList &lines, |
| int cursor_position, |
| int tab_size) { |
| // FIXME: Not implemented. |
| return LLDB_INVALID_OFFSET; |
| } |
| |
| lldb::LanguageType ClangREPL::GetLanguage() { return m_language; } |
| |
| bool ClangREPL::PrintOneVariable(Debugger &debugger, |
| lldb::StreamFileSP &output_sp, |
| lldb::ValueObjectSP &valobj_sp, |
| ExpressionVariable *var) { |
| // If a ExpressionVariable was passed, check first if that variable is just |
| // an automatically created expression result. These variables are already |
| // printed by the REPL so this is done to prevent printing the variable twice. |
| if (var) { |
| if (m_implicit_expr_result_regex.Execute(var->GetName().GetStringRef())) |
| return true; |
| } |
| valobj_sp->Dump(*output_sp); |
| return true; |
| } |
| |
| void ClangREPL::CompleteCode(const std::string ¤t_code, |
| CompletionRequest &request) { |
| // Not implemented. |
| } |