aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/include/lldb/Core
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb/Core')
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Address.h508
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h253
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h63
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h56
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h62
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Architecture.h111
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ClangForward.h134
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Communication.h367
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Debugger.h431
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h551
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h92
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/DumpRegisterValue.h30
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h507
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h66
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h207
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h220
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Highlighter.h156
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h585
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/IOStreamMacros.h41
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h116
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Mangled.h276
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h310
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Module.h1056
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ModuleChild.h62
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h519
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h424
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Opcode.h273
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h27
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h481
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/PropertiesBase.td49
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h107
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/STLUtils.h74
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h456
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Section.h275
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h167
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h40
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h54
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h62
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h156
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseMap.h65
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseSet.h55
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLMap.h128
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLVector.h72
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h61
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/UniqueCStringMap.h207
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h91
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/Value.h261
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h1042
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h65
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h96
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h154
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h69
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h78
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h79
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h136
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h62
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h78
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h171
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h169
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h87
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Core/dwarf.h76
61 files changed, 12726 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Address.h b/contrib/llvm-project/lldb/include/lldb/Core/Address.h
new file mode 100644
index 000000000000..07bb450d6092
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Address.h
@@ -0,0 +1,508 @@
+//===-- Address.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_Address_h_
+#define liblldb_Address_h_
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class Block;
+class CompileUnit;
+class ExecutionContextScope;
+class Function;
+class SectionList;
+class Stream;
+class Symbol;
+class SymbolContext;
+class Target;
+struct LineEntry;
+
+/// \class Address Address.h "lldb/Core/Address.h"
+/// A section + offset based address class.
+///
+/// The Address class allows addresses to be relative to a section that can
+/// move during runtime due to images (executables, shared libraries, bundles,
+/// frameworks) being loaded at different addresses than the addresses found
+/// in the object file that represents them on disk. There are currently two
+/// types of addresses for a section:
+/// \li file addresses
+/// \li load addresses
+///
+/// File addresses represent the virtual addresses that are in the "on disk"
+/// object files. These virtual addresses are converted to be relative to
+/// unique sections scoped to the object file so that when/if the addresses
+/// slide when the images are loaded/unloaded in memory, we can easily track
+/// these changes without having to update every object (compile unit ranges,
+/// line tables, function address ranges, lexical block and inlined subroutine
+/// address ranges, global and static variables) each time an image is loaded
+/// or unloaded.
+///
+/// Load addresses represent the virtual addresses where each section ends up
+/// getting loaded at runtime. Before executing a program, it is common for
+/// all of the load addresses to be unresolved. When a DynamicLoader plug-in
+/// receives notification that shared libraries have been loaded/unloaded, the
+/// load addresses of the main executable and any images (shared libraries)
+/// will be resolved/unresolved. When this happens, breakpoints that are in
+/// one of these sections can be set/cleared.
+class Address {
+public:
+ /// Dump styles allow the Address::Dump(Stream *,DumpStyle) const function
+ /// to display Address contents in a variety of ways.
+ enum DumpStyle {
+ DumpStyleInvalid, ///< Invalid dump style
+ DumpStyleSectionNameOffset, ///< Display as the section name + offset.
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a section name + offset
+ /// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf \endcode
+ DumpStyleSectionPointerOffset, ///< Display as the section pointer + offset
+ ///(debug output).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a section pointer +
+ /// offset (lldb::Section *)0x35cc50 + 0x000000000005cfdf \endcode
+ DumpStyleFileAddress, ///< Display as the file address (if any).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a file address
+ /// 0x000000000005dcff \endcode
+ DumpStyleModuleWithFileAddress, ///< Display as the file address with the
+ /// module name prepended (if any).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a file address
+ /// libSystem.B.dylib[0x000000000005dcff] \endcode
+ DumpStyleLoadAddress, ///< Display as the load address (if resolved).
+ ///< \code
+ /// // address for printf in libSystem.B.dylib as a load address
+ /// 0x00007fff8306bcff \endcode
+ DumpStyleResolvedDescription, ///< Display the details about what an address
+ /// resolves to. This can
+ ///< be anything from a symbol context summary (module, function/symbol,
+ ///< and file and line), to information about what the pointer points to
+ ///< if the address is in a section (section of pointers, c strings, etc).
+ DumpStyleResolvedDescriptionNoModule,
+ DumpStyleResolvedDescriptionNoFunctionArguments,
+ DumpStyleNoFunctionName, ///< Elide the function name; display an offset
+ /// into the current function.
+ ///< Used primarily in disassembly symbolication
+ DumpStyleDetailedSymbolContext, ///< Detailed symbol context information for
+ /// an address for all symbol
+ ///< context members.
+ DumpStyleResolvedPointerDescription ///< Dereference a pointer at the
+ /// current address and then lookup the
+ ///< dereferenced address using DumpStyleResolvedDescription
+ };
+
+ /// Default constructor.
+ ///
+ /// Initialize with a invalid section (NULL) and an invalid offset
+ /// (LLDB_INVALID_ADDRESS).
+ Address() : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {}
+
+ /// Copy constructor
+ ///
+ /// Makes a copy of the another Address object \a rhs.
+ ///
+ /// \param[in] rhs
+ /// A const Address object reference to copy.
+ Address(const Address &rhs)
+ : m_section_wp(rhs.m_section_wp), m_offset(rhs.m_offset) {}
+
+ /// Construct with a section pointer and offset.
+ ///
+ /// Initialize the address with the supplied \a section and \a offset.
+ ///
+ /// \param[in] section
+ /// A section pointer to a valid lldb::Section, or NULL if the
+ /// address doesn't have a section or will get resolved later.
+ ///
+ /// \param[in] offset
+ /// The offset in bytes into \a section.
+ Address(const lldb::SectionSP &section_sp, lldb::addr_t offset)
+ : m_section_wp(), // Don't init with section_sp in case section_sp is
+ // invalid (the weak_ptr will throw)
+ m_offset(offset) {
+ if (section_sp)
+ m_section_wp = section_sp;
+ }
+
+ /// Construct with a virtual address and section list.
+ ///
+ /// Initialize and resolve the address with the supplied virtual address \a
+ /// file_addr.
+ ///
+ /// \param[in] file_addr
+ /// A virtual file address.
+ ///
+ /// \param[in] section_list
+ /// A list of sections, one of which may contain the \a file_addr.
+ Address(lldb::addr_t file_addr, const SectionList *section_list);
+
+ Address(lldb::addr_t abs_addr);
+
+/// Assignment operator.
+///
+/// Copies the address value from another Address object \a rhs into \a this
+/// object.
+///
+/// \param[in] rhs
+/// A const Address object reference to copy.
+///
+/// \return
+/// A const Address object reference to \a this.
+ const Address &operator=(const Address &rhs);
+
+ /// Clear the object's state.
+ ///
+ /// Sets the section to an invalid value (NULL) and an invalid offset
+ /// (LLDB_INVALID_ADDRESS).
+ void Clear() {
+ m_section_wp.reset();
+ m_offset = LLDB_INVALID_ADDRESS;
+ }
+
+ /// Compare two Address objects.
+ ///
+ /// \param[in] lhs
+ /// The Left Hand Side const Address object reference.
+ ///
+ /// \param[in] rhs
+ /// The Right Hand Side const Address object reference.
+ ///
+ /// \return
+ /// \li -1 if lhs < rhs
+ /// \li 0 if lhs == rhs
+ /// \li 1 if lhs > rhs
+ static int CompareFileAddress(const Address &lhs, const Address &rhs);
+
+ static int CompareLoadAddress(const Address &lhs, const Address &rhs,
+ Target *target);
+
+ static int CompareModulePointerAndOffset(const Address &lhs,
+ const Address &rhs);
+
+ // For use with std::map, std::multi_map
+ class ModulePointerAndOffsetLessThanFunctionObject {
+ public:
+ ModulePointerAndOffsetLessThanFunctionObject() = default;
+
+ bool operator()(const Address &a, const Address &b) const {
+ return Address::CompareModulePointerAndOffset(a, b) < 0;
+ }
+ };
+
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the supplied stream
+ /// \a s. There are many ways to display a section offset based address, and
+ /// \a style lets the user choose.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ ///
+ /// \param[in] style
+ /// The display style for the address.
+ ///
+ /// \param[in] fallback_style
+ /// The display style for the address.
+ ///
+ /// \return
+ /// Returns \b true if the address was able to be displayed.
+ /// File and load addresses may be unresolved and it may not be
+ /// possible to display a valid value, \b false will be returned
+ /// in such cases.
+ ///
+ /// \see Address::DumpStyle
+ bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
+ DumpStyle fallback_style = DumpStyleInvalid,
+ uint32_t addr_byte_size = UINT32_MAX) const;
+
+ AddressClass GetAddressClass() const;
+
+ /// Get the file address.
+ ///
+ /// If an address comes from a file on disk that has section relative
+ /// addresses, then it has a virtual address that is relative to unique
+ /// section in the object file.
+ ///
+ /// \return
+ /// The valid file virtual address, or LLDB_INVALID_ADDRESS if
+ /// the address doesn't have a file virtual address (image is
+ /// from memory only with no representation on disk).
+ lldb::addr_t GetFileAddress() const;
+
+ /// Get the load address.
+ ///
+ /// If an address comes from a file on disk that has section relative
+ /// addresses, then it has a virtual address that is relative to unique
+ /// section in the object file. Sections get resolved at runtime by
+ /// DynamicLoader plug-ins as images (executables and shared libraries) get
+ /// loaded/unloaded. If a section is loaded, then the load address can be
+ /// resolved.
+ ///
+ /// \return
+ /// The valid load virtual address, or LLDB_INVALID_ADDRESS if
+ /// the address is currently not loaded.
+ lldb::addr_t GetLoadAddress(Target *target) const;
+
+ /// Get the load address as a callable code load address.
+ ///
+ /// This function will first resolve its address to a load address. Then, if
+ /// the address turns out to be in code address, return the load address
+ /// that would be required to call or return to. The address might have
+ /// extra bits set (bit zero will be set to Thumb functions for an ARM
+ /// target) that are required when changing the program counter to setting a
+ /// return address.
+ ///
+ /// \return
+ /// The valid load virtual address, or LLDB_INVALID_ADDRESS if
+ /// the address is currently not loaded.
+ lldb::addr_t GetCallableLoadAddress(Target *target,
+ bool is_indirect = false) const;
+
+ /// Get the load address as an opcode load address.
+ ///
+ /// This function will first resolve its address to a load address. Then, if
+ /// the address turns out to be in code address, return the load address for
+ /// an opcode. This address object might have extra bits set (bit zero will
+ /// be set to Thumb functions for an
+ /// ARM target) that are required for changing the program counter
+ /// and this function will remove any bits that are intended for these
+ /// special purposes. The result of this function can be used to safely
+ /// write a software breakpoint trap to memory.
+ ///
+ /// \return
+ /// The valid load virtual address with extra callable bits
+ /// removed, or LLDB_INVALID_ADDRESS if the address is currently
+ /// not loaded.
+ lldb::addr_t GetOpcodeLoadAddress(
+ Target *target,
+ AddressClass addr_class = AddressClass::eInvalid) const;
+
+ /// Get the section relative offset value.
+ ///
+ /// \return
+ /// The current offset, or LLDB_INVALID_ADDRESS if this address
+ /// doesn't contain a valid offset.
+ lldb::addr_t GetOffset() const { return m_offset; }
+
+ /// Check if an address is section offset.
+ ///
+ /// When converting a virtual file or load address into a section offset
+ /// based address, we often need to know if, given a section list, if the
+ /// address was able to be converted to section offset. This function
+ /// returns true if the current value contained in this object is section
+ /// offset based.
+ ///
+ /// \return
+ /// Returns \b true if the address has a valid section and
+ /// offset, \b false otherwise.
+ bool IsSectionOffset() const {
+ return IsValid() && (GetSection().get() != nullptr);
+ }
+
+ /// Check if the object state is valid.
+ ///
+ /// A valid Address object contains either a section pointer and
+ /// offset (for section offset based addresses), or just a valid offset
+ /// (for absolute addresses that have no section).
+ ///
+ /// \return
+ /// Returns \b true if the offset is valid, \b false
+ /// otherwise.
+ bool IsValid() const { return m_offset != LLDB_INVALID_ADDRESS; }
+
+ /// Get the memory cost of this object.
+ ///
+ /// \return
+ /// The number of bytes that this object occupies in memory.
+ size_t MemorySize() const;
+
+ /// Resolve a file virtual address using a section list.
+ ///
+ /// Given a list of sections, attempt to resolve \a addr as an offset into
+ /// one of the file sections.
+ ///
+ /// \return
+ /// Returns \b true if \a addr was able to be resolved, \b false
+ /// otherwise.
+ 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
+ /// contains \a load_addr. If successful, this address object will have a
+ /// valid section and offset. Else this address object will have no section
+ /// (NULL) and the offset will be \a load_addr.
+ ///
+ /// \param[in] load_addr
+ /// A load address from a current process.
+ ///
+ /// \param[in] target
+ /// The target to use when trying resolve the address into
+ /// a section + offset. The Target's SectionLoadList object
+ /// is used to resolve the address.
+ ///
+ /// \param[in] allow_section_end
+ /// If true, treat an address pointing to the end of the module as
+ /// belonging to that module.
+ ///
+ /// \return
+ /// Returns \b true if the load address was resolved to be
+ /// section/offset, \b false otherwise. It is often ok for an
+ /// address to not resolve to a section in a module, this often
+ /// happens for JIT'ed code, or any load addresses on the stack
+ /// or heap.
+ bool SetLoadAddress(lldb::addr_t load_addr, Target *target,
+ bool allow_section_end = false);
+
+ bool SetOpcodeLoadAddress(
+ lldb::addr_t load_addr, Target *target,
+ AddressClass addr_class = AddressClass::eInvalid,
+ bool allow_section_end = false);
+
+ bool SetCallableLoadAddress(lldb::addr_t load_addr, Target *target);
+
+ /// Get accessor for the module for this address.
+ ///
+ /// \return
+ /// Returns the Module pointer that this address is an offset
+ /// in, or NULL if this address doesn't belong in a module, or
+ /// isn't resolved yet.
+ lldb::ModuleSP GetModule() const;
+
+ /// Get const accessor for the section.
+ ///
+ /// \return
+ /// Returns the const lldb::Section pointer that this address is an
+ /// offset in, or NULL if this address is absolute.
+ lldb::SectionSP GetSection() const { return m_section_wp.lock(); }
+
+ /// Set accessor for the offset.
+ ///
+ /// \param[in] offset
+ /// A new offset value for this object.
+ ///
+ /// \return
+ /// Returns \b true if the offset changed, \b false otherwise.
+ bool SetOffset(lldb::addr_t offset) {
+ bool changed = m_offset != offset;
+ m_offset = offset;
+ return changed;
+ }
+
+ void SetRawAddress(lldb::addr_t addr) {
+ m_section_wp.reset();
+ m_offset = addr;
+ }
+
+ bool Slide(int64_t offset) {
+ if (m_offset != LLDB_INVALID_ADDRESS) {
+ m_offset += offset;
+ return true;
+ }
+ return false;
+ }
+
+ /// Set accessor for the section.
+ ///
+ /// \param[in] section
+ /// A new lldb::Section pointer to use as the section base. Can
+ /// be NULL for absolute addresses that are not relative to
+ /// any section.
+ void SetSection(const lldb::SectionSP &section_sp) {
+ m_section_wp = section_sp;
+ }
+
+ void ClearSection() { m_section_wp.reset(); }
+
+ /// Reconstruct a symbol context from an address.
+ ///
+ /// This class doesn't inherit from SymbolContextScope because many address
+ /// objects have short lifespans. Address objects that are section offset
+ /// can reconstruct their symbol context by looking up the address in the
+ /// module found in the section.
+ ///
+ /// \see SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ uint32_t CalculateSymbolContext(SymbolContext *sc,
+ lldb::SymbolContextItem resolve_scope =
+ lldb::eSymbolContextEverything) const;
+
+ lldb::ModuleSP CalculateSymbolContextModule() const;
+
+ CompileUnit *CalculateSymbolContextCompileUnit() const;
+
+ Function *CalculateSymbolContextFunction() const;
+
+ Block *CalculateSymbolContextBlock() const;
+
+ Symbol *CalculateSymbolContextSymbol() const;
+
+ bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const;
+
+ // Returns true if the section should be valid, but isn't because the shared
+ // pointer to the section can't be reconstructed from a weak pointer that
+ // contains a valid weak reference to a section. Returns false if the section
+ // weak pointer has no reference to a section, or if the section is still
+ // valid
+ bool SectionWasDeleted() const;
+
+protected:
+ // Member variables.
+ lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL.
+ lldb::addr_t m_offset; ///< Offset into section if \a m_section_wp is valid...
+
+ // Returns true if the m_section_wp once had a reference to a valid section
+ // shared pointer, but no longer does. This can happen if we have an address
+ // from a module that gets unloaded and deleted. This function should only be
+ // called if GetSection() returns an empty shared pointer and you want to
+ // know if this address used to have a valid section.
+ bool SectionWasDeletedPrivate() const;
+};
+
+// NOTE: Be careful using this operator. It can correctly compare two
+// addresses from the same Module correctly. It can't compare two addresses
+// from different modules in any meaningful way, but it will compare the module
+// pointers.
+//
+// To sum things up:
+// - works great for addresses within the same module - it works for addresses
+// across multiple modules, but don't expect the
+// address results to make much sense
+//
+// This basically lets Address objects be used in ordered collection classes.
+bool operator<(const Address &lhs, const Address &rhs);
+bool operator>(const Address &lhs, const Address &rhs);
+bool operator==(const Address &lhs, const Address &rhs);
+bool operator!=(const Address &lhs, const Address &rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_Address_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h
new file mode 100644
index 000000000000..4a019bfcfc3f
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h
@@ -0,0 +1,253 @@
+//===-- AddressRange.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_AddressRange_h_
+#define liblldb_AddressRange_h_
+
+#include "lldb/Core/Address.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+
+namespace lldb_private {
+class SectionList;
+class Stream;
+class Target;
+
+/// \class AddressRange AddressRange.h "lldb/Core/AddressRange.h"
+/// A section + offset based address range class.
+class AddressRange {
+public:
+ /// Default constructor.
+ ///
+ /// Initialize with a invalid section (NULL), an invalid offset
+ /// (LLDB_INVALID_ADDRESS), and zero byte size.
+ AddressRange();
+
+ /// Construct with a section pointer, offset, and byte_size.
+ ///
+ /// Initialize the address with the supplied \a section, \a offset and \a
+ /// byte_size.
+ ///
+ /// \param[in] section
+ /// A section pointer to a valid lldb::Section, or NULL if the
+ /// address doesn't have a section or will get resolved later.
+ ///
+ /// \param[in] offset
+ /// The offset in bytes into \a section.
+ ///
+ /// \param[in] byte_size
+ /// The size in bytes of the address range.
+ AddressRange(const lldb::SectionSP &section, lldb::addr_t offset,
+ lldb::addr_t byte_size);
+
+ /// Construct with a virtual address, section list and byte size.
+ ///
+ /// Initialize and resolve the address with the supplied virtual address \a
+ /// file_addr, and byte size \a byte_size.
+ ///
+ /// \param[in] file_addr
+ /// A virtual address.
+ ///
+ /// \param[in] byte_size
+ /// The size in bytes of the address range.
+ ///
+ /// \param[in] section_list
+ /// A list of sections, one of which may contain the \a vaddr.
+ AddressRange(lldb::addr_t file_addr, lldb::addr_t byte_size,
+ const SectionList *section_list = nullptr);
+
+ /// Construct with a Address object address and byte size.
+ ///
+ /// Initialize by copying the section offset address in \a so_addr, and
+ /// setting the byte size to \a byte_size.
+ ///
+ /// \param[in] so_addr
+ /// A section offset address object.
+ ///
+ /// \param[in] byte_size
+ /// The size in bytes of the address range.
+ AddressRange(const Address &so_addr, lldb::addr_t byte_size);
+
+ /// Destructor.
+ ///
+ /// The destructor is virtual in case this class is subclassed.
+ ~AddressRange();
+
+ /// Clear the object's state.
+ ///
+ /// Sets the section to an invalid value (NULL), an invalid offset
+ /// (LLDB_INVALID_ADDRESS) and a zero byte size.
+ void Clear();
+
+ /// Check if a section offset address is contained in this range.
+ ///
+ /// \param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// \return
+ /// Returns \b true if \a so_addr is contained in this range,
+ /// \b false otherwise.
+ // bool
+ // Contains (const Address &so_addr) const;
+
+ /// Check if a section offset address is contained in this range.
+ ///
+ /// \param[in] so_addr_ptr
+ /// A section offset address object pointer.
+ ///
+ /// \return
+ /// Returns \b true if \a so_addr is contained in this range,
+ /// \b false otherwise.
+ // bool
+ // Contains (const Address *so_addr_ptr) const;
+
+ /// Check if a section offset \a so_addr when represented as a file address
+ /// is contained within this object's file address range.
+ ///
+ /// \param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// \return
+ /// Returns \b true if both \a this and \a so_addr have
+ /// resolvable file address values and \a so_addr is contained
+ /// in the address range, \b false otherwise.
+ bool ContainsFileAddress(const Address &so_addr) const;
+
+ /// Check if the resolved file address \a file_addr is contained within this
+ /// object's file address range.
+ ///
+ /// \param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// \return
+ /// Returns \b true if both \a this has a resolvable file
+ /// address value and \a so_addr is contained in the address
+ /// range, \b false otherwise.
+ bool ContainsFileAddress(lldb::addr_t file_addr) const;
+
+ /// Check if a section offset \a so_addr when represented as a load address
+ /// is contained within this object's load address range.
+ ///
+ /// \param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// \return
+ /// Returns \b true if both \a this and \a so_addr have
+ /// resolvable load address values and \a so_addr is contained
+ /// in the address range, \b false otherwise.
+ bool ContainsLoadAddress(const Address &so_addr, Target *target) const;
+
+ /// Check if the resolved load address \a load_addr is contained within this
+ /// object's load address range.
+ ///
+ /// \param[in] so_addr
+ /// A section offset address object reference.
+ ///
+ /// \return
+ /// Returns \b true if both \a this has a resolvable load
+ /// address value and \a so_addr is contained in the address
+ /// range, \b false otherwise.
+ bool ContainsLoadAddress(lldb::addr_t load_addr, Target *target) const;
+
+ //------------------------------------------------------------------
+ /// Extends this range with \b rhs_range if it overlaps this range on the
+ /// right side. The range overlaps on the right side if the base address
+ /// of \b rhs_range lies within this range or if it's contiguous on its
+ /// right side.
+ ///
+ /// @param[in] rhs_range
+ /// The range to extend at the right side.
+ ///
+ /// @return
+ /// Returns \b true if this range was extended, \b false otherwise.
+ //------------------------------------------------------------------
+ bool Extend(const AddressRange &rhs_range);
+
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the supplied stream
+ /// \a s. There are many ways to display a section offset based address
+ /// range, and \a style lets the user choose how the base address gets
+ /// displayed.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ ///
+ /// \param[in] style
+ /// The display style for the address.
+ ///
+ /// \return
+ /// Returns \b true if the address was able to be displayed.
+ /// File and load addresses may be unresolved and it may not be
+ /// possible to display a valid value, \b false will be returned
+ /// in such cases.
+ ///
+ /// \see Address::DumpStyle
+ bool
+ Dump(Stream *s, Target *target, Address::DumpStyle style,
+ Address::DumpStyle fallback_style = Address::DumpStyleInvalid) const;
+
+ /// Dump a debug description of this object to a Stream.
+ ///
+ /// Dump a debug description of the contents of this object to the supplied
+ /// stream \a s.
+ ///
+ /// The debug description contains verbose internal state such and pointer
+ /// values, reference counts, etc.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ void DumpDebug(Stream *s) const;
+
+ /// Get accessor for the base address of the range.
+ ///
+ /// \return
+ /// A reference to the base address object.
+ Address &GetBaseAddress() { return m_base_addr; }
+
+ /// Get const accessor for the base address of the range.
+ ///
+ /// \return
+ /// A const reference to the base address object.
+ const Address &GetBaseAddress() const { return m_base_addr; }
+
+ /// Get accessor for the byte size of this range.
+ ///
+ /// \return
+ /// The size in bytes of this address range.
+ lldb::addr_t GetByteSize() const { return m_byte_size; }
+
+ /// Get the memory cost of this object.
+ ///
+ /// \return
+ /// The number of bytes that this object occupies in memory.
+ size_t MemorySize() const {
+ // Noting special for the memory size of a single AddressRange object, it
+ // is just the size of itself.
+ return sizeof(AddressRange);
+ }
+
+ /// Set accessor for the byte size of this range.
+ ///
+ /// \param[in] byte_size
+ /// The new size in bytes of this address range.
+ void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; }
+
+protected:
+ // Member variables
+ Address m_base_addr; ///< The section offset base address of this range.
+ lldb::addr_t m_byte_size; ///< The size in bytes of this address range.
+};
+
+// bool operator== (const AddressRange& lhs, const AddressRange& rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressRange_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h
new file mode 100644
index 000000000000..cd95c7c31cd6
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolver.h
@@ -0,0 +1,63 @@
+//===-- AddressResolver.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_AddressResolver_h_
+#define liblldb_AddressResolver_h_
+
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/lldb-defines.h"
+
+#include <stddef.h>
+#include <vector>
+
+namespace lldb_private {
+class ModuleList;
+class Stream;
+
+/// \class AddressResolver AddressResolver.h "lldb/Core/AddressResolver.h"
+/// This class works with SearchFilter to resolve function names and source
+/// file locations to their concrete addresses.
+
+/// General Outline:
+/// The AddressResolver is a Searcher. In that protocol, the SearchFilter
+/// asks the question "At what depth of the symbol context descent do you want
+/// your callback to get called?" of the filter. The resolver answers this
+/// question (in the GetDepth method) and provides the resolution callback.
+
+class AddressResolver : public Searcher {
+public:
+ enum MatchType { Exact, Regexp, Glob };
+
+ AddressResolver();
+
+ ~AddressResolver() override;
+
+ virtual void ResolveAddress(SearchFilter &filter);
+
+ virtual void ResolveAddressInModules(SearchFilter &filter,
+ ModuleList &modules);
+
+ void GetDescription(Stream *s) override = 0;
+
+ std::vector<AddressRange> &GetAddressRanges();
+
+ size_t GetNumberOfAddresses();
+
+ AddressRange &GetAddressRangeAtIndex(size_t idx);
+
+protected:
+ std::vector<AddressRange> m_address_ranges;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AddressResolver);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressResolver_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h
new file mode 100644
index 000000000000..efbe3de1f294
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverFileLine.h
@@ -0,0 +1,56 @@
+//===-- AddressResolverFileLine.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_AddressResolverFileLine_h_
+#define liblldb_AddressResolverFileLine_h_
+
+#include "lldb/Core/AddressResolver.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-defines.h"
+
+#include <stdint.h>
+
+namespace lldb_private {
+class Address;
+class Stream;
+class SymbolContext;
+
+/// \class AddressResolverFileLine AddressResolverFileLine.h
+/// "lldb/Core/AddressResolverFileLine.h" This class finds address for source
+/// file and line. Optionally, it will look for inlined instances of the file
+/// and line specification.
+
+class AddressResolverFileLine : public AddressResolver {
+public:
+ AddressResolverFileLine(const FileSpec &resolver, uint32_t line_no,
+ bool check_inlines);
+
+ ~AddressResolverFileLine() override;
+
+ Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr) override;
+
+ lldb::SearchDepth GetDepth() override;
+
+ void GetDescription(Stream *s) override;
+
+protected:
+ FileSpec m_file_spec; // This is the file spec we are looking for.
+ uint32_t m_line_number; // This is the line number that we are looking for.
+ bool m_inlines; // This determines whether the resolver looks for inlined
+ // functions or not.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AddressResolverFileLine);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressResolverFileLine_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h
new file mode 100644
index 000000000000..8a039f9e1d92
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressResolverName.h
@@ -0,0 +1,62 @@
+//===-- AddressResolverName.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_AddressResolverName_h_
+#define liblldb_AddressResolverName_h_
+
+#include "lldb/Core/AddressResolver.h"
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegularExpression.h"
+#include "lldb/lldb-defines.h"
+
+namespace lldb_private {
+class Address;
+class Stream;
+class SymbolContext;
+
+/// \class AddressResolverName AddressResolverName.h
+/// "lldb/Core/AddressResolverName.h" This class finds addresses for a given
+/// function name, either by exact match or by regular expression.
+
+class AddressResolverName : public AddressResolver {
+public:
+ AddressResolverName(const char *func_name,
+ AddressResolver::MatchType type = Exact);
+
+ // Creates a function breakpoint by regular expression. Takes over control
+ // of the lifespan of func_regex.
+ AddressResolverName(RegularExpression func_regex);
+
+ AddressResolverName(const char *class_name, const char *method,
+ AddressResolver::MatchType type);
+
+ ~AddressResolverName() override;
+
+ Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr) override;
+
+ lldb::SearchDepth GetDepth() override;
+
+ void GetDescription(Stream *s) override;
+
+protected:
+ ConstString m_func_name;
+ ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop
+ // on methods of this class.
+ RegularExpression m_regex;
+ AddressResolver::MatchType m_match_type;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(AddressResolverName);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AddressResolverName_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h
new file mode 100644
index 000000000000..d8dbbb4f540f
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Architecture.h
@@ -0,0 +1,111 @@
+//===-- Architecture.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_CORE_ARCHITECTURE_H
+#define LLDB_CORE_ARCHITECTURE_H
+
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+
+class Architecture : public PluginInterface {
+public:
+ Architecture() = default;
+ ~Architecture() override = default;
+
+ /// This is currently intended to handle cases where a
+ /// program stops at an instruction that won't get executed and it
+ /// allows the stop reason, like "breakpoint hit", to be replaced
+ /// with a different stop reason like "no stop reason".
+ ///
+ /// This is specifically used for ARM in Thumb code when we stop in
+ /// an IT instruction (if/then/else) where the instruction won't get
+ /// executed and therefore it wouldn't be correct to show the program
+ /// stopped at the current PC. The code is generic and applies to all
+ /// ARM CPUs.
+ virtual void OverrideStopInfo(Thread &thread) const = 0;
+
+ /// This method is used to get the number of bytes that should be
+ /// skipped, from function start address, to reach the first
+ /// instruction after the prologue. If overrode, it must return
+ /// non-zero only if the current address matches one of the known
+ /// function entry points.
+ ///
+ /// This method is called only if the standard platform-independent
+ /// code fails to get the number of bytes to skip, giving the plugin
+ /// a chance to try to find the missing info.
+ ///
+ /// This is specifically used for PPC64, where functions may have
+ /// more than one entry point, global and local, so both should
+ /// be compared with current address, in order to find out the
+ /// number of bytes that should be skipped, in case we are stopped
+ /// at either function entry point.
+ virtual size_t GetBytesToSkip(Symbol &func, const Address &curr_addr) const {
+ return 0;
+ }
+
+ /// Adjust function breakpoint address, if needed. In some cases,
+ /// the function start address is not the right place to set the
+ /// breakpoint, specially in functions with multiple entry points.
+ ///
+ /// This is specifically used for PPC64, for functions that have
+ /// both a global and a local entry point. In this case, the
+ /// breakpoint is adjusted to the first function address reached
+ /// by both entry points.
+ virtual void AdjustBreakpointAddress(const Symbol &func,
+ Address &addr) const {}
+
+
+ /// Get \a load_addr as a callable code load address for this target
+ ///
+ /// Take \a load_addr and potentially add any address bits that are
+ /// needed to make the address callable. For ARM this can set bit
+ /// zero (if it already isn't) if \a load_addr is a thumb function.
+ /// If \a addr_class is set to AddressClass::eInvalid, then the address
+ /// adjustment will always happen. If it is set to an address class
+ /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
+ /// returned.
+ virtual lldb::addr_t GetCallableLoadAddress(
+ lldb::addr_t addr, AddressClass addr_class = AddressClass::eInvalid) const {
+ return addr;
+ }
+
+ /// Get \a load_addr as an opcode for this target.
+ ///
+ /// Take \a load_addr and potentially strip any address bits that are
+ /// needed to make the address point to an opcode. For ARM this can
+ /// clear bit zero (if it already isn't) if \a load_addr is a
+ /// thumb function and load_addr is in code.
+ /// If \a addr_class is set to AddressClass::eInvalid, then the address
+ /// adjustment will always happen. If it is set to an address class
+ /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be
+ /// returned.
+
+ virtual lldb::addr_t GetOpcodeLoadAddress(
+ lldb::addr_t addr, AddressClass addr_class = AddressClass::eInvalid) const {
+ return addr;
+ }
+
+ // Get load_addr as breakable load address for this target. Take a addr and
+ // check if for any reason there is a better address than this to put a
+ // breakpoint on. If there is then return that address. For MIPS, if
+ // instruction at addr is a delay slot instruction then this method will find
+ // the address of its previous instruction and return that address.
+ virtual lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr,
+ Target &target) const {
+ return addr;
+ }
+
+private:
+ Architecture(const Architecture &) = delete;
+ void operator=(const Architecture &) = delete;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_CORE_ARCHITECTURE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ClangForward.h b/contrib/llvm-project/lldb/include/lldb/Core/ClangForward.h
new file mode 100644
index 000000000000..6b24b47c8a96
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ClangForward.h
@@ -0,0 +1,134 @@
+//===-- ClangForward.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_ClangForward_h_
+#define liblldb_ClangForward_h_
+
+
+#if defined(__cplusplus)
+
+namespace clang {
+namespace Builtin {
+class Context;
+}
+
+class Action;
+class ASTConsumer;
+class ASTContext;
+class ASTRecordLayout;
+class AddrLabelExpr;
+class AnalyzerOptions;
+class BinaryOperator;
+class ClassTemplateDecl;
+class ClassTemplateSpecializationDecl;
+class CodeGenOptions;
+class CodeGenerator;
+class CompilerInstance;
+class CompoundStmt;
+class CXXBaseSpecifier;
+class CXXBoolLiteralExpr;
+class CXXFunctionalCastExpr;
+class CXXMethodDecl;
+class CXXNamedCastExpr;
+class CXXRecordDecl;
+class CXXThisExpr;
+class CharacterLiteral;
+class CompoundAssignOperator;
+class Decl;
+class DeclarationName;
+class DeclaratorDecl;
+class DeclContext;
+class DeclRefExpr;
+class DeclStmt;
+class DependencyOutputOptions;
+class Diagnostic;
+class DiagnosticConsumer;
+class DiagnosticsEngine;
+class DiagnosticOptions;
+class EnumDecl;
+class EnumConstantDecl;
+class Expr;
+class ExternalASTSource;
+class ExtVectorElementExpr;
+class FieldDecl;
+class FileManager;
+class FileSystemOptions;
+class FloatingLiteral;
+class FrontendOptions;
+class FunctionDecl;
+class FunctionTemplateDecl;
+class FunctionTemplateSpecializationInfo;
+class GotoStmt;
+class HeaderSearchOptions;
+class IdentifierInfo;
+class IdentifierTable;
+class IntegerLiteral;
+class LabelStmt;
+class LangOptions;
+class MacroDirective;
+class MemberExpr;
+class Module;
+class NamedDecl;
+class NamespaceDecl;
+class NonTypeTemplateParmDecl;
+class ObjCEncodeExpr;
+class ObjCImplicitSetterGetterRefExpr;
+class ObjCInterfaceDecl;
+class ObjCIvarDecl;
+class ObjCIvarRefExpr;
+class ObjCMessageExpr;
+class ObjCMethodDecl;
+class ObjCPropertyRefExpr;
+class ObjCProtocolDecl;
+class ObjCProtocolExpr;
+class ObjCSelectorExpr;
+class ObjCSuperExpr;
+class ParenExpr;
+class ParmVarDecl;
+class PredefinedExpr;
+class PreprocessorOptions;
+class PreprocessorOutputOptions;
+class QualType;
+class QualifiedNameType;
+class RecordDecl;
+class SelectorTable;
+class SizeOfAlignOfExpr;
+class SourceLocation;
+class SourceManager;
+class Stmt;
+class StmtIteratorBase;
+class StringLiteral;
+class TagDecl;
+class TargetInfo;
+class TargetOptions;
+class TemplateArgument;
+class TemplateDecl;
+class TemplateParameterList;
+class TemplateTemplateParmDecl;
+class TemplateTypeParmDecl;
+class TextDiagnosticBuffer;
+class TranslationUnitDecl;
+class Type;
+class TypeDecl;
+class TypedefDecl;
+class TypesCompatibleExpr;
+class UnaryOperator;
+class ValueDecl;
+class VarDecl;
+struct PrintingPolicy;
+}
+
+namespace llvm {
+class APInt;
+class APSInt;
+class LLVMContext;
+class ExecutionEngine;
+}
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_ClangForward_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h
new file mode 100644
index 000000000000..901b8fdb8c8b
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h
@@ -0,0 +1,367 @@
+//===-- Communication.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_Communication_h_
+#define liblldb_Communication_h_
+
+#include "lldb/Host/HostThread.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/Timeout.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include <atomic>
+#include <mutex>
+#include <ratio>
+#include <string>
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class Connection;
+class ConstString;
+class Status;
+
+/// \class Communication Communication.h "lldb/Core/Communication.h" An
+/// abstract communications class.
+///
+/// Communication is an class that handles data communication between two data
+/// sources. It uses a Connection class to do the real communication. This
+/// approach has a couple of advantages: it allows a single instance of this
+/// class to be used even though its connection can change. Connections could
+/// negotiate for different connections based on abilities like starting with
+/// Bluetooth and negotiating up to WiFi if available. It also allows this
+/// class to be subclassed by any interfaces that don't want to give bytes but
+/// want to validate and give out packets. This can be done by overriding:
+///
+/// AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);
+///
+/// Communication inherits from Broadcaster which means it can be used in
+/// conjunction with Listener to wait for multiple broadcaster objects and
+/// multiple events from each of those objects. Communication defines a set of
+/// pre-defined event bits (see enumerations definitions that start with
+/// "eBroadcastBit" below).
+///
+/// There are two modes in which communications can occur:
+/// \li single-threaded
+/// \li multi-threaded
+///
+/// In single-threaded mode, all reads and writes happen synchronously on the
+/// calling thread.
+///
+/// In multi-threaded mode, a read thread is spawned that continually reads
+/// data and caches any received bytes. To start the read thread clients call:
+///
+/// bool Communication::StartReadThread (Status *);
+///
+/// If true is returned a read thread has been spawned that will continually
+/// execute a call to the pure virtual DoRead function:
+///
+/// size_t Communication::ReadFromConnection (void *, size_t, uint32_t);
+///
+/// When bytes are received the data gets cached in \a m_bytes and this class
+/// will broadcast a \b eBroadcastBitReadThreadGotBytes event. Clients that
+/// want packet based communication should override AppendBytesToCache. The
+/// subclasses can choose to call the built in AppendBytesToCache with the \a
+/// broadcast parameter set to false. This will cause the \b
+/// eBroadcastBitReadThreadGotBytes event not get broadcast, and then the
+/// subclass can post a \b eBroadcastBitPacketAvailable event when a full
+/// packet of data has been received.
+///
+/// If the connection is disconnected a \b eBroadcastBitDisconnected event
+/// gets broadcast. If the read thread exits a \b
+/// eBroadcastBitReadThreadDidExit event will be broadcast. Clients can also
+/// post a \b eBroadcastBitReadThreadShouldExit event to this object which
+/// will cause the read thread to exit.
+class Communication : public Broadcaster {
+public:
+ FLAGS_ANONYMOUS_ENUM(){
+ eBroadcastBitDisconnected =
+ (1u << 0), ///< Sent when the communications connection is lost.
+ eBroadcastBitReadThreadGotBytes =
+ (1u << 1), ///< Sent by the read thread when bytes become available.
+ eBroadcastBitReadThreadDidExit =
+ (1u
+ << 2), ///< Sent by the read thread when it exits to inform clients.
+ eBroadcastBitReadThreadShouldExit =
+ (1u << 3), ///< Sent by clients that need to cancel the read thread.
+ eBroadcastBitPacketAvailable =
+ (1u << 4), ///< Sent when data received makes a complete packet.
+ eBroadcastBitNoMorePendingInput = (1u << 5), ///< Sent by the read thread
+ ///to indicate all pending
+ ///input has been processed.
+ kLoUserBroadcastBit =
+ (1u << 16), ///< Subclasses can used bits 31:16 for any needed events.
+ kHiUserBroadcastBit = (1u << 31),
+ eAllEventBits = 0xffffffff};
+
+ typedef void (*ReadThreadBytesReceived)(void *baton, const void *src,
+ size_t src_len);
+
+ /// Construct the Communication object with the specified name for the
+ /// Broadcaster that this object inherits from.
+ ///
+ /// \param[in] broadcaster_name
+ /// The name of the broadcaster object. This name should be as
+ /// complete as possible to uniquely identify this object. The
+ /// broadcaster name can be updated after the connect function
+ /// is called.
+ Communication(const char *broadcaster_name);
+
+ /// Destructor.
+ ///
+ /// The destructor is virtual since this class gets subclassed.
+ ~Communication() override;
+
+ void Clear();
+
+ /// Connect using the current connection by passing \a url to its connect
+ /// function. string.
+ ///
+ /// \param[in] url
+ /// A string that contains all information needed by the
+ /// subclass to connect to another client.
+ ///
+ /// \return
+ /// \b True if the connect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// \see Status& Communication::GetError ();
+ /// \see bool Connection::Connect (const char *url);
+ lldb::ConnectionStatus Connect(const char *url, Status *error_ptr);
+
+ /// Disconnect the communications connection if one is currently connected.
+ ///
+ /// \return
+ /// \b True if the disconnect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// \see Status& Communication::GetError ();
+ /// \see bool Connection::Disconnect ();
+ lldb::ConnectionStatus Disconnect(Status *error_ptr = nullptr);
+
+ /// Check if the connection is valid.
+ ///
+ /// \return
+ /// \b True if this object is currently connected, \b false
+ /// otherwise.
+ bool IsConnected() const;
+
+ bool HasConnection() const;
+
+ lldb_private::Connection *GetConnection() { return m_connection_sp.get(); }
+
+ /// Read bytes from the current connection.
+ ///
+ /// If no read thread is running, this function call the connection's
+ /// Connection::Read(...) function to get any available.
+ ///
+ /// If a read thread has been started, this function will check for any
+ /// cached bytes that have already been read and return any currently
+ /// available bytes. If no bytes are cached, it will wait for the bytes to
+ /// become available by listening for the \a eBroadcastBitReadThreadGotBytes
+ /// event. If this function consumes all of the bytes in the cache, it will
+ /// reset the \a eBroadcastBitReadThreadGotBytes event bit.
+ ///
+ /// \param[in] dst
+ /// A destination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// \param[in] dst_len
+ /// The number of bytes to attempt to read, and also the max
+ /// number of bytes that can be placed into \a dst.
+ ///
+ /// \param[in] timeout
+ /// A timeout value or llvm::None for no timeout.
+ ///
+ /// \return
+ /// The number of bytes actually read.
+ ///
+ /// \see size_t Connection::Read (void *, size_t);
+ size_t Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout,
+ lldb::ConnectionStatus &status, Status *error_ptr);
+
+ /// The actual write function that attempts to write to the communications
+ /// protocol.
+ ///
+ /// Subclasses must override this function.
+ ///
+ /// \param[in] src
+ /// A source buffer that must be at least \a src_len bytes
+ /// long.
+ ///
+ /// \param[in] src_len
+ /// The number of bytes to attempt to write, and also the
+ /// number of bytes are currently available in \a src.
+ ///
+ /// \return
+ /// The number of bytes actually Written.
+ size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status,
+ Status *error_ptr);
+
+ /// Sets the connection that it to be used by this class.
+ ///
+ /// By making a communication class that uses different connections it
+ /// allows a single communication interface to negotiate and change its
+ /// connection without any interruption to the client. It also allows the
+ /// Communication class to be subclassed for packet based communication.
+ ///
+ /// \param[in] connection
+ /// A connection that this class will own and destroy.
+ ///
+ /// \see
+ /// class Connection
+ void SetConnection(Connection *connection);
+
+ /// Starts a read thread whose sole purpose it to read bytes from the
+ /// current connection. This function will call connection's read function:
+ ///
+ /// size_t Connection::Read (void *, size_t);
+ ///
+ /// When bytes are read and cached, this function will call:
+ ///
+ /// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len,
+ /// bool
+ /// broadcast);
+ ///
+ /// Subclasses should override this function if they wish to override the
+ /// default action of caching the bytes and broadcasting a \b
+ /// eBroadcastBitReadThreadGotBytes event.
+ ///
+ /// \return
+ /// \b True if the read thread was successfully started, \b
+ /// false otherwise.
+ ///
+ /// \see size_t Connection::Read (void *, size_t);
+ /// \see void Communication::AppendBytesToCache (const uint8_t * bytes,
+ /// size_t len, bool broadcast);
+ virtual bool StartReadThread(Status *error_ptr = nullptr);
+
+ /// Stops the read thread by cancelling it.
+ ///
+ /// \return
+ /// \b True if the read thread was successfully canceled, \b
+ /// false otherwise.
+ virtual bool StopReadThread(Status *error_ptr = nullptr);
+
+ virtual bool JoinReadThread(Status *error_ptr = nullptr);
+ /// Checks if there is a currently running read thread.
+ ///
+ /// \return
+ /// \b True if the read thread is running, \b false otherwise.
+ bool ReadThreadIsRunning();
+
+ /// The static read thread function. This function will call the "DoRead"
+ /// function continuously and wait for data to become available. When data
+ /// is received it will append the available data to the internal cache and
+ /// broadcast a \b eBroadcastBitReadThreadGotBytes event.
+ ///
+ /// \param[in] comm_ptr
+ /// A pointer to an instance of this class.
+ ///
+ /// \return
+ /// \b NULL.
+ ///
+ /// \see void Communication::ReadThreadGotBytes (const uint8_t *, size_t);
+ static lldb::thread_result_t ReadThread(lldb::thread_arg_t comm_ptr);
+
+ void SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,
+ void *callback_baton);
+
+ /// Wait for the read thread to process all outstanding data.
+ ///
+ /// After this function returns, the read thread has processed all data that
+ /// has been waiting in the Connection queue.
+ ///
+ void SynchronizeWithReadThread();
+
+ static const char *ConnectionStatusAsCString(lldb::ConnectionStatus status);
+
+ bool GetCloseOnEOF() const { return m_close_on_eof; }
+
+ void SetCloseOnEOF(bool b) { m_close_on_eof = b; }
+
+ static ConstString &GetStaticBroadcasterClass();
+
+ ConstString &GetBroadcasterClass() const override {
+ return GetStaticBroadcasterClass();
+ }
+
+protected:
+ lldb::ConnectionSP m_connection_sp; ///< The connection that is current in use
+ ///by this communications class.
+ HostThread m_read_thread; ///< The read thread handle in case we need to
+ ///cancel the thread.
+ std::atomic<bool> m_read_thread_enabled;
+ std::atomic<bool> m_read_thread_did_exit;
+ std::string
+ m_bytes; ///< A buffer to cache bytes read in the ReadThread function.
+ std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded
+ ///access to the cached bytes.
+ std::mutex
+ m_write_mutex; ///< Don't let multiple threads write at the same time...
+ std::mutex m_synchronize_mutex;
+ ReadThreadBytesReceived m_callback;
+ void *m_callback_baton;
+ bool m_close_on_eof;
+
+ size_t ReadFromConnection(void *dst, size_t dst_len,
+ const Timeout<std::micro> &timeout,
+ lldb::ConnectionStatus &status, Status *error_ptr);
+
+ /// Append new bytes that get read from the read thread into the internal
+ /// object byte cache. This will cause a \b eBroadcastBitReadThreadGotBytes
+ /// event to be broadcast if \a broadcast is true.
+ ///
+ /// Subclasses can override this function in order to inspect the received
+ /// data and check if a packet is available.
+ ///
+ /// Subclasses can also still call this function from the overridden method
+ /// to allow the caching to correctly happen and suppress the broadcasting
+ /// of the \a eBroadcastBitReadThreadGotBytes event by setting \a broadcast
+ /// to false.
+ ///
+ /// \param[in] src
+ /// A source buffer that must be at least \a src_len bytes
+ /// long.
+ ///
+ /// \param[in] src_len
+ /// The number of bytes to append to the cache.
+ virtual void AppendBytesToCache(const uint8_t *src, size_t src_len,
+ bool broadcast,
+ lldb::ConnectionStatus status);
+
+ /// Get any available bytes from our data cache. If this call empties the
+ /// data cache, the \b eBroadcastBitReadThreadGotBytes event will be reset
+ /// to signify no more bytes are available.
+ ///
+ /// \param[in] dst
+ /// A destination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// \param[in] dst_len
+ /// The number of bytes to attempt to read from the cache,
+ /// and also the max number of bytes that can be placed into
+ /// \a dst.
+ ///
+ /// \return
+ /// The number of bytes extracted from the data cache.
+ size_t GetCachedBytes(void *dst, size_t dst_len);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(Communication);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Communication_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h
new file mode 100644
index 000000000000..b2f696c22834
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Debugger.h
@@ -0,0 +1,431 @@
+//===-- Debugger.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_Debugger_h_
+#define liblldb_Debugger_h_
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#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"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/TargetList.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-private-types.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Threading.h"
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+
+namespace llvm {
+class raw_ostream;
+}
+
+namespace lldb_private {
+class Address;
+class CommandInterpreter;
+class Process;
+class Stream;
+class SymbolContext;
+class Target;
+
+namespace repro {
+class DataRecorder;
+}
+
+/// \class Debugger Debugger.h "lldb/Core/Debugger.h"
+/// A class to manage flag bits.
+///
+/// Provides a global root objects for the debugger core.
+
+class Debugger : public std::enable_shared_from_this<Debugger>,
+ public UserID,
+ public Properties {
+ friend class SourceManager; // For GetSourceFileCache.
+
+public:
+ ~Debugger() override;
+
+ static lldb::DebuggerSP
+ CreateInstance(lldb::LogOutputCallback log_callback = nullptr,
+ void *baton = nullptr);
+
+ static lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid);
+
+ static lldb::TargetSP FindTargetWithProcess(Process *process);
+
+ static void Initialize(LoadPluginCallbackType load_plugin_callback);
+
+ static void Terminate();
+
+ static void SettingsInitialize();
+
+ static void SettingsTerminate();
+
+ static void Destroy(lldb::DebuggerSP &debugger_sp);
+
+ static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id);
+
+ static lldb::DebuggerSP
+ FindDebuggerWithInstanceName(ConstString instance_name);
+
+ static size_t GetNumDebuggers();
+
+ static lldb::DebuggerSP GetDebuggerAtIndex(size_t index);
+
+ static bool FormatDisassemblerAddress(const FormatEntity::Entry *format,
+ const SymbolContext *sc,
+ const SymbolContext *prev_sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, Stream &s);
+
+ void Clear();
+
+ bool GetAsyncExecution();
+
+ void SetAsyncExecution(bool async);
+
+ lldb::FileSP GetInputFileSP() { return m_input_file_sp; }
+
+ lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_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 SetInputFile(lldb::FileSP file, repro::DataRecorder *recorder = nullptr);
+
+ void SetOutputFile(lldb::FileSP file);
+
+ void SetErrorFile(lldb::FileSP file);
+
+ void SaveInputTerminalState();
+
+ void RestoreInputTerminalState();
+
+ lldb::StreamSP GetAsyncOutputStream();
+
+ lldb::StreamSP GetAsyncErrorStream();
+
+ CommandInterpreter &GetCommandInterpreter() {
+ assert(m_command_interpreter_up.get());
+ return *m_command_interpreter_up;
+ }
+
+ ScriptInterpreter *GetScriptInterpreter(bool can_create = true);
+
+ lldb::ListenerSP GetListener() { return m_listener_sp; }
+
+ // This returns the Debugger's scratch source manager. It won't be able to
+ // look up files in debug information, but it can look up files by absolute
+ // path and display them to you. To get the target's source manager, call
+ // GetSourceManager on the target instead.
+ SourceManager &GetSourceManager();
+
+ lldb::TargetSP GetSelectedTarget() {
+ return m_target_list.GetSelectedTarget();
+ }
+
+ ExecutionContext GetSelectedExecutionContext();
+ /// Get accessor for the target list.
+ ///
+ /// The target list is part of the global debugger object. This the single
+ /// debugger shared instance to control where targets get created and to
+ /// allow for tracking and searching for targets based on certain criteria.
+ ///
+ /// \return
+ /// A global shared target list.
+ TargetList &GetTargetList() { return m_target_list; }
+
+ PlatformList &GetPlatformList() { return m_platform_list; }
+
+ void DispatchInputInterrupt();
+
+ void DispatchInputEndOfFile();
+
+ // 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::FileSP &in,
+ lldb::StreamFileSP &out,
+ lldb::StreamFileSP &err);
+
+ void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
+ bool cancel_top_handler = true);
+
+ bool PopIOHandler(const lldb::IOHandlerSP &reader_sp);
+
+ // Synchronously run an input reader until it is done
+ void RunIOHandler(const lldb::IOHandlerSP &reader_sp);
+
+ bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp);
+
+ bool CheckTopIOHandlerTypes(IOHandler::Type top_type,
+ IOHandler::Type second_top_type);
+
+ void PrintAsync(const char *s, size_t len, bool is_stdout);
+
+ ConstString GetTopIOHandlerControlSequence(char ch);
+
+ const char *GetIOHandlerCommandPrefix();
+
+ const char *GetIOHandlerHelpPrologue();
+
+ void ClearIOHandlers();
+
+ bool GetCloseInputOnEOF() const;
+
+ void SetCloseInputOnEOF(bool b);
+
+ bool EnableLog(llvm::StringRef channel,
+ llvm::ArrayRef<const char *> categories,
+ llvm::StringRef log_file, uint32_t log_options,
+ llvm::raw_ostream &error_stream);
+
+ void SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton);
+
+ // Properties Functions
+ enum StopDisassemblyType {
+ eStopDisassemblyTypeNever = 0,
+ eStopDisassemblyTypeNoDebugInfo,
+ eStopDisassemblyTypeNoSource,
+ eStopDisassemblyTypeAlways
+ };
+
+ Status SetPropertyValue(const ExecutionContext *exe_ctx,
+ VarSetOperationType op, llvm::StringRef property_path,
+ llvm::StringRef value) override;
+
+ bool GetAutoConfirm() const;
+
+ const FormatEntity::Entry *GetDisassemblyFormat() const;
+
+ const FormatEntity::Entry *GetFrameFormat() const;
+
+ const FormatEntity::Entry *GetFrameFormatUnique() const;
+
+ const FormatEntity::Entry *GetThreadFormat() const;
+
+ const FormatEntity::Entry *GetThreadStopFormat() const;
+
+ lldb::ScriptLanguage GetScriptLanguage() const;
+
+ bool SetScriptLanguage(lldb::ScriptLanguage script_lang);
+
+ uint32_t GetTerminalWidth() const;
+
+ bool SetTerminalWidth(uint32_t term_width);
+
+ llvm::StringRef GetPrompt() const;
+
+ void SetPrompt(llvm::StringRef p);
+ void SetPrompt(const char *) = delete;
+
+ llvm::StringRef GetReproducerPath() const;
+
+ bool GetUseExternalEditor() const;
+
+ bool SetUseExternalEditor(bool use_external_editor_p);
+
+ bool GetUseColor() const;
+
+ bool SetUseColor(bool use_color);
+
+ bool GetHighlightSource() const;
+
+ lldb::StopShowColumn GetStopShowColumn() const;
+
+ llvm::StringRef GetStopShowColumnAnsiPrefix() const;
+
+ llvm::StringRef GetStopShowColumnAnsiSuffix() const;
+
+ uint32_t GetStopSourceLineCount(bool before) const;
+
+ StopDisassemblyType GetStopDisassemblyDisplay() const;
+
+ uint32_t GetDisassemblyLineCount() const;
+
+ bool GetAutoOneLineSummaries() const;
+
+ bool GetAutoIndent() const;
+
+ bool SetAutoIndent(bool b);
+
+ bool GetPrintDecls() const;
+
+ bool SetPrintDecls(bool b);
+
+ uint32_t GetTabSize() const;
+
+ bool SetTabSize(uint32_t tab_size);
+
+ bool GetEscapeNonPrintables() const;
+
+ bool GetNotifyVoid() const;
+
+ ConstString GetInstanceName() { return m_instance_name; }
+
+ bool LoadPlugin(const FileSpec &spec, Status &error);
+
+ void ExecuteIOHandlers();
+
+ bool IsForwardingEvents();
+
+ void EnableForwardEvents(const lldb::ListenerSP &listener_sp);
+
+ void CancelForwardEvents(const lldb::ListenerSP &listener_sp);
+
+ bool IsHandlingEvents() const { return m_event_handler_thread.IsJoinable(); }
+
+ Status RunREPL(lldb::LanguageType language, const char *repl_options);
+
+ // 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() { return m_dummy_target_sp.get(); }
+
+ lldb::BroadcasterManagerSP GetBroadcasterManager() {
+ return m_broadcaster_manager_sp;
+ }
+
+protected:
+ friend class CommandInterpreter;
+ friend class REPL;
+
+ bool StartEventHandlerThread();
+
+ void StopEventHandlerThread();
+
+ static lldb::thread_result_t EventHandlerThread(lldb::thread_arg_t arg);
+
+ bool HasIOHandlerThread();
+
+ bool StartIOHandlerThread();
+
+ void StopIOHandlerThread();
+
+ void JoinIOHandlerThread();
+
+ static lldb::thread_result_t IOHandlerThread(lldb::thread_arg_t arg);
+
+ void DefaultEventHandler();
+
+ void HandleBreakpointEvent(const lldb::EventSP &event_sp);
+
+ void HandleProcessEvent(const lldb::EventSP &event_sp);
+
+ void HandleThreadEvent(const lldb::EventSP &event_sp);
+
+ // 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;
+ }
+
+ void InstanceInitialize();
+
+ // 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;
+
+ lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a
+ // broadcaster manager of
+ // last resort.
+ // It needs to get constructed before the target_list or any other member
+ // that might want to broadcast through the debugger.
+
+ TerminalState m_terminal_state;
+ TargetList m_target_list;
+
+ PlatformList m_platform_list;
+ lldb::ListenerSP m_listener_sp;
+ std::unique_ptr<SourceManager> m_source_manager_up; // This is a scratch
+ // source manager that we
+ // return if we have no
+ // targets.
+ SourceManager::SourceFileCache m_source_file_cache; // All the source managers
+ // for targets created in
+ // this debugger used this
+ // shared
+ // source file cache.
+ std::unique_ptr<CommandInterpreter> m_command_interpreter_up;
+
+ lldb::ScriptInterpreterSP m_script_interpreter_sp;
+ std::recursive_mutex m_script_interpreter_mutex;
+
+ IOHandlerStack m_input_reader_stack;
+ llvm::StringMap<std::weak_ptr<llvm::raw_ostream>> m_log_streams;
+ std::shared_ptr<llvm::raw_ostream> m_log_callback_stream_sp;
+ ConstString m_instance_name;
+ static LoadPluginCallbackType g_load_plugin_callback;
+ typedef std::vector<llvm::sys::DynamicLibrary> LoadedPluginsList;
+ LoadedPluginsList m_loaded_plugins;
+ HostThread m_event_handler_thread;
+ HostThread m_io_handler_thread;
+ 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 {
+ eBroadcastBitEventThreadIsListening = (1 << 0),
+ };
+
+private:
+ // Use Debugger::CreateInstance() to get a shared pointer to a new debugger
+ // object
+ Debugger(lldb::LogOutputCallback m_log_callback, void *baton);
+
+ DISALLOW_COPY_AND_ASSIGN(Debugger);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Debugger_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h
new file mode 100644
index 000000000000..ba9ca87832f6
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h
@@ -0,0 +1,551 @@
+//===-- Disassembler.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_Disassembler_h_
+#define liblldb_Disassembler_h_
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/FormatEntity.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Symbol/LineEntry.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/StringRef.h"
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+namespace llvm {
+template <typename T> class SmallVectorImpl;
+}
+
+namespace lldb_private {
+class AddressRange;
+class DataExtractor;
+class Debugger;
+class Disassembler;
+class Module;
+class Stream;
+class SymbolContext;
+class SymbolContextList;
+class Target;
+struct RegisterInfo;
+
+class Instruction {
+public:
+ Instruction(const Address &address,
+ AddressClass addr_class = AddressClass::eInvalid);
+
+ virtual ~Instruction();
+
+ const Address &GetAddress() const { return m_address; }
+
+ const char *GetMnemonic(const ExecutionContext *exe_ctx) {
+ CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
+ return m_opcode_name.c_str();
+ }
+
+ const char *GetOperands(const ExecutionContext *exe_ctx) {
+ CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
+ return m_mnemonics.c_str();
+ }
+
+ const char *GetComment(const ExecutionContext *exe_ctx) {
+ CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
+ return m_comment.c_str();
+ }
+
+ virtual void
+ CalculateMnemonicOperandsAndComment(const ExecutionContext *exe_ctx) = 0;
+
+ AddressClass GetAddressClass();
+
+ void SetAddress(const Address &addr) {
+ // Invalidate the address class to lazily discover it if we need to.
+ m_address_class = AddressClass::eInvalid;
+ m_address = addr;
+ }
+
+ /// Dump the text representation of this Instruction to a Stream
+ ///
+ /// Print the (optional) address, (optional) bytes, opcode,
+ /// operands, and instruction comments to a stream.
+ ///
+ /// \param[in] s
+ /// The Stream to add the text to.
+ ///
+ /// \param[in] show_address
+ /// Whether the address (using disassembly_addr_format_spec formatting)
+ /// should be printed.
+ ///
+ /// \param[in] show_bytes
+ /// Whether the bytes of the assembly instruction should be printed.
+ ///
+ /// \param[in] max_opcode_byte_size
+ /// The size (in bytes) of the largest instruction in the list that
+ /// we are printing (for text justification/alignment purposes)
+ /// Only needed if show_bytes is true.
+ ///
+ /// \param[in] exe_ctx
+ /// The current execution context, if available. May be used in
+ /// the assembling of the operands+comments for this instruction.
+ /// Pass NULL if not applicable.
+ ///
+ /// \param[in] sym_ctx
+ /// The SymbolContext for this instruction.
+ /// Pass NULL if not available/computed.
+ /// Only needed if show_address is true.
+ ///
+ /// \param[in] prev_sym_ctx
+ /// The SymbolContext for the previous instruction. Depending on
+ /// the disassembly address format specification, a change in
+ /// Symbol / Function may mean that a line is printed with the new
+ /// symbol/function name.
+ /// Pass NULL if unavailable, or if this is the first instruction of
+ /// the InstructionList.
+ /// Only needed if show_address is true.
+ ///
+ /// \param[in] disassembly_addr_format
+ /// The format specification for how addresses are printed.
+ /// Only needed if show_address is true.
+ ///
+ /// \param[in] max_address_text_size
+ /// The length of the longest address string at the start of the
+ /// disassembly line that will be printed (the
+ /// Debugger::FormatDisassemblerAddress() string)
+ /// so this method can properly align the instruction opcodes.
+ /// May be 0 to indicate no indentation/alignment of the opcodes.
+ virtual void Dump(Stream *s, uint32_t max_opcode_byte_size, bool show_address,
+ bool show_bytes, const ExecutionContext *exe_ctx,
+ const SymbolContext *sym_ctx,
+ const SymbolContext *prev_sym_ctx,
+ const FormatEntity::Entry *disassembly_addr_format,
+ size_t max_address_text_size);
+
+ virtual bool DoesBranch() = 0;
+
+ virtual bool HasDelaySlot();
+
+ bool CanSetBreakpoint ();
+
+ virtual size_t Decode(const Disassembler &disassembler,
+ const DataExtractor &data,
+ lldb::offset_t data_offset) = 0;
+
+ virtual void SetDescription(llvm::StringRef) {
+ } // May be overridden in sub-classes that have descriptions.
+
+ lldb::OptionValueSP ReadArray(FILE *in_file, Stream *out_stream,
+ OptionValue::Type data_type);
+
+ lldb::OptionValueSP ReadDictionary(FILE *in_file, Stream *out_stream);
+
+ bool DumpEmulation(const ArchSpec &arch);
+
+ virtual bool TestEmulation(Stream *stream, const char *test_file_name);
+
+ bool Emulate(const ArchSpec &arch, uint32_t evaluate_options, void *baton,
+ EmulateInstruction::ReadMemoryCallback read_mem_callback,
+ EmulateInstruction::WriteMemoryCallback write_mem_calback,
+ EmulateInstruction::ReadRegisterCallback read_reg_callback,
+ EmulateInstruction::WriteRegisterCallback write_reg_callback);
+
+ const Opcode &GetOpcode() const { return m_opcode; }
+
+ uint32_t GetData(DataExtractor &data);
+
+ struct Operand {
+ enum class Type {
+ Invalid = 0,
+ Register,
+ Immediate,
+ Dereference,
+ Sum,
+ Product
+ } m_type = Type::Invalid;
+ std::vector<Operand> m_children;
+ lldb::addr_t m_immediate = 0;
+ ConstString m_register;
+ bool m_negative = false;
+ bool m_clobbered = false;
+
+ bool IsValid() { return m_type != Type::Invalid; }
+
+ static Operand BuildRegister(ConstString &r);
+ static Operand BuildImmediate(lldb::addr_t imm, bool neg);
+ static Operand BuildImmediate(int64_t imm);
+ static Operand BuildDereference(const Operand &ref);
+ static Operand BuildSum(const Operand &lhs, const Operand &rhs);
+ static Operand BuildProduct(const Operand &lhs, const Operand &rhs);
+ };
+
+ virtual bool ParseOperands(llvm::SmallVectorImpl<Operand> &operands) {
+ return false;
+ }
+
+ virtual bool IsCall() { return false; }
+
+protected:
+ Address m_address; // The section offset address of this instruction
+ // We include an address class in the Instruction class to
+ // allow the instruction specify the
+ // AddressClass::eCodeAlternateISA (currently used for
+ // thumb), and also to specify data (AddressClass::eData).
+ // The usual value will be AddressClass::eCode, but often
+ // when disassembling memory, you might run into data.
+ // This can help us to disassemble appropriately.
+private:
+ AddressClass m_address_class; // Use GetAddressClass () accessor function!
+
+protected:
+ Opcode m_opcode; // The opcode for this instruction
+ std::string m_opcode_name;
+ std::string m_mnemonics;
+ std::string m_comment;
+ bool m_calculated_strings;
+
+ void
+ CalculateMnemonicOperandsAndCommentIfNeeded(const ExecutionContext *exe_ctx) {
+ if (!m_calculated_strings) {
+ m_calculated_strings = true;
+ CalculateMnemonicOperandsAndComment(exe_ctx);
+ }
+ }
+};
+
+namespace OperandMatchers {
+std::function<bool(const Instruction::Operand &)>
+MatchBinaryOp(std::function<bool(const Instruction::Operand &)> base,
+ std::function<bool(const Instruction::Operand &)> left,
+ std::function<bool(const Instruction::Operand &)> right);
+
+std::function<bool(const Instruction::Operand &)>
+MatchUnaryOp(std::function<bool(const Instruction::Operand &)> base,
+ std::function<bool(const Instruction::Operand &)> child);
+
+std::function<bool(const Instruction::Operand &)>
+MatchRegOp(const RegisterInfo &info);
+
+std::function<bool(const Instruction::Operand &)> FetchRegOp(ConstString &reg);
+
+std::function<bool(const Instruction::Operand &)> MatchImmOp(int64_t imm);
+
+std::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm);
+
+std::function<bool(const Instruction::Operand &)>
+MatchOpType(Instruction::Operand::Type type);
+}
+
+class InstructionList {
+public:
+ InstructionList();
+ ~InstructionList();
+
+ size_t GetSize() const;
+
+ uint32_t GetMaxOpcocdeByteSize() const;
+
+ lldb::InstructionSP GetInstructionAtIndex(size_t idx) const;
+
+ //------------------------------------------------------------------
+ /// Get the index of the next branch instruction.
+ ///
+ /// Given a list of instructions, find the next branch instruction
+ /// in the list by returning an index.
+ ///
+ /// @param[in] start
+ /// The instruction index of the first instruction to check.
+ ///
+ /// @param[in] target
+ /// A LLDB target object that is used to resolve addresses.
+ ///
+ /// @param[in] ignore_calls
+ /// It true, then fine the first branch instruction that isn't
+ /// a function call (a branch that calls and returns to the next
+ /// instruction). If false, find the instruction index of any
+ /// branch in the list.
+ ///
+ /// @return
+ /// The instruction index of the first branch that is at or past
+ /// \a start. Returns UINT32_MAX if no matching branches are
+ /// found.
+ //------------------------------------------------------------------
+ uint32_t GetIndexOfNextBranchInstruction(uint32_t start,
+ Target &target,
+ bool ignore_calls) const;
+
+ uint32_t GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
+ Target &target);
+
+ uint32_t GetIndexOfInstructionAtAddress(const Address &addr);
+
+ void Clear();
+
+ void Append(lldb::InstructionSP &inst_sp);
+
+ void Dump(Stream *s, bool show_address, bool show_bytes,
+ const ExecutionContext *exe_ctx);
+
+private:
+ typedef std::vector<lldb::InstructionSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ collection m_instructions;
+};
+
+class PseudoInstruction : public Instruction {
+public:
+ PseudoInstruction();
+
+ ~PseudoInstruction() override;
+
+ bool DoesBranch() override;
+
+ bool HasDelaySlot() override;
+
+ void CalculateMnemonicOperandsAndComment(
+ const ExecutionContext *exe_ctx) override {
+ // TODO: fill this in and put opcode name into Instruction::m_opcode_name,
+ // mnemonic into Instruction::m_mnemonics, and any comment into
+ // Instruction::m_comment
+ }
+
+ size_t Decode(const Disassembler &disassembler, const DataExtractor &data,
+ lldb::offset_t data_offset) override;
+
+ void SetOpcode(size_t opcode_size, void *opcode_data);
+
+ void SetDescription(llvm::StringRef description) override;
+
+protected:
+ std::string m_description;
+
+ DISALLOW_COPY_AND_ASSIGN(PseudoInstruction);
+};
+
+class Disassembler : public std::enable_shared_from_this<Disassembler>,
+ public PluginInterface {
+public:
+ enum {
+ eOptionNone = 0u,
+ eOptionShowBytes = (1u << 0),
+ eOptionRawOuput = (1u << 1),
+ eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains
+ // the current PC (mixed mode only)
+ eOptionMarkPCAddress =
+ (1u << 3) // Mark the disassembly line the contains the PC
+ };
+
+ enum HexImmediateStyle {
+ eHexStyleC,
+ eHexStyleAsm,
+ };
+
+ // FindPlugin should be lax about the flavor string (it is too annoying to
+ // have various internal uses of the disassembler fail because the global
+ // flavor string gets set wrong. Instead, if you get a flavor string you
+ // don't understand, use the default. Folks who care to check can use the
+ // FlavorValidForArchSpec method on the disassembler they got back.
+ static lldb::DisassemblerSP
+ FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name);
+
+ // This version will use the value in the Target settings if flavor is NULL;
+ static lldb::DisassemblerSP
+ FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch,
+ const char *flavor, const char *plugin_name);
+
+ static lldb::DisassemblerSP
+ DisassembleRange(const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const ExecutionContext &exe_ctx,
+ const AddressRange &disasm_range, bool prefer_file_cache);
+
+ static lldb::DisassemblerSP
+ DisassembleBytes(const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const Address &start, const void *bytes,
+ size_t length, uint32_t max_num_instructions,
+ bool data_from_file);
+
+ static bool Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &range, uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines, uint32_t options,
+ Stream &strm);
+
+ static bool Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx, const Address &start,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines, uint32_t options,
+ Stream &strm);
+
+ static size_t
+ Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const ExecutionContext &exe_ctx,
+ SymbolContextList &sc_list, uint32_t num_instructions,
+ bool mixed_source_and_assembly, uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm);
+
+ static bool
+ Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const ExecutionContext &exe_ctx,
+ ConstString name, Module *module,
+ uint32_t num_instructions, bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines, uint32_t options, Stream &strm);
+
+ static bool
+ Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const ExecutionContext &exe_ctx,
+ uint32_t num_instructions, bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines, uint32_t options, Stream &strm);
+
+ // Constructors and Destructors
+ Disassembler(const ArchSpec &arch, const char *flavor);
+ ~Disassembler() override;
+
+ typedef const char *(*SummaryCallback)(const Instruction &inst,
+ ExecutionContext *exe_context,
+ void *user_data);
+
+ static bool PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger,
+ const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm);
+
+ size_t ParseInstructions(const ExecutionContext *exe_ctx,
+ const AddressRange &range, Stream *error_strm_ptr,
+ bool prefer_file_cache);
+
+ size_t ParseInstructions(const ExecutionContext *exe_ctx,
+ const Address &range, uint32_t num_instructions,
+ bool prefer_file_cache);
+
+ virtual size_t DecodeInstructions(const Address &base_addr,
+ const DataExtractor &data,
+ lldb::offset_t data_offset,
+ size_t num_instructions, bool append,
+ bool data_from_file) = 0;
+
+ InstructionList &GetInstructionList();
+
+ const InstructionList &GetInstructionList() const;
+
+ const ArchSpec &GetArchitecture() const { return m_arch; }
+
+ const char *GetFlavor() const { return m_flavor.c_str(); }
+
+ virtual bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch,
+ const char *flavor) = 0;
+
+protected:
+ // SourceLine and SourceLinesToDisplay structures are only used in the mixed
+ // source and assembly display methods internal to this class.
+
+ struct SourceLine {
+ FileSpec file;
+ uint32_t line;
+ uint32_t column;
+
+ SourceLine() : file(), line(LLDB_INVALID_LINE_NUMBER), column(0) {}
+
+ bool operator==(const SourceLine &rhs) const {
+ return file == rhs.file && line == rhs.line && rhs.column == column;
+ }
+
+ bool operator!=(const SourceLine &rhs) const {
+ return file != rhs.file || line != rhs.line || column != rhs.column;
+ }
+
+ bool IsValid() const { return line != LLDB_INVALID_LINE_NUMBER; }
+ };
+
+ struct SourceLinesToDisplay {
+ std::vector<SourceLine> lines;
+
+ // index of the "current" source line, if we want to highlight that when
+ // displaying the source lines. (as opposed to the surrounding source
+ // lines provided to give context)
+ size_t current_source_line;
+
+ // Whether to print a blank line at the end of the source lines.
+ bool print_source_context_end_eol;
+
+ SourceLinesToDisplay()
+ : lines(), current_source_line(-1), print_source_context_end_eol(true) {
+ }
+ };
+
+ // Get the function's declaration line number, hopefully a line number
+ // earlier than the opening curly brace at the start of the function body.
+ static SourceLine GetFunctionDeclLineEntry(const SymbolContext &sc);
+
+ // Add the provided SourceLine to the map of filenames-to-source-lines-seen.
+ static void AddLineToSourceLineTables(
+ SourceLine &line,
+ std::map<FileSpec, std::set<uint32_t>> &source_lines_seen);
+
+ // Given a source line, determine if we should print it when we're doing
+ // mixed source & assembly output. We're currently using the
+ // target.process.thread.step-avoid-regexp setting (which is used for
+ // stepping over inlined STL functions by default) to determine what source
+ // lines to avoid showing.
+ //
+ // Returns true if this source line should be elided (if the source line
+ // should not be displayed).
+ static bool
+ ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx,
+ const SymbolContext &sc, SourceLine &line);
+
+ static bool
+ ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx,
+ const SymbolContext &sc, LineEntry &line) {
+ SourceLine sl;
+ sl.file = line.file;
+ sl.line = line.line;
+ sl.column = line.column;
+ return ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, sl);
+ };
+
+ // Classes that inherit from Disassembler can see and modify these
+ ArchSpec m_arch;
+ InstructionList m_instruction_list;
+ lldb::addr_t m_base_addr;
+ std::string m_flavor;
+
+private:
+ // For Disassembler only
+ DISALLOW_COPY_AND_ASSIGN(Disassembler);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Disassembler_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h b/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h
new file mode 100644
index 000000000000..2a9d778e0a6a
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/DumpDataExtractor.h
@@ -0,0 +1,92 @@
+//===-- DumpDataExtractor.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_CORE_DUMPDATAEXTRACTOR_H
+#define LLDB_CORE_DUMPDATAEXTRACTOR_H
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class ExecutionContextScope;
+class Stream;
+
+/// Dumps \a item_count objects into the stream \a s.
+///
+/// Dumps \a item_count objects using \a item_format, each of which
+/// are \a item_byte_size bytes long starting at offset \a offset
+/// bytes into the contained data, into the stream \a s. \a
+/// num_per_line objects will be dumped on each line before a new
+/// line will be output. If \a base_addr is a valid address, then
+/// each new line of output will be preceded by the address value
+/// plus appropriate offset, and a colon and space. Bitfield values
+/// can be dumped by calling this function multiple times with the
+/// same start offset, format and size, yet differing \a
+/// item_bit_size and \a item_bit_offset values.
+///
+/// \param[in] s
+/// The stream to dump the output to. This value can not be nullptr.
+///
+/// \param[in] offset
+/// The offset into the data at which to start dumping.
+///
+/// \param[in] item_format
+/// The format to use when dumping each item.
+///
+/// \param[in] item_byte_size
+/// The byte size of each item.
+///
+/// \param[in] item_count
+/// The number of items to dump.
+///
+/// \param[in] num_per_line
+/// The number of items to display on each line.
+///
+/// \param[in] base_addr
+/// The base address that gets added to the offset displayed on
+/// each line if the value is valid. Is \a base_addr is
+/// LLDB_INVALID_ADDRESS then no address values will be prepended
+/// to any lines.
+///
+/// \param[in] item_bit_size
+/// If the value to display is a bitfield, this value should
+/// be the number of bits that the bitfield item has within the
+/// item's byte size value. This function will need to be called
+/// multiple times with identical \a offset and \a item_byte_size
+/// values in order to display multiple bitfield values that
+/// exist within the same integer value. If the items being
+/// displayed are not bitfields, this value should be zero.
+///
+/// \param[in] item_bit_offset
+/// If the value to display is a bitfield, this value should
+/// be the offset in bits, or shift right amount, that the
+/// bitfield item occupies within the item's byte size value.
+/// This function will need to be called multiple times with
+/// identical \a offset and \a item_byte_size values in order
+/// to display multiple bitfield values that exist within the
+/// same integer value. If the items being displayed are not
+/// bitfields, this value should be zero.
+///
+/// \return
+/// The offset at which dumping ended.
+lldb::offset_t
+DumpDataExtractor(const DataExtractor &DE, Stream *s, lldb::offset_t offset,
+ lldb::Format item_format, size_t item_byte_size,
+ size_t item_count, size_t num_per_line, uint64_t base_addr,
+ uint32_t item_bit_size, uint32_t item_bit_offset,
+ ExecutionContextScope *exe_scope = nullptr);
+
+void DumpHexBytes(Stream *s, const void *src, size_t src_len,
+ uint32_t bytes_per_line, lldb::addr_t base_addr);
+}
+
+#endif
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/DumpRegisterValue.h b/contrib/llvm-project/lldb/include/lldb/Core/DumpRegisterValue.h
new file mode 100644
index 000000000000..443fdb34266a
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/DumpRegisterValue.h
@@ -0,0 +1,30 @@
+//===-- DumpRegisterValue.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_CORE_DUMPREGISTERVALUE_H
+#define LLDB_CORE_DUMPREGISTERVALUE_H
+
+#include "lldb/lldb-enumerations.h"
+#include <cstdint>
+
+namespace lldb_private {
+
+class RegisterValue;
+struct RegisterInfo;
+class Stream;
+
+// The default value of 0 for reg_name_right_align_at means no alignment at
+// all.
+bool DumpRegisterValue(const RegisterValue &reg_val, Stream *s,
+ const RegisterInfo *reg_info, bool prefix_with_name,
+ bool prefix_with_alt_name, lldb::Format format,
+ uint32_t reg_name_right_align_at = 0);
+
+} // namespace lldb_private
+
+#endif // LLDB_CORE_DUMPREGISTERVALUE_H
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h b/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h
new file mode 100644
index 000000000000..6b19c17e5491
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h
@@ -0,0 +1,507 @@
+//===-- EmulateInstruction.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_EmulateInstruction_h_
+#define lldb_EmulateInstruction_h_
+
+#include <string>
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Opcode.h"
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-private-types.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class OptionValueDictionary;
+class RegisterContext;
+class RegisterValue;
+class Stream;
+class Target;
+class UnwindPlan;
+
+/// \class EmulateInstruction EmulateInstruction.h
+/// "lldb/Core/EmulateInstruction.h"
+/// A class that allows emulation of CPU opcodes.
+///
+/// This class is a plug-in interface that is accessed through the standard
+/// static FindPlugin function call in the EmulateInstruction class. The
+/// FindPlugin takes a target triple and returns a new object if there is a
+/// plug-in that supports the architecture and OS. Four callbacks and a baton
+/// are provided. The four callbacks are read register, write register, read
+/// memory and write memory.
+///
+/// This class is currently designed for these main use cases: - Auto
+/// generation of Call Frame Information (CFI) from assembly code - Predicting
+/// single step breakpoint locations - Emulating instructions for breakpoint
+/// traps
+///
+/// Objects can be asked to read an instruction which will cause a call to the
+/// read register callback to get the PC, followed by a read memory call to
+/// read the opcode. If ReadInstruction () returns true, then a call to
+/// EmulateInstruction::EvaluateInstruction () can be made. At this point the
+/// EmulateInstruction subclass will use all of the callbacks to emulate an
+/// instruction.
+///
+/// Clients that provide the callbacks can either do the read/write
+/// registers/memory to actually emulate the instruction on a real or virtual
+/// CPU, or watch for the EmulateInstruction::Context which is context for the
+/// read/write register/memory which explains why the callback is being
+/// called. Examples of a context are: "pushing register 3 onto the stack at
+/// offset -12", or "adjusting stack pointer by -16". This extra context
+/// allows the generation of
+/// CFI information from assembly code without having to actually do
+/// the read/write register/memory.
+///
+/// Clients must be prepared that not all instructions for an Instruction Set
+/// Architecture (ISA) will be emulated.
+///
+/// Subclasses at the very least should implement the instructions that save
+/// and restore registers onto the stack and adjustment to the stack pointer.
+/// By just implementing a few instructions for an ISA that are the typical
+/// prologue opcodes, you can then generate CFI using a class that will soon
+/// be available.
+///
+/// Implementing all of the instructions that affect the PC can then allow
+/// single step prediction support.
+///
+/// Implementing all of the instructions allows for emulation of opcodes for
+/// breakpoint traps and will pave the way for "thread centric" debugging. The
+/// current debugging model is "process centric" where all threads must be
+/// stopped when any thread is stopped; when hitting software breakpoints we
+/// must disable the breakpoint by restoring the original breakpoint opcode,
+/// single stepping and restoring the breakpoint trap. If all threads were
+/// allowed to run then other threads could miss the breakpoint.
+///
+/// This class centralizes the code that usually is done in separate code
+/// paths in a debugger (single step prediction, finding save restore
+/// locations of registers for unwinding stack frame variables) and emulating
+/// the instruction is just a bonus.
+
+class EmulateInstruction : public PluginInterface {
+public:
+ static EmulateInstruction *FindPlugin(const ArchSpec &arch,
+ InstructionType supported_inst_type,
+ const char *plugin_name);
+
+ enum ContextType {
+ eContextInvalid = 0,
+ // Read an instruction opcode from memory
+ eContextReadOpcode,
+
+ // Usually used for writing a register value whose source value is an
+ // immediate
+ eContextImmediate,
+
+ // Exclusively used when saving a register to the stack as part of the
+ // prologue
+ eContextPushRegisterOnStack,
+
+ // Exclusively used when restoring a register off the stack as part of the
+ // epilogue
+ eContextPopRegisterOffStack,
+
+ // Add or subtract a value from the stack
+ eContextAdjustStackPointer,
+
+ // Adjust the frame pointer for the current frame
+ eContextSetFramePointer,
+
+ // Typically in an epilogue sequence. Copy the frame pointer back into the
+ // stack pointer, use SP for CFA calculations again.
+ eContextRestoreStackPointer,
+
+ // Add or subtract a value from a base address register (other than SP)
+ eContextAdjustBaseRegister,
+
+ // Add or subtract a value from the PC or store a value to the PC.
+ eContextAdjustPC,
+
+ // Used in WriteRegister callbacks to indicate where the
+ eContextRegisterPlusOffset,
+
+ // Used in WriteMemory callback to indicate where the data came from
+ eContextRegisterStore,
+
+ eContextRegisterLoad,
+
+ // Used when performing a PC-relative branch where the
+ eContextRelativeBranchImmediate,
+
+ // Used when performing an absolute branch where the
+ eContextAbsoluteBranchRegister,
+
+ // Used when performing a supervisor call to an operating system to provide
+ // a service:
+ eContextSupervisorCall,
+
+ // Used when performing a MemU operation to read the PC-relative offset
+ // from an address.
+ eContextTableBranchReadMemory,
+
+ // Used when random bits are written into a register
+ eContextWriteRegisterRandomBits,
+
+ // Used when random bits are written to memory
+ eContextWriteMemoryRandomBits,
+
+ eContextArithmetic,
+
+ eContextAdvancePC,
+
+ eContextReturnFromException
+ };
+
+ enum InfoType {
+ eInfoTypeRegisterPlusOffset,
+ eInfoTypeRegisterPlusIndirectOffset,
+ eInfoTypeRegisterToRegisterPlusOffset,
+ eInfoTypeRegisterToRegisterPlusIndirectOffset,
+ eInfoTypeRegisterRegisterOperands,
+ eInfoTypeOffset,
+ eInfoTypeRegister,
+ eInfoTypeImmediate,
+ eInfoTypeImmediateSigned,
+ eInfoTypeAddress,
+ eInfoTypeISAAndImmediate,
+ eInfoTypeISAAndImmediateSigned,
+ eInfoTypeISA,
+ eInfoTypeNoArgs
+ } InfoType;
+
+ struct Context {
+ ContextType type;
+ enum InfoType info_type;
+ union {
+ struct RegisterPlusOffset {
+ RegisterInfo reg; // base register
+ int64_t signed_offset; // signed offset added to base register
+ } RegisterPlusOffset;
+
+ struct RegisterPlusIndirectOffset {
+ RegisterInfo base_reg; // base register number
+ RegisterInfo offset_reg; // offset register kind
+ } RegisterPlusIndirectOffset;
+
+ struct RegisterToRegisterPlusOffset {
+ RegisterInfo data_reg; // source/target register for data
+ RegisterInfo base_reg; // base register for address calculation
+ int64_t offset; // offset for address calculation
+ } RegisterToRegisterPlusOffset;
+
+ struct RegisterToRegisterPlusIndirectOffset {
+ RegisterInfo base_reg; // base register for address calculation
+ RegisterInfo offset_reg; // offset register for address calculation
+ RegisterInfo data_reg; // source/target register for data
+ } RegisterToRegisterPlusIndirectOffset;
+
+ struct RegisterRegisterOperands {
+ RegisterInfo
+ operand1; // register containing first operand for binary op
+ RegisterInfo
+ operand2; // register containing second operand for binary op
+ } RegisterRegisterOperands;
+
+ int64_t signed_offset; // signed offset by which to adjust self (for
+ // registers only)
+
+ RegisterInfo reg; // plain register
+
+ uint64_t unsigned_immediate; // unsigned immediate value
+ int64_t signed_immediate; // signed immediate value
+
+ lldb::addr_t address; // direct address
+
+ struct ISAAndImmediate {
+ uint32_t isa;
+ uint32_t unsigned_data32; // immediate data
+ } ISAAndImmediate;
+
+ struct ISAAndImmediateSigned {
+ uint32_t isa;
+ int32_t signed_data32; // signed immediate data
+ } ISAAndImmediateSigned;
+
+ uint32_t isa;
+ } info;
+
+ Context() : type(eContextInvalid), info_type(eInfoTypeNoArgs) {}
+
+ void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) {
+ info_type = eInfoTypeRegisterPlusOffset;
+ info.RegisterPlusOffset.reg = base_reg;
+ info.RegisterPlusOffset.signed_offset = signed_offset;
+ }
+
+ void SetRegisterPlusIndirectOffset(RegisterInfo base_reg,
+ RegisterInfo offset_reg) {
+ info_type = eInfoTypeRegisterPlusIndirectOffset;
+ info.RegisterPlusIndirectOffset.base_reg = base_reg;
+ info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
+ }
+
+ void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
+ RegisterInfo base_reg,
+ int64_t offset) {
+ info_type = eInfoTypeRegisterToRegisterPlusOffset;
+ info.RegisterToRegisterPlusOffset.data_reg = data_reg;
+ info.RegisterToRegisterPlusOffset.base_reg = base_reg;
+ info.RegisterToRegisterPlusOffset.offset = offset;
+ }
+
+ void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg,
+ RegisterInfo offset_reg,
+ RegisterInfo data_reg) {
+ info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
+ info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
+ info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
+ info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
+ }
+
+ void SetRegisterRegisterOperands(RegisterInfo op1_reg,
+ RegisterInfo op2_reg) {
+ info_type = eInfoTypeRegisterRegisterOperands;
+ info.RegisterRegisterOperands.operand1 = op1_reg;
+ info.RegisterRegisterOperands.operand2 = op2_reg;
+ }
+
+ void SetOffset(int64_t signed_offset) {
+ info_type = eInfoTypeOffset;
+ info.signed_offset = signed_offset;
+ }
+
+ void SetRegister(RegisterInfo reg) {
+ info_type = eInfoTypeRegister;
+ info.reg = reg;
+ }
+
+ void SetImmediate(uint64_t immediate) {
+ info_type = eInfoTypeImmediate;
+ info.unsigned_immediate = immediate;
+ }
+
+ void SetImmediateSigned(int64_t signed_immediate) {
+ info_type = eInfoTypeImmediateSigned;
+ info.signed_immediate = signed_immediate;
+ }
+
+ void SetAddress(lldb::addr_t address) {
+ info_type = eInfoTypeAddress;
+ info.address = address;
+ }
+ void SetISAAndImmediate(uint32_t isa, uint32_t data) {
+ info_type = eInfoTypeISAAndImmediate;
+ info.ISAAndImmediate.isa = isa;
+ info.ISAAndImmediate.unsigned_data32 = data;
+ }
+
+ void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
+ info_type = eInfoTypeISAAndImmediateSigned;
+ info.ISAAndImmediateSigned.isa = isa;
+ info.ISAAndImmediateSigned.signed_data32 = data;
+ }
+
+ void SetISA(uint32_t isa) {
+ info_type = eInfoTypeISA;
+ info.isa = isa;
+ }
+
+ void SetNoArgs() { info_type = eInfoTypeNoArgs; }
+
+ void Dump(Stream &s, EmulateInstruction *instruction) const;
+ };
+
+ typedef size_t (*ReadMemoryCallback)(EmulateInstruction *instruction,
+ void *baton, const Context &context,
+ lldb::addr_t addr, void *dst,
+ size_t length);
+
+ typedef size_t (*WriteMemoryCallback)(EmulateInstruction *instruction,
+ void *baton, const Context &context,
+ lldb::addr_t addr, const void *dst,
+ size_t length);
+
+ typedef bool (*ReadRegisterCallback)(EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value);
+
+ typedef bool (*WriteRegisterCallback)(EmulateInstruction *instruction,
+ void *baton, const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value);
+
+ // Type to represent the condition of an instruction. The UINT32 value is
+ // reserved for the unconditional case and all other value can be used in an
+ // architecture dependent way.
+ typedef uint32_t InstructionCondition;
+ static const InstructionCondition UnconditionalCondition = UINT32_MAX;
+
+ EmulateInstruction(const ArchSpec &arch);
+
+ ~EmulateInstruction() override = default;
+
+ // Mandatory overrides
+ virtual bool
+ SupportsEmulatingInstructionsOfType(InstructionType inst_type) = 0;
+
+ virtual bool SetTargetTriple(const ArchSpec &arch) = 0;
+
+ virtual bool ReadInstruction() = 0;
+
+ virtual bool EvaluateInstruction(uint32_t evaluate_options) = 0;
+
+ virtual InstructionCondition GetInstructionCondition() {
+ return UnconditionalCondition;
+ }
+
+ virtual bool TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) = 0;
+
+ virtual bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ RegisterInfo &reg_info) = 0;
+
+ // Optional overrides
+ virtual bool SetInstruction(const Opcode &insn_opcode,
+ const Address &inst_addr, Target *target);
+
+ virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan);
+
+ static const char *TranslateRegister(lldb::RegisterKind reg_kind,
+ uint32_t reg_num, std::string &reg_name);
+
+ // RegisterInfo variants
+ bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value);
+
+ uint64_t ReadRegisterUnsigned(const RegisterInfo *reg_info,
+ uint64_t fail_value, bool *success_ptr);
+
+ bool WriteRegister(const Context &context, const RegisterInfo *ref_info,
+ const RegisterValue &reg_value);
+
+ bool WriteRegisterUnsigned(const Context &context,
+ const RegisterInfo *reg_info, uint64_t reg_value);
+
+ // Register kind and number variants
+ bool ReadRegister(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ RegisterValue &reg_value);
+
+ bool WriteRegister(const Context &context, lldb::RegisterKind reg_kind,
+ uint32_t reg_num, const RegisterValue &reg_value);
+
+ uint64_t ReadRegisterUnsigned(lldb::RegisterKind reg_kind, uint32_t reg_num,
+ uint64_t fail_value, bool *success_ptr);
+
+ bool WriteRegisterUnsigned(const Context &context,
+ lldb::RegisterKind reg_kind, uint32_t reg_num,
+ uint64_t reg_value);
+
+ size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst,
+ size_t dst_len);
+
+ uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr,
+ size_t byte_size, uint64_t fail_value,
+ bool *success_ptr);
+
+ bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src,
+ size_t src_len);
+
+ bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr,
+ uint64_t uval, size_t uval_byte_size);
+
+ uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }
+
+ lldb::ByteOrder GetByteOrder() const { return m_arch.GetByteOrder(); }
+
+ const Opcode &GetOpcode() const { return m_opcode; }
+
+ lldb::addr_t GetAddress() const { return m_addr; }
+
+ const ArchSpec &GetArchitecture() const { return m_arch; }
+
+ static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton,
+ const Context &context, lldb::addr_t addr,
+ void *dst, size_t length);
+
+ static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton,
+ const Context &context, lldb::addr_t addr,
+ const void *dst, size_t length);
+
+ static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value);
+
+ static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton,
+ const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value);
+
+ static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton,
+ const Context &context, lldb::addr_t addr,
+ void *dst, size_t length);
+
+ static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton,
+ const Context &context, lldb::addr_t addr,
+ const void *dst, size_t length);
+
+ static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value);
+
+ static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton,
+ const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value);
+
+ void SetBaton(void *baton);
+
+ void SetCallbacks(ReadMemoryCallback read_mem_callback,
+ WriteMemoryCallback write_mem_callback,
+ ReadRegisterCallback read_reg_callback,
+ WriteRegisterCallback write_reg_callback);
+
+ void SetReadMemCallback(ReadMemoryCallback read_mem_callback);
+
+ void SetWriteMemCallback(WriteMemoryCallback write_mem_callback);
+
+ void SetReadRegCallback(ReadRegisterCallback read_reg_callback);
+
+ void SetWriteRegCallback(WriteRegisterCallback write_reg_callback);
+
+ static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info,
+ lldb::RegisterKind &reg_kind,
+ uint32_t &reg_num);
+
+ static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
+ const RegisterInfo &reg_info);
+
+protected:
+ ArchSpec m_arch;
+ void *m_baton = nullptr;
+ ReadMemoryCallback m_read_mem_callback = &ReadMemoryDefault;
+ WriteMemoryCallback m_write_mem_callback = &WriteMemoryDefault;
+ ReadRegisterCallback m_read_reg_callback = &ReadRegisterDefault;
+ WriteRegisterCallback m_write_reg_callback = &WriteRegisterDefault;
+ lldb::addr_t m_addr = LLDB_INVALID_ADDRESS;
+ Opcode m_opcode;
+
+private:
+ // For EmulateInstruction only
+ DISALLOW_COPY_AND_ASSIGN(EmulateInstruction);
+};
+
+} // namespace lldb_private
+
+#endif // lldb_EmulateInstruction_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h b/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h
new file mode 100644
index 000000000000..d6525b71bfdf
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/FileLineResolver.h
@@ -0,0 +1,66 @@
+//===-- FileLineResolver.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_FileLineResolver_h_
+#define liblldb_FileLineResolver_h_
+
+#include "lldb/Core/SearchFilter.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-defines.h"
+
+#include <stdint.h>
+
+namespace lldb_private {
+class Address;
+class Stream;
+
+/// \class FileLineResolver FileLineResolver.h "lldb/Core/FileLineResolver.h"
+/// This class finds address for source file and line. Optionally, it will
+/// look for inlined instances of the file and line specification.
+
+class FileLineResolver : public Searcher {
+public:
+ FileLineResolver()
+ : m_file_spec(),
+ m_line_number(UINT32_MAX), // Set this to zero for all lines in a file
+ m_sc_list(), m_inlines(true) {}
+
+ FileLineResolver(const FileSpec &resolver, uint32_t line_no,
+ bool check_inlines);
+
+ ~FileLineResolver() override;
+
+ Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr) override;
+
+ lldb::SearchDepth GetDepth() override;
+
+ void GetDescription(Stream *s) override;
+
+ const SymbolContextList &GetFileLineMatches() { return m_sc_list; }
+
+ void Clear();
+
+ void Reset(const FileSpec &file_spec, uint32_t line, bool check_inlines);
+
+protected:
+ FileSpec m_file_spec; // This is the file spec we are looking for.
+ uint32_t m_line_number; // This is the line number that we are looking for.
+ SymbolContextList m_sc_list;
+ bool m_inlines; // This determines whether the resolver looks for inlined
+ // functions or not.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(FileLineResolver);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_FileLineResolver_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h b/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h
new file mode 100644
index 000000000000..8edc3280b01b
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/FileSpecList.h
@@ -0,0 +1,207 @@
+//===-- FileSpecList.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_FileSpecList_h_
+#define liblldb_FileSpecList_h_
+#if defined(__cplusplus)
+
+#include "lldb/Utility/FileSpec.h"
+
+#include <vector>
+
+#include <stddef.h>
+
+namespace lldb_private {
+class Stream;
+
+/// \class FileSpecList FileSpecList.h "lldb/Core/FileSpecList.h"
+/// A file collection class.
+///
+/// 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.
+ FileSpecList();
+
+ /// Copy constructor.
+ FileSpecList(const FileSpecList &rhs) = default;
+
+ /// Move constructor
+ FileSpecList(FileSpecList &&rhs) = default;
+
+ /// Initialize this object from a vector of FileSpecs
+ FileSpecList(std::vector<FileSpec> &&rhs) : m_files(std::move(rhs)) {}
+
+ /// Destructor.
+ ~FileSpecList();
+
+ /// Assignment operator.
+ ///
+ /// Replace the file list in this object with the file list from \a rhs.
+ ///
+ /// \param[in] rhs
+ /// A file list object to copy.
+ ///
+ /// \return
+ /// A const reference to this object.
+ FileSpecList &operator=(const FileSpecList &rhs) = default;
+
+ /// Move-assignment operator.
+ FileSpecList &operator=(FileSpecList &&rhs) = default;
+
+ /// Append a FileSpec object to the list.
+ ///
+ /// Appends \a file to the end of the file list.
+ ///
+ /// \param[in] file
+ /// A new file to append to this file list.
+ void Append(const FileSpec &file);
+
+ /// Append a FileSpec object if unique.
+ ///
+ /// Appends \a file to the end of the file list if it doesn't already exist
+ /// in the file list.
+ ///
+ /// \param[in] file
+ /// A new file to append to this file list.
+ ///
+ /// \return
+ /// \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();
+
+ /// Dumps the file list to the supplied stream pointer "s".
+ ///
+ /// \param[in] s
+ /// The stream that will be used to dump the object description.
+ void Dump(Stream *s, const char *separator_cstr = "\n") const;
+
+ /// Find a file index.
+ ///
+ /// Find the index of the file in the file spec list that matches \a file
+ /// starting \a idx entries into the file spec list.
+ ///
+ /// \param[in] idx
+ /// An index into the file list.
+ ///
+ /// \param[in] file
+ /// The file specification to search for.
+ ///
+ /// \param[in] full
+ /// Should FileSpec::Equal be called with "full" true or false.
+ ///
+ /// \return
+ /// The index of the file that matches \a file if it is found,
+ /// else UINT32_MAX is returned.
+ size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
+
+ /// Get file at index.
+ ///
+ /// Gets a file from the file list. If \a idx is not a valid index, an empty
+ /// FileSpec object will be returned. The file objects that are returned can
+ /// be tested using FileSpec::operator void*().
+ ///
+ /// \param[in] idx
+ /// An index into the file list.
+ ///
+ /// \return
+ /// A copy of the FileSpec object at index \a idx. If \a idx
+ /// is out of range, then an empty FileSpec object will be
+ /// returned.
+ const FileSpec &GetFileSpecAtIndex(size_t idx) const;
+
+ /// Get file specification pointer at index.
+ ///
+ /// Gets a file from the file list. The file objects that are returned can
+ /// be tested using FileSpec::operator void*().
+ ///
+ /// \param[in] idx
+ /// An index into the file list.
+ ///
+ /// \return
+ /// A pointer to a contained FileSpec object at index \a idx.
+ /// If \a idx is out of range, then an NULL is returned.
+ const FileSpec *GetFileSpecPointerAtIndex(size_t idx) const;
+
+ /// Get the memory cost of this object.
+ ///
+ /// Return the size in bytes that this object takes in memory. This returns
+ /// the size in bytes of this object, not any shared string values it may
+ /// refer to.
+ ///
+ /// \return
+ /// The number of bytes that this object occupies in memory.
+ ///
+ /// \see ConstString::StaticMemorySize ()
+ size_t MemorySize() const;
+
+ bool IsEmpty() const { return m_files.empty(); }
+
+ /// Get the number of files in the file list.
+ ///
+ /// \return
+ /// The number of files in the file spec list.
+ size_t GetSize() const;
+
+ bool Insert(size_t idx, const FileSpec &file) {
+ if (idx < m_files.size()) {
+ m_files.insert(m_files.begin() + idx, file);
+ return true;
+ } else if (idx == m_files.size()) {
+ m_files.push_back(file);
+ return true;
+ }
+ return false;
+ }
+
+ bool Replace(size_t idx, const FileSpec &file) {
+ if (idx < m_files.size()) {
+ m_files[idx] = file;
+ return true;
+ }
+ return false;
+ }
+
+ bool Remove(size_t idx) {
+ if (idx < m_files.size()) {
+ m_files.erase(m_files.begin() + idx);
+ return true;
+ }
+ return false;
+ }
+
+ 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:
+ collection m_files; ///< A collection of FileSpec objects.
+};
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_FileSpecList_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h b/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h
new file mode 100644
index 000000000000..ae6c402a45be
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h
@@ -0,0 +1,220 @@
+//===-- FormatEntity.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_FormatEntity_h_
+#define liblldb_FormatEntity_h_
+
+#include "lldb/Utility/CompletionRequest.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-types.h"
+#include <algorithm>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+class Address;
+class ExecutionContext;
+class Stream;
+class StringList;
+class SymbolContext;
+class ValueObject;
+}
+namespace llvm {
+class StringRef;
+}
+
+namespace lldb_private {
+class FormatEntity {
+public:
+ struct Entry {
+ enum class Type {
+ Invalid,
+ ParentNumber,
+ ParentString,
+ EscapeCode,
+ Root,
+ String,
+ Scope,
+ Variable,
+ VariableSynthetic,
+ ScriptVariable,
+ ScriptVariableSynthetic,
+ AddressLoad,
+ AddressFile,
+ AddressLoadOrFile,
+ ProcessID,
+ ProcessFile,
+ ScriptProcess,
+ ThreadID,
+ ThreadProtocolID,
+ ThreadIndexID,
+ ThreadName,
+ ThreadQueue,
+ ThreadStopReason,
+ ThreadReturnValue,
+ ThreadCompletedExpression,
+ ScriptThread,
+ ThreadInfo,
+ TargetArch,
+ ScriptTarget,
+ ModuleFile,
+ File,
+ Lang,
+ FrameIndex,
+ FrameNoDebug,
+ FrameRegisterPC,
+ FrameRegisterSP,
+ FrameRegisterFP,
+ FrameRegisterFlags,
+ FrameRegisterByName,
+ FrameIsArtificial,
+ ScriptFrame,
+ FunctionID,
+ FunctionDidChange,
+ FunctionInitialFunction,
+ FunctionName,
+ FunctionNameWithArgs,
+ FunctionNameNoArgs,
+ FunctionAddrOffset,
+ FunctionAddrOffsetConcrete,
+ FunctionLineOffset,
+ FunctionPCOffset,
+ FunctionInitial,
+ FunctionChanged,
+ FunctionIsOptimized,
+ LineEntryFile,
+ LineEntryLineNumber,
+ LineEntryColumn,
+ LineEntryStartAddress,
+ LineEntryEndAddress,
+ CurrentPCArrow
+ };
+
+ struct Definition {
+ const char *name;
+ const char *string; // Insert this exact string into the output
+ Entry::Type type;
+ uint64_t data;
+ uint32_t num_children;
+ Definition *children; // An array of "num_children" Definition entries,
+ bool keep_separator;
+ };
+
+ Entry(Type t = Type::Invalid, const char *s = nullptr,
+ const char *f = nullptr)
+ : string(s ? s : ""), printf_format(f ? f : ""), children(),
+ definition(nullptr), type(t), fmt(lldb::eFormatDefault), number(0),
+ deref(false) {}
+
+ Entry(llvm::StringRef s);
+ Entry(char ch);
+
+ void AppendChar(char ch);
+
+ void AppendText(const llvm::StringRef &s);
+
+ void AppendText(const char *cstr);
+
+ void AppendEntry(const Entry &&entry) { children.push_back(entry); }
+
+ void Clear() {
+ string.clear();
+ printf_format.clear();
+ children.clear();
+ definition = nullptr;
+ type = Type::Invalid;
+ fmt = lldb::eFormatDefault;
+ number = 0;
+ deref = false;
+ }
+
+ static const char *TypeToCString(Type t);
+
+ void Dump(Stream &s, int depth = 0) const;
+
+ bool operator==(const Entry &rhs) const {
+ if (string != rhs.string)
+ return false;
+ if (printf_format != rhs.printf_format)
+ return false;
+ const size_t n = children.size();
+ const size_t m = rhs.children.size();
+ for (size_t i = 0; i < std::min<size_t>(n, m); ++i) {
+ if (!(children[i] == rhs.children[i]))
+ return false;
+ }
+ if (children != rhs.children)
+ return false;
+ if (definition != rhs.definition)
+ return false;
+ if (type != rhs.type)
+ return false;
+ if (fmt != rhs.fmt)
+ return false;
+ if (deref != rhs.deref)
+ return false;
+ return true;
+ }
+
+ std::string string;
+ std::string printf_format;
+ std::vector<Entry> children;
+ Definition *definition;
+ Type type;
+ lldb::Format fmt;
+ lldb::addr_t number;
+ bool deref;
+ };
+
+ static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc,
+ const ExecutionContext *exe_ctx, const Address *addr,
+ ValueObject *valobj, bool function_changed,
+ bool initial_function);
+
+ static bool FormatStringRef(const llvm::StringRef &format, Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, ValueObject *valobj,
+ bool function_changed, bool initial_function);
+
+ static bool FormatCString(const char *format, Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, ValueObject *valobj,
+ bool function_changed, bool initial_function);
+
+ static Status Parse(const llvm::StringRef &format, Entry &entry);
+
+ static Status ExtractVariableInfo(llvm::StringRef &format_str,
+ llvm::StringRef &variable_name,
+ llvm::StringRef &variable_format);
+
+ static void AutoComplete(lldb_private::CompletionRequest &request);
+
+ // Format the current elements into the stream \a s.
+ //
+ // The root element will be stripped off and the format str passed in will be
+ // either an empty string (print a description of this object), or contain a
+ // `.`-separated series like a domain name that identifies further
+ // sub-elements to display.
+ static bool FormatFileSpec(const FileSpec &file, Stream &s,
+ llvm::StringRef elements,
+ llvm::StringRef element_format);
+
+protected:
+ static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
+ uint32_t depth);
+};
+} // namespace lldb_private
+
+#endif // liblldb_FormatEntity_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Highlighter.h b/contrib/llvm-project/lldb/include/lldb/Core/Highlighter.h
new file mode 100644
index 000000000000..88d3bb3a3cd1
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Highlighter.h
@@ -0,0 +1,156 @@
+//===-- Highlighter.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_Highlighter_h_
+#define liblldb_Highlighter_h_
+
+#include <utility>
+#include <vector>
+
+#include "lldb/Utility/Stream.h"
+#include "lldb/lldb-enumerations.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace lldb_private {
+
+/// Represents style that the highlighter should apply to the given source code.
+/// Stores information about how every kind of token should be annotated.
+struct HighlightStyle {
+
+ /// A pair of strings that should be placed around a certain token. Usually
+ /// stores color codes in these strings (the suffix string is often used for
+ /// resetting the terminal attributes back to normal).
+ class ColorStyle {
+ std::string m_prefix;
+ std::string m_suffix;
+
+ public:
+ ColorStyle() = default;
+ ColorStyle(llvm::StringRef prefix, llvm::StringRef suffix) {
+ Set(prefix, suffix);
+ }
+
+ /// Applies this style to the given value.
+ /// \param s
+ /// The stream to which the result should be appended.
+ /// \param value
+ /// The value that we should place our strings around.
+ void Apply(Stream &s, llvm::StringRef value) const;
+
+ /// Sets the prefix and suffix strings.
+ /// \param prefix
+ /// \param suffix
+ void Set(llvm::StringRef prefix, llvm::StringRef suffix);
+ };
+
+ /// The style for the token which is below the cursor of the user. Note that
+ /// this style is overwritten by the SourceManager with the values of
+ /// stop-show-column-ansi-prefix/stop-show-column-ansi-suffix.
+ ColorStyle selected;
+
+ /// Matches identifiers to variable or functions.
+ ColorStyle identifier;
+ /// Matches any string or character literals in the language: "foo" or 'f'
+ ColorStyle string_literal;
+ /// Matches scalar value literals like '42' or '0.1'.
+ ColorStyle scalar_literal;
+ /// Matches all reserved keywords in the language.
+ ColorStyle keyword;
+ /// Matches any comments in the language.
+ ColorStyle comment;
+ /// Matches commas: ','
+ ColorStyle comma;
+ /// Matches one colon: ':'
+ ColorStyle colon;
+ /// Matches any semicolon: ';'
+ ColorStyle semicolons;
+ /// Matches operators like '+', '-', '%', '&', '='
+ ColorStyle operators;
+
+ /// Matches '{' or '}'
+ ColorStyle braces;
+ /// Matches '[' or ']'
+ ColorStyle square_brackets;
+ /// Matches '(' or ')'
+ ColorStyle parentheses;
+
+ // C language specific options
+
+ /// Matches directives to a preprocessor (if the language has any).
+ ColorStyle pp_directive;
+
+ /// Returns a HighlightStyle that is based on vim's default highlight style.
+ static HighlightStyle MakeVimStyle();
+};
+
+/// Annotates source code with color attributes.
+class Highlighter {
+public:
+ Highlighter() = default;
+ virtual ~Highlighter() = default;
+ DISALLOW_COPY_AND_ASSIGN(Highlighter);
+
+ /// Returns a human readable name for the selected highlighter.
+ virtual llvm::StringRef GetName() const = 0;
+
+ /// Highlights the given line
+ /// \param options
+ /// \param line
+ /// The user supplied line that needs to be highlighted.
+ /// \param cursor_pos
+ /// The cursor position of the user in this line, starting at 0 (which
+ /// means the cursor is on the first character in 'line').
+ /// \param previous_lines
+ /// Any previous lines the user has written which we should only use
+ /// for getting the context of the Highlighting right.
+ /// \param s
+ /// The stream to which the highlighted version of the user string should
+ /// be written.
+ virtual void Highlight(const HighlightStyle &options, llvm::StringRef line,
+ llvm::Optional<size_t> cursor_pos,
+ llvm::StringRef previous_lines, Stream &s) const = 0;
+
+ /// Utility method for calling Highlight without a stream.
+ std::string Highlight(const HighlightStyle &options, llvm::StringRef line,
+ llvm::Optional<size_t> cursor_pos,
+ llvm::StringRef previous_lines = "") const;
+};
+
+/// A default highlighter that only highlights the user cursor, but doesn't
+/// do any other highlighting.
+class DefaultHighlighter : public Highlighter {
+public:
+ llvm::StringRef GetName() const override { return "none"; }
+
+ void Highlight(const HighlightStyle &options, llvm::StringRef line,
+ llvm::Optional<size_t> cursor_pos,
+ llvm::StringRef previous_lines, Stream &s) const override;
+};
+
+/// Manages the available highlighters.
+class HighlighterManager {
+ DefaultHighlighter m_default;
+
+public:
+ /// Queries all known highlighter for one that can highlight some source code.
+ /// \param language_type
+ /// The language type that the caller thinks the source code was given in.
+ /// \param path
+ /// The path to the file the source code is from. Used as a fallback when
+ /// the user can't provide a language.
+ /// \return
+ /// The highlighter that wants to highlight the source code. Could be an
+ /// empty highlighter that does nothing.
+ const Highlighter &getHighlighterFor(lldb::LanguageType language_type,
+ llvm::StringRef path) const;
+ const Highlighter &getDefaultHighlighter() const { return m_default; }
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Highlighter_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h
new file mode 100644
index 000000000000..37142a5a8396
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h
@@ -0,0 +1,585 @@
+//===-- IOHandler.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_IOHandler_h_
+#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"
+#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StringList.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+#include <stdint.h>
+#include <stdio.h>
+
+namespace lldb_private {
+class Debugger;
+}
+
+namespace curses {
+class Application;
+typedef std::unique_ptr<Application> ApplicationAP;
+} // namespace curses
+
+namespace lldb_private {
+
+class IOHandler {
+public:
+ enum class Type {
+ CommandInterpreter,
+ CommandList,
+ Confirm,
+ Curses,
+ Expression,
+ REPL,
+ ProcessIO,
+ PythonInterpreter,
+ PythonCode,
+ Other
+ };
+
+ IOHandler(Debugger &debugger, IOHandler::Type type);
+
+ IOHandler(Debugger &debugger, IOHandler::Type type,
+ const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp,
+ const lldb::StreamFileSP &error_sp, uint32_t flags,
+ repro::DataRecorder *data_recorder);
+
+ virtual ~IOHandler();
+
+ // Each IOHandler gets to run until it is done. It should read data from the
+ // "in" and place output into "out" and "err and return when done.
+ virtual void Run() = 0;
+
+ // Called when an input reader should relinquish its control so another can
+ // be pushed onto the IO handler stack, or so the current IO handler can pop
+ // itself off the stack
+
+ virtual void Cancel() = 0;
+
+ // Called when CTRL+C is pressed which usually causes
+ // Debugger::DispatchInputInterrupt to be called.
+
+ virtual bool Interrupt() = 0;
+
+ virtual void GotEOF() = 0;
+
+ virtual bool IsActive() { return m_active && !m_done; }
+
+ virtual void SetIsDone(bool b) { m_done = b; }
+
+ virtual bool GetIsDone() { return m_done; }
+
+ Type GetType() const { return m_type; }
+
+ virtual void Activate() { m_active = true; }
+
+ virtual void Deactivate() { m_active = false; }
+
+ virtual const char *GetPrompt() {
+ // Prompt support isn't mandatory
+ return nullptr;
+ }
+
+ virtual bool SetPrompt(llvm::StringRef prompt) {
+ // Prompt support isn't mandatory
+ return false;
+ }
+ bool SetPrompt(const char *) = delete;
+
+ virtual ConstString GetControlSequence(char ch) { return ConstString(); }
+
+ virtual const char *GetCommandPrefix() { return nullptr; }
+
+ virtual const char *GetHelpPrologue() { return nullptr; }
+
+ int GetInputFD();
+
+ int GetOutputFD();
+
+ int GetErrorFD();
+
+ FILE *GetInputFILE();
+
+ FILE *GetOutputFILE();
+
+ FILE *GetErrorFILE();
+
+ lldb::FileSP &GetInputFileSP();
+
+ lldb::StreamFileSP &GetOutputStreamFileSP();
+
+ lldb::StreamFileSP &GetErrorStreamFileSP();
+
+ Debugger &GetDebugger() { return m_debugger; }
+
+ void *GetUserData() { return m_user_data; }
+
+ void SetUserData(void *user_data) { m_user_data = user_data; }
+
+ Flags &GetFlags() { return m_flags; }
+
+ const Flags &GetFlags() const { return m_flags; }
+
+ /// Check if the input is being supplied interactively by a user
+ ///
+ /// This will return true if the input stream is a terminal (tty or
+ /// pty) and can cause IO handlers to do different things (like
+ /// for a confirmation when deleting all breakpoints).
+ bool GetIsInteractive();
+
+ /// Check if the input is coming from a real terminal.
+ ///
+ /// A real terminal has a valid size with a certain number of rows
+ /// and columns. If this function returns true, then terminal escape
+ /// sequences are expected to work (cursor movement escape sequences,
+ /// clearing lines, etc).
+ bool GetIsRealTerminal();
+
+ void SetPopped(bool b);
+
+ void WaitForPop();
+
+ virtual void PrintAsync(Stream *stream, const char *s, size_t len) {
+ stream->Write(s, len);
+ stream->Flush();
+ }
+
+protected:
+ Debugger &m_debugger;
+ lldb::FileSP m_input_sp;
+ lldb::StreamFileSP m_output_sp;
+ lldb::StreamFileSP m_error_sp;
+ repro::DataRecorder *m_data_recorder;
+ Predicate<bool> m_popped;
+ Flags m_flags;
+ Type m_type;
+ void *m_user_data;
+ bool m_done;
+ bool m_active;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(IOHandler);
+};
+
+/// A delegate class for use with IOHandler subclasses.
+///
+/// The IOHandler delegate is designed to be mixed into classes so
+/// they can use an IOHandler subclass to fetch input and notify the
+/// object that inherits from this delegate class when a token is
+/// received.
+class IOHandlerDelegate {
+public:
+ enum class Completion { None, LLDBCommand, Expression };
+
+ IOHandlerDelegate(Completion completion = Completion::None)
+ : m_completion(completion) {}
+
+ virtual ~IOHandlerDelegate() = default;
+
+ virtual void IOHandlerActivated(IOHandler &io_handler, bool interactive) {}
+
+ virtual void IOHandlerDeactivated(IOHandler &io_handler) {}
+
+ virtual void IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request);
+
+ virtual const char *IOHandlerGetFixIndentationCharacters() { return nullptr; }
+
+ /// Called when a new line is created or one of an identified set of
+ /// indentation characters is typed.
+ ///
+ /// This function determines how much indentation should be added
+ /// or removed to match the recommended amount for the final line.
+ ///
+ /// \param[in] io_handler
+ /// The IOHandler that responsible for input.
+ ///
+ /// \param[in] lines
+ /// The current input up to the line to be corrected. Lines
+ /// following the line containing the cursor are not included.
+ ///
+ /// \param[in] cursor_position
+ /// The number of characters preceding the cursor on the final
+ /// line at the time.
+ ///
+ /// \return
+ /// Returns an integer describing the number of spaces needed
+ /// to correct the indentation level. Positive values indicate
+ /// that spaces should be added, while negative values represent
+ /// spaces that should be removed.
+ virtual int IOHandlerFixIndentation(IOHandler &io_handler,
+ const StringList &lines,
+ int cursor_position) {
+ return 0;
+ }
+
+ /// Called when a line or lines have been retrieved.
+ ///
+ /// This function can handle the current line and possibly call
+ /// IOHandler::SetIsDone(true) when the IO handler is done like when
+ /// "quit" is entered as a command, of when an empty line is
+ /// received. It is up to the delegate to determine when a line
+ /// should cause a IOHandler to exit.
+ virtual void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) = 0;
+
+ virtual void IOHandlerInputInterrupted(IOHandler &io_handler,
+ std::string &data) {}
+
+ /// Called to determine whether typing enter after the last line in
+ /// \a lines should end input. This function will not be called on
+ /// IOHandler objects that are getting single lines.
+ /// \param[in] io_handler
+ /// The IOHandler that responsible for updating the lines.
+ ///
+ /// \param[in] lines
+ /// The current multi-line content. May be altered to provide
+ /// alternative input when complete.
+ ///
+ /// \return
+ /// Return an boolean to indicate whether input is complete,
+ /// true indicates that no additional input is necessary, while
+ /// false indicates that more input is required.
+ virtual bool IOHandlerIsInputComplete(IOHandler &io_handler,
+ StringList &lines) {
+ // Impose no requirements for input to be considered complete. subclasses
+ // should do something more intelligent.
+ return true;
+ }
+
+ virtual ConstString IOHandlerGetControlSequence(char ch) {
+ return ConstString();
+ }
+
+ virtual const char *IOHandlerGetCommandPrefix() { return nullptr; }
+
+ virtual const char *IOHandlerGetHelpPrologue() { return nullptr; }
+
+ // Intercept the IOHandler::Interrupt() calls and do something.
+ //
+ // Return true if the interrupt was handled, false if the IOHandler should
+ // continue to try handle the interrupt itself.
+ virtual bool IOHandlerInterrupt(IOHandler &io_handler) { return false; }
+
+protected:
+ Completion m_completion; // Support for common builtin completions
+};
+
+// IOHandlerDelegateMultiline
+//
+// A IOHandlerDelegate that handles terminating multi-line input when
+// the last line is equal to "end_line" which is specified in the constructor.
+class IOHandlerDelegateMultiline : public IOHandlerDelegate {
+public:
+ IOHandlerDelegateMultiline(const char *end_line,
+ Completion completion = Completion::None)
+ : IOHandlerDelegate(completion),
+ m_end_line((end_line && end_line[0]) ? end_line : "") {}
+
+ ~IOHandlerDelegateMultiline() override = default;
+
+ ConstString IOHandlerGetControlSequence(char ch) override {
+ if (ch == 'd')
+ return ConstString(m_end_line + "\n");
+ return ConstString();
+ }
+
+ bool IOHandlerIsInputComplete(IOHandler &io_handler,
+ StringList &lines) override {
+ // Determine whether the end of input signal has been entered
+ const size_t num_lines = lines.GetSize();
+ if (num_lines > 0 && lines[num_lines - 1] == m_end_line) {
+ // Remove the terminal line from "lines" so it doesn't appear in the
+ // resulting input and return true to indicate we are done getting lines
+ lines.PopBack();
+ return true;
+ }
+ return false;
+ }
+
+protected:
+ const std::string m_end_line;
+};
+
+class IOHandlerEditline : public IOHandler {
+public:
+ IOHandlerEditline(Debugger &debugger, IOHandler::Type type,
+ const char *editline_name, // Used for saving history files
+ llvm::StringRef prompt, llvm::StringRef continuation_prompt,
+ bool multi_line, bool color_prompts,
+ uint32_t line_number_start, // If non-zero show line numbers
+ // starting at
+ // 'line_number_start'
+ IOHandlerDelegate &delegate,
+ repro::DataRecorder *data_recorder);
+
+ IOHandlerEditline(Debugger &debugger, IOHandler::Type type,
+ 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
+ llvm::StringRef prompt, llvm::StringRef continuation_prompt,
+ bool multi_line, bool color_prompts,
+ uint32_t line_number_start, // If non-zero show line numbers
+ // starting at
+ // 'line_number_start'
+ IOHandlerDelegate &delegate,
+ repro::DataRecorder *data_recorder);
+
+ IOHandlerEditline(Debugger &, IOHandler::Type, const char *, const char *,
+ const char *, bool, bool, uint32_t,
+ IOHandlerDelegate &) = delete;
+
+ 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;
+
+ ~IOHandlerEditline() override;
+
+ void Run() override;
+
+ void Cancel() override;
+
+ bool Interrupt() override;
+
+ void GotEOF() override;
+
+ void Activate() override;
+
+ void Deactivate() override;
+
+ ConstString GetControlSequence(char ch) override {
+ return m_delegate.IOHandlerGetControlSequence(ch);
+ }
+
+ const char *GetCommandPrefix() override {
+ return m_delegate.IOHandlerGetCommandPrefix();
+ }
+
+ const char *GetHelpPrologue() override {
+ return m_delegate.IOHandlerGetHelpPrologue();
+ }
+
+ const char *GetPrompt() override;
+
+ bool SetPrompt(llvm::StringRef prompt) override;
+ bool SetPrompt(const char *prompt) = delete;
+
+ const char *GetContinuationPrompt();
+
+ void SetContinuationPrompt(llvm::StringRef prompt);
+ void SetContinuationPrompt(const char *) = delete;
+
+ bool GetLine(std::string &line, bool &interrupted);
+
+ bool GetLines(StringList &lines, bool &interrupted);
+
+ void SetBaseLineNumber(uint32_t line);
+
+ bool GetInterruptExits() { return m_interrupt_exits; }
+
+ void SetInterruptExits(bool b) { m_interrupt_exits = b; }
+
+ const StringList *GetCurrentLines() const { return m_current_lines_ptr; }
+
+ uint32_t GetCurrentLineIndex() const;
+
+ void PrintAsync(Stream *stream, const char *s, size_t len) override;
+
+private:
+#ifndef LLDB_DISABLE_LIBEDIT
+ static bool IsInputCompleteCallback(Editline *editline, StringList &lines,
+ void *baton);
+
+ static int FixIndentationCallback(Editline *editline, const StringList &lines,
+ int cursor_position, void *baton);
+
+ static void AutoCompleteCallback(CompletionRequest &request, void *baton);
+#endif
+
+protected:
+#ifndef LLDB_DISABLE_LIBEDIT
+ std::unique_ptr<Editline> m_editline_up;
+#endif
+ IOHandlerDelegate &m_delegate;
+ std::string m_prompt;
+ std::string m_continuation_prompt;
+ StringList *m_current_lines_ptr;
+ uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt
+ uint32_t m_curr_line_idx;
+ bool m_multi_line;
+ bool m_color_prompts;
+ 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
+// IOHandlerConfirm to see how.
+class IOHandlerConfirm : public IOHandlerDelegate, public IOHandlerEditline {
+public:
+ IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
+ bool default_response);
+
+ ~IOHandlerConfirm() override;
+
+ bool GetResponse() const { return m_user_response; }
+
+ void IOHandlerComplete(IOHandler &io_handler,
+ CompletionRequest &request) override;
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override;
+
+protected:
+ const bool m_default_response;
+ bool m_user_response;
+};
+
+class IOHandlerCursesGUI : public IOHandler {
+public:
+ IOHandlerCursesGUI(Debugger &debugger);
+
+ ~IOHandlerCursesGUI() override;
+
+ void Run() override;
+
+ void Cancel() override;
+
+ bool Interrupt() override;
+
+ void GotEOF() override;
+
+ void Activate() override;
+
+ void Deactivate() override;
+
+protected:
+ curses::ApplicationAP m_app_ap;
+};
+
+class IOHandlerCursesValueObjectList : public IOHandler {
+public:
+ IOHandlerCursesValueObjectList(Debugger &debugger,
+ ValueObjectList &valobj_list);
+
+ ~IOHandlerCursesValueObjectList() override;
+
+ void Run() override;
+
+ void GotEOF() override;
+
+protected:
+ ValueObjectList m_valobj_list;
+};
+
+class IOHandlerStack {
+public:
+ IOHandlerStack() : m_stack(), m_mutex(), m_top(nullptr) {}
+
+ ~IOHandlerStack() = default;
+
+ size_t GetSize() const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_stack.size();
+ }
+
+ void Push(const lldb::IOHandlerSP &sp) {
+ if (sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ sp->SetPopped(false);
+ m_stack.push_back(sp);
+ // Set m_top the non-locking IsTop() call
+ m_top = sp.get();
+ }
+ }
+
+ bool IsEmpty() const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_stack.empty();
+ }
+
+ lldb::IOHandlerSP Top() {
+ lldb::IOHandlerSP sp;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_stack.empty())
+ sp = m_stack.back();
+ }
+ return sp;
+ }
+
+ void Pop() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_stack.empty()) {
+ lldb::IOHandlerSP sp(m_stack.back());
+ m_stack.pop_back();
+ sp->SetPopped(true);
+ }
+ // Set m_top the non-locking IsTop() call
+
+ m_top = (m_stack.empty() ? nullptr : m_stack.back().get());
+ }
+
+ std::recursive_mutex &GetMutex() { return m_mutex; }
+
+ bool IsTop(const lldb::IOHandlerSP &io_handler_sp) const {
+ return m_top == io_handler_sp.get();
+ }
+
+ bool CheckTopIOHandlerTypes(IOHandler::Type top_type,
+ IOHandler::Type second_top_type) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ const size_t num_io_handlers = m_stack.size();
+ return (num_io_handlers >= 2 &&
+ m_stack[num_io_handlers - 1]->GetType() == top_type &&
+ m_stack[num_io_handlers - 2]->GetType() == second_top_type);
+ }
+
+ ConstString GetTopIOHandlerControlSequence(char ch) {
+ return ((m_top != nullptr) ? m_top->GetControlSequence(ch) : ConstString());
+ }
+
+ const char *GetTopIOHandlerCommandPrefix() {
+ return ((m_top != nullptr) ? m_top->GetCommandPrefix() : nullptr);
+ }
+
+ const char *GetTopIOHandlerHelpPrologue() {
+ return ((m_top != nullptr) ? m_top->GetHelpPrologue() : nullptr);
+ }
+
+ void PrintAsync(Stream *stream, const char *s, size_t len);
+
+protected:
+ typedef std::vector<lldb::IOHandlerSP> collection;
+ collection m_stack;
+ mutable std::recursive_mutex m_mutex;
+ IOHandler *m_top;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(IOHandlerStack);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_IOHandler_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOStreamMacros.h b/contrib/llvm-project/lldb/include/lldb/Core/IOStreamMacros.h
new file mode 100644
index 000000000000..45bde88f9441
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/IOStreamMacros.h
@@ -0,0 +1,41 @@
+//===-- IOStreamMacros.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_IOStreamMacros_h_
+#define liblldb_IOStreamMacros_h_
+#if defined(__cplusplus)
+
+#include <iomanip>
+
+#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
+#define HEXBASE '0' << 'x' << RAW_HEXBASE
+#define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)(x))
+#define RAWHEX16 RAW_HEXBASE << std::setw(4)
+#define RAWHEX32 RAW_HEXBASE << std::setw(8)
+#define RAWHEX64 RAW_HEXBASE << std::setw(16)
+#define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x))
+#define HEX16 HEXBASE << std::setw(4)
+#define HEX32 HEXBASE << std::setw(8)
+#define HEX64 HEXBASE << std::setw(16)
+#define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x) * 2) << (x)
+#define HEX(x) HEXBASE << std::setw(sizeof(x) * 2) << (x)
+#define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x)
+#define STRING_WIDTH(w) std::setfill(' ') << std::setw(w)
+#define LEFT_STRING_WIDTH(s, w) \
+ std::left << std::setfill(' ') << std::setw(w) << (s) << std::right
+#define DECIMAL std::dec << std::setfill(' ')
+#define DECIMAL_WIDTH(w) DECIMAL << std::setw(w)
+//#define FLOAT(n, d) std::setfill(' ') << std::setw((n)+(d)+1) <<
+//std::setprecision(d) << std::showpoint << std::fixed
+#define INDENT_WITH_SPACES(iword_idx) \
+ std::setfill(' ') << std::setw((iword_idx)) << ""
+#define INDENT_WITH_TABS(iword_idx) \
+ std::setfill('\t') << std::setw((iword_idx)) << ""
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_IOStreamMacros_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h b/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h
new file mode 100644
index 000000000000..04e58fcdf313
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/LoadedModuleInfoList.h
@@ -0,0 +1,116 @@
+//===-- LoadedModuleInfoList.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_LoadedModuleInfoList_h_
+#define liblldb_LoadedModuleInfoList_h_
+
+
+#include <cassert>
+#include <string>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-private-forward.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+class LoadedModuleInfoList {
+public:
+ class LoadedModuleInfo {
+ public:
+ enum e_data_point {
+ e_has_name = 0,
+ e_has_base,
+ e_has_dynamic,
+ e_has_link_map,
+ e_num
+ };
+
+ LoadedModuleInfo() {
+ for (uint32_t i = 0; i < e_num; ++i)
+ m_has[i] = false;
+ };
+
+ void set_name(const std::string &name) {
+ m_name = name;
+ m_has[e_has_name] = true;
+ }
+ bool get_name(std::string &out) const {
+ out = m_name;
+ return m_has[e_has_name];
+ }
+
+ void set_base(const lldb::addr_t base) {
+ m_base = base;
+ m_has[e_has_base] = true;
+ }
+ bool get_base(lldb::addr_t &out) const {
+ out = m_base;
+ return m_has[e_has_base];
+ }
+
+ void set_base_is_offset(bool is_offset) { m_base_is_offset = is_offset; }
+ bool get_base_is_offset(bool &out) const {
+ out = m_base_is_offset;
+ return m_has[e_has_base];
+ }
+
+ void set_link_map(const lldb::addr_t addr) {
+ m_link_map = addr;
+ m_has[e_has_link_map] = true;
+ }
+ bool get_link_map(lldb::addr_t &out) const {
+ out = m_link_map;
+ return m_has[e_has_link_map];
+ }
+
+ void set_dynamic(const lldb::addr_t addr) {
+ m_dynamic = addr;
+ m_has[e_has_dynamic] = true;
+ }
+ bool get_dynamic(lldb::addr_t &out) const {
+ out = m_dynamic;
+ return m_has[e_has_dynamic];
+ }
+
+ bool has_info(e_data_point datum) const {
+ assert(datum < e_num);
+ return m_has[datum];
+ }
+
+ bool operator==(LoadedModuleInfo const &rhs) const {
+ for (size_t i = 0; i < e_num; ++i) {
+ if (m_has[i] != rhs.m_has[i])
+ return false;
+ }
+
+ return (m_base == rhs.m_base) && (m_link_map == rhs.m_link_map) &&
+ (m_dynamic == rhs.m_dynamic) && (m_name == rhs.m_name);
+ }
+
+ protected:
+ bool m_has[e_num];
+ std::string m_name;
+ lldb::addr_t m_link_map;
+ lldb::addr_t m_base;
+ bool m_base_is_offset;
+ lldb::addr_t m_dynamic;
+ };
+
+ LoadedModuleInfoList() : m_list(), m_link_map(LLDB_INVALID_ADDRESS) {}
+
+ void add(const LoadedModuleInfo &mod) { m_list.push_back(mod); }
+
+ void clear() { m_list.clear(); }
+
+ std::vector<LoadedModuleInfo> m_list;
+ lldb::addr_t m_link_map;
+};
+} // namespace lldb_private
+
+#endif // liblldb_LoadedModuleInfoList_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h b/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h
new file mode 100644
index 000000000000..63fa0f618dae
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h
@@ -0,0 +1,276 @@
+//===-- Mangled.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_Mangled_h_
+#define liblldb_Mangled_h_
+#if defined(__cplusplus)
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include "lldb/Utility/ConstString.h"
+
+#include "llvm/ADT/StringRef.h"
+
+#include <memory>
+#include <stddef.h>
+
+namespace lldb_private {
+
+/// \class Mangled Mangled.h "lldb/Core/Mangled.h"
+/// A class that handles mangled names.
+///
+/// Designed to handle mangled names. The demangled version of any names will
+/// be computed when the demangled name is accessed through the Demangled()
+/// acccessor. This class can also tokenize the demangled version of the name
+/// for powerful searches. Functions and symbols could make instances of this
+/// class for their mangled names. Uniqued string pools are used for the
+/// mangled, demangled, and token string values to allow for faster
+/// comparisons and for efficient memory use.
+class Mangled {
+public:
+ enum NamePreference {
+ ePreferMangled,
+ ePreferDemangled,
+ ePreferDemangledWithoutArguments
+ };
+
+ enum ManglingScheme {
+ eManglingSchemeNone = 0,
+ eManglingSchemeMSVC,
+ eManglingSchemeItanium
+ };
+
+ /// Default constructor.
+ ///
+ /// Initialize with both mangled and demangled names empty.
+ Mangled() = default;
+
+ /// Construct with name.
+ ///
+ /// Constructor with an optional string and auto-detect if \a name is
+ /// mangled or not.
+ ///
+ /// \param[in] name
+ /// The already const name to copy into this object.
+ explicit Mangled(ConstString name);
+
+ explicit Mangled(llvm::StringRef name);
+
+ /// Convert to pointer operator.
+ ///
+ /// This allows code to check a Mangled object to see if it contains a valid
+ /// mangled name using code such as:
+ ///
+ /// \code
+ /// Mangled mangled(...);
+ /// if (mangled)
+ /// { ...
+ /// \endcode
+ ///
+ /// \return
+ /// A pointer to this object if either the mangled or unmangled
+ /// name is set, NULL otherwise.
+ operator void *() const;
+
+ /// Logical NOT operator.
+ ///
+ /// This allows code to check a Mangled object to see if it contains an
+ /// empty mangled name using code such as:
+ ///
+ /// \code
+ /// Mangled mangled(...);
+ /// if (!mangled)
+ /// { ...
+ /// \endcode
+ ///
+ /// \return
+ /// Returns \b true if the object has an empty mangled and
+ /// unmangled name, \b false otherwise.
+ bool operator!() const;
+
+ /// Clear the mangled and demangled values.
+ void Clear();
+
+ /// Compare the mangled string values
+ ///
+ /// Compares the Mangled::GetName() string in \a lhs and \a rhs.
+ ///
+ /// \param[in] lhs
+ /// A const reference to the Left Hand Side object to compare.
+ ///
+ /// \param[in] rhs
+ /// A const reference to the Right Hand Side object to compare.
+ ///
+ /// \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
+ static int Compare(const Mangled &lhs, const Mangled &rhs);
+
+ /// Dump a description of this object to a Stream \a s.
+ ///
+ /// Dump a Mangled object to stream \a s. We don't force our demangled name
+ /// to be computed currently (we don't use the accessor).
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ void Dump(Stream *s) const;
+
+ /// Dump a debug description of this object to a Stream \a s.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ void DumpDebug(Stream *s) const;
+
+ /// Demangled name get accessor.
+ ///
+ /// \return
+ /// A const reference to the demangled name string object.
+ ConstString GetDemangledName(lldb::LanguageType language) const;
+
+ /// Display demangled name get accessor.
+ ///
+ /// \return
+ /// A const reference to the display demangled name string object.
+ ConstString GetDisplayDemangledName(lldb::LanguageType language) const;
+
+ void SetDemangledName(ConstString name) { m_demangled = name; }
+
+ void SetMangledName(ConstString name) { m_mangled = name; }
+
+ /// Mangled name get accessor.
+ ///
+ /// \return
+ /// A reference to the mangled name string object.
+ ConstString &GetMangledName() { return m_mangled; }
+
+ /// Mangled name get accessor.
+ ///
+ /// \return
+ /// A const reference to the mangled name string object.
+ ConstString GetMangledName() const { return m_mangled; }
+
+ /// Best name get accessor.
+ ///
+ /// \param[in] preference
+ /// Which name would you prefer to get?
+ ///
+ /// \return
+ /// A const reference to the preferred name string object if this
+ /// object has a valid name of that kind, else a const reference to the
+ /// other name is returned.
+ ConstString GetName(lldb::LanguageType language,
+ NamePreference preference = ePreferDemangled) const;
+
+ /// Check if "name" matches either the mangled or demangled name.
+ ///
+ /// \param[in] name
+ /// A name to match against both strings.
+ ///
+ /// \return
+ /// \b True if \a name matches either name, \b false otherwise.
+ bool NameMatches(ConstString name, lldb::LanguageType language) const {
+ if (m_mangled == name)
+ return true;
+ return GetDemangledName(language) == name;
+ }
+ bool NameMatches(const RegularExpression &regex,
+ lldb::LanguageType language) const;
+
+ /// Get the memory cost of this object.
+ ///
+ /// Return the size in bytes that this object takes in memory. This returns
+ /// the size in bytes of this object, not any shared string values it may
+ /// refer to.
+ ///
+ /// \return
+ /// The number of bytes that this object occupies in memory.
+ ///
+ /// \see ConstString::StaticMemorySize ()
+ size_t MemorySize() const;
+
+ /// Set the string value in this object.
+ ///
+ /// If \a is_mangled is \b true, then the mangled named is set to \a name,
+ /// else the demangled name is set to \a name.
+ ///
+ /// \param[in] name
+ /// The already const version of the name for this object.
+ ///
+ /// \param[in] is_mangled
+ /// If \b true then \a name is a mangled name, if \b false then
+ /// \a name is demangled.
+ void SetValue(ConstString name, bool is_mangled);
+
+ /// Set the string value in this object.
+ ///
+ /// This version auto detects if the string is mangled by inspecting the
+ /// string value and looking for common mangling prefixes.
+ ///
+ /// \param[in] name
+ /// The already const version of the name for this object.
+ void SetValue(ConstString name);
+
+ /// Try to guess the language from the mangling.
+ ///
+ /// For a mangled name to have a language it must have both a mangled and a
+ /// demangled name and it can be guessed from the mangling what the language
+ /// is. Note: this will return C++ for any language that uses Itanium ABI
+ /// mangling.
+ ///
+ /// Standard C function names will return eLanguageTypeUnknown because they
+ /// aren't mangled and it isn't clear what language the name represents
+ /// (there will be no mangled name).
+ ///
+ /// \return
+ /// The language for the mangled/demangled name, eLanguageTypeUnknown
+ /// if there is no mangled or demangled counterpart.
+ lldb::LanguageType GuessLanguage() const;
+
+ /// Function signature for filtering mangled names.
+ using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
+
+ /// Trigger explicit demangling to obtain rich mangling information. This is
+ /// optimized for batch processing while populating a name index. To get the
+ /// pure demangled name string for a single entity, use GetDemangledName()
+ /// instead.
+ ///
+ /// For names that match the Itanium mangling scheme, this uses LLVM's
+ /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
+ /// parser currently.
+ ///
+ /// This function is thread-safe when used with different \a context
+ /// instances in different threads.
+ ///
+ /// \param[in] context
+ /// The context for this function. A single instance can be stack-
+ /// allocated in the caller's frame and used for multiple calls.
+ ///
+ /// \param[in] skip_mangled_name
+ /// A filtering function for skipping entities based on name and mangling
+ /// scheme. This can be null if unused.
+ ///
+ /// \return
+ /// True on success, false otherwise.
+ bool DemangleWithRichManglingInfo(RichManglingContext &context,
+ SkipMangledNameFn *skip_mangled_name);
+
+private:
+ /// Mangled member variables.
+ ConstString m_mangled; ///< The mangled version of the name
+ mutable ConstString m_demangled; ///< Mutable so we can get it on demand with
+ ///a const version of this object
+};
+
+Stream &operator<<(Stream &s, const Mangled &obj);
+
+} // namespace lldb_private
+
+#endif // #if defined(__cplusplus)
+#endif // liblldb_Mangled_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h b/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h
new file mode 100644
index 000000000000..7dc9b5be3465
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/MappedHash.h
@@ -0,0 +1,310 @@
+//===-- MappedHash.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_MappedHash_h_
+#define liblldb_MappedHash_h_
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <vector>
+
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Stream.h"
+#include "llvm/Support/DJB.h"
+
+class MappedHash {
+public:
+ enum HashFunctionType {
+ eHashFunctionDJB = 0u // Daniel J Bernstein hash function that is also used
+ // by the ELF GNU_HASH sections
+ };
+
+ static uint32_t HashString(uint32_t hash_function, llvm::StringRef s) {
+ switch (hash_function) {
+ case MappedHash::eHashFunctionDJB:
+ return llvm::djbHash(s);
+
+ default:
+ break;
+ }
+ llvm_unreachable("Invalid hash function index");
+ }
+
+ static const uint32_t HASH_MAGIC = 0x48415348u;
+ static const uint32_t HASH_CIGAM = 0x48534148u;
+
+ template <typename T> struct Header {
+ typedef T HeaderData;
+
+ uint32_t
+ magic; // HASH_MAGIC or HASH_CIGAM magic value to allow endian detection
+ uint16_t version; // Version number
+ uint16_t hash_function; // The hash function enumeration that was used
+ uint32_t bucket_count; // The number of buckets in this hash table
+ uint32_t hashes_count; // The total number of unique hash values and hash
+ // data offsets in this table
+ uint32_t header_data_len; // The size in bytes of the "header_data" template
+ // member below
+ HeaderData header_data; //
+
+ Header()
+ : magic(HASH_MAGIC), version(1), hash_function(eHashFunctionDJB),
+ bucket_count(0), hashes_count(0), header_data_len(sizeof(T)),
+ header_data() {}
+
+ virtual ~Header() = default;
+
+ size_t GetByteSize() const {
+ return sizeof(magic) + sizeof(version) + sizeof(hash_function) +
+ sizeof(bucket_count) + sizeof(hashes_count) +
+ sizeof(header_data_len) + header_data_len;
+ }
+
+ virtual size_t GetByteSize(const HeaderData &header_data) = 0;
+
+ void SetHeaderDataByteSize(uint32_t header_data_byte_size) {
+ header_data_len = header_data_byte_size;
+ }
+
+ void Dump(lldb_private::Stream &s) {
+ s.Printf("header.magic = 0x%8.8x\n", magic);
+ s.Printf("header.version = 0x%4.4x\n", version);
+ s.Printf("header.hash_function = 0x%4.4x\n", hash_function);
+ s.Printf("header.bucket_count = 0x%8.8x %u\n", bucket_count,
+ bucket_count);
+ s.Printf("header.hashes_count = 0x%8.8x %u\n", hashes_count,
+ hashes_count);
+ s.Printf("header.header_data_len = 0x%8.8x %u\n", header_data_len,
+ header_data_len);
+ }
+
+ virtual lldb::offset_t Read(lldb_private::DataExtractor &data,
+ lldb::offset_t offset) {
+ if (data.ValidOffsetForDataOfSize(
+ offset, sizeof(magic) + sizeof(version) + sizeof(hash_function) +
+ sizeof(bucket_count) + sizeof(hashes_count) +
+ sizeof(header_data_len))) {
+ magic = data.GetU32(&offset);
+ if (magic != HASH_MAGIC) {
+ if (magic == HASH_CIGAM) {
+ switch (data.GetByteOrder()) {
+ case lldb::eByteOrderBig:
+ data.SetByteOrder(lldb::eByteOrderLittle);
+ break;
+ case lldb::eByteOrderLittle:
+ data.SetByteOrder(lldb::eByteOrderBig);
+ break;
+ default:
+ return LLDB_INVALID_OFFSET;
+ }
+ } else {
+ // Magic bytes didn't match
+ version = 0;
+ return LLDB_INVALID_OFFSET;
+ }
+ }
+
+ version = data.GetU16(&offset);
+ if (version != 1) {
+ // Unsupported version
+ return LLDB_INVALID_OFFSET;
+ }
+ hash_function = data.GetU16(&offset);
+ if (hash_function == 4)
+ hash_function = 0; // Deal with pre-release version of this table...
+ bucket_count = data.GetU32(&offset);
+ hashes_count = data.GetU32(&offset);
+ header_data_len = data.GetU32(&offset);
+ return offset;
+ }
+ return LLDB_INVALID_OFFSET;
+ }
+ //
+ // // Returns a buffer that contains a serialized version of this
+ // table
+ // // that must be freed with free().
+ // virtual void *
+ // Write (int fd);
+ };
+
+ // A class for reading and using a saved hash table from a block of data
+ // in memory
+ template <typename __KeyType, class __HeaderType, class __HashData>
+ class MemoryTable {
+ public:
+ typedef __HeaderType HeaderType;
+ typedef __KeyType KeyType;
+ typedef __HashData HashData;
+
+ enum Result {
+ eResultKeyMatch = 0u, // The entry was found, key matched and "pair" was
+ // filled in successfully
+ eResultKeyMismatch =
+ 1u, // Bucket hash data collision, but key didn't match
+ eResultEndOfHashData = 2u, // The chain of items for this hash data in
+ // this bucket is terminated, search no more
+ eResultError = 3u // Status parsing the hash data, abort
+ };
+
+ struct Pair {
+ KeyType key;
+ HashData value;
+ };
+
+ MemoryTable(lldb_private::DataExtractor &data)
+ : m_header(), m_hash_indexes(nullptr), m_hash_values(nullptr),
+ m_hash_offsets(nullptr) {
+ lldb::offset_t offset = m_header.Read(data, 0);
+ if (offset != LLDB_INVALID_OFFSET && IsValid()) {
+ m_hash_indexes = (const uint32_t *)data.GetData(
+ &offset, m_header.bucket_count * sizeof(uint32_t));
+ m_hash_values = (const uint32_t *)data.GetData(
+ &offset, m_header.hashes_count * sizeof(uint32_t));
+ m_hash_offsets = (const uint32_t *)data.GetData(
+ &offset, m_header.hashes_count * sizeof(uint32_t));
+ }
+ }
+
+ virtual ~MemoryTable() = default;
+
+ bool IsValid() const {
+ return m_header.version == 1 &&
+ m_header.hash_function == eHashFunctionDJB &&
+ m_header.bucket_count > 0;
+ }
+
+ uint32_t GetHashIndex(uint32_t bucket_idx) const {
+ uint32_t result = UINT32_MAX;
+ if (m_hash_indexes && bucket_idx < m_header.bucket_count)
+ memcpy(&result, m_hash_indexes + bucket_idx, sizeof(uint32_t));
+ return result;
+ }
+
+ uint32_t GetHashValue(uint32_t hash_idx) const {
+ uint32_t result = UINT32_MAX;
+ if (m_hash_values && hash_idx < m_header.hashes_count)
+ memcpy(&result, m_hash_values + hash_idx, sizeof(uint32_t));
+ return result;
+ }
+
+ uint32_t GetHashDataOffset(uint32_t hash_idx) const {
+ uint32_t result = UINT32_MAX;
+ if (m_hash_offsets && hash_idx < m_header.hashes_count)
+ memcpy(&result, m_hash_offsets + hash_idx, sizeof(uint32_t));
+ return result;
+ }
+
+ bool Find(llvm::StringRef name, Pair &pair) const {
+ if (name.empty())
+ return false;
+
+ if (IsValid()) {
+ const uint32_t bucket_count = m_header.bucket_count;
+ const uint32_t hash_count = m_header.hashes_count;
+ const uint32_t hash_value =
+ MappedHash::HashString(m_header.hash_function, name);
+ const uint32_t bucket_idx = hash_value % bucket_count;
+ uint32_t hash_idx = GetHashIndex(bucket_idx);
+ if (hash_idx < hash_count) {
+ for (; hash_idx < hash_count; ++hash_idx) {
+ const uint32_t curr_hash_value = GetHashValue(hash_idx);
+ if (curr_hash_value == hash_value) {
+ lldb::offset_t hash_data_offset = GetHashDataOffset(hash_idx);
+ while (hash_data_offset != UINT32_MAX) {
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
+ Result hash_result =
+ GetHashDataForName(name, &hash_data_offset, pair);
+ // Check the result of getting our hash data
+ switch (hash_result) {
+ case eResultKeyMatch:
+ return true;
+
+ case eResultKeyMismatch:
+ if (prev_hash_data_offset == hash_data_offset)
+ return false;
+ break;
+
+ case eResultEndOfHashData:
+ // The last HashData for this key has been reached, stop
+ // searching
+ return false;
+ case eResultError:
+ // Status parsing the hash data, abort
+ return false;
+ }
+ }
+ }
+ if ((curr_hash_value % bucket_count) != bucket_idx)
+ break;
+ }
+ }
+ }
+ return false;
+ }
+
+ // This method must be implemented in any subclasses. The KeyType is user
+ // specified and must somehow result in a string value. For example, the
+ // KeyType might be a string offset in a string table and subclasses can
+ // store their string table as a member of the subclass and return a valie
+ // "const char *" given a "key". The value could also be a C string
+ // pointer, in which case just returning "key" will suffice.
+ virtual const char *GetStringForKeyType(KeyType key) const = 0;
+
+ virtual bool ReadHashData(uint32_t hash_data_offset,
+ HashData &hash_data) const = 0;
+
+ // This method must be implemented in any subclasses and it must try to
+ // read one "Pair" at the offset pointed to by the "hash_data_offset_ptr"
+ // parameter. This offset should be updated as bytes are consumed and a
+ // value "Result" enum should be returned. If the "name" matches the full
+ // name for the "pair.key" (which must be filled in by this call), then the
+ // HashData in the pair ("pair.value") should be extracted and filled in
+ // and "eResultKeyMatch" should be returned. If "name" doesn't match this
+ // string for the key, then "eResultKeyMismatch" should be returned and all
+ // data for the current HashData must be consumed or skipped and the
+ // "hash_data_offset_ptr" offset needs to be updated to point to the next
+ // HashData. If the end of the HashData objects for a given hash value have
+ // been reached, then "eResultEndOfHashData" should be returned. If
+ // anything else goes wrong during parsing, return "eResultError" and the
+ // corresponding "Find()" function will be canceled and return false.
+ virtual Result GetHashDataForName(llvm::StringRef name,
+ lldb::offset_t *hash_data_offset_ptr,
+ Pair &pair) const = 0;
+
+ const HeaderType &GetHeader() { return m_header; }
+
+ void ForEach(
+ std::function<bool(const HashData &hash_data)> const &callback) const {
+ const size_t num_hash_offsets = m_header.hashes_count;
+ for (size_t i = 0; i < num_hash_offsets; ++i) {
+ uint32_t hash_data_offset = GetHashDataOffset(i);
+ if (hash_data_offset != UINT32_MAX) {
+ HashData hash_data;
+ if (ReadHashData(hash_data_offset, hash_data)) {
+ // If the callback returns false, then we are done and should stop
+ if (callback(hash_data) == false)
+ return;
+ }
+ }
+ }
+ }
+
+ protected:
+ // Implementation agnostic information
+ HeaderType m_header;
+ const uint32_t *m_hash_indexes;
+ const uint32_t *m_hash_values;
+ const uint32_t *m_hash_offsets;
+ };
+};
+
+#endif // liblldb_MappedHash_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Module.h b/contrib/llvm-project/lldb/include/lldb/Core/Module.h
new file mode 100644
index 000000000000..89b731427e3f
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Module.h
@@ -0,0 +1,1056 @@
+//===-- Module.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_Module_h_
+#define liblldb_Module_h_
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContextScope.h"
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Target/PathMappingList.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/UUID.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Chrono.h"
+
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+class CompilerDeclContext;
+class Function;
+class Log;
+class ObjectFile;
+class RegularExpression;
+class SectionList;
+class Stream;
+class Symbol;
+class SymbolContext;
+class SymbolContextList;
+class SymbolFile;
+class Symtab;
+class Target;
+class TypeList;
+class TypeMap;
+class VariableList;
+
+/// \class Module Module.h "lldb/Core/Module.h"
+/// A class that describes an executable image and its associated
+/// object and symbol files.
+///
+/// The module is designed to be able to select a single slice of an
+/// executable image as it would appear on disk and during program execution.
+///
+/// Modules control when and if information is parsed according to which
+/// 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 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>,
+ public SymbolContextScope {
+public:
+ // Static functions that can track the lifetime of module objects. This is
+ // handy because we might have Module objects that are in shared pointers
+ // that aren't in the global module list (from ModuleList). If this is the
+ // case we need to know about it. The modules in the global list maintained
+ // by these functions can be viewed using the "target modules list" command
+ // using the "--global" (-g for short).
+ static size_t GetNumberAllocatedModules();
+
+ static Module *GetAllocatedModuleAtIndex(size_t idx);
+
+ static std::recursive_mutex &GetAllocationModuleCollectionMutex();
+
+ /// Construct with file specification and architecture.
+ ///
+ /// Clients that wish to share modules with other targets should use
+ /// ModuleList::GetSharedModule().
+ ///
+ /// \param[in] file_spec
+ /// The file specification for the on disk representation of
+ /// this executable image.
+ ///
+ /// \param[in] arch
+ /// The architecture to set as the current architecture in
+ /// this module.
+ ///
+ /// \param[in] object_name
+ /// The name of an object in a module used to extract a module
+ /// within a module (.a files and modules that contain multiple
+ /// architectures).
+ ///
+ /// \param[in] object_offset
+ /// The offset within an existing module used to extract a
+ /// module within a module (.a files and modules that contain
+ /// multiple architectures).
+ Module(
+ const FileSpec &file_spec, const ArchSpec &arch,
+ const ConstString *object_name = nullptr,
+ lldb::offset_t object_offset = 0,
+ const llvm::sys::TimePoint<> &object_mod_time = llvm::sys::TimePoint<>());
+
+ Module(const ModuleSpec &module_spec);
+
+ template <typename ObjFilePlugin, typename... Args>
+ static lldb::ModuleSP CreateModuleFromObjectFile(Args &&... args) {
+ // Must create a module and place it into a shared pointer before we can
+ // create an object file since it has a std::weak_ptr back to the module,
+ // so we need to control the creation carefully in this static function
+ lldb::ModuleSP module_sp(new Module());
+ module_sp->m_objfile_sp =
+ std::make_shared<ObjFilePlugin>(module_sp, std::forward<Args>(args)...);
+ module_sp->m_did_load_objfile.store(true, std::memory_order_relaxed);
+
+ // Once we get the object file, set module ArchSpec to the one we get from
+ // the object file. If the object file does not have an architecture, we
+ // consider the creation a failure.
+ ArchSpec arch = module_sp->m_objfile_sp->GetArchitecture();
+ if (!arch)
+ return nullptr;
+ module_sp->m_arch = arch;
+
+ // Also copy the object file's FileSpec.
+ module_sp->m_file = module_sp->m_objfile_sp->GetFileSpec();
+ return module_sp;
+ }
+
+ /// Destructor.
+ ~Module() override;
+
+ bool MatchesModuleSpec(const ModuleSpec &module_ref);
+
+ /// Set the load address for all sections in a module to be the file address
+ /// plus \a slide.
+ ///
+ /// Many times a module will be loaded in a target with a constant offset
+ /// applied to all top level sections. This function can set the load
+ /// address for all top level sections to be the section file address +
+ /// offset.
+ ///
+ /// \param[in] target
+ /// The target in which to apply the section load addresses.
+ ///
+ /// \param[in] value
+ /// if \a value_is_offset is true, then value is the offset to
+ /// apply to all file addresses for all top level sections in
+ /// the object file as each section load address is being set.
+ /// If \a value_is_offset is false, then "value" is the new
+ /// absolute base address for the image.
+ ///
+ /// \param[in] value_is_offset
+ /// If \b true, then \a value is an offset to apply to each
+ /// file address of each top level section.
+ /// If \b false, then \a value is the image base address that
+ /// will be used to rigidly slide all loadable sections.
+ ///
+ /// \param[out] changed
+ /// If any section load addresses were changed in \a target,
+ /// then \a changed will be set to \b true. Else \a changed
+ /// will be set to false. This allows this function to be
+ /// called multiple times on the same module for the same
+ /// target. If the module hasn't moved, then \a changed will
+ /// be false and no module updated notification will need to
+ /// be sent out.
+ ///
+ /// \return
+ /// /b True if any sections were successfully loaded in \a target,
+ /// /b false otherwise.
+ bool SetLoadAddress(Target &target, lldb::addr_t value, bool value_is_offset,
+ bool &changed);
+
+ /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
+ ///
+ /// \see SymbolContextScope
+ void CalculateSymbolContext(SymbolContext *sc) override;
+
+ lldb::ModuleSP CalculateSymbolContextModule() override;
+
+ void
+ GetDescription(Stream *s,
+ lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);
+
+ /// Get the module path and object name.
+ ///
+ /// Modules can refer to object files. In this case the specification is
+ /// simple and would return the path to the file:
+ ///
+ /// "/usr/lib/foo.dylib"
+ ///
+ /// Modules can be .o files inside of a BSD archive (.a file). In this case,
+ /// the object specification will look like:
+ ///
+ /// "/usr/lib/foo.a(bar.o)"
+ ///
+ /// There are many places where logging wants to log this fully qualified
+ /// specification, so we centralize this functionality here.
+ ///
+ /// \return
+ /// The object path + object name if there is one.
+ std::string GetSpecificationDescription() const;
+
+ /// Dump a description of this object to a Stream.
+ ///
+ /// Dump a description of the contents of this object to the supplied stream
+ /// \a s. The dumped content will be only what has been loaded or parsed up
+ /// to this point at which this function is called, so this is a good way to
+ /// see what has been parsed in a module.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ void Dump(Stream *s);
+
+ /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
+ ///
+ /// \see SymbolContextScope
+ void DumpSymbolContext(Stream *s) override;
+
+ /// Find a symbol in the object file's symbol table.
+ ///
+ /// \param[in] name
+ /// The name of the symbol that we are looking for.
+ ///
+ /// \param[in] symbol_type
+ /// If set to eSymbolTypeAny, find a symbol of any type that
+ /// has a name that matches \a name. If set to any other valid
+ /// SymbolType enumeration value, then search only for
+ /// symbols that match \a symbol_type.
+ ///
+ /// \return
+ /// Returns a valid symbol pointer if a symbol was found,
+ /// nullptr otherwise.
+ const Symbol *FindFirstSymbolWithNameAndType(
+ ConstString name,
+ lldb::SymbolType symbol_type = lldb::eSymbolTypeAny);
+
+ void FindSymbolsWithNameAndType(ConstString name,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
+
+ void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
+
+ /// Find a function symbols in the object file's symbol table.
+ ///
+ /// \param[in] name
+ /// The name of the symbol that we are looking for.
+ ///
+ /// \param[in] name_type_mask
+ /// A mask that has one or more bitwise OR'ed values from the
+ /// lldb::FunctionNameType enumeration type that indicate what
+ /// kind of names we are looking for.
+ ///
+ /// \param[out] sc_list
+ /// A list to append any matching symbol contexts to.
+ void FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
+ SymbolContextList &sc_list);
+
+ /// Find compile units by partial or full path.
+ ///
+ /// Finds all compile units that match \a path in all of the modules and
+ /// returns the results in \a sc_list.
+ ///
+ /// \param[in] path
+ /// The name of the function we are looking for.
+ ///
+ /// \param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list);
+
+ /// Find functions by name.
+ ///
+ /// If the function is an inlined function, it will have a block,
+ /// representing the inlined function, and the function will be the
+ /// containing function. If it is not inlined, then the block will be NULL.
+ ///
+ /// \param[in] name
+ /// The name of the compile unit we are looking for.
+ ///
+ /// \param[in] namespace_decl
+ /// If valid, a namespace to search in.
+ ///
+ /// \param[in] name_type_mask
+ /// A bit mask of bits that indicate what kind of names should
+ /// be used when doing the lookup. Bits include fully qualified
+ /// names, base names, C++ methods, or ObjC selectors.
+ /// See FunctionNameType for more details.
+ ///
+ /// \param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ 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.
+ ///
+ /// If the function is an inlined function, it will have a block,
+ /// representing the inlined function, and the function will be the
+ /// containing function. If it is not inlined, then the block will be NULL.
+ ///
+ /// \param[in] regex
+ /// A regular expression to use when matching the name.
+ ///
+ /// \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.
+ void FindFunctions(const RegularExpression &regex, bool symbols_ok,
+ bool inlines_ok, SymbolContextList &sc_list);
+
+ /// Find addresses by file/line
+ ///
+ /// \param[in] target_sp
+ /// The target the addresses are desired for.
+ ///
+ /// \param[in] file
+ /// Source file to locate.
+ ///
+ /// \param[in] line
+ /// Source line to locate.
+ ///
+ /// \param[in] function
+ /// Optional filter function. Addresses within this function will be
+ /// added to the 'local' list. All others will be added to the 'extern'
+ /// list.
+ ///
+ /// \param[out] output_local
+ /// All matching addresses within 'function'
+ ///
+ /// \param[out] output_extern
+ /// All matching addresses not within 'function'
+ void FindAddressesForLine(const lldb::TargetSP target_sp,
+ const FileSpec &file, uint32_t line,
+ Function *function,
+ std::vector<Address> &output_local,
+ std::vector<Address> &output_extern);
+
+ /// Find global and static variables by name.
+ ///
+ /// \param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// \param[in] parent_decl_ctx
+ /// If valid, a decl context that results must exist within
+ ///
+ /// \param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// \param[in] variable_list
+ /// A list of variables that gets the matches appended to.
+ ///
+ void FindGlobalVariables(ConstString name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, VariableList &variable_list);
+
+ /// Find global and static variables by regular expression.
+ ///
+ /// \param[in] regex
+ /// A regular expression to use when matching the name.
+ ///
+ /// \param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// \param[in] variable_list
+ /// A list of variables that gets the matches appended to.
+ ///
+ void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
+ VariableList &variable_list);
+
+ /// Find types by name.
+ ///
+ /// 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
+ /// as long as the base typename matches and as long as any immediate
+ /// containing namespaces/class scopes that are specified match. So to
+ /// search for a type "d" in "b::c", the name "b::c::d" can be specified and
+ /// it will match any class/namespace "b" which contains a class/namespace
+ /// "c" which contains type "d". We do this to allow users to not always
+ /// have to specify complete scoping on all expressions, but it also allows
+ /// for exact matching when required.
+ ///
+ /// \param[in] type_name
+ /// The name of the type we are looking for that is a fully
+ /// or partially qualified type name.
+ ///
+ /// \param[in] exact_match
+ /// If \b true, \a type_name is fully qualified and must match
+ /// exactly. If \b false, \a type_name is a partially qualified
+ /// name where the leading namespaces or classes can be
+ /// omitted to make finding types that a user may type
+ /// easier.
+ ///
+ /// \param[out] type_list
+ /// A type list gets populated with any matches.
+ ///
+ 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);
+
+ /// Find types by name that are in a namespace. This function is used by the
+ /// expression parser when searches need to happen in an exact namespace
+ /// scope.
+ ///
+ /// \param[in] type_name
+ /// The name of a type within a namespace that should not include
+ /// any qualifying namespaces (just a type basename).
+ ///
+ /// \param[in] namespace_decl
+ /// The namespace declaration that this type must exist in.
+ ///
+ /// \param[out] type_list
+ /// A type list gets populated with any matches.
+ ///
+ void FindTypesInNamespace(ConstString type_name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, TypeList &type_list);
+
+ /// Get const accessor for the module architecture.
+ ///
+ /// \return
+ /// A const reference to the architecture object.
+ const ArchSpec &GetArchitecture() const;
+
+ /// Get const accessor for the module file specification.
+ ///
+ /// This function returns the file for the module on the host system that is
+ /// running LLDB. This can differ from the path on the platform since we
+ /// might be doing remote debugging.
+ ///
+ /// \return
+ /// A const reference to the file specification object.
+ const FileSpec &GetFileSpec() const { return m_file; }
+
+ /// Get accessor for the module platform file specification.
+ ///
+ /// Platform file refers to the path of the module as it is known on the
+ /// remote system on which it is being debugged. For local debugging this is
+ /// always the same as Module::GetFileSpec(). But remote debugging might
+ /// mention a file "/usr/lib/liba.dylib" which might be locally downloaded
+ /// and cached. In this case the platform file could be something like:
+ /// "/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib" The
+ /// file could also be cached in a local developer kit directory.
+ ///
+ /// \return
+ /// A const reference to the file specification object.
+ const FileSpec &GetPlatformFileSpec() const {
+ if (m_platform_file)
+ return m_platform_file;
+ return m_file;
+ }
+
+ void SetPlatformFileSpec(const FileSpec &file) { m_platform_file = file; }
+
+ const FileSpec &GetRemoteInstallFileSpec() const {
+ return m_remote_install_file;
+ }
+
+ void SetRemoteInstallFileSpec(const FileSpec &file) {
+ m_remote_install_file = file;
+ }
+
+ const FileSpec &GetSymbolFileFileSpec() const { return m_symfile_spec; }
+
+ void PreloadSymbols();
+
+ void SetSymbolFileFileSpec(const FileSpec &file);
+
+ const llvm::sys::TimePoint<> &GetModificationTime() const {
+ return m_mod_time;
+ }
+
+ const llvm::sys::TimePoint<> &GetObjectModificationTime() const {
+ return m_object_mod_time;
+ }
+
+ void SetObjectModificationTime(const llvm::sys::TimePoint<> &mod_time) {
+ m_mod_time = mod_time;
+ }
+
+ /// Tells whether this module is capable of being the main executable for a
+ /// process.
+ ///
+ /// \return
+ /// \b true if it is, \b false otherwise.
+ bool IsExecutable();
+
+ /// Tells whether this module has been loaded in the target passed in. This
+ /// call doesn't distinguish between whether the module is loaded by the
+ /// dynamic loader, or by a "target module add" type call.
+ ///
+ /// \param[in] target
+ /// The target to check whether this is loaded in.
+ ///
+ /// \return
+ /// \b true if it is, \b false otherwise.
+ bool IsLoadedInTarget(Target *target);
+
+ bool LoadScriptingResourceInTarget(Target *target, Status &error,
+ Stream *feedback_stream = nullptr);
+
+ /// Get the number of compile units for this module.
+ ///
+ /// \return
+ /// The number of compile units that the symbol vendor plug-in
+ /// finds.
+ size_t GetNumCompileUnits();
+
+ lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx);
+
+ ConstString GetObjectName() const;
+
+ uint64_t GetObjectOffset() const { return m_object_offset; }
+
+ /// Get the object file representation for the current architecture.
+ ///
+ /// If the object file has not been located or parsed yet, this function
+ /// will find the best ObjectFile plug-in that can parse Module::m_file.
+ ///
+ /// \return
+ /// If Module::m_file does not exist, or no plug-in was found
+ /// that can parse the file, or the object file doesn't contain
+ /// the current architecture in Module::m_arch, nullptr will be
+ /// returned, else a valid object file interface will be
+ /// returned. The returned pointer is owned by this object and
+ /// remains valid as long as the object is around.
+ virtual ObjectFile *GetObjectFile();
+
+ /// Get the unified section list for the module. This is the section list
+ /// created by the module's object file and any debug info and symbol files
+ /// created by the symbol vendor.
+ ///
+ /// If the symbol vendor has not been loaded yet, this function will return
+ /// the section list for the object file.
+ ///
+ /// \return
+ /// Unified module section list.
+ virtual SectionList *GetSectionList();
+
+ /// Notify the module that the file addresses for the Sections have been
+ /// updated.
+ ///
+ /// If the Section file addresses for a module are updated, this method
+ /// should be called. Any parts of the module, object file, or symbol file
+ /// that has cached those file addresses must invalidate or update its
+ /// cache.
+ virtual void SectionFileAddressesChanged();
+
+ /// Returns a reference to the UnwindTable for this Module
+ ///
+ /// The UnwindTable contains FuncUnwinders objects for any function in this
+ /// Module. If a FuncUnwinders object hasn't been created yet (i.e. the
+ /// function has yet to be unwound in a stack walk), it will be created when
+ /// requested. Specifically, we do not create FuncUnwinders objects for
+ /// functions until they are needed.
+ ///
+ /// \return
+ /// Returns the unwind table for this module. If this object has no
+ /// associated object file, an empty UnwindTable is returned.
+ UnwindTable &GetUnwindTable();
+
+ llvm::VersionTuple GetVersion();
+
+ /// Load an object file from memory.
+ ///
+ /// If available, the size of the object file in memory may be passed to
+ /// avoid additional round trips to process memory. If the size is not
+ /// provided, a default value is used. This value should be large enough to
+ /// enable the ObjectFile plugins to read the header of the object file
+ /// without going back to the process.
+ ///
+ /// \return
+ /// The object file loaded from memory or nullptr, if the operation
+ /// failed (see the `error` for more information in that case).
+ ObjectFile *GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr, Status &error,
+ size_t size_to_read = 512);
+
+ /// Get the module's symbol file
+ ///
+ /// 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.
+ ///
+ /// If the executable image file doesn't not have a UUID value built into
+ /// the file format, an MD5 checksum of the entire file, or slice of the
+ /// file for the current architecture should be used.
+ ///
+ /// \return
+ /// A const pointer to the internal copy of the UUID value in
+ /// this module if this module has a valid UUID value, NULL
+ /// otherwise.
+ const lldb_private::UUID &GetUUID();
+
+ /// A debugging function that will cause everything in a module to
+ /// be parsed.
+ ///
+ /// All compile units will be parsed, along with all globals and static
+ /// variables and all functions for those compile units. All types, scopes,
+ /// local variables, static variables, global variables, and line tables
+ /// will be parsed. This can be used prior to dumping a module to see a
+ /// complete list of the resulting debug information that gets parsed, or as
+ /// a debug function to ensure that the module can consume all of the debug
+ /// data the symbol vendor provides.
+ void ParseAllDebugSymbols();
+
+ bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr);
+
+ /// Resolve the symbol context for the given address.
+ ///
+ /// Tries to resolve the matching symbol context based on a lookup from the
+ /// current symbol vendor. If the lazy lookup fails, an attempt is made to
+ /// parse the eh_frame section to handle stripped symbols. If this fails,
+ /// an attempt is made to resolve the symbol to the previous address to
+ /// handle the case of a function with a tail call.
+ ///
+ /// Use properties of the modified SymbolContext to inspect any resolved
+ /// target, module, compilation unit, symbol, function, function block or
+ /// line entry. Use the return value to determine which of these properties
+ /// have been modified.
+ ///
+ /// \param[in] so_addr
+ /// A load address to resolve.
+ ///
+ /// \param[in] resolve_scope
+ /// The scope that should be resolved (see SymbolContext::Scope).
+ /// A combination of flags from the enumeration SymbolContextItem
+ /// requesting a resolution depth. Note that the flags that are
+ /// actually resolved may be a superset of the requested flags.
+ /// For instance, eSymbolContextSymbol requires resolution of
+ /// eSymbolContextModule, and eSymbolContextFunction requires
+ /// eSymbolContextSymbol.
+ ///
+ /// \param[out] sc
+ /// The SymbolContext that is modified based on symbol resolution.
+ ///
+ /// \param[in] resolve_tail_call_address
+ /// Determines if so_addr should resolve to a symbol in the case
+ /// of a function whose last instruction is a call. In this case,
+ /// the PC can be one past the address range of the function.
+ ///
+ /// \return
+ /// The scope that has been resolved (see SymbolContext::Scope).
+ ///
+ /// \see SymbolContext::Scope
+ uint32_t ResolveSymbolContextForAddress(
+ const Address &so_addr, lldb::SymbolContextItem resolve_scope,
+ SymbolContext &sc, bool resolve_tail_call_address = false);
+
+ /// Resolve items in the symbol context for a given file and line.
+ ///
+ /// Tries to resolve \a file_path and \a line to a list of matching symbol
+ /// contexts.
+ ///
+ /// The line table entries contains addresses that can be used to further
+ /// resolve the values in each match: the function, block, symbol. Care
+ /// should be taken to minimize the amount of information that is requested
+ /// to only what is needed -- typically the module, compile unit, line table
+ /// and line table entry are sufficient.
+ ///
+ /// \param[in] file_path
+ /// A path to a source file to match. If \a file_path does not
+ /// specify a directory, then this query will match all files
+ /// whose base filename matches. If \a file_path does specify
+ /// a directory, the fullpath to the file must match.
+ ///
+ /// \param[in] line
+ /// The source line to match, or zero if just the compile unit
+ /// should be resolved.
+ ///
+ /// \param[in] check_inlines
+ /// Check for inline file and line number matches. This option
+ /// should be used sparingly as it will cause all line tables
+ /// for every compile unit to be parsed and searched for
+ /// matching inline file entries.
+ ///
+ /// \param[in] resolve_scope
+ /// The scope that should be resolved (see
+ /// SymbolContext::Scope).
+ ///
+ /// \param[out] sc_list
+ /// A symbol context list that gets matching symbols contexts
+ /// appended to.
+ ///
+ /// \return
+ /// The number of matches that were added to \a sc_list.
+ ///
+ /// \see SymbolContext::Scope
+ uint32_t ResolveSymbolContextForFilePath(
+ const char *file_path, uint32_t line, bool check_inlines,
+ lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list);
+
+ /// Resolve items in the symbol context for a given file and line.
+ ///
+ /// Tries to resolve \a file_spec and \a line to a list of matching symbol
+ /// contexts.
+ ///
+ /// The line table entries contains addresses that can be used to further
+ /// resolve the values in each match: the function, block, symbol. Care
+ /// should be taken to minimize the amount of information that is requested
+ /// to only what is needed -- typically the module, compile unit, line table
+ /// and line table entry are sufficient.
+ ///
+ /// \param[in] file_spec
+ /// A file spec to a source file to match. If \a file_path does
+ /// not specify a directory, then this query will match all
+ /// files whose base filename matches. If \a file_path does
+ /// specify a directory, the fullpath to the file must match.
+ ///
+ /// \param[in] line
+ /// The source line to match, or zero if just the compile unit
+ /// should be resolved.
+ ///
+ /// \param[in] check_inlines
+ /// Check for inline file and line number matches. This option
+ /// should be used sparingly as it will cause all line tables
+ /// for every compile unit to be parsed and searched for
+ /// matching inline file entries.
+ ///
+ /// \param[in] resolve_scope
+ /// The scope that should be resolved (see
+ /// SymbolContext::Scope).
+ ///
+ /// \param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// \return
+ /// A integer that contains SymbolContext::Scope bits set for
+ /// each item that was successfully resolved.
+ ///
+ /// \see SymbolContext::Scope
+ uint32_t ResolveSymbolContextsForFileSpec(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list);
+
+ void SetFileSpecAndObjectName(const FileSpec &file,
+ ConstString object_name);
+
+ bool GetIsDynamicLinkEditor();
+
+ 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
+ // architecture, path and object name (if any)). This centralizes code so
+ // that everyone doesn't need to format their error and log messages on their
+ // own and keeps the output a bit more consistent.
+ void LogMessage(Log *log, const char *format, ...)
+ __attribute__((format(printf, 3, 4)));
+
+ void LogMessageVerboseBacktrace(Log *log, const char *format, ...)
+ __attribute__((format(printf, 3, 4)));
+
+ void ReportWarning(const char *format, ...)
+ __attribute__((format(printf, 2, 3)));
+
+ void ReportError(const char *format, ...)
+ __attribute__((format(printf, 2, 3)));
+
+ // Only report an error once when the module is first detected to be modified
+ // so we don't spam the console with many messages.
+ void ReportErrorIfModifyDetected(const char *format, ...)
+ __attribute__((format(printf, 2, 3)));
+
+ // Return true if the file backing this module has changed since the module
+ // was originally created since we saved the initial file modification time
+ // when the module first gets created.
+ bool FileHasChanged() const;
+
+ // SymbolFile and ObjectFile member objects should lock the
+ // module mutex to avoid deadlocks.
+ std::recursive_mutex &GetMutex() const { return m_mutex; }
+
+ PathMappingList &GetSourceMappingList() { return m_source_mappings; }
+
+ const PathMappingList &GetSourceMappingList() const {
+ return m_source_mappings;
+ }
+
+ /// Finds a source file given a file spec using the module source path
+ /// remappings (if any).
+ ///
+ /// Tries to resolve \a orig_spec by checking the module source path
+ /// remappings. It makes sure the file exists, so this call can be expensive
+ /// if the remappings are on a network file system, so use this function
+ /// sparingly (not in a tight debug info parsing loop).
+ ///
+ /// \param[in] orig_spec
+ /// The original source file path to try and remap.
+ ///
+ /// \param[out] new_spec
+ /// The newly remapped filespec that is guaranteed to exist.
+ ///
+ /// \return
+ /// /b true if \a orig_spec was successfully located and
+ /// \a new_spec is filled in with an existing file spec,
+ /// \b false otherwise.
+ bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
+
+ /// Remaps a source file given \a path into \a new_path.
+ ///
+ /// Remaps \a path if any source remappings match. This function does NOT
+ /// stat the file system so it can be used in tight loops where debug info
+ /// is being parsed.
+ ///
+ /// \param[in] path
+ /// The original source file path to try and remap.
+ ///
+ /// \param[out] new_path
+ /// The newly remapped filespec that is may or may not exist.
+ ///
+ /// \return
+ /// /b true if \a path was successfully located and \a new_path
+ /// is filled in with a new source path, \b false otherwise.
+ 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. 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
+ /// the symbol or objects files. Lanaguage is included in case we need to
+ /// filter results by language at a later date. The "m_name_type_mask"
+ /// member variable tells us what kinds of names we are looking for and can
+ /// help us prune out unwanted results.
+ ///
+ /// Function lookups are done in Module.cpp, ModuleList.cpp and in
+ /// BreakpointResolverName.cpp and they all now use this class to do lookups
+ /// correctly.
+ class LookupInfo {
+ public:
+ LookupInfo()
+ : m_name(), m_lookup_name(), m_language(lldb::eLanguageTypeUnknown),
+ m_name_type_mask(lldb::eFunctionNameTypeNone),
+ m_match_name_after_lookup(false) {}
+
+ LookupInfo(ConstString name, lldb::FunctionNameType name_type_mask,
+ lldb::LanguageType language);
+
+ ConstString GetName() const { return m_name; }
+
+ void SetName(ConstString name) { m_name = name; }
+
+ ConstString GetLookupName() const { return m_lookup_name; }
+
+ void SetLookupName(ConstString name) { m_lookup_name = name; }
+
+ lldb::FunctionNameType GetNameTypeMask() const { return m_name_type_mask; }
+
+ void SetNameTypeMask(lldb::FunctionNameType mask) {
+ m_name_type_mask = mask;
+ }
+
+ void Prune(SymbolContextList &sc_list, size_t start_idx) const;
+
+ protected:
+ /// What the user originally typed
+ ConstString m_name;
+
+ /// The actual name will lookup when calling in the object or symbol file
+ ConstString m_lookup_name;
+
+ /// Limit matches to only be for this language
+ lldb::LanguageType m_language;
+
+ /// One or more bits from lldb::FunctionNameType that indicate what kind of
+ /// names we are looking for
+ lldb::FunctionNameType m_name_type_mask;
+
+ ///< If \b true, then demangled names that match will need to contain
+ ///< "m_name" in order to be considered a match
+ bool m_match_name_after_lookup;
+ };
+
+protected:
+ // Member Variables
+ mutable std::recursive_mutex m_mutex; ///< A mutex to keep this object happy
+ ///in multi-threaded environments.
+
+ /// The modification time for this module when it was created.
+ llvm::sys::TimePoint<> m_mod_time;
+
+ ArchSpec m_arch; ///< The architecture for this module.
+ UUID m_uuid; ///< Each module is assumed to have a unique identifier to help
+ ///match it up to debug symbols.
+ FileSpec m_file; ///< The file representation on disk for this module (if
+ ///there is one).
+ FileSpec m_platform_file; ///< The path to the module on the platform on which
+ ///it is being debugged
+ FileSpec m_remote_install_file; ///< If set when debugging on remote
+ ///platforms, this module will be installed at
+ ///this location
+ FileSpec m_symfile_spec; ///< If this path is valid, then this is the file
+ ///that _will_ be used as the symbol file for this
+ ///module
+ ConstString m_object_name; ///< The name an object within this module that is
+ ///selected, or empty of the module is represented
+ ///by \a m_file.
+ uint64_t m_object_offset;
+ llvm::sys::TimePoint<> m_object_mod_time;
+ lldb::ObjectFileSP m_objfile_sp; ///< A shared pointer to the object file
+ ///parser for this module as it may or may
+ ///not be shared with the SymbolFile
+ llvm::Optional<UnwindTable> m_unwind_table; ///< Table of FuncUnwinders
+ /// objects created for this
+ /// Module's functions
+ lldb::SymbolVendorUP
+ m_symfile_up; ///< A pointer to the symbol vendor for this module.
+ std::vector<lldb::SymbolVendorUP>
+ m_old_symfiles; ///< If anyone calls Module::SetSymbolFileFileSpec() and
+ ///changes the symbol file,
+ ///< we need to keep all old symbol files around in case anyone has type
+ ///references to them
+ TypeSystemMap m_type_system_map; ///< A map of any type systems associated
+ ///with this module
+ PathMappingList m_source_mappings; ///< Module specific source remappings for
+ ///when you have debug info for a module
+ ///that doesn't match where the sources
+ ///currently are
+ lldb::SectionListUP m_sections_up; ///< Unified section list for module that
+ /// is used by the ObjectFile and and
+ /// ObjectFile instances for the debug info
+
+ std::atomic<bool> m_did_load_objfile{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
+ /// was initially opened.
+
+ /// Resolve a file or load virtual address.
+ ///
+ /// Tries to resolve \a vm_addr as a file address (if \a
+ /// vm_addr_is_file_addr is true) or as a load address if \a
+ /// vm_addr_is_file_addr is false) in the symbol vendor. \a resolve_scope
+ /// indicates what clients wish to resolve and can be used to limit the
+ /// scope of what is parsed.
+ ///
+ /// \param[in] vm_addr
+ /// The load virtual address to resolve.
+ ///
+ /// \param[in] vm_addr_is_file_addr
+ /// If \b true, \a vm_addr is a file address, else \a vm_addr
+ /// if a load address.
+ ///
+ /// \param[in] resolve_scope
+ /// The scope that should be resolved (see
+ /// SymbolContext::Scope).
+ ///
+ /// \param[out] so_addr
+ /// The section offset based address that got resolved if
+ /// any bits are returned.
+ ///
+ /// \param[out] sc
+ // The symbol context that has objects filled in. Each bit
+ /// in the \a resolve_scope pertains to a member in the \a sc.
+ ///
+ /// \return
+ /// A integer that contains SymbolContext::Scope bits set for
+ /// each item that was successfully resolved.
+ ///
+ /// \see SymbolContext::Scope
+ uint32_t ResolveSymbolContextForAddress(lldb::addr_t vm_addr,
+ bool vm_addr_is_file_addr,
+ lldb::SymbolContextItem resolve_scope,
+ Address &so_addr, SymbolContext &sc);
+
+ void SymbolIndicesToSymbolContextList(Symtab *symtab,
+ std::vector<uint32_t> &symbol_indexes,
+ SymbolContextList &sc_list);
+
+ bool SetArchitecture(const ArchSpec &new_arch);
+
+ void SetUUID(const lldb_private::UUID &uuid);
+
+ SectionList *GetUnifiedSectionList();
+
+ friend class ModuleList;
+ friend class ObjectFile;
+ friend class SymbolFile;
+
+private:
+ Module(); // Only used internally by CreateJITModule ()
+
+ void FindTypes_Impl(
+ ConstString name, const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ TypeMap &types);
+
+ DISALLOW_COPY_AND_ASSIGN(Module);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Module_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleChild.h
new file mode 100644
index 000000000000..8a81c1a6cf8a
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleChild.h
@@ -0,0 +1,62 @@
+//===-- ModuleChild.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_ModuleChild_h_
+#define liblldb_ModuleChild_h_
+
+#include "lldb/lldb-forward.h"
+
+namespace lldb_private {
+
+/// \class ModuleChild ModuleChild.h "lldb/Core/ModuleChild.h"
+/// A mix in class that contains a pointer back to the module
+/// that owns the object which inherits from it.
+class ModuleChild {
+public:
+ /// Construct with owning module.
+ ///
+ /// \param[in] module
+ /// The module that owns the object that inherits from this
+ /// class.
+ ModuleChild(const lldb::ModuleSP &module_sp);
+
+ /// Destructor.
+ ~ModuleChild();
+
+ /// Assignment operator.
+ ///
+ /// \param[in] rhs
+ /// A const ModuleChild class reference to copy.
+ ///
+ /// \return
+ /// A const reference to this object.
+ const ModuleChild &operator=(const ModuleChild &rhs);
+
+ /// Get const accessor for the module pointer.
+ ///
+ /// \return
+ /// A const pointer to the module that owns the object that
+ /// inherits from this class.
+ lldb::ModuleSP GetModule() const;
+
+ /// Set accessor for the module pointer.
+ ///
+ /// \param[in] module
+ /// A new module that owns the object that inherits from this
+ /// class.
+ void SetModule(const lldb::ModuleSP &module_sp);
+
+protected:
+ // Member variables
+ lldb::ModuleWP m_module_wp; ///< The Module that owns the object that inherits
+ ///< from this class.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ModuleChild_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h
new file mode 100644
index 000000000000..e21655551b61
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h
@@ -0,0 +1,519 @@
+//===-- ModuleList.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_ModuleList_h_
+#define liblldb_ModuleList_h_
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Iterable.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/DenseSet.h"
+
+#include <functional>
+#include <list>
+#include <mutex>
+#include <vector>
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class ConstString;
+class FileSpecList;
+class Function;
+class Log;
+class Module;
+class RegularExpression;
+class Stream;
+class SymbolContext;
+class SymbolContextList;
+class SymbolFile;
+class Target;
+class TypeList;
+class UUID;
+class VariableList;
+
+class ModuleListProperties : public Properties {
+public:
+ ModuleListProperties();
+
+ FileSpec GetClangModulesCachePath() const;
+ bool SetClangModulesCachePath(llvm::StringRef path);
+ bool GetEnableExternalLookup() const;
+ bool SetEnableExternalLookup(bool new_value);
+};
+
+/// \class ModuleList ModuleList.h "lldb/Core/ModuleList.h"
+/// A collection class for Module objects.
+///
+/// Modules in the module collection class are stored as reference counted
+/// shared pointers to Module objects.
+class ModuleList {
+public:
+ class Notifier {
+ public:
+ virtual ~Notifier() = default;
+
+ virtual void NotifyModuleAdded(const ModuleList &module_list,
+ const lldb::ModuleSP &module_sp) = 0;
+ virtual void NotifyModuleRemoved(const ModuleList &module_list,
+ const lldb::ModuleSP &module_sp) = 0;
+ virtual void NotifyModuleUpdated(const ModuleList &module_list,
+ const lldb::ModuleSP &old_module_sp,
+ const lldb::ModuleSP &new_module_sp) = 0;
+ virtual void NotifyWillClearList(const ModuleList &module_list) = 0;
+
+ virtual void NotifyModulesRemoved(lldb_private::ModuleList &module_list) = 0;
+ };
+
+ /// Default constructor.
+ ///
+ /// Creates an empty list of Module objects.
+ ModuleList();
+
+ /// Copy Constructor.
+ ///
+ /// Creates a new module list object with a copy of the modules from \a rhs.
+ ///
+ /// \param[in] rhs
+ /// Another module list object.
+ ModuleList(const ModuleList &rhs);
+
+ ModuleList(ModuleList::Notifier *notifier);
+
+ /// Destructor.
+ ~ModuleList();
+
+ /// Assignment operator.
+ ///
+ /// Copies the module list from \a rhs into this list.
+ ///
+ /// \param[in] rhs
+ /// Another module list object.
+ ///
+ /// \return
+ /// A const reference to this object.
+ const ModuleList &operator=(const ModuleList &rhs);
+
+ /// Append a module to the module list.
+ ///
+ /// \param[in] module_sp
+ /// A shared pointer to a module to add to this collection.
+ ///
+ /// \param[in] notify
+ /// If true, and a notifier function is set, the notifier function
+ /// will be called. Defaults to true.
+ ///
+ /// When this ModuleList is the Target's ModuleList, the notifier
+ /// function is Target::ModulesDidLoad -- the call to
+ /// ModulesDidLoad may be deferred when adding multiple Modules
+ /// to the Target, but it must be called at the end,
+ /// before resuming execution.
+ void Append(const lldb::ModuleSP &module_sp, bool notify = true);
+
+ /// Append a module to the module list and remove any equivalent modules.
+ /// Equivalent modules are ones whose file, platform file and architecture
+ /// matches.
+ ///
+ /// Replaces the module to the collection.
+ ///
+ /// \param[in] module_sp
+ /// A shared pointer to a module to replace in this collection.
+ void ReplaceEquivalent(const lldb::ModuleSP &module_sp);
+
+ /// Append a module to the module list, if it is not already there.
+ ///
+ /// \param[in] module_sp
+ ///
+ /// \param[in] notify
+ /// If true, and a notifier function is set, the notifier function
+ /// will be called. Defaults to true.
+ ///
+ /// When this ModuleList is the Target's ModuleList, the notifier
+ /// function is Target::ModulesDidLoad -- the call to
+ /// ModulesDidLoad may be deferred when adding multiple Modules
+ /// to the Target, but it must be called at the end,
+ /// before resuming execution.
+ bool AppendIfNeeded(const lldb::ModuleSP &module_sp, bool notify = true);
+
+ void Append(const ModuleList &module_list);
+
+ bool AppendIfNeeded(const ModuleList &module_list);
+
+ bool ReplaceModule(const lldb::ModuleSP &old_module_sp,
+ const lldb::ModuleSP &new_module_sp);
+
+ /// Clear the object's state.
+ ///
+ /// Clears the list of modules and releases a reference to each module
+ /// object and if the reference count goes to zero, the module will be
+ /// deleted.
+ void Clear();
+
+ /// Clear the object's state.
+ ///
+ /// Clears the list of modules and releases a reference to each module
+ /// object and if the reference count goes to zero, the module will be
+ /// deleted. Also release all memory that might be held by any collection
+ /// classes (like std::vector)
+ void Destroy();
+
+ /// Dump the description of each module contained in this list.
+ ///
+ /// Dump the description of each module contained in this list to the
+ /// supplied stream \a s.
+ ///
+ /// \param[in] s
+ /// The stream to which to dump the object description.
+ ///
+ /// \see Module::Dump(Stream *) const
+ void Dump(Stream *s) const;
+
+ void LogUUIDAndPaths(Log *log, const char *prefix_cstr);
+
+ std::recursive_mutex &GetMutex() const { return m_modules_mutex; }
+
+ size_t GetIndexForModule(const Module *module) const;
+
+ /// Get the module shared pointer for the module at index \a idx.
+ ///
+ /// \param[in] idx
+ /// An index into this module collection.
+ ///
+ /// \return
+ /// A shared pointer to a Module which can contain NULL if
+ /// \a idx is out of range.
+ ///
+ /// \see ModuleList::GetSize()
+ lldb::ModuleSP GetModuleAtIndex(size_t idx) const;
+
+ /// Get the module shared pointer for the module at index \a idx without
+ /// acquiring the ModuleList mutex. This MUST already have been acquired
+ /// with ModuleList::GetMutex and locked for this call to be safe.
+ ///
+ /// \param[in] idx
+ /// An index into this module collection.
+ ///
+ /// \return
+ /// A shared pointer to a Module which can contain NULL if
+ /// \a idx is out of range.
+ ///
+ /// \see ModuleList::GetSize()
+ lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const;
+
+ /// Get the module pointer for the module at index \a idx.
+ ///
+ /// \param[in] idx
+ /// An index into this module collection.
+ ///
+ /// \return
+ /// A pointer to a Module which can by nullptr if \a idx is out
+ /// of range.
+ ///
+ /// \see ModuleList::GetSize()
+ Module *GetModulePointerAtIndex(size_t idx) const;
+
+ /// Get the module pointer for the module at index \a idx without acquiring
+ /// the ModuleList mutex. This MUST already have been acquired with
+ /// ModuleList::GetMutex and locked for this call to be safe.
+ ///
+ /// \param[in] idx
+ /// An index into this module collection.
+ ///
+ /// \return
+ /// A pointer to a Module which can by nullptr if \a idx is out
+ /// of range.
+ ///
+ /// \see ModuleList::GetSize()
+ Module *GetModulePointerAtIndexUnlocked(size_t idx) const;
+
+ /// Find compile units by partial or full path.
+ ///
+ /// Finds all compile units that match \a path in all of the modules and
+ /// returns the results in \a sc_list.
+ ///
+ /// \param[in] path
+ /// The name of the compile unit we are looking for.
+ ///
+ /// \param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const;
+
+ /// \see Module::FindFunctions ()
+ void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask,
+ bool include_symbols, bool include_inlines,
+ SymbolContextList &sc_list) const;
+
+ /// \see Module::FindFunctionSymbols ()
+ void FindFunctionSymbols(ConstString name,
+ lldb::FunctionNameType name_type_mask,
+ SymbolContextList &sc_list);
+
+ /// \see Module::FindFunctions ()
+ void FindFunctions(const RegularExpression &name, bool include_symbols,
+ bool include_inlines, SymbolContextList &sc_list);
+
+ /// Find global and static variables by name.
+ ///
+ /// \param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// \param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// \param[in] variable_list
+ /// A list of variables that gets the matches appended to.
+ void FindGlobalVariables(ConstString name, size_t max_matches,
+ VariableList &variable_list) const;
+
+ /// Find global and static variables by regular expression.
+ ///
+ /// \param[in] regex
+ /// A regular expression to use when matching the name.
+ ///
+ /// \param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// \param[in] variable_list
+ /// A list of variables that gets the matches appended to.
+ void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
+ VariableList &variable_list) const;
+
+ /// Finds the first module whose file specification matches \a file_spec.
+ ///
+ /// \param[in] file_spec_ptr
+ /// A file specification object to match against the Module's
+ /// file specifications. If \a file_spec does not have
+ /// directory information, matches will occur by matching only
+ /// the basename of any modules in this list. If this value is
+ /// NULL, then file specifications won't be compared when
+ /// searching for matching modules.
+ ///
+ /// \param[in] arch_ptr
+ /// The architecture to search for if non-NULL. If this value
+ /// is NULL no architecture matching will be performed.
+ ///
+ /// \param[in] uuid_ptr
+ /// The uuid to search for if non-NULL. If this value is NULL
+ /// no uuid matching will be performed.
+ ///
+ /// \param[in] object_name
+ /// An optional object name that must match as well. This value
+ /// can be NULL.
+ ///
+ /// \param[out] matching_module_list
+ /// A module list that gets filled in with any modules that
+ /// match the search criteria.
+ void FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const;
+
+ lldb::ModuleSP FindModule(const Module *module_ptr) const;
+
+ // Find a module by UUID
+ //
+ // The UUID value for a module is extracted from the ObjectFile and is the
+ // MD5 checksum, or a smarter object file equivalent, so finding modules by
+ // UUID values is very efficient and accurate.
+ lldb::ModuleSP FindModule(const UUID &uuid) const;
+
+ lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const;
+
+ void FindSymbolsWithNameAndType(ConstString name,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list) const;
+
+ void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list) const;
+
+ /// Find types by name.
+ ///
+ /// \param[in] search_first
+ /// If non-null, this module will be searched before any other
+ /// modules.
+ ///
+ /// \param[in] name
+ /// The name of the type we are looking for.
+ ///
+ /// \param[in] append
+ /// If \b true, any matches will be appended to \a
+ /// variable_list, else matches replace the contents of
+ /// \a variable_list.
+ ///
+ /// \param[in] max_matches
+ /// Allow the number of matches to be limited to \a
+ /// max_matches. Specify UINT32_MAX to get all possible matches.
+ ///
+ /// \param[in] encoding
+ /// Limit the search to specific types, or get all types if
+ /// set to Type::invalid.
+ ///
+ /// \param[in] udt_name
+ /// If the encoding is a user defined type, specify the name
+ /// of the user defined type ("struct", "union", "class", etc).
+ ///
+ /// \param[out] type_list
+ /// A type list gets populated with any matches.
+ ///
+ 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;
+
+ /// Find addresses by file/line
+ ///
+ /// \param[in] target_sp
+ /// The target the addresses are desired for.
+ ///
+ /// \param[in] file
+ /// Source file to locate.
+ ///
+ /// \param[in] line
+ /// Source line to locate.
+ ///
+ /// \param[in] function
+ /// Optional filter function. Addresses within this function will be
+ /// added to the 'local' list. All others will be added to the 'extern'
+ /// list.
+ ///
+ /// \param[out] output_local
+ /// All matching addresses within 'function'
+ ///
+ /// \param[out] output_extern
+ /// All matching addresses not within 'function'
+ void FindAddressesForLine(const lldb::TargetSP target_sp,
+ const FileSpec &file, uint32_t line,
+ Function *function,
+ std::vector<Address> &output_local,
+ std::vector<Address> &output_extern);
+
+ /// Remove a module from the module list.
+ ///
+ /// \param[in] module_sp
+ /// A shared pointer to a module to remove from this collection.
+ ///
+ /// \param[in] notify
+ /// If true, and a notifier function is set, the notifier function
+ /// will be called. Defaults to true.
+ ///
+ /// When this ModuleList is the Target's ModuleList, the notifier
+ /// function is Target::ModulesDidUnload -- the call to
+ /// ModulesDidUnload may be deferred when removing multiple Modules
+ /// from the Target, but it must be called at the end,
+ /// before resuming execution.
+ bool Remove(const lldb::ModuleSP &module_sp, bool notify = true);
+
+ size_t Remove(ModuleList &module_list);
+
+ bool RemoveIfOrphaned(const Module *module_ptr);
+
+ size_t RemoveOrphans(bool mandatory);
+
+ bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const;
+
+ /// \copydoc Module::ResolveSymbolContextForAddress (const Address
+ /// &,uint32_t,SymbolContext&)
+ uint32_t ResolveSymbolContextForAddress(const Address &so_addr,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContext &sc) const;
+
+ /// \copydoc Module::ResolveSymbolContextForFilePath (const char
+ /// *,uint32_t,bool,uint32_t,SymbolContextList&)
+ uint32_t ResolveSymbolContextForFilePath(
+ const char *file_path, uint32_t line, bool check_inlines,
+ lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const;
+
+ /// \copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec
+ /// &,uint32_t,bool,uint32_t,SymbolContextList&)
+ uint32_t ResolveSymbolContextsForFileSpec(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const;
+
+ /// Gets the size of the module list.
+ ///
+ /// \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,
+ bool continue_on_error = true);
+
+ static ModuleListProperties &GetGlobalModuleListProperties();
+
+ static bool ModuleIsInCache(const Module *module_ptr);
+
+ static Status GetSharedModule(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr,
+ bool always_create = false);
+
+ static bool RemoveSharedModule(lldb::ModuleSP &module_sp);
+
+ static void FindSharedModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list);
+
+ static size_t RemoveOrphanSharedModules(bool mandatory);
+
+ static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr);
+
+ void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
+ &callback) const;
+
+protected:
+ // Class typedefs.
+ typedef std::vector<lldb::ModuleSP>
+ collection; ///< The module collection type.
+
+ void AppendImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
+
+ bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier = true);
+
+ collection::iterator RemoveImpl(collection::iterator pos,
+ bool use_notifier = true);
+
+ void ClearImpl(bool use_notifier = true);
+
+ // Member variables.
+ collection m_modules; ///< The collection of modules.
+ mutable std::recursive_mutex m_modules_mutex;
+
+ Notifier *m_notifier;
+
+public:
+ typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter,
+ std::recursive_mutex>
+ ModuleIterable;
+ ModuleIterable Modules() { return ModuleIterable(m_modules, GetMutex()); }
+
+ typedef AdaptedIterable<collection, lldb::ModuleSP, vector_adapter>
+ ModuleIterableNoLocking;
+ ModuleIterableNoLocking ModulesNoLocking() {
+ return ModuleIterableNoLocking(m_modules);
+ }
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ModuleList_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h
new file mode 100644
index 000000000000..651d0dc869bc
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleSpec.h
@@ -0,0 +1,424 @@
+//===-- ModuleSpec.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_ModuleSpec_h_
+#define liblldb_ModuleSpec_h_
+
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Target/PathMappingList.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/UUID.h"
+
+#include "llvm/Support/Chrono.h"
+
+#include <mutex>
+#include <vector>
+
+namespace lldb_private {
+
+class ModuleSpec {
+public:
+ ModuleSpec()
+ : m_file(), m_platform_file(), m_symbol_file(), m_arch(), m_uuid(),
+ m_object_name(), m_object_offset(0), m_object_size(0),
+ m_source_mappings() {}
+
+ ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID())
+ : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(),
+ m_uuid(uuid), m_object_name(), m_object_offset(0),
+ m_object_size(FileSystem::Instance().GetByteSize(file_spec)),
+ m_source_mappings() {}
+
+ ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch)
+ : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(arch),
+ m_uuid(), m_object_name(), m_object_offset(0),
+ m_object_size(FileSystem::Instance().GetByteSize(file_spec)),
+ m_source_mappings() {}
+
+ ModuleSpec(const ModuleSpec &rhs)
+ : m_file(rhs.m_file), m_platform_file(rhs.m_platform_file),
+ m_symbol_file(rhs.m_symbol_file), m_arch(rhs.m_arch),
+ m_uuid(rhs.m_uuid), m_object_name(rhs.m_object_name),
+ m_object_offset(rhs.m_object_offset), m_object_size(rhs.m_object_size),
+ m_object_mod_time(rhs.m_object_mod_time),
+ m_source_mappings(rhs.m_source_mappings) {}
+
+ ModuleSpec &operator=(const ModuleSpec &rhs) {
+ if (this != &rhs) {
+ m_file = rhs.m_file;
+ m_platform_file = rhs.m_platform_file;
+ m_symbol_file = rhs.m_symbol_file;
+ m_arch = rhs.m_arch;
+ m_uuid = rhs.m_uuid;
+ m_object_name = rhs.m_object_name;
+ m_object_offset = rhs.m_object_offset;
+ m_object_size = rhs.m_object_size;
+ m_object_mod_time = rhs.m_object_mod_time;
+ m_source_mappings = rhs.m_source_mappings;
+ }
+ return *this;
+ }
+
+ FileSpec *GetFileSpecPtr() { return (m_file ? &m_file : nullptr); }
+
+ const FileSpec *GetFileSpecPtr() const {
+ return (m_file ? &m_file : nullptr);
+ }
+
+ FileSpec &GetFileSpec() { return m_file; }
+
+ const FileSpec &GetFileSpec() const { return m_file; }
+
+ FileSpec *GetPlatformFileSpecPtr() {
+ return (m_platform_file ? &m_platform_file : nullptr);
+ }
+
+ const FileSpec *GetPlatformFileSpecPtr() const {
+ return (m_platform_file ? &m_platform_file : nullptr);
+ }
+
+ FileSpec &GetPlatformFileSpec() { return m_platform_file; }
+
+ const FileSpec &GetPlatformFileSpec() const { return m_platform_file; }
+
+ FileSpec *GetSymbolFileSpecPtr() {
+ return (m_symbol_file ? &m_symbol_file : nullptr);
+ }
+
+ const FileSpec *GetSymbolFileSpecPtr() const {
+ return (m_symbol_file ? &m_symbol_file : nullptr);
+ }
+
+ FileSpec &GetSymbolFileSpec() { return m_symbol_file; }
+
+ const FileSpec &GetSymbolFileSpec() const { return m_symbol_file; }
+
+ ArchSpec *GetArchitecturePtr() {
+ return (m_arch.IsValid() ? &m_arch : nullptr);
+ }
+
+ const ArchSpec *GetArchitecturePtr() const {
+ return (m_arch.IsValid() ? &m_arch : nullptr);
+ }
+
+ ArchSpec &GetArchitecture() { return m_arch; }
+
+ const ArchSpec &GetArchitecture() const { return m_arch; }
+
+ UUID *GetUUIDPtr() { return (m_uuid.IsValid() ? &m_uuid : nullptr); }
+
+ const UUID *GetUUIDPtr() const {
+ return (m_uuid.IsValid() ? &m_uuid : nullptr);
+ }
+
+ UUID &GetUUID() { return m_uuid; }
+
+ const UUID &GetUUID() const { return m_uuid; }
+
+ ConstString &GetObjectName() { return m_object_name; }
+
+ ConstString GetObjectName() const { return m_object_name; }
+
+ uint64_t GetObjectOffset() const { return m_object_offset; }
+
+ void SetObjectOffset(uint64_t object_offset) {
+ m_object_offset = object_offset;
+ }
+
+ uint64_t GetObjectSize() const { return m_object_size; }
+
+ void SetObjectSize(uint64_t object_size) { m_object_size = object_size; }
+
+ llvm::sys::TimePoint<> &GetObjectModificationTime() {
+ return m_object_mod_time;
+ }
+
+ const llvm::sys::TimePoint<> &GetObjectModificationTime() const {
+ return m_object_mod_time;
+ }
+
+ PathMappingList &GetSourceMappingList() const { return m_source_mappings; }
+
+ void Clear() {
+ m_file.Clear();
+ m_platform_file.Clear();
+ m_symbol_file.Clear();
+ m_arch.Clear();
+ m_uuid.Clear();
+ m_object_name.Clear();
+ m_object_offset = 0;
+ m_object_size = 0;
+ m_source_mappings.Clear(false);
+ m_object_mod_time = llvm::sys::TimePoint<>();
+ }
+
+ explicit operator bool() const {
+ if (m_file)
+ return true;
+ if (m_platform_file)
+ return true;
+ if (m_symbol_file)
+ return true;
+ if (m_arch.IsValid())
+ return true;
+ if (m_uuid.IsValid())
+ return true;
+ if (m_object_name)
+ return true;
+ if (m_object_size)
+ return true;
+ if (m_object_mod_time != llvm::sys::TimePoint<>())
+ return true;
+ return false;
+ }
+
+ void Dump(Stream &strm) const {
+ bool dumped_something = false;
+ if (m_file) {
+ strm.PutCString("file = '");
+ strm << m_file;
+ strm.PutCString("'");
+ dumped_something = true;
+ }
+ if (m_platform_file) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.PutCString("platform_file = '");
+ strm << m_platform_file;
+ strm.PutCString("'");
+ dumped_something = true;
+ }
+ if (m_symbol_file) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.PutCString("symbol_file = '");
+ strm << m_symbol_file;
+ strm.PutCString("'");
+ dumped_something = true;
+ }
+ if (m_arch.IsValid()) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("arch = ");
+ m_arch.DumpTriple(strm);
+ dumped_something = true;
+ }
+ if (m_uuid.IsValid()) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.PutCString("uuid = ");
+ m_uuid.Dump(&strm);
+ dumped_something = true;
+ }
+ if (m_object_name) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("object_name = %s", m_object_name.GetCString());
+ dumped_something = true;
+ }
+ if (m_object_offset > 0) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("object_offset = %" PRIu64, m_object_offset);
+ dumped_something = true;
+ }
+ if (m_object_size > 0) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Printf("object size = %" PRIu64, m_object_size);
+ dumped_something = true;
+ }
+ if (m_object_mod_time != llvm::sys::TimePoint<>()) {
+ if (dumped_something)
+ strm.PutCString(", ");
+ strm.Format("object_mod_time = {0:x+}",
+ uint64_t(llvm::sys::toTimeT(m_object_mod_time)));
+ }
+ }
+
+ bool Matches(const ModuleSpec &match_module_spec,
+ bool exact_arch_match) const {
+ if (match_module_spec.GetUUIDPtr() &&
+ match_module_spec.GetUUID() != GetUUID())
+ return false;
+ if (match_module_spec.GetObjectName() &&
+ match_module_spec.GetObjectName() != GetObjectName())
+ return false;
+ if (match_module_spec.GetFileSpecPtr()) {
+ const FileSpec &fspec = match_module_spec.GetFileSpec();
+ if (!FileSpec::Equal(fspec, GetFileSpec(),
+ !fspec.GetDirectory().IsEmpty()))
+ return false;
+ }
+ if (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr()) {
+ const FileSpec &fspec = match_module_spec.GetPlatformFileSpec();
+ if (!FileSpec::Equal(fspec, GetPlatformFileSpec(),
+ !fspec.GetDirectory().IsEmpty()))
+ return false;
+ }
+ // Only match the symbol file spec if there is one in this ModuleSpec
+ if (GetSymbolFileSpec() && match_module_spec.GetSymbolFileSpecPtr()) {
+ const FileSpec &fspec = match_module_spec.GetSymbolFileSpec();
+ if (!FileSpec::Equal(fspec, GetSymbolFileSpec(),
+ !fspec.GetDirectory().IsEmpty()))
+ return false;
+ }
+ if (match_module_spec.GetArchitecturePtr()) {
+ if (exact_arch_match) {
+ if (!GetArchitecture().IsExactMatch(
+ match_module_spec.GetArchitecture()))
+ return false;
+ } else {
+ if (!GetArchitecture().IsCompatibleMatch(
+ match_module_spec.GetArchitecture()))
+ return false;
+ }
+ }
+ return true;
+ }
+
+protected:
+ FileSpec m_file;
+ FileSpec m_platform_file;
+ FileSpec m_symbol_file;
+ ArchSpec m_arch;
+ UUID m_uuid;
+ ConstString m_object_name;
+ uint64_t m_object_offset;
+ uint64_t m_object_size;
+ llvm::sys::TimePoint<> m_object_mod_time;
+ mutable PathMappingList m_source_mappings;
+};
+
+class ModuleSpecList {
+public:
+ ModuleSpecList() : m_specs(), m_mutex() {}
+
+ ModuleSpecList(const ModuleSpecList &rhs) : m_specs(), m_mutex() {
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
+ m_specs = rhs.m_specs;
+ }
+
+ ~ModuleSpecList() = default;
+
+ ModuleSpecList &operator=(const ModuleSpecList &rhs) {
+ if (this != &rhs) {
+ std::lock(m_mutex, rhs.m_mutex);
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex, std::adopt_lock);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex,
+ std::adopt_lock);
+ m_specs = rhs.m_specs;
+ }
+ return *this;
+ }
+
+ size_t GetSize() const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_specs.size();
+ }
+
+ void Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_specs.clear();
+ }
+
+ void Append(const ModuleSpec &spec) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_specs.push_back(spec);
+ }
+
+ void Append(const ModuleSpecList &rhs) {
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex);
+ m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
+ }
+
+ // The index "i" must be valid and this can't be used in multi-threaded code
+ // as no mutex lock is taken.
+ ModuleSpec &GetModuleSpecRefAtIndex(size_t i) { return m_specs[i]; }
+
+ bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (i < m_specs.size()) {
+ module_spec = m_specs[i];
+ return true;
+ }
+ module_spec.Clear();
+ return false;
+ }
+
+ bool FindMatchingModuleSpec(const ModuleSpec &module_spec,
+ ModuleSpec &match_module_spec) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ bool exact_arch_match = true;
+ for (auto spec : m_specs) {
+ if (spec.Matches(module_spec, exact_arch_match)) {
+ match_module_spec = spec;
+ return true;
+ }
+ }
+
+ // If there was an architecture, retry with a compatible arch
+ if (module_spec.GetArchitecturePtr()) {
+ exact_arch_match = false;
+ for (auto spec : m_specs) {
+ if (spec.Matches(module_spec, exact_arch_match)) {
+ match_module_spec = spec;
+ return true;
+ }
+ }
+ }
+ match_module_spec.Clear();
+ return false;
+ }
+
+ 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();
+ for (auto spec : m_specs) {
+ if (spec.Matches(module_spec, exact_arch_match))
+ matching_list.Append(spec);
+ }
+
+ // If there was an architecture, retry with a compatible arch if no matches
+ // were found
+ if (module_spec.GetArchitecturePtr() &&
+ (initial_match_count == matching_list.GetSize())) {
+ exact_arch_match = false;
+ for (auto spec : m_specs) {
+ if (spec.Matches(module_spec, exact_arch_match))
+ matching_list.Append(spec);
+ }
+ }
+ }
+
+ void Dump(Stream &strm) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ uint32_t idx = 0;
+ for (auto spec : m_specs) {
+ strm.Printf("[%u] ", idx);
+ spec.Dump(strm);
+ strm.EOL();
+ ++idx;
+ }
+ }
+
+protected:
+ typedef std::vector<ModuleSpec> collection; ///< The module collection type.
+ collection m_specs; ///< The collection of modules.
+ mutable std::recursive_mutex m_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ModuleSpec_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h b/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h
new file mode 100644
index 000000000000..1a30ce4834ac
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Opcode.h
@@ -0,0 +1,273 @@
+//===-- Opcode.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_Opcode_h
+#define lldb_Opcode_h
+
+#include "lldb/Utility/Endian.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "llvm/Support/MathExtras.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+namespace lldb {
+class SBInstruction;
+}
+
+namespace lldb_private {
+class DataExtractor;
+class Stream;
+
+class Opcode {
+public:
+ enum Type {
+ eTypeInvalid,
+ eType8,
+ eType16,
+ eType16_2, // a 32-bit Thumb instruction, made up of two words
+ eType32,
+ eType64,
+ eTypeBytes
+ };
+
+ Opcode() : m_byte_order(lldb::eByteOrderInvalid), m_type(eTypeInvalid) {}
+
+ Opcode(uint8_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType8) {
+ m_data.inst8 = inst;
+ }
+
+ Opcode(uint16_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType16) {
+ m_data.inst16 = inst;
+ }
+
+ Opcode(uint32_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType32) {
+ m_data.inst32 = inst;
+ }
+
+ Opcode(uint64_t inst, lldb::ByteOrder order)
+ : m_byte_order(order), m_type(eType64) {
+ m_data.inst64 = inst;
+ }
+
+ Opcode(uint8_t *bytes, size_t length)
+ : m_byte_order(lldb::eByteOrderInvalid) {
+ SetOpcodeBytes(bytes, length);
+ }
+
+ void Clear() {
+ m_byte_order = lldb::eByteOrderInvalid;
+ m_type = Opcode::eTypeInvalid;
+ }
+
+ Opcode::Type GetType() const { return m_type; }
+
+ uint8_t GetOpcode8(uint8_t invalid_opcode = UINT8_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ break;
+ case Opcode::eType16_2:
+ break;
+ case Opcode::eType32:
+ break;
+ case Opcode::eType64:
+ break;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint16_t GetOpcode16(uint16_t invalid_opcode = UINT16_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
+ case Opcode::eType16_2:
+ break;
+ case Opcode::eType32:
+ break;
+ case Opcode::eType64:
+ break;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint32_t GetOpcode32(uint32_t invalid_opcode = UINT32_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
+ case Opcode::eType64:
+ break;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ uint64_t GetOpcode64(uint64_t invalid_opcode = UINT64_MAX) const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return m_data.inst8;
+ case Opcode::eType16:
+ return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32;
+ case Opcode::eType64:
+ return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64;
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return invalid_opcode;
+ }
+
+ void SetOpcode8(uint8_t inst, lldb::ByteOrder order) {
+ m_type = eType8;
+ m_data.inst8 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode16(uint16_t inst, lldb::ByteOrder order) {
+ m_type = eType16;
+ m_data.inst16 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode16_2(uint32_t inst, lldb::ByteOrder order) {
+ m_type = eType16_2;
+ m_data.inst32 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode32(uint32_t inst, lldb::ByteOrder order) {
+ m_type = eType32;
+ m_data.inst32 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcode64(uint64_t inst, lldb::ByteOrder order) {
+ m_type = eType64;
+ m_data.inst64 = inst;
+ m_byte_order = order;
+ }
+
+ void SetOpcodeBytes(const void *bytes, size_t length) {
+ if (bytes != nullptr && length > 0) {
+ m_type = eTypeBytes;
+ m_data.inst.length = length;
+ assert(length < sizeof(m_data.inst.bytes));
+ memcpy(m_data.inst.bytes, bytes, length);
+ m_byte_order = lldb::eByteOrderInvalid;
+ } else {
+ m_type = eTypeInvalid;
+ m_data.inst.length = 0;
+ }
+ }
+
+ int Dump(Stream *s, uint32_t min_byte_width);
+
+ const void *GetOpcodeBytes() const {
+ return ((m_type == Opcode::eTypeBytes) ? m_data.inst.bytes : nullptr);
+ }
+
+ uint32_t GetByteSize() const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return sizeof(m_data.inst8);
+ case Opcode::eType16:
+ return sizeof(m_data.inst16);
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return sizeof(m_data.inst32);
+ case Opcode::eType64:
+ return sizeof(m_data.inst64);
+ case Opcode::eTypeBytes:
+ return m_data.inst.length;
+ }
+ return 0;
+ }
+
+ // Get the opcode exactly as it would be laid out in memory.
+ uint32_t GetData(DataExtractor &data) const;
+
+protected:
+ friend class lldb::SBInstruction;
+
+ const void *GetOpcodeDataBytes() const {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ return &m_data.inst8;
+ case Opcode::eType16:
+ return &m_data.inst16;
+ case Opcode::eType16_2: // passthrough
+ case Opcode::eType32:
+ return &m_data.inst32;
+ case Opcode::eType64:
+ return &m_data.inst64;
+ case Opcode::eTypeBytes:
+ return m_data.inst.bytes;
+ }
+ return nullptr;
+ }
+
+ lldb::ByteOrder GetDataByteOrder() const;
+
+ bool GetEndianSwap() const {
+ return (m_byte_order == lldb::eByteOrderBig &&
+ endian::InlHostByteOrder() == lldb::eByteOrderLittle) ||
+ (m_byte_order == lldb::eByteOrderLittle &&
+ endian::InlHostByteOrder() == lldb::eByteOrderBig);
+ }
+
+ lldb::ByteOrder m_byte_order;
+
+ Opcode::Type m_type;
+ union {
+ uint8_t inst8;
+ uint16_t inst16;
+ uint32_t inst32;
+ uint64_t inst64;
+ struct {
+ uint8_t bytes[16]; // This must be big enough to handle any opcode for any
+ // supported target.
+ uint8_t length;
+ } inst;
+ } m_data;
+};
+
+} // namespace lldb_private
+
+#endif // lldb_Opcode_h
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h
new file mode 100644
index 000000000000..6e625a605917
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h
@@ -0,0 +1,27 @@
+//===-- PluginInterface.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_PluginInterface_h_
+#define liblldb_PluginInterface_h_
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class PluginInterface {
+public:
+ virtual ~PluginInterface() {}
+
+ virtual ConstString GetPluginName() = 0;
+
+ virtual uint32_t GetPluginVersion() = 0;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_PluginInterface_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h
new file mode 100644
index 000000000000..5b859752b3c7
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h
@@ -0,0 +1,481 @@
+//===-- PluginManager.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_PluginManager_h_
+#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"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-interfaces.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class CommandInterpreter;
+class ConstString;
+class Debugger;
+class StringList;
+
+class PluginManager {
+public:
+ static void Initialize();
+
+ static void Terminate();
+
+ // ABI
+ static bool RegisterPlugin(ConstString name, const char *description,
+ ABICreateInstance create_callback);
+
+ static bool UnregisterPlugin(ABICreateInstance create_callback);
+
+ static ABICreateInstance GetABICreateCallbackAtIndex(uint32_t idx);
+
+ static ABICreateInstance
+ GetABICreateCallbackForPluginName(ConstString name);
+
+ // Architecture
+ using ArchitectureCreateInstance =
+ std::unique_ptr<Architecture> (*)(const ArchSpec &);
+
+ static void RegisterPlugin(ConstString name,
+ llvm::StringRef description,
+ ArchitectureCreateInstance create_callback);
+
+ static void UnregisterPlugin(ArchitectureCreateInstance create_callback);
+
+ static std::unique_ptr<Architecture>
+ CreateArchitectureInstance(const ArchSpec &arch);
+
+ // Disassembler
+ static bool RegisterPlugin(ConstString name, const char *description,
+ DisassemblerCreateInstance create_callback);
+
+ static bool UnregisterPlugin(DisassemblerCreateInstance create_callback);
+
+ static DisassemblerCreateInstance
+ GetDisassemblerCreateCallbackAtIndex(uint32_t idx);
+
+ static DisassemblerCreateInstance
+ GetDisassemblerCreateCallbackForPluginName(ConstString name);
+
+ // DynamicLoader
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ DynamicLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = nullptr);
+
+ static bool UnregisterPlugin(DynamicLoaderCreateInstance create_callback);
+
+ static DynamicLoaderCreateInstance
+ GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx);
+
+ static DynamicLoaderCreateInstance
+ GetDynamicLoaderCreateCallbackForPluginName(ConstString name);
+
+ // JITLoader
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ JITLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = nullptr);
+
+ static bool UnregisterPlugin(JITLoaderCreateInstance create_callback);
+
+ static JITLoaderCreateInstance
+ GetJITLoaderCreateCallbackAtIndex(uint32_t idx);
+
+ static JITLoaderCreateInstance
+ GetJITLoaderCreateCallbackForPluginName(ConstString name);
+
+ // EmulateInstruction
+ static bool RegisterPlugin(ConstString name, const char *description,
+ EmulateInstructionCreateInstance create_callback);
+
+ static bool
+ UnregisterPlugin(EmulateInstructionCreateInstance create_callback);
+
+ static EmulateInstructionCreateInstance
+ GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx);
+
+ static EmulateInstructionCreateInstance
+ GetEmulateInstructionCreateCallbackForPluginName(ConstString name);
+
+ // OperatingSystem
+ static bool RegisterPlugin(ConstString name, const char *description,
+ OperatingSystemCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback);
+
+ static bool UnregisterPlugin(OperatingSystemCreateInstance create_callback);
+
+ static OperatingSystemCreateInstance
+ GetOperatingSystemCreateCallbackAtIndex(uint32_t idx);
+
+ static OperatingSystemCreateInstance
+ GetOperatingSystemCreateCallbackForPluginName(ConstString name);
+
+ // Language
+ static bool RegisterPlugin(ConstString name, const char *description,
+ LanguageCreateInstance create_callback);
+
+ static bool UnregisterPlugin(LanguageCreateInstance create_callback);
+
+ static LanguageCreateInstance GetLanguageCreateCallbackAtIndex(uint32_t idx);
+
+ static LanguageCreateInstance
+ GetLanguageCreateCallbackForPluginName(ConstString name);
+
+ // LanguageRuntime
+ static bool RegisterPlugin(
+ ConstString name, const char *description,
+ LanguageRuntimeCreateInstance create_callback,
+ LanguageRuntimeGetCommandObject command_callback = nullptr,
+ LanguageRuntimeGetExceptionPrecondition precondition_callback = nullptr);
+
+ static bool UnregisterPlugin(LanguageRuntimeCreateInstance create_callback);
+
+ static LanguageRuntimeCreateInstance
+ GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx);
+
+ static LanguageRuntimeGetCommandObject
+ GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx);
+
+ static LanguageRuntimeGetExceptionPrecondition
+ GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx);
+
+ static LanguageRuntimeCreateInstance
+ GetLanguageRuntimeCreateCallbackForPluginName(ConstString name);
+
+ // SystemRuntime
+ static bool RegisterPlugin(ConstString name, const char *description,
+ SystemRuntimeCreateInstance create_callback);
+
+ static bool UnregisterPlugin(SystemRuntimeCreateInstance create_callback);
+
+ static SystemRuntimeCreateInstance
+ GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx);
+
+ static SystemRuntimeCreateInstance
+ GetSystemRuntimeCreateCallbackForPluginName(ConstString name);
+
+ // ObjectFile
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ ObjectFileCreateInstance create_callback,
+ ObjectFileCreateMemoryInstance create_memory_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications,
+ ObjectFileSaveCore save_core = nullptr);
+
+ static bool UnregisterPlugin(ObjectFileCreateInstance create_callback);
+
+ static ObjectFileCreateInstance
+ GetObjectFileCreateCallbackAtIndex(uint32_t idx);
+
+ static ObjectFileCreateMemoryInstance
+ GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx);
+
+ static ObjectFileGetModuleSpecifications
+ GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx);
+
+ static ObjectFileCreateInstance
+ GetObjectFileCreateCallbackForPluginName(ConstString name);
+
+ static ObjectFileCreateMemoryInstance
+ GetObjectFileCreateMemoryCallbackForPluginName(ConstString name);
+
+ static Status SaveCore(const lldb::ProcessSP &process_sp,
+ const FileSpec &outfile);
+
+ // ObjectContainer
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ ObjectContainerCreateInstance create_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications);
+
+ static bool UnregisterPlugin(ObjectContainerCreateInstance create_callback);
+
+ static ObjectContainerCreateInstance
+ GetObjectContainerCreateCallbackAtIndex(uint32_t idx);
+
+ static ObjectContainerCreateInstance
+ GetObjectContainerCreateCallbackForPluginName(ConstString name);
+
+ static ObjectFileGetModuleSpecifications
+ GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx);
+
+ // Platform
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ PlatformCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = nullptr);
+
+ static bool UnregisterPlugin(PlatformCreateInstance create_callback);
+
+ static PlatformCreateInstance GetPlatformCreateCallbackAtIndex(uint32_t idx);
+
+ static PlatformCreateInstance
+ GetPlatformCreateCallbackForPluginName(ConstString name);
+
+ static const char *GetPlatformPluginNameAtIndex(uint32_t idx);
+
+ static const char *GetPlatformPluginDescriptionAtIndex(uint32_t idx);
+
+ static void AutoCompletePlatformName(llvm::StringRef partial_name,
+ CompletionRequest &request);
+ // Process
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ ProcessCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = nullptr);
+
+ static bool UnregisterPlugin(ProcessCreateInstance create_callback);
+
+ static ProcessCreateInstance GetProcessCreateCallbackAtIndex(uint32_t idx);
+
+ static ProcessCreateInstance
+ GetProcessCreateCallbackForPluginName(ConstString name);
+
+ static const char *GetProcessPluginNameAtIndex(uint32_t idx);
+
+ static const char *GetProcessPluginDescriptionAtIndex(uint32_t idx);
+
+ // ScriptInterpreter
+ static bool RegisterPlugin(ConstString name, const char *description,
+ lldb::ScriptLanguage script_lang,
+ ScriptInterpreterCreateInstance create_callback);
+
+ static bool UnregisterPlugin(ScriptInterpreterCreateInstance create_callback);
+
+ static ScriptInterpreterCreateInstance
+ GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx);
+
+ static lldb::ScriptInterpreterSP
+ GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
+ Debugger &debugger);
+
+ // StructuredDataPlugin
+
+ /// Register a StructuredDataPlugin class along with optional
+ /// callbacks for debugger initialization and Process launch info
+ /// filtering and manipulation.
+ ///
+ /// \param[in] name
+ /// The name of the plugin.
+ ///
+ /// \param[in] description
+ /// A description string for the plugin.
+ ///
+ /// \param[in] create_callback
+ /// The callback that will be invoked to create an instance of
+ /// the callback. This may not be nullptr.
+ ///
+ /// \param[in] debugger_init_callback
+ /// An optional callback that will be made when a Debugger
+ /// instance is initialized.
+ ///
+ /// \param[in] filter_callback
+ /// An optional callback that will be invoked before LLDB
+ /// launches a process for debugging. The callback must
+ /// do the following:
+ /// 1. Only do something if the plugin's behavior is enabled.
+ /// 2. Only make changes for processes that are relevant to the
+ /// plugin. The callback gets a pointer to the Target, which
+ /// can be inspected as needed. The ProcessLaunchInfo is
+ /// provided in read-write mode, and may be modified by the
+ /// plugin if, for instance, additional environment variables
+ /// are needed to support the feature when enabled.
+ ///
+ /// \return
+ /// Returns true upon success; otherwise, false.
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ StructuredDataPluginCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = nullptr,
+ StructuredDataFilterLaunchInfo filter_callback = nullptr);
+
+ static bool
+ UnregisterPlugin(StructuredDataPluginCreateInstance create_callback);
+
+ static StructuredDataPluginCreateInstance
+ GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx);
+
+ static StructuredDataPluginCreateInstance
+ GetStructuredDataPluginCreateCallbackForPluginName(ConstString name);
+
+ static StructuredDataFilterLaunchInfo
+ GetStructuredDataFilterCallbackAtIndex(uint32_t idx,
+ bool &iteration_complete);
+
+ // SymbolFile
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ SymbolFileCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback = nullptr);
+
+ static bool UnregisterPlugin(SymbolFileCreateInstance create_callback);
+
+ static SymbolFileCreateInstance
+ GetSymbolFileCreateCallbackAtIndex(uint32_t idx);
+
+ static SymbolFileCreateInstance
+ GetSymbolFileCreateCallbackForPluginName(ConstString name);
+
+ // SymbolVendor
+ static bool RegisterPlugin(ConstString name, const char *description,
+ SymbolVendorCreateInstance create_callback);
+
+ static bool UnregisterPlugin(SymbolVendorCreateInstance create_callback);
+
+ static SymbolVendorCreateInstance
+ GetSymbolVendorCreateCallbackAtIndex(uint32_t idx);
+
+ static SymbolVendorCreateInstance
+ GetSymbolVendorCreateCallbackForPluginName(ConstString name);
+
+ // UnwindAssembly
+ static bool RegisterPlugin(ConstString name, const char *description,
+ UnwindAssemblyCreateInstance create_callback);
+
+ static bool UnregisterPlugin(UnwindAssemblyCreateInstance create_callback);
+
+ static UnwindAssemblyCreateInstance
+ GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx);
+
+ static UnwindAssemblyCreateInstance
+ GetUnwindAssemblyCreateCallbackForPluginName(ConstString name);
+
+ // MemoryHistory
+ static bool RegisterPlugin(ConstString name, const char *description,
+ MemoryHistoryCreateInstance create_callback);
+
+ static bool UnregisterPlugin(MemoryHistoryCreateInstance create_callback);
+
+ static MemoryHistoryCreateInstance
+ GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx);
+
+ static MemoryHistoryCreateInstance
+ GetMemoryHistoryCreateCallbackForPluginName(ConstString name);
+
+ // InstrumentationRuntime
+ static bool
+ RegisterPlugin(ConstString name, const char *description,
+ InstrumentationRuntimeCreateInstance create_callback,
+ InstrumentationRuntimeGetType get_type_callback);
+
+ static bool
+ UnregisterPlugin(InstrumentationRuntimeCreateInstance create_callback);
+
+ static InstrumentationRuntimeGetType
+ GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx);
+
+ static InstrumentationRuntimeCreateInstance
+ GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx);
+
+ static InstrumentationRuntimeCreateInstance
+ GetInstrumentationRuntimeCreateCallbackForPluginName(ConstString name);
+
+ // TypeSystem
+ 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);
+
+ static TypeSystemCreateInstance
+ GetTypeSystemCreateCallbackAtIndex(uint32_t idx);
+
+ static TypeSystemCreateInstance
+ GetTypeSystemCreateCallbackForPluginName(ConstString name);
+
+ static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes();
+
+ static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions();
+
+ // REPL
+ static bool RegisterPlugin(ConstString name, const char *description,
+ REPLCreateInstance create_callback,
+ LanguageSet supported_languages);
+
+ static bool UnregisterPlugin(REPLCreateInstance create_callback);
+
+ static REPLCreateInstance GetREPLCreateCallbackAtIndex(uint32_t idx);
+
+ static REPLCreateInstance
+ GetREPLCreateCallbackForPluginName(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
+ // DebuggerInitialize function will get called. This allows plug-ins to
+ // install Properties and do any other initialization that requires a
+ // debugger instance.
+ static void DebuggerInitialize(Debugger &debugger);
+
+ static lldb::OptionValuePropertiesSP
+ GetSettingForDynamicLoaderPlugin(Debugger &debugger,
+ ConstString setting_name);
+
+ static bool CreateSettingForDynamicLoaderPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ ConstString description, bool is_global_property);
+
+ static lldb::OptionValuePropertiesSP
+ 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);
+
+ 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);
+
+ 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);
+
+ static bool CreateSettingForJITLoaderPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ ConstString description, bool is_global_property);
+
+ static lldb::OptionValuePropertiesSP
+ GetSettingForOperatingSystemPlugin(Debugger &debugger,
+ ConstString setting_name);
+
+ static bool CreateSettingForOperatingSystemPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ ConstString description, bool is_global_property);
+
+ static lldb::OptionValuePropertiesSP
+ GetSettingForStructuredDataPlugin(Debugger &debugger,
+ ConstString setting_name);
+
+ static bool CreateSettingForStructuredDataPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ ConstString description, bool is_global_property);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_PluginManager_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PropertiesBase.td b/contrib/llvm-project/lldb/include/lldb/Core/PropertiesBase.td
new file mode 100644
index 000000000000..be97d44ae8e4
--- /dev/null
+++ b/contrib/llvm-project/lldb/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/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h b/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h
new file mode 100644
index 000000000000..e6fa2599e55a
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h
@@ -0,0 +1,107 @@
+//===-- RichManglingContext.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_RichManglingContext_h_
+#define liblldb_RichManglingContext_h_
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+
+#include "lldb/Utility/ConstString.h"
+
+#include "llvm/ADT/Any.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Demangle/Demangle.h"
+
+namespace lldb_private {
+
+/// Uniform wrapper for access to rich mangling information from different
+/// providers. See Mangled::DemangleWithRichManglingInfo()
+class RichManglingContext {
+public:
+ RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) {
+ m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size));
+ m_ipd_buf[0] = '\0';
+ }
+
+ ~RichManglingContext() { std::free(m_ipd_buf); }
+
+ /// Use the ItaniumPartialDemangler to obtain rich mangling information from
+ /// the given mangled name.
+ bool FromItaniumName(ConstString mangled);
+
+ /// Use the legacy language parser implementation to obtain rich mangling
+ /// information from the given demangled name.
+ bool FromCxxMethodName(ConstString demangled);
+
+ /// If this symbol describes a constructor or destructor.
+ bool IsCtorOrDtor() const;
+
+ /// If this symbol describes a function.
+ bool IsFunction() const;
+
+ /// Get the base name of a function. This doesn't include trailing template
+ /// arguments, ie "a::b<int>" gives "b". The result will overwrite the
+ /// internal buffer. It can be obtained via GetBufferRef().
+ void ParseFunctionBaseName();
+
+ /// Get the context name for a function. For "a::b::c", this function returns
+ /// "a::b". The result will overwrite the internal buffer. It can be obtained
+ /// via GetBufferRef().
+ void ParseFunctionDeclContextName();
+
+ /// Get the entire demangled name. The result will overwrite the internal
+ /// buffer. It can be obtained via GetBufferRef().
+ void ParseFullName();
+
+ /// Obtain a StringRef to the internal buffer that holds the result of the
+ /// most recent ParseXy() operation. The next ParseXy() call invalidates it.
+ llvm::StringRef GetBufferRef() const {
+ assert(m_provider != None && "Initialize a provider first");
+ return m_buffer;
+ }
+
+private:
+ enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage };
+
+ /// Selects the rich mangling info provider.
+ InfoProvider m_provider;
+
+ /// Reference to the buffer used for results of ParseXy() operations.
+ llvm::StringRef m_buffer;
+
+ /// Members for ItaniumPartialDemangler
+ llvm::ItaniumPartialDemangler m_ipd;
+ char *m_ipd_buf;
+ size_t m_ipd_buf_size;
+
+ /// Members for PluginCxxLanguage
+ /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
+ /// respective header is in Plugins and including it from here causes cyclic
+ /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp.
+ llvm::Any m_cxx_method_parser;
+
+ /// Clean up memory and set a new info provider for this instance.
+ void ResetProvider(InfoProvider new_provider);
+
+ /// Uniform handling of string buffers for ItaniumPartialDemangler.
+ void processIPDStrResult(char *ipd_res, size_t res_len);
+
+ /// Cast the given parser to the given type. Ideally we would have a type
+ /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
+ /// can't access CPlusPlusLanguage::MethodName from within the header.
+ template <class ParserT> static ParserT *get(llvm::Any parser) {
+ assert(parser.hasValue());
+ assert(llvm::any_isa<ParserT *>(parser));
+ return llvm::any_cast<ParserT *>(parser);
+ }
+};
+
+} // namespace lldb_private
+
+#endif
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/STLUtils.h b/contrib/llvm-project/lldb/include/lldb/Core/STLUtils.h
new file mode 100644
index 000000000000..830aca36a116
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/STLUtils.h
@@ -0,0 +1,74 @@
+//===-- STLUtils.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_STLUtils_h_
+#define liblldb_STLUtils_h_
+
+#include <string.h>
+
+#include <map>
+#include <ostream>
+#include <vector>
+
+
+// C string less than compare function object
+struct CStringCompareFunctionObject {
+ bool operator()(const char *s1, const char *s2) const {
+ return strcmp(s1, s2) < 0;
+ }
+};
+
+// C string equality function object (binary predicate).
+struct CStringEqualBinaryPredicate {
+ bool operator()(const char *s1, const char *s2) const {
+ return strcmp(s1, s2) == 0;
+ }
+};
+
+// Templated type for finding an entry in a std::map<F,S> whose value is equal
+// to something
+template <class F, class S> class ValueEquals {
+public:
+ ValueEquals(const S &val) : second_value(val) {}
+
+ // Compare the second item
+ bool operator()(std::pair<const F, S> elem) {
+ return elem.second == second_value;
+ }
+
+private:
+ S second_value;
+};
+
+template <class T>
+inline void PrintAllCollectionElements(std::ostream &s, const T &coll,
+ const char *header_cstr = nullptr,
+ const char *separator_cstr = " ") {
+ typename T::const_iterator pos;
+
+ if (header_cstr)
+ s << header_cstr;
+ for (pos = coll.begin(); pos != coll.end(); ++pos) {
+ s << *pos << separator_cstr;
+ }
+ s << std::endl;
+}
+
+// The function object below can be used to delete a STL container that
+// contains C++ object pointers.
+//
+// Usage: std::for_each(vector.begin(), vector.end(), for_each_delete());
+
+struct for_each_cplusplus_delete {
+ template <typename T> void operator()(T *ptr) { delete ptr; }
+};
+
+typedef std::vector<std::string> STLStringArray;
+typedef std::vector<const char *> CStringArray;
+
+#endif // liblldb_STLUtils_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h b/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h
new file mode 100644
index 000000000000..6823daf9e3ed
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/SearchFilter.h
@@ -0,0 +1,456 @@
+//===-- SearchFilter.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_SearchFilter_h_
+#define liblldb_SearchFilter_h_
+
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Utility/StructuredData.h"
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-forward.h"
+
+#include <stdint.h>
+
+namespace lldb_private {
+class Address;
+class Breakpoint;
+class CompileUnit;
+class Status;
+class Function;
+class ModuleList;
+class SearchFilter;
+class Stream;
+class SymbolContext;
+class Target;
+}
+
+namespace lldb_private {
+
+/// \class Searcher SearchFilter.h "lldb/Core/SearchFilter.h" Class that is
+/// driven by the SearchFilter to search the SymbolContext space of the target
+/// program.
+
+/// General Outline:
+/// Provides the callback and search depth for the SearchFilter search.
+
+class Searcher {
+public:
+ enum CallbackReturn {
+ eCallbackReturnStop = 0, // Stop the iteration
+ eCallbackReturnContinue, // Continue the iteration
+ eCallbackReturnPop // Pop one level up and continue iterating
+ };
+
+ Searcher();
+
+ virtual ~Searcher();
+
+ virtual CallbackReturn SearchCallback(SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr) = 0;
+
+ virtual lldb::SearchDepth GetDepth() = 0;
+
+ /// Prints a canonical description for the searcher to the stream \a s.
+ ///
+ /// \param[in] s
+ /// Stream to which the output is copied.
+ virtual void GetDescription(Stream *s);
+};
+
+/// \class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h" Class
+/// descends through the SymbolContext space of the target, applying a filter
+/// at each stage till it reaches the depth specified by the GetDepth method
+/// of the searcher, and calls its callback at that point.
+
+/// General Outline:
+/// Provides the callback and search depth for the SearchFilter search.
+///
+/// The search is done by cooperation between the search filter and the
+/// searcher. The search filter does the heavy work of recursing through the
+/// SymbolContext space of the target program's symbol space. The Searcher
+/// specifies the depth at which it wants its callback to be invoked. Note
+/// that since the resolution of the Searcher may be greater than that of the
+/// SearchFilter, before the Searcher qualifies an address it should pass it
+/// to "AddressPasses." The default implementation is "Everything Passes."
+
+class SearchFilter {
+public:
+ /// The basic constructor takes a Target, which gives the space to search.
+ ///
+ /// \param[in] target
+ /// The Target that provides the module list to search.
+ SearchFilter(const lldb::TargetSP &target_sp);
+
+ SearchFilter(const lldb::TargetSP &target_sp, unsigned char filterType);
+
+ virtual ~SearchFilter();
+
+ /// Call this method with a file spec to see if that spec passes the filter.
+ ///
+ /// \param[in] spec
+ /// The file spec to check against the filter.
+ /// \return
+ /// \b true if \a spec passes, and \b false otherwise.
+ virtual bool ModulePasses(const FileSpec &spec);
+
+ /// Call this method with a Module to see if that module passes the filter.
+ ///
+ /// \param[in] module
+ /// The Module to check against the filter.
+ ///
+ /// \return
+ /// \b true if \a module passes, and \b false otherwise.
+ virtual bool ModulePasses(const lldb::ModuleSP &module_sp);
+
+ /// Call this method with a Address to see if \a address passes the filter.
+ ///
+ /// \param[in] addr
+ /// The address to check against the filter.
+ ///
+ /// \return
+ /// \b true if \a address passes, and \b false otherwise.
+ virtual bool AddressPasses(Address &addr);
+
+ /// Call this method with a FileSpec to see if \a file spec passes the
+ /// filter as the name of a compilation unit.
+ ///
+ /// \param[in] fileSpec
+ /// The file spec to check against the filter.
+ ///
+ /// \return
+ /// \b true if \a file spec passes, and \b false otherwise.
+ virtual bool CompUnitPasses(FileSpec &fileSpec);
+
+ /// Call this method with a CompileUnit to see if \a comp unit passes the
+ /// filter.
+ ///
+ /// \param[in] compUnit
+ /// The CompileUnit to check against the filter.
+ ///
+ /// \return
+ /// \b true if \a Comp Unit passes, and \b false otherwise.
+ virtual bool CompUnitPasses(CompileUnit &compUnit);
+
+ /// Call this method with a Function to see if \a function passes the
+ /// filter.
+ ///
+ /// \param[in] function
+ /// The Functions to check against the filter.
+ ///
+ /// \return
+ /// \b true if \a function passes, and \b false otherwise.
+ virtual bool FunctionPasses(Function &function);
+
+ /// Call this method to do the search using the Searcher.
+ ///
+ /// \param[in] searcher
+ /// The searcher to drive with this search.
+ ///
+ virtual void Search(Searcher &searcher);
+
+ /// Call this method to do the search using the Searcher in the module list
+ /// \a modules.
+ ///
+ /// \param[in] searcher
+ /// The searcher to drive with this search.
+ ///
+ /// \param[in] modules
+ /// The module list within which to restrict the search.
+ ///
+ virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules);
+
+ /// This determines which items are REQUIRED for the filter to pass. For
+ /// instance, if you are filtering by Compilation Unit, obviously symbols
+ /// that have no compilation unit can't pass So return eSymbolContextCU and
+ /// search callbacks can then short cut the search to avoid looking at
+ /// things that obviously won't pass.
+ ///
+ /// \return
+ /// The required elements for the search, which is an or'ed together
+ /// set of lldb:SearchContextItem enum's.
+ ///
+ virtual uint32_t GetFilterRequiredItems();
+
+ /// Prints a canonical description for the search filter to the stream \a s.
+ ///
+ /// \param[in] s
+ /// Stream to which the output is copied.
+ virtual void GetDescription(Stream *s);
+
+ /// Standard "Dump" method. At present it does nothing.
+ virtual void Dump(Stream *s) const;
+
+ lldb::SearchFilterSP CopyForBreakpoint(Breakpoint &breakpoint);
+
+ static lldb::SearchFilterSP
+ CreateFromStructuredData(Target &target,
+ const StructuredData::Dictionary &data_dict,
+ Status &error);
+
+ virtual StructuredData::ObjectSP SerializeToStructuredData() {
+ return StructuredData::ObjectSP();
+ }
+
+ static const char *GetSerializationKey() { return "SearchFilter"; }
+
+ static const char *GetSerializationSubclassKey() { return "Type"; }
+
+ static const char *GetSerializationSubclassOptionsKey() { return "Options"; }
+
+ enum FilterTy {
+ Unconstrained = 0,
+ Exception,
+ ByModule,
+ ByModules,
+ ByModulesAndCU,
+ LastKnownFilterType = ByModulesAndCU,
+ UnknownFilter
+ };
+
+ static const char *g_ty_to_name[LastKnownFilterType + 2];
+
+ enum FilterTy GetFilterTy() {
+ if (SubclassID > FilterTy::LastKnownFilterType)
+ return FilterTy::UnknownFilter;
+ else
+ return (enum FilterTy)SubclassID;
+ }
+
+ const char *GetFilterName() { return FilterTyToName(GetFilterTy()); }
+
+ static const char *FilterTyToName(enum FilterTy);
+
+ static FilterTy NameToFilterTy(llvm::StringRef name);
+
+protected:
+ // Serialization of SearchFilter options:
+ enum OptionNames { ModList = 0, CUList, LanguageName, LastOptionName };
+ static const char *g_option_names[LastOptionName];
+
+ static const char *GetKey(enum OptionNames enum_value) {
+ return g_option_names[enum_value];
+ }
+
+ StructuredData::DictionarySP
+ WrapOptionsDict(StructuredData::DictionarySP options_dict_sp);
+
+ void SerializeFileSpecList(StructuredData::DictionarySP &options_dict_sp,
+ OptionNames name, FileSpecList &file_list);
+
+ // These are utility functions to assist with the search iteration. They are
+ // used by the default Search method.
+
+ Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context,
+ Searcher &searcher);
+
+ Searcher::CallbackReturn DoModuleIteration(const lldb::ModuleSP &module_sp,
+ Searcher &searcher);
+
+ Searcher::CallbackReturn DoCUIteration(const lldb::ModuleSP &module_sp,
+ const SymbolContext &context,
+ Searcher &searcher);
+
+ Searcher::CallbackReturn DoFunctionIteration(Function *function,
+ const SymbolContext &context,
+ Searcher &searcher);
+
+ virtual lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) = 0;
+
+ void SetTarget(lldb::TargetSP &target_sp) { m_target_sp = target_sp; }
+
+ lldb::TargetSP
+ m_target_sp; // Every filter has to be associated with a target for
+ // now since you need a starting place for the search.
+private:
+ unsigned char SubclassID;
+};
+
+/// \class SearchFilterForUnconstrainedSearches SearchFilter.h
+/// "lldb/Core/SearchFilter.h" This is a SearchFilter that searches through
+/// all modules. It also consults the
+/// Target::ModuleIsExcludedForUnconstrainedSearches.
+class SearchFilterForUnconstrainedSearches : public SearchFilter {
+public:
+ SearchFilterForUnconstrainedSearches(const lldb::TargetSP &target_sp)
+ : SearchFilter(target_sp, FilterTy::Unconstrained) {}
+
+ ~SearchFilterForUnconstrainedSearches() override = default;
+
+ bool ModulePasses(const FileSpec &module_spec) override;
+
+ bool ModulePasses(const lldb::ModuleSP &module_sp) override;
+
+ static lldb::SearchFilterSP
+ CreateFromStructuredData(Target &target,
+ const StructuredData::Dictionary &data_dict,
+ Status &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData() override;
+
+protected:
+ lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
+};
+
+/// \class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This
+/// is a SearchFilter that restricts the search to a given module.
+
+class SearchFilterByModule : public SearchFilter {
+public:
+ /// The basic constructor takes a Target, which gives the space to search,
+ /// and the module to restrict the search to.
+ ///
+ /// \param[in] target
+ /// The Target that provides the module list to search.
+ ///
+ /// \param[in] module
+ /// The Module that limits the search.
+ SearchFilterByModule(const lldb::TargetSP &targetSP, const FileSpec &module);
+
+ ~SearchFilterByModule() override;
+
+ bool ModulePasses(const lldb::ModuleSP &module_sp) override;
+
+ bool ModulePasses(const FileSpec &spec) override;
+
+ bool AddressPasses(Address &address) override;
+
+ bool CompUnitPasses(FileSpec &fileSpec) override;
+
+ bool CompUnitPasses(CompileUnit &compUnit) override;
+
+ void GetDescription(Stream *s) override;
+
+ uint32_t GetFilterRequiredItems() override;
+
+ void Dump(Stream *s) const override;
+
+ void Search(Searcher &searcher) override;
+
+ static lldb::SearchFilterSP
+ CreateFromStructuredData(Target &target,
+ const StructuredData::Dictionary &data_dict,
+ Status &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData() override;
+
+protected:
+ lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
+
+private:
+ FileSpec m_module_spec;
+};
+
+class SearchFilterByModuleList : public SearchFilter {
+public:
+ /// The basic constructor takes a Target, which gives the space to search,
+ /// and the module list to restrict the search to.
+ ///
+ /// \param[in] target
+ /// The Target that provides the module list to search.
+ ///
+ /// \param[in] module
+ /// The Module that limits the search.
+ SearchFilterByModuleList(const lldb::TargetSP &targetSP,
+ const FileSpecList &module_list);
+
+ SearchFilterByModuleList(const lldb::TargetSP &targetSP,
+ const FileSpecList &module_list,
+ enum FilterTy filter_ty);
+
+ ~SearchFilterByModuleList() override;
+
+ SearchFilterByModuleList &operator=(const SearchFilterByModuleList &rhs);
+
+ bool ModulePasses(const lldb::ModuleSP &module_sp) override;
+
+ bool ModulePasses(const FileSpec &spec) override;
+
+ bool AddressPasses(Address &address) override;
+
+ bool CompUnitPasses(FileSpec &fileSpec) override;
+
+ bool CompUnitPasses(CompileUnit &compUnit) override;
+
+ void GetDescription(Stream *s) override;
+
+ uint32_t GetFilterRequiredItems() override;
+
+ void Dump(Stream *s) const override;
+
+ void Search(Searcher &searcher) override;
+
+ static lldb::SearchFilterSP
+ CreateFromStructuredData(Target &target,
+ const StructuredData::Dictionary &data_dict,
+ Status &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData() override;
+
+ void SerializeUnwrapped(StructuredData::DictionarySP &options_dict_sp);
+
+protected:
+ lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
+
+protected:
+ FileSpecList m_module_spec_list;
+};
+
+class SearchFilterByModuleListAndCU : public SearchFilterByModuleList {
+public:
+ /// The basic constructor takes a Target, which gives the space to search,
+ /// and the module list to restrict the search to.
+ ///
+ /// \param[in] target
+ /// The Target that provides the module list to search.
+ ///
+ /// \param[in] module
+ /// The Module that limits the search.
+ SearchFilterByModuleListAndCU(const lldb::TargetSP &targetSP,
+ const FileSpecList &module_list,
+ const FileSpecList &cu_list);
+
+ SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU &rhs);
+
+ ~SearchFilterByModuleListAndCU() override;
+
+ SearchFilterByModuleListAndCU &
+ operator=(const SearchFilterByModuleListAndCU &rhs);
+
+ bool AddressPasses(Address &address) override;
+
+ bool CompUnitPasses(FileSpec &fileSpec) override;
+
+ bool CompUnitPasses(CompileUnit &compUnit) override;
+
+ void GetDescription(Stream *s) override;
+
+ uint32_t GetFilterRequiredItems() override;
+
+ void Dump(Stream *s) const override;
+
+ void Search(Searcher &searcher) override;
+
+ static lldb::SearchFilterSP
+ CreateFromStructuredData(Target &target,
+ const StructuredData::Dictionary &data_dict,
+ Status &error);
+
+ StructuredData::ObjectSP SerializeToStructuredData() override;
+
+protected:
+ lldb::SearchFilterSP DoCopyForBreakpoint(Breakpoint &breakpoint) override;
+
+private:
+ FileSpecList m_cu_spec_list;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_SearchFilter_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Section.h b/contrib/llvm-project/lldb/include/lldb/Core/Section.h
new file mode 100644
index 000000000000..509a0767be1d
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Section.h
@@ -0,0 +1,275 @@
+//===-- Section.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_Section_h_
+#define liblldb_Section_h_
+
+#include "lldb/Core/ModuleChild.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include <memory>
+#include <vector>
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class Address;
+class DataExtractor;
+class ObjectFile;
+class Section;
+class Stream;
+class Target;
+
+class SectionList {
+public:
+ typedef std::vector<lldb::SectionSP> collection;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ const_iterator begin() const { return m_sections.begin(); }
+ const_iterator end() const { return m_sections.end(); }
+ const_iterator begin() { return m_sections.begin(); }
+ const_iterator end() { return m_sections.end(); }
+
+ /// Create an empty list.
+ SectionList() = default;
+
+ SectionList &operator=(const SectionList &rhs);
+
+ size_t AddSection(const lldb::SectionSP &section_sp);
+
+ size_t AddUniqueSection(const lldb::SectionSP &section_sp);
+
+ size_t FindSectionIndex(const Section *sect);
+
+ bool ContainsSection(lldb::user_id_t sect_id) const;
+
+ void Dump(Stream *s, Target *target, bool show_header, uint32_t depth) const;
+
+ lldb::SectionSP FindSectionByName(ConstString section_dstr) const;
+
+ lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const;
+
+ lldb::SectionSP FindSectionByType(lldb::SectionType sect_type,
+ bool check_children,
+ size_t start_idx = 0) const;
+
+ lldb::SectionSP
+ FindSectionContainingFileAddress(lldb::addr_t addr,
+ uint32_t depth = UINT32_MAX) const;
+
+ // Get the number of sections in this list only
+ size_t GetSize() const { return m_sections.size(); }
+
+ // Get the number of sections in this list, and any contained child sections
+ size_t GetNumSections(uint32_t depth) const;
+
+ bool ReplaceSection(lldb::user_id_t sect_id,
+ const lldb::SectionSP &section_sp,
+ uint32_t depth = UINT32_MAX);
+
+ // Warning, this can be slow as it's removing items from a std::vector.
+ bool DeleteSection(size_t idx);
+
+ lldb::SectionSP GetSectionAtIndex(size_t idx) const;
+
+ size_t Slide(lldb::addr_t slide_amount, bool slide_children);
+
+ void Clear() { m_sections.clear(); }
+
+protected:
+ collection m_sections;
+};
+
+class Section : public std::enable_shared_from_this<Section>,
+ public ModuleChild,
+ public UserID,
+ public Flags {
+public:
+ // Create a root section (one that has no parent)
+ Section(const lldb::ModuleSP &module_sp, ObjectFile *obj_file,
+ lldb::user_id_t sect_id, ConstString name,
+ lldb::SectionType sect_type, lldb::addr_t file_vm_addr,
+ lldb::addr_t vm_size, lldb::offset_t file_offset,
+ lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
+ uint32_t target_byte_size = 1);
+
+ // Create a section that is a child of parent_section_sp
+ Section(const lldb::SectionSP &parent_section_sp, // NULL for top level
+ // sections, non-NULL for
+ // child sections
+ const lldb::ModuleSP &module_sp, ObjectFile *obj_file,
+ lldb::user_id_t sect_id, ConstString name,
+ lldb::SectionType sect_type, lldb::addr_t file_vm_addr,
+ lldb::addr_t vm_size, lldb::offset_t file_offset,
+ lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
+ uint32_t target_byte_size = 1);
+
+ ~Section();
+
+ static int Compare(const Section &a, const Section &b);
+
+ bool ContainsFileAddress(lldb::addr_t vm_addr) const;
+
+ SectionList &GetChildren() { return m_children; }
+
+ const SectionList &GetChildren() const { return m_children; }
+
+ void Dump(Stream *s, Target *target, uint32_t depth) const;
+
+ void DumpName(Stream *s) const;
+
+ lldb::addr_t GetLoadBaseAddress(Target *target) const;
+
+ bool ResolveContainedAddress(lldb::addr_t offset, Address &so_addr,
+ bool allow_section_end = false) const;
+
+ lldb::offset_t GetFileOffset() const { return m_file_offset; }
+
+ void SetFileOffset(lldb::offset_t file_offset) {
+ m_file_offset = file_offset;
+ }
+
+ lldb::offset_t GetFileSize() const { return m_file_size; }
+
+ void SetFileSize(lldb::offset_t file_size) { m_file_size = file_size; }
+
+ lldb::addr_t GetFileAddress() const;
+
+ bool SetFileAddress(lldb::addr_t file_addr);
+
+ lldb::addr_t GetOffset() const;
+
+ lldb::addr_t GetByteSize() const { return m_byte_size; }
+
+ void SetByteSize(lldb::addr_t byte_size) { m_byte_size = byte_size; }
+
+ bool IsFake() const { return m_fake; }
+
+ void SetIsFake(bool fake) { m_fake = fake; }
+
+ bool IsEncrypted() const { return m_encrypted; }
+
+ void SetIsEncrypted(bool b) { m_encrypted = b; }
+
+ bool IsDescendant(const Section *section);
+
+ ConstString GetName() const { return m_name; }
+
+ bool Slide(lldb::addr_t slide_amount, bool slide_children);
+
+ lldb::SectionType GetType() const { return m_type; }
+
+ const char *GetTypeAsCString() const;
+
+ lldb::SectionSP GetParent() const { return m_parent_wp.lock(); }
+
+ bool IsThreadSpecific() const { return m_thread_specific; }
+
+ void SetIsThreadSpecific(bool b) { m_thread_specific = b; }
+
+ /// Get the permissions as OR'ed bits from lldb::Permissions
+ uint32_t GetPermissions() const;
+
+ /// Set the permissions using bits OR'ed from lldb::Permissions
+ void SetPermissions(uint32_t permissions);
+
+ ObjectFile *GetObjectFile() { return m_obj_file; }
+ const ObjectFile *GetObjectFile() const { return m_obj_file; }
+
+ /// Read the section data from the object file that the section
+ /// resides in.
+ ///
+ /// \param[in] dst
+ /// Where to place the data
+ ///
+ /// \param[in] dst_len
+ /// How many bytes of section data to read
+ ///
+ /// \param[in] offset
+ /// The offset in bytes within this section's data at which to
+ /// start copying data from.
+ ///
+ /// \return
+ /// The number of bytes read from the section, or zero if the
+ /// section has no data or \a offset is not a valid offset
+ /// in this section.
+ lldb::offset_t GetSectionData(void *dst, lldb::offset_t dst_len,
+ lldb::offset_t offset = 0);
+
+ /// Get the shared reference to the section data from the object
+ /// file that the section resides in. No copies of the data will be
+ /// make unless the object file has been read from memory. If the
+ /// object file is on disk, it will shared the mmap data for the
+ /// entire object file.
+ ///
+ /// \param[in] data
+ /// Where to place the data, address byte size, and byte order
+ ///
+ /// \return
+ /// The number of bytes read from the section, or zero if the
+ /// section has no data or \a offset is not a valid offset
+ /// in this section.
+ lldb::offset_t GetSectionData(DataExtractor &data);
+
+ uint32_t GetLog2Align() { return m_log2align; }
+
+ void SetLog2Align(uint32_t align) { m_log2align = align; }
+
+ // Get the number of host bytes required to hold a target byte
+ uint32_t GetTargetByteSize() const { return m_target_byte_size; }
+
+ bool IsRelocated() const { return m_relocated; }
+
+ void SetIsRelocated(bool b) { m_relocated = b; }
+
+protected:
+ ObjectFile *m_obj_file; // The object file that data for this section should
+ // be read from
+ lldb::SectionType m_type; // The type of this section
+ lldb::SectionWP m_parent_wp; // Weak pointer to parent section
+ ConstString m_name; // Name of this section
+ lldb::addr_t m_file_addr; // The absolute file virtual address range of this
+ // section if m_parent == NULL,
+ // offset from parent file virtual address if m_parent != NULL
+ lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in
+ // memory at runtime
+ lldb::offset_t m_file_offset; // Object file offset (if any)
+ lldb::offset_t m_file_size; // Object file size (can be smaller than
+ // m_byte_size for zero filled sections...)
+ uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be
+ // aligned to 2^m_log2align)
+ SectionList m_children; // Child sections
+ bool m_fake : 1, // If true, then this section only can contain the address if
+ // one of its
+ // children contains an address. This allows for gaps between the
+ // children that are contained in the address range for this section, but
+ // do not produce hits unless the children contain the address.
+ m_encrypted : 1, // Set to true if the contents are encrypted
+ m_thread_specific : 1, // This section is thread specific
+ m_readable : 1, // If this section has read permissions
+ m_writable : 1, // If this section has write permissions
+ m_executable : 1, // If this section has executable permissions
+ m_relocated : 1; // If this section has had relocations applied
+ uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size.
+ // This is specified as
+ // as a multiple number of a host bytes
+private:
+ DISALLOW_COPY_AND_ASSIGN(Section);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Section_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h b/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h
new file mode 100644
index 000000000000..bca817750d8d
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/SourceManager.h
@@ -0,0 +1,167 @@
+//===-- SourceManager.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_SourceManager_h_
+#define liblldb_SourceManager_h_
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+
+#include "llvm/Support/Chrono.h"
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <stddef.h>
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+class RegularExpression;
+class Stream;
+class SymbolContextList;
+class Target;
+
+class SourceManager {
+public:
+ class File {
+ friend bool operator==(const SourceManager::File &lhs,
+ const SourceManager::File &rhs);
+
+ public:
+ File(const FileSpec &file_spec, Target *target);
+ File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp);
+ ~File() = default;
+
+ void UpdateIfNeeded();
+
+ size_t DisplaySourceLines(uint32_t line, llvm::Optional<size_t> column,
+ uint32_t context_before, uint32_t context_after,
+ Stream *s);
+ void FindLinesMatchingRegex(RegularExpression &regex, uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines);
+
+ bool GetLine(uint32_t line_no, std::string &buffer);
+
+ uint32_t GetLineOffset(uint32_t line);
+
+ bool LineIsValid(uint32_t line);
+
+ bool FileSpecMatches(const FileSpec &file_spec);
+
+ const FileSpec &GetFileSpec() { return m_file_spec; }
+
+ uint32_t GetSourceMapModificationID() const { return m_source_map_mod_id; }
+
+ const char *PeekLineData(uint32_t line);
+
+ uint32_t GetLineLength(uint32_t line, bool include_newline_chars);
+
+ uint32_t GetNumLines();
+
+ protected:
+ bool CalculateLineOffsets(uint32_t line = UINT32_MAX);
+
+ FileSpec m_file_spec_orig; // The original file spec that was used (can be
+ // different from m_file_spec)
+ FileSpec m_file_spec; // The actually file spec being used (if the target
+ // has source mappings, this might be different from
+ // m_file_spec_orig)
+
+ // Keep the modification time that this file data is valid for
+ llvm::sys::TimePoint<> m_mod_time;
+
+ // If the target uses path remappings, be sure to clear our notion of a
+ // source file if the path modification ID changes
+ uint32_t m_source_map_mod_id = 0;
+ lldb::DataBufferSP m_data_sp;
+ typedef std::vector<uint32_t> LineOffsets;
+ LineOffsets m_offsets;
+ lldb::DebuggerWP m_debugger_wp;
+
+ private:
+ void CommonInitializer(const FileSpec &file_spec, Target *target);
+ };
+
+ typedef std::shared_ptr<File> FileSP;
+
+ // The SourceFileCache class separates the source manager from the cache of
+ // source files, so the cache can be stored in the Debugger, but the source
+ // managers can be per target.
+ class SourceFileCache {
+ public:
+ SourceFileCache() = default;
+ ~SourceFileCache() = default;
+
+ void AddSourceFile(const FileSP &file_sp);
+ FileSP FindSourceFile(const FileSpec &file_spec) const;
+
+ protected:
+ typedef std::map<FileSpec, FileSP> FileCache;
+ FileCache m_file_cache;
+ };
+
+ // Constructors and Destructors
+ // A source manager can be made with a non-null target, in which case it can
+ // use the path remappings to find
+ // source files that are not in their build locations. With no target it
+ // won't be able to do this.
+ SourceManager(const lldb::DebuggerSP &debugger_sp);
+ SourceManager(const lldb::TargetSP &target_sp);
+
+ ~SourceManager();
+
+ FileSP GetLastFile() { return m_last_file_sp; }
+
+ size_t
+ DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line,
+ uint32_t column, uint32_t context_before,
+ uint32_t context_after,
+ const char *current_line_cstr, Stream *s,
+ const SymbolContextList *bp_locs = nullptr);
+
+ // This variant uses the last file we visited.
+ size_t DisplaySourceLinesWithLineNumbersUsingLastFile(
+ uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
+ const char *current_line_cstr, Stream *s,
+ const SymbolContextList *bp_locs = nullptr);
+
+ size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse,
+ const SymbolContextList *bp_locs = nullptr);
+
+ bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line);
+
+ bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line);
+
+ bool DefaultFileAndLineSet() { return (m_last_file_sp.get() != nullptr); }
+
+ void FindLinesMatchingRegex(FileSpec &file_spec, RegularExpression &regex,
+ uint32_t start_line, uint32_t end_line,
+ std::vector<uint32_t> &match_lines);
+
+ FileSP GetFile(const FileSpec &file_spec);
+
+protected:
+ FileSP m_last_file_sp;
+ uint32_t m_last_line;
+ uint32_t m_last_count;
+ bool m_default_set;
+ lldb::TargetWP m_target_wp;
+ lldb::DebuggerWP m_debugger_wp;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(SourceManager);
+};
+
+bool operator==(const SourceManager::File &lhs, const SourceManager::File &rhs);
+
+} // namespace lldb_private
+
+#endif // liblldb_SourceManager_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h
new file mode 100644
index 000000000000..6237e12b7d1e
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamAsynchronousIO.h
@@ -0,0 +1,40 @@
+//===-- StreamAsynchronousIO.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_StreamAsynchronousIO_h_
+#define liblldb_StreamAsynchronousIO_h_
+
+#include "lldb/Utility/Stream.h"
+
+#include <string>
+
+#include <stddef.h>
+
+namespace lldb_private {
+class Debugger;
+
+class StreamAsynchronousIO : public Stream {
+public:
+ StreamAsynchronousIO(Debugger &debugger, bool for_stdout);
+
+ ~StreamAsynchronousIO() override;
+
+ void Flush() override;
+
+protected:
+ size_t WriteImpl(const void *src, size_t src_len) override;
+
+private:
+ Debugger &m_debugger;
+ std::string m_data;
+ bool m_for_stdout;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StreamAsynchronousIO_h
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h
new file mode 100644
index 000000000000..6c516519781f
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamBuffer.h
@@ -0,0 +1,54 @@
+//===-- StreamBuffer.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_StreamBuffer_h_
+#define liblldb_StreamBuffer_h_
+
+#include "lldb/Utility/Stream.h"
+#include "llvm/ADT/SmallVector.h"
+#include <stdio.h>
+#include <string>
+
+namespace lldb_private {
+
+template <unsigned N> class StreamBuffer : public Stream {
+public:
+ StreamBuffer() : Stream(0, 4, lldb::eByteOrderBig), m_packet() {}
+
+ StreamBuffer(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order)
+ : Stream(flags, addr_size, byte_order), m_packet() {}
+
+ ~StreamBuffer() override {}
+
+ void Flush() override {
+ // Nothing to do when flushing a buffer based stream...
+ }
+
+ void Clear() { m_packet.clear(); }
+
+ // Beware, this might not be NULL terminated as you can expect from
+ // StringString as there may be random bits in the llvm::SmallVector. If you
+ // are using this class to create a C string, be sure the call PutChar ('\0')
+ // after you have created your string, or use StreamString.
+ const char *GetData() const { return m_packet.data(); }
+
+ size_t GetSize() const { return m_packet.size(); }
+
+protected:
+ llvm::SmallVector<char, N> m_packet;
+
+ size_t WriteImpl(const void *s, size_t length) override {
+ if (s && length)
+ m_packet.append((const char *)s, ((const char *)s) + length);
+ return length;
+ }
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_StreamBuffer_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h b/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h
new file mode 100644
index 000000000000..712b289aa8d9
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/StreamFile.h
@@ -0,0 +1,62 @@
+//===-- StreamFile.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_StreamFile_h_
+#define liblldb_StreamFile_h_
+
+#include "lldb/Host/File.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+
+#include <stdint.h>
+#include <stdio.h>
+
+namespace lldb_private {
+
+class StreamFile : public Stream {
+public:
+ // Constructors and Destructors
+ StreamFile();
+
+ StreamFile(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order);
+
+ StreamFile(int fd, bool transfer_ownership);
+
+ StreamFile(const char *path);
+
+ 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_sp; }
+
+ const File &GetFile() const { return *m_file_sp; }
+
+ std::shared_ptr<File> GetFileSP() { return m_file_sp; }
+
+ void Flush() override;
+
+
+protected:
+ // Classes that inherit from StreamFile can see and modify these
+ std::shared_ptr<File> m_file_sp; // never NULL
+ size_t WriteImpl(const void *s, size_t length) override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(StreamFile);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StreamFile_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h
new file mode 100644
index 000000000000..c66e4736dc26
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h
@@ -0,0 +1,156 @@
+//===-- StructuredDataImpl.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_StructuredDataImpl_h_
+#define liblldb_StructuredDataImpl_h_
+
+#include "lldb/Target/StructuredDataPlugin.h"
+#include "lldb/Utility/Event.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StructuredData.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringRef.h"
+
+#pragma mark--
+#pragma mark StructuredDataImpl
+
+namespace lldb_private {
+
+class StructuredDataImpl {
+public:
+ StructuredDataImpl() : m_plugin_wp(), m_data_sp() {}
+
+ StructuredDataImpl(const StructuredDataImpl &rhs) = default;
+
+ StructuredDataImpl(const lldb::EventSP &event_sp)
+ : m_plugin_wp(
+ EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
+ m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) {
+ }
+
+ ~StructuredDataImpl() = default;
+
+ StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default;
+
+ bool IsValid() const { return m_data_sp.get() != nullptr; }
+
+ void Clear() {
+ m_plugin_wp.reset();
+ m_data_sp.reset();
+ }
+
+ Status GetAsJSON(Stream &stream) const {
+ Status error;
+
+ if (!m_data_sp) {
+ error.SetErrorString("No structured data.");
+ return error;
+ }
+
+ llvm::json::OStream s(stream.AsRawOstream());
+ m_data_sp->Serialize(s);
+ return error;
+ }
+
+ Status GetDescription(Stream &stream) const {
+ Status error;
+
+ if (!m_data_sp) {
+ error.SetErrorString("Cannot pretty print structured data: "
+ "no data to print.");
+ return error;
+ }
+
+ // Grab the plugin.
+ auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp);
+ if (!plugin_sp) {
+ error.SetErrorString("Cannot pretty print structured data: "
+ "plugin doesn't exist.");
+ return error;
+ }
+
+ // Get the data's description.
+ return plugin_sp->GetDescription(m_data_sp, stream);
+ }
+
+ StructuredData::ObjectSP GetObjectSP() { return m_data_sp; }
+
+ void SetObjectSP(const StructuredData::ObjectSP &obj) { m_data_sp = obj; }
+
+ lldb::StructuredDataType GetType() const {
+ return (m_data_sp ? m_data_sp->GetType() :
+ lldb::eStructuredDataTypeInvalid);
+ }
+
+ size_t GetSize() const {
+ if (!m_data_sp)
+ return 0;
+
+ if (m_data_sp->GetType() == lldb::eStructuredDataTypeDictionary) {
+ auto dict = m_data_sp->GetAsDictionary();
+ return (dict->GetSize());
+ } else if (m_data_sp->GetType() == lldb::eStructuredDataTypeArray) {
+ auto array = m_data_sp->GetAsArray();
+ return (array->GetSize());
+ } else
+ return 0;
+ }
+
+ StructuredData::ObjectSP GetValueForKey(const char *key) const {
+ if (m_data_sp) {
+ auto dict = m_data_sp->GetAsDictionary();
+ if (dict)
+ return dict->GetValueForKey(llvm::StringRef(key));
+ }
+ return StructuredData::ObjectSP();
+ }
+
+ StructuredData::ObjectSP GetItemAtIndex(size_t idx) const {
+ if (m_data_sp) {
+ auto array = m_data_sp->GetAsArray();
+ if (array)
+ return array->GetItemAtIndex(idx);
+ }
+ return StructuredData::ObjectSP();
+ }
+
+ uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
+ return (m_data_sp ? m_data_sp->GetIntegerValue(fail_value) : fail_value);
+ }
+
+ double GetFloatValue(double fail_value = 0.0) const {
+ return (m_data_sp ? m_data_sp->GetFloatValue(fail_value) : fail_value);
+ }
+
+ bool GetBooleanValue(bool fail_value = false) const {
+ return (m_data_sp ? m_data_sp->GetBooleanValue(fail_value) : fail_value);
+ }
+
+ size_t GetStringValue(char *dst, size_t dst_len) const {
+ if (!m_data_sp)
+ return 0;
+
+ llvm::StringRef result = m_data_sp->GetStringValue();
+ if (result.empty())
+ return 0;
+
+ if (!dst || !dst_len) {
+ char s[1];
+ return (::snprintf(s, 1, "%s", result.data()));
+ }
+ return (::snprintf(dst, dst_len, "%s", result.data()));
+ }
+
+private:
+ lldb::StructuredDataPluginWP m_plugin_wp;
+ StructuredData::ObjectSP m_data_sp;
+};
+} // namespace lldb_private
+#endif
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseMap.h b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseMap.h
new file mode 100644
index 000000000000..c485b91acb47
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseMap.h
@@ -0,0 +1,65 @@
+//===-- ThreadSafeDenseMap.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_ThreadSafeDenseMap_h_
+#define liblldb_ThreadSafeDenseMap_h_
+
+#include <mutex>
+
+#include "llvm/ADT/DenseMap.h"
+
+
+namespace lldb_private {
+
+template <typename _KeyType, typename _ValueType,
+ typename _MutexType = std::mutex>
+class ThreadSafeDenseMap {
+public:
+ typedef llvm::DenseMap<_KeyType, _ValueType> LLVMMapType;
+
+ ThreadSafeDenseMap(unsigned map_initial_capacity = 0)
+ : m_map(map_initial_capacity), m_mutex() {}
+
+ void Insert(_KeyType k, _ValueType v) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ m_map.insert(std::make_pair(k, v));
+ }
+
+ void Erase(_KeyType k) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ m_map.erase(k);
+ }
+
+ _ValueType Lookup(_KeyType k) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ return m_map.lookup(k);
+ }
+
+ bool Lookup(_KeyType k, _ValueType &v) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ auto iter = m_map.find(k), end = m_map.end();
+ if (iter == end)
+ return false;
+ v = iter->second;
+ return true;
+ }
+
+ void Clear() {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ m_map.clear();
+ }
+
+protected:
+ LLVMMapType m_map;
+ _MutexType m_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSafeSTLMap_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseSet.h b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseSet.h
new file mode 100644
index 000000000000..fbc8d3fb02f8
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeDenseSet.h
@@ -0,0 +1,55 @@
+//===-- ThreadSafeDenseSet.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_ThreadSafeDenseSet_h_
+#define liblldb_ThreadSafeDenseSet_h_
+
+#include <mutex>
+
+#include "llvm/ADT/DenseSet.h"
+
+
+namespace lldb_private {
+
+template <typename _ElementType, typename _MutexType = std::mutex>
+class ThreadSafeDenseSet {
+public:
+ typedef llvm::DenseSet<_ElementType> LLVMSetType;
+
+ ThreadSafeDenseSet(unsigned set_initial_capacity = 0)
+ : m_set(set_initial_capacity), m_mutex() {}
+
+ void Insert(_ElementType e) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ m_set.insert(e);
+ }
+
+ void Erase(_ElementType e) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ m_set.erase(e);
+ }
+
+ bool Lookup(_ElementType e) {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ return (m_set.count(e) > 0);
+ }
+
+ void Clear() {
+ std::lock_guard<_MutexType> guard(m_mutex);
+ m_set.clear();
+ }
+
+protected:
+ LLVMSetType m_set;
+ _MutexType m_mutex;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSafeDenseSet_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLMap.h b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLMap.h
new file mode 100644
index 000000000000..df0208cd49b3
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLMap.h
@@ -0,0 +1,128 @@
+//===-- ThreadSafeSTLMap.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_ThreadSafeSTLMap_h_
+#define liblldb_ThreadSafeSTLMap_h_
+
+#include <map>
+#include <mutex>
+
+#include "lldb/lldb-defines.h"
+
+namespace lldb_private {
+
+template <typename _Key, typename _Tp> class ThreadSafeSTLMap {
+public:
+ typedef std::map<_Key, _Tp> collection;
+ typedef typename collection::iterator iterator;
+ typedef typename collection::const_iterator const_iterator;
+ // Constructors and Destructors
+ ThreadSafeSTLMap() : m_collection(), m_mutex() {}
+
+ ~ThreadSafeSTLMap() {}
+
+ bool IsEmpty() const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.empty();
+ }
+
+ void Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.clear();
+ }
+
+ size_t Erase(const _Key &key) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return EraseNoLock(key);
+ }
+
+ size_t EraseNoLock(const _Key &key) { return m_collection.erase(key); }
+
+ bool GetValueForKey(const _Key &key, _Tp &value) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return GetValueForKeyNoLock(key, value);
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ bool GetValueForKeyNoLock(const _Key &key, _Tp &value) const {
+ const_iterator pos = m_collection.find(key);
+ if (pos != m_collection.end()) {
+ value = pos->second;
+ return true;
+ }
+ return false;
+ }
+
+ bool GetFirstKeyForValue(const _Tp &value, _Key &key) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return GetFirstKeyForValueNoLock(value, key);
+ }
+
+ bool GetFirstKeyForValueNoLock(const _Tp &value, _Key &key) const {
+ const_iterator pos, end = m_collection.end();
+ for (pos = m_collection.begin(); pos != end; ++pos) {
+ if (pos->second == value) {
+ key = pos->first;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool LowerBound(const _Key &key, _Key &match_key, _Tp &match_value,
+ bool decrement_if_not_equal) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return LowerBoundNoLock(key, match_key, match_value,
+ decrement_if_not_equal);
+ }
+
+ bool LowerBoundNoLock(const _Key &key, _Key &match_key, _Tp &match_value,
+ bool decrement_if_not_equal) const {
+ const_iterator pos = m_collection.lower_bound(key);
+ if (pos != m_collection.end()) {
+ match_key = pos->first;
+ if (decrement_if_not_equal && key != match_key &&
+ pos != m_collection.begin()) {
+ --pos;
+ match_key = pos->first;
+ }
+ match_value = pos->second;
+ return true;
+ }
+ return false;
+ }
+
+ iterator lower_bound_unsafe(const _Key &key) {
+ return m_collection.lower_bound(key);
+ }
+
+ void SetValueForKey(const _Key &key, const _Tp &value) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ SetValueForKeyNoLock(key, value);
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ void SetValueForKeyNoLock(const _Key &key, const _Tp &value) {
+ m_collection[key] = value;
+ }
+
+ std::recursive_mutex &GetMutex() { return m_mutex; }
+
+private:
+ collection m_collection;
+ mutable std::recursive_mutex m_mutex;
+
+ // For ThreadSafeSTLMap only
+ DISALLOW_COPY_AND_ASSIGN(ThreadSafeSTLMap);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSafeSTLMap_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLVector.h b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLVector.h
new file mode 100644
index 000000000000..e1666a69ef7e
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeSTLVector.h
@@ -0,0 +1,72 @@
+//===-- ThreadSafeSTLVector.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_ThreadSafeSTLVector_h_
+#define liblldb_ThreadSafeSTLVector_h_
+
+#include <mutex>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+
+namespace lldb_private {
+
+template <typename _Object> class ThreadSafeSTLVector {
+public:
+ typedef std::vector<_Object> collection;
+ typedef typename collection::iterator iterator;
+ typedef typename collection::const_iterator const_iterator;
+ // Constructors and Destructors
+ ThreadSafeSTLVector() : m_collection(), m_mutex() {}
+
+ ~ThreadSafeSTLVector() = default;
+
+ bool IsEmpty() const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.empty();
+ }
+
+ void Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.clear();
+ }
+
+ size_t GetCount() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.size();
+ }
+
+ void AppendObject(_Object &object) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_collection.push_back(object);
+ }
+
+ _Object GetObject(size_t index) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_collection.at(index);
+ }
+
+ void SetObject(size_t index, const _Object &object) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_collection.at(index) = object;
+ }
+
+ std::recursive_mutex &GetMutex() { return m_mutex; }
+
+private:
+ collection m_collection;
+ mutable std::recursive_mutex m_mutex;
+
+ // For ThreadSafeSTLVector only
+ DISALLOW_COPY_AND_ASSIGN(ThreadSafeSTLVector);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSafeSTLVector_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h
new file mode 100644
index 000000000000..91f96814363f
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ThreadSafeValue.h
@@ -0,0 +1,61 @@
+//===-- ThreadSafeValue.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_ThreadSafeValue_h_
+#define liblldb_ThreadSafeValue_h_
+
+
+#include <mutex>
+
+#include "lldb/lldb-defines.h"
+
+namespace lldb_private {
+
+template <class T> class ThreadSafeValue {
+public:
+ // Constructors and Destructors
+ ThreadSafeValue() : m_value(), m_mutex() {}
+
+ ThreadSafeValue(const T &value) : m_value(value), m_mutex() {}
+
+ ~ThreadSafeValue() {}
+
+ T GetValue() const {
+ T value;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ value = m_value;
+ }
+ return value;
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ const T &GetValueNoLock() const { return m_value; }
+
+ void SetValue(const T &value) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_value = value;
+ }
+
+ // Call this if you have already manually locked the mutex using the
+ // GetMutex() accessor
+ void SetValueNoLock(const T &value) { m_value = value; }
+
+ std::recursive_mutex &GetMutex() { return m_mutex; }
+
+private:
+ T m_value;
+ mutable std::recursive_mutex m_mutex;
+
+ // For ThreadSafeValue only
+ DISALLOW_COPY_AND_ASSIGN(ThreadSafeValue);
+};
+
+} // namespace lldb_private
+#endif // liblldb_ThreadSafeValue_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/UniqueCStringMap.h b/contrib/llvm-project/lldb/include/lldb/Core/UniqueCStringMap.h
new file mode 100644
index 000000000000..9949bd45f4fa
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/UniqueCStringMap.h
@@ -0,0 +1,207 @@
+//===-- UniqueCStringMap.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_UniqueCStringMap_h_
+#define liblldb_UniqueCStringMap_h_
+
+#include <algorithm>
+#include <vector>
+
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegularExpression.h"
+
+namespace lldb_private {
+
+// Templatized uniqued string map.
+//
+// This map is useful for mapping unique C string names to values of type T.
+// Each "const char *" name added must be unique for a given
+// C string value. ConstString::GetCString() can provide such strings.
+// Any other string table that has guaranteed unique values can also be used.
+template <typename T> class UniqueCStringMap {
+public:
+ struct Entry {
+ Entry(ConstString cstr, const T &v) : cstring(cstr), value(v) {}
+
+ ConstString cstring;
+ T value;
+ };
+
+ // Call this function multiple times to add a bunch of entries to this map,
+ // then later call UniqueCStringMap<T>::Sort() before doing any searches by
+ // name.
+ void Append(ConstString unique_cstr, const T &value) {
+ m_map.push_back(typename UniqueCStringMap<T>::Entry(unique_cstr, value));
+ }
+
+ void Append(const Entry &e) { m_map.push_back(e); }
+
+ void Clear() { m_map.clear(); }
+
+ // Get an entries by index in a variety of forms.
+ //
+ // The caller is responsible for ensuring that the collection does not change
+ // during while using the returned values.
+ bool GetValueAtIndex(uint32_t idx, T &value) const {
+ if (idx < m_map.size()) {
+ value = m_map[idx].value;
+ return true;
+ }
+ return false;
+ }
+
+ ConstString GetCStringAtIndexUnchecked(uint32_t idx) const {
+ return m_map[idx].cstring;
+ }
+
+ // Use this function if you have simple types in your map that you can easily
+ // copy when accessing values by index.
+ T GetValueAtIndexUnchecked(uint32_t idx) const { return m_map[idx].value; }
+
+ // Use this function if you have complex types in your map that you don't
+ // want to copy when accessing values by index.
+ const T &GetValueRefAtIndexUnchecked(uint32_t idx) const {
+ return m_map[idx].value;
+ }
+
+ ConstString GetCStringAtIndex(uint32_t idx) const {
+ return ((idx < m_map.size()) ? m_map[idx].cstring : ConstString());
+ }
+
+ // Find the value for the unique string in the map.
+ //
+ // Return the value for \a unique_cstr if one is found, return \a fail_value
+ // otherwise. This method works well for simple type
+ // T values and only if there is a sensible failure value that can
+ // be returned and that won't match any existing values.
+ T Find(ConstString unique_cstr, T fail_value) const {
+ auto pos = llvm::lower_bound(m_map, unique_cstr, Compare());
+ if (pos != m_map.end() && pos->cstring == unique_cstr)
+ return pos->value;
+ return fail_value;
+ }
+
+ // Get a pointer to the first entry that matches "name". nullptr will be
+ // returned if there is no entry that matches "name".
+ //
+ // The caller is responsible for ensuring that the collection does not change
+ // during while using the returned pointer.
+ const Entry *FindFirstValueForName(ConstString unique_cstr) const {
+ auto pos = llvm::lower_bound(m_map, unique_cstr, Compare());
+ if (pos != m_map.end() && pos->cstring == unique_cstr)
+ return &(*pos);
+ return nullptr;
+ }
+
+ // Get a pointer to the next entry that matches "name" from a previously
+ // returned Entry pointer. nullptr will be returned if there is no subsequent
+ // entry that matches "name".
+ //
+ // The caller is responsible for ensuring that the collection does not change
+ // during while using the returned pointer.
+ const Entry *FindNextValueForName(const Entry *entry_ptr) const {
+ if (!m_map.empty()) {
+ const Entry *first_entry = &m_map[0];
+ const Entry *after_last_entry = first_entry + m_map.size();
+ const Entry *next_entry = entry_ptr + 1;
+ if (first_entry <= next_entry && next_entry < after_last_entry) {
+ if (next_entry->cstring == entry_ptr->cstring)
+ return next_entry;
+ }
+ }
+ return nullptr;
+ }
+
+ size_t GetValues(ConstString unique_cstr, std::vector<T> &values) const {
+ const size_t start_size = values.size();
+
+ for (const Entry &entry : llvm::make_range(std::equal_range(
+ m_map.begin(), m_map.end(), unique_cstr, Compare())))
+ values.push_back(entry.value);
+
+ return values.size() - start_size;
+ }
+
+ size_t GetValues(const RegularExpression &regex,
+ std::vector<T> &values) const {
+ const size_t start_size = values.size();
+
+ const_iterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; ++pos) {
+ if (regex.Execute(pos->cstring.GetCString()))
+ values.push_back(pos->value);
+ }
+
+ return values.size() - start_size;
+ }
+
+ // Get the total number of entries in this map.
+ size_t GetSize() const { return m_map.size(); }
+
+ // Returns true if this map is empty.
+ bool IsEmpty() const { return m_map.empty(); }
+
+ // Reserve memory for at least "n" entries in the map. This is useful to call
+ // when you know you will be adding a lot of entries using
+ // UniqueCStringMap::Append() (which should be followed by a call to
+ // UniqueCStringMap::Sort()) or to UniqueCStringMap::Insert().
+ void Reserve(size_t n) { m_map.reserve(n); }
+
+ // Sort the unsorted contents in this map. A typical code flow would be:
+ // size_t approximate_num_entries = ....
+ // UniqueCStringMap<uint32_t> my_map;
+ // my_map.Reserve (approximate_num_entries);
+ // for (...)
+ // {
+ // my_map.Append (UniqueCStringMap::Entry(GetName(...), GetValue(...)));
+ // }
+ // my_map.Sort();
+ void Sort() { llvm::sort(m_map.begin(), m_map.end(), Compare()); }
+
+ // Since we are using a vector to contain our items it will always double its
+ // memory consumption as things are added to the vector, so if you intend to
+ // keep a UniqueCStringMap around and have a lot of entries in the map, you
+ // will want to call this function to create a new vector and copy _only_ the
+ // exact size needed as part of the finalization of the string map.
+ void SizeToFit() {
+ if (m_map.size() < m_map.capacity()) {
+ collection temp(m_map.begin(), m_map.end());
+ m_map.swap(temp);
+ }
+ }
+
+protected:
+ struct Compare {
+ bool operator()(const Entry &lhs, const Entry &rhs) {
+ return operator()(lhs.cstring, rhs.cstring);
+ }
+
+ bool operator()(const Entry &lhs, ConstString rhs) {
+ return operator()(lhs.cstring, rhs);
+ }
+
+ bool operator()(ConstString lhs, const Entry &rhs) {
+ return operator()(lhs, rhs.cstring);
+ }
+
+ // This is only for uniqueness, not lexicographical ordering, so we can
+ // just compare pointers. *However*, comparing pointers from different
+ // allocations is UB, so we need compare their integral values instead.
+ bool operator()(ConstString lhs, ConstString rhs) {
+ return uintptr_t(lhs.GetCString()) < uintptr_t(rhs.GetCString());
+ }
+ };
+ typedef std::vector<Entry> collection;
+ typedef typename collection::iterator iterator;
+ typedef typename collection::const_iterator const_iterator;
+ collection m_map;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UniqueCStringMap_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h b/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h
new file mode 100644
index 000000000000..6ae3bdec1665
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/UserSettingsController.h
@@ -0,0 +1,91 @@
+//====-- UserSettingsController.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_UserSettingsController_h_
+#define liblldb_UserSettingsController_h_
+
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+
+#include "llvm/ADT/StringRef.h"
+
+#include <vector>
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class CommandInterpreter;
+class ConstString;
+class ExecutionContext;
+class Property;
+class Stream;
+}
+
+namespace lldb_private {
+
+class Properties {
+public:
+ Properties() : m_collection_sp() {}
+
+ Properties(const lldb::OptionValuePropertiesSP &collection_sp)
+ : m_collection_sp(collection_sp) {}
+
+ virtual ~Properties() {}
+
+ virtual lldb::OptionValuePropertiesSP GetValueProperties() const {
+ // This function is virtual in case subclasses want to lazily implement
+ // creating the properties.
+ return m_collection_sp;
+ }
+
+ virtual lldb::OptionValueSP GetPropertyValue(const ExecutionContext *exe_ctx,
+ llvm::StringRef property_path,
+ bool will_modify,
+ Status &error) const;
+
+ virtual Status SetPropertyValue(const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ llvm::StringRef property_path,
+ llvm::StringRef value);
+
+ virtual Status DumpPropertyValue(const ExecutionContext *exe_ctx,
+ Stream &strm, llvm::StringRef property_path,
+ uint32_t dump_mask);
+
+ virtual void DumpAllPropertyValues(const ExecutionContext *exe_ctx,
+ Stream &strm, uint32_t dump_mask);
+
+ virtual void DumpAllDescriptions(CommandInterpreter &interpreter,
+ Stream &strm) const;
+
+ size_t Apropos(llvm::StringRef keyword,
+ std::vector<const Property *> &matching_properties) const;
+
+ lldb::OptionValuePropertiesSP GetSubProperty(const ExecutionContext *exe_ctx,
+ ConstString name);
+
+ // We sometimes need to introduce a setting to enable experimental features,
+ // but then we don't want the setting for these to cause errors when the
+ // setting goes away. Add a sub-topic of the settings using this
+ // experimental name, and two things will happen. One is that settings that
+ // don't find the name will not be treated as errors. Also, if you decide to
+ // keep the settings just move them into the containing properties, and we
+ // will auto-forward the experimental settings to the real one.
+ static const char *GetExperimentalSettingsName();
+
+ static bool IsSettingExperimental(llvm::StringRef setting);
+
+protected:
+ lldb::OptionValuePropertiesSP m_collection_sp;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UserSettingsController_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Value.h b/contrib/llvm-project/lldb/include/lldb/Core/Value.h
new file mode 100644
index 000000000000..7b4cc3b71c28
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/Value.h
@@ -0,0 +1,261 @@
+//===-- Value.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_Value_h_
+#define liblldb_Value_h_
+
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Scalar.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-private-types.h"
+
+#include "llvm/ADT/APInt.h"
+
+#include <vector>
+
+#include <stdint.h>
+#include <string.h>
+
+namespace lldb_private {
+class DataExtractor;
+class ExecutionContext;
+class Module;
+class Stream;
+class Type;
+class Variable;
+}
+
+namespace lldb_private {
+
+class Value {
+public:
+ // Values Less than zero are an error, greater than or equal to zero returns
+ // what the Scalar result is.
+ enum ValueType {
+ // m_value contains...
+ // ============================
+ eValueTypeScalar, // raw scalar value
+ eValueTypeVector, // byte array of m_vector.length with endianness of
+ // m_vector.byte_order
+ eValueTypeFileAddress, // file address value
+ eValueTypeLoadAddress, // load address value
+ eValueTypeHostAddress // host address value (for memory in the process that
+ // is using liblldb)
+ };
+
+ enum ContextType // Type that describes Value::m_context
+ {
+ // m_context contains...
+ // ====================
+ eContextTypeInvalid, // undefined
+ eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector
+ // register)
+ eContextTypeLLDBType, // lldb_private::Type *
+ eContextTypeVariable // lldb_private::Variable *
+ };
+
+ const static size_t kMaxByteSize = 32u;
+
+ struct Vector {
+ // The byte array must be big enough to hold vector registers for any
+ // supported target.
+ uint8_t bytes[kMaxByteSize];
+ size_t length;
+ lldb::ByteOrder byte_order;
+
+ Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {}
+
+ Vector(const Vector &vector) { *this = vector; }
+ const Vector &operator=(const Vector &vector) {
+ SetBytes(vector.bytes, vector.length, vector.byte_order);
+ return *this;
+ }
+
+ void Clear() { length = 0; }
+
+ bool SetBytes(const void *bytes, size_t length,
+ lldb::ByteOrder byte_order) {
+ this->length = length;
+ this->byte_order = byte_order;
+ if (length)
+ ::memcpy(this->bytes, bytes,
+ length < kMaxByteSize ? length : kMaxByteSize);
+ return IsValid();
+ }
+
+ bool IsValid() const {
+ return (length > 0 && length < kMaxByteSize &&
+ byte_order != lldb::eByteOrderInvalid);
+ }
+ // Casts a vector, if valid, to an unsigned int of matching or largest
+ // supported size. Truncates to the beginning of the vector if required.
+ // Returns a default constructed Scalar if the Vector data is internally
+ // inconsistent.
+ llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
+ ((type128 *)bytes)->x);
+ Scalar GetAsScalar() const {
+ Scalar scalar;
+ if (IsValid()) {
+ if (length == 1)
+ scalar = *(const uint8_t *)bytes;
+ else if (length == 2)
+ scalar = *(const uint16_t *)bytes;
+ else if (length == 4)
+ scalar = *(const uint32_t *)bytes;
+ else if (length == 8)
+ scalar = *(const uint64_t *)bytes;
+ else if (length >= 16)
+ scalar = rhs;
+ }
+ return scalar;
+ }
+ };
+
+ Value();
+ Value(const Scalar &scalar);
+ Value(const Vector &vector);
+ Value(const void *bytes, int len);
+ Value(const Value &rhs);
+
+ void SetBytes(const void *bytes, int len);
+
+ void AppendBytes(const void *bytes, int len);
+
+ Value &operator=(const Value &rhs);
+
+ const CompilerType &GetCompilerType();
+
+ void SetCompilerType(const CompilerType &compiler_type);
+
+ ValueType GetValueType() const;
+
+ AddressType GetValueAddressType() const;
+
+ ContextType GetContextType() const { return m_context_type; }
+
+ void SetValueType(ValueType value_type) { m_value_type = value_type; }
+
+ void ClearContext() {
+ m_context = nullptr;
+ m_context_type = eContextTypeInvalid;
+ }
+
+ void SetContext(ContextType context_type, void *p) {
+ m_context_type = context_type;
+ m_context = p;
+ if (m_context_type == eContextTypeRegisterInfo) {
+ RegisterInfo *reg_info = GetRegisterInfo();
+ if (reg_info->encoding == lldb::eEncodingVector &&
+ m_vector.byte_order != lldb::eByteOrderInvalid)
+ SetValueType(eValueTypeScalar);
+ }
+ }
+
+ RegisterInfo *GetRegisterInfo() const;
+
+ Type *GetType();
+
+ Scalar &ResolveValue(ExecutionContext *exe_ctx);
+
+ const Scalar &GetScalar() const { return m_value; }
+
+ const Vector &GetVector() const { return m_vector; }
+
+ Scalar &GetScalar() { return m_value; }
+
+ Vector &GetVector() { return m_vector; }
+
+ bool SetVectorBytes(const Vector &vector) {
+ m_vector = vector;
+ return m_vector.IsValid();
+ }
+
+ bool SetVectorBytes(uint8_t *bytes, size_t length,
+ lldb::ByteOrder byte_order) {
+ return m_vector.SetBytes(bytes, length, byte_order);
+ }
+
+ bool SetScalarFromVector() {
+ if (m_vector.IsValid()) {
+ m_value = m_vector.GetAsScalar();
+ return true;
+ }
+ return false;
+ }
+
+ size_t ResizeData(size_t len);
+
+ size_t AppendDataToHostBuffer(const Value &rhs);
+
+ DataBufferHeap &GetBuffer() { return m_data_buffer; }
+
+ const DataBufferHeap &GetBuffer() const { return m_data_buffer; }
+
+ bool ValueOf(ExecutionContext *exe_ctx);
+
+ Variable *GetVariable();
+
+ void Dump(Stream *strm);
+
+ lldb::Format GetValueDefaultFormat();
+
+ uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);
+
+ Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
+ Module *module); // Can be nullptr
+
+ static const char *GetValueTypeAsCString(ValueType context_type);
+
+ static const char *GetContextTypeAsCString(ContextType context_type);
+
+ /// Convert this value's file address to a load address, if possible.
+ void ConvertToLoadAddress(Module *module, Target *target);
+
+ bool GetData(DataExtractor &data);
+
+ void Clear();
+
+protected:
+ Scalar m_value;
+ Vector m_vector;
+ CompilerType m_compiler_type;
+ void *m_context;
+ ValueType m_value_type;
+ ContextType m_context_type;
+ DataBufferHeap m_data_buffer;
+};
+
+class ValueList {
+public:
+ ValueList() : m_values() {}
+
+ ValueList(const ValueList &rhs);
+
+ ~ValueList() = default;
+
+ const ValueList &operator=(const ValueList &rhs);
+
+ // void InsertValue (Value *value, size_t idx);
+ void PushValue(const Value &value);
+
+ size_t GetSize();
+ Value *GetValueAtIndex(size_t idx);
+ void Clear();
+
+private:
+ typedef std::vector<Value> collection;
+
+ collection m_values;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Value_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h
new file mode 100644
index 000000000000..0808b86c67a1
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObject.h
@@ -0,0 +1,1042 @@
+//===-- ValueObject.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_ValueObject_h_
+#define liblldb_ValueObject_h_
+
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/SharedCluster.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/UserID.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <functional>
+#include <initializer_list>
+#include <map>
+#include <mutex>
+#include <string>
+#include <utility>
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class Declaration;
+class DumpValueObjectOptions;
+class EvaluateExpressionOptions;
+class ExecutionContextScope;
+class Log;
+class Scalar;
+class Stream;
+class SymbolContextScope;
+class TypeFormatImpl;
+class TypeSummaryImpl;
+class TypeSummaryOptions;
+
+/// ValueObject:
+///
+/// This abstract class provides an interface to a particular value, be it a
+/// register, a local or global variable,
+/// that is evaluated in some particular scope. The ValueObject also has the
+/// capability of being the "child" of
+/// some other variable object, and in turn of having children.
+/// If a ValueObject is a root variable object - having no parent - then it must
+/// be constructed with respect to some
+/// particular ExecutionContextScope. If it is a child, it inherits the
+/// ExecutionContextScope from its parent.
+/// The ValueObject will update itself if necessary before fetching its value,
+/// summary, object description, etc.
+/// But it will always update itself in the ExecutionContextScope with which it
+/// was originally created.
+
+/// A brief note on life cycle management for ValueObjects. This is a little
+/// tricky because a ValueObject can contain
+/// various other ValueObjects - the Dynamic Value, its children, the
+/// dereference value, etc. Any one of these can be
+/// handed out as a shared pointer, but for that contained value object to be
+/// valid, the root object and potentially other
+/// of the value objects need to stay around.
+/// We solve this problem by handing out shared pointers to the Value Object and
+/// any of its dependents using a shared
+/// ClusterManager. This treats each shared pointer handed out for the entire
+/// cluster as a reference to the whole
+/// cluster. The whole cluster will stay around until the last reference is
+/// released.
+///
+/// The ValueObject mostly handle this automatically, if a value object is made
+/// with a Parent ValueObject, then it adds
+/// itself to the ClusterManager of the parent.
+
+/// It does mean that external to the ValueObjects we should only ever make
+/// available ValueObjectSP's, never ValueObjects
+/// or pointers to them. So all the "Root level" ValueObject derived
+/// constructors should be private, and
+/// should implement a Create function that new's up object and returns a Shared
+/// Pointer that it gets from the GetSP() method.
+///
+/// However, if you are making an derived ValueObject that will be contained in
+/// a parent value object, you should just
+/// hold onto a pointer to it internally, and by virtue of passing the parent
+/// ValueObject into its constructor, it will
+/// be added to the ClusterManager for the parent. Then if you ever hand out a
+/// Shared Pointer to the contained ValueObject,
+/// just do so by calling GetSP() on the contained object.
+
+class ValueObject : public UserID {
+public:
+ enum GetExpressionPathFormat {
+ eGetExpressionPathFormatDereferencePointers = 1,
+ eGetExpressionPathFormatHonorPointers
+ };
+
+ enum ValueObjectRepresentationStyle {
+ eValueObjectRepresentationStyleValue = 1,
+ eValueObjectRepresentationStyleSummary,
+ eValueObjectRepresentationStyleLanguageSpecific,
+ eValueObjectRepresentationStyleLocation,
+ eValueObjectRepresentationStyleChildrenCount,
+ eValueObjectRepresentationStyleType,
+ eValueObjectRepresentationStyleName,
+ eValueObjectRepresentationStyleExpressionPath
+ };
+
+ enum ExpressionPathScanEndReason {
+ eExpressionPathScanEndReasonEndOfString = 1, // out of data to parse
+ eExpressionPathScanEndReasonNoSuchChild, // child element not found
+ eExpressionPathScanEndReasonNoSuchSyntheticChild, // (synthetic) child
+ // element not found
+ eExpressionPathScanEndReasonEmptyRangeNotAllowed, // [] only allowed for
+ // arrays
+ eExpressionPathScanEndReasonDotInsteadOfArrow, // . used when -> should be
+ // used
+ eExpressionPathScanEndReasonArrowInsteadOfDot, // -> used when . should be
+ // used
+ eExpressionPathScanEndReasonFragileIVarNotAllowed, // ObjC ivar expansion
+ // not allowed
+ eExpressionPathScanEndReasonRangeOperatorNotAllowed, // [] not allowed by
+ // options
+ eExpressionPathScanEndReasonRangeOperatorInvalid, // [] not valid on objects
+ // other than scalars,
+ // pointers or arrays
+ eExpressionPathScanEndReasonArrayRangeOperatorMet, // [] is good for arrays,
+ // but I cannot parse it
+ eExpressionPathScanEndReasonBitfieldRangeOperatorMet, // [] is good for
+ // bitfields, but I
+ // cannot parse after
+ // it
+ eExpressionPathScanEndReasonUnexpectedSymbol, // something is malformed in
+ // the expression
+ eExpressionPathScanEndReasonTakingAddressFailed, // impossible to apply &
+ // operator
+ eExpressionPathScanEndReasonDereferencingFailed, // impossible to apply *
+ // operator
+ eExpressionPathScanEndReasonRangeOperatorExpanded, // [] was expanded into a
+ // VOList
+ eExpressionPathScanEndReasonSyntheticValueMissing, // getting the synthetic
+ // children failed
+ eExpressionPathScanEndReasonUnknown = 0xFFFF
+ };
+
+ enum ExpressionPathEndResultType {
+ eExpressionPathEndResultTypePlain = 1, // anything but...
+ eExpressionPathEndResultTypeBitfield, // a bitfield
+ eExpressionPathEndResultTypeBoundedRange, // a range [low-high]
+ eExpressionPathEndResultTypeUnboundedRange, // a range []
+ eExpressionPathEndResultTypeValueObjectList, // several items in a VOList
+ eExpressionPathEndResultTypeInvalid = 0xFFFF
+ };
+
+ enum ExpressionPathAftermath {
+ eExpressionPathAftermathNothing = 1, // just return it
+ eExpressionPathAftermathDereference, // dereference the target
+ eExpressionPathAftermathTakeAddress // take target's address
+ };
+
+ enum ClearUserVisibleDataItems {
+ eClearUserVisibleDataItemsNothing = 1u << 0,
+ eClearUserVisibleDataItemsValue = 1u << 1,
+ eClearUserVisibleDataItemsSummary = 1u << 2,
+ eClearUserVisibleDataItemsLocation = 1u << 3,
+ eClearUserVisibleDataItemsDescription = 1u << 4,
+ eClearUserVisibleDataItemsSyntheticChildren = 1u << 5,
+ eClearUserVisibleDataItemsValidator = 1u << 6,
+ eClearUserVisibleDataItemsAllStrings =
+ eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary |
+ eClearUserVisibleDataItemsLocation |
+ eClearUserVisibleDataItemsDescription,
+ eClearUserVisibleDataItemsAll = 0xFFFF
+ };
+
+ struct GetValueForExpressionPathOptions {
+ enum class SyntheticChildrenTraversal {
+ None,
+ ToSynthetic,
+ FromSynthetic,
+ Both
+ };
+
+ bool m_check_dot_vs_arrow_syntax;
+ bool m_no_fragile_ivar;
+ bool m_allow_bitfields_syntax;
+ SyntheticChildrenTraversal m_synthetic_children_traversal;
+
+ GetValueForExpressionPathOptions(
+ bool dot = false, bool no_ivar = false, bool bitfield = true,
+ SyntheticChildrenTraversal synth_traverse =
+ SyntheticChildrenTraversal::ToSynthetic)
+ : m_check_dot_vs_arrow_syntax(dot), m_no_fragile_ivar(no_ivar),
+ m_allow_bitfields_syntax(bitfield),
+ m_synthetic_children_traversal(synth_traverse) {}
+
+ GetValueForExpressionPathOptions &DoCheckDotVsArrowSyntax() {
+ m_check_dot_vs_arrow_syntax = true;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions &DontCheckDotVsArrowSyntax() {
+ m_check_dot_vs_arrow_syntax = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions &DoAllowFragileIVar() {
+ m_no_fragile_ivar = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions &DontAllowFragileIVar() {
+ m_no_fragile_ivar = true;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions &DoAllowBitfieldSyntax() {
+ m_allow_bitfields_syntax = true;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions &DontAllowBitfieldSyntax() {
+ m_allow_bitfields_syntax = false;
+ return *this;
+ }
+
+ GetValueForExpressionPathOptions &
+ SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse) {
+ m_synthetic_children_traversal = traverse;
+ return *this;
+ }
+
+ static const GetValueForExpressionPathOptions DefaultOptions() {
+ static GetValueForExpressionPathOptions g_default_options;
+
+ return g_default_options;
+ }
+ };
+
+ class EvaluationPoint {
+ public:
+ EvaluationPoint();
+
+ EvaluationPoint(ExecutionContextScope *exe_scope,
+ bool use_selected = false);
+
+ EvaluationPoint(const EvaluationPoint &rhs);
+
+ ~EvaluationPoint();
+
+ const ExecutionContextRef &GetExecutionContextRef() const {
+ return m_exe_ctx_ref;
+ }
+
+ // Set the EvaluationPoint to the values in exe_scope, Return true if the
+ // Evaluation Point changed. Since the ExecutionContextScope is always
+ // going to be valid currently, the Updated Context will also always be
+ // valid.
+
+ // bool
+ // SetContext (ExecutionContextScope *exe_scope);
+
+ void SetIsConstant() {
+ SetUpdated();
+ m_mod_id.SetInvalid();
+ }
+
+ bool IsConstant() const { return !m_mod_id.IsValid(); }
+
+ ProcessModID GetModID() const { return m_mod_id; }
+
+ void SetUpdateID(ProcessModID new_id) { m_mod_id = new_id; }
+
+ void SetNeedsUpdate() { m_needs_update = true; }
+
+ void SetUpdated();
+
+ bool NeedsUpdating(bool accept_invalid_exe_ctx) {
+ SyncWithProcessState(accept_invalid_exe_ctx);
+ return m_needs_update;
+ }
+
+ bool IsValid() {
+ const bool accept_invalid_exe_ctx = false;
+ if (!m_mod_id.IsValid())
+ return false;
+ else if (SyncWithProcessState(accept_invalid_exe_ctx)) {
+ if (!m_mod_id.IsValid())
+ return false;
+ }
+ return true;
+ }
+
+ void SetInvalid() {
+ // Use the stop id to mark us as invalid, leave the thread id and the
+ // stack id around for logging and history purposes.
+ m_mod_id.SetInvalid();
+
+ // Can't update an invalid state.
+ m_needs_update = false;
+ }
+
+ private:
+ bool SyncWithProcessState(bool accept_invalid_exe_ctx);
+
+ ProcessModID m_mod_id; // This is the stop id when this ValueObject was last
+ // evaluated.
+ ExecutionContextRef m_exe_ctx_ref;
+ bool m_needs_update;
+ };
+
+ virtual ~ValueObject();
+
+ const EvaluationPoint &GetUpdatePoint() const { return m_update_point; }
+
+ EvaluationPoint &GetUpdatePoint() { return m_update_point; }
+
+ const ExecutionContextRef &GetExecutionContextRef() const {
+ return m_update_point.GetExecutionContextRef();
+ }
+
+ lldb::TargetSP GetTargetSP() const {
+ return m_update_point.GetExecutionContextRef().GetTargetSP();
+ }
+
+ lldb::ProcessSP GetProcessSP() const {
+ return m_update_point.GetExecutionContextRef().GetProcessSP();
+ }
+
+ lldb::ThreadSP GetThreadSP() const {
+ return m_update_point.GetExecutionContextRef().GetThreadSP();
+ }
+
+ lldb::StackFrameSP GetFrameSP() const {
+ return m_update_point.GetExecutionContextRef().GetFrameSP();
+ }
+
+ void SetNeedsUpdate();
+
+ CompilerType GetCompilerType();
+
+ // this vends a TypeImpl that is useful at the SB API layer
+ virtual TypeImpl GetTypeImpl();
+
+ virtual bool CanProvideValue();
+
+ // Subclasses must implement the functions below.
+ virtual uint64_t GetByteSize() = 0;
+
+ virtual lldb::ValueType GetValueType() const = 0;
+
+ // Subclasses can implement the functions below.
+ virtual ConstString GetTypeName();
+
+ virtual ConstString GetDisplayTypeName();
+
+ virtual ConstString GetQualifiedTypeName();
+
+ virtual lldb::LanguageType GetObjectRuntimeLanguage();
+
+ virtual uint32_t
+ GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr);
+
+ virtual bool IsPointerType();
+
+ virtual bool IsArrayType();
+
+ virtual bool IsScalarType();
+
+ virtual bool IsPointerOrReferenceType();
+
+ virtual bool IsPossibleDynamicType();
+
+ bool IsNilReference();
+
+ bool IsUninitializedReference();
+
+ virtual bool IsBaseClass() { return false; }
+
+ bool IsBaseClass(uint32_t &depth);
+
+ virtual bool IsDereferenceOfParent() { return false; }
+
+ bool IsIntegerType(bool &is_signed);
+
+ virtual bool GetBaseClassPath(Stream &s);
+
+ virtual void GetExpressionPath(
+ Stream &s, bool qualify_cxx_base_classes,
+ GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers);
+
+ lldb::ValueObjectSP GetValueForExpressionPath(
+ llvm::StringRef expression,
+ ExpressionPathScanEndReason *reason_to_stop = nullptr,
+ ExpressionPathEndResultType *final_value_type = nullptr,
+ const GetValueForExpressionPathOptions &options =
+ GetValueForExpressionPathOptions::DefaultOptions(),
+ ExpressionPathAftermath *final_task_on_target = nullptr);
+
+ virtual bool IsInScope() { return true; }
+
+ virtual lldb::offset_t GetByteOffset() { return 0; }
+
+ virtual uint32_t GetBitfieldBitSize() { return 0; }
+
+ virtual uint32_t GetBitfieldBitOffset() { return 0; }
+
+ bool IsBitfield() {
+ return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0);
+ }
+
+ virtual bool IsArrayItemForPointer() { return m_is_array_item_for_pointer; }
+
+ virtual const char *GetValueAsCString();
+
+ virtual bool GetValueAsCString(const lldb_private::TypeFormatImpl &format,
+ std::string &destination);
+
+ bool GetValueAsCString(lldb::Format format, std::string &destination);
+
+ virtual uint64_t GetValueAsUnsigned(uint64_t fail_value,
+ bool *success = nullptr);
+
+ virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = nullptr);
+
+ virtual bool SetValueFromCString(const char *value_str, Status &error);
+
+ // Return the module associated with this value object in case the value is
+ // from an executable file and might have its data in sections of the file.
+ // This can be used for variables.
+ virtual lldb::ModuleSP GetModule();
+
+ ValueObject *GetRoot();
+
+ // Given a ValueObject, loop over itself and its parent, and its parent's
+ // parent, .. until either the given callback returns false, or you end up at
+ // a null pointer
+ ValueObject *FollowParentChain(std::function<bool(ValueObject *)>);
+
+ virtual bool GetDeclaration(Declaration &decl);
+
+ // The functions below should NOT be modified by subclasses
+ const Status &GetError();
+
+ ConstString GetName() const;
+
+ virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create);
+
+ // this will always create the children if necessary
+ lldb::ValueObjectSP GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
+ size_t *index_of_error = nullptr);
+
+ lldb::ValueObjectSP
+ GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t, bool>> idxs,
+ size_t *index_of_error = nullptr);
+
+ // this will always create the children if necessary
+ lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
+ ConstString *name_of_error = nullptr);
+
+ lldb::ValueObjectSP
+ GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString, bool>> names,
+ ConstString *name_of_error = nullptr);
+
+ virtual lldb::ValueObjectSP GetChildMemberWithName(ConstString name,
+ bool can_create);
+
+ virtual size_t GetIndexOfChildWithName(ConstString name);
+
+ size_t GetNumChildren(uint32_t max = UINT32_MAX);
+
+ const Value &GetValue() const;
+
+ Value &GetValue();
+
+ virtual bool ResolveValue(Scalar &scalar);
+
+ // return 'false' whenever you set the error, otherwise callers may assume
+ // true means everything is OK - this will break breakpoint conditions among
+ // potentially a few others
+ virtual bool IsLogicalTrue(Status &error);
+
+ virtual const char *GetLocationAsCString();
+
+ const char *
+ GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown);
+
+ bool
+ GetSummaryAsCString(TypeSummaryImpl *summary_ptr, std::string &destination,
+ lldb::LanguageType lang = lldb::eLanguageTypeUnknown);
+
+ bool GetSummaryAsCString(std::string &destination,
+ const TypeSummaryOptions &options);
+
+ bool GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
+ std::string &destination,
+ const TypeSummaryOptions &options);
+
+ std::pair<TypeValidatorResult, std::string> GetValidationStatus();
+
+ const char *GetObjectDescription();
+
+ bool HasSpecialPrintableRepresentation(
+ ValueObjectRepresentationStyle val_obj_display,
+ lldb::Format custom_format);
+
+ enum class PrintableRepresentationSpecialCases : bool {
+ eDisable = false,
+ eAllow = true
+ };
+
+ bool
+ DumpPrintableRepresentation(Stream &s,
+ ValueObjectRepresentationStyle val_obj_display =
+ eValueObjectRepresentationStyleSummary,
+ lldb::Format custom_format = lldb::eFormatInvalid,
+ PrintableRepresentationSpecialCases special =
+ PrintableRepresentationSpecialCases::eAllow,
+ bool do_dump_error = true);
+ bool GetValueIsValid() const;
+
+ // If you call this on a newly created ValueObject, it will always return
+ // false.
+ bool GetValueDidChange();
+
+ bool UpdateValueIfNeeded(bool update_format = true);
+
+ bool UpdateFormatsIfNeeded();
+
+ lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(this); }
+
+ // Change the name of the current ValueObject. Should *not* be used from a
+ // synthetic child provider as it would change the name of the non synthetic
+ // child as well.
+ void SetName(ConstString name);
+
+ virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
+ AddressType *address_type = nullptr);
+
+ lldb::addr_t GetPointerValue(AddressType *address_type = nullptr);
+
+ lldb::ValueObjectSP GetSyntheticChild(ConstString key) const;
+
+ lldb::ValueObjectSP GetSyntheticArrayMember(size_t index, bool can_create);
+
+ lldb::ValueObjectSP GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
+ bool can_create);
+
+ lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression,
+ bool can_create);
+
+ virtual lldb::ValueObjectSP
+ GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type,
+ bool can_create,
+ ConstString name_const_str = ConstString());
+
+ virtual lldb::ValueObjectSP
+ GetSyntheticBase(uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str = ConstString());
+
+ virtual lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType);
+
+ lldb::DynamicValueType GetDynamicValueType();
+
+ virtual lldb::ValueObjectSP GetStaticValue();
+
+ virtual lldb::ValueObjectSP GetNonSyntheticValue();
+
+ lldb::ValueObjectSP GetSyntheticValue(bool use_synthetic = true);
+
+ virtual bool HasSyntheticValue();
+
+ virtual bool IsSynthetic() { return false; }
+
+ lldb::ValueObjectSP
+ GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue,
+ bool synthValue);
+
+ virtual lldb::ValueObjectSP CreateConstantValue(ConstString name);
+
+ virtual lldb::ValueObjectSP Dereference(Status &error);
+
+ // Creates a copy of the ValueObject with a new name and setting the current
+ // ValueObject as its parent. It should be used when we want to change the
+ // name of a ValueObject without modifying the actual ValueObject itself
+ // (e.g. sythetic child provider).
+ virtual lldb::ValueObjectSP Clone(ConstString new_name);
+
+ virtual lldb::ValueObjectSP AddressOf(Status &error);
+
+ virtual lldb::addr_t GetLiveAddress() { return LLDB_INVALID_ADDRESS; }
+
+ virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad) {}
+
+ virtual lldb::ValueObjectSP Cast(const CompilerType &compiler_type);
+
+ virtual lldb::ValueObjectSP CastPointerType(const char *name,
+ CompilerType &ast_type);
+
+ virtual lldb::ValueObjectSP CastPointerType(const char *name,
+ lldb::TypeSP &type_sp);
+
+ // The backing bits of this value object were updated, clear any descriptive
+ // string, so we know we have to refetch them
+ virtual void ValueUpdated() {
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue |
+ eClearUserVisibleDataItemsSummary |
+ eClearUserVisibleDataItemsDescription);
+ }
+
+ virtual bool IsDynamic() { return false; }
+
+ virtual bool DoesProvideSyntheticValue() { return false; }
+
+ virtual bool IsSyntheticChildrenGenerated();
+
+ virtual void SetSyntheticChildrenGenerated(bool b);
+
+ virtual SymbolContextScope *GetSymbolContextScope();
+
+ void Dump(Stream &s);
+
+ void Dump(Stream &s, const DumpValueObjectOptions &options);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromExpression(llvm::StringRef name,
+ llvm::StringRef expression,
+ const ExecutionContext &exe_ctx);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromExpression(llvm::StringRef name,
+ llvm::StringRef expression,
+ const ExecutionContext &exe_ctx,
+ const EvaluateExpressionOptions &options);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
+ const ExecutionContext &exe_ctx,
+ CompilerType type);
+
+ static lldb::ValueObjectSP
+ CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
+ const ExecutionContext &exe_ctx, CompilerType type);
+
+ void LogValueObject(Log *log);
+
+ void LogValueObject(Log *log, const DumpValueObjectOptions &options);
+
+ lldb::ValueObjectSP Persist();
+
+ // returns true if this is a char* or a char[] if it is a char* and
+ // check_pointer is true, it also checks that the pointer is valid
+ bool IsCStringContainer(bool check_pointer = false);
+
+ std::pair<size_t, bool>
+ ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
+ uint32_t max_length = 0, bool honor_array = true,
+ lldb::Format item_format = lldb::eFormatCharArray);
+
+ virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+ virtual uint64_t GetData(DataExtractor &data, Status &error);
+
+ virtual bool SetData(DataExtractor &data, Status &error);
+
+ virtual bool GetIsConstant() const { return m_update_point.IsConstant(); }
+
+ bool NeedsUpdating() {
+ const bool accept_invalid_exe_ctx =
+ (CanUpdateWithInvalidExecutionContext() == eLazyBoolYes);
+ return m_update_point.NeedsUpdating(accept_invalid_exe_ctx);
+ }
+
+ void SetIsConstant() { m_update_point.SetIsConstant(); }
+
+ lldb::Format GetFormat() const;
+
+ virtual void SetFormat(lldb::Format format) {
+ if (format != m_format)
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue);
+ m_format = format;
+ }
+
+ virtual lldb::LanguageType GetPreferredDisplayLanguage();
+
+ void SetPreferredDisplayLanguage(lldb::LanguageType);
+
+ lldb::TypeSummaryImplSP GetSummaryFormat() {
+ UpdateFormatsIfNeeded();
+ return m_type_summary_sp;
+ }
+
+ void SetSummaryFormat(lldb::TypeSummaryImplSP format) {
+ m_type_summary_sp = format;
+ ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
+ }
+
+ lldb::TypeValidatorImplSP GetValidator() {
+ UpdateFormatsIfNeeded();
+ return m_type_validator_sp;
+ }
+
+ void SetValidator(lldb::TypeValidatorImplSP format) {
+ m_type_validator_sp = format;
+ ClearUserVisibleData(eClearUserVisibleDataItemsValidator);
+ }
+
+ void SetValueFormat(lldb::TypeFormatImplSP format) {
+ m_type_format_sp = format;
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue);
+ }
+
+ lldb::TypeFormatImplSP GetValueFormat() {
+ UpdateFormatsIfNeeded();
+ return m_type_format_sp;
+ }
+
+ void SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp) {
+ if (synth_sp.get() == m_synthetic_children_sp.get())
+ return;
+ ClearUserVisibleData(eClearUserVisibleDataItemsSyntheticChildren);
+ m_synthetic_children_sp = synth_sp;
+ }
+
+ lldb::SyntheticChildrenSP GetSyntheticChildren() {
+ UpdateFormatsIfNeeded();
+ return m_synthetic_children_sp;
+ }
+
+ // Use GetParent for display purposes, but if you want to tell the parent to
+ // update itself then use m_parent. The ValueObjectDynamicValue's parent is
+ // not the correct parent for displaying, they are really siblings, so for
+ // display it needs to route through to its grandparent.
+ virtual ValueObject *GetParent() { return m_parent; }
+
+ virtual const ValueObject *GetParent() const { return m_parent; }
+
+ ValueObject *GetNonBaseClassParent();
+
+ void SetAddressTypeOfChildren(AddressType at) {
+ m_address_type_of_ptr_or_ref_children = at;
+ }
+
+ AddressType GetAddressTypeOfChildren();
+
+ void SetHasCompleteType() { m_did_calculate_complete_objc_class_type = true; }
+
+ /// Find out if a ValueObject might have children.
+ ///
+ /// This call is much more efficient than CalculateNumChildren() as
+ /// it doesn't need to complete the underlying type. This is designed
+ /// to be used in a UI environment in order to detect if the
+ /// disclosure triangle should be displayed or not.
+ ///
+ /// This function returns true for class, union, structure,
+ /// pointers, references, arrays and more. Again, it does so without
+ /// doing any expensive type completion.
+ ///
+ /// \return
+ /// Returns \b true if the ValueObject might have children, or \b
+ /// false otherwise.
+ virtual bool MightHaveChildren();
+
+ virtual lldb::VariableSP GetVariable() { return nullptr; }
+
+ virtual bool IsRuntimeSupportValue();
+
+ virtual uint64_t GetLanguageFlags();
+
+ virtual void SetLanguageFlags(uint64_t flags);
+
+protected:
+ typedef ClusterManager<ValueObject> ValueObjectManager;
+
+ class ChildrenManager {
+ public:
+ ChildrenManager() : m_mutex(), m_children(), m_children_count(0) {}
+
+ bool HasChildAtIndex(size_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return (m_children.find(idx) != m_children.end());
+ }
+
+ ValueObject *GetChildAtIndex(size_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ const auto iter = m_children.find(idx);
+ return ((iter == m_children.end()) ? nullptr : iter->second);
+ }
+
+ void SetChildAtIndex(size_t idx, ValueObject *valobj) {
+ // we do not need to be mutex-protected to make a pair
+ ChildrenPair pair(idx, valobj);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_children.insert(pair);
+ }
+
+ void SetChildrenCount(size_t count) { Clear(count); }
+
+ size_t GetChildrenCount() { return m_children_count; }
+
+ void Clear(size_t new_count = 0) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ m_children_count = new_count;
+ m_children.clear();
+ }
+
+ private:
+ typedef std::map<size_t, ValueObject *> ChildrenMap;
+ typedef ChildrenMap::iterator ChildrenIterator;
+ typedef ChildrenMap::value_type ChildrenPair;
+ std::recursive_mutex m_mutex;
+ ChildrenMap m_children;
+ size_t m_children_count;
+ };
+
+ // Classes that inherit from ValueObject can see and modify these
+ ValueObject
+ *m_parent; // The parent value object, or nullptr if this has no parent
+ ValueObject *m_root; // The root of the hierarchy for this ValueObject (or
+ // nullptr if never calculated)
+ EvaluationPoint m_update_point; // Stores both the stop id and the full
+ // context at which this value was last
+ // updated. When we are asked to update the value object, we check whether
+ // the context & stop id are the same before updating.
+ ConstString m_name; // The name of this object
+ DataExtractor
+ m_data; // A data extractor that can be used to extract the value.
+ Value m_value;
+ Status
+ m_error; // An error object that can describe any errors that occur when
+ // updating values.
+ std::string m_value_str; // Cached value string that will get cleared if/when
+ // the value is updated.
+ std::string m_old_value_str; // Cached old value string from the last time the
+ // value was gotten
+ std::string m_location_str; // Cached location string that will get cleared
+ // if/when the value is updated.
+ std::string m_summary_str; // Cached summary string that will get cleared
+ // if/when the value is updated.
+ std::string m_object_desc_str; // Cached result of the "object printer". This
+ // differs from the summary
+ // in that the summary is consed up by us, the object_desc_string is builtin.
+
+ llvm::Optional<std::pair<TypeValidatorResult, std::string>>
+ m_validation_result;
+
+ CompilerType m_override_type; // If the type of the value object should be
+ // overridden, the type to impose.
+
+ ValueObjectManager *m_manager; // This object is managed by the root object
+ // (any ValueObject that gets created
+ // without a parent.) The manager gets passed through all the generations of
+ // dependent objects, and will keep the whole cluster of objects alive as
+ // long as a shared pointer to any of them has been handed out. Shared
+ // pointers to value objects must always be made with the GetSP method.
+
+ ChildrenManager m_children;
+ std::map<ConstString, ValueObject *> m_synthetic_children;
+
+ ValueObject *m_dynamic_value;
+ ValueObject *m_synthetic_value;
+ ValueObject *m_deref_valobj;
+
+ lldb::ValueObjectSP m_addr_of_valobj_sp; // We have to hold onto a shared
+ // pointer to this one because it is
+ // created
+ // as an independent ValueObjectConstResult, which isn't managed by us.
+
+ lldb::Format m_format;
+ lldb::Format m_last_format;
+ uint32_t m_last_format_mgr_revision;
+ lldb::TypeSummaryImplSP m_type_summary_sp;
+ lldb::TypeFormatImplSP m_type_format_sp;
+ lldb::SyntheticChildrenSP m_synthetic_children_sp;
+ lldb::TypeValidatorImplSP m_type_validator_sp;
+ ProcessModID m_user_id_of_forced_summary;
+ AddressType m_address_type_of_ptr_or_ref_children;
+
+ llvm::SmallVector<uint8_t, 16> m_value_checksum;
+
+ lldb::LanguageType m_preferred_display_language;
+
+ uint64_t m_language_flags;
+
+ bool m_value_is_valid : 1, m_value_did_change : 1, m_children_count_valid : 1,
+ m_old_value_valid : 1, m_is_deref_of_parent : 1,
+ m_is_array_item_for_pointer : 1, m_is_bitfield_for_scalar : 1,
+ m_is_child_at_offset : 1, m_is_getting_summary : 1,
+ m_did_calculate_complete_objc_class_type : 1,
+ m_is_synthetic_children_generated : 1;
+
+ friend class ValueObjectChild;
+ friend class ClangExpressionDeclMap; // For GetValue
+ friend class ExpressionVariable; // For SetName
+ friend class Target; // For SetName
+ friend class ValueObjectConstResultImpl;
+ friend class ValueObjectSynthetic; // For ClearUserVisibleData
+
+ // Constructors and Destructors
+
+ // Use the no-argument constructor to make a constant variable object (with
+ // no ExecutionContextScope.)
+
+ ValueObject();
+
+ // Use this constructor to create a "root variable object". The ValueObject
+ // will be locked to this context through-out its lifespan.
+
+ ValueObject(ExecutionContextScope *exe_scope,
+ AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad);
+
+ // Use this constructor to create a ValueObject owned by another ValueObject.
+ // It will inherit the ExecutionContext of its parent.
+
+ ValueObject(ValueObject &parent);
+
+ ValueObjectManager *GetManager() { return m_manager; }
+
+ virtual bool UpdateValue() = 0;
+
+ virtual LazyBool CanUpdateWithInvalidExecutionContext() {
+ return eLazyBoolCalculate;
+ }
+
+ virtual void CalculateDynamicValue(lldb::DynamicValueType use_dynamic);
+
+ virtual lldb::DynamicValueType GetDynamicValueTypeImpl() {
+ return lldb::eNoDynamicValues;
+ }
+
+ virtual bool HasDynamicValueTypeInfo() { return false; }
+
+ virtual void CalculateSyntheticValue(bool use_synthetic = true);
+
+ // Should only be called by ValueObject::GetChildAtIndex() Returns a
+ // ValueObject managed by this ValueObject's manager.
+ virtual ValueObject *CreateChildAtIndex(size_t idx,
+ bool synthetic_array_member,
+ int32_t synthetic_index);
+
+ // Should only be called by ValueObject::GetNumChildren()
+ virtual size_t CalculateNumChildren(uint32_t max = UINT32_MAX) = 0;
+
+ void SetNumChildren(size_t num_children);
+
+ void SetValueDidChange(bool value_changed);
+
+ void SetValueIsValid(bool valid);
+
+ void ClearUserVisibleData(
+ uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings);
+
+ void AddSyntheticChild(ConstString key, ValueObject *valobj);
+
+ DataExtractor &GetDataExtractor();
+
+ void ClearDynamicTypeInformation();
+
+ // Subclasses must implement the functions below.
+
+ virtual CompilerType GetCompilerTypeImpl() = 0;
+
+ const char *GetLocationAsCStringImpl(const Value &value,
+ const DataExtractor &data);
+
+ bool IsChecksumEmpty();
+
+ void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType);
+
+private:
+ virtual CompilerType MaybeCalculateCompleteType();
+
+ lldb::ValueObjectSP GetValueForExpressionPath_Impl(
+ llvm::StringRef expression_cstr,
+ ExpressionPathScanEndReason *reason_to_stop,
+ ExpressionPathEndResultType *final_value_type,
+ const GetValueForExpressionPathOptions &options,
+ ExpressionPathAftermath *final_task_on_target);
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObject);
+};
+
+// A value object manager class that is seeded with the static variable value
+// and it vends the user facing value object. If the type is dynamic it can
+// vend the dynamic type. If this user type also has a synthetic type
+// associated with it, it will vend the synthetic type. The class watches the
+// process' stop
+// ID and will update the user type when needed.
+class ValueObjectManager {
+ // The root value object is the static typed variable object.
+ lldb::ValueObjectSP m_root_valobj_sp;
+ // The user value object is the value object the user wants to see.
+ lldb::ValueObjectSP m_user_valobj_sp;
+ lldb::DynamicValueType m_use_dynamic;
+ uint32_t m_stop_id; // The stop ID that m_user_valobj_sp is valid for.
+ bool m_use_synthetic;
+
+public:
+ ValueObjectManager() {}
+
+ ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
+ lldb::DynamicValueType use_dynamic, bool use_synthetic);
+
+ bool IsValid() const;
+
+ lldb::ValueObjectSP GetRootSP() const { return m_root_valobj_sp; }
+
+ // Gets the correct value object from the root object for a given process
+ // stop ID. If dynamic values are enabled, or if synthetic children are
+ // enabled, the value object that the user wants to see might change while
+ // debugging.
+ lldb::ValueObjectSP GetSP();
+
+ void SetUseDynamic(lldb::DynamicValueType use_dynamic);
+ void SetUseSynthetic(bool use_synthetic);
+ lldb::DynamicValueType GetUseDynamic() const { return m_use_dynamic; }
+ bool GetUseSynthetic() const { return m_use_synthetic; }
+ lldb::TargetSP GetTargetSP() const;
+ lldb::ProcessSP GetProcessSP() const;
+ lldb::ThreadSP GetThreadSP() const;
+ lldb::StackFrameSP GetFrameSP() const;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObject_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h
new file mode 100644
index 000000000000..feee493dfafb
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectCast.h
@@ -0,0 +1,65 @@
+//===-- ValueObjectCast.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_ValueObjectCast_h_
+#define liblldb_ValueObjectCast_h_
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class ConstString;
+
+// A ValueObject that represents a given value represented as a different type.
+class ValueObjectCast : public ValueObject {
+public:
+ ~ValueObjectCast() override;
+
+ static lldb::ValueObjectSP Create(ValueObject &parent,
+ ConstString name,
+ const CompilerType &cast_type);
+
+ uint64_t GetByteSize() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ lldb::ValueType GetValueType() const override;
+
+ bool IsInScope() override;
+
+ ValueObject *GetParent() override {
+ return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
+ }
+
+ const ValueObject *GetParent() const override {
+ return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
+ }
+
+protected:
+ ValueObjectCast(ValueObject &parent, ConstString name,
+ const CompilerType &cast_type);
+
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ CompilerType m_cast_type;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectCast);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectCast_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h
new file mode 100644
index 000000000000..76209a22ec20
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectChild.h
@@ -0,0 +1,96 @@
+//===-- ValueObjectChild.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_ValueObjectChild_h_
+#define liblldb_ValueObjectChild_h_
+
+#include "lldb/Core/ValueObject.h"
+
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/Optional.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+
+// A child of another ValueObject.
+class ValueObjectChild : public ValueObject {
+public:
+ ~ValueObjectChild() override;
+
+ uint64_t GetByteSize() override { return m_byte_size; }
+
+ lldb::offset_t GetByteOffset() override { return m_byte_offset; }
+
+ uint32_t GetBitfieldBitSize() override { return m_bitfield_bit_size; }
+
+ uint32_t GetBitfieldBitOffset() override { return m_bitfield_bit_offset; }
+
+ lldb::ValueType GetValueType() const override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ ConstString GetTypeName() override;
+
+ ConstString GetQualifiedTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ bool IsInScope() override;
+
+ bool IsBaseClass() override { return m_is_base_class; }
+
+ bool IsDereferenceOfParent() override { return m_is_deref_of_parent; }
+
+protected:
+ bool UpdateValue() override;
+
+ LazyBool CanUpdateWithInvalidExecutionContext() override;
+
+ CompilerType GetCompilerTypeImpl() override { return m_compiler_type; }
+
+ CompilerType m_compiler_type;
+ ConstString m_type_name;
+ uint64_t m_byte_size;
+ int32_t m_byte_offset;
+ uint8_t m_bitfield_bit_size;
+ uint8_t m_bitfield_bit_offset;
+ bool m_is_base_class;
+ bool m_is_deref_of_parent;
+ llvm::Optional<LazyBool> m_can_update_with_invalid_exe_ctx;
+
+ //
+ // void
+ // ReadValueFromMemory (ValueObject* parent, lldb::addr_t address);
+
+protected:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ friend class ValueObjectConstResultImpl;
+
+ ValueObjectChild(ValueObject &parent, const CompilerType &compiler_type,
+ ConstString name, uint64_t byte_size,
+ int32_t byte_offset, uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset, bool is_base_class,
+ bool is_deref_of_parent,
+ AddressType child_ptr_or_ref_addr_type,
+ uint64_t language_flags);
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectChild);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectChild_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h
new file mode 100644
index 000000000000..3bc957ef2b84
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResult.h
@@ -0,0 +1,154 @@
+//===-- ValueObjectConstResult.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_ValueObjectConstResult_h_
+#define liblldb_ValueObjectConstResult_h_
+
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResultImpl.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class ExecutionContextScope;
+class Module;
+
+// A frozen ValueObject copied into host memory
+class ValueObjectConstResult : public ValueObject {
+public:
+ ~ValueObjectConstResult() override;
+
+ static lldb::ValueObjectSP
+ Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order,
+ uint32_t addr_byte_size, lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ static lldb::ValueObjectSP
+ Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
+ ConstString name, const DataExtractor &data,
+ lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ static lldb::ValueObjectSP
+ Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
+ ConstString name, const lldb::DataBufferSP &result_data_sp,
+ lldb::ByteOrder byte_order, uint32_t addr_size,
+ lldb::addr_t address = LLDB_INVALID_ADDRESS);
+
+ static lldb::ValueObjectSP
+ Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
+ ConstString name, lldb::addr_t address,
+ AddressType address_type, uint32_t addr_byte_size);
+
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ Value &value, ConstString name,
+ Module *module = nullptr);
+
+ // When an expression fails to evaluate, we return an error
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ const Status &error);
+
+ uint64_t GetByteSize() override;
+
+ lldb::ValueType GetValueType() const override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ ConstString GetTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ bool IsInScope() override;
+
+ void SetByteSize(size_t size);
+
+ lldb::ValueObjectSP Dereference(Status &error) override;
+
+ ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member,
+ int32_t synthetic_index) override;
+
+ lldb::ValueObjectSP GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str = ConstString()) override;
+
+ lldb::ValueObjectSP AddressOf(Status &error) override;
+
+ lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
+ AddressType *address_type = nullptr) override;
+
+ size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
+ uint32_t item_count = 1) override;
+
+ lldb::addr_t GetLiveAddress() override { return m_impl.GetLiveAddress(); }
+
+ void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad) override {
+ m_impl.SetLiveAddress(addr, address_type);
+ }
+
+ lldb::ValueObjectSP
+ GetDynamicValue(lldb::DynamicValueType valueType) override;
+
+ lldb::LanguageType GetPreferredDisplayLanguage() override;
+
+ lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override;
+
+protected:
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ ConstString m_type_name;
+ uint64_t m_byte_size;
+
+ ValueObjectConstResultImpl m_impl;
+
+private:
+ friend class ValueObjectConstResultImpl;
+
+ ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ lldb::ByteOrder byte_order, uint32_t addr_byte_size,
+ lldb::addr_t address);
+
+ ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ const CompilerType &compiler_type,
+ ConstString name, const DataExtractor &data,
+ lldb::addr_t address);
+
+ ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ const CompilerType &compiler_type,
+ ConstString name,
+ const lldb::DataBufferSP &result_data_sp,
+ lldb::ByteOrder byte_order, uint32_t addr_size,
+ lldb::addr_t address);
+
+ ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ const CompilerType &compiler_type,
+ ConstString name, lldb::addr_t address,
+ AddressType address_type, uint32_t addr_byte_size);
+
+ ValueObjectConstResult(ExecutionContextScope *exe_scope, const Value &value,
+ ConstString name, Module *module = nullptr);
+
+ ValueObjectConstResult(ExecutionContextScope *exe_scope, const Status &error);
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResult);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResult_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h
new file mode 100644
index 000000000000..be9b12b4b57c
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultCast.h
@@ -0,0 +1,69 @@
+//===-- ValueObjectConstResultCast.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_ValueObjectConstResultCast_h_
+#define liblldb_ValueObjectConstResultCast_h_
+
+#include "lldb/Core/ValueObjectCast.h"
+#include "lldb/Core/ValueObjectConstResultImpl.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class Status;
+class ValueObject;
+
+class ValueObjectConstResultCast : public ValueObjectCast {
+public:
+ ValueObjectConstResultCast(ValueObject &parent, ConstString name,
+ const CompilerType &cast_type,
+ lldb::addr_t live_address = LLDB_INVALID_ADDRESS);
+
+ ~ValueObjectConstResultCast() override;
+
+ lldb::ValueObjectSP Dereference(Status &error) override;
+
+ ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member,
+ int32_t synthetic_index) override;
+
+ virtual CompilerType GetCompilerType() {
+ return ValueObjectCast::GetCompilerType();
+ }
+
+ lldb::ValueObjectSP GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str = ConstString()) override;
+
+ lldb::ValueObjectSP AddressOf(Status &error) override;
+
+ size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
+ uint32_t item_count = 1) override;
+
+ lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override;
+
+protected:
+ ValueObjectConstResultImpl m_impl;
+
+private:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ friend class ValueObjectConstResultImpl;
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResultCast);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResultCast_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h
new file mode 100644
index 000000000000..16fa74f71ed5
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultChild.h
@@ -0,0 +1,78 @@
+//===-- ValueObjectConstResultChild.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_ValueObjectConstResultChild_h_
+#define liblldb_ValueObjectConstResultChild_h_
+
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Core/ValueObjectConstResultImpl.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class Status;
+class ValueObject;
+
+// A child of a ValueObjectConstResult.
+class ValueObjectConstResultChild : public ValueObjectChild {
+public:
+ ValueObjectConstResultChild(ValueObject &parent,
+ const CompilerType &compiler_type,
+ ConstString name, uint32_t byte_size,
+ int32_t byte_offset, uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset, bool is_base_class,
+ bool is_deref_of_parent,
+ lldb::addr_t live_address,
+ uint64_t language_flags);
+
+ ~ValueObjectConstResultChild() override;
+
+ lldb::ValueObjectSP Dereference(Status &error) override;
+
+ ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member,
+ int32_t synthetic_index) override;
+
+ virtual CompilerType GetCompilerType() {
+ return ValueObjectChild::GetCompilerType();
+ }
+
+ lldb::ValueObjectSP GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str = ConstString()) override;
+
+ lldb::ValueObjectSP AddressOf(Status &error) override;
+
+ lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
+ AddressType *address_type = nullptr) override;
+
+ size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
+ uint32_t item_count = 1) override;
+
+ lldb::ValueObjectSP Cast(const CompilerType &compiler_type) override;
+
+protected:
+ ValueObjectConstResultImpl m_impl;
+
+private:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ friend class ValueObjectConstResultImpl;
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResultChild);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResultChild_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h
new file mode 100644
index 000000000000..ffac98e12e61
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h
@@ -0,0 +1,79 @@
+//===-- ValueObjectConstResultImpl.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_ValueObjectConstResultImpl_h_
+#define liblldb_ValueObjectConstResultImpl_h_
+
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "lldb/lldb-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+namespace lldb_private {
+class CompilerType;
+class DataExtractor;
+class Status;
+class ValueObject;
+}
+
+namespace lldb_private {
+
+// A class wrapping common implementation details for operations in
+// ValueObjectConstResult ( & Child ) that may need to jump from the host
+// memory space into the target's memory space
+class ValueObjectConstResultImpl {
+public:
+ ValueObjectConstResultImpl(ValueObject *valobj,
+ lldb::addr_t live_address = LLDB_INVALID_ADDRESS);
+
+ virtual ~ValueObjectConstResultImpl() = default;
+
+ lldb::ValueObjectSP Dereference(Status &error);
+
+ ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member,
+ int32_t synthetic_index);
+
+ lldb::ValueObjectSP
+ GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type,
+ bool can_create,
+ ConstString name_const_str = ConstString());
+
+ lldb::ValueObjectSP AddressOf(Status &error);
+
+ lldb::addr_t GetLiveAddress() { return m_live_address; }
+
+ lldb::ValueObjectSP Cast(const CompilerType &compiler_type);
+
+ void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad) {
+ m_live_address = addr;
+ m_live_address_type = address_type;
+ }
+
+ virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
+ AddressType *address_type = nullptr);
+
+ virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
+ uint32_t item_count = 1);
+
+private:
+ ValueObject *m_impl_backend;
+ lldb::addr_t m_live_address;
+ AddressType m_live_address_type;
+ lldb::ValueObjectSP m_load_addr_backend;
+ lldb::ValueObjectSP m_address_of_backend;
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectConstResultImpl);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectConstResultImpl_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h
new file mode 100644
index 000000000000..f656d42e9a97
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h
@@ -0,0 +1,136 @@
+//===-- ValueObjectDynamicValue.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_ValueObjectDynamicValue_h_
+#define liblldb_ValueObjectDynamicValue_h_
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/SharingPtr.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class Declaration;
+class Status;
+
+// A ValueObject that represents memory at a given address, viewed as some
+// set lldb type.
+class ValueObjectDynamicValue : public ValueObject {
+public:
+ ~ValueObjectDynamicValue() override;
+
+ uint64_t GetByteSize() override;
+
+ ConstString GetTypeName() override;
+
+ ConstString GetQualifiedTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ lldb::ValueType GetValueType() const override;
+
+ bool IsInScope() override;
+
+ bool IsDynamic() override { return true; }
+
+ bool IsBaseClass() override {
+ if (m_parent)
+ return m_parent->IsBaseClass();
+ return false;
+ }
+
+ bool GetIsConstant() const override { return false; }
+
+ ValueObject *GetParent() override {
+ return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
+ }
+
+ const ValueObject *GetParent() const override {
+ return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
+ }
+
+ lldb::ValueObjectSP GetStaticValue() override { return m_parent->GetSP(); }
+
+ void SetOwningSP(lldb::ValueObjectSP &owning_sp) {
+ if (m_owning_valobj_sp == owning_sp)
+ return;
+
+ assert(m_owning_valobj_sp.get() == nullptr);
+ m_owning_valobj_sp = owning_sp;
+ }
+
+ bool SetValueFromCString(const char *value_str, Status &error) override;
+
+ bool SetData(DataExtractor &data, Status &error) override;
+
+ TypeImpl GetTypeImpl() override;
+
+ lldb::VariableSP GetVariable() override {
+ return m_parent ? m_parent->GetVariable() : nullptr;
+ }
+
+ lldb::LanguageType GetPreferredDisplayLanguage() override;
+
+ void SetPreferredDisplayLanguage(lldb::LanguageType);
+
+ bool IsSyntheticChildrenGenerated() override;
+
+ void SetSyntheticChildrenGenerated(bool b) override;
+
+ bool GetDeclaration(Declaration &decl) override;
+
+ uint64_t GetLanguageFlags() override;
+
+ void SetLanguageFlags(uint64_t flags) override;
+
+protected:
+ bool UpdateValue() override;
+
+ LazyBool CanUpdateWithInvalidExecutionContext() override {
+ return eLazyBoolYes;
+ }
+
+ lldb::DynamicValueType GetDynamicValueTypeImpl() override {
+ return m_use_dynamic;
+ }
+
+ bool HasDynamicValueTypeInfo() override { return true; }
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ Address m_address; ///< The variable that this value object is based upon
+ TypeAndOrName m_dynamic_type_info; // We can have a type_sp or just a name
+ lldb::ValueObjectSP m_owning_valobj_sp;
+ lldb::DynamicValueType m_use_dynamic;
+ TypeImpl m_type_impl;
+
+private:
+ friend class ValueObject;
+ friend class ValueObjectConstResult;
+ ValueObjectDynamicValue(ValueObject &parent,
+ lldb::DynamicValueType use_dynamic);
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectDynamicValue);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectDynamicValue_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h
new file mode 100644
index 000000000000..42d19676d5d3
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectList.h
@@ -0,0 +1,62 @@
+//===-- ValueObjectList.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_ValueObjectList_h_
+#define liblldb_ValueObjectList_h_
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include <vector>
+
+#include <stddef.h>
+
+namespace lldb_private {
+class ValueObject;
+
+// A collection of ValueObject values that
+class ValueObjectList {
+public:
+ const ValueObjectList &operator=(const ValueObjectList &rhs);
+
+ void Append(const lldb::ValueObjectSP &val_obj_sp);
+
+ void Append(const ValueObjectList &valobj_list);
+
+ lldb::ValueObjectSP FindValueObjectByPointer(ValueObject *valobj);
+
+ size_t GetSize() const;
+
+ void Resize(size_t size);
+
+ lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx);
+
+ lldb::ValueObjectSP RemoveValueObjectAtIndex(size_t idx);
+
+ void SetValueObjectAtIndex(size_t idx, const lldb::ValueObjectSP &valobj_sp);
+
+ lldb::ValueObjectSP FindValueObjectByValueName(const char *name);
+
+ lldb::ValueObjectSP FindValueObjectByUID(lldb::user_id_t uid);
+
+ void Swap(ValueObjectList &value_object_list);
+
+ void Clear() { m_value_objects.clear(); }
+
+ const std::vector<lldb::ValueObjectSP> &GetObjects() const {
+ return m_value_objects;
+ }
+protected:
+ typedef std::vector<lldb::ValueObjectSP> collection;
+ // Classes that inherit from ValueObjectList can see and modify these
+ collection m_value_objects;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectList_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h
new file mode 100644
index 000000000000..df3557f14989
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectMemory.h
@@ -0,0 +1,78 @@
+//===-- ValueObjectMemory.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_ValueObjectMemory_h_
+#define liblldb_ValueObjectMemory_h_
+
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class ExecutionContextScope;
+
+// A ValueObject that represents memory at a given address, viewed as some
+// set lldb type.
+class ValueObjectMemory : public ValueObject {
+public:
+ ~ValueObjectMemory() override;
+
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ llvm::StringRef name,
+ const Address &address,
+ lldb::TypeSP &type_sp);
+
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ llvm::StringRef name,
+ const Address &address,
+ const CompilerType &ast_type);
+
+ uint64_t GetByteSize() override;
+
+ ConstString GetTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ lldb::ValueType GetValueType() const override;
+
+ bool IsInScope() override;
+
+ lldb::ModuleSP GetModule() override;
+
+protected:
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ Address m_address; ///< The variable that this value object is based upon
+ lldb::TypeSP m_type_sp;
+ CompilerType m_compiler_type;
+
+private:
+ ValueObjectMemory(ExecutionContextScope *exe_scope, llvm::StringRef name,
+ const Address &address, lldb::TypeSP &type_sp);
+
+ ValueObjectMemory(ExecutionContextScope *exe_scope, llvm::StringRef name,
+ const Address &address, const CompilerType &ast_type);
+ // For ValueObject only
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectMemory);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectMemory_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h
new file mode 100644
index 000000000000..e584be6e6057
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h
@@ -0,0 +1,171 @@
+//===-- ValueObjectRegister.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_ValueObjectRegister_h_
+#define liblldb_ValueObjectRegister_h_
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-types.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class Status;
+class ExecutionContextScope;
+class Scalar;
+class Stream;
+
+// A ValueObject that contains a root variable that may or may not
+// have children.
+class ValueObjectRegisterContext : public ValueObject {
+public:
+ ~ValueObjectRegisterContext() override;
+
+ uint64_t GetByteSize() override;
+
+ lldb::ValueType GetValueType() const override {
+ return lldb::eValueTypeRegisterSet;
+ }
+
+ ConstString GetTypeName() override;
+
+ ConstString GetQualifiedTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member,
+ int32_t synthetic_index) override;
+
+protected:
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+
+private:
+ ValueObjectRegisterContext(ValueObject &parent,
+ lldb::RegisterContextSP &reg_ctx_sp);
+ // For ValueObject only
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectRegisterContext);
+};
+
+class ValueObjectRegisterSet : public ValueObject {
+public:
+ ~ValueObjectRegisterSet() override;
+
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx_sp,
+ uint32_t set_idx);
+
+ uint64_t GetByteSize() override;
+
+ lldb::ValueType GetValueType() const override {
+ return lldb::eValueTypeRegisterSet;
+ }
+
+ ConstString GetTypeName() override;
+
+ ConstString GetQualifiedTypeName() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ ValueObject *CreateChildAtIndex(size_t idx, bool synthetic_array_member,
+ int32_t synthetic_index) override;
+
+ lldb::ValueObjectSP GetChildMemberWithName(ConstString name,
+ bool can_create) override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+protected:
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ const RegisterSet *m_reg_set;
+ uint32_t m_reg_set_idx;
+
+private:
+ friend class ValueObjectRegisterContext;
+
+ ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx);
+
+ // For ValueObject only
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectRegisterSet);
+};
+
+class ValueObjectRegister : public ValueObject {
+public:
+ ~ValueObjectRegister() override;
+
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx_sp,
+ uint32_t reg_num);
+
+ uint64_t GetByteSize() override;
+
+ lldb::ValueType GetValueType() const override {
+ return lldb::eValueTypeRegister;
+ }
+
+ ConstString GetTypeName() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ bool SetValueFromCString(const char *value_str, Status &error) override;
+
+ bool SetData(DataExtractor &data, Status &error) override;
+
+ bool ResolveValue(Scalar &scalar) override;
+
+ void
+ GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
+ GetExpressionPathFormat epformat =
+ eGetExpressionPathFormatDereferencePointers) override;
+
+protected:
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ lldb::RegisterContextSP m_reg_ctx_sp;
+ RegisterInfo m_reg_info;
+ RegisterValue m_reg_value;
+ ConstString m_type_name;
+ CompilerType m_compiler_type;
+
+private:
+ void ConstructObject(uint32_t reg_num);
+
+ friend class ValueObjectRegisterSet;
+
+ ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp,
+ uint32_t reg_num);
+ ValueObjectRegister(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
+
+ // For ValueObject only
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectRegister);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectRegister_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
new file mode 100644
index 000000000000..3b14a3e9f388
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
@@ -0,0 +1,169 @@
+//===-- ValueObjectSyntheticFilter.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_ValueObjectSyntheticFilter_h_
+#define liblldb_ValueObjectSyntheticFilter_h_
+
+#include "lldb/Core/ThreadSafeSTLMap.h"
+#include "lldb/Core/ThreadSafeSTLVector.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+
+#include <cstdint>
+#include <memory>
+
+#include <stddef.h>
+
+namespace lldb_private {
+class Declaration;
+class Status;
+class SyntheticChildrenFrontEnd;
+
+// A ValueObject that obtains its children from some source other than
+// real information
+// This is currently used to implement Python-based children and filters but
+// you can bind it to any source of synthetic information and have it behave
+// accordingly
+class ValueObjectSynthetic : public ValueObject {
+public:
+ ~ValueObjectSynthetic() override;
+
+ uint64_t GetByteSize() override;
+
+ ConstString GetTypeName() override;
+
+ ConstString GetQualifiedTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ bool MightHaveChildren() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ lldb::ValueType GetValueType() const override;
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create) override;
+
+ lldb::ValueObjectSP GetChildMemberWithName(ConstString name,
+ bool can_create) override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+ lldb::ValueObjectSP
+ GetDynamicValue(lldb::DynamicValueType valueType) override;
+
+ bool IsInScope() override;
+
+ bool HasSyntheticValue() override { return false; }
+
+ bool IsSynthetic() override { return true; }
+
+ void CalculateSyntheticValue(bool use_synthetic) override {}
+
+ bool IsDynamic() override {
+ return ((m_parent != nullptr) ? m_parent->IsDynamic() : false);
+ }
+
+ lldb::ValueObjectSP GetStaticValue() override {
+ return ((m_parent != nullptr) ? m_parent->GetStaticValue() : GetSP());
+ }
+
+ virtual lldb::DynamicValueType GetDynamicValueType() {
+ return ((m_parent != nullptr) ? m_parent->GetDynamicValueType()
+ : lldb::eNoDynamicValues);
+ }
+
+ ValueObject *GetParent() override {
+ return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
+ }
+
+ const ValueObject *GetParent() const override {
+ return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
+ }
+
+ lldb::ValueObjectSP GetNonSyntheticValue() override;
+
+ bool CanProvideValue() override;
+
+ bool DoesProvideSyntheticValue() override {
+ return (UpdateValueIfNeeded(), m_provides_value == eLazyBoolYes);
+ }
+
+ bool GetIsConstant() const override { return false; }
+
+ bool SetValueFromCString(const char *value_str, Status &error) override;
+
+ void SetFormat(lldb::Format format) override;
+
+ lldb::LanguageType GetPreferredDisplayLanguage() override;
+
+ void SetPreferredDisplayLanguage(lldb::LanguageType);
+
+ bool IsSyntheticChildrenGenerated() override;
+
+ void SetSyntheticChildrenGenerated(bool b) override;
+
+ bool GetDeclaration(Declaration &decl) override;
+
+ uint64_t GetLanguageFlags() override;
+
+ void SetLanguageFlags(uint64_t flags) override;
+
+protected:
+ bool UpdateValue() override;
+
+ LazyBool CanUpdateWithInvalidExecutionContext() override {
+ return eLazyBoolYes;
+ }
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ virtual void CreateSynthFilter();
+
+ // we need to hold on to the SyntheticChildren because someone might delete
+ // the type binding while we are alive
+ lldb::SyntheticChildrenSP m_synth_sp;
+ std::unique_ptr<SyntheticChildrenFrontEnd> m_synth_filter_up;
+
+ typedef ThreadSafeSTLMap<uint32_t, ValueObject *> ByIndexMap;
+ typedef ThreadSafeSTLMap<const char *, uint32_t> NameToIndexMap;
+ typedef ThreadSafeSTLVector<lldb::ValueObjectSP> SyntheticChildrenCache;
+
+ typedef ByIndexMap::iterator ByIndexIterator;
+ typedef NameToIndexMap::iterator NameToIndexIterator;
+
+ ByIndexMap m_children_byindex;
+ NameToIndexMap m_name_toindex;
+ uint32_t m_synthetic_children_count; // FIXME use the ValueObject's
+ // ChildrenManager instead of a special
+ // purpose solution
+ SyntheticChildrenCache m_synthetic_children_cache;
+
+ ConstString m_parent_type_name;
+
+ LazyBool m_might_have_children;
+
+ LazyBool m_provides_value;
+
+private:
+ friend class ValueObject;
+ ValueObjectSynthetic(ValueObject &parent, lldb::SyntheticChildrenSP filter);
+
+ void CopyValueData(ValueObject *source);
+
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectSynthetic);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectSyntheticFilter_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h
new file mode 100644
index 000000000000..86bb8ef90070
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectVariable.h
@@ -0,0 +1,87 @@
+//===-- ValueObjectVariable.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_ValueObjectVariable_h_
+#define liblldb_ValueObjectVariable_h_
+
+#include "lldb/Core/ValueObject.h"
+
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace lldb_private {
+class DataExtractor;
+class Declaration;
+class Status;
+class ExecutionContextScope;
+class SymbolContextScope;
+
+// A ValueObject that contains a root variable that may or may not
+// have children.
+class ValueObjectVariable : public ValueObject {
+public:
+ ~ValueObjectVariable() override;
+
+ static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
+ const lldb::VariableSP &var_sp);
+
+ uint64_t GetByteSize() override;
+
+ ConstString GetTypeName() override;
+
+ ConstString GetQualifiedTypeName() override;
+
+ ConstString GetDisplayTypeName() override;
+
+ size_t CalculateNumChildren(uint32_t max) override;
+
+ lldb::ValueType GetValueType() const override;
+
+ bool IsInScope() override;
+
+ lldb::ModuleSP GetModule() override;
+
+ SymbolContextScope *GetSymbolContextScope() override;
+
+ bool GetDeclaration(Declaration &decl) override;
+
+ const char *GetLocationAsCString() override;
+
+ bool SetValueFromCString(const char *value_str, Status &error) override;
+
+ bool SetData(DataExtractor &data, Status &error) override;
+
+ lldb::VariableSP GetVariable() override { return m_variable_sp; }
+
+protected:
+ bool UpdateValue() override;
+
+ CompilerType GetCompilerTypeImpl() override;
+
+ lldb::VariableSP
+ m_variable_sp; ///< The variable that this value object is based upon
+ Value m_resolved_value; ///< The value that DWARFExpression resolves this
+ ///variable to before we patch it up
+
+private:
+ ValueObjectVariable(ExecutionContextScope *exe_scope,
+ const lldb::VariableSP &var_sp);
+ // For ValueObject only
+ DISALLOW_COPY_AND_ASSIGN(ValueObjectVariable);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ValueObjectVariable_h_
diff --git a/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h b/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h
new file mode 100644
index 000000000000..832109e55c70
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Core/dwarf.h
@@ -0,0 +1,76 @@
+//===-- dwarf.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 DebugBase_dwarf_h_
+#define DebugBase_dwarf_h_
+
+#include "lldb/Utility/RangeMap.h"
+#include <stdint.h>
+
+// Get the DWARF constant definitions from llvm
+#include "llvm/BinaryFormat/Dwarf.h"
+
+// and stuff them in our default namespace
+using namespace llvm::dwarf;
+
+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 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
+
+typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any
+ // offset into the file
+
+/* Constants */
+#define DW_INVALID_OFFSET (~(dw_offset_t)0)
+#define DW_INVALID_INDEX 0xFFFFFFFFul
+
+// #define DW_ADDR_none 0x0
+
+#define DW_EH_PE_MASK_ENCODING 0x0F
+
+//// The following are used only internally within lldb - don't
+//// document them in the llvm Dwarf.h header file, we won't see
+//// them in executable files anywhere.
+//// These constants fit between DW_OP_lo_user (0xe0) and DW_OP_hi_user (0xff).
+//
+//#define DW_OP_APPLE_array_ref 0xEE // first pops index, then pops array;
+//pushes array[index]
+//#define DW_OP_APPLE_extern 0xEF // ULEB128 index of external object
+//(i.e., an entity from the program that was used in the expression)
+#define DW_OP_APPLE_uninit \
+ 0xF0 // This is actually generated by some apple compilers in locations lists
+//#define DW_OP_APPLE_assign 0xF1 // pops value off and assigns it to
+//second item on stack (2nd item must have assignable context)
+//#define DW_OP_APPLE_address_of 0xF2 // gets the address of the top stack
+//item (top item must be a variable, or have value_type that is an address
+//already)
+//#define DW_OP_APPLE_value_of 0xF3 // pops the value off the stack and
+//pushes the value of that object (top item must be a variable, or expression
+//local)
+//#define DW_OP_APPLE_deref_type 0xF4 // gets the address of the top stack
+//item (top item must be a variable, or a clang type)
+//#define DW_OP_APPLE_expr_local 0xF5 // ULEB128 expression local index
+//#define DW_OP_APPLE_constf 0xF6 // 1 byte float size, followed by
+//constant float data
+//#define DW_OP_APPLE_scalar_cast 0xF7 // Cast top of stack to 2nd in stack's
+//type leaving all items in place
+//#define DW_OP_APPLE_clang_cast 0xF8 // pointer size clang::Type * off the
+//stack and cast top stack item to this type
+//#define DW_OP_APPLE_clear 0xFE // clears the entire expression stack,
+//ok if the stack is empty
+//#define DW_OP_APPLE_error 0xFF // Stops expression evaluation and
+//returns an error (no args)
+
+typedef lldb_private::RangeArray<dw_addr_t, dw_addr_t, 2> DWARFRangeList;
+
+#endif // DebugBase_dwarf_h_