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