xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===-- ClangREPL.cpp -----------------------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric 
9349cc55cSDimitry Andric #include "ClangREPL.h"
10349cc55cSDimitry Andric #include "lldb/Core/Debugger.h"
11349cc55cSDimitry Andric #include "lldb/Core/PluginManager.h"
12349cc55cSDimitry Andric #include "lldb/Expression/ExpressionVariable.h"
13349cc55cSDimitry Andric 
14349cc55cSDimitry Andric using namespace lldb_private;
15349cc55cSDimitry Andric 
16349cc55cSDimitry Andric LLDB_PLUGIN_DEFINE(ClangREPL)
17349cc55cSDimitry Andric 
1806c3fb27SDimitry Andric char ClangREPL::ID;
1906c3fb27SDimitry Andric 
20349cc55cSDimitry Andric ClangREPL::ClangREPL(lldb::LanguageType language, Target &target)
2106c3fb27SDimitry Andric     : llvm::RTTIExtends<ClangREPL, REPL>(target), m_language(language),
22349cc55cSDimitry Andric       m_implicit_expr_result_regex("\\$[0-9]+") {}
23349cc55cSDimitry Andric 
2481ad6265SDimitry Andric ClangREPL::~ClangREPL() = default;
25349cc55cSDimitry Andric 
26349cc55cSDimitry Andric void ClangREPL::Initialize() {
27349cc55cSDimitry Andric   LanguageSet languages;
28349cc55cSDimitry Andric   // FIXME: There isn't a way to ask CPlusPlusLanguage and ObjCLanguage for
29349cc55cSDimitry Andric   // a list of languages they support.
30349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC);
31349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC89);
32349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC99);
33349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC11);
34349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus);
35349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_03);
36349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_11);
37349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_14);
38349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeObjC);
39349cc55cSDimitry Andric   languages.Insert(lldb::LanguageType::eLanguageTypeObjC_plus_plus);
40349cc55cSDimitry Andric   PluginManager::RegisterPlugin(GetPluginNameStatic(), "C language REPL",
41349cc55cSDimitry Andric                                 &CreateInstance, languages);
42349cc55cSDimitry Andric }
43349cc55cSDimitry Andric 
44349cc55cSDimitry Andric void ClangREPL::Terminate() {
45349cc55cSDimitry Andric   PluginManager::UnregisterPlugin(&CreateInstance);
46349cc55cSDimitry Andric }
47349cc55cSDimitry Andric 
48349cc55cSDimitry Andric lldb::REPLSP ClangREPL::CreateInstance(Status &error,
49349cc55cSDimitry Andric                                        lldb::LanguageType language,
50349cc55cSDimitry Andric                                        Debugger *debugger, Target *target,
51349cc55cSDimitry Andric                                        const char *repl_options) {
52349cc55cSDimitry Andric   // Creating a dummy target if only a debugger is given isn't implemented yet.
53349cc55cSDimitry Andric   if (!target) {
54349cc55cSDimitry Andric     error.SetErrorString("must have a target to create a REPL");
55349cc55cSDimitry Andric     return nullptr;
56349cc55cSDimitry Andric   }
57349cc55cSDimitry Andric   lldb::REPLSP result = std::make_shared<ClangREPL>(language, *target);
58349cc55cSDimitry Andric   target->SetREPL(language, result);
59349cc55cSDimitry Andric   error = Status();
60349cc55cSDimitry Andric   return result;
61349cc55cSDimitry Andric }
62349cc55cSDimitry Andric 
63349cc55cSDimitry Andric Status ClangREPL::DoInitialization() { return Status(); }
64349cc55cSDimitry Andric 
6506c3fb27SDimitry Andric llvm::StringRef ClangREPL::GetSourceFileBasename() {
6606c3fb27SDimitry Andric   static constexpr llvm::StringLiteral g_repl("repl.c");
6706c3fb27SDimitry Andric   return g_repl;
68349cc55cSDimitry Andric }
69349cc55cSDimitry Andric 
70349cc55cSDimitry Andric const char *ClangREPL::GetAutoIndentCharacters() { return "  "; }
71349cc55cSDimitry Andric 
72349cc55cSDimitry Andric bool ClangREPL::SourceIsComplete(const std::string &source) {
73349cc55cSDimitry Andric   // FIXME: There isn't a good way to know if the input source is complete or
74349cc55cSDimitry Andric   // not, so just say that every single REPL line is ready to be parsed.
75349cc55cSDimitry Andric   return !source.empty();
76349cc55cSDimitry Andric }
77349cc55cSDimitry Andric 
78349cc55cSDimitry Andric lldb::offset_t ClangREPL::GetDesiredIndentation(const StringList &lines,
79349cc55cSDimitry Andric                                                 int cursor_position,
80349cc55cSDimitry Andric                                                 int tab_size) {
81349cc55cSDimitry Andric   // FIXME: Not implemented.
82349cc55cSDimitry Andric   return LLDB_INVALID_OFFSET;
83349cc55cSDimitry Andric }
84349cc55cSDimitry Andric 
85349cc55cSDimitry Andric lldb::LanguageType ClangREPL::GetLanguage() { return m_language; }
86349cc55cSDimitry Andric 
87349cc55cSDimitry Andric bool ClangREPL::PrintOneVariable(Debugger &debugger,
88349cc55cSDimitry Andric                                  lldb::StreamFileSP &output_sp,
89349cc55cSDimitry Andric                                  lldb::ValueObjectSP &valobj_sp,
90349cc55cSDimitry Andric                                  ExpressionVariable *var) {
91349cc55cSDimitry Andric   // If a ExpressionVariable was passed, check first if that variable is just
92349cc55cSDimitry Andric   // an automatically created expression result. These variables are already
93349cc55cSDimitry Andric   // printed by the REPL so this is done to prevent printing the variable twice.
94349cc55cSDimitry Andric   if (var) {
95349cc55cSDimitry Andric     if (m_implicit_expr_result_regex.Execute(var->GetName().GetStringRef()))
96349cc55cSDimitry Andric       return true;
97349cc55cSDimitry Andric   }
98*0fca6ea1SDimitry Andric   if (llvm::Error error = valobj_sp->Dump(*output_sp))
99*0fca6ea1SDimitry Andric     *output_sp << "error: " << toString(std::move(error));
100*0fca6ea1SDimitry Andric 
101349cc55cSDimitry Andric   return true;
102349cc55cSDimitry Andric }
103349cc55cSDimitry Andric 
104349cc55cSDimitry Andric void ClangREPL::CompleteCode(const std::string &current_code,
105349cc55cSDimitry Andric                              CompletionRequest &request) {
106349cc55cSDimitry Andric   // Not implemented.
107349cc55cSDimitry Andric }
108