diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
commit | ead246455adf1a215ec2715dad6533073a6beb4e (patch) | |
tree | f3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source | |
parent | fdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff) | |
download | src-vendor/lldb.tar.gz src-vendor/lldb.zip |
Vendor import of stripped lldb trunk r375505, the last commit before thevendor/lldb/lldb-trunk-r375505vendor/lldb
upstream Subversion repository was made read-only, and the LLVM project
migrated to GitHub:
https://llvm.org/svn/llvm-project/lldb/trunk@375505
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=353952
svn path=/vendor/lldb/lldb-r375505/; revision=353953; tag=vendor/lldb/lldb-trunk-r375505
Diffstat (limited to 'source')
502 files changed, 23251 insertions, 23233 deletions
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp index 358cb400a76c..dcde25b77917 100644 --- a/source/API/SBAddress.cpp +++ b/source/API/SBAddress.cpp @@ -28,7 +28,7 @@ SBAddress::SBAddress() : m_opaque_up(new Address()) { SBAddress::SBAddress(const Address *lldb_object_ptr) : m_opaque_up(new Address()) { if (lldb_object_ptr) - m_opaque_up = llvm::make_unique<Address>(*lldb_object_ptr); + m_opaque_up = std::make_unique<Address>(*lldb_object_ptr); } SBAddress::SBAddress(const SBAddress &rhs) : m_opaque_up(new Address()) { @@ -210,12 +210,6 @@ bool SBAddress::GetDescription(SBStream &description) { if (m_opaque_up->IsValid()) { m_opaque_up->Dump(&strm, nullptr, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress, 4); - StreamString sstrm; - // m_opaque_up->Dump (&sstrm, NULL, - // Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, - // 4); - // if (sstrm.GetData()) - // strm.Printf (" (%s)", sstrm.GetData()); } else strm.PutCString("No value"); diff --git a/source/API/SBBreakpointOptionCommon.cpp b/source/API/SBBreakpointOptionCommon.cpp index 058b3e0398cd..870b4b941ada 100644 --- a/source/API/SBBreakpointOptionCommon.cpp +++ b/source/API/SBBreakpointOptionCommon.cpp @@ -41,7 +41,7 @@ using namespace lldb_private; SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback callback, void *baton) - : TypedBaton(llvm::make_unique<CallbackData>()) { + : TypedBaton(std::make_unique<CallbackData>()) { getItem()->callback = callback; getItem()->callback_baton = baton; } diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp index c07dffce0baa..6e5ebe6a7ded 100644 --- a/source/API/SBCommandInterpreter.cpp +++ b/source/API/SBCommandInterpreter.cpp @@ -162,12 +162,11 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - SBCommandReturnObject sb_return(&result); + SBCommandReturnObject sb_return(result); SBCommandInterpreter sb_interpreter(&m_interpreter); SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); bool ret = m_backend->DoExecute( debugger_sb, (char **)command.GetArgumentVector(), sb_return); - sb_return.Release(); return ret; } std::shared_ptr<lldb::SBCommandPluginInterface> m_backend; @@ -353,8 +352,6 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions( current_line, cursor, last_char, match_start_point, max_return_elements, matches, descriptions); - int num_completions = 0; - // Sanity check the arguments that are passed in: cursor & last_char have to // be within the current_line. if (current_line == nullptr || cursor == nullptr || last_char == nullptr) @@ -368,20 +365,50 @@ int SBCommandInterpreter::HandleCompletionWithDescriptions( last_char - current_line > static_cast<ptrdiff_t>(current_line_size)) return 0; + if (!IsValid()) + return 0; - if (IsValid()) { - lldb_private::StringList lldb_matches, lldb_descriptions; - num_completions = m_opaque_ptr->HandleCompletion( - current_line, cursor, last_char, match_start_point, max_return_elements, - lldb_matches, lldb_descriptions); - - SBStringList temp_matches_list(&lldb_matches); - matches.AppendList(temp_matches_list); - SBStringList temp_descriptions_list(&lldb_descriptions); - descriptions.AppendList(temp_descriptions_list); + lldb_private::StringList lldb_matches, lldb_descriptions; + CompletionResult result; + CompletionRequest request(current_line, cursor - current_line, result); + m_opaque_ptr->HandleCompletion(request); + result.GetMatches(lldb_matches); + result.GetDescriptions(lldb_descriptions); + + // Make the result array indexed from 1 again by adding the 'common prefix' + // of all completions as element 0. This is done to emulate the old API. + if (request.GetParsedLine().GetArgumentCount() == 0) { + // If we got an empty string, insert nothing. + lldb_matches.InsertStringAtIndex(0, ""); + lldb_descriptions.InsertStringAtIndex(0, ""); + } else { + // Now figure out if there is a common substring, and if so put that in + // element 0, otherwise put an empty string in element 0. + std::string command_partial_str = request.GetCursorArgumentPrefix().str(); + + std::string common_prefix = lldb_matches.LongestCommonPrefix(); + const size_t partial_name_len = command_partial_str.size(); + common_prefix.erase(0, partial_name_len); + + // If we matched a unique single command, add a space... Only do this if + // the completer told us this was a complete word, however... + if (lldb_matches.GetSize() == 1) { + char quote_char = request.GetParsedArg().GetQuoteChar(); + common_prefix = + Args::EscapeLLDBCommandArgument(common_prefix, quote_char); + if (request.GetParsedArg().IsQuoted()) + common_prefix.push_back(quote_char); + common_prefix.push_back(' '); + } + lldb_matches.InsertStringAtIndex(0, common_prefix.c_str()); + lldb_descriptions.InsertStringAtIndex(0, ""); } - return num_completions; + SBStringList temp_matches_list(&lldb_matches); + matches.AppendList(temp_matches_list); + SBStringList temp_descriptions_list(&lldb_descriptions); + descriptions.AppendList(temp_descriptions_list); + return result.GetNumberOfResults(); } int SBCommandInterpreter::HandleCompletionWithDescriptions( diff --git a/source/API/SBCommandReturnObject.cpp b/source/API/SBCommandReturnObject.cpp index 94e89916f7f6..eec1383df875 100644 --- a/source/API/SBCommandReturnObject.cpp +++ b/source/API/SBCommandReturnObject.cpp @@ -10,6 +10,7 @@ #include "SBReproducerPrivate.h" #include "Utils.h" #include "lldb/API/SBError.h" +#include "lldb/API/SBFile.h" #include "lldb/API/SBStream.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/ConstString.h" @@ -18,11 +19,43 @@ using namespace lldb; using namespace lldb_private; +class lldb_private::SBCommandReturnObjectImpl { +public: + SBCommandReturnObjectImpl() + : m_ptr(new CommandReturnObject()), m_owned(true) {} + SBCommandReturnObjectImpl(CommandReturnObject &ref) + : m_ptr(&ref), m_owned(false) {} + SBCommandReturnObjectImpl(const SBCommandReturnObjectImpl &rhs) + : m_ptr(new CommandReturnObject(*rhs.m_ptr)), m_owned(rhs.m_owned) {} + SBCommandReturnObjectImpl &operator=(const SBCommandReturnObjectImpl &rhs) { + SBCommandReturnObjectImpl copy(rhs); + std::swap(*this, copy); + return *this; + } + // rvalue ctor+assignment are not used by SBCommandReturnObject. + ~SBCommandReturnObjectImpl() { + if (m_owned) + delete m_ptr; + } + + CommandReturnObject &operator*() const { return *m_ptr; } + +private: + CommandReturnObject *m_ptr; + bool m_owned; +}; + SBCommandReturnObject::SBCommandReturnObject() - : m_opaque_up(new CommandReturnObject()) { + : m_opaque_up(new SBCommandReturnObjectImpl()) { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommandReturnObject); } +SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject &ref) + : m_opaque_up(new SBCommandReturnObjectImpl(ref)) { + LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, + (lldb_private::CommandReturnObject &), ref); +} + SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) : m_opaque_up() { LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, @@ -31,25 +64,10 @@ SBCommandReturnObject::SBCommandReturnObject(const SBCommandReturnObject &rhs) m_opaque_up = clone(rhs.m_opaque_up); } -SBCommandReturnObject::SBCommandReturnObject(CommandReturnObject *ptr) - : m_opaque_up(ptr) { - LLDB_RECORD_CONSTRUCTOR(SBCommandReturnObject, - (lldb_private::CommandReturnObject *), ptr); -} - -SBCommandReturnObject::~SBCommandReturnObject() = default; - -CommandReturnObject *SBCommandReturnObject::Release() { - LLDB_RECORD_METHOD_NO_ARGS(lldb_private::CommandReturnObject *, - SBCommandReturnObject, Release); - - return LLDB_RECORD_RESULT(m_opaque_up.release()); -} - -const SBCommandReturnObject &SBCommandReturnObject:: +SBCommandReturnObject &SBCommandReturnObject:: operator=(const SBCommandReturnObject &rhs) { LLDB_RECORD_METHOD( - const lldb::SBCommandReturnObject &, + lldb::SBCommandReturnObject &, SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &), rhs); @@ -58,6 +76,8 @@ operator=(const SBCommandReturnObject &rhs) { return LLDB_RECORD_RESULT(*this); } +SBCommandReturnObject::~SBCommandReturnObject() = default; + bool SBCommandReturnObject::IsValid() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, IsValid); return this->operator bool(); @@ -65,49 +85,38 @@ bool SBCommandReturnObject::IsValid() const { SBCommandReturnObject::operator bool() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommandReturnObject, operator bool); - return m_opaque_up != nullptr; + // This method is not useful but it needs to stay to keep SB API stable. + return true; } const char *SBCommandReturnObject::GetOutput() { LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetOutput); - if (m_opaque_up) { - llvm::StringRef output = m_opaque_up->GetOutputData(); - ConstString result(output.empty() ? llvm::StringRef("") : output); - - return result.AsCString(); - } - - return nullptr; + ConstString output(ref().GetOutputData()); + return output.AsCString(/*value_if_empty*/ ""); } const char *SBCommandReturnObject::GetError() { LLDB_RECORD_METHOD_NO_ARGS(const char *, SBCommandReturnObject, GetError); - if (m_opaque_up) { - llvm::StringRef output = m_opaque_up->GetErrorData(); - ConstString result(output.empty() ? llvm::StringRef("") : output); - return result.AsCString(); - } - - return nullptr; + ConstString output(ref().GetErrorData()); + return output.AsCString(/*value_if_empty*/ ""); } size_t SBCommandReturnObject::GetOutputSize() { LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetOutputSize); - return (m_opaque_up ? m_opaque_up->GetOutputData().size() : 0); + return ref().GetOutputData().size(); } size_t SBCommandReturnObject::GetErrorSize() { LLDB_RECORD_METHOD_NO_ARGS(size_t, SBCommandReturnObject, GetErrorSize); - return (m_opaque_up ? m_opaque_up->GetErrorData().size() : 0); + return ref().GetErrorData().size(); } size_t SBCommandReturnObject::PutOutput(FILE *fh) { - LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh); - + LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh); if (fh) { size_t num_bytes = GetOutputSize(); if (num_bytes) @@ -116,9 +125,23 @@ size_t SBCommandReturnObject::PutOutput(FILE *fh) { return 0; } -size_t SBCommandReturnObject::PutError(FILE *fh) { - LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *), fh); +size_t SBCommandReturnObject::PutOutput(FileSP file_sp) { + LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP), + file_sp); + if (!file_sp) + return 0; + return file_sp->Printf("%s", GetOutput()); +} + +size_t SBCommandReturnObject::PutOutput(SBFile file) { + LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile), file); + if (!file.m_opaque_sp) + return 0; + return file.m_opaque_sp->Printf("%s", GetOutput()); +} +size_t SBCommandReturnObject::PutError(FILE *fh) { + LLDB_RECORD_DUMMY(size_t, SBCommandReturnObject, PutError, (FILE *), fh); if (fh) { size_t num_bytes = GetErrorSize(); if (num_bytes) @@ -127,77 +150,81 @@ size_t SBCommandReturnObject::PutError(FILE *fh) { return 0; } +size_t SBCommandReturnObject::PutError(FileSP file_sp) { + LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP), + file_sp); + if (!file_sp) + return 0; + return file_sp->Printf("%s", GetError()); +} + +size_t SBCommandReturnObject::PutError(SBFile file) { + LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile), file); + if (!file.m_opaque_sp) + return 0; + return file.m_opaque_sp->Printf("%s", GetError()); +} + void SBCommandReturnObject::Clear() { LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear); - if (m_opaque_up) - m_opaque_up->Clear(); + ref().Clear(); } lldb::ReturnStatus SBCommandReturnObject::GetStatus() { LLDB_RECORD_METHOD_NO_ARGS(lldb::ReturnStatus, SBCommandReturnObject, GetStatus); - return (m_opaque_up ? m_opaque_up->GetStatus() : lldb::eReturnStatusInvalid); + return ref().GetStatus(); } void SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) { LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetStatus, (lldb::ReturnStatus), status); - if (m_opaque_up) - m_opaque_up->SetStatus(status); + ref().SetStatus(status); } bool SBCommandReturnObject::Succeeded() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, Succeeded); - return (m_opaque_up ? m_opaque_up->Succeeded() : false); + return ref().Succeeded(); } bool SBCommandReturnObject::HasResult() { LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommandReturnObject, HasResult); - return (m_opaque_up ? m_opaque_up->HasResult() : false); + return ref().HasResult(); } void SBCommandReturnObject::AppendMessage(const char *message) { LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendMessage, (const char *), message); - if (m_opaque_up) - m_opaque_up->AppendMessage(message); + ref().AppendMessage(message); } void SBCommandReturnObject::AppendWarning(const char *message) { LLDB_RECORD_METHOD(void, SBCommandReturnObject, AppendWarning, (const char *), message); - if (m_opaque_up) - m_opaque_up->AppendWarning(message); + ref().AppendWarning(message); } CommandReturnObject *SBCommandReturnObject::operator->() const { - return m_opaque_up.get(); + return &**m_opaque_up; } CommandReturnObject *SBCommandReturnObject::get() const { - return m_opaque_up.get(); + return &**m_opaque_up; } CommandReturnObject &SBCommandReturnObject::operator*() const { - assert(m_opaque_up.get()); - return *(m_opaque_up.get()); + return **m_opaque_up; } CommandReturnObject &SBCommandReturnObject::ref() const { - assert(m_opaque_up.get()); - return *(m_opaque_up.get()); -} - -void SBCommandReturnObject::SetLLDBObjectPtr(CommandReturnObject *ptr) { - if (m_opaque_up) - m_opaque_up.reset(ptr); + return **m_opaque_up; } bool SBCommandReturnObject::GetDescription(SBStream &description) { @@ -206,84 +233,99 @@ bool SBCommandReturnObject::GetDescription(SBStream &description) { Stream &strm = description.ref(); - if (m_opaque_up) { - description.Printf("Error: "); - lldb::ReturnStatus status = m_opaque_up->GetStatus(); - if (status == lldb::eReturnStatusStarted) - strm.PutCString("Started"); - else if (status == lldb::eReturnStatusInvalid) - strm.PutCString("Invalid"); - else if (m_opaque_up->Succeeded()) - strm.PutCString("Success"); - else - strm.PutCString("Fail"); - - if (GetOutputSize() > 0) - strm.Printf("\nOutput Message:\n%s", GetOutput()); - - if (GetErrorSize() > 0) - strm.Printf("\nError Message:\n%s", GetError()); - } else - strm.PutCString("No value"); + description.Printf("Error: "); + lldb::ReturnStatus status = ref().GetStatus(); + if (status == lldb::eReturnStatusStarted) + strm.PutCString("Started"); + else if (status == lldb::eReturnStatusInvalid) + strm.PutCString("Invalid"); + else if (ref().Succeeded()) + strm.PutCString("Success"); + else + strm.PutCString("Fail"); + + if (GetOutputSize() > 0) + strm.Printf("\nOutput Message:\n%s", GetOutput()); + + if (GetErrorSize() > 0) + strm.Printf("\nError Message:\n%s", GetError()); return true; } void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh) { - LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, - (FILE *), fh); + LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile, + (FILE *), fh); SetImmediateOutputFile(fh, false); } void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh) { - LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, - (FILE *), fh); + LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile, + (FILE *), fh); SetImmediateErrorFile(fh, false); } void SBCommandReturnObject::SetImmediateOutputFile(FILE *fh, bool transfer_ownership) { - LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, - (FILE *, bool), fh, transfer_ownership); - - if (m_opaque_up) - m_opaque_up->SetImmediateOutputFile(fh, transfer_ownership); + LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateOutputFile, + (FILE *, bool), fh, transfer_ownership); + FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership); + ref().SetImmediateOutputFile(file); } void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh, bool transfer_ownership) { + LLDB_RECORD_DUMMY(void, SBCommandReturnObject, SetImmediateErrorFile, + (FILE *, bool), fh, transfer_ownership); + FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership); + ref().SetImmediateErrorFile(file); +} + +void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) { + LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, + (SBFile), file); + ref().SetImmediateOutputFile(file.m_opaque_sp); +} + +void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) { LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, - (FILE *, bool), fh, transfer_ownership); + (SBFile), file); + ref().SetImmediateErrorFile(file.m_opaque_sp); +} - if (m_opaque_up) - m_opaque_up->SetImmediateErrorFile(fh, transfer_ownership); +void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) { + LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, + (FileSP), file_sp); + SetImmediateOutputFile(SBFile(file_sp)); +} + +void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) { + LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, + (FileSP), file_sp); + SetImmediateErrorFile(SBFile(file_sp)); } void SBCommandReturnObject::PutCString(const char *string, int len) { LLDB_RECORD_METHOD(void, SBCommandReturnObject, PutCString, (const char *, int), string, len); - if (m_opaque_up) { - if (len == 0 || string == nullptr || *string == 0) { - return; - } else if (len > 0) { - std::string buffer(string, len); - m_opaque_up->AppendMessage(buffer.c_str()); - } else - m_opaque_up->AppendMessage(string); - } + if (len == 0 || string == nullptr || *string == 0) { + return; + } else if (len > 0) { + std::string buffer(string, len); + ref().AppendMessage(buffer.c_str()); + } else + ref().AppendMessage(string); } const char *SBCommandReturnObject::GetOutput(bool only_if_no_immediate) { LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetOutput, (bool), only_if_no_immediate); - if (!m_opaque_up) - return nullptr; if (!only_if_no_immediate || - m_opaque_up->GetImmediateOutputStream().get() == nullptr) + ref().GetImmediateOutputStream().get() == nullptr) return GetOutput(); return nullptr; } @@ -292,23 +334,17 @@ const char *SBCommandReturnObject::GetError(bool only_if_no_immediate) { LLDB_RECORD_METHOD(const char *, SBCommandReturnObject, GetError, (bool), only_if_no_immediate); - if (!m_opaque_up) - return nullptr; - if (!only_if_no_immediate || - m_opaque_up->GetImmediateErrorStream().get() == nullptr) + if (!only_if_no_immediate || ref().GetImmediateErrorStream().get() == nullptr) return GetError(); return nullptr; } size_t SBCommandReturnObject::Printf(const char *format, ...) { - if (m_opaque_up) { - va_list args; - va_start(args, format); - size_t result = m_opaque_up->GetOutputStream().PrintfVarArg(format, args); - va_end(args); - return result; - } - return 0; + va_list args; + va_start(args, format); + size_t result = ref().GetOutputStream().PrintfVarArg(format, args); + va_end(args); + return result; } void SBCommandReturnObject::SetError(lldb::SBError &error, @@ -317,20 +353,18 @@ void SBCommandReturnObject::SetError(lldb::SBError &error, (lldb::SBError &, const char *), error, fallback_error_cstr); - if (m_opaque_up) { - if (error.IsValid()) - m_opaque_up->SetError(error.ref(), fallback_error_cstr); - else if (fallback_error_cstr) - m_opaque_up->SetError(Status(), fallback_error_cstr); - } + if (error.IsValid()) + ref().SetError(error.ref(), fallback_error_cstr); + else if (fallback_error_cstr) + ref().SetError(Status(), fallback_error_cstr); } void SBCommandReturnObject::SetError(const char *error_cstr) { LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetError, (const char *), error_cstr); - if (m_opaque_up && error_cstr) - m_opaque_up->SetError(error_cstr); + if (error_cstr) + ref().SetError(error_cstr); } namespace lldb_private { @@ -340,13 +374,11 @@ template <> void RegisterMethods<SBCommandReturnObject>(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, ()); LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, - (const lldb::SBCommandReturnObject &)); + (lldb_private::CommandReturnObject &)); LLDB_REGISTER_CONSTRUCTOR(SBCommandReturnObject, - (lldb_private::CommandReturnObject *)); - LLDB_REGISTER_METHOD(lldb_private::CommandReturnObject *, - SBCommandReturnObject, Release, ()); + (const lldb::SBCommandReturnObject &)); LLDB_REGISTER_METHOD( - const lldb::SBCommandReturnObject &, + lldb::SBCommandReturnObject &, SBCommandReturnObject, operator=,(const lldb::SBCommandReturnObject &)); LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBCommandReturnObject, operator bool, ()); @@ -356,6 +388,10 @@ void RegisterMethods<SBCommandReturnObject>(Registry &R) { LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ()); LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *)); LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *)); + LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile)); + LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile)); + LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP)); + LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP)); LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ()); LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus, ()); @@ -374,6 +410,14 @@ void RegisterMethods<SBCommandReturnObject>(Registry &R) { LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, (FILE *)); LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, + (SBFile)); + LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, + (SBFile)); + LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, + (FileSP)); + LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, + (FileSP)); + LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile, (FILE *, bool)); LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile, (FILE *, bool)); diff --git a/source/API/SBCompileUnit.cpp b/source/API/SBCompileUnit.cpp index c9ca70645d95..581bda363507 100644 --- a/source/API/SBCompileUnit.cpp +++ b/source/API/SBCompileUnit.cpp @@ -14,8 +14,9 @@ #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Type.h" +#include "lldb/Symbol/TypeList.h" using namespace lldb; using namespace lldb_private; @@ -137,13 +138,13 @@ lldb::SBTypeList SBCompileUnit::GetTypes(uint32_t type_mask) { if (!module_sp) return LLDB_RECORD_RESULT(sb_type_list); - SymbolVendor *vendor = module_sp->GetSymbolVendor(); - if (!vendor) + SymbolFile *symfile = module_sp->GetSymbolFile(); + if (!symfile) return LLDB_RECORD_RESULT(sb_type_list); TypeClass type_class = static_cast<TypeClass>(type_mask); TypeList type_list; - vendor->GetTypes(m_opaque_ptr, type_class, type_list); + symfile->GetTypes(m_opaque_ptr, type_class, type_list); sb_type_list.m_opaque_up->Append(type_list); return LLDB_RECORD_RESULT(sb_type_list); } diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp index 634c4a929595..82dc60489008 100644 --- a/source/API/SBDebugger.cpp +++ b/source/API/SBDebugger.cpp @@ -18,6 +18,7 @@ #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" +#include "lldb/API/SBFile.h" #include "lldb/API/SBFrame.h" #include "lldb/API/SBListener.h" #include "lldb/API/SBProcess.h" @@ -57,51 +58,6 @@ using namespace lldb; using namespace lldb_private; -/// Helper class for replaying commands through the reproducer. -class CommandLoader { -public: - CommandLoader(std::vector<std::string> files) : m_files(files) {} - - static std::unique_ptr<CommandLoader> Create() { - repro::Loader *loader = repro::Reproducer::Instance().GetLoader(); - if (!loader) - return {}; - - FileSpec file = loader->GetFile<repro::CommandProvider::Info>(); - if (!file) - return {}; - - auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); - if (auto err = error_or_file.getError()) - return {}; - - std::vector<std::string> files; - llvm::yaml::Input yin((*error_or_file)->getBuffer()); - yin >> files; - - if (auto err = yin.error()) - return {}; - - for (auto &file : files) { - FileSpec absolute_path = - loader->GetRoot().CopyByAppendingPathComponent(file); - file = absolute_path.GetPath(); - } - - return llvm::make_unique<CommandLoader>(std::move(files)); - } - - FILE *GetNextFile() { - if (m_index >= m_files.size()) - return nullptr; - return FileSystem::Instance().Fopen(m_files[m_index++].c_str(), "r"); - } - -private: - std::vector<std::string> m_files; - unsigned m_index = 0; -}; - static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp, const FileSpec &spec, Status &error) { @@ -200,11 +156,9 @@ lldb::SBError SBDebugger::InitializeWithErrorHandling() { LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBError, SBDebugger, InitializeWithErrorHandling); - - SBError error; if (auto e = g_debugger_lifetime->Initialize( - llvm::make_unique<SystemInitializerFull>(), LoadPlugin)) { + std::make_unique<SystemInitializerFull>(), LoadPlugin)) { error.SetError(Status(std::move(e))); } return LLDB_RECORD_RESULT(error); @@ -219,7 +173,6 @@ void SBDebugger::Terminate() { void SBDebugger::Clear() { LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, Clear); - if (m_opaque_sp) m_opaque_sp->ClearIOHandlers(); @@ -260,7 +213,6 @@ SBDebugger SBDebugger::Create(bool source_init_files, debugger.reset(Debugger::CreateInstance(callback, baton)); - SBCommandInterpreter interp = debugger.GetCommandInterpreter(); if (source_init_files) { interp.get()->SkipLLDBInitFiles(false); @@ -278,7 +230,6 @@ void SBDebugger::Destroy(SBDebugger &debugger) { LLDB_RECORD_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &), debugger); - Debugger::Destroy(debugger.m_opaque_sp); if (debugger.m_opaque_sp.get() != nullptr) @@ -335,86 +286,173 @@ void SBDebugger::SkipAppInitFiles(bool b) { m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b); } -// Shouldn't really be settable after initialization as this could cause lots -// of problems; don't want users trying to switch modes in the middle of a -// debugging session. void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) { LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh, transfer_ownership); + SetInputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); +} - if (!m_opaque_sp) - return; +SBError SBDebugger::SetInputFile(FileSP file_sp) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp); + return SetInputFile(SBFile(file_sp)); +} + +// Shouldn't really be settable after initialization as this could cause lots +// of problems; don't want users trying to switch modes in the middle of a +// debugging session. +SBError SBDebugger::SetInputFile(SBFile file) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (SBFile), file); + + SBError error; + if (!m_opaque_sp) { + error.ref().SetErrorString("invalid debugger"); + return error; + } repro::DataRecorder *recorder = nullptr; if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) recorder = g->GetOrCreate<repro::CommandProvider>().GetNewDataRecorder(); - static std::unique_ptr<CommandLoader> loader = CommandLoader::Create(); - if (loader) - fh = loader->GetNextFile(); + FileSP file_sp = file.m_opaque_sp; + + static std::unique_ptr<repro::CommandLoader> loader = + repro::CommandLoader::Create(repro::Reproducer::Instance().GetLoader()); + if (loader) { + llvm::Optional<std::string> nextfile = loader->GetNextFile(); + FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r") + : nullptr; + // FIXME Jonas Devlieghere: shouldn't this error be propagated out to the + // reproducer somehow if fh is NULL? + if (fh) { + file_sp = std::make_shared<NativeFile>(fh, true); + } + } + + if (!file_sp || !file_sp->IsValid()) { + error.ref().SetErrorString("invalid file"); + return error; + } + + m_opaque_sp->SetInputFile(file_sp, recorder); + return error; +} - m_opaque_sp->SetInputFileHandle(fh, transfer_ownership, recorder); +SBError SBDebugger::SetOutputFile(FileSP file_sp) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp); + return SetOutputFile(SBFile(file_sp)); } void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) { LLDB_RECORD_METHOD(void, SBDebugger, SetOutputFileHandle, (FILE *, bool), fh, transfer_ownership); + SetOutputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); +} - if (m_opaque_sp) - m_opaque_sp->SetOutputFileHandle(fh, transfer_ownership); +SBError SBDebugger::SetOutputFile(SBFile file) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (SBFile file), file); + SBError error; + if (!m_opaque_sp) { + error.ref().SetErrorString("invalid debugger"); + return error; + } + if (!file) { + error.ref().SetErrorString("invalid file"); + return error; + } + m_opaque_sp->SetOutputFile(file.m_opaque_sp); + return error; } void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) { LLDB_RECORD_METHOD(void, SBDebugger, SetErrorFileHandle, (FILE *, bool), fh, transfer_ownership); + SetErrorFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); +} +SBError SBDebugger::SetErrorFile(FileSP file_sp) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (FileSP), file_sp); + return SetErrorFile(SBFile(file_sp)); +} - if (m_opaque_sp) - m_opaque_sp->SetErrorFileHandle(fh, transfer_ownership); +SBError SBDebugger::SetErrorFile(SBFile file) { + LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (SBFile file), file); + SBError error; + if (!m_opaque_sp) { + error.ref().SetErrorString("invalid debugger"); + return error; + } + if (!file) { + error.ref().SetErrorString("invalid file"); + return error; + } + m_opaque_sp->SetErrorFile(file.m_opaque_sp); + return error; } FILE *SBDebugger::GetInputFileHandle() { LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle); - if (m_opaque_sp) { - StreamFileSP stream_file_sp(m_opaque_sp->GetInputFile()); - if (stream_file_sp) - return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + File &file_sp = m_opaque_sp->GetInputFile(); + return LLDB_RECORD_RESULT(file_sp.GetStream()); } return nullptr; } +SBFile SBDebugger::GetInputFile() { + LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetInputFile); + if (m_opaque_sp) { + return LLDB_RECORD_RESULT(SBFile(m_opaque_sp->GetInputFileSP())); + } + return LLDB_RECORD_RESULT(SBFile()); +} + FILE *SBDebugger::GetOutputFileHandle() { LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle); - if (m_opaque_sp) { - StreamFileSP stream_file_sp(m_opaque_sp->GetOutputFile()); - if (stream_file_sp) - return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + StreamFile &stream_file = m_opaque_sp->GetOutputStream(); + return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream()); } return nullptr; } +SBFile SBDebugger::GetOutputFile() { + LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetOutputFile); + if (m_opaque_sp) { + SBFile file(m_opaque_sp->GetOutputStream().GetFileSP()); + return LLDB_RECORD_RESULT(file); + } + return LLDB_RECORD_RESULT(SBFile()); +} + FILE *SBDebugger::GetErrorFileHandle() { LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle); if (m_opaque_sp) { - StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile()); - if (stream_file_sp) - return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + StreamFile &stream_file = m_opaque_sp->GetErrorStream(); + return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream()); } return nullptr; } +SBFile SBDebugger::GetErrorFile() { + LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetErrorFile); + SBFile file; + if (m_opaque_sp) { + SBFile file(m_opaque_sp->GetErrorStream().GetFileSP()); + return LLDB_RECORD_RESULT(file); + } + return LLDB_RECORD_RESULT(SBFile()); +} + void SBDebugger::SaveInputTerminalState() { - LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, SaveInputTerminalState); + LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, SaveInputTerminalState); if (m_opaque_sp) m_opaque_sp->SaveInputTerminalState(); } void SBDebugger::RestoreInputTerminalState() { - LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, RestoreInputTerminalState); + LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, RestoreInputTerminalState); if (m_opaque_sp) m_opaque_sp->RestoreInputTerminalState(); @@ -423,12 +461,10 @@ SBCommandInterpreter SBDebugger::GetCommandInterpreter() { LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCommandInterpreter, SBDebugger, GetCommandInterpreter); - SBCommandInterpreter sb_interpreter; if (m_opaque_sp) sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter()); - return LLDB_RECORD_RESULT(sb_interpreter); } @@ -446,10 +482,8 @@ void SBDebugger::HandleCommand(const char *command) { sb_interpreter.HandleCommand(command, result, false); - if (GetErrorFileHandle() != nullptr) - result.PutError(GetErrorFileHandle()); - if (GetOutputFileHandle() != nullptr) - result.PutOutput(GetOutputFileHandle()); + result.PutError(m_opaque_sp->GetErrorStream().GetFileSP()); + result.PutOutput(m_opaque_sp->GetOutputStream().GetFileSP()); if (!m_opaque_sp->GetAsyncExecution()) { SBProcess process(GetCommandInterpreter().GetProcess()); @@ -460,8 +494,7 @@ void SBDebugger::HandleCommand(const char *command) { while (lldb_listener_sp->GetEventForBroadcaster( process_sp.get(), event_sp, std::chrono::seconds(0))) { SBEvent event(event_sp); - HandleProcessEvent(process, event, GetOutputFileHandle(), - GetErrorFileHandle()); + HandleProcessEvent(process, event, GetOutputFile(), GetErrorFile()); } } } @@ -471,16 +504,25 @@ void SBDebugger::HandleCommand(const char *command) { SBListener SBDebugger::GetListener() { LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBDebugger, GetListener); - SBListener sb_listener; if (m_opaque_sp) sb_listener.reset(m_opaque_sp->GetListener()); - return LLDB_RECORD_RESULT(sb_listener); } void SBDebugger::HandleProcessEvent(const SBProcess &process, + const SBEvent &event, SBFile out, + SBFile err) { + LLDB_RECORD_METHOD( + void, SBDebugger, HandleProcessEvent, + (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile), process, + event, out, err); + + return HandleProcessEvent(process, event, out.m_opaque_sp, err.m_opaque_sp); +} + +void SBDebugger::HandleProcessEvent(const SBProcess &process, const SBEvent &event, FILE *out, FILE *err) { LLDB_RECORD_METHOD( @@ -488,6 +530,20 @@ void SBDebugger::HandleProcessEvent(const SBProcess &process, (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *), process, event, out, err); + FileSP outfile = std::make_shared<NativeFile>(out, false); + FileSP errfile = std::make_shared<NativeFile>(err, false); + return HandleProcessEvent(process, event, outfile, errfile); +} + +void SBDebugger::HandleProcessEvent(const SBProcess &process, + const SBEvent &event, FileSP out_sp, + FileSP err_sp) { + + LLDB_RECORD_METHOD( + void, SBDebugger, HandleProcessEvent, + (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP), process, + event, out_sp, err_sp); + if (!process.IsValid()) return; @@ -505,16 +561,16 @@ void SBDebugger::HandleProcessEvent(const SBProcess &process, (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) { // Drain stdout when we stop just in case we have any bytes while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0) - if (out != nullptr) - ::fwrite(stdio_buffer, 1, len, out); + if (out_sp) + out_sp->Write(stdio_buffer, len); } if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) { // Drain stderr when we stop just in case we have any bytes while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0) - if (err != nullptr) - ::fwrite(stdio_buffer, 1, len, err); + if (err_sp) + err_sp->Write(stdio_buffer, len); } if (event_type & Process::eBroadcastBitStateChanged) { @@ -525,7 +581,7 @@ void SBDebugger::HandleProcessEvent(const SBProcess &process, bool is_stopped = StateIsStoppedState(event_state); if (!is_stopped) - process.ReportEventState(event, out); + process.ReportEventState(event, out_sp); } } @@ -578,7 +634,8 @@ SBDebugger::GetScriptingLanguage(const char *script_language_name) { LLDB_RECORD_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage, (const char *), script_language_name); - if (!script_language_name) return eScriptLanguageDefault; + if (!script_language_name) + return eScriptLanguageDefault; return OptionArgParser::ToScriptLanguage( llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr); } @@ -599,18 +656,18 @@ const char *SBDebugger::StateAsCString(StateType state) { static void AddBoolConfigEntry(StructuredData::Dictionary &dict, llvm::StringRef name, bool value, llvm::StringRef description) { - auto entry_up = llvm::make_unique<StructuredData::Dictionary>(); + auto entry_up = std::make_unique<StructuredData::Dictionary>(); entry_up->AddBooleanItem("value", value); entry_up->AddStringItem("description", description); dict.AddItem(name, std::move(entry_up)); } static void AddLLVMTargets(StructuredData::Dictionary &dict) { - auto array_up = llvm::make_unique<StructuredData::Array>(); + auto array_up = std::make_unique<StructuredData::Array>(); #define LLVM_TARGET(target) \ - array_up->AddItem(llvm::make_unique<StructuredData::String>(#target)); + array_up->AddItem(std::make_unique<StructuredData::String>(#target)); #include "llvm/Config/Targets.def" - auto entry_up = llvm::make_unique<StructuredData::Dictionary>(); + auto entry_up = std::make_unique<StructuredData::Dictionary>(); entry_up->AddItem("value", std::move(array_up)); entry_up->AddStringItem("description", "A list of configured LLVM targets."); dict.AddItem("targets", std::move(entry_up)); @@ -620,10 +677,17 @@ SBStructuredData SBDebugger::GetBuildConfiguration() { LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBStructuredData, SBDebugger, GetBuildConfiguration); - auto config_up = llvm::make_unique<StructuredData::Dictionary>(); + auto config_up = std::make_unique<StructuredData::Dictionary>(); AddBoolConfigEntry( *config_up, "xml", XMLDocument::XMLEnabled(), "A boolean value that indicates if XML support is enabled in LLDB"); + bool have_curses = true; +#ifdef LLDB_DISABLE_CURSES + have_curses = false; +#endif + AddBoolConfigEntry( + *config_up, "curses", have_curses, + "A boolean value that indicates if curses support is enabled in LLDB"); AddLLVMTargets(*config_up); SBStructuredData data; @@ -635,7 +699,6 @@ bool SBDebugger::StateIsRunningState(StateType state) { LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsRunningState, (lldb::StateType), state); - const bool result = lldb_private::StateIsRunningState(state); return result; @@ -645,7 +708,6 @@ bool SBDebugger::StateIsStoppedState(StateType state) { LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState, (lldb::StateType), state); - const bool result = lldb_private::StateIsStoppedState(state, false); return result; @@ -680,13 +742,13 @@ lldb::SBTarget SBDebugger::CreateTarget(const char *filename, } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " - "platform_name=%s, add_dependent_modules=%u, error=%s) => " - "SBTarget(%p)", - static_cast<void *>(m_opaque_sp.get()), filename, target_triple, - platform_name, add_dependent_modules, sb_error.GetCString(), - static_cast<void *>(target_sp.get())); + LLDB_LOGF(log, + "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " + "platform_name=%s, add_dependent_modules=%u, error=%s) => " + "SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, target_triple, + platform_name, add_dependent_modules, sb_error.GetCString(), + static_cast<void *>(target_sp.get())); return LLDB_RECORD_RESULT(sb_target); } @@ -710,11 +772,11 @@ SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " - "(filename=\"%s\", triple=%s) => SBTarget(%p)", - static_cast<void *>(m_opaque_sp.get()), filename, target_triple, - static_cast<void *>(target_sp.get())); + LLDB_LOGF(log, + "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " + "(filename=\"%s\", triple=%s) => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, target_triple, + static_cast<void *>(target_sp.get())); return LLDB_RECORD_RESULT(sb_target); } @@ -743,11 +805,11 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, } } - if (log) - log->Printf("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " - "arch=%s) => SBTarget(%p)", - static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr, - static_cast<void *>(target_sp.get())); + LLDB_LOGF(log, + "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " + "arch=%s) => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr, + static_cast<void *>(target_sp.get())); return LLDB_RECORD_RESULT(sb_target); } @@ -772,11 +834,10 @@ SBTarget SBDebugger::CreateTarget(const char *filename) { } } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf( - "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", - static_cast<void *>(m_opaque_sp.get()), filename, - static_cast<void *>(target_sp.get())); + LLDB_LOGF(log, + "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), filename, + static_cast<void *>(target_sp.get())); return LLDB_RECORD_RESULT(sb_target); } @@ -785,14 +846,12 @@ SBTarget SBDebugger::GetDummyTarget() { SBTarget sb_target; if (m_opaque_sp) { - sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this()); + sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this()); } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf( - "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", - static_cast<void *>(m_opaque_sp.get()), - static_cast<void *>(sb_target.GetSP().get())); + LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(sb_target.GetSP().get())); return LLDB_RECORD_RESULT(sb_target); } @@ -814,10 +873,9 @@ bool SBDebugger::DeleteTarget(lldb::SBTarget &target) { } Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", - static_cast<void *>(m_opaque_sp.get()), - static_cast<void *>(target.m_opaque_sp.get()), result); + LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(target.m_opaque_sp.get()), result); return result; } @@ -914,9 +972,9 @@ SBTarget SBDebugger::GetSelectedTarget() { if (log) { SBStream sstr; sb_target.GetDescription(sstr, eDescriptionLevelBrief); - log->Printf("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", - static_cast<void *>(m_opaque_sp.get()), - static_cast<void *>(target_sp.get()), sstr.GetData()); + LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(target_sp.get()), sstr.GetData()); } return LLDB_RECORD_RESULT(sb_target); @@ -935,9 +993,9 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { if (log) { SBStream sstr; sb_target.GetDescription(sstr, eDescriptionLevelBrief); - log->Printf("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", - static_cast<void *>(m_opaque_sp.get()), - static_cast<void *>(target_sp.get()), sstr.GetData()); + LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(target_sp.get()), sstr.GetData()); } } @@ -951,11 +1009,10 @@ SBPlatform SBDebugger::GetSelectedPlatform() { if (debugger_sp) { sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); } - if (log) - log->Printf("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", - static_cast<void *>(m_opaque_sp.get()), - static_cast<void *>(sb_platform.GetSP().get()), - sb_platform.GetName()); + LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(sb_platform.GetSP().get()), + sb_platform.GetName()); return LLDB_RECORD_RESULT(sb_platform); } @@ -970,11 +1027,10 @@ void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); } - if (log) - log->Printf("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", - static_cast<void *>(m_opaque_sp.get()), - static_cast<void *>(sb_platform.GetSP().get()), - sb_platform.GetName()); + LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", + static_cast<void *>(m_opaque_sp.get()), + static_cast<void *>(sb_platform.GetSP().get()), + sb_platform.GetName()); } uint32_t SBDebugger::GetNumPlatforms() { @@ -1018,7 +1074,7 @@ SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) { GetAvailablePlatformInfoAtIndex, (uint32_t), idx); SBStructuredData data; - auto platform_dict = llvm::make_unique<StructuredData::Dictionary>(); + auto platform_dict = std::make_unique<StructuredData::Dictionary>(); llvm::StringRef name_str("name"), desc_str("description"); if (idx == 0) { @@ -1062,7 +1118,7 @@ void SBDebugger::DispatchInput(const void *data, size_t data_len) { // Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); // // if (log) - // log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", + // LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\", // size_t=%" PRIu64 ")", // m_opaque_sp.get(), // (int) data_len, @@ -1074,7 +1130,7 @@ void SBDebugger::DispatchInput(const void *data, size_t data_len) { } void SBDebugger::DispatchInputInterrupt() { - LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputInterrupt); + LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, DispatchInputInterrupt); if (m_opaque_sp) m_opaque_sp->DispatchInputInterrupt(); @@ -1234,8 +1290,7 @@ uint32_t SBDebugger::GetTerminalWidth() const { } void SBDebugger::SetTerminalWidth(uint32_t term_width) { - LLDB_RECORD_METHOD(void, SBDebugger, SetTerminalWidth, (uint32_t), - term_width); + LLDB_RECORD_DUMMY(void, SBDebugger, SetTerminalWidth, (uint32_t), term_width); if (m_opaque_sp) m_opaque_sp->SetTerminalWidth(term_width); @@ -1246,10 +1301,9 @@ const char *SBDebugger::GetPrompt() const { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf("SBDebugger(%p)::GetPrompt () => \"%s\"", - static_cast<void *>(m_opaque_sp.get()), - (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : "")); + LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"", + static_cast<void *>(m_opaque_sp.get()), + (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : "")); return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString() : nullptr); @@ -1374,7 +1428,8 @@ bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) { if (platform_sp) { if (log && sysroot) - log->Printf("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot); + LLDB_LOGF(log, "SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", + sysroot); platform_sp->SetSDKRootDirectory(ConstString(sysroot)); return true; } @@ -1549,8 +1604,7 @@ void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, namespace lldb_private { namespace repro { -template <> -void RegisterMethods<SBInputReader>(Registry &R) { +template <> void RegisterMethods<SBInputReader>(Registry &R) { LLDB_REGISTER_METHOD(void, SBInputReader, SetIsDone, (bool)); LLDB_REGISTER_METHOD_CONST(bool, SBInputReader, IsActive, ()); } @@ -1559,6 +1613,10 @@ static void SetFileHandleRedirect(SBDebugger *, FILE *, bool) { // Do nothing. } +static SBError SetFileRedirect(SBDebugger *, SBFile file) { return SBError(); } + +static SBError SetFileRedirect(SBDebugger *, FileSP file) { return SBError(); } + static bool GetDefaultArchitectureRedirect(char *arch_name, size_t arch_name_len) { // The function is writing to its argument. Without the redirect it would @@ -1567,8 +1625,7 @@ static bool GetDefaultArchitectureRedirect(char *arch_name, return SBDebugger::GetDefaultArchitecture(buffer, arch_name_len); } -template <> -void RegisterMethods<SBDebugger>(Registry &R) { +template <> void RegisterMethods<SBDebugger>(Registry &R) { // Custom implementation. R.Register(&invoke<void (SBDebugger::*)( FILE *, bool)>::method<&SBDebugger::SetErrorFileHandle>::doit, @@ -1580,6 +1637,26 @@ void RegisterMethods<SBDebugger>(Registry &R) { &SBDebugger::GetDefaultArchitecture), &GetDefaultArchitectureRedirect); + R.Register(&invoke<SBError (SBDebugger::*)( + SBFile)>::method<&SBDebugger::SetInputFile>::doit, + &SetFileRedirect); + R.Register(&invoke<SBError (SBDebugger::*)( + SBFile)>::method<&SBDebugger::SetOutputFile>::doit, + &SetFileRedirect); + R.Register(&invoke<SBError (SBDebugger::*)( + SBFile)>::method<&SBDebugger::SetErrorFile>::doit, + &SetFileRedirect); + + R.Register(&invoke<SBError (SBDebugger::*)( + FileSP)>::method<&SBDebugger::SetInputFile>::doit, + &SetFileRedirect); + R.Register(&invoke<SBError (SBDebugger::*)( + FileSP)>::method<&SBDebugger::SetOutputFile>::doit, + &SetFileRedirect); + R.Register(&invoke<SBError (SBDebugger::*)( + FileSP)>::method<&SBDebugger::SetErrorFile>::doit, + &SetFileRedirect); + LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ()); LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &)); LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &)); @@ -1592,11 +1669,10 @@ void RegisterMethods<SBDebugger>(Registry &R) { LLDB_REGISTER_METHOD(void, SBDebugger, Clear, ()); LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, ()); LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool)); - LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, - (lldb::SBDebugger &)); + LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &)); LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, MemoryPressureDetected, ()); LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, IsValid, ()); - LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool,()); LLDB_REGISTER_METHOD(void, SBDebugger, SetAsync, (bool)); LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ()); LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool)); @@ -1605,6 +1681,9 @@ void RegisterMethods<SBDebugger>(Registry &R) { LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ()); LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ()); LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetErrorFileHandle, ()); + LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetInputFile, ()); + LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetOutputFile, ()); + LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetErrorFile, ()); LLDB_REGISTER_METHOD(void, SBDebugger, SaveInputTerminalState, ()); LLDB_REGISTER_METHOD(void, SBDebugger, RestoreInputTerminalState, ()); LLDB_REGISTER_METHOD(lldb::SBCommandInterpreter, SBDebugger, @@ -1614,8 +1693,13 @@ void RegisterMethods<SBDebugger>(Registry &R) { LLDB_REGISTER_METHOD( void, SBDebugger, HandleProcessEvent, (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *)); - LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager, - ()); + LLDB_REGISTER_METHOD( + void, SBDebugger, HandleProcessEvent, + (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile)); + LLDB_REGISTER_METHOD( + void, SBDebugger, HandleProcessEvent, + (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP)); + LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager, ()); LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture, (const char *)); LLDB_REGISTER_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage, @@ -1635,8 +1719,7 @@ void RegisterMethods<SBDebugger>(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndTargetTriple, (const char *, const char *)); - LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, - CreateTargetWithFileAndArch, + LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch, (const char *, const char *)); LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTarget, (const char *)); @@ -1652,8 +1735,7 @@ void RegisterMethods<SBDebugger>(Registry &R) { (const char *, const char *)); LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumTargets, ()); LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetSelectedTarget, ()); - LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget, - (lldb::SBTarget &)); + LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &)); LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetSelectedPlatform, ()); LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedPlatform, (lldb::SBPlatform &)); @@ -1673,8 +1755,8 @@ void RegisterMethods<SBDebugger>(Registry &R) { int &, bool &, bool &)); LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, RunREPL, (lldb::LanguageType, const char *)); - LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, - FindDebuggerWithID, (int)); + LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID, + (int)); LLDB_REGISTER_METHOD(const char *, SBDebugger, GetInstanceName, ()); LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable, (const char *, const char *, const char *)); @@ -1726,5 +1808,5 @@ void RegisterMethods<SBDebugger>(Registry &R) { (const char *, const char **)); } -} -} +} // namespace repro +} // namespace lldb_private diff --git a/source/API/SBDeclaration.cpp b/source/API/SBDeclaration.cpp index a7790b293981..50db1770c612 100644 --- a/source/API/SBDeclaration.cpp +++ b/source/API/SBDeclaration.cpp @@ -32,7 +32,7 @@ SBDeclaration::SBDeclaration(const SBDeclaration &rhs) : m_opaque_up() { SBDeclaration::SBDeclaration(const lldb_private::Declaration *lldb_object_ptr) : m_opaque_up() { if (lldb_object_ptr) - m_opaque_up = llvm::make_unique<Declaration>(*lldb_object_ptr); + m_opaque_up = std::make_unique<Declaration>(*lldb_object_ptr); } const SBDeclaration &SBDeclaration::operator=(const SBDeclaration &rhs) { diff --git a/source/API/SBFile.cpp b/source/API/SBFile.cpp new file mode 100644 index 000000000000..f5a38efe4a77 --- /dev/null +++ b/source/API/SBFile.cpp @@ -0,0 +1,129 @@ +//===-- SBFile.cpp ------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBFile.h" +#include "SBReproducerPrivate.h" +#include "lldb/API/SBError.h" +#include "lldb/Host/File.h" + +using namespace lldb; +using namespace lldb_private; + +SBFile::~SBFile() {} + +SBFile::SBFile(FileSP file_sp) : m_opaque_sp(file_sp) { + LLDB_RECORD_DUMMY(void, SBfile, SBFile, (FileSP), file_sp); +} + +SBFile::SBFile() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFile); } + +SBFile::SBFile(FILE *file, bool transfer_ownership) { + LLDB_RECORD_DUMMY(void, SBFile, (FILE *, bool), file, transfer_ownership); + m_opaque_sp = std::make_shared<NativeFile>(file, transfer_ownership); +} + +SBFile::SBFile(int fd, const char *mode, bool transfer_owndership) { + LLDB_RECORD_DUMMY(void, SBFile, (int, const char *, bool), fd, mode, + transfer_owndership); + auto options = File::GetOptionsFromMode(mode); + if (!options) { + llvm::consumeError(options.takeError()); + return; + } + m_opaque_sp = + std::make_shared<NativeFile>(fd, options.get(), transfer_owndership); +} + +SBError SBFile::Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read) { + LLDB_RECORD_DUMMY(lldb::SBError, SBFile, Read, (uint8_t *, size_t, size_t *), + buf, num_bytes, bytes_read); + SBError error; + if (!m_opaque_sp) { + error.SetErrorString("invalid SBFile"); + *bytes_read = 0; + } else { + Status status = m_opaque_sp->Read(buf, num_bytes); + error.SetError(status); + *bytes_read = num_bytes; + } + return LLDB_RECORD_RESULT(error); +} + +SBError SBFile::Write(const uint8_t *buf, size_t num_bytes, + size_t *bytes_written) { + LLDB_RECORD_DUMMY(lldb::SBError, SBFile, Write, + (const uint8_t *, size_t, size_t *), buf, num_bytes, + bytes_written); + SBError error; + if (!m_opaque_sp) { + error.SetErrorString("invalid SBFile"); + *bytes_written = 0; + } else { + Status status = m_opaque_sp->Write(buf, num_bytes); + error.SetError(status); + *bytes_written = num_bytes; + } + return LLDB_RECORD_RESULT(error); +} + +SBError SBFile::Flush() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBFile, Flush); + SBError error; + if (!m_opaque_sp) { + error.SetErrorString("invalid SBFile"); + } else { + Status status = m_opaque_sp->Flush(); + error.SetError(status); + } + return LLDB_RECORD_RESULT(error); +} + +bool SBFile::IsValid() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFile, IsValid); + return m_opaque_sp && m_opaque_sp->IsValid(); +} + +SBError SBFile::Close() { + LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBFile, Close); + SBError error; + if (m_opaque_sp) { + Status status = m_opaque_sp->Close(); + error.SetError(status); + } + return LLDB_RECORD_RESULT(error); +} + +SBFile::operator bool() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFile, operator bool); + return LLDB_RECORD_RESULT(IsValid()); +} + +bool SBFile::operator!() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFile, operator!); + return LLDB_RECORD_RESULT(!IsValid()); +} + +FileSP SBFile::GetFile() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(FileSP, SBFile, GetFile); + return m_opaque_sp; +} + +namespace lldb_private { +namespace repro { + +template <> void RegisterMethods<SBFile>(Registry &R) { + + LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Flush, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBFile, IsValid, ()); + LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator bool,()); + LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator!,()); + LLDB_REGISTER_METHOD_CONST(FileSP, SBFile, GetFile, ()); + LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Close, ()); +} +} // namespace repro +} // namespace lldb_private diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp index 9268f0f9bdbf..c0e272e1bcd4 100644 --- a/source/API/SBFrame.cpp +++ b/source/API/SBFrame.cpp @@ -1107,7 +1107,7 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, if (target->GetDisplayExpressionsInCrashlogs()) { StreamString frame_description; frame->DumpUsingSettingsFormat(&frame_description); - stack_trace = llvm::make_unique<llvm::PrettyStackTraceFormat>( + stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>( "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value " "= %u) %s", expr, options.GetFetchDynamicValue(), @@ -1120,10 +1120,10 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, } } - if (expr_log) - expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is " - "%s, summary %s **", - expr_result.GetValue(), expr_result.GetSummary()); + LLDB_LOGF(expr_log, + "** [SBFrame::EvaluateExpression] Expression result is " + "%s, summary %s **", + expr_result.GetValue(), expr_result.GetSummary()); return LLDB_RECORD_RESULT(expr_result); } diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp index fcf66fd25824..a9ef9fb59d24 100644 --- a/source/API/SBInstruction.cpp +++ b/source/API/SBInstruction.cpp @@ -11,6 +11,7 @@ #include "lldb/API/SBAddress.h" #include "lldb/API/SBFrame.h" +#include "lldb/API/SBFile.h" #include "lldb/API/SBInstruction.h" #include "lldb/API/SBStream.h" @@ -255,10 +256,21 @@ bool SBInstruction::GetDescription(lldb::SBStream &s) { return false; } -void SBInstruction::Print(FILE *out) { - LLDB_RECORD_METHOD(void, SBInstruction, Print, (FILE *), out); +void SBInstruction::Print(FILE *outp) { + LLDB_RECORD_METHOD(void, SBInstruction, Print, (FILE *), outp); + FileSP out = std::make_shared<NativeFile>(outp, /*take_ownership=*/false); + Print(out); +} + +void SBInstruction::Print(SBFile out) { + LLDB_RECORD_METHOD(void, SBInstruction, Print, (SBFile), out); + Print(out.m_opaque_sp); +} + +void SBInstruction::Print(FileSP out_sp) { + LLDB_RECORD_METHOD(void, SBInstruction, Print, (FileSP), out_sp); - if (out == nullptr) + if (!out_sp || !out_sp->IsValid()) return; lldb::InstructionSP inst_sp(GetOpaque()); @@ -269,7 +281,7 @@ void SBInstruction::Print(FILE *out) { if (module_sp) module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); - StreamFile out_stream(out, false); + StreamFile out_stream(out_sp); FormatEntity::Entry format; FormatEntity::Parse("${addr}: ", format); inst_sp->Dump(&out_stream, 0, true, false, nullptr, &sc, nullptr, &format, @@ -358,6 +370,8 @@ void RegisterMethods<SBInstruction>(Registry &R) { LLDB_REGISTER_METHOD(bool, SBInstruction, GetDescription, (lldb::SBStream &)); LLDB_REGISTER_METHOD(void, SBInstruction, Print, (FILE *)); + LLDB_REGISTER_METHOD(void, SBInstruction, Print, (SBFile)); + LLDB_REGISTER_METHOD(void, SBInstruction, Print, (FileSP)); LLDB_REGISTER_METHOD(bool, SBInstruction, EmulateWithFrame, (lldb::SBFrame &, uint32_t)); LLDB_REGISTER_METHOD(bool, SBInstruction, DumpEmulation, (const char *)); diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp index cce923bf04a4..8b3855c0883b 100644 --- a/source/API/SBInstructionList.cpp +++ b/source/API/SBInstructionList.cpp @@ -11,8 +11,10 @@ #include "lldb/API/SBAddress.h" #include "lldb/API/SBInstruction.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBFile.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" +#include "lldb/Core/StreamFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Utility/Stream.h" @@ -118,21 +120,41 @@ void SBInstructionList::SetDisassembler(const lldb::DisassemblerSP &opaque_sp) { void SBInstructionList::Print(FILE *out) { LLDB_RECORD_METHOD(void, SBInstructionList, Print, (FILE *), out); - if (out == nullptr) return; + StreamFile stream(out, false); + GetDescription(stream); } -bool SBInstructionList::GetDescription(lldb::SBStream &description) { +void SBInstructionList::Print(SBFile out) { + LLDB_RECORD_METHOD(void, SBInstructionList, Print, (SBFile), out); + if (!out.IsValid()) + return; + StreamFile stream(out.m_opaque_sp); + GetDescription(stream); +} + +void SBInstructionList::Print(FileSP out_sp) { + LLDB_RECORD_METHOD(void, SBInstructionList, Print, (FileSP), out_sp); + if (!out_sp || !out_sp->IsValid()) + return; + StreamFile stream(out_sp); + GetDescription(stream); +} + +bool SBInstructionList::GetDescription(lldb::SBStream &stream) { LLDB_RECORD_METHOD(bool, SBInstructionList, GetDescription, - (lldb::SBStream &), description); + (lldb::SBStream &), stream); + return GetDescription(stream.ref()); +} + +bool SBInstructionList::GetDescription(Stream &sref) { if (m_opaque_sp) { size_t num_instructions = GetSize(); if (num_instructions) { // Call the ref() to make sure a stream is created if one deesn't exist // already inside description... - Stream &sref = description.ref(); const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize(); FormatEntity::Entry format; @@ -200,6 +222,8 @@ void RegisterMethods<SBInstructionList>(Registry &R) { LLDB_REGISTER_METHOD(void, SBInstructionList, AppendInstruction, (lldb::SBInstruction)); LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (FILE *)); + LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (SBFile)); + LLDB_REGISTER_METHOD(void, SBInstructionList, Print, (FileSP)); LLDB_REGISTER_METHOD(bool, SBInstructionList, GetDescription, (lldb::SBStream &)); LLDB_REGISTER_METHOD(bool, SBInstructionList, diff --git a/source/API/SBLineEntry.cpp b/source/API/SBLineEntry.cpp index 010a6057cd31..66884f763398 100644 --- a/source/API/SBLineEntry.cpp +++ b/source/API/SBLineEntry.cpp @@ -32,7 +32,7 @@ SBLineEntry::SBLineEntry(const SBLineEntry &rhs) : m_opaque_up() { SBLineEntry::SBLineEntry(const lldb_private::LineEntry *lldb_object_ptr) : m_opaque_up() { if (lldb_object_ptr) - m_opaque_up = llvm::make_unique<LineEntry>(*lldb_object_ptr); + m_opaque_up = std::make_unique<LineEntry>(*lldb_object_ptr); } const SBLineEntry &SBLineEntry::operator=(const SBLineEntry &rhs) { @@ -45,7 +45,7 @@ const SBLineEntry &SBLineEntry::operator=(const SBLineEntry &rhs) { } void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) { - m_opaque_up = llvm::make_unique<LineEntry>(lldb_object_ref); + m_opaque_up = std::make_unique<LineEntry>(lldb_object_ref); } SBLineEntry::~SBLineEntry() {} diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp index 4bd32bce1c53..6cc6d2628ace 100644 --- a/source/API/SBModule.cpp +++ b/source/API/SBModule.cpp @@ -20,7 +20,6 @@ #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Symtab.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/VariableList.h" @@ -283,18 +282,14 @@ SBSymbolContextList SBModule::FindCompileUnits(const SBFileSpec &sb_file_spec) { SBSymbolContextList sb_sc_list; const ModuleSP module_sp(GetSP()); if (sb_file_spec.IsValid() && module_sp) { - const bool append = true; - module_sp->FindCompileUnits(*sb_file_spec, append, *sb_sc_list); + module_sp->FindCompileUnits(*sb_file_spec, *sb_sc_list); } return LLDB_RECORD_RESULT(sb_sc_list); } static Symtab *GetUnifiedSymbolTable(const lldb::ModuleSP &module_sp) { - if (module_sp) { - SymbolVendor *symbols = module_sp->GetSymbolVendor(); - if (symbols) - return symbols->GetSymtab(); - } + if (module_sp) + return module_sp->GetSymtab(); return nullptr; } @@ -302,11 +297,8 @@ size_t SBModule::GetNumSymbols() { LLDB_RECORD_METHOD_NO_ARGS(size_t, SBModule, GetNumSymbols); ModuleSP module_sp(GetSP()); - if (module_sp) { - Symtab *symtab = GetUnifiedSymbolTable(module_sp); - if (symtab) - return symtab->GetNumSymbols(); - } + if (Symtab *symtab = GetUnifiedSymbolTable(module_sp)) + return symtab->GetNumSymbols(); return 0; } @@ -349,8 +341,9 @@ lldb::SBSymbolContextList SBModule::FindSymbols(const char *name, Symtab *symtab = GetUnifiedSymbolTable(module_sp); if (symtab) { std::vector<uint32_t> matching_symbol_indexes; - const size_t num_matches = symtab->FindAllSymbolsWithNameAndType( - ConstString(name), symbol_type, matching_symbol_indexes); + symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, + matching_symbol_indexes); + const size_t num_matches = matching_symbol_indexes.size(); if (num_matches) { SymbolContext sc; sc.module_sp = module_sp; @@ -372,7 +365,7 @@ size_t SBModule::GetNumSections() { ModuleSP module_sp(GetSP()); if (module_sp) { // Give the symbol vendor a chance to add to the unified section list. - module_sp->GetSymbolVendor(); + module_sp->GetSymbolFile(); SectionList *section_list = module_sp->GetSectionList(); if (section_list) return section_list->GetSize(); @@ -388,7 +381,7 @@ SBSection SBModule::GetSectionAtIndex(size_t idx) { ModuleSP module_sp(GetSP()); if (module_sp) { // Give the symbol vendor a chance to add to the unified section list. - module_sp->GetSymbolVendor(); + module_sp->GetSymbolFile(); SectionList *section_list = module_sp->GetSectionList(); if (section_list) @@ -405,12 +398,11 @@ lldb::SBSymbolContextList SBModule::FindFunctions(const char *name, lldb::SBSymbolContextList sb_sc_list; ModuleSP module_sp(GetSP()); if (name && module_sp) { - const bool append = true; const bool symbols_ok = true; const bool inlines_ok = true; FunctionNameType type = static_cast<FunctionNameType>(name_type_mask); module_sp->FindFunctions(ConstString(name), nullptr, type, symbols_ok, - inlines_ok, append, *sb_sc_list); + inlines_ok, *sb_sc_list); } return LLDB_RECORD_RESULT(sb_sc_list); } @@ -425,9 +417,9 @@ SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name, ModuleSP module_sp(GetSP()); if (name && module_sp) { VariableList variable_list; - const uint32_t match_count = module_sp->FindGlobalVariables( - ConstString(name), nullptr, max_matches, variable_list); - + module_sp->FindGlobalVariables(ConstString(name), nullptr, max_matches, + variable_list); + const uint32_t match_count = variable_list.GetSize(); if (match_count > 0) { for (uint32_t i = 0; i < match_count; ++i) { lldb::ValueObjectSP valobj_sp; @@ -468,10 +460,13 @@ lldb::SBType SBModule::FindFirstType(const char *name_cstr) { sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match)); if (!sb_type.IsValid()) { - TypeSystem *type_system = + auto type_system_or_err = module_sp->GetTypeSystemForLanguage(eLanguageTypeC); - if (type_system) - sb_type = SBType(type_system->GetBuiltinTypeByName(name)); + if (auto err = type_system_or_err.takeError()) { + llvm::consumeError(std::move(err)); + return LLDB_RECORD_RESULT(SBType()); + } + sb_type = SBType(type_system_or_err->GetBuiltinTypeByName(name)); } } return LLDB_RECORD_RESULT(sb_type); @@ -483,10 +478,14 @@ lldb::SBType SBModule::GetBasicType(lldb::BasicType type) { ModuleSP module_sp(GetSP()); if (module_sp) { - TypeSystem *type_system = + auto type_system_or_err = module_sp->GetTypeSystemForLanguage(eLanguageTypeC); - if (type_system) - return LLDB_RECORD_RESULT(SBType(type_system->GetBasicTypeFromAST(type))); + if (auto err = type_system_or_err.takeError()) { + llvm::consumeError(std::move(err)); + } else { + return LLDB_RECORD_RESULT( + SBType(type_system_or_err->GetBasicTypeFromAST(type))); + } } return LLDB_RECORD_RESULT(SBType()); } @@ -503,26 +502,28 @@ lldb::SBTypeList SBModule::FindTypes(const char *type) { const bool exact_match = false; ConstString name(type); llvm::DenseSet<SymbolFile *> searched_symbol_files; - const uint32_t num_matches = module_sp->FindTypes( - name, exact_match, UINT32_MAX, searched_symbol_files, type_list); + module_sp->FindTypes(name, exact_match, UINT32_MAX, searched_symbol_files, + type_list); - if (num_matches > 0) { - for (size_t idx = 0; idx < num_matches; idx++) { - TypeSP type_sp(type_list.GetTypeAtIndex(idx)); - if (type_sp) - retval.Append(SBType(type_sp)); - } - } else { - TypeSystem *type_system = + if (type_list.Empty()) { + auto type_system_or_err = module_sp->GetTypeSystemForLanguage(eLanguageTypeC); - if (type_system) { - CompilerType compiler_type = type_system->GetBuiltinTypeByName(name); + if (auto err = type_system_or_err.takeError()) { + llvm::consumeError(std::move(err)); + } else { + CompilerType compiler_type = + type_system_or_err->GetBuiltinTypeByName(name); if (compiler_type) retval.Append(SBType(compiler_type)); } + } else { + for (size_t idx = 0; idx < type_list.GetSize(); idx++) { + TypeSP type_sp(type_list.GetTypeAtIndex(idx)); + if (type_sp) + retval.Append(SBType(type_sp)); + } } } - return LLDB_RECORD_RESULT(retval); } @@ -532,9 +533,8 @@ lldb::SBType SBModule::GetTypeByID(lldb::user_id_t uid) { ModuleSP module_sp(GetSP()); if (module_sp) { - SymbolVendor *vendor = module_sp->GetSymbolVendor(); - if (vendor) { - Type *type_ptr = vendor->ResolveTypeUID(uid); + if (SymbolFile *symfile = module_sp->GetSymbolFile()) { + Type *type_ptr = symfile->ResolveTypeUID(uid); if (type_ptr) return LLDB_RECORD_RESULT(SBType(type_ptr->shared_from_this())); } @@ -551,13 +551,13 @@ lldb::SBTypeList SBModule::GetTypes(uint32_t type_mask) { ModuleSP module_sp(GetSP()); if (!module_sp) return LLDB_RECORD_RESULT(sb_type_list); - SymbolVendor *vendor = module_sp->GetSymbolVendor(); - if (!vendor) + SymbolFile *symfile = module_sp->GetSymbolFile(); + if (!symfile) return LLDB_RECORD_RESULT(sb_type_list); TypeClass type_class = static_cast<TypeClass>(type_mask); TypeList type_list; - vendor->GetTypes(nullptr, type_class, type_list); + symfile->GetTypes(nullptr, type_class, type_list); sb_type_list.m_opaque_up->Append(type_list); return LLDB_RECORD_RESULT(sb_type_list); } @@ -571,7 +571,7 @@ SBSection SBModule::FindSection(const char *sect_name) { ModuleSP module_sp(GetSP()); if (sect_name && module_sp) { // Give the symbol vendor a chance to add to the unified section list. - module_sp->GetSymbolVendor(); + module_sp->GetSymbolFile(); SectionList *section_list = module_sp->GetSectionList(); if (section_list) { ConstString const_sect_name(sect_name); @@ -653,9 +653,8 @@ lldb::SBFileSpec SBModule::GetSymbolFileSpec() const { lldb::SBFileSpec sb_file_spec; ModuleSP module_sp(GetSP()); if (module_sp) { - SymbolVendor *symbol_vendor_ptr = module_sp->GetSymbolVendor(); - if (symbol_vendor_ptr) - sb_file_spec.SetFileSpec(symbol_vendor_ptr->GetMainFileSpec()); + if (SymbolFile *symfile = module_sp->GetSymbolFile()) + sb_file_spec.SetFileSpec(symfile->GetObjectFile()->GetFileSpec()); } return LLDB_RECORD_RESULT(sb_file_spec); } diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp index 4226ff77ecdc..45aaa0bd2d8a 100644 --- a/source/API/SBProcess.cpp +++ b/source/API/SBProcess.cpp @@ -29,11 +29,11 @@ #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" - #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBEvent.h" +#include "lldb/API/SBFile.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBMemoryRegionInfoList.h" @@ -331,23 +331,34 @@ lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options, return LLDB_RECORD_RESULT(trace_instance); } +void SBProcess::ReportEventState(const SBEvent &event, SBFile out) const { + LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState, + (const SBEvent &, SBFile), event, out); + + return ReportEventState(event, out.m_opaque_sp); +} + void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const { LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState, (const lldb::SBEvent &, FILE *), event, out); + FileSP outfile = std::make_shared<NativeFile>(out, false); + return ReportEventState(event, outfile); +} + +void SBProcess::ReportEventState(const SBEvent &event, FileSP out) const { + + LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState, + (const SBEvent &, FileSP), event, out); - if (out == nullptr) + if (!out || !out->IsValid()) return; ProcessSP process_sp(GetSP()); if (process_sp) { + StreamFile stream(out); const StateType event_state = SBProcess::GetStateFromEvent(event); - char message[1024]; - int message_len = ::snprintf( - message, sizeof(message), "Process %" PRIu64 " %s\n", + stream.Printf("Process %" PRIu64 " %s\n", process_sp->GetID(), SBDebugger::StateAsCString(event_state)); - - if (message_len > 0) - ::fwrite(message, 1, message_len, out); } } @@ -1180,6 +1191,9 @@ bool SBProcess::IsInstrumentationRuntimePresent( if (!process_sp) return false; + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type); @@ -1307,6 +1321,10 @@ void RegisterMethods<SBProcess>(Registry &R) { (lldb::SBTraceOptions &, lldb::SBError &)); LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState, (const lldb::SBEvent &, FILE *)); + LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState, + (const lldb::SBEvent &, FileSP)); + LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState, + (const lldb::SBEvent &, SBFile)); LLDB_REGISTER_METHOD( void, SBProcess, AppendEventStateReport, (const lldb::SBEvent &, lldb::SBCommandReturnObject &)); diff --git a/source/API/SBReproducer.cpp b/source/API/SBReproducer.cpp index 439ee5a70460..6e11b2c6366f 100644 --- a/source/API/SBReproducer.cpp +++ b/source/API/SBReproducer.cpp @@ -52,6 +52,7 @@ SBRegistry::SBRegistry() { RegisterMethods<SBEvent>(R); RegisterMethods<SBExecutionContext>(R); RegisterMethods<SBExpressionOptions>(R); + RegisterMethods<SBFile>(R); RegisterMethods<SBFileSpec>(R); RegisterMethods<SBFileSpecList>(R); RegisterMethods<SBFrame>(R); diff --git a/source/API/SBReproducerPrivate.h b/source/API/SBReproducerPrivate.h index 84b6ce967c0b..edd06941398f 100644 --- a/source/API/SBReproducerPrivate.h +++ b/source/API/SBReproducerPrivate.h @@ -40,7 +40,7 @@ public: SBProvider(const FileSpec &directory) : Provider(directory), m_stream(directory.CopyByAppendingPathComponent("sbapi.bin").GetPath(), - m_ec, llvm::sys::fs::OpenFlags::F_None), + m_ec, llvm::sys::fs::OpenFlags::OF_None), m_serializer(m_stream) {} Serializer &GetSerializer() { return m_serializer; } diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp index ae652338e1ea..d57634d2947c 100644 --- a/source/API/SBStream.cpp +++ b/source/API/SBStream.cpp @@ -9,6 +9,7 @@ #include "lldb/API/SBStream.h" #include "SBReproducerPrivate.h" +#include "lldb/API/SBFile.h" #include "lldb/Core/StreamFile.h" #include "lldb/Host/FileSystem.h" #include "lldb/Utility/Status.h" @@ -82,33 +83,45 @@ void SBStream::RedirectToFile(const char *path, bool append) { if (!m_is_file) local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString(); } - StreamFile *stream_file = new StreamFile; - uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; + auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; if (append) open_options |= File::eOpenOptionAppend; else open_options |= File::eOpenOptionTruncate; - FileSystem::Instance().Open(stream_file->GetFile(), FileSpec(path), - open_options); - m_opaque_up.reset(stream_file); + llvm::Expected<FileUP> file = + FileSystem::Instance().Open(FileSpec(path), open_options); + if (!file) { + LLDB_LOG_ERROR(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API), file.takeError(), + "Cannot open {1}: {0}", path); + return; + } - if (m_opaque_up) { - m_is_file = true; + m_opaque_up = std::make_unique<StreamFile>(std::move(file.get())); + m_is_file = true; - // If we had any data locally in our StreamString, then pass that along to - // the to new file we are redirecting to. - if (!local_data.empty()) - m_opaque_up->Write(&local_data[0], local_data.size()); - } else - m_is_file = false; + // If we had any data locally in our StreamString, then pass that along to + // the to new file we are redirecting to. + if (!local_data.empty()) + m_opaque_up->Write(&local_data[0], local_data.size()); } void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) { LLDB_RECORD_METHOD(void, SBStream, RedirectToFileHandle, (FILE *, bool), fh, transfer_fh_ownership); + FileSP file = std::make_unique<NativeFile>(fh, transfer_fh_ownership); + return RedirectToFile(file); +} - if (fh == nullptr) +void SBStream::RedirectToFile(SBFile file) { + LLDB_RECORD_METHOD(void, SBStream, RedirectToFile, (SBFile), file) + RedirectToFile(file.GetFile()); +} + +void SBStream::RedirectToFile(FileSP file_sp) { + LLDB_RECORD_METHOD(void, SBStream, RedirectToFile, (FileSP), file_sp); + + if (!file_sp || !file_sp->IsValid()) return; std::string local_data; @@ -118,17 +131,14 @@ void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) { if (!m_is_file) local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString(); } - m_opaque_up.reset(new StreamFile(fh, transfer_fh_ownership)); - if (m_opaque_up) { - m_is_file = true; + m_opaque_up = std::make_unique<StreamFile>(file_sp); + m_is_file = true; - // If we had any data locally in our StreamString, then pass that along to - // the to new file we are redirecting to. - if (!local_data.empty()) - m_opaque_up->Write(&local_data[0], local_data.size()); - } else - m_is_file = false; + // If we had any data locally in our StreamString, then pass that along to + // the to new file we are redirecting to. + if (!local_data.empty()) + m_opaque_up->Write(&local_data[0], local_data.size()); } void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) { @@ -143,16 +153,13 @@ void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) { local_data = static_cast<StreamString *>(m_opaque_up.get())->GetString(); } - m_opaque_up.reset(new StreamFile(::fdopen(fd, "w"), transfer_fh_ownership)); - if (m_opaque_up) { - m_is_file = true; + m_opaque_up = std::make_unique<StreamFile>(fd, transfer_fh_ownership); + m_is_file = true; - // If we had any data locally in our StreamString, then pass that along to - // the to new file we are redirecting to. - if (!local_data.empty()) - m_opaque_up->Write(&local_data[0], local_data.size()); - } else - m_is_file = false; + // If we had any data locally in our StreamString, then pass that along to + // the to new file we are redirecting to. + if (!local_data.empty()) + m_opaque_up->Write(&local_data[0], local_data.size()); } lldb_private::Stream *SBStream::operator->() { return m_opaque_up.get(); } @@ -189,6 +196,8 @@ void RegisterMethods<SBStream>(Registry &R) { LLDB_REGISTER_METHOD(const char *, SBStream, GetData, ()); LLDB_REGISTER_METHOD(size_t, SBStream, GetSize, ()); LLDB_REGISTER_METHOD(void, SBStream, RedirectToFile, (const char *, bool)); + LLDB_REGISTER_METHOD(void, SBStream, RedirectToFile, (FileSP)); + LLDB_REGISTER_METHOD(void, SBStream, RedirectToFile, (SBFile)); LLDB_REGISTER_METHOD(void, SBStream, RedirectToFileHandle, (FILE *, bool)); LLDB_REGISTER_METHOD(void, SBStream, RedirectToFileDescriptor, (int, bool)); LLDB_REGISTER_METHOD(void, SBStream, Clear, ()); diff --git a/source/API/SBStringList.cpp b/source/API/SBStringList.cpp index 2f8bd55855a1..ac07b8faac4d 100644 --- a/source/API/SBStringList.cpp +++ b/source/API/SBStringList.cpp @@ -21,7 +21,7 @@ SBStringList::SBStringList() : m_opaque_up() { SBStringList::SBStringList(const lldb_private::StringList *lldb_strings_ptr) : m_opaque_up() { if (lldb_strings_ptr) - m_opaque_up = llvm::make_unique<StringList>(*lldb_strings_ptr); + m_opaque_up = std::make_unique<StringList>(*lldb_strings_ptr); } SBStringList::SBStringList(const SBStringList &rhs) : m_opaque_up() { diff --git a/source/API/SBSymbolContext.cpp b/source/API/SBSymbolContext.cpp index 365f0ccc2fbf..6e01e5535c32 100644 --- a/source/API/SBSymbolContext.cpp +++ b/source/API/SBSymbolContext.cpp @@ -27,7 +27,7 @@ SBSymbolContext::SBSymbolContext(const SymbolContext *sc_ptr) : m_opaque_up() { (const lldb_private::SymbolContext *), sc_ptr); if (sc_ptr) - m_opaque_up = llvm::make_unique<SymbolContext>(*sc_ptr); + m_opaque_up = std::make_unique<SymbolContext>(*sc_ptr); } SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_up() { @@ -51,7 +51,7 @@ const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) { void SBSymbolContext::SetSymbolContext(const SymbolContext *sc_ptr) { if (sc_ptr) - m_opaque_up = llvm::make_unique<SymbolContext>(*sc_ptr); + m_opaque_up = std::make_unique<SymbolContext>(*sc_ptr); else m_opaque_up->Clear(true); } diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp index 5e87eb6273b3..1d13087eef69 100644 --- a/source/API/SBTarget.cpp +++ b/source/API/SBTarget.cpp @@ -44,11 +44,11 @@ #include "lldb/Core/ValueObjectList.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Host/Host.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/DeclVendor.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ABI.h" #include "lldb/Target/Language.h" @@ -218,7 +218,7 @@ SBStructuredData SBTarget::GetStatistics() { if (!target_sp) return LLDB_RECORD_RESULT(data); - auto stats_up = llvm::make_unique<StructuredData::Dictionary>(); + auto stats_up = std::make_unique<StructuredData::Dictionary>(); int i = 0; for (auto &Entry : target_sp->GetStatistics()) { std::string Desc = lldb_private::GetStatDescription( @@ -960,8 +960,8 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateByRegex( const LazyBool skip_prologue = eLazyBoolCalculate; sb_bp = target_sp->CreateFuncRegexBreakpoint( - module_list.get(), comp_unit_list.get(), regexp, symbol_language, - skip_prologue, internal, hardware); + module_list.get(), comp_unit_list.get(), std::move(regexp), + symbol_language, skip_prologue, internal, hardware); } return LLDB_RECORD_RESULT(sb_bp); @@ -1061,8 +1061,8 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateBySourceRegex( } sb_bp = target_sp->CreateSourceRegexBreakpoint( - module_list.get(), source_file_list.get(), func_names_set, regexp, - false, hardware, move_to_nearest_code); + module_list.get(), source_file_list.get(), func_names_set, + std::move(regexp), false, hardware, move_to_nearest_code); } return LLDB_RECORD_RESULT(sb_bp); @@ -1653,11 +1653,8 @@ SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) { SBSymbolContextList sb_sc_list; const TargetSP target_sp(GetSP()); - if (target_sp && sb_file_spec.IsValid()) { - const bool append = true; - target_sp->GetImages().FindCompileUnits(*sb_file_spec, - append, *sb_sc_list); - } + if (target_sp && sb_file_spec.IsValid()) + target_sp->GetImages().FindCompileUnits(*sb_file_spec, *sb_sc_list); return LLDB_RECORD_RESULT(sb_sc_list); } @@ -1783,10 +1780,9 @@ lldb::SBSymbolContextList SBTarget::FindFunctions(const char *name, const bool symbols_ok = true; const bool inlines_ok = true; - const bool append = true; FunctionNameType mask = static_cast<FunctionNameType>(name_type_mask); target_sp->GetImages().FindFunctions(ConstString(name), mask, symbols_ok, - inlines_ok, append, *sb_sc_list); + inlines_ok, *sb_sc_list); return LLDB_RECORD_RESULT(sb_sc_list); } @@ -1806,17 +1802,16 @@ lldb::SBSymbolContextList SBTarget::FindGlobalFunctions(const char *name, switch (matchtype) { case eMatchTypeRegex: target_sp->GetImages().FindFunctions(RegularExpression(name_ref), true, - true, true, *sb_sc_list); + true, *sb_sc_list); break; case eMatchTypeStartsWith: regexstr = llvm::Regex::escape(name) + ".*"; target_sp->GetImages().FindFunctions(RegularExpression(regexstr), true, - true, true, *sb_sc_list); + true, *sb_sc_list); break; default: - target_sp->GetImages().FindFunctions(ConstString(name), - eFunctionNameTypeAny, true, true, - true, *sb_sc_list); + target_sp->GetImages().FindFunctions( + ConstString(name), eFunctionNameTypeAny, true, true, *sb_sc_list); break; } } @@ -1858,11 +1853,11 @@ lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) { } // No matches, search for basic typename matches - ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); - if (clang_ast) - return LLDB_RECORD_RESULT(SBType(ClangASTContext::GetBasicType( - clang_ast->getASTContext(), const_typename))); + for (auto *type_system : target_sp->GetScratchTypeSystems()) + if (auto type = type_system->GetBuiltinTypeByName(const_typename)) + return LLDB_RECORD_RESULT(SBType(type)); } + return LLDB_RECORD_RESULT(SBType()); } @@ -1872,10 +1867,9 @@ SBType SBTarget::GetBasicType(lldb::BasicType type) { TargetSP target_sp(GetSP()); if (target_sp) { - ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); - if (clang_ast) - return LLDB_RECORD_RESULT(SBType( - ClangASTContext::GetBasicType(clang_ast->getASTContext(), type))); + for (auto *type_system : target_sp->GetScratchTypeSystems()) + if (auto compiler_type = type_system->GetBasicTypeFromAST(type)) + return LLDB_RECORD_RESULT(SBType(compiler_type)); } return LLDB_RECORD_RESULT(SBType()); } @@ -1892,16 +1886,13 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) { bool exact_match = false; TypeList type_list; llvm::DenseSet<SymbolFile *> searched_symbol_files; - uint32_t num_matches = - images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX, - searched_symbol_files, type_list); + images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX, + searched_symbol_files, type_list); - if (num_matches > 0) { - for (size_t idx = 0; idx < num_matches; idx++) { - TypeSP type_sp(type_list.GetTypeAtIndex(idx)); - if (type_sp) - sb_type_list.Append(SBType(type_sp)); - } + for (size_t idx = 0; idx < type_list.GetSize(); idx++) { + TypeSP type_sp(type_list.GetTypeAtIndex(idx)); + if (type_sp) + sb_type_list.Append(SBType(type_sp)); } // Try the loaded language runtimes @@ -1918,10 +1909,10 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) { if (sb_type_list.GetSize() == 0) { // No matches, search for basic typename matches - ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); - if (clang_ast) - sb_type_list.Append(SBType(ClangASTContext::GetBasicType( - clang_ast->getASTContext(), const_typename))); + for (auto *type_system : target_sp->GetScratchTypeSystems()) + if (auto compiler_type = + type_system->GetBuiltinTypeByName(const_typename)) + sb_type_list.Append(SBType(compiler_type)); } } return LLDB_RECORD_RESULT(sb_type_list); @@ -1937,9 +1928,9 @@ SBValueList SBTarget::FindGlobalVariables(const char *name, TargetSP target_sp(GetSP()); if (name && target_sp) { VariableList variable_list; - const uint32_t match_count = target_sp->GetImages().FindGlobalVariables( - ConstString(name), max_matches, variable_list); - + target_sp->GetImages().FindGlobalVariables(ConstString(name), max_matches, + variable_list); + const uint32_t match_count = variable_list.GetSize(); if (match_count > 0) { ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); if (exe_scope == nullptr) @@ -1974,20 +1965,20 @@ SBValueList SBTarget::FindGlobalVariables(const char *name, uint32_t match_count; switch (matchtype) { case eMatchTypeNormal: - match_count = target_sp->GetImages().FindGlobalVariables( - ConstString(name), max_matches, variable_list); + target_sp->GetImages().FindGlobalVariables(ConstString(name), max_matches, + variable_list); break; case eMatchTypeRegex: - match_count = target_sp->GetImages().FindGlobalVariables( - RegularExpression(name_ref), max_matches, variable_list); + target_sp->GetImages().FindGlobalVariables(RegularExpression(name_ref), + max_matches, variable_list); break; case eMatchTypeStartsWith: regexstr = llvm::Regex::escape(name) + ".*"; - match_count = target_sp->GetImages().FindGlobalVariables( - RegularExpression(regexstr), max_matches, variable_list); + target_sp->GetImages().FindGlobalVariables(RegularExpression(regexstr), + max_matches, variable_list); break; } - + match_count = variable_list.GetSize(); if (match_count > 0) { ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); if (exe_scope == nullptr) @@ -2291,11 +2282,9 @@ lldb::SBSymbolContextList SBTarget::FindSymbols(const char *name, SBSymbolContextList sb_sc_list; if (name && name[0]) { TargetSP target_sp(GetSP()); - if (target_sp) { - bool append = true; + if (target_sp) target_sp->GetImages().FindSymbolsWithNameAndType( - ConstString(name), symbol_type, *sb_sc_list, append); - } + ConstString(name), symbol_type, *sb_sc_list); } return LLDB_RECORD_RESULT(sb_sc_list); } @@ -2355,10 +2344,10 @@ lldb::SBValue SBTarget::EvaluateExpression(const char *expr, expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); } } - if (expr_log) - expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is " - "%s, summary %s **", - expr_result.GetValue(), expr_result.GetSummary()); + LLDB_LOGF(expr_log, + "** [SBTarget::EvaluateExpression] Expression result is " + "%s, summary %s **", + expr_result.GetValue(), expr_result.GetSummary()); return LLDB_RECORD_RESULT(expr_result); } diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp index 85e9a6b47955..8d4930bf6edb 100644 --- a/source/API/SBThread.cpp +++ b/source/API/SBThread.cpp @@ -16,6 +16,7 @@ #include "lldb/API/SBFrame.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBStructuredData.h" #include "lldb/API/SBSymbolContext.h" #include "lldb/API/SBThreadCollection.h" #include "lldb/API/SBThreadPlan.h" @@ -23,6 +24,7 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Core/ValueObject.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/CompileUnit.h" @@ -965,9 +967,24 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { } SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, + bool resume_immediately) { + LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, + (const char *, bool), script_class_name, + resume_immediately); + + lldb::SBStructuredData no_data; + return LLDB_RECORD_RESULT( + StepUsingScriptedThreadPlan(script_class_name, + no_data, + resume_immediately)); +} + +SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, + SBStructuredData &args_data, bool resume_immediately) { LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, - (const char *, bool), script_class_name, + (const char *, lldb::SBStructuredData &, bool), + script_class_name, args_data, resume_immediately); SBError error; @@ -982,8 +999,10 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, Thread *thread = exe_ctx.GetThreadPtr(); Status new_plan_status; + StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP(); + ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( - false, script_class_name, false, new_plan_status); + false, script_class_name, obj_sp, false, new_plan_status); if (new_plan_status.Fail()) { error.SetErrorString(new_plan_status.AsCString()); @@ -1460,6 +1479,8 @@ void RegisterMethods<SBThread>(Registry &R) { (const char *)); LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, (const char *, bool)); + LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, + (const char *, SBStructuredData &, bool)); LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine, (lldb::SBFileSpec &, uint32_t)); LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame, diff --git a/source/API/SBThreadPlan.cpp b/source/API/SBThreadPlan.cpp index 8f6802fe9cef..eed4d1bfb9c4 100644 --- a/source/API/SBThreadPlan.cpp +++ b/source/API/SBThreadPlan.cpp @@ -11,10 +11,12 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBStructuredData.h" #include "lldb/API/SBSymbolContext.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SymbolContext.h" @@ -67,7 +69,20 @@ SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) { Thread *thread = sb_thread.get(); if (thread) - m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name); + m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name, + nullptr); +} + +SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name, + lldb::SBStructuredData &args_data) { + LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *, + SBStructuredData &), + sb_thread, class_name, args_data); + + Thread *thread = sb_thread.get(); + if (thread) + m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name, + args_data.m_impl_up.get()); } // Assignment operator @@ -368,9 +383,35 @@ SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name, if (m_opaque_sp) { Status plan_status; + StructuredData::ObjectSP empty_args; SBThreadPlan plan = SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( - false, script_class_name, false, plan_status)); + false, script_class_name, empty_args, false, plan_status)); + + if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); + + return LLDB_RECORD_RESULT(plan); + } else { + return LLDB_RECORD_RESULT(SBThreadPlan()); + } +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name, + lldb::SBStructuredData &args_data, + SBError &error) { + LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan, + QueueThreadPlanForStepScripted, + (const char *, lldb::SBStructuredData &, lldb::SBError &), + script_class_name, args_data, error); + + if (m_opaque_sp) { + Status plan_status; + StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP(); + SBThreadPlan plan = + SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( + false, script_class_name, args_obj, false, plan_status)); if (plan_status.Fail()) error.SetErrorString(plan_status.AsCString()); @@ -390,6 +431,8 @@ void RegisterMethods<SBThreadPlan>(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &)); LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &)); LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *)); + LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *, + lldb::SBStructuredData &)); LLDB_REGISTER_METHOD(const lldb::SBThreadPlan &, SBThreadPlan, operator=,(const lldb::SBThreadPlan &)); LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, IsValid, ()); @@ -433,6 +476,10 @@ void RegisterMethods<SBThreadPlan>(Registry &R) { LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan, QueueThreadPlanForStepScripted, (const char *, lldb::SBError &)); + LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan, + QueueThreadPlanForStepScripted, + (const char *, lldb::SBStructuredData &, + lldb::SBError &)); } } diff --git a/source/API/SBType.cpp b/source/API/SBType.cpp index 5402128b3fae..8efc701a79fb 100644 --- a/source/API/SBType.cpp +++ b/source/API/SBType.cpp @@ -799,7 +799,7 @@ const char *SBTypeMemberFunction::GetDemangledName() { if (m_opaque_sp) { ConstString mangled_str = m_opaque_sp->GetMangledName(); if (mangled_str) { - Mangled mangled(mangled_str, true); + Mangled mangled(mangled_str); return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString(); } } diff --git a/source/API/SBTypeCategory.cpp b/source/API/SBTypeCategory.cpp index 43d5a3ab140f..1e4496575098 100644 --- a/source/API/SBTypeCategory.cpp +++ b/source/API/SBTypeCategory.cpp @@ -364,8 +364,8 @@ bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeFormatsContainer()->Add( - lldb::RegularExpressionSP(new RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName()))), + RegularExpression( + llvm::StringRef::withNullAsEmpty(type_name.GetName())), format.GetSP()); else m_opaque_sp->GetTypeFormatsContainer()->Add( @@ -443,8 +443,8 @@ bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeSummariesContainer()->Add( - lldb::RegularExpressionSP(new RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName()))), + RegularExpression( + llvm::StringRef::withNullAsEmpty(type_name.GetName())), summary.GetSP()); else m_opaque_sp->GetTypeSummariesContainer()->Add( @@ -488,8 +488,8 @@ bool SBTypeCategory::AddTypeFilter(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeFiltersContainer()->Add( - lldb::RegularExpressionSP(new RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName()))), + RegularExpression( + llvm::StringRef::withNullAsEmpty(type_name.GetName())), filter.GetSP()); else m_opaque_sp->GetTypeFiltersContainer()->Add( @@ -567,8 +567,8 @@ bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name, if (type_name.IsRegex()) m_opaque_sp->GetRegexTypeSyntheticsContainer()->Add( - lldb::RegularExpressionSP(new RegularExpression( - llvm::StringRef::withNullAsEmpty(type_name.GetName()))), + RegularExpression( + llvm::StringRef::withNullAsEmpty(type_name.GetName())), synth.GetSP()); else m_opaque_sp->GetTypeSyntheticsContainer()->Add( diff --git a/source/API/SystemInitializerFull.cpp b/source/API/SystemInitializerFull.cpp index e7f2206b9a59..0acc496ff879 100644 --- a/source/API/SystemInitializerFull.cpp +++ b/source/API/SystemInitializerFull.cpp @@ -24,6 +24,7 @@ #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h" #include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h" #include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h" +#include "Plugins/ABI/SysV-arc/ABISysV_arc.h" #include "Plugins/ABI/SysV-arm/ABISysV_arm.h" #include "Plugins/ABI/SysV-arm64/ABISysV_arm64.h" #include "Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h" @@ -131,6 +132,39 @@ SystemInitializerFull::SystemInitializerFull() {} SystemInitializerFull::~SystemInitializerFull() {} +#define LLDB_PROCESS_AArch64(op) \ + ABIMacOSX_arm64::op(); \ + ABISysV_arm64::op(); +#define LLDB_PROCESS_ARM(op) \ + ABIMacOSX_arm::op(); \ + ABISysV_arm::op(); +#define LLDB_PROCESS_ARC(op) \ + ABISysV_arc::op(); +#define LLDB_PROCESS_Hexagon(op) ABISysV_hexagon::op(); +#define LLDB_PROCESS_Mips(op) \ + ABISysV_mips::op(); \ + ABISysV_mips64::op(); +#define LLDB_PROCESS_PowerPC(op) \ + ABISysV_ppc::op(); \ + ABISysV_ppc64::op(); +#define LLDB_PROCESS_SystemZ(op) ABISysV_s390x::op(); +#define LLDB_PROCESS_X86(op) \ + ABIMacOSX_i386::op(); \ + ABISysV_i386::op(); \ + ABISysV_x86_64::op(); \ + ABIWindows_x86_64::op(); + +#define LLDB_PROCESS_AMDGPU(op) +#define LLDB_PROCESS_AVR(op) +#define LLDB_PROCESS_BPF(op) +#define LLDB_PROCESS_Lanai(op) +#define LLDB_PROCESS_MSP430(op) +#define LLDB_PROCESS_NVPTX(op) +#define LLDB_PROCESS_RISCV(op) +#define LLDB_PROCESS_Sparc(op) +#define LLDB_PROCESS_WebAssembly(op) +#define LLDB_PROCESS_XCore(op) + llvm::Error SystemInitializerFull::Initialize() { if (auto e = SystemInitializerCommon::Initialize()) return e; @@ -174,20 +208,8 @@ llvm::Error SystemInitializerFull::Initialize() { ClangASTContext::Initialize(); - ABIMacOSX_i386::Initialize(); - ABIMacOSX_arm::Initialize(); - ABIMacOSX_arm64::Initialize(); - ABISysV_arm::Initialize(); - ABISysV_arm64::Initialize(); - ABISysV_hexagon::Initialize(); - ABISysV_i386::Initialize(); - ABISysV_x86_64::Initialize(); - ABISysV_ppc::Initialize(); - ABISysV_ppc64::Initialize(); - ABISysV_mips::Initialize(); - ABISysV_mips64::Initialize(); - ABISysV_s390x::Initialize(); - ABIWindows_x86_64::Initialize(); +#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Initialize) +#include "llvm/Config/Targets.def" ArchitectureArm::Initialize(); ArchitectureMips::Initialize(); @@ -288,20 +310,9 @@ void SystemInitializerFull::Terminate() { ArchitectureMips::Terminate(); ArchitecturePPC64::Terminate(); - ABIMacOSX_i386::Terminate(); - ABIMacOSX_arm::Terminate(); - ABIMacOSX_arm64::Terminate(); - ABISysV_arm::Terminate(); - ABISysV_arm64::Terminate(); - ABISysV_hexagon::Terminate(); - ABISysV_i386::Terminate(); - ABISysV_x86_64::Terminate(); - ABISysV_ppc::Terminate(); - ABISysV_ppc64::Terminate(); - ABISysV_mips::Terminate(); - ABISysV_mips64::Terminate(); - ABISysV_s390x::Terminate(); - ABIWindows_x86_64::Terminate(); +#define LLVM_TARGET(t) LLDB_PROCESS_ ## t(Terminate) +#include "llvm/Config/Targets.def" + DisassemblerLLVMC::Terminate(); JITLoaderGDB::Terminate(); diff --git a/source/API/Utils.h b/source/API/Utils.h index b1975e5421dd..ed81534d2d12 100644 --- a/source/API/Utils.h +++ b/source/API/Utils.h @@ -16,7 +16,7 @@ namespace lldb_private { template <typename T> std::unique_ptr<T> clone(const std::unique_ptr<T> &src) { if (src) - return llvm::make_unique<T>(*src); + return std::make_unique<T>(*src); return nullptr; } diff --git a/source/Breakpoint/Breakpoint.cpp b/source/Breakpoint/Breakpoint.cpp index 3c3841949b91..a112542803c4 100644 --- a/source/Breakpoint/Breakpoint.cpp +++ b/source/Breakpoint/Breakpoint.cpp @@ -496,10 +496,10 @@ void Breakpoint::ClearAllBreakpointSites() { void Breakpoint::ModulesChanged(ModuleList &module_list, bool load, bool delete_locations) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("Breakpoint::ModulesChanged: num_modules: %zu load: %i " - "delete_locations: %i\n", - module_list.GetSize(), load, delete_locations); + LLDB_LOGF(log, + "Breakpoint::ModulesChanged: num_modules: %zu load: %i " + "delete_locations: %i\n", + module_list.GetSize(), load, delete_locations); std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); if (load) { @@ -550,10 +550,10 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load, seen = true; if (!break_loc_sp->ResolveBreakpointSite()) { - if (log) - log->Printf("Warning: could not set breakpoint site for " - "breakpoint location %d of breakpoint %d.\n", - break_loc_sp->GetID(), GetID()); + LLDB_LOGF(log, + "Warning: could not set breakpoint site for " + "breakpoint location %d of breakpoint %d.\n", + break_loc_sp->GetID(), GetID()); } } } @@ -659,9 +659,8 @@ static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc, void Breakpoint::ModuleReplaced(ModuleSP old_module_sp, ModuleSP new_module_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("Breakpoint::ModulesReplaced for %s\n", - old_module_sp->GetSpecificationDescription().c_str()); + LLDB_LOGF(log, "Breakpoint::ModulesReplaced for %s\n", + old_module_sp->GetSpecificationDescription().c_str()); // First find all the locations that are in the old module BreakpointLocationCollection old_break_locs; diff --git a/source/Breakpoint/BreakpointIDList.cpp b/source/Breakpoint/BreakpointIDList.cpp index 1e695fae6995..de68c44ec6a4 100644 --- a/source/Breakpoint/BreakpointIDList.cpp +++ b/source/Breakpoint/BreakpointIDList.cpp @@ -122,7 +122,7 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, for (size_t i = 0; i < old_args.size(); ++i) { bool is_range = false; - current_arg = old_args[i].ref; + current_arg = old_args[i].ref(); if (!allow_locations && current_arg.contains('.')) { result.AppendErrorWithFormat( "Breakpoint locations not allowed, saw location: %s.", @@ -146,16 +146,16 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target, } else names_found.insert(current_arg); } else if ((i + 2 < old_args.size()) && - BreakpointID::IsRangeIdentifier(old_args[i + 1].ref) && + BreakpointID::IsRangeIdentifier(old_args[i + 1].ref()) && BreakpointID::IsValidIDExpression(current_arg) && - BreakpointID::IsValidIDExpression(old_args[i + 2].ref)) { + BreakpointID::IsValidIDExpression(old_args[i + 2].ref())) { range_from = current_arg; - range_to = old_args[i + 2].ref; + range_to = old_args[i + 2].ref(); is_range = true; i = i + 2; } else { // See if user has specified id.* - llvm::StringRef tmp_str = old_args[i].ref; + llvm::StringRef tmp_str = old_args[i].ref(); size_t pos = tmp_str.find('.'); if (pos != llvm::StringRef::npos) { llvm::StringRef bp_id_str = tmp_str.substr(0, pos); diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp index b718e2aeea5c..46b8f25c5668 100644 --- a/source/Breakpoint/BreakpointLocation.cpp +++ b/source/Breakpoint/BreakpointLocation.cpp @@ -257,9 +257,8 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, condition_text, llvm::StringRef(), language, Expression::eResultTypeAny, EvaluateExpressionOptions(), nullptr, error)); if (error.Fail()) { - if (log) - log->Printf("Error getting condition expression: %s.", - error.AsCString()); + LLDB_LOGF(log, "Error getting condition expression: %s.", + error.AsCString()); m_user_expression_sp.reset(); return true; } @@ -312,8 +311,8 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, ret = result_value_sp->IsLogicalTrue(error); if (log) { if (error.Success()) { - log->Printf("Condition successfully evaluated, result is %s.\n", - ret ? "true" : "false"); + LLDB_LOGF(log, "Condition successfully evaluated, result is %s.\n", + ret ? "true" : "false"); } else { error.SetErrorString( "Failed to get an integer result from the expression"); @@ -408,8 +407,8 @@ bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) { if (log) { StreamString s; GetDescription(&s, lldb::eDescriptionLevelVerbose); - log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(), - should_stop ? "stopping" : "continuing"); + LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(), + should_stop ? "stopping" : "continuing"); } return should_stop; diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp index f6f279dc382a..0d4c6173c3c5 100644 --- a/source/Breakpoint/BreakpointOptions.cpp +++ b/source/Breakpoint/BreakpointOptions.cpp @@ -309,7 +309,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( } } - auto bp_options = llvm::make_unique<BreakpointOptions>( + auto bp_options = std::make_unique<BreakpointOptions>( condition_ref.str().c_str(), enabled, ignore_count, one_shot, auto_continue); if (cmd_data_up) { diff --git a/source/Breakpoint/BreakpointResolver.cpp b/source/Breakpoint/BreakpointResolver.cpp index b3224aa91753..e0a4e6ac6712 100644 --- a/source/Breakpoint/BreakpointResolver.cpp +++ b/source/Breakpoint/BreakpointResolver.cpp @@ -34,7 +34,8 @@ using namespace lldb; // BreakpointResolver: const char *BreakpointResolver::g_ty_to_name[] = {"FileAndLine", "Address", "SymbolName", "SourceRegex", - "Exception", "Unknown"}; + "Python", "Exception", + "Unknown"}; const char *BreakpointResolver::g_option_names[static_cast<uint32_t>( BreakpointResolver::OptionNames::LastOptionName)] = { @@ -294,18 +295,18 @@ void BreakpointResolver::AddLocation(SearchFilter &filter, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); Address line_start = sc.line_entry.range.GetBaseAddress(); if (!line_start.IsValid()) { - if (log) - log->Printf("error: Unable to set breakpoint %s at file address " - "0x%" PRIx64 "\n", - log_ident.str().c_str(), line_start.GetFileAddress()); + LLDB_LOGF(log, + "error: Unable to set breakpoint %s at file address " + "0x%" PRIx64 "\n", + log_ident.str().c_str(), line_start.GetFileAddress()); return; } if (!filter.AddressPasses(line_start)) { - if (log) - log->Printf("Breakpoint %s at file address 0x%" PRIx64 - " didn't pass the filter.\n", - log_ident.str().c_str(), line_start.GetFileAddress()); + LLDB_LOGF(log, + "Breakpoint %s at file address 0x%" PRIx64 + " didn't pass the filter.\n", + log_ident.str().c_str(), line_start.GetFileAddress()); } // If the line number is before the prologue end, move it there... @@ -329,8 +330,8 @@ void BreakpointResolver::AddLocation(SearchFilter &filter, if (log && bp_loc_sp && !m_breakpoint->IsInternal()) { StreamString s; bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - log->Printf("Added location (skipped prologue: %s): %s \n", - skipped_prologue ? "yes" : "no", s.GetData()); + LLDB_LOGF(log, "Added location (skipped prologue: %s): %s \n", + skipped_prologue ? "yes" : "no", s.GetData()); } } diff --git a/source/Breakpoint/BreakpointResolverAddress.cpp b/source/Breakpoint/BreakpointResolverAddress.cpp index 8a6fd6a2692c..b98568098b4b 100644 --- a/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/source/Breakpoint/BreakpointResolverAddress.cpp @@ -120,10 +120,8 @@ void BreakpointResolverAddress::ResolveBreakpointInModules( BreakpointResolver::ResolveBreakpointInModules(filter, modules); } -Searcher::CallbackReturn -BreakpointResolverAddress::SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) { +Searcher::CallbackReturn BreakpointResolverAddress::SearchCallback( + SearchFilter &filter, SymbolContext &context, Address *addr) { assert(m_breakpoint != nullptr); if (filter.AddressPasses(m_addr)) { @@ -149,8 +147,7 @@ BreakpointResolverAddress::SearchCallback(SearchFilter &filter, bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); Log *log( lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("Added location: %s\n", s.GetData()); + LLDB_LOGF(log, "Added location: %s\n", s.GetData()); } } else { BreakpointLocationSP loc_sp = m_breakpoint->GetLocationAtIndex(0); diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp index a6095be31647..2b26f65816bd 100644 --- a/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -198,10 +198,8 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, } } -Searcher::CallbackReturn -BreakpointResolverFileLine::SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr, bool containing) { +Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( + SearchFilter &filter, SymbolContext &context, Address *addr) { SymbolContextList sc_list; assert(m_breakpoint != nullptr); diff --git a/source/Breakpoint/BreakpointResolverFileRegex.cpp b/source/Breakpoint/BreakpointResolverFileRegex.cpp index 0b2485245b72..3cb04263c6dc 100644 --- a/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -20,11 +20,11 @@ using namespace lldb_private; // BreakpointResolverFileRegex: BreakpointResolverFileRegex::BreakpointResolverFileRegex( - Breakpoint *bkpt, RegularExpression ®ex, + Breakpoint *bkpt, RegularExpression regex, const std::unordered_set<std::string> &func_names, bool exact_match) : BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver), - m_regex(regex), m_exact_match(exact_match), m_function_names(func_names) { -} + m_regex(std::move(regex)), m_exact_match(exact_match), + m_function_names(func_names) {} BreakpointResolverFileRegex::~BreakpointResolverFileRegex() {} @@ -69,7 +69,8 @@ BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData( } } - return new BreakpointResolverFileRegex(bkpt, regex, names_set, exact_match); + return new BreakpointResolverFileRegex(bkpt, std::move(regex), names_set, + exact_match); } StructuredData::ObjectSP @@ -93,10 +94,8 @@ BreakpointResolverFileRegex::SerializeToStructuredData() { return WrapOptionsDict(options_dict_sp); } -Searcher::CallbackReturn -BreakpointResolverFileRegex::SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr, bool containing) { +Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback( + SearchFilter &filter, SymbolContext &context, Address *addr) { assert(m_breakpoint != nullptr); if (!context.target_sp) diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp index 3ad2e8867f2a..ba9c88c7eae8 100644 --- a/source/Breakpoint/BreakpointResolverName.cpp +++ b/source/Breakpoint/BreakpointResolverName.cpp @@ -31,7 +31,8 @@ BreakpointResolverName::BreakpointResolverName( m_class_name(), m_regex(), m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) { if (m_match_type == Breakpoint::Regexp) { - if (!m_regex.Compile(llvm::StringRef::withNullAsEmpty(name_cstr))) { + m_regex = RegularExpression(llvm::StringRef::withNullAsEmpty(name_cstr)); + if (!m_regex.IsValid()) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); if (log) @@ -70,12 +71,12 @@ BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, } BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, - RegularExpression &func_regex, + RegularExpression func_regex, lldb::LanguageType language, lldb::addr_t offset, bool skip_prologue) : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset), - m_class_name(nullptr), m_regex(func_regex), + m_class_name(nullptr), m_regex(std::move(func_regex)), m_match_type(Breakpoint::Regexp), m_language(language), m_skip_prologue(skip_prologue) {} @@ -125,9 +126,8 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData( success = options_dict.GetValueForKeyAsString( GetKey(OptionNames::RegexString), regex_text); if (success) { - RegularExpression regex(regex_text); - return new BreakpointResolverName(bkpt, regex, language, offset, - skip_prologue); + return new BreakpointResolverName(bkpt, RegularExpression(regex_text), + language, offset, skip_prologue); } else { StructuredData::Array *names_array; success = options_dict.GetValueForKeyAsArray( @@ -250,8 +250,7 @@ void BreakpointResolverName::AddNameLookup(ConstString name, Searcher::CallbackReturn BreakpointResolverName::SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) { + SymbolContext &context, Address *addr) { SymbolContextList func_list; // SymbolContextList sym_list; @@ -272,7 +271,6 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, bool filter_by_language = (m_language != eLanguageTypeUnknown); const bool include_symbols = !filter_by_cu; const bool include_inlines = true; - const bool append = true; switch (m_match_type) { case Breakpoint::Exact: @@ -281,7 +279,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, const size_t start_func_idx = func_list.GetSize(); context.module_sp->FindFunctions( lookup.GetLookupName(), nullptr, lookup.GetNameTypeMask(), - include_symbols, include_inlines, append, func_list); + include_symbols, include_inlines, func_list); const size_t end_func_idx = func_list.GetSize(); @@ -295,7 +293,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, context.module_sp->FindFunctions( m_regex, !filter_by_cu, // include symbols only if we aren't filtering by CU - include_inlines, append, func_list); + include_inlines, func_list); } break; case Breakpoint::Glob: @@ -388,7 +386,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, if (log) { StreamString s; bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - log->Printf("Added location: %s\n", s.GetData()); + LLDB_LOGF(log, "Added location: %s\n", s.GetData()); } } } diff --git a/source/Breakpoint/BreakpointResolverScripted.cpp b/source/Breakpoint/BreakpointResolverScripted.cpp index 8363795a4d7f..288fd37c1c79 100644 --- a/source/Breakpoint/BreakpointResolverScripted.cpp +++ b/source/Breakpoint/BreakpointResolverScripted.cpp @@ -29,8 +29,7 @@ BreakpointResolverScripted::BreakpointResolverScripted( Breakpoint *bkpt, const llvm::StringRef class_name, lldb::SearchDepth depth, - StructuredDataImpl *args_data, - ScriptInterpreter &script_interp) + StructuredDataImpl *args_data) : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) { CreateImplementationIfNeeded(); @@ -68,45 +67,25 @@ BreakpointResolverScripted::CreateFromStructuredData( llvm::StringRef class_name; bool success; - if (!bkpt) - return nullptr; - success = options_dict.GetValueForKeyAsString( GetKey(OptionNames::PythonClassName), class_name); if (!success) { error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); return nullptr; } - lldb::SearchDepth depth; - int depth_as_int; - success = options_dict.GetValueForKeyAsInteger( - GetKey(OptionNames::SearchDepth), depth_as_int); - if (!success) { - error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); - return nullptr; - } - if (depth_as_int >= (int) OptionNames::LastOptionName) { - error.SetErrorString("BRFL::CFSD: Invalid value for search depth."); - return nullptr; - } - depth = (lldb::SearchDepth) depth_as_int; + // The Python function will actually provide the search depth, this is a + // placeholder. + lldb::SearchDepth depth = lldb::eSearchDepthTarget; StructuredDataImpl *args_data_impl = new StructuredDataImpl(); - StructuredData::Dictionary *args_dict = new StructuredData::Dictionary(); + StructuredData::Dictionary *args_dict = nullptr; success = options_dict.GetValueForKeyAsDictionary( GetKey(OptionNames::ScriptArgs), args_dict); if (success) { - // FIXME: The resolver needs a copy of the ARGS dict that it can own, - // so I need to make a copy constructor for the Dictionary so I can pass - // that to it here. For now the args are empty. - //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict); - + args_data_impl->SetObjectSP(args_dict->shared_from_this()); } - ScriptInterpreter *script_interp = bkpt->GetTarget() - .GetDebugger() - .GetScriptInterpreter(); - return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl, - *script_interp); + return new BreakpointResolverScripted(bkpt, class_name, depth, + args_data_impl); } StructuredData::ObjectSP @@ -116,6 +95,10 @@ BreakpointResolverScripted::SerializeToStructuredData() { options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), m_class_name); + if (m_args_ptr->IsValid()) + options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs), + m_args_ptr->GetObjectSP()); + return WrapOptionsDict(options_dict_sp); } @@ -123,10 +106,8 @@ ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { return m_breakpoint->GetTarget().GetDebugger().GetScriptInterpreter(); } -Searcher::CallbackReturn -BreakpointResolverScripted::SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) { +Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback( + SearchFilter &filter, SymbolContext &context, Address *addr) { assert(m_breakpoint != nullptr); bool should_continue = true; if (!m_implementation_sp) @@ -173,11 +154,10 @@ void BreakpointResolverScripted::Dump(Stream *s) const {} lldb::BreakpointResolverSP BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) { - ScriptInterpreter *script_interp = GetScriptInterpreter(); // FIXME: Have to make a copy of the arguments from the m_args_ptr and then // pass that to the new resolver. lldb::BreakpointResolverSP ret_sp( - new BreakpointResolverScripted(&breakpoint, m_class_name, - m_depth, nullptr, *script_interp)); + new BreakpointResolverScripted(&breakpoint, m_class_name, m_depth, + nullptr)); return ret_sp; } diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp index e8a926527d24..17dcda13e9b9 100644 --- a/source/Breakpoint/Watchpoint.cpp +++ b/source/Breakpoint/Watchpoint.cpp @@ -13,10 +13,11 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectMemory.h" #include "lldb/Expression/UserExpression.h" -#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" using namespace lldb; @@ -30,14 +31,22 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size, m_watch_write(0), m_watch_was_read(0), m_watch_was_written(0), m_ignore_count(0), m_false_alarms(0), m_decl_str(), m_watch_spec_str(), m_type(), m_error(), m_options(), m_being_created(true) { + if (type && type->IsValid()) m_type = *type; else { // If we don't have a known type, then we force it to unsigned int of the // right size. - ClangASTContext *ast_context = target.GetScratchClangASTContext(); - m_type = ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, - 8 * size); + auto type_system_or_err = + target.GetScratchTypeSystemForLanguage(eLanguageTypeC); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR( + lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS), + std::move(err), "Failed to set type."); + } else { + m_type = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize( + eEncodingUint, 8 * size); + } } // Set the initial value of the watched variable: diff --git a/source/Breakpoint/WatchpointOptions.cpp b/source/Breakpoint/WatchpointOptions.cpp index 7dd130a3072c..cd5ef930e5dc 100644 --- a/source/Breakpoint/WatchpointOptions.cpp +++ b/source/Breakpoint/WatchpointOptions.cpp @@ -170,9 +170,8 @@ void WatchpointOptions::CommandBaton::GetDescription( s->IndentMore(); if (data && data->user_source.GetSize() > 0) { - const size_t num_strings = data->user_source.GetSize(); - for (size_t i = 0; i < num_strings; ++i) { - s->Indent(data->user_source.GetStringAtIndex(i)); + for (const std::string &line : data->user_source) { + s->Indent(line); s->EOL(); } } else { diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp index 5d2fb3d67f57..469a6bbbadf6 100644 --- a/source/Commands/CommandCompletions.cpp +++ b/source/Commands/CommandCompletions.cpp @@ -71,10 +71,9 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( return handled; } -int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - request.SetWordComplete(true); +void CommandCompletions::SourceFiles(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { // Find some way to switch "include support files..." SourceFileCompleter completer(interpreter, false, request); @@ -85,20 +84,18 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return request.GetNumberOfMatches(); } -static int DiskFilesOrDirectories(const llvm::Twine &partial_name, - bool only_directories, StringList &matches, - TildeExpressionResolver &Resolver) { - matches.Clear(); - +static void DiskFilesOrDirectories(const llvm::Twine &partial_name, + bool only_directories, + CompletionRequest &request, + TildeExpressionResolver &Resolver) { llvm::SmallString<256> CompletionBuffer; llvm::SmallString<256> Storage; partial_name.toVector(CompletionBuffer); if (CompletionBuffer.size() >= PATH_MAX) - return matches.GetSize(); + return; namespace path = llvm::sys::path; @@ -126,10 +123,10 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, for (const auto &S : MatchSet) { Resolved = S.getKey(); path::append(Resolved, path::get_separator()); - matches.AppendString(Resolved); + request.AddCompletion(Resolved, "", CompletionMode::Partial); } } - return matches.GetSize(); + return; } // If there was no trailing slash, then we're done as soon as we resolve @@ -138,8 +135,8 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, if (FirstSep == llvm::StringRef::npos) { // Make sure it ends with a separator. path::append(CompletionBuffer, path::get_separator()); - matches.AppendString(CompletionBuffer); - return matches.GetSize(); + request.AddCompletion(CompletionBuffer, "", CompletionMode::Partial); + return; } // We want to keep the form the user typed, so we special case this to @@ -219,51 +216,56 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, path::append(CompletionBuffer, path::get_separator()); } - matches.AppendString(CompletionBuffer); + CompletionMode mode = + is_dir ? CompletionMode::Partial : CompletionMode::Normal; + request.AddCompletion(CompletionBuffer, "", mode); } +} - return matches.GetSize(); +static void DiskFilesOrDirectories(const llvm::Twine &partial_name, + bool only_directories, StringList &matches, + TildeExpressionResolver &Resolver) { + CompletionResult result; + std::string partial_name_str = partial_name.str(); + CompletionRequest request(partial_name_str, partial_name_str.size(), result); + DiskFilesOrDirectories(partial_name, only_directories, request, Resolver); + result.GetMatches(matches); } -static int DiskFilesOrDirectories(CompletionRequest &request, - bool only_directories) { - request.SetWordComplete(false); +static void DiskFilesOrDirectories(CompletionRequest &request, + bool only_directories) { StandardTildeExpressionResolver resolver; - StringList matches; DiskFilesOrDirectories(request.GetCursorArgumentPrefix(), only_directories, - matches, resolver); - request.AddCompletions(matches); - return request.GetNumberOfMatches(); + request, resolver); } -int CommandCompletions::DiskFiles(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - return DiskFilesOrDirectories(request, /*only_dirs*/ false); +void CommandCompletions::DiskFiles(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + DiskFilesOrDirectories(request, /*only_dirs*/ false); } -int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name, - StringList &matches, - TildeExpressionResolver &Resolver) { - return DiskFilesOrDirectories(partial_file_name, false, matches, Resolver); +void CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name, + StringList &matches, + TildeExpressionResolver &Resolver) { + DiskFilesOrDirectories(partial_file_name, false, matches, Resolver); } -int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - return DiskFilesOrDirectories(request, /*only_dirs*/ true); +void CommandCompletions::DiskDirectories(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + DiskFilesOrDirectories(request, /*only_dirs*/ true); } -int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name, - StringList &matches, - TildeExpressionResolver &Resolver) { - return DiskFilesOrDirectories(partial_file_name, true, matches, Resolver); +void CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name, + StringList &matches, + TildeExpressionResolver &Resolver) { + DiskFilesOrDirectories(partial_file_name, true, matches, Resolver); } -int CommandCompletions::Modules(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - request.SetWordComplete(true); +void CommandCompletions::Modules(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { ModuleCompleter completer(interpreter, request); if (searcher == nullptr) { @@ -273,13 +275,11 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return request.GetNumberOfMatches(); } -int CommandCompletions::Symbols(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - request.SetWordComplete(true); +void CommandCompletions::Symbols(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { SymbolCompleter completer(interpreter, request); if (searcher == nullptr) { @@ -289,12 +289,11 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return request.GetNumberOfMatches(); } -int CommandCompletions::SettingsNames(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { +void CommandCompletions::SettingsNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { // Cache the full setting name list static StringList g_property_names; if (g_property_names.GetSize() == 0) { @@ -309,38 +308,27 @@ int CommandCompletions::SettingsNames(CommandInterpreter &interpreter, } } - size_t exact_matches_idx = SIZE_MAX; - StringList matches; - g_property_names.AutoComplete(request.GetCursorArgumentPrefix(), matches, - exact_matches_idx); - request.SetWordComplete(exact_matches_idx != SIZE_MAX); - request.AddCompletions(matches); - return request.GetNumberOfMatches(); + for (const std::string &s : g_property_names) + request.TryCompleteCurrentArg(s); } -int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - StringList new_matches; - std::size_t num_matches = PluginManager::AutoCompletePlatformName( - request.GetCursorArgumentPrefix(), new_matches); - request.SetWordComplete(num_matches == 1); - request.AddCompletions(new_matches); - return request.GetNumberOfMatches(); +void CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + PluginManager::AutoCompletePlatformName(request.GetCursorArgumentPrefix(), + request); } -int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - const uint32_t num_matches = ArchSpec::AutoComplete(request); - request.SetWordComplete(num_matches == 1); - return num_matches; +void CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + ArchSpec::AutoComplete(request); } -int CommandCompletions::VariablePath(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher) { - return Variable::AutoComplete(interpreter.GetExecutionContext(), request); +void CommandCompletions::VariablePath(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher) { + Variable::AutoComplete(interpreter.GetExecutionContext(), request); } CommandCompletions::Completer::Completer(CommandInterpreter &interpreter, @@ -368,8 +356,7 @@ lldb::SearchDepth CommandCompletions::SourceFileCompleter::GetDepth() { Searcher::CallbackReturn CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter, SymbolContext &context, - Address *addr, - bool complete) { + Address *addr) { if (context.comp_unit != nullptr) { if (m_include_support_files) { FileSpecList supporting_files = context.comp_unit->GetSupportFiles(); @@ -411,15 +398,14 @@ CommandCompletions::SourceFileCompleter::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnContinue; } -size_t -CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) { +void CommandCompletions::SourceFileCompleter::DoCompletion( + SearchFilter *filter) { filter->Search(*this); // Now convert the filelist to completions: for (size_t i = 0; i < m_matching_files.GetSize(); i++) { m_request.AddCompletion( m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); } - return m_request.GetNumberOfMatches(); } // SymbolCompleter @@ -448,7 +434,7 @@ CommandCompletions::SymbolCompleter::SymbolCompleter( pos = regex_str.insert(pos, '\\'); pos = find_if(pos + 2, regex_str.end(), regex_chars); } - m_regex.Compile(regex_str); + m_regex = RegularExpression(regex_str); } lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() { @@ -456,22 +442,24 @@ lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() { } Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr, - bool complete) { + SearchFilter &filter, SymbolContext &context, Address *addr) { if (context.module_sp) { SymbolContextList sc_list; const bool include_symbols = true; const bool include_inlines = true; - const bool append = true; context.module_sp->FindFunctions(m_regex, include_symbols, include_inlines, - append, sc_list); + sc_list); SymbolContext sc; // Now add the functions & symbols to the list - only add if unique: for (uint32_t i = 0; i < sc_list.GetSize(); i++) { if (sc_list.GetContextAtIndex(i, sc)) { ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); - if (!func_name.IsEmpty()) + // Ensure that the function name matches the regex. This is more than a + // sanity check. It is possible that the demangled function name does + // not start with the prefix, for example when it's in an anonymous + // namespace. + if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) m_match_set.insert(func_name); } } @@ -479,13 +467,11 @@ Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback( return Searcher::eCallbackReturnContinue; } -size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { +void CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); for (pos = m_match_set.begin(); pos != end; pos++) m_request.AddCompletion((*pos).GetCString()); - - return m_request.GetNumberOfMatches(); } // ModuleCompleter @@ -502,8 +488,7 @@ lldb::SearchDepth CommandCompletions::ModuleCompleter::GetDepth() { } Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr, - bool complete) { + SearchFilter &filter, SymbolContext &context, Address *addr) { if (context.module_sp) { const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString(); @@ -526,7 +511,6 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( return Searcher::eCallbackReturnContinue; } -size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { +void CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); - return m_request.GetNumberOfMatches(); } diff --git a/source/Commands/CommandObjectApropos.cpp b/source/Commands/CommandObjectApropos.cpp index 957de475569c..7ba0b250fbd5 100644 --- a/source/Commands/CommandObjectApropos.cpp +++ b/source/Commands/CommandObjectApropos.cpp @@ -44,7 +44,7 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { const size_t argc = args.GetArgumentCount(); if (argc == 1) { - auto search_word = args[0].ref; + auto search_word = args[0].ref(); if (!search_word.empty()) { // The bulk of the work must be done inside the Command Interpreter, // since the command dictionary is private. @@ -63,13 +63,7 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { if (commands_found.GetSize() > 0) { result.AppendMessageWithFormat( "The following commands may relate to '%s':\n", args[0].c_str()); - size_t max_len = 0; - - for (size_t i = 0; i < commands_found.GetSize(); ++i) { - size_t len = strlen(commands_found.GetStringAtIndex(i)); - if (len > max_len) - max_len = len; - } + const size_t max_len = commands_found.GetMaxStringLength(); for (size_t i = 0; i < commands_found.GetSize(); ++i) m_interpreter.OutputFormattedHelpText( @@ -85,7 +79,7 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { const bool dump_qualified_name = true; result.AppendMessageWithFormatv( "\nThe following settings variables may relate to '{0}': \n\n", - args[0].ref); + args[0].ref()); for (size_t i = 0; i < num_properties; ++i) properties[i]->DumpDescription( m_interpreter, result.GetOutputStream(), 0, dump_qualified_name); diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp index c33f3834cb13..ad699975b507 100644 --- a/source/Commands/CommandObjectBreakpoint.cpp +++ b/source/Commands/CommandObjectBreakpoint.cpp @@ -16,6 +16,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" @@ -44,21 +45,9 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp, // Modifiable Breakpoint Options #pragma mark Modify::CommandOptions -static constexpr OptionDefinition g_breakpoint_modify_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, - { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, - { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." }, - { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." }, - { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." }, - { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." }, - { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." }, - { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." }, - { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable the breakpoint." }, - { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disable the breakpoint." }, - { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." }, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_modify +#include "CommandOptions.inc" + class lldb_private::BreakpointOptionGroup : public OptionGroup { public: @@ -153,9 +142,7 @@ public: } break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -171,7 +158,7 @@ public: { if (!m_commands.empty()) { - auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>(); + auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); for (std::string &str : m_commands) cmd_data->user_source.AppendString(str); @@ -192,12 +179,9 @@ public: BreakpointOptions m_bp_opts; }; -static constexpr OptionDefinition g_breakpoint_dummy_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, " - "which prime new targets." }, - // clang-format on -}; + +#define LLDB_OPTIONS_breakpoint_dummy +#include "CommandOptions.inc" class BreakpointDummyOptionGroup : public OptionGroup { @@ -221,9 +205,7 @@ public: m_use_dummy = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -237,88 +219,8 @@ public: }; -// If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to -// update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. -#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_10) -#define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8)) -#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_2 & ~LLDB_OPT_SET_10) -#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_FROM_TO(1, 8) & ~LLDB_OPT_SET_2) -#define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9) -#define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8)) - -static constexpr OptionDefinition g_breakpoint_set_options[] = { - // clang-format off - { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option " - "multiple times to specify multiple shared libraries." }, - { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." }, - { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default " - "lldb only looks for files that are #included if they use the standard include " - "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are " - "#included, set target.inline-breakpoint-strategy to \"always\"." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." }, - - // Comment out this option for the moment, as we don't actually use it, but - // will in the future. This way users won't see it, but the infrastructure is - // left in place. - // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "<column>", - // "Set the breakpoint by source location at this particular column."}, - - { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to " - "a particular binary, then the address will be converted to a \"file\" " - "address, so that the breakpoint will track that binary+offset no matter where " - "the binary eventually loads. Alternately, if you also specify the module - " - "with the -s option - then the address will be treated as a file address in " - "that module, and resolved accordingly. Again, this will allow lldb to track " - "that offset on subsequent reloads. The module need not have been loaded at " - "the time you specify this breakpoint, and will get resolved when the module " - "is loaded." }, - { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make " - "one breakpoint for multiple names" }, - { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named " - "functions. Can be repeated multiple times." }, - { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means " - "namespaces and all arguments, and for Objective-C this means a full function " - "prototype with class and selector. Can be repeated multiple times to make " - "one breakpoint for multiple names." }, - { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to " - "make one breakpoint for multiple Selectors." }, - { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to " - "make one breakpoint for multiple methods." }, - { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find " - "the function name(s)." }, - { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be " - "ignored). Can be repeated multiple times to make one breakpoint for multiple " - "symbols." }, - { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched " - "against the source text in a source file or files specified with the -f " - "option. The -f option can be specified more than once. If no source files " - "are specified, uses the current \"default source file\". If you want to " - "match against all source files, pass the \"--all-files\" option." }, - { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "All files are searched for source pattern matches." }, - { LLDB_OPT_SET_11, true, "python-class", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that implement a scripted breakpoint." }, - { LLDB_OPT_SET_11, false, "python-class-key", 'k', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The key for a key/value pair passed to the class that implements a scripted breakpoint. Can be specified more than once." }, - { LLDB_OPT_SET_11, false, "python-class-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The value for the previous key in the pair passed to the class that implements a scripted breakpoint. Can be specified more than once." }, - { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without " - "options, on throw but not catch.)" }, - { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." }, - { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." }, - - // Don't add this option till it actually does something useful... - // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName, - // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" }, - - { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression " - "(note: currently only implemented for setting breakpoints on identifiers). " - "If not set the target.language setting is used." }, - { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. " - "If not set the target.skip-prologue setting is used." }, - { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." }, - { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. " - "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." }, - { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code " - "setting is used." }, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_set +#include "CommandOptions.inc" // CommandObjectBreakpointSet @@ -340,15 +242,18 @@ public: interpreter, "breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.", "breakpoint set <cmd-options>"), - m_bp_opts(), m_options() { - // We're picking up all the normal options, commands and disable. - m_all_options.Append(&m_bp_opts, - LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, - LLDB_OPT_SET_ALL); - m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); - m_all_options.Append(&m_options); - m_all_options.Finalize(); - } + m_bp_opts(), m_python_class_options("scripted breakpoint", 'P'), + m_options() { + // We're picking up all the normal options, commands and disable. + m_all_options.Append(&m_python_class_options, LLDB_OPT_SET_1, + LLDB_OPT_SET_11); + m_all_options.Append(&m_bp_opts, + LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4, + LLDB_OPT_SET_ALL); + m_all_options.Append(&m_dummy_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL); + m_all_options.Append(&m_options); + m_all_options.Finalize(); + } ~CommandObjectBreakpointSet() override = default; @@ -451,14 +356,6 @@ public: m_hardware = true; break; - case 'k': { - if (m_current_key.empty()) - m_current_key.assign(option_arg); - else - error.SetErrorStringWithFormat("Key: %s missing value.", - m_current_key.c_str()); - - } break; case 'K': { bool success; bool value; @@ -540,10 +437,6 @@ public: m_source_text_regexp.assign(option_arg); break; - case 'P': - m_python_class.assign(option_arg); - break; - case 'r': m_func_regexp.assign(option_arg); break; @@ -557,16 +450,6 @@ public: m_func_name_type_mask |= eFunctionNameTypeSelector; break; - case 'v': { - if (!m_current_key.empty()) { - m_extra_args_sp->AddStringItem(m_current_key, option_arg); - m_current_key.clear(); - } - else - error.SetErrorStringWithFormat("Value \"%s\" missing matching key.", - option_arg.str().c_str()); - } break; - case 'w': { bool success; m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); @@ -581,9 +464,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -611,8 +492,6 @@ public: m_exception_extra_args.Clear(); m_move_to_nearest_code = eLazyBoolCalculate; m_source_regex_func_names.clear(); - m_python_class.clear(); - m_extra_args_sp = std::make_shared<StructuredData::Dictionary>(); m_current_key.clear(); } @@ -644,21 +523,12 @@ public: Args m_exception_extra_args; LazyBool m_move_to_nearest_code; std::unordered_set<std::string> m_source_regex_func_names; - std::string m_python_class; - StructuredData::DictionarySP m_extra_args_sp; std::string m_current_key; }; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy); - - if (target == nullptr) { - result.AppendError("Invalid target. Must set target before setting " - "breakpoints (see 'target create' command)."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(m_dummy_options.m_use_dummy); // The following are the various types of breakpoints that could be set: // 1). -f -l -p [-s -g] (setting breakpoint by source location) @@ -673,7 +543,7 @@ protected: BreakpointSetType break_type = eSetTypeInvalid; - if (!m_options.m_python_class.empty()) + if (!m_python_class_options.GetClassName().empty()) break_type = eSetTypeScripted; else if (m_options.m_line_num != 0) break_type = eSetTypeFileAndLine; @@ -720,16 +590,11 @@ protected: // Only check for inline functions if LazyBool check_inlines = eLazyBoolCalculate; - bp_sp = target->CreateBreakpoint(&(m_options.m_modules), - file, - m_options.m_line_num, - m_options.m_column, - m_options.m_offset_addr, - check_inlines, - m_options.m_skip_prologue, - internal, - m_options.m_hardware, - m_options.m_move_to_nearest_code); + bp_sp = target.CreateBreakpoint( + &(m_options.m_modules), file, m_options.m_line_num, + m_options.m_column, m_options.m_offset_addr, check_inlines, + m_options.m_skip_prologue, internal, m_options.m_hardware, + m_options.m_move_to_nearest_code); } break; case eSetTypeAddress: // Breakpoint by address @@ -741,12 +606,11 @@ protected: if (num_modules_specified == 1) { const FileSpec *file_spec = m_options.m_modules.GetFileSpecPointerAtIndex(0); - bp_sp = target->CreateAddressInModuleBreakpoint(m_options.m_load_addr, - internal, file_spec, - m_options.m_hardware); + bp_sp = target.CreateAddressInModuleBreakpoint( + m_options.m_load_addr, internal, file_spec, m_options.m_hardware); } else if (num_modules_specified == 0) { - bp_sp = target->CreateBreakpoint(m_options.m_load_addr, internal, - m_options.m_hardware); + bp_sp = target.CreateBreakpoint(m_options.m_load_addr, internal, + m_options.m_hardware); } else { result.AppendError("Only one shared library can be specified for " "address breakpoints."); @@ -762,38 +626,29 @@ protected: if (name_type_mask == 0) name_type_mask = eFunctionNameTypeAuto; - bp_sp = target->CreateBreakpoint(&(m_options.m_modules), - &(m_options.m_filenames), - m_options.m_func_names, - name_type_mask, - m_options.m_language, - m_options.m_offset_addr, - m_options.m_skip_prologue, - internal, - m_options.m_hardware); + bp_sp = target.CreateBreakpoint( + &(m_options.m_modules), &(m_options.m_filenames), + m_options.m_func_names, name_type_mask, m_options.m_language, + m_options.m_offset_addr, m_options.m_skip_prologue, internal, + m_options.m_hardware); } break; case eSetTypeFunctionRegexp: // Breakpoint by regular expression function // name { RegularExpression regexp(m_options.m_func_regexp); - if (!regexp.IsValid()) { - char err_str[1024]; - regexp.GetErrorAsCString(err_str, sizeof(err_str)); + if (llvm::Error err = regexp.GetError()) { result.AppendErrorWithFormat( "Function name regular expression could not be compiled: \"%s\"", - err_str); + llvm::toString(std::move(err)).c_str()); result.SetStatus(eReturnStatusFailed); return false; } - bp_sp = target->CreateFuncRegexBreakpoint(&(m_options.m_modules), - &(m_options.m_filenames), - regexp, - m_options.m_language, - m_options.m_skip_prologue, - internal, - m_options.m_hardware); + bp_sp = target.CreateFuncRegexBreakpoint( + &(m_options.m_modules), &(m_options.m_filenames), std::move(regexp), + m_options.m_language, m_options.m_skip_prologue, internal, + m_options.m_hardware); } break; case eSetTypeSourceRegexp: // Breakpoint by regexp on source text. @@ -813,39 +668,29 @@ protected: } RegularExpression regexp(m_options.m_source_text_regexp); - if (!regexp.IsValid()) { - char err_str[1024]; - regexp.GetErrorAsCString(err_str, sizeof(err_str)); + if (llvm::Error err = regexp.GetError()) { result.AppendErrorWithFormat( "Source text regular expression could not be compiled: \"%s\"", - err_str); + llvm::toString(std::move(err)).c_str()); result.SetStatus(eReturnStatusFailed); return false; } - bp_sp = - target->CreateSourceRegexBreakpoint(&(m_options.m_modules), - &(m_options.m_filenames), - m_options - .m_source_regex_func_names, - regexp, - internal, - m_options.m_hardware, - m_options.m_move_to_nearest_code); + bp_sp = target.CreateSourceRegexBreakpoint( + &(m_options.m_modules), &(m_options.m_filenames), + m_options.m_source_regex_func_names, std::move(regexp), internal, + m_options.m_hardware, m_options.m_move_to_nearest_code); } break; case eSetTypeException: { Status precond_error; - bp_sp = target->CreateExceptionBreakpoint(m_options.m_exception_language, - m_options.m_catch_bp, - m_options.m_throw_bp, - internal, - &m_options - .m_exception_extra_args, - &precond_error); + bp_sp = target.CreateExceptionBreakpoint( + m_options.m_exception_language, m_options.m_catch_bp, + m_options.m_throw_bp, internal, &m_options.m_exception_extra_args, + &precond_error); if (precond_error.Fail()) { result.AppendErrorWithFormat( "Error setting extra exception arguments: %s", precond_error.AsCString()); - target->RemoveBreakpointByID(bp_sp->GetID()); + target.RemoveBreakpointByID(bp_sp->GetID()); result.SetStatus(eReturnStatusFailed); return false; } @@ -853,18 +698,15 @@ protected: case eSetTypeScripted: { Status error; - bp_sp = target->CreateScriptedBreakpoint(m_options.m_python_class, - &(m_options.m_modules), - &(m_options.m_filenames), - false, - m_options.m_hardware, - m_options.m_extra_args_sp, - &error); + bp_sp = target.CreateScriptedBreakpoint( + m_python_class_options.GetClassName().c_str(), &(m_options.m_modules), + &(m_options.m_filenames), false, m_options.m_hardware, + m_python_class_options.GetStructuredData(), &error); if (error.Fail()) { result.AppendErrorWithFormat( "Error setting extra exception arguments: %s", error.AsCString()); - target->RemoveBreakpointByID(bp_sp->GetID()); + target.RemoveBreakpointByID(bp_sp->GetID()); result.SetStatus(eReturnStatusFailed); return false; } @@ -880,11 +722,11 @@ protected: if (!m_options.m_breakpoint_names.empty()) { Status name_error; for (auto name : m_options.m_breakpoint_names) { - target->AddNameToBreakpoint(bp_sp, name.c_str(), name_error); + target.AddNameToBreakpoint(bp_sp, name.c_str(), name_error); if (name_error.Fail()) { result.AppendErrorWithFormat("Invalid breakpoint name: %s", name.c_str()); - target->RemoveBreakpointByID(bp_sp->GetID()); + target.RemoveBreakpointByID(bp_sp->GetID()); result.SetStatus(eReturnStatusFailed); return false; } @@ -897,7 +739,7 @@ protected: const bool show_locations = false; bp_sp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations); - if (target == GetDebugger().GetDummyTarget()) + if (&target == &GetDummyTarget()) output_stream.Printf("Breakpoint set in dummy target, will get copied " "into future targets.\n"); else { @@ -919,12 +761,12 @@ protected: } private: - bool GetDefaultFile(Target *target, FileSpec &file, + bool GetDefaultFile(Target &target, FileSpec &file, CommandReturnObject &result) { uint32_t default_line; // First use the Source Manager's default file. Then use the current stack // frame's file. - if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) { + if (!target.GetSourceManager().GetDefaultFileAndLine(file, default_line)) { StackFrame *cur_frame = m_exe_ctx.GetFramePtr(); if (cur_frame == nullptr) { result.AppendError( @@ -954,6 +796,7 @@ private: BreakpointOptionGroup m_bp_opts; BreakpointDummyOptionGroup m_dummy_options; + OptionGroupPythonClassWithDict m_python_class_options; CommandOptions m_options; OptionGroupOptions m_all_options; }; @@ -993,20 +836,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(m_dummy_opts.m_use_dummy); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::disablePerm); if (result.Succeeded()) { @@ -1016,7 +854,7 @@ protected: if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { Breakpoint *bp = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { BreakpointLocation *location = bp->FindLocationByID(cur_bp_id.GetLocationID()).get(); @@ -1062,17 +900,12 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); @@ -1084,7 +917,7 @@ protected: if (command.empty()) { // No breakpoint selected; enable all currently set breakpoints. - target->EnableAllowedBreakpoints(); + target.EnableAllowedBreakpoints(); result.AppendMessageWithFormat("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); @@ -1093,7 +926,7 @@ protected: // Particular breakpoint selected; enable that breakpoint. BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::disablePerm); if (result.Succeeded()) { @@ -1105,7 +938,7 @@ protected: if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { Breakpoint *breakpoint = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { BreakpointLocation *location = breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); @@ -1175,17 +1008,11 @@ the second re-enables the first location."); protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } - + Target &target = GetSelectedOrDummyTarget(); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { @@ -1196,7 +1023,7 @@ protected: if (command.empty()) { // No breakpoint selected; disable all currently set breakpoints. - target->DisableAllowedBreakpoints(); + target.DisableAllowedBreakpoints(); result.AppendMessageWithFormat("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints); @@ -1206,7 +1033,7 @@ protected: BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::disablePerm); if (result.Succeeded()) { @@ -1218,7 +1045,7 @@ protected: if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { Breakpoint *breakpoint = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { BreakpointLocation *location = breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); @@ -1245,12 +1072,8 @@ protected: // CommandObjectBreakpointList #pragma mark List::CommandOptions -static constexpr OptionDefinition g_breakpoint_list_options[] = { - // FIXME: We need to add an "internal" command, and then add this sort of - // thing to it. But I need to see it for now, and don't want to wait. #define LLDB_OPTIONS_breakpoint_list #include "CommandOptions.inc" -}; #pragma mark List @@ -1311,9 +1134,7 @@ public: m_internal = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1339,18 +1160,12 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - - if (target == nullptr) { - result.AppendError("Invalid target. No current target or breakpoints."); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return true; - } + Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); const BreakpointList &breakpoints = - target->GetBreakpointList(m_options.m_internal); + target.GetBreakpointList(m_options.m_internal); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList(m_options.m_internal).GetListMutex(lock); + target.GetBreakpointList(m_options.m_internal).GetListMutex(lock); size_t num_breakpoints = breakpoints.GetSize(); @@ -1376,14 +1191,14 @@ protected: // Particular breakpoints selected; show info about that breakpoint. BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::listPerm); if (result.Succeeded()) { for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i) { BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); Breakpoint *breakpoint = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); AddBreakpointDescription(&output_stream, breakpoint, m_options.m_level); } @@ -1404,12 +1219,8 @@ private: // CommandObjectBreakpointClear #pragma mark Clear::CommandOptions -static constexpr OptionDefinition g_breakpoint_clear_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." } - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_clear +#include "CommandOptions.inc" #pragma mark Clear @@ -1449,9 +1260,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1474,12 +1283,7 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(); // The following are the various types of breakpoints that could be // cleared: @@ -1491,9 +1295,9 @@ protected: break_type = eClearTypeFileAndLine; std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - BreakpointList &breakpoints = target->GetBreakpointList(); + BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); // Early return if there's no breakpoint at all. @@ -1527,7 +1331,7 @@ protected: if (loc_coll.GetSize() == 0) { bp->GetDescription(&ss, lldb::eDescriptionLevelBrief); ss.EOL(); - target->RemoveBreakpointByID(bp->GetID()); + target.RemoveBreakpointByID(bp->GetID()); ++num_cleared; } } @@ -1557,12 +1361,8 @@ private: }; // CommandObjectBreakpointDelete -static constexpr OptionDefinition g_breakpoint_delete_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." }, - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_delete +#include "CommandOptions.inc" #pragma mark Delete @@ -1607,9 +1407,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1631,18 +1429,12 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); @@ -1659,7 +1451,7 @@ protected: true)) { result.AppendMessage("Operation cancelled..."); } else { - target->RemoveAllowedBreakpoints(); + target.RemoveAllowedBreakpoints(); result.AppendMessageWithFormat( "All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : ""); @@ -1669,7 +1461,7 @@ protected: // Particular breakpoint selected; disable that breakpoint. BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::deletePerm); if (result.Succeeded()) { @@ -1682,7 +1474,7 @@ protected: if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { Breakpoint *breakpoint = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); BreakpointLocation *location = breakpoint->FindLocationByID(cur_bp_id.GetLocationID()).get(); // It makes no sense to try to delete individual locations, so we @@ -1692,7 +1484,7 @@ protected: ++disable_count; } } else { - target->RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); + target.RemoveBreakpointByID(cur_bp_id.GetBreakpointID()); ++delete_count; } } @@ -1711,15 +1503,9 @@ private: }; // CommandObjectBreakpointName +#define LLDB_OPTIONS_breakpoint_name +#include "CommandOptions.inc" -static constexpr OptionDefinition g_breakpoint_name_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, - {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, - {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, - {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A help string describing the purpose of this name."}, - // clang-format on -}; class BreakpointNameOptionGroup : public OptionGroup { public: BreakpointNameOptionGroup() @@ -1760,9 +1546,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -1781,13 +1565,8 @@ public: OptionValueString m_help_string; }; -static constexpr OptionDefinition g_breakpoint_access_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."}, - {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."}, - {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."}, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_access +#include "CommandOptions.inc" class BreakpointAccessOptionGroup : public OptionGroup { public: @@ -1835,7 +1614,8 @@ public: "invalid boolean value '%s' passed for -L option", option_arg.str().c_str()); } break; - + default: + llvm_unreachable("Unimplemented option"); } return error; @@ -1897,23 +1677,16 @@ protected: result.SetStatus(eReturnStatusFailed); return false; } - - Target *target = - GetSelectedOrDummyTarget(false); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(false); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); // Make a pass through first to see that all the names are legal. for (auto &entry : command.entries()) { Status error; - if (!BreakpointID::StringIsBreakpointName(entry.ref, error)) + if (!BreakpointID::StringIsBreakpointName(entry.ref(), error)) { result.AppendErrorWithFormat("Invalid breakpoint name: %s - %s", entry.c_str(), error.AsCString()); @@ -1927,7 +1700,7 @@ protected: if (m_bp_id.m_breakpoint.OptionWasSet()) { lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value(); - bp_sp = target->GetBreakpointByID(bp_id); + bp_sp = target.GetBreakpointByID(bp_id); if (!bp_sp) { result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", @@ -1940,18 +1713,17 @@ protected: Status error; for (auto &entry : command.entries()) { ConstString name(entry.c_str()); - BreakpointName *bp_name = target->FindBreakpointName(name, true, error); + BreakpointName *bp_name = target.FindBreakpointName(name, true, error); if (!bp_name) continue; if (m_bp_id.m_help_string.OptionWasSet()) bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); if (bp_sp) - target->ConfigureBreakpointName(*bp_name, - *bp_sp->GetOptions(), + target.ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(), m_access_options.GetPermissions()); else - target->ConfigureBreakpointName(*bp_name, + target.ConfigureBreakpointName(*bp_name, m_bp_opts.GetBreakpointOptions(), m_access_options.GetPermissions()); } @@ -1996,19 +1768,13 @@ protected: return false; } - Target *target = + Target &target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } - std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { @@ -2020,7 +1786,7 @@ protected: // Particular breakpoint selected; disable that breakpoint. BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::listPerm); if (result.Succeeded()) { @@ -2037,7 +1803,7 @@ protected: lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); - target->AddNameToBreakpoint(bp_sp, bp_name, error); + target.AddNameToBreakpoint(bp_sp, bp_name, error); } } @@ -2081,19 +1847,13 @@ protected: return false; } - Target *target = + Target &target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } - std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { @@ -2105,7 +1865,7 @@ protected: // Particular breakpoint selected; disable that breakpoint. BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::deletePerm); if (result.Succeeded()) { @@ -2120,7 +1880,7 @@ protected: lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID(); BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id); - target->RemoveNameFromBreakpoint(bp_sp, bp_name); + target.RemoveNameFromBreakpoint(bp_sp, bp_name); } } @@ -2151,19 +1911,12 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = + Target &target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue()); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } - - std::vector<std::string> name_list; if (command.empty()) { - target->GetBreakpointNames(name_list); + target.GetBreakpointNames(name_list); } else { for (const Args::ArgEntry &arg : command) { @@ -2178,9 +1931,8 @@ protected: const char *name = name_str.c_str(); // First print out the options for the name: Status error; - BreakpointName *bp_name = target->FindBreakpointName(ConstString(name), - false, - error); + BreakpointName *bp_name = + target.FindBreakpointName(ConstString(name), false, error); if (bp_name) { StreamString s; @@ -2191,9 +1943,9 @@ protected: } std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); - BreakpointList &breakpoints = target->GetBreakpointList(); + BreakpointList &breakpoints = target.GetBreakpointList(); bool any_set = false; for (BreakpointSP bp_sp : breakpoints.Breakpoints()) { if (bp_sp->MatchesName(name)) { @@ -2246,12 +1998,8 @@ public: // CommandObjectBreakpointRead #pragma mark Read::CommandOptions -static constexpr OptionDefinition g_breakpoint_read_options[] = { - // clang-format off - {LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." }, - {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."}, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_read +#include "CommandOptions.inc" #pragma mark Read @@ -2301,9 +2049,7 @@ public: break; } default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -2326,21 +2072,16 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); FileSpec input_spec(m_options.m_filename); FileSystem::Instance().Resolve(input_spec); BreakpointIDList new_bps; - Status error = target->CreateBreakpointsFromFile( - input_spec, m_options.m_names, new_bps); + Status error = target.CreateBreakpointsFromFile(input_spec, + m_options.m_names, new_bps); if (!error.Success()) { result.AppendError(error.AsCString()); @@ -2358,7 +2099,7 @@ protected: result.AppendMessage("New breakpoints:"); for (size_t i = 0; i < num_breakpoints; ++i) { BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i); - Breakpoint *bp = target->GetBreakpointList() + Breakpoint *bp = target.GetBreakpointList() .FindBreakpointByID(bp_id.GetBreakpointID()) .get(); if (bp) @@ -2375,12 +2116,8 @@ private: // CommandObjectBreakpointWrite #pragma mark Write::CommandOptions -static constexpr OptionDefinition g_breakpoint_write_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." }, - { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."}, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_write +#include "CommandOptions.inc" #pragma mark Write class CommandObjectBreakpointWrite : public CommandObjectParsed { @@ -2423,9 +2160,7 @@ public: m_append = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -2448,20 +2183,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target == nullptr) { - result.AppendError("Invalid target. No existing target or breakpoints."); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(); std::unique_lock<std::recursive_mutex> lock; - target->GetBreakpointList().GetListMutex(lock); + target.GetBreakpointList().GetListMutex(lock); BreakpointIDList valid_bp_ids; if (!command.empty()) { CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::listPerm); if (!result.Succeeded()) { @@ -2471,8 +2201,8 @@ protected: } FileSpec file_spec(m_options.m_filename); FileSystem::Instance().Resolve(file_spec); - Status error = target->SerializeBreakpointsToFile(file_spec, valid_bp_ids, - m_options.m_append); + Status error = target.SerializeBreakpointsToFile(file_spec, valid_bp_ids, + m_options.m_append); if (!error.Success()) { result.AppendErrorWithFormat("error serializing breakpoints: %s.", error.AsCString()); diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index 3f9d83cd86a8..a6bcd1d8dc32 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -26,33 +26,33 @@ using namespace lldb; using namespace lldb_private; -// CommandObjectBreakpointCommandAdd - // FIXME: "script-type" needs to have its contents determined dynamically, so -// somebody can add a new scripting -// language to lldb and have it pickable here without having to change this -// enumeration by hand and rebuild lldb proper. - +// somebody can add a new scripting language to lldb and have it pickable here +// without having to change this enumeration by hand and rebuild lldb proper. static constexpr OptionEnumValueElement g_script_option_enumeration[] = { - {eScriptLanguageNone, "command", - "Commands are in the lldb command interpreter language"}, - {eScriptLanguagePython, "python", "Commands are in the Python language."}, - {eSortOrderByName, "default-script", - "Commands are in the default scripting language."} }; + { + eScriptLanguageNone, + "command", + "Commands are in the lldb command interpreter language", + }, + { + eScriptLanguagePython, + "python", + "Commands are in the Python language.", + }, + { + eSortOrderByName, + "default-script", + "Commands are in the default scripting language.", + }, +}; static constexpr OptionEnumValues ScriptOptionEnum() { return OptionEnumValues(g_script_option_enumeration); } -static constexpr OptionDefinition g_breakpoint_add_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate." }, - { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_command_add +#include "CommandOptions.inc" class CommandObjectBreakpointCommandAdd : public CommandObjectParsed, public IOHandlerDelegateMultiline { @@ -221,7 +221,7 @@ are no syntax errors may indicate that a function was declared but never called. Options *GetOptions() override { return &m_options; } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString(g_reader_instructions); output_sp->Flush(); @@ -238,7 +238,7 @@ are no syntax errors may indicate that a function was declared but never called. if (!bp_options) continue; - auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>(); + auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); cmd_data->user_source.SplitIntoLines(line.c_str(), line.size()); bp_options->SetCommandDataCallback(cmd_data); } @@ -260,7 +260,7 @@ are no syntax errors may indicate that a function was declared but never called. SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec, const char *oneliner) { for (auto bp_options : bp_options_vec) { - auto cmd_data = llvm::make_unique<BreakpointOptions::CommandData>(); + auto cmd_data = std::make_unique<BreakpointOptions::CommandData>(); cmd_data->user_source.AppendString(oneliner); cmd_data->stop_on_error = m_options.m_stop_on_error; @@ -291,7 +291,8 @@ are no syntax errors may indicate that a function was declared but never called. case 's': m_script_language = (lldb::ScriptLanguage)OptionArgParser::ToOptionEnum( - option_arg, g_breakpoint_add_options[option_idx].enum_values, + option_arg, + g_breakpoint_command_add_options[option_idx].enum_values, eScriptLanguageNone, error); if (m_script_language == eScriptLanguagePython || @@ -323,7 +324,7 @@ are no syntax errors may indicate that a function was declared but never called. break; default: - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -341,7 +342,7 @@ are no syntax errors may indicate that a function was declared but never called. } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_breakpoint_add_options); + return llvm::makeArrayRef(g_breakpoint_command_add_options); } // Instance variables to hold the values for command options. @@ -360,16 +361,9 @@ are no syntax errors may indicate that a function was declared but never called. protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); + Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - if (target == nullptr) { - result.AppendError("There is not a current executable; there are no " - "breakpoints to which to add commands"); - result.SetStatus(eReturnStatusFailed); - return false; - } - - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { @@ -388,7 +382,7 @@ protected: BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::listPerm); m_bp_options_vec.clear(); @@ -400,7 +394,7 @@ protected: BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { Breakpoint *bp = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); BreakpointOptions *bp_options = nullptr; if (cur_bp_id.GetLocationID() == LLDB_INVALID_BREAK_ID) { // This breakpoint does not have an associated location. @@ -469,11 +463,8 @@ const char *CommandObjectBreakpointCommandAdd::g_reader_instructions = // CommandObjectBreakpointCommandDelete -static constexpr OptionDefinition g_breakpoint_delete_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, - // clang-format on -}; +#define LLDB_OPTIONS_breakpoint_command_delete +#include "CommandOptions.inc" class CommandObjectBreakpointCommandDelete : public CommandObjectParsed { public: @@ -518,9 +509,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -531,7 +520,7 @@ public: } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_breakpoint_delete_options); + return llvm::makeArrayRef(g_breakpoint_command_delete_options); } // Instance variables to hold the values for command options. @@ -540,16 +529,9 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - - if (target == nullptr) { - result.AppendError("There is not a current executable; there are no " - "breakpoints from which to delete commands"); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - const BreakpointList &breakpoints = target->GetBreakpointList(); + const BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); if (num_breakpoints == 0) { @@ -567,7 +549,7 @@ protected: BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, &target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::listPerm); if (result.Succeeded()) { @@ -576,7 +558,7 @@ protected: BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex(i); if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID) { Breakpoint *bp = - target->GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); + target.GetBreakpointByID(cur_bp_id.GetBreakpointID()).get(); if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID) { BreakpointLocationSP bp_loc_sp( bp->FindLocationByID(cur_bp_id.GetLocationID())); @@ -607,10 +589,10 @@ private: class CommandObjectBreakpointCommandList : public CommandObjectParsed { public: CommandObjectBreakpointCommandList(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "list", "List the script or set of " - "commands to be executed when " - "the breakpoint is hit.", - nullptr) { + : CommandObjectParsed(interpreter, "list", + "List the script or set of commands to be " + "executed when the breakpoint is hit.", + nullptr, eCommandRequiresTarget) { CommandArgumentEntry arg; CommandArgumentData bp_id_arg; @@ -630,14 +612,7 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - - if (target == nullptr) { - result.AppendError("There is not a current executable; there are no " - "breakpoints for which to list commands"); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target *target = &GetSelectedTarget(); const BreakpointList &breakpoints = target->GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); @@ -657,7 +632,7 @@ protected: BreakpointIDList valid_bp_ids; CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, target, result, &valid_bp_ids, + command, target, result, &valid_bp_ids, BreakpointName::Permissions::PermissionKinds::listPerm); if (result.Succeeded()) { diff --git a/source/Commands/CommandObjectBugreport.cpp b/source/Commands/CommandObjectBugreport.cpp deleted file mode 100644 index 515cc9a113b1..000000000000 --- a/source/Commands/CommandObjectBugreport.cpp +++ /dev/null @@ -1,124 +0,0 @@ -//===-- CommandObjectBugreport.cpp ------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectBugreport.h" - -#include <cstdio> - - -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/OptionGroupOutputFile.h" -#include "lldb/Target/Thread.h" - -using namespace lldb; -using namespace lldb_private; - -// "bugreport unwind" - -class CommandObjectBugreportUnwind : public CommandObjectParsed { -public: - CommandObjectBugreportUnwind(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "bugreport unwind", - "Create a bugreport for a bug in the stack unwinding code.", - nullptr), - m_option_group(), m_outfile_options() { - m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL, - LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3); - m_option_group.Finalize(); - } - - ~CommandObjectBugreportUnwind() override {} - - Options *GetOptions() override { return &m_option_group; } - -protected: - bool DoExecute(Args &command, CommandReturnObject &result) override { - StringList commands; - commands.AppendString("thread backtrace"); - - Thread *thread = m_exe_ctx.GetThreadPtr(); - if (thread) { - char command_buffer[256]; - - uint32_t frame_count = thread->GetStackFrameCount(); - for (uint32_t i = 0; i < frame_count; ++i) { - StackFrameSP frame = thread->GetStackFrameAtIndex(i); - lldb::addr_t pc = frame->GetStackID().GetPC(); - - snprintf(command_buffer, sizeof(command_buffer), - "disassemble --bytes --address 0x%" PRIx64, pc); - commands.AppendString(command_buffer); - - snprintf(command_buffer, sizeof(command_buffer), - "image show-unwind --address 0x%" PRIx64, pc); - commands.AppendString(command_buffer); - } - } - - const FileSpec &outfile_spec = - m_outfile_options.GetFile().GetCurrentValue(); - if (outfile_spec) { - - uint32_t open_options = - File::eOpenOptionWrite | File::eOpenOptionCanCreate | - File::eOpenOptionAppend | File::eOpenOptionCloseOnExec; - - const bool append = m_outfile_options.GetAppend().GetCurrentValue(); - if (!append) - open_options |= File::eOpenOptionTruncate; - - StreamFileSP outfile_stream = std::make_shared<StreamFile>(); - File &file = outfile_stream->GetFile(); - Status error = - FileSystem::Instance().Open(file, outfile_spec, open_options); - if (error.Fail()) { - auto path = outfile_spec.GetPath(); - result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n", - path.c_str(), append ? "append" : "write", - error.AsCString()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - result.SetImmediateOutputStream(outfile_stream); - } - - CommandInterpreterRunOptions options; - options.SetStopOnError(false); - options.SetEchoCommands(true); - options.SetPrintResults(true); - options.SetPrintErrors(true); - options.SetAddToHistory(false); - m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result); - - return result.Succeeded(); - } - -private: - OptionGroupOptions m_option_group; - OptionGroupOutputFile m_outfile_options; -}; - -#pragma mark CommandObjectMultiwordBugreport - -// CommandObjectMultiwordBugreport - -CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport( - CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "bugreport", - "Commands for creating domain-specific bug reports.", - "bugreport <subcommand> [<subcommand-options>]") { - - LoadSubCommand( - "unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter))); -} - -CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport() {} diff --git a/source/Commands/CommandObjectBugreport.h b/source/Commands/CommandObjectBugreport.h deleted file mode 100644 index 24ce6d237d56..000000000000 --- a/source/Commands/CommandObjectBugreport.h +++ /dev/null @@ -1,27 +0,0 @@ -//===-- CommandObjectBugreport.h --------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectBugreport_h_ -#define liblldb_CommandObjectBugreport_h_ - -#include "lldb/Interpreter/CommandObjectMultiword.h" - -namespace lldb_private { - -// CommandObjectMultiwordBugreport - -class CommandObjectMultiwordBugreport : public CommandObjectMultiword { -public: - CommandObjectMultiwordBugreport(CommandInterpreter &interpreter); - - ~CommandObjectMultiwordBugreport() override; -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectBugreport_h_ diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index 4092e76be6ac..259affbe6e0a 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -31,14 +31,8 @@ using namespace lldb_private; // CommandObjectCommandsSource -static constexpr OptionDefinition g_history_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "How many history commands to print." }, - { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." }, - { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." }, - { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeBoolean, "Clears the current command history." }, - // clang-format on -}; +#define LLDB_OPTIONS_history +#include "CommandOptions.inc" class CommandObjectCommandsHistory : public CommandObjectParsed { public: @@ -91,9 +85,7 @@ protected: m_clear.SetOptionWasSet(); break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -188,13 +180,8 @@ protected: // CommandObjectCommandsSource -static constexpr OptionDefinition g_source_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on error." }, - { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on continue." }, - { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true don't echo commands while executing." }, - // clang-format on -}; +#define LLDB_OPTIONS_source +#include "CommandOptions.inc" class CommandObjectCommandsSource : public CommandObjectParsed { public: @@ -226,13 +213,12 @@ public: return ""; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_options; } @@ -265,9 +251,7 @@ protected: break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -299,7 +283,7 @@ protected: return false; } - FileSpec cmd_file(command[0].ref); + FileSpec cmd_file(command[0].ref()); FileSystem::Instance().Resolve(cmd_file); ExecutionContext *exe_ctx = nullptr; // Just use the default context. @@ -343,12 +327,8 @@ protected: #pragma mark CommandObjectCommandsAlias // CommandObjectCommandsAlias -static constexpr OptionDefinition g_alias_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Help text for this command" }, - { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Long help text for this command" }, - // clang-format on -}; +#define LLDB_OPTIONS_alias +#include "CommandOptions.inc" static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" @@ -386,9 +366,7 @@ protected: break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -568,7 +546,7 @@ protected: // Get the alias command. - auto alias_command = args[0].ref; + auto alias_command = args[0].ref(); if (alias_command.startswith("-")) { result.AppendError("aliases starting with a dash are not supported"); if (alias_command == "--help" || alias_command == "--long-help") { @@ -675,8 +653,8 @@ protected: } // Save these in std::strings since we're going to shift them off. - const std::string alias_command(args[0].ref); - const std::string actual_command(args[1].ref); + const std::string alias_command(args[0].ref()); + const std::string actual_command(args[1].ref()); args.Shift(); // Shift the alias command word off the argument vector. args.Shift(); // Shift the old command word off the argument vector. @@ -708,7 +686,7 @@ protected: OptionArgVectorSP(new OptionArgVector); while (cmd_obj->IsMultiwordObject() && !args.empty()) { - auto sub_command = args[0].ref; + auto sub_command = args[0].ref(); assert(!sub_command.empty()); subcommand_obj_sp = cmd_obj->GetSubcommandSP(sub_command); if (!subcommand_obj_sp) { @@ -802,7 +780,7 @@ protected: return false; } - auto command_name = args[0].ref; + auto command_name = args[0].ref(); cmd_obj = m_interpreter.GetCommandObject(command_name); if (!cmd_obj) { result.AppendErrorWithFormat( @@ -881,9 +859,10 @@ protected: "defined regular expression command names", GetCommandName().str().c_str()); result.SetStatus(eReturnStatusFailed); + return false; } - auto command_name = args[0].ref; + auto command_name = args[0].ref(); if (!m_interpreter.CommandExists(command_name)) { StreamString error_msg_stream; const bool generate_upropos = true; @@ -911,12 +890,8 @@ protected: // CommandObjectCommandsAddRegex -static constexpr OptionDefinition g_regex_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The help text to display for this command." }, - { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." }, - // clang-format on -}; +#define LLDB_OPTIONS_regex +#include "CommandOptions.inc" #pragma mark CommandObjectCommandsAddRegex @@ -970,7 +945,7 @@ a number follows 'f':" protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString("Enter one or more sed substitution commands in " "the form: 's/<regex>/<subst>/'.\nTerminate the " @@ -985,11 +960,9 @@ protected: if (m_regex_cmd_up) { StringList lines; if (lines.SplitIntoLines(data)) { - const size_t num_lines = lines.GetSize(); bool check_only = false; - for (size_t i = 0; i < num_lines; ++i) { - llvm::StringRef bytes_strref(lines[i]); - Status error = AppendRegexSubstitution(bytes_strref, check_only); + for (const std::string &line : lines) { + Status error = AppendRegexSubstitution(line, check_only); if (error.Fail()) { if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) { StreamSP out_stream = GetDebugger().GetAsyncOutputStream(); @@ -1015,8 +988,8 @@ protected: } Status error; - auto name = command[0].ref; - m_regex_cmd_up = llvm::make_unique<CommandObjectRegexCommand>( + auto name = command[0].ref(); + m_regex_cmd_up = std::make_unique<CommandObjectRegexCommand>( m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 10, 0, true); @@ -1040,7 +1013,7 @@ protected: } else { for (auto &entry : command.entries().drop_front()) { bool check_only = false; - error = AppendRegexSubstitution(entry.ref, check_only); + error = AppendRegexSubstitution(entry.ref(), check_only); if (error.Fail()) break; } @@ -1183,9 +1156,7 @@ private: m_syntax.assign(option_arg); break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1315,8 +1286,6 @@ public: bool IsRemovable() const override { return true; } - StructuredData::GenericSP GetImplementingObject() { return m_cmd_obj_sp; } - ScriptedCommandSynchronicity GetSynchronicity() { return m_synchro; } llvm::StringRef GetHelp() override { @@ -1385,12 +1354,8 @@ private: }; // CommandObjectCommandsScriptImport - -static constexpr OptionDefinition g_script_import_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." }, - // clang-format on -}; +#define LLDB_OPTIONS_script_import +#include "CommandOptions.inc" class CommandObjectCommandsScriptImport : public CommandObjectParsed { public: @@ -1415,13 +1380,12 @@ public: ~CommandObjectCommandsScriptImport() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_options; } @@ -1443,9 +1407,7 @@ protected: m_allow_reload = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1509,25 +1471,29 @@ protected: // CommandObjectCommandsScriptAdd static constexpr OptionEnumValueElement g_script_synchro_type[] = { - {eScriptedCommandSynchronicitySynchronous, "synchronous", - "Run synchronous"}, - {eScriptedCommandSynchronicityAsynchronous, "asynchronous", - "Run asynchronous"}, - {eScriptedCommandSynchronicityCurrentValue, "current", - "Do not alter current setting"} }; + { + eScriptedCommandSynchronicitySynchronous, + "synchronous", + "Run synchronous", + }, + { + eScriptedCommandSynchronicityAsynchronous, + "asynchronous", + "Run asynchronous", + }, + { + eScriptedCommandSynchronicityCurrentValue, + "current", + "Do not alter current setting", + }, +}; static constexpr OptionEnumValues ScriptSynchroType() { return OptionEnumValues(g_script_synchro_type); } -static constexpr OptionDefinition g_script_add_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." }, - { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." }, - { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "The help text to display for this command." }, - { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, ScriptSynchroType(), 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." }, - // clang-format on -}; +#define LLDB_OPTIONS_script_add +#include "CommandOptions.inc" class CommandObjectCommandsScriptAdd : public CommandObjectParsed, public IOHandlerDelegateMultiline { @@ -1593,9 +1559,7 @@ protected: option_arg.str().c_str()); break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1621,7 +1585,7 @@ protected: }; void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString(g_python_command_instructions); output_sp->Flush(); @@ -1630,7 +1594,7 @@ protected: void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - StreamFileSP error_sp = io_handler.GetErrorStreamFile(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (interpreter) { @@ -1692,7 +1656,7 @@ protected: } // Store the options in case we get multi-line input - m_cmd_name = command[0].ref; + m_cmd_name = command[0].ref(); m_short_help.assign(m_options.m_short_help); m_synchronicity = m_options.m_synchronicity; @@ -1761,6 +1725,12 @@ public: ~CommandObjectCommandsScriptList() override = default; bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.GetArgumentCount() != 0) { + result.AppendError("'command script list' doesn't take any arguments"); + result.SetStatus(eReturnStatusFailed); + return false; + } + m_interpreter.GetHelp(result, CommandInterpreter::eCommandTypesUserDef); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1781,6 +1751,12 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.GetArgumentCount() != 0) { + result.AppendError("'command script clear' doesn't take any arguments"); + result.SetStatus(eReturnStatusFailed); + return false; + } + m_interpreter.RemoveAllUser(); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1822,7 +1798,7 @@ protected: return false; } - auto cmd_name = command[0].ref; + auto cmd_name = command[0].ref(); if (cmd_name.empty() || !m_interpreter.HasUserCommands() || !m_interpreter.UserCommandExists(cmd_name)) { diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp index 5972555b2499..69e2d757b5fe 100644 --- a/source/Commands/CommandObjectDisassemble.cpp +++ b/source/Commands/CommandObjectDisassemble.cpp @@ -30,32 +30,8 @@ using namespace lldb; using namespace lldb_private; -static constexpr OptionDefinition g_disassemble_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "bytes", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show opcode bytes when disassembling." }, - { LLDB_OPT_SET_ALL, false, "context", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of context lines of source to show." }, - { LLDB_OPT_SET_ALL, false, "mixed", 'm', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable mixed source and assembly display." }, - { LLDB_OPT_SET_ALL, false, "raw", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print raw disassembly with no symbol information." }, - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use." }, - { LLDB_OPT_SET_ALL, false, "flavor", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. " - "Currently the only valid options are default, and for Intel " - "architectures, att and intel." }, - { LLDB_OPT_SET_ALL, false, "arch", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Specify the architecture to use from cross disassembly." }, - { LLDB_OPT_SET_1 | - LLDB_OPT_SET_2, true, "start-address", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to start disassembling." }, - { LLDB_OPT_SET_1, false, "end-address", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling." }, - { LLDB_OPT_SET_2 | - LLDB_OPT_SET_3 | - LLDB_OPT_SET_4 | - LLDB_OPT_SET_5, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of instructions to display." }, - { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name." }, - { LLDB_OPT_SET_4, false, "frame", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble from the start of the current frame's function." }, - { LLDB_OPT_SET_5, false, "pc", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble around the current pc." }, - { LLDB_OPT_SET_6, false, "line", 'l', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line " - "table information, else disassemble around the pc." }, - { LLDB_OPT_SET_7, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address." }, - // clang-format on -}; +#define LLDB_OPTIONS_disassemble +#include "CommandOptions.inc" CommandObjectDisassemble::CommandOptions::CommandOptions() : Options(), num_lines_context(0), num_instructions(0), func_name(), @@ -171,9 +147,7 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue( } break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -238,20 +212,15 @@ CommandObjectDisassemble::CommandObjectDisassemble( "Disassemble specified instructions in the current target. " "Defaults to the current function for the current thread and " "stack frame.", - "disassemble [<cmd-options>]"), + "disassemble [<cmd-options>]", eCommandRequiresTarget), m_options() {} CommandObjectDisassemble::~CommandObjectDisassemble() = default; bool CommandObjectDisassemble::DoExecute(Args &command, CommandReturnObject &result) { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target *target = &GetSelectedTarget(); + if (!m_options.arch.IsValid()) m_options.arch = target->GetArchitecture(); @@ -541,7 +510,7 @@ bool CommandObjectDisassemble::DoExecute(Args &command, } else { result.AppendErrorWithFormat( "Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", - m_options.start_addr); + cur_range.GetBaseAddress().GetLoadAddress(target)); result.SetStatus(eReturnStatusFailed); } if (print_sc_header) diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index 29e4ab695522..9bafdc149804 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -38,34 +38,24 @@ CommandObjectExpression::CommandOptions::CommandOptions() : OptionGroup() {} CommandObjectExpression::CommandOptions::~CommandOptions() = default; static constexpr OptionEnumValueElement g_description_verbosity_type[] = { - {eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", - "Only show the description string"}, - {eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", - "Show the full output, including persistent variable's name and type"} }; + { + eLanguageRuntimeDescriptionDisplayVerbosityCompact, + "compact", + "Only show the description string", + }, + { + eLanguageRuntimeDescriptionDisplayVerbosityFull, + "full", + "Show the full output, including persistent variable's name and type", + }, +}; static constexpr OptionEnumValues DescriptionVerbosityTypes() { return OptionEnumValues(g_description_verbosity_type); } -static constexpr OptionDefinition g_expression_options[] = { - // clang-format off - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. " - "Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction " - "and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language " - "setting is used." }, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." }, - {LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, DescriptionVerbosityTypes(), 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Interpret the expression as a complete translation unit, without injecting it into the local " - "context. Allows declaration of persistent, top-level entities without a $ prefix."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by " - "the interpreter (defaults to true)."} - // clang-format on -}; +#define LLDB_OPTIONS_expression +#include "CommandOptions.inc" Status CommandObjectExpression::CommandOptions::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, @@ -176,9 +166,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( } default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -304,7 +292,7 @@ CommandObjectExpression::~CommandObjectExpression() = default; Options *CommandObjectExpression::GetOptions() { return &m_option_group; } -int CommandObjectExpression::HandleCompletion(CompletionRequest &request) { +void CommandObjectExpression::HandleCompletion(CompletionRequest &request) { EvaluateExpressionOptions options; options.SetCoerceToId(m_varobj_options.use_objc); options.SetLanguage(m_command_options.language); @@ -321,17 +309,14 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) { // This didn't work, so let's get out before we start doing things that // expect a valid frame pointer. if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr) - return 0; + return; ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); Target *target = exe_ctx.GetTargetPtr(); if (!target) - target = GetDummyTarget(); - - if (!target) - return 0; + target = &GetDummyTarget(); unsigned cursor_pos = request.GetRawCursorPos(); llvm::StringRef code = request.GetRawLine(); @@ -351,7 +336,7 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) { // exit. // FIXME: We should complete the options here. if (cursor_pos < raw_start) - return 0; + return; // Make the cursor_pos again relative to the start of the code string. assert(cursor_pos >= raw_start); @@ -364,10 +349,9 @@ int CommandObjectExpression::HandleCompletion(CompletionRequest &request) { code, llvm::StringRef(), language, UserExpression::eResultTypeAny, options, nullptr, error)); if (error.Fail()) - return 0; + return; expr->Complete(exe_ctx, request, cursor_pos); - return request.GetNumberOfMatches(); } static lldb_private::Status @@ -393,123 +377,116 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, Target *target = exe_ctx.GetTargetPtr(); if (!target) - target = GetDummyTarget(); - - if (target) { - lldb::ValueObjectSP result_valobj_sp; - bool keep_in_memory = true; - StackFrame *frame = exe_ctx.GetFramePtr(); - - EvaluateExpressionOptions options; - options.SetCoerceToId(m_varobj_options.use_objc); - options.SetUnwindOnError(m_command_options.unwind_on_error); - options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints); - options.SetKeepInMemory(keep_in_memory); - options.SetUseDynamic(m_varobj_options.use_dynamic); - options.SetTryAllThreads(m_command_options.try_all_threads); - options.SetDebug(m_command_options.debug); - options.SetLanguage(m_command_options.language); - options.SetExecutionPolicy( - m_command_options.allow_jit - ? EvaluateExpressionOptions::default_execution_policy - : lldb_private::eExecutionPolicyNever); - - bool auto_apply_fixits; - if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) - auto_apply_fixits = target->GetEnableAutoApplyFixIts(); - else - auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes; + target = &GetDummyTarget(); - options.SetAutoApplyFixIts(auto_apply_fixits); + lldb::ValueObjectSP result_valobj_sp; + bool keep_in_memory = true; + StackFrame *frame = exe_ctx.GetFramePtr(); + + EvaluateExpressionOptions options; + options.SetCoerceToId(m_varobj_options.use_objc); + options.SetUnwindOnError(m_command_options.unwind_on_error); + options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints); + options.SetKeepInMemory(keep_in_memory); + options.SetUseDynamic(m_varobj_options.use_dynamic); + options.SetTryAllThreads(m_command_options.try_all_threads); + options.SetDebug(m_command_options.debug); + options.SetLanguage(m_command_options.language); + options.SetExecutionPolicy( + m_command_options.allow_jit + ? EvaluateExpressionOptions::default_execution_policy + : lldb_private::eExecutionPolicyNever); + + bool auto_apply_fixits; + if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) + auto_apply_fixits = target->GetEnableAutoApplyFixIts(); + else + auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes; - if (m_command_options.top_level) - options.SetExecutionPolicy(eExecutionPolicyTopLevel); + options.SetAutoApplyFixIts(auto_apply_fixits); - // If there is any chance we are going to stop and want to see what went - // wrong with our expression, we should generate debug info - if (!m_command_options.ignore_breakpoints || - !m_command_options.unwind_on_error) - options.SetGenerateDebugInfo(true); + if (m_command_options.top_level) + options.SetExecutionPolicy(eExecutionPolicyTopLevel); - if (m_command_options.timeout > 0) - options.SetTimeout(std::chrono::microseconds(m_command_options.timeout)); - else - options.SetTimeout(llvm::None); - - ExpressionResults success = target->EvaluateExpression( - expr, frame, result_valobj_sp, options, &m_fixed_expression); - - // We only tell you about the FixIt if we applied it. The compiler errors - // will suggest the FixIt if it parsed. - if (error_stream && !m_fixed_expression.empty() && - target->GetEnableNotifyAboutFixIts()) { - if (success == eExpressionCompleted) - error_stream->Printf( - " Fix-it applied, fixed expression was: \n %s\n", - m_fixed_expression.c_str()); - } + // If there is any chance we are going to stop and want to see what went + // wrong with our expression, we should generate debug info + if (!m_command_options.ignore_breakpoints || + !m_command_options.unwind_on_error) + options.SetGenerateDebugInfo(true); - if (result_valobj_sp) { - Format format = m_format_options.GetFormat(); - - if (result_valobj_sp->GetError().Success()) { - if (format != eFormatVoid) { - if (format != eFormatDefault) - result_valobj_sp->SetFormat(format); - - if (m_varobj_options.elem_count > 0) { - Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp)); - if (error.Fail()) { - result->AppendErrorWithFormat( - "expression cannot be used with --element-count %s\n", - error.AsCString("")); - result->SetStatus(eReturnStatusFailed); - return false; - } + if (m_command_options.timeout > 0) + options.SetTimeout(std::chrono::microseconds(m_command_options.timeout)); + else + options.SetTimeout(llvm::None); + + ExpressionResults success = target->EvaluateExpression( + expr, frame, result_valobj_sp, options, &m_fixed_expression); + + // We only tell you about the FixIt if we applied it. The compiler errors + // will suggest the FixIt if it parsed. + if (error_stream && !m_fixed_expression.empty() && + target->GetEnableNotifyAboutFixIts()) { + if (success == eExpressionCompleted) + error_stream->Printf(" Fix-it applied, fixed expression was: \n %s\n", + m_fixed_expression.c_str()); + } + + if (result_valobj_sp) { + Format format = m_format_options.GetFormat(); + + if (result_valobj_sp->GetError().Success()) { + if (format != eFormatVoid) { + if (format != eFormatDefault) + result_valobj_sp->SetFormat(format); + + if (m_varobj_options.elem_count > 0) { + Status error(CanBeUsedForElementCountPrinting(*result_valobj_sp)); + if (error.Fail()) { + result->AppendErrorWithFormat( + "expression cannot be used with --element-count %s\n", + error.AsCString("")); + result->SetStatus(eReturnStatusFailed); + return false; } + } - DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions( - m_command_options.m_verbosity, format)); - options.SetVariableFormatDisplayLanguage( - result_valobj_sp->GetPreferredDisplayLanguage()); + DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions( + m_command_options.m_verbosity, format)); + options.SetVariableFormatDisplayLanguage( + result_valobj_sp->GetPreferredDisplayLanguage()); - result_valobj_sp->Dump(*output_stream, options); + result_valobj_sp->Dump(*output_stream, options); - if (result) - result->SetStatus(eReturnStatusSuccessFinishResult); + if (result) + result->SetStatus(eReturnStatusSuccessFinishResult); + } + } else { + if (result_valobj_sp->GetError().GetError() == + UserExpression::kNoResult) { + if (format != eFormatVoid && GetDebugger().GetNotifyVoid()) { + error_stream->PutCString("(void)\n"); } - } else { - if (result_valobj_sp->GetError().GetError() == - UserExpression::kNoResult) { - if (format != eFormatVoid && GetDebugger().GetNotifyVoid()) { - error_stream->PutCString("(void)\n"); - } - if (result) - result->SetStatus(eReturnStatusSuccessFinishResult); + if (result) + result->SetStatus(eReturnStatusSuccessFinishResult); + } else { + const char *error_cstr = result_valobj_sp->GetError().AsCString(); + if (error_cstr && error_cstr[0]) { + const size_t error_cstr_len = strlen(error_cstr); + const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n'; + if (strstr(error_cstr, "error:") != error_cstr) + error_stream->PutCString("error: "); + error_stream->Write(error_cstr, error_cstr_len); + if (!ends_with_newline) + error_stream->EOL(); } else { - const char *error_cstr = result_valobj_sp->GetError().AsCString(); - if (error_cstr && error_cstr[0]) { - const size_t error_cstr_len = strlen(error_cstr); - const bool ends_with_newline = - error_cstr[error_cstr_len - 1] == '\n'; - if (strstr(error_cstr, "error:") != error_cstr) - error_stream->PutCString("error: "); - error_stream->Write(error_cstr, error_cstr_len); - if (!ends_with_newline) - error_stream->EOL(); - } else { - error_stream->PutCString("error: unknown error\n"); - } - - if (result) - result->SetStatus(eReturnStatusFailed); + error_stream->PutCString("error: unknown error\n"); } + + if (result) + result->SetStatus(eReturnStatusFailed); } } - } else { - error_stream->Printf("error: invalid execution context for expression\n"); - return false; } return true; @@ -521,8 +498,8 @@ void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, // StreamSP output_stream = // io_handler.GetDebugger().GetAsyncOutputStream(); // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream(); - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); - StreamFileSP error_sp(io_handler.GetErrorStreamFile()); + StreamFileSP output_sp = io_handler.GetOutputStreamFileSP(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get()); if (output_sp) @@ -560,7 +537,7 @@ void CommandObjectExpression::GetMultilineExpression() { 1, // Show line numbers starting at 1 *this, nullptr)); - StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); + StreamFileSP output_sp = io_handler_sp->GetOutputStreamFileSP(); if (output_sp) { output_sp->PutCString( "Enter expressions, then terminate with an empty line to evaluate:\n"); @@ -675,11 +652,11 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, } } - Target *target = GetSelectedOrDummyTarget(); + Target &target = GetSelectedOrDummyTarget(); if (EvaluateExpression(expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result)) { - if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) { + if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) { CommandHistory &history = m_interpreter.GetCommandHistory(); // FIXME: Can we figure out what the user actually typed (e.g. some alias // for expr???) @@ -694,12 +671,12 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, history.AppendString(fixed_command); } // Increment statistics to record this expression evaluation success. - target->IncrementStats(StatisticKind::ExpressionSuccessful); + target.IncrementStats(StatisticKind::ExpressionSuccessful); return true; } // Increment statistics to record this expression evaluation failure. - target->IncrementStats(StatisticKind::ExpressionFailure); + target.IncrementStats(StatisticKind::ExpressionFailure); result.SetStatus(eReturnStatusFailed); return false; } diff --git a/source/Commands/CommandObjectExpression.h b/source/Commands/CommandObjectExpression.h index 89c8e1dbeceb..8ef764239069 100644 --- a/source/Commands/CommandObjectExpression.h +++ b/source/Commands/CommandObjectExpression.h @@ -54,7 +54,7 @@ public: Options *GetOptions() override; - int HandleCompletion(CompletionRequest &request) override; + void HandleCompletion(CompletionRequest &request) override; protected: // IOHandler::Delegate functions diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp index ab6a07952f19..6a7facdaff35 100644 --- a/source/Commands/CommandObjectFrame.cpp +++ b/source/Commands/CommandObjectFrame.cpp @@ -23,7 +23,6 @@ #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" #include "lldb/Interpreter/OptionGroupVariable.h" #include "lldb/Interpreter/Options.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" @@ -54,13 +53,8 @@ using namespace lldb_private; // CommandObjectFrameDiagnose -static constexpr OptionDefinition g_frame_diag_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "register", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegisterName, "A register to diagnose." }, - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "An address to diagnose." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "An optional offset. Requires --register." } - // clang-format on -}; +#define LLDB_OPTIONS_frame_diag +#include "CommandOptions.inc" class CommandObjectFrameDiagnose : public CommandObjectParsed { public: @@ -98,9 +92,7 @@ public: } break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -238,11 +230,8 @@ protected: // CommandObjectFrameSelect -static OptionDefinition g_frame_select_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "A relative frame index offset from the current frame index." }, - // clang-format on -}; +#define LLDB_OPTIONS_frame_select +#include "CommandOptions.inc" class CommandObjectFrameSelect : public CommandObjectParsed { public: @@ -257,32 +246,32 @@ public: Status error; const int short_option = m_getopt_table[option_idx].val; switch (short_option) { - case 'r': - if (option_arg.getAsInteger(0, relative_frame_offset)) { - relative_frame_offset = INT32_MIN; + case 'r': { + int32_t offset = 0; + if (option_arg.getAsInteger(0, offset) || offset == INT32_MIN) { error.SetErrorStringWithFormat("invalid frame offset argument '%s'", option_arg.str().c_str()); - } + } else + relative_frame_offset = offset; break; + } default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } void OptionParsingStarting(ExecutionContext *execution_context) override { - relative_frame_offset = INT32_MIN; + relative_frame_offset.reset(); } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::makeArrayRef(g_frame_select_options); } - int32_t relative_frame_offset; + llvm::Optional<int32_t> relative_frame_offset; }; CommandObjectFrameSelect(CommandInterpreter &interpreter) @@ -320,15 +309,16 @@ protected: Thread *thread = m_exe_ctx.GetThreadPtr(); uint32_t frame_idx = UINT32_MAX; - if (m_options.relative_frame_offset != INT32_MIN) { + if (m_options.relative_frame_offset.hasValue()) { // The one and only argument is a signed relative frame index frame_idx = thread->GetSelectedFrameIndex(); if (frame_idx == UINT32_MAX) frame_idx = 0; - if (m_options.relative_frame_offset < 0) { - if (static_cast<int32_t>(frame_idx) >= -m_options.relative_frame_offset) - frame_idx += m_options.relative_frame_offset; + if (*m_options.relative_frame_offset < 0) { + if (static_cast<int32_t>(frame_idx) >= + -*m_options.relative_frame_offset) + frame_idx += *m_options.relative_frame_offset; else { if (frame_idx == 0) { // If you are already at the bottom of the stack, then just warn @@ -339,15 +329,15 @@ protected: } else frame_idx = 0; } - } else if (m_options.relative_frame_offset > 0) { + } else if (*m_options.relative_frame_offset > 0) { // I don't want "up 20" where "20" takes you past the top of the stack // to produce // an error, but rather to just go to the top. So I have to count the // stack here... const uint32_t num_frames = thread->GetStackFrameCount(); if (static_cast<int32_t>(num_frames - frame_idx) > - m_options.relative_frame_offset) - frame_idx += m_options.relative_frame_offset; + *m_options.relative_frame_offset) + frame_idx += *m_options.relative_frame_offset; else { if (frame_idx == num_frames - 1) { // If we are already at the top of the stack, just warn and don't @@ -371,7 +361,7 @@ protected: } if (command.GetArgumentCount() == 1) { - if (command[0].ref.getAsInteger(0, frame_idx)) { + if (command[0].ref().getAsInteger(0, frame_idx)) { result.AppendErrorWithFormat("invalid frame index argument '%s'.", command[0].c_str()); result.SetStatus(eReturnStatusFailed); @@ -460,14 +450,13 @@ public: Options *GetOptions() override { return &m_option_group; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Arguments are the standard source file completer. CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -541,9 +530,9 @@ protected: for (auto &entry : command) { if (m_option_variable.use_regex) { const size_t regex_start_index = regex_var_list.GetSize(); - llvm::StringRef name_str = entry.ref; + llvm::StringRef name_str = entry.ref(); RegularExpression regex(name_str); - if (regex.Compile(name_str)) { + if (regex.IsValid()) { size_t num_matches = 0; const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex, regex_var_list, @@ -582,9 +571,9 @@ protected: entry.c_str()); } } else { - char regex_error[1024]; - if (regex.GetErrorAsCString(regex_error, sizeof(regex_error))) - result.GetErrorStream().Printf("error: %s\n", regex_error); + if (llvm::Error err = regex.GetError()) + result.GetErrorStream().Printf( + "error: %s\n", llvm::toString(std::move(err)).c_str()); else result.GetErrorStream().Printf( "error: unknown regex error when compiling '%s'\n", @@ -600,7 +589,7 @@ protected: StackFrame::eExpressionPathOptionsInspectAnonymousUnions; lldb::VariableSP var_sp; valobj_sp = frame->GetValueForVariableExpressionPath( - entry.ref, m_varobj_options.use_dynamic, expr_path_options, + entry.ref(), m_varobj_options.use_dynamic, expr_path_options, var_sp, error); if (valobj_sp) { std::string scope_string; @@ -727,11 +716,11 @@ protected: // Increment statistics. bool res = result.Succeeded(); - Target *target = GetSelectedOrDummyTarget(); + Target &target = GetSelectedOrDummyTarget(); if (res) - target->IncrementStats(StatisticKind::FrameVarSuccess); + target.IncrementStats(StatisticKind::FrameVarSuccess); else - target->IncrementStats(StatisticKind::FrameVarFailure); + target.IncrementStats(StatisticKind::FrameVarFailure); return res; } @@ -744,14 +733,8 @@ protected: #pragma mark CommandObjectFrameRecognizer -static OptionDefinition g_frame_recognizer_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Name of the module or shared library that this recognizer applies to." }, - { LLDB_OPT_SET_ALL, false, "function", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeName, "Name of the function that this recognizer applies to." }, - { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Give the name of a Python class to use for this frame recognizer." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Function name and module name are actually regular expressions." } - // clang-format on -}; +#define LLDB_OPTIONS_frame_recognizer_add +#include "CommandOptions.inc" class CommandObjectFrameRecognizerAdd : public CommandObjectParsed { private: @@ -779,9 +762,7 @@ private: m_regex = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; diff --git a/source/Commands/CommandObjectGUI.cpp b/source/Commands/CommandObjectGUI.cpp index 21ed510d1264..fac2e9627783 100644 --- a/source/Commands/CommandObjectGUI.cpp +++ b/source/Commands/CommandObjectGUI.cpp @@ -28,9 +28,10 @@ bool CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { if (args.GetArgumentCount() == 0) { Debugger &debugger = GetDebugger(); - lldb::StreamFileSP input_sp = debugger.GetInputFile(); - if (input_sp && input_sp->GetFile().GetIsRealTerminal() && - input_sp->GetFile().GetIsInteractive()) { + File &input = debugger.GetInputFile(); + File &output = debugger.GetOutputFile(); + if (input.GetStream() && output.GetStream() && input.GetIsRealTerminal() && + input.GetIsInteractive()) { IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); if (io_handler_sp) debugger.PushIOHandler(io_handler_sp); diff --git a/source/Commands/CommandObjectHelp.cpp b/source/Commands/CommandObjectHelp.cpp index ab557919d0a0..c02a583bf9df 100644 --- a/source/Commands/CommandObjectHelp.cpp +++ b/source/Commands/CommandObjectHelp.cpp @@ -65,10 +65,8 @@ CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter) CommandObjectHelp::~CommandObjectHelp() = default; -static constexpr OptionDefinition g_help_options[] = { #define LLDB_OPTIONS_help #include "CommandOptions.inc" -}; llvm::ArrayRef<OptionDefinition> CommandObjectHelp::CommandOptions::GetDefinitions() { @@ -98,7 +96,7 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { // Get command object for the first command argument. Only search built-in // command dictionary. StringList matches; - auto command_name = command[0].ref; + auto command_name = command[0].ref(); cmd_obj = m_interpreter.GetCommandObject(command_name, &matches); if (cmd_obj != nullptr) { @@ -109,7 +107,7 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { // object that corresponds to the help command entered. std::string sub_command; for (auto &entry : command.entries().drop_front()) { - sub_command = entry.ref; + sub_command = entry.ref(); matches.Clear(); if (sub_cmd_obj->IsAlias()) sub_cmd_obj = @@ -203,24 +201,23 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { return result.Succeeded(); } -int CommandObjectHelp::HandleCompletion(CompletionRequest &request) { +void CommandObjectHelp::HandleCompletion(CompletionRequest &request) { // Return the completions of the commands in the help system: if (request.GetCursorIndex() == 0) { - return m_interpreter.HandleCompletionMatches(request); - } else { - CommandObject *cmd_obj = - m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref); + m_interpreter.HandleCompletionMatches(request); + return; + } + CommandObject *cmd_obj = + m_interpreter.GetCommandObject(request.GetParsedLine()[0].ref()); - // The command that they are getting help on might be ambiguous, in which - // case we should complete that, otherwise complete with the command the - // user is getting help on... + // The command that they are getting help on might be ambiguous, in which + // case we should complete that, otherwise complete with the command the + // user is getting help on... - if (cmd_obj) { - request.GetParsedLine().Shift(); - request.SetCursorIndex(request.GetCursorIndex() - 1); - return cmd_obj->HandleCompletion(request); - } else { - return m_interpreter.HandleCompletionMatches(request); - } + if (cmd_obj) { + request.ShiftArguments(); + cmd_obj->HandleCompletion(request); + return; } + m_interpreter.HandleCompletionMatches(request); } diff --git a/source/Commands/CommandObjectHelp.h b/source/Commands/CommandObjectHelp.h index a641b19a46d0..52a00ac79ff9 100644 --- a/source/Commands/CommandObjectHelp.h +++ b/source/Commands/CommandObjectHelp.h @@ -23,7 +23,7 @@ public: ~CommandObjectHelp() override; - int HandleCompletion(CompletionRequest &request) override; + void HandleCompletion(CompletionRequest &request) override; static void GenerateAdditionalHelpAvenuesMessage( Stream *s, llvm::StringRef command, llvm::StringRef prefix, @@ -52,9 +52,7 @@ public: m_show_hidden = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp index 2ad61de1a3e9..31a876c3430e 100644 --- a/source/Commands/CommandObjectLog.cpp +++ b/source/Commands/CommandObjectLog.cpp @@ -31,20 +31,23 @@ using namespace lldb; using namespace lldb_private; -static constexpr OptionDefinition g_log_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Set the destination file to log to." }, - { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, - { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose logging." }, - { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, - { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, - { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, - { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, - { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, - { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to the log file instead of overwriting." }, - { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend the names of files and function that generate the logs." }, - // clang-format on -}; +#define LLDB_OPTIONS_log +#include "CommandOptions.inc" + +/// Common completion logic for log enable/disable. +static void CompleteEnableDisable(CompletionRequest &request) { + size_t arg_index = request.GetCursorIndex(); + if (arg_index == 0) { // We got: log enable/disable x[tab] + for (llvm::StringRef channel : Log::ListChannels()) + request.TryCompleteCurrentArg(channel); + } else if (arg_index >= 1) { // We got: log enable/disable channel x[tab] + llvm::StringRef channel = request.GetParsedLine().GetArgumentAtIndex(0); + Log::ForEachChannelCategory( + channel, [&request](llvm::StringRef name, llvm::StringRef desc) { + request.TryCompleteCurrentArg(name, desc); + }); + } +} class CommandObjectLogEnable : public CommandObjectParsed { public: @@ -125,9 +128,7 @@ public: log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -148,17 +149,24 @@ public: uint32_t log_options; }; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CompleteEnableDisable(request); + } + protected: bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.GetArgumentCount() < 2) { result.AppendErrorWithFormat( "%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); return false; } // Store into a std::string since we're about to shift the channel off. - const std::string channel = args[0].ref; + const std::string channel = args[0].ref(); args.Shift(); // Shift off the channel char log_file[PATH_MAX]; if (m_options.log_file) @@ -215,16 +223,23 @@ public: ~CommandObjectLogDisable() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CompleteEnableDisable(request); + } + protected: bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.empty()) { result.AppendErrorWithFormat( "%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); return false; } - const std::string channel = args[0].ref; + const std::string channel = args[0].ref(); args.Shift(); // Shift off the channel if (channel == "all") { Log::DisableAllLogChannels(); @@ -266,6 +281,13 @@ public: ~CommandObjectLogList() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + for (llvm::StringRef channel : Log::ListChannels()) + request.TryCompleteCurrentArg(channel); + } + protected: bool DoExecute(Args &args, CommandReturnObject &result) override { std::string output; @@ -277,7 +299,7 @@ protected: bool success = true; for (const auto &entry : args.entries()) success = - success && Log::ListChannelCategories(entry.ref, output_stream); + success && Log::ListChannelCategories(entry.ref(), output_stream); if (success) result.SetStatus(eReturnStatusSuccessFinishResult); } @@ -303,7 +325,7 @@ protected: result.SetStatus(eReturnStatusFailed); if (args.GetArgumentCount() == 1) { - auto sub_command = args[0].ref; + auto sub_command = args[0].ref(); if (sub_command.equals_lower("enable")) { Timer::SetDisplayDepth(UINT32_MAX); @@ -320,8 +342,8 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } } else if (args.GetArgumentCount() == 2) { - auto sub_command = args[0].ref; - auto param = args[1].ref; + auto sub_command = args[0].ref(); + auto param = args[1].ref(); if (sub_command.equals_lower("enable")) { uint32_t depth; diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp index 1afcac71318d..38bd3d179096 100644 --- a/source/Commands/CommandObjectMemory.cpp +++ b/source/Commands/CommandObjectMemory.cpp @@ -46,20 +46,8 @@ using namespace lldb; using namespace lldb_private; -static constexpr OptionDefinition g_read_memory_options[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumberPerLine, "The number of items per line to display." }, - {LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that " - "uses the format, size, count and number per line settings." }, - {LLDB_OPT_SET_3 | - LLDB_OPT_SET_4, true , "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "The name of a type to view memory as." }, - {LLDB_OPT_SET_4, false, "language", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "The language of the type to view memory as."}, - {LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." }, - {LLDB_OPT_SET_1 | - LLDB_OPT_SET_2 | - LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Necessary if reading over target.max-memory-read-size bytes." }, - // clang-format on -}; +#define LLDB_OPTIONS_memory_read +#include "CommandOptions.inc" class OptionGroupReadMemory : public OptionGroup { public: @@ -70,13 +58,13 @@ public: ~OptionGroupReadMemory() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_read_memory_options); + return llvm::makeArrayRef(g_memory_read_options); } Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override { Status error; - const int short_option = g_read_memory_options[option_idx].short_option; + const int short_option = g_memory_read_options[option_idx].short_option; switch (short_option) { case 'l': @@ -108,9 +96,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -175,6 +161,7 @@ public: case eFormatOctal: case eFormatDecimal: case eFormatEnum: + case eFormatUnicode8: case eFormatUnicode16: case eFormatUnicode32: case eFormatUnsigned: @@ -606,7 +593,7 @@ protected: } if (argc > 0) - addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref, + addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { @@ -618,7 +605,7 @@ protected: if (argc == 2) { lldb::addr_t end_addr = OptionArgParser::ToAddress( - &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, nullptr); + &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, nullptr); if (end_addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid end address expression."); result.AppendError(error.AsCString()); @@ -778,26 +765,27 @@ protected: m_prev_varobj_options = m_varobj_options; m_prev_compiler_type = compiler_type; - StreamFile outfile_stream; - Stream *output_stream = nullptr; + std::unique_ptr<Stream> output_stream_storage; + Stream *output_stream_p = nullptr; const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue(); std::string path = outfile_spec.GetPath(); if (outfile_spec) { - uint32_t open_options = - File::eOpenOptionWrite | File::eOpenOptionCanCreate; + auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; const bool append = m_outfile_options.GetAppend().GetCurrentValue(); if (append) open_options |= File::eOpenOptionAppend; - Status error = FileSystem::Instance().Open(outfile_stream.GetFile(), - outfile_spec, open_options); - if (error.Success()) { + auto outfile = FileSystem::Instance().Open(outfile_spec, open_options); + + if (outfile) { + auto outfile_stream_up = + std::make_unique<StreamFile>(std::move(outfile.get())); if (m_memory_options.m_output_as_binary) { const size_t bytes_written = - outfile_stream.Write(data_sp->GetBytes(), bytes_read); + outfile_stream_up->Write(data_sp->GetBytes(), bytes_read); if (bytes_written > 0) { result.GetOutputStream().Printf( "%zi bytes %s to '%s'\n", bytes_written, @@ -813,16 +801,19 @@ protected: } else { // We are going to write ASCII to the file just point the // output_stream to our outfile_stream... - output_stream = &outfile_stream; + output_stream_storage = std::move(outfile_stream_up); + output_stream_p = output_stream_storage.get(); } } else { - result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", + result.AppendErrorWithFormat("Failed to open file '%s' for %s:\n", path.c_str(), append ? "append" : "write"); + + result.AppendError(llvm::toString(outfile.takeError())); result.SetStatus(eReturnStatusFailed); return false; } } else { - output_stream = &result.GetOutputStream(); + output_stream_p = &result.GetOutputStream(); } ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); @@ -842,7 +833,7 @@ protected: DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions( eLanguageRuntimeDescriptionDisplayVerbosityFull, format)); - valobj_sp->Dump(*output_stream, options); + valobj_sp->Dump(*output_stream_p, options); } else { result.AppendErrorWithFormat( "failed to create a value object for: (%s) %s\n", @@ -882,13 +873,13 @@ protected: } } - assert(output_stream); + assert(output_stream_p); size_t bytes_dumped = DumpDataExtractor( - data, output_stream, 0, format, item_byte_size, item_count, + data, output_stream_p, 0, format, item_byte_size, item_count, num_per_line / target->GetArchitecture().GetDataByteSize(), addr, 0, 0, exe_scope); m_next_addr = addr + bytes_dumped; - output_stream->EOL(); + output_stream_p->EOL(); return true; } @@ -906,14 +897,8 @@ protected: CompilerType m_prev_compiler_type; }; -static constexpr OptionDefinition g_memory_find_option_table[] = { - // clang-format off - {LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, - {LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Use text to find a byte pattern."}, - {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many times to perform the search."}, - {LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, - // clang-format on -}; +#define LLDB_OPTIONS_memory_find +#include "CommandOptions.inc" // Find the specified data in memory class CommandObjectMemoryFind : public CommandObjectParsed { @@ -925,14 +910,13 @@ public: ~OptionGroupFindMemory() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_memory_find_option_table); + return llvm::makeArrayRef(g_memory_find_options); } Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override { Status error; - const int short_option = - g_memory_find_option_table[option_idx].short_option; + const int short_option = g_memory_find_options[option_idx].short_option; switch (short_option) { case 'e': @@ -954,9 +938,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -1056,13 +1038,13 @@ protected: Status error; lldb::addr_t low_addr = OptionArgParser::ToAddress( - &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error); + &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) { result.AppendError("invalid low address"); return false; } lldb::addr_t high_addr = OptionArgParser::ToAddress( - &m_exe_ctx, command[1].ref, LLDB_INVALID_ADDRESS, &error); + &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, &error); if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) { result.AppendError("invalid high address"); return false; @@ -1203,12 +1185,8 @@ protected: OptionGroupFindMemory m_memory_options; }; -static constexpr OptionDefinition g_memory_write_option_table[] = { - // clang-format off - {LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Write memory using the contents of a file."}, - {LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."}, - // clang-format on -}; +#define LLDB_OPTIONS_memory_write +#include "CommandOptions.inc" // Write memory to the inferior process class CommandObjectMemoryWrite : public CommandObjectParsed { @@ -1220,14 +1198,13 @@ public: ~OptionGroupWriteMemory() override = default; llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_memory_write_option_table); + return llvm::makeArrayRef(g_memory_write_options); } Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override { Status error; - const int short_option = - g_memory_write_option_table[option_idx].short_option; + const int short_option = g_memory_write_options[option_idx].short_option; switch (short_option) { case 'i': @@ -1249,9 +1226,7 @@ public: } break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -1368,7 +1343,7 @@ protected: Status error; lldb::addr_t addr = OptionArgParser::ToAddress( - &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error); + &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid address expression\n"); @@ -1435,6 +1410,7 @@ protected: case eFormatBytesWithASCII: case eFormatComplex: case eFormatEnum: + case eFormatUnicode8: case eFormatUnicode16: case eFormatUnicode32: case eFormatVectorOfChar: @@ -1470,10 +1446,10 @@ protected: // Be careful, getAsInteger with a radix of 16 rejects "0xab" so we // have to special case that: bool success = false; - if (entry.ref.startswith("0x")) - success = !entry.ref.getAsInteger(0, uval64); + if (entry.ref().startswith("0x")) + success = !entry.ref().getAsInteger(0, uval64); if (!success) - success = !entry.ref.getAsInteger(16, uval64); + success = !entry.ref().getAsInteger(16, uval64); if (!success) { result.AppendErrorWithFormat( "'%s' is not a valid hex string value.\n", entry.c_str()); @@ -1491,7 +1467,7 @@ protected: break; } case eFormatBoolean: - uval64 = OptionArgParser::ToBoolean(entry.ref, false, &success); + uval64 = OptionArgParser::ToBoolean(entry.ref(), false, &success); if (!success) { result.AppendErrorWithFormat( "'%s' is not a valid boolean string value.\n", entry.c_str()); @@ -1502,7 +1478,7 @@ protected: break; case eFormatBinary: - if (entry.ref.getAsInteger(2, uval64)) { + if (entry.ref().getAsInteger(2, uval64)) { result.AppendErrorWithFormat( "'%s' is not a valid binary string value.\n", entry.c_str()); result.SetStatus(eReturnStatusFailed); @@ -1521,10 +1497,10 @@ protected: case eFormatCharArray: case eFormatChar: case eFormatCString: { - if (entry.ref.empty()) + if (entry.ref().empty()) break; - size_t len = entry.ref.size(); + size_t len = entry.ref().size(); // Include the NULL for C strings... if (m_format_options.GetFormat() == eFormatCString) ++len; @@ -1541,7 +1517,7 @@ protected: break; } case eFormatDecimal: - if (entry.ref.getAsInteger(0, sval64)) { + if (entry.ref().getAsInteger(0, sval64)) { result.AppendErrorWithFormat( "'%s' is not a valid signed decimal value.\n", entry.c_str()); result.SetStatus(eReturnStatusFailed); @@ -1559,7 +1535,7 @@ protected: case eFormatUnsigned: - if (!entry.ref.getAsInteger(0, uval64)) { + if (!entry.ref().getAsInteger(0, uval64)) { result.AppendErrorWithFormat( "'%s' is not a valid unsigned decimal string value.\n", entry.c_str()); @@ -1577,7 +1553,7 @@ protected: break; case eFormatOctal: - if (entry.ref.getAsInteger(8, uval64)) { + if (entry.ref().getAsInteger(8, uval64)) { result.AppendErrorWithFormat( "'%s' is not a valid octal string value.\n", entry.c_str()); result.SetStatus(eReturnStatusFailed); @@ -1663,7 +1639,7 @@ protected: Status error; lldb::addr_t addr = OptionArgParser::ToAddress( - &m_exe_ctx, command[0].ref, LLDB_INVALID_ADDRESS, &error); + &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); if (addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid address expression"); @@ -1728,7 +1704,7 @@ protected: result.SetStatus(eReturnStatusFailed); } else { if (command.GetArgumentCount() == 1) { - auto load_addr_str = command[0].ref; + auto load_addr_str = command[0].ref(); load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str, LLDB_INVALID_ADDRESS, &error); if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) { diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp index 4011cceb8a26..03a3770d8df7 100644 --- a/source/Commands/CommandObjectMultiword.cpp +++ b/source/Commands/CommandObjectMultiword.cpp @@ -93,9 +93,11 @@ bool CommandObjectMultiword::Execute(const char *args_string, return result.Succeeded(); } - auto sub_command = args[0].ref; - if (sub_command.empty()) + auto sub_command = args[0].ref(); + if (sub_command.empty()) { + result.AppendError("Need to specify a non-empty subcommand."); return result.Succeeded(); + } if (sub_command.equals_lower("help")) { this->CommandObject::GenerateHelpText(result); @@ -136,9 +138,9 @@ bool CommandObjectMultiword::Execute(const char *args_string, if (num_subcmd_matches > 0) { error_msg.append(" Possible completions:"); - for (size_t i = 0; i < matches.GetSize(); i++) { + for (const std::string &match : matches) { error_msg.append("\n\t"); - error_msg.append(matches.GetStringAtIndex(i)); + error_msg.append(match); } } error_msg.append("\n"); @@ -179,12 +181,8 @@ void CommandObjectMultiword::GenerateHelpText(Stream &output_stream) { "'help <command> <subcommand>'.\n"); } -int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { - // Any of the command matches will provide a complete word, otherwise the - // individual completers will override this. - request.SetWordComplete(true); - - auto arg0 = request.GetParsedLine()[0].ref; +void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { + auto arg0 = request.GetParsedLine()[0].ref(); if (request.GetCursorIndex() == 0) { StringList new_matches, descriptions; AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches, @@ -197,32 +195,28 @@ int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { StringList temp_matches; CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches); if (cmd_obj != nullptr) { - if (request.GetParsedLine().GetArgumentCount() == 1) { - request.SetWordComplete(true); - } else { + if (request.GetParsedLine().GetArgumentCount() != 1) { request.GetParsedLine().Shift(); - request.SetCursorCharPosition(0); - request.GetParsedLine().AppendArgument(llvm::StringRef()); - return cmd_obj->HandleCompletion(request); + request.AppendEmptyArgument(); + cmd_obj->HandleCompletion(request); } } } - return new_matches.GetSize(); - } else { - StringList new_matches; - CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches); - if (sub_command_object == nullptr) { - request.AddCompletions(new_matches); - return request.GetNumberOfMatches(); - } else { - // Remove the one match that we got from calling GetSubcommandObject. - new_matches.DeleteStringAtIndex(0); - request.AddCompletions(new_matches); - request.GetParsedLine().Shift(); - request.SetCursorIndex(request.GetCursorIndex() - 1); - return sub_command_object->HandleCompletion(request); - } + return; } + + StringList new_matches; + CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches); + if (sub_command_object == nullptr) { + request.AddCompletions(new_matches); + return; + } + + // Remove the one match that we got from calling GetSubcommandObject. + new_matches.DeleteStringAtIndex(0); + request.AddCompletions(new_matches); + request.ShiftArguments(); + sub_command_object->HandleCompletion(request); } const char *CommandObjectMultiword::GetRepeatCommand(Args ¤t_command_args, @@ -231,7 +225,7 @@ const char *CommandObjectMultiword::GetRepeatCommand(Args ¤t_command_args, if (current_command_args.GetArgumentCount() <= index) return nullptr; CommandObject *sub_command_object = - GetSubcommandObject(current_command_args[index].ref); + GetSubcommandObject(current_command_args[index].ref()); if (sub_command_object == nullptr) return nullptr; return sub_command_object->GetRepeatCommand(current_command_args, index); @@ -360,19 +354,17 @@ Options *CommandObjectProxy::GetOptions() { return nullptr; } -int CommandObjectProxy::HandleCompletion(CompletionRequest &request) { +void CommandObjectProxy::HandleCompletion(CompletionRequest &request) { CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) - return proxy_command->HandleCompletion(request); - return 0; + proxy_command->HandleCompletion(request); } -int CommandObjectProxy::HandleArgumentCompletion( +void CommandObjectProxy::HandleArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector) { CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) - return proxy_command->HandleArgumentCompletion(request, opt_element_vector); - return 0; + proxy_command->HandleArgumentCompletion(request, opt_element_vector); } const char *CommandObjectProxy::GetRepeatCommand(Args ¤t_command_args, diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index 53549cdeee32..fbd13aa37bda 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -58,21 +58,8 @@ static mode_t ParsePermissionString(llvm::StringRef permissions) { return user | group | world; } -static constexpr OptionDefinition g_permissions_options[] = { - // clang-format off - {LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsNumber, "Give out the numeric value for permissions (e.g. 757)"}, - {LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsString, "Give out the string value for permissions (e.g. rwxr-xr--)."}, - {LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to read."}, - {LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to write."}, - {LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to execute."}, - {LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to read."}, - {LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to write."}, - {LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to execute."}, - {LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to read."}, - {LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to write."}, - {LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to execute."}, - // clang-format on -}; +#define LLDB_OPTIONS_permissions +#include "CommandOptions.inc" class OptionPermissions : public OptionGroup { public: @@ -130,8 +117,7 @@ public: m_permissions |= lldb::eFilePermissionsWorldExecute; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -171,10 +157,9 @@ public: ~CommandObjectPlatformSelect() override = default; - int HandleCompletion(CompletionRequest &request) override { + void HandleCompletion(CompletionRequest &request) override { CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request, nullptr); - return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_option_group; } @@ -585,12 +570,8 @@ public: // "platform fread" -static constexpr OptionDefinition g_platform_fread_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Number of bytes to read from the file." }, - // clang-format on -}; +#define LLDB_OPTIONS_platform_fread +#include "CommandOptions.inc" class CommandObjectPlatformFRead : public CommandObjectParsed { public: @@ -650,9 +631,7 @@ protected: option_arg.str().c_str()); break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -678,12 +657,8 @@ protected: // "platform fwrite" -static constexpr OptionDefinition g_platform_fwrite_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "data", 'd', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Text to write to the file." }, - // clang-format on -}; +#define LLDB_OPTIONS_platform_fwrite +#include "CommandOptions.inc" class CommandObjectPlatformFWrite : public CommandObjectParsed { public: @@ -740,9 +715,7 @@ protected: m_data.assign(option_arg); break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -1056,24 +1029,9 @@ protected: // "platform process list" -static OptionDefinition g_platform_process_list_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "List the process info for a specific process ID." }, - { LLDB_OPT_SET_2, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that match a string." }, - { LLDB_OPT_SET_3, true, "ends-with", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that end with a string." }, - { LLDB_OPT_SET_4, true, "starts-with", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that start with a string." }, - { LLDB_OPT_SET_5, true, "contains", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that contain a string." }, - { LLDB_OPT_SET_6, true, "regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "Find processes that have a matching parent process ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching user ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid", 'U', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective user ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid", 'g', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching group ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid", 'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective group ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Find processes that have a matching architecture." }, - { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show process arguments instead of the process executable basename." }, - { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose output." }, - // clang-format on -}; +static PosixPlatformCommandOptionValidator posix_validator; +#define LLDB_OPTIONS_platform_process_list +#include "CommandOptions.inc" class CommandObjectPlatformProcessList : public CommandObjectParsed { public: @@ -1195,23 +1153,6 @@ protected: public: CommandOptions() : Options(), match_info(), show_args(false), verbose(false) { - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { - PosixPlatformCommandOptionValidator *posix_validator = - new PosixPlatformCommandOptionValidator(); - for (auto &Option : g_platform_process_list_options) { - switch (Option.short_option) { - case 'u': - case 'U': - case 'g': - case 'G': - Option.validator = posix_validator; - break; - default: - break; - } - } - }); } ~CommandOptions() override = default; @@ -1323,10 +1264,12 @@ protected: verbose = true; break; - default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); + case 'x': + match_info.SetMatchAllUsers(true); break; + + default: + llvm_unreachable("Unimplemented option"); } return error; @@ -1397,9 +1340,9 @@ protected: Stream &ostrm = result.GetOutputStream(); for (auto &entry : args.entries()) { lldb::pid_t pid; - if (entry.ref.getAsInteger(0, pid)) { + if (entry.ref().getAsInteger(0, pid)) { result.AppendErrorWithFormat("invalid process ID argument '%s'", - entry.ref.str().c_str()); + entry.ref().str().c_str()); result.SetStatus(eReturnStatusFailed); break; } else { @@ -1436,14 +1379,8 @@ protected: } }; -static constexpr OptionDefinition g_platform_process_attach_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." }, - { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with <process-name> to launch." }, - // clang-format on -}; +#define LLDB_OPTIONS_platform_process_attach +#include "CommandOptions.inc" class CommandObjectPlatformProcessAttach : public CommandObjectParsed { public: @@ -1486,9 +1423,7 @@ public: break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -1501,7 +1436,7 @@ public: return llvm::makeArrayRef(g_platform_process_attach_options); } - bool HandleOptionArgumentCompletion( + void HandleOptionArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector, int opt_element_index, CommandInterpreter &interpreter) override { int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; @@ -1509,37 +1444,36 @@ public: // We are only completing the name option for now... - if (GetDefinitions()[opt_defs_index].short_option == 'n') { - // Are we in the name? + // Are we in the name? + if (GetDefinitions()[opt_defs_index].short_option != 'n') + return; - // Look to see if there is a -P argument provided, and if so use that - // plugin, otherwise use the default plugin. + // Look to see if there is a -P argument provided, and if so use that + // plugin, otherwise use the default plugin. - const char *partial_name = nullptr; - partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); + const char *partial_name = nullptr; + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); - PlatformSP platform_sp(interpreter.GetPlatform(true)); - if (platform_sp) { - ProcessInstanceInfoList process_infos; - ProcessInstanceInfoMatch match_info; - if (partial_name) { - match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, FileSpec::Style::native); - match_info.SetNameMatchType(NameMatch::StartsWith); - } - platform_sp->FindProcesses(match_info, process_infos); - const uint32_t num_matches = process_infos.GetSize(); - if (num_matches > 0) { - for (uint32_t i = 0; i < num_matches; ++i) { - request.AddCompletion(llvm::StringRef( - process_infos.GetProcessNameAtIndex(i), - process_infos.GetProcessNameLengthAtIndex(i))); - } - } - } + PlatformSP platform_sp(interpreter.GetPlatform(true)); + if (!platform_sp) + return; + + ProcessInstanceInfoList process_infos; + ProcessInstanceInfoMatch match_info; + if (partial_name) { + match_info.GetProcessInfo().GetExecutableFile().SetFile( + partial_name, FileSpec::Style::native); + match_info.SetNameMatchType(NameMatch::StartsWith); } + platform_sp->FindProcesses(match_info, process_infos); + const uint32_t num_matches = process_infos.GetSize(); + if (num_matches == 0) + return; - return false; + for (uint32_t i = 0; i < num_matches; ++i) { + request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); + } + return; } // Options table: Required for subclasses of Options. @@ -1615,11 +1549,8 @@ private: }; // "platform shell" -static constexpr OptionDefinition g_platform_shell_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command." }, - // clang-format on -}; +#define LLDB_OPTIONS_platform_shell +#include "CommandOptions.inc" class CommandObjectPlatformShell : public CommandObjectRaw { public: @@ -1650,9 +1581,7 @@ public: timeout = std::chrono::seconds(timeout_sec); break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp index 89e01ba52027..b70885061385 100644 --- a/source/Commands/CommandObjectPlugin.cpp +++ b/source/Commands/CommandObjectPlugin.cpp @@ -37,13 +37,12 @@ public: ~CommandObjectPluginLoad() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -58,7 +57,7 @@ protected: Status error; - FileSpec dylib_fspec(command[0].ref); + FileSpec dylib_fspec(command[0].ref()); FileSystem::Instance().Resolve(dylib_fspec); if (GetDebugger().LoadPlugin(dylib_fspec, error)) diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index b20a2d533332..e5aa78afabb3 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -127,14 +127,13 @@ public: ~CommandObjectProcessLaunch() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_options; } @@ -255,16 +254,8 @@ protected: ProcessLaunchCommandOptions m_options; }; -static constexpr OptionDefinition g_process_attach_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Immediately continue the process once attached." }, - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." }, - { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include existing processes when doing attach -w." }, - { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with <process-name> to launch." }, - // clang-format on -}; +#define LLDB_OPTIONS_process_attach +#include "CommandOptions.inc" #pragma mark CommandObjectProcessAttach class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach { @@ -316,9 +307,7 @@ public: break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -331,7 +320,7 @@ public: return llvm::makeArrayRef(g_process_attach_options); } - bool HandleOptionArgumentCompletion( + void HandleOptionArgumentCompletion( CompletionRequest &request, OptionElementVector &opt_element_vector, int opt_element_index, CommandInterpreter &interpreter) override { int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; @@ -339,37 +328,33 @@ public: // We are only completing the name option for now... - if (GetDefinitions()[opt_defs_index].short_option == 'n') { - // Are we in the name? - - // Look to see if there is a -P argument provided, and if so use that - // plugin, otherwise use the default plugin. - - const char *partial_name = nullptr; - partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); - - PlatformSP platform_sp(interpreter.GetPlatform(true)); - if (platform_sp) { - ProcessInstanceInfoList process_infos; - ProcessInstanceInfoMatch match_info; - if (partial_name) { - match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, FileSpec::Style::native); - match_info.SetNameMatchType(NameMatch::StartsWith); - } - platform_sp->FindProcesses(match_info, process_infos); - const size_t num_matches = process_infos.GetSize(); - if (num_matches > 0) { - for (size_t i = 0; i < num_matches; ++i) { - request.AddCompletion(llvm::StringRef( - process_infos.GetProcessNameAtIndex(i), - process_infos.GetProcessNameLengthAtIndex(i))); - } - } - } + // Are we in the name? + if (GetDefinitions()[opt_defs_index].short_option != 'n') + return; + + // Look to see if there is a -P argument provided, and if so use that + // plugin, otherwise use the default plugin. + + const char *partial_name = nullptr; + partial_name = request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos); + + PlatformSP platform_sp(interpreter.GetPlatform(true)); + if (!platform_sp) + return; + ProcessInstanceInfoList process_infos; + ProcessInstanceInfoMatch match_info; + if (partial_name) { + match_info.GetProcessInfo().GetExecutableFile().SetFile( + partial_name, FileSpec::Style::native); + match_info.SetNameMatchType(NameMatch::StartsWith); + } + platform_sp->FindProcesses(match_info, process_infos); + const size_t num_matches = process_infos.GetSize(); + if (num_matches == 0) + return; + for (size_t i = 0; i < num_matches; ++i) { + request.AddCompletion(process_infos.GetProcessNameAtIndex(i)); } - - return false; } // Instance variables to hold the values for command options. @@ -444,7 +429,6 @@ protected: result.AppendMessage(stream.GetString()); result.SetStatus(eReturnStatusSuccessFinishNoResult); result.SetDidChangeProcessState(true); - result.SetAbnormalStopWasExpected(true); } else { result.AppendError( "no error returned from Target::Attach, and target has no process"); @@ -505,11 +489,8 @@ protected: // CommandObjectProcessContinue -static constexpr OptionDefinition g_process_continue_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread." } - // clang-format on -}; +#define LLDB_OPTIONS_process_continue +#include "CommandOptions.inc" #pragma mark CommandObjectProcessContinue @@ -550,9 +531,7 @@ protected: break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -666,11 +645,8 @@ protected: }; // CommandObjectProcessDetach -static constexpr OptionDefinition g_process_detach_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, - // clang-format on -}; +#define LLDB_OPTIONS_process_detach +#include "CommandOptions.inc" #pragma mark CommandObjectProcessDetach @@ -703,9 +679,7 @@ public: } break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -762,12 +736,8 @@ protected: }; // CommandObjectProcessConnect - -static constexpr OptionDefinition g_process_connect_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - // clang-format on -}; +#define LLDB_OPTIONS_process_connect +#include "CommandOptions.inc" #pragma mark CommandObjectProcessConnect @@ -794,9 +764,7 @@ public: break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -887,12 +855,8 @@ public: }; // CommandObjectProcessLoad - -static constexpr OptionDefinition g_process_load_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory." }, - // clang-format on -}; +#define LLDB_OPTIONS_process_load +#include "CommandOptions.inc" #pragma mark CommandObjectProcessLoad @@ -919,9 +883,7 @@ public: install_path.SetFile(option_arg, FileSpec::Style::native); break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -960,7 +922,7 @@ protected: for (auto &entry : command.entries()) { Status error; PlatformSP platform = process->GetTarget().GetPlatform(); - llvm::StringRef image_path = entry.ref; + llvm::StringRef image_path = entry.ref(); uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN; if (!m_options.do_install) { @@ -1022,9 +984,9 @@ protected: for (auto &entry : command.entries()) { uint32_t image_token; - if (entry.ref.getAsInteger(0, image_token)) { + if (entry.ref().getAsInteger(0, image_token)) { result.AppendErrorWithFormat("invalid image index argument '%s'", - entry.ref.str().c_str()); + entry.ref().str().c_str()); result.SetStatus(eReturnStatusFailed); break; } else { @@ -1271,14 +1233,8 @@ public: }; // CommandObjectProcessHandle - -static constexpr OptionDefinition g_process_handle_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, - { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, - { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." } - // clang-format on -}; +#define LLDB_OPTIONS_process_handle +#include "CommandOptions.inc" #pragma mark CommandObjectProcessHandle @@ -1306,9 +1262,7 @@ public: pass = option_arg; break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -1335,7 +1289,7 @@ public: "Manage LLDB handling of OS signals for the " "current target process. Defaults to showing " "current policy.", - nullptr), + nullptr, eCommandRequiresTarget), m_options() { SetHelpLong("\nIf no signals are specified, update them all. If no update " "option is specified, list the current values."); @@ -1420,15 +1374,7 @@ public: protected: bool DoExecute(Args &signal_args, CommandReturnObject &result) override { - TargetSP target_sp = GetDebugger().GetSelectedTarget(); - - if (!target_sp) { - result.AppendError("No current target;" - " cannot handle signals until you have a valid target " - "and process.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target *target_sp = &GetSelectedTarget(); ProcessSP process_sp = target_sp->GetProcessSP(); diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp index 34482a8b1e4f..13266f8fce35 100644 --- a/source/Commands/CommandObjectRegister.cpp +++ b/source/Commands/CommandObjectRegister.cpp @@ -32,14 +32,8 @@ using namespace lldb; using namespace lldb_private; // "register read" - -static constexpr OptionDefinition g_register_read_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display register names using the alternate register name if there is one." }, - { LLDB_OPT_SET_1, false, "set", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Specify which register sets to dump by index." }, - { LLDB_OPT_SET_2, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show all register sets." }, - // clang-format on -}; +#define LLDB_OPTIONS_register_read +#include "CommandOptions.inc" class CommandObjectRegisterRead : public CommandObjectParsed { public: @@ -212,7 +206,7 @@ protected: // consistent towards the user and allow them to say reg read $rbx - // internally, however, we should be strict and not allow ourselves // to call our registers $rbx in our own API - auto arg_str = entry.ref; + auto arg_str = entry.ref(); arg_str.consume_front("$"); reg_info = reg_ctx->GetRegisterInfoByName(arg_str); @@ -278,9 +272,7 @@ protected: break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -343,8 +335,8 @@ protected: "register write takes exactly 2 arguments: <reg-name> <value>"); result.SetStatus(eReturnStatusFailed); } else { - auto reg_name = command[0].ref; - auto value_str = command[1].ref; + auto reg_name = command[0].ref(); + auto value_str = command[1].ref(); // in most LLDB commands we accept $rbx as the name for register RBX - // and here we would reject it and non-existant. we should be more diff --git a/source/Commands/CommandObjectReproducer.cpp b/source/Commands/CommandObjectReproducer.cpp index 4b0e9e36d202..dc4579c20fc2 100644 --- a/source/Commands/CommandObjectReproducer.cpp +++ b/source/Commands/CommandObjectReproducer.cpp @@ -8,6 +8,8 @@ #include "CommandObjectReproducer.h" +#include "lldb/Host/OptionParser.h" +#include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -16,7 +18,58 @@ #include "lldb/Interpreter/OptionGroupBoolean.h" using namespace lldb; +using namespace llvm; using namespace lldb_private; +using namespace lldb_private::repro; + +enum ReproducerProvider { + eReproducerProviderCommands, + eReproducerProviderFiles, + eReproducerProviderGDB, + eReproducerProviderVersion, + eReproducerProviderWorkingDirectory, + eReproducerProviderNone +}; + +static constexpr OptionEnumValueElement g_reproducer_provider_type[] = { + { + eReproducerProviderCommands, + "commands", + "Command Interpreter Commands", + }, + { + eReproducerProviderFiles, + "files", + "Files", + }, + { + eReproducerProviderGDB, + "gdb", + "GDB Remote Packets", + }, + { + eReproducerProviderVersion, + "version", + "Version", + }, + { + eReproducerProviderWorkingDirectory, + "cwd", + "Working Directory", + }, + { + eReproducerProviderNone, + "none", + "None", + }, +}; + +static constexpr OptionEnumValues ReproducerProviderType() { + return OptionEnumValues(g_reproducer_provider_type); +} + +#define LLDB_OPTIONS_reproducer +#include "CommandOptions.inc" class CommandObjectReproducerGenerate : public CommandObjectParsed { public: @@ -38,10 +91,10 @@ protected: return false; } - auto &r = repro::Reproducer::Instance(); + auto &r = Reproducer::Instance(); if (auto generator = r.GetGenerator()) { generator->Keep(); - } else if (r.GetLoader()) { + } else if (r.IsReplaying()) { // Make this operation a NOP in replay mode. result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); @@ -84,10 +137,10 @@ protected: return false; } - auto &r = repro::Reproducer::Instance(); - if (r.GetGenerator()) { + auto &r = Reproducer::Instance(); + if (r.IsCapturing()) { result.GetOutputStream() << "Reproducer is in capture mode.\n"; - } else if (r.GetLoader()) { + } else if (r.IsReplaying()) { result.GetOutputStream() << "Reproducer is in replay mode.\n"; } else { result.GetOutputStream() << "Reproducer is off.\n"; @@ -98,17 +151,235 @@ protected: } }; +static void SetError(CommandReturnObject &result, Error err) { + result.GetErrorStream().Printf("error: %s\n", + toString(std::move(err)).c_str()); + result.SetStatus(eReturnStatusFailed); +} + +class CommandObjectReproducerDump : public CommandObjectParsed { +public: + CommandObjectReproducerDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "reproducer dump", + "Dump the information contained in a reproducer. " + "If no reproducer is specified during replay, it " + "dumps the content of the current reproducer.", + nullptr) {} + + ~CommandObjectReproducerDump() override = default; + + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() : Options(), file() {} + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'f': + file.SetFile(option_arg, FileSpec::Style::native); + FileSystem::Instance().Resolve(file); + break; + case 'p': + provider = (ReproducerProvider)OptionArgParser::ToOptionEnum( + option_arg, GetDefinitions()[option_idx].enum_values, 0, error); + if (!error.Success()) + error.SetErrorStringWithFormat("unrecognized value for provider '%s'", + option_arg.str().c_str()); + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + file.Clear(); + provider = eReproducerProviderNone; + } + + ArrayRef<OptionDefinition> GetDefinitions() override { + return makeArrayRef(g_reproducer_options); + } + + FileSpec file; + ReproducerProvider provider = eReproducerProviderNone; + }; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (!command.empty()) { + result.AppendErrorWithFormat("'%s' takes no arguments", + m_cmd_name.c_str()); + return false; + } + + // If no reproducer path is specified, use the loader currently used for + // replay. Otherwise create a new loader just for dumping. + llvm::Optional<Loader> loader_storage; + Loader *loader = nullptr; + if (!m_options.file) { + loader = Reproducer::Instance().GetLoader(); + if (loader == nullptr) { + result.SetError( + "Not specifying a reproducer is only support during replay."); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return false; + } + } else { + loader_storage.emplace(m_options.file); + loader = &(*loader_storage); + if (Error err = loader->LoadIndex()) { + SetError(result, std::move(err)); + return false; + } + } + + // If we get here we should have a valid loader. + assert(loader); + + switch (m_options.provider) { + case eReproducerProviderFiles: { + FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>(); + + // Read the VFS mapping. + ErrorOr<std::unique_ptr<MemoryBuffer>> buffer = + vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath()); + if (!buffer) { + SetError(result, errorCodeToError(buffer.getError())); + return false; + } + + // Initialize a VFS from the given mapping. + IntrusiveRefCntPtr<vfs::FileSystem> vfs = vfs::getVFSFromYAML( + std::move(buffer.get()), nullptr, vfs_mapping.GetPath()); + + // Dump the VFS to a buffer. + std::string str; + raw_string_ostream os(str); + static_cast<vfs::RedirectingFileSystem &>(*vfs).dump(os); + os.flush(); + + // Return the string. + result.AppendMessage(str); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderVersion: { + Expected<std::string> version = loader->LoadBuffer<VersionProvider>(); + if (!version) { + SetError(result, version.takeError()); + return false; + } + result.AppendMessage(*version); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderWorkingDirectory: { + Expected<std::string> cwd = + loader->LoadBuffer<WorkingDirectoryProvider>(); + if (!cwd) { + SetError(result, cwd.takeError()); + return false; + } + result.AppendMessage(*cwd); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderCommands: { + // Create a new command loader. + std::unique_ptr<repro::CommandLoader> command_loader = + repro::CommandLoader::Create(loader); + if (!command_loader) { + SetError(result, + make_error<StringError>(llvm::inconvertibleErrorCode(), + "Unable to create command loader.")); + return false; + } + + // Iterate over the command files and dump them. + while (true) { + llvm::Optional<std::string> command_file = + command_loader->GetNextFile(); + if (!command_file) + break; + + auto command_buffer = llvm::MemoryBuffer::getFile(*command_file); + if (auto err = command_buffer.getError()) { + SetError(result, errorCodeToError(err)); + return false; + } + result.AppendMessage((*command_buffer)->getBuffer()); + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderGDB: { + FileSpec gdb_file = loader->GetFile<ProcessGDBRemoteProvider::Info>(); + auto error_or_file = MemoryBuffer::getFile(gdb_file.GetPath()); + if (auto err = error_or_file.getError()) { + SetError(result, errorCodeToError(err)); + return false; + } + + std::vector<GDBRemotePacket> packets; + yaml::Input yin((*error_or_file)->getBuffer()); + yin >> packets; + + if (auto err = yin.error()) { + SetError(result, errorCodeToError(err)); + return false; + } + + for (GDBRemotePacket &packet : packets) { + packet.Dump(result.GetOutputStream()); + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + case eReproducerProviderNone: + result.SetError("No valid provider specified."); + return false; + } + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + +private: + CommandOptions m_options; +}; + CommandObjectReproducer::CommandObjectReproducer( CommandInterpreter &interpreter) : CommandObjectMultiword( interpreter, "reproducer", - "Commands to inspect and manipulate the reproducer functionality.", - "log <subcommand> [<command-options>]") { + "Commands for manipulating reproducers. Reproducers make it possible " + "to capture full debug sessions with all its dependencies. The " + "resulting reproducer is used to replay the debug session while " + "debugging the debugger.\n" + "Because reproducers need the whole the debug session from " + "beginning to end, you need to launch the debugger in capture or " + "replay mode, commonly though the command line driver.\n" + "Reproducers are unrelated record-replay debugging, as you cannot " + "interact with the debugger during replay.\n", + "reproducer <subcommand> [<subcommand-options>]") { LoadSubCommand( "generate", CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); LoadSubCommand("status", CommandObjectSP( new CommandObjectReproducerStatus(interpreter))); + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectReproducerDump(interpreter))); } CommandObjectReproducer::~CommandObjectReproducer() = default; diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index 55a0002c5997..248a04613d7a 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -20,11 +20,8 @@ using namespace lldb; using namespace lldb_private; // CommandObjectSettingsSet - -static constexpr OptionDefinition g_settings_set_options[] = { #define LLDB_OPTIONS_settings_set #include "CommandOptions.inc" -}; class CommandObjectSettingsSet : public CommandObjectRaw { public: @@ -107,9 +104,7 @@ insert-before or insert-after."); m_global = true; break; default: - error.SetErrorStringWithFormat("unrecognized options '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -129,15 +124,14 @@ insert-before or insert-after."); bool m_force; }; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { const size_t argc = request.GetParsedLine().GetArgumentCount(); const char *arg = nullptr; - int setting_var_idx; - for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc); - ++setting_var_idx) { + size_t setting_var_idx; + for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) { arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); if (arg && arg[0] != '-') break; // We found our setting variable name index @@ -147,27 +141,27 @@ insert-before or insert-after."); CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - } else { + return; + } arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()); - if (arg) { - if (arg[0] == '-') { - // Complete option name - } else { - // Complete setting value - const char *setting_var_name = - request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); - Status error; - lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue( - &m_exe_ctx, setting_var_name, false, error)); - if (value_sp) { - value_sp->AutoComplete(m_interpreter, request); - } - } - } - } - return request.GetNumberOfMatches(); + if (!arg) + return; + + // Complete option name + if (arg[0] != '-') + return; + + // Complete setting value + const char *setting_var_name = + request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); + Status error; + lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue( + &m_exe_ctx, setting_var_name, false, error)); + if (!value_sp) + return; + value_sp->AutoComplete(m_interpreter, request); } protected: @@ -210,16 +204,13 @@ protected: } // Split the raw command into var_name and value pair. - llvm::StringRef raw_str(command); - std::string var_value_string = raw_str.split(var_name).second.str(); - const char *var_value_cstr = - Args::StripSpaces(var_value_string, true, false, false); + llvm::StringRef var_value(command); + var_value = var_value.split(var_name).second.ltrim(); Status error; - if (m_options.m_global) { + if (m_options.m_global) error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign, - var_name, var_value_cstr); - } + var_name, var_value); if (error.Success()) { // FIXME this is the same issue as the one in commands script import @@ -230,7 +221,7 @@ protected: ExecutionContext exe_ctx(m_exe_ctx); m_exe_ctx.Clear(); error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign, - var_name, var_value_cstr); + var_name, var_value); } if (error.Fail()) { @@ -274,13 +265,12 @@ public: ~CommandObjectSettingsShow() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -290,7 +280,7 @@ protected: if (!args.empty()) { for (const auto &arg : args) { Status error(GetDebugger().DumpPropertyValue( - &m_exe_ctx, result.GetOutputStream(), arg.ref, + &m_exe_ctx, result.GetOutputStream(), arg.ref(), OptionValue::eDumpGroupValue)); if (error.Success()) { result.GetOutputStream().EOL(); @@ -309,11 +299,8 @@ protected: }; // CommandObjectSettingsWrite -- Write settings to file - -static constexpr OptionDefinition g_settings_write_options[] = { #define LLDB_OPTIONS_settings_write #include "CommandOptions.inc" -}; class CommandObjectSettingsWrite : public CommandObjectParsed { public: @@ -363,9 +350,7 @@ public: m_append = true; break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -390,12 +375,11 @@ protected: FileSpec file_spec(m_options.m_filename); FileSystem::Instance().Resolve(file_spec); std::string path(file_spec.GetPath()); - uint32_t options = File::OpenOptions::eOpenOptionWrite | - File::OpenOptions::eOpenOptionCanCreate; + auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; if (m_options.m_append) - options |= File::OpenOptions::eOpenOptionAppend; + options |= File::eOpenOptionAppend; else - options |= File::OpenOptions::eOpenOptionTruncate; + options |= File::eOpenOptionTruncate; StreamFile out_file(path.c_str(), options, lldb::eFilePermissionsFileDefault); @@ -417,7 +401,7 @@ protected: for (const auto &arg : args) { Status error(GetDebugger().DumpPropertyValue( - &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport)); + &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport)); if (!error.Success()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -432,11 +416,8 @@ private: }; // CommandObjectSettingsRead -- Read settings from file - -static constexpr OptionDefinition g_settings_read_options[] = { #define LLDB_OPTIONS_settings_read #include "CommandOptions.inc" -}; class CommandObjectSettingsRead : public CommandObjectParsed { public: @@ -467,9 +448,7 @@ public: m_filename.assign(option_arg); break; default: - error.SetErrorStringWithFormat("unrecognized option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -536,13 +515,12 @@ public: ~CommandObjectSettingsList() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -622,14 +600,15 @@ public: ~CommandObjectSettingsRemove() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + bool WantsCompletion() override { return true; } + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -645,8 +624,8 @@ protected: const size_t argc = cmd_args.GetArgumentCount(); if (argc == 0) { - result.AppendError("'settings set' takes an array or dictionary item, or " - "an array followed by one or more indexes, or a " + result.AppendError("'settings remove' takes an array or dictionary item, " + "or an array followed by one or more indexes, or a " "dictionary followed by one or more key names to " "remove"); result.SetStatus(eReturnStatusFailed); @@ -656,19 +635,17 @@ protected: const char *var_name = cmd_args.GetArgumentAtIndex(0); if ((var_name == nullptr) || (var_name[0] == '\0')) { result.AppendError( - "'settings set' command requires a valid variable name"); + "'settings remove' command requires a valid variable name"); result.SetStatus(eReturnStatusFailed); return false; } // Split the raw command into var_name and value pair. - llvm::StringRef raw_str(command); - std::string var_value_string = raw_str.split(var_name).second.str(); - const char *var_value_cstr = - Args::StripSpaces(var_value_string, true, true, false); + llvm::StringRef var_value(command); + var_value = var_value.split(var_name).second.trim(); Status error(GetDebugger().SetPropertyValue( - &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr)); + &m_exe_ctx, eVarSetOperationRemove, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -735,16 +712,14 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - - return request.GetNumberOfMatches(); } protected: @@ -762,13 +737,11 @@ protected: } // Split the raw command into var_name, index_value, and value triple. - llvm::StringRef raw_str(command); - std::string var_value_string = raw_str.split(var_name).second.str(); - const char *var_value_cstr = - Args::StripSpaces(var_value_string, true, true, false); + llvm::StringRef var_value(command); + var_value = var_value.split(var_name).second.trim(); Status error(GetDebugger().SetPropertyValue( - &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr)); + &m_exe_ctx, eVarSetOperationReplace, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -833,16 +806,14 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - - return request.GetNumberOfMatches(); } protected: @@ -868,13 +839,11 @@ protected: } // Split the raw command into var_name, index_value, and value triple. - llvm::StringRef raw_str(command); - std::string var_value_string = raw_str.split(var_name).second.str(); - const char *var_value_cstr = - Args::StripSpaces(var_value_string, true, true, false); + llvm::StringRef var_value(command); + var_value = var_value.split(var_name).second.trim(); Status error(GetDebugger().SetPropertyValue( - &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr)); + &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -936,16 +905,14 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - - return request.GetNumberOfMatches(); } protected: @@ -971,13 +938,11 @@ protected: } // Split the raw command into var_name, index_value, and value triple. - llvm::StringRef raw_str(command); - std::string var_value_string = raw_str.split(var_name).second.str(); - const char *var_value_cstr = - Args::StripSpaces(var_value_string, true, true, false); + llvm::StringRef var_value(command); + var_value = var_value.split(var_name).second.trim(); Status error(GetDebugger().SetPropertyValue( - &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr)); + &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -1028,16 +993,14 @@ public: // !WantsRawCommandString. bool WantsCompletion() override { return true; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - - return request.GetNumberOfMatches(); } protected: @@ -1065,13 +1028,11 @@ protected: // character string later on. // Split the raw command into var_name and value pair. - llvm::StringRef raw_str(command); - std::string var_value_string = raw_str.split(var_name).second.str(); - const char *var_value_cstr = - Args::StripSpaces(var_value_string, true, true, false); + llvm::StringRef var_value(command); + var_value = var_value.split(var_name).second.trim(); Status error(GetDebugger().SetPropertyValue( - &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr)); + &m_exe_ctx, eVarSetOperationAppend, var_name, var_value)); if (error.Fail()) { result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); @@ -1107,16 +1068,14 @@ public: ~CommandObjectSettingsClear() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - - return request.GetNumberOfMatches(); } protected: diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp index 1b515d0f1099..78c8bc811926 100644 --- a/source/Commands/CommandObjectSource.cpp +++ b/source/Commands/CommandObjectSource.cpp @@ -33,18 +33,8 @@ using namespace lldb_private; #pragma mark CommandObjectSourceInfo // CommandObjectSourceInfo - debug line entries dumping command - -static constexpr OptionDefinition g_source_info_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of line entries to display." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, - { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." }, - { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, - { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, - // clang-format on -}; +#define LLDB_OPTIONS_source_info +#include "CommandOptions.inc" class CommandObjectSourceInfo : public CommandObjectParsed { class CommandOptions : public Options { @@ -92,9 +82,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed { modules.push_back(std::string(option_arg)); break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -404,17 +392,18 @@ protected: // const. ModuleList module_list = (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages(); - size_t num_matches = - module_list.FindFunctions(name, eFunctionNameTypeAuto, - /*include_symbols=*/false, - /*include_inlines=*/true, - /*append=*/true, sc_list_funcs); + module_list.FindFunctions(name, eFunctionNameTypeAuto, + /*include_symbols=*/false, + /*include_inlines=*/true, sc_list_funcs); + size_t num_matches = sc_list_funcs.GetSize(); + if (!num_matches) { // If we didn't find any functions with that name, try searching for // symbols that line up exactly with function addresses. SymbolContextList sc_list_symbols; - size_t num_symbol_matches = module_list.FindFunctionSymbols( + module_list.FindFunctionSymbols( name, eFunctionNameTypeAuto, sc_list_symbols); + size_t num_symbol_matches = sc_list_symbols.GetSize(); for (size_t i = 0; i < num_symbol_matches; i++) { SymbolContext sc; sc_list_symbols.GetContextAtIndex(i, sc); @@ -592,7 +581,8 @@ protected: FileSpec module_file_spec(m_options.modules[i]); if (module_file_spec) { ModuleSpec module_spec(module_file_spec); - if (target->GetImages().FindModules(module_spec, m_module_list) == 0) + target->GetImages().FindModules(module_spec, m_module_list); + if (m_module_list.IsEmpty()) result.AppendWarningWithFormat("No module found for '%s'.\n", m_options.modules[i].c_str()); } @@ -643,19 +633,8 @@ protected: #pragma mark CommandObjectSourceList // CommandObjectSourceList - -static constexpr OptionDefinition g_source_list_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of source lines to display." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." }, - { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, - { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the display source." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, - { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, - { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." }, - // clang-format on -}; +#define LLDB_OPTIONS_source_list +#include "CommandOptions.inc" class CommandObjectSourceList : public CommandObjectParsed { class CommandOptions : public Options { @@ -704,9 +683,7 @@ class CommandObjectSourceList : public CommandObjectParsed { reverse = true; break; default: - error.SetErrorStringWithFormat("unrecognized short option '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -759,7 +736,7 @@ public: // the arguments directly. auto iter = llvm::find_if(current_command_args, [](const Args::ArgEntry &e) { - return e.ref == "-r" || e.ref == "--reverse"; + return e.ref() == "-r" || e.ref() == "--reverse"; }); if (iter == current_command_args.end()) return m_cmd_name.c_str(); @@ -897,13 +874,11 @@ protected: // these somewhere, there should probably be a module-filter-list that can be // passed to the various ModuleList::Find* calls, which would either be a // vector of string names or a ModuleSpecList. - size_t FindMatchingFunctions(Target *target, ConstString name, + void FindMatchingFunctions(Target *target, ConstString name, SymbolContextList &sc_list) { // Displaying the source for a symbol: bool include_inlines = true; - bool append = true; bool include_symbols = false; - size_t num_matches = 0; if (m_options.num_lines == 0) m_options.num_lines = 10; @@ -917,22 +892,20 @@ protected: ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); target->GetImages().FindModules(module_spec, matching_modules); - num_matches += matching_modules.FindFunctions( + matching_modules.FindFunctions( name, eFunctionNameTypeAuto, include_symbols, include_inlines, - append, sc_list); + sc_list); } } } else { - num_matches = target->GetImages().FindFunctions( - name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, - sc_list); + target->GetImages().FindFunctions(name, eFunctionNameTypeAuto, + include_symbols, include_inlines, + sc_list); } - return num_matches; } - size_t FindMatchingFunctionSymbols(Target *target, ConstString name, - SymbolContextList &sc_list) { - size_t num_matches = 0; + void FindMatchingFunctionSymbols(Target *target, ConstString name, + SymbolContextList &sc_list) { const size_t num_modules = m_options.modules.size(); if (num_modules > 0) { ModuleList matching_modules; @@ -942,15 +915,14 @@ protected: ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); target->GetImages().FindModules(module_spec, matching_modules); - num_matches += matching_modules.FindFunctionSymbols( - name, eFunctionNameTypeAuto, sc_list); + matching_modules.FindFunctionSymbols(name, eFunctionNameTypeAuto, + sc_list); } } } else { - num_matches = target->GetImages().FindFunctionSymbols( - name, eFunctionNameTypeAuto, sc_list); + target->GetImages().FindFunctionSymbols(name, eFunctionNameTypeAuto, + sc_list); } - return num_matches; } bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -970,13 +942,15 @@ protected: ConstString name(m_options.symbol_name.c_str()); // Displaying the source for a symbol. Search for function named name. - size_t num_matches = FindMatchingFunctions(target, name, sc_list); + FindMatchingFunctions(target, name, sc_list); + size_t num_matches = sc_list.GetSize(); if (!num_matches) { // If we didn't find any functions with that name, try searching for // symbols that line up exactly with function addresses. SymbolContextList sc_list_symbols; - size_t num_symbol_matches = - FindMatchingFunctionSymbols(target, name, sc_list_symbols); + FindMatchingFunctionSymbols(target, name, sc_list_symbols); + size_t num_symbol_matches =sc_list_symbols.GetSize(); + for (size_t i = 0; i < num_symbol_matches; i++) { SymbolContext sc; sc_list_symbols.GetContextAtIndex(i, sc); diff --git a/source/Commands/CommandObjectStats.cpp b/source/Commands/CommandObjectStats.cpp index a73c2a8e0409..e3a1f9433662 100644 --- a/source/Commands/CommandObjectStats.cpp +++ b/source/Commands/CommandObjectStats.cpp @@ -26,15 +26,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); + Target &target = GetSelectedOrDummyTarget(); - if (target->GetCollectingStats()) { + if (target.GetCollectingStats()) { result.AppendError("statistics already enabled"); result.SetStatus(eReturnStatusFailed); return false; } - target->SetCollectingStats(true); + target.SetCollectingStats(true); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -51,15 +51,15 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); + Target &target = GetSelectedOrDummyTarget(); - if (!target->GetCollectingStats()) { + if (!target.GetCollectingStats()) { result.AppendError("need to enable statistics before disabling them"); result.SetStatus(eReturnStatusFailed); return false; } - target->SetCollectingStats(false); + target.SetCollectingStats(false); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -75,10 +75,10 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); + Target &target = GetSelectedOrDummyTarget(); uint32_t i = 0; - for (auto &stat : target->GetStatistics()) { + for (auto &stat : target.GetStatistics()) { result.AppendMessageWithFormat( "%s : %u\n", lldb_private::GetStatDescription(static_cast<lldb_private::StatisticKind>(i)) diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index e913a28501f2..abf7895a7384 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -37,7 +37,6 @@ #include "lldb/Symbol/LocateSymbolFile.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ABI.h" @@ -135,22 +134,27 @@ static uint32_t DumpTargetList(TargetList &target_list, } // Note that the negation in the argument name causes a slightly confusing -// mapping of the enum values, +// mapping of the enum values. static constexpr OptionEnumValueElement g_dependents_enumaration[] = { - {eLoadDependentsDefault, "default", - "Only load dependents when the target is an executable."}, - {eLoadDependentsNo, "true", - "Don't load dependents, even if the target is an executable."}, - {eLoadDependentsYes, "false", - "Load dependents, even if the target is not an executable."}}; - -static constexpr OptionDefinition g_dependents_options[] = { - {LLDB_OPT_SET_1, false, "no-dependents", 'd', - OptionParser::eOptionalArgument, nullptr, - OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue, - "Whether or not to load dependents when creating a target. If the option " - "is not specified, the value is implicitly 'default'. If the option is " - "specified but without a value, the value is implicitly 'true'."}}; + { + eLoadDependentsDefault, + "default", + "Only load dependents when the target is an executable.", + }, + { + eLoadDependentsNo, + "true", + "Don't load dependents, even if the target is an executable.", + }, + { + eLoadDependentsYes, + "false", + "Load dependents, even if the target is not an executable.", + }, +}; + +#define LLDB_OPTIONS_target_dependents +#include "CommandOptions.inc" class OptionGroupDependents : public OptionGroup { public: @@ -159,7 +163,7 @@ public: ~OptionGroupDependents() override {} llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_dependents_options); + return llvm::makeArrayRef(g_target_dependents_options); } Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, @@ -172,11 +176,13 @@ public: return error; } - const char short_option = g_dependents_options[option_idx].short_option; + const char short_option = + g_target_dependents_options[option_idx].short_option; if (short_option == 'd') { LoadDependentFiles tmp_load_dependents; tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum( - option_value, g_dependents_options[option_idx].enum_values, 0, error); + option_value, g_target_dependents_options[option_idx].enum_values, 0, + error); if (error.Success()) m_load_dependent_files = tmp_load_dependents; } else { @@ -252,13 +258,12 @@ public: Options *GetOptions() override { return &m_option_group; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -444,7 +449,8 @@ protected: } } else { result.AppendMessageWithFormat( - "Current executable set to '%s' (%s).\n", file_path, + "Current executable set to '%s' (%s).\n", + file_spec.GetPath().c_str(), target_sp->GetArchitecture().GetArchitectureName()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } @@ -619,7 +625,7 @@ protected: for (auto &entry : args.entries()) { uint32_t target_idx; - if (entry.ref.getAsInteger(0, target_idx)) { + if (entry.ref().getAsInteger(0, target_idx)) { result.AppendErrorWithFormat("invalid target index '%s'\n", entry.c_str()); result.SetStatus(eReturnStatusFailed); @@ -792,12 +798,12 @@ public: static size_t GetVariableCallback(void *baton, const char *name, VariableList &variable_list) { + size_t old_size = variable_list.GetSize(); Target *target = static_cast<Target *>(baton); - if (target) { - return target->GetImages().FindGlobalVariables(ConstString(name), - UINT32_MAX, variable_list); - } - return 0; + if (target) + target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX, + variable_list); + return variable_list.GetSize() - old_size; } Options *GetOptions() override { return &m_option_group; } @@ -860,8 +866,9 @@ protected: return false; } use_var_name = true; - matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX, - variable_list); + target->GetImages().FindGlobalVariables(regex, UINT32_MAX, + variable_list); + matches = variable_list.GetSize(); } else { Status error(Variable::GetValuesForVariableExpressionPath( arg, m_exe_ctx.GetBestExecutionContextScope(), @@ -936,7 +943,6 @@ protected: } } else { SymbolContextList sc_list; - const bool append = true; // We have one or more compile unit or shlib if (num_shlibs > 0) { for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) { @@ -949,8 +955,7 @@ protected: if (num_compile_units > 0) { for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) module_sp->FindCompileUnits( - compile_units.GetFileSpecAtIndex(cu_idx), append, - sc_list); + compile_units.GetFileSpecAtIndex(cu_idx), sc_list); } else { SymbolContext sc; sc.module_sp = module_sp; @@ -968,7 +973,7 @@ protected: // units files that were specified for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) target->GetImages().FindCompileUnits( - compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); + compile_units.GetFileSpecAtIndex(cu_idx), sc_list); } const uint32_t num_scs = sc_list.GetSize(); @@ -1024,7 +1029,7 @@ public: : CommandObjectParsed(interpreter, "target modules search-paths add", "Add new image search paths substitution pairs to " "the current target.", - nullptr) { + nullptr, eCommandRequiresTarget) { CommandArgumentEntry arg; CommandArgumentData old_prefix_arg; CommandArgumentData new_prefix_arg; @@ -1053,41 +1058,37 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target) { - const size_t argc = command.GetArgumentCount(); - if (argc & 1) { - result.AppendError("add requires an even number of arguments\n"); - result.SetStatus(eReturnStatusFailed); - } else { - for (size_t i = 0; i < argc; i += 2) { - const char *from = command.GetArgumentAtIndex(i); - const char *to = command.GetArgumentAtIndex(i + 1); - - if (from[0] && to[0]) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) { - log->Printf("target modules search path adding ImageSearchPath " - "pair: '%s' -> '%s'", - from, to); - } - bool last_pair = ((argc - i) == 2); - target->GetImageSearchPathList().Append( - ConstString(from), ConstString(to), - last_pair); // Notify if this is the last pair - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - if (from[0]) - result.AppendError("<path-prefix> can't be empty\n"); - else - result.AppendError("<new-path-prefix> can't be empty\n"); - result.SetStatus(eReturnStatusFailed); + Target *target = &GetSelectedTarget(); + const size_t argc = command.GetArgumentCount(); + if (argc & 1) { + result.AppendError("add requires an even number of arguments\n"); + result.SetStatus(eReturnStatusFailed); + } else { + for (size_t i = 0; i < argc; i += 2) { + const char *from = command.GetArgumentAtIndex(i); + const char *to = command.GetArgumentAtIndex(i + 1); + + if (from[0] && to[0]) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (log) { + LLDB_LOGF(log, + "target modules search path adding ImageSearchPath " + "pair: '%s' -> '%s'", + from, to); } + bool last_pair = ((argc - i) == 2); + target->GetImageSearchPathList().Append( + ConstString(from), ConstString(to), + last_pair); // Notify if this is the last pair + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } else { + if (from[0]) + result.AppendError("<path-prefix> can't be empty\n"); + else + result.AppendError("<new-path-prefix> can't be empty\n"); + result.SetStatus(eReturnStatusFailed); } } - } else { - result.AppendError("invalid target\n"); - result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -1101,21 +1102,17 @@ public: : CommandObjectParsed(interpreter, "target modules search-paths clear", "Clear all current image search path substitution " "pairs from the current target.", - "target modules search-paths clear") {} + "target modules search-paths clear", + eCommandRequiresTarget) {} ~CommandObjectTargetModulesSearchPathsClear() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target) { - bool notify = true; - target->GetImageSearchPathList().Clear(notify); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("invalid target\n"); - result.SetStatus(eReturnStatusFailed); - } + Target *target = &GetSelectedTarget(); + bool notify = true; + target->GetImageSearchPathList().Clear(notify); + result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); } }; @@ -1128,7 +1125,7 @@ public: : CommandObjectParsed(interpreter, "target modules search-paths insert", "Insert a new image search path substitution pair " "into the current target at the specified index.", - nullptr) { + nullptr, eCommandRequiresTarget) { CommandArgumentEntry arg1; CommandArgumentEntry arg2; CommandArgumentData index_arg; @@ -1168,55 +1165,49 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target) { - size_t argc = command.GetArgumentCount(); - // check for at least 3 arguments and an odd number of parameters - if (argc >= 3 && argc & 1) { - bool success = false; + Target *target = &GetSelectedTarget(); + size_t argc = command.GetArgumentCount(); + // check for at least 3 arguments and an odd number of parameters + if (argc >= 3 && argc & 1) { + bool success = false; - uint32_t insert_idx = StringConvert::ToUInt32( - command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); + uint32_t insert_idx = StringConvert::ToUInt32( + command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); - if (!success) { - result.AppendErrorWithFormat( - "<index> parameter is not an integer: '%s'.\n", - command.GetArgumentAtIndex(0)); - result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); - } + if (!success) { + result.AppendErrorWithFormat( + "<index> parameter is not an integer: '%s'.\n", + command.GetArgumentAtIndex(0)); + result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); + } - // shift off the index - command.Shift(); - argc = command.GetArgumentCount(); + // shift off the index + command.Shift(); + argc = command.GetArgumentCount(); - for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) { - const char *from = command.GetArgumentAtIndex(i); - const char *to = command.GetArgumentAtIndex(i + 1); + for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) { + const char *from = command.GetArgumentAtIndex(i); + const char *to = command.GetArgumentAtIndex(i + 1); - if (from[0] && to[0]) { - bool last_pair = ((argc - i) == 2); - target->GetImageSearchPathList().Insert( - ConstString(from), ConstString(to), insert_idx, last_pair); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - if (from[0]) - result.AppendError("<path-prefix> can't be empty\n"); - else - result.AppendError("<new-path-prefix> can't be empty\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } + if (from[0] && to[0]) { + bool last_pair = ((argc - i) == 2); + target->GetImageSearchPathList().Insert( + ConstString(from), ConstString(to), insert_idx, last_pair); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } else { + if (from[0]) + result.AppendError("<path-prefix> can't be empty\n"); + else + result.AppendError("<new-path-prefix> can't be empty\n"); + result.SetStatus(eReturnStatusFailed); + return false; } - } else { - result.AppendError("insert requires at least three arguments\n"); - result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); } - } else { - result.AppendError("invalid target\n"); + result.AppendError("insert requires at least three arguments\n"); result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); } return result.Succeeded(); } @@ -1230,26 +1221,22 @@ public: : CommandObjectParsed(interpreter, "target modules search-paths list", "List all current image search path substitution " "pairs in the current target.", - "target modules search-paths list") {} + "target modules search-paths list", + eCommandRequiresTarget) {} ~CommandObjectTargetModulesSearchPathsList() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target) { - if (command.GetArgumentCount() != 0) { - result.AppendError("list takes no arguments\n"); - result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); - } - - target->GetImageSearchPathList().Dump(&result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendError("invalid target\n"); + Target *target = &GetSelectedTarget(); + if (command.GetArgumentCount() != 0) { + result.AppendError("list takes no arguments\n"); result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); } + + target->GetImageSearchPathList().Dump(&result.GetOutputStream()); + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } }; @@ -1262,7 +1249,7 @@ public: : CommandObjectParsed( interpreter, "target modules search-paths query", "Transform a path using the first applicable image search path.", - nullptr) { + nullptr, eCommandRequiresTarget) { CommandArgumentEntry arg; CommandArgumentData path_arg; @@ -1282,26 +1269,21 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target) { - if (command.GetArgumentCount() != 1) { - result.AppendError("query requires one argument\n"); - result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); - } - - ConstString orig(command.GetArgumentAtIndex(0)); - ConstString transformed; - if (target->GetImageSearchPathList().RemapPath(orig, transformed)) - result.GetOutputStream().Printf("%s\n", transformed.GetCString()); - else - result.GetOutputStream().Printf("%s\n", orig.GetCString()); - - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendError("invalid target\n"); + Target *target = &GetSelectedTarget(); + if (command.GetArgumentCount() != 1) { + result.AppendError("query requires one argument\n"); result.SetStatus(eReturnStatusFailed); + return result.Succeeded(); } + + ConstString orig(command.GetArgumentAtIndex(0)); + ConstString transformed; + if (target->GetImageSearchPathList().RemapPath(orig, transformed)) + result.GetOutputStream().Printf("%s\n", transformed.GetCString()); + else + result.GetOutputStream().Printf("%s\n", orig.GetCString()); + + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } }; @@ -1439,15 +1421,11 @@ static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) { static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) { - if (module) { - SymbolVendor *sym_vendor = module->GetSymbolVendor(); - if (sym_vendor) { - Symtab *symtab = sym_vendor->GetSymtab(); - if (symtab) - symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), - sort_order); - } - } + if (!module) + return; + if (Symtab *symtab = module->GetSymtab()) + symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), + sort_order); } static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, @@ -1467,11 +1445,10 @@ static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, } } -static bool DumpModuleSymbolVendor(Stream &strm, Module *module) { +static bool DumpModuleSymbolFile(Stream &strm, Module *module) { if (module) { - SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); - if (symbol_vendor) { - symbol_vendor->Dump(&strm); + if (SymbolFile *symbol_file = module->GetSymbolFile(true)) { + symbol_file->Dump(strm); return true; } } @@ -1553,47 +1530,44 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) { - if (module) { - SymbolContext sc; + if (!module) + return 0; - SymbolVendor *sym_vendor = module->GetSymbolVendor(); - if (sym_vendor) { - Symtab *symtab = sym_vendor->GetSymtab(); - if (symtab) { - std::vector<uint32_t> match_indexes; - ConstString symbol_name(name); - uint32_t num_matches = 0; - if (name_is_regex) { - RegularExpression name_regexp(symbol_name.GetStringRef()); - num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType( - name_regexp, eSymbolTypeAny, match_indexes); - } else { - num_matches = - symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes); - } + Symtab *symtab = module->GetSymtab(); + if (!symtab) + return 0; - if (num_matches > 0) { - strm.Indent(); - strm.Printf("%u symbols match %s'%s' in ", num_matches, - name_is_regex ? "the regular expression " : "", name); - DumpFullpath(strm, &module->GetFileSpec(), 0); - strm.PutCString(":\n"); - strm.IndentMore(); - for (uint32_t i = 0; i < num_matches; ++i) { - Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); - if (symbol && symbol->ValueIsAddress()) { - DumpAddress(interpreter.GetExecutionContext() - .GetBestExecutionContextScope(), - symbol->GetAddressRef(), verbose, strm); - } - } - strm.IndentLess(); - return num_matches; - } + SymbolContext sc; + std::vector<uint32_t> match_indexes; + ConstString symbol_name(name); + uint32_t num_matches = 0; + if (name_is_regex) { + RegularExpression name_regexp(symbol_name.GetStringRef()); + num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType( + name_regexp, eSymbolTypeAny, match_indexes); + } else { + num_matches = + symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes); + } + + if (num_matches > 0) { + strm.Indent(); + strm.Printf("%u symbols match %s'%s' in ", num_matches, + name_is_regex ? "the regular expression " : "", name); + DumpFullpath(strm, &module->GetFileSpec(), 0); + strm.PutCString(":\n"); + strm.IndentMore(); + for (uint32_t i = 0; i < num_matches; ++i) { + Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); + if (symbol && symbol->ValueIsAddress()) { + DumpAddress( + interpreter.GetExecutionContext().GetBestExecutionContextScope(), + symbol->GetAddressRef(), verbose, strm); } } + strm.IndentLess(); } - return 0; + return num_matches; } static void DumpSymbolContextList(ExecutionContextScope *exe_scope, @@ -1623,19 +1597,17 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter, bool verbose) { if (module && name && name[0]) { SymbolContextList sc_list; - const bool append = true; size_t num_matches = 0; if (name_is_regex) { RegularExpression function_name_regex((llvm::StringRef(name))); - num_matches = module->FindFunctions(function_name_regex, include_symbols, - include_inlines, append, sc_list); + module->FindFunctions(function_name_regex, include_symbols, + include_inlines, sc_list); } else { ConstString function_name(name); - num_matches = module->FindFunctions( - function_name, nullptr, eFunctionNameTypeAuto, include_symbols, - include_inlines, append, sc_list); + module->FindFunctions(function_name, nullptr, eFunctionNameTypeAuto, + include_symbols, include_inlines, sc_list); } - + num_matches = sc_list.GetSize(); if (num_matches) { strm.Indent(); strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, @@ -1654,75 +1626,30 @@ static size_t LookupFunctionInModule(CommandInterpreter &interpreter, static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name_cstr, bool name_is_regex) { + TypeList type_list; if (module && name_cstr && name_cstr[0]) { - TypeList type_list; const uint32_t max_num_matches = UINT32_MAX; size_t num_matches = 0; bool name_is_fully_qualified = false; ConstString name(name_cstr); llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files; - num_matches = - module->FindTypes(name, name_is_fully_qualified, max_num_matches, - searched_symbol_files, type_list); + module->FindTypes(name, name_is_fully_qualified, max_num_matches, + searched_symbol_files, type_list); - if (num_matches) { - strm.Indent(); - strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, - num_matches > 1 ? "es" : ""); - DumpFullpath(strm, &module->GetFileSpec(), 0); - strm.PutCString(":\n"); - for (TypeSP type_sp : type_list.Types()) { - if (type_sp) { - // Resolve the clang type so that any forward references to types - // that haven't yet been parsed will get parsed. - type_sp->GetFullCompilerType(); - type_sp->GetDescription(&strm, eDescriptionLevelFull, true); - // Print all typedef chains - TypeSP typedef_type_sp(type_sp); - TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType()); - while (typedefed_type_sp) { - strm.EOL(); - strm.Printf(" typedef '%s': ", - typedef_type_sp->GetName().GetCString()); - typedefed_type_sp->GetFullCompilerType(); - typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, - true); - typedef_type_sp = typedefed_type_sp; - typedefed_type_sp = typedef_type_sp->GetTypedefType(); - } - } - strm.EOL(); - } - } - return num_matches; - } - return 0; -} - -static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm, - Module &module, const char *name_cstr, - bool name_is_regex) { - TypeList type_list; - const uint32_t max_num_matches = UINT32_MAX; - size_t num_matches = 1; - bool name_is_fully_qualified = false; + if (type_list.Empty()) + return 0; - ConstString name(name_cstr); - llvm::DenseSet<SymbolFile *> searched_symbol_files; - num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches, - searched_symbol_files, type_list); - - if (num_matches) { strm.Indent(); - strm.PutCString("Best match found in "); - DumpFullpath(strm, &module.GetFileSpec(), 0); + strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, + num_matches > 1 ? "es" : ""); + DumpFullpath(strm, &module->GetFileSpec(), 0); strm.PutCString(":\n"); - - TypeSP type_sp(type_list.GetTypeAtIndex(0)); - if (type_sp) { - // Resolve the clang type so that any forward references to types that - // haven't yet been parsed will get parsed. + for (TypeSP type_sp : type_list.Types()) { + if (!type_sp) + continue; + // Resolve the clang type so that any forward references to types + // that haven't yet been parsed will get parsed. type_sp->GetFullCompilerType(); type_sp->GetDescription(&strm, eDescriptionLevelFull, true); // Print all typedef chains @@ -1740,7 +1667,50 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm, } strm.EOL(); } - return num_matches; + return type_list.GetSize(); +} + +static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm, + Module &module, const char *name_cstr, + bool name_is_regex) { + TypeList type_list; + const uint32_t max_num_matches = UINT32_MAX; + bool name_is_fully_qualified = false; + + ConstString name(name_cstr); + llvm::DenseSet<SymbolFile *> searched_symbol_files; + module.FindTypes(name, name_is_fully_qualified, max_num_matches, + searched_symbol_files, type_list); + + if (type_list.Empty()) + return 0; + + strm.Indent(); + strm.PutCString("Best match found in "); + DumpFullpath(strm, &module.GetFileSpec(), 0); + strm.PutCString(":\n"); + + TypeSP type_sp(type_list.GetTypeAtIndex(0)); + if (type_sp) { + // Resolve the clang type so that any forward references to types that + // haven't yet been parsed will get parsed. + type_sp->GetFullCompilerType(); + type_sp->GetDescription(&strm, eDescriptionLevelFull, true); + // Print all typedef chains + TypeSP typedef_type_sp(type_sp); + TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType()); + while (typedefed_type_sp) { + strm.EOL(); + strm.Printf(" typedef '%s': ", + typedef_type_sp->GetName().GetCString()); + typedefed_type_sp->GetFullCompilerType(); + typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true); + typedef_type_sp = typedefed_type_sp; + typedefed_type_sp = typedef_type_sp->GetTypedefType(); + } + } + strm.EOL(); + return type_list.GetSize(); } static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, @@ -1797,8 +1767,8 @@ static size_t FindModulesByName(Target *target, const char *module_name, } } else { if (target) { - const size_t num_matches = - target->GetImages().FindModules(module_spec, module_list); + target->GetImages().FindModules(module_spec, module_list); + const size_t num_matches = module_list.GetSize(); // Not found in our module list for our target, check the main shared // module list in case it is a extra file used somewhere else @@ -1825,8 +1795,9 @@ public: CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, - const char *syntax) - : CommandObjectParsed(interpreter, name, help, syntax) { + const char *syntax, + uint32_t flags = 0) + : CommandObjectParsed(interpreter, name, help, syntax, flags) { CommandArgumentEntry arg; CommandArgumentData file_arg; @@ -1844,13 +1815,12 @@ public: ~CommandObjectTargetModulesModuleAutoComplete() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request, nullptr); - return request.GetNumberOfMatches(); } }; @@ -1883,13 +1853,12 @@ public: ~CommandObjectTargetModulesSourceFileAutoComplete() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } }; @@ -1902,19 +1871,13 @@ public: : CommandObjectTargetModulesModuleAutoComplete( interpreter, "target modules dump objfile", "Dump the object file headers from one or more target modules.", - nullptr) {} + nullptr, eCommandRequiresTarget) {} ~CommandObjectTargetModulesDumpObjfile() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target *target = &GetSelectedTarget(); uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); result.GetOutputStream().SetAddressByteSize(addr_byte_size); @@ -1961,15 +1924,25 @@ protected: #pragma mark CommandObjectTargetModulesDumpSymtab static constexpr OptionEnumValueElement g_sort_option_enumeration[] = { - {eSortOrderNone, "none", - "No sorting, use the original symbol table order."}, - {eSortOrderByAddress, "address", "Sort output by symbol address."}, - {eSortOrderByName, "name", "Sort output by symbol name."} }; + { + eSortOrderNone, + "none", + "No sorting, use the original symbol table order.", + }, + { + eSortOrderByAddress, + "address", + "Sort output by symbol address.", + }, + { + eSortOrderByName, + "name", + "Sort output by symbol name.", + }, +}; -static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = { #define LLDB_OPTIONS_target_modules_dump_symtab #include "CommandOptions.inc" -}; class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete { @@ -1977,7 +1950,8 @@ public: CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter) : CommandObjectTargetModulesModuleAutoComplete( interpreter, "target modules dump symtab", - "Dump the symbol table from one or more target modules.", nullptr), + "Dump the symbol table from one or more target modules.", nullptr, + eCommandRequiresTarget), m_options() {} ~CommandObjectTargetModulesDumpSymtab() override = default; @@ -2003,9 +1977,7 @@ public: break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -2023,82 +1995,75 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - uint32_t num_dumped = 0; + Target *target = &GetSelectedTarget(); + uint32_t num_dumped = 0; - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); - if (command.GetArgumentCount() == 0) { - // Dump all sections for all modules images - std::lock_guard<std::recursive_mutex> guard( - target->GetImages().GetMutex()); - const size_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) { - result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 - " modules.\n", - (uint64_t)num_modules); - for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { - if (num_dumped > 0) { - result.GetOutputStream().EOL(); - result.GetOutputStream().EOL(); - } - if (m_interpreter.WasInterrupted()) - break; - num_dumped++; - DumpModuleSymtab( - m_interpreter, result.GetOutputStream(), - target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), - m_options.m_sort_order); + if (command.GetArgumentCount() == 0) { + // Dump all sections for all modules images + std::lock_guard<std::recursive_mutex> guard( + target->GetImages().GetMutex()); + const size_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) { + result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64 + " modules.\n", + (uint64_t)num_modules); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { + if (num_dumped > 0) { + result.GetOutputStream().EOL(); + result.GetOutputStream().EOL(); } - } else { - result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); - return false; + if (m_interpreter.WasInterrupted()) + break; + num_dumped++; + DumpModuleSymtab( + m_interpreter, result.GetOutputStream(), + target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), + m_options.m_sort_order); } } else { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; - (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; - ++arg_idx) { - ModuleList module_list; - const size_t num_matches = - FindModulesByName(target, arg_cstr, module_list, true); - if (num_matches > 0) { - for (size_t i = 0; i < num_matches; ++i) { - Module *module = module_list.GetModulePointerAtIndex(i); - if (module) { - if (num_dumped > 0) { - result.GetOutputStream().EOL(); - result.GetOutputStream().EOL(); - } - if (m_interpreter.WasInterrupted()) - break; - num_dumped++; - DumpModuleSymtab(m_interpreter, result.GetOutputStream(), - module, m_options.m_sort_order); + result.AppendError("the target has no associated executable images"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; + (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; + ++arg_idx) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(target, arg_cstr, module_list, true); + if (num_matches > 0) { + for (size_t i = 0; i < num_matches; ++i) { + Module *module = module_list.GetModulePointerAtIndex(i); + if (module) { + if (num_dumped > 0) { + result.GetOutputStream().EOL(); + result.GetOutputStream().EOL(); } + if (m_interpreter.WasInterrupted()) + break; + num_dumped++; + DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module, + m_options.m_sort_order); } - } else - result.AppendWarningWithFormat( - "Unable to find an image that matches '%s'.\n", arg_cstr); - } + } + } else + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg_cstr); } + } - if (num_dumped > 0) - result.SetStatus(eReturnStatusSuccessFinishResult); - else { - result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); - } + if (num_dumped > 0) + result.SetStatus(eReturnStatusSuccessFinishResult); + else { + result.AppendError("no matching executable images found"); + result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2118,82 +2083,75 @@ public: interpreter, "target modules dump sections", "Dump the sections from one or more target modules.", //"target modules dump sections [<file1> ...]") - nullptr) {} + nullptr, eCommandRequiresTarget) {} ~CommandObjectTargetModulesDumpSections() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - uint32_t num_dumped = 0; + Target *target = &GetSelectedTarget(); + uint32_t num_dumped = 0; - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); - if (command.GetArgumentCount() == 0) { - // Dump all sections for all modules images - const size_t num_modules = target->GetImages().GetSize(); - if (num_modules > 0) { - result.GetOutputStream().Printf("Dumping sections for %" PRIu64 - " modules.\n", - (uint64_t)num_modules); - for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { + if (command.GetArgumentCount() == 0) { + // Dump all sections for all modules images + const size_t num_modules = target->GetImages().GetSize(); + if (num_modules > 0) { + result.GetOutputStream().Printf("Dumping sections for %" PRIu64 + " modules.\n", + (uint64_t)num_modules); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { + if (m_interpreter.WasInterrupted()) + break; + num_dumped++; + DumpModuleSections( + m_interpreter, result.GetOutputStream(), + target->GetImages().GetModulePointerAtIndex(image_idx)); + } + } else { + result.AppendError("the target has no associated executable images"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; + (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; + ++arg_idx) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(target, arg_cstr, module_list, true); + if (num_matches > 0) { + for (size_t i = 0; i < num_matches; ++i) { if (m_interpreter.WasInterrupted()) break; - num_dumped++; - DumpModuleSections( - m_interpreter, result.GetOutputStream(), - target->GetImages().GetModulePointerAtIndex(image_idx)); + Module *module = module_list.GetModulePointerAtIndex(i); + if (module) { + num_dumped++; + DumpModuleSections(m_interpreter, result.GetOutputStream(), + module); + } } } else { - result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } else { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; - (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; - ++arg_idx) { - ModuleList module_list; - const size_t num_matches = - FindModulesByName(target, arg_cstr, module_list, true); - if (num_matches > 0) { - for (size_t i = 0; i < num_matches; ++i) { - if (m_interpreter.WasInterrupted()) - break; - Module *module = module_list.GetModulePointerAtIndex(i); - if (module) { - num_dumped++; - DumpModuleSections(m_interpreter, result.GetOutputStream(), - module); - } - } - } else { - // Check the global list - std::lock_guard<std::recursive_mutex> guard( - Module::GetAllocationModuleCollectionMutex()); + // Check the global list + std::lock_guard<std::recursive_mutex> guard( + Module::GetAllocationModuleCollectionMutex()); - result.AppendWarningWithFormat( - "Unable to find an image that matches '%s'.\n", arg_cstr); - } + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg_cstr); } } + } - if (num_dumped > 0) - result.SetStatus(eReturnStatusSuccessFinishResult); - else { - result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); - } + if (num_dumped > 0) + result.SetStatus(eReturnStatusSuccessFinishResult); + else { + result.AppendError("no matching executable images found"); + result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } @@ -2211,19 +2169,13 @@ public: interpreter, "target modules dump ast", "Dump the clang ast for a given module's symbol file.", //"target modules dump ast [<file1> ...]") - nullptr) {} + nullptr, eCommandRequiresTarget) {} ~CommandObjectTargetModulesDumpClangAST() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } + Target *target = &GetSelectedTarget(); const size_t num_modules = target->GetImages().GetSize(); if (num_modules == 0) { @@ -2241,8 +2193,8 @@ protected: if (m_interpreter.WasInterrupted()) break; Module *m = target->GetImages().GetModulePointerAtIndex(image_idx); - SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile(); - sf->DumpClangAST(result.GetOutputStream()); + if (SymbolFile *sf = m->GetSymbolFile()) + sf->DumpClangAST(result.GetOutputStream()); } result.SetStatus(eReturnStatusSuccessFinishResult); return true; @@ -2267,8 +2219,8 @@ protected: if (m_interpreter.WasInterrupted()) break; Module *m = module_list.GetModulePointerAtIndex(i); - SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile(); - sf->DumpClangAST(result.GetOutputStream()); + if (SymbolFile *sf = m->GetSymbolFile()) + sf->DumpClangAST(result.GetOutputStream()); } } result.SetStatus(eReturnStatusSuccessFinishResult); @@ -2288,84 +2240,79 @@ public: interpreter, "target modules dump symfile", "Dump the debug symbol file for one or more target modules.", //"target modules dump symfile [<file1> ...]") - nullptr) {} + nullptr, eCommandRequiresTarget) {} ~CommandObjectTargetModulesDumpSymfile() override = default; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - uint32_t num_dumped = 0; + Target *target = &GetSelectedTarget(); + uint32_t num_dumped = 0; - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); - if (command.GetArgumentCount() == 0) { - // Dump all sections for all modules images - const ModuleList &target_modules = target->GetImages(); - std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); - const size_t num_modules = target_modules.GetSize(); - if (num_modules > 0) { - result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 - " modules.\n", - (uint64_t)num_modules); - for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) { - if (m_interpreter.WasInterrupted()) - break; - if (DumpModuleSymbolVendor( - result.GetOutputStream(), - target_modules.GetModulePointerAtIndexUnlocked(image_idx))) - num_dumped++; - } - } else { - result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); - return false; + if (command.GetArgumentCount() == 0) { + // Dump all sections for all modules images + const ModuleList &target_modules = target->GetImages(); + std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); + const size_t num_modules = target_modules.GetSize(); + if (num_modules > 0) { + result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64 + " modules.\n", + (uint64_t)num_modules); + for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) { + if (m_interpreter.WasInterrupted()) + break; + if (DumpModuleSymbolFile( + result.GetOutputStream(), + target_modules.GetModulePointerAtIndexUnlocked(image_idx))) + num_dumped++; } } else { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (int arg_idx = 0; - (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; - ++arg_idx) { - ModuleList module_list; - const size_t num_matches = - FindModulesByName(target, arg_cstr, module_list, true); - if (num_matches > 0) { - for (size_t i = 0; i < num_matches; ++i) { - if (m_interpreter.WasInterrupted()) - break; - Module *module = module_list.GetModulePointerAtIndex(i); - if (module) { - if (DumpModuleSymbolVendor(result.GetOutputStream(), module)) - num_dumped++; - } + result.AppendError("the target has no associated executable images"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (int arg_idx = 0; + (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; + ++arg_idx) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(target, arg_cstr, module_list, true); + if (num_matches > 0) { + for (size_t i = 0; i < num_matches; ++i) { + if (m_interpreter.WasInterrupted()) + break; + Module *module = module_list.GetModulePointerAtIndex(i); + if (module) { + if (DumpModuleSymbolFile(result.GetOutputStream(), module)) + num_dumped++; } - } else - result.AppendWarningWithFormat( - "Unable to find an image that matches '%s'.\n", arg_cstr); - } + } + } else + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg_cstr); } + } - if (num_dumped > 0) - result.SetStatus(eReturnStatusSuccessFinishResult); - else { - result.AppendError("no matching executable images found"); - result.SetStatus(eReturnStatusFailed); - } + if (num_dumped > 0) + result.SetStatus(eReturnStatusSuccessFinishResult); + else { + result.AppendError("no matching executable images found"); + result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); } }; #pragma mark CommandObjectTargetModulesDumpLineTable +#define LLDB_OPTIONS_target_modules_dump +#include "CommandOptions.inc" // Image debug line table dumping command @@ -2454,19 +2401,7 @@ protected: } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - static constexpr OptionDefinition g_options[] = { - {LLDB_OPT_SET_ALL, - false, - "verbose", - 'v', - OptionParser::eNoArgument, - nullptr, - {}, - 0, - eArgTypeNone, - "Enable verbose dump."}, - }; - return llvm::makeArrayRef(g_options); + return llvm::makeArrayRef(g_target_modules_dump_options); } bool m_verbose; @@ -2518,10 +2453,11 @@ public: CommandObjectTargetModulesAdd(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "target modules add", "Add a new module to the current target's modules.", - "target modules add [<module>]"), - m_option_group(), - m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0, - eArgTypeFilename, "Fullpath to a stand alone debug " + "target modules add [<module>]", + eCommandRequiresTarget), + m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', + 0, eArgTypeFilename, + "Fullpath to a stand alone debug " "symbols file for when debug symbols " "are not in the executable.") { m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, @@ -2534,13 +2470,12 @@ public: Options *GetOptions() override { return &m_option_group; } - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } protected: @@ -2549,125 +2484,117 @@ protected: OptionGroupFile m_symbol_file; bool DoExecute(Args &args, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - bool flush = false; + Target *target = &GetSelectedTarget(); + bool flush = false; - const size_t argc = args.GetArgumentCount(); - if (argc == 0) { - if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { - // We are given a UUID only, go locate the file - ModuleSpec module_spec; - module_spec.GetUUID() = - m_uuid_option_group.GetOptionValue().GetCurrentValue(); - if (m_symbol_file.GetOptionValue().OptionWasSet()) - module_spec.GetSymbolFileSpec() = - m_symbol_file.GetOptionValue().GetCurrentValue(); - if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { - ModuleSP module_sp(target->GetOrCreateModule(module_spec, - true /* notify */)); - if (module_sp) { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } else { - StreamString strm; - module_spec.GetUUID().Dump(&strm); - if (module_spec.GetFileSpec()) { - if (module_spec.GetSymbolFileSpec()) { - result.AppendErrorWithFormat( - "Unable to create the executable or symbol file with " - "UUID %s with path %s and symbol file %s", - strm.GetData(), - module_spec.GetFileSpec().GetPath().c_str(), - module_spec.GetSymbolFileSpec().GetPath().c_str()); - } else { - result.AppendErrorWithFormat( - "Unable to create the executable or symbol file with " - "UUID %s with path %s", - strm.GetData(), - module_spec.GetFileSpec().GetPath().c_str()); - } - } else { - result.AppendErrorWithFormat("Unable to create the executable " - "or symbol file with UUID %s", - strm.GetData()); - } - result.SetStatus(eReturnStatusFailed); - return false; - } + const size_t argc = args.GetArgumentCount(); + if (argc == 0) { + if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { + // We are given a UUID only, go locate the file + ModuleSpec module_spec; + module_spec.GetUUID() = + m_uuid_option_group.GetOptionValue().GetCurrentValue(); + if (m_symbol_file.GetOptionValue().OptionWasSet()) + module_spec.GetSymbolFileSpec() = + m_symbol_file.GetOptionValue().GetCurrentValue(); + if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { + ModuleSP module_sp( + target->GetOrCreateModule(module_spec, true /* notify */)); + if (module_sp) { + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; } else { StreamString strm; module_spec.GetUUID().Dump(&strm); - result.AppendErrorWithFormat( - "Unable to locate the executable or symbol file with UUID %s", - strm.GetData()); + if (module_spec.GetFileSpec()) { + if (module_spec.GetSymbolFileSpec()) { + result.AppendErrorWithFormat( + "Unable to create the executable or symbol file with " + "UUID %s with path %s and symbol file %s", + strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(), + module_spec.GetSymbolFileSpec().GetPath().c_str()); + } else { + result.AppendErrorWithFormat( + "Unable to create the executable or symbol file with " + "UUID %s with path %s", + strm.GetData(), + module_spec.GetFileSpec().GetPath().c_str()); + } + } else { + result.AppendErrorWithFormat("Unable to create the executable " + "or symbol file with UUID %s", + strm.GetData()); + } result.SetStatus(eReturnStatusFailed); return false; } } else { - result.AppendError( - "one or more executable image paths must be specified"); + StreamString strm; + module_spec.GetUUID().Dump(&strm); + result.AppendErrorWithFormat( + "Unable to locate the executable or symbol file with UUID %s", + strm.GetData()); result.SetStatus(eReturnStatusFailed); return false; } } else { - for (auto &entry : args.entries()) { - if (entry.ref.empty()) - continue; + result.AppendError( + "one or more executable image paths must be specified"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + for (auto &entry : args.entries()) { + if (entry.ref().empty()) + continue; - FileSpec file_spec(entry.ref); - if (FileSystem::Instance().Exists(file_spec)) { - ModuleSpec module_spec(file_spec); - if (m_uuid_option_group.GetOptionValue().OptionWasSet()) - module_spec.GetUUID() = - m_uuid_option_group.GetOptionValue().GetCurrentValue(); - if (m_symbol_file.GetOptionValue().OptionWasSet()) - module_spec.GetSymbolFileSpec() = - m_symbol_file.GetOptionValue().GetCurrentValue(); - if (!module_spec.GetArchitecture().IsValid()) - module_spec.GetArchitecture() = target->GetArchitecture(); - Status error; - ModuleSP module_sp(target->GetOrCreateModule(module_spec, - true /* notify */, &error)); - if (!module_sp) { - const char *error_cstr = error.AsCString(); - if (error_cstr) - result.AppendError(error_cstr); - else - result.AppendErrorWithFormat("unsupported module: %s", - entry.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - flush = true; - } - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - std::string resolved_path = file_spec.GetPath(); + FileSpec file_spec(entry.ref()); + if (FileSystem::Instance().Exists(file_spec)) { + ModuleSpec module_spec(file_spec); + if (m_uuid_option_group.GetOptionValue().OptionWasSet()) + module_spec.GetUUID() = + m_uuid_option_group.GetOptionValue().GetCurrentValue(); + if (m_symbol_file.GetOptionValue().OptionWasSet()) + module_spec.GetSymbolFileSpec() = + m_symbol_file.GetOptionValue().GetCurrentValue(); + if (!module_spec.GetArchitecture().IsValid()) + module_spec.GetArchitecture() = target->GetArchitecture(); + Status error; + ModuleSP module_sp(target->GetOrCreateModule( + module_spec, true /* notify */, &error)); + if (!module_sp) { + const char *error_cstr = error.AsCString(); + if (error_cstr) + result.AppendError(error_cstr); + else + result.AppendErrorWithFormat("unsupported module: %s", + entry.c_str()); result.SetStatus(eReturnStatusFailed); - if (resolved_path != entry.ref) { - result.AppendErrorWithFormat( - "invalid module path '%s' with resolved path '%s'\n", - entry.ref.str().c_str(), resolved_path.c_str()); - break; - } - result.AppendErrorWithFormat("invalid module path '%s'\n", - entry.c_str()); + return false; + } else { + flush = true; + } + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + std::string resolved_path = file_spec.GetPath(); + result.SetStatus(eReturnStatusFailed); + if (resolved_path != entry.ref()) { + result.AppendErrorWithFormat( + "invalid module path '%s' with resolved path '%s'\n", + entry.ref().str().c_str(), resolved_path.c_str()); break; } + result.AppendErrorWithFormat("invalid module path '%s'\n", + entry.c_str()); + break; } } + } - if (flush) { - ProcessSP process = target->GetProcessSP(); - if (process) - process->Flush(); - } + if (flush) { + ProcessSP process = target->GetProcessSP(); + if (process) + process->Flush(); } return result.Succeeded(); @@ -2679,11 +2606,12 @@ class CommandObjectTargetModulesLoad public: CommandObjectTargetModulesLoad(CommandInterpreter &interpreter) : CommandObjectTargetModulesModuleAutoComplete( - interpreter, "target modules load", "Set the load addresses for " - "one or more sections in a " - "target module.", + interpreter, "target modules load", + "Set the load addresses for one or more sections in a target " + "module.", "target modules load [--file <module> --uuid <uuid>] <sect-name> " - "<address> [<sect-name> <address> ....]"), + "<address> [<sect-name> <address> ....]", + eCommandRequiresTarget), m_option_group(), m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""), @@ -2712,249 +2640,241 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); + Target *target = &GetSelectedTarget(); const bool load = m_load_option.GetOptionValue().GetCurrentValue(); const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - const size_t argc = args.GetArgumentCount(); - ModuleSpec module_spec; - bool search_using_module_spec = false; - - // Allow "load" option to work without --file or --uuid option. - if (load) { - if (!m_file_option.GetOptionValue().OptionWasSet() && - !m_uuid_option_group.GetOptionValue().OptionWasSet()) { - ModuleList &module_list = target->GetImages(); - if (module_list.GetSize() == 1) { - search_using_module_spec = true; - module_spec.GetFileSpec() = - module_list.GetModuleAtIndex(0)->GetFileSpec(); - } - } - } - if (m_file_option.GetOptionValue().OptionWasSet()) { - search_using_module_spec = true; - const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); - const bool use_global_module_list = true; - ModuleList module_list; - const size_t num_matches = FindModulesByName( - target, arg_cstr, module_list, use_global_module_list); - if (num_matches == 1) { + const size_t argc = args.GetArgumentCount(); + ModuleSpec module_spec; + bool search_using_module_spec = false; + + // Allow "load" option to work without --file or --uuid option. + if (load) { + if (!m_file_option.GetOptionValue().OptionWasSet() && + !m_uuid_option_group.GetOptionValue().OptionWasSet()) { + ModuleList &module_list = target->GetImages(); + if (module_list.GetSize() == 1) { + search_using_module_spec = true; module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec(); - } else if (num_matches > 1) { - search_using_module_spec = false; - result.AppendErrorWithFormat( - "more than 1 module matched by name '%s'\n", arg_cstr); - result.SetStatus(eReturnStatusFailed); - } else { - search_using_module_spec = false; - result.AppendErrorWithFormat("no object file for module '%s'\n", - arg_cstr); - result.SetStatus(eReturnStatusFailed); } } + } - if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { - search_using_module_spec = true; - module_spec.GetUUID() = - m_uuid_option_group.GetOptionValue().GetCurrentValue(); + if (m_file_option.GetOptionValue().OptionWasSet()) { + search_using_module_spec = true; + const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); + const bool use_global_module_list = true; + ModuleList module_list; + const size_t num_matches = FindModulesByName( + target, arg_cstr, module_list, use_global_module_list); + if (num_matches == 1) { + module_spec.GetFileSpec() = + module_list.GetModuleAtIndex(0)->GetFileSpec(); + } else if (num_matches > 1) { + search_using_module_spec = false; + result.AppendErrorWithFormat( + "more than 1 module matched by name '%s'\n", arg_cstr); + result.SetStatus(eReturnStatusFailed); + } else { + search_using_module_spec = false; + result.AppendErrorWithFormat("no object file for module '%s'\n", + arg_cstr); + result.SetStatus(eReturnStatusFailed); } + } - if (search_using_module_spec) { - ModuleList matching_modules; - const size_t num_matches = - target->GetImages().FindModules(module_spec, matching_modules); - - char path[PATH_MAX]; - if (num_matches == 1) { - Module *module = matching_modules.GetModulePointerAtIndex(0); - if (module) { - ObjectFile *objfile = module->GetObjectFile(); - if (objfile) { - SectionList *section_list = module->GetSectionList(); - if (section_list) { - bool changed = false; - if (argc == 0) { - if (m_slide_option.GetOptionValue().OptionWasSet()) { - const addr_t slide = - m_slide_option.GetOptionValue().GetCurrentValue(); - const bool slide_is_offset = true; - module->SetLoadAddress(*target, slide, slide_is_offset, - changed); - } else { - result.AppendError("one or more section name + load " - "address pair must be specified"); - result.SetStatus(eReturnStatusFailed); - return false; - } + if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { + search_using_module_spec = true; + module_spec.GetUUID() = + m_uuid_option_group.GetOptionValue().GetCurrentValue(); + } + + if (search_using_module_spec) { + ModuleList matching_modules; + target->GetImages().FindModules(module_spec, matching_modules); + const size_t num_matches = matching_modules.GetSize(); + + char path[PATH_MAX]; + if (num_matches == 1) { + Module *module = matching_modules.GetModulePointerAtIndex(0); + if (module) { + ObjectFile *objfile = module->GetObjectFile(); + if (objfile) { + SectionList *section_list = module->GetSectionList(); + if (section_list) { + bool changed = false; + if (argc == 0) { + if (m_slide_option.GetOptionValue().OptionWasSet()) { + const addr_t slide = + m_slide_option.GetOptionValue().GetCurrentValue(); + const bool slide_is_offset = true; + module->SetLoadAddress(*target, slide, slide_is_offset, + changed); } else { - if (m_slide_option.GetOptionValue().OptionWasSet()) { - result.AppendError("The \"--slide <offset>\" option can't " - "be used in conjunction with setting " - "section load addresses.\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } + result.AppendError("one or more section name + load " + "address pair must be specified"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + if (m_slide_option.GetOptionValue().OptionWasSet()) { + result.AppendError("The \"--slide <offset>\" option can't " + "be used in conjunction with setting " + "section load addresses.\n"); + result.SetStatus(eReturnStatusFailed); + return false; + } - for (size_t i = 0; i < argc; i += 2) { - const char *sect_name = args.GetArgumentAtIndex(i); - const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1); - if (sect_name && load_addr_cstr) { - ConstString const_sect_name(sect_name); - bool success = false; - addr_t load_addr = StringConvert::ToUInt64( - load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); - if (success) { - SectionSP section_sp( - section_list->FindSectionByName(const_sect_name)); - if (section_sp) { - if (section_sp->IsThreadSpecific()) { - result.AppendErrorWithFormat( - "thread specific sections are not yet " - "supported (section '%s')\n", - sect_name); - result.SetStatus(eReturnStatusFailed); - break; - } else { - if (target->GetSectionLoadList() - .SetSectionLoadAddress(section_sp, - load_addr)) - changed = true; - result.AppendMessageWithFormat( - "section '%s' loaded at 0x%" PRIx64 "\n", - sect_name, load_addr); - } - } else { - result.AppendErrorWithFormat("no section found that " - "matches the section " - "name '%s'\n", - sect_name); + for (size_t i = 0; i < argc; i += 2) { + const char *sect_name = args.GetArgumentAtIndex(i); + const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1); + if (sect_name && load_addr_cstr) { + ConstString const_sect_name(sect_name); + bool success = false; + addr_t load_addr = StringConvert::ToUInt64( + load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); + if (success) { + SectionSP section_sp( + section_list->FindSectionByName(const_sect_name)); + if (section_sp) { + if (section_sp->IsThreadSpecific()) { + result.AppendErrorWithFormat( + "thread specific sections are not yet " + "supported (section '%s')\n", + sect_name); result.SetStatus(eReturnStatusFailed); break; + } else { + if (target->GetSectionLoadList() + .SetSectionLoadAddress(section_sp, load_addr)) + changed = true; + result.AppendMessageWithFormat( + "section '%s' loaded at 0x%" PRIx64 "\n", + sect_name, load_addr); } } else { - result.AppendErrorWithFormat( - "invalid load address string '%s'\n", - load_addr_cstr); + result.AppendErrorWithFormat("no section found that " + "matches the section " + "name '%s'\n", + sect_name); result.SetStatus(eReturnStatusFailed); break; } } else { - if (sect_name) - result.AppendError("section names must be followed by " - "a load address.\n"); - else - result.AppendError("one or more section name + load " - "address pair must be specified.\n"); + result.AppendErrorWithFormat( + "invalid load address string '%s'\n", load_addr_cstr); result.SetStatus(eReturnStatusFailed); break; } + } else { + if (sect_name) + result.AppendError("section names must be followed by " + "a load address.\n"); + else + result.AppendError("one or more section name + load " + "address pair must be specified.\n"); + result.SetStatus(eReturnStatusFailed); + break; } } + } - if (changed) { - target->ModulesDidLoad(matching_modules); - Process *process = m_exe_ctx.GetProcessPtr(); - if (process) - process->Flush(); + if (changed) { + target->ModulesDidLoad(matching_modules); + Process *process = m_exe_ctx.GetProcessPtr(); + if (process) + process->Flush(); + } + if (load) { + ProcessSP process = target->CalculateProcess(); + Address file_entry = objfile->GetEntryPointAddress(); + if (!process) { + result.AppendError("No process"); + return false; } - if (load) { - ProcessSP process = target->CalculateProcess(); - Address file_entry = objfile->GetEntryPointAddress(); - if (!process) { - result.AppendError("No process"); - return false; - } - if (set_pc && !file_entry.IsValid()) { - result.AppendError("No entry address in object file"); - return false; - } - std::vector<ObjectFile::LoadableData> loadables( - objfile->GetLoadableData(*target)); - if (loadables.size() == 0) { - result.AppendError("No loadable sections"); - return false; - } - Status error = process->WriteObjectFile(std::move(loadables)); - if (error.Fail()) { - result.AppendError(error.AsCString()); - return false; - } - if (set_pc) { - ThreadList &thread_list = process->GetThreadList(); - RegisterContextSP reg_context( - thread_list.GetSelectedThread()->GetRegisterContext()); - addr_t file_entry_addr = file_entry.GetLoadAddress(target); - if (!reg_context->SetPC(file_entry_addr)) { - result.AppendErrorWithFormat("failed to set PC value to " - "0x%" PRIx64 "\n", - file_entry_addr); - result.SetStatus(eReturnStatusFailed); - } + if (set_pc && !file_entry.IsValid()) { + result.AppendError("No entry address in object file"); + return false; + } + std::vector<ObjectFile::LoadableData> loadables( + objfile->GetLoadableData(*target)); + if (loadables.size() == 0) { + result.AppendError("No loadable sections"); + return false; + } + Status error = process->WriteObjectFile(std::move(loadables)); + if (error.Fail()) { + result.AppendError(error.AsCString()); + return false; + } + if (set_pc) { + ThreadList &thread_list = process->GetThreadList(); + RegisterContextSP reg_context( + thread_list.GetSelectedThread()->GetRegisterContext()); + addr_t file_entry_addr = file_entry.GetLoadAddress(target); + if (!reg_context->SetPC(file_entry_addr)) { + result.AppendErrorWithFormat("failed to set PC value to " + "0x%" PRIx64 "\n", + file_entry_addr); + result.SetStatus(eReturnStatusFailed); } } - } else { - module->GetFileSpec().GetPath(path, sizeof(path)); - result.AppendErrorWithFormat( - "no sections in object file '%s'\n", path); - result.SetStatus(eReturnStatusFailed); } } else { module->GetFileSpec().GetPath(path, sizeof(path)); - result.AppendErrorWithFormat("no object file for module '%s'\n", + result.AppendErrorWithFormat("no sections in object file '%s'\n", path); result.SetStatus(eReturnStatusFailed); } } else { - FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); - if (module_spec_file) { - module_spec_file->GetPath(path, sizeof(path)); - result.AppendErrorWithFormat("invalid module '%s'.\n", path); - } else - result.AppendError("no module spec"); + module->GetFileSpec().GetPath(path, sizeof(path)); + result.AppendErrorWithFormat("no object file for module '%s'\n", + path); result.SetStatus(eReturnStatusFailed); } } else { - std::string uuid_str; + FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); + if (module_spec_file) { + module_spec_file->GetPath(path, sizeof(path)); + result.AppendErrorWithFormat("invalid module '%s'.\n", path); + } else + result.AppendError("no module spec"); + result.SetStatus(eReturnStatusFailed); + } + } else { + std::string uuid_str; - if (module_spec.GetFileSpec()) - module_spec.GetFileSpec().GetPath(path, sizeof(path)); - else - path[0] = '\0'; + if (module_spec.GetFileSpec()) + module_spec.GetFileSpec().GetPath(path, sizeof(path)); + else + path[0] = '\0'; - if (module_spec.GetUUIDPtr()) - uuid_str = module_spec.GetUUID().GetAsString(); - if (num_matches > 1) { - result.AppendErrorWithFormat( - "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "", - path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str()); - for (size_t i = 0; i < num_matches; ++i) { - if (matching_modules.GetModulePointerAtIndex(i) - ->GetFileSpec() - .GetPath(path, sizeof(path))) - result.AppendMessageWithFormat("%s\n", path); - } - } else { - result.AppendErrorWithFormat( - "no modules were found that match%s%s%s%s.\n", - path[0] ? " file=" : "", path, - !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str()); + if (module_spec.GetUUIDPtr()) + uuid_str = module_spec.GetUUID().GetAsString(); + if (num_matches > 1) { + result.AppendErrorWithFormat( + "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "", + path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str()); + for (size_t i = 0; i < num_matches; ++i) { + if (matching_modules.GetModulePointerAtIndex(i) + ->GetFileSpec() + .GetPath(path, sizeof(path))) + result.AppendMessageWithFormat("%s\n", path); } - result.SetStatus(eReturnStatusFailed); + } else { + result.AppendErrorWithFormat( + "no modules were found that match%s%s%s%s.\n", + path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "", + uuid_str.c_str()); } - } else { - result.AppendError("either the \"--file <module>\" or the \"--uuid " - "<uuid>\" option must be specified.\n"); result.SetStatus(eReturnStatusFailed); - return false; } + } else { + result.AppendError("either the \"--file <module>\" or the \"--uuid " + "<uuid>\" option must be specified.\n"); + result.SetStatus(eReturnStatusFailed); + return false; } return result.Succeeded(); } @@ -2968,26 +2888,8 @@ protected: }; // List images with associated information - -static constexpr OptionDefinition g_target_modules_list_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." }, - { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the architecture when listing images." }, - { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the triple when listing images." }, - { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image base address as a load address if debugging, a file address otherwise." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image load address offset from the base file address (the slide amount)." }, - { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the UUID when listing images." }, - { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image object file." }, - { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." }, - { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." }, - { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." }, - { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." }, - { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the modification time with optional width of the module." }, - { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." }, - { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone, "Display the module pointer." }, - { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." } - // clang-format on -}; +#define LLDB_OPTIONS_target_modules_list +#include "CommandOptions.inc" class CommandObjectTargetModulesList : public CommandObjectParsed { public: @@ -3282,9 +3184,9 @@ protected: case 's': case 'S': { - const SymbolVendor *symbol_vendor = module->GetSymbolVendor(); - if (symbol_vendor) { - const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec(); + if (const SymbolFile *symbol_file = module->GetSymbolFile()) { + const FileSpec symfile_spec = + symbol_file->GetObjectFile()->GetFileSpec(); if (format_char == 'S') { // Dump symbol file only if different from module file if (!symfile_spec || symfile_spec == module->GetFileSpec()) { @@ -3332,13 +3234,8 @@ protected: #pragma mark CommandObjectTargetModulesShowUnwind // Lookup unwind information in images - -static constexpr OptionDefinition g_target_modules_show_unwind_options[] = { - // clang-format off - { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." }, - { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" } - // clang-format on -}; +#define LLDB_OPTIONS_target_modules_show_unwind +#include "CommandOptions.inc" class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed { public: @@ -3383,8 +3280,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized option %c.", short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; @@ -3453,7 +3349,7 @@ protected: if (m_options.m_type == eLookupTypeFunctionOrSymbol) { ConstString function_name(m_options.m_str.c_str()); target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto, - true, false, true, sc_list); + true, false, sc_list); } else if (m_options.m_type == eLookupTypeAddress && target) { Address addr; if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr, @@ -3546,6 +3442,25 @@ protected: result.GetOutputStream().Printf("\n"); } + UnwindPlanSP of_unwind_sp = + func_unwinders_sp->GetObjectFileUnwindPlan(*target); + if (of_unwind_sp) { + result.GetOutputStream().Printf("object file UnwindPlan:\n"); + of_unwind_sp->Dump(result.GetOutputStream(), thread.get(), + LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + + UnwindPlanSP of_unwind_augmented_sp = + func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, + *thread); + if (of_unwind_augmented_sp) { + result.GetOutputStream().Printf("object file augmented UnwindPlan:\n"); + of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(), + LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target); if (ehframe_sp) { @@ -3643,24 +3558,8 @@ protected: }; // Lookup information in images - -static constexpr OptionDefinition g_target_modules_lookup_options[] = { - // clang-format off - { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." }, - /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ - { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." }, - { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." }, - { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." }, - { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." }, - { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." }, - { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." }, - { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." }, - { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." }, - { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose lookup information." }, - { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." }, - // clang-format on -}; +#define LLDB_OPTIONS_target_modules_lookup +#include "CommandOptions.inc" class CommandObjectTargetModulesLookup : public CommandObjectParsed { public: @@ -3749,6 +3648,8 @@ public: case 'r': m_use_regex = true; break; + default: + llvm_unreachable("Unimplemented option"); } return error; @@ -3935,91 +3836,82 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetDebugger().GetSelectedTarget().get(); - if (target == nullptr) { - result.AppendError("invalid target, create a debug target using the " - "'target create' command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - bool syntax_error = false; - uint32_t i; - uint32_t num_successful_lookups = 0; - uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); - result.GetOutputStream().SetAddressByteSize(addr_byte_size); - result.GetErrorStream().SetAddressByteSize(addr_byte_size); - // Dump all sections for all modules images - - if (command.GetArgumentCount() == 0) { - ModuleSP current_module; + Target *target = &GetSelectedTarget(); + bool syntax_error = false; + uint32_t i; + uint32_t num_successful_lookups = 0; + uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + result.GetOutputStream().SetAddressByteSize(addr_byte_size); + result.GetErrorStream().SetAddressByteSize(addr_byte_size); + // Dump all sections for all modules images - // Where it is possible to look in the current symbol context first, - // try that. If this search was successful and --all was not passed, - // don't print anything else. - if (LookupHere(m_interpreter, result, syntax_error)) { - result.GetOutputStream().EOL(); - num_successful_lookups++; - if (!m_options.m_print_all) { - result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); - } + if (command.GetArgumentCount() == 0) { + ModuleSP current_module; + + // Where it is possible to look in the current symbol context first, + // try that. If this search was successful and --all was not passed, + // don't print anything else. + if (LookupHere(m_interpreter, result, syntax_error)) { + result.GetOutputStream().EOL(); + num_successful_lookups++; + if (!m_options.m_print_all) { + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); } + } - // Dump all sections for all other modules + // Dump all sections for all other modules - const ModuleList &target_modules = target->GetImages(); - std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); - const size_t num_modules = target_modules.GetSize(); - if (num_modules > 0) { - for (i = 0; i < num_modules && !syntax_error; ++i) { - Module *module_pointer = - target_modules.GetModulePointerAtIndexUnlocked(i); - - if (module_pointer != current_module.get() && - LookupInModule( - m_interpreter, - target_modules.GetModulePointerAtIndexUnlocked(i), result, - syntax_error)) { - result.GetOutputStream().EOL(); - num_successful_lookups++; - } + const ModuleList &target_modules = target->GetImages(); + std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); + const size_t num_modules = target_modules.GetSize(); + if (num_modules > 0) { + for (i = 0; i < num_modules && !syntax_error; ++i) { + Module *module_pointer = + target_modules.GetModulePointerAtIndexUnlocked(i); + + if (module_pointer != current_module.get() && + LookupInModule(m_interpreter, + target_modules.GetModulePointerAtIndexUnlocked(i), + result, syntax_error)) { + result.GetOutputStream().EOL(); + num_successful_lookups++; } - } else { - result.AppendError("the target has no associated executable images"); - result.SetStatus(eReturnStatusFailed); - return false; } } else { - // Dump specified images (by basename or fullpath) - const char *arg_cstr; - for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && - !syntax_error; - ++i) { - ModuleList module_list; - const size_t num_matches = - FindModulesByName(target, arg_cstr, module_list, false); - if (num_matches > 0) { - for (size_t j = 0; j < num_matches; ++j) { - Module *module = module_list.GetModulePointerAtIndex(j); - if (module) { - if (LookupInModule(m_interpreter, module, result, - syntax_error)) { - result.GetOutputStream().EOL(); - num_successful_lookups++; - } + result.AppendError("the target has no associated executable images"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + // Dump specified images (by basename or fullpath) + const char *arg_cstr; + for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && + !syntax_error; + ++i) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(target, arg_cstr, module_list, false); + if (num_matches > 0) { + for (size_t j = 0; j < num_matches; ++j) { + Module *module = module_list.GetModulePointerAtIndex(j); + if (module) { + if (LookupInModule(m_interpreter, module, result, syntax_error)) { + result.GetOutputStream().EOL(); + num_successful_lookups++; } } - } else - result.AppendWarningWithFormat( - "Unable to find an image that matches '%s'.\n", arg_cstr); - } + } + } else + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg_cstr); } - - if (num_successful_lookups > 0) - result.SetStatus(eReturnStatusSuccessFinishResult); - else - result.SetStatus(eReturnStatusFailed); } + + if (num_successful_lookups > 0) + result.SetStatus(eReturnStatusSuccessFinishResult); + else + result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } @@ -4129,13 +4021,12 @@ public: ~CommandObjectTargetSymbolsAdd() override = default; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override { + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_option_group; } @@ -4173,8 +4064,9 @@ protected: // It has a UUID, look for this UUID in the target modules ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); - num_matches = target->GetImages().FindModules( - symfile_uuid_module_spec, matching_module_list); + target->GetImages().FindModules(symfile_uuid_module_spec, + matching_module_list); + num_matches = matching_module_list.GetSize(); } } @@ -4192,8 +4084,9 @@ protected: ModuleSpec symfile_uuid_module_spec; symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); - num_matches = target->GetImages().FindModules( - symfile_uuid_module_spec, matching_module_list); + target->GetImages().FindModules(symfile_uuid_module_spec, + matching_module_list); + num_matches = matching_module_list.GetSize(); } } } @@ -4202,9 +4095,10 @@ protected: // Just try to match up the file by basename if we have no matches at // this point - if (num_matches == 0) - num_matches = - target->GetImages().FindModules(module_spec, matching_module_list); + if (num_matches == 0) { + target->GetImages().FindModules(module_spec, matching_module_list); + num_matches = matching_module_list.GetSize(); + } while (num_matches == 0) { ConstString filename_no_extension( @@ -4221,8 +4115,8 @@ protected: // Replace basename with one less extension module_spec.GetFileSpec().GetFilename() = filename_no_extension; - num_matches = - target->GetImages().FindModules(module_spec, matching_module_list); + target->GetImages().FindModules(module_spec, matching_module_list); + num_matches = matching_module_list.GetSize(); } if (num_matches > 1) { @@ -4238,48 +4132,44 @@ protected: // decides to create it! module_sp->SetSymbolFileFileSpec(symbol_fspec); - SymbolVendor *symbol_vendor = - module_sp->GetSymbolVendor(true, &result.GetErrorStream()); - if (symbol_vendor) { - SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); - - if (symbol_file) { - ObjectFile *object_file = symbol_file->GetObjectFile(); - - if (object_file && object_file->GetFileSpec() == symbol_fspec) { - // Provide feedback that the symfile has been successfully added. - const FileSpec &module_fs = module_sp->GetFileSpec(); - result.AppendMessageWithFormat( - "symbol file '%s' has been added to '%s'\n", symfile_path, - module_fs.GetPath().c_str()); - - // Let clients know something changed in the module if it is - // currently loaded - ModuleList module_list; - module_list.Append(module_sp); - target->SymbolsDidLoad(module_list); - - // Make sure we load any scripting resources that may be embedded - // in the debug info files in case the platform supports that. - Status error; - StreamString feedback_stream; - module_sp->LoadScriptingResourceInTarget(target, error, - &feedback_stream); - if (error.Fail() && error.AsCString()) - result.AppendWarningWithFormat( - "unable to load scripting data for module %s - error " - "reported was %s", - module_sp->GetFileSpec() - .GetFileNameStrippingExtension() - .GetCString(), - error.AsCString()); - else if (feedback_stream.GetSize()) - result.AppendWarningWithFormat("%s", feedback_stream.GetData()); - - flush = true; - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } + SymbolFile *symbol_file = + module_sp->GetSymbolFile(true, &result.GetErrorStream()); + if (symbol_file) { + ObjectFile *object_file = symbol_file->GetObjectFile(); + + if (object_file && object_file->GetFileSpec() == symbol_fspec) { + // Provide feedback that the symfile has been successfully added. + const FileSpec &module_fs = module_sp->GetFileSpec(); + result.AppendMessageWithFormat( + "symbol file '%s' has been added to '%s'\n", symfile_path, + module_fs.GetPath().c_str()); + + // Let clients know something changed in the module if it is + // currently loaded + ModuleList module_list; + module_list.Append(module_sp); + target->SymbolsDidLoad(module_list); + + // Make sure we load any scripting resources that may be embedded + // in the debug info files in case the platform supports that. + Status error; + StreamString feedback_stream; + module_sp->LoadScriptingResourceInTarget(target, error, + &feedback_stream); + if (error.Fail() && error.AsCString()) + result.AppendWarningWithFormat( + "unable to load scripting data for module %s - error " + "reported was %s", + module_sp->GetFileSpec() + .GetFileNameStrippingExtension() + .GetCString(), + error.AsCString()); + else if (feedback_stream.GetSize()) + result.AppendWarningWithFormat("%s", feedback_stream.GetData()); + + flush = true; + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; } } // Clear the symbol file spec if anything went wrong @@ -4430,9 +4320,9 @@ protected: PlatformSP platform_sp(target->GetPlatform()); for (auto &entry : args.entries()) { - if (!entry.ref.empty()) { + if (!entry.ref().empty()) { auto &symbol_file_spec = module_spec.GetSymbolFileSpec(); - symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native); + symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native); FileSystem::Instance().Resolve(symbol_file_spec); if (file_option_set) { module_spec.GetFileSpec() = @@ -4456,7 +4346,7 @@ protected: } else { std::string resolved_symfile_path = module_spec.GetSymbolFileSpec().GetPath(); - if (resolved_symfile_path != entry.ref) { + if (resolved_symfile_path != entry.ref()) { result.AppendErrorWithFormat( "invalid module path '%s' with resolved path '%s'\n", entry.c_str(), resolved_symfile_path.c_str()); @@ -4511,23 +4401,8 @@ private: #pragma mark CommandObjectTargetStopHookAdd // CommandObjectTargetStopHookAdd - -static constexpr OptionDefinition g_target_stop_hook_add_options[] = { - // clang-format off - { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Add a command for the stop hook. Can be specified more than once, and commands will be run in the order they appear." }, - { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." }, - { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." }, - { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." }, - { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." }, - { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." }, - { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." }, - { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." }, - { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." }, - { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." }, - { LLDB_OPT_SET_ALL, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." }, - // clang-format on -}; +#define LLDB_OPTIONS_target_stop_hook_add +#include "CommandOptions.inc" class CommandObjectTargetStopHookAdd : public CommandObjectParsed, public IOHandlerDelegateMultiline { @@ -4636,8 +4511,7 @@ public: break; default: - error.SetErrorStringWithFormat("unrecognized option %c.", short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -4698,7 +4572,7 @@ public: protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString( "Enter your stop hook command(s). Type 'DONE' to end.\n"); @@ -4710,7 +4584,7 @@ protected: std::string &line) override { if (m_stop_hook_sp) { if (line.empty()) { - StreamFileSP error_sp(io_handler.GetErrorStreamFile()); + StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); if (error_sp) { error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", @@ -4722,7 +4596,7 @@ protected: target->RemoveStopHookByID(m_stop_hook_sp->GetID()); } else { m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line); - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp) { output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID()); @@ -4737,52 +4611,50 @@ protected: bool DoExecute(Args &command, CommandReturnObject &result) override { m_stop_hook_sp.reset(); - Target *target = GetSelectedOrDummyTarget(); - if (target) { - Target::StopHookSP new_hook_sp = target->CreateStopHook(); - - // First step, make the specifier. - std::unique_ptr<SymbolContextSpecifier> specifier_up; - if (m_options.m_sym_ctx_specified) { - specifier_up.reset( - new SymbolContextSpecifier(GetDebugger().GetSelectedTarget())); - - if (!m_options.m_module_name.empty()) { - specifier_up->AddSpecification( - m_options.m_module_name.c_str(), - SymbolContextSpecifier::eModuleSpecified); - } + Target &target = GetSelectedOrDummyTarget(); + Target::StopHookSP new_hook_sp = target.CreateStopHook(); - if (!m_options.m_class_name.empty()) { - specifier_up->AddSpecification( - m_options.m_class_name.c_str(), - SymbolContextSpecifier::eClassOrNamespaceSpecified); - } + // First step, make the specifier. + std::unique_ptr<SymbolContextSpecifier> specifier_up; + if (m_options.m_sym_ctx_specified) { + specifier_up.reset( + new SymbolContextSpecifier(GetDebugger().GetSelectedTarget())); - if (!m_options.m_file_name.empty()) { - specifier_up->AddSpecification( - m_options.m_file_name.c_str(), - SymbolContextSpecifier::eFileSpecified); - } + if (!m_options.m_module_name.empty()) { + specifier_up->AddSpecification( + m_options.m_module_name.c_str(), + SymbolContextSpecifier::eModuleSpecified); + } - if (m_options.m_line_start != 0) { - specifier_up->AddLineSpecification( - m_options.m_line_start, - SymbolContextSpecifier::eLineStartSpecified); - } + if (!m_options.m_class_name.empty()) { + specifier_up->AddSpecification( + m_options.m_class_name.c_str(), + SymbolContextSpecifier::eClassOrNamespaceSpecified); + } - if (m_options.m_line_end != UINT_MAX) { - specifier_up->AddLineSpecification( - m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); - } + if (!m_options.m_file_name.empty()) { + specifier_up->AddSpecification(m_options.m_file_name.c_str(), + SymbolContextSpecifier::eFileSpecified); + } - if (!m_options.m_function_name.empty()) { - specifier_up->AddSpecification( - m_options.m_function_name.c_str(), - SymbolContextSpecifier::eFunctionSpecified); - } + if (m_options.m_line_start != 0) { + specifier_up->AddLineSpecification( + m_options.m_line_start, + SymbolContextSpecifier::eLineStartSpecified); } + if (m_options.m_line_end != UINT_MAX) { + specifier_up->AddLineSpecification( + m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); + } + + if (!m_options.m_function_name.empty()) { + specifier_up->AddSpecification( + m_options.m_function_name.c_str(), + SymbolContextSpecifier::eFunctionSpecified); + } + } + if (specifier_up) new_hook_sp->SetSpecifier(specifier_up.release()); @@ -4825,10 +4697,6 @@ protected: // into our IOHandlerDelegate functions } result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("invalid target\n"); - result.SetStatus(eReturnStatusFailed); - } return result.Succeeded(); } @@ -4853,43 +4721,37 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target) { - // FIXME: see if we can use the breakpoint id style parser? - size_t num_args = command.GetArgumentCount(); - if (num_args == 0) { - if (!m_interpreter.Confirm("Delete all stop hooks?", true)) { + Target &target = GetSelectedOrDummyTarget(); + // FIXME: see if we can use the breakpoint id style parser? + size_t num_args = command.GetArgumentCount(); + if (num_args == 0) { + if (!m_interpreter.Confirm("Delete all stop hooks?", true)) { + result.SetStatus(eReturnStatusFailed); + return false; + } else { + target.RemoveAllStopHooks(); + } + } else { + bool success; + for (size_t i = 0; i < num_args; i++) { + lldb::user_id_t user_id = StringConvert::ToUInt32( + command.GetArgumentAtIndex(i), 0, 0, &success); + if (!success) { + result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", + command.GetArgumentAtIndex(i)); result.SetStatus(eReturnStatusFailed); return false; - } else { - target->RemoveAllStopHooks(); } - } else { - bool success; - for (size_t i = 0; i < num_args; i++) { - lldb::user_id_t user_id = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { - result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", - command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); - return false; - } - success = target->RemoveStopHookByID(user_id); - if (!success) { - result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", - command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); - return false; - } + success = target.RemoveStopHookByID(user_id); + if (!success) { + result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", + command.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; } } - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("invalid target\n"); - result.SetStatus(eReturnStatusFailed); } - + result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); } }; @@ -4910,38 +4772,33 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (target) { - // FIXME: see if we can use the breakpoint id style parser? - size_t num_args = command.GetArgumentCount(); - bool success; + Target &target = GetSelectedOrDummyTarget(); + // FIXME: see if we can use the breakpoint id style parser? + size_t num_args = command.GetArgumentCount(); + bool success; - if (num_args == 0) { - target->SetAllStopHooksActiveState(m_enable); - } else { - for (size_t i = 0; i < num_args; i++) { - lldb::user_id_t user_id = StringConvert::ToUInt32( - command.GetArgumentAtIndex(i), 0, 0, &success); - if (!success) { - result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", - command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); - return false; - } - success = target->SetStopHookActiveStateByID(user_id, m_enable); - if (!success) { - result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", - command.GetArgumentAtIndex(i)); - result.SetStatus(eReturnStatusFailed); - return false; - } + if (num_args == 0) { + target.SetAllStopHooksActiveState(m_enable); + } else { + for (size_t i = 0; i < num_args; i++) { + lldb::user_id_t user_id = StringConvert::ToUInt32( + command.GetArgumentAtIndex(i), 0, 0, &success); + if (!success) { + result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", + command.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; + } + success = target.SetStopHookActiveStateByID(user_id, m_enable); + if (!success) { + result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", + command.GetArgumentAtIndex(i)); + result.SetStatus(eReturnStatusFailed); + return false; } } - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("invalid target\n"); - result.SetStatus(eReturnStatusFailed); } + result.SetStatus(eReturnStatusSuccessFinishNoResult); return result.Succeeded(); } @@ -4964,19 +4821,14 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target *target = GetSelectedOrDummyTarget(); - if (!target) { - result.AppendError("invalid target\n"); - result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); - } + Target &target = GetSelectedOrDummyTarget(); - size_t num_hooks = target->GetNumStopHooks(); + size_t num_hooks = target.GetNumStopHooks(); if (num_hooks == 0) { result.GetOutputStream().PutCString("No stop hooks.\n"); } else { for (size_t i = 0; i < num_hooks; i++) { - Target::StopHookSP this_hook = target->GetStopHookAtIndex(i); + Target::StopHookSP this_hook = target.GetStopHookAtIndex(i); if (i > 0) result.GetOutputStream().PutCString("\n"); this_hook->GetDescription(&(result.GetOutputStream()), diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp index ed7cf0a1a48d..8c5274553902 100644 --- a/source/Commands/CommandObjectThread.cpp +++ b/source/Commands/CommandObjectThread.cpp @@ -16,6 +16,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Interpreter/Options.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -237,11 +238,8 @@ protected: }; // CommandObjectThreadBacktrace - -static constexpr OptionDefinition g_thread_backtrace_options[] = { #define LLDB_OPTIONS_thread_backtrace #include "CommandOptions.inc" -}; class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads { public: @@ -284,9 +282,7 @@ public: "invalid boolean value for option '%c'", short_option); } break; default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); - break; + llvm_unreachable("Unimplemented option"); } return error; } @@ -403,134 +399,125 @@ static constexpr OptionEnumValues TriRunningModes() { return OptionEnumValues(g_tri_running_mode); } -static constexpr OptionDefinition g_thread_step_scope_options[] = { #define LLDB_OPTIONS_thread_step_scope #include "CommandOptions.inc" -}; -class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { +class ThreadStepScopeOptionGroup : public OptionGroup { public: - class CommandOptions : public Options { - public: - CommandOptions() : Options() { - // Keep default values of all options in one place: OptionParsingStarting - // () - OptionParsingStarting(nullptr); - } - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'a': { - bool success; - bool avoid_no_debug = - OptionArgParser::ToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat( - "invalid boolean value for option '%c'", short_option); - else { - m_step_in_avoid_no_debug = - avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; - } - } break; - - case 'A': { - bool success; - bool avoid_no_debug = - OptionArgParser::ToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat( - "invalid boolean value for option '%c'", short_option); - else { - m_step_out_avoid_no_debug = - avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; - } - } break; - - case 'c': - if (option_arg.getAsInteger(0, m_step_count)) - error.SetErrorStringWithFormat("invalid step count '%s'", - option_arg.str().c_str()); - break; - - case 'C': - m_class_name.clear(); - m_class_name.assign(option_arg); - break; - - case 'm': { - auto enum_values = GetDefinitions()[option_idx].enum_values; - m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum( - option_arg, enum_values, eOnlyDuringStepping, error); - } break; - - case 'e': - if (option_arg == "block") { - m_end_line_is_block_end = true; - break; - } - if (option_arg.getAsInteger(0, m_end_line)) - error.SetErrorStringWithFormat("invalid end line number '%s'", - option_arg.str().c_str()); - break; + ThreadStepScopeOptionGroup() : OptionGroup() { + // Keep default values of all options in one place: OptionParsingStarting + // () + OptionParsingStarting(nullptr); + } - case 'r': - m_avoid_regexp.clear(); - m_avoid_regexp.assign(option_arg); - break; + ~ThreadStepScopeOptionGroup() override = default; - case 't': - m_step_in_target.clear(); - m_step_in_target.assign(option_arg); - break; + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_thread_step_scope_options); + } - default: - error.SetErrorStringWithFormat("invalid short option character '%c'", - short_option); + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option + = g_thread_step_scope_options[option_idx].short_option; + + switch (short_option) { + case 'a': { + bool success; + bool avoid_no_debug = + OptionArgParser::ToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat( + "invalid boolean value for option '%c'", short_option); + else { + m_step_in_avoid_no_debug = + avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; + } + } break; + + case 'A': { + bool success; + bool avoid_no_debug = + OptionArgParser::ToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat( + "invalid boolean value for option '%c'", short_option); + else { + m_step_out_avoid_no_debug = + avoid_no_debug ? eLazyBoolYes : eLazyBoolNo; + } + } break; + + case 'c': + if (option_arg.getAsInteger(0, m_step_count)) + error.SetErrorStringWithFormat("invalid step count '%s'", + option_arg.str().c_str()); + break; + + case 'm': { + auto enum_values = GetDefinitions()[option_idx].enum_values; + m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum( + option_arg, enum_values, eOnlyDuringStepping, error); + } break; + + case 'e': + if (option_arg == "block") { + m_end_line_is_block_end = true; break; } - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - m_step_in_avoid_no_debug = eLazyBoolCalculate; - m_step_out_avoid_no_debug = eLazyBoolCalculate; - m_run_mode = eOnlyDuringStepping; - - // Check if we are in Non-Stop mode - TargetSP target_sp = - execution_context ? execution_context->GetTargetSP() : TargetSP(); - if (target_sp && target_sp->GetNonStopModeEnabled()) - m_run_mode = eOnlyThisThread; + if (option_arg.getAsInteger(0, m_end_line)) + error.SetErrorStringWithFormat("invalid end line number '%s'", + option_arg.str().c_str()); + break; + case 'r': m_avoid_regexp.clear(); + m_avoid_regexp.assign(option_arg); + break; + + case 't': m_step_in_target.clear(); - m_class_name.clear(); - m_step_count = 1; - m_end_line = LLDB_INVALID_LINE_NUMBER; - m_end_line_is_block_end = false; - } + m_step_in_target.assign(option_arg); + break; - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::makeArrayRef(g_thread_step_scope_options); + default: + llvm_unreachable("Unimplemented option"); } + return error; + } - // Instance variables to hold the values for command options. - LazyBool m_step_in_avoid_no_debug; - LazyBool m_step_out_avoid_no_debug; - RunMode m_run_mode; - std::string m_avoid_regexp; - std::string m_step_in_target; - std::string m_class_name; - uint32_t m_step_count; - uint32_t m_end_line; - bool m_end_line_is_block_end; - }; + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_step_in_avoid_no_debug = eLazyBoolCalculate; + m_step_out_avoid_no_debug = eLazyBoolCalculate; + m_run_mode = eOnlyDuringStepping; + + // Check if we are in Non-Stop mode + TargetSP target_sp = + execution_context ? execution_context->GetTargetSP() : TargetSP(); + if (target_sp && target_sp->GetNonStopModeEnabled()) + m_run_mode = eOnlyThisThread; + + m_avoid_regexp.clear(); + m_step_in_target.clear(); + m_step_count = 1; + m_end_line = LLDB_INVALID_LINE_NUMBER; + m_end_line_is_block_end = false; + } + + // Instance variables to hold the values for command options. + LazyBool m_step_in_avoid_no_debug; + LazyBool m_step_out_avoid_no_debug; + RunMode m_run_mode; + std::string m_avoid_regexp; + std::string m_step_in_target; + uint32_t m_step_count; + uint32_t m_end_line; + bool m_end_line_is_block_end; +}; + +class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { +public: CommandObjectThreadStepWithTypeAndScope(CommandInterpreter &interpreter, const char *name, const char *help, @@ -542,7 +529,8 @@ public: eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), - m_step_typ |