Skip to content

Commit 6681041

Browse files
committedOct 19, 2015
Added the concept of a Read-Eval-Print-Loop to LLDB.
A REPL takes over the command line and typically treats input as source code. REPLs can also do code completion. The REPL class allows its subclasses to implement the language-specific functionality without having to know about the IOHandler-specific internals. Also added a PluginManager-based way of getting to a REPL given a language and a target. Also brought in some utility code and expression options that are useful for REPLs, such as line offsets for expressions, ANSI terminal coloring of errors, and a few IOHandler convenience functions. llvm-svn: 250753
1 parent cc25301 commit 6681041

File tree

19 files changed

+1219
-7
lines changed

19 files changed

+1219
-7
lines changed
 

‎lldb/include/lldb/Core/Debugger.h

+29
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ friend class SourceManager; // For GetSourceFileCache.
203203

204204
bool
205205
IsTopIOHandler (const lldb::IOHandlerSP& reader_sp);
206+
207+
bool
208+
CheckTopIOHandlerTypes (IOHandler::Type top_type,
209+
IOHandler::Type second_top_type);
206210

207211
void
208212
PrintAsync (const char *s, size_t len, bool is_stdout);
@@ -321,6 +325,24 @@ friend class SourceManager; // For GetSourceFileCache.
321325
bool
322326
GetAutoOneLineSummaries () const;
323327

328+
bool
329+
GetAutoIndent () const;
330+
331+
bool
332+
SetAutoIndent (bool b);
333+
334+
bool
335+
GetPrintDecls () const;
336+
337+
bool
338+
SetPrintDecls (bool b);
339+
340+
uint32_t
341+
GetTabSize () const;
342+
343+
bool
344+
SetTabSize (uint32_t tab_size);
345+
324346
bool
325347
GetEscapeNonPrintables () const;
326348

@@ -362,6 +384,7 @@ friend class SourceManager; // For GetSourceFileCache.
362384
protected:
363385

364386
friend class CommandInterpreter;
387+
friend class REPL;
365388

366389
bool
367390
StartEventHandlerThread();
@@ -372,12 +395,18 @@ friend class SourceManager; // For GetSourceFileCache.
372395
static lldb::thread_result_t
373396
EventHandlerThread (lldb::thread_arg_t arg);
374397

398+
bool
399+
HasIOHandlerThread();
400+
375401
bool
376402
StartIOHandlerThread();
377403

378404
void
379405
StopIOHandlerThread();
380406

407+
void
408+
JoinIOHandlerThread();
409+
381410
static lldb::thread_result_t
382411
IOHandlerThread (lldb::thread_arg_t arg);
383412

‎lldb/include/lldb/Core/IOHandler.h

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace lldb_private {
4242
Confirm,
4343
Curses,
4444
Expression,
45+
REPL,
4546
ProcessIO,
4647
PythonInterpreter,
4748
PythonCode,

‎lldb/include/lldb/Core/PluginManager.h

+17
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,23 @@ class PluginManager
443443
static TypeSystemEnumerateSupportedLanguages
444444
GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name);
445445

446+
//------------------------------------------------------------------
447+
// REPL
448+
//------------------------------------------------------------------
449+
static bool
450+
RegisterPlugin (const ConstString &name,
451+
const char *description,
452+
REPLCreateInstance create_callback);
453+
454+
static bool
455+
UnregisterPlugin (REPLCreateInstance create_callback);
456+
457+
static REPLCreateInstance
458+
GetREPLCreateCallbackAtIndex (uint32_t idx);
459+
460+
static REPLCreateInstance
461+
GetREPLCreateCallbackForPluginName (const ConstString &name);
462+
446463
//------------------------------------------------------------------
447464
// Some plug-ins might register a DebuggerInitializeCallback
448465
// callback when registering the plug-in. After a new Debugger

‎lldb/include/lldb/Expression/REPL.h

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
//===-- REPL.h --------------------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
11+
#ifndef lldb_REPL_h
12+
#define lldb_REPL_h
13+
14+
#include "lldb/Interpreter/OptionGroupFormat.h"
15+
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
16+
#include "lldb/../../source/Commands/CommandObjectExpression.h"
17+
18+
namespace lldb_private
19+
{
20+
21+
class REPL : public IOHandlerDelegate
22+
{
23+
public:
24+
//----------------------------------------------------------------------
25+
// See TypeSystem.h for how to add subclasses to this.
26+
//----------------------------------------------------------------------
27+
enum LLVMCastKind {
28+
eKindClang,
29+
eKindSwift,
30+
eKindGo,
31+
kNumKinds
32+
};
33+
34+
LLVMCastKind getKind() const { return m_kind; }
35+
36+
REPL(LLVMCastKind kind, Target &target);
37+
38+
virtual ~REPL();
39+
40+
static lldb::REPLSP
41+
Create (lldb::LanguageType language, Target *target);
42+
43+
void
44+
SetFormatOptions (const OptionGroupFormat &options)
45+
{
46+
m_format_options = options;
47+
}
48+
49+
void
50+
SetValueObjectDisplayOptions (const OptionGroupValueObjectDisplay &options)
51+
{
52+
m_varobj_options = options;
53+
}
54+
55+
void
56+
SetCommandOptions (const CommandObjectExpression::CommandOptions &options)
57+
{
58+
m_command_options = options;
59+
}
60+
61+
void
62+
SetCompilerOptions (const char *options)
63+
{
64+
if (options)
65+
m_compiler_options = options;
66+
}
67+
68+
lldb::IOHandlerSP
69+
GetIOHandler ();
70+
71+
Error
72+
RunLoop ();
73+
74+
//------------------------------------------------------------------
75+
// IOHandler::Delegate functions
76+
//------------------------------------------------------------------
77+
void
78+
IOHandlerActivated (IOHandler &io_handler) override;
79+
80+
bool
81+
IOHandlerInterrupt (IOHandler &io_handler) override;
82+
83+
void
84+
IOHandlerInputInterrupted (IOHandler &io_handler,
85+
std::string &line) override;
86+
87+
const char *
88+
IOHandlerGetFixIndentationCharacters () override;
89+
90+
ConstString
91+
IOHandlerGetControlSequence (char ch) override;
92+
93+
const char *
94+
IOHandlerGetCommandPrefix () override;
95+
96+
const char *
97+
IOHandlerGetHelpPrologue () override;
98+
99+
bool
100+
IOHandlerIsInputComplete (IOHandler &io_handler,
101+
StringList &lines) override;
102+
103+
int
104+
IOHandlerFixIndentation (IOHandler &io_handler,
105+
const StringList &lines,
106+
int cursor_position) override;
107+
108+
void
109+
IOHandlerInputComplete (IOHandler &io_handler,
110+
std::string &line) override;
111+
112+
int
113+
IOHandlerComplete (IOHandler &io_handler,
114+
const char *current_line,
115+
const char *cursor,
116+
const char *last_char,
117+
int skip_first_n_matches,
118+
int max_matches,
119+
StringList &matches) override;
120+
121+
private:
122+
std::string
123+
GetSourcePath();
124+
125+
protected:
126+
static int
127+
CalculateActualIndentation (const StringList &lines);
128+
129+
//----------------------------------------------------------------------
130+
// Subclasses should override these functions to implement a functional REPL.
131+
//----------------------------------------------------------------------
132+
133+
virtual Error
134+
DoInitialization () = 0;
135+
136+
virtual ConstString
137+
GetSourceFileBasename () = 0;
138+
139+
virtual const char *
140+
GetAutoIndentCharacters () = 0;
141+
142+
virtual bool
143+
SourceIsComplete (const std::string &source) = 0;
144+
145+
virtual lldb::offset_t
146+
GetDesiredIndentation (const StringList &lines,
147+
int cursor_position,
148+
int tab_size) = 0; // LLDB_INVALID_OFFSET means no change
149+
150+
virtual lldb::LanguageType
151+
GetLanguage () = 0;
152+
153+
virtual bool
154+
PrintOneVariable (Debugger &debugger,
155+
lldb::StreamFileSP &output_sp,
156+
lldb::ValueObjectSP &valobj_sp,
157+
ExpressionVariable *var = nullptr) = 0;
158+
159+
virtual int
160+
CompleteCode(const std::string &current_code,
161+
StringList &matches) = 0;
162+
163+
OptionGroupFormat m_format_options = OptionGroupFormat(lldb::eFormatDefault);
164+
OptionGroupValueObjectDisplay m_varobj_options;
165+
CommandObjectExpression::CommandOptions m_command_options;
166+
std::string m_compiler_options;
167+
168+
bool m_enable_auto_indent = true;
169+
std::string m_indent_str; // Use this string for each level of indentation
170+
std::string m_current_indent_str;
171+
uint32_t m_current_indent_level = 0;
172+
173+
std::string m_repl_source_path;
174+
bool m_dedicated_repl_mode = false;
175+
176+
StringList m_code; // All accumulated REPL statements are saved here
177+
178+
Target &m_target;
179+
lldb::IOHandlerSP m_io_handler_sp;
180+
LLVMCastKind m_kind;
181+
};
182+
183+
}
184+
185+
#endif /* REPL_h */

‎lldb/include/lldb/Expression/UserExpression.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,16 @@ class UserExpression : public Expression
273273
/// @param[in,out] result_valobj_sp
274274
/// If execution is successful, the result valobj is placed here.
275275
///
276-
/// @param[out]
276+
/// @param[out] error
277277
/// Filled in with an error in case the expression evaluation
278278
/// fails to parse, run, or evaluated.
279279
///
280+
/// @param[in] line_offset
281+
/// The offset of the first line of the expression from the "beginning" of a virtual source file used for error reporting and debug info.
282+
///
283+
/// @param[out] jit_module_sp_ptr
284+
/// If non-NULL, used to persist the generated IR module.
285+
///
280286
/// @result
281287
/// A Process::ExpressionResults value. eExpressionCompleted for success.
282288
//------------------------------------------------------------------
@@ -286,7 +292,9 @@ class UserExpression : public Expression
286292
const char *expr_cstr,
287293
const char *expr_prefix,
288294
lldb::ValueObjectSP &result_valobj_sp,
289-
Error &error);
295+
Error &error,
296+
uint32_t line_offset = 0,
297+
lldb::ModuleSP *jit_module_sp_ptr = NULL);
290298

291299
static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
292300
protected:

‎lldb/include/lldb/Host/File.h

+4
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,9 @@ class File : public IOObject
494494
//------------------------------------------------------------------
495495
bool
496496
GetIsRealTerminal ();
497+
498+
bool
499+
GetIsTerminalWithColors ();
497500

498501
//------------------------------------------------------------------
499502
/// Output printf formatted output to the stream.
@@ -546,6 +549,7 @@ class File : public IOObject
546549
bool m_own_stream;
547550
LazyBool m_is_interactive;
548551
LazyBool m_is_real_terminal;
552+
LazyBool m_supports_colors;
549553
};
550554

551555
} // namespace lldb_private

‎lldb/include/lldb/Interpreter/CommandInterpreter.h

+3
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,9 @@ class CommandInterpreter :
659659
return m_stopped_for_crash;
660660
}
661661

662+
bool
663+
GetSpaceReplPrompts () const;
664+
662665
protected:
663666
friend class Debugger;
664667

0 commit comments

Comments
 (0)
Please sign in to comment.