diff options
Diffstat (limited to 'lldb/source/Commands/CommandObjectFrame.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 126 |
1 files changed, 99 insertions, 27 deletions
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 50d5c751de5c0..6ebad9b5c488d 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -1,4 +1,4 @@ -//===-- CommandObjectFrame.cpp ----------------------------------*- C++ -*-===// +//===-- CommandObjectFrame.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,7 +12,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/Config.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFormat.h" @@ -172,8 +171,7 @@ protected: Stream &stream) -> bool { const ValueObject::GetExpressionPathFormat format = ValueObject:: GetExpressionPathFormat::eGetExpressionPathFormatHonorPointers; - const bool qualify_cxx_base_classes = false; - valobj_sp->GetExpressionPath(stream, qualify_cxx_base_classes, format); + valobj_sp->GetExpressionPath(stream, format); stream.PutCString(" ="); return true; }; @@ -187,7 +185,6 @@ protected: return true; } -protected: CommandOptions m_options; }; @@ -291,6 +288,22 @@ public: ~CommandObjectFrameSelect() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + + lldb::ThreadSP thread_sp = m_exe_ctx.GetThreadSP(); + const uint32_t frame_num = thread_sp->GetStackFrameCount(); + for (uint32_t i = 0; i < frame_num; ++i) { + lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i); + StreamString strm; + frame_sp->Dump(&strm, false, true); + request.TryCompleteCurrentArg(std::to_string(i), strm.GetString()); + } + } + Options *GetOptions() override { return &m_options; } protected: @@ -380,7 +393,6 @@ protected: return result.Succeeded(); } -protected: CommandOptions m_options; }; @@ -715,7 +727,6 @@ protected: return res; } -protected: OptionGroupOptions m_option_group; OptionGroupVariable m_option_variable; OptionGroupFormat m_option_format; @@ -747,7 +758,7 @@ private: m_module = std::string(option_arg); break; case 'n': - m_function = std::string(option_arg); + m_symbols.push_back(std::string(option_arg)); break; case 'x': m_regex = true; @@ -761,7 +772,7 @@ private: void OptionParsingStarting(ExecutionContext *execution_context) override { m_module = ""; - m_function = ""; + m_symbols.clear(); m_class_name = ""; m_regex = false; } @@ -773,7 +784,7 @@ private: // Instance variables to hold the values for command options. std::string m_class_name; std::string m_module; - std::string m_function; + std::vector<std::string> m_symbols; bool m_regex; }; @@ -855,9 +866,18 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, return false; } - if (m_options.m_function.empty()) { - result.AppendErrorWithFormat("%s needs a function name (-n argument).\n", - m_cmd_name.c_str()); + if (m_options.m_symbols.empty()) { + result.AppendErrorWithFormat( + "%s needs at least one symbol name (-n argument).\n", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_regex && m_options.m_symbols.size() > 1) { + result.AppendErrorWithFormat( + "%s needs only one symbol regular expression (-n argument).\n", + m_cmd_name.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -877,12 +897,13 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, auto module = RegularExpressionSP(new RegularExpression(m_options.m_module)); auto func = - RegularExpressionSP(new RegularExpression(m_options.m_function)); + RegularExpressionSP(new RegularExpression(m_options.m_symbols.front())); StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func); } else { auto module = ConstString(m_options.m_module); - auto func = ConstString(m_options.m_function); - StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func); + std::vector<ConstString> symbols(m_options.m_symbols.begin(), + m_options.m_symbols.end()); + StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, symbols); } #endif @@ -914,6 +935,33 @@ public: ~CommandObjectFrameRecognizerDelete() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + StackFrameRecognizerManager::ForEach( + [&request](uint32_t rid, std::string rname, std::string module, + llvm::ArrayRef<lldb_private::ConstString> symbols, + bool regexp) { + StreamString strm; + if (rname.empty()) + rname = "(internal)"; + + strm << rname; + if (!module.empty()) + strm << ", module " << module; + if (!symbols.empty()) + for (auto &symbol : symbols) + strm << ", symbol " << symbol; + if (regexp) + strm << " (regexp)"; + + request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString()); + }); + } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { if (command.GetArgumentCount() == 0) { @@ -937,8 +985,13 @@ protected: return false; } - uint32_t recognizer_id = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + uint32_t recognizer_id; + if (!llvm::to_integer(command.GetArgumentAtIndex(0), recognizer_id)) { + result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n", + command.GetArgumentAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return false; + } StackFrameRecognizerManager::RemoveRecognizerWithID(recognizer_id); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -959,14 +1012,26 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { bool any_printed = false; StackFrameRecognizerManager::ForEach( - [&result, &any_printed](uint32_t recognizer_id, std::string name, - std::string function, std::string symbol, - bool regexp) { - if (name == "") + [&result, &any_printed]( + uint32_t recognizer_id, std::string name, std::string module, + llvm::ArrayRef<ConstString> symbols, bool regexp) { + Stream &stream = result.GetOutputStream(); + + if (name.empty()) name = "(internal)"; - result.GetOutputStream().Printf( - "%d: %s, module %s, function %s%s\n", recognizer_id, name.c_str(), - function.c_str(), symbol.c_str(), regexp ? " (regexp)" : ""); + + stream << std::to_string(recognizer_id) << ": " << name; + if (!module.empty()) + stream << ", module " << module; + if (!symbols.empty()) + for (auto &symbol : symbols) + stream << ", symbol " << symbol; + if (regexp) + stream << " (regexp)"; + + stream.EOL(); + stream.Flush(); + any_printed = true; }); @@ -1006,6 +1071,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { + const char *frame_index_str = command.GetArgumentAtIndex(0); + uint32_t frame_index; + if (!llvm::to_integer(frame_index_str, frame_index)) { + result.AppendErrorWithFormat("'%s' is not a valid frame index.", + frame_index_str); + result.SetStatus(eReturnStatusFailed); + return false; + } + Process *process = m_exe_ctx.GetProcessPtr(); if (process == nullptr) { result.AppendError("no process"); @@ -1025,8 +1099,6 @@ protected: return false; } - uint32_t frame_index = - StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_index); if (!frame_sp) { result.AppendErrorWithFormat("no frame with index %u", frame_index); |