1 //===-- ClangREPL.cpp -----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ClangREPL.h" 10 #include "lldb/Core/Debugger.h" 11 #include "lldb/Core/PluginManager.h" 12 #include "lldb/Expression/ExpressionVariable.h" 13 14 using namespace lldb_private; 15 16 LLDB_PLUGIN_DEFINE(ClangREPL) 17 18 char ClangREPL::ID; 19 20 ClangREPL::ClangREPL(lldb::LanguageType language, Target &target) 21 : llvm::RTTIExtends<ClangREPL, REPL>(target), m_language(language), 22 m_implicit_expr_result_regex("\\$[0-9]+") {} 23 24 ClangREPL::~ClangREPL() = default; 25 26 void ClangREPL::Initialize() { 27 LanguageSet languages; 28 // FIXME: There isn't a way to ask CPlusPlusLanguage and ObjCLanguage for 29 // a list of languages they support. 30 languages.Insert(lldb::LanguageType::eLanguageTypeC); 31 languages.Insert(lldb::LanguageType::eLanguageTypeC89); 32 languages.Insert(lldb::LanguageType::eLanguageTypeC99); 33 languages.Insert(lldb::LanguageType::eLanguageTypeC11); 34 languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus); 35 languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_03); 36 languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_11); 37 languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_14); 38 languages.Insert(lldb::LanguageType::eLanguageTypeObjC); 39 languages.Insert(lldb::LanguageType::eLanguageTypeObjC_plus_plus); 40 PluginManager::RegisterPlugin(GetPluginNameStatic(), "C language REPL", 41 &CreateInstance, languages); 42 } 43 44 void ClangREPL::Terminate() { 45 PluginManager::UnregisterPlugin(&CreateInstance); 46 } 47 48 lldb::REPLSP ClangREPL::CreateInstance(Status &error, 49 lldb::LanguageType language, 50 Debugger *debugger, Target *target, 51 const char *repl_options) { 52 // Creating a dummy target if only a debugger is given isn't implemented yet. 53 if (!target) { 54 error.SetErrorString("must have a target to create a REPL"); 55 return nullptr; 56 } 57 lldb::REPLSP result = std::make_shared<ClangREPL>(language, *target); 58 target->SetREPL(language, result); 59 error = Status(); 60 return result; 61 } 62 63 Status ClangREPL::DoInitialization() { return Status(); } 64 65 llvm::StringRef ClangREPL::GetSourceFileBasename() { 66 static constexpr llvm::StringLiteral g_repl("repl.c"); 67 return g_repl; 68 } 69 70 const char *ClangREPL::GetAutoIndentCharacters() { return " "; } 71 72 bool ClangREPL::SourceIsComplete(const std::string &source) { 73 // FIXME: There isn't a good way to know if the input source is complete or 74 // not, so just say that every single REPL line is ready to be parsed. 75 return !source.empty(); 76 } 77 78 lldb::offset_t ClangREPL::GetDesiredIndentation(const StringList &lines, 79 int cursor_position, 80 int tab_size) { 81 // FIXME: Not implemented. 82 return LLDB_INVALID_OFFSET; 83 } 84 85 lldb::LanguageType ClangREPL::GetLanguage() { return m_language; } 86 87 bool ClangREPL::PrintOneVariable(Debugger &debugger, 88 lldb::StreamFileSP &output_sp, 89 lldb::ValueObjectSP &valobj_sp, 90 ExpressionVariable *var) { 91 // If a ExpressionVariable was passed, check first if that variable is just 92 // an automatically created expression result. These variables are already 93 // printed by the REPL so this is done to prevent printing the variable twice. 94 if (var) { 95 if (m_implicit_expr_result_regex.Execute(var->GetName().GetStringRef())) 96 return true; 97 } 98 valobj_sp->Dump(*output_sp); 99 return true; 100 } 101 102 void ClangREPL::CompleteCode(const std::string ¤t_code, 103 CompletionRequest &request) { 104 // Not implemented. 105 } 106