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 /include | |
parent | fdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff) | |
download | src-ead246455adf1a215ec2715dad6533073a6beb4e.tar.gz src-ead246455adf1a215ec2715dad6533073a6beb4e.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 'include')
145 files changed, 2547 insertions, 2643 deletions
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h index 0806ab700a94..75e2d70c0c39 100644 --- a/include/lldb/API/LLDB.h +++ b/include/lldb/API/LLDB.h @@ -13,8 +13,8 @@ #include "lldb/API/SBAttachInfo.h" #include "lldb/API/SBBlock.h" #include "lldb/API/SBBreakpoint.h" -#include "lldb/API/SBBreakpointName.h" #include "lldb/API/SBBreakpointLocation.h" +#include "lldb/API/SBBreakpointName.h" #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" #include "lldb/API/SBCommandReturnObject.h" @@ -28,6 +28,7 @@ #include "lldb/API/SBEvent.h" #include "lldb/API/SBExecutionContext.h" #include "lldb/API/SBExpressionOptions.h" +#include "lldb/API/SBFile.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFileSpecList.h" #include "lldb/API/SBFrame.h" diff --git a/include/lldb/API/SBCommandReturnObject.h b/include/lldb/API/SBCommandReturnObject.h index 2877afb9b8b0..e3fbacf85afc 100644 --- a/include/lldb/API/SBCommandReturnObject.h +++ b/include/lldb/API/SBCommandReturnObject.h @@ -15,23 +15,27 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class SBCommandReturnObjectImpl; +} + namespace lldb { class LLDB_API SBCommandReturnObject { public: SBCommandReturnObject(); + SBCommandReturnObject(lldb_private::CommandReturnObject &ref); + + // rvalue ctor+assignment are incompatible with Reproducers. + SBCommandReturnObject(const lldb::SBCommandReturnObject &rhs); ~SBCommandReturnObject(); - const lldb::SBCommandReturnObject & + lldb::SBCommandReturnObject & operator=(const lldb::SBCommandReturnObject &rhs); - SBCommandReturnObject(lldb_private::CommandReturnObject *ptr); - - lldb_private::CommandReturnObject *Release(); - explicit operator bool() const; bool IsValid() const; @@ -40,13 +44,21 @@ public: const char *GetError(); - size_t PutOutput(FILE *fh); + size_t PutOutput(FILE *fh); // DEPRECATED + + size_t PutOutput(SBFile file); + + size_t PutOutput(FileSP file); size_t GetOutputSize(); size_t GetErrorSize(); - size_t PutError(FILE *fh); + size_t PutError(FILE *fh); // DEPRECATED + + size_t PutError(SBFile file); + + size_t PutError(FileSP file); void Clear(); @@ -64,14 +76,21 @@ public: bool GetDescription(lldb::SBStream &description); - // deprecated, these two functions do not take ownership of file handle - void SetImmediateOutputFile(FILE *fh); + void SetImmediateOutputFile(FILE *fh); // DEPRECATED - void SetImmediateErrorFile(FILE *fh); + void SetImmediateErrorFile(FILE *fh); // DEPRECATED - void SetImmediateOutputFile(FILE *fh, bool transfer_ownership); + void SetImmediateOutputFile(FILE *fh, bool transfer_ownership); // DEPRECATED - void SetImmediateErrorFile(FILE *fh, bool transfer_ownership); + void SetImmediateErrorFile(FILE *fh, bool transfer_ownership); // DEPRECATED + + void SetImmediateOutputFile(SBFile file); + + void SetImmediateErrorFile(SBFile file); + + void SetImmediateOutputFile(FileSP file); + + void SetImmediateErrorFile(FileSP file); void PutCString(const char *string, int len = -1); @@ -86,6 +105,9 @@ public: void SetError(const char *error_cstr); + // ref() is internal for LLDB only. + lldb_private::CommandReturnObject &ref() const; + protected: friend class SBCommandInterpreter; friend class SBOptions; @@ -96,12 +118,8 @@ protected: lldb_private::CommandReturnObject &operator*() const; - lldb_private::CommandReturnObject &ref() const; - - void SetLLDBObjectPtr(lldb_private::CommandReturnObject *ptr); - private: - std::unique_ptr<lldb_private::CommandReturnObject> m_opaque_up; + std::unique_ptr<lldb_private::SBCommandReturnObjectImpl> m_opaque_up; }; } // namespace lldb diff --git a/include/lldb/API/SBDebugger.h b/include/lldb/API/SBDebugger.h index 417cead24a8c..580f6281fbb6 100644 --- a/include/lldb/API/SBDebugger.h +++ b/include/lldb/API/SBDebugger.h @@ -88,6 +88,24 @@ public: FILE *GetErrorFileHandle(); + SBError SetInputFile(SBFile file); + + SBError SetOutputFile(SBFile file); + + SBError SetErrorFile(SBFile file); + + SBError SetInputFile(FileSP file); + + SBError SetOutputFile(FileSP file); + + SBError SetErrorFile(FileSP file); + + SBFile GetInputFile(); + + SBFile GetOutputFile(); + + SBFile GetErrorFile(); + void SaveInputTerminalState(); void RestoreInputTerminalState(); @@ -99,7 +117,14 @@ public: lldb::SBListener GetListener(); void HandleProcessEvent(const lldb::SBProcess &process, - const lldb::SBEvent &event, FILE *out, FILE *err); + const lldb::SBEvent &event, FILE *out, + FILE *err); // DEPRECATED + + void HandleProcessEvent(const lldb::SBProcess &process, + const lldb::SBEvent &event, SBFile out, SBFile err); + + void HandleProcessEvent(const lldb::SBProcess &process, + const lldb::SBEvent &event, FileSP out, FileSP err); lldb::SBTarget CreateTarget(const char *filename, const char *target_triple, const char *platform_name, diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index 838c84cece6d..68aca930d199 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -41,6 +41,7 @@ class LLDB_API SBEvent; class LLDB_API SBEventList; class LLDB_API SBExecutionContext; class LLDB_API SBExpressionOptions; +class LLDB_API SBFile; class LLDB_API SBFileSpec; class LLDB_API SBFileSpecList; class LLDB_API SBFrame; diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h index b076f87b7669..3db2658d9fb7 100644 --- a/include/lldb/API/SBError.h +++ b/include/lldb/API/SBError.h @@ -70,6 +70,7 @@ protected: friend class SBTrace; friend class SBValue; friend class SBWatchpoint; + friend class SBFile; lldb_private::Status *get(); diff --git a/include/lldb/API/SBFile.h b/include/lldb/API/SBFile.h new file mode 100644 index 000000000000..7d6c14809923 --- /dev/null +++ b/include/lldb/API/SBFile.h @@ -0,0 +1,47 @@ +//===-- SBFile.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 LLDB_SBFile_h_ +#define LLDB_SBFile_h_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class LLDB_API SBFile { + friend class SBInstruction; + friend class SBInstructionList; + friend class SBDebugger; + friend class SBCommandReturnObject; + friend class SBProcess; + +public: + SBFile(); + SBFile(FileSP file_sp); + SBFile(FILE *file, bool transfer_ownership); + SBFile(int fd, const char *mode, bool transfer_ownership); + ~SBFile(); + + SBError Read(uint8_t *buf, size_t num_bytes, size_t *bytes_read); + SBError Write(const uint8_t *buf, size_t num_bytes, size_t *bytes_written); + SBError Flush(); + bool IsValid() const; + SBError Close(); + + operator bool() const; + bool operator!() const; + + FileSP GetFile() const; + +private: + FileSP m_opaque_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBFile_h_ diff --git a/include/lldb/API/SBInstruction.h b/include/lldb/API/SBInstruction.h index 0bb587795607..7d83a37ba5d6 100644 --- a/include/lldb/API/SBInstruction.h +++ b/include/lldb/API/SBInstruction.h @@ -55,6 +55,10 @@ public: void Print(FILE *out); + void Print(SBFile out); + + void Print(FileSP out); + bool GetDescription(lldb::SBStream &description); bool EmulateWithFrame(lldb::SBFrame &frame, uint32_t evaluate_options); diff --git a/include/lldb/API/SBInstructionList.h b/include/lldb/API/SBInstructionList.h index 4434d50f471f..e203d0b80564 100644 --- a/include/lldb/API/SBInstructionList.h +++ b/include/lldb/API/SBInstructionList.h @@ -46,6 +46,10 @@ public: void Print(FILE *out); + void Print(SBFile out); + + void Print(FileSP out); + bool GetDescription(lldb::SBStream &description); bool DumpEmulationForAllInstructions(const char *triple); @@ -56,6 +60,8 @@ protected: friend class SBTarget; void SetDisassembler(const lldb::DisassemblerSP &opaque_sp); + bool GetDescription(lldb_private::Stream &description); + private: lldb::DisassemblerSP m_opaque_sp; diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index 863cb3ced674..8ab8bfa3a93e 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -67,6 +67,10 @@ public: void ReportEventState(const lldb::SBEvent &event, FILE *out) const; + void ReportEventState(const lldb::SBEvent &event, SBFile file) const; + + void ReportEventState(const lldb::SBEvent &event, FileSP file) const; + void AppendEventStateReport(const lldb::SBEvent &event, lldb::SBCommandReturnObject &result); diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h index 8afbf4575621..b78c498e5f3d 100644 --- a/include/lldb/API/SBStream.h +++ b/include/lldb/API/SBStream.h @@ -39,6 +39,10 @@ public: void RedirectToFile(const char *path, bool append); + void RedirectToFile(lldb::SBFile file); + + void RedirectToFile(lldb::FileSP file); + void RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership); void RedirectToFileDescriptor(int fd, bool transfer_fh_ownership); diff --git a/include/lldb/API/SBStructuredData.h b/include/lldb/API/SBStructuredData.h index 5b10133500ef..a090272e45ac 100644 --- a/include/lldb/API/SBStructuredData.h +++ b/include/lldb/API/SBStructuredData.h @@ -91,6 +91,8 @@ protected: friend class SBTraceOptions; friend class SBDebugger; friend class SBTarget; + friend class SBThread; + friend class SBThreadPlan; StructuredDataImplUP m_impl_up; }; diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h index da8726a2a9b2..b5f1794f9fe0 100644 --- a/include/lldb/API/SBThread.h +++ b/include/lldb/API/SBThread.h @@ -122,6 +122,10 @@ public: SBError StepUsingScriptedThreadPlan(const char *script_class_name, bool resume_immediately); + SBError StepUsingScriptedThreadPlan(const char *script_class_name, + lldb::SBStructuredData &args_data, + bool resume_immediately); + SBError JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line); void RunToAddress(lldb::addr_t addr); diff --git a/include/lldb/API/SBThreadPlan.h b/include/lldb/API/SBThreadPlan.h index 007e9e2de21a..dbe417e63749 100644 --- a/include/lldb/API/SBThreadPlan.h +++ b/include/lldb/API/SBThreadPlan.h @@ -28,6 +28,9 @@ public: SBThreadPlan(lldb::SBThread &thread, const char *class_name); + SBThreadPlan(lldb::SBThread &thread, const char *class_name, + lldb::SBStructuredData &args_data); + ~SBThreadPlan(); explicit operator bool() const; @@ -100,6 +103,9 @@ public: SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name); SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name, SBError &error); + SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name, + lldb::SBStructuredData &args_data, + SBError &error); private: friend class SBBreakpoint; diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h index 7b27160563a0..aadd52288485 100644 --- a/include/lldb/Breakpoint/BreakpointLocation.h +++ b/include/lldb/Breakpoint/BreakpointLocation.h @@ -67,7 +67,7 @@ public: // The next section deals with various breakpoint options. - /// If \a enable is \b true, enable the breakpoint, if \b false disable it. + /// If \a enabled is \b true, enable the breakpoint, if \b false disable it. void SetEnabled(bool enabled); /// Check the Enable/Disable state. diff --git a/include/lldb/Breakpoint/BreakpointOptions.h b/include/lldb/Breakpoint/BreakpointOptions.h index cdac5d3dbd75..55a4be2d19c1 100644 --- a/include/lldb/Breakpoint/BreakpointOptions.h +++ b/include/lldb/Breakpoint/BreakpointOptions.h @@ -107,6 +107,12 @@ public: /// \param[in] ignore /// How many breakpoint hits we should ignore before stopping. /// + /// \param[in] one_shot + /// Should this breakpoint delete itself after being hit once. + /// + /// \param[in] auto_continue + /// Should this breakpoint auto-continue after running its commands. + /// BreakpointOptions(const char *condition, bool enabled = true, int32_t ignore = 0, bool one_shot = false, bool auto_continue = false); @@ -319,7 +325,10 @@ public: void GetDescription(Stream *s, lldb::DescriptionLevel level) const; - /// Returns true if the breakpoint option has a callback set. + /// Check if the breakpoint option has a callback set. + /// + /// \return + /// If the breakpoint option has a callback, \b true otherwise \b false. bool HasCallback() const; /// This is the default empty callback. @@ -367,22 +376,32 @@ protected: void SetThreadSpec(std::unique_ptr<ThreadSpec> &thread_spec_up); private: - // For BreakpointOptions only - BreakpointHitCallback m_callback; // This is the callback function pointer - lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback + /// For BreakpointOptions only + + /// This is the callback function pointer + BreakpointHitCallback m_callback; + /// This is the client data for the callback + lldb::BatonSP m_callback_baton_sp; bool m_baton_is_command_baton; bool m_callback_is_synchronous; bool m_enabled; + /// If set, the breakpoint delete itself after being hit once. bool m_one_shot; - uint32_t m_ignore_count; // Number of times to ignore this breakpoint - std::unique_ptr<ThreadSpec> - m_thread_spec_up; // Thread for which this breakpoint will take - std::string m_condition_text; // The condition to test. - size_t m_condition_text_hash; // Its hash, so that locations know when the - // condition is updated. - bool m_auto_continue; // If set, auto-continue from breakpoint. - Flags m_set_flags; // Which options are set at this level. Drawn - // from BreakpointOptions::SetOptionsFlags. + /// Number of times to ignore this breakpoint. + uint32_t m_ignore_count; + /// Thread for which this breakpoint will stop. + std::unique_ptr<ThreadSpec> m_thread_spec_up; + /// The condition to test. + std::string m_condition_text; + /// Its hash, so that locations know when the condition is updated. + size_t m_condition_text_hash; + /// If set, inject breakpoint condition into process. + bool m_inject_condition; + /// If set, auto-continue from breakpoint. + bool m_auto_continue; + /// Which options are set at this level. + /// Drawn from BreakpointOptions::SetOptionsFlags. + Flags m_set_flags; }; } // namespace lldb_private diff --git a/include/lldb/Breakpoint/BreakpointResolverAddress.h b/include/lldb/Breakpoint/BreakpointResolverAddress.h index 949a788282b9..3df89641c711 100644 --- a/include/lldb/Breakpoint/BreakpointResolverAddress.h +++ b/include/lldb/Breakpoint/BreakpointResolverAddress.h @@ -41,8 +41,8 @@ public: ModuleList &modules) override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h index f146a704ca54..9ca48ecf0dc0 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -35,8 +35,8 @@ public: ~BreakpointResolverFileLine() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index 963145722e39..df4c13ed59e2 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -24,7 +24,7 @@ namespace lldb_private { class BreakpointResolverFileRegex : public BreakpointResolver { public: BreakpointResolverFileRegex( - Breakpoint *bkpt, RegularExpression ®ex, + Breakpoint *bkpt, RegularExpression regex, const std::unordered_set<std::string> &func_name_set, bool exact_match); static BreakpointResolver * @@ -37,8 +37,8 @@ public: ~BreakpointResolverFileRegex() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h index 85a41b6007f0..196d88db848c 100644 --- a/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/include/lldb/Breakpoint/BreakpointResolverName.h @@ -44,7 +44,7 @@ public: // Creates a function breakpoint by regular expression. Takes over control // of the lifespan of func_regex. - BreakpointResolverName(Breakpoint *bkpt, RegularExpression &func_regex, + BreakpointResolverName(Breakpoint *bkpt, RegularExpression func_regex, lldb::LanguageType language, lldb::addr_t offset, bool skip_prologue); @@ -58,8 +58,8 @@ public: ~BreakpointResolverName() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Breakpoint/BreakpointResolverScripted.h b/include/lldb/Breakpoint/BreakpointResolverScripted.h index 980bb4693d03..89a7d03ce93f 100644 --- a/include/lldb/Breakpoint/BreakpointResolverScripted.h +++ b/include/lldb/Breakpoint/BreakpointResolverScripted.h @@ -26,8 +26,7 @@ public: BreakpointResolverScripted(Breakpoint *bkpt, const llvm::StringRef class_name, lldb::SearchDepth depth, - StructuredDataImpl *args_data, - ScriptInterpreter &script_interp); + StructuredDataImpl *args_data); ~BreakpointResolverScripted() override; @@ -39,8 +38,8 @@ public: StructuredData::ObjectSP SerializeToStructuredData() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Core/Address.h b/include/lldb/Core/Address.h index 080c00e76328..07bb450d6092 100644 --- a/include/lldb/Core/Address.h +++ b/include/lldb/Core/Address.h @@ -338,6 +338,23 @@ public: bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections); + /// Resolve this address to its containing function and optionally get + /// that function's address range. + /// + /// \param[out] sym_ctx + /// The symbol context describing the function in which this address lies + /// + /// \parm[out] addr_range_ptr + /// Pointer to the AddressRange to fill in with the function's address + /// range. Caller may pass null if they don't need the address range. + /// + /// \return + /// Returns \b false if the function/symbol could not be resolved + /// or if the address range was requested and could not be resolved; + /// returns \b true otherwise. + bool ResolveFunctionScope(lldb_private::SymbolContext &sym_ctx, + lldb_private::AddressRange *addr_range_ptr = nullptr); + /// Set the address to represent \a load_addr. /// /// The address will attempt to find a loaded section within \a target that diff --git a/include/lldb/Core/AddressResolverFileLine.h b/include/lldb/Core/AddressResolverFileLine.h index b98e7d4c6338..efbe3de1f294 100644 --- a/include/lldb/Core/AddressResolverFileLine.h +++ b/include/lldb/Core/AddressResolverFileLine.h @@ -34,8 +34,8 @@ public: ~AddressResolverFileLine() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Core/AddressResolverName.h b/include/lldb/Core/AddressResolverName.h index ad14ef6daeb1..8a039f9e1d92 100644 --- a/include/lldb/Core/AddressResolverName.h +++ b/include/lldb/Core/AddressResolverName.h @@ -31,7 +31,7 @@ public: // Creates a function breakpoint by regular expression. Takes over control // of the lifespan of func_regex. - AddressResolverName(RegularExpression &func_regex); + AddressResolverName(RegularExpression func_regex); AddressResolverName(const char *class_name, const char *method, AddressResolver::MatchType type); @@ -39,8 +39,8 @@ public: ~AddressResolverName() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index 8e608717a801..b2f696c22834 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -17,6 +17,7 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/SourceManager.h" +#include "lldb/Core/StreamFile.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/Terminal.h" @@ -113,20 +114,29 @@ public: void SetAsyncExecution(bool async); - lldb::StreamFileSP GetInputFile() { return m_input_file_sp; } + lldb::FileSP GetInputFileSP() { return m_input_file_sp; } - lldb::StreamFileSP GetOutputFile() { return m_output_file_sp; } + lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_sp; } - lldb::StreamFileSP GetErrorFile() { return m_error_file_sp; } + lldb::StreamFileSP GetErrorStreamSP() { return m_error_stream_sp; } + + File &GetInputFile() { return *m_input_file_sp; } + + File &GetOutputFile() { return m_output_stream_sp->GetFile(); } + + File &GetErrorFile() { return m_error_stream_sp->GetFile(); } + + StreamFile &GetOutputStream() { return *m_output_stream_sp; } + + StreamFile &GetErrorStream() { return *m_error_stream_sp; } repro::DataRecorder *GetInputRecorder(); - void SetInputFileHandle(FILE *fh, bool tranfer_ownership, - repro::DataRecorder *recorder = nullptr); + void SetInputFile(lldb::FileSP file, repro::DataRecorder *recorder = nullptr); - void SetOutputFileHandle(FILE *fh, bool tranfer_ownership); + void SetOutputFile(lldb::FileSP file); - void SetErrorFileHandle(FILE *fh, bool tranfer_ownership); + void SetErrorFile(lldb::FileSP file); void SaveInputTerminalState(); @@ -174,7 +184,7 @@ public: // If any of the streams are not set, set them to the in/out/err stream of // the top most input reader to ensure they at least have something - void AdoptTopIOHandlerFilesIfInvalid(lldb::StreamFileSP &in, + void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, lldb::StreamFileSP &out, lldb::StreamFileSP &err); @@ -311,7 +321,7 @@ public: // selected target, or if no target is present you want to prime the dummy // target with entities that will be copied over to new targets. Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); - Target *GetDummyTarget(); + Target *GetDummyTarget() { return m_dummy_target_sp.get(); } lldb::BroadcasterManagerSP GetBroadcasterManager() { return m_broadcaster_manager_sp; @@ -345,9 +355,10 @@ protected: void HandleThreadEvent(const lldb::EventSP &event_sp); - size_t GetProcessSTDOUT(Process *process, Stream *stream); - - size_t GetProcessSTDERR(Process *process, Stream *stream); + // Ensures two threads don't attempt to flush process output in parallel. + std::mutex m_output_flush_mutex; + void FlushProcessOutput(Process &process, bool flush_stdout, + bool flush_stderr); SourceManager::SourceFileCache &GetSourceFileCache() { return m_source_file_cache; @@ -355,9 +366,10 @@ protected: void InstanceInitialize(); - lldb::StreamFileSP m_input_file_sp; - lldb::StreamFileSP m_output_file_sp; - lldb::StreamFileSP m_error_file_sp; + // these should never be NULL + lldb::FileSP m_input_file_sp; + lldb::StreamFileSP m_output_stream_sp; + lldb::StreamFileSP m_error_stream_sp; /// Used for shadowing the input file when capturing a reproducer. repro::DataRecorder *m_input_recorder; @@ -399,6 +411,7 @@ protected: Broadcaster m_sync_broadcaster; lldb::ListenerSP m_forward_listener_sp; llvm::once_flag m_clear_once; + lldb::TargetSP m_dummy_target_sp; // Events for m_sync_broadcaster enum { diff --git a/include/lldb/Core/FileLineResolver.h b/include/lldb/Core/FileLineResolver.h index 1967ed58cd3b..d6525b71bfdf 100644 --- a/include/lldb/Core/FileLineResolver.h +++ b/include/lldb/Core/FileLineResolver.h @@ -37,8 +37,8 @@ public: ~FileLineResolver() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool containing) override; + SymbolContext &context, + Address *addr) override; lldb::SearchDepth GetDepth() override; diff --git a/include/lldb/Core/FileSpecList.h b/include/lldb/Core/FileSpecList.h index 79623ef1fdca..8edc3280b01b 100644 --- a/include/lldb/Core/FileSpecList.h +++ b/include/lldb/Core/FileSpecList.h @@ -25,6 +25,9 @@ class Stream; /// A class that contains a mutable list of FileSpec objects. class FileSpecList { public: + typedef std::vector<FileSpec> collection; + typedef collection::const_iterator const_iterator; + /// Default constructor. /// /// Initialize this object with an empty file list. @@ -76,6 +79,15 @@ public: /// \b true if the file was appended, \b false otherwise. bool AppendIfUnique(const FileSpec &file); + /// Inserts a new FileSpec into the FileSpecList constructed in-place with + /// the given arguments. + /// + /// \param[in] args + /// Arguments to create the FileSpec + template <class... Args> void EmplaceBack(Args &&... args) { + m_files.emplace_back(std::forward<Args>(args)...); + } + /// Clears the file list. void Clear(); @@ -182,9 +194,10 @@ public: static size_t GetFilesMatchingPartialPath(const char *path, bool dir_okay, FileSpecList &matches); + const_iterator begin() const { return m_files.begin(); } + const_iterator end() const { return m_files.end(); } + protected: - typedef std::vector<FileSpec> - collection; ///< The collection type for the file list. collection m_files; ///< A collection of FileSpec objects. }; diff --git a/include/lldb/Core/FormatEntity.h b/include/lldb/Core/FormatEntity.h index 634d9df2ad83..ae6c402a45be 100644 --- a/include/lldb/Core/FormatEntity.h +++ b/include/lldb/Core/FormatEntity.h @@ -199,7 +199,7 @@ public: llvm::StringRef &variable_name, llvm::StringRef &variable_format); - static size_t AutoComplete(lldb_private::CompletionRequest &request); + static void AutoComplete(lldb_private::CompletionRequest &request); // Format the current elements into the stream \a s. // diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h index b7180675cf4e..37142a5a8396 100644 --- a/include/lldb/Core/IOHandler.h +++ b/include/lldb/Core/IOHandler.h @@ -10,6 +10,7 @@ #define liblldb_IOHandler_h_ #include "lldb/Core/ValueObjectList.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/Predicate.h" @@ -57,8 +58,7 @@ public: IOHandler(Debugger &debugger, IOHandler::Type type); IOHandler(Debugger &debugger, IOHandler::Type type, - const lldb::StreamFileSP &input_sp, - const lldb::StreamFileSP &output_sp, + const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, uint32_t flags, repro::DataRecorder *data_recorder); @@ -122,11 +122,11 @@ public: FILE *GetErrorFILE(); - lldb::StreamFileSP &GetInputStreamFile(); + lldb::FileSP &GetInputFileSP(); - lldb::StreamFileSP &GetOutputStreamFile(); + lldb::StreamFileSP &GetOutputStreamFileSP(); - lldb::StreamFileSP &GetErrorStreamFile(); + lldb::StreamFileSP &GetErrorStreamFileSP(); Debugger &GetDebugger() { return m_debugger; } @@ -164,7 +164,7 @@ public: protected: Debugger &m_debugger; - lldb::StreamFileSP m_input_sp; + lldb::FileSP m_input_sp; lldb::StreamFileSP m_output_sp; lldb::StreamFileSP m_error_sp; repro::DataRecorder *m_data_recorder; @@ -198,10 +198,8 @@ public: virtual void IOHandlerDeactivated(IOHandler &io_handler) {} - virtual int IOHandlerComplete(IOHandler &io_handler, const char *current_line, - const char *cursor, const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, StringList &descriptions); + virtual void IOHandlerComplete(IOHandler &io_handler, + CompletionRequest &request); virtual const char *IOHandlerGetFixIndentationCharacters() { return nullptr; } @@ -334,7 +332,7 @@ public: repro::DataRecorder *data_recorder); IOHandlerEditline(Debugger &debugger, IOHandler::Type type, - const lldb::StreamFileSP &input_sp, + const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, uint32_t flags, const char *editline_name, // Used for saving history files @@ -350,7 +348,7 @@ public: const char *, bool, bool, uint32_t, IOHandlerDelegate &) = delete; - IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::StreamFileSP &, + IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::FileSP &, const lldb::StreamFileSP &, const lldb::StreamFileSP &, uint32_t, const char *, const char *, const char *, bool, bool, uint32_t, IOHandlerDelegate &) = delete; @@ -415,11 +413,7 @@ private: static int FixIndentationCallback(Editline *editline, const StringList &lines, int cursor_position, void *baton); - static int AutoCompleteCallback(const char *current_line, const char *cursor, - const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, StringList &descriptions, - void *baton); + static void AutoCompleteCallback(CompletionRequest &request, void *baton); #endif protected: @@ -437,6 +431,7 @@ protected: bool m_interrupt_exits; bool m_editing; // Set to true when fetching a line manually (not using // libedit) + std::string m_line_buffer; }; // The order of base classes is important. Look at the constructor of @@ -450,10 +445,8 @@ public: bool GetResponse() const { return m_user_response; } - int IOHandlerComplete(IOHandler &io_handler, const char *current_line, - const char *cursor, const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, StringList &descriptions) override; + void IOHandlerComplete(IOHandler &io_handler, + CompletionRequest &request) override; void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override; diff --git a/include/lldb/Core/LoadedModuleInfoList.h b/include/lldb/Core/LoadedModuleInfoList.h index f7f83604fc1a..04e58fcdf313 100644 --- a/include/lldb/Core/LoadedModuleInfoList.h +++ b/include/lldb/Core/LoadedModuleInfoList.h @@ -84,9 +84,6 @@ public: } bool operator==(LoadedModuleInfo const &rhs) const { - if (e_num != rhs.e_num) - return false; - for (size_t i = 0; i < e_num; ++i) { if (m_has[i] != rhs.m_has[i]) return false; diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h index fb52afd6ed34..63fa0f618dae 100644 --- a/include/lldb/Core/Mangled.h +++ b/include/lldb/Core/Mangled.h @@ -49,21 +49,7 @@ public: /// Default constructor. /// /// Initialize with both mangled and demangled names empty. - Mangled(); - - /// Construct with name. - /// - /// Constructor with an optional string and a boolean indicating if it is - /// the mangled version. - /// - /// \param[in] name - /// The already const name to copy into this object. - /// - /// \param[in] is_mangled - /// If \b true then \a name is a mangled name, if \b false then - /// \a name is demangled. - Mangled(ConstString name, bool is_mangled); - Mangled(llvm::StringRef name, bool is_mangled); + Mangled() = default; /// Construct with name. /// @@ -76,12 +62,6 @@ public: explicit Mangled(llvm::StringRef name); - /// Destructor - /// - /// Releases its ref counts on the mangled and demangled strings that live - /// in the global string pool. - ~Mangled(); - /// Convert to pointer operator. /// /// This allows code to check a Mangled object to see if it contains a valid diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h index 544895ea89e9..89b731427e3f 100644 --- a/include/lldb/Core/Module.h +++ b/include/lldb/Core/Module.h @@ -49,7 +49,6 @@ class Symbol; class SymbolContext; class SymbolContextList; class SymbolFile; -class SymbolVendor; class Symtab; class Target; class TypeList; @@ -67,8 +66,8 @@ class VariableList; /// accessors are called. For example the object file (ObjectFile) /// representation will only be parsed if the object file is requested using /// the Module::GetObjectFile() is called. The debug symbols will only be -/// parsed if the symbol vendor (SymbolVendor) is requested using the -/// Module::GetSymbolVendor() is called. +/// parsed if the symbol file (SymbolFile) is requested using the +/// Module::GetSymbolFile() method. /// /// The module will parse more detailed information as more queries are made. class Module : public std::enable_shared_from_this<Module>, @@ -247,13 +246,13 @@ public: ConstString name, lldb::SymbolType symbol_type = lldb::eSymbolTypeAny); - size_t FindSymbolsWithNameAndType(ConstString name, - lldb::SymbolType symbol_type, - SymbolContextList &sc_list); + void FindSymbolsWithNameAndType(ConstString name, + lldb::SymbolType symbol_type, + SymbolContextList &sc_list); - size_t FindSymbolsMatchingRegExAndType(const RegularExpression ®ex, - lldb::SymbolType symbol_type, - SymbolContextList &sc_list); + void FindSymbolsMatchingRegExAndType(const RegularExpression ®ex, + lldb::SymbolType symbol_type, + SymbolContextList &sc_list); /// Find a function symbols in the object file's symbol table. /// @@ -267,11 +266,8 @@ public: /// /// \param[out] sc_list /// A list to append any matching symbol contexts to. - /// - /// \return - /// The number of symbol contexts that were added to \a sc_list - size_t FindFunctionSymbols(ConstString name, uint32_t name_type_mask, - SymbolContextList &sc_list); + void FindFunctionSymbols(ConstString name, uint32_t name_type_mask, + SymbolContextList &sc_list); /// Find compile units by partial or full path. /// @@ -281,19 +277,10 @@ public: /// \param[in] path /// The name of the function we are looking for. /// - /// \param[in] append - /// If \b true, then append any compile units that were found - /// to \a sc_list. If \b false, then the \a sc_list is cleared - /// and the contents of \a sc_list are replaced. - /// /// \param[out] sc_list /// A symbol context list that gets filled in with all of the /// matches. - /// - /// \return - /// The number of matches added to \a sc_list. - size_t FindCompileUnits(const FileSpec &path, bool append, - SymbolContextList &sc_list); + void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list); /// Find functions by name. /// @@ -313,21 +300,13 @@ public: /// names, base names, C++ methods, or ObjC selectors. /// See FunctionNameType for more details. /// - /// \param[in] append - /// If \b true, any matches will be appended to \a sc_list, else - /// matches replace the contents of \a sc_list. - /// /// \param[out] sc_list /// A symbol context list that gets filled in with all of the /// matches. - /// - /// \return - /// The number of matches added to \a sc_list. - size_t FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool symbols_ok, - bool inlines_ok, bool append, - SymbolContextList &sc_list); + void FindFunctions(ConstString name, + const CompilerDeclContext *parent_decl_ctx, + lldb::FunctionNameType name_type_mask, bool symbols_ok, + bool inlines_ok, SymbolContextList &sc_list); /// Find functions by name. /// @@ -345,12 +324,8 @@ public: /// \param[out] sc_list /// A symbol context list that gets filled in with all of the /// matches. - /// - /// \return - /// The number of matches added to \a sc_list. - size_t FindFunctions(const RegularExpression ®ex, bool symbols_ok, - bool inlines_ok, bool append, - SymbolContextList &sc_list); + void FindFunctions(const RegularExpression ®ex, bool symbols_ok, + bool inlines_ok, SymbolContextList &sc_list); /// Find addresses by file/line /// @@ -395,11 +370,9 @@ public: /// \param[in] variable_list /// A list of variables that gets the matches appended to. /// - /// \return - /// The number of matches added to \a variable_list. - size_t FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, - size_t max_matches, VariableList &variable_list); + void FindGlobalVariables(ConstString name, + const CompilerDeclContext *parent_decl_ctx, + size_t max_matches, VariableList &variable_list); /// Find global and static variables by regular expression. /// @@ -413,17 +386,14 @@ public: /// \param[in] variable_list /// A list of variables that gets the matches appended to. /// - /// \return - /// The number of matches added to \a variable_list. - size_t FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, - VariableList &variable_list); + void FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, + VariableList &variable_list); /// Find types by name. /// - /// Type lookups in modules go through the SymbolVendor (which will use one - /// or more SymbolFile subclasses). The SymbolFile needs to be able to - /// lookup types by basename and not the fully qualified typename. This - /// allows the type accelerator tables to stay small, even with heavily + /// Type lookups in modules go through the SymbolFile. The SymbolFile needs to + /// be able to lookup types by basename and not the fully qualified typename. + /// This allows the type accelerator tables to stay small, even with heavily /// templatized C++. The type search will then narrow down the search /// results. If "exact_match" is true, then the type search will only match /// exact type name matches. If "exact_match" is false, the type will match @@ -449,13 +419,19 @@ public: /// \param[out] type_list /// A type list gets populated with any matches. /// - /// \return - /// The number of matches added to \a type_list. - size_t + void FindTypes(ConstString type_name, bool exact_match, size_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeList &types); + /// Find types by name. + /// + /// This behaves like the other FindTypes method but allows to + /// specify a DeclContext and a language for the type being searched + /// for. + void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, + TypeMap &types); + lldb::TypeSP FindFirstType(const SymbolContext &sc, ConstString type_name, bool exact_match); @@ -473,11 +449,9 @@ public: /// \param[out] type_list /// A type list gets populated with any matches. /// - /// \return - /// The number of matches added to \a type_list. - size_t FindTypesInNamespace(ConstString type_name, - const CompilerDeclContext *parent_decl_ctx, - size_t max_matches, TypeList &type_list); + void FindTypesInNamespace(ConstString type_name, + const CompilerDeclContext *parent_decl_ctx, + size_t max_matches, TypeList &type_list); /// Get const accessor for the module architecture. /// @@ -638,27 +612,19 @@ public: ObjectFile *GetMemoryObjectFile(const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, Status &error, size_t size_to_read = 512); - /// Get the symbol vendor interface for the current architecture. - /// - /// If the symbol vendor file has not been located yet, this function will - /// find the best SymbolVendor plug-in that can use the current object file. - /// - /// \return - /// If this module does not have a valid object file, or no - /// plug-in can be found that can use the object file, nullptr will - /// be returned, else a valid symbol vendor plug-in interface - /// will be returned. The returned pointer is owned by this - /// object and remains valid as long as the object is around. - virtual SymbolVendor * - GetSymbolVendor(bool can_create = true, - lldb_private::Stream *feedback_strm = nullptr); - /// Get accessor the type list for this module. + /// Get the module's symbol file /// - /// \return - /// A valid type list pointer, or nullptr if there is no valid - /// symbol vendor for this module. - TypeList *GetTypeList(); + /// If the symbol file has already been loaded, this function returns it. All + /// arguments are ignored. If the symbol file has not been located yet, and + /// the can_create argument is false, the function returns nullptr. If + /// can_create is true, this function will find the best SymbolFile plug-in + /// that can use the current object file. feedback_strm, if not null, is used + /// to report the details of the search process. + virtual SymbolFile *GetSymbolFile(bool can_create = true, + Stream *feedback_strm = nullptr); + + Symtab *GetSymtab(); /// Get a reference to the UUID value contained in this object. /// @@ -819,7 +785,8 @@ public: bool GetIsDynamicLinkEditor(); - TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language); + llvm::Expected<TypeSystem &> + GetTypeSystemForLanguage(lldb::LanguageType language); // Special error functions that can do printf style formatting that will // prepend the message with something appropriate for this module (like the @@ -848,7 +815,7 @@ public: // when the module first gets created. bool FileHasChanged() const; - // SymbolVendor, SymbolFile and ObjectFile member objects should lock the + // SymbolFile and ObjectFile member objects should lock the // module mutex to avoid deadlocks. std::recursive_mutex &GetMutex() const { return m_mutex; } @@ -896,16 +863,19 @@ public: bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const; bool RemapSourceFile(const char *, std::string &) const = delete; + /// Update the ArchSpec to a more specific variant. + bool MergeArchitecture(const ArchSpec &arch_spec); + /// \class LookupInfo Module.h "lldb/Core/Module.h" /// A class that encapsulates name lookup information. /// /// Users can type a wide variety of partial names when setting breakpoints - /// by name or when looking for functions by name. SymbolVendor and - /// SymbolFile objects are only required to implement name lookup for - /// function basenames and for fully mangled names. This means if the user - /// types in a partial name, we must reduce this to a name lookup that will - /// work with all SymbolFile objects. So we might reduce a name lookup to - /// look for a basename, and then prune out any results that don't match. + /// by name or when looking for functions by name. The SymbolFile object is + /// only required to implement name lookup for function basenames and for + /// fully mangled names. This means if the user types in a partial name, we + /// must reduce this to a name lookup that will work with all SymbolFile + /// objects. So we might reduce a name lookup to look for a basename, and then + /// prune out any results that don't match. /// /// The "m_name" member variable represents the name as it was typed by the /// user. "m_lookup_name" will be the name we actually search for through @@ -1012,7 +982,7 @@ protected: /// ObjectFile instances for the debug info std::atomic<bool> m_did_load_objfile{false}; - std::atomic<bool> m_did_load_symbol_vendor{false}; + std::atomic<bool> m_did_load_symfile{false}; std::atomic<bool> m_did_set_uuid{false}; mutable bool m_file_has_changed : 1, m_first_file_changed_log : 1; /// See if the module was modified after it @@ -1072,9 +1042,9 @@ protected: private: Module(); // Only used internally by CreateJITModule () - size_t FindTypes_Impl( + void FindTypes_Impl( ConstString name, const CompilerDeclContext *parent_decl_ctx, - bool append, size_t max_matches, + size_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types); diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h index 1e26c35e4c15..e21655551b61 100644 --- a/include/lldb/Core/ModuleList.h +++ b/include/lldb/Core/ModuleList.h @@ -247,35 +247,24 @@ public: /// \param[in] path /// The name of the compile unit we are looking for. /// - /// \param[in] append - /// If \b true, then append any compile units that were found - /// to \a sc_list. If \b false, then the \a sc_list is cleared - /// and the contents of \a sc_list are replaced. - /// /// \param[out] sc_list /// A symbol context list that gets filled in with all of the /// matches. - /// - /// \return - /// The number of matches added to \a sc_list. - size_t FindCompileUnits(const FileSpec &path, bool append, - SymbolContextList &sc_list) const; + void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const; /// \see Module::FindFunctions () - size_t FindFunctions(ConstString name, - lldb::FunctionNameType name_type_mask, - bool include_symbols, bool include_inlines, bool append, - SymbolContextList &sc_list) const; + void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, + bool include_symbols, bool include_inlines, + SymbolContextList &sc_list) const; /// \see Module::FindFunctionSymbols () - size_t FindFunctionSymbols(ConstString name, - lldb::FunctionNameType name_type_mask, - SymbolContextList &sc_list); + void FindFunctionSymbols(ConstString name, + lldb::FunctionNameType name_type_mask, + SymbolContextList &sc_list); /// \see Module::FindFunctions () - size_t FindFunctions(const RegularExpression &name, bool include_symbols, - bool include_inlines, bool append, - SymbolContextList &sc_list); + void FindFunctions(const RegularExpression &name, bool include_symbols, + bool include_inlines, SymbolContextList &sc_list); /// Find global and static variables by name. /// @@ -289,11 +278,8 @@ public: /// /// \param[in] variable_list /// A list of variables that gets the matches appended to. - /// - /// \return - /// The number of matches added to \a variable_list. - size_t FindGlobalVariables(ConstString name, size_t max_matches, - VariableList &variable_list) const; + void FindGlobalVariables(ConstString name, size_t max_matches, + VariableList &variable_list) const; /// Find global and static variables by regular expression. /// @@ -306,11 +292,8 @@ public: /// /// \param[in] variable_list /// A list of variables that gets the matches appended to. - /// - /// \return - /// The number of matches added to \a variable_list. - size_t FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, - VariableList &variable_list) const; + void FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, + VariableList &variable_list) const; /// Finds the first module whose file specification matches \a file_spec. /// @@ -337,11 +320,8 @@ public: /// \param[out] matching_module_list /// A module list that gets filled in with any modules that /// match the search criteria. - /// - /// \return - /// The number of matching modules found by the search. - size_t FindModules(const ModuleSpec &module_spec, - ModuleList &matching_module_list) const; + void FindModules(const ModuleSpec &module_spec, + ModuleList &matching_module_list) const; lldb::ModuleSP FindModule(const Module *module_ptr) const; @@ -354,15 +334,13 @@ public: lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const; - size_t FindSymbolsWithNameAndType(ConstString name, - lldb::SymbolType symbol_type, - SymbolContextList &sc_list, - bool append = false) const; + void FindSymbolsWithNameAndType(ConstString name, + lldb::SymbolType symbol_type, + SymbolContextList &sc_list) const; - size_t FindSymbolsMatchingRegExAndType(const RegularExpression ®ex, - lldb::SymbolType symbol_type, - SymbolContextList &sc_list, - bool append = false) const; + void FindSymbolsMatchingRegExAndType(const RegularExpression ®ex, + lldb::SymbolType symbol_type, + SymbolContextList &sc_list) const; /// Find types by name. /// @@ -393,12 +371,10 @@ public: /// \param[out] type_list /// A type list gets populated with any matches. /// - /// \return - /// The number of matches added to \a type_list. - size_t FindTypes(Module *search_first, ConstString name, - bool name_is_fully_qualified, size_t max_matches, - llvm::DenseSet<SymbolFile *> &searched_symbol_files, - TypeList &types) const; + void FindTypes(Module *search_first, ConstString name, + bool name_is_fully_qualified, size_t max_matches, + llvm::DenseSet<SymbolFile *> &searched_symbol_files, + TypeList &types) const; bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const; @@ -476,6 +452,7 @@ public: /// \return /// The number of modules in the module list. size_t GetSize() const; + bool IsEmpty() const { return !GetSize(); } bool LoadScriptingResourcesInTarget(Target *target, std::list<Status> &errors, Stream *feedback_stream = nullptr, @@ -494,8 +471,8 @@ public: static bool RemoveSharedModule(lldb::ModuleSP &module_sp); - static size_t FindSharedModules(const ModuleSpec &module_spec, - ModuleList &matching_module_list); + static void FindSharedModules(const ModuleSpec &module_spec, + ModuleList &matching_module_list); static size_t RemoveOrphanSharedModules(bool mandatory); diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h index ab0f4e9912a8..651d0dc869bc 100644 --- a/include/lldb/Core/ModuleSpec.h +++ b/include/lldb/Core/ModuleSpec.h @@ -380,8 +380,8 @@ public: return false; } - size_t FindMatchingModuleSpecs(const ModuleSpec &module_spec, - ModuleSpecList &matching_list) const { + void FindMatchingModuleSpecs(const ModuleSpec &module_spec, + ModuleSpecList &matching_list) const { std::lock_guard<std::recursive_mutex> guard(m_mutex); bool exact_arch_match = true; const size_t initial_match_count = matching_list.GetSize(); @@ -400,7 +400,6 @@ public: matching_list.Append(spec); } } - return matching_list.GetSize() - initial_match_count; } void Dump(Stream &strm) { diff --git a/include/lldb/Core/PluginManager.h b/include/lldb/Core/PluginManager.h index 1bac1e5df694..5b859752b3c7 100644 --- a/include/lldb/Core/PluginManager.h +++ b/include/lldb/Core/PluginManager.h @@ -10,6 +10,8 @@ #define liblldb_PluginManager_h_ #include "lldb/Core/Architecture.h" +#include "lldb/Symbol/TypeSystem.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" @@ -228,8 +230,8 @@ public: static const char *GetPlatformPluginDescriptionAtIndex(uint32_t idx); - static size_t AutoCompletePlatformName(llvm::StringRef partial_name, - StringList &matches); + static void AutoCompletePlatformName(llvm::StringRef partial_name, + CompletionRequest &request); // Process static bool RegisterPlugin(ConstString name, const char *description, @@ -383,10 +385,10 @@ public: GetInstrumentationRuntimeCreateCallbackForPluginName(ConstString name); // TypeSystem - static bool RegisterPlugin( - ConstString name, const char *description, - TypeSystemCreateInstance create_callback, - TypeSystemEnumerateSupportedLanguages enumerate_languages_callback); + static bool RegisterPlugin(ConstString name, const char *description, + TypeSystemCreateInstance create_callback, + LanguageSet supported_languages_for_types, + LanguageSet supported_languages_for_expressions); static bool UnregisterPlugin(TypeSystemCreateInstance create_callback); @@ -396,18 +398,14 @@ public: static TypeSystemCreateInstance GetTypeSystemCreateCallbackForPluginName(ConstString name); - static TypeSystemEnumerateSupportedLanguages - GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx); + static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes(); - static TypeSystemEnumerateSupportedLanguages - GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName( - ConstString name); + static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions(); // REPL - static bool - RegisterPlugin(ConstString name, const char *description, - REPLCreateInstance create_callback, - REPLEnumerateSupportedLanguages enumerate_languages_callback); + static bool RegisterPlugin(ConstString name, const char *description, + REPLCreateInstance create_callback, + LanguageSet supported_languages); static bool UnregisterPlugin(REPLCreateInstance create_callback); @@ -416,12 +414,7 @@ public: static REPLCreateInstance GetREPLCreateCallbackForPluginName(ConstString name); - static REPLEnumerateSupportedLanguages - GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx); - - static REPLEnumerateSupportedLanguages - GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName( - ConstString name); + static LanguageSet GetREPLAllTypeSystemSupportedLanguages(); // Some plug-ins might register a DebuggerInitializeCallback callback when // registering the plug-in. After a new Debugger instance is created, this @@ -439,32 +432,28 @@ public: ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForPlatformPlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForPlatformPlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForPlatformPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForProcessPlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForProcessPlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForProcessPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForSymbolFilePlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForSymbolFilePlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForJITLoaderPlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForJITLoaderPlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForJITLoaderPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, diff --git a/include/lldb/Core/PropertiesBase.td b/include/lldb/Core/PropertiesBase.td new file mode 100644 index 000000000000..be97d44ae8e4 --- /dev/null +++ b/include/lldb/Core/PropertiesBase.td @@ -0,0 +1,49 @@ +// Base class for all options. +class Property<string name, string type> { + string Name = name; + string Type = type; + string Definition; +} + +// Sets the description for the property that should be displayed to the user. +class Desc<string description> { + string Description = description; +} + +// Marks the property as global. +class Global { + bit Global = 1; +} + +class DefaultTrue { + int DefaultUnsignedValue = 1; + bit HasDefaultUnsignedValue = 1; +} + +class DefaultFalse { + int DefaultUnsignedValue = 0; + bit HasDefaultUnsignedValue = 1; +} + +// Gives the property a default string value. +class DefaultStringValue<string value> { + string DefaultStringValue = value; + bit HasDefaultStringValue = 1; +} + +// Gives the property a default enum value. +class DefaultEnumValue<string value> { + string DefaultEnumValue = value; + bit HasDefaultEnumValue = 1; +} + +// Gives the property a default string value. +class DefaultUnsignedValue<int value> { + int DefaultUnsignedValue = value; + bit HasDefaultUnsignedValue = 1; +} + +// Gives the property enum values. +class EnumValues<string enum> { + string EnumValues = enum; +} diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h index f38690c95f52..6823daf9e3ed 100644 --- a/include/lldb/Core/SearchFilter.h +++ b/include/lldb/Core/SearchFilter.h @@ -52,8 +52,8 @@ public: virtual ~Searcher(); virtual CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *addr, - bool complete) = 0; + SymbolContext &context, + Address *addr) = 0; virtual lldb::SearchDepth GetDepth() = 0; diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h index 881d43702cee..509a0767be1d 100644 --- a/include/lldb/Core/Section.h +++ b/include/lldb/Core/Section.h @@ -43,9 +43,8 @@ public: const_iterator begin() { return m_sections.begin(); } const_iterator end() { return m_sections.end(); } - SectionList(); - - ~SectionList(); + /// Create an empty list. + SectionList() = default; SectionList &operator=(const SectionList &rhs); diff --git a/include/lldb/Core/StreamFile.h b/include/lldb/Core/StreamFile.h index 54aeab16b3f1..712b289aa8d9 100644 --- a/include/lldb/Core/StreamFile.h +++ b/include/lldb/Core/StreamFile.h @@ -30,23 +30,27 @@ public: StreamFile(const char *path); - StreamFile(const char *path, uint32_t options, + StreamFile(const char *path, File::OpenOptions options, uint32_t permissions = lldb::eFilePermissionsFileDefault); StreamFile(FILE *fh, bool transfer_ownership); + StreamFile(std::shared_ptr<File> file) : m_file_sp(file) { assert(file); }; + ~StreamFile() override; - File &GetFile() { return m_file; } + File &GetFile() { return *m_file_sp; } + + const File &GetFile() const { return *m_file_sp; } - const File &GetFile() const { return m_file; } + std::shared_ptr<File> GetFileSP() { return m_file_sp; } void Flush() override; protected: // Classes that inherit from StreamFile can see and modify these - File m_file; + std::shared_ptr<File> m_file_sp; // never NULL size_t WriteImpl(const void *s, size_t length) override; private: diff --git a/include/lldb/Core/StructuredDataImpl.h b/include/lldb/Core/StructuredDataImpl.h index 79a709af7ca3..c66e4736dc26 100644 --- a/include/lldb/Core/StructuredDataImpl.h +++ b/include/lldb/Core/StructuredDataImpl.h @@ -54,7 +54,8 @@ public: return error; } - m_data_sp->Dump(stream); + llvm::json::OStream s(stream.AsRawOstream()); + m_data_sp->Serialize(s); return error; } diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h index b786e4866f6c..7b4cc3b71c28 100644 --- a/include/lldb/Core/Value.h +++ b/include/lldb/Core/Value.h @@ -210,7 +210,6 @@ public: uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx); Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, - uint32_t data_offset, Module *module); // Can be nullptr static const char *GetValueTypeAsCString(ValueType context_type); diff --git a/include/lldb/Core/dwarf.h b/include/lldb/Core/dwarf.h index afe62e09fe16..832109e55c70 100644 --- a/include/lldb/Core/dwarf.h +++ b/include/lldb/Core/dwarf.h @@ -22,7 +22,7 @@ typedef uint32_t dw_uleb128_t; typedef int32_t dw_sleb128_t; typedef uint16_t dw_attr_t; typedef uint16_t dw_form_t; -typedef uint16_t dw_tag_t; +typedef llvm::dwarf::Tag dw_tag_t; typedef uint64_t dw_addr_t; // Dwarf address define that must be big enough for // any addresses in the compile units that get // parsed diff --git a/include/lldb/DataFormatters/FormattersContainer.h b/include/lldb/DataFormatters/FormattersContainer.h index 9d7d37343ac2..de2edb103151 100644 --- a/include/lldb/DataFormatters/FormattersContainer.h +++ b/include/lldb/DataFormatters/FormattersContainer.h @@ -47,7 +47,7 @@ static inline ConstString GetValidTypeName_Impl(ConstString type) { return type; std::string type_cstr(type.AsCString()); - lldb_utility::StringLexer type_lexer(type_cstr); + StringLexer type_lexer(type_cstr); type_lexer.AdvanceIf("class "); type_lexer.AdvanceIf("enum "); @@ -65,9 +65,9 @@ template <typename KeyType, typename ValueType> class FormattersContainer; template <typename KeyType, typename ValueType> class FormatMap { public: typedef typename ValueType::SharedPointer ValueSP; - typedef std::map<KeyType, ValueSP> MapType; + typedef std::vector<std::pair<KeyType, ValueSP>> MapType; typedef typename MapType::iterator MapIterator; - typedef std::function<bool(KeyType, const ValueSP &)> ForEachCallback; + typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback; FormatMap(IFormatChangeListener *lst) : m_map(), m_map_mutex(), listener(lst) {} @@ -79,20 +79,22 @@ public: entry->GetRevision() = 0; std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - m_map[name] = entry; + Delete(name); + m_map.emplace_back(std::move(name), std::move(entry)); if (listener) listener->Changed(); } - bool Delete(KeyType name) { + bool Delete(const KeyType &name) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - MapIterator iter = m_map.find(name); - if (iter == m_map.end()) - return false; - m_map.erase(name); - if (listener) - listener->Changed(); - return true; + for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter) + if (iter->first == name) { + m_map.erase(iter); + if (listener) + listener->Changed(); + return true; + } + return false; } void Clear() { @@ -102,22 +104,22 @@ public: listener->Changed(); } - bool Get(KeyType name, ValueSP &entry) { + bool Get(const KeyType &name, ValueSP &entry) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - MapIterator iter = m_map.find(name); - if (iter == m_map.end()) - return false; - entry = iter->second; - return true; + for (const auto &pos : m_map) + if (pos.first == name) { + entry = pos.second; + return true; + } + return false; } void ForEach(ForEachCallback callback) { if (callback) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - MapIterator pos, end = m_map.end(); - for (pos = m_map.begin(); pos != end; pos++) { - KeyType type = pos->first; - if (!callback(type, pos->second)) + for (const auto &pos : m_map) { + const KeyType &type = pos.first; + if (!callback(type, pos.second)) break; } } @@ -127,28 +129,17 @@ public: ValueSP GetValueAtIndex(size_t index) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - MapIterator iter = m_map.begin(); - MapIterator end = m_map.end(); - while (index > 0) { - iter++; - index--; - if (end == iter) - return ValueSP(); - } - return iter->second; + if (index >= m_map.size()) + return ValueSP(); + return m_map[index].second; } + // If caller holds the mutex we could return a reference without copy ctor. KeyType GetKeyAtIndex(size_t index) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - MapIterator iter = m_map.begin(); - MapIterator end = m_map.end(); - while (index > 0) { - iter++; - index--; - if (end == iter) - return KeyType(); - } - return iter->first; + if (index >= m_map.size()) + return {}; + return m_map[index].first; } protected: @@ -171,8 +162,8 @@ protected: public: typedef typename BackEndType::MapType MapType; typedef typename MapType::iterator MapIterator; - typedef typename MapType::key_type MapKeyType; - typedef typename MapType::mapped_type MapValueType; + typedef KeyType MapKeyType; + typedef std::shared_ptr<ValueType> MapValueType; typedef typename BackEndType::ForEachCallback ForEachCallback; typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>> SharedPointer; @@ -182,8 +173,8 @@ public: FormattersContainer(std::string name, IFormatChangeListener *lst) : m_format_map(lst), m_name(name) {} - void Add(const MapKeyType &type, const MapValueType &entry) { - Add_Impl(type, entry, static_cast<KeyType *>(nullptr)); + void Add(MapKeyType type, const MapValueType &entry) { + Add_Impl(std::move(type), entry, static_cast<KeyType *>(nullptr)); } bool Delete(ConstString type) { @@ -233,9 +224,9 @@ protected: DISALLOW_COPY_AND_ASSIGN(FormattersContainer); - void Add_Impl(const MapKeyType &type, const MapValueType &entry, - lldb::RegularExpressionSP *dummy) { - m_format_map.Add(type, entry); + void Add_Impl(MapKeyType type, const MapValueType &entry, + RegularExpression *dummy) { + m_format_map.Add(std::move(type), entry); } void Add_Impl(ConstString type, const MapValueType &entry, @@ -247,12 +238,12 @@ protected: return m_format_map.Delete(type); } - bool Delete_Impl(ConstString type, lldb::RegularExpressionSP *dummy) { + bool Delete_Impl(ConstString type, RegularExpression *dummy) { std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); MapIterator pos, end = m_format_map.map().end(); for (pos = m_format_map.map().begin(); pos != end; pos++) { - lldb::RegularExpressionSP regex = pos->first; - if (type.GetStringRef() == regex->GetText()) { + const RegularExpression ®ex = pos->first; + if (type.GetStringRef() == regex.GetText()) { m_format_map.map().erase(pos); if (m_format_map.listener) m_format_map.listener->Changed(); @@ -282,24 +273,23 @@ protected: } lldb::TypeNameSpecifierImplSP - GetTypeNameSpecifierAtIndex_Impl(size_t index, - lldb::RegularExpressionSP *dummy) { - lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index); - if (regex.get() == nullptr) + GetTypeNameSpecifierAtIndex_Impl(size_t index, RegularExpression *dummy) { + RegularExpression regex = m_format_map.GetKeyAtIndex(index); + if (regex == RegularExpression()) return lldb::TypeNameSpecifierImplSP(); return lldb::TypeNameSpecifierImplSP( - new TypeNameSpecifierImpl(regex->GetText().str().c_str(), true)); + new TypeNameSpecifierImpl(regex.GetText().str().c_str(), true)); } bool Get_Impl(ConstString key, MapValueType &value, - lldb::RegularExpressionSP *dummy) { + RegularExpression *dummy) { llvm::StringRef key_str = key.GetStringRef(); std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - MapIterator pos, end = m_format_map.map().end(); - for (pos = m_format_map.map().begin(); pos != end; pos++) { - lldb::RegularExpressionSP regex = pos->first; - if (regex->Execute(key_str)) { - value = pos->second; + // Patterns are matched in reverse-chronological order. + for (const auto &pos : llvm::reverse(m_format_map.map())) { + const RegularExpression ®ex = pos.first; + if (regex.Execute(key_str)) { + value = pos.second; return true; } } @@ -307,13 +297,12 @@ protected: } bool GetExact_Impl(ConstString key, MapValueType &value, - lldb::RegularExpressionSP *dummy) { + RegularExpression *dummy) { std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - MapIterator pos, end = m_format_map.map().end(); - for (pos = m_format_map.map().begin(); pos != end; pos++) { - lldb::RegularExpressionSP regex = pos->first; - if (regex->GetText() == key.GetStringRef()) { - value = pos->second; + for (const auto &pos : m_format_map.map()) { + const RegularExpression ®ex = pos.first; + if (regex.GetText() == key.GetStringRef()) { + value = pos.second; return true; } } diff --git a/include/lldb/DataFormatters/StringPrinter.h b/include/lldb/DataFormatters/StringPrinter.h index 41d5edd88021..43b92019e6fd 100644 --- a/include/lldb/DataFormatters/StringPrinter.h +++ b/include/lldb/DataFormatters/StringPrinter.h @@ -24,238 +24,121 @@ public: enum class GetPrintableElementType { ASCII, UTF8 }; - class ReadStringAndDumpToStreamOptions { + class DumpToStreamOptions { public: - ReadStringAndDumpToStreamOptions() - : m_location(0), m_process_sp(), m_stream(nullptr), m_prefix_token(), - m_suffix_token(), m_quote('"'), m_source_size(0), - m_needs_zero_termination(true), m_escape_non_printables(true), - m_ignore_max_length(false), m_zero_is_terminator(true), - m_language_type(lldb::eLanguageTypeUnknown) {} + DumpToStreamOptions() = default; - ReadStringAndDumpToStreamOptions(ValueObject &valobj); - - ReadStringAndDumpToStreamOptions &SetLocation(uint64_t l) { - m_location = l; - return *this; - } - - uint64_t GetLocation() const { return m_location; } - - ReadStringAndDumpToStreamOptions &SetProcessSP(lldb::ProcessSP p) { - m_process_sp = p; - return *this; - } - - lldb::ProcessSP GetProcessSP() const { return m_process_sp; } - - ReadStringAndDumpToStreamOptions &SetStream(Stream *s) { - m_stream = s; - return *this; - } + void SetStream(Stream *s) { m_stream = s; } Stream *GetStream() const { return m_stream; } - ReadStringAndDumpToStreamOptions &SetPrefixToken(const std::string &p) { - m_prefix_token = p; - return *this; - } + void SetPrefixToken(const std::string &p) { m_prefix_token = p; } - ReadStringAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) { - m_prefix_token.clear(); - return *this; - } + void SetPrefixToken(std::nullptr_t) { m_prefix_token.clear(); } const char *GetPrefixToken() const { return m_prefix_token.c_str(); } - ReadStringAndDumpToStreamOptions &SetSuffixToken(const std::string &p) { - m_suffix_token = p; - return *this; - } + void SetSuffixToken(const std::string &p) { m_suffix_token = p; } - ReadStringAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) { - m_suffix_token.clear(); - return *this; - } + void SetSuffixToken(std::nullptr_t) { m_suffix_token.clear(); } const char *GetSuffixToken() const { return m_suffix_token.c_str(); } - ReadStringAndDumpToStreamOptions &SetQuote(char q) { - m_quote = q; - return *this; - } + void SetQuote(char q) { m_quote = q; } char GetQuote() const { return m_quote; } - ReadStringAndDumpToStreamOptions &SetSourceSize(uint32_t s) { - m_source_size = s; - return *this; - } + void SetSourceSize(uint32_t s) { m_source_size = s; } uint32_t GetSourceSize() const { return m_source_size; } - ReadStringAndDumpToStreamOptions &SetNeedsZeroTermination(bool z) { - m_needs_zero_termination = z; - return *this; - } + void SetNeedsZeroTermination(bool z) { m_needs_zero_termination = z; } bool GetNeedsZeroTermination() const { return m_needs_zero_termination; } - ReadStringAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) { - m_zero_is_terminator = e; - return *this; - } + void SetBinaryZeroIsTerminator(bool e) { m_zero_is_terminator = e; } bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; } - ReadStringAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) { - m_escape_non_printables = e; - return *this; - } + void SetEscapeNonPrintables(bool e) { m_escape_non_printables = e; } bool GetEscapeNonPrintables() const { return m_escape_non_printables; } - ReadStringAndDumpToStreamOptions &SetIgnoreMaxLength(bool e) { - m_ignore_max_length = e; - return *this; - } + void SetIgnoreMaxLength(bool e) { m_ignore_max_length = e; } bool GetIgnoreMaxLength() const { return m_ignore_max_length; } - ReadStringAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) { - m_language_type = l; - return *this; - } - - lldb::LanguageType GetLanguage() const + void SetLanguage(lldb::LanguageType l) { m_language_type = l; } - { - return m_language_type; - } + lldb::LanguageType GetLanguage() const { return m_language_type; } private: - uint64_t m_location; - lldb::ProcessSP m_process_sp; - Stream *m_stream; + /// The used output stream. + Stream *m_stream = nullptr; + /// String that should be printed before the heading quote character. std::string m_prefix_token; + /// String that should be printed after the trailing quote character. std::string m_suffix_token; - char m_quote; - uint32_t m_source_size; - bool m_needs_zero_termination; - bool m_escape_non_printables; - bool m_ignore_max_length; - bool m_zero_is_terminator; - lldb::LanguageType m_language_type; + /// The quote character that should surround the string. + char m_quote = '"'; + /// The length of the memory region that should be dumped in bytes. + uint32_t m_source_size = 0; + bool m_needs_zero_termination = true; + /// True iff non-printable characters should be escaped when dumping + /// them to the stream. + bool m_escape_non_printables = true; + /// True iff the max-string-summary-length setting of the target should + /// be ignored. + bool m_ignore_max_length = false; + /// True iff a zero bytes ('\0') should terminate the memory region that + /// is being dumped. + bool m_zero_is_terminator = true; + /// The language that the generated string literal is supposed to be valid + /// for. This changes for example what and how certain characters are + /// escaped. + /// For example, printing the a string containing only a quote (") char + /// with eLanguageTypeC would escape the quote character. + lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown; }; - class ReadBufferAndDumpToStreamOptions { + class ReadStringAndDumpToStreamOptions : public DumpToStreamOptions { public: - ReadBufferAndDumpToStreamOptions() - : m_data(), m_stream(nullptr), m_prefix_token(), m_suffix_token(), - m_quote('"'), m_source_size(0), m_escape_non_printables(true), - m_zero_is_terminator(true), m_is_truncated(false), - m_language_type(lldb::eLanguageTypeUnknown) {} + ReadStringAndDumpToStreamOptions() = default; - ReadBufferAndDumpToStreamOptions(ValueObject &valobj); - - ReadBufferAndDumpToStreamOptions( - const ReadStringAndDumpToStreamOptions &options); - - ReadBufferAndDumpToStreamOptions &SetData(DataExtractor d) { - m_data = d; - return *this; - } - - lldb_private::DataExtractor GetData() const { return m_data; } - - ReadBufferAndDumpToStreamOptions &SetStream(Stream *s) { - m_stream = s; - return *this; - } - - Stream *GetStream() const { return m_stream; } - - ReadBufferAndDumpToStreamOptions &SetPrefixToken(const std::string &p) { - m_prefix_token = p; - return *this; - } - - ReadBufferAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) { - m_prefix_token.clear(); - return *this; - } - - const char *GetPrefixToken() const { return m_prefix_token.c_str(); } - - ReadBufferAndDumpToStreamOptions &SetSuffixToken(const std::string &p) { - m_suffix_token = p; - return *this; - } + ReadStringAndDumpToStreamOptions(ValueObject &valobj); - ReadBufferAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) { - m_suffix_token.clear(); - return *this; - } + void SetLocation(uint64_t l) { m_location = l; } - const char *GetSuffixToken() const { return m_suffix_token.c_str(); } + uint64_t GetLocation() const { return m_location; } - ReadBufferAndDumpToStreamOptions &SetQuote(char q) { - m_quote = q; - return *this; - } + void SetProcessSP(lldb::ProcessSP p) { m_process_sp = p; } - char GetQuote() const { return m_quote; } + lldb::ProcessSP GetProcessSP() const { return m_process_sp; } - ReadBufferAndDumpToStreamOptions &SetSourceSize(uint32_t s) { - m_source_size = s; - return *this; - } + private: + uint64_t m_location = 0; + lldb::ProcessSP m_process_sp; + }; - uint32_t GetSourceSize() const { return m_source_size; } + class ReadBufferAndDumpToStreamOptions : public DumpToStreamOptions { + public: + ReadBufferAndDumpToStreamOptions() = default; - ReadBufferAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) { - m_escape_non_printables = e; - return *this; - } + ReadBufferAndDumpToStreamOptions(ValueObject &valobj); - bool GetEscapeNonPrintables() const { return m_escape_non_printables; } + ReadBufferAndDumpToStreamOptions( + const ReadStringAndDumpToStreamOptions &options); - ReadBufferAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) { - m_zero_is_terminator = e; - return *this; - } + void SetData(DataExtractor d) { m_data = d; } - bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; } + lldb_private::DataExtractor GetData() const { return m_data; } - ReadBufferAndDumpToStreamOptions &SetIsTruncated(bool t) { - m_is_truncated = t; - return *this; - } + void SetIsTruncated(bool t) { m_is_truncated = t; } bool GetIsTruncated() const { return m_is_truncated; } - - ReadBufferAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) { - m_language_type = l; - return *this; - } - - lldb::LanguageType GetLanguage() const - - { - return m_language_type; - } - private: DataExtractor m_data; - Stream *m_stream; - std::string m_prefix_token; - std::string m_suffix_token; - char m_quote; - uint32_t m_source_size; - bool m_escape_non_printables; - bool m_zero_is_terminator; - bool m_is_truncated; - lldb::LanguageType m_language_type; + bool m_is_truncated = false; }; // I can't use a std::unique_ptr for this because the Deleter is a template diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h index bdb393abd848..a5438226bbbb 100644 --- a/include/lldb/DataFormatters/TypeCategory.h +++ b/include/lldb/DataFormatters/TypeCategory.h @@ -26,7 +26,7 @@ namespace lldb_private { template <typename FormatterImpl> class FormatterContainerPair { public: typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer; - typedef FormattersContainer<lldb::RegularExpressionSP, FormatterImpl> + typedef FormattersContainer<RegularExpression, FormatterImpl> RegexMatchContainer; typedef typename ExactMatchContainer::MapType ExactMatchMap; diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h index 21830a562800..44015b4e418f 100644 --- a/include/lldb/Expression/DWARFExpression.h +++ b/include/lldb/Expression/DWARFExpression.h @@ -50,15 +50,8 @@ public: /// \param[in] data /// A data extractor configured to read the DWARF location expression's /// bytecode. - /// - /// \param[in] data_offset - /// The offset of the location expression in the extractor. - /// - /// \param[in] data_length - /// The byte length of the location expression. DWARFExpression(lldb::ModuleSP module, const DataExtractor &data, - const DWARFUnit *dwarf_cu, lldb::offset_t data_offset, - lldb::offset_t data_length); + const DWARFUnit *dwarf_cu); /// Destructor virtual ~DWARFExpression(); @@ -211,12 +204,6 @@ public: /// in the case where an expression needs to be evaluated while building /// the stack frame list, this short-cut is available. /// - /// \param[in] offset - /// The offset of the location expression in the data extractor. - /// - /// \param[in] length - /// The length in bytes of the location expression. - /// /// \param[in] reg_set /// The call-frame-info style register kind. /// @@ -236,8 +223,7 @@ public: /// details of the failure are provided through it. static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes, - const DWARFUnit *dwarf_cu, const lldb::offset_t offset, - const lldb::offset_t length, + const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_set, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, @@ -252,10 +238,6 @@ public: lldb::addr_t loclist_base_load_addr, lldb::addr_t address, ABI *abi); - static size_t LocationListSize(const DWARFUnit *dwarf_cu, - const DataExtractor &debug_loc_data, - lldb::offset_t offset); - static bool PrintDWARFExpression(Stream &s, const DataExtractor &data, int address_size, int dwarf_ref_size, bool location_expression); diff --git a/include/lldb/Expression/DiagnosticManager.h b/include/lldb/Expression/DiagnosticManager.h index 7e3e2bb8606a..e5aecce08727 100644 --- a/include/lldb/Expression/DiagnosticManager.h +++ b/include/lldb/Expression/DiagnosticManager.h @@ -12,6 +12,7 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -23,7 +24,6 @@ enum DiagnosticOrigin { eDiagnosticOriginUnknown = 0, eDiagnosticOriginLLDB, eDiagnosticOriginClang, - eDiagnosticOriginGo, eDiagnosticOriginSwift, eDiagnosticOriginLLVM }; @@ -47,7 +47,6 @@ public: switch (kind) { case eDiagnosticOriginUnknown: case eDiagnosticOriginLLDB: - case eDiagnosticOriginGo: case eDiagnosticOriginLLVM: return true; case eDiagnosticOriginClang: @@ -89,7 +88,7 @@ protected: uint32_t m_compiler_id; // Compiler-specific diagnostic ID }; -typedef std::vector<Diagnostic *> DiagnosticList; +typedef std::vector<std::unique_ptr<Diagnostic>> DiagnosticList; class DiagnosticManager { public: @@ -98,45 +97,33 @@ public: m_fixed_expression.clear(); } - // The diagnostic manager holds a list of diagnostics, which are owned by the - // manager. const DiagnosticList &Diagnostics() { return m_diagnostics; } - ~DiagnosticManager() { - for (Diagnostic *diag : m_diagnostics) { - delete diag; - } - } - - bool HasFixIts() { - for (Diagnostic *diag : m_diagnostics) { - if (diag->HasFixIts()) - return true; - } - return false; + bool HasFixIts() const { + return llvm::any_of(m_diagnostics, + [](const std::unique_ptr<Diagnostic> &diag) { + return diag->HasFixIts(); + }); } void AddDiagnostic(llvm::StringRef message, DiagnosticSeverity severity, DiagnosticOrigin origin, uint32_t compiler_id = LLDB_INVALID_COMPILER_ID) { - m_diagnostics.push_back( - new Diagnostic(message, severity, origin, compiler_id)); + m_diagnostics.emplace_back( + std::make_unique<Diagnostic>(message, severity, origin, compiler_id)); } - void AddDiagnostic(Diagnostic *diagnostic) { - m_diagnostics.push_back(diagnostic); + void AddDiagnostic(std::unique_ptr<Diagnostic> diagnostic) { + m_diagnostics.push_back(std::move(diagnostic)); } - void CopyDiagnostics(DiagnosticManager &otherDiagnostics); - size_t Printf(DiagnosticSeverity severity, const char *format, ...) __attribute__((format(printf, 3, 4))); - size_t PutString(DiagnosticSeverity severity, llvm::StringRef str); + void PutString(DiagnosticSeverity severity, llvm::StringRef str); void AppendMessageToDiagnostic(llvm::StringRef str) { - if (!m_diagnostics.empty()) { + if (!m_diagnostics.empty()) m_diagnostics.back()->AppendMessage(str); - } } // Returns a string containing errors in this format: @@ -153,7 +140,6 @@ public: // Moves fixed_expression to the internal storage. void SetFixedExpression(std::string fixed_expression) { m_fixed_expression = std::move(fixed_expression); - fixed_expression.clear(); } protected: diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h index d0d01b5f9b59..e7d39e7ca24a 100644 --- a/include/lldb/Expression/ExpressionSourceCode.h +++ b/include/lldb/Expression/ExpressionSourceCode.h @@ -17,20 +17,27 @@ namespace lldb_private { class ExpressionSourceCode { +protected: + enum Wrapping : bool { + Wrap = true, + NoWrap = false, + }; + public: - bool NeedsWrapping() const { return m_wrap; } + bool NeedsWrapping() const { return m_wrap == Wrap; } const char *GetName() const { return m_name.c_str(); } protected: - ExpressionSourceCode(const char *name, const char *prefix, const char *body, - bool wrap) - : m_name(name), m_prefix(prefix), m_body(body), m_wrap(wrap) {} + ExpressionSourceCode(llvm::StringRef name, llvm::StringRef prefix, + llvm::StringRef body, Wrapping wrap) + : m_name(name.str()), m_prefix(prefix.str()), m_body(body.str()), + m_wrap(wrap) {} std::string m_name; std::string m_prefix; std::string m_body; - bool m_wrap; + Wrapping m_wrap; }; } // namespace lldb_private diff --git a/include/lldb/Expression/LLVMUserExpression.h b/include/lldb/Expression/LLVMUserExpression.h index c2af7239951b..c3b8ed506f17 100644 --- a/include/lldb/Expression/LLVMUserExpression.h +++ b/include/lldb/Expression/LLVMUserExpression.h @@ -103,22 +103,6 @@ protected: /// when running the /// expression. lldb::ModuleWP m_jit_module_wp; - bool m_enforce_valid_object; ///< True if the expression parser should enforce - ///the presence of a valid class pointer - /// in order to generate the expression as a method. - bool m_in_cplusplus_method; ///< True if the expression is compiled as a C++ - ///member function (true if it was parsed - /// when exe_ctx was in a C++ method). - bool m_in_objectivec_method; ///< True if the expression is compiled as an - ///Objective-C method (true if it was parsed - /// when exe_ctx was in an Objective-C method). - bool m_in_static_method; ///< True if the expression is compiled as a static - ///(or class) method (currently true if it - /// was parsed when exe_ctx was in an Objective-C class method). - bool m_needs_object_ptr; ///< True if "this" or "self" must be looked up and - ///passed in. False if the expression - /// doesn't really use them and they can be NULL. - bool m_const_object; ///< True if "this" is const. Target *m_target; ///< The target for storing persistent data like types and ///variables. diff --git a/include/lldb/Expression/Materializer.h b/include/lldb/Expression/Materializer.h index 603b4e0066cd..70f622e7850b 100644 --- a/include/lldb/Expression/Materializer.h +++ b/include/lldb/Expression/Materializer.h @@ -115,8 +115,6 @@ public: void SetOffset(uint32_t offset) { m_offset = offset; } protected: - void SetSizeAndAlignmentFromType(CompilerType &type); - uint32_t m_alignment; uint32_t m_size; uint32_t m_offset; diff --git a/include/lldb/Expression/REPL.h b/include/lldb/Expression/REPL.h index 850d2f6f961a..d34a792f58f1 100644 --- a/include/lldb/Expression/REPL.h +++ b/include/lldb/Expression/REPL.h @@ -103,10 +103,8 @@ public: void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override; - int IOHandlerComplete(IOHandler &io_handler, const char *current_line, - const char *cursor, const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, StringList &descriptions) override; + void IOHandlerComplete(IOHandler &io_handler, + CompletionRequest &request) override; protected: static int CalculateActualIndentation(const StringList &lines); diff --git a/include/lldb/Host/Config.h.cmake b/include/lldb/Host/Config.h.cmake index b8fb9e9de868..662c07668d14 100644 --- a/include/lldb/Host/Config.h.cmake +++ b/include/lldb/Host/Config.h.cmake @@ -19,6 +19,8 @@ #define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" +#cmakedefine01 HAVE_SYS_TYPES_H + #cmakedefine01 HAVE_SYS_EVENT_H #cmakedefine01 HAVE_PPOLL @@ -33,4 +35,6 @@ #cmakedefine HAVE_LIBCOMPRESSION #endif +#cmakedefine01 LLDB_ENABLE_LZMA + #endif // #ifndef LLDB_HOST_CONFIG_H diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h index a942ede05ce5..65bf15531bc4 100644 --- a/include/lldb/Host/Editline.h +++ b/include/lldb/Host/Editline.h @@ -53,6 +53,7 @@ #include <vector> #include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Predicate.h" @@ -97,11 +98,7 @@ typedef int (*FixIndentationCallbackType)(Editline *editline, const StringList &lines, int cursor_position, void *baton); -typedef int (*CompleteCallbackType)(const char *current_line, - const char *cursor, const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, - StringList &descriptions, void *baton); +typedef void (*CompleteCallbackType)(CompletionRequest &request, void *baton); /// Status used to decide when and how to start editing another line in /// multi-line sessions diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h index eb28c4ada0e7..0102beb141ee 100644 --- a/include/lldb/Host/File.h +++ b/include/lldb/Host/File.h @@ -13,6 +13,7 @@ #include "lldb/Utility/IOObject.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" +#include "llvm/ADT/BitmaskEnum.h" #include <mutex> #include <stdarg.h> @@ -21,11 +22,15 @@ namespace lldb_private { +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + /// \class File File.h "lldb/Host/File.h" -/// A file class. +/// An abstract base class for files. /// -/// A file class that divides abstracts the LLDB core from host file -/// functionality. +/// Files will often be NativeFiles, which provides a wrapper +/// around host OS file functionality. But it +/// is also possible to subclass file to provide objects that have file +/// or stream functionality but are not backed by any host OS file. class File : public IOObject { public: static int kInvalidDescriptor; @@ -33,7 +38,12 @@ public: // NB this enum is used in the lldb platform gdb-remote packet // vFile:open: and existing values cannot be modified. - enum OpenOptions { + // + // FIXME + // These values do not match the values used by GDB + // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags + // * rdar://problem/46788934 + enum OpenOptions : uint32_t { eOpenOptionRead = (1u << 0), // Open file for reading eOpenOptionWrite = (1u << 1), // Open file for writing eOpenOptionAppend = @@ -45,128 +55,105 @@ public: (1u << 6), // Can create file only if it doesn't already exist eOpenOptionDontFollowSymlinks = (1u << 7), eOpenOptionCloseOnExec = - (1u << 8) // Close the file when executing a new process + (1u << 8), // Close the file when executing a new process + LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec) }; - static mode_t ConvertOpenOptionsForPOSIXOpen(uint32_t open_options); + static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options); + static llvm::Expected<OpenOptions> GetOptionsFromMode(llvm::StringRef mode); + static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; }; + static llvm::Expected<const char *> + GetStreamOpenModeFromOptions(OpenOptions options); File() - : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), - m_stream(kInvalidStream), m_options(0), m_own_stream(false), - m_is_interactive(eLazyBoolCalculate), + : IOObject(eFDTypeFile), m_is_interactive(eLazyBoolCalculate), m_is_real_terminal(eLazyBoolCalculate), - m_supports_colors(eLazyBoolCalculate) {} - - File(FILE *fh, bool transfer_ownership) - : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), - m_stream(fh), m_options(0), m_own_stream(transfer_ownership), - m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate), - m_supports_colors(eLazyBoolCalculate) {} - - File(int fd, bool transfer_ownership) - : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd), - m_stream(kInvalidStream), m_options(0), m_own_stream(false), - m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate) {} + m_supports_colors(eLazyBoolCalculate){}; - /// Destructor. + /// Read bytes from a file from the current file position into buf. /// - /// The destructor is virtual in case this class is subclassed. - ~File() override; - - bool IsValid() const override { - return DescriptorIsValid() || StreamIsValid(); - } - - /// Convert to pointer operator. + /// NOTE: This function is NOT thread safe. Use the read function + /// that takes an "off_t &offset" to ensure correct operation in multi- + /// threaded environments. /// - /// This allows code to check a File object to see if it contains anything - /// valid using code such as: + /// \param[out] buf /// - /// \code - /// File file(...); - /// if (file) - /// { ... - /// \endcode + /// \param[in,out] num_bytes. + /// Pass in the size of buf. Read will pass out the number + /// of bytes read. Zero bytes read with no error indicates + /// EOF. /// /// \return - /// A pointer to this object if either the directory or filename - /// is valid, nullptr otherwise. - operator bool() const { return DescriptorIsValid() || StreamIsValid(); } + /// success, ENOTSUP, or another error. + Status Read(void *buf, size_t &num_bytes) override; - /// Logical NOT operator. + /// Write bytes from buf to a file at the current file position. /// - /// This allows code to check a File object to see if it is invalid using - /// code such as: + /// NOTE: This function is NOT thread safe. Use the write function + /// that takes an "off_t &offset" to ensure correct operation in multi- + /// threaded environments. + /// + /// \param[in] buf /// - /// \code - /// File file(...); - /// if (!file) - /// { ... - /// \endcode + /// \param[in,out] num_bytes + /// Pass in the size of buf. Write will pass out the number + /// of bytes written. Write will attempt write the full number + /// of bytes and will not return early except on error. /// /// \return - /// Returns \b true if the object has an empty directory and - /// filename, \b false otherwise. - bool operator!() const { return !DescriptorIsValid() && !StreamIsValid(); } + /// success, ENOTSUP, or another error. + Status Write(const void *buf, size_t &num_bytes) override; - /// Get the file spec for this file. + /// IsValid /// /// \return - /// A reference to the file specification object. - Status GetFileSpec(FileSpec &file_spec) const; + /// true iff the file is valid. + bool IsValid() const override; + /// Flush any buffers and release any resources owned by the file. + /// After Close() the file will be invalid. + /// + /// \return + /// success or an error. Status Close() override; - void Clear(); - - int GetDescriptor() const; - + /// Get a handle that can be used for OS polling interfaces, such + /// as WaitForMultipleObjects, select, or epoll. This may return + /// IOObject::kInvalidHandleValue if none is available. This will + /// generally be the same as the file descriptor, this function + /// is not interchangeable with GetDescriptor(). A WaitableHandle + /// must only be used for polling, not actual I/O. + /// + /// \return + /// a valid handle or IOObject::kInvalidHandleValue WaitableHandle GetWaitableHandle() override; - void SetDescriptor(int fd, bool transfer_ownership); - - FILE *GetStream(); - - void SetStream(FILE *fh, bool transfer_ownership); - - /// Read bytes from a file from the current file position. - /// - /// NOTE: This function is NOT thread safe. Use the read function - /// that takes an "off_t &offset" to ensure correct operation in multi- - /// threaded environments. - /// - /// \param[in] buf - /// A buffer where to put the bytes that are read. - /// - /// \param[in,out] num_bytes - /// The number of bytes to read form the current file position - /// which gets modified with the number of bytes that were read. + /// Get the file specification for this file, if possible. /// + /// \param[out] file_spec + /// the file specification. /// \return - /// An error object that indicates success or the reason for - /// failure. - Status Read(void *buf, size_t &num_bytes) override; + /// ENOTSUP, success, or another error. + virtual Status GetFileSpec(FileSpec &file_spec) const; - /// Write bytes to a file at the current file position. - /// - /// NOTE: This function is NOT thread safe. Use the write function - /// that takes an "off_t &offset" to ensure correct operation in multi- - /// threaded environments. + /// Get underlying OS file descriptor for this file, or kInvalidDescriptor. + /// If the descriptor is valid, then it may be used directly for I/O + /// However, the File may also perform it's own buffering, so avoid using + /// this if it is not necessary, or use Flush() appropriately. /// - /// \param[in] buf - /// A buffer where to put the bytes that are read. + /// \return + /// a valid file descriptor for this file or kInvalidDescriptor + virtual int GetDescriptor() const; + + /// Get the underlying libc stream for this file, or NULL. /// - /// \param[in,out] num_bytes - /// The number of bytes to write to the current file position - /// which gets modified with the number of bytes that were - /// written. + /// Not all valid files will have a FILE* stream. This should only be + /// used if absolutely necessary, such as to interact with 3rd party + /// libraries that need FILE* streams. /// /// \return - /// An error object that indicates success or the reason for - /// failure. - Status Write(const void *buf, size_t &num_bytes) override; + /// a valid stream or NULL; + virtual FILE *GetStream(); /// Seek to an offset relative to the beginning of the file. /// @@ -186,7 +173,7 @@ public: /// /// \return /// The resulting seek offset, or -1 on error. - off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr); + virtual off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr); /// Seek to an offset relative to the current file position. /// @@ -206,7 +193,7 @@ public: /// /// \return /// The resulting seek offset, or -1 on error. - off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr); + virtual off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr); /// Seek to an offset relative to the end of the file. /// @@ -227,7 +214,7 @@ public: /// /// \return /// The resulting seek offset, or -1 on error. - off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr); + virtual off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr); /// Read bytes from a file from the specified file offset. /// @@ -250,37 +237,7 @@ public: /// \return /// An error object that indicates success or the reason for /// failure. - Status Read(void *dst, size_t &num_bytes, off_t &offset); - - /// Read bytes from a file from the specified file offset. - /// - /// NOTE: This function is thread safe in that clients manager their - /// own file position markers and reads on other threads won't mess up the - /// current read. - /// - /// \param[in,out] num_bytes - /// The number of bytes to read form the current file position - /// which gets modified with the number of bytes that were read. - /// - /// \param[in,out] offset - /// The offset within the file from which to read \a num_bytes - /// bytes. This offset gets incremented by the number of bytes - /// that were read. - /// - /// \param[in] null_terminate - /// Ensure that the data that is read is terminated with a NULL - /// character so that the data can be used as a C string. - /// - /// \param[out] data_buffer_sp - /// A data buffer to create and fill in that will contain any - /// data that is read from the file. This buffer will be reset - /// if an error occurs. - /// - /// \return - /// An error object that indicates success or the reason for - /// failure. - Status Read(size_t &num_bytes, off_t &offset, bool null_terminate, - lldb::DataBufferSP &data_buffer_sp); + virtual Status Read(void *dst, size_t &num_bytes, off_t &offset); /// Write bytes to a file at the specified file offset. /// @@ -305,21 +262,67 @@ public: /// \return /// An error object that indicates success or the reason for /// failure. - Status Write(const void *src, size_t &num_bytes, off_t &offset); + virtual Status Write(const void *src, size_t &num_bytes, off_t &offset); /// Flush the current stream /// /// \return /// An error object that indicates success or the reason for /// failure. - Status Flush(); + virtual Status Flush(); /// Sync to disk. /// /// \return /// An error object that indicates success or the reason for /// failure. - Status Sync(); + virtual Status Sync(); + + /// Output printf formatted output to the stream. + /// + /// NOTE: this is not virtual, because it just calls the va_list + /// version of the function. + /// + /// Print some formatted output to the stream. + /// + /// \param[in] format + /// A printf style format string. + /// + /// \param[in] ... + /// Variable arguments that are needed for the printf style + /// format string \a format. + size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); + + /// Output printf formatted output to the stream. + /// + /// Print some formatted output to the stream. + /// + /// \param[in] format + /// A printf style format string. + /// + /// \param[in] args + /// Variable arguments that are needed for the printf style + /// format string \a format. + virtual size_t PrintfVarArg(const char *format, va_list args); + + /// Return the OpenOptions for this file. + /// + /// Some options like eOpenOptionDontFollowSymlinks only make + /// sense when a file is being opened (or not at all) + /// and may not be preserved for this method. But any valid + /// File should return either or both of eOpenOptionRead and + /// eOpenOptionWrite here. + /// + /// \return + /// OpenOptions flags for this file, or an error. + virtual llvm::Expected<OpenOptions> GetOptions() const; + + llvm::Expected<const char *> GetOpenMode() const { + auto opts = GetOptions(); + if (!opts) + return opts.takeError(); + return GetStreamOpenModeFromOptions(opts.get()); + } /// Get the permissions for a this file. /// @@ -346,45 +349,90 @@ public: /// a non-zero width and height, false otherwise. bool GetIsRealTerminal(); - bool GetIsTerminalWithColors(); - - /// Output printf formatted output to the stream. - /// - /// Print some formatted output to the stream. + /// Return true if this file is a terminal which supports colors. /// - /// \param[in] format - /// A printf style format string. - /// - /// \param[in] ... - /// Variable arguments that are needed for the printf style - /// format string \a format. - size_t Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); + /// \return + /// True iff this is a terminal and it supports colors. + bool GetIsTerminalWithColors(); - size_t PrintfVarArg(const char *format, va_list args); + operator bool() const { return IsValid(); }; - void SetOptions(uint32_t options) { m_options = options; } + bool operator!() const { return !IsValid(); }; - static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; }; + static char ID; + virtual bool isA(const void *classID) const { return classID == &ID; } + static bool classof(const File *file) { return file->isA(&ID); } protected: - bool DescriptorIsValid() const { return DescriptorIsValid(m_descriptor); } - - bool StreamIsValid() const { return m_stream != kInvalidStream; } + LazyBool m_is_interactive; + LazyBool m_is_real_terminal; + LazyBool m_supports_colors; void CalculateInteractiveAndTerminal(); +private: + DISALLOW_COPY_AND_ASSIGN(File); +}; + +class NativeFile : public File { +public: + NativeFile() + : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), + m_stream(kInvalidStream), m_options(), m_own_stream(false) {} + + NativeFile(FILE *fh, bool transfer_ownership) + : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh), + m_options(), m_own_stream(transfer_ownership) {} + + NativeFile(int fd, OpenOptions options, bool transfer_ownership) + : m_descriptor(fd), m_own_descriptor(transfer_ownership), + m_stream(kInvalidStream), m_options(options), m_own_stream(false) {} + + ~NativeFile() override { Close(); } + + bool IsValid() const override { + return DescriptorIsValid() || StreamIsValid(); + } + + Status Read(void *buf, size_t &num_bytes) override; + Status Write(const void *buf, size_t &num_bytes) override; + Status Close() override; + WaitableHandle GetWaitableHandle() override; + Status GetFileSpec(FileSpec &file_spec) const override; + int GetDescriptor() const override; + FILE *GetStream() override; + off_t SeekFromStart(off_t offset, Status *error_ptr = nullptr) override; + off_t SeekFromCurrent(off_t offset, Status *error_ptr = nullptr) override; + off_t SeekFromEnd(off_t offset, Status *error_ptr = nullptr) override; + Status Read(void *dst, size_t &num_bytes, off_t &offset) override; + Status Write(const void *src, size_t &num_bytes, off_t &offset) override; + Status Flush() override; + Status Sync() override; + size_t PrintfVarArg(const char *format, va_list args) override; + llvm::Expected<OpenOptions> GetOptions() const override; + + static char ID; + virtual bool isA(const void *classID) const override { + return classID == &ID || File::isA(classID); + } + static bool classof(const File *file) { return file->isA(&ID); } + +protected: + bool DescriptorIsValid() const { + return File::DescriptorIsValid(m_descriptor); + } + bool StreamIsValid() const { return m_stream != kInvalidStream; } + // Member variables int m_descriptor; + bool m_own_descriptor; FILE *m_stream; - uint32_t m_options; + OpenOptions m_options; bool m_own_stream; - LazyBool m_is_interactive; - LazyBool m_is_real_terminal; - LazyBool m_supports_colors; std::mutex offset_access_mutex; private: - DISALLOW_COPY_AND_ASSIGN(File); + DISALLOW_COPY_AND_ASSIGN(NativeFile); }; } // namespace lldb_private diff --git a/include/lldb/Host/FileCache.h b/include/lldb/Host/FileCache.h index 0c1ef1961645..c76916701ebb 100644 --- a/include/lldb/Host/FileCache.h +++ b/include/lldb/Host/FileCache.h @@ -14,6 +14,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" +#include "lldb/Host/File.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" @@ -22,12 +23,12 @@ class FileCache { private: FileCache() {} - typedef std::map<lldb::user_id_t, lldb::FileSP> FDToFileMap; + typedef std::map<lldb::user_id_t, lldb::FileUP> FDToFileMap; public: static FileCache &GetInstance(); - lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, + lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error); bool CloseFile(lldb::user_id_t fd, Status &error); diff --git a/include/lldb/Host/FileSystem.h b/include/lldb/Host/FileSystem.h index 865b09b23103..528c43519a32 100644 --- a/include/lldb/Host/FileSystem.h +++ b/include/lldb/Host/FileSystem.h @@ -11,12 +11,12 @@ #include "lldb/Host/File.h" #include "lldb/Utility/DataBufferLLVM.h" -#include "lldb/Utility/FileCollector.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Chrono.h" +#include "llvm/Support/FileCollector.h" #include "llvm/Support/VirtualFileSystem.h" #include "lldb/lldb-types.h" @@ -34,8 +34,8 @@ public: FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr), m_mapped(false) {} - FileSystem(FileCollector &collector) - : m_fs(llvm::vfs::getRealFileSystem()), m_collector(&collector), + FileSystem(std::shared_ptr<llvm::FileCollector> collector) + : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector), m_mapped(false) {} FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, bool mapped = false) @@ -47,7 +47,7 @@ public: static FileSystem &Instance(); static void Initialize(); - static void Initialize(FileCollector &collector); + static void Initialize(std::shared_ptr<llvm::FileCollector> collector); static llvm::Error Initialize(const FileSpec &mapping); static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs); static void Terminate(); @@ -63,9 +63,10 @@ public: /// Wraps ::open in a platform-independent way. int Open(const char *path, int flags, int mode); - Status Open(File &File, const FileSpec &file_spec, uint32_t options, - uint32_t permissions = lldb::eFilePermissionsFileDefault, - bool should_close_fd = true); + llvm::Expected<std::unique_ptr<File>> + Open(const FileSpec &file_spec, File::OpenOptions options, + uint32_t permissions = lldb::eFilePermissionsFileDefault, + bool should_close_fd = true); /// Get a directory iterator. /// \{ @@ -188,7 +189,7 @@ public: private: static llvm::Optional<FileSystem> &InstanceImpl(); llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; - FileCollector *m_collector; + std::shared_ptr<llvm::FileCollector> m_collector; bool m_mapped; }; } // namespace lldb_private diff --git a/include/lldb/Host/LZMA.h b/include/lldb/Host/LZMA.h new file mode 100644 index 000000000000..c741cc3bbde1 --- /dev/null +++ b/include/lldb/Host/LZMA.h @@ -0,0 +1,34 @@ +//===-- LZMA.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_Host_LZMA_h_ +#define liblldb_Host_LZMA_h_ + +#include "llvm/ADT/ArrayRef.h" + +namespace llvm { +class Error; +} // End of namespace llvm + +namespace lldb_private { + +namespace lzma { + +bool isAvailable(); + +llvm::Expected<uint64_t> +getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer); + +llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer, + llvm::SmallVectorImpl<uint8_t> &Uncompressed); + +} // End of namespace lzma + +} // End of namespace lldb_private + +#endif // liblldb_Host_LZMA_h_ diff --git a/include/lldb/Host/Socket.h b/include/lldb/Host/Socket.h index 6f96bd73e753..c6df5634e24e 100644 --- a/include/lldb/Host/Socket.h +++ b/include/lldb/Host/Socket.h @@ -31,7 +31,7 @@ class StringRef; namespace lldb_private { -#if defined(_MSC_VER) +#if defined(_WIN32) typedef SOCKET NativeSocket; #else typedef int NativeSocket; @@ -122,6 +122,7 @@ protected: SocketProtocol m_protocol; NativeSocket m_socket; bool m_child_processes_inherit; + bool m_should_close_fd; }; } // namespace lldb_private diff --git a/include/lldb/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h index f05b8d01a1c9..2d48717c4fbb 100644 --- a/include/lldb/Host/common/NativeProcessProtocol.h +++ b/include/lldb/Host/common/NativeProcessProtocol.h @@ -32,6 +32,14 @@ namespace lldb_private { class MemoryRegionInfo; class ResumeActionList; +struct SVR4LibraryInfo { + std::string name; + lldb::addr_t link_map; + lldb::addr_t base_addr; + lldb::addr_t ld_addr; + lldb::addr_t next; +}; + // NativeProcessProtocol class NativeProcessProtocol { public: @@ -76,6 +84,31 @@ public: Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read); + /// Reads a null terminated string from memory. + /// + /// Reads up to \p max_size bytes of memory until it finds a '\0'. + /// If a '\0' is not found then it reads max_size-1 bytes as a string and a + /// '\0' is added as the last character of the \p buffer. + /// + /// \param[in] addr + /// The address in memory to read from. + /// + /// \param[in] buffer + /// An allocated buffer with at least \p max_size size. + /// + /// \param[in] max_size + /// The maximum number of bytes to read from memory until it reads the + /// string. + /// + /// \param[out] total_bytes_read + /// The number of bytes read from memory into \p buffer. + /// + /// \return + /// Returns a StringRef backed up by the \p buffer passed in. + llvm::Expected<llvm::StringRef> + ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size, + size_t &total_bytes_read); + virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) = 0; @@ -86,6 +119,12 @@ public: virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0; + virtual llvm::Expected<std::vector<SVR4LibraryInfo>> + GetLoadedSVR4Libraries() { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Not implemented"); + } + virtual bool IsAlive() const; virtual size_t UpdateThreads() = 0; @@ -391,6 +430,8 @@ protected: NativeProcessProtocol(lldb::pid_t pid, int terminal_fd, NativeDelegate &delegate); + void SetID(lldb::pid_t pid) { m_pid = pid; } + // interface for state handling void SetState(lldb::StateType state, bool notify_delegates = true); diff --git a/include/lldb/Interpreter/CommandAlias.h b/include/lldb/Interpreter/CommandAlias.h index c2a7a383f35a..1e186d77f8e6 100644 --- a/include/lldb/Interpreter/CommandAlias.h +++ b/include/lldb/Interpreter/CommandAlias.h @@ -36,11 +36,11 @@ public: bool WantsCompletion() override; - int HandleCompletion(CompletionRequest &request) override; + void HandleCompletion(CompletionRequest &request) override; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override; Options *GetOptions() override; diff --git a/include/lldb/Interpreter/CommandCompletions.h b/include/lldb/Interpreter/CommandCompletions.h index 3d09db5ce5e7..275cc7e7c145 100644 --- a/include/lldb/Interpreter/CommandCompletions.h +++ b/include/lldb/Interpreter/CommandCompletions.h @@ -26,10 +26,10 @@ public: // This is the command completion callback that is used to complete the // argument of the option it is bound to (in the OptionDefinition table // below). Return the total number of matches. - typedef int (*CompletionCallback)(CommandInterpreter &interpreter, - CompletionRequest &request, - // A search filter to limit the search... - lldb_private::SearchFilter *searcher); + typedef void (*CompletionCallback)(CommandInterpreter &interpreter, + CompletionRequest &request, + // A search filter to limit the search... + lldb_private::SearchFilter *searcher); enum CommonCompletionTypes { eNoCompletion = 0u, eSourceFileCompletion = (1u << 0), @@ -57,42 +57,42 @@ public: lldb_private::CompletionRequest &request, SearchFilter *searcher); // These are the generic completer functions: - static int DiskFiles(CommandInterpreter &interpreter, - CompletionRequest &request, SearchFilter *searcher); + static void DiskFiles(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); - static int DiskFiles(const llvm::Twine &partial_file_name, - StringList &matches, TildeExpressionResolver &Resolver); + static void DiskFiles(const llvm::Twine &partial_file_name, + StringList &matches, TildeExpressionResolver &Resolver); - static int DiskDirectories(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher); + static void DiskDirectories(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); - static int DiskDirectories(const llvm::Twine &partial_file_name, - StringList &matches, - TildeExpressionResolver &Resolver); + static void DiskDirectories(const llvm::Twine &partial_file_name, + StringList &matches, + TildeExpressionResolver &Resolver); - static int SourceFiles(CommandInterpreter &interpreter, - CompletionRequest &request, SearchFilter *searcher); + static void SourceFiles(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); - static int Modules(CommandInterpreter &interpreter, - CompletionRequest &request, SearchFilter *searcher); + static void Modules(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); - static int Symbols(CommandInterpreter &interpreter, - CompletionRequest &request, SearchFilter *searcher); + static void Symbols(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); - static int SettingsNames(CommandInterpreter &interpreter, - CompletionRequest &request, SearchFilter *searcher); + static void SettingsNames(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); - static int PlatformPluginNames(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher); + static void PlatformPluginNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); - static int ArchitectureNames(CommandInterpreter &interpreter, - CompletionRequest &request, - SearchFilter *searcher); + static void ArchitectureNames(CommandInterpreter &interpreter, + CompletionRequest &request, + SearchFilter *searcher); - static int VariablePath(CommandInterpreter &interpreter, - CompletionRequest &request, SearchFilter *searcher); + static void VariablePath(CommandInterpreter &interpreter, + CompletionRequest &request, SearchFilter *searcher); // The Completer class is a convenient base class for building searchers that // go along with the SearchFilter passed to the standard Completer functions. @@ -103,11 +103,11 @@ public: ~Completer() override; CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, - Address *addr, bool complete) override = 0; + Address *addr) override = 0; lldb::SearchDepth GetDepth() override = 0; - virtual size_t DoCompletion(SearchFilter *filter) = 0; + virtual void DoCompletion(SearchFilter *filter) = 0; protected: CommandInterpreter &m_interpreter; @@ -127,10 +127,9 @@ public: Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, - Address *addr, - bool complete) override; + Address *addr) override; - size_t DoCompletion(SearchFilter *filter) override; + void DoCompletion(SearchFilter *filter) override; private: bool m_include_support_files; @@ -151,10 +150,9 @@ public: Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, - Address *addr, - bool complete) override; + Address *addr) override; - size_t DoCompletion(SearchFilter *filter) override; + void DoCompletion(SearchFilter *filter) override; private: const char *m_file_name; @@ -173,20 +171,11 @@ public: Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, - Address *addr, - bool complete) override; + Address *addr) override; - size_t DoCompletion(SearchFilter *filter) override; + void DoCompletion(SearchFilter *filter) override; private: - // struct NameCmp { - // bool operator() (const ConstString& lhs, const ConstString& - // rhs) const - // { - // return lhs < rhs; - // } - // }; - RegularExpression m_regex; typedef std::set<ConstString> collection; collection m_match_set; diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h index c3dd6606e0db..3b98b2a521dd 100644 --- a/include/lldb/Interpreter/CommandInterpreter.h +++ b/include/lldb/Interpreter/CommandInterpreter.h @@ -308,31 +308,12 @@ public: CommandObject *GetCommandObjectForCommand(llvm::StringRef &command_line); - // This handles command line completion. You are given a pointer to the - // command string buffer, to the current cursor, and to the end of the string - // (in case it is not NULL terminated). You also passed in an StringList - // object to fill with the returns. The first element of the array will be - // filled with the string that you would need to insert at the cursor point - // to complete the cursor point to the longest common matching prefix. If you - // want to limit the number of elements returned, set max_return_elements to - // the number of elements you want returned. Otherwise set - // max_return_elements to -1. If you want to start some way into the match - // list, then set match_start_point to the desired start point. Returns: -1 - // if the completion character should be inserted -2 if the entire command - // line should be deleted and replaced with matches.GetStringAtIndex(0) - // INT_MAX if the number of matches is > max_return_elements, but it is - // expensive to compute. Otherwise, returns the number of matches. - // - // FIXME: Only max_return_elements == -1 is supported at present. - int HandleCompletion(const char *current_line, const char *cursor, - const char *last_char, int match_start_point, - int max_return_elements, StringList &matches, - StringList &descriptions); - - // This version just returns matches, and doesn't compute the substring. It - // is here so the Help command can call it for the first argument. It uses - // a CompletionRequest for simplicity reasons. - int HandleCompletionMatches(CompletionRequest &request); + // This handles command line completion. + void HandleCompletion(CompletionRequest &request); + + // This version just returns matches, and doesn't compute the substring. It + // is here so the Help command can call it for the first argument. + void HandleCompletionMatches(CompletionRequest &request); int GetCommandNamesMatchingPartialString(const char *cmd_cstr, bool include_aliases, @@ -519,7 +500,9 @@ protected: bool IOHandlerInterrupt(IOHandler &io_handler) override; - size_t GetProcessOutput(); + void GetProcessOutput(); + + bool DidProcessStopAbnormally() const; void SetSynchronous(bool value); diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h index 31f7f126a9fe..2dad84f036c0 100644 --- a/include/lldb/Interpreter/CommandObject.h +++ b/include/lldb/Interpreter/CommandObject.h @@ -228,36 +228,18 @@ public: /// /// \param[in/out] request /// The completion request that needs to be answered. - /// - /// FIXME: This is the wrong return value, since we also need to make a - /// distinction between - /// total number of matches, and the window the user wants returned. - /// - /// \return - /// \btrue if we were in an option, \bfalse otherwise. - virtual int HandleCompletion(CompletionRequest &request); + virtual void HandleCompletion(CompletionRequest &request); - /// The input array contains a parsed version of the line. The insertion - /// point is given by cursor_index (the index in input of the word containing - /// the cursor) and cursor_char_position (the position of the cursor in that - /// word.) + /// The input array contains a parsed version of the line. + /// /// We've constructed the map of options and their arguments as well if that /// is helpful for the completion. /// /// \param[in/out] request /// The completion request that needs to be answered. - /// - /// FIXME: This is the wrong return value, since we also need to make a - /// distinction between - /// total number of matches, and the window the user wants returned. - /// - /// \return - /// The number of completions. - virtual int + virtual void HandleArgumentCompletion(CompletionRequest &request, - OptionElementVector &opt_element_vector) { - return 0; - } + OptionElementVector &opt_element_vector) {} bool HelpTextContainsWord(llvm::StringRef search_word, bool search_short_help = true, @@ -348,8 +330,9 @@ protected: // This is for use in the command interpreter, when you either want the // selected target, or if no target is present you want to prime the dummy // target with entities that will be copied over to new targets. - Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); - Target *GetDummyTarget(); + Target &GetSelectedOrDummyTarget(bool prefer_dummy = false); + Target &GetSelectedTarget(); + Target &GetDummyTarget(); // If a command needs to use the "current" thread, use this call. Command // objects will have an ExecutionContext to use, and that may or may not have diff --git a/include/lldb/Interpreter/CommandObjectMultiword.h b/include/lldb/Interpreter/CommandObjectMultiword.h index 660e9d49d977..72ec8a9c5ca9 100644 --- a/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/include/lldb/Interpreter/CommandObjectMultiword.h @@ -50,7 +50,7 @@ public: bool WantsRawCommandString() override { return false; } - int HandleCompletion(CompletionRequest &request) override; + void HandleCompletion(CompletionRequest &request) override; const char *GetRepeatCommand(Args ¤t_command_args, uint32_t index) override; @@ -112,11 +112,11 @@ public: Options *GetOptions() override; - int HandleCompletion(CompletionRequest &request) override; + void HandleCompletion(CompletionRequest &request) override; - int HandleArgumentCompletion( - CompletionRequest &request, - OptionElementVector &opt_element_vector) override; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override; const char *GetRepeatCommand(Args ¤t_command_args, uint32_t index) override; diff --git a/include/lldb/Interpreter/CommandObjectRegexCommand.h b/include/lldb/Interpreter/CommandObjectRegexCommand.h index 7f06e269d64f..7800d5de1b38 100644 --- a/include/lldb/Interpreter/CommandObjectRegexCommand.h +++ b/include/lldb/Interpreter/CommandObjectRegexCommand.h @@ -34,7 +34,7 @@ public: bool HasRegexEntries() const { return !m_entries.empty(); } - int HandleCompletion(CompletionRequest &request) override; + void HandleCompletion(CompletionRequest &request) override; protected: bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; diff --git a/include/lldb/Interpreter/CommandReturnObject.h b/include/lldb/Interpreter/CommandReturnObject.h index a5f61261455e..61e57fb798a1 100644 --- a/include/lldb/Interpreter/CommandReturnObject.h +++ b/include/lldb/Interpreter/CommandReturnObject.h @@ -62,13 +62,13 @@ public: return m_err_stream; } - void SetImmediateOutputFile(FILE *fh, bool transfer_fh_ownership = false) { - lldb::StreamSP stream_sp(new StreamFile(fh, transfer_fh_ownership)); + void SetImmediateOutputFile(lldb::FileSP file_sp) { + lldb::StreamSP stream_sp(new StreamFile(file_sp)); m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } - void SetImmediateErrorFile(FILE *fh, bool transfer_fh_ownership = false) { - lldb::StreamSP stream_sp(new StreamFile(fh, transfer_fh_ownership)); + void SetImmediateErrorFile(lldb::FileSP file_sp) { + lldb::StreamSP stream_sp(new StreamFile(file_sp)); m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp); } @@ -144,14 +144,6 @@ public: void SetInteractive(bool b); - bool GetAbnormalStopWasExpected() const { - return m_abnormal_stop_was_expected; - } - - void SetAbnormalStopWasExpected(bool signal_was_expected) { - m_abnormal_stop_was_expected = signal_was_expected; - } - private: enum { eStreamStringIndex = 0, eImmediateStreamIndex = 1 }; @@ -162,14 +154,6 @@ private: bool m_did_change_process_state; bool m_interactive; // If true, then the input handle from the debugger will // be hooked up - bool m_abnormal_stop_was_expected; // This is to support - // eHandleCommandFlagStopOnCrash vrs. - // attach. - // The attach command often ends up with the process stopped due to a signal. - // Normally that would mean stop on crash should halt batch execution, but we - // obviously don't want that for attach. Using this flag, the attach command - // (and anything else for which this is relevant) can say that the signal is - // expected, and batch command execution can continue. }; } // namespace lldb_private diff --git a/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h b/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h new file mode 100644 index 000000000000..6aec7eb0f0b8 --- /dev/null +++ b/include/lldb/Interpreter/OptionGroupPythonClassWithDict.h @@ -0,0 +1,65 @@ +//===-- OptionGroupPythonClassWithDict.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_OptionGroupPythonClassWithDict_h_ +#define liblldb_OptionGroupPythonClassWithDict_h_ + +#include "lldb/lldb-types.h" +#include "lldb/Interpreter/Options.h" +#include "lldb/Utility/StructuredData.h" + +namespace lldb_private { + +// Use this Option group if you have a python class that implements some +// Python extension point, and you pass a SBStructuredData to the class +// __init__ method. +// class_option specifies the class name +// the key and value options are read in in pairs, and a +// StructuredData::Dictionary is constructed with those pairs. +class OptionGroupPythonClassWithDict : public OptionGroup { +public: + OptionGroupPythonClassWithDict(const char *class_use, + int class_option = 'C', + int key_option = 'k', + int value_option = 'v', + const char *class_long_option = "python-class", + const char *key_long_option = "python-class-key", + const char *value_long_option = "python-class-value", + bool required = false); + + ~OptionGroupPythonClassWithDict() override; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::ArrayRef<OptionDefinition>(m_option_definition); + } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, + ExecutionContext *execution_context) override; + Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; + + void OptionParsingStarting(ExecutionContext *execution_context) override; + Status OptionParsingFinished(ExecutionContext *execution_context) override; + + const StructuredData::DictionarySP GetStructuredData() { + return m_dict_sp; + } + const std::string &GetClassName() { + return m_class_name; + } + +protected: + std::string m_class_name; + std::string m_current_key; + StructuredData::DictionarySP m_dict_sp; + std::string m_class_usage_text, m_key_usage_text, m_value_usage_text; + OptionDefinition m_option_definition[3]; +}; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupPythonClassWithDict_h_ diff --git a/include/lldb/Interpreter/OptionValue.h b/include/lldb/Interpreter/OptionValue.h index 0b85bc19dd2a..9fc18551c26a 100644 --- a/include/lldb/Interpreter/OptionValue.h +++ b/include/lldb/Interpreter/OptionValue.h @@ -93,8 +93,8 @@ public: virtual lldb::OptionValueSP DeepCopy() const = 0; - virtual size_t AutoComplete(CommandInterpreter &interpreter, - CompletionRequest &request); + virtual void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request); // Subclasses can override these functions virtual lldb::OptionValueSP GetSubValue(const ExecutionContext *exe_ctx, diff --git a/include/lldb/Interpreter/OptionValueArch.h b/include/lldb/Interpreter/OptionValueArch.h index f8f406890841..3923e3d3dba4 100644 --- a/include/lldb/Interpreter/OptionValueArch.h +++ b/include/lldb/Interpreter/OptionValueArch.h @@ -55,8 +55,8 @@ public: lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, - lldb_private::CompletionRequest &request) override; + void AutoComplete(CommandInterpreter &interpreter, + lldb_private::CompletionRequest &request) override; // Subclass specific functions diff --git a/include/lldb/Interpreter/OptionValueBoolean.h b/include/lldb/Interpreter/OptionValueBoolean.h index 2fc97d494988..42b2ca4d2845 100644 --- a/include/lldb/Interpreter/OptionValueBoolean.h +++ b/include/lldb/Interpreter/OptionValueBoolean.h @@ -43,8 +43,8 @@ public: return true; } - size_t AutoComplete(CommandInterpreter &interpreter, - CompletionRequest &request) override; + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; // Subclass specific functions diff --git a/include/lldb/Interpreter/OptionValueEnumeration.h b/include/lldb/Interpreter/OptionValueEnumeration.h index 71f3ab53b2ff..eb19737f8653 100644 --- a/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/include/lldb/Interpreter/OptionValueEnumeration.h @@ -55,8 +55,8 @@ public: lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, - CompletionRequest &request) override; + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; // Subclass specific functions diff --git a/include/lldb/Interpreter/OptionValueFileSpec.h b/include/lldb/Interpreter/OptionValueFileSpec.h index aa1022a4fe2c..a6df18149076 100644 --- a/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/include/lldb/Interpreter/OptionValueFileSpec.h @@ -51,8 +51,8 @@ public: lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, - CompletionRequest &request) override; + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; // Subclass specific functions diff --git a/include/lldb/Interpreter/OptionValueFormatEntity.h b/include/lldb/Interpreter/OptionValueFormatEntity.h index b05be959f3d4..419ff5c03e3a 100644 --- a/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -38,8 +38,8 @@ public: lldb::OptionValueSP DeepCopy() const override; - size_t AutoComplete(CommandInterpreter &interpreter, - CompletionRequest &request) override; + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; // Subclass specific functions diff --git a/include/lldb/Interpreter/OptionValueRegex.h b/include/lldb/Interpreter/OptionValueRegex.h index f5b2557634df..8c10dacb0313 100644 --- a/include/lldb/Interpreter/OptionValueRegex.h +++ b/include/lldb/Interpreter/OptionValueRegex.h @@ -36,7 +36,7 @@ public: VarSetOperationType = eVarSetOperationAssign) = delete; bool Clear() override { - m_regex.Clear(); + m_regex = RegularExpression(); m_value_was_set = false; return true; } @@ -50,9 +50,9 @@ public: void SetCurrentValue(const char *value) { if (value && value[0]) - m_regex.Compile(llvm::StringRef(value)); + m_regex = RegularExpression(llvm::StringRef(value)); else - m_regex.Clear(); + m_regex = RegularExpression(); } bool IsValid() const { return m_regex.IsValid(); } diff --git a/include/lldb/Interpreter/OptionValueUUID.h b/include/lldb/Interpreter/OptionValueUUID.h index 7273e35bd75b..576440d80519 100644 --- a/include/lldb/Interpreter/OptionValueUUID.h +++ b/include/lldb/Interpreter/OptionValueUUID.h @@ -52,8 +52,8 @@ public: void SetCurrentValue(const UUID &value) { m_uuid = value; } - size_t AutoComplete(CommandInterpreter &interpreter, - CompletionRequest &request) override; + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; protected: UUID m_uuid; diff --git a/include/lldb/Interpreter/Options.h b/include/lldb/Interpreter/Options.h index a008d51d721e..b6c824d5a199 100644 --- a/include/lldb/Interpreter/Options.h +++ b/include/lldb/Interpreter/Options.h @@ -187,14 +187,7 @@ public: /// /// \param[in] interpreter /// The command interpreter doing the completion. - /// - /// FIXME: This is the wrong return value, since we also need to - /// make a distinction between total number of matches, and the window the - /// user wants returned. - /// - /// \return - /// \btrue if we were in an option, \bfalse otherwise. - virtual bool + virtual void HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request, OptionElementVector &opt_element_vector, int opt_element_index, diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h index c8fa3901350d..23fadf02e591 100644 --- a/include/lldb/Interpreter/ScriptInterpreter.h +++ b/include/lldb/Interpreter/ScriptInterpreter.h @@ -65,6 +65,9 @@ public: bool GetSetLLDBGlobals() const { return m_set_lldb_globals; } + // If this is true then any exceptions raised by the script will be + // cleared with PyErr_Clear(). If false then they will be left for + // the caller to clean up bool GetMaskoutErrors() const { return m_maskout_errors; } ExecuteScriptOptions &SetEnableIO(bool enable) { @@ -208,6 +211,8 @@ public: virtual StructuredData::ObjectSP CreateScriptedThreadPlan(const char *class_name, + StructuredDataImpl *args_data, + std::string &error_str, lldb::ThreadPlanSP thread_plan_sp) { return StructuredData::ObjectSP(); } @@ -463,8 +468,6 @@ public: static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string); - virtual void ResetOutputFileHandle(FILE *new_fh) {} // By default, do nothing. - lldb::ScriptLanguage GetLanguage() { return m_script_lang; } protected: diff --git a/include/lldb/Symbol/CallFrameInfo.h b/include/lldb/Symbol/CallFrameInfo.h new file mode 100644 index 000000000000..765ddb41ab0c --- /dev/null +++ b/include/lldb/Symbol/CallFrameInfo.h @@ -0,0 +1,28 @@ +//===-- CallFrameInfo.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_CallFrameInfo_h_ +#define liblldb_CallFrameInfo_h_ + +#include "lldb/Core/Address.h" + +namespace lldb_private { + +class CallFrameInfo { +public: + virtual ~CallFrameInfo() = default; + + virtual bool GetAddressRange(Address addr, AddressRange &range) = 0; + + virtual bool GetUnwindPlan(const Address &addr, UnwindPlan &unwind_plan) = 0; + virtual bool GetUnwindPlan(const AddressRange &range, UnwindPlan &unwind_plan) = 0; +}; + +} // namespace lldb_private + +#endif // liblldb_CallFrameInfo_h_ diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index d0a834e01f3a..c5d840973ae6 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -26,8 +26,8 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" -#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Core/ClangForward.h" +#include "lldb/Expression/ExpressionVariable.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Utility/ConstString.h" @@ -52,7 +52,14 @@ public: } // Constructors and Destructors - ClangASTContext(const char *triple = nullptr); + explicit ClangASTContext(llvm::StringRef triple = ""); + explicit ClangASTContext(ArchSpec arch); + + /// Constructs a ClangASTContext that uses an existing ASTContext internally. + /// Useful when having an existing ASTContext created by Clang. + /// + /// \param existing_ctxt An existing ASTContext. + explicit ClangASTContext(clang::ASTContext &existing_ctxt); ~ClangASTContext() override; @@ -68,9 +75,8 @@ public: static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module, Target *target); - static void EnumerateSupportedLanguages( - std::set<lldb::LanguageType> &languages_for_types, - std::set<lldb::LanguageType> &languages_for_expressions); + static LanguageSet GetSupportedLanguagesForTypes(); + static LanguageSet GetSupportedLanguagesForExpressions(); static void Initialize(); @@ -80,8 +86,6 @@ public: clang::ASTContext *getASTContext(); - void setASTContext(clang::ASTContext *ast_ctx); - clang::Builtin::Context *getBuiltinContext(); clang::IdentifierTable *getIdentifierTable(); @@ -107,21 +111,11 @@ public: void setSema(clang::Sema *s); clang::Sema *getSema() { return m_sema; } - void Clear(); - const char *GetTargetTriple(); - void SetTargetTriple(const char *target_triple); - - void SetArchitecture(const ArchSpec &arch); - - bool HasExternalSource(); - void SetExternalSource( llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_up); - void RemoveExternalSource(); - bool GetCompleteDecl(clang::Decl *decl) { return ClangASTContext::GetCompleteDecl(getASTContext(), decl); } @@ -229,7 +223,8 @@ public: if (const RecordDeclType *record_decl = llvm::dyn_cast<RecordDeclType>(named_decl)) compiler_type.SetCompilerType( - ast, clang::QualType(record_decl->getTypeForDecl(), 0)); + this, clang::QualType(record_decl->getTypeForDecl(), 0) + .getAsOpaquePtr()); } } } @@ -249,7 +244,7 @@ public: &type_fields, bool packed = false); - static bool IsOperator(const char *name, + static bool IsOperator(llvm::StringRef name, clang::OverloadedOperatorKind &op_kind); // Structure, Unions, Classes @@ -395,7 +390,8 @@ public: clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx, const char *name, const CompilerType ¶m_type, - int storage); + int storage, + bool add_decl=false); void SetFunctionParameters(clang::FunctionDecl *function_decl, clang::ParmVarDecl **params, unsigned num_params); @@ -464,6 +460,8 @@ public: CompilerType DeclGetFunctionArgumentType(void *opaque_decl, size_t arg_idx) override; + CompilerType GetTypeForDecl(void *opaque_decl) override; + // CompilerDeclContext override functions std::vector<CompilerDecl> @@ -605,9 +603,6 @@ public: static bool GetCXXClassName(const CompilerType &type, std::string &class_name); - static bool GetObjCClassName(const CompilerType &type, - std::string &class_name); - // Type Completion bool GetCompleteType(lldb::opaque_compiler_type_t type) override; @@ -691,6 +686,8 @@ public: // Exploring the type + const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override; + llvm::Optional<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) { if (llvm::Optional<uint64_t> bit_size = GetBitSize(type, exe_scope)) @@ -707,7 +704,9 @@ public: lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + llvm::Optional<size_t> + GetTypeBitAlign(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override; uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes, @@ -855,7 +854,6 @@ public: static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type, bool has_extern); - static bool GetHasExternalStorage(const CompilerType &type); // Tag Declarations static bool StartTagDeclarationDefinition(const CompilerType &type); @@ -878,12 +876,6 @@ public: static CompilerType CreateMemberPointerType(const CompilerType &type, const CompilerType &pointee_type); - // Converts "s" to a floating point value and place resulting floating point - // bytes in the "dst" buffer. - size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) override; - // Dumping types #ifndef NDEBUG /// Convenience LLVM-style dump method for use in the debugger only. @@ -894,6 +886,14 @@ public: void Dump(Stream &s); + /// Dump clang AST types from the symbol file. + /// + /// \param[in] s + /// A stream to send the dumped AST node(s) to + /// \param[in] symbol_name + /// The name of the symbol to dump, if it is empty dump all the symbols + void DumpFromSymbolFile(Stream &s, llvm::StringRef symbol_name); + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, @@ -977,43 +977,45 @@ protected: GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); // Classes that inherit from ClangASTContext can see and modify these - // clang-format off - std::string m_target_triple; - std::unique_ptr<clang::ASTContext> m_ast_up; - std::unique_ptr<clang::LangOptions> m_language_options_up; - std::unique_ptr<clang::FileManager> m_file_manager_up; - std::unique_ptr<clang::SourceManager> m_source_manager_up; - std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_up; - std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_up; - std::shared_ptr<clang::TargetOptions> m_target_options_rp; - std::unique_ptr<clang::TargetInfo> m_target_info_up; - std::unique_ptr<clang::IdentifierTable> m_identifier_table_up; - std::unique_ptr<clang::SelectorTable> m_selector_table_up; - std::unique_ptr<clang::Builtin::Context> m_builtins_up; - std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up; - std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up; - std::unique_ptr<ClangASTSource> m_scratch_ast_source_up; - std::unique_ptr<clang::MangleContext> m_mangle_ctx_up; - CompleteTagDeclCallback m_callback_tag_decl; - CompleteObjCInterfaceDeclCallback m_callback_objc_decl; - void * m_callback_baton; - clang::ExternalASTMerger::OriginMap m_origins; - uint32_t m_pointer_byte_size; - bool m_ast_owned; - /// The sema associated that is currently used to build this ASTContext. - /// May be null if we are already done parsing this ASTContext or the - /// ASTContext wasn't created by parsing source code. - clang::Sema * m_sema = nullptr; - // clang-format on + std::string m_target_triple; + std::unique_ptr<clang::ASTContext> m_ast_up; + std::unique_ptr<clang::LangOptions> m_language_options_up; + std::unique_ptr<clang::FileManager> m_file_manager_up; + std::unique_ptr<clang::SourceManager> m_source_manager_up; + std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_up; + std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_up; + std::shared_ptr<clang::TargetOptions> m_target_options_rp; + std::unique_ptr<clang::TargetInfo> m_target_info_up; + std::unique_ptr<clang::IdentifierTable> m_identifier_table_up; + std::unique_ptr<clang::SelectorTable> m_selector_table_up; + std::unique_ptr<clang::Builtin::Context> m_builtins_up; + std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up; + std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up; + std::unique_ptr<ClangASTSource> m_scratch_ast_source_up; + std::unique_ptr<clang::MangleContext> m_mangle_ctx_up; + CompleteTagDeclCallback m_callback_tag_decl = nullptr; + CompleteObjCInterfaceDeclCallback m_callback_objc_decl = nullptr; + void *m_callback_baton = nullptr; + clang::ExternalASTMerger::OriginMap m_origins; + uint32_t m_pointer_byte_size = 0; + bool m_ast_owned = false; + /// The sema associated that is currently used to build this ASTContext. + /// May be null if we are already done parsing this ASTContext or the + /// ASTContext wasn't created by parsing source code. + clang::Sema *m_sema = nullptr; + private: // For ClangASTContext only ClangASTContext(const ClangASTContext &); const ClangASTContext &operator=(const ClangASTContext &); + /// Creates the internal ASTContext. + void CreateASTContext(); + void SetTargetTriple(llvm::StringRef target_triple); }; class ClangASTContextForExpressions : public ClangASTContext { public: - ClangASTContextForExpressions(Target &target); + ClangASTContextForExpressions(Target &target, ArchSpec arch); ~ClangASTContextForExpressions() override = default; @@ -1041,13 +1043,9 @@ public: } private: lldb::TargetWP m_target_wp; - lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the - ///persistent - ///variables - ///associated with - ///this process for - ///the expression - ///parser. + std::unique_ptr<PersistentExpressionState> + m_persistent_variables; // These are the persistent variables associated + // with this process for the expression parser }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h index 353b1232d940..f963f9b2b1dc 100644 --- a/include/lldb/Symbol/ClangASTImporter.h +++ b/include/lldb/Symbol/ClangASTImporter.h @@ -210,7 +210,7 @@ public: void ForgetDestination(clang::ASTContext *dst_ctx); void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); -private: +public: struct DeclOrigin { DeclOrigin() : ctx(nullptr), decl(nullptr) {} @@ -235,24 +235,32 @@ private: typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; + /// Listener interface used by the ASTImporterDelegate to inform other code + /// about decls that have been imported the first time. + struct NewDeclListener { + virtual ~NewDeclListener() = default; + /// A decl has been imported for the first time. + virtual void NewDeclImported(clang::Decl *from, clang::Decl *to) = 0; + }; + /// ASTImporter that intercepts and records the import process of the /// underlying ASTImporter. /// /// This class updates the map from declarations to their original - /// declarations and can record and complete declarations that have been - /// imported in a certain interval. + /// declarations and can record declarations that have been imported in a + /// certain interval. /// /// When intercepting a declaration import, the ASTImporterDelegate uses the /// CxxModuleHandler to replace any missing or malformed declarations with /// their counterpart from a C++ module. - class ASTImporterDelegate : public clang::ASTImporter { - public: + struct ASTImporterDelegate : public clang::ASTImporter { ASTImporterDelegate(ClangASTImporter &master, clang::ASTContext *target_ctx, clang::ASTContext *source_ctx) : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, master.m_file_manager, true /*minimal*/), - m_decls_to_deport(nullptr), m_decls_already_deported(nullptr), - m_master(master), m_source_ctx(source_ctx) {} + m_master(master), m_source_ctx(source_ctx) { + setODRHandling(clang::ASTImporter::ODRHandlingType::Liberal); + } /// Scope guard that attaches a CxxModuleHandler to an ASTImporterDelegate /// and deattaches it at the end of the scope. Supports being used multiple @@ -285,43 +293,32 @@ private: } }; - protected: - llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override; - - public: - // A call to "InitDeportWorkQueues" puts the delegate into deport mode. - // In deport mode, every copied Decl that could require completion is - // recorded and placed into the decls_to_deport set. - // - // A call to "ExecuteDeportWorkQueues" completes all the Decls that - // are in decls_to_deport, adding any Decls it sees along the way that it - // hasn't already deported. It proceeds until decls_to_deport is empty. - // - // These calls must be paired. Leaving a delegate in deport mode or trying - // to start deport delegate with a new pair of queues will result in an - // assertion failure. - - void - InitDeportWorkQueues(std::set<clang::NamedDecl *> *decls_to_deport, - std::set<clang::NamedDecl *> *decls_already_deported); - void ExecuteDeportWorkQueues(); - void ImportDefinitionTo(clang::Decl *to, clang::Decl *from); void Imported(clang::Decl *from, clang::Decl *to) override; clang::Decl *GetOriginalDecl(clang::Decl *To) override; + void SetImportListener(NewDeclListener *listener) { + assert(m_new_decl_listener == nullptr && "Already attached a listener?"); + m_new_decl_listener = listener; + } + void RemoveImportListener() { m_new_decl_listener = nullptr; } + + protected: + llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override; + + private: /// Decls we should ignore when mapping decls back to their original /// ASTContext. Used by the CxxModuleHandler to mark declarations that /// were created from the 'std' C++ module to prevent that the Importer /// tries to sync them with the broken equivalent in the debug info AST. std::set<clang::Decl *> m_decls_to_ignore; - std::set<clang::NamedDecl *> *m_decls_to_deport; - std::set<clang::NamedDecl *> *m_decls_already_deported; ClangASTImporter &m_master; clang::ASTContext *m_source_ctx; CxxModuleHandler *m_std_handler = nullptr; + /// The currently attached listener. + NewDeclListener *m_new_decl_listener = nullptr; }; typedef std::shared_ptr<ASTImporterDelegate> ImporterDelegateSP; @@ -387,6 +384,7 @@ private: } } +public: DeclOrigin GetDeclOrigin(const clang::Decl *decl); clang::FileManager m_file_manager; diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h index c3ba2e2176e7..d132c367b999 100644 --- a/include/lldb/Symbol/CompileUnit.h +++ b/include/lldb/Symbol/CompileUnit.h @@ -225,6 +225,14 @@ public: DebugMacros *GetDebugMacros(); + /// Apply a lambda to each external lldb::Module referenced by this + /// compilation unit. Recursively also descends into the referenced external + /// modules of any encountered compilation unit. + /// + /// \param[in] lambda + /// The lambda that should be applied to every module. + void ForEachExternalModule(llvm::function_ref<void(lldb::ModuleSP)> f); + /// Get the compile unit's support file list. /// /// The support file list is used by the line table, and any objects that @@ -298,6 +306,8 @@ public: /// A line table object pointer that this object now owns. void SetLineTable(LineTable *line_table); + void SetSupportFiles(const FileSpecList &support_files); + void SetDebugMacros(const DebugMacrosSP &debug_macros); /// Set accessor for the variable list. diff --git a/include/lldb/Symbol/CompilerType.h b/include/lldb/Symbol/CompilerType.h index 98d916597f42..bb9881c0bae3 100644 --- a/include/lldb/Symbol/CompilerType.h +++ b/include/lldb/Symbol/CompilerType.h @@ -13,7 +13,6 @@ #include <string> #include <vector> -#include "lldb/Core/ClangForward.h" #include "lldb/lldb-private.h" #include "llvm/ADT/APSInt.h" @@ -32,7 +31,6 @@ class CompilerType { public: // Constructors and Destructors CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type); - CompilerType(clang::ASTContext *ast_context, clang::QualType qual_type); CompilerType(const CompilerType &rhs) : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {} @@ -169,8 +167,6 @@ public: void SetCompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type); - void SetCompilerType(clang::ASTContext *ast, clang::QualType qual_type); - unsigned GetTypeQualifiers() const; // Creating related types @@ -257,7 +253,7 @@ public: lldb::Format GetFormat() const; - size_t GetTypeBitAlign() const; + llvm::Optional<size_t> GetTypeBitAlign(ExecutionContextScope *exe_scope) const; uint32_t GetNumChildren(bool omit_empty_base_classes, const ExecutionContext *exe_ctx) const; @@ -336,13 +332,6 @@ public: bool IsMeaninglessWithoutDynamicResolution() const; - // Pointers & References - - // Converts "s" to a floating point value and place resulting floating point - // bytes in the "dst" buffer. - size_t ConvertStringToFloatValue(const char *s, uint8_t *dst, - size_t dst_size) const; - // Dumping types #ifndef NDEBUG diff --git a/include/lldb/Symbol/DeclVendor.h b/include/lldb/Symbol/DeclVendor.h index 9c10fe1177fb..748c0c8ac961 100644 --- a/include/lldb/Symbol/DeclVendor.h +++ b/include/lldb/Symbol/DeclVendor.h @@ -9,11 +9,8 @@ #ifndef liblldb_DeclVendor_h_ #define liblldb_DeclVendor_h_ -#include "lldb/Core/ClangForward.h" #include "lldb/lldb-defines.h" -#include "clang/AST/ExternalASTMerger.h" - #include <vector> namespace lldb_private { @@ -22,11 +19,19 @@ namespace lldb_private { // declarations that are not necessarily backed by a specific symbol file. class DeclVendor { public: + enum DeclVendorKind { + eClangDeclVendor, + eClangModuleDeclVendor, + eAppleObjCDeclVendor, + eLastClangDeclVendor, + }; // Constructors and Destructors - DeclVendor() {} + DeclVendor(DeclVendorKind kind) : m_kind(kind) {} virtual ~DeclVendor() {} + DeclVendorKind GetKind() const { return m_kind; } + /// Look up the set of Decls that the DeclVendor currently knows about /// matching a given name. /// @@ -45,7 +50,7 @@ public: /// max_matches. virtual uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches, - std::vector<clang::NamedDecl *> &decls) = 0; + std::vector<CompilerDecl> &decls) = 0; /// Look up the types that the DeclVendor currently knows about matching a /// given name. @@ -60,16 +65,11 @@ public: /// The vector of CompilerTypes that was found. std::vector<CompilerType> FindTypes(ConstString name, uint32_t max_matches); - /// Interface for ExternalASTMerger. Returns an ImporterSource - /// allowing type completion. - /// - /// \return - /// An ImporterSource for this DeclVendor. - virtual clang::ExternalASTMerger::ImporterSource GetImporterSource() = 0; - private: // For DeclVendor only DISALLOW_COPY_AND_ASSIGN(DeclVendor); + + const DeclVendorKind m_kind; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index cc767d4e1e82..c49f6b0fa942 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -76,6 +76,11 @@ public: lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread); + lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target); + + lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target, + Thread &thread); + lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target); lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target, @@ -113,10 +118,12 @@ private: std::recursive_mutex m_mutex; lldb::UnwindPlanSP m_unwind_plan_assembly_sp; + lldb::UnwindPlanSP m_unwind_plan_object_file_sp; lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp; // augmented by assembly inspection so it's valid everywhere + lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp; lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp; lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp; @@ -130,7 +137,9 @@ private: // Fetching the UnwindPlans can be expensive - if we've already attempted to // get one & failed, don't try again. bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1, + m_tried_unwind_plan_object_file : 1, m_tried_unwind_plan_debug_frame : 1, + m_tried_unwind_plan_object_file_augmented : 1, m_tried_unwind_plan_eh_frame_augmented : 1, m_tried_unwind_plan_debug_frame_augmented : 1, m_tried_unwind_plan_compact_unwind : 1, diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index f68a16705d93..1b23a99373ca 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -140,7 +140,7 @@ public: /// \param[in] call_decl_ptr /// Optional calling location declaration information that /// describes from where this inlined function was called. - InlineFunctionInfo(const char *name, const char *mangled, + InlineFunctionInfo(const char *name, llvm::StringRef mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); @@ -246,10 +246,22 @@ private: class Function; +/// \class CallSiteParameter Function.h "lldb/Symbol/Function.h" +/// +/// Represent the locations of a parameter at a call site, both in the caller +/// and in the callee. +struct CallSiteParameter { + DWARFExpression LocationInCallee; + DWARFExpression LocationInCaller; +}; + +/// A vector of \c CallSiteParameter. +using CallSiteParameterArray = llvm::SmallVector<CallSiteParameter, 0>; + /// \class CallEdge Function.h "lldb/Symbol/Function.h" /// /// Represent a call made within a Function. This can be used to find a path -/// in the call graph between two functions. +/// in the call graph between two functions, or to evaluate DW_OP_entry_value. class CallEdge { public: /// Construct a call edge using a symbol name to identify the calling @@ -259,7 +271,8 @@ public: /// TODO: A symbol name may not be globally unique. To disambiguate ODR /// conflicts, it's necessary to determine the \c Target a call edge is /// associated with before resolving it. - CallEdge(const char *symbol_name, lldb::addr_t return_pc); + CallEdge(const char *symbol_name, lldb::addr_t return_pc, + CallSiteParameterArray parameters); CallEdge(CallEdge &&) = default; CallEdge &operator=(CallEdge &&) = default; @@ -279,6 +292,9 @@ public: /// offset. lldb::addr_t GetUnresolvedReturnPCAddress() const { return return_pc; } + /// Get the call site parameters available at this call edge. + llvm::ArrayRef<CallSiteParameter> GetCallSiteParameters() const; + private: void ParseSymbolFileAndResolve(ModuleList &images); @@ -294,6 +310,8 @@ private: /// gives the return PC for the call. lldb::addr_t return_pc; + CallSiteParameterArray parameters; + /// Whether or not an attempt was made to find the callee's definition. bool resolved; @@ -402,6 +420,11 @@ public: /// return None. llvm::MutableArrayRef<CallEdge> GetTailCallingEdges(); + /// Get the outgoing call edge from this function which has the given return + /// address \p return_pc, or return nullptr. Note that this will not return a + /// tail-calling edge. + CallEdge *GetCallEdgeForReturnAddress(lldb::addr_t return_pc, Target &target); + /// Get accessor for the block list. /// /// \return @@ -564,6 +587,8 @@ protected: uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it + // TODO: Use a layer of indirection to point to call edges, to save space + // when call info hasn't been parsed. bool m_call_edges_resolved = false; ///< Whether call site info has been /// parsed. std::vector<CallEdge> m_call_edges; ///< Outgoing call edges. diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index 84683e3f2a3f..4d04f23a8286 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -63,16 +63,22 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>, public: enum Type { eTypeInvalid = 0, - eTypeCoreFile, /// A core file that has a checkpoint of a program's - /// execution state - eTypeExecutable, /// A normal executable - eTypeDebugInfo, /// An object file that contains only debug information - eTypeDynamicLinker, /// The platform's dynamic linker executable - eTypeObjectFile, /// An intermediate object file - eTypeSharedLibrary, /// A shared library that can be used during execution - eTypeStubLibrary, /// A library that can be linked against but not used for - /// execution - eTypeJIT, /// JIT code that has symbols, sections and possibly debug info + /// A core file that has a checkpoint of a program's execution state. + eTypeCoreFile, + /// A normal executable. + eTypeExecutable, + /// An object file that contains only debug information. + eTypeDebugInfo, + /// The platform's dynamic linker executable. + eTypeDynamicLinker, + /// An intermediate object file. + eTypeObjectFile, + /// A shared library that can be used during execution. + eTypeSharedLibrary, + /// A library that can be linked against but not used for execution. + eTypeStubLibrary, + /// JIT code that has symbols, sections and possibly debug info. + eTypeJIT, eTypeUnknown }; @@ -201,9 +207,13 @@ public: /// \b false otherwise and \a archive_file and \a archive_object /// are guaranteed to be remain unchanged. static bool SplitArchivePathWithObject( - const char *path_with_object, lldb_private::FileSpec &archive_file, + llvm::StringRef path_with_object, lldb_private::FileSpec &archive_file, lldb_private::ConstString &archive_object, bool must_exist); + // LLVM RTTI support + static char ID; + virtual bool isA(const void *ClassID) const { return ClassID == &ID; } + /// Gets the address size in bytes for the current object file. /// /// \return @@ -366,17 +376,6 @@ public: /// returned. virtual UUID GetUUID() = 0; - /// Gets the symbol file spec list for this object file. - /// - /// If the object file format contains a debug symbol file link, the values - /// will be returned in the FileSpecList. - /// - /// \return - /// Returns filespeclist. - virtual lldb_private::FileSpecList GetDebugSymbolFilePaths() { - return FileSpecList(); - } - /// Gets the file spec list of libraries re-exported by this object file. /// /// If the object file format has the notion of one library re-exporting the @@ -657,6 +656,9 @@ public: /// \return virtual std::vector<LoadableData> GetLoadableData(Target &target); + /// Creates a plugin-specific call frame info + virtual std::unique_ptr<CallFrameInfo> CreateCallFrameInfo(); + protected: // Member variables. FileSpec m_file; diff --git a/include/lldb/Symbol/PostfixExpression.h b/include/lldb/Symbol/PostfixExpression.h index e3a8587a5f84..fa7793315899 100644 --- a/include/lldb/Symbol/PostfixExpression.h +++ b/include/lldb/Symbol/PostfixExpression.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" +#include <vector> namespace lldb_private { @@ -211,7 +212,10 @@ inline T *MakeNode(llvm::BumpPtrAllocator &alloc, Args &&... args) { /// Parse the given postfix expression. The parsed nodes are placed into the /// provided allocator. -Node *Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc); +Node *ParseOneExpression(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc); + +std::vector<std::pair<llvm::StringRef, Node *>> +ParseFPOProgram(llvm::StringRef prog, llvm::BumpPtrAllocator &alloc); /// Serialize the given expression tree as DWARF. The result is written into the /// given stream. The AST should not contain any SymbolNodes. If the expression diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index 1cbc2f5492f4..b7f179d1449b 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -24,9 +24,8 @@ public: // drastically different meanings and sorting requirements. Symbol(); - Symbol(uint32_t symID, const char *name, bool name_is_mangled, - lldb::SymbolType type, bool external, bool is_debug, - bool is_trampoline, bool is_artificial, + Symbol(uint32_t symID, llvm::StringRef name, lldb::SymbolType type, + bool external, bool is_debug, bool is_trampoline, bool is_artificial, const lldb::SectionSP §ion_sp, lldb::addr_t value, lldb::addr_t size, bool size_is_valid, bool contains_linker_annotations, uint32_t flags); diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index 55a345489358..76ec1a7de68e 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -470,6 +470,8 @@ public: /// Returns the number of symbol context objects in the list. uint32_t GetSize() const; + bool IsEmpty() const; + uint32_t NumLineEntriesWithLine(uint32_t line) const; void GetDescription(Stream *s, lldb::DescriptionLevel level, diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h index dbb723e9d369..6724b425abf3 100644 --- a/include/lldb/Symbol/SymbolFile.h +++ b/include/lldb/Symbol/SymbolFile.h @@ -16,9 +16,11 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SourceModule.h" #include "lldb/Symbol/Type.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/lldb-private.h" - #include "llvm/ADT/DenseSet.h" +#include "llvm/Support/Errc.h" #include <mutex> @@ -49,11 +51,12 @@ public: kAllAbilities = ((1u << 7) - 1u) }; - static SymbolFile *FindPlugin(ObjectFile *obj_file); + static SymbolFile *FindPlugin(lldb::ObjectFileSP objfile_sp); // Constructors and Destructors - SymbolFile(ObjectFile *obj_file) - : m_obj_file(obj_file), m_abilities(0), m_calculated_abilities(false) {} + SymbolFile(lldb::ObjectFileSP objfile_sp) + : m_objfile_sp(std::move(objfile_sp)), m_abilities(0), + m_calculated_abilities(false) {} ~SymbolFile() override {} @@ -110,13 +113,18 @@ public: // Compile Unit function calls // Approach 1 - iterator - virtual uint32_t GetNumCompileUnits() = 0; - virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0; + uint32_t GetNumCompileUnits(); + lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx); + + Symtab *GetSymtab(); virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0; virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0; virtual bool ParseLineTable(CompileUnit &comp_unit) = 0; virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0; + virtual void + ForEachExternalModule(CompileUnit &comp_unit, + llvm::function_ref<void(lldb::ModuleSP)> f) {} virtual bool ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files) = 0; virtual size_t ParseTypes(CompileUnit &comp_unit) = 0; @@ -165,43 +173,41 @@ public: SymbolContextList &sc_list); virtual void DumpClangAST(Stream &s) {} - virtual uint32_t + virtual void FindGlobalVariables(ConstString name, const CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, VariableList &variables); - virtual uint32_t FindGlobalVariables(const RegularExpression ®ex, - uint32_t max_matches, - VariableList &variables); - virtual uint32_t FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, - lldb::FunctionNameType name_type_mask, - bool include_inlines, bool append, - SymbolContextList &sc_list); - virtual uint32_t FindFunctions(const RegularExpression ®ex, - bool include_inlines, bool append, - SymbolContextList &sc_list); - virtual uint32_t + virtual void FindGlobalVariables(const RegularExpression ®ex, + uint32_t max_matches, + VariableList &variables); + virtual void FindFunctions(ConstString name, + const CompilerDeclContext *parent_decl_ctx, + lldb::FunctionNameType name_type_mask, + bool include_inlines, SymbolContextList &sc_list); + virtual void FindFunctions(const RegularExpression ®ex, + bool include_inlines, SymbolContextList &sc_list); + virtual void FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, - bool append, uint32_t max_matches, + uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types); - virtual size_t FindTypes(const std::vector<CompilerContext> &context, - bool append, TypeMap &types); + + /// Find types specified by a CompilerContextPattern. + /// \param languages Only return results in these languages. + virtual void FindTypes(llvm::ArrayRef<CompilerContext> pattern, + LanguageSet languages, TypeMap &types); virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names); - // virtual uint32_t FindTypes (const SymbolContext& sc, const - // RegularExpression& regex, bool append, uint32_t max_matches, TypeList& - // types) = 0; - virtual TypeList *GetTypeList(); - virtual size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - lldb::TypeClass type_mask, - lldb_private::TypeList &type_list) = 0; + + virtual void GetTypes(lldb_private::SymbolContextScope *sc_scope, + lldb::TypeClass type_mask, + lldb_private::TypeList &type_list) = 0; virtual void PreloadSymbols(); - virtual lldb_private::TypeSystem * + virtual llvm::Expected<lldb_private::TypeSystem &> GetTypeSystemForLanguage(lldb::LanguageType language); virtual CompilerDeclContext @@ -210,8 +216,9 @@ public: return CompilerDeclContext(); } - ObjectFile *GetObjectFile() { return m_obj_file; } - const ObjectFile *GetObjectFile() const { return m_obj_file; } + ObjectFile *GetObjectFile() { return m_objfile_sp.get(); } + const ObjectFile *GetObjectFile() const { return m_objfile_sp.get(); } + ObjectFile *GetMainObjectFile(); virtual std::vector<CallEdge> ParseCallEdgesInFunction(UserID func_id) { return {}; @@ -221,7 +228,7 @@ public: /// Notify the SymbolFile that the file addresses in the Sections /// for this module have been changed. - virtual void SectionFileAddressesChanged() {} + virtual void SectionFileAddressesChanged(); struct RegisterInfoResolver { virtual ~RegisterInfoResolver(); // anchor @@ -235,12 +242,30 @@ public: return nullptr; } - virtual void Dump(Stream &s) {} + /// Return the number of stack bytes taken up by the parameters to this + /// function. + virtual llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) { + return llvm::createStringError(make_error_code(llvm::errc::not_supported), + "Operation not supported."); + } + + virtual void Dump(Stream &s); protected: void AssertModuleLock(); - - ObjectFile *m_obj_file; // The object file that symbols can be extracted from. + virtual uint32_t CalculateNumCompileUnits() = 0; + virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t idx) = 0; + virtual TypeList &GetTypeList() { return m_type_list; } + + void SetCompileUnitAtIndex(uint32_t idx, const lldb::CompUnitSP &cu_sp); + + lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in + // case it isn't the same as the module + // object file (debug symbols in a separate + // file) + llvm::Optional<std::vector<lldb::CompUnitSP>> m_compile_units; + TypeList m_type_list; + Symtab *m_symtab = nullptr; uint32_t m_abilities; bool m_calculated_abilities; diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h index c4015ff03492..96c6ea5c7332 100644 --- a/include/lldb/Symbol/SymbolVendor.h +++ b/include/lldb/Symbol/SymbolVendor.h @@ -14,7 +14,6 @@ #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/SourceModule.h" -#include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" @@ -40,123 +39,16 @@ public: void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp); - virtual void Dump(Stream *s); - - virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit); - - virtual size_t ParseFunctions(CompileUnit &comp_unit); - - virtual bool ParseLineTable(CompileUnit &comp_unit); - - virtual bool ParseDebugMacros(CompileUnit &comp_unit); - - virtual bool ParseSupportFiles(CompileUnit &comp_unit, - FileSpecList &support_files); - - virtual bool ParseIsOptimized(CompileUnit &comp_unit); - - virtual size_t ParseTypes(CompileUnit &comp_unit); - - virtual bool - ParseImportedModules(const SymbolContext &sc, - std::vector<SourceModule> &imported_modules); - - virtual size_t ParseBlocksRecursive(Function &func); - - virtual size_t ParseVariablesForContext(const SymbolContext &sc); - - virtual Type *ResolveTypeUID(lldb::user_id_t type_uid); - - virtual uint32_t ResolveSymbolContext(const Address &so_addr, - lldb::SymbolContextItem resolve_scope, - SymbolContext &sc); - - virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - lldb::SymbolContextItem resolve_scope, - SymbolContextList &sc_list); - - virtual size_t FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, - size_t max_matches, - VariableList &variables); - - virtual size_t FindGlobalVariables(const RegularExpression ®ex, - size_t max_matches, - VariableList &variables); - - virtual size_t FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, - lldb::FunctionNameType name_type_mask, - bool include_inlines, bool append, - SymbolContextList &sc_list); - - virtual size_t FindFunctions(const RegularExpression ®ex, - bool include_inlines, bool append, - SymbolContextList &sc_list); - - virtual size_t - FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, - bool append, size_t max_matches, - llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, - TypeMap &types); - - virtual size_t FindTypes(const std::vector<CompilerContext> &context, - bool append, TypeMap &types); - - virtual CompilerDeclContext - FindNamespace(ConstString name, - const CompilerDeclContext *parent_decl_ctx); - - virtual size_t GetNumCompileUnits(); - - virtual bool SetCompileUnitAtIndex(size_t cu_idx, - const lldb::CompUnitSP &cu_sp); - - virtual lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx); - - TypeList &GetTypeList() { return m_type_list; } - - const TypeList &GetTypeList() const { return m_type_list; } - - virtual size_t GetTypes(SymbolContextScope *sc_scope, - lldb::TypeClass type_mask, TypeList &type_list); - SymbolFile *GetSymbolFile() { return m_sym_file_up.get(); } - FileSpec GetMainFileSpec() const; - - // Get module unified section list symbol table. - virtual Symtab *GetSymtab(); - - // Clear module unified section list symbol table. - virtual void ClearSymtab(); - - /// Notify the SymbolVendor that the file addresses in the Sections - /// for this module have been changed. - virtual void SectionFileAddressesChanged(); - // PluginInterface protocol ConstString GetPluginName() override; uint32_t GetPluginVersion() override; protected: - // Classes that inherit from SymbolVendor can see and modify these - typedef std::vector<lldb::CompUnitSP> CompileUnits; - typedef CompileUnits::iterator CompileUnitIter; - typedef CompileUnits::const_iterator CompileUnitConstIter; - - TypeList m_type_list; // Uniqued types for all parsers owned by this module - CompileUnits m_compile_units; // The current compile units - lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in - // case it isn't the same as the module - // object file (debug symbols in a separate - // file) std::unique_ptr<SymbolFile> m_sym_file_up; // A single symbol file. Subclasses // can add more of these if needed. - Symtab *m_symtab; // Save a symtab once to not pass it through `AddSymbols` of - // the symbol file each time when it is needed private: // For SymbolVendor only diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h index 868edcdc9290..99d15771ccc5 100644 --- a/include/lldb/Symbol/Symtab.h +++ b/include/lldb/Symbol/Symtab.h @@ -92,15 +92,15 @@ public: const RegularExpression ®ex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t> &indexes); - size_t FindAllSymbolsWithNameAndType(ConstString name, - lldb::SymbolType symbol_type, - std::vector<uint32_t> &symbol_indexes); - size_t FindAllSymbolsWithNameAndType(ConstString name, - lldb::SymbolType symbol_type, - Debug symbol_debug_type, - Visibility symbol_visibility, - std::vector<uint32_t> &symbol_indexes); - size_t FindAllSymbolsMatchingRexExAndType( + void FindAllSymbolsWithNameAndType(ConstString name, + lldb::SymbolType symbol_type, + std::vector<uint32_t> &symbol_indexes); + void FindAllSymbolsWithNameAndType(ConstString name, + lldb::SymbolType symbol_type, + Debug symbol_debug_type, + Visibility symbol_visibility, + std::vector<uint32_t> &symbol_indexes); + void FindAllSymbolsMatchingRexExAndType( const RegularExpression ®ex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes); @@ -112,8 +112,8 @@ public: Symbol *FindSymbolContainingFileAddress(lldb::addr_t file_addr); void ForEachSymbolContainingFileAddress( lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback); - size_t FindFunctionSymbols(ConstString name, uint32_t name_type_mask, - SymbolContextList &sc_list); + void FindFunctionSymbols(ConstString name, uint32_t name_type_mask, + SymbolContextList &sc_list); void CalculateSymbolSizes(); void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes, diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index efc9bf049a35..446e043a95ee 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -9,7 +9,6 @@ #ifndef liblldb_Type_h_ #define liblldb_Type_h_ -#include "lldb/Core/ClangForward.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Declaration.h" @@ -22,22 +21,28 @@ #include <set> namespace lldb_private { -// CompilerContext allows an array of these items to be passed to perform -// detailed lookups in SymbolVendor and SymbolFile functions. + +/// CompilerContext allows an array of these items to be passed to perform +/// detailed lookups in SymbolVendor and SymbolFile functions. struct CompilerContext { - CompilerContext(CompilerContextKind t, ConstString n) - : type(t), name(n) {} + CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {} bool operator==(const CompilerContext &rhs) const { - return type == rhs.type && name == rhs.name; + return kind == rhs.kind && name == rhs.name; } + bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); } void Dump() const; - CompilerContextKind type; + CompilerContextKind kind; ConstString name; }; +/// Match \p context_chain against \p pattern, which may contain "Any" +/// kinds. The \p context_chain should *not* contain any "Any" kinds. +bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain, + llvm::ArrayRef<CompilerContext> pattern); + class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, public UserID { public: @@ -117,8 +122,6 @@ public: SymbolFile *GetSymbolFile() { return m_symbol_file; } const SymbolFile *GetSymbolFile() const { return m_symbol_file; } - TypeList *GetTypeList(); - ConstString GetName(); llvm::Optional<uint64_t> GetByteSize(); diff --git a/include/lldb/Symbol/TypeList.h b/include/lldb/Symbol/TypeList.h index 982f673fff6e..38342b6d6f4f 100644 --- a/include/lldb/Symbol/TypeList.h +++ b/include/lldb/Symbol/TypeList.h @@ -28,15 +28,14 @@ public: void Dump(Stream *s, bool show_context); - // lldb::TypeSP - // FindType(lldb::user_id_t uid); - TypeList FindTypes(ConstString name); void Insert(const lldb::TypeSP &type); uint32_t GetSize() const; + bool Empty() const { return !GetSize(); } + lldb::TypeSP GetTypeAtIndex(uint32_t idx); typedef std::vector<lldb::TypeSP> collection; diff --git a/include/lldb/Symbol/TypeSystem.h b/include/lldb/Symbol/TypeSystem.h index 4bef2a4446eb..07295c244a5d 100644 --- a/include/lldb/Symbol/TypeSystem.h +++ b/include/lldb/Symbol/TypeSystem.h @@ -14,8 +14,11 @@ #include <mutex> #include <string> +#include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Error.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Expression/Expression.h" @@ -29,7 +32,24 @@ class PDBASTParser; namespace lldb_private { -// Interface for representing the Type Systems in different languages. +/// A SmallBitVector that represents a set of source languages (\p +/// lldb::LanguageType). Each lldb::LanguageType is represented by +/// the bit with the position of its enumerator. The largest +/// LanguageType is < 64, so this is space-efficient and on 64-bit +/// architectures a LanguageSet can be completely stack-allocated. +struct LanguageSet { + llvm::SmallBitVector bitvector; + LanguageSet(); + + /// If the set contains a single language only, return it. + llvm::Optional<lldb::LanguageType> GetSingularLanguage(); + void Insert(lldb::LanguageType language); + bool Empty() const; + size_t Size() const; + bool operator[](unsigned i) const; +}; + +/// Interface for representing the Type Systems in different languages. class TypeSystem : public PluginInterface { public: // Intrusive type system that allows us to use llvm casting. @@ -107,6 +127,8 @@ public: virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, size_t arg_idx); + virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0; + // CompilerDeclContext functions virtual std::vector<CompilerDecl> @@ -255,6 +277,8 @@ public: // Exploring the type + virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0; + virtual llvm::Optional<uint64_t> GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) = 0; @@ -375,12 +399,6 @@ public: lldb::offset_t data_offset, size_t data_byte_size) = 0; - // Converts "s" to a floating point value and place resulting floating point - // bytes in the "dst" buffer. - virtual size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) = 0; - // TODO: Determine if these methods should move to ClangASTContext. virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, @@ -391,7 +409,9 @@ public: virtual bool IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) = 0; - virtual size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) = 0; + virtual llvm::Optional<size_t> + GetTypeBitAlign(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) = 0; virtual CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) = 0; @@ -491,18 +511,15 @@ public: // callback to keep iterating, false to stop iterating. void ForEach(std::function<bool(TypeSystem *)> const &callback); - TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language, - Module *module, bool can_create); + llvm::Expected<TypeSystem &> + GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, + bool can_create); - TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language, - Target *target, bool can_create); + llvm::Expected<TypeSystem &> + GetTypeSystemForLanguage(lldb::LanguageType language, Target *target, + bool can_create); protected: - // This function does not take the map mutex, and should only be called from - // functions that do take the mutex. - void AddToMap(lldb::LanguageType language, - lldb::TypeSystemSP const &type_system_sp); - typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection; mutable std::mutex m_mutex; ///< A mutex to keep this object happy in ///multi-threaded environments. diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h index 2b49acaafa04..fa41ba5d056a 100644 --- a/include/lldb/Symbol/UnwindPlan.h +++ b/include/lldb/Symbol/UnwindPlan.h @@ -201,7 +201,8 @@ public: unspecified, // not specified isRegisterPlusOffset, // FA = register + offset isRegisterDereferenced, // FA = [reg] - isDWARFExpression // FA = eval(dwarf_expr) + isDWARFExpression, // FA = eval(dwarf_expr) + isRaSearch, // FA = SP + offset + ??? }; FAValue() : m_type(unspecified), m_value() {} @@ -214,6 +215,11 @@ public: bool IsUnspecified() const { return m_type == unspecified; } + void SetRaSearch(int32_t offset) { + m_type = isRaSearch; + m_value.ra_search_offset = offset; + } + bool IsRegisterPlusOffset() const { return m_type == isRegisterPlusOffset; } @@ -250,9 +256,14 @@ public: ValueType GetValueType() const { return m_type; } int32_t GetOffset() const { - if (m_type == isRegisterPlusOffset) - return m_value.reg.offset; - return 0; + switch (m_type) { + case isRegisterPlusOffset: + return m_value.reg.offset; + case isRaSearch: + return m_value.ra_search_offset; + default: + return 0; + } } void IncOffset(int32_t delta) { @@ -304,6 +315,8 @@ public: const uint8_t *opcodes; uint16_t length; } expr; + // For m_type == isRaSearch + int32_t ra_search_offset; } m_value; }; // class FAValue @@ -370,6 +383,7 @@ public: m_return_addr_register(LLDB_INVALID_REGNUM), m_source_name(), m_plan_is_sourced_from_compiler(eLazyBoolCalculate), m_plan_is_valid_at_all_instruction_locations(eLazyBoolCalculate), + m_plan_is_for_signal_trap(eLazyBoolCalculate), m_lsda_address(), m_personality_func_addr() {} // Performs a deep copy of the plan, including all the rows (expensive). @@ -463,6 +477,17 @@ public: m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn; } + // Is this UnwindPlan for a signal trap frame? If so, then its saved pc + // may have been set manually by the signal dispatch code and therefore + // not follow a call to the child frame. + lldb_private::LazyBool GetUnwindPlanForSignalTrap() const { + return m_plan_is_for_signal_trap; + } + + void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap) { + m_plan_is_for_signal_trap = is_for_signal_trap; + } + int GetRowCount() const; void Clear() { @@ -472,6 +497,7 @@ public: m_source_name.Clear(); m_plan_is_sourced_from_compiler = eLazyBoolCalculate; m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate; + m_plan_is_for_signal_trap = eLazyBoolCalculate; m_lsda_address.Clear(); m_personality_func_addr.Clear(); } @@ -502,6 +528,7 @@ private: m_source_name; // for logging, where this UnwindPlan originated from lldb_private::LazyBool m_plan_is_sourced_from_compiler; lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations; + lldb_private::LazyBool m_plan_is_for_signal_trap; Address m_lsda_address; // Where the language specific data area exists in the // module - used diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h index b4d7f0661d5b..c1dc519c4b20 100644 --- a/include/lldb/Symbol/UnwindTable.h +++ b/include/lldb/Symbol/UnwindTable.h @@ -27,6 +27,8 @@ public: ~UnwindTable(); + lldb_private::CallFrameInfo *GetObjectFileUnwindInfo(); + lldb_private::DWARFCallFrameInfo *GetEHFrameInfo(); lldb_private::DWARFCallFrameInfo *GetDebugFrameInfo(); @@ -71,6 +73,7 @@ private: bool m_initialized; // delay some initialization until ObjectFile is set up std::mutex m_mutex; + std::unique_ptr<CallFrameInfo> m_object_file_unwind_up; std::unique_ptr<DWARFCallFrameInfo> m_eh_frame_up; std::unique_ptr<DWARFCallFrameInfo> m_debug_frame_up; std::unique_ptr<CompactUnwindInfo> m_compact_unwind_up; diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h index 12daecfc04e6..30f57f1f9110 100644 --- a/include/lldb/Symbol/Variable.h +++ b/include/lldb/Symbol/Variable.h @@ -26,15 +26,14 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> { public: typedef RangeVector<lldb::addr_t, lldb::addr_t> RangeList; - // Constructors and Destructors - Variable(lldb::user_id_t uid, const char *name, - const char - *mangled, // The mangled or fully qualified name of the variable. - const lldb::SymbolFileTypeSP &symfile_type_sp, - lldb::ValueType scope, SymbolContextScope *owner_scope, - const RangeList &scope_range, Declaration *decl, - const DWARFExpression &location, bool external, bool artificial, - bool static_member = false); + /// Constructors and Destructors. + /// + /// \param mangled The mangled or fully qualified name of the variable. + Variable(lldb::user_id_t uid, const char *name, const char *mangled, + const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope, + SymbolContextScope *owner_scope, const RangeList &scope_range, + Declaration *decl, const DWARFExpression &location, bool external, + bool artificial, bool static_member = false); virtual ~Variable(); @@ -50,11 +49,11 @@ public: SymbolContextScope *GetSymbolContextScope() const { return m_owner_scope; } - // Since a variable can have a basename "i" and also a mangled named - // "_ZN12_GLOBAL__N_11iE" and a demangled mangled name "(anonymous - // namespace)::i", this function will allow a generic match function that can - // be called by commands and expression parsers to make sure we match - // anything we come across. + /// Since a variable can have a basename "i" and also a mangled named + /// "_ZN12_GLOBAL__N_11iE" and a demangled mangled name "(anonymous + /// namespace)::i", this function will allow a generic match function that can + /// be called by commands and expression parsers to make sure we match + /// anything we come across. bool NameMatches(ConstString name) const; bool NameMatches(const RegularExpression ®ex) const; @@ -99,34 +98,42 @@ public: GetVariableCallback callback, void *baton, VariableList &variable_list, ValueObjectList &valobj_list); - static size_t AutoComplete(const ExecutionContext &exe_ctx, - CompletionRequest &request); + static void AutoComplete(const ExecutionContext &exe_ctx, + CompletionRequest &request); CompilerDeclContext GetDeclContext(); CompilerDecl GetDecl(); protected: - ConstString m_name; // The basename of the variable (no namespaces) - Mangled m_mangled; // The mangled name of the variable - lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable - // (int, struct, class, etc) - lldb::ValueType m_scope; // global, parameter, local - SymbolContextScope - *m_owner_scope; // The symbol file scope that this variable was defined in - RangeList m_scope_range; // The list of ranges inside the owner's scope where - // this variable is valid - Declaration m_declaration; // Declaration location for this item. - DWARFExpression m_location; // The location of this variable that can be fed - // to DWARFExpression::Evaluate() - uint8_t m_external : 1, // Visible outside the containing compile unit? - m_artificial : 1, // Non-zero if the variable is not explicitly declared - // in source - m_loc_is_const_data : 1, // The m_location expression contains the - // constant variable value data, not a DWARF - // location - m_static_member : 1; // Non-zero if variable is static member of a class - // or struct. + /// The basename of the variable (no namespaces). + ConstString m_name; + /// The mangled name of the variable. + Mangled m_mangled; + /// The type pointer of the variable (int, struct, class, etc) + /// global, parameter, local. + lldb::SymbolFileTypeSP m_symfile_type_sp; + lldb::ValueType m_scope; + /// The symbol file scope that this variable was defined in + SymbolContextScope *m_owner_scope; + /// The list of ranges inside the owner's scope where this variable + /// is valid. + RangeList m_scope_range; + /// Declaration location for this item. + Declaration m_declaration; + /// The location of this variable that can be fed to + /// DWARFExpression::Evaluate(). + DWARFExpression m_location; + /// Visible outside the containing compile unit? + unsigned m_external : 1; + /// Non-zero if the variable is not explicitly declared in source. + unsigned m_artificial : 1; + /// The m_location expression contains the constant variable value + /// data, not a DWARF location. + unsigned m_loc_is_const_data : 1; + /// Non-zero if variable is static member of a class or struct. + unsigned m_static_member : 1; + private: Variable(const Variable &rhs) = delete; Variable &operator=(const Variable &rhs) = delete; diff --git a/include/lldb/Symbol/VerifyDecl.h b/include/lldb/Symbol/VerifyDecl.h deleted file mode 100644 index f412b94a7859..000000000000 --- a/include/lldb/Symbol/VerifyDecl.h +++ /dev/null @@ -1,18 +0,0 @@ -//===-- VerifyDecl.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 lldb_VariableList_h_ -#define lldb_VariableList_h_ - -#include "lldb/Core/ClangForward.h" - -namespace lldb_private { -void VerifyDecl(clang::Decl *decl); -} - -#endif diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h index f254839fc975..93378abc2ac2 100644 --- a/include/lldb/Target/ABI.h +++ b/include/lldb/Target/ABI.h @@ -15,8 +15,8 @@ #include "lldb/lldb-private.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/MC/MCRegisterInfo.h" -// forward define the llvm::Type class namespace llvm { class Type; } @@ -124,6 +124,8 @@ public: return pc; } + llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } + virtual const RegisterInfo *GetRegisterInfoArray(uint32_t &count) = 0; bool GetRegisterInfoByName(ConstString name, RegisterInfo &info); @@ -136,13 +138,19 @@ public: static lldb::ABISP FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch); protected: - // Classes that inherit from ABI can see and modify these - ABI(lldb::ProcessSP process_sp) { - if (process_sp.get()) - m_process_wp = process_sp; + ABI(lldb::ProcessSP process_sp, std::unique_ptr<llvm::MCRegisterInfo> info_up) + : m_process_wp(process_sp), m_mc_register_info_up(std::move(info_up)) { + assert(m_mc_register_info_up && "ABI must have MCRegisterInfo"); } + /// Utility function to construct a MCRegisterInfo using the ArchSpec triple. + /// Plugins wishing to customize the construction can construct the + /// MCRegisterInfo themselves. + static std::unique_ptr<llvm::MCRegisterInfo> + MakeMCRegisterInfo(const ArchSpec &arch); + lldb::ProcessWP m_process_wp; + std::unique_ptr<llvm::MCRegisterInfo> m_mc_register_info_up; private: DISALLOW_COPY_AND_ASSIGN(ABI); diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h index 2bf3f32b5eef..ac72b98e5e1a 100644 --- a/include/lldb/Target/DynamicLoader.h +++ b/include/lldb/Target/DynamicLoader.h @@ -148,13 +148,9 @@ public: /// The equivalent symbol list - any equivalent symbols found are appended /// to this list. /// - /// \return - /// Number of equivalent symbols found. - virtual size_t FindEquivalentSymbols(Symbol *original_symbol, - ModuleList &module_list, - SymbolContextList &equivalent_symbols) { - return 0; - } + virtual void FindEquivalentSymbols(Symbol *original_symbol, + ModuleList &module_list, + SymbolContextList &equivalent_symbols) {} /// Ask if it is ok to try and load or unload an shared library (image). /// diff --git a/include/lldb/Target/Language.h b/include/lldb/Target/Language.h index 6ea6029bdace..b49e96eeac17 100644 --- a/include/lldb/Target/Language.h +++ b/include/lldb/Target/Language.h @@ -20,6 +20,7 @@ #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/DataFormatters/StringPrinter.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" @@ -266,12 +267,9 @@ public: static std::set<lldb::LanguageType> GetSupportedLanguages(); - static void GetLanguagesSupportingTypeSystems( - std::set<lldb::LanguageType> &languages, - std::set<lldb::LanguageType> &languages_for_expressions); - - static void - GetLanguagesSupportingREPLs(std::set<lldb::LanguageType> &languages); + static LanguageSet GetLanguagesSupportingTypeSystems(); + static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions(); + static LanguageSet GetLanguagesSupportingREPLs(); protected: // Classes that inherit from Language can see and modify these diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h index 3ba58c0ec741..6f643df53d1e 100644 --- a/include/lldb/Target/Platform.h +++ b/include/lldb/Target/Platform.h @@ -18,6 +18,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Core/UserSettingsController.h" +#include "lldb/Host/File.h" #include "lldb/Interpreter/Options.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" @@ -257,19 +258,6 @@ public: virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir); - /// Retrieve the system include directories on this platform for the - /// given language. - /// - /// \param[in] lang - /// The language for which the include directories should be queried. - /// - /// \param[out] directories - /// The include directories for this system. - virtual std::vector<std::string> - GetSystemIncludeDirectories(lldb::LanguageType lang) { - return {}; - } - virtual UserIDResolver &GetUserIDResolver() = 0; /// Locate a file for a platform. @@ -518,8 +506,9 @@ public: virtual Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions); - virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, - uint32_t mode, Status &error) { + virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, + File::OpenOptions flags, uint32_t mode, + Status &error) { return UINT64_MAX; } diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index f85069ea0906..a4ef1cc40414 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -50,6 +50,7 @@ #include "lldb/lldb-private.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Threading.h" #include "llvm/Support/VersionTuple.h" namespace lldb_private { @@ -680,10 +681,19 @@ public: /// shared library load state. /// /// \return - /// The number of shared libraries that were loaded - virtual size_t LoadModules() { return 0; } + /// A status object indicating if the operation was sucessful or not. + virtual llvm::Error LoadModules() { + return llvm::make_error<llvm::StringError>("Not implemented.", + llvm::inconvertibleErrorCode()); + } - virtual size_t LoadModules(LoadedModuleInfoList &) { return 0; } + /// Query remote GDBServer for a detailed loaded library list + /// \return + /// The list of modules currently loaded by the process, or an error. + virtual llvm::Expected<LoadedModuleInfoList> GetLoadedModuleList() { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Not implemented"); + } protected: virtual JITLoaderList &GetJITLoaders(); @@ -1186,6 +1196,9 @@ public: /// VersionTuple is returner. virtual llvm::VersionTuple GetHostOSVersion() { return llvm::VersionTuple(); } + /// \return the macCatalyst version of the host OS. + virtual llvm::VersionTuple GetHostMacCatalystVersion() { return {}; } + /// Get the target object pointer for this module. /// /// \return @@ -2259,6 +2272,8 @@ public: void ClearPreResumeAction(PreResumeActionCallback callback, void *baton); ProcessRunLock &GetRunLock(); + + bool CurrentThreadIsPrivateStateThread(); virtual Status SendEventData(const char *data) { Status return_error("Sending an event is not supported for this process."); @@ -2453,6 +2468,11 @@ public: return Status("Not implemented"); } + // This calls a function of the form "void * (*)(void)". + bool CallVoidArgVoidPtrReturn(const Address *address, + lldb::addr_t &returned_func, + bool trap_exceptions = false); + protected: void SetState(lldb::EventSP &event_sp); @@ -2732,7 +2752,7 @@ protected: enum { eCanJITDontKnow = 0, eCanJITYes, eCanJITNo } m_can_jit; std::unique_ptr<UtilityFunction> m_dlopen_utility_func_up; - std::once_flag m_dlopen_utility_func_flag_once; + llvm::once_flag m_dlopen_utility_func_flag_once; size_t RemoveBreakpointOpcodesFromBuffer(lldb::addr_t addr, size_t size, uint8_t *buf) const; diff --git a/include/lldb/Target/RemoteAwarePlatform.h b/include/lldb/Target/RemoteAwarePlatform.h index 524332f948a5..55d5ff673f1d 100644 --- a/include/lldb/Target/RemoteAwarePlatform.h +++ b/include/lldb/Target/RemoteAwarePlatform.h @@ -22,7 +22,7 @@ public: bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; - lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, + lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) override; bool CloseFile(lldb::user_id_t fd, Status &error) override; diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h index 4e6e79befc6a..d2e5795162cf 100644 --- a/include/lldb/Target/StackFrame.h +++ b/include/lldb/Target/StackFrame.h @@ -108,17 +108,19 @@ public: StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, - const SymbolContext *sc_ptr); + bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr); StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, - lldb::addr_t pc, const SymbolContext *sc_ptr); + lldb::addr_t pc, bool behaves_like_zeroth_frame, + const SymbolContext *sc_ptr); StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, - const Address &pc, const SymbolContext *sc_ptr); + const Address &pc, bool behaves_like_zeroth_frame, + const SymbolContext *sc_ptr); ~StackFrame() override; @@ -367,6 +369,12 @@ public: /// may have limited support for inspecting variables. bool IsArtificial() const; + /// Query whether this frame behaves like the zeroth frame, in the sense + /// that its pc value might not immediately follow a call (and thus might + /// be the first address of its function). True for actual frame zero as + /// well as any other frame with the same trait. + bool BehavesLikeZerothFrame() const; + /// Query this frame to find what frame it is in this Thread's /// StackFrameList. /// @@ -511,6 +519,7 @@ private: bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == // LLDB_INVALID_ADDRESS Kind m_stack_frame_kind; + bool m_behaves_like_zeroth_frame; lldb::VariableListSP m_variable_list_sp; ValueObjectList m_variable_list_value_objects; // Value objects for each // variable in diff --git a/include/lldb/Target/StopInfo.h b/include/lldb/Target/StopInfo.h index 59033b1b6441..61e1fbd4bd46 100644 --- a/include/lldb/Target/StopInfo.h +++ b/include/lldb/Target/StopInfo.h @@ -33,10 +33,13 @@ public: lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); } - // The value of the StopInfo depends on the StopReason. StopReason - // Meaning ---------------------------------------------- - // eStopReasonBreakpoint BreakpointSiteID eStopReasonSignal - // Signal number eStopReasonWatchpoint WatchpointLocationID + // The value of the StopInfo depends on the StopReason. + // + // StopReason Meaning + // ------------------------------------------------ + // eStopReasonBreakpoint BreakpointSiteID + // eStopReasonSignal Signal number + // eStopReasonWatchpoint WatchpointLocationID // eStopReasonPlanComplete No significance uint64_t GetValue() const { return m_value; } diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index 4ed11afc31ba..e465046959f2 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -121,7 +121,7 @@ public: FileSpecList GetExecutableSearchPaths(); - void AppendExecutableSearchPaths(const FileSpec&); + void AppendExecutableSearchPaths(const FileSpec &); FileSpecList GetDebugFileSearchPaths(); @@ -139,6 +139,8 @@ public: bool GetEnableSyntheticValue() const; + uint32_t GetMaxZeroPaddingInFloatFormat() const; + uint32_t GetMaximumNumberOfChildrenToDisplay() const; uint32_t GetMaximumSizeOfStringSummary() const; @@ -495,7 +497,7 @@ public: static void SetDefaultArchitecture(const ArchSpec &arch); - /// Find a binary on the system and return its Module, + /// Find a binary on the system and return its Module, /// or return an existing Module that is already in the Target. /// /// Given a ModuleSpec, find a binary satisifying that specification, @@ -507,34 +509,33 @@ public: /// e.g. UUID, architecture, file path. /// /// \param[in] notify - /// If notify is true, and the Module is new to this Target, - /// Target::ModulesDidLoad will be called. - /// If notify is false, it is assumed that the caller is adding - /// multiple Modules and will call ModulesDidLoad with the + /// If notify is true, and the Module is new to this Target, + /// Target::ModulesDidLoad will be called. + /// If notify is false, it is assumed that the caller is adding + /// multiple Modules and will call ModulesDidLoad with the /// full list at the end. /// ModulesDidLoad must be called when a Module/Modules have /// been added to the target, one way or the other. /// /// \param[out] error_ptr - /// Optional argument, pointing to a Status object to fill in + /// Optional argument, pointing to a Status object to fill in /// with any results / messages while attempting to find/load /// this binary. Many callers will be internal functions that /// will handle / summarize the failures in a custom way and /// don't use these messages. /// - /// \return + /// \return /// An empty ModuleSP will be returned if no matching file /// was found. If error_ptr was non-nullptr, an error message /// will likely be provided. - lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, - bool notify, + lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr = nullptr); // Settings accessors static const lldb::TargetPropertiesSP &GetGlobalProperties(); - std::recursive_mutex &GetAPIMutex() { return m_mutex; } + std::recursive_mutex &GetAPIMutex(); void DeleteCurrentProcess(); @@ -599,7 +600,7 @@ public: const FileSpecList *containingModules, const FileSpecList *source_file_list, const std::unordered_set<std::string> &function_names, - RegularExpression &source_regex, bool internal, bool request_hardware, + RegularExpression source_regex, bool internal, bool request_hardware, LazyBool move_to_nearest_code); // Use this to create a breakpoint from a load address @@ -622,7 +623,7 @@ public: // target setting, else we use the values passed in lldb::BreakpointSP CreateFuncRegexBreakpoint( const FileSpecList *containingModules, - const FileSpecList *containingSourceFiles, RegularExpression &func_regexp, + const FileSpecList *containingSourceFiles, RegularExpression func_regexp, lldb::LanguageType requested_language, LazyBool skip_prologue, bool internal, bool request_hardware); @@ -644,14 +645,11 @@ public: Args *additional_args = nullptr, Status *additional_args_error = nullptr); - lldb::BreakpointSP - CreateScriptedBreakpoint(const llvm::StringRef class_name, - const FileSpecList *containingModules, - const FileSpecList *containingSourceFiles, - bool internal, - bool request_hardware, - StructuredData::ObjectSP extra_args_sp, - Status *creation_error = nullptr); + lldb::BreakpointSP CreateScriptedBreakpoint( + const llvm::StringRef class_name, const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, bool internal, + bool request_hardware, StructuredData::ObjectSP extra_args_sp, + Status *creation_error = nullptr); // This is the same as the func_name breakpoint except that you can specify a // vector of names. This is cheaper than a regular expression breakpoint in @@ -690,43 +688,42 @@ public: } WatchpointList &GetWatchpointList() { return m_watchpoint_list; } - + // Manages breakpoint names: void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error); - - void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name, + + void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name, Status &error); - - void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, - ConstString name); - - BreakpointName *FindBreakpointName(ConstString name, bool can_create, + + void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, ConstString name); + + BreakpointName *FindBreakpointName(ConstString name, bool can_create, Status &error); - + void DeleteBreakpointName(ConstString name); - + void ConfigureBreakpointName(BreakpointName &bp_name, const BreakpointOptions &options, const BreakpointName::Permissions &permissions); - void ApplyNameToBreakpoints(BreakpointName &bp_name); - + void ApplyNameToBreakpoints(BreakpointName &bp_name); + // This takes ownership of the name obj passed in. void AddBreakpointName(BreakpointName *bp_name); - + void GetBreakpointNames(std::vector<std::string> &names); - - //This call removes ALL breakpoints regardless of permission. + + // This call removes ALL breakpoints regardless of permission. void RemoveAllBreakpoints(bool internal_also = false); - + // This removes all the breakpoints, but obeys the ePermDelete on them. void RemoveAllowedBreakpoints(); void DisableAllBreakpoints(bool internal_also = false); - + void DisableAllowedBreakpoints(); void EnableAllBreakpoints(bool internal_also = false); - + void EnableAllowedBreakpoints(); bool DisableBreakpointByID(lldb::break_id_t break_id); @@ -1027,9 +1024,11 @@ public: PathMappingList &GetImageSearchPathList(); - TypeSystem *GetScratchTypeSystemForLanguage(Status *error, - lldb::LanguageType language, - bool create_on_demand = true); + llvm::Expected<TypeSystem &> + GetScratchTypeSystemForLanguage(lldb::LanguageType language, + bool create_on_demand = true); + + std::vector<TypeSystem *> GetScratchTypeSystems(bool create_on_demand = true); PersistentExpressionState * GetPersistentExpressionStateForLanguage(lldb::LanguageType language); @@ -1038,11 +1037,12 @@ public: // parameters have the same meaning as for the UserExpression constructor. // Returns a new-ed object which the caller owns. - UserExpression *GetUserExpressionForLanguage( - llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options, - ValueObject *ctx_obj, Status &error); + UserExpression * + GetUserExpressionForLanguage(llvm::StringRef expr, llvm::StringRef prefix, + lldb::LanguageType language, + Expression::ResultType desired_type, + const EvaluateExpressionOptions &options, + ValueObject *ctx_obj, Status &error); // Creates a FunctionCaller for the given language, the rest of the // parameters have the same meaning as for the FunctionCaller constructor. @@ -1104,8 +1104,7 @@ public: llvm::StringRef expression, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, const EvaluateExpressionOptions &options = EvaluateExpressionOptions(), - std::string *fixed_expression = nullptr, - ValueObject *ctx_obj = nullptr); + std::string *fixed_expression = nullptr, ValueObject *ctx_obj = nullptr); lldb::ExpressionVariableSP GetPersistentVariable(ConstString name); @@ -1116,6 +1115,24 @@ public: lldb::addr_t GetPersistentSymbol(ConstString name); + /// This method will return the address of the starting function for + /// this binary, e.g. main() or its equivalent. This can be used as + /// an address of a function that is not called once a binary has + /// started running - e.g. as a return address for inferior function + /// calls that are unambiguous completion of the function call, not + /// called during the course of the inferior function code running. + /// + /// If no entry point can be found, an invalid address is returned. + /// + /// \param [out] err + /// This object will be set to failure if no entry address could + /// be found, and may contain a helpful error message. + // + /// \return + /// Returns the entry address for this program, or an error + /// if none can be found. + llvm::Expected<lldb_private::Address> GetEntryPointAddress(); + // Target Stop Hooks class StopHook : public UserID { public: @@ -1147,7 +1164,9 @@ public: void SetIsActive(bool is_active) { m_active = is_active; } - void SetAutoContinue(bool auto_continue) {m_auto_continue = auto_continue;} + void SetAutoContinue(bool auto_continue) { + m_auto_continue = auto_continue; + } bool GetAutoContinue() const { return m_auto_continue; } @@ -1242,7 +1261,7 @@ protected: const lldb::ModuleSP &module_sp) override; void NotifyModuleRemoved(const ModuleList &module_list, - const lldb::ModuleSP &module_sp) override; + const lldb::ModuleSP &module_sp) override; void NotifyModuleUpdated(const ModuleList &module_list, const lldb::ModuleSP &old_module_sp, @@ -1269,6 +1288,12 @@ protected: lldb::PlatformSP m_platform_sp; ///< The platform for this target. std::recursive_mutex m_mutex; ///< An API mutex that is used by the lldb::SB* /// classes make the SB interface thread safe + /// When the private state thread calls SB API's - usually because it is + /// running OS plugin or Python ThreadPlan code - it should not block on the + /// API mutex that is held by the code that kicked off the sequence of events + /// that led us to run the code. We hand out this mutex instead when we + /// detect that code is running on the private state thread. + std::recursive_mutex m_private_mutex; Arch m_arch; ModuleList m_images; ///< The list of images for this process (shared /// libraries and anything dynamically loaded). @@ -1277,7 +1302,7 @@ protected: BreakpointList m_internal_breakpoint_list; using BreakpointNameList = std::map<ConstString, BreakpointName *>; BreakpointNameList m_breakpoint_names; - + lldb::BreakpointSP m_last_created_breakpoint; WatchpointList m_watchpoint_list; lldb::WatchpointSP m_last_created_watchpoint; diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h index 7aeaece5b5d5..7c5ff6093baf 100644 --- a/include/lldb/Target/Thread.h +++ b/include/lldb/Target/Thread.h @@ -899,6 +899,7 @@ public: virtual lldb::ThreadPlanSP QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name, + StructuredData::ObjectSP extra_args_sp, bool stop_other_threads, Status &status); // Thread Plan accessors: @@ -1101,6 +1102,17 @@ public: // right even if you have not calculated this yourself, or if it disagrees // with what you might have calculated. virtual lldb::StopInfoSP GetPrivateStopInfo(); + + // Calculate the stop info that will be shown to lldb clients. For instance, + // a "step out" is implemented by running to a breakpoint on the function + // return PC, so the process plugin initially sets the stop info to a + // StopInfoBreakpoint. But once we've run the ShouldStop machinery, we + // discover that there's a completed ThreadPlanStepOut, and that's really + // the StopInfo we want to show. That will happen naturally the next + // time GetStopInfo is called, but if you want to force the replacement, + // you can call this. + + void CalculatePublicStopInfo(); // Ask the thread subclass to set its stop info. // diff --git a/include/lldb/Target/ThreadPlanPython.h b/include/lldb/Target/ThreadPlanPython.h index 3825bf6ee4f3..0ee559b12960 100644 --- a/include/lldb/Target/ThreadPlanPython.h +++ b/include/lldb/Target/ThreadPlanPython.h @@ -12,6 +12,8 @@ #include <string> +#include "lldb/lldb-forward.h" + #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" @@ -29,7 +31,8 @@ namespace lldb_private { class ThreadPlanPython : public ThreadPlan { public: - ThreadPlanPython(Thread &thread, const char *class_name); + ThreadPlanPython(Thread &thread, const char *class_name, + StructuredDataImpl *args_data); ~ThreadPlanPython() override; void GetDescription(Stream *s, lldb::DescriptionLevel level) override; @@ -55,6 +58,11 @@ protected: private: std::string m_class_name; + StructuredDataImpl *m_args_data; // We own this, but the implementation + // has to manage the UP (since that is + // how it gets stored in the + // SBStructuredData). + std::string m_error_str; StructuredData::ObjectSP m_implementation_sp; bool m_did_push; diff --git a/include/lldb/Target/Unwind.h b/include/lldb/Target/Unwind.h index a648e063e34b..652918ddad43 100644 --- a/include/lldb/Target/Unwind.h +++ b/include/lldb/Target/Unwind.h @@ -37,9 +37,10 @@ public: lldb::addr_t cfa; lldb::addr_t pc; uint32_t idx; + bool behaves_like_zeroth_frame = (end_idx == 0); for (idx = 0; idx < end_idx; idx++) { - if (!DoGetFrameInfoAtIndex(idx, cfa, pc)) { + if (!DoGetFrameInfoAtIndex(idx, cfa, pc, behaves_like_zeroth_frame)) { break; } } @@ -47,9 +48,9 @@ public: } bool GetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &pc) { + lldb::addr_t &pc, bool &behaves_like_zeroth_frame) { std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); - return DoGetFrameInfoAtIndex(frame_idx, cfa, pc); + return DoGetFrameInfoAtIndex(frame_idx, cfa, pc, behaves_like_zeroth_frame); } lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) { @@ -66,7 +67,8 @@ protected: virtual uint32_t DoGetFrameCount() = 0; virtual bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, - lldb::addr_t &pc) = 0; + lldb::addr_t &pc, + bool &behaves_like_zeroth_frame) = 0; virtual lldb::RegisterContextSP DoCreateRegisterContextForFrame(StackFrame *frame) = 0; diff --git a/include/lldb/Utility/AnsiTerminal.h b/include/lldb/Utility/AnsiTerminal.h index 1473c60eeaf2..21375e3821ca 100644 --- a/include/lldb/Utility/AnsiTerminal.h +++ b/include/lldb/Utility/AnsiTerminal.h @@ -55,7 +55,7 @@ #include <string> -namespace lldb_utility { +namespace lldb_private { namespace ansi { @@ -137,4 +137,4 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format, return fmt; } } -} +} // namespace lldb_private diff --git a/include/lldb/Utility/ArchSpec.h b/include/lldb/Utility/ArchSpec.h index 7a32556310c4..3bfc988abf0b 100644 --- a/include/lldb/Utility/ArchSpec.h +++ b/include/lldb/Utility/ArchSpec.h @@ -122,6 +122,7 @@ public: eCore_thumbv7em, eCore_arm_arm64, eCore_arm_armv8, + eCore_arm_arm64_32, eCore_arm_aarch64, eCore_mips32, @@ -183,6 +184,8 @@ public: eCore_uknownMach32, eCore_uknownMach64, + eCore_arc, // little endian ARC + kNumCores, kCore_invalid, @@ -268,7 +271,7 @@ public: static bool ContainsOnlyArch(const llvm::Triple &normalized_triple); static void ListSupportedArchNames(StringList &list); - static size_t AutoComplete(CompletionRequest &request); + static void AutoComplete(CompletionRequest &request); /// Returns a static string representing the current architecture. /// diff --git a/include/lldb/Utility/Args.h b/include/lldb/Utility/Args.h index 6f258498d5ba..7987787e7af5 100644 --- a/include/lldb/Utility/Args.h +++ b/include/lldb/Utility/Args.h @@ -35,6 +35,7 @@ public: private: friend class Args; std::unique_ptr<char[]> ptr; + char quote; char *data() { return ptr.get(); } @@ -42,12 +43,12 @@ public: ArgEntry() = default; ArgEntry(llvm::StringRef str, char quote); - llvm::StringRef ref; - char quote; + llvm::StringRef ref() const { return c_str(); } const char *c_str() const { return ptr.get(); } /// Returns true if this argument was quoted in any way. bool IsQuoted() const { return quote != '\0'; } + char GetQuoteChar() const { return quote; } }; /// Construct with an option command string. @@ -121,7 +122,6 @@ public: const char *GetArgumentAtIndex(size_t idx) const; llvm::ArrayRef<ArgEntry> entries() const { return m_entries; } - char GetArgumentQuoteCharAtIndex(size_t idx) const; using const_iterator = std::vector<ArgEntry>::const_iterator; @@ -168,8 +168,8 @@ public: /// Appends a new argument to the end of the list argument list. /// - /// \param[in] arg_cstr - /// The new argument as a NULL terminated C string. + /// \param[in] arg_str + /// The new argument. /// /// \param[in] quote_char /// If the argument was originally quoted, put in the quote char here. @@ -179,30 +179,27 @@ public: void AppendArguments(const char **argv); - /// Insert the argument value at index \a idx to \a arg_cstr. + /// Insert the argument value at index \a idx to \a arg_str. /// /// \param[in] idx /// The index of where to insert the argument. /// - /// \param[in] arg_cstr - /// The new argument as a NULL terminated C string. + /// \param[in] arg_str + /// The new argument. /// /// \param[in] quote_char /// If the argument was originally quoted, put in the quote char here. - /// - /// \return - /// The NULL terminated C string of the copy of \a arg_cstr. void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char = '\0'); - /// Replaces the argument value at index \a idx to \a arg_cstr if \a idx is + /// Replaces the argument value at index \a idx to \a arg_str if \a idx is /// a valid argument index. /// /// \param[in] idx /// The index of the argument that will have its value replaced. /// - /// \param[in] arg_cstr - /// The new argument as a NULL terminated C string. + /// \param[in] arg_str + /// The new argument. /// /// \param[in] quote_char /// If the argument was originally quoted, put in the quote char here. @@ -238,12 +235,12 @@ public: /// \see Args::GetArgumentAtIndex (size_t) const void Shift(); - /// Inserts a class owned copy of \a arg_cstr at the beginning of the + /// Inserts a class owned copy of \a arg_str at the beginning of the /// argument vector. /// - /// A copy \a arg_cstr will be made. + /// A copy \a arg_str will be made. /// - /// \param[in] arg_cstr + /// \param[in] arg_str /// The argument to push on the front of the argument stack. /// /// \param[in] quote_char @@ -255,10 +252,6 @@ public: // For re-setting or blanking out the list of arguments. void Clear(); - static const char *StripSpaces(std::string &s, bool leading = true, - bool trailing = true, - bool return_null_if_empty = true); - static bool UInt64ValueIsValidForByteSize(uint64_t uval64, size_t total_byte_size) { if (total_byte_size > 8) diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h deleted file mode 100644 index 6cd5f332ef95..000000000000 --- a/include/lldb/Utility/CleanUp.h +++ /dev/null @@ -1,42 +0,0 @@ -//===-- CleanUp.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_CleanUp_h_ -#define liblldb_CleanUp_h_ - -#include "lldb/lldb-public.h" -#include <functional> - -namespace lldb_private { - -/// Run a cleanup function on scope exit unless it's explicitly disabled. -class CleanUp { - std::function<void()> Clean; - -public: - /// Register a cleanup function which applies \p Func to a list of arguments. - /// Use caution with arguments which are references: they will be copied. - template <typename F, typename... Args> - CleanUp(F &&Func, Args &&... args) - : Clean(std::bind(std::forward<F>(Func), std::forward<Args>(args)...)) {} - - ~CleanUp() { - if (Clean) - Clean(); - } - - /// Disable the cleanup. - void disable() { Clean = nullptr; } - - // Prevent cleanups from being run more than once. - DISALLOW_COPY_AND_ASSIGN(CleanUp); -}; - -} // namespace lldb_private - -#endif // #ifndef liblldb_CleanUp_h_ diff --git a/include/lldb/Utility/CompletionRequest.h b/include/lldb/Utility/CompletionRequest.h index f5ccb01ca16f..570f626ac54e 100644 --- a/include/lldb/Utility/CompletionRequest.h +++ b/include/lldb/Utility/CompletionRequest.h @@ -16,25 +16,53 @@ #include "llvm/ADT/StringSet.h" namespace lldb_private { +enum class CompletionMode { + // The current token has been completed. + Normal, + // The current token has been partially completed. This means that we found + // a completion, but that the completed token is still incomplete. Examples + // for this are file paths, where we want to complete "/bi" to "/bin/", but + // the file path token is still incomplete after the completion. Clients + // should not indicate to the user that this is a full completion (e.g. by + // not inserting the usual trailing space after a successful completion). + Partial, + // The full line has been rewritten by the completion. + RewriteLine, +}; + class CompletionResult { +public: /// A single completion and all associated data. - struct Completion { - Completion(llvm::StringRef completion, llvm::StringRef description) - : m_completion(completion.str()), m_descripton(description.str()) {} + class Completion { std::string m_completion; std::string m_descripton; + CompletionMode m_mode; + + public: + Completion(llvm::StringRef completion, llvm::StringRef description, + CompletionMode mode) + : m_completion(completion.str()), m_descripton(description.str()), + m_mode(mode) {} + const std::string &GetCompletion() const { return m_completion; } + const std::string &GetDescription() const { return m_descripton; } + CompletionMode GetMode() const { return m_mode; } /// Generates a string that uniquely identifies this completion result. std::string GetUniqueKey() const; }; + +private: std::vector<Completion> m_results; /// List of added completions so far. Used to filter out duplicates. llvm::StringSet<> m_added_values; public: - void AddResult(llvm::StringRef completion, llvm::StringRef description); + void AddResult(llvm::StringRef completion, llvm::StringRef description, + CompletionMode mode); + + llvm::ArrayRef<Completion> GetResults() const { return m_results; } /// Adds all collected completion matches to the given list. /// The list will be cleared before the results are added. The number of @@ -68,18 +96,10 @@ public: /// the cursor is at the start of the line. The completion starts from /// this cursor position. /// - /// \param [in] match_start_point - /// \param [in] max_return_elements - /// If there is a match that is expensive to compute, these are here to - /// allow you to compute the completions in batches. Start the - /// completion from match_start_point, and return match_return_elements - /// elements. - /// /// \param [out] result /// The CompletionResult that will be filled with the results after this /// request has been handled. CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, - int match_start_point, int max_return_elements, CompletionResult &result); llvm::StringRef GetRawLine() const { return m_command; } @@ -90,21 +110,25 @@ public: Args &GetParsedLine() { return m_parsed_line; } - const Args &GetPartialParsedLine() const { return m_partial_parsed_line; } - - void SetCursorIndex(int i) { m_cursor_index = i; } - int GetCursorIndex() const { return m_cursor_index; } - - void SetCursorCharPosition(int pos) { m_cursor_char_position = pos; } - int GetCursorCharPosition() const { return m_cursor_char_position; } - - int GetMatchStartPoint() const { return m_match_start_point; } + const Args::ArgEntry &GetParsedArg() { + return GetParsedLine()[GetCursorIndex()]; + } - int GetMaxReturnElements() const { return m_max_return_elements; } + /// Drops the first argument from the argument list. + void ShiftArguments() { + m_cursor_index--; + m_parsed_line.Shift(); + } - bool GetWordComplete() { return m_word_complete; } + /// Adds an empty argument at the end of the argument list and moves + /// the cursor to this new argument. + void AppendEmptyArgument() { + m_parsed_line.AppendArgument(llvm::StringRef()); + m_cursor_index++; + m_cursor_char_position = 0; + } - void SetWordComplete(bool v) { m_word_complete = v; } + size_t GetCursorIndex() const { return m_cursor_index; } /// Adds a possible completion string. If the completion was already /// suggested before, it will not be added to the list of results. A copy of @@ -112,11 +136,31 @@ public: /// afterwards. /// /// \param match The suggested completion. - /// \param match An optional description of the completion string. The + /// \param completion An optional description of the completion string. The /// description will be displayed to the user alongside the completion. + /// \param mode The CompletionMode for this completion. void AddCompletion(llvm::StringRef completion, - llvm::StringRef description = "") { - m_result.AddResult(completion, description); + llvm::StringRef description = "", + CompletionMode mode = CompletionMode::Normal) { + m_result.AddResult(completion, description, mode); + } + + /// Adds a possible completion string if the completion would complete the + /// current argument. + /// + /// \param match The suggested completion. + /// \param description An optional description of the completion string. The + /// description will be displayed to the user alongside the completion. + template <CompletionMode M = CompletionMode::Normal> + void TryCompleteCurrentArg(llvm::StringRef completion, + llvm::StringRef description = "") { + // Trying to rewrite the whole line while checking for the current + // argument never makes sense. Completion modes are always hardcoded, so + // this can be a static_assert. + static_assert(M != CompletionMode::RewriteLine, + "Shouldn't rewrite line with this function"); + if (completion.startswith(GetCursorArgumentPrefix())) + AddCompletion(completion, description, M); } /// Adds multiple possible completion strings. @@ -125,8 +169,8 @@ public: /// /// \see AddCompletion void AddCompletions(const StringList &completions) { - for (std::size_t i = 0; i < completions.GetSize(); ++i) - AddCompletion(completions.GetStringAtIndex(i)); + for (const std::string &completion : completions) + AddCompletion(completion); } /// Adds multiple possible completion strings alongside their descriptions. @@ -145,16 +189,8 @@ public: descriptions.GetStringAtIndex(i)); } - std::size_t GetNumberOfMatches() const { - return m_result.GetNumberOfResults(); - } - - llvm::StringRef GetCursorArgument() const { - return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); - } - llvm::StringRef GetCursorArgumentPrefix() const { - return GetCursorArgument().substr(0, GetCursorCharPosition()); + return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); } private: @@ -164,22 +200,10 @@ private: unsigned m_raw_cursor_pos; /// The command line parsed as arguments. Args m_parsed_line; - /// The command line until the cursor position parsed as arguments. - Args m_partial_parsed_line; /// The index of the argument in which the completion cursor is. - int m_cursor_index; + size_t m_cursor_index; /// The cursor position in the argument indexed by m_cursor_index. - int m_cursor_char_position; - /// If there is a match that is expensive - /// to compute, these are here to allow you to compute the completions in - /// batches. Start the completion from \amatch_start_point, and return - /// \amatch_return_elements elements. - // FIXME: These two values are not implemented. - int m_match_start_point; - int m_max_return_elements; - /// \btrue if this is a complete option value (a space will be inserted - /// after the completion.) \bfalse otherwise. - bool m_word_complete = false; + size_t m_cursor_char_position; /// The result this request is supposed to fill out. /// We keep this object private to ensure that no backend can in any way diff --git a/include/lldb/Utility/ConstString.h b/include/lldb/Utility/ConstString.h index 8576c18ddcd8..9a9ee458239f 100644 --- a/include/lldb/Utility/ConstString.h +++ b/include/lldb/Utility/ConstString.h @@ -10,6 +10,7 @@ #define liblldb_ConstString_h_ #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/FormatVariadic.h" #include <stddef.h> @@ -204,9 +205,7 @@ public: /// \param[in] rhs /// Another string object to compare this object to. /// - /// \return - /// \li \b true if this object is not equal to \a rhs. - /// \li \b false if this object is equal to \a rhs. + /// \return \b true if this object is not equal to \a rhs, false otherwise. bool operator!=(const char *rhs) const { return !(*this == rhs); } bool operator<(ConstString rhs) const; @@ -218,8 +217,7 @@ public: /// /// If \a value_if_empty is nullptr, then nullptr will be returned. /// - /// \return - /// Returns \a value_if_empty if the string is empty, otherwise + /// \return Returns \a value_if_empty if the string is empty, otherwise /// the C string value contained in this object. const char *AsCString(const char *value_if_empty = nullptr) const { return (IsEmpty() ? value_if_empty : m_string); @@ -269,7 +267,7 @@ public: /// in a pointer comparison since all strings are in a uniqued in a global /// string pool. /// - /// \param[in] rhs + /// \param[in] lhs /// The Left Hand Side const ConstString object reference. /// /// \param[in] rhs @@ -279,9 +277,7 @@ public: /// Case sensitivity. If true, case sensitive equality /// will be tested, otherwise character case will be ignored /// - /// \return - /// \li \b true if this object is equal to \a rhs. - /// \li \b false if this object is not equal to \a rhs. + /// \return \b true if this object is equal to \a rhs, \b false otherwise. static bool Equals(ConstString lhs, ConstString rhs, const bool case_sensitive = true); @@ -305,10 +301,7 @@ public: /// Case sensitivity of compare. If true, case sensitive compare /// will be performed, otherwise character case will be ignored /// - /// \return - /// \li -1 if lhs < rhs - /// \li 0 if lhs == rhs - /// \li 1 if lhs > rhs + /// \return -1 if lhs < rhs, 0 if lhs == rhs, 1 if lhs > rhs static int Compare(ConstString lhs, ConstString rhs, const bool case_sensitive = true); @@ -445,6 +438,14 @@ public: static size_t StaticMemorySize(); protected: + template <typename T> friend struct ::llvm::DenseMapInfo; + /// Only used by DenseMapInfo. + static ConstString FromStringPoolPointer(const char *ptr) { + ConstString s; + s.m_string = ptr; + return s; + }; + // Member variables const char *m_string; }; @@ -459,6 +460,27 @@ template <> struct format_provider<lldb_private::ConstString> { static void format(const lldb_private::ConstString &CS, llvm::raw_ostream &OS, llvm::StringRef Options); }; + +/// DenseMapInfo implementation. +/// \{ +template <> struct DenseMapInfo<lldb_private::ConstString> { + static inline lldb_private::ConstString getEmptyKey() { + return lldb_private::ConstString::FromStringPoolPointer( + DenseMapInfo<const char *>::getEmptyKey()); + } + static inline lldb_private::ConstString getTombstoneKey() { + return lldb_private::ConstString::FromStringPoolPointer( + DenseMapInfo<const char *>::getTombstoneKey()); + } + static unsigned getHashValue(lldb_private::ConstString val) { + return DenseMapInfo<const char *>::getHashValue(val.m_string); + } + static bool isEqual(lldb_private::ConstString LHS, + lldb_private::ConstString RHS) { + return LHS == RHS; + } +}; +/// \} } #endif // liblldb_ConstString_h_ diff --git a/include/lldb/Utility/DataEncoder.h b/include/lldb/Utility/DataEncoder.h index 19b7cef9f0ca..7d44afd2ce69 100644 --- a/include/lldb/Utility/DataEncoder.h +++ b/include/lldb/Utility/DataEncoder.h @@ -204,12 +204,11 @@ public: /// m_addr_size member variable and should be set correctly prior to /// extracting any address values. /// - /// \param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. + /// \param[in] offset + /// The offset where to encode the address. + /// + /// \param[in] addr + /// The address to encode. /// /// \return /// The next valid offset within data if the put operation @@ -220,19 +219,18 @@ public: /// /// Encodes a C string into the existing data including the terminating /// - /// \param[in,out] offset_ptr - /// A pointer to an offset within the data that will be advanced - /// by the appropriate number of bytes if the value is extracted - /// correctly. If the offset is out of bounds or there are not - /// enough bytes to extract this value, the offset will be left - /// unmodified. + /// \param[in] offset + /// The offset where to encode the string. + /// + /// \param[in] cstr + /// The string to encode. /// /// \return /// A pointer to the C string value in the data. If the offset /// pointed to by \a offset_ptr is out of bounds, or if the /// offset plus the length of the C string is out of bounds, /// NULL will be returned. - uint32_t PutCString(uint32_t offset_ptr, const char *cstr); + uint32_t PutCString(uint32_t offset, const char *cstr); lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; } diff --git a/include/lldb/Utility/DataExtractor.h b/include/lldb/Utility/DataExtractor.h index 74174b34ce99..333baf9fd349 100644 --- a/include/lldb/Utility/DataExtractor.h +++ b/include/lldb/Utility/DataExtractor.h @@ -14,6 +14,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataExtractor.h" #include <cassert> #include <stdint.h> @@ -167,9 +168,8 @@ public: /// the beginning of each line and can be offset by base address \a /// base_addr. \a num_per_line objects will be displayed on each line. /// - /// \param[in] s - /// The stream to dump the output to. If nullptr the output will - /// be dumped to Log(). + /// \param[in] log + /// The log to dump the output to. /// /// \param[in] offset /// The offset into the data at which to start dumping. @@ -362,30 +362,29 @@ public: /// when say copying a partial data value into a register. /// /// \param[in] src_offset - /// The offset into this data from which to start copying an - /// endian entity + /// The offset into this data from which to start copying an endian + /// entity /// /// \param[in] src_len - /// The length of the endian data to copy from this object - /// into the \a dst object + /// The length of the endian data to copy from this object into the \a + /// dst object /// /// \param[out] dst - /// The buffer where to place the endian data. The data might - /// need to be byte swapped (and appropriately padded with - /// zeroes if \a src_len != \a dst_len) if \a dst_byte_order - /// does not match the byte order in this object. + /// The buffer where to place the endian data. The data might need to be + /// byte swapped (and appropriately padded with zeroes if \a src_len != + /// \a dst_len) if \a dst_byte_order does not match the byte order in + /// this object. /// /// \param[in] dst_len - /// The length number of bytes that the endian value will - /// occupy is \a dst. + /// The length number of bytes that the endian value will occupy is \a + /// dst. /// - /// \param[in] byte_order - /// The byte order that the endian value should be in the \a dst - /// buffer. + /// \param[in] dst_byte_order + /// The byte order that the endian value should be in the \a dst buffer. /// /// \return - /// Returns the number of bytes that were copied, or zero if - /// anything goes wrong. + /// Returns the number of bytes that were copied, or zero if anything + /// goes wrong. lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset, lldb::offset_t src_len, void *dst, lldb::offset_t dst_len, @@ -520,7 +519,7 @@ public: /// enough bytes to extract this value, the offset will be left /// unmodified. /// - /// \param[in] byte_size + /// \param[in] size /// The size in byte of the integer to extract. /// /// \param[in] bitfield_bit_size @@ -558,7 +557,7 @@ public: /// enough bytes to extract this value, the offset will be left /// unmodified. /// - /// \param[in] byte_size + /// \param[in] size /// The size in bytes of the integer to extract. /// /// \param[in] bitfield_bit_size @@ -956,14 +955,14 @@ public: /// unmodified. /// /// \return - // The number of bytes consumed during the extraction. + /// The number of bytes consumed during the extraction. uint32_t Skip_LEB128(lldb::offset_t *offset_ptr) const; /// Test the validity of \a offset. /// /// \return - /// \b true if \a offset is a valid offset into the data in this - /// object, \b false otherwise. + /// true if \a offset is a valid offset into the data in this object, + /// false otherwise. bool ValidOffset(lldb::offset_t offset) const { return offset < GetByteSize(); } @@ -971,8 +970,8 @@ public: /// Test the availability of \a length bytes of data from \a offset. /// /// \return - /// \b true if \a offset is a valid offset and there are \a - /// length bytes available at that offset, \b false otherwise. + /// true if \a offset is a valid offset and there are \a + /// length bytes available at that offset, false otherwise. bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const { return length <= BytesLeft(offset); @@ -997,6 +996,11 @@ public: return {GetDataStart(), size_t(GetByteSize())}; } + llvm::DataExtractor GetAsLLVM() const { + return {GetData(), GetByteOrder() == lldb::eByteOrderLittle, + uint8_t(GetAddressByteSize())}; + } + protected: // Member variables const uint8_t *m_start; ///< A pointer to the first byte of data. diff --git a/include/lldb/Utility/FileCollector.h b/include/lldb/Utility/FileCollector.h deleted file mode 100644 index a89206747fe1..000000000000 --- a/include/lldb/Utility/FileCollector.h +++ /dev/null @@ -1,77 +0,0 @@ -//===-- FileCollector.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 LLDB_UTILITY_FILE_COLLECTOR_H -#define LLDB_UTILITY_FILE_COLLECTOR_H - -#include "lldb/Utility/FileSpec.h" - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/VirtualFileSystem.h" - -#include <mutex> - -namespace lldb_private { - -/// Collects files into a directory and generates a mapping that can be used by -/// the VFS. -class FileCollector { -public: - FileCollector(const FileSpec &root, const FileSpec &overlay); - - void AddFile(const llvm::Twine &file); - void AddFile(const FileSpec &file) { return AddFile(file.GetPath()); } - - /// Write the yaml mapping (for the VFS) to the given file. - std::error_code WriteMapping(const FileSpec &mapping_file); - - /// Copy the files into the root directory. - /// - /// When stop_on_error is true (the default) we abort as soon as one file - /// cannot be copied. This is relatively common, for example when a file was - /// removed after it was added to the mapping. - std::error_code CopyFiles(bool stop_on_error = true); - -protected: - void AddFileImpl(llvm::StringRef src_path); - - bool MarkAsSeen(llvm::StringRef path) { return m_seen.insert(path).second; } - - bool GetRealPath(llvm::StringRef src_path, - llvm::SmallVectorImpl<char> &result); - - void AddFileToMapping(llvm::StringRef virtual_path, - llvm::StringRef real_path) { - m_vfs_writer.addFileMapping(virtual_path, real_path); - } - - /// Synchronizes adding files. - std::mutex m_mutex; - - /// The root directory where files are copied. - FileSpec m_root; - - /// The root directory where the VFS overlay lives. - FileSpec m_overlay_root; - - /// Tracks already seen files so they can be skipped. - llvm::StringSet<> m_seen; - - /// The yaml mapping writer. - llvm::vfs::YAMLVFSWriter m_vfs_writer; - - /// Caches real_path calls when resolving symlinks. - llvm::StringMap<std::string> m_symlink_map; -}; - -} // namespace lldb_private - -#endif // LLDB_UTILITY_FILE_COLLECTOR_H diff --git a/include/lldb/Utility/FileSpec.h b/include/lldb/Utility/FileSpec.h index f0bc5c89fec7..50ad1f1600d8 100644 --- a/include/lldb/Utility/FileSpec.h +++ b/include/lldb/Utility/FileSpec.h @@ -73,7 +73,7 @@ public: /// \see FileSpec::SetFile (const char *path) explicit FileSpec(llvm::StringRef path, Style style = Style::native); - explicit FileSpec(llvm::StringRef path, const llvm::Triple &Triple); + explicit FileSpec(llvm::StringRef path, const llvm::Triple &triple); /// Copy constructor /// @@ -200,10 +200,8 @@ public: /// only the filename will be compared, else a full comparison /// is done. /// - /// \return - /// \li -1 if \a lhs is less than \a rhs - /// \li 0 if \a lhs is equal to \a rhs - /// \li 1 if \a lhs is greater than \a rhs + /// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs, + /// 1 if \a lhs is greater than \a rhs static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full); static bool Equal(const FileSpec &a, const FileSpec &b, bool full); @@ -322,10 +320,6 @@ public: /// Extract the full path to the file. /// /// Extract the directory and path into an llvm::SmallVectorImpl<> - /// - /// \return - /// Returns a std::string with the directory and filename - /// concatenated. void GetPath(llvm::SmallVectorImpl<char> &path, bool denormalize = true) const; @@ -336,8 +330,7 @@ public: /// filename has no extension, ConstString(nullptr) is returned. The dot /// ('.') character is not returned as part of the extension /// - /// \return - /// Returns the extension of the file as a ConstString object. + /// \return Returns the extension of the file as a ConstString object. ConstString GetFileNameExtension() const; /// Return the filename without the extension part @@ -346,9 +339,7 @@ public: /// without the extension part (e.g. for a file named "foo.bar", "foo" is /// returned) /// - /// \return - /// Returns the filename without extension - /// as a ConstString object. + /// \return Returns the filename without extension as a ConstString object. ConstString GetFileNameStrippingExtension() const; /// Get the memory cost of this object. @@ -372,12 +363,22 @@ public: /// \param[in] path /// A full, partial, or relative path to a file. /// - /// \param[in] resolve_path - /// If \b true, then we will try to resolve links the path using - /// the static FileSpec::Resolve. + /// \param[in] style + /// The style for the given path. void SetFile(llvm::StringRef path, Style style); - void SetFile(llvm::StringRef path, const llvm::Triple &Triple); + /// Change the file specified with a new path. + /// + /// Update the contents of this object with a new path. The path will be + /// split up into a directory and filename and stored as uniqued string + /// values for quick comparison and efficient memory usage. + /// + /// \param[in] path + /// A full, partial, or relative path to a file. + /// + /// \param[in] triple + /// The triple which is used to set the Path style. + void SetFile(llvm::StringRef path, const llvm::Triple &triple); bool IsResolved() const { return m_is_resolved; } diff --git a/include/lldb/Utility/Flags.h b/include/lldb/Utility/Flags.h index 48b14e7d2a2c..aa869eca0c6e 100644 --- a/include/lldb/Utility/Flags.h +++ b/include/lldb/Utility/Flags.h @@ -121,32 +121,6 @@ public: /// \b true if \a bit is 0, \b false otherwise. bool IsClear(ValueType bit) const { return (m_flags & bit) == 0; } - /// Get the number of zero bits in \a m_flags. - /// - /// \return - /// The number of bits that are set to 0 in the current flags. - size_t ClearCount() const { - size_t count = 0; - for (ValueType shift = 0; shift < sizeof(ValueType) * 8; ++shift) { - if ((m_flags & (1u << shift)) == 0) - ++count; - } - return count; - } - - /// Get the number of one bits in \a m_flags. - /// - /// \return - /// The number of bits that are set to 1 in the current flags. - size_t SetCount() const { - size_t count = 0; - for (ValueType mask = m_flags; mask; mask >>= 1) { - if (mask & 1u) - ++count; - } - return count; - } - protected: ValueType m_flags; ///< The flags. }; diff --git a/include/lldb/Utility/GDBRemote.h b/include/lldb/Utility/GDBRemote.h new file mode 100644 index 000000000000..b4adeb368524 --- /dev/null +++ b/include/lldb/Utility/GDBRemote.h @@ -0,0 +1,117 @@ +//===-- GDBRemote.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_GDBRemote_h_ +#define liblldb_GDBRemote_h_ + +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-public.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" + +#include <stddef.h> +#include <stdint.h> +#include <string> +#include <vector> + +namespace lldb_private { + +class StreamGDBRemote : public StreamString { +public: + StreamGDBRemote(); + + StreamGDBRemote(uint32_t flags, uint32_t addr_size, + lldb::ByteOrder byte_order); + + ~StreamGDBRemote() override; + + /// Output a block of data to the stream performing GDB-remote escaping. + /// + /// \param[in] s + /// A block of data. + /// + /// \param[in] src_len + /// The amount of data to write. + /// + /// \return + /// Number of bytes written. + // TODO: Convert this function to take ArrayRef<uint8_t> + int PutEscapedBytes(const void *s, size_t src_len); +}; + +/// GDB remote packet as used by the reproducer and the GDB remote +/// communication history. Packets can be serialized to file. +struct GDBRemotePacket { + + friend llvm::yaml::MappingTraits<GDBRemotePacket>; + + enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; + + GDBRemotePacket() + : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0), + tid(LLDB_INVALID_THREAD_ID) {} + + void Clear() { + packet.data.clear(); + type = ePacketTypeInvalid; + bytes_transmitted = 0; + packet_idx = 0; + tid = LLDB_INVALID_THREAD_ID; + } + + struct BinaryData { + std::string data; + }; + + void Serialize(llvm::raw_ostream &strm) const; + void Dump(Stream &strm) const; + + BinaryData packet; + Type type; + uint32_t bytes_transmitted; + uint32_t packet_idx; + lldb::tid_t tid; + +private: + llvm::StringRef GetTypeStr() const; +}; + +} // namespace lldb_private + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::GDBRemotePacket) +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector<lldb_private::GDBRemotePacket>) + +namespace llvm { +namespace yaml { + +template <> +struct ScalarEnumerationTraits<lldb_private::GDBRemotePacket::Type> { + static void enumeration(IO &io, lldb_private::GDBRemotePacket::Type &value); +}; + +template <> struct ScalarTraits<lldb_private::GDBRemotePacket::BinaryData> { + static void output(const lldb_private::GDBRemotePacket::BinaryData &, void *, + raw_ostream &); + + static StringRef input(StringRef, void *, + lldb_private::GDBRemotePacket::BinaryData &); + + static QuotingType mustQuote(StringRef S) { return QuotingType::None; } +}; + +template <> struct MappingTraits<lldb_private::GDBRemotePacket> { + static void mapping(IO &io, lldb_private::GDBRemotePacket &Packet); + + static StringRef validate(IO &io, lldb_private::GDBRemotePacket &); +}; + +} // namespace yaml +} // namespace llvm + +#endif // liblldb_GDBRemote_h_ diff --git a/include/lldb/Utility/IOObject.h b/include/lldb/Utility/IOObject.h index 1640200a01d9..16ed580abf71 100644 --- a/include/lldb/Utility/IOObject.h +++ b/include/lldb/Utility/IOObject.h @@ -29,8 +29,7 @@ public: typedef int WaitableHandle; static const WaitableHandle kInvalidHandleValue; - IOObject(FDType type, bool should_close) - : m_fd_type(type), m_should_close_fd(should_close) {} + IOObject(FDType type) : m_fd_type(type) {} virtual ~IOObject(); virtual Status Read(void *buf, size_t &num_bytes) = 0; @@ -44,8 +43,6 @@ public: protected: FDType m_fd_type; - bool m_should_close_fd; // True if this class should close the file descriptor - // when it goes away. private: DISALLOW_COPY_AND_ASSIGN(IOObject); diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h deleted file mode 100644 index 172f77afb01f..000000000000 --- a/include/lldb/Utility/JSON.h +++ /dev/null @@ -1,283 +0,0 @@ -//===---------------------JSON.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 utility_JSON_h_ -#define utility_JSON_h_ - -#include "lldb/Utility/StringExtractor.h" - -#include <map> -#include <memory> -#include <string> -#include <type_traits> -#include <vector> - -#include <stdint.h> - -namespace lldb_private { -class Stream; - -class JSONValue { -public: - virtual void Write(Stream &s) = 0; - - typedef std::shared_ptr<JSONValue> SP; - - enum class Kind { String, Number, True, False, Null, Object, Array }; - - JSONValue(Kind k) : m_kind(k) {} - - Kind GetKind() const { return m_kind; } - - virtual ~JSONValue() = default; - -private: - const Kind m_kind; -}; - -class JSONString : public JSONValue { -public: - JSONString(); - JSONString(const char *s); - JSONString(const std::string &s); - - JSONString(const JSONString &s) = delete; - JSONString &operator=(const JSONString &s) = delete; - - void Write(Stream &s) override; - - typedef std::shared_ptr<JSONString> SP; - - std::string GetData() { return m_data; } - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::String; - } - - ~JSONString() override = default; - -private: - static std::string json_string_quote_metachars(const std::string &); - - std::string m_data; -}; - -class JSONNumber : public JSONValue { -public: - typedef std::shared_ptr<JSONNumber> SP; - - // We cretae a constructor for all integer and floating point type with using - // templates and - // SFINAE to avoid having ambiguous overloads because of the implicit type - // promotion. If we - // would have constructors only with int64_t, uint64_t and double types then - // constructing a JSONNumber from an int32_t (or any other similar type) - // would fail to compile. - - template <typename T, typename std::enable_if< - std::is_integral<T>::value && - std::is_unsigned<T>::value>::type * = nullptr> - explicit JSONNumber(T u) - : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { - m_data.m_unsigned = u; - } - - template <typename T, - typename std::enable_if<std::is_integral<T>::value && - std::is_signed<T>::value>::type * = nullptr> - explicit JSONNumber(T s) - : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { - m_data.m_signed = s; - } - - template <typename T, typename std::enable_if< - std::is_floating_point<T>::value>::type * = nullptr> - explicit JSONNumber(T d) - : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { - m_data.m_double = d; - } - - ~JSONNumber() override = default; - - JSONNumber(const JSONNumber &s) = delete; - JSONNumber &operator=(const JSONNumber &s) = delete; - - void Write(Stream &s) override; - - uint64_t GetAsUnsigned() const; - - int64_t GetAsSigned() const; - - double GetAsDouble() const; - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::Number; - } - -private: - enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; - - union { - uint64_t m_unsigned; - int64_t m_signed; - double m_double; - } m_data; -}; - -class JSONTrue : public JSONValue { -public: - JSONTrue(); - - JSONTrue(const JSONTrue &s) = delete; - JSONTrue &operator=(const JSONTrue &s) = delete; - - void Write(Stream &s) override; - - typedef std::shared_ptr<JSONTrue> SP; - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::True; - } - - ~JSONTrue() override = default; -}; - -class JSONFalse : public JSONValue { -public: - JSONFalse(); - - JSONFalse(const JSONFalse &s) = delete; - JSONFalse &operator=(const JSONFalse &s) = delete; - - void Write(Stream &s) override; - - typedef std::shared_ptr<JSONFalse> SP; - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::False; - } - - ~JSONFalse() override = default; -}; - -class JSONNull : public JSONValue { -public: - JSONNull(); - - JSONNull(const JSONNull &s) = delete; - JSONNull &operator=(const JSONNull &s) = delete; - - void Write(Stream &s) override; - - typedef std::shared_ptr<JSONNull> SP; - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::Null; - } - - ~JSONNull() override = default; -}; - -class JSONObject : public JSONValue { -public: - JSONObject(); - - JSONObject(const JSONObject &s) = delete; - JSONObject &operator=(const JSONObject &s) = delete; - - void Write(Stream &s) override; - - typedef std::shared_ptr<JSONObject> SP; - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::Object; - } - - bool SetObject(const std::string &key, JSONValue::SP value); - - JSONValue::SP GetObject(const std::string &key); - - ~JSONObject() override = default; - -private: - typedef std::map<std::string, JSONValue::SP> Map; - typedef Map::iterator Iterator; - Map m_elements; -}; - -class JSONArray : public JSONValue { -public: - JSONArray(); - - JSONArray(const JSONArray &s) = delete; - JSONArray &operator=(const JSONArray &s) = delete; - - void Write(Stream &s) override; - - typedef std::shared_ptr<JSONArray> SP; - - static bool classof(const JSONValue *V) { - return V->GetKind() == JSONValue::Kind::Array; - } - -private: - typedef std::vector<JSONValue::SP> Vector; - typedef Vector::iterator Iterator; - typedef Vector::size_type Index; - typedef Vector::size_type Size; - -public: - bool SetObject(Index i, JSONValue::SP value); - - bool AppendObject(JSONValue::SP value); - - JSONValue::SP GetObject(Index i); - - Size GetNumElements(); - - ~JSONArray() override = default; - - Vector m_elements; -}; - -class JSONParser : public StringExtractor { -public: - enum Token { - Invalid, - Status, - ObjectStart, - ObjectEnd, - ArrayStart, - ArrayEnd, - Comma, - Colon, - String, - Integer, - Float, - True, - False, - Null, - EndOfFile - }; - - JSONParser(llvm::StringRef data); - - int GetEscapedChar(bool &was_escaped); - - Token GetToken(std::string &value); - - JSONValue::SP ParseJSONValue(); - -protected: - JSONValue::SP ParseJSONObject(); - - JSONValue::SP ParseJSONArray(); -}; -} // namespace lldb_private - -#endif // utility_JSON_h_ diff --git a/include/lldb/Utility/Log.h b/include/lldb/Utility/Log.h index 949de69c8e5a..09c0f6954478 100644 --- a/include/lldb/Utility/Log.h +++ b/include/lldb/Utility/Log.h @@ -14,6 +14,7 @@ #include "lldb/lldb-defines.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -112,6 +113,14 @@ public: static bool ListChannelCategories(llvm::StringRef channel, llvm::raw_ostream &stream); + /// Returns the list of log channels. + static std::vector<llvm::StringRef> ListChannels(); + /// Calls the given lambda for every category in the given channel. + /// If no channel with the given name exists, lambda is never called. + static void ForEachChannelCategory( + llvm::StringRef channel, + llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda); + static void DisableAllLogChannels(); static void ListAllLogChannels(llvm::raw_ostream &stream); @@ -142,14 +151,11 @@ public: std::forward<Args>(args)...)); } + /// Prefer using LLDB_LOGF whenever possible. void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); - void VAPrintf(const char *format, va_list args); - void Error(const char *fmt, ...) __attribute__((format(printf, 2, 3))); - void VAError(const char *format, va_list args); - void Verbose(const char *fmt, ...) __attribute__((format(printf, 2, 3))); void Warning(const char *fmt, ...) __attribute__((format(printf, 2, 3))); @@ -161,6 +167,9 @@ public: bool GetVerbose() const; private: + void VAPrintf(const char *format, va_list args); + void VAError(const char *format, va_list args); + Channel &m_channel; // The mutex makes sure enable/disable operations are thread-safe. The @@ -193,6 +202,10 @@ private: typedef llvm::StringMap<Log> ChannelMap; static llvm::ManagedStatic<ChannelMap> g_channel_map; + static void ForEachCategory( + const Log::ChannelMap::value_type &entry, + llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda); + static void ListCategories(llvm::raw_ostream &stream, const ChannelMap::value_type &entry); static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry, @@ -206,6 +219,26 @@ private: } // namespace lldb_private +/// The LLDB_LOG* macros defined below are the way to emit log messages. +/// +/// Note that the macros surround the arguments in a check for the log +/// being on, so you can freely call methods in arguments without affecting +/// the non-log execution flow. +/// +/// If you need to do more complex computations to prepare the log message +/// be sure to add your own if (log) check, since we don't want logging to +/// have any effect when not on. +/// +/// However, the LLDB_LOG macro uses the llvm::formatv system (see the +/// ProgrammersManual page in the llvm docs for more details). This allows +/// the use of "format_providers" to auto-format datatypes, and there are +/// already formatters for some of the llvm and lldb datatypes. +/// +/// So if you need to do non-trivial formatting of one of these types, be +/// sure to grep the lldb and llvm sources for "format_provider" to see if +/// there is already a formatter before doing in situ formatting, and if +/// possible add a provider if one does not already exist. + #define LLDB_LOG(log, ...) \ do { \ ::lldb_private::Log *log_private = (log); \ @@ -213,6 +246,13 @@ private: log_private->Format(__FILE__, __func__, __VA_ARGS__); \ } while (0) +#define LLDB_LOGF(log, ...) \ + do { \ + ::lldb_private::Log *log_private = (log); \ + if (log_private) \ + log_private->Printf(__VA_ARGS__); \ + } while (0) + #define LLDB_LOGV(log, ...) \ do { \ ::lldb_private::Log *log_private = (log); \ diff --git a/include/lldb/Utility/Logging.h b/include/lldb/Utility/Logging.h index 41086fedf8c2..1a8a1022c5c0 100644 --- a/include/lldb/Utility/Logging.h +++ b/include/lldb/Utility/Logging.h @@ -54,8 +54,6 @@ namespace lldb_private { class Log; -void LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...); - Log *GetLogIfAllCategoriesSet(uint32_t mask); Log *GetLogIfAnyCategoriesSet(uint32_t mask); diff --git a/include/lldb/Utility/Predicate.h b/include/lldb/Utility/Predicate.h index f1539b576686..cbccc3e91a8b 100644 --- a/include/lldb/Utility/Predicate.h +++ b/include/lldb/Utility/Predicate.h @@ -117,8 +117,7 @@ public: /// How long to wait for the condition to hold. /// /// \return - /// \li m_value if Cond(m_value) is true. - /// \li None otherwise (timeout occurred). + /// m_value if Cond(m_value) is true, None otherwise (timeout occurred). template <typename C> llvm::Optional<T> WaitFor(C Cond, const Timeout<std::micro> &timeout) { std::unique_lock<std::mutex> lock(m_mutex); @@ -151,8 +150,8 @@ public: /// How long to wait for the condition to hold. /// /// \return - /// \li \b true if the \a m_value is equal to \a value - /// \li \b false otherwise (timeout occurred) + /// true if the \a m_value is equal to \a value, false otherwise (timeout + /// occurred). bool WaitForValueEqualTo(T value, const Timeout<std::micro> &timeout = llvm::None) { return WaitFor([&value](T current) { return value == current; }, timeout) != @@ -179,8 +178,7 @@ public: /// How long to wait for the condition to hold. /// /// \return - /// \li m_value if m_value != value - /// \li None otherwise (timeout occurred). + /// m_value if m_value != value, None otherwise (timeout occurred). llvm::Optional<T> WaitForValueNotEqualTo(T value, const Timeout<std::micro> &timeout = llvm::None) { diff --git a/include/lldb/Utility/ProcessInfo.h b/include/lldb/Utility/ProcessInfo.h index a25c06cabdf6..9188bf3b7090 100644 --- a/include/lldb/Utility/ProcessInfo.h +++ b/include/lldb/Utility/ProcessInfo.h @@ -38,7 +38,7 @@ public: const char *GetName() const; - size_t GetNameLength() const; + llvm::StringRef GetNameAsStringRef() const; FileSpec &GetExecutableFile() { return m_executable; } @@ -165,12 +165,8 @@ public: void Append(const ProcessInstanceInfo &info) { m_infos.push_back(info); } - const char *GetProcessNameAtIndex(size_t idx) { - return ((idx < m_infos.size()) ? m_infos[idx].GetName() : nullptr); - } - - size_t GetProcessNameLengthAtIndex(size_t idx) { - return ((idx < m_infos.size()) ? m_infos[idx].GetNameLength() : 0); + llvm::StringRef GetProcessNameAtIndex(size_t idx) { + return ((idx < m_infos.size()) ? m_infos[idx].GetNameAsStringRef() : ""); } lldb::pid_t GetProcessIDAtIndex(size_t idx) { @@ -227,8 +223,20 @@ public: m_name_match_type = name_match_type; } + /// Return true iff the architecture in this object matches arch_spec. + bool ArchitectureMatches(const ArchSpec &arch_spec) const; + + /// Return true iff the process name in this object matches process_name. bool NameMatches(const char *process_name) const; + /// Return true iff the process ID and parent process IDs in this object match + /// the ones in proc_info. + bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const; + + /// Return true iff the (both effective and real) user and group IDs in this + /// object match the ones in proc_info. + bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const; + bool Matches(const ProcessInstanceInfo &proc_info) const; bool MatchAllProcesses() const; diff --git a/include/lldb/Utility/RangeMap.h b/include/lldb/Utility/RangeMap.h index 36401f59d34f..709b5d2f66c7 100644 --- a/include/lldb/Utility/RangeMap.h +++ b/include/lldb/Utility/RangeMap.h @@ -724,12 +724,14 @@ public: #ifdef ASSERT_RANGEMAP_ARE_SORTED assert(IsSorted()); #endif - - if (!m_entries.empty()) { - for (const auto &entry : m_entries) { - if (entry.Contains(addr)) - indexes.push_back(entry.data); - } + // Search the entries until the first entry that has a larger base address + // than `addr`. As m_entries is sorted by their base address, all following + // entries can't contain `addr` as their base address is already larger. + for (const auto &entry : m_entries) { + if (entry.Contains(addr)) + indexes.push_back(entry.data); + else if (entry.GetRangeBase() > addr) + break; } return indexes.size(); } diff --git a/include/lldb/Utility/RegularExpression.h b/include/lldb/Utility/RegularExpression.h index 54f3dd89c7a2..6acc203d8e7c 100644 --- a/include/lldb/Utility/RegularExpression.h +++ b/include/lldb/Utility/RegularExpression.h @@ -9,189 +9,84 @@ #ifndef liblldb_RegularExpression_h_ #define liblldb_RegularExpression_h_ -#ifdef _WIN32 -#include "../lib/Support/regex_impl.h" - -typedef llvm_regmatch_t regmatch_t; -typedef llvm_regex_t regex_t; - -inline int regcomp(llvm_regex_t *a, const char *b, int c) { - return llvm_regcomp(a, b, c); -} - -inline size_t regerror(int a, const llvm_regex_t *b, char *c, size_t d) { - return llvm_regerror(a, b, c, d); -} - -inline int regexec(const llvm_regex_t *a, const char *b, size_t c, - llvm_regmatch_t d[], int e) { - return llvm_regexec(a, b, c, d, e); -} - -inline void regfree(llvm_regex_t *a) { llvm_regfree(a); } -#else -#ifdef __ANDROID__ -#include <regex> -#endif -#include <regex.h> -#endif - -#include <string> -#include <vector> - -#include <stddef.h> -#include <stdint.h> - -namespace llvm { -class StringRef; -} // namespace llvm +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Regex.h" namespace lldb_private { -/// \class RegularExpression RegularExpression.h -/// "lldb/Utility/RegularExpression.h" -/// A C++ wrapper class for regex. -/// -/// This regular expression class wraps the posix regex functions \c -/// regcomp(), \c regerror(), \c regexec(), and \c regfree() from the header -/// file in \c /usr/include/regex\.h. class RegularExpression { public: - class Match { - public: - Match(uint32_t max_matches) : m_matches() { - if (max_matches > 0) - m_matches.resize(max_matches + 1); - } - - void Clear() { - const size_t num_matches = m_matches.size(); - regmatch_t invalid_match = {-1, -1}; - for (size_t i = 0; i < num_matches; ++i) - m_matches[i] = invalid_match; - } - - size_t GetSize() const { return m_matches.size(); } - - regmatch_t *GetData() { - return (m_matches.empty() ? nullptr : m_matches.data()); - } - - bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx, - std::string &match_str) const; - - bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx, - llvm::StringRef &match_str) const; - - bool GetMatchSpanningIndices(llvm::StringRef s, uint32_t idx1, - uint32_t idx2, - llvm::StringRef &match_str) const; - - protected: - std::vector<regmatch_t> - m_matches; ///< Where parenthesized subexpressions results are stored - }; - - /// Default constructor. - /// /// The default constructor that initializes the object state such that it /// contains no compiled regular expression. - RegularExpression(); + RegularExpression() = default; - explicit RegularExpression(llvm::StringRef string); - - /// Destructor. - /// - /// Any previously compiled regular expression contained in this object will - /// be freed. - ~RegularExpression(); - - RegularExpression(const RegularExpression &rhs); - - const RegularExpression &operator=(const RegularExpression &rhs); - - /// Compile a regular expression. + /// Constructor for a regular expression. /// /// Compile a regular expression using the supplied regular expression text. /// The compiled regular expression lives in this object so that it can be /// readily used for regular expression matches. Execute() can be called - /// after the regular expression is compiled. Any previously compiled - /// regular expression contained in this object will be freed. + /// after the regular expression is compiled. /// - /// \param[in] re - /// A NULL terminated C string that represents the regular - /// expression to compile. - /// - /// \return - /// \b true if the regular expression compiles successfully, - /// \b false otherwise. - bool Compile(llvm::StringRef string); - bool Compile(const char *) = delete; + /// \param[in] string + /// An llvm::StringRef that represents the regular expression to compile. + // String is not referenced anymore after the object is constructed. + explicit RegularExpression(llvm::StringRef string); + + ~RegularExpression() = default; + + RegularExpression(const RegularExpression &rhs); + RegularExpression(RegularExpression &&rhs) = default; + + RegularExpression &operator=(RegularExpression &&rhs) = default; + RegularExpression &operator=(const RegularExpression &rhs) = default; - /// Executes a regular expression. - /// /// Execute a regular expression match using the compiled regular expression - /// that is already in this object against the match string \a s. If any - /// parens are used for regular expression matches \a match_count should - /// indicate the number of regmatch_t values that are present in \a - /// match_ptr. + /// that is already in this object against the given \a string. If any parens + /// are used for regular expression matches. /// /// \param[in] string /// The string to match against the compile regular expression. /// - /// \param[in] match - /// A pointer to a RegularExpression::Match structure that was - /// properly initialized with the desired number of maximum - /// matches, or nullptr if no parenthesized matching is needed. + /// \param[out] matches + /// A pointer to a SmallVector to hold the matches. /// /// \return - /// \b true if \a string matches the compiled regular - /// expression, \b false otherwise. - bool Execute(llvm::StringRef string, Match *match = nullptr) const; - bool Execute(const char *, Match * = nullptr) = delete; - - size_t GetErrorAsCString(char *err_str, size_t err_str_max_len) const; - - /// Free the compiled regular expression. - /// - /// If this object contains a valid compiled regular expression, this - /// function will free any resources it was consuming. - void Free(); + /// true if \a string matches the compiled regular expression, false + /// otherwise incl. the case regular exression failed to compile. + bool Execute(llvm::StringRef string, + llvm::SmallVectorImpl<llvm::StringRef> *matches = nullptr) const; /// Access the regular expression text. /// - /// Returns the text that was used to compile the current regular - /// expression. - /// /// \return /// The NULL terminated C string that was used to compile the /// current regular expression llvm::StringRef GetText() const; - /// Test if valid. - /// /// Test if this object contains a valid regular expression. /// /// \return - /// \b true if the regular expression compiled and is ready - /// for execution, \b false otherwise. + /// true if the regular expression compiled and is ready for execution, + /// false otherwise. bool IsValid() const; - void Clear() { - Free(); - m_re.clear(); - m_comp_err = 1; - } - - int GetErrorCode() const { return m_comp_err; } + /// Return an error if the regular expression failed to compile. + /// + /// \return + /// A string error if the regular expression failed to compile, success + /// otherwise. + llvm::Error GetError() const; - bool operator<(const RegularExpression &rhs) const; + bool operator==(const RegularExpression &rhs) const { + return GetText() == rhs.GetText(); + } private: - // Member variables - std::string m_re; ///< A copy of the original regular expression text - int m_comp_err; ///< Status code for the regular expression compilation - regex_t m_preg; ///< The compiled regular expression + /// A copy of the original regular expression text. + std::string m_regex_text; + /// The compiled regular expression. + mutable llvm::Regex m_regex; }; } // namespace lldb_private diff --git a/include/lldb/Utility/Reproducer.h b/include/lldb/Utility/Reproducer.h index 670041d06bba..3db98a781d4c 100644 --- a/include/lldb/Utility/Reproducer.h +++ b/include/lldb/Utility/Reproducer.h @@ -9,11 +9,10 @@ #ifndef LLDB_UTILITY_REPRODUCER_H #define LLDB_UTILITY_REPRODUCER_H -#include "lldb/Utility/FileCollector.h" #include "lldb/Utility/FileSpec.h" - #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Error.h" +#include "llvm/Support/FileCollector.h" #include "llvm/Support/YAMLTraits.h" #include <mutex> @@ -91,23 +90,26 @@ public: FileProvider(const FileSpec &directory) : Provider(directory), - m_collector(directory.CopyByAppendingPathComponent("root"), directory) { - } + m_collector(std::make_shared<llvm::FileCollector>( + directory.CopyByAppendingPathComponent("root").GetPath(), + directory.GetPath())) {} - FileCollector &GetFileCollector() { return m_collector; } + std::shared_ptr<llvm::FileCollector> GetFileCollector() { + return m_collector; + } void Keep() override { auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file); // Temporary files that are removed during execution can cause copy errors. - if (auto ec = m_collector.CopyFiles(/*stop_on_error=*/false)) + if (auto ec = m_collector->copyFiles(/*stop_on_error=*/false)) return; - m_collector.WriteMapping(mapping); + m_collector->writeMapping(mapping.GetPath()); } static char ID; private: - FileCollector m_collector; + std::shared_ptr<llvm::FileCollector> m_collector; }; /// Provider for the LLDB version number. @@ -130,11 +132,32 @@ public: static char ID; }; +/// Provider for the LLDB current working directroy. +/// +/// When the reproducer is kept, it writes lldb's current working directory to +/// a file named cwd.txt in the reproducer root. +class WorkingDirectoryProvider : public Provider<WorkingDirectoryProvider> { +public: + WorkingDirectoryProvider(const FileSpec &directory) : Provider(directory) { + llvm::SmallString<128> cwd; + if (std::error_code EC = llvm::sys::fs::current_path(cwd)) + return; + m_cwd = cwd.str(); + } + struct Info { + static const char *name; + static const char *file; + }; + void Keep() override; + std::string m_cwd; + static char ID; +}; + class DataRecorder { public: DataRecorder(const FileSpec &filename, std::error_code &ec) : m_filename(filename.GetFilename().GetStringRef()), - m_os(filename.GetPath(), ec, llvm::sys::fs::F_Text), m_record(true) {} + m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {} static llvm::Expected<std::unique_ptr<DataRecorder>> Create(const FileSpec &filename); @@ -181,12 +204,39 @@ private: std::vector<std::unique_ptr<DataRecorder>> m_data_recorders; }; +class ProcessGDBRemoteProvider + : public repro::Provider<ProcessGDBRemoteProvider> { +public: + struct Info { + static const char *name; + static const char *file; + }; + + ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {} + + llvm::raw_ostream *GetHistoryStream(); + + void SetCallback(std::function<void()> callback) { + m_callback = std::move(callback); + } + + void Keep() override { m_callback(); } + void Discard() override { m_callback(); } + + static char ID; + +private: + std::function<void()> m_callback; + std::unique_ptr<llvm::raw_fd_ostream> m_stream_up; +}; + /// The generator is responsible for the logic needed to generate a /// reproducer. For doing so it relies on providers, who serialize data that /// is necessary for reproducing a failure. class Generator final { + public: - Generator(const FileSpec &root); + Generator(FileSpec root); ~Generator(); /// Method to indicate we want to keep the reproducer. If reproducer @@ -200,7 +250,7 @@ public: /// Create and register a new provider. template <typename T> T *Create() { - std::unique_ptr<ProviderBase> provider = llvm::make_unique<T>(m_root); + std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root); return static_cast<T *>(Register(std::move(provider))); } @@ -243,7 +293,7 @@ private: class Loader final { public: - Loader(const FileSpec &root); + Loader(FileSpec root); template <typename T> FileSpec GetFile() { if (!HasFile(T::file)) @@ -252,6 +302,15 @@ public: return GetRoot().CopyByAppendingPathComponent(T::file); } + template <typename T> llvm::Expected<std::string> LoadBuffer() { + FileSpec file = GetFile<typename T::Info>(); + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer = + llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath()); + if (!buffer) + return llvm::errorCodeToError(buffer.getError()); + return (*buffer)->getBuffer().str(); + } + llvm::Error LoadIndex(); const FileSpec &GetRoot() const { return m_root; } @@ -284,6 +343,9 @@ public: FileSpec GetReproducerPath() const; + bool IsCapturing() { return static_cast<bool>(m_generator); }; + bool IsReplaying() { return static_cast<bool>(m_loader); }; + protected: llvm::Error SetCapture(llvm::Optional<FileSpec> root); llvm::Error SetReplay(llvm::Optional<FileSpec> root); @@ -297,6 +359,19 @@ private: mutable std::mutex m_mutex; }; +/// 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(Loader *loader); + llvm::Optional<std::string> GetNextFile(); + +private: + std::vector<std::string> m_files; + unsigned m_index = 0; +}; + } // namespace repro } // namespace lldb_private diff --git a/include/lldb/Utility/ReproducerInstrumentation.h b/include/lldb/Utility/ReproducerInstrumentation.h index f90ce4bc767a..75d66045758f 100644 --- a/include/lldb/Utility/ReproducerInstrumentation.h +++ b/include/lldb/Utility/ReproducerInstrumentation.h @@ -40,7 +40,7 @@ inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) { template <> inline void stringify_append<char>(llvm::raw_string_ostream &ss, const char *t) { - ss << t; + ss << '\"' << t << '\"'; } template <typename Head> @@ -105,8 +105,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) { } #define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ + lldb_private::repro::Recorder sb_recorder( \ + LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \ if (lldb_private::repro::InstrumentationData data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ sb_recorder.Record( \ @@ -117,8 +117,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) { } #define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ + lldb_private::repro::Recorder sb_recorder( \ + LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \ if (lldb_private::repro::InstrumentationData data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ sb_recorder.Record( \ @@ -129,7 +129,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) { } #define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \ + lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ + stringify_args(*this)); \ if (lldb_private::repro::InstrumentationData data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \ @@ -139,7 +140,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) { } #define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \ + lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ + stringify_args(*this)); \ if (lldb_private::repro::InstrumentationData data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ sb_recorder.Record( \ @@ -175,6 +177,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) { #define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...) \ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \ stringify_args(__VA_ARGS__)); +#define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method) \ + lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); namespace lldb_private { namespace repro { @@ -234,9 +238,12 @@ struct ReferenceTag {}; struct ValueTag {}; struct FundamentalPointerTag {}; struct FundamentalReferenceTag {}; +struct NotImplementedTag {}; /// Return the deserialization tag for the given type T. -template <class T> struct serializer_tag { typedef ValueTag type; }; +template <class T> struct serializer_tag { + typedef typename std::conditional<std::is_trivially_copyable<T>::value, ValueTag, NotImplementedTag>::type type; +}; template <class T> struct serializer_tag<T *> { typedef typename std::conditional<std::is_fundamental<T>::value, @@ -300,6 +307,11 @@ public: } private: + template <typename T> T Read(NotImplementedTag) { + m_buffer = m_buffer.drop_front(sizeof(T)); + return T(); + } + template <typename T> T Read(ValueTag) { assert(HasData(sizeof(T))); T t; @@ -442,7 +454,7 @@ public: void Register(Signature *f, llvm::StringRef result = {}, llvm::StringRef scope = {}, llvm::StringRef name = {}, llvm::StringRef args = {}) { - DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(f), + DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(f), SignatureStr(result, scope, name, args)); } @@ -452,7 +464,7 @@ public: void Register(Signature *f, Signature *g, llvm::StringRef result = {}, llvm::StringRef scope = {}, llvm::StringRef name = {}, llvm::StringRef args = {}) { - DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(g), + DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(g), SignatureStr(result, scope, name, args)); } @@ -542,9 +554,7 @@ public: SerializeAll(tail...); } - void SerializeAll() { - m_stream.flush(); - } + void SerializeAll() { m_stream.flush(); } private: /// Serialize pointers. We need to differentiate between pointers to diff --git a/include/lldb/Utility/Scalar.h b/include/lldb/Utility/Scalar.h index 62ee9f666e89..72f153ff97cd 100644 --- a/include/lldb/Utility/Scalar.h +++ b/include/lldb/Utility/Scalar.h @@ -38,6 +38,7 @@ namespace lldb_private { // follows the ANSI C type promotion rules. class Scalar { public: + // FIXME: These are host types which seems to be an odd choice. enum Type { e_void = 0, e_sint, @@ -98,30 +99,14 @@ public: } Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) { m_integer = llvm::APInt(v); - switch (m_integer.getBitWidth()) { - case 8: - case 16: - case 32: - m_type = e_sint; - return; - case 64: - m_type = e_slonglong; - return; - case 128: - m_type = e_sint128; - return; - case 256: - m_type = e_sint256; - return; - case 512: - m_type = e_sint512; - return; - } - lldbassert(false && "unsupported bitwidth"); + m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true); } // Scalar(const RegisterValue& reg_value); virtual ~Scalar(); + /// Return the most efficient Scalar::Type for the requested bit size. + static Type GetBestTypeForBitSize(size_t bit_size, bool sign); + bool SignExtend(uint32_t bit_pos); bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset); @@ -154,6 +139,9 @@ public: return (m_type >= e_sint) && (m_type <= e_long_double); } + /// Convert integer to \p type, limited to \p bits size. + void TruncOrExtendTo(Scalar::Type type, uint16_t bits); + bool Promote(Scalar::Type type); bool MakeSigned(); diff --git a/include/lldb/Utility/Status.h b/include/lldb/Utility/Status.h index ae730b90dffe..e6a0a8e7fce1 100644 --- a/include/lldb/Utility/Status.h +++ b/include/lldb/Utility/Status.h @@ -47,8 +47,8 @@ public: /// into ValueType. typedef uint32_t ValueType; - /// Default constructor. - /// + Status(); + /// Initialize the error object with a generic success value. /// /// \param[in] err @@ -56,23 +56,14 @@ public: /// /// \param[in] type /// The type for \a err. - Status(); - explicit Status(ValueType err, lldb::ErrorType type = lldb::eErrorTypeGeneric); - /* implicit */ Status(std::error_code EC); + Status(std::error_code EC); explicit Status(const char *format, ...) __attribute__((format(printf, 2, 3))); - /// Assignment operator. - /// - /// \param[in] err - /// An error code. - /// - /// \return - /// A const reference to this object. const Status &operator=(const Status &rhs); ~Status(); @@ -221,4 +212,11 @@ template <> struct format_provider<lldb_private::Status> { }; } +#define LLDB_ERRORF(status, fmt, ...) \ + do { \ + if (status) { \ + (status)->SetErrorStringWithFormat((fmt), __VA_ARGS__); \ + } \ + } while (0); + #endif // #ifndef LLDB_UTILITY_STATUS_H diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h index b24d4e457177..414f92177303 100644 --- a/include/lldb/Utility/Stream.h +++ b/include/lldb/Utility/Stream.h @@ -35,11 +35,11 @@ public: /// Utility class for counting the bytes that were written to a stream in a /// certain time span. + /// /// \example /// ByteDelta delta(*this); /// WriteDataToStream("foo"); /// return *delta; - /// \endcode class ByteDelta { Stream *m_stream; /// Bytes we have written so far when ByteDelta was created. diff --git a/include/lldb/Utility/StreamGDBRemote.h b/include/lldb/Utility/StreamGDBRemote.h deleted file mode 100644 index dd0ea31126d9..000000000000 --- a/include/lldb/Utility/StreamGDBRemote.h +++ /dev/null @@ -1,45 +0,0 @@ -//===-- StreamGDBRemote.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_StreamGDBRemote_h_ -#define liblldb_StreamGDBRemote_h_ - -#include "lldb/Utility/StreamString.h" -#include "lldb/lldb-enumerations.h" - -#include <stddef.h> -#include <stdint.h> - -namespace lldb_private { - -class StreamGDBRemote : public StreamString { -public: - StreamGDBRemote(); - - StreamGDBRemote(uint32_t flags, uint32_t addr_size, - lldb::ByteOrder byte_order); - - ~StreamGDBRemote() override; - - /// Output a block of data to the stream performing GDB-remote escaping. - /// - /// \param[in] s - /// A block of data. - /// - /// \param[in] src_len - /// The amount of data to write. - /// - /// \return - /// Number of bytes written. - // TODO: Convert this function to take ArrayRef<uint8_t> - int PutEscapedBytes(const void *s, size_t src_len); -}; - -} // namespace lldb_private - -#endif // liblldb_StreamGDBRemote_h_ diff --git a/include/lldb/Utility/StringExtractor.h b/include/lldb/Utility/StringExtractor.h index f20ec92199bb..293fef2fbe6b 100644 --- a/include/lldb/Utility/StringExtractor.h +++ b/include/lldb/Utility/StringExtractor.h @@ -45,9 +45,7 @@ public: void SkipSpaces(); - std::string &GetStringRef() { return m_packet; } - - const std::string &GetStringRef() const { return m_packet; } + llvm::StringRef GetStringRef() const { return m_packet; } bool Empty() { return m_packet.empty(); } @@ -91,9 +89,6 @@ public: size_t GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest); - uint64_t GetHexWithFixedSize(uint32_t byte_size, bool little_endian, - uint64_t fail_value); - size_t GetHexByteString(std::string &str); size_t GetHexByteStringFixedLength(std::string &str, uint32_t nibble_length); @@ -113,12 +108,14 @@ protected: m_index = UINT64_MAX; return false; } - // For StringExtractor only - std::string m_packet; // The string in which to extract data. - uint64_t m_index; // When extracting data from a packet, this index - // will march along as things get extracted. If set to - // UINT64_MAX the end of the packet data was reached - // when decoding information + + /// The string in which to extract data. + std::string m_packet; + + /// When extracting data from a packet, this index will march along as things + /// get extracted. If set to UINT64_MAX the end of the packet data was + /// reached when decoding information. + uint64_t m_index; }; #endif // utility_StringExtractor_h_ diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h index d9806c1b37d7..533fd4fb896e 100644 --- a/include/lldb/Utility/StringLexer.h +++ b/include/lldb/Utility/StringLexer.h @@ -1,4 +1,4 @@ -//===--------------------- StringLexer.h ------------------------*- C++ -*-===// +//===-- StringLexer.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. @@ -13,7 +13,7 @@ #include <string> #include <utility> -namespace lldb_utility { +namespace lldb_private { class StringLexer { public: diff --git a/include/lldb/Utility/StringList.h b/include/lldb/Utility/StringList.h index 68c1f87510f6..0b1d955678b3 100644 --- a/include/lldb/Utility/StringList.h +++ b/include/lldb/Utility/StringList.h @@ -23,6 +23,8 @@ class Stream; namespace lldb_private { class StringList { + typedef std::vector<std::string> collection; + public: StringList(); @@ -52,6 +54,14 @@ public: size_t GetMaxStringLength() const; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + iterator begin() { return m_strings.begin(); } + iterator end() { return m_strings.end(); } + const_iterator begin() const { return m_strings.begin(); } + const_iterator end() const { return m_strings.end(); } + std::string &operator[](size_t idx) { // No bounds checking, verify "idx" is good prior to calling this function return m_strings[idx]; @@ -69,7 +79,7 @@ public: void Clear(); - void LongestCommonPrefix(std::string &common_prefix); + std::string LongestCommonPrefix(); void InsertStringAtIndex(size_t idx, const std::string &str); @@ -97,14 +107,6 @@ public: // Copy assignment for a vector of strings StringList &operator=(const std::vector<std::string> &rhs); - // This string list contains a list of valid auto completion strings, and the - // "s" is passed in. "matches" is filled in with zero or more string values - // that start with "s", and the first string to exactly match one of the - // string values in this collection, will have "exact_matches_idx" filled in - // to match the index, or "exact_matches_idx" will have SIZE_MAX - size_t AutoComplete(llvm::StringRef s, StringList &matches, - size_t &exact_matches_idx) const; - // Dump the StringList to the given lldb_private::Log, `log`, one item per // line. If given, `name` will be used to identify the start and end of the // list in the output. @@ -125,7 +127,7 @@ public: } private: - std::vector<std::string> m_strings; + collection m_strings; }; } // namespace lldb_private diff --git a/include/lldb/Utility/StructuredData.h b/include/lldb/Utility/StructuredData.h index 75eb2f7b7291..01b14fc3d4d3 100644 --- a/include/lldb/Utility/StructuredData.h +++ b/include/lldb/Utility/StructuredData.h @@ -10,9 +10,11 @@ #define liblldb_StructuredData_h_ #include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" #include <cassert> @@ -28,7 +30,6 @@ namespace lldb_private { class Status; -class Stream; } namespace lldb_private { @@ -150,7 +151,12 @@ public: void DumpToStdout(bool pretty_print = true) const; - virtual void Dump(Stream &s, bool pretty_print = true) const = 0; + virtual void Serialize(llvm::json::OStream &s) const = 0; + + void Dump(lldb_private::Stream &s, bool pretty_print = true) const { + llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 2 : 0); + Serialize(jso); + } private: lldb::StructuredDataType m_type; @@ -269,7 +275,7 @@ public: void AddItem(ObjectSP item) { m_items.push_back(item); } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: typedef std::vector<ObjectSP> collection; @@ -287,7 +293,7 @@ public: uint64_t GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: uint64_t m_value; @@ -304,7 +310,7 @@ public: double GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: double m_value; @@ -321,7 +327,7 @@ public: bool GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: bool m_value; @@ -337,7 +343,7 @@ public: llvm::StringRef GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: std::string m_value; @@ -506,7 +512,7 @@ public: AddItem(key, std::make_shared<Boolean>(value)); } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: typedef std::map<ConstString, ObjectSP> collection; @@ -521,7 +527,7 @@ public: bool IsValid() const override { return false; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; }; class Generic : public Object { @@ -535,14 +541,13 @@ public: bool IsValid() const override { return m_object != nullptr; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; private: void *m_object; }; static ObjectSP ParseJSON(std::string json_text); - static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); }; diff --git a/include/lldb/Utility/UUID.h b/include/lldb/Utility/UUID.h index dbeb9db611b2..0284357be44a 100644 --- a/include/lldb/Utility/UUID.h +++ b/include/lldb/Utility/UUID.h @@ -9,14 +9,11 @@ #ifndef LLDB_UTILITY_UUID_H #define LLDB_UTILITY_UUID_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include <stddef.h> #include <stdint.h> #include <string> -#include "llvm/ADT/ArrayRef.h" - -namespace llvm { - class StringRef; -} namespace lldb_private { @@ -67,10 +64,10 @@ public: std::string GetAsString(llvm::StringRef separator = "-") const; size_t SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16); - - // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the + + // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the // UUID to invalid. - size_t SetFromOptionalStringRef(llvm::StringRef str, + size_t SetFromOptionalStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16); // Decode as many UUID bytes (up to 16) as possible from the C string "cstr" @@ -79,14 +76,13 @@ public: /// Decode as many UUID bytes (up to 16) as possible from the C /// string \a cstr. /// - /// \param[in] cstr - /// A NULL terminate C string that points at a UUID string value - /// (no leading spaces). The string must contain only hex - /// characters and optionally can contain the '-' sepearators. + /// \param[in] str + /// An llvm::StringRef that points at a UUID string value (no leading + /// spaces). The string must contain only hex characters and optionally + /// can contain the '-' sepearators. /// /// \param[in] uuid_bytes - /// A buffer of bytes that will contain a full or patially - /// decoded UUID. + /// A buffer of bytes that will contain a full or partially decoded UUID. /// /// \return /// The original string, with all decoded bytes removed. diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index f9830c04bc39..3c80bcffec20 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -69,21 +69,22 @@ namespace lldb { -// Process and Thread States +/// Process and Thread States. enum StateType { eStateInvalid = 0, eStateUnloaded, ///< Process is object is valid, but not currently loaded eStateConnected, ///< Process is connected to remote debug services, but not - ///launched or attached to anything yet + /// launched or attached to anything yet eStateAttaching, ///< Process is currently trying to attach eStateLaunching, ///< Process is in the process of launching - // The state changes eStateAttaching and eStateLaunching are both sent while the - // private state thread is either not yet started or paused. For that reason, they - // should only be signaled as public state changes, and not private state changes. + // The state changes eStateAttaching and eStateLaunching are both sent while + // the private state thread is either not yet started or paused. For that + // reason, they should only be signaled as public state changes, and not + // private state changes. eStateStopped, ///< Process or thread is stopped and can be examined. eStateRunning, ///< Process or thread is running and can't be examined. eStateStepping, ///< Process or thread is in the process of stepping and can - ///not be examined. + /// not be examined. eStateCrashed, ///< Process or thread has crashed and can be examined. eStateDetached, ///< Process has been detached and can't be examined. eStateExited, ///< Process has exited and can't be examined. @@ -93,16 +94,17 @@ enum StateType { kLastStateType = eStateSuspended }; -// Launch Flags +/// Launch Flags. FLAGS_ENUM(LaunchFlags){ eLaunchFlagNone = 0u, eLaunchFlagExec = (1u << 0), ///< Exec when launching and turn the calling - ///process into a new process + /// process into a new process eLaunchFlagDebug = (1u << 1), ///< Stop as soon as the process launches to - ///allow the process to be debugged - eLaunchFlagStopAtEntry = (1u << 2), ///< Stop at the program entry point - ///instead of auto-continuing when - ///launching or attaching at entry point + /// allow the process to be debugged + eLaunchFlagStopAtEntry = (1u + << 2), ///< Stop at the program entry point + /// instead of auto-continuing when + /// launching or attaching at entry point eLaunchFlagDisableASLR = (1u << 3), ///< Disable Address Space Layout Randomization eLaunchFlagDisableSTDIO = @@ -113,23 +115,23 @@ FLAGS_ENUM(LaunchFlags){ (1u << 6), ///< Launch the process inside a shell to get shell expansion eLaunchFlagLaunchInSeparateProcessGroup = (1u << 7), ///< Launch the process in a separate process group - eLaunchFlagDontSetExitStatus = (1u << 8), ///< If you are going to hand the - ///process off (e.g. to - ///debugserver) + ///< If you are going to hand the process off (e.g. to + ///< debugserver) + eLaunchFlagDontSetExitStatus = (1u << 8), ///< set this flag so lldb & the handee don't race to set its exit status. eLaunchFlagDetachOnError = (1u << 9), ///< If set, then the client stub - ///should detach rather than killing - ///the debugee + ///< should detach rather than killing + ///< the debugee ///< if it loses connection with lldb. eLaunchFlagShellExpandArguments = (1u << 10), ///< Perform shell-style argument expansion eLaunchFlagCloseTTYOnExit = (1u << 11), ///< Close the open TTY on exit }; -// Thread Run Modes +/// Thread Run Modes. enum RunMode { eOnlyThisThread, eAllThreads, eOnlyDuringStepping }; -// Byte ordering definitions +/// Byte ordering definitions. enum ByteOrder { eByteOrderInvalid = 0, eByteOrderBig = 1, @@ -137,16 +139,16 @@ enum ByteOrder { eByteOrderLittle = 4 }; -// Register encoding definitions +/// Register encoding definitions. enum Encoding { eEncodingInvalid = 0, - eEncodingUint, // unsigned integer - eEncodingSint, // signed integer - eEncodingIEEE754, // float - eEncodingVector // vector registers + eEncodingUint, ///< unsigned integer + eEncodingSint, ///< signed integer + eEncodingIEEE754, ///< float + eEncodingVector ///< vector registers }; -// Display format definitions +/// Display format definitions. enum Format { eFormatDefault = 0, eFormatInvalid = 0, @@ -155,18 +157,18 @@ enum Format { eFormatBytes, eFormatBytesWithASCII, eFormatChar, - eFormatCharPrintable, // Only printable characters, space if not printable - eFormatComplex, // Floating point complex type + eFormatCharPrintable, ///< Only printable characters, space if not printable + eFormatComplex, ///< Floating point complex type eFormatComplexFloat = eFormatComplex, - eFormatCString, // NULL terminated C strings + eFormatCString, ///< NULL terminated C strings eFormatDecimal, eFormatEnum, eFormatHex, eFormatHexUppercase, eFormatFloat, eFormatOctal, - eFormatOSType, // OS character codes encoded into an integer 'PICT' 'text' - // etc... + eFormatOSType, ///< OS character codes encoded into an integer 'PICT' 'text' + ///< etc... eFormatUnicode16, eFormatUnicode32, eFormatUnsigned, @@ -184,20 +186,21 @@ enum Format { eFormatVectorOfFloat32, eFormatVectorOfFloat64, eFormatVectorOfUInt128, - eFormatComplexInteger, // Integer complex type - eFormatCharArray, // Print characters with no single quotes, used for - // character arrays that can contain non printable - // characters - eFormatAddressInfo, // Describe what an address points to (func + offset with - // file/line, symbol + offset, data, etc) - eFormatHexFloat, // ISO C99 hex float string - eFormatInstruction, // Disassemble an opcode - eFormatVoid, // Do not print this + eFormatComplexInteger, ///< Integer complex type + eFormatCharArray, ///< Print characters with no single quotes, used for + ///< character arrays that can contain non printable + ///< characters + eFormatAddressInfo, ///< Describe what an address points to (func + offset + ///< with file/line, symbol + offset, data, etc) + eFormatHexFloat, ///< ISO C99 hex float string + eFormatInstruction, ///< Disassemble an opcode + eFormatVoid, ///< Do not print this + eFormatUnicode8, kNumFormats }; -// Description levels for "void GetDescription(Stream *, DescriptionLevel)" -// calls +/// Description levels for "void GetDescription(Stream *, DescriptionLevel)" +/// calls. enum DescriptionLevel { eDescriptionLevelBrief = 0, eDescriptionLevelFull, @@ -206,7 +209,7 @@ enum DescriptionLevel { kNumDescriptionLevels }; -// Script interpreter types +/// Script interpreter types. enum ScriptLanguage { eScriptLanguageNone, eScriptLanguagePython, @@ -214,21 +217,21 @@ enum ScriptLanguage { eScriptLanguageUnknown }; -// Register numbering types +/// Register numbering types. // See RegisterContext::ConvertRegisterKindToRegisterNumber to convert any of // these to the lldb internal register numbering scheme (eRegisterKindLLDB). enum RegisterKind { - eRegisterKindEHFrame = 0, // the register numbers seen in eh_frame - eRegisterKindDWARF, // the register numbers seen DWARF - eRegisterKindGeneric, // insn ptr reg, stack ptr reg, etc not specific to any - // particular target - eRegisterKindProcessPlugin, // num used by the process plugin - e.g. by the - // remote gdb-protocol stub program - eRegisterKindLLDB, // lldb's internal register numbers + eRegisterKindEHFrame = 0, ///< the register numbers seen in eh_frame + eRegisterKindDWARF, ///< the register numbers seen DWARF + eRegisterKindGeneric, ///< insn ptr reg, stack ptr reg, etc not specific to + ///< any particular target + eRegisterKindProcessPlugin, ///< num used by the process plugin - e.g. by the + ///< remote gdb-protocol stub program + eRegisterKindLLDB, ///< lldb's internal register numbers kNumRegisterKinds }; -// Thread stop reasons +/// Thread stop reasons. enum StopReason { eStopReasonInvalid = 0, eStopReasonNone, @@ -237,13 +240,13 @@ enum StopReason { eStopReasonWatchpoint, eStopReasonSignal, eStopReasonException, - eStopReasonExec, // Program was re-exec'ed + eStopReasonExec, ///< Program was re-exec'ed eStopReasonPlanComplete, eStopReasonThreadExiting, eStopReasonInstrumentation }; -// Command Return Status Types +/// Command Return Status Types. enum ReturnStatus { eReturnStatusInvalid, eReturnStatusSuccessFinishNoResult, @@ -255,7 +258,7 @@ enum ReturnStatus { eReturnStatusQuit }; -// The results of expression evaluation: +/// The results of expression evaluation. enum ExpressionResults { eExpressionCompleted = 0, eExpressionSetupError, @@ -269,26 +272,26 @@ enum ExpressionResults { }; enum SearchDepth { - eSearchDepthInvalid = 0, - eSearchDepthTarget, - eSearchDepthModule, - eSearchDepthCompUnit, - eSearchDepthFunction, - eSearchDepthBlock, - eSearchDepthAddress, - kLastSearchDepthKind = eSearchDepthAddress + eSearchDepthInvalid = 0, + eSearchDepthTarget, + eSearchDepthModule, + eSearchDepthCompUnit, + eSearchDepthFunction, + eSearchDepthBlock, + eSearchDepthAddress, + kLastSearchDepthKind = eSearchDepthAddress }; -// Connection Status Types +/// Connection Status Types. enum ConnectionStatus { - eConnectionStatusSuccess, // Success - eConnectionStatusEndOfFile, // End-of-file encountered - eConnectionStatusError, // Check GetError() for details - eConnectionStatusTimedOut, // Request timed out - eConnectionStatusNoConnection, // No connection - eConnectionStatusLostConnection, // Lost connection while connected to a valid - // connection - eConnectionStatusInterrupted // Interrupted read + eConnectionStatusSuccess, ///< Success + eConnectionStatusEndOfFile, ///< End-of-file encountered + eConnectionStatusError, ///< Check GetError() for details + eConnectionStatusTimedOut, ///< Request timed out + eConnectionStatusNoConnection, ///< No connection + eConnectionStatusLostConnection, ///< Lost connection while connected to a + ///< valid connection + eConnectionStatusInterrupted ///< Interrupted read }; enum ErrorType { @@ -302,17 +305,17 @@ enum ErrorType { enum ValueType { eValueTypeInvalid = 0, - eValueTypeVariableGlobal = 1, // globals variable - eValueTypeVariableStatic = 2, // static variable - eValueTypeVariableArgument = 3, // function argument variables - eValueTypeVariableLocal = 4, // function local variables - eValueTypeRegister = 5, // stack frame register value - eValueTypeRegisterSet = 6, // A collection of stack frame register values - eValueTypeConstResult = 7, // constant result variables - eValueTypeVariableThreadLocal = 8 // thread local storage variable + eValueTypeVariableGlobal = 1, ///< globals variable + eValueTypeVariableStatic = 2, ///< static variable + eValueTypeVariableArgument = 3, ///< function argument variables + eValueTypeVariableLocal = 4, ///< function local variables + eValueTypeRegister = 5, ///< stack frame register value + eValueTypeRegisterSet = 6, ///< A collection of stack frame register values + eValueTypeConstResult = 7, ///< constant result variables + eValueTypeVariableThreadLocal = 8 ///< thread local storage variable }; -// Token size/granularities for Input Readers +/// Token size/granularities for Input Readers. enum InputReaderGranularity { eInputReaderGranularityInvalid = 0, @@ -331,39 +334,37 @@ enum InputReaderGranularity { /// in this class, and requests that that item be resolved, or /// indicates that the member did get resolved. FLAGS_ENUM(SymbolContextItem){ - eSymbolContextTarget = (1u << 0), ///< Set when \a target is requested from - /// a query, or was located in query - /// results - eSymbolContextModule = (1u << 1), ///< Set when \a module is requested from - /// a query, or was located in query - /// results - eSymbolContextCompUnit = (1u << 2), ///< Set when \a comp_unit is requested - /// from a query, or was located in - /// query results - eSymbolContextFunction = (1u << 3), ///< Set when \a function is requested - /// from a query, or was located in - /// query results - eSymbolContextBlock = (1u << 4), ///< Set when the deepest \a block is - /// requested from a query, or was located - /// in query results - eSymbolContextLineEntry = (1u << 5), ///< Set when \a line_entry is - /// requested from a query, or was - /// located in query results - eSymbolContextSymbol = (1u << 6), ///< Set when \a symbol is requested from - /// a query, or was located in query - /// results - eSymbolContextEverything = ((eSymbolContextSymbol << 1) - - 1u), ///< Indicates to try and lookup everything - /// up during a routine symbol context - /// query. - eSymbolContextVariable = (1u << 7), ///< Set when \a global or static - /// variable is requested from a query, - /// or was located in query results. - ///< eSymbolContextVariable is potentially expensive to lookup so it isn't - /// included in - ///< eSymbolContextEverything which stops it from being used during frame PC - /// lookups and - ///< many other potential address to symbol context lookups. + /// Set when \a target is requested from a query, or was located + /// in query results + eSymbolContextTarget = (1u << 0), + /// Set when \a module is requested from a query, or was located + /// in query results + eSymbolContextModule = (1u << 1), + /// Set when \a comp_unit is requested from a query, or was + /// located in query results + eSymbolContextCompUnit = (1u << 2), + /// Set when \a function is requested from a query, or was located + /// in query results + eSymbolContextFunction = (1u << 3), + /// Set when the deepest \a block is requested from a query, or + /// was located in query results + eSymbolContextBlock = (1u << 4), + /// Set when \a line_entry is requested from a query, or was + /// located in query results + eSymbolContextLineEntry = (1u << 5), + /// Set when \a symbol is requested from a query, or was located + /// in query results + eSymbolContextSymbol = (1u << 6), + /// Indicates to try and lookup everything up during a routine + /// symbol context query. + eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u), + /// Set when \a global or static variable is requested from a + /// query, or was located in query results. + /// eSymbolContextVariable is potentially expensive to lookup so + /// it isn't included in eSymbolContextEverything which stops it + /// from being used during frame PC lookups and many other + /// potential address to symbol context lookups. + eSymbolContextVariable = (1u << 7), }; LLDB_MARK_AS_BITMASK_ENUM(SymbolContextItem) @@ -373,27 +374,28 @@ FLAGS_ENUM(Permissions){ePermissionsWritable = (1u << 0), LLDB_MARK_AS_BITMASK_ENUM(Permissions) enum InputReaderAction { - eInputReaderActivate, // reader is newly pushed onto the reader stack - eInputReaderAsynchronousOutputWritten, // an async output event occurred; the - // reader may want to do something - eInputReaderReactivate, // reader is on top of the stack again after another - // reader was popped off - eInputReaderDeactivate, // another reader was pushed on the stack - eInputReaderGotToken, // reader got one of its tokens (granularity) - eInputReaderInterrupt, // reader received an interrupt signal (probably from a - // control-c) - eInputReaderEndOfFile, // reader received an EOF char (probably from a - // control-d) - eInputReaderDone // reader was just popped off the stack and is done + eInputReaderActivate, ///< reader is newly pushed onto the reader stack + eInputReaderAsynchronousOutputWritten, ///< an async output event occurred; + ///< the reader may want to do + ///< something + eInputReaderReactivate, ///< reader is on top of the stack again after another + ///< reader was popped off + eInputReaderDeactivate, ///< another reader was pushed on the stack + eInputReaderGotToken, ///< reader got one of its tokens (granularity) + eInputReaderInterrupt, ///< reader received an interrupt signal (probably from + ///< a control-c) + eInputReaderEndOfFile, ///< reader received an EOF char (probably from a + ///< control-d) + eInputReaderDone ///< reader was just popped off the stack and is done }; FLAGS_ENUM(BreakpointEventType){ eBreakpointEventTypeInvalidType = (1u << 0), eBreakpointEventTypeAdded = (1u << 1), eBreakpointEventTypeRemoved = (1u << 2), - eBreakpointEventTypeLocationsAdded = (1u << 3), // Locations added doesn't - // get sent when the - // breakpoint is created + eBreakpointEventTypeLocationsAdded = (1u << 3), ///< Locations added doesn't + ///< get sent when the + ///< breakpoint is created eBreakpointEventTypeLocationsRemoved = (1u << 4), eBreakpointEventTypeLocationsResolved = (1u << 5), eBreakpointEventTypeEnabled = (1u << 6), @@ -591,8 +593,8 @@ enum CommandArgumentType { // enumeration!! }; -// Symbol types -// Symbol holds the SymbolType in a 6-bit field (m_type), so if you get over 63 +/// Symbol types. +// Symbol holds the SymbolType in a 6-bit field (m_type), so if you get over 63 // entries you will have to resize that field. enum SymbolType { eSymbolTypeAny = 0, @@ -617,8 +619,8 @@ enum SymbolType { eSymbolTypeLineHeader, eSymbolTypeScopeBegin, eSymbolTypeScopeEnd, - eSymbolTypeAdditional, // When symbols take more than one entry, the extra - // entries get this type + eSymbolTypeAdditional, ///< When symbols take more than one entry, the extra + ///< entries get this type eSymbolTypeCompiler, eSymbolTypeInstrumentation, eSymbolTypeUndefined, @@ -631,19 +633,20 @@ enum SymbolType { enum SectionType { eSectionTypeInvalid, eSectionTypeCode, - eSectionTypeContainer, // The section contains child sections + eSectionTypeContainer, ///< The section contains child sections eSectionTypeData, - eSectionTypeDataCString, // Inlined C string data - eSectionTypeDataCStringPointers, // Pointers to C string data - eSectionTypeDataSymbolAddress, // Address of a symbol in the symbol table + eSectionTypeDataCString, ///< Inlined C string data + eSectionTypeDataCStringPointers, ///< Pointers to C string data + eSectionTypeDataSymbolAddress, ///< Address of a symbol in the symbol table eSectionTypeData4, eSectionTypeData8, eSectionTypeData16, eSectionTypeDataPointers, eSectionTypeDebug, eSectionTypeZeroFill, - eSectionTypeDataObjCMessageRefs, // Pointer to function pointer + selector - eSectionTypeDataObjCCFStrings, // Objective-C const CFString/NSString objects + eSectionTypeDataObjCMessageRefs, ///< Pointer to function pointer + selector + eSectionTypeDataObjCCFStrings, ///< Objective-C const CFString/NSString + ///< objects eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, eSectionTypeDWARFDebugAranges, @@ -663,25 +666,25 @@ enum SectionType { eSectionTypeDWARFAppleTypes, eSectionTypeDWARFAppleNamespaces, eSectionTypeDWARFAppleObjC, - eSectionTypeELFSymbolTable, // Elf SHT_SYMTAB section - eSectionTypeELFDynamicSymbols, // Elf SHT_DYNSYM section - eSectionTypeELFRelocationEntries, // Elf SHT_REL or SHT_REL section - eSectionTypeELFDynamicLinkInfo, // Elf SHT_DYNAMIC section + eSectionTypeELFSymbolTable, ///< Elf SHT_SYMTAB section + eSectionTypeELFDynamicSymbols, ///< Elf SHT_DYNSYM section + eSectionTypeELFRelocationEntries, ///< Elf SHT_REL or SHT_REL section + eSectionTypeELFDynamicLinkInfo, ///< Elf SHT_DYNAMIC section eSectionTypeEHFrame, eSectionTypeARMexidx, eSectionTypeARMextab, - eSectionTypeCompactUnwind, // compact unwind section in Mach-O, - // __TEXT,__unwind_info + eSectionTypeCompactUnwind, ///< compact unwind section in Mach-O, + ///< __TEXT,__unwind_info eSectionTypeGoSymtab, - eSectionTypeAbsoluteAddress, // Dummy section for symbols with absolute - // address + eSectionTypeAbsoluteAddress, ///< Dummy section for symbols with absolute + ///< address eSectionTypeDWARFGNUDebugAltLink, - eSectionTypeDWARFDebugTypes, // DWARF .debug_types section - eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names + eSectionTypeDWARFDebugTypes, ///< DWARF .debug_types section + eSectionTypeDWARFDebugNames, ///< DWARF v5 .debug_names eSectionTypeOther, - eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str - eSectionTypeDWARFDebugRngLists, // DWARF v5 .debug_rnglists - eSectionTypeDWARFDebugLocLists, // DWARF v5 .debug_loclists + eSectionTypeDWARFDebugLineStr, ///< DWARF v5 .debug_line_str + eSectionTypeDWARFDebugRngLists, ///< DWARF v5 .debug_rnglists + eSectionTypeDWARFDebugLocLists, ///< DWARF v5 .debug_loclists eSectionTypeDWARFDebugAbbrevDwo, eSectionTypeDWARFDebugInfoDwo, eSectionTypeDWARFDebugStrDwo, @@ -697,26 +700,27 @@ FLAGS_ENUM(EmulateInstructionOptions){ FLAGS_ENUM(FunctionNameType){ eFunctionNameTypeNone = 0u, eFunctionNameTypeAuto = - (1u << 1), // Automatically figure out which FunctionNameType - // bits to set based on the function name. - eFunctionNameTypeFull = (1u << 2), // The function name. - // For C this is the same as just the name of the function For C++ this is - // the mangled or demangled version of the mangled name. For ObjC this is - // the full function signature with the + or - and the square brackets and - // the class and selector - eFunctionNameTypeBase = (1u << 3), // The function name only, no namespaces - // or arguments and no class - // methods or selectors will be searched. - eFunctionNameTypeMethod = (1u << 4), // Find function by method name (C++) - // with no namespace or arguments + (1u << 1), ///< Automatically figure out which FunctionNameType + ///< bits to set based on the function name. + eFunctionNameTypeFull = (1u << 2), ///< The function name. + ///< For C this is the same as just the name of the function For C++ this is + ///< the mangled or demangled version of the mangled name. For ObjC this is + ///< the full function signature with the + or - and the square brackets and + ///< the class and selector + eFunctionNameTypeBase = (1u + << 3), ///< The function name only, no namespaces + ///< or arguments and no class + ///< methods or selectors will be searched. + eFunctionNameTypeMethod = (1u << 4), ///< Find function by method name (C++) + ///< with no namespace or arguments eFunctionNameTypeSelector = - (1u << 5), // Find function by selector name (ObjC) names + (1u << 5), ///< Find function by selector name (ObjC) names eFunctionNameTypeAny = - eFunctionNameTypeAuto // DEPRECATED: use eFunctionNameTypeAuto + eFunctionNameTypeAuto ///< DEPRECATED: use eFunctionNameTypeAuto }; LLDB_MARK_AS_BITMASK_ENUM(FunctionNameType) -// Basic types enumeration for the public API SBType::GetBasicType() +/// Basic types enumeration for the public API SBType::GetBasicType(). enum BasicType { eBasicTypeInvalid = 0, eBasicTypeVoid = 1, @@ -801,8 +805,8 @@ enum TemplateArgumentKind { eTemplateArgumentKindNullPtr, }; -// Options that can be set for a formatter to alter its behavior Not all of -// these are applicable to all formatter types +/// Options that can be set for a formatter to alter its behavior. Not +/// all of these are applicable to all formatter types. FLAGS_ENUM(TypeOptions){eTypeOptionNone = (0u), eTypeOptionCascade = (1u << 0), eTypeOptionSkipPointers = (1u << 1), @@ -813,20 +817,28 @@ FLAGS_ENUM(TypeOptions){eTypeOptionNone = (0u), eTypeOptionHideNames = (1u << 6), eTypeOptionNonCacheable = (1u << 7), eTypeOptionHideEmptyAggregates = (1u << 8), - eTypeOptionFrontEndWantsDereference = (1u << 9) -}; + eTypeOptionFrontEndWantsDereference = (1u << 9)}; -// This is the return value for frame comparisons. If you are comparing frame -// A to frame B the following cases arise: 1) When frame A pushes frame B (or a -// frame that ends up pushing B) A is Older than B. 2) When frame A pushed -// frame B (or if frame A is on the stack but B is not) A is Younger than B 3) -// When frame A and frame B have the same StackID, they are Equal. 4) When -// frame A and frame B have the same immediate parent frame, but are not equal, -// the comparison yields -// SameParent. -// 5) If the two frames are on different threads or processes the comparison is -// Invalid 6) If for some reason we can't figure out what went on, we return -// Unknown. +/// This is the return value for frame comparisons. If you are comparing frame +/// A to frame B the following cases arise: +/// +/// 1) When frame A pushes frame B (or a frame that ends up pushing +/// B) A is Older than B. +/// +/// 2) When frame A pushed frame B (or if frameA is on the stack +/// but B is not) A is Younger than B. +/// +/// 3) When frame A and frame B have the same StackID, they are +/// Equal. +/// +/// 4) When frame A and frame B have the same immediate parent +/// frame, but are not equal, the comparison yields SameParent. +/// +/// 5) If the two frames are on different threads or processes the +/// comparison is Invalid. +/// +/// 6) If for some reason we can't figure out what went on, we +/// return Unknown. enum FrameComparison { eFrameCompareInvalid, eFrameCompareUnknown, @@ -836,12 +848,13 @@ enum FrameComparison { eFrameCompareOlder }; -// File Permissions -// -// Designed to mimic the unix file permission bits so they can be used with -// functions that set 'mode_t' to certain values for permissions. +/// File Permissions. +/// +/// Designed to mimic the unix file permission bits so they can be used with +/// functions that set 'mode_t' to certain values for permissions. FLAGS_ENUM(FilePermissions){ - eFilePermissionsUserRead = (1u << 8), eFilePermissionsUserWrite = (1u << 7), + eFilePermissionsUserRead = (1u << 8), + eFilePermissionsUserWrite = (1u << 7), eFilePermissionsUserExecute = (1u << 6), eFilePermissionsGroupRead = (1u << 5), eFilePermissionsGroupWrite = (1u << 4), @@ -895,29 +908,32 @@ FLAGS_ENUM(FilePermissions){ eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX, }; -// Queue work item types -// -// The different types of work that can be enqueued on a libdispatch aka Grand -// Central Dispatch (GCD) queue. +/// Queue work item types. +/// +/// The different types of work that can be enqueued on a libdispatch aka Grand +/// Central Dispatch (GCD) queue. enum QueueItemKind { eQueueItemKindUnknown = 0, eQueueItemKindFunction, eQueueItemKindBlock }; -// Queue type -// libdispatch aka Grand Central Dispatch (GCD) queues can be either serial -// (executing on one thread) or concurrent (executing on multiple threads). +/// Queue type. +/// +/// libdispatch aka Grand Central Dispatch (GCD) queues can be either +/// serial (executing on one thread) or concurrent (executing on +/// multiple threads). enum QueueKind { eQueueKindUnknown = 0, eQueueKindSerial, eQueueKindConcurrent }; -// Expression Evaluation Stages -// These are the cancellable stages of expression evaluation, passed to the -// expression evaluation callback, so that you can interrupt expression -// evaluation at the various points in its lifecycle. +/// Expression Evaluation Stages. +/// +/// These are the cancellable stages of expression evaluation, passed +/// to the expression evaluation callback, so that you can interrupt +/// expression evaluation at the various points in its lifecycle. enum ExpressionEvaluationPhase { eExpressionEvaluationParse = 0, eExpressionEvaluationIRGen, @@ -925,9 +941,10 @@ enum ExpressionEvaluationPhase { eExpressionEvaluationComplete }; -// Watchpoint Kind -// Indicates what types of events cause the watchpoint to fire. Used by Native -// *Protocol-related classes. +/// Watchpoint Kind. +/// +/// Indicates what types of events cause the watchpoint to fire. Used by Native +/// *Protocol-related classes. FLAGS_ENUM(WatchpointKind){eWatchpointKindWrite = (1u << 0), eWatchpointKindRead = (1u << 1)}; @@ -940,42 +957,44 @@ enum GdbSignal { eGdbSignalBreakpoint = 0x96 }; -// Used with SBHost::GetPath (lldb::PathType) to find files that are related to -// LLDB on the current host machine. Most files are relative to LLDB or are in -// known locations. +/// Used with SBHost::GetPath (lldb::PathType) to find files that are +/// related to LLDB on the current host machine. Most files are +/// relative to LLDB or are in known locations. enum PathType { - ePathTypeLLDBShlibDir, // The directory where the lldb.so (unix) or LLDB - // mach-o file in LLDB.framework (MacOSX) exists - ePathTypeSupportExecutableDir, // Find LLDB support executable directory - // (debugserver, etc) - ePathTypeHeaderDir, // Find LLDB header file directory - ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory - ePathTypeLLDBSystemPlugins, // System plug-ins directory - ePathTypeLLDBUserPlugins, // User plug-ins directory - ePathTypeLLDBTempSystemDir, // The LLDB temp directory for this system that - // will be cleaned up on exit - ePathTypeGlobalLLDBTempSystemDir, // The LLDB temp directory for this system, - // NOT cleaned up on a process exit. - ePathTypeClangDir // Find path to Clang builtin headers + ePathTypeLLDBShlibDir, ///< The directory where the lldb.so (unix) or LLDB + ///< mach-o file in LLDB.framework (MacOSX) exists + ePathTypeSupportExecutableDir, ///< Find LLDB support executable directory + ///< (debugserver, etc) + ePathTypeHeaderDir, ///< Find LLDB header file directory + ePathTypePythonDir, ///< Find Python modules (PYTHONPATH) directory + ePathTypeLLDBSystemPlugins, ///< System plug-ins directory + ePathTypeLLDBUserPlugins, ///< User plug-ins directory + ePathTypeLLDBTempSystemDir, ///< The LLDB temp directory for this system that + ///< will be cleaned up on exit + ePathTypeGlobalLLDBTempSystemDir, ///< The LLDB temp directory for this + ///< system, NOT cleaned up on a process + ///< exit. + ePathTypeClangDir ///< Find path to Clang builtin headers }; -// Kind of member function -// Used by the type system +/// Kind of member function. +/// +/// Used by the type system. enum MemberFunctionKind { - eMemberFunctionKindUnknown = 0, // Not sure what the type of this is - eMemberFunctionKindConstructor, // A function used to create instances - eMemberFunctionKindDestructor, // A function used to tear down existing - // instances - eMemberFunctionKindInstanceMethod, // A function that applies to a specific - // instance - eMemberFunctionKindStaticMethod // A function that applies to a type rather - // than any instance + eMemberFunctionKindUnknown = 0, ///< Not sure what the type of this is + eMemberFunctionKindConstructor, ///< A function used to create instances + eMemberFunctionKindDestructor, ///< A function used to tear down existing + ///< instances + eMemberFunctionKindInstanceMethod, ///< A function that applies to a specific + ///< instance + eMemberFunctionKindStaticMethod ///< A function that applies to a type rather + ///< than any instance }; -// String matching algorithm used by SBTarget +/// String matching algorithm used by SBTarget. enum MatchType { eMatchTypeNormal, eMatchTypeRegex, eMatchTypeStartsWith }; -// Bitmask that describes details about a type +/// Bitmask that describes details about a type. FLAGS_ENUM(TypeFlags){ eTypeHasChildren = (1u << 0), eTypeHasValue = (1u << 1), eTypeIsArray = (1u << 2), eTypeIsBlock = (1u << 3), @@ -991,67 +1010,67 @@ FLAGS_ENUM(TypeFlags){ eTypeInstanceIsPointer = (1u << 22)}; FLAGS_ENUM(CommandFlags){ - // eCommandRequiresTarget - // - // Ensures a valid target is contained in m_exe_ctx prior to executing the - // command. If a target doesn't exist or is invalid, the command will fail - // and CommandObject::GetInvalidTargetDescription() will be returned as the - // error. CommandObject subclasses can override the virtual function for - // GetInvalidTargetDescription() to provide custom strings when needed. + /// eCommandRequiresTarget + /// + /// Ensures a valid target is contained in m_exe_ctx prior to executing the + /// command. If a target doesn't exist or is invalid, the command will fail + /// and CommandObject::GetInvalidTargetDescription() will be returned as the + /// error. CommandObject subclasses can override the virtual function for + /// GetInvalidTargetDescription() to provide custom strings when needed. eCommandRequiresTarget = (1u << 0), - // eCommandRequiresProcess - // - // Ensures a valid process is contained in m_exe_ctx prior to executing the - // command. If a process doesn't exist or is invalid, the command will fail - // and CommandObject::GetInvalidProcessDescription() will be returned as - // the error. CommandObject subclasses can override the virtual function - // for GetInvalidProcessDescription() to provide custom strings when - // needed. + /// eCommandRequiresProcess + /// + /// Ensures a valid process is contained in m_exe_ctx prior to executing the + /// command. If a process doesn't exist or is invalid, the command will fail + /// and CommandObject::GetInvalidProcessDescription() will be returned as + /// the error. CommandObject subclasses can override the virtual function + /// for GetInvalidProcessDescription() to provide custom strings when + /// needed. eCommandRequiresProcess = (1u << 1), - // eCommandRequiresThread - // - // Ensures a valid thread is contained in m_exe_ctx prior to executing the - // command. If a thread doesn't exist or is invalid, the command will fail - // and CommandObject::GetInvalidThreadDescription() will be returned as the - // error. CommandObject subclasses can override the virtual function for - // GetInvalidThreadDescription() to provide custom strings when needed. + /// eCommandRequiresThread + /// + /// Ensures a valid thread is contained in m_exe_ctx prior to executing the + /// command. If a thread doesn't exist or is invalid, the command will fail + /// and CommandObject::GetInvalidThreadDescription() will be returned as the + /// error. CommandObject subclasses can override the virtual function for + /// GetInvalidThreadDescription() to provide custom strings when needed. eCommandRequiresThread = (1u << 2), - // eCommandRequiresFrame - // - // Ensures a valid frame is contained in m_exe_ctx prior to executing the - // command. If a frame doesn't exist or is invalid, the command will fail - // and CommandObject::GetInvalidFrameDescription() will be returned as the - // error. CommandObject subclasses can override the virtual function for - // GetInvalidFrameDescription() to provide custom strings when needed. + /// eCommandRequiresFrame + /// + /// Ensures a valid frame is contained in m_exe_ctx prior to executing the + /// command. If a frame doesn't exist or is invalid, the command will fail + /// and CommandObject::GetInvalidFrameDescription() will be returned as the + /// error. CommandObject subclasses can override the virtual function for + /// GetInvalidFrameDescription() to provide custom strings when needed. eCommandRequiresFrame = (1u << 3), - // eCommandRequiresRegContext - // - // Ensures a valid register context (from the selected frame if there is a - // frame in m_exe_ctx, or from the selected thread from m_exe_ctx) is - // available from m_exe_ctx prior to executing the command. If a target - // doesn't exist or is invalid, the command will fail and - // CommandObject::GetInvalidRegContextDescription() will be returned as the - // error. CommandObject subclasses can override the virtual function for - // GetInvalidRegContextDescription() to provide custom strings when needed. + /// eCommandRequiresRegContext + /// + /// Ensures a valid register context (from the selected frame if there is a + /// frame in m_exe_ctx, or from the selected thread from m_exe_ctx) is + /// available from m_exe_ctx prior to executing the command. If a target + /// doesn't exist or is invalid, the command will fail and + /// CommandObject::GetInvalidRegContextDescription() will be returned as the + /// error. CommandObject subclasses can override the virtual function for + /// GetInvalidRegContextDescription() to provide custom strings when needed. eCommandRequiresRegContext = (1u << 4), - // eCommandTryTargetAPILock - // - // Attempts to acquire the target lock if a target is selected in the - // command interpreter. If the command object fails to acquire the API - // lock, the command will fail with an appropriate error message. + /// eCommandTryTargetAPILock + /// + /// Attempts to acquire the target lock if a target is selected in the + /// command interpreter. If the command object fails to acquire the API + /// lock, the command will fail with an appropriate error message. eCommandTryTargetAPILock = (1u << 5), - // eCommandProcessMustBeLaunched - // - // Verifies that there is a launched process in m_exe_ctx, if there isn't, - // the command will fail with an appropriate error message. + /// eCommandProcessMustBeLaunched + /// + /// Verifies that there is a launched process in m_exe_ctx, if there isn't, + /// the command will fail with an appropriate error message. eCommandProcessMustBeLaunched = (1u << 6), - // eCommandProcessMustBePaused - // - // Verifies that there is a paused process in m_exe_ctx, if there isn't, - // the command will fail with an appropriate error message. + /// eCommandProcessMustBePaused + /// + /// Verifies that there is a paused process in m_exe_ctx, if there isn't, + /// the command will fail with an appropriate error message. eCommandProcessMustBePaused = (1u << 7)}; -// Whether a summary should cap how much data it returns to users or not +/// Whether a summary should cap how much data it returns to users or not. enum TypeSummaryCapping { eTypeSummaryCapped = true, eTypeSummaryUncapped = false diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index 0cdaf1cf9bf8..8315fbb27346 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -44,6 +44,7 @@ class BreakpointSiteList; class BroadcastEventSpec; class Broadcaster; class BroadcasterManager; +class CallFrameInfo; class ClangASTContext; class ClangASTImporter; class ClangASTMetadata; @@ -331,6 +332,7 @@ typedef std::shared_ptr<lldb_private::EventDataStructuredData> typedef std::shared_ptr<lldb_private::ExecutionContextRef> ExecutionContextRefSP; typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP; +typedef std::unique_ptr<lldb_private::File> FileUP; typedef std::shared_ptr<lldb_private::File> FileSP; typedef std::shared_ptr<lldb_private::Function> FunctionSP; typedef std::shared_ptr<lldb_private::FunctionCaller> FunctionCallerSP; diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h index 3d8b360fb301..9b7879c05f9e 100644 --- a/include/lldb/lldb-private-enumerations.h +++ b/include/lldb/lldb-private-enumerations.h @@ -198,18 +198,24 @@ enum class LineStatus { enum class TypeValidatorResult : bool { Success = true, Failure = false }; // Enumerations that can be used to specify scopes types when looking up types. -enum class CompilerContextKind { +enum class CompilerContextKind : uint16_t { Invalid = 0, - TranslationUnit, - Module, - Namespace, - Class, - Structure, - Union, - Function, - Variable, - Enumeration, - Typedef + TranslationUnit = 1, + Module = 1 << 1, + Namespace = 1 << 2, + Class = 1 << 3, + Struct = 1 << 4, + Union = 1 << 5, + Function = 1 << 6, + Variable = 1 << 7, + Enum = 1 << 8, + Typedef = 1 << 9, + + Any = 1 << 15, + /// Match 0..n nested modules. + AnyModule = Any | Module, + /// Match any type. + AnyType = Any | Class | Struct | Union | Enum | Typedef }; // Enumerations that can be used to specify the kind of metric we're looking at diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h index 3a9f78aae0fe..04b78bcc19f8 100644 --- a/include/lldb/lldb-private-interfaces.h +++ b/include/lldb/lldb-private-interfaces.h @@ -70,7 +70,7 @@ typedef lldb::ProcessSP (*ProcessCreateInstance)( const FileSpec *crash_file_path); typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)( Debugger &debugger); -typedef SymbolFile *(*SymbolFileCreateInstance)(ObjectFile *obj_file); +typedef SymbolFile *(*SymbolFileCreateInstance)(lldb::ObjectFileSP objfile_sp); typedef SymbolVendor *(*SymbolVendorCreateInstance)( const lldb::ModuleSP &module_sp, lldb_private::Stream @@ -102,11 +102,6 @@ typedef lldb::REPLSP (*REPLCreateInstance)(Status &error, lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options); -typedef void (*TypeSystemEnumerateSupportedLanguages)( - std::set<lldb::LanguageType> &languages_for_types, - std::set<lldb::LanguageType> &languages_for_expressions); -typedef void (*REPLEnumerateSupportedLanguages)( - std::set<lldb::LanguageType> &languages); typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); |