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