aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Core
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-03-20 11:40:34 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-05-14 11:43:05 +0000
commit349cc55c9796c4596a5b9904cd3281af295f878f (patch)
tree410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/lldb/source/Core
parentcb2ae6163174b90e999326ecec3699ee093a5d43 (diff)
parentc0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Core')
-rw-r--r--contrib/llvm-project/lldb/source/Core/Address.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Core/AddressRange.cpp17
-rw-r--r--contrib/llvm-project/lldb/source/Core/Communication.cpp14
-rw-r--r--contrib/llvm-project/lldb/source/Core/Debugger.cpp15
-rw-r--r--contrib/llvm-project/lldb/source/Core/Disassembler.cpp9
-rw-r--r--contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp8
-rw-r--r--contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp3
-rw-r--r--contrib/llvm-project/lldb/source/Core/IOHandler.cpp5
-rw-r--r--contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp1896
-rw-r--r--contrib/llvm-project/lldb/source/Core/Mangled.cpp74
-rw-r--r--contrib/llvm-project/lldb/source/Core/Module.cpp37
-rw-r--r--contrib/llvm-project/lldb/source/Core/ModuleList.cpp115
-rw-r--r--contrib/llvm-project/lldb/source/Core/PluginManager.cpp246
-rw-r--r--contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp13
-rw-r--r--contrib/llvm-project/lldb/source/Core/Section.cpp82
-rw-r--r--contrib/llvm-project/lldb/source/Core/SourceManager.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Core/StreamFile.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObject.cpp11
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp2
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp4
-rw-r--r--contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp23
21 files changed, 2104 insertions, 498 deletions
diff --git a/contrib/llvm-project/lldb/source/Core/Address.cpp b/contrib/llvm-project/lldb/source/Core/Address.cpp
index f0c7e2b34f99..122bed924b42 100644
--- a/contrib/llvm-project/lldb/source/Core/Address.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Address.cpp
@@ -389,6 +389,19 @@ bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
return false;
}
+bool Address::GetDescription(Stream &s, Target &target,
+ DescriptionLevel level) const {
+ assert(level == eDescriptionLevelBrief &&
+ "Non-brief descriptions not implemented");
+ LineEntry line_entry;
+ if (CalculateSymbolContextLineEntry(line_entry)) {
+ s.Printf(" (%s:%u:%u)", line_entry.file.GetFilename().GetCString(),
+ line_entry.line, line_entry.column);
+ return true;
+ }
+ return false;
+}
+
bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
DumpStyle fallback_style, uint32_t addr_size) const {
// If the section was nullptr, only load address is going to work unless we
diff --git a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp
index af6e31a67da3..66dcda574890 100644
--- a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp
+++ b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp
@@ -59,15 +59,6 @@ bool AddressRange::Contains(const Address &addr) const {
return ContainsFileAddress(addr);
}
-//
-// bool
-// AddressRange::Contains (const Address *addr) const
-//{
-// if (addr)
-// return Contains (*addr);
-// return false;
-//}
-
bool AddressRange::ContainsFileAddress(const Address &addr) const {
if (addr.GetSection() == m_base_addr.GetSection())
return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
@@ -212,11 +203,3 @@ void AddressRange::DumpDebug(Stream *s) const {
static_cast<void *>(m_base_addr.GetSection().get()),
m_base_addr.GetOffset(), GetByteSize());
}
-//
-// bool
-// lldb::operator== (const AddressRange& lhs, const AddressRange& rhs)
-//{
-// if (lhs.GetBaseAddress() == rhs.GetBaseAddress())
-// return lhs.GetByteSize() == rhs.GetByteSize();
-// return false;
-//}
diff --git a/contrib/llvm-project/lldb/source/Core/Communication.cpp b/contrib/llvm-project/lldb/source/Core/Communication.cpp
index 5640e0510cf1..0ad2751f24f0 100644
--- a/contrib/llvm-project/lldb/source/Core/Communication.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Communication.cpp
@@ -176,8 +176,8 @@ size_t Communication::Write(const void *src, size_t src_len,
std::lock_guard<std::mutex> guard(m_write_mutex);
LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION),
- "{0} Communication::Write (src = {1}, src_len = %" PRIu64
- ") connection = {2}",
+ "{0} Communication::Write (src = {1}, src_len = {2}"
+ ") connection = {3}",
this, src, (uint64_t)src_len, connection_sp.get());
if (connection_sp)
@@ -189,6 +189,16 @@ size_t Communication::Write(const void *src, size_t src_len,
return 0;
}
+size_t Communication::WriteAll(const void *src, size_t src_len,
+ ConnectionStatus &status, Status *error_ptr) {
+ size_t total_written = 0;
+ do
+ total_written += Write(static_cast<const char *>(src) + total_written,
+ src_len - total_written, status, error_ptr);
+ while (status == eConnectionStatusSuccess && total_written < src_len);
+ return total_written;
+}
+
bool Communication::StartReadThread(Status *error_ptr) {
if (error_ptr)
error_ptr->Clear();
diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp
index 17c3ba426f71..32dcfb1ce17b 100644
--- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp
@@ -488,7 +488,7 @@ void Debugger::Terminate() {
"Debugger::Terminate called without a matching Debugger::Initialize!");
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
- // Clear our master list of debugger objects
+ // Clear our global list of debugger objects
{
std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
for (const auto &debugger : *g_debugger_list_ptr)
@@ -723,10 +723,10 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
m_collection_sp->AppendProperty(
ConstString("target"),
ConstString("Settings specify to debugging targets."), true,
- Target::GetGlobalProperties()->GetValueProperties());
+ Target::GetGlobalProperties().GetValueProperties());
m_collection_sp->AppendProperty(
ConstString("platform"), ConstString("Platform settings."), true,
- Platform::GetGlobalPlatformProperties()->GetValueProperties());
+ Platform::GetGlobalPlatformProperties().GetValueProperties());
m_collection_sp->AppendProperty(
ConstString("symbols"), ConstString("Symbol lookup and cache settings."),
true, ModuleList::GetGlobalModuleListProperties().GetValueProperties());
@@ -1243,7 +1243,7 @@ bool Debugger::EnableLog(llvm::StringRef channel,
log_stream_sp = pos->second.lock();
if (!log_stream_sp) {
File::OpenOptions flags =
- File::eOpenOptionWrite | File::eOpenOptionCanCreate;
+ File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
if (log_options & LLDB_LOG_OPTION_APPEND)
flags |= File::eOpenOptionAppend;
else
@@ -1423,10 +1423,9 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) {
output_stream_sp->PutCString(content_stream.GetString());
}
} else {
- error_stream_sp->Printf("Failed to print structured "
- "data with plugin %s: %s",
- plugin_sp->GetPluginName().AsCString(),
- error.AsCString());
+ error_stream_sp->Format("Failed to print structured "
+ "data with plugin {0}: {1}",
+ plugin_sp->GetPluginName(), error);
}
}
}
diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
index 704b3df4b2ac..00d92053bc4f 100644
--- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp
@@ -64,9 +64,8 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch,
DisassemblerCreateInstance create_callback = nullptr;
if (plugin_name) {
- ConstString const_plugin_name(plugin_name);
- create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName(
- const_plugin_name);
+ create_callback =
+ PluginManager::GetDisassemblerCreateCallbackForPluginName(plugin_name);
if (create_callback) {
DisassemblerSP disassembler_sp(create_callback(arch, flavor));
@@ -1123,6 +1122,10 @@ bool PseudoInstruction::HasDelaySlot() {
return false;
}
+bool PseudoInstruction::IsLoad() { return false; }
+
+bool PseudoInstruction::IsAuthenticated() { return false; }
+
size_t PseudoInstruction::Decode(const lldb_private::Disassembler &disassembler,
const lldb_private::DataExtractor &data,
lldb::offset_t data_offset) {
diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp
index 10d2b7207018..1c7b9125e4d1 100644
--- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp
+++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp
@@ -30,13 +30,11 @@ using namespace lldb;
using namespace lldb_private;
DynamicLoader *DynamicLoader::FindPlugin(Process *process,
- const char *plugin_name) {
+ llvm::StringRef plugin_name) {
DynamicLoaderCreateInstance create_callback = nullptr;
- if (plugin_name) {
- ConstString const_plugin_name(plugin_name);
+ if (!plugin_name.empty()) {
create_callback =
- PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
- const_plugin_name);
+ PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name);
if (create_callback) {
std::unique_ptr<DynamicLoader> instance_up(
create_callback(process, true));
diff --git a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp
index 9b9111408209..c352b0129382 100644
--- a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp
+++ b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp
@@ -46,10 +46,9 @@ EmulateInstruction::FindPlugin(const ArchSpec &arch,
const char *plugin_name) {
EmulateInstructionCreateInstance create_callback = nullptr;
if (plugin_name) {
- ConstString const_plugin_name(plugin_name);
create_callback =
PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
- const_plugin_name);
+ plugin_name);
if (create_callback) {
EmulateInstruction *emulate_insn_ptr =
create_callback(arch, supported_inst_type);
diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp
index c6f05d43a2a7..c35b17990842 100644
--- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp
+++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp
@@ -251,8 +251,7 @@ IOHandlerEditline::IOHandlerEditline(
m_delegate(delegate), m_prompt(), m_continuation_prompt(),
m_current_lines_ptr(nullptr), m_base_line_number(line_number_start),
m_curr_line_idx(UINT32_MAX), m_multi_line(multi_line),
- m_color_prompts(color_prompts), m_interrupt_exits(true),
- m_editing(false) {
+ m_color_prompts(color_prompts), m_interrupt_exits(true) {
SetPrompt(prompt);
#if LLDB_ENABLE_LIBEDIT
@@ -399,7 +398,6 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
}
if (!got_line && in) {
- m_editing = true;
while (!got_line) {
char *r = fgets(buffer, sizeof(buffer), in);
#ifdef _WIN32
@@ -425,7 +423,6 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
m_line_buffer += buffer;
got_line = SplitLine(m_line_buffer);
}
- m_editing = false;
}
if (got_line) {
diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp
index 4bed788d4863..9122117ef5ff 100644
--- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp
+++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp
@@ -36,6 +36,7 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
#if LLDB_ENABLE_CURSES
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -44,6 +45,7 @@
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/VariableList.h"
@@ -83,10 +85,15 @@ using llvm::StringRef;
// we may want curses to be disabled for some builds for instance, windows
#if LLDB_ENABLE_CURSES
+#define KEY_CTRL_A 1
+#define KEY_CTRL_E 5
+#define KEY_CTRL_K 11
#define KEY_RETURN 10
#define KEY_ESCAPE 27
+#define KEY_DELETE 127
#define KEY_SHIFT_TAB (KEY_MAX + 1)
+#define KEY_ALT_ENTER (KEY_MAX + 2)
namespace curses {
class Menu;
@@ -342,15 +349,30 @@ protected:
// A surface is an abstraction for something than can be drawn on. The surface
// have a width, a height, a cursor position, and a multitude of drawing
// operations. This type should be sub-classed to get an actually useful ncurses
-// object, such as a Window, SubWindow, Pad, or a SubPad.
+// object, such as a Window or a Pad.
class Surface {
public:
- Surface() : m_window(nullptr) {}
+ enum class Type { Window, Pad };
+
+ Surface(Surface::Type type) : m_type(type), m_window(nullptr) {}
WINDOW *get() { return m_window; }
operator WINDOW *() { return m_window; }
+ Surface SubSurface(Rect bounds) {
+ Surface subSurface(m_type);
+ if (m_type == Type::Pad)
+ subSurface.m_window =
+ ::subpad(m_window, bounds.size.height, bounds.size.width,
+ bounds.origin.y, bounds.origin.x);
+ else
+ subSurface.m_window =
+ ::derwin(m_window, bounds.size.height, bounds.size.width,
+ bounds.origin.y, bounds.origin.x);
+ return subSurface;
+ }
+
// Copy a region of the surface to another surface.
void CopyToSurface(Surface &target, Point source_origin, Point target_origin,
Size size) {
@@ -534,41 +556,32 @@ public:
}
protected:
+ Type m_type;
WINDOW *m_window;
};
class Pad : public Surface {
public:
- Pad(Size size) { m_window = ::newpad(size.height, size.width); }
-
- ~Pad() { ::delwin(m_window); }
-};
-
-class SubPad : public Surface {
-public:
- SubPad(Pad &pad, Rect bounds) {
- m_window = ::subpad(pad.get(), bounds.size.height, bounds.size.width,
- bounds.origin.y, bounds.origin.x);
- }
- SubPad(SubPad &subpad, Rect bounds) {
- m_window = ::subpad(subpad.get(), bounds.size.height, bounds.size.width,
- bounds.origin.y, bounds.origin.x);
+ Pad(Size size) : Surface(Surface::Type::Pad) {
+ m_window = ::newpad(size.height, size.width);
}
- ~SubPad() { ::delwin(m_window); }
+ ~Pad() { ::delwin(m_window); }
};
class Window : public Surface {
public:
Window(const char *name)
- : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(),
- m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX),
+ : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr),
+ m_parent(nullptr), m_subwindows(), m_delegate_sp(),
+ m_curr_active_window_idx(UINT32_MAX),
m_prev_active_window_idx(UINT32_MAX), m_delete(false),
m_needs_update(true), m_can_activate(true), m_is_subwin(false) {}
Window(const char *name, WINDOW *w, bool del = true)
- : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(),
- m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX),
+ : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr),
+ m_parent(nullptr), m_subwindows(), m_delegate_sp(),
+ m_curr_active_window_idx(UINT32_MAX),
m_prev_active_window_idx(UINT32_MAX), m_delete(del),
m_needs_update(true), m_can_activate(true), m_is_subwin(false) {
if (w)
@@ -576,8 +589,8 @@ public:
}
Window(const char *name, const Rect &bounds)
- : m_name(name), m_parent(nullptr), m_subwindows(), m_delegate_sp(),
- m_curr_active_window_idx(UINT32_MAX),
+ : Surface(Surface::Type::Window), m_name(name), m_parent(nullptr),
+ m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX),
m_prev_active_window_idx(UINT32_MAX), m_delete(true),
m_needs_update(true), m_can_activate(true), m_is_subwin(false) {
Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y,
@@ -969,20 +982,6 @@ private:
const Window &operator=(const Window &) = delete;
};
-class DerivedWindow : public Surface {
-public:
- DerivedWindow(Window &window, Rect bounds) {
- m_window = ::derwin(window.get(), bounds.size.height, bounds.size.width,
- bounds.origin.y, bounds.origin.x);
- }
- DerivedWindow(DerivedWindow &derived_window, Rect bounds) {
- m_window = ::derwin(derived_window.get(), bounds.size.height,
- bounds.size.width, bounds.origin.y, bounds.origin.x);
- }
-
- ~DerivedWindow() { ::delwin(m_window); }
-};
-
/////////
// Forms
/////////
@@ -1024,7 +1023,7 @@ public:
// Draw the field in the given subpad surface. The surface have a height that
// is equal to the height returned by FieldDelegateGetHeight(). If the field
// is selected in the form window, then is_selected will be true.
- virtual void FieldDelegateDraw(SubPad &surface, bool is_selected) = 0;
+ virtual void FieldDelegateDraw(Surface &surface, bool is_selected) = 0;
// Handle the key that wasn't handled by the form window or a container field.
virtual HandleCharResult FieldDelegateHandleChar(int key) {
@@ -1111,11 +1110,12 @@ public:
int GetContentLength() { return m_content.length(); }
- void DrawContent(SubPad &surface, bool is_selected) {
+ void DrawContent(Surface &surface, bool is_selected) {
+ UpdateScrolling(surface.GetWidth());
+
surface.MoveCursor(0, 0);
const char *text = m_content.c_str() + m_first_visibile_char;
surface.PutCString(text, surface.GetWidth());
- m_last_drawn_content_width = surface.GetWidth();
// Highlight the cursor.
surface.MoveCursor(GetCursorXPosition(), 0);
@@ -1130,17 +1130,17 @@ public:
surface.AttributeOff(A_REVERSE);
}
- void DrawField(SubPad &surface, bool is_selected) {
+ void DrawField(Surface &surface, bool is_selected) {
surface.TitledBox(m_label.c_str());
Rect content_bounds = surface.GetFrame();
content_bounds.Inset(1, 1);
- SubPad content_surface = SubPad(surface, content_bounds);
+ Surface content_surface = surface.SubSurface(content_bounds);
DrawContent(content_surface, is_selected);
}
- void DrawError(SubPad &surface) {
+ void DrawError(Surface &surface) {
if (!FieldDelegateHasError())
return;
surface.MoveCursor(0, 0);
@@ -1151,17 +1151,33 @@ public:
surface.AttributeOff(COLOR_PAIR(RedOnBlack));
}
- void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
+ void FieldDelegateDraw(Surface &surface, bool is_selected) override {
Rect frame = surface.GetFrame();
Rect field_bounds, error_bounds;
frame.HorizontalSplit(GetFieldHeight(), field_bounds, error_bounds);
- SubPad field_surface = SubPad(surface, field_bounds);
- SubPad error_surface = SubPad(surface, error_bounds);
+ Surface field_surface = surface.SubSurface(field_bounds);
+ Surface error_surface = surface.SubSurface(error_bounds);
DrawField(field_surface, is_selected);
DrawError(error_surface);
}
+ // Get the position of the last visible character.
+ int GetLastVisibleCharPosition(int width) {
+ int position = m_first_visibile_char + width - 1;
+ return std::min(position, GetContentLength());
+ }
+
+ void UpdateScrolling(int width) {
+ if (m_cursor_position < m_first_visibile_char) {
+ m_first_visibile_char = m_cursor_position;
+ return;
+ }
+
+ if (m_cursor_position > GetLastVisibleCharPosition(width))
+ m_first_visibile_char = m_cursor_position - (width - 1);
+ }
+
// The cursor is allowed to move one character past the string.
// m_cursor_position is in range [0, GetContentLength()].
void MoveCursorRight() {
@@ -1174,47 +1190,65 @@ public:
m_cursor_position--;
}
- // If the cursor moved past the last visible character, scroll right by one
- // character.
- void ScrollRightIfNeeded() {
- if (m_cursor_position - m_first_visibile_char == m_last_drawn_content_width)
- m_first_visibile_char++;
- }
+ void MoveCursorToStart() { m_cursor_position = 0; }
+
+ void MoveCursorToEnd() { m_cursor_position = GetContentLength(); }
void ScrollLeft() {
if (m_first_visibile_char > 0)
m_first_visibile_char--;
}
- // If the cursor moved past the first visible character, scroll left by one
- // character.
- void ScrollLeftIfNeeded() {
- if (m_cursor_position < m_first_visibile_char)
- m_first_visibile_char--;
- }
-
- // Insert a character at the current cursor position, advance the cursor
- // position, and make sure to scroll right if needed.
+ // Insert a character at the current cursor position and advance the cursor
+ // position.
void InsertChar(char character) {
m_content.insert(m_cursor_position, 1, character);
m_cursor_position++;
- ScrollRightIfNeeded();
+ ClearError();
}
// Remove the character before the cursor position, retreat the cursor
- // position, and make sure to scroll left if needed.
- void RemoveChar() {
+ // position, and scroll left.
+ void RemovePreviousChar() {
if (m_cursor_position == 0)
return;
m_content.erase(m_cursor_position - 1, 1);
m_cursor_position--;
ScrollLeft();
+ ClearError();
+ }
+
+ // Remove the character after the cursor position.
+ void RemoveNextChar() {
+ if (m_cursor_position == GetContentLength())
+ return;
+
+ m_content.erase(m_cursor_position, 1);
+ ClearError();
+ }
+
+ // Clear characters from the current cursor position to the end.
+ void ClearToEnd() {
+ m_content.erase(m_cursor_position);
+ ClearError();
+ }
+
+ void Clear() {
+ m_content.clear();
+ m_cursor_position = 0;
+ ClearError();
}
// True if the key represents a char that can be inserted in the field
// content, false otherwise.
- virtual bool IsAcceptableChar(int key) { return isprint(key); }
+ virtual bool IsAcceptableChar(int key) {
+ // The behavior of isprint is undefined when the value is not representable
+ // as an unsigned char. So explicitly check for non-ascii key codes.
+ if (key > 127)
+ return false;
+ return isprint(key);
+ }
HandleCharResult FieldDelegateHandleChar(int key) override {
if (IsAcceptableChar(key)) {
@@ -1224,17 +1258,36 @@ public:
}
switch (key) {
+ case KEY_HOME:
+ case KEY_CTRL_A:
+ MoveCursorToStart();
+ return eKeyHandled;
+ case KEY_END:
+ case KEY_CTRL_E:
+ MoveCursorToEnd();
+ return eKeyHandled;
case KEY_RIGHT:
+ case KEY_SF:
MoveCursorRight();
- ScrollRightIfNeeded();
return eKeyHandled;
case KEY_LEFT:
+ case KEY_SR:
MoveCursorLeft();
- ScrollLeftIfNeeded();
return eKeyHandled;
case KEY_BACKSPACE:
- ClearError();
- RemoveChar();
+ case KEY_DELETE:
+ RemovePreviousChar();
+ return eKeyHandled;
+ case KEY_DC:
+ RemoveNextChar();
+ return eKeyHandled;
+ case KEY_EOL:
+ case KEY_CTRL_K:
+ ClearToEnd();
+ return eKeyHandled;
+ case KEY_DL:
+ case KEY_CLEAR:
+ Clear();
return eKeyHandled;
default:
break;
@@ -1259,6 +1312,14 @@ public:
const std::string &GetText() { return m_content; }
+ void SetText(const char *text) {
+ if (text == nullptr) {
+ m_content.clear();
+ return;
+ }
+ m_content = text;
+ }
+
protected:
std::string m_label;
bool m_required;
@@ -1269,9 +1330,6 @@ protected:
int m_cursor_position;
// The index of the first visible character in the content.
int m_first_visibile_char;
- // The width of the fields content that was last drawn. Width can change, so
- // this is used to determine if scrolling is needed dynamically.
- int m_last_drawn_content_width;
// Optional error message. If empty, field is considered to have no error.
std::string m_error;
};
@@ -1405,7 +1463,7 @@ public:
// Boolean fields are have a single line.
int FieldDelegateGetHeight() override { return 1; }
- void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
+ void FieldDelegateDraw(Surface &surface, bool is_selected) override {
surface.MoveCursor(0, 0);
surface.PutChar('[');
if (is_selected)
@@ -1485,7 +1543,7 @@ public:
return std::min(index, GetNumberOfChoices()) - 1;
}
- void DrawContent(SubPad &surface, bool is_selected) {
+ void DrawContent(Surface &surface, bool is_selected) {
int choices_to_draw = GetLastVisibleChoice() - m_first_visibile_choice + 1;
for (int i = 0; i < choices_to_draw; i++) {
surface.MoveCursor(0, i);
@@ -1501,14 +1559,14 @@ public:
}
}
- void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
+ void FieldDelegateDraw(Surface &surface, bool is_selected) override {
UpdateScrolling();
surface.TitledBox(m_label.c_str());
Rect content_bounds = surface.GetFrame();
content_bounds.Inset(1, 1);
- SubPad content_surface = SubPad(surface, content_bounds);
+ Surface content_surface = surface.SubSurface(content_bounds);
DrawContent(content_surface, is_selected);
}
@@ -1584,8 +1642,10 @@ public:
std::vector<std::string> GetPossiblePluginNames() {
std::vector<std::string> names;
size_t i = 0;
- while (auto name = PluginManager::GetPlatformPluginNameAtIndex(i++))
- names.push_back(name);
+ for (llvm::StringRef name =
+ PluginManager::GetPlatformPluginNameAtIndex(i++);
+ !name.empty(); name = PluginManager::GetProcessPluginNameAtIndex(i++))
+ names.push_back(name.str());
return names;
}
@@ -1605,8 +1665,9 @@ public:
names.push_back("<default>");
size_t i = 0;
- while (auto name = PluginManager::GetProcessPluginNameAtIndex(i++))
- names.push_back(name);
+ for (llvm::StringRef name = PluginManager::GetProcessPluginNameAtIndex(i++);
+ !name.empty(); name = PluginManager::GetProcessPluginNameAtIndex(i++))
+ names.push_back(name.str());
return names;
}
@@ -1618,6 +1679,33 @@ public:
}
};
+class LazyBooleanFieldDelegate : public ChoicesFieldDelegate {
+public:
+ LazyBooleanFieldDelegate(const char *label, const char *calculate_label)
+ : ChoicesFieldDelegate(label, 3, GetPossibleOptions(calculate_label)) {}
+
+ static constexpr const char *kNo = "No";
+ static constexpr const char *kYes = "Yes";
+
+ std::vector<std::string> GetPossibleOptions(const char *calculate_label) {
+ std::vector<std::string> options;
+ options.push_back(calculate_label);
+ options.push_back(kYes);
+ options.push_back(kNo);
+ return options;
+ }
+
+ LazyBool GetLazyBoolean() {
+ std::string choice = GetChoiceContent();
+ if (choice == kNo)
+ return eLazyBoolNo;
+ else if (choice == kYes)
+ return eLazyBoolYes;
+ else
+ return eLazyBoolCalculate;
+ }
+};
+
template <class T> class ListFieldDelegate : public FieldDelegate {
public:
ListFieldDelegate(const char *label, T default_field)
@@ -1683,7 +1771,7 @@ public:
return context;
}
- void DrawRemoveButton(SubPad &surface, int highlight) {
+ void DrawRemoveButton(Surface &surface, int highlight) {
surface.MoveCursor(1, surface.GetHeight() / 2);
if (highlight)
surface.AttributeOn(A_REVERSE);
@@ -1692,7 +1780,7 @@ public:
surface.AttributeOff(A_REVERSE);
}
- void DrawFields(SubPad &surface, bool is_selected) {
+ void DrawFields(Surface &surface, bool is_selected) {
int line = 0;
int width = surface.GetWidth();
for (int i = 0; i < GetNumberOfFields(); i++) {
@@ -1701,8 +1789,8 @@ public:
Rect field_bounds, remove_button_bounds;
bounds.VerticalSplit(bounds.size.width - sizeof(" [Remove]"),
field_bounds, remove_button_bounds);
- SubPad field_surface = SubPad(surface, field_bounds);
- SubPad remove_button_surface = SubPad(surface, remove_button_bounds);
+ Surface field_surface = surface.SubSurface(field_bounds);
+ Surface remove_button_surface = surface.SubSurface(remove_button_bounds);
bool is_element_selected = m_selection_index == i && is_selected;
bool is_field_selected =
@@ -1717,7 +1805,7 @@ public:
}
}
- void DrawNewButton(SubPad &surface, bool is_selected) {
+ void DrawNewButton(Surface &surface, bool is_selected) {
const char *button_text = "[New]";
int x = (surface.GetWidth() - sizeof(button_text) - 1) / 2;
surface.MoveCursor(x, 0);
@@ -1730,7 +1818,7 @@ public:
surface.AttributeOff(A_REVERSE);
}
- void FieldDelegateDraw(SubPad &surface, bool is_selected) override {
+ void FieldDelegateDraw(Surface &surface, bool is_selected) override {
surface.TitledBox(m_label.c_str());
Rect content_bounds = surface.GetFrame();
@@ -1738,8 +1826,8 @@ public:
Rect fields_bounds, new_button_bounds;
content_bounds.HorizontalSplit(content_bounds.size.height - 1,
fields_bounds, new_button_bounds);
- SubPad fields_surface = SubPad(surface, fields_bounds);
- SubPad new_button_surface = SubPad(surface, new_button_bounds);
+ Surface fields_surface = surface.SubSurface(fields_bounds);
+ Surface new_button_surface = surface.SubSurface(new_button_bounds);
DrawFields(fields_surface, is_selected);
DrawNewButton(new_button_surface, is_selected);
@@ -1822,6 +1910,31 @@ public:
return eKeyHandled;
}
+ // If the last element of the field is selected and it didn't handle the key.
+ // Select the next field or new button if the selected field is the last one.
+ HandleCharResult SelectNextInList(int key) {
+ assert(m_selection_type == SelectionType::Field);
+
+ FieldDelegate &field = m_fields[m_selection_index];
+ if (field.FieldDelegateHandleChar(key) == eKeyHandled)
+ return eKeyHandled;
+
+ if (!field.FieldDelegateOnLastOrOnlyElement())
+ return eKeyNotHandled;
+
+ field.FieldDelegateExitCallback();
+
+ if (m_selection_index == GetNumberOfFields() - 1) {
+ m_selection_type = SelectionType::NewButton;
+ return eKeyHandled;
+ }
+
+ m_selection_index++;
+ FieldDelegate &next_field = m_fields[m_selection_index];
+ next_field.FieldDelegateSelectFirstElement();
+ return eKeyHandled;
+ }
+
HandleCharResult FieldDelegateHandleChar(int key) override {
switch (key) {
case '\r':
@@ -1834,16 +1947,14 @@ public:
case SelectionType::RemoveButton:
RemoveField();
return eKeyHandled;
- default:
- break;
+ case SelectionType::Field:
+ return SelectNextInList(key);
}
break;
case '\t':
- SelectNext(key);
- return eKeyHandled;
+ return SelectNext(key);
case KEY_SHIFT_TAB:
- SelectPrevious(key);
- return eKeyHandled;
+ return SelectPrevious(key);
default:
break;
}
@@ -1908,6 +2019,241 @@ protected:
SelectionType m_selection_type;
};
+class ArgumentsFieldDelegate : public ListFieldDelegate<TextFieldDelegate> {
+public:
+ ArgumentsFieldDelegate()
+ : ListFieldDelegate("Arguments",
+ TextFieldDelegate("Argument", "", false)) {}
+
+ Args GetArguments() {
+ Args arguments;
+ for (int i = 0; i < GetNumberOfFields(); i++) {
+ arguments.AppendArgument(GetField(i).GetText());
+ }
+ return arguments;
+ }
+
+ void AddArguments(const Args &arguments) {
+ for (size_t i = 0; i < arguments.GetArgumentCount(); i++) {
+ AddNewField();
+ TextFieldDelegate &field = GetField(GetNumberOfFields() - 1);
+ field.SetText(arguments.GetArgumentAtIndex(i));
+ }
+ }
+};
+
+template <class KeyFieldDelegateType, class ValueFieldDelegateType>
+class MappingFieldDelegate : public FieldDelegate {
+public:
+ MappingFieldDelegate(KeyFieldDelegateType key_field,
+ ValueFieldDelegateType value_field)
+ : m_key_field(key_field), m_value_field(value_field),
+ m_selection_type(SelectionType::Key) {}
+
+ // Signify which element is selected. The key field or its value field.
+ enum class SelectionType { Key, Value };
+
+ // A mapping field is drawn as two text fields with a right arrow in between.
+ // The first field stores the key of the mapping and the second stores the
+ // value if the mapping.
+ //
+ // __[Key]_____________ __[Value]___________
+ // | | > | |
+ // |__________________| |__________________|
+ // - Error message if it exists.
+
+ // The mapping field has a height that is equal to the maximum height between
+ // the key and value fields.
+ int FieldDelegateGetHeight() override {
+ return std::max(m_key_field.FieldDelegateGetHeight(),
+ m_value_field.FieldDelegateGetHeight());
+ }
+
+ void DrawArrow(Surface &surface) {
+ surface.MoveCursor(0, 1);
+ surface.PutChar(ACS_RARROW);
+ }
+
+ void FieldDelegateDraw(Surface &surface, bool is_selected) override {
+ Rect bounds = surface.GetFrame();
+ Rect key_field_bounds, arrow_and_value_field_bounds;
+ bounds.VerticalSplit(bounds.size.width / 2, key_field_bounds,
+ arrow_and_value_field_bounds);
+ Rect arrow_bounds, value_field_bounds;
+ arrow_and_value_field_bounds.VerticalSplit(1, arrow_bounds,
+ value_field_bounds);
+
+ Surface key_field_surface = surface.SubSurface(key_field_bounds);
+ Surface arrow_surface = surface.SubSurface(arrow_bounds);
+ Surface value_field_surface = surface.SubSurface(value_field_bounds);
+
+ bool key_is_selected =
+ m_selection_type == SelectionType::Key && is_selected;
+ m_key_field.FieldDelegateDraw(key_field_surface, key_is_selected);
+ DrawArrow(arrow_surface);
+ bool value_is_selected =
+ m_selection_type == SelectionType::Value && is_selected;
+ m_value_field.FieldDelegateDraw(value_field_surface, value_is_selected);
+ }
+
+ HandleCharResult SelectNext(int key) {
+ if (FieldDelegateOnLastOrOnlyElement())
+ return eKeyNotHandled;
+
+ if (!m_key_field.FieldDelegateOnLastOrOnlyElement()) {
+ return m_key_field.FieldDelegateHandleChar(key);
+ }
+
+ m_key_field.FieldDelegateExitCallback();
+ m_selection_type = SelectionType::Value;
+ m_value_field.FieldDelegateSelectFirstElement();
+ return eKeyHandled;
+ }
+
+ HandleCharResult SelectPrevious(int key) {
+ if (FieldDelegateOnFirstOrOnlyElement())
+ return eKeyNotHandled;
+
+ if (!m_value_field.FieldDelegateOnFirstOrOnlyElement()) {
+ return m_value_field.FieldDelegateHandleChar(key);
+ }
+
+ m_value_field.FieldDelegateExitCallback();
+ m_selection_type = SelectionType::Key;
+ m_key_field.FieldDelegateSelectLastElement();
+ return eKeyHandled;
+ }
+
+ // If the value field is selected, pass the key to it. If the key field is
+ // selected, its last element is selected, and it didn't handle the key, then
+ // select its corresponding value field.
+ HandleCharResult SelectNextField(int key) {
+ if (m_selection_type == SelectionType::Value) {
+ return m_value_field.FieldDelegateHandleChar(key);
+ }
+
+ if (m_key_field.FieldDelegateHandleChar(key) == eKeyHandled)
+ return eKeyHandled;
+
+ if (!m_key_field.FieldDelegateOnLastOrOnlyElement())
+ return eKeyNotHandled;
+
+ m_key_field.FieldDelegateExitCallback();
+ m_selection_type = SelectionType::Value;
+ m_value_field.FieldDelegateSelectFirstElement();
+ return eKeyHandled;
+ }
+
+ HandleCharResult FieldDelegateHandleChar(int key) override {
+ switch (key) {
+ case KEY_RETURN:
+ return SelectNextField(key);
+ case '\t':
+ return SelectNext(key);
+ case KEY_SHIFT_TAB:
+ return SelectPrevious(key);
+ default:
+ break;
+ }
+
+ // If the key wasn't handled, pass the key to the selected field.
+ if (m_selection_type == SelectionType::Key)
+ return m_key_field.FieldDelegateHandleChar(key);
+ else
+ return m_value_field.FieldDelegateHandleChar(key);
+
+ return eKeyNotHandled;
+ }
+
+ bool FieldDelegateOnFirstOrOnlyElement() override {
+ return m_selection_type == SelectionType::Key;
+ }
+
+ bool FieldDelegateOnLastOrOnlyElement() override {
+ return m_selection_type == SelectionType::Value;
+ }
+
+ void FieldDelegateSelectFirstElement() override {
+ m_selection_type = SelectionType::Key;
+ }
+
+ void FieldDelegateSelectLastElement() override {
+ m_selection_type = SelectionType::Value;
+ }
+
+ bool FieldDelegateHasError() override {
+ return m_key_field.FieldDelegateHasError() ||
+ m_value_field.FieldDelegateHasError();
+ }
+
+ KeyFieldDelegateType &GetKeyField() { return m_key_field; }
+
+ ValueFieldDelegateType &GetValueField() { return m_value_field; }
+
+protected:
+ KeyFieldDelegateType m_key_field;
+ ValueFieldDelegateType m_value_field;
+ // See SelectionType class enum.
+ SelectionType m_selection_type;
+};
+
+class EnvironmentVariableNameFieldDelegate : public TextFieldDelegate {
+public:
+ EnvironmentVariableNameFieldDelegate(const char *content)
+ : TextFieldDelegate("Name", content, true) {}
+
+ // Environment variable names can't contain an equal sign.
+ bool IsAcceptableChar(int key) override {
+ return TextFieldDelegate::IsAcceptableChar(key) && key != '=';
+ }
+
+ const std::string &GetName() { return m_content; }
+};
+
+class EnvironmentVariableFieldDelegate
+ : public MappingFieldDelegate<EnvironmentVariableNameFieldDelegate,
+ TextFieldDelegate> {
+public:
+ EnvironmentVariableFieldDelegate()
+ : MappingFieldDelegate(
+ EnvironmentVariableNameFieldDelegate(""),
+ TextFieldDelegate("Value", "", /*required=*/false)) {}
+
+ const std::string &GetName() { return GetKeyField().GetName(); }
+
+ const std::string &GetValue() { return GetValueField().GetText(); }
+
+ void SetName(const char *name) { return GetKeyField().SetText(name); }
+
+ void SetValue(const char *value) { return GetValueField().SetText(value); }
+};
+
+class EnvironmentVariableListFieldDelegate
+ : public ListFieldDelegate<EnvironmentVariableFieldDelegate> {
+public:
+ EnvironmentVariableListFieldDelegate(const char *label)
+ : ListFieldDelegate(label, EnvironmentVariableFieldDelegate()) {}
+
+ Environment GetEnvironment() {
+ Environment environment;
+ for (int i = 0; i < GetNumberOfFields(); i++) {
+ environment.insert(
+ std::make_pair(GetField(i).GetName(), GetField(i).GetValue()));
+ }
+ return environment;
+ }
+
+ void AddEnvironmentVariables(const Environment &environment) {
+ for (auto &variable : environment) {
+ AddNewField();
+ EnvironmentVariableFieldDelegate &field =
+ GetField(GetNumberOfFields() - 1);
+ field.SetName(variable.getKey().str().c_str());
+ field.SetValue(variable.getValue().c_str());
+ }
+ }
+};
+
class FormAction {
public:
FormAction(const char *label, std::function<void(Window &)> action)
@@ -1917,7 +2263,7 @@ public:
}
// Draw a centered [Label].
- void Draw(SubPad &surface, bool is_selected) {
+ void Draw(Surface &surface, bool is_selected) {
int x = (surface.GetWidth() - m_label.length()) / 2;
surface.MoveCursor(x, 0);
if (is_selected)
@@ -1973,6 +2319,7 @@ public:
// action that requires valid fields.
bool CheckFieldsValidity() {
for (int i = 0; i < GetNumberOfFields(); i++) {
+ GetField(i)->FieldDelegateExitCallback();
if (GetField(i)->FieldDelegateHasError()) {
SetError("Some fields are invalid!");
return false;
@@ -2030,6 +2377,14 @@ public:
return delegate;
}
+ LazyBooleanFieldDelegate *AddLazyBooleanField(const char *label,
+ const char *calculate_label) {
+ LazyBooleanFieldDelegate *delegate =
+ new LazyBooleanFieldDelegate(label, calculate_label);
+ m_fields.push_back(FieldDelegateUP(delegate));
+ return delegate;
+ }
+
ChoicesFieldDelegate *AddChoicesField(const char *label, int height,
std::vector<std::string> choices) {
ChoicesFieldDelegate *delegate =
@@ -2059,6 +2414,43 @@ public:
return delegate;
}
+ ArgumentsFieldDelegate *AddArgumentsField() {
+ ArgumentsFieldDelegate *delegate = new ArgumentsFieldDelegate();
+ m_fields.push_back(FieldDelegateUP(delegate));
+ return delegate;
+ }
+
+ template <class K, class V>
+ MappingFieldDelegate<K, V> *AddMappingField(K key_field, V value_field) {
+ MappingFieldDelegate<K, V> *delegate =
+ new MappingFieldDelegate<K, V>(key_field, value_field);
+ m_fields.push_back(FieldDelegateUP(delegate));
+ return delegate;
+ }
+
+ EnvironmentVariableNameFieldDelegate *
+ AddEnvironmentVariableNameField(const char *content) {
+ EnvironmentVariableNameFieldDelegate *delegate =
+ new EnvironmentVariableNameFieldDelegate(content);
+ m_fields.push_back(FieldDelegateUP(delegate));
+ return delegate;
+ }
+
+ EnvironmentVariableFieldDelegate *AddEnvironmentVariableField() {
+ EnvironmentVariableFieldDelegate *delegate =
+ new EnvironmentVariableFieldDelegate();
+ m_fields.push_back(FieldDelegateUP(delegate));
+ return delegate;
+ }
+
+ EnvironmentVariableListFieldDelegate *
+ AddEnvironmentVariableListField(const char *label) {
+ EnvironmentVariableListFieldDelegate *delegate =
+ new EnvironmentVariableListFieldDelegate(label);
+ m_fields.push_back(FieldDelegateUP(delegate));
+ return delegate;
+ }
+
// Factory methods for adding actions.
void AddAction(const char *label, std::function<void(Window &)> action) {
@@ -2156,7 +2548,7 @@ public:
return context;
}
- void UpdateScrolling(DerivedWindow &surface) {
+ void UpdateScrolling(Surface &surface) {
ScrollContext context = GetScrollContext();
int content_height = GetContentHeight();
int surface_height = surface.GetHeight();
@@ -2180,7 +2572,7 @@ public:
}
}
- void DrawError(SubPad &surface) {
+ void DrawError(Surface &surface) {
if (!m_delegate_sp->HasError())
return;
surface.MoveCursor(0, 0);
@@ -2194,7 +2586,7 @@ public:
surface.HorizontalLine(surface.GetWidth());
}
- void DrawFields(SubPad &surface) {
+ void DrawFields(Surface &surface) {
int line = 0;
int width = surface.GetWidth();
bool a_field_is_selected = m_selection_type == SelectionType::Field;
@@ -2205,13 +2597,13 @@ public:
bool is_field_selected = a_field_is_selected && m_selection_index == i;
int height = field->FieldDelegateGetHeight();
Rect bounds = Rect(Point(0, line), Size(width, height));
- SubPad field_surface = SubPad(surface, bounds);
+ Surface field_surface = surface.SubSurface(bounds);
field->FieldDelegateDraw(field_surface, is_field_selected);
line += height;
}
}
- void DrawActions(SubPad &surface) {
+ void DrawActions(Surface &surface) {
int number_of_actions = m_delegate_sp->GetNumberOfActions();
int width = surface.GetWidth() / number_of_actions;
bool an_action_is_selected = m_selection_type == SelectionType::Action;
@@ -2220,19 +2612,19 @@ public:
bool is_action_selected = an_action_is_selected && m_selection_index == i;
FormAction &action = m_delegate_sp->GetAction(i);
Rect bounds = Rect(Point(x, 0), Size(width, 1));
- SubPad action_surface = SubPad(surface, bounds);
+ Surface action_surface = surface.SubSurface(bounds);
action.Draw(action_surface, is_action_selected);
x += width;
}
}
- void DrawElements(SubPad &surface) {
+ void DrawElements(Surface &surface) {
Rect frame = surface.GetFrame();
Rect fields_bounds, actions_bounds;
frame.HorizontalSplit(surface.GetHeight() - GetActionsHeight(),
fields_bounds, actions_bounds);
- SubPad fields_surface = SubPad(surface, fields_bounds);
- SubPad actions_surface = SubPad(surface, actions_bounds);
+ Surface fields_surface = surface.SubSurface(fields_bounds);
+ Surface actions_surface = surface.SubSurface(actions_bounds);
DrawFields(fields_surface);
DrawActions(actions_surface);
@@ -2241,7 +2633,7 @@ public:
// Contents are first drawn on a pad. Then a subset of that pad is copied to
// the derived window starting at the first visible line. This essentially
// provides scrolling functionality.
- void DrawContent(DerivedWindow &surface) {
+ void DrawContent(Surface &surface) {
UpdateScrolling(surface);
int width = surface.GetWidth();
@@ -2251,8 +2643,8 @@ public:
Rect frame = pad.GetFrame();
Rect error_bounds, elements_bounds;
frame.HorizontalSplit(GetErrorHeight(), error_bounds, elements_bounds);
- SubPad error_surface = SubPad(pad, error_bounds);
- SubPad elements_surface = SubPad(pad, elements_bounds);
+ Surface error_surface = pad.SubSurface(error_bounds);
+ Surface elements_surface = pad.SubSurface(elements_bounds);
DrawError(error_surface);
DrawElements(elements_surface);
@@ -2262,17 +2654,28 @@ public:
Size(width, copy_height));
}
+ void DrawSubmitHint(Surface &surface, bool is_active) {
+ surface.MoveCursor(2, surface.GetHeight() - 1);
+ if (is_active)
+ surface.AttributeOn(A_BOLD | COLOR_PAIR(BlackOnWhite));
+ surface.Printf("[Press Alt+Enter to %s]",
+ m_delegate_sp->GetAction(0).GetLabel().c_str());
+ if (is_active)
+ surface.AttributeOff(A_BOLD | COLOR_PAIR(BlackOnWhite));
+ }
+
bool WindowDelegateDraw(Window &window, bool force) override {
m_delegate_sp->UpdateFieldsVisibility();
window.Erase();
window.DrawTitleBox(m_delegate_sp->GetName().c_str(),
- "Press Esc to cancel");
+ "Press Esc to Cancel");
+ DrawSubmitHint(window, window.IsActive());
Rect content_bounds = window.GetFrame();
content_bounds.Inset(2, 2);
- DerivedWindow content_surface = DerivedWindow(window, content_bounds);
+ Surface content_surface = window.SubSurface(content_bounds);
DrawContent(content_surface);
return true;
@@ -2391,8 +2794,8 @@ public:
return eKeyHandled;
}
- void ExecuteAction(Window &window) {
- FormAction &action = m_delegate_sp->GetAction(m_selection_index);
+ void ExecuteAction(Window &window, int index) {
+ FormAction &action = m_delegate_sp->GetAction(index);
action.Execute(window);
if (m_delegate_sp->HasError()) {
m_first_visible_line = 0;
@@ -2401,20 +2804,27 @@ public:
}
}
+ // Always return eKeyHandled to absorb all events since forms are always
+ // added as pop-ups that should take full control until canceled or submitted.
HandleCharResult WindowDelegateHandleChar(Window &window, int key) override {
switch (key) {
case '\r':
case '\n':
case KEY_ENTER:
if (m_selection_type == SelectionType::Action) {
- ExecuteAction(window);
+ ExecuteAction(window, m_selection_index);
return eKeyHandled;
}
break;
+ case KEY_ALT_ENTER:
+ ExecuteAction(window, 0);
+ return eKeyHandled;
case '\t':
- return SelectNext(key);
+ SelectNext(key);
+ return eKeyHandled;
case KEY_SHIFT_TAB:
- return SelectPrevious(key);
+ SelectPrevious(key);
+ return eKeyHandled;
case KEY_ESCAPE:
window.GetParent()->RemoveSubWindow(&window);
return eKeyHandled;
@@ -2426,10 +2836,24 @@ public:
// to that field.
if (m_selection_type == SelectionType::Field) {
FieldDelegate *field = m_delegate_sp->GetField(m_selection_index);
- return field->FieldDelegateHandleChar(key);
+ if (field->FieldDelegateHandleChar(key) == eKeyHandled)
+ return eKeyHandled;
}
- return eKeyNotHandled;
+ // If the key wasn't handled by the possibly selected field, handle some
+ // extra keys for navigation.
+ switch (key) {
+ case KEY_DOWN:
+ SelectNext(key);
+ return eKeyHandled;
+ case KEY_UP:
+ SelectPrevious(key);
+ return eKeyHandled;
+ default:
+ break;
+ }
+
+ return eKeyHandled;
}
protected:
@@ -2651,6 +3075,801 @@ protected:
ProcessPluginFieldDelegate *m_plugin_field;
};
+class TargetCreateFormDelegate : public FormDelegate {
+public:
+ TargetCreateFormDelegate(Debugger &debugger) : m_debugger(debugger) {
+ m_executable_field = AddFileField("Executable", "", /*need_to_exist=*/true,
+ /*required=*/true);
+ m_core_file_field = AddFileField("Core File", "", /*need_to_exist=*/true,
+ /*required=*/false);
+ m_symbol_file_field = AddFileField(
+ "Symbol File", "", /*need_to_exist=*/true, /*required=*/false);
+ m_show_advanced_field = AddBooleanField("Show advanced settings.", false);
+ m_remote_file_field = AddFileField(
+ "Remote File", "", /*need_to_exist=*/false, /*required=*/false);
+ m_arch_field = AddArchField("Architecture", "", /*required=*/false);
+ m_platform_field = AddPlatformPluginField(debugger);
+ m_load_dependent_files_field =
+ AddChoicesField("Load Dependents", 3, GetLoadDependentFilesChoices());
+
+ AddAction("Create", [this](Window &window) { CreateTarget(window); });
+ }
+
+ std::string GetName() override { return "Create Target"; }
+
+ void UpdateFieldsVisibility() override {
+ if (m_show_advanced_field->GetBoolean()) {
+ m_remote_file_field->FieldDelegateShow();
+ m_arch_field->FieldDelegateShow();
+ m_platform_field->FieldDelegateShow();
+ m_load_dependent_files_field->FieldDelegateShow();
+ } else {
+ m_remote_file_field->FieldDelegateHide();
+ m_arch_field->FieldDelegateHide();
+ m_platform_field->FieldDelegateHide();
+ m_load_dependent_files_field->FieldDelegateHide();
+ }
+ }
+
+ static constexpr const char *kLoadDependentFilesNo = "No";
+ static constexpr const char *kLoadDependentFilesYes = "Yes";
+ static constexpr const char *kLoadDependentFilesExecOnly = "Executable only";
+
+ std::vector<std::string> GetLoadDependentFilesChoices() {
+ std::vector<std::string> load_depentents_options;
+ load_depentents_options.push_back(kLoadDependentFilesExecOnly);
+ load_depentents_options.push_back(kLoadDependentFilesYes);
+ load_depentents_options.push_back(kLoadDependentFilesNo);
+ return load_depentents_options;
+ }
+
+ LoadDependentFiles GetLoadDependentFiles() {
+ std::string choice = m_load_dependent_files_field->GetChoiceContent();
+ if (choice == kLoadDependentFilesNo)
+ return eLoadDependentsNo;
+ if (choice == kLoadDependentFilesYes)
+ return eLoadDependentsYes;
+ return eLoadDependentsDefault;
+ }
+
+ OptionGroupPlatform GetPlatformOptions() {
+ OptionGroupPlatform platform_options(false);
+ platform_options.SetPlatformName(m_platform_field->GetPluginName().c_str());
+ return platform_options;
+ }
+
+ TargetSP GetTarget() {
+ OptionGroupPlatform platform_options = GetPlatformOptions();
+ TargetSP target_sp;
+ Status status = m_debugger.GetTargetList().CreateTarget(
+ m_debugger, m_executable_field->GetPath(),
+ m_arch_field->GetArchString(), GetLoadDependentFiles(),
+ &platform_options, target_sp);
+
+ if (status.Fail()) {
+ SetError(status.AsCString());
+ return nullptr;
+ }
+
+ m_debugger.GetTargetList().SetSelectedTarget(target_sp);
+
+ return target_sp;
+ }
+
+ void SetSymbolFile(TargetSP target_sp) {
+ if (!m_symbol_file_field->IsSpecified())
+ return;
+
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (!module_sp)
+ return;
+
+ module_sp->SetSymbolFileFileSpec(
+ m_symbol_file_field->GetResolvedFileSpec());
+ }
+
+ void SetCoreFile(TargetSP target_sp) {
+ if (!m_core_file_field->IsSpecified())
+ return;
+
+ FileSpec core_file_spec = m_core_file_field->GetResolvedFileSpec();
+
+ FileSpec core_file_directory_spec;
+ core_file_directory_spec.GetDirectory() = core_file_spec.GetDirectory();
+ target_sp->AppendExecutableSearchPaths(core_file_directory_spec);
+
+ ProcessSP process_sp(target_sp->CreateProcess(
+ m_debugger.GetListener(), llvm::StringRef(), &core_file_spec, false));
+
+ if (!process_sp) {
+ SetError("Unable to find process plug-in for core file!");
+ return;
+ }
+
+ Status status = process_sp->LoadCore();
+ if (status.Fail()) {
+ SetError("Can't find plug-in for core file!");
+ return;
+ }
+ }
+
+ void SetRemoteFile(TargetSP target_sp) {
+ if (!m_remote_file_field->IsSpecified())
+ return;
+
+ ModuleSP module_sp(target_sp->GetExecutableModule());
+ if (!module_sp)
+ return;
+
+ FileSpec remote_file_spec = m_remote_file_field->GetFileSpec();
+ module_sp->SetPlatformFileSpec(remote_file_spec);
+ }
+
+ void RemoveTarget(TargetSP target_sp) {
+ m_debugger.GetTargetList().DeleteTarget(target_sp);
+ }
+
+ void CreateTarget(Window &window) {
+ ClearError();
+
+ bool all_fields_are_valid = CheckFieldsValidity();
+ if (!all_fields_are_valid)
+ return;
+
+ TargetSP target_sp = GetTarget();
+ if (HasError())
+ return;
+
+ SetSymbolFile(target_sp);
+ if (HasError()) {
+ RemoveTarget(target_sp);
+ return;
+ }
+
+ SetCoreFile(target_sp);
+ if (HasError()) {
+ RemoveTarget(target_sp);
+ return;
+ }
+
+ SetRemoteFile(target_sp);
+ if (HasError()) {
+ RemoveTarget(target_sp);
+ return;
+ }
+
+ window.GetParent()->RemoveSubWindow(&window);
+ }
+
+protected:
+ Debugger &m_debugger;
+
+ FileFieldDelegate *m_executable_field;
+ FileFieldDelegate *m_core_file_field;
+ FileFieldDelegate *m_symbol_file_field;
+ BooleanFieldDelegate *m_show_advanced_field;
+ FileFieldDelegate *m_remote_file_field;
+ ArchFieldDelegate *m_arch_field;
+ PlatformPluginFieldDelegate *m_platform_field;
+ ChoicesFieldDelegate *m_load_dependent_files_field;
+};
+
+class ProcessLaunchFormDelegate : public FormDelegate {
+public:
+ ProcessLaunchFormDelegate(Debugger &debugger, WindowSP main_window_sp)
+ : m_debugger(debugger), m_main_window_sp(main_window_sp) {
+
+ m_arguments_field = AddArgumentsField();
+ SetArgumentsFieldDefaultValue();
+ m_target_environment_field =
+ AddEnvironmentVariableListField("Target Environment Variables");
+ SetTargetEnvironmentFieldDefaultValue();
+ m_working_directory_field = AddDirectoryField(
+ "Working Directory", GetDefaultWorkingDirectory().c_str(), true, false);
+
+ m_show_advanced_field = AddBooleanField("Show advanced settings.", false);
+
+ m_stop_at_entry_field = AddBooleanField("Stop at entry point.", false);
+ m_detach_on_error_field =
+ AddBooleanField("Detach on error.", GetDefaultDetachOnError());
+ m_disable_aslr_field =
+ AddBooleanField("Disable ASLR", GetDefaultDisableASLR());
+ m_plugin_field = AddProcessPluginField();
+ m_arch_field = AddArchField("Architecture", "", false);
+ m_shell_field = AddFileField("Shell", "", true, false);
+ m_expand_shell_arguments_field =
+ AddBooleanField("Expand shell arguments.", false);
+
+ m_disable_standard_io_field =
+ AddBooleanField("Disable Standard IO", GetDefaultDisableStandardIO());
+ m_standard_output_field =
+ AddFileField("Standard Output File", "", /*need_to_exist=*/false,
+ /*required=*/false);
+ m_standard_error_field =
+ AddFileField("Standard Error File", "", /*need_to_exist=*/false,
+ /*required=*/false);
+ m_standard_input_field =
+ AddFileField("Standard Input File", "", /*need_to_exist=*/false,
+ /*required=*/false);
+
+ m_show_inherited_environment_field =
+ AddBooleanField("Show inherited environment variables.", false);
+ m_inherited_environment_field =
+ AddEnvironmentVariableListField("Inherited Environment Variables");
+ SetInheritedEnvironmentFieldDefaultValue();
+
+ AddAction("Launch", [this](Window &window) { Launch(window); });
+ }
+
+ std::string GetName() override { return "Launch Process"; }
+
+ void UpdateFieldsVisibility() override {
+ if (m_show_advanced_field->GetBoolean()) {
+ m_stop_at_entry_field->FieldDelegateShow();
+ m_detach_on_error_field->FieldDelegateShow();
+ m_disable_aslr_field->FieldDelegateShow();
+ m_plugin_field->FieldDelegateShow();
+ m_arch_field->FieldDelegateShow();
+ m_shell_field->FieldDelegateShow();
+ m_expand_shell_arguments_field->FieldDelegateShow();
+ m_disable_standard_io_field->FieldDelegateShow();
+ if (m_disable_standard_io_field->GetBoolean()) {
+ m_standard_input_field->FieldDelegateHide();
+ m_standard_output_field->FieldDelegateHide();
+ m_standard_error_field->FieldDelegateHide();
+ } else {
+ m_standard_input_field->FieldDelegateShow();
+ m_standard_output_field->FieldDelegateShow();
+ m_standard_error_field->FieldDelegateShow();
+ }
+ m_show_inherited_environment_field->FieldDelegateShow();
+ if (m_show_inherited_environment_field->GetBoolean())
+ m_inherited_environment_field->FieldDelegateShow();
+ else
+ m_inherited_environment_field->FieldDelegateHide();
+ } else {
+ m_stop_at_entry_field->FieldDelegateHide();
+ m_detach_on_error_field->FieldDelegateHide();
+ m_disable_aslr_field->FieldDelegateHide();
+ m_plugin_field->FieldDelegateHide();
+ m_arch_field->FieldDelegateHide();
+ m_shell_field->FieldDelegateHide();
+ m_expand_shell_arguments_field->FieldDelegateHide();
+ m_disable_standard_io_field->FieldDelegateHide();
+ m_standard_input_field->FieldDelegateHide();
+ m_standard_output_field->FieldDelegateHide();
+ m_standard_error_field->FieldDelegateHide();
+ m_show_inherited_environment_field->FieldDelegateHide();
+ m_inherited_environment_field->FieldDelegateHide();
+ }
+ }
+
+ // Methods for setting the default value of the fields.
+
+ void SetArgumentsFieldDefaultValue() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return;
+
+ const Args &target_arguments =
+ target->GetProcessLaunchInfo().GetArguments();
+ m_arguments_field->AddArguments(target_arguments);
+ }
+
+ void SetTargetEnvironmentFieldDefaultValue() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return;
+
+ const Environment &target_environment = target->GetTargetEnvironment();
+ m_target_environment_field->AddEnvironmentVariables(target_environment);
+ }
+
+ void SetInheritedEnvironmentFieldDefaultValue() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return;
+
+ const Environment &inherited_environment =
+ target->GetInheritedEnvironment();
+ m_inherited_environment_field->AddEnvironmentVariables(
+ inherited_environment);
+ }
+
+ std::string GetDefaultWorkingDirectory() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return "";
+
+ PlatformSP platform = target->GetPlatform();
+ return platform->GetWorkingDirectory().GetPath();
+ }
+
+ bool GetDefaultDisableASLR() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return false;
+
+ return target->GetDisableASLR();
+ }
+
+ bool GetDefaultDisableStandardIO() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return true;
+
+ return target->GetDisableSTDIO();
+ }
+
+ bool GetDefaultDetachOnError() {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (target == nullptr)
+ return true;
+
+ return target->GetDetachOnError();
+ }
+
+ // Methods for getting the necessary information and setting them to the
+ // ProcessLaunchInfo.
+
+ void GetExecutableSettings(ProcessLaunchInfo &launch_info) {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ ModuleSP executable_module = target->GetExecutableModule();
+ llvm::StringRef target_settings_argv0 = target->GetArg0();
+
+ if (!target_settings_argv0.empty()) {
+ launch_info.GetArguments().AppendArgument(target_settings_argv0);
+ launch_info.SetExecutableFile(executable_module->GetPlatformFileSpec(),
+ false);
+ return;
+ }
+
+ launch_info.SetExecutableFile(executable_module->GetPlatformFileSpec(),
+ true);
+ }
+
+ void GetArguments(ProcessLaunchInfo &launch_info) {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ Args arguments = m_arguments_field->GetArguments();
+ launch_info.GetArguments().AppendArguments(arguments);
+ }
+
+ void GetEnvironment(ProcessLaunchInfo &launch_info) {
+ Environment target_environment =
+ m_target_environment_field->GetEnvironment();
+ Environment inherited_environment =
+ m_inherited_environment_field->GetEnvironment();
+ launch_info.GetEnvironment().insert(target_environment.begin(),
+ target_environment.end());
+ launch_info.GetEnvironment().insert(inherited_environment.begin(),
+ inherited_environment.end());
+ }
+
+ void GetWorkingDirectory(ProcessLaunchInfo &launch_info) {
+ if (m_working_directory_field->IsSpecified())
+ launch_info.SetWorkingDirectory(
+ m_working_directory_field->GetResolvedFileSpec());
+ }
+
+ void GetStopAtEntry(ProcessLaunchInfo &launch_info) {
+ if (m_stop_at_entry_field->GetBoolean())
+ launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
+ else
+ launch_info.GetFlags().Clear(eLaunchFlagStopAtEntry);
+ }
+
+ void GetDetachOnError(ProcessLaunchInfo &launch_info) {
+ if (m_detach_on_error_field->GetBoolean())
+ launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
+ else
+ launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
+ }
+
+ void GetDisableASLR(ProcessLaunchInfo &launch_info) {
+ if (m_disable_aslr_field->GetBoolean())
+ launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
+ else
+ launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+ }
+
+ void GetPlugin(ProcessLaunchInfo &launch_info) {
+ launch_info.SetProcessPluginName(m_plugin_field->GetPluginName());
+ }
+
+ void GetArch(ProcessLaunchInfo &launch_info) {
+ if (!m_arch_field->IsSpecified())
+ return;
+
+ TargetSP target_sp = m_debugger.GetSelectedTarget();
+ PlatformSP platform_sp =
+ target_sp ? target_sp->GetPlatform() : PlatformSP();
+ launch_info.GetArchitecture() = Platform::GetAugmentedArchSpec(
+ platform_sp.get(), m_arch_field->GetArchString());
+ }
+
+ void GetShell(ProcessLaunchInfo &launch_info) {
+ if (!m_shell_field->IsSpecified())
+ return;
+
+ launch_info.SetShell(m_shell_field->GetResolvedFileSpec());
+ launch_info.SetShellExpandArguments(
+ m_expand_shell_arguments_field->GetBoolean());
+ }
+
+ void GetStandardIO(ProcessLaunchInfo &launch_info) {
+ if (m_disable_standard_io_field->GetBoolean()) {
+ launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
+ return;
+ }
+
+ FileAction action;
+ if (m_standard_input_field->IsSpecified()) {
+ action.Open(STDIN_FILENO, m_standard_input_field->GetFileSpec(), true,
+ false);
+ launch_info.AppendFileAction(action);
+ }
+ if (m_standard_output_field->IsSpecified()) {
+ action.Open(STDOUT_FILENO, m_standard_output_field->GetFileSpec(), false,
+ true);
+ launch_info.AppendFileAction(action);
+ }
+ if (m_standard_error_field->IsSpecified()) {
+ action.Open(STDERR_FILENO, m_standard_error_field->GetFileSpec(), false,
+ true);
+ launch_info.AppendFileAction(action);
+ }
+ }
+
+ void GetInheritTCC(ProcessLaunchInfo &launch_info) {
+ if (m_debugger.GetSelectedTarget()->GetInheritTCC())
+ launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent);
+ }
+
+ ProcessLaunchInfo GetLaunchInfo() {
+ ProcessLaunchInfo launch_info;
+
+ GetExecutableSettings(launch_info);
+ GetArguments(launch_info);
+ GetEnvironment(launch_info);
+ GetWorkingDirectory(launch_info);
+ GetStopAtEntry(launch_info);
+ GetDetachOnError(launch_info);
+ GetDisableASLR(launch_info);
+ GetPlugin(launch_info);
+ GetArch(launch_info);
+ GetShell(launch_info);
+ GetStandardIO(launch_info);
+ GetInheritTCC(launch_info);
+
+ return launch_info;
+ }
+
+ bool StopRunningProcess() {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+
+ if (!exe_ctx.HasProcessScope())
+ return false;
+
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!(process && process->IsAlive()))
+ return false;
+
+ FormDelegateSP form_delegate_sp =
+ FormDelegateSP(new DetachOrKillProcessFormDelegate(process));
+ Rect bounds = m_main_window_sp->GetCenteredRect(85, 8);
+ WindowSP form_window_sp = m_main_window_sp->CreateSubWindow(
+ form_delegate_sp->GetName().c_str(), bounds, true);
+ WindowDelegateSP window_delegate_sp =
+ WindowDelegateSP(new FormWindowDelegate(form_delegate_sp));
+ form_window_sp->SetDelegate(window_delegate_sp);
+
+ return true;
+ }
+
+ Target *GetTarget() {
+ Target *target = m_debugger.GetSelectedTarget().get();
+
+ if (target == nullptr) {
+ SetError("No target exists!");
+ return nullptr;
+ }
+
+ ModuleSP exe_module_sp = target->GetExecutableModule();
+
+ if (exe_module_sp == nullptr) {
+ SetError("No executable in target!");
+ return nullptr;
+ }
+
+ return target;
+ }
+
+ void Launch(Window &window) {
+ ClearError();
+
+ bool all_fields_are_valid = CheckFieldsValidity();
+ if (!all_fields_are_valid)
+ return;
+
+ bool process_is_running = StopRunningProcess();
+ if (process_is_running)
+ return;
+
+ Target *target = GetTarget();
+ if (HasError())
+ return;
+
+ StreamString stream;
+ ProcessLaunchInfo launch_info = GetLaunchInfo();
+ Status status = target->Launch(launch_info, &stream);
+
+ if (status.Fail()) {
+ SetError(status.AsCString());
+ return;
+ }
+
+ ProcessSP process_sp(target->GetProcessSP());
+ if (!process_sp) {
+ SetError("Launched successfully but target has no process!");
+ return;
+ }
+
+ window.GetParent()->RemoveSubWindow(&window);
+ }
+
+protected:
+ Debugger &m_debugger;
+ WindowSP m_main_window_sp;
+
+ ArgumentsFieldDelegate *m_arguments_field;
+ EnvironmentVariableListFieldDelegate *m_target_environment_field;
+ DirectoryFieldDelegate *m_working_directory_field;
+
+ BooleanFieldDelegate *m_show_advanced_field;
+
+ BooleanFieldDelegate *m_stop_at_entry_field;
+ BooleanFieldDelegate *m_detach_on_error_field;
+ BooleanFieldDelegate *m_disable_aslr_field;
+ ProcessPluginFieldDelegate *m_plugin_field;
+ ArchFieldDelegate *m_arch_field;
+ FileFieldDelegate *m_shell_field;
+ BooleanFieldDelegate *m_expand_shell_arguments_field;
+ BooleanFieldDelegate *m_disable_standard_io_field;
+ FileFieldDelegate *m_standard_input_field;
+ FileFieldDelegate *m_standard_output_field;
+ FileFieldDelegate *m_standard_error_field;
+
+ BooleanFieldDelegate *m_show_inherited_environment_field;
+ EnvironmentVariableListFieldDelegate *m_inherited_environment_field;
+};
+
+////////////
+// Searchers
+////////////
+
+class SearcherDelegate {
+public:
+ SearcherDelegate() {}
+
+ virtual ~SearcherDelegate() = default;
+
+ virtual int GetNumberOfMatches() = 0;
+
+ // Get the string that will be displayed for the match at the input index.
+ virtual const std::string &GetMatchTextAtIndex(int index) = 0;
+
+ // Update the matches of the search. This is executed every time the text
+ // field handles an event.
+ virtual void UpdateMatches(const std::string &text) = 0;
+
+ // Execute the user callback given the index of some match. This is executed
+ // once the user selects a match.
+ virtual void ExecuteCallback(int match_index) = 0;
+};
+
+typedef std::shared_ptr<SearcherDelegate> SearcherDelegateSP;
+
+class SearcherWindowDelegate : public WindowDelegate {
+public:
+ SearcherWindowDelegate(SearcherDelegateSP &delegate_sp)
+ : m_delegate_sp(delegate_sp), m_text_field("Search", "", false),
+ m_selected_match(0), m_first_visible_match(0) {
+ ;
+ }
+
+ // A completion window is padded by one character from all sides. A text field
+ // is first drawn for inputting the searcher request, then a list of matches
+ // are displayed in a scrollable list.
+ //
+ // ___<Searcher Window Name>____________________________
+ // | |
+ // | __[Search]_______________________________________ |
+ // | | | |
+ // | |_______________________________________________| |
+ // | - Match 1. |
+ // | - Match 2. |
+ // | - ... |
+ // | |
+ // |____________________________[Press Esc to Cancel]__|
+ //
+
+ // Get the index of the last visible match. Assuming at least one match
+ // exists.
+ int GetLastVisibleMatch(int height) {
+ int index = m_first_visible_match + height;
+ return std::min(index, m_delegate_sp->GetNumberOfMatches()) - 1;
+ }
+
+ int GetNumberOfVisibleMatches(int height) {
+ return GetLastVisibleMatch(height) - m_first_visible_match + 1;
+ }
+
+ void UpdateScrolling(Surface &surface) {
+ if (m_selected_match < m_first_visible_match) {
+ m_first_visible_match = m_selected_match;
+ return;
+ }
+
+ int height = surface.GetHeight();
+ int last_visible_match = GetLastVisibleMatch(height);
+ if (m_selected_match > last_visible_match) {
+ m_first_visible_match = m_selected_match - height + 1;
+ }
+ }
+
+ void DrawMatches(Surface &surface) {
+ if (m_delegate_sp->GetNumberOfMatches() == 0)
+ return;
+
+ UpdateScrolling(surface);
+
+ int count = GetNumberOfVisibleMatches(surface.GetHeight());
+ for (int i = 0; i < count; i++) {
+ surface.MoveCursor(1, i);
+ int current_match = m_first_visible_match + i;
+ if (current_match == m_selected_match)
+ surface.AttributeOn(A_REVERSE);
+ surface.PutCString(
+ m_delegate_sp->GetMatchTextAtIndex(current_match).c_str());
+ if (current_match == m_selected_match)
+ surface.AttributeOff(A_REVERSE);
+ }
+ }
+
+ void DrawContent(Surface &surface) {
+ Rect content_bounds = surface.GetFrame();
+ Rect text_field_bounds, matchs_bounds;
+ content_bounds.HorizontalSplit(m_text_field.FieldDelegateGetHeight(),
+ text_field_bounds, matchs_bounds);
+ Surface text_field_surface = surface.SubSurface(text_field_bounds);
+ Surface matches_surface = surface.SubSurface(matchs_bounds);
+
+ m_text_field.FieldDelegateDraw(text_field_surface, true);
+ DrawMatches(matches_surface);
+ }
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ window.Erase();
+
+ window.DrawTitleBox(window.GetName(), "Press Esc to Cancel");
+
+ Rect content_bounds = window.GetFrame();
+ content_bounds.Inset(2, 2);
+ Surface content_surface = window.SubSurface(content_bounds);
+
+ DrawContent(content_surface);
+ return true;
+ }
+
+ void SelectNext() {
+ if (m_selected_match != m_delegate_sp->GetNumberOfMatches() - 1)
+ m_selected_match++;
+ return;
+ }
+
+ void SelectPrevious() {
+ if (m_selected_match != 0)
+ m_selected_match--;
+ return;
+ }
+
+ void ExecuteCallback(Window &window) {
+ m_delegate_sp->ExecuteCallback(m_selected_match);
+ window.GetParent()->RemoveSubWindow(&window);
+ }
+
+ void UpdateMatches() {
+ m_delegate_sp->UpdateMatches(m_text_field.GetText());
+ m_selected_match = 0;
+ }
+
+ HandleCharResult WindowDelegateHandleChar(Window &window, int key) override {
+ switch (key) {
+ case '\r':
+ case '\n':
+ case KEY_ENTER:
+ ExecuteCallback(window);
+ return eKeyHandled;
+ case '\t':
+ case KEY_DOWN:
+ SelectNext();
+ return eKeyHandled;
+ case KEY_SHIFT_TAB:
+ case KEY_UP:
+ SelectPrevious();
+ return eKeyHandled;
+ case KEY_ESCAPE:
+ window.GetParent()->RemoveSubWindow(&window);
+ return eKeyHandled;
+ default:
+ break;
+ }
+
+ if (m_text_field.FieldDelegateHandleChar(key) == eKeyHandled)
+ UpdateMatches();
+
+ return eKeyHandled;
+ }
+
+protected:
+ SearcherDelegateSP m_delegate_sp;
+ TextFieldDelegate m_text_field;
+ // The index of the currently selected match.
+ int m_selected_match;
+ // The index of the first visible match.
+ int m_first_visible_match;
+};
+
+//////////////////////////////
+// Searcher Delegate Instances
+//////////////////////////////
+
+// This is a searcher delegate wrapper around CommandCompletions common
+// callbacks. The callbacks are only given the match string. The completion_mask
+// can be a combination of CommonCompletionTypes.
+class CommonCompletionSearcherDelegate : public SearcherDelegate {
+public:
+ typedef std::function<void(const std::string &)> CallbackType;
+
+ CommonCompletionSearcherDelegate(Debugger &debugger, uint32_t completion_mask,
+ CallbackType callback)
+ : m_debugger(debugger), m_completion_mask(completion_mask),
+ m_callback(callback) {}
+
+ int GetNumberOfMatches() override { return m_matches.GetSize(); }
+
+ const std::string &GetMatchTextAtIndex(int index) override {
+ return m_matches[index];
+ }
+
+ void UpdateMatches(const std::string &text) override {
+ CompletionResult result;
+ CompletionRequest request(text.c_str(), text.size(), result);
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ m_debugger.GetCommandInterpreter(), m_completion_mask, request,
+ nullptr);
+ result.GetMatches(m_matches);
+ }
+
+ void ExecuteCallback(int match_index) override {
+ m_callback(m_matches[match_index]);
+ }
+
+protected:
+ Debugger &m_debugger;
+ // A compound mask from CommonCompletionTypes.
+ uint32_t m_completion_mask;
+ // A callback to execute once the user selects a match. The match is passed to
+ // the callback as a string.
+ CallbackType m_callback;
+ StringList m_matches;
+};
+
+////////
+// Menus
+////////
+
class MenuDelegate {
public:
virtual ~MenuDelegate() = default;
@@ -3078,15 +4297,15 @@ public:
bool done = false;
int delay_in_tenths_of_a_second = 1;
- // Alas the threading model in curses is a bit lame so we need to resort to
- // polling every 0.5 seconds. We could poll for stdin ourselves and then
- // pass the keys down but then we need to translate all of the escape
+ // Alas the threading model in curses is a bit lame so we need to resort
+ // to polling every 0.5 seconds. We could poll for stdin ourselves and
+ // then pass the keys down but then we need to translate all of the escape
// sequences ourselves. So we resort to polling for input because we need
// to receive async process events while in this loop.
- halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths
- // of seconds seconds when calling
- // Window::GetChar()
+ halfdelay(delay_in_tenths_of_a_second); // Poll using some number of
+ // tenths of seconds seconds when
+ // calling Window::GetChar()
ListenerSP listener_sp(
Listener::MakeListener("lldb.IOHandler.curses.Application"));
@@ -3392,9 +4611,14 @@ public:
TreeItem *&selected_item) {
return;
}
- virtual bool TreeDelegateItemSelected(
- TreeItem &item) = 0; // Return true if we need to update views
+ // This is invoked when a tree item is selected. If true is returned, the
+ // views are updated.
+ virtual bool TreeDelegateItemSelected(TreeItem &item) = 0;
virtual bool TreeDelegateExpandRootByDefault() { return false; }
+ // This is mostly useful for root tree delegates. If false is returned,
+ // drawing will be skipped completely. This is needed, for instance, in
+ // skipping drawing of the threads tree if there is no running process.
+ virtual bool TreeDelegateShouldDraw() { return true; }
};
typedef std::shared_ptr<TreeDelegate> TreeDelegateSP;
@@ -3584,6 +4808,16 @@ public:
void SetIdentifier(uint64_t identifier) { m_identifier = identifier; }
+ const std::string &GetText() const { return m_text; }
+
+ void SetText(const char *text) {
+ if (text == nullptr) {
+ m_text.clear();
+ return;
+ }
+ m_text = text;
+ }
+
void SetMightHaveChildren(bool b) { m_might_have_children = b; }
protected:
@@ -3591,6 +4825,7 @@ protected:
TreeDelegate &m_delegate;
void *m_user_data;
uint64_t m_identifier;
+ std::string m_text;
int m_row_idx; // Zero based visible row index, -1 if not visible or for the
// root item
std::vector<TreeItem> m_children;
@@ -3609,21 +4844,6 @@ public:
int NumVisibleRows() const { return m_max_y - m_min_y; }
bool WindowDelegateDraw(Window &window, bool force) override {
- ExecutionContext exe_ctx(
- m_debugger.GetCommandInterpreter().GetExecutionContext());
- Process *process = exe_ctx.GetProcessPtr();
-
- bool display_content = false;
- if (process) {
- StateType state = process->GetState();
- if (StateIsStoppedState(state, true)) {
- // We are stopped, so it is ok to
- display_content = true;
- } else if (StateIsRunningState(state)) {
- return true; // Don't do any updating when we are running
- }
- }
-
m_min_x = 2;
m_min_y = 1;
m_max_x = window.GetWidth() - 1;
@@ -3632,35 +4852,36 @@ public:
window.Erase();
window.DrawTitleBox(window.GetName());
- if (display_content) {
- const int num_visible_rows = NumVisibleRows();
- m_num_rows = 0;
- m_root.CalculateRowIndexes(m_num_rows);
- m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx,
- m_selected_item);
-
- // If we unexpanded while having something selected our total number of
- // rows is less than the num visible rows, then make sure we show all the
- // rows by setting the first visible row accordingly.
- if (m_first_visible_row > 0 && m_num_rows < num_visible_rows)
- m_first_visible_row = 0;
-
- // Make sure the selected row is always visible
- if (m_selected_row_idx < m_first_visible_row)
- m_first_visible_row = m_selected_row_idx;
- else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
- m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
-
- int row_idx = 0;
- int num_rows_left = num_visible_rows;
- m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx,
- num_rows_left);
- // Get the selected row
- m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
- } else {
+ if (!m_delegate_sp->TreeDelegateShouldDraw()) {
m_selected_item = nullptr;
+ return true;
}
+ const int num_visible_rows = NumVisibleRows();
+ m_num_rows = 0;
+ m_root.CalculateRowIndexes(m_num_rows);
+ m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx,
+ m_selected_item);
+
+ // If we unexpanded while having something selected our total number of
+ // rows is less than the num visible rows, then make sure we show all the
+ // rows by setting the first visible row accordingly.
+ if (m_first_visible_row > 0 && m_num_rows < num_visible_rows)
+ m_first_visible_row = 0;
+
+ // Make sure the selected row is always visible
+ if (m_selected_row_idx < m_first_visible_row)
+ m_first_visible_row = m_selected_row_idx;
+ else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
+ m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
+
+ int row_idx = 0;
+ int num_rows_left = num_visible_rows;
+ m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx,
+ num_rows_left);
+ // Get the selected row
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+
return true; // Drawing handled
}
@@ -3788,6 +5009,23 @@ protected:
int m_max_y;
};
+// A tree delegate that just draws the text member of the tree item, it doesn't
+// have any children or actions.
+class TextTreeDelegate : public TreeDelegate {
+public:
+ TextTreeDelegate() : TreeDelegate() {}
+
+ ~TextTreeDelegate() override = default;
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ window.PutCStringTruncated(1, item.GetText().c_str());
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {}
+
+ bool TreeDelegateItemSelected(TreeItem &item) override { return false; }
+};
+
class FrameTreeDelegate : public TreeDelegate {
public:
FrameTreeDelegate() : TreeDelegate() {
@@ -3952,6 +5190,17 @@ public:
.GetProcessSP();
}
+ bool TreeDelegateShouldDraw() override {
+ ProcessSP process = GetProcess();
+ if (!process)
+ return false;
+
+ if (StateIsRunningState(process->GetState()))
+ return false;
+
+ return true;
+ }
+
void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
ProcessSP process_sp = GetProcess();
if (process_sp && process_sp->IsAlive()) {
@@ -4043,6 +5292,240 @@ protected:
FormatEntity::Entry m_format;
};
+class BreakpointLocationTreeDelegate : public TreeDelegate {
+public:
+ BreakpointLocationTreeDelegate(Debugger &debugger)
+ : TreeDelegate(), m_debugger(debugger) {}
+
+ ~BreakpointLocationTreeDelegate() override = default;
+
+ Process *GetProcess() {
+ ExecutionContext exe_ctx(
+ m_debugger.GetCommandInterpreter().GetExecutionContext());
+ return exe_ctx.GetProcessPtr();
+ }
+
+ BreakpointLocationSP GetBreakpointLocation(const TreeItem &item) {
+ Breakpoint *breakpoint = (Breakpoint *)item.GetUserData();
+ return breakpoint->GetLocationAtIndex(item.GetIdentifier());
+ }
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ BreakpointLocationSP breakpoint_location = GetBreakpointLocation(item);
+ Process *process = GetProcess();
+ StreamString stream;
+ stream.Printf("%i.%i: ", breakpoint_location->GetBreakpoint().GetID(),
+ breakpoint_location->GetID());
+ Address address = breakpoint_location->GetAddress();
+ address.Dump(&stream, process, Address::DumpStyleResolvedDescription,
+ Address::DumpStyleInvalid);
+ window.PutCStringTruncated(1, stream.GetString().str().c_str());
+ }
+
+ StringList ComputeDetailsList(BreakpointLocationSP breakpoint_location) {
+ StringList details;
+
+ Address address = breakpoint_location->GetAddress();
+ SymbolContext symbol_context;
+ address.CalculateSymbolContext(&symbol_context);
+
+ if (symbol_context.module_sp) {
+ StreamString module_stream;
+ module_stream.PutCString("module = ");
+ symbol_context.module_sp->GetFileSpec().Dump(
+ module_stream.AsRawOstream());
+ details.AppendString(module_stream.GetString());
+ }
+
+ if (symbol_context.comp_unit != nullptr) {
+ StreamString compile_unit_stream;
+ compile_unit_stream.PutCString("compile unit = ");
+ symbol_context.comp_unit->GetPrimaryFile().GetFilename().Dump(
+ &compile_unit_stream);
+ details.AppendString(compile_unit_stream.GetString());
+
+ if (symbol_context.function != nullptr) {
+ StreamString function_stream;
+ function_stream.PutCString("function = ");
+ function_stream.PutCString(
+ symbol_context.function->GetName().AsCString("<unknown>"));
+ details.AppendString(function_stream.GetString());
+ }
+
+ if (symbol_context.line_entry.line > 0) {
+ StreamString location_stream;
+ location_stream.PutCString("location = ");
+ symbol_context.line_entry.DumpStopContext(&location_stream, true);
+ details.AppendString(location_stream.GetString());
+ }
+
+ } else {
+ if (symbol_context.symbol) {
+ StreamString symbol_stream;
+ if (breakpoint_location->IsReExported())
+ symbol_stream.PutCString("re-exported target = ");
+ else
+ symbol_stream.PutCString("symbol = ");
+ symbol_stream.PutCString(
+ symbol_context.symbol->GetName().AsCString("<unknown>"));
+ details.AppendString(symbol_stream.GetString());
+ }
+ }
+
+ Process *process = GetProcess();
+
+ StreamString address_stream;
+ address.Dump(&address_stream, process, Address::DumpStyleLoadAddress,
+ Address::DumpStyleModuleWithFileAddress);
+ details.AppendString(address_stream.GetString());
+
+ BreakpointSiteSP breakpoint_site = breakpoint_location->GetBreakpointSite();
+ if (breakpoint_location->IsIndirect() && breakpoint_site) {
+ Address resolved_address;
+ resolved_address.SetLoadAddress(breakpoint_site->GetLoadAddress(),
+ &breakpoint_location->GetTarget());
+ Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
+ if (resolved_symbol) {
+ StreamString indirect_target_stream;
+ indirect_target_stream.PutCString("indirect target = ");
+ indirect_target_stream.PutCString(
+ resolved_symbol->GetName().GetCString());
+ details.AppendString(indirect_target_stream.GetString());
+ }
+ }
+
+ bool is_resolved = breakpoint_location->IsResolved();
+ StreamString resolved_stream;
+ resolved_stream.Printf("resolved = %s", is_resolved ? "true" : "false");
+ details.AppendString(resolved_stream.GetString());
+
+ bool is_hardware = is_resolved && breakpoint_site->IsHardware();
+ StreamString hardware_stream;
+ hardware_stream.Printf("hardware = %s", is_hardware ? "true" : "false");
+ details.AppendString(hardware_stream.GetString());
+
+ StreamString hit_count_stream;
+ hit_count_stream.Printf("hit count = %-4u",
+ breakpoint_location->GetHitCount());
+ details.AppendString(hit_count_stream.GetString());
+
+ return details;
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {
+ BreakpointLocationSP breakpoint_location = GetBreakpointLocation(item);
+ StringList details = ComputeDetailsList(breakpoint_location);
+
+ if (!m_string_delegate_sp)
+ m_string_delegate_sp = std::make_shared<TextTreeDelegate>();
+ TreeItem details_tree_item(&item, *m_string_delegate_sp, false);
+
+ item.Resize(details.GetSize(), details_tree_item);
+ for (size_t i = 0; i < details.GetSize(); i++) {
+ item[i].SetText(details.GetStringAtIndex(i));
+ }
+ }
+
+ bool TreeDelegateItemSelected(TreeItem &item) override { return false; }
+
+protected:
+ Debugger &m_debugger;
+ std::shared_ptr<TextTreeDelegate> m_string_delegate_sp;
+};
+
+class BreakpointTreeDelegate : public TreeDelegate {
+public:
+ BreakpointTreeDelegate(Debugger &debugger)
+ : TreeDelegate(), m_debugger(debugger),
+ m_breakpoint_location_delegate_sp() {}
+
+ ~BreakpointTreeDelegate() override = default;
+
+ BreakpointSP GetBreakpoint(const TreeItem &item) {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ BreakpointList &breakpoints = target->GetBreakpointList(false);
+ return breakpoints.GetBreakpointAtIndex(item.GetIdentifier());
+ }
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ BreakpointSP breakpoint = GetBreakpoint(item);
+ StreamString stream;
+ stream.Format("{0}: ", breakpoint->GetID());
+ breakpoint->GetResolverDescription(&stream);
+ breakpoint->GetFilterDescription(&stream);
+ window.PutCStringTruncated(1, stream.GetString().str().c_str());
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {
+ BreakpointSP breakpoint = GetBreakpoint(item);
+
+ if (!m_breakpoint_location_delegate_sp)
+ m_breakpoint_location_delegate_sp =
+ std::make_shared<BreakpointLocationTreeDelegate>(m_debugger);
+ TreeItem breakpoint_location_tree_item(
+ &item, *m_breakpoint_location_delegate_sp, true);
+
+ item.Resize(breakpoint->GetNumLocations(), breakpoint_location_tree_item);
+ for (size_t i = 0; i < breakpoint->GetNumLocations(); i++) {
+ item[i].SetIdentifier(i);
+ item[i].SetUserData(breakpoint.get());
+ }
+ }
+
+ bool TreeDelegateItemSelected(TreeItem &item) override { return false; }
+
+protected:
+ Debugger &m_debugger;
+ std::shared_ptr<BreakpointLocationTreeDelegate>
+ m_breakpoint_location_delegate_sp;
+};
+
+class BreakpointsTreeDelegate : public TreeDelegate {
+public:
+ BreakpointsTreeDelegate(Debugger &debugger)
+ : TreeDelegate(), m_debugger(debugger), m_breakpoint_delegate_sp() {}
+
+ ~BreakpointsTreeDelegate() override = default;
+
+ bool TreeDelegateShouldDraw() override {
+ TargetSP target = m_debugger.GetSelectedTarget();
+ if (!target)
+ return false;
+
+ return true;
+ }
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ window.PutCString("Breakpoints");
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {
+ TargetSP target = m_debugger.GetSelectedTarget();
+
+ BreakpointList &breakpoints = target->GetBreakpointList(false);
+ std::unique_lock<std::recursive_mutex> lock;
+ breakpoints.GetListMutex(lock);
+
+ if (!m_breakpoint_delegate_sp)
+ m_breakpoint_delegate_sp =
+ std::make_shared<BreakpointTreeDelegate>(m_debugger);
+ TreeItem breakpoint_tree_item(&item, *m_breakpoint_delegate_sp, true);
+
+ item.Resize(breakpoints.GetSize(), breakpoint_tree_item);
+ for (size_t i = 0; i < breakpoints.GetSize(); i++) {
+ item[i].SetIdentifier(i);
+ }
+ }
+
+ bool TreeDelegateItemSelected(TreeItem &item) override { return false; }
+
+ bool TreeDelegateExpandRootByDefault() override { return true; }
+
+protected:
+ Debugger &m_debugger;
+ std::shared_ptr<BreakpointTreeDelegate> m_breakpoint_delegate_sp;
+};
+
class ValueObjectListDelegate : public WindowDelegate {
public:
ValueObjectListDelegate() : m_rows() {}
@@ -4844,6 +6327,7 @@ public:
eMenuID_ViewRegisters,
eMenuID_ViewSource,
eMenuID_ViewVariables,
+ eMenuID_ViewBreakpoints,
eMenuID_Help,
eMenuID_HelpGUIHelp
@@ -4908,6 +6392,18 @@ public:
MenuActionResult MenuDelegateAction(Menu &menu) override {
switch (menu.GetIdentifier()) {
+ case eMenuID_TargetCreate: {
+ WindowSP main_window_sp = m_app.GetMainWindow();
+ FormDelegateSP form_delegate_sp =
+ FormDelegateSP(new TargetCreateFormDelegate(m_debugger));
+ Rect bounds = main_window_sp->GetCenteredRect(80, 19);
+ WindowSP form_window_sp = main_window_sp->CreateSubWindow(
+ form_delegate_sp->GetName().c_str(), bounds, true);
+ WindowDelegateSP window_delegate_sp =
+ WindowDelegateSP(new FormWindowDelegate(form_delegate_sp));
+ form_window_sp->SetDelegate(window_delegate_sp);
+ return MenuActionResult::Handled;
+ }
case eMenuID_ThreadStepIn: {
ExecutionContext exe_ctx =
m_debugger.GetCommandInterpreter().GetExecutionContext();
@@ -4956,6 +6452,18 @@ public:
form_window_sp->SetDelegate(window_delegate_sp);
return MenuActionResult::Handled;
}
+ case eMenuID_ProcessLaunch: {
+ WindowSP main_window_sp = m_app.GetMainWindow();
+ FormDelegateSP form_delegate_sp = FormDelegateSP(
+ new ProcessLaunchFormDelegate(m_debugger, main_window_sp));
+ Rect bounds = main_window_sp->GetCenteredRect(80, 22);
+ WindowSP form_window_sp = main_window_sp->CreateSubWindow(
+ form_delegate_sp->GetName().c_str(), bounds, true);
+ WindowDelegateSP window_delegate_sp =
+ WindowDelegateSP(new FormWindowDelegate(form_delegate_sp));
+ form_window_sp->SetDelegate(window_delegate_sp);
+ return MenuActionResult::Handled;
+ }
case eMenuID_ProcessContinue: {
ExecutionContext exe_ctx =
@@ -5046,8 +6554,8 @@ public:
// previously added
submenus.erase(submenus.begin() + 7, submenus.end());
}
- // Since we are adding and removing items we need to recalculate the name
- // lengths
+ // Since we are adding and removing items we need to recalculate the
+ // name lengths
menu.RecalculateNameLengths();
}
return MenuActionResult::Handled;
@@ -5155,6 +6663,39 @@ public:
}
return MenuActionResult::Handled;
+ case eMenuID_ViewBreakpoints: {
+ WindowSP main_window_sp = m_app.GetMainWindow();
+ WindowSP threads_window_sp = main_window_sp->FindSubWindow("Threads");
+ WindowSP breakpoints_window_sp =
+ main_window_sp->FindSubWindow("Breakpoints");
+ const Rect threads_bounds = threads_window_sp->GetBounds();
+
+ // If a breakpoints window already exists, remove it and give the area
+ // it used to occupy to the threads window. If it doesn't exist, split
+ // the threads window horizontally into two windows where the top window
+ // is the threads window and the bottom window is a newly added
+ // breakpoints window.
+ if (breakpoints_window_sp) {
+ threads_window_sp->Resize(threads_bounds.size.width,
+ threads_bounds.size.height +
+ breakpoints_window_sp->GetHeight());
+ main_window_sp->RemoveSubWindow(breakpoints_window_sp.get());
+ } else {
+ Rect new_threads_bounds, breakpoints_bounds;
+ threads_bounds.HorizontalSplitPercentage(0.70, new_threads_bounds,
+ breakpoints_bounds);
+ threads_window_sp->SetBounds(new_threads_bounds);
+ breakpoints_window_sp = main_window_sp->CreateSubWindow(
+ "Breakpoints", breakpoints_bounds, false);
+ TreeDelegateSP breakpoints_delegate_sp(
+ new BreakpointsTreeDelegate(m_debugger));
+ breakpoints_window_sp->SetDelegate(WindowDelegateSP(
+ new TreeWindowDelegate(m_debugger, breakpoints_delegate_sp)));
+ }
+ touchwin(stdscr);
+ return MenuActionResult::Handled;
+ }
+
case eMenuID_HelpGUIHelp:
m_app.GetMainWindow()->CreateHelpSubwindow();
return MenuActionResult::Handled;
@@ -5347,8 +6888,8 @@ public:
m_selected_line = m_pc_line;
if (m_file_sp && m_file_sp->GetFileSpec() == m_sc.line_entry.file) {
- // Same file, nothing to do, we should either have the lines or not
- // (source file missing)
+ // Same file, nothing to do, we should either have the lines or
+ // not (source file missing)
if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) {
if (m_selected_line >= m_first_visible_line + num_visible_lines)
m_first_visible_line = m_selected_line - 10;
@@ -5470,8 +7011,8 @@ public:
window.MoveCursor(1, line_y);
const bool is_pc_line = curr_line == m_pc_line;
const bool line_is_selected = m_selected_line == curr_line;
- // Highlight the line as the PC line first, then if the selected line
- // isn't the same as the PC line, highlight it differently
+ // Highlight the line as the PC line first, then if the selected
+ // line isn't the same as the PC line, highlight it differently
attr_t highlight_attr = 0;
attr_t bp_attr = 0;
if (is_pc_line)
@@ -5610,8 +7151,8 @@ public:
window.MoveCursor(1, line_y);
const bool is_pc_line = frame_sp && inst_idx == pc_idx;
const bool line_is_selected = m_selected_line == inst_idx;
- // Highlight the line as the PC line first, then if the selected line
- // isn't the same as the PC line, highlight it differently
+ // Highlight the line as the PC line first, then if the selected
+ // line isn't the same as the PC line, highlight it differently
attr_t highlight_attr = 0;
attr_t bp_attr = 0;
if (is_pc_line)
@@ -6075,7 +7616,7 @@ void IOHandlerCursesGUI::Activate() {
MenuSP view_menu_sp(
new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View));
view_menu_sp->AddSubmenu(
- MenuSP(new Menu("Backtrace", nullptr, 'b',
+ MenuSP(new Menu("Backtrace", nullptr, 't',
ApplicationDelegate::eMenuID_ViewBacktrace)));
view_menu_sp->AddSubmenu(
MenuSP(new Menu("Registers", nullptr, 'r',
@@ -6085,6 +7626,9 @@ void IOHandlerCursesGUI::Activate() {
view_menu_sp->AddSubmenu(
MenuSP(new Menu("Variables", nullptr, 'v',
ApplicationDelegate::eMenuID_ViewVariables)));
+ view_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Breakpoints", nullptr, 'b',
+ ApplicationDelegate::eMenuID_ViewBreakpoints)));
MenuSP help_menu_sp(
new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help));
@@ -6145,7 +7689,8 @@ void IOHandlerCursesGUI::Activate() {
status_window_sp->SetDelegate(
WindowDelegateSP(new StatusBarWindowDelegate(m_debugger)));
- // Show the main help window once the first time the curses GUI is launched
+ // Show the main help window once the first time the curses GUI is
+ // launched
static bool g_showed_help = false;
if (!g_showed_help) {
g_showed_help = true;
@@ -6176,6 +7721,7 @@ void IOHandlerCursesGUI::Activate() {
static_assert(LastColorPairIndex == 18, "Color indexes do not match.");
define_key("\033[Z", KEY_SHIFT_TAB);
+ define_key("\033\015", KEY_ALT_ENTER);
}
}
diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp
index fbaf9ff7151a..20f4dbdb419f 100644
--- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp
@@ -9,6 +9,7 @@
#include "lldb/Core/Mangled.h"
#include "lldb/Core/RichManglingContext.h"
+#include "lldb/Target/Language.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
@@ -16,8 +17,6 @@
#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-
#include "llvm/ADT/StringRef.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Compiler.h"
@@ -34,35 +33,6 @@ static inline bool cstring_is_mangled(llvm::StringRef s) {
return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone;
}
-static ConstString GetDemangledNameWithoutArguments(ConstString mangled,
- ConstString demangled) {
- const char *mangled_name_cstr = mangled.GetCString();
-
- if (demangled && mangled_name_cstr && mangled_name_cstr[0]) {
- if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
- (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
- // typeinfo structure, and typeinfo
- // mangled_name
- mangled_name_cstr[2] != 'G' && // avoid guard variables
- mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually
- // handle eSymbolTypeData, we will want
- // this back)
- {
- CPlusPlusLanguage::MethodName cxx_method(demangled);
- if (!cxx_method.GetBasename().empty()) {
- std::string shortname;
- if (!cxx_method.GetContext().empty())
- shortname = cxx_method.GetContext().str() + "::";
- shortname += cxx_method.GetBasename().str();
- return ConstString(shortname);
- }
- }
- }
- if (demangled)
- return demangled;
- return mangled;
-}
-
#pragma mark Mangled
Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) {
@@ -75,6 +45,9 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) {
if (name.startswith("_R"))
return Mangled::eManglingSchemeRustV0;
+ if (name.startswith("_D"))
+ return Mangled::eManglingSchemeD;
+
if (name.startswith("_Z"))
return Mangled::eManglingSchemeItanium;
@@ -161,9 +134,9 @@ void Mangled::SetValue(ConstString name) {
static char *GetMSVCDemangledStr(const char *M) {
char *demangled_cstr = llvm::microsoftDemangle(
M, nullptr, nullptr, nullptr, nullptr,
- llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier |
- llvm::MSDF_NoCallingConvention |
- llvm::MSDF_NoMemberType));
+ llvm::MSDemangleFlags(
+ llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention |
+ llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType));
if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
if (demangled_cstr && demangled_cstr[0])
@@ -215,6 +188,19 @@ static char *GetRustV0DemangledStr(const char *M) {
return demangled_cstr;
}
+static char *GetDLangDemangledStr(const char *M) {
+ char *demangled_cstr = llvm::dlangDemangle(M);
+
+ if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
+ if (demangled_cstr && demangled_cstr[0])
+ LLDB_LOG(log, "demangled dlang: {0} -> \"{1}\"", M, demangled_cstr);
+ else
+ LLDB_LOG(log, "demangled dlang: {0} -> error: failed to demangle", M);
+ }
+
+ return demangled_cstr;
+}
+
// Explicit demangling for scheduled requests during batch processing. This
// makes use of ItaniumPartialDemangler's rich demangle info
bool Mangled::DemangleWithRichManglingInfo(
@@ -274,7 +260,8 @@ bool Mangled::DemangleWithRichManglingInfo(
}
case eManglingSchemeRustV0:
- // Rich demangling scheme is not supported for Rust
+ case eManglingSchemeD:
+ // Rich demangling scheme is not supported
return false;
}
llvm_unreachable("Fully covered switch above!");
@@ -290,7 +277,8 @@ ConstString Mangled::GetDemangledName() const {
if (m_mangled && m_demangled.IsNull()) {
// Don't bother running anything that isn't mangled
const char *mangled_name = m_mangled.GetCString();
- ManglingScheme mangling_scheme = GetManglingScheme(m_mangled.GetStringRef());
+ ManglingScheme mangling_scheme =
+ GetManglingScheme(m_mangled.GetStringRef());
if (mangling_scheme != eManglingSchemeNone &&
!m_mangled.GetMangledCounterpart(m_demangled)) {
// We didn't already mangle this name, demangle it and if all goes well
@@ -307,6 +295,9 @@ ConstString Mangled::GetDemangledName() const {
case eManglingSchemeRustV0:
demangled_name = GetRustV0DemangledStr(mangled_name);
break;
+ case eManglingSchemeD:
+ demangled_name = GetDLangDemangledStr(mangled_name);
+ break;
case eManglingSchemeNone:
llvm_unreachable("eManglingSchemeNone was handled already");
}
@@ -326,8 +317,7 @@ ConstString Mangled::GetDemangledName() const {
return m_demangled;
}
-ConstString
-Mangled::GetDisplayDemangledName() const {
+ConstString Mangled::GetDisplayDemangledName() const {
return GetDemangledName();
}
@@ -344,14 +334,16 @@ ConstString Mangled::GetName(Mangled::NamePreference preference) const {
if (preference == ePreferMangled && m_mangled)
return m_mangled;
+ // Call the accessor to make sure we get a demangled name in case it hasn't
+ // been demangled yet...
ConstString demangled = GetDemangledName();
if (preference == ePreferDemangledWithoutArguments) {
- return GetDemangledNameWithoutArguments(m_mangled, demangled);
+ if (Language *lang = Language::FindPlugin(GuessLanguage())) {
+ return lang->GetDemangledFunctionNameWithoutArguments(*this);
+ }
}
if (preference == ePreferDemangled) {
- // Call the accessor to make sure we get a demangled name in case it hasn't
- // been demangled yet...
if (demangled)
return demangled;
return m_mangled;
diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp
index 19c97be15066..bd0a667171a5 100644
--- a/contrib/llvm-project/lldb/source/Core/Module.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Module.cpp
@@ -796,7 +796,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
void Module::FindFunctions(ConstString name,
const CompilerDeclContext &parent_decl_ctx,
FunctionNameType name_type_mask,
- bool include_symbols, bool include_inlines,
+ const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
const size_t old_size = sc_list.GetSize();
@@ -808,12 +808,12 @@ void Module::FindFunctions(ConstString name,
if (symbols) {
symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx,
- lookup_info.GetNameTypeMask(), include_inlines,
- sc_list);
+ lookup_info.GetNameTypeMask(),
+ options.include_inlines, sc_list);
// Now check our symbol table for symbols that are code symbols if
// requested
- if (include_symbols) {
+ if (options.include_symbols) {
Symtab *symtab = symbols->GetSymtab();
if (symtab)
symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
@@ -828,11 +828,11 @@ void Module::FindFunctions(ConstString name,
} else {
if (symbols) {
symbols->FindFunctions(name, parent_decl_ctx, name_type_mask,
- include_inlines, sc_list);
+ options.include_inlines, sc_list);
// Now check our symbol table for symbols that are code symbols if
// requested
- if (include_symbols) {
+ if (options.include_symbols) {
Symtab *symtab = symbols->GetSymtab();
if (symtab)
symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
@@ -841,17 +841,17 @@ void Module::FindFunctions(ConstString name,
}
}
-void Module::FindFunctions(const RegularExpression &regex, bool include_symbols,
- bool include_inlines,
+void Module::FindFunctions(const RegularExpression &regex,
+ const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
const size_t start_size = sc_list.GetSize();
if (SymbolFile *symbols = GetSymbolFile()) {
- symbols->FindFunctions(regex, include_inlines, sc_list);
+ symbols->FindFunctions(regex, options.include_inlines, sc_list);
// Now check our symbol table for symbols that are code symbols if
// requested
- if (include_symbols) {
+ if (options.include_symbols) {
Symtab *symtab = symbols->GetSymtab();
if (symtab) {
std::vector<uint32_t> symbol_indexes;
@@ -1614,24 +1614,23 @@ llvm::Optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const
void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) {
XcodeSDK sdk(sdk_name.str());
- ConstString sdk_path(HostInfo::GetXcodeSDKPath(sdk));
- if (!sdk_path)
+ llvm::StringRef sdk_path(HostInfo::GetXcodeSDKPath(sdk));
+ if (sdk_path.empty())
return;
// If the SDK changed for a previously registered source path, update it.
// This could happend with -fdebug-prefix-map, otherwise it's unlikely.
- ConstString sysroot_cs(sysroot);
- if (!m_source_mappings.Replace(sysroot_cs, sdk_path, true))
+ if (!m_source_mappings.Replace(sysroot, sdk_path, true))
// In the general case, however, append it to the list.
- m_source_mappings.Append(sysroot_cs, sdk_path, false);
+ m_source_mappings.Append(sysroot, sdk_path, false);
}
bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
if (!arch_spec.IsValid())
return false;
- LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES),
- "module has arch %s, merging/replacing with arch %s",
- m_arch.GetTriple().getTriple().c_str(),
- arch_spec.GetTriple().getTriple().c_str());
+ LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES),
+ "module has arch %s, merging/replacing with arch %s",
+ m_arch.GetTriple().getTriple().c_str(),
+ arch_spec.GetTriple().getTriple().c_str());
if (!m_arch.IsCompatibleMatch(arch_spec)) {
// The new architecture is different, we just need to replace it.
return SetArchitecture(arch_spec);
diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp
index 56bc4c72d8e9..9176c9dbb357 100644
--- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp
@@ -122,8 +122,7 @@ void ModuleListProperties::UpdateSymlinkMappings() {
FileSpec resolved;
Status status = FileSystem::Instance().Readlink(symlink, resolved);
if (status.Success())
- m_symlink_paths.Append(ConstString(symlink.GetPath()),
- ConstString(resolved.GetPath()), notify);
+ m_symlink_paths.Append(symlink.GetPath(), resolved.GetPath(), notify);
}
}
@@ -200,16 +199,15 @@ void ModuleList::ReplaceEquivalent(
}
}
-bool ModuleList::AppendIfNeeded(const ModuleSP &module_sp, bool notify) {
- if (module_sp) {
+bool ModuleList::AppendIfNeeded(const ModuleSP &new_module, bool notify) {
+ if (new_module) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- if (pos->get() == module_sp.get())
+ for (const ModuleSP &module_sp : m_modules) {
+ if (module_sp.get() == new_module.get())
return false; // Already in the list
}
// Only push module_sp on the list if it wasn't already in there.
- Append(module_sp, notify);
+ Append(new_module, notify);
return true;
}
return false;
@@ -364,7 +362,7 @@ ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {
void ModuleList::FindFunctions(ConstString name,
FunctionNameType name_type_mask,
- bool include_symbols, bool include_inlines,
+ const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) const {
const size_t old_size = sc_list.GetSize();
@@ -372,11 +370,10 @@ void ModuleList::FindFunctions(ConstString name,
Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindFunctions(lookup_info.GetLookupName(), CompilerDeclContext(),
- lookup_info.GetNameTypeMask(), include_symbols,
- include_inlines, sc_list);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->FindFunctions(lookup_info.GetLookupName(),
+ CompilerDeclContext(),
+ lookup_info.GetNameTypeMask(), options, sc_list);
}
const size_t new_size = sc_list.GetSize();
@@ -385,10 +382,9 @@ void ModuleList::FindFunctions(ConstString name,
lookup_info.Prune(sc_list, old_size);
} else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindFunctions(name, CompilerDeclContext(), name_type_mask,
- include_symbols, include_inlines, sc_list);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->FindFunctions(name, CompilerDeclContext(), name_type_mask,
+ options, sc_list);
}
}
}
@@ -402,10 +398,9 @@ void ModuleList::FindFunctionSymbols(ConstString name,
Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindFunctionSymbols(lookup_info.GetLookupName(),
- lookup_info.GetNameTypeMask(), sc_list);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->FindFunctionSymbols(lookup_info.GetLookupName(),
+ lookup_info.GetNameTypeMask(), sc_list);
}
const size_t new_size = sc_list.GetSize();
@@ -414,39 +409,33 @@ void ModuleList::FindFunctionSymbols(ConstString name,
lookup_info.Prune(sc_list, old_size);
} else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindFunctionSymbols(name, name_type_mask, sc_list);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->FindFunctionSymbols(name, name_type_mask, sc_list);
}
}
}
void ModuleList::FindFunctions(const RegularExpression &name,
- bool include_symbols, bool include_inlines,
+ const ModuleFunctionSearchOptions &options,
SymbolContextList &sc_list) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindFunctions(name, include_symbols, include_inlines, sc_list);
- }
+ for (const ModuleSP &module_sp : m_modules)
+ module_sp->FindFunctions(name, options, sc_list);
}
void ModuleList::FindCompileUnits(const FileSpec &path,
SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindCompileUnits(path, sc_list);
- }
+ for (const ModuleSP &module_sp : m_modules)
+ module_sp->FindCompileUnits(path, sc_list);
}
void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches,
VariableList &variable_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindGlobalVariables(name, CompilerDeclContext(), max_matches,
- variable_list);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->FindGlobalVariables(name, CompilerDeclContext(), max_matches,
+ variable_list);
}
}
@@ -454,36 +443,30 @@ void ModuleList::FindGlobalVariables(const RegularExpression &regex,
size_t max_matches,
VariableList &variable_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindGlobalVariables(regex, max_matches, variable_list);
- }
+ for (const ModuleSP &module_sp : m_modules)
+ module_sp->FindGlobalVariables(regex, max_matches, variable_list);
}
void ModuleList::FindSymbolsWithNameAndType(ConstString name,
SymbolType symbol_type,
SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- (*pos)->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
+ for (const ModuleSP &module_sp : m_modules)
+ module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
}
void ModuleList::FindSymbolsMatchingRegExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- (*pos)->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
+ for (const ModuleSP &module_sp : m_modules)
+ module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
}
void ModuleList::FindModules(const ModuleSpec &module_spec,
ModuleList &matching_module_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- ModuleSP module_sp(*pos);
+ for (const ModuleSP &module_sp : m_modules) {
if (module_sp->MatchesModuleSpec(module_spec))
matching_module_list.Append(module_sp);
}
@@ -559,9 +542,8 @@ void ModuleList::FindTypes(Module *search_first, ConstString name,
bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
FileSpec &new_spec) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- if ((*pos)->FindSourceFile(orig_spec, new_spec))
+ for (const ModuleSP &module_sp : m_modules) {
+ if (module_sp->FindSourceFile(orig_spec, new_spec))
return true;
}
return false;
@@ -573,10 +555,9 @@ void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp,
std::vector<Address> &output_local,
std::vector<Address> &output_extern) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local,
- output_extern);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->FindAddressesForLine(target_sp, file, line, function,
+ output_local, output_extern);
}
}
@@ -603,10 +584,8 @@ size_t ModuleList::GetSize() const {
void ModuleList::Dump(Stream *s) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->Dump(s);
- }
+ for (const ModuleSP &module_sp : m_modules)
+ module_sp->Dump(s);
}
void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
@@ -629,9 +608,8 @@ void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr,
Address &so_addr) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- if ((*pos)->ResolveFileAddress(vm_addr, so_addr))
+ for (const ModuleSP &module_sp : m_modules) {
+ if (module_sp->ResolveFileAddress(vm_addr, so_addr))
return true;
}
@@ -674,10 +652,9 @@ uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos) {
- (*pos)->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
- resolve_scope, sc_list);
+ for (const ModuleSP &module_sp : m_modules) {
+ module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
+ resolve_scope, sc_list);
}
return sc_list.GetSize();
diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp
index fcaa868b083e..801591129244 100644
--- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp
+++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp
@@ -12,6 +12,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Target/Process.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
@@ -184,15 +185,14 @@ template <typename Callback> struct PluginInstance {
typedef Callback CallbackType;
PluginInstance() = default;
- PluginInstance(ConstString name, std::string description,
- Callback create_callback = nullptr,
+ PluginInstance(llvm::StringRef name, llvm::StringRef description,
+ Callback create_callback,
DebuggerInitializeCallback debugger_init_callback = nullptr)
- : name(name), description(std::move(description)),
- create_callback(create_callback),
+ : name(name), description(description), create_callback(create_callback),
debugger_init_callback(debugger_init_callback) {}
- ConstString name;
- std::string description;
+ llvm::StringRef name;
+ llvm::StringRef description;
Callback create_callback;
DebuggerInitializeCallback debugger_init_callback;
};
@@ -200,12 +200,12 @@ template <typename Callback> struct PluginInstance {
template <typename Instance> class PluginInstances {
public:
template <typename... Args>
- bool RegisterPlugin(ConstString name, const char *description,
+ bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
typename Instance::CallbackType callback,
- Args &&... args) {
+ Args &&...args) {
if (!callback)
return false;
- assert((bool)name);
+ assert(!name.empty());
Instance instance =
Instance(name, description, callback, std::forward<Args>(args)...);
m_instances.push_back(instance);
@@ -232,20 +232,20 @@ public:
return nullptr;
}
- const char *GetDescriptionAtIndex(uint32_t idx) {
+ llvm::StringRef GetDescriptionAtIndex(uint32_t idx) {
if (Instance *instance = GetInstanceAtIndex(idx))
- return instance->description.c_str();
- return nullptr;
+ return instance->description;
+ return "";
}
- const char *GetNameAtIndex(uint32_t idx) {
+ llvm::StringRef GetNameAtIndex(uint32_t idx) {
if (Instance *instance = GetInstanceAtIndex(idx))
- return instance->name.GetCString();
- return nullptr;
+ return instance->name;
+ return "";
}
- typename Instance::CallbackType GetCallbackForName(ConstString name) {
- if (!name)
+ typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) {
+ if (name.empty())
return nullptr;
for (auto &instance : m_instances) {
if (name == instance.name)
@@ -284,7 +284,8 @@ static ABIInstances &GetABIInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+bool PluginManager::RegisterPlugin(llvm::StringRef name,
+ llvm::StringRef description,
ABICreateInstance create_callback) {
return GetABIInstances().RegisterPlugin(name, description, create_callback);
}
@@ -307,11 +308,10 @@ static ArchitectureInstances &GetArchitectureInstances() {
return g_instances;
}
-void PluginManager::RegisterPlugin(ConstString name,
+void PluginManager::RegisterPlugin(llvm::StringRef name,
llvm::StringRef description,
ArchitectureCreateInstance create_callback) {
- GetArchitectureInstances().push_back(
- {name, std::string(description), create_callback});
+ GetArchitectureInstances().push_back({name, description, create_callback});
}
void PluginManager::UnregisterPlugin(
@@ -346,7 +346,8 @@ static DisassemblerInstances &GetDisassemblerInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+bool PluginManager::RegisterPlugin(llvm::StringRef name,
+ llvm::StringRef description,
DisassemblerCreateInstance create_callback) {
return GetDisassemblerInstances().RegisterPlugin(name, description,
create_callback);
@@ -363,7 +364,8 @@ PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
}
DisassemblerCreateInstance
-PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) {
+PluginManager::GetDisassemblerCreateCallbackForPluginName(
+ llvm::StringRef name) {
return GetDisassemblerInstances().GetCallbackForName(name);
}
@@ -378,7 +380,7 @@ static DynamicLoaderInstances &GetDynamicLoaderInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
DynamicLoaderCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback) {
return GetDynamicLoaderInstances().RegisterPlugin(
@@ -396,7 +398,8 @@ PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
}
DynamicLoaderCreateInstance
-PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) {
+PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
+ llvm::StringRef name) {
return GetDynamicLoaderInstances().GetCallbackForName(name);
}
@@ -411,7 +414,7 @@ static JITLoaderInstances &GetJITLoaderInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
JITLoaderCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback) {
return GetJITLoaderInstances().RegisterPlugin(
@@ -439,7 +442,7 @@ static EmulateInstructionInstances &GetEmulateInstructionInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
EmulateInstructionCreateInstance create_callback) {
return GetEmulateInstructionInstances().RegisterPlugin(name, description,
create_callback);
@@ -457,7 +460,7 @@ PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
EmulateInstructionCreateInstance
PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
- ConstString name) {
+ llvm::StringRef name) {
return GetEmulateInstructionInstances().GetCallbackForName(name);
}
@@ -472,7 +475,7 @@ static OperatingSystemInstances &GetOperatingSystemInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
OperatingSystemCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback) {
return GetOperatingSystemInstances().RegisterPlugin(
@@ -490,7 +493,8 @@ PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
}
OperatingSystemCreateInstance
-PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) {
+PluginManager::GetOperatingSystemCreateCallbackForPluginName(
+ llvm::StringRef name) {
return GetOperatingSystemInstances().GetCallbackForName(name);
}
@@ -504,7 +508,8 @@ static LanguageInstances &GetLanguageInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+bool PluginManager::RegisterPlugin(llvm::StringRef name,
+ llvm::StringRef description,
LanguageCreateInstance create_callback) {
return GetLanguageInstances().RegisterPlugin(name, description,
create_callback);
@@ -524,13 +529,13 @@ PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
struct LanguageRuntimeInstance
: public PluginInstance<LanguageRuntimeCreateInstance> {
LanguageRuntimeInstance(
- ConstString name, std::string description, CallbackType create_callback,
+ llvm::StringRef name, llvm::StringRef description,
+ CallbackType create_callback,
DebuggerInitializeCallback debugger_init_callback,
LanguageRuntimeGetCommandObject command_callback,
LanguageRuntimeGetExceptionPrecondition precondition_callback)
: PluginInstance<LanguageRuntimeCreateInstance>(
- name, std::move(description), create_callback,
- debugger_init_callback),
+ name, description, create_callback, debugger_init_callback),
command_callback(command_callback),
precondition_callback(precondition_callback) {}
@@ -546,7 +551,7 @@ static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
LanguageRuntimeCreateInstance create_callback,
LanguageRuntimeGetCommandObject command_callback,
LanguageRuntimeGetExceptionPrecondition precondition_callback) {
@@ -592,7 +597,7 @@ static SystemRuntimeInstances &GetSystemRuntimeInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
SystemRuntimeCreateInstance create_callback) {
return GetSystemRuntimeInstances().RegisterPlugin(name, description,
create_callback);
@@ -612,11 +617,12 @@ PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
ObjectFileInstance(
- ConstString name, std::string description, CallbackType create_callback,
+ llvm::StringRef name, llvm::StringRef description,
+ CallbackType create_callback,
ObjectFileCreateMemoryInstance create_memory_callback,
ObjectFileGetModuleSpecifications get_module_specifications,
ObjectFileSaveCore save_core)
- : PluginInstance<ObjectFileCreateInstance>(name, std::move(description),
+ : PluginInstance<ObjectFileCreateInstance>(name, description,
create_callback),
create_memory_callback(create_memory_callback),
get_module_specifications(get_module_specifications),
@@ -634,7 +640,7 @@ static ObjectFileInstances &GetObjectFileInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
ObjectFileCreateInstance create_callback,
ObjectFileCreateMemoryInstance create_memory_callback,
ObjectFileGetModuleSpecifications get_module_specifications,
@@ -672,9 +678,7 @@ PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
ObjectFileCreateMemoryInstance
PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
- ConstString name) {
- if (!name)
- return nullptr;
+ llvm::StringRef name) {
const auto &instances = GetObjectFileInstances().GetInstances();
for (auto &instance : instances) {
if (instance.name == name)
@@ -685,13 +689,26 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
const FileSpec &outfile,
- lldb::SaveCoreStyle &core_style) {
+ lldb::SaveCoreStyle &core_style,
+ llvm::StringRef plugin_name) {
+ if (plugin_name.empty()) {
+ // Try saving core directly from the process plugin first.
+ llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath());
+ if (!ret)
+ return Status(ret.takeError());
+ if (ret.get())
+ return Status();
+ }
+
+ // Fall back to object plugins.
Status error;
auto &instances = GetObjectFileInstances().GetInstances();
for (auto &instance : instances) {
- if (instance.save_core &&
- instance.save_core(process_sp, outfile, core_style, error))
- return error;
+ if (plugin_name.empty() || instance.name == plugin_name) {
+ if (instance.save_core &&
+ instance.save_core(process_sp, outfile, core_style, error))
+ return error;
+ }
}
error.SetErrorString(
"no ObjectFile plugins were able to save a core for this process");
@@ -703,10 +720,11 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
struct ObjectContainerInstance
: public PluginInstance<ObjectContainerCreateInstance> {
ObjectContainerInstance(
- ConstString name, std::string description, CallbackType create_callback,
+ llvm::StringRef name, llvm::StringRef description,
+ CallbackType create_callback,
ObjectFileGetModuleSpecifications get_module_specifications)
- : PluginInstance<ObjectContainerCreateInstance>(
- name, std::move(description), create_callback),
+ : PluginInstance<ObjectContainerCreateInstance>(name, description,
+ create_callback),
get_module_specifications(get_module_specifications) {}
ObjectFileGetModuleSpecifications get_module_specifications;
@@ -719,7 +737,7 @@ static ObjectContainerInstances &GetObjectContainerInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
ObjectContainerCreateInstance create_callback,
ObjectFileGetModuleSpecifications get_module_specifications) {
return GetObjectContainerInstances().RegisterPlugin(
@@ -756,7 +774,7 @@ static PlatformInstances &GetPlatformInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
PlatformCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback) {
return GetPlatformInstances().RegisterPlugin(
@@ -767,11 +785,12 @@ bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
return GetPlatformInstances().UnregisterPlugin(create_callback);
}
-const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
+llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
return GetPlatformInstances().GetNameAtIndex(idx);
}
-const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
+llvm::StringRef
+PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
return GetPlatformInstances().GetDescriptionAtIndex(idx);
}
@@ -781,15 +800,15 @@ PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
}
PlatformCreateInstance
-PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) {
+PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
return GetPlatformInstances().GetCallbackForName(name);
}
void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
CompletionRequest &request) {
for (const auto &instance : GetPlatformInstances().GetInstances()) {
- if (instance.name.GetStringRef().startswith(name))
- request.AddCompletion(instance.name.GetCString());
+ if (instance.name.startswith(name))
+ request.AddCompletion(instance.name);
}
}
@@ -804,7 +823,7 @@ static ProcessInstances &GetProcessInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
ProcessCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback) {
return GetProcessInstances().RegisterPlugin(
@@ -815,11 +834,11 @@ bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
return GetProcessInstances().UnregisterPlugin(create_callback);
}
-const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
+llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
return GetProcessInstances().GetNameAtIndex(idx);
}
-const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
+llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
return GetProcessInstances().GetDescriptionAtIndex(idx);
}
@@ -829,15 +848,15 @@ PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
}
ProcessCreateInstance
-PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) {
+PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
return GetProcessInstances().GetCallbackForName(name);
}
void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
CompletionRequest &request) {
for (const auto &instance : GetProcessInstances().GetInstances()) {
- if (instance.name.GetStringRef().startswith(name))
- request.AddCompletion(instance.name.GetCString(), instance.description);
+ if (instance.name.startswith(name))
+ request.AddCompletion(instance.name, instance.description);
}
}
@@ -845,11 +864,11 @@ void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
struct ScriptInterpreterInstance
: public PluginInstance<ScriptInterpreterCreateInstance> {
- ScriptInterpreterInstance(ConstString name, std::string description,
+ ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
CallbackType create_callback,
lldb::ScriptLanguage language)
- : PluginInstance<ScriptInterpreterCreateInstance>(
- name, std::move(description), create_callback),
+ : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
+ create_callback),
language(language) {}
lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
@@ -863,7 +882,7 @@ static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
lldb::ScriptLanguage script_language,
ScriptInterpreterCreateInstance create_callback) {
return GetScriptInterpreterInstances().RegisterPlugin(
@@ -903,12 +922,12 @@ PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
struct StructuredDataPluginInstance
: public PluginInstance<StructuredDataPluginCreateInstance> {
StructuredDataPluginInstance(
- ConstString name, std::string description, CallbackType create_callback,
+ llvm::StringRef name, llvm::StringRef description,
+ CallbackType create_callback,
DebuggerInitializeCallback debugger_init_callback,
StructuredDataFilterLaunchInfo filter_callback)
: PluginInstance<StructuredDataPluginCreateInstance>(
- name, std::move(description), create_callback,
- debugger_init_callback),
+ name, description, create_callback, debugger_init_callback),
filter_callback(filter_callback) {}
StructuredDataFilterLaunchInfo filter_callback = nullptr;
@@ -923,7 +942,7 @@ static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
StructuredDataPluginCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback,
StructuredDataFilterLaunchInfo filter_callback) {
@@ -966,7 +985,7 @@ static SymbolFileInstances &GetSymbolFileInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
SymbolFileCreateInstance create_callback,
DebuggerInitializeCallback debugger_init_callback) {
return GetSymbolFileInstances().RegisterPlugin(
@@ -992,7 +1011,8 @@ static SymbolVendorInstances &GetSymbolVendorInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+bool PluginManager::RegisterPlugin(llvm::StringRef name,
+ llvm::StringRef description,
SymbolVendorCreateInstance create_callback) {
return GetSymbolVendorInstances().RegisterPlugin(name, description,
create_callback);
@@ -1013,12 +1033,12 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
struct TraceInstance
: public PluginInstance<TraceCreateInstanceForSessionFile> {
TraceInstance(
- ConstString name, std::string description,
+ llvm::StringRef name, llvm::StringRef description,
CallbackType create_callback_for_session_file,
TraceCreateInstanceForLiveProcess create_callback_for_live_process,
llvm::StringRef schema)
: PluginInstance<TraceCreateInstanceForSessionFile>(
- name, std::move(description), create_callback_for_session_file),
+ name, description, create_callback_for_session_file),
schema(schema),
create_callback_for_live_process(create_callback_for_live_process) {}
@@ -1034,7 +1054,7 @@ static TraceInstances &GetTracePluginInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
TraceCreateInstanceForSessionFile create_callback_for_session_file,
TraceCreateInstanceForLiveProcess create_callback_for_live_process,
llvm::StringRef schema) {
@@ -1050,19 +1070,19 @@ bool PluginManager::UnregisterPlugin(
}
TraceCreateInstanceForSessionFile
-PluginManager::GetTraceCreateCallback(ConstString plugin_name) {
+PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
return GetTracePluginInstances().GetCallbackForName(plugin_name);
}
TraceCreateInstanceForLiveProcess
-PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) {
+PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
if (instance.name == plugin_name)
return instance.create_callback_for_live_process;
return nullptr;
}
-llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) {
+llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
if (instance.name == plugin_name)
return instance.schema;
@@ -1081,11 +1101,11 @@ llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
struct TraceExporterInstance
: public PluginInstance<TraceExporterCreateInstance> {
TraceExporterInstance(
- ConstString name, std::string description,
+ llvm::StringRef name, llvm::StringRef description,
TraceExporterCreateInstance create_instance,
ThreadTraceExportCommandCreator create_thread_trace_export_command)
- : PluginInstance<TraceExporterCreateInstance>(
- name, std::move(description), create_instance),
+ : PluginInstance<TraceExporterCreateInstance>(name, description,
+ create_instance),
create_thread_trace_export_command(create_thread_trace_export_command) {
}
@@ -1100,7 +1120,7 @@ static TraceExporterInstances &GetTraceExporterInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
TraceExporterCreateInstance create_callback,
ThreadTraceExportCommandCreator create_thread_trace_export_command) {
return GetTraceExporterInstances().RegisterPlugin(
@@ -1108,7 +1128,7 @@ bool PluginManager::RegisterPlugin(
}
TraceExporterCreateInstance
-PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) {
+PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
return GetTraceExporterInstances().GetCallbackForName(plugin_name);
}
@@ -1125,7 +1145,8 @@ PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
return nullptr;
}
-const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
+llvm::StringRef
+PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
return GetTraceExporterInstances().GetNameAtIndex(index);
}
@@ -1140,7 +1161,7 @@ static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
UnwindAssemblyCreateInstance create_callback) {
return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
create_callback);
@@ -1167,7 +1188,7 @@ static MemoryHistoryInstances &GetMemoryHistoryInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
MemoryHistoryCreateInstance create_callback) {
return GetMemoryHistoryInstances().RegisterPlugin(name, description,
create_callback);
@@ -1188,10 +1209,11 @@ PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
struct InstrumentationRuntimeInstance
: public PluginInstance<InstrumentationRuntimeCreateInstance> {
InstrumentationRuntimeInstance(
- ConstString name, std::string description, CallbackType create_callback,
+ llvm::StringRef name, llvm::StringRef description,
+ CallbackType create_callback,
InstrumentationRuntimeGetType get_type_callback)
- : PluginInstance<InstrumentationRuntimeCreateInstance>(
- name, std::move(description), create_callback),
+ : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
+ create_callback),
get_type_callback(get_type_callback) {}
InstrumentationRuntimeGetType get_type_callback = nullptr;
@@ -1206,7 +1228,7 @@ static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
InstrumentationRuntimeCreateInstance create_callback,
InstrumentationRuntimeGetType get_type_callback) {
return GetInstrumentationRuntimeInstances().RegisterPlugin(
@@ -1234,11 +1256,11 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
#pragma mark TypeSystem
struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
- TypeSystemInstance(ConstString name, std::string description,
+ TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
CallbackType create_callback,
LanguageSet supported_languages_for_types,
LanguageSet supported_languages_for_expressions)
- : PluginInstance<TypeSystemCreateInstance>(name, std::move(description),
+ : PluginInstance<TypeSystemCreateInstance>(name, description,
create_callback),
supported_languages_for_types(supported_languages_for_types),
supported_languages_for_expressions(
@@ -1256,7 +1278,7 @@ static TypeSystemInstances &GetTypeSystemInstances() {
}
bool PluginManager::RegisterPlugin(
- ConstString name, const char *description,
+ llvm::StringRef name, llvm::StringRef description,
TypeSystemCreateInstance create_callback,
LanguageSet supported_languages_for_types,
LanguageSet supported_languages_for_expressions) {
@@ -1293,10 +1315,9 @@ LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
#pragma mark REPL
struct REPLInstance : public PluginInstance<REPLCreateInstance> {
- REPLInstance(ConstString name, std::string description,
+ REPLInstance(llvm::StringRef name, llvm::StringRef description,
CallbackType create_callback, LanguageSet supported_languages)
- : PluginInstance<REPLCreateInstance>(name, std::move(description),
- create_callback),
+ : PluginInstance<REPLCreateInstance>(name, description, create_callback),
supported_languages(supported_languages) {}
LanguageSet supported_languages;
@@ -1309,7 +1330,7 @@ static REPLInstances &GetREPLInstances() {
return g_instances;
}
-bool PluginManager::RegisterPlugin(ConstString name, const char *description,
+bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
REPLCreateInstance create_callback,
LanguageSet supported_languages) {
return GetREPLInstances().RegisterPlugin(name, description, create_callback,
@@ -1421,8 +1442,9 @@ namespace {
typedef lldb::OptionValuePropertiesSP
GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
bool can_create);
+}
-lldb::OptionValuePropertiesSP
+static lldb::OptionValuePropertiesSP
GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
ConstString plugin_type_name,
GetDebuggerPropertyForPluginsPtr get_debugger_property =
@@ -1438,13 +1460,13 @@ GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
return properties_sp;
}
-bool CreateSettingForPlugin(
- Debugger &debugger, ConstString plugin_type_name,
- ConstString plugin_type_desc,
- const lldb::OptionValuePropertiesSP &properties_sp, ConstString description,
- bool is_global_property,
- GetDebuggerPropertyForPluginsPtr get_debugger_property =
- GetDebuggerPropertyForPlugins) {
+static bool
+CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name,
+ ConstString plugin_type_desc,
+ const lldb::OptionValuePropertiesSP &properties_sp,
+ ConstString description, bool is_global_property,
+ GetDebuggerPropertyForPluginsPtr get_debugger_property =
+ GetDebuggerPropertyForPlugins) {
if (properties_sp) {
lldb::OptionValuePropertiesSP plugin_type_properties_sp(
get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
@@ -1459,14 +1481,12 @@ bool CreateSettingForPlugin(
return false;
}
-const char *kDynamicLoaderPluginName("dynamic-loader");
-const char *kPlatformPluginName("platform");
-const char *kProcessPluginName("process");
-const char *kSymbolFilePluginName("symbol-file");
-const char *kJITLoaderPluginName("jit-loader");
-const char *kStructuredDataPluginName("structured-data");
-
-} // anonymous namespace
+static const char *kDynamicLoaderPluginName("dynamic-loader");
+static const char *kPlatformPluginName("platform");
+static const char *kProcessPluginName("process");
+static const char *kSymbolFilePluginName("symbol-file");
+static const char *kJITLoaderPluginName("jit-loader");
+static const char *kStructuredDataPluginName("structured-data");
lldb::OptionValuePropertiesSP
PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
diff --git a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp
index 2dcb1407e6c7..63170feb6231 100644
--- a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp
+++ b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp
@@ -83,19 +83,6 @@ bool RichManglingContext::IsCtorOrDtor() const {
llvm_unreachable("Fully covered switch above!");
}
-bool RichManglingContext::IsFunction() const {
- assert(m_provider != None && "Initialize a provider first");
- switch (m_provider) {
- case ItaniumPartialDemangler:
- return m_ipd.isFunction();
- case PluginCxxLanguage:
- return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->IsValid();
- case None:
- return false;
- }
- llvm_unreachable("Fully covered switch above!");
-}
-
void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
// Error case: Clear the buffer.
if (LLVM_UNLIKELY(ipd_res == nullptr)) {
diff --git a/contrib/llvm-project/lldb/source/Core/Section.cpp b/contrib/llvm-project/lldb/source/Core/Section.cpp
index a5a10141aa64..1660e3c92f2c 100644
--- a/contrib/llvm-project/lldb/source/Core/Section.cpp
+++ b/contrib/llvm-project/lldb/source/Core/Section.cpp
@@ -396,6 +396,76 @@ lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {
return 0;
}
+bool Section::ContainsOnlyDebugInfo() const {
+ switch (m_type) {
+ case eSectionTypeInvalid:
+ case eSectionTypeCode:
+ case eSectionTypeContainer:
+ case eSectionTypeData:
+ case eSectionTypeDataCString:
+ case eSectionTypeDataCStringPointers:
+ case eSectionTypeDataSymbolAddress:
+ case eSectionTypeData4:
+ case eSectionTypeData8:
+ case eSectionTypeData16:
+ case eSectionTypeDataPointers:
+ case eSectionTypeZeroFill:
+ case eSectionTypeDataObjCMessageRefs:
+ case eSectionTypeDataObjCCFStrings:
+ case eSectionTypeELFSymbolTable:
+ case eSectionTypeELFDynamicSymbols:
+ case eSectionTypeELFRelocationEntries:
+ case eSectionTypeELFDynamicLinkInfo:
+ case eSectionTypeEHFrame:
+ case eSectionTypeARMexidx:
+ case eSectionTypeARMextab:
+ case eSectionTypeCompactUnwind:
+ case eSectionTypeGoSymtab:
+ case eSectionTypeAbsoluteAddress:
+ case eSectionTypeOther:
+ return false;
+
+ case eSectionTypeDebug:
+ case eSectionTypeDWARFDebugAbbrev:
+ case eSectionTypeDWARFDebugAbbrevDwo:
+ case eSectionTypeDWARFDebugAddr:
+ case eSectionTypeDWARFDebugAranges:
+ case eSectionTypeDWARFDebugCuIndex:
+ case eSectionTypeDWARFDebugTuIndex:
+ case eSectionTypeDWARFDebugFrame:
+ case eSectionTypeDWARFDebugInfo:
+ case eSectionTypeDWARFDebugInfoDwo:
+ case eSectionTypeDWARFDebugLine:
+ case eSectionTypeDWARFDebugLineStr:
+ case eSectionTypeDWARFDebugLoc:
+ case eSectionTypeDWARFDebugLocDwo:
+ case eSectionTypeDWARFDebugLocLists:
+ case eSectionTypeDWARFDebugLocListsDwo:
+ case eSectionTypeDWARFDebugMacInfo:
+ case eSectionTypeDWARFDebugMacro:
+ case eSectionTypeDWARFDebugPubNames:
+ case eSectionTypeDWARFDebugPubTypes:
+ case eSectionTypeDWARFDebugRanges:
+ case eSectionTypeDWARFDebugRngLists:
+ case eSectionTypeDWARFDebugRngListsDwo:
+ case eSectionTypeDWARFDebugStr:
+ case eSectionTypeDWARFDebugStrDwo:
+ case eSectionTypeDWARFDebugStrOffsets:
+ case eSectionTypeDWARFDebugStrOffsetsDwo:
+ case eSectionTypeDWARFDebugTypes:
+ case eSectionTypeDWARFDebugTypesDwo:
+ case eSectionTypeDWARFDebugNames:
+ case eSectionTypeDWARFAppleNames:
+ case eSectionTypeDWARFAppleTypes:
+ case eSectionTypeDWARFAppleNamespaces:
+ case eSectionTypeDWARFAppleObjC:
+ case eSectionTypeDWARFGNUDebugAltLink:
+ return true;
+ }
+ return false;
+}
+
+
#pragma mark SectionList
SectionList &SectionList::operator=(const SectionList &rhs) {
@@ -599,3 +669,15 @@ size_t SectionList::Slide(addr_t slide_amount, bool slide_children) {
}
return count;
}
+
+uint64_t SectionList::GetDebugInfoSize() const {
+ uint64_t debug_info_size = 0;
+ for (const auto &section : m_sections) {
+ const SectionList &sub_sections = section->GetChildren();
+ if (sub_sections.GetSize() > 0)
+ debug_info_size += sub_sections.GetDebugInfoSize();
+ else if (section->ContainsOnlyDebugInfo())
+ debug_info_size += section->GetFileSize();
+ }
+ return debug_info_size;
+}
diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp
index 9c1112979c54..effba485f026 100644
--- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp
+++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp
@@ -339,11 +339,14 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) {
if (executable_ptr) {
SymbolContextList sc_list;
ConstString main_name("main");
- bool symbols_okay = false; // Force it to be a debug symbol.
- bool inlines_okay = true;
+
+ ModuleFunctionSearchOptions function_options;
+ function_options.include_symbols =
+ false; // Force it to be a debug symbol.
+ function_options.include_inlines = true;
executable_ptr->FindFunctions(main_name, CompilerDeclContext(),
- lldb::eFunctionNameTypeBase, inlines_okay,
- symbols_okay, sc_list);
+ lldb::eFunctionNameTypeBase,
+ function_options, sc_list);
size_t num_matches = sc_list.GetSize();
for (size_t idx = 0; idx < num_matches; idx++) {
SymbolContext sc;
diff --git a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp
index 2f922fe11440..7753397ae0f1 100644
--- a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp
+++ b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp
@@ -21,8 +21,8 @@ StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
}
StreamFile::StreamFile(int fd, bool transfer_ownership) : Stream() {
- m_file_sp =
- std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, transfer_ownership);
+ m_file_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWriteOnly,
+ transfer_ownership);
}
StreamFile::StreamFile(FILE *fh, bool transfer_ownership) : Stream() {
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
index 9c1ba99da1d0..6794d0c7331d 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp
@@ -849,8 +849,10 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) {
static bool CopyStringDataToBufferSP(const StreamString &source,
lldb::DataBufferSP &destination) {
- destination = std::make_shared<DataBufferHeap>(source.GetSize() + 1, 0);
- memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
+ llvm::StringRef src = source.GetString();
+ src.consume_back(llvm::StringRef("\0", 1));
+ destination = std::make_shared<DataBufferHeap>(src.size(), 0);
+ memcpy(destination->GetBytes(), src.data(), src.size());
return true;
}
@@ -912,8 +914,8 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
CopyStringDataToBufferSP(s, buffer_sp);
return {0, was_capped};
}
- buffer_sp = std::make_shared<DataBufferHeap>(cstr_len, 0);
- memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
+ s << llvm::StringRef(cstr, cstr_len);
+ CopyStringDataToBufferSP(s, buffer_sp);
return {cstr_len, was_capped};
} else {
s << "<invalid address>";
@@ -1196,6 +1198,7 @@ bool ValueObject::DumpPrintableRepresentation(
options.SetQuote('"');
options.SetSourceSize(buffer_sp->GetByteSize());
options.SetIsTruncated(read_string.second);
+ options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar);
formatters::StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
options);
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp
index 980cea049f6f..fee1da138bbc 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp
@@ -34,7 +34,7 @@ using namespace lldb_private;
ValueObjectConstResultImpl::ValueObjectConstResultImpl(
ValueObject *valobj, lldb::addr_t live_address)
: m_impl_backend(valobj), m_live_address(live_address),
- m_live_address_type(eAddressTypeLoad), m_load_addr_backend(),
+ m_live_address_type(eAddressTypeLoad),
m_address_of_backend() {}
lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Status &error) {
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp
index d77509496509..bf087f33c0e9 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -36,10 +36,6 @@ ValueObjectDynamicValue::ValueObjectDynamicValue(
SetName(parent.GetName());
}
-ValueObjectDynamicValue::~ValueObjectDynamicValue() {
- m_owning_valobj_sp.reset();
-}
-
CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
const bool success = UpdateValueIfNeeded(false);
if (success) {
diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
index 089fd7667080..743083a2d1ed 100644
--- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
+++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
@@ -118,8 +118,9 @@ ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
if (m_reg_ctx_sp && m_reg_set) {
const size_t num_children = GetNumChildren();
if (idx < num_children)
- valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
- m_reg_set->registers[idx]);
+ valobj = new ValueObjectRegister(
+ *this, m_reg_ctx_sp,
+ m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx]));
}
return valobj;
}
@@ -132,8 +133,7 @@ ValueObjectRegisterSet::GetChildMemberWithName(ConstString name,
const RegisterInfo *reg_info =
m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef());
if (reg_info != nullptr)
- valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
- reg_info->kinds[eRegisterKindLLDB]);
+ valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info);
}
if (valobj)
return valobj->GetSP();
@@ -155,8 +155,7 @@ ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) {
#pragma mark -
#pragma mark ValueObjectRegister
-void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
- const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+void ValueObjectRegister::ConstructObject(const RegisterInfo *reg_info) {
if (reg_info) {
m_reg_info = *reg_info;
if (reg_info->name)
@@ -168,29 +167,29 @@ void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
lldb::RegisterContextSP &reg_ctx_sp,
- uint32_t reg_num)
+ const RegisterInfo *reg_info)
: ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
m_reg_value(), m_type_name(), m_compiler_type() {
assert(reg_ctx_sp.get());
- ConstructObject(reg_num);
+ ConstructObject(reg_info);
}
ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
lldb::RegisterContextSP &reg_ctx_sp,
- uint32_t reg_num) {
+ const RegisterInfo *reg_info) {
auto manager_sp = ValueObjectManager::Create();
- return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_num))
+ return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info))
->GetSP();
}
ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
ValueObjectManager &manager,
lldb::RegisterContextSP &reg_ctx,
- uint32_t reg_num)
+ const RegisterInfo *reg_info)
: ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
m_reg_value(), m_type_name(), m_compiler_type() {
assert(reg_ctx);
- ConstructObject(reg_num);
+ ConstructObject(reg_info);
}
ValueObjectRegister::~ValueObjectRegister() = default;