diff options
Diffstat (limited to 'include/lldb/Symbol')
41 files changed, 9312 insertions, 10958 deletions
diff --git a/include/lldb/Symbol/ArmUnwindInfo.h b/include/lldb/Symbol/ArmUnwindInfo.h index 8c40f19d2859..cc80c0fa9663 100644 --- a/include/lldb/Symbol/ArmUnwindInfo.h +++ b/include/lldb/Symbol/ArmUnwindInfo.h @@ -29,48 +29,42 @@ namespace lldb_private { -class ArmUnwindInfo -{ +class ArmUnwindInfo { public: - ArmUnwindInfo(const ObjectFile& objfile, - lldb::SectionSP& arm_exidx, - lldb::SectionSP& arm_extab); + ArmUnwindInfo(const ObjectFile &objfile, lldb::SectionSP &arm_exidx, + lldb::SectionSP &arm_extab); - ~ArmUnwindInfo(); + ~ArmUnwindInfo(); - bool - GetUnwindPlan(Target &target, const Address& addr, UnwindPlan& unwind_plan); + bool GetUnwindPlan(Target &target, const Address &addr, + UnwindPlan &unwind_plan); private: - struct ArmExidxEntry - { - ArmExidxEntry(uint32_t f, lldb::addr_t a, uint32_t d); + struct ArmExidxEntry { + ArmExidxEntry(uint32_t f, lldb::addr_t a, uint32_t d); - bool - operator<(const ArmExidxEntry& other) const; + bool operator<(const ArmExidxEntry &other) const; - uint32_t file_address; - lldb::addr_t address; - uint32_t data; - }; + uint32_t file_address; + lldb::addr_t address; + uint32_t data; + }; - const uint8_t* - GetExceptionHandlingTableEntry(const Address& addr); + const uint8_t *GetExceptionHandlingTableEntry(const Address &addr); - uint8_t - GetByteAtOffset(const uint32_t* data, uint16_t offset) const; + uint8_t GetByteAtOffset(const uint32_t *data, uint16_t offset) const; - uint64_t - GetULEB128(const uint32_t* data, uint16_t& offset, uint16_t max_offset) const; + uint64_t GetULEB128(const uint32_t *data, uint16_t &offset, + uint16_t max_offset) const; - const lldb::ByteOrder m_byte_order; - lldb::SectionSP m_arm_exidx_sp; // .ARM.exidx section - lldb::SectionSP m_arm_extab_sp; // .ARM.extab section - DataExtractor m_arm_exidx_data; // .ARM.exidx section data - DataExtractor m_arm_extab_data; // .ARM.extab section data - std::vector<ArmExidxEntry> m_exidx_entries; + const lldb::ByteOrder m_byte_order; + lldb::SectionSP m_arm_exidx_sp; // .ARM.exidx section + lldb::SectionSP m_arm_extab_sp; // .ARM.extab section + DataExtractor m_arm_exidx_data; // .ARM.exidx section data + DataExtractor m_arm_extab_data; // .ARM.extab section data + std::vector<ArmExidxEntry> m_exidx_entries; }; } // namespace lldb_private -#endif // liblldb_ArmUnwindInfo_h_ +#endif // liblldb_ArmUnwindInfo_h_ diff --git a/include/lldb/Symbol/Block.h b/include/lldb/Symbol/Block.h index 6dbb9c56097b..eb96318dac04 100644 --- a/include/lldb/Symbol/Block.h +++ b/include/lldb/Symbol/Block.h @@ -16,14 +16,14 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/Stream.h" #include "lldb/Core/UserID.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/CompilerType.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -45,451 +45,394 @@ namespace lldb_private { /// InlineFunctionInfo shared pointer object to a block. Inlined /// functions are represented as named blocks. //---------------------------------------------------------------------- -class Block : - public UserID, - public SymbolContextScope -{ +class Block : public UserID, public SymbolContextScope { public: - typedef RangeArray<uint32_t, uint32_t, 1> RangeList; - typedef RangeList::Entry Range; - - //------------------------------------------------------------------ - /// Construct with a User ID \a uid, \a depth. - /// - /// Initialize this block with the specified UID \a uid. The - /// \a depth in the \a block_list is used to represent the parent, - /// sibling, and child block information and also allows for partial - /// parsing at the block level. - /// - /// @param[in] uid - /// The UID for a given block. This value is given by the - /// SymbolFile plug-in and can be any value that helps the - /// SymbolFile plug-in to match this block back to the debug - /// information data that it parses for further or more in - /// depth parsing. Common values would be the index into a - /// table, or an offset into the debug information. - /// - /// @param[in] depth - /// The integer depth of this block in the block list hierarchy. - /// - /// @param[in] block_list - /// The block list that this object belongs to. - /// - /// @see BlockList - //------------------------------------------------------------------ - Block (lldb::user_id_t uid); - - //------------------------------------------------------------------ - /// Destructor. - //------------------------------------------------------------------ - ~Block() override; - - //------------------------------------------------------------------ - /// Add a child to this object. - /// - /// @param[in] child_block_sp - /// A shared pointer to a child block that will get added to - /// this block. - //------------------------------------------------------------------ - void - AddChild (const lldb::BlockSP &child_block_sp); - - //------------------------------------------------------------------ - /// Add a new offset range to this block. - /// - /// @param[in] start_offset - /// An offset into this Function's address range that - /// describes the start address of a range for this block. - /// - /// @param[in] end_offset - /// An offset into this Function's address range that - /// describes the end address of a range for this block. - //------------------------------------------------------------------ - void - AddRange (const Range& range); - - void - FinalizeRanges (); - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - CalculateSymbolContext(SymbolContext* sc) override; - - lldb::ModuleSP - CalculateSymbolContextModule() override; - - CompileUnit * - CalculateSymbolContextCompileUnit() override; - - Function * - CalculateSymbolContextFunction() override; - - Block * - CalculateSymbolContextBlock() override; - - //------------------------------------------------------------------ - /// Check if an offset is in one of the block offset ranges. - /// - /// @param[in] range_offset - /// An offset into the Function's address range. - /// - /// @return - /// Returns \b true if \a range_offset falls in one of this - /// block's ranges, \b false otherwise. - //------------------------------------------------------------------ - bool - Contains (lldb::addr_t range_offset) const; - - //------------------------------------------------------------------ - /// Check if a offset range is in one of the block offset ranges. - /// - /// @param[in] range - /// An offset range into the Function's address range. - /// - /// @return - /// Returns \b true if \a range falls in one of this - /// block's ranges, \b false otherwise. - //------------------------------------------------------------------ - bool - Contains (const Range& range) const; - - //------------------------------------------------------------------ - /// Check if this object contains "block" as a child block at any - /// depth. - /// - /// @param[in] block - /// A potential child block. - /// - /// @return - /// Returns \b true if \a block is a child of this block, \b - /// false otherwise. - //------------------------------------------------------------------ - bool - Contains (const Block *block) const; - - //------------------------------------------------------------------ - /// Dump the block contents. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] base_addr - /// The resolved start address of the Function's address - /// range. This should be resolved as the file or load address - /// prior to passing the value into this function for dumping. - /// - /// @param[in] depth - /// Limit the number of levels deep that this function should - /// print as this block can contain child blocks. Specify - /// INT_MAX to dump all child blocks. - /// - /// @param[in] show_context - /// If \b true, variables will dump their context information. - //------------------------------------------------------------------ - void - Dump (Stream *s, lldb::addr_t base_addr, int32_t depth, bool show_context) const; - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - DumpSymbolContext(Stream *s) override; - - void - DumpAddressRanges (Stream *s, - lldb::addr_t base_addr); - - void - GetDescription (Stream *s, - Function *function, - lldb::DescriptionLevel level, - Target *target) const; - - //------------------------------------------------------------------ - /// Get the parent block. - /// - /// @return - /// The parent block pointer, or nullptr if this block has no - /// parent. - //------------------------------------------------------------------ - Block * - GetParent () const; - - //------------------------------------------------------------------ - /// Get the inlined block that contains this block. - /// - /// @return - /// If this block contains inlined function info, it will return - /// this block, else parent blocks will be searched to see if - /// any contain this block. nullptr will be returned if this block - /// nor any parent blocks are inlined function blocks. - //------------------------------------------------------------------ - Block * - GetContainingInlinedBlock (); - - //------------------------------------------------------------------ - /// Get the inlined parent block for this block. - /// - /// @return - /// The parent block pointer, or nullptr if this block has no - /// parent. - //------------------------------------------------------------------ - Block * - GetInlinedParent (); - - //------------------------------------------------------------------ - /// Get the sibling block for this block. - /// - /// @return - /// The sibling block pointer, or nullptr if this block has no - /// sibling. - //------------------------------------------------------------------ - Block * - GetSibling () const; - - //------------------------------------------------------------------ - /// Get the first child block. - /// - /// @return - /// The first child block pointer, or nullptr if this block has no - /// children. - //------------------------------------------------------------------ - Block * - GetFirstChild () const - { - return (m_children.empty() ? nullptr : m_children.front().get()); - } - - //------------------------------------------------------------------ - /// Get the variable list for this block only. - /// - /// @param[in] can_create - /// If \b true, the variables can be parsed if they already - /// haven't been, else the current state of the block will be - /// returned. - /// - /// @return - /// A variable list shared pointer that contains all variables - /// for this block. - //------------------------------------------------------------------ - lldb::VariableListSP - GetBlockVariableList (bool can_create); - - //------------------------------------------------------------------ - /// Get the variable list for this block and optionally all child - /// blocks if \a get_child_variables is \b true. - /// - /// @param[in] get_child_variables - /// If \b true, all variables from all child blocks will be - /// added to the variable list. - /// - /// @param[in] can_create - /// If \b true, the variables can be parsed if they already - /// haven't been, else the current state of the block will be - /// returned. Passing \b true for this parameter can be used - /// to see the current state of what has been parsed up to this - /// point. - /// - /// @param[in] add_inline_child_block_variables - /// If this is \b false, no child variables of child blocks - /// that are inlined functions will be gotten. If \b true then - /// all child variables will be added regardless of whether they - /// come from inlined functions or not. - /// - /// @return - /// A variable list shared pointer that contains all variables - /// for this block. - //------------------------------------------------------------------ - uint32_t - AppendBlockVariables (bool can_create, - bool get_child_block_variables, - bool stop_if_child_block_is_inlined_function, - const std::function<bool(Variable*)>& filter, - VariableList *variable_list); - - //------------------------------------------------------------------ - /// Appends the variables from this block, and optionally from all - /// parent blocks, to \a variable_list. - /// - /// @param[in] can_create - /// If \b true, the variables can be parsed if they already - /// haven't been, else the current state of the block will be - /// returned. Passing \b true for this parameter can be used - /// to see the current state of what has been parsed up to this - /// point. - /// - /// @param[in] get_parent_variables - /// If \b true, all variables from all parent blocks will be - /// added to the variable list. - /// - /// @param[in] stop_if_block_is_inlined_function - /// If \b true, all variables from all parent blocks will be - /// added to the variable list until there are no parent blocks - /// or the parent block has inlined function info. - /// - /// @param[in,out] variable_list - /// All variables in this block, and optionally all parent - /// blocks will be added to this list. - /// - /// @return - /// The number of variable that were appended to \a - /// variable_list. - //------------------------------------------------------------------ - uint32_t - AppendVariables (bool can_create, - bool get_parent_variables, - bool stop_if_block_is_inlined_function, - const std::function<bool(Variable*)>& filter, - VariableList *variable_list); - - //------------------------------------------------------------------ - /// Get const accessor for any inlined function information. - /// - /// @return - /// A const pointer to any inlined function information, or nullptr - /// if this is a regular block. - //------------------------------------------------------------------ - const InlineFunctionInfo* - GetInlinedFunctionInfo () const - { - return m_inlineInfoSP.get(); - } - - CompilerDeclContext - GetDeclContext(); - - //------------------------------------------------------------------ - /// Get the memory cost of this object. - /// - /// Returns the cost of this object plus any owned objects from the - /// ranges, variables, and inline function information. - /// - /// @return - /// The number of bytes that this object occupies in memory. - //------------------------------------------------------------------ - size_t - MemorySize() const; - - //------------------------------------------------------------------ - /// Set accessor for any inlined function information. - /// - /// @param[in] name - /// The method name for the inlined function. This value should - /// not be nullptr. - /// - /// @param[in] mangled - /// The mangled method name for the inlined function. This can - /// be nullptr if there is no mangled name for an inlined function - /// or if the name is the same as \a name. - /// - /// @param[in] decl_ptr - /// A optional pointer to declaration information for the - /// inlined function information. This value can be nullptr to - /// indicate that no declaration information is available. - /// - /// @param[in] call_decl_ptr - /// Optional calling location declaration information that - /// describes from where this inlined function was called. - //------------------------------------------------------------------ - void - SetInlinedFunctionInfo (const char *name, - const char *mangled, - const Declaration *decl_ptr, - const Declaration *call_decl_ptr); - - void - SetParentScope (SymbolContextScope *parent_scope) - { - m_parent_scope = parent_scope; - } - - //------------------------------------------------------------------ - /// Set accessor for the variable list. - /// - /// Called by the SymbolFile plug-ins after they have parsed the - /// variable lists and are ready to hand ownership of the list over - /// to this object. - /// - /// @param[in] variable_list_sp - /// A shared pointer to a VariableList. - //------------------------------------------------------------------ - void - SetVariableList (lldb::VariableListSP& variable_list_sp) - { - m_variable_list_sp = variable_list_sp; - } - - bool - BlockInfoHasBeenParsed() const - { - return m_parsed_block_info; - } - - void - SetBlockInfoHasBeenParsed (bool b, bool set_children); - - Block * - FindBlockByID (lldb::user_id_t block_id); - - size_t - GetNumRanges () const - { - return m_ranges.GetSize(); - } - - bool - GetRangeContainingOffset (const lldb::addr_t offset, Range &range); - - bool - GetRangeContainingAddress (const Address& addr, AddressRange &range); - - bool - GetRangeContainingLoadAddress (lldb::addr_t load_addr, Target &target, AddressRange &range); - - uint32_t - GetRangeIndexContainingAddress (const Address& addr); - - //------------------------------------------------------------------ - // Since blocks might have multiple discontiguous address ranges, - // we need to be able to get at any of the address ranges in a block. - //------------------------------------------------------------------ - bool - GetRangeAtIndex (uint32_t range_idx, - AddressRange &range); - - bool - GetStartAddress (Address &addr); - - void - SetDidParseVariables (bool b, bool set_children); + typedef RangeArray<uint32_t, uint32_t, 1> RangeList; + typedef RangeList::Entry Range; + + //------------------------------------------------------------------ + /// Construct with a User ID \a uid, \a depth. + /// + /// Initialize this block with the specified UID \a uid. The + /// \a depth in the \a block_list is used to represent the parent, + /// sibling, and child block information and also allows for partial + /// parsing at the block level. + /// + /// @param[in] uid + /// The UID for a given block. This value is given by the + /// SymbolFile plug-in and can be any value that helps the + /// SymbolFile plug-in to match this block back to the debug + /// information data that it parses for further or more in + /// depth parsing. Common values would be the index into a + /// table, or an offset into the debug information. + /// + /// @param[in] depth + /// The integer depth of this block in the block list hierarchy. + /// + /// @param[in] block_list + /// The block list that this object belongs to. + /// + /// @see BlockList + //------------------------------------------------------------------ + Block(lldb::user_id_t uid); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Block() override; + + //------------------------------------------------------------------ + /// Add a child to this object. + /// + /// @param[in] child_block_sp + /// A shared pointer to a child block that will get added to + /// this block. + //------------------------------------------------------------------ + void AddChild(const lldb::BlockSP &child_block_sp); + + //------------------------------------------------------------------ + /// Add a new offset range to this block. + /// + /// @param[in] start_offset + /// An offset into this Function's address range that + /// describes the start address of a range for this block. + /// + /// @param[in] end_offset + /// An offset into this Function's address range that + /// describes the end address of a range for this block. + //------------------------------------------------------------------ + void AddRange(const Range &range); + + void FinalizeRanges(); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void CalculateSymbolContext(SymbolContext *sc) override; + + lldb::ModuleSP CalculateSymbolContextModule() override; + + CompileUnit *CalculateSymbolContextCompileUnit() override; + + Function *CalculateSymbolContextFunction() override; + + Block *CalculateSymbolContextBlock() override; + + //------------------------------------------------------------------ + /// Check if an offset is in one of the block offset ranges. + /// + /// @param[in] range_offset + /// An offset into the Function's address range. + /// + /// @return + /// Returns \b true if \a range_offset falls in one of this + /// block's ranges, \b false otherwise. + //------------------------------------------------------------------ + bool Contains(lldb::addr_t range_offset) const; + + //------------------------------------------------------------------ + /// Check if a offset range is in one of the block offset ranges. + /// + /// @param[in] range + /// An offset range into the Function's address range. + /// + /// @return + /// Returns \b true if \a range falls in one of this + /// block's ranges, \b false otherwise. + //------------------------------------------------------------------ + bool Contains(const Range &range) const; + + //------------------------------------------------------------------ + /// Check if this object contains "block" as a child block at any + /// depth. + /// + /// @param[in] block + /// A potential child block. + /// + /// @return + /// Returns \b true if \a block is a child of this block, \b + /// false otherwise. + //------------------------------------------------------------------ + bool Contains(const Block *block) const; + + //------------------------------------------------------------------ + /// Dump the block contents. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] base_addr + /// The resolved start address of the Function's address + /// range. This should be resolved as the file or load address + /// prior to passing the value into this function for dumping. + /// + /// @param[in] depth + /// Limit the number of levels deep that this function should + /// print as this block can contain child blocks. Specify + /// INT_MAX to dump all child blocks. + /// + /// @param[in] show_context + /// If \b true, variables will dump their context information. + //------------------------------------------------------------------ + void Dump(Stream *s, lldb::addr_t base_addr, int32_t depth, + bool show_context) const; + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void DumpSymbolContext(Stream *s) override; + + void DumpAddressRanges(Stream *s, lldb::addr_t base_addr); + + void GetDescription(Stream *s, Function *function, + lldb::DescriptionLevel level, Target *target) const; + + //------------------------------------------------------------------ + /// Get the parent block. + /// + /// @return + /// The parent block pointer, or nullptr if this block has no + /// parent. + //------------------------------------------------------------------ + Block *GetParent() const; + + //------------------------------------------------------------------ + /// Get the inlined block that contains this block. + /// + /// @return + /// If this block contains inlined function info, it will return + /// this block, else parent blocks will be searched to see if + /// any contain this block. nullptr will be returned if this block + /// nor any parent blocks are inlined function blocks. + //------------------------------------------------------------------ + Block *GetContainingInlinedBlock(); + + //------------------------------------------------------------------ + /// Get the inlined parent block for this block. + /// + /// @return + /// The parent block pointer, or nullptr if this block has no + /// parent. + //------------------------------------------------------------------ + Block *GetInlinedParent(); + + //------------------------------------------------------------------ + /// Get the sibling block for this block. + /// + /// @return + /// The sibling block pointer, or nullptr if this block has no + /// sibling. + //------------------------------------------------------------------ + Block *GetSibling() const; + + //------------------------------------------------------------------ + /// Get the first child block. + /// + /// @return + /// The first child block pointer, or nullptr if this block has no + /// children. + //------------------------------------------------------------------ + Block *GetFirstChild() const { + return (m_children.empty() ? nullptr : m_children.front().get()); + } + + //------------------------------------------------------------------ + /// Get the variable list for this block only. + /// + /// @param[in] can_create + /// If \b true, the variables can be parsed if they already + /// haven't been, else the current state of the block will be + /// returned. + /// + /// @return + /// A variable list shared pointer that contains all variables + /// for this block. + //------------------------------------------------------------------ + lldb::VariableListSP GetBlockVariableList(bool can_create); + + //------------------------------------------------------------------ + /// Get the variable list for this block and optionally all child + /// blocks if \a get_child_variables is \b true. + /// + /// @param[in] get_child_variables + /// If \b true, all variables from all child blocks will be + /// added to the variable list. + /// + /// @param[in] can_create + /// If \b true, the variables can be parsed if they already + /// haven't been, else the current state of the block will be + /// returned. Passing \b true for this parameter can be used + /// to see the current state of what has been parsed up to this + /// point. + /// + /// @param[in] add_inline_child_block_variables + /// If this is \b false, no child variables of child blocks + /// that are inlined functions will be gotten. If \b true then + /// all child variables will be added regardless of whether they + /// come from inlined functions or not. + /// + /// @return + /// A variable list shared pointer that contains all variables + /// for this block. + //------------------------------------------------------------------ + uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables, + bool stop_if_child_block_is_inlined_function, + const std::function<bool(Variable *)> &filter, + VariableList *variable_list); + + //------------------------------------------------------------------ + /// Appends the variables from this block, and optionally from all + /// parent blocks, to \a variable_list. + /// + /// @param[in] can_create + /// If \b true, the variables can be parsed if they already + /// haven't been, else the current state of the block will be + /// returned. Passing \b true for this parameter can be used + /// to see the current state of what has been parsed up to this + /// point. + /// + /// @param[in] get_parent_variables + /// If \b true, all variables from all parent blocks will be + /// added to the variable list. + /// + /// @param[in] stop_if_block_is_inlined_function + /// If \b true, all variables from all parent blocks will be + /// added to the variable list until there are no parent blocks + /// or the parent block has inlined function info. + /// + /// @param[in,out] variable_list + /// All variables in this block, and optionally all parent + /// blocks will be added to this list. + /// + /// @return + /// The number of variable that were appended to \a + /// variable_list. + //------------------------------------------------------------------ + uint32_t AppendVariables(bool can_create, bool get_parent_variables, + bool stop_if_block_is_inlined_function, + const std::function<bool(Variable *)> &filter, + VariableList *variable_list); + + //------------------------------------------------------------------ + /// Get const accessor for any inlined function information. + /// + /// @return + /// A const pointer to any inlined function information, or nullptr + /// if this is a regular block. + //------------------------------------------------------------------ + const InlineFunctionInfo *GetInlinedFunctionInfo() const { + return m_inlineInfoSP.get(); + } + + CompilerDeclContext GetDeclContext(); + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// Returns the cost of this object plus any owned objects from the + /// ranges, variables, and inline function information. + /// + /// @return + /// The number of bytes that this object occupies in memory. + //------------------------------------------------------------------ + size_t MemorySize() const; + + //------------------------------------------------------------------ + /// Set accessor for any inlined function information. + /// + /// @param[in] name + /// The method name for the inlined function. This value should + /// not be nullptr. + /// + /// @param[in] mangled + /// The mangled method name for the inlined function. This can + /// be nullptr if there is no mangled name for an inlined function + /// or if the name is the same as \a name. + /// + /// @param[in] decl_ptr + /// A optional pointer to declaration information for the + /// inlined function information. This value can be nullptr to + /// indicate that no declaration information is available. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + //------------------------------------------------------------------ + void SetInlinedFunctionInfo(const char *name, const char *mangled, + const Declaration *decl_ptr, + const Declaration *call_decl_ptr); + + void SetParentScope(SymbolContextScope *parent_scope) { + m_parent_scope = parent_scope; + } + + //------------------------------------------------------------------ + /// Set accessor for the variable list. + /// + /// Called by the SymbolFile plug-ins after they have parsed the + /// variable lists and are ready to hand ownership of the list over + /// to this object. + /// + /// @param[in] variable_list_sp + /// A shared pointer to a VariableList. + //------------------------------------------------------------------ + void SetVariableList(lldb::VariableListSP &variable_list_sp) { + m_variable_list_sp = variable_list_sp; + } + + bool BlockInfoHasBeenParsed() const { return m_parsed_block_info; } + + void SetBlockInfoHasBeenParsed(bool b, bool set_children); + + Block *FindBlockByID(lldb::user_id_t block_id); + + size_t GetNumRanges() const { return m_ranges.GetSize(); } + + bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range); + + bool GetRangeContainingAddress(const Address &addr, AddressRange &range); + + bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, + AddressRange &range); + + uint32_t GetRangeIndexContainingAddress(const Address &addr); + + //------------------------------------------------------------------ + // Since blocks might have multiple discontiguous address ranges, + // we need to be able to get at any of the address ranges in a block. + //------------------------------------------------------------------ + bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range); + + bool GetStartAddress(Address &addr); + + void SetDidParseVariables(bool b, bool set_children); protected: - typedef std::vector<lldb::BlockSP> collection; - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - SymbolContextScope *m_parent_scope; - collection m_children; - RangeList m_ranges; - lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. - lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, static and parameter variables scoped to this block. - bool m_parsed_block_info:1, ///< Set to true if this block and it's children have all been parsed - m_parsed_block_variables:1, - m_parsed_child_blocks:1; - - // A parent of child blocks can be asked to find a sibling block given - // one of its child blocks - Block * - GetSiblingForChild (const Block *child_block) const; + typedef std::vector<lldb::BlockSP> collection; + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + SymbolContextScope *m_parent_scope; + collection m_children; + RangeList m_ranges; + lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. + lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, + ///static and parameter variables + ///scoped to this block. + bool m_parsed_block_info : 1, ///< Set to true if this block and it's children + ///have all been parsed + m_parsed_block_variables : 1, m_parsed_child_blocks : 1; + + // A parent of child blocks can be asked to find a sibling block given + // one of its child blocks + Block *GetSiblingForChild(const Block *child_block) const; private: - DISALLOW_COPY_AND_ASSIGN (Block); + DISALLOW_COPY_AND_ASSIGN(Block); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index 08f7b6b412dc..4262ecb4bf0e 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -20,13 +20,13 @@ #include <memory> #include <set> #include <string> -#include <vector> #include <utility> +#include <vector> // Other libraries and framework includes -#include "llvm/ADT/SmallVector.h" #include "clang/AST/ASTContext.h" #include "clang/AST/TemplateBase.h" +#include "llvm/ADT/SmallVector.h" // Project includes #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" @@ -43,1156 +43,934 @@ namespace lldb_private { class Declaration; -class ClangASTContext : public TypeSystem -{ +class ClangASTContext : public TypeSystem { public: - typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); - typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *); - - //------------------------------------------------------------------ - // llvm casting support - //------------------------------------------------------------------ - static bool classof(const TypeSystem *ts) - { - return ts->getKind() == TypeSystem::eKindClang; - } + typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); + typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, + clang::ObjCInterfaceDecl *); - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ClangASTContext(const char *triple = nullptr); + //------------------------------------------------------------------ + // llvm casting support + //------------------------------------------------------------------ + static bool classof(const TypeSystem *ts) { + return ts->getKind() == TypeSystem::eKindClang; + } - ~ClangASTContext() override; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ClangASTContext(const char *triple = nullptr); - void - Finalize() override; + ~ClangASTContext() override; - //------------------------------------------------------------------ - // PluginInterface functions - //------------------------------------------------------------------ - ConstString - GetPluginName() override; + void Finalize() override; - uint32_t - GetPluginVersion() override; + //------------------------------------------------------------------ + // PluginInterface functions + //------------------------------------------------------------------ + ConstString GetPluginName() override; - static ConstString - GetPluginNameStatic (); + uint32_t GetPluginVersion() override; - static lldb::TypeSystemSP - CreateInstance (lldb::LanguageType language, Module *module, Target *target); - - static void - EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types, std::set<lldb::LanguageType> &languages_for_expressions); + static ConstString GetPluginNameStatic(); - static void - Initialize (); + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Module *module, Target *target); - static void - Terminate (); + static void EnumerateSupportedLanguages( + std::set<lldb::LanguageType> &languages_for_types, + std::set<lldb::LanguageType> &languages_for_expressions); - static ClangASTContext* - GetASTContext (clang::ASTContext* ast_ctx); + static void Initialize(); - clang::ASTContext * - getASTContext(); - - void setASTContext(clang::ASTContext* ast_ctx); - - clang::Builtin::Context * - getBuiltinContext(); + static void Terminate(); - clang::IdentifierTable * - getIdentifierTable(); + static ClangASTContext *GetASTContext(clang::ASTContext *ast_ctx); - clang::LangOptions * - getLanguageOptions(); + clang::ASTContext *getASTContext(); - clang::SelectorTable * - getSelectorTable(); + void setASTContext(clang::ASTContext *ast_ctx); - clang::FileManager * - getFileManager(); - - clang::SourceManager * - getSourceManager(); + clang::Builtin::Context *getBuiltinContext(); - clang::DiagnosticsEngine * - getDiagnosticsEngine(); - - clang::DiagnosticConsumer * - getDiagnosticConsumer(); + clang::IdentifierTable *getIdentifierTable(); - clang::MangleContext * - getMangleContext(); + clang::LangOptions *getLanguageOptions(); - std::shared_ptr<clang::TargetOptions> &getTargetOptions(); + clang::SelectorTable *getSelectorTable(); - clang::TargetInfo * - getTargetInfo(); + clang::FileManager *getFileManager(); - void - Clear(); - - const char * - GetTargetTriple (); + clang::SourceManager *getSourceManager(); - void - SetTargetTriple (const char *target_triple); + clang::DiagnosticsEngine *getDiagnosticsEngine(); - void - SetArchitecture (const ArchSpec &arch); + clang::DiagnosticConsumer *getDiagnosticConsumer(); - bool - HasExternalSource (); + clang::MangleContext *getMangleContext(); - void - SetExternalSource (llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_ap); + std::shared_ptr<clang::TargetOptions> &getTargetOptions(); - void - RemoveExternalSource (); - - bool - GetCompleteDecl (clang::Decl *decl) - { - return ClangASTContext::GetCompleteDecl(getASTContext(), decl); - } + clang::TargetInfo *getTargetInfo(); - static void - DumpDeclHiearchy (clang::Decl *decl); + void Clear(); - static void - DumpDeclContextHiearchy (clang::DeclContext *decl_ctx); + const char *GetTargetTriple(); - static bool - DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl); + void SetTargetTriple(const char *target_triple); - static bool - GetCompleteDecl (clang::ASTContext *ast, - clang::Decl *decl); + void SetArchitecture(const ArchSpec &arch); - void SetMetadataAsUserID (const void *object, - lldb::user_id_t user_id); + bool HasExternalSource(); - void SetMetadata (const void *object, - ClangASTMetadata &meta_data) - { - SetMetadata(getASTContext(), object, meta_data); - } - - static void - SetMetadata (clang::ASTContext *ast, - const void *object, - ClangASTMetadata &meta_data); - - ClangASTMetadata * - GetMetadata (const void *object) - { - return GetMetadata(getASTContext(), object); - } - - static ClangASTMetadata * - GetMetadata (clang::ASTContext *ast, - const void *object); - - //------------------------------------------------------------------ - // Basic Types - //------------------------------------------------------------------ - CompilerType - GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, - size_t bit_size) override; - - static CompilerType - GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast, - lldb::Encoding encoding, - uint32_t bit_size); - - CompilerType - GetBasicType (lldb::BasicType type); - - static CompilerType - GetBasicType (clang::ASTContext *ast, lldb::BasicType type); - - static CompilerType - GetBasicType (clang::ASTContext *ast, const ConstString &name); - - static lldb::BasicType - GetBasicTypeEnumeration (const ConstString &name); - - CompilerType - GetBuiltinTypeForDWARFEncodingAndBitSize ( - const char *type_name, - uint32_t dw_ate, - uint32_t bit_size); - - CompilerType - GetCStringType(bool is_const); - - static CompilerType - GetUnknownAnyType(clang::ASTContext *ast); - - CompilerType - GetUnknownAnyType() - { - return ClangASTContext::GetUnknownAnyType(getASTContext()); + void SetExternalSource( + llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_ap); + + void RemoveExternalSource(); + + bool GetCompleteDecl(clang::Decl *decl) { + return ClangASTContext::GetCompleteDecl(getASTContext(), decl); + } + + static void DumpDeclHiearchy(clang::Decl *decl); + + static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx); + + static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl); + + static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl); + + void SetMetadataAsUserID(const void *object, lldb::user_id_t user_id); + + void SetMetadata(const void *object, ClangASTMetadata &meta_data) { + SetMetadata(getASTContext(), object, meta_data); + } + + static void SetMetadata(clang::ASTContext *ast, const void *object, + ClangASTMetadata &meta_data); + + ClangASTMetadata *GetMetadata(const void *object) { + return GetMetadata(getASTContext(), object); + } + + static ClangASTMetadata *GetMetadata(clang::ASTContext *ast, + const void *object); + + //------------------------------------------------------------------ + // Basic Types + //------------------------------------------------------------------ + CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) override; + + static CompilerType GetBuiltinTypeForEncodingAndBitSize( + clang::ASTContext *ast, lldb::Encoding encoding, uint32_t bit_size); + + CompilerType GetBasicType(lldb::BasicType type); + + static CompilerType GetBasicType(clang::ASTContext *ast, + lldb::BasicType type); + + static CompilerType GetBasicType(clang::ASTContext *ast, + const ConstString &name); + + static lldb::BasicType GetBasicTypeEnumeration(const ConstString &name); + + CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize(const char *type_name, + uint32_t dw_ate, + uint32_t bit_size); + + CompilerType GetCStringType(bool is_const); + + static CompilerType GetUnknownAnyType(clang::ASTContext *ast); + + CompilerType GetUnknownAnyType() { + return ClangASTContext::GetUnknownAnyType(getASTContext()); + } + + static clang::DeclContext *GetDeclContextForType(clang::QualType type); + + static clang::DeclContext *GetDeclContextForType(const CompilerType &type); + + uint32_t GetPointerByteSize() override; + + static clang::DeclContext *GetTranslationUnitDecl(clang::ASTContext *ast); + + clang::DeclContext *GetTranslationUnitDecl() { + return GetTranslationUnitDecl(getASTContext()); + } + + static clang::Decl *CopyDecl(clang::ASTContext *dest_context, + clang::ASTContext *source_context, + clang::Decl *source_decl); + + static bool AreTypesSame(CompilerType type1, CompilerType type2, + bool ignore_qualifiers = false); + + static CompilerType GetTypeForDecl(clang::NamedDecl *decl); + + static CompilerType GetTypeForDecl(clang::TagDecl *decl); + + static CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl); + + template <typename RecordDeclType> + CompilerType GetTypeForIdentifier(const ConstString &type_name) { + CompilerType compiler_type; + + if (type_name.GetLength()) { + clang::ASTContext *ast = getASTContext(); + if (ast) { + clang::IdentifierInfo &myIdent = + ast->Idents.get(type_name.GetCString()); + clang::DeclarationName myName = + ast->DeclarationNames.getIdentifier(&myIdent); + + clang::DeclContext::lookup_result result = + ast->getTranslationUnitDecl()->lookup(myName); + + if (!result.empty()) { + clang::NamedDecl *named_decl = result[0]; + if (const RecordDeclType *record_decl = + llvm::dyn_cast<RecordDeclType>(named_decl)) + compiler_type.SetCompilerType( + ast, clang::QualType(record_decl->getTypeForDecl(), 0)); + } + } } - - static clang::DeclContext * - GetDeclContextForType (clang::QualType type); - - static clang::DeclContext * - GetDeclContextForType (const CompilerType& type); - - uint32_t - GetPointerByteSize () override; - - static clang::DeclContext * - GetTranslationUnitDecl (clang::ASTContext *ast); - - clang::DeclContext * - GetTranslationUnitDecl () - { - return GetTranslationUnitDecl (getASTContext()); + + return compiler_type; + } + + CompilerType CreateStructForIdentifier( + const ConstString &type_name, + const std::initializer_list<std::pair<const char *, CompilerType>> + &type_fields, + bool packed = false); + + CompilerType GetOrCreateStructForIdentifier( + const ConstString &type_name, + const std::initializer_list<std::pair<const char *, CompilerType>> + &type_fields, + bool packed = false); + + //------------------------------------------------------------------ + // Structure, Unions, Classes + //------------------------------------------------------------------ + + static clang::AccessSpecifier + ConvertAccessTypeToAccessSpecifier(lldb::AccessType access); + + static clang::AccessSpecifier + UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs); + + static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl, + bool omit_empty_base_classes); + + CompilerType CreateRecordType(clang::DeclContext *decl_ctx, + lldb::AccessType access_type, const char *name, + int kind, lldb::LanguageType language, + ClangASTMetadata *metadata = nullptr); + + class TemplateParameterInfos { + public: + bool IsValid() const { + if (args.empty()) + return false; + return args.size() == names.size(); } - - static clang::Decl * - CopyDecl (clang::ASTContext *dest_context, - clang::ASTContext *source_context, - clang::Decl *source_decl); - - static bool - AreTypesSame(CompilerType type1, - CompilerType type2, - bool ignore_qualifiers = false); - - static CompilerType - GetTypeForDecl (clang::NamedDecl *decl); - - static CompilerType - GetTypeForDecl (clang::TagDecl *decl); - - static CompilerType - GetTypeForDecl (clang::ObjCInterfaceDecl *objc_decl); - - template <typename RecordDeclType> - CompilerType - GetTypeForIdentifier (const ConstString &type_name) - { - CompilerType compiler_type; - - if (type_name.GetLength()) - { - clang::ASTContext *ast = getASTContext(); - if (ast) - { - clang::IdentifierInfo &myIdent = ast->Idents.get(type_name.GetCString()); - clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent); - - clang::DeclContext::lookup_result result = ast->getTranslationUnitDecl()->lookup(myName); - - if (!result.empty()) - { - clang::NamedDecl *named_decl = result[0]; - if (const RecordDeclType *record_decl = llvm::dyn_cast<RecordDeclType>(named_decl)) - compiler_type.SetCompilerType(ast, clang::QualType(record_decl->getTypeForDecl(), 0)); - } - } - } - - return compiler_type; + + size_t GetSize() const { + if (IsValid()) + return args.size(); + return 0; } - - CompilerType - CreateStructForIdentifier (const ConstString &type_name, - const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, - bool packed = false); - - CompilerType - GetOrCreateStructForIdentifier (const ConstString &type_name, - const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, - bool packed = false); - - //------------------------------------------------------------------ - // Structure, Unions, Classes - //------------------------------------------------------------------ - - static clang::AccessSpecifier - ConvertAccessTypeToAccessSpecifier (lldb::AccessType access); - - static clang::AccessSpecifier - UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs); - - static uint32_t - GetNumBaseClasses (const clang::CXXRecordDecl *cxx_record_decl, - bool omit_empty_base_classes); - - CompilerType - CreateRecordType(clang::DeclContext *decl_ctx, - lldb::AccessType access_type, - const char *name, - int kind, - lldb::LanguageType language, - ClangASTMetadata *metadata = nullptr); - - class TemplateParameterInfos - { - public: - bool - IsValid() const - { - if (args.empty()) - return false; - return args.size() == names.size(); - } - size_t - GetSize () const - { - if (IsValid()) - return args.size(); - return 0; - } + llvm::SmallVector<const char *, 2> names; + llvm::SmallVector<clang::TemplateArgument, 2> args; + }; - llvm::SmallVector<const char *, 2> names; - llvm::SmallVector<clang::TemplateArgument, 2> args; - }; - - clang::FunctionTemplateDecl * - CreateFunctionTemplateDecl (clang::DeclContext *decl_ctx, - clang::FunctionDecl *func_decl, - const char *name, - const TemplateParameterInfos &infos); - - void - CreateFunctionTemplateSpecializationInfo (clang::FunctionDecl *func_decl, - clang::FunctionTemplateDecl *Template, - const TemplateParameterInfos &infos); - - clang::ClassTemplateDecl * - CreateClassTemplateDecl (clang::DeclContext *decl_ctx, - lldb::AccessType access_type, - const char *class_name, - int kind, + clang::FunctionTemplateDecl * + CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx, + clang::FunctionDecl *func_decl, const char *name, const TemplateParameterInfos &infos); - clang::ClassTemplateSpecializationDecl * - CreateClassTemplateSpecializationDecl (clang::DeclContext *decl_ctx, - clang::ClassTemplateDecl *class_template_decl, - int kind, - const TemplateParameterInfos &infos); - - CompilerType - CreateClassTemplateSpecializationType (clang::ClassTemplateSpecializationDecl *class_template_specialization_decl); - - static clang::DeclContext * - GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl); - - static clang::DeclContext * - GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl); - - - static bool - CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, - uint32_t num_params); - - bool - FieldIsBitfield (clang::FieldDecl* field, - uint32_t& bitfield_bit_size); - - static bool - FieldIsBitfield (clang::ASTContext *ast, - clang::FieldDecl* field, - uint32_t& bitfield_bit_size); - - static bool - RecordHasFields (const clang::RecordDecl *record_decl); - - CompilerType - CreateObjCClass(const char *name, - clang::DeclContext *decl_ctx, - bool isForwardDecl, - bool isInternal, - ClangASTMetadata *metadata = nullptr); - - bool - SetTagTypeKind (clang::QualType type, int kind) const; - - bool - SetDefaultAccessForRecordFields (clang::RecordDecl* record_decl, - int default_accessibility, - int *assigned_accessibilities, - size_t num_assigned_accessibilities); - - // Returns a mask containing bits from the ClangASTContext::eTypeXXX enumerations - - //------------------------------------------------------------------ - // Namespace Declarations - //------------------------------------------------------------------ - - clang::NamespaceDecl * - GetUniqueNamespaceDeclaration (const char *name, - clang::DeclContext *decl_ctx); - - static clang::NamespaceDecl * - GetUniqueNamespaceDeclaration (clang::ASTContext *ast, - const char *name, - clang::DeclContext *decl_ctx); - - //------------------------------------------------------------------ - // Function Types - //------------------------------------------------------------------ - - clang::FunctionDecl * - CreateFunctionDeclaration (clang::DeclContext *decl_ctx, - const char *name, - const CompilerType &function_Type, - int storage, - bool is_inline); - - static CompilerType - CreateFunctionType (clang::ASTContext *ast, - const CompilerType &result_type, - const CompilerType *args, - unsigned num_args, - bool is_variadic, - unsigned type_quals); - - CompilerType - CreateFunctionType (const CompilerType &result_type, - const CompilerType *args, - unsigned num_args, - bool is_variadic, - unsigned type_quals) - { - return ClangASTContext::CreateFunctionType(getASTContext(), - result_type, - args, - num_args, - is_variadic, - type_quals); - } - - clang::ParmVarDecl * - CreateParameterDeclaration (const char *name, - const CompilerType ¶m_type, - int storage); - - void - SetFunctionParameters (clang::FunctionDecl *function_decl, - clang::ParmVarDecl **params, - unsigned num_params); - - CompilerType - CreateBlockPointerType (const CompilerType &function_type); - - //------------------------------------------------------------------ - // Array Types - //------------------------------------------------------------------ - - CompilerType - CreateArrayType (const CompilerType &element_type, - size_t element_count, - bool is_vector); - - //------------------------------------------------------------------ - // Enumeration Types - //------------------------------------------------------------------ - CompilerType - CreateEnumerationType (const char *name, - clang::DeclContext *decl_ctx, - const Declaration &decl, - const CompilerType &integer_qual_type); - - //------------------------------------------------------------------ - // Integer type functions - //------------------------------------------------------------------ - - static CompilerType - GetIntTypeFromBitSize (clang::ASTContext *ast, - size_t bit_size, bool is_signed); - - CompilerType - GetPointerSizedIntType (bool is_signed) - { - return GetPointerSizedIntType (getASTContext(), is_signed); - } - - static CompilerType - GetPointerSizedIntType (clang::ASTContext *ast, bool is_signed); - - //------------------------------------------------------------------ - // Floating point functions - //------------------------------------------------------------------ - - static CompilerType - GetFloatTypeFromBitSize (clang::ASTContext *ast, - size_t bit_size); - - //------------------------------------------------------------------ - // TypeSystem methods - //------------------------------------------------------------------ - DWARFASTParser * - GetDWARFParser() override; - PDBASTParser * - GetPDBParser(); - - //------------------------------------------------------------------ - // ClangASTContext callbacks for external source lookups. - //------------------------------------------------------------------ - static void - CompleteTagDecl (void *baton, clang::TagDecl *); - - static void - CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *); - - static bool - LayoutRecordType(void *baton, - const clang::RecordDecl *record_decl, - uint64_t &size, - uint64_t &alignment, - llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); - - //---------------------------------------------------------------------- - // CompilerDecl override functions - //---------------------------------------------------------------------- - ConstString - DeclGetName (void *opaque_decl) override; - - ConstString - DeclGetMangledName (void *opaque_decl) override; - - CompilerDeclContext - DeclGetDeclContext (void *opaque_decl) override; - - CompilerType - DeclGetFunctionReturnType(void *opaque_decl) override; - - size_t - DeclGetFunctionNumArguments(void *opaque_decl) override; - - CompilerType - DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx) override; - - //---------------------------------------------------------------------- - // CompilerDeclContext override functions - //---------------------------------------------------------------------- - - std::vector<CompilerDecl> - DeclContextFindDeclByName (void *opaque_decl_ctx, - ConstString name, - const bool ignore_using_decls) override; - - bool - DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) override; - - ConstString - DeclContextGetName (void *opaque_decl_ctx) override; - - ConstString - DeclContextGetScopeQualifiedName (void *opaque_decl_ctx) override; - - bool - DeclContextIsClassMethod (void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override; - - //---------------------------------------------------------------------- - // Clang specific clang::DeclContext functions - //---------------------------------------------------------------------- - - static clang::DeclContext * - DeclContextGetAsDeclContext (const CompilerDeclContext &dc); - - static clang::ObjCMethodDecl * - DeclContextGetAsObjCMethodDecl (const CompilerDeclContext &dc); - - static clang::CXXMethodDecl * - DeclContextGetAsCXXMethodDecl (const CompilerDeclContext &dc); - - static clang::FunctionDecl * - DeclContextGetAsFunctionDecl (const CompilerDeclContext &dc); - - static clang::NamespaceDecl * - DeclContextGetAsNamespaceDecl (const CompilerDeclContext &dc); - - static ClangASTMetadata * - DeclContextGetMetaData (const CompilerDeclContext &dc, const void *object); - - static clang::ASTContext * - DeclContextGetClangASTContext (const CompilerDeclContext &dc); - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - bool - IsArrayType (lldb::opaque_compiler_type_t type, - CompilerType *element_type, - uint64_t *size, - bool *is_incomplete) override; - - bool - IsVectorType (lldb::opaque_compiler_type_t type, - CompilerType *element_type, - uint64_t *size) override; - - bool - IsAggregateType (lldb::opaque_compiler_type_t type) override; - - bool - IsAnonymousType (lldb::opaque_compiler_type_t type) override; - - bool - IsBeingDefined (lldb::opaque_compiler_type_t type) override; - - bool - IsCharType (lldb::opaque_compiler_type_t type) override; - - bool - IsCompleteType (lldb::opaque_compiler_type_t type) override; - - bool - IsConst(lldb::opaque_compiler_type_t type) override; - - bool - IsCStringType (lldb::opaque_compiler_type_t type, uint32_t &length) override; - - static bool - IsCXXClassType (const CompilerType& type); - - bool - IsDefined(lldb::opaque_compiler_type_t type) override; - - bool - IsFloatingPointType (lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override; - - bool - IsFunctionType (lldb::opaque_compiler_type_t type, bool *is_variadic_ptr) override; - - uint32_t - IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, CompilerType* base_type_ptr) override; - - size_t - GetNumberOfFunctionArguments (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetFunctionArgumentAtIndex (lldb::opaque_compiler_type_t type, const size_t index) override; - - bool - IsFunctionPointerType (lldb::opaque_compiler_type_t type) override; - - bool - IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; - - bool - IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) override; - - bool - IsEnumerationType (lldb::opaque_compiler_type_t type, bool &is_signed) override; - - static bool - IsObjCClassType (const CompilerType& type); - - static bool - IsObjCClassTypeAndHasIVars (const CompilerType& type, bool check_superclass); - - static bool - IsObjCObjectOrInterfaceType (const CompilerType& type); - - static bool - IsObjCObjectPointerType(const CompilerType& type, CompilerType *target_type = nullptr); - - bool - IsPolymorphicClass (lldb::opaque_compiler_type_t type) override; - - static bool - IsClassType(lldb::opaque_compiler_type_t type); - - static bool - IsEnumType(lldb::opaque_compiler_type_t type); - - bool - IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, // Can pass nullptr - bool check_cplusplus, - bool check_objc) override; - - bool - IsRuntimeGeneratedType (lldb::opaque_compiler_type_t type) override; - - bool - IsPointerType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type) override; - - bool - IsPointerOrReferenceType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type) override; - - bool - IsReferenceType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool* is_rvalue) override; - - bool - IsScalarType (lldb::opaque_compiler_type_t type) override; - - bool - IsTypedefType (lldb::opaque_compiler_type_t type) override; - - bool - IsVoidType (lldb::opaque_compiler_type_t type) override; - - bool - SupportsLanguage (lldb::LanguageType language) override; - - static bool - GetCXXClassName (const CompilerType& type, std::string &class_name); - - static bool - GetObjCClassName (const CompilerType& type, std::string &class_name); - - //---------------------------------------------------------------------- - // Type Completion - //---------------------------------------------------------------------- - - bool - GetCompleteType (lldb::opaque_compiler_type_t type) override; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - - ConstString - GetTypeName (lldb::opaque_compiler_type_t type) override; - - uint32_t - GetTypeInfo (lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type) override; - - lldb::LanguageType - GetMinimumLanguage (lldb::opaque_compiler_type_t type) override; - - lldb::TypeClass - GetTypeClass (lldb::opaque_compiler_type_t type) override; - - unsigned - GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; - - //---------------------------------------------------------------------- - // Creating related types - //---------------------------------------------------------------------- - - // Using the current type, create a new typedef to that type using "typedef_name" - // as the name and "decl_ctx" as the decl context. - static CompilerType - CreateTypedefType (const CompilerType& type, - const char *typedef_name, - const CompilerDeclContext &compiler_decl_ctx); - - CompilerType - GetArrayElementType (lldb::opaque_compiler_type_t type, uint64_t *stride) override; - - CompilerType - GetCanonicalType (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetFullyUnqualifiedType (lldb::opaque_compiler_type_t type) override; - - // Returns -1 if this isn't a function of if the function doesn't have a prototype - // Returns a value >= 0 if there is a prototype. - int - GetFunctionArgumentCount (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetFunctionArgumentTypeAtIndex (lldb::opaque_compiler_type_t type, size_t idx) override; - - CompilerType - GetFunctionReturnType (lldb::opaque_compiler_type_t type) override; - - size_t - GetNumMemberFunctions (lldb::opaque_compiler_type_t type) override; - - TypeMemberFunctionImpl - GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, size_t idx) override; - - CompilerType - GetNonReferenceType (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetPointeeType (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetPointerType (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetLValueReferenceType (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetRValueReferenceType (lldb::opaque_compiler_type_t type) override; - - CompilerType - AddConstModifier (lldb::opaque_compiler_type_t type) override; - - CompilerType - AddVolatileModifier (lldb::opaque_compiler_type_t type) override; - - CompilerType - AddRestrictModifier (lldb::opaque_compiler_type_t type) override; - - CompilerType - CreateTypedef (lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx) override; - - // If the current object represents a typedef type, get the underlying type - CompilerType - GetTypedefedType (lldb::opaque_compiler_type_t type) override; - - //---------------------------------------------------------------------- - // Create related types using the current type's AST - //---------------------------------------------------------------------- - CompilerType - GetBasicTypeFromAST (lldb::BasicType basic_type) override; - - //---------------------------------------------------------------------- - // Exploring the type - //---------------------------------------------------------------------- - - uint64_t - GetByteSize (lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) - { - return (GetBitSize (type, exe_scope) + 7) / 8; - } - - uint64_t - GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override; - - lldb::Encoding - GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count) override; - - lldb::Format - GetFormat (lldb::opaque_compiler_type_t type) override; - - size_t - GetTypeBitAlign (lldb::opaque_compiler_type_t type) override; - - uint32_t - GetNumChildren (lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override; - - CompilerType - GetBuiltinTypeByName (const ConstString &name) override; - - lldb::BasicType - GetBasicTypeEnumeration (lldb::opaque_compiler_type_t type) override; - - static lldb::BasicType - GetBasicTypeEnumeration (lldb::opaque_compiler_type_t type, const ConstString &name); - - void - ForEachEnumerator (lldb::opaque_compiler_type_t type, std::function <bool (const CompilerType &integer_type, const ConstString &name, const llvm::APSInt &value)> const &callback) override; - - uint32_t - GetNumFields (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetFieldAtIndex (lldb::opaque_compiler_type_t type, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) override; - - uint32_t - GetNumDirectBaseClasses (lldb::opaque_compiler_type_t type) override; - - uint32_t - GetNumVirtualBaseClasses (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetDirectBaseClassAtIndex (lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override; - - CompilerType - GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override; - - static uint32_t - GetNumPointeeChildren (clang::QualType type); - - CompilerType - GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, - size_t idx, - bool transparent_pointers, - bool omit_empty_base_classes, - bool ignore_array_bounds, - std::string& child_name, - uint32_t &child_byte_size, - int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, - bool &child_is_deref_of_parent, - ValueObject *valobj, - uint64_t &language_flags) override; - - // Lookup a child given a name. This function will match base class names - // and member member names in "clang_type" only, not descendants. - uint32_t - GetIndexOfChildWithName (lldb::opaque_compiler_type_t type, + void CreateFunctionTemplateSpecializationInfo( + clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template, + const TemplateParameterInfos &infos); + + clang::ClassTemplateDecl * + CreateClassTemplateDecl(clang::DeclContext *decl_ctx, + lldb::AccessType access_type, const char *class_name, + int kind, const TemplateParameterInfos &infos); + + clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( + clang::DeclContext *decl_ctx, + clang::ClassTemplateDecl *class_template_decl, int kind, + const TemplateParameterInfos &infos); + + CompilerType + CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl * + class_template_specialization_decl); + + static clang::DeclContext * + GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl); + + static clang::DeclContext * + GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl); + + static bool CheckOverloadedOperatorKindParameterCount( + bool is_method, clang::OverloadedOperatorKind op_kind, + uint32_t num_params); + + bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size); + + static bool FieldIsBitfield(clang::ASTContext *ast, clang::FieldDecl *field, + uint32_t &bitfield_bit_size); + + static bool RecordHasFields(const clang::RecordDecl *record_decl); + + CompilerType CreateObjCClass(const char *name, clang::DeclContext *decl_ctx, + bool isForwardDecl, bool isInternal, + ClangASTMetadata *metadata = nullptr); + + bool SetTagTypeKind(clang::QualType type, int kind) const; + + bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl, + int default_accessibility, + int *assigned_accessibilities, + size_t num_assigned_accessibilities); + + // Returns a mask containing bits from the ClangASTContext::eTypeXXX + // enumerations + + //------------------------------------------------------------------ + // Namespace Declarations + //------------------------------------------------------------------ + + clang::NamespaceDecl * + GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx); + + static clang::NamespaceDecl * + GetUniqueNamespaceDeclaration(clang::ASTContext *ast, const char *name, + clang::DeclContext *decl_ctx); + + //------------------------------------------------------------------ + // Function Types + //------------------------------------------------------------------ + + clang::FunctionDecl * + CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name, + const CompilerType &function_Type, int storage, + bool is_inline); + + static CompilerType CreateFunctionType(clang::ASTContext *ast, + const CompilerType &result_type, + const CompilerType *args, + unsigned num_args, bool is_variadic, + unsigned type_quals); + + CompilerType CreateFunctionType(const CompilerType &result_type, + const CompilerType *args, unsigned num_args, + bool is_variadic, unsigned type_quals) { + return ClangASTContext::CreateFunctionType( + getASTContext(), result_type, args, num_args, is_variadic, type_quals); + } + + clang::ParmVarDecl *CreateParameterDeclaration(const char *name, + const CompilerType ¶m_type, + int storage); + + void SetFunctionParameters(clang::FunctionDecl *function_decl, + clang::ParmVarDecl **params, unsigned num_params); + + CompilerType CreateBlockPointerType(const CompilerType &function_type); + + //------------------------------------------------------------------ + // Array Types + //------------------------------------------------------------------ + + CompilerType CreateArrayType(const CompilerType &element_type, + size_t element_count, bool is_vector); + + //------------------------------------------------------------------ + // Enumeration Types + //------------------------------------------------------------------ + CompilerType CreateEnumerationType(const char *name, + clang::DeclContext *decl_ctx, + const Declaration &decl, + const CompilerType &integer_qual_type); + + //------------------------------------------------------------------ + // Integer type functions + //------------------------------------------------------------------ + + static CompilerType GetIntTypeFromBitSize(clang::ASTContext *ast, + size_t bit_size, bool is_signed); + + CompilerType GetPointerSizedIntType(bool is_signed) { + return GetPointerSizedIntType(getASTContext(), is_signed); + } + + static CompilerType GetPointerSizedIntType(clang::ASTContext *ast, + bool is_signed); + + //------------------------------------------------------------------ + // Floating point functions + //------------------------------------------------------------------ + + static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast, + size_t bit_size); + + //------------------------------------------------------------------ + // TypeSystem methods + //------------------------------------------------------------------ + DWARFASTParser *GetDWARFParser() override; + PDBASTParser *GetPDBParser(); + + //------------------------------------------------------------------ + // ClangASTContext callbacks for external source lookups. + //------------------------------------------------------------------ + static void CompleteTagDecl(void *baton, clang::TagDecl *); + + static void CompleteObjCInterfaceDecl(void *baton, + clang::ObjCInterfaceDecl *); + + static bool LayoutRecordType( + void *baton, const clang::RecordDecl *record_decl, uint64_t &size, + uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &vbase_offsets); + + //---------------------------------------------------------------------- + // CompilerDecl override functions + //---------------------------------------------------------------------- + ConstString DeclGetName(void *opaque_decl) override; + + ConstString DeclGetMangledName(void *opaque_decl) override; + + CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override; + + CompilerType DeclGetFunctionReturnType(void *opaque_decl) override; + + size_t DeclGetFunctionNumArguments(void *opaque_decl) override; + + CompilerType DeclGetFunctionArgumentType(void *opaque_decl, + size_t arg_idx) override; + + //---------------------------------------------------------------------- + // CompilerDeclContext override functions + //---------------------------------------------------------------------- + + std::vector<CompilerDecl> + DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, + const bool ignore_using_decls) override; + + bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override; + + ConstString DeclContextGetName(void *opaque_decl_ctx) override; + + ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override; + + bool DeclContextIsClassMethod(void *opaque_decl_ctx, + lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, + ConstString *language_object_name_ptr) override; + + //---------------------------------------------------------------------- + // Clang specific clang::DeclContext functions + //---------------------------------------------------------------------- + + static clang::DeclContext * + DeclContextGetAsDeclContext(const CompilerDeclContext &dc); + + static clang::ObjCMethodDecl * + DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc); + + static clang::CXXMethodDecl * + DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc); + + static clang::FunctionDecl * + DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc); + + static clang::NamespaceDecl * + DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc); + + static ClangASTMetadata *DeclContextGetMetaData(const CompilerDeclContext &dc, + const void *object); + + static clang::ASTContext * + DeclContextGetClangASTContext(const CompilerDeclContext &dc); + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override; + + bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) override; + + bool IsAggregateType(lldb::opaque_compiler_type_t type) override; + + bool IsAnonymousType(lldb::opaque_compiler_type_t type) override; + + bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; + + bool IsCharType(lldb::opaque_compiler_type_t type) override; + + bool IsCompleteType(lldb::opaque_compiler_type_t type) override; + + bool IsConst(lldb::opaque_compiler_type_t type) override; + + bool IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) override; + + static bool IsCXXClassType(const CompilerType &type); + + bool IsDefined(lldb::opaque_compiler_type_t type) override; + + bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, + bool &is_complex) override; + + bool IsFunctionType(lldb::opaque_compiler_type_t type, + bool *is_variadic_ptr) override; + + uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) override; + + size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; + + CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) override; + + bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; + + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) override; + + bool IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) override; + + bool IsEnumerationType(lldb::opaque_compiler_type_t type, + bool &is_signed) override; + + static bool IsObjCClassType(const CompilerType &type); + + static bool IsObjCClassTypeAndHasIVars(const CompilerType &type, + bool check_superclass); + + static bool IsObjCObjectOrInterfaceType(const CompilerType &type); + + static bool IsObjCObjectPointerType(const CompilerType &type, + CompilerType *target_type = nullptr); + + bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; + + static bool IsClassType(lldb::opaque_compiler_type_t type); + + static bool IsEnumType(lldb::opaque_compiler_type_t type); + + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, // Can pass nullptr + bool check_cplusplus, bool check_objc) override; + + bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + + bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) override; + + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) override; + + bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type, bool *is_rvalue) override; + + bool IsScalarType(lldb::opaque_compiler_type_t type) override; + + bool IsTypedefType(lldb::opaque_compiler_type_t type) override; + + bool IsVoidType(lldb::opaque_compiler_type_t type) override; + + bool SupportsLanguage(lldb::LanguageType language) override; + + static bool GetCXXClassName(const CompilerType &type, + std::string &class_name); + + static bool GetObjCClassName(const CompilerType &type, + std::string &class_name); + + //---------------------------------------------------------------------- + // Type Completion + //---------------------------------------------------------------------- + + bool GetCompleteType(lldb::opaque_compiler_type_t type) override; + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + + ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; + + uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type) override; + + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; + + lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; + + unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + + //---------------------------------------------------------------------- + // Creating related types + //---------------------------------------------------------------------- + + // Using the current type, create a new typedef to that type using + // "typedef_name" + // as the name and "decl_ctx" as the decl context. + static CompilerType + CreateTypedefType(const CompilerType &type, const char *typedef_name, + const CompilerDeclContext &compiler_decl_ctx); + + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride) override; + + CompilerType GetArrayType(lldb::opaque_compiler_type_t type, + uint64_t size) override; + + CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; + + // Returns -1 if this isn't a function of if the function doesn't have a + // prototype + // Returns a value >= 0 if there is a prototype. + int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; + + CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; + + CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; + + size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; + + TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; + + CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetRValueReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override; + + CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override; + + CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override; + + CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, - bool omit_empty_base_classes) override; - - // Lookup a child member given a name. This function will match member names - // only and will descend into "clang_type" children in search for the first - // member in this class, or any base class that matches "name". - // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>> - // so we catch all names that match a given child name, not just the first. - size_t - GetIndexOfChildMemberWithName (lldb::opaque_compiler_type_t type, + const CompilerDeclContext &decl_ctx) override; + + // If the current object represents a typedef type, get the underlying type + CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; + + //---------------------------------------------------------------------- + // Create related types using the current type's AST + //---------------------------------------------------------------------- + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; + + //---------------------------------------------------------------------- + // Exploring the type + //---------------------------------------------------------------------- + + uint64_t GetByteSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) { + return (GetBitSize(type, exe_scope) + 7) / 8; + } + + uint64_t GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override; + + lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, + uint64_t &count) override; + + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; + + size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + + uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes) override; + + CompilerType GetBuiltinTypeByName(const ConstString &name) override; + + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; + + static lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type, + const ConstString &name); + + void ForEachEnumerator( + lldb::opaque_compiler_type_t type, + std::function<bool(const CompilerType &integer_type, + const ConstString &name, + const llvm::APSInt &value)> const &callback) override; + + uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; + + CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) override; + + uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; + + uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; + + CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override; + + CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override; + + static uint32_t GetNumPointeeChildren(clang::QualType type); + + CompilerType GetChildCompilerTypeAtIndex( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags) override; + + // Lookup a child given a name. This function will match base class names + // and member member names in "clang_type" only, not descendants. + uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, - bool omit_empty_base_classes, - std::vector<uint32_t>& child_indexes) override; - - size_t - GetNumTemplateArguments (lldb::opaque_compiler_type_t type) override; - - CompilerType - GetTemplateArgument (lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) override; - - CompilerType - GetTypeForFormatters (void* type) override; - -#define LLDB_INVALID_DECL_LEVEL UINT32_MAX - // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if - // child_decl_ctx could not be found in decl_ctx. - uint32_t - CountDeclLevels (clang::DeclContext *frame_decl_ctx, - clang::DeclContext *child_decl_ctx, - ConstString *child_name = nullptr, - CompilerType *child_type = nullptr); - - //---------------------------------------------------------------------- - // Modifying RecordType - //---------------------------------------------------------------------- - static clang::FieldDecl * - AddFieldToRecordType (const CompilerType& type, - const char *name, - const CompilerType &field_type, - lldb::AccessType access, - uint32_t bitfield_bit_size); - - static void - BuildIndirectFields (const CompilerType& type); - - static void - SetIsPacked (const CompilerType& type); - - static clang::VarDecl * - AddVariableToRecordType (const CompilerType& type, - const char *name, - const CompilerType &var_type, - lldb::AccessType access); - - clang::CXXMethodDecl * - AddMethodToCXXRecordType (lldb::opaque_compiler_type_t type, - const char *name, - const CompilerType &method_type, - lldb::AccessType access, - bool is_virtual, - bool is_static, - bool is_inline, - bool is_explicit, - bool is_attr_used, - bool is_artificial); - - // C++ Base Classes - clang::CXXBaseSpecifier * - CreateBaseClassSpecifier (lldb::opaque_compiler_type_t type, - lldb::AccessType access, - bool is_virtual, - bool base_of_class); - - static void - DeleteBaseClassSpecifiers (clang::CXXBaseSpecifier **base_classes, - unsigned num_base_classes); - - bool - SetBaseClassesForClassType (lldb::opaque_compiler_type_t type, - clang::CXXBaseSpecifier const * const *base_classes, - unsigned num_base_classes); - - static bool - SetObjCSuperClass (const CompilerType& type, - const CompilerType &superclass_compiler_type); - - static bool - AddObjCClassProperty (const CompilerType& type, - const char *property_name, - const CompilerType &property_compiler_type, - clang::ObjCIvarDecl *ivar_decl, - const char *property_setter_name, - const char *property_getter_name, - uint32_t property_attributes, - ClangASTMetadata *metadata); - - static clang::ObjCMethodDecl * - AddMethodToObjCObjectType (const CompilerType& type, - const char *name, // the full symbol name as seen in the symbol table (lldb::opaque_compiler_type_t type, "-[NString stringWithCString:]") - const CompilerType &method_compiler_type, - lldb::AccessType access, - bool is_artificial, - bool is_variadic); - - static bool - SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern); - - static bool - GetHasExternalStorage (const CompilerType &type); - //------------------------------------------------------------------ - // Tag Declarations - //------------------------------------------------------------------ - static bool - StartTagDeclarationDefinition (const CompilerType &type); - - static bool - CompleteTagDeclarationDefinition (const CompilerType &type); - - //---------------------------------------------------------------------- - // Modifying Enumeration types - //---------------------------------------------------------------------- - bool - AddEnumerationValueToEnumerationType (lldb::opaque_compiler_type_t type, - const CompilerType &enumerator_qual_type, - const Declaration &decl, - const char *name, - int64_t enum_value, - uint32_t enum_value_bit_size); - - CompilerType - GetEnumerationIntegerType (lldb::opaque_compiler_type_t type); - - //------------------------------------------------------------------ - // Pointers & References - //------------------------------------------------------------------ - - // Call this function using the class type when you want to make a - // member pointer type to pointee_type. - static CompilerType - CreateMemberPointerType (const CompilerType& type, const CompilerType &pointee_type); - - // Converts "s" to a floating point value and place resulting floating - // point bytes in the "dst" buffer. - size_t - ConvertStringToFloatValue (lldb::opaque_compiler_type_t type, - const char *s, - uint8_t *dst, - size_t dst_size) override; - - //---------------------------------------------------------------------- - // Dumping types - //---------------------------------------------------------------------- - void - DumpValue (lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, - Stream *s, - lldb::Format format, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - bool show_types, - bool show_summary, - bool verbose, - uint32_t depth) override; - - bool - DumpTypeValue (lldb::opaque_compiler_type_t type, - Stream *s, - lldb::Format format, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) override; - - void - DumpSummary (lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, - Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) override; - - void - DumpTypeDescription (lldb::opaque_compiler_type_t type) override; // Dump to stdout - - void - DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream *s) override; - - static void - DumpTypeName (const CompilerType &type); - - static clang::EnumDecl * - GetAsEnumDecl (const CompilerType& type); - - static clang::RecordDecl * - GetAsRecordDecl (const CompilerType& type); - - static clang::TagDecl * - GetAsTagDecl (const CompilerType& type); - - clang::CXXRecordDecl * - GetAsCXXRecordDecl (lldb::opaque_compiler_type_t type); - - static clang::ObjCInterfaceDecl * - GetAsObjCInterfaceDecl (const CompilerType& type); - - clang::ClassTemplateDecl * - ParseClassTemplateDecl (clang::DeclContext *decl_ctx, - lldb::AccessType access_type, - const char *parent_name, - int tag_decl_kind, - const ClangASTContext::TemplateParameterInfos &template_param_infos); - - clang::BlockDecl * - CreateBlockDeclaration (clang::DeclContext *ctx); - - clang::UsingDirectiveDecl * - CreateUsingDirectiveDeclaration (clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl); - - clang::UsingDecl * - CreateUsingDeclaration (clang::DeclContext *current_decl_ctx, clang::NamedDecl *target); - - clang::VarDecl * - CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type); - - static lldb::opaque_compiler_type_t - GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); - - static clang::QualType - GetQualType(lldb::opaque_compiler_type_t type) - { - if (type) - return clang::QualType::getFromOpaquePtr(type); - return clang::QualType(); - } + bool omit_empty_base_classes) override; + + // Lookup a child member given a name. This function will match member names + // only and will descend into "clang_type" children in search for the first + // member in this class, or any base class that matches "name". + // TODO: Return all matches for a given name by returning a + // vector<vector<uint32_t>> + // so we catch all names that match a given child name, not just the first. + size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, + const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) override; + + size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; + + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override; + + CompilerType GetTypeForFormatters(void *type) override; + +#define LLDB_INVALID_DECL_LEVEL UINT32_MAX + // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if + // child_decl_ctx could not be found in decl_ctx. + uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx, + clang::DeclContext *child_decl_ctx, + ConstString *child_name = nullptr, + CompilerType *child_type = nullptr); + + //---------------------------------------------------------------------- + // Modifying RecordType + //---------------------------------------------------------------------- + static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type, + const char *name, + const CompilerType &field_type, + lldb::AccessType access, + uint32_t bitfield_bit_size); + + static void BuildIndirectFields(const CompilerType &type); + + static void SetIsPacked(const CompilerType &type); + + static clang::VarDecl *AddVariableToRecordType(const CompilerType &type, + const char *name, + const CompilerType &var_type, + lldb::AccessType access); + + clang::CXXMethodDecl * + AddMethodToCXXRecordType(lldb::opaque_compiler_type_t type, const char *name, + const CompilerType &method_type, + lldb::AccessType access, bool is_virtual, + bool is_static, bool is_inline, bool is_explicit, + bool is_attr_used, bool is_artificial); + + // C++ Base Classes + clang::CXXBaseSpecifier * + CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, + lldb::AccessType access, bool is_virtual, + bool base_of_class); + + static void DeleteBaseClassSpecifiers(clang::CXXBaseSpecifier **base_classes, + unsigned num_base_classes); + + bool + SetBaseClassesForClassType(lldb::opaque_compiler_type_t type, + clang::CXXBaseSpecifier const *const *base_classes, + unsigned num_base_classes); + + static bool SetObjCSuperClass(const CompilerType &type, + const CompilerType &superclass_compiler_type); + + static bool AddObjCClassProperty(const CompilerType &type, + const char *property_name, + const CompilerType &property_compiler_type, + clang::ObjCIvarDecl *ivar_decl, + const char *property_setter_name, + const char *property_getter_name, + uint32_t property_attributes, + ClangASTMetadata *metadata); + + static clang::ObjCMethodDecl *AddMethodToObjCObjectType( + const CompilerType &type, + const char *name, // the full symbol name as seen in the symbol table + // (lldb::opaque_compiler_type_t type, "-[NString + // stringWithCString:]") + const CompilerType &method_compiler_type, lldb::AccessType access, + bool is_artificial, bool is_variadic); + + static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type, + bool has_extern); + + static bool GetHasExternalStorage(const CompilerType &type); + //------------------------------------------------------------------ + // Tag Declarations + //------------------------------------------------------------------ + static bool StartTagDeclarationDefinition(const CompilerType &type); + + static bool CompleteTagDeclarationDefinition(const CompilerType &type); + + //---------------------------------------------------------------------- + // Modifying Enumeration types + //---------------------------------------------------------------------- + bool AddEnumerationValueToEnumerationType( + lldb::opaque_compiler_type_t type, + const CompilerType &enumerator_qual_type, const Declaration &decl, + const char *name, int64_t enum_value, uint32_t enum_value_bit_size); + + CompilerType GetEnumerationIntegerType(lldb::opaque_compiler_type_t type); + + //------------------------------------------------------------------ + // Pointers & References + //------------------------------------------------------------------ + + // Call this function using the class type when you want to make a + // member pointer type to pointee_type. + static CompilerType CreateMemberPointerType(const CompilerType &type, + const CompilerType &pointee_type); + + // Converts "s" to a floating point value and place resulting floating + // point bytes in the "dst" buffer. + size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, + const char *s, uint8_t *dst, + size_t dst_size) override; + + //---------------------------------------------------------------------- + // Dumping types + //---------------------------------------------------------------------- + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + bool show_types, bool show_summary, bool verbose, + uint32_t depth) override; + + bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) override; + + void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size) override; + + void DumpTypeDescription( + lldb::opaque_compiler_type_t type) override; // Dump to stdout + + void DumpTypeDescription(lldb::opaque_compiler_type_t type, + Stream *s) override; + + static void DumpTypeName(const CompilerType &type); + + static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type); + + static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type); + + static clang::TagDecl *GetAsTagDecl(const CompilerType &type); + + clang::CXXRecordDecl *GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type); + + static clang::ObjCInterfaceDecl * + GetAsObjCInterfaceDecl(const CompilerType &type); + + clang::ClassTemplateDecl *ParseClassTemplateDecl( + clang::DeclContext *decl_ctx, lldb::AccessType access_type, + const char *parent_name, int tag_decl_kind, + const ClangASTContext::TemplateParameterInfos &template_param_infos); + + clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx); + + clang::UsingDirectiveDecl * + CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx, + clang::NamespaceDecl *ns_decl); + + clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, + clang::NamedDecl *target); + + clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context, + const char *name, + clang::QualType type); + + static lldb::opaque_compiler_type_t + GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); - static clang::QualType - GetCanonicalQualType(lldb::opaque_compiler_type_t type) - { - if (type) - return clang::QualType::getFromOpaquePtr(type).getCanonicalType(); - return clang::QualType(); - } + static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) { + if (type) + return clang::QualType::getFromOpaquePtr(type); + return clang::QualType(); + } + + static clang::QualType + GetCanonicalQualType(lldb::opaque_compiler_type_t type) { + if (type) + return clang::QualType::getFromOpaquePtr(type).getCanonicalType(); + return clang::QualType(); + } + + clang::DeclarationName + GetDeclarationName(const char *name, const CompilerType &function_clang_type); protected: - //------------------------------------------------------------------ - // Classes that inherit from ClangASTContext can see and modify these - //------------------------------------------------------------------ - // clang-format off + //------------------------------------------------------------------ + // Classes that inherit from ClangASTContext can see and modify these + //------------------------------------------------------------------ + // clang-format off std::string m_target_triple; std::unique_ptr<clang::ASTContext> m_ast_ap; std::unique_ptr<clang::LangOptions> m_language_options_ap; @@ -1216,43 +994,46 @@ protected: uint32_t m_pointer_byte_size; bool m_ast_owned; bool m_can_evaluate_expressions; - // clang-format on + // clang-format on private: - //------------------------------------------------------------------ - // For ClangASTContext only - //------------------------------------------------------------------ - ClangASTContext(const ClangASTContext&); - const ClangASTContext& operator=(const ClangASTContext&); + //------------------------------------------------------------------ + // For ClangASTContext only + //------------------------------------------------------------------ + ClangASTContext(const ClangASTContext &); + const ClangASTContext &operator=(const ClangASTContext &); }; -class ClangASTContextForExpressions : public ClangASTContext -{ +class ClangASTContextForExpressions : public ClangASTContext { public: - ClangASTContextForExpressions (Target &target); - - ~ClangASTContextForExpressions() override = default; - - UserExpression * - GetUserExpression (const char *expr, - const char *expr_prefix, - lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) override; - - FunctionCaller * - GetFunctionCaller (const CompilerType &return_type, - const Address& function_address, - const ValueList &arg_value_list, - const char *name) override; - - UtilityFunction * - GetUtilityFunction(const char *text, const char *name) override; - - PersistentExpressionState * - GetPersistentExpressionState() override; + ClangASTContextForExpressions(Target &target); + + ~ClangASTContextForExpressions() override = default; + + UserExpression * + GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, + lldb::LanguageType language, + Expression::ResultType desired_type, + const EvaluateExpressionOptions &options) override; + + FunctionCaller *GetFunctionCaller(const CompilerType &return_type, + const Address &function_address, + const ValueList &arg_value_list, + const char *name) override; + + UtilityFunction *GetUtilityFunction(const char *text, + const char *name) override; + + PersistentExpressionState *GetPersistentExpressionState() override; + private: - lldb::TargetWP m_target_wp; - lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the persistent variables associated with this process for the expression parser. + lldb::TargetWP m_target_wp; + lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the + ///persistent + ///variables + ///associated with + ///this process for + ///the expression + ///parser. }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h index 0ea7308d9541..6823ad748282 100644 --- a/include/lldb/Symbol/ClangASTImporter.h +++ b/include/lldb/Symbol/ClangASTImporter.h @@ -26,399 +26,325 @@ #include "clang/Basic/FileSystemOptions.h" // Project includes -#include "lldb/lldb-types.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/lldb-types.h" #include "llvm/ADT/DenseMap.h" namespace lldb_private { - -class ClangASTMetrics -{ + +class ClangASTMetrics { public: - static void DumpCounters (Log *log); - static void ClearLocalCounters () - { - local_counters = { 0, 0, 0, 0, 0, 0 }; - } - - static void RegisterVisibleQuery () - { - ++global_counters.m_visible_query_count; - ++local_counters.m_visible_query_count; - } - - static void RegisterLexicalQuery () - { - ++global_counters.m_lexical_query_count; - ++local_counters.m_lexical_query_count; - } - - static void RegisterLLDBImport () - { - ++global_counters.m_lldb_import_count; - ++local_counters.m_lldb_import_count; - } - - static void RegisterClangImport () - { - ++global_counters.m_clang_import_count; - ++local_counters.m_clang_import_count; - } - - static void RegisterDeclCompletion () - { - ++global_counters.m_decls_completed_count; - ++local_counters.m_decls_completed_count; - } - - static void RegisterRecordLayout () - { - ++global_counters.m_record_layout_count; - ++local_counters.m_record_layout_count; - } - + static void DumpCounters(Log *log); + static void ClearLocalCounters() { local_counters = {0, 0, 0, 0, 0, 0}; } + + static void RegisterVisibleQuery() { + ++global_counters.m_visible_query_count; + ++local_counters.m_visible_query_count; + } + + static void RegisterLexicalQuery() { + ++global_counters.m_lexical_query_count; + ++local_counters.m_lexical_query_count; + } + + static void RegisterLLDBImport() { + ++global_counters.m_lldb_import_count; + ++local_counters.m_lldb_import_count; + } + + static void RegisterClangImport() { + ++global_counters.m_clang_import_count; + ++local_counters.m_clang_import_count; + } + + static void RegisterDeclCompletion() { + ++global_counters.m_decls_completed_count; + ++local_counters.m_decls_completed_count; + } + + static void RegisterRecordLayout() { + ++global_counters.m_record_layout_count; + ++local_counters.m_record_layout_count; + } + private: - struct Counters - { - uint64_t m_visible_query_count; - uint64_t m_lexical_query_count; - uint64_t m_lldb_import_count; - uint64_t m_clang_import_count; - uint64_t m_decls_completed_count; - uint64_t m_record_layout_count; - }; - - static Counters global_counters; - static Counters local_counters; - - static void DumpCounters (Log *log, Counters &counters); + struct Counters { + uint64_t m_visible_query_count; + uint64_t m_lexical_query_count; + uint64_t m_lldb_import_count; + uint64_t m_clang_import_count; + uint64_t m_decls_completed_count; + uint64_t m_record_layout_count; + }; + + static Counters global_counters; + static Counters local_counters; + + static void DumpCounters(Log *log, Counters &counters); }; -class ClangASTImporter -{ +class ClangASTImporter { public: - struct LayoutInfo - { - LayoutInfo() : bit_size(0), alignment(0), field_offsets(), base_offsets(), vbase_offsets() {} - uint64_t bit_size; - uint64_t alignment; - llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets; - }; - - ClangASTImporter () : - m_file_manager(clang::FileSystemOptions()) - { + struct LayoutInfo { + LayoutInfo() + : bit_size(0), alignment(0), field_offsets(), base_offsets(), + vbase_offsets() {} + uint64_t bit_size; + uint64_t alignment; + llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + vbase_offsets; + }; + + ClangASTImporter() : m_file_manager(clang::FileSystemOptions()) {} + + clang::QualType CopyType(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx, clang::QualType type); + + lldb::opaque_compiler_type_t CopyType(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx, + lldb::opaque_compiler_type_t type); + + CompilerType CopyType(ClangASTContext &dst, const CompilerType &src_type); + + clang::Decl *CopyDecl(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx, + clang::Decl *decl); + + lldb::opaque_compiler_type_t DeportType(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx, + lldb::opaque_compiler_type_t type); + + clang::Decl *DeportDecl(clang::ASTContext *dst_ctx, + clang::ASTContext *src_ctx, clang::Decl *decl); + + void InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout); + + bool LayoutRecordType( + const clang::RecordDecl *record_decl, uint64_t &bit_size, + uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &vbase_offsets); + + bool CanImport(const CompilerType &type); + + bool Import(const CompilerType &type); + + bool CompleteType(const CompilerType &compiler_type); + + void CompleteDecl(clang::Decl *decl); + + bool CompleteTagDecl(clang::TagDecl *decl); + + bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin); + + bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl); + + bool CompleteAndFetchChildren(clang::QualType type); + + bool RequireCompleteType(clang::QualType type); + + bool ResolveDeclOrigin(const clang::Decl *decl, clang::Decl **original_decl, + clang::ASTContext **original_ctx) { + DeclOrigin origin = GetDeclOrigin(decl); + + if (original_decl) + *original_decl = origin.decl; + + if (original_ctx) + *original_ctx = origin.ctx; + + return origin.Valid(); + } + + void SetDeclOrigin(const clang::Decl *decl, clang::Decl *original_decl); + + ClangASTMetadata *GetDeclMetadata(const clang::Decl *decl); + + // + // Namespace maps + // + + typedef std::vector<std::pair<lldb::ModuleSP, CompilerDeclContext>> + NamespaceMap; + typedef std::shared_ptr<NamespaceMap> NamespaceMapSP; + + void RegisterNamespaceMap(const clang::NamespaceDecl *decl, + NamespaceMapSP &namespace_map); + + NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl); + + void BuildNamespaceMap(const clang::NamespaceDecl *decl); + + // + // Completers for maps + // + + class MapCompleter { + public: + virtual ~MapCompleter(); + + virtual void CompleteNamespaceMap(NamespaceMapSP &namespace_map, + const ConstString &name, + NamespaceMapSP &parent_map) const = 0; + }; + + void InstallMapCompleter(clang::ASTContext *dst_ctx, + MapCompleter &completer) { + ASTContextMetadataSP context_md; + ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); + + if (context_md_iter == m_metadata_map.end()) { + context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); + m_metadata_map[dst_ctx] = context_md; + } else { + context_md = context_md_iter->second; } - - clang::QualType - CopyType (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - clang::QualType type); - - lldb::opaque_compiler_type_t - CopyType (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - lldb::opaque_compiler_type_t type); - - CompilerType - CopyType (ClangASTContext &dst, - const CompilerType &src_type); - - clang::Decl * - CopyDecl (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - clang::Decl *decl); - - lldb::opaque_compiler_type_t - DeportType (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - lldb::opaque_compiler_type_t type); - - clang::Decl * - DeportDecl (clang::ASTContext *dst_ctx, - clang::ASTContext *src_ctx, - clang::Decl *decl); - void - InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout); + context_md->m_map_completer = &completer; + } - bool - LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment, - llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); + void ForgetDestination(clang::ASTContext *dst_ctx); + void ForgetSource(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); - bool - CanImport(const CompilerType &type); +private: + struct DeclOrigin { + DeclOrigin() : ctx(nullptr), decl(nullptr) {} - bool - Import(const CompilerType &type); + DeclOrigin(clang::ASTContext *_ctx, clang::Decl *_decl) + : ctx(_ctx), decl(_decl) {} - bool - CompleteType(const CompilerType &compiler_type); + DeclOrigin(const DeclOrigin &rhs) { + ctx = rhs.ctx; + decl = rhs.decl; + } - void - CompleteDecl(clang::Decl *decl); - - bool - CompleteTagDecl (clang::TagDecl *decl); - - bool - CompleteTagDeclWithOrigin (clang::TagDecl *decl, clang::TagDecl *origin); - - bool - CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface_decl); - - bool - CompleteAndFetchChildren (clang::QualType type); - - bool - RequireCompleteType (clang::QualType type); - - bool - ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) - { - DeclOrigin origin = GetDeclOrigin(decl); - - if (original_decl) - *original_decl = origin.decl; - - if (original_ctx) - *original_ctx = origin.ctx; - - return origin.Valid(); + void operator=(const DeclOrigin &rhs) { + ctx = rhs.ctx; + decl = rhs.decl; } - - void - SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl); - - ClangASTMetadata * - GetDeclMetadata (const clang::Decl *decl); - - // - // Namespace maps - // - - typedef std::vector < std::pair<lldb::ModuleSP, CompilerDeclContext> > NamespaceMap; - typedef std::shared_ptr<NamespaceMap> NamespaceMapSP; - - void RegisterNamespaceMap (const clang::NamespaceDecl *decl, - NamespaceMapSP &namespace_map); - - NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); - - void BuildNamespaceMap (const clang::NamespaceDecl *decl); - + + bool Valid() { return (ctx != nullptr || decl != nullptr); } + + clang::ASTContext *ctx; + clang::Decl *decl; + }; + + typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; + + class Minion : public clang::ASTImporter { + public: + Minion(ClangASTImporter &master, clang::ASTContext *target_ctx, + clang::ASTContext *source_ctx) + : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, + master.m_file_manager, true /*minimal*/), + m_decls_to_deport(nullptr), m_decls_already_deported(nullptr), + m_master(master), m_source_ctx(source_ctx) {} + + // A call to "InitDeportWorkQueues" puts the minion into deport mode. + // In deport mode, every copied Decl that could require completion is + // recorded and placed into the decls_to_deport set. // - // Completers for maps + // A call to "ExecuteDeportWorkQueues" completes all the Decls that + // are in decls_to_deport, adding any Decls it sees along the way that + // it hasn't already deported. It proceeds until decls_to_deport is + // empty. // - - class MapCompleter - { - public: - virtual ~MapCompleter (); - - virtual void CompleteNamespaceMap (NamespaceMapSP &namespace_map, - const ConstString &name, - NamespaceMapSP &parent_map) const = 0; - }; - - void InstallMapCompleter (clang::ASTContext *dst_ctx, MapCompleter &completer) - { - ASTContextMetadataSP context_md; - ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); - - if (context_md_iter == m_metadata_map.end()) - { - context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); - m_metadata_map[dst_ctx] = context_md; - } - else - { - context_md = context_md_iter->second; - } - - context_md->m_map_completer = &completer; - } - - void ForgetDestination (clang::ASTContext *dst_ctx); - void ForgetSource (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx); + // These calls must be paired. Leaving a minion in deport mode or + // trying to start deport minion with a new pair of queues will result + // in an assertion failure. -private: - struct DeclOrigin - { - DeclOrigin () : - ctx(nullptr), - decl(nullptr) - { - } - - DeclOrigin (clang::ASTContext *_ctx, - clang::Decl *_decl) : - ctx(_ctx), - decl(_decl) - { - } - - DeclOrigin (const DeclOrigin &rhs) - { - ctx = rhs.ctx; - decl = rhs.decl; - } - - void operator= (const DeclOrigin &rhs) - { - ctx = rhs.ctx; - decl = rhs.decl; - } - - bool - Valid () - { - return (ctx != nullptr || decl != nullptr); - } - - clang::ASTContext *ctx; - clang::Decl *decl; - }; - - typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; - - class Minion : public clang::ASTImporter - { - public: - Minion (ClangASTImporter &master, - clang::ASTContext *target_ctx, - clang::ASTContext *source_ctx) : - clang::ASTImporter(*target_ctx, - master.m_file_manager, - *source_ctx, - master.m_file_manager, - true /*minimal*/), - m_decls_to_deport(nullptr), - m_decls_already_deported(nullptr), - m_master(master), - m_source_ctx(source_ctx) - { - } - - // A call to "InitDeportWorkQueues" puts the minion into deport mode. - // In deport mode, every copied Decl that could require completion is - // recorded and placed into the decls_to_deport set. - // - // A call to "ExecuteDeportWorkQueues" completes all the Decls that - // are in decls_to_deport, adding any Decls it sees along the way that - // it hasn't already deported. It proceeds until decls_to_deport is - // empty. - // - // These calls must be paired. Leaving a minion in deport mode or - // trying to start deport minion with a new pair of queues will result - // in an assertion failure. - - void InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport, - std::set<clang::NamedDecl *> *decls_already_deported); - void ExecuteDeportWorkQueues (); - - void ImportDefinitionTo (clang::Decl *to, clang::Decl *from); - - clang::Decl *Imported(clang::Decl *from, clang::Decl *to) override; - - clang::Decl *GetOriginalDecl(clang::Decl *To) override; - - std::set<clang::NamedDecl *> *m_decls_to_deport; - std::set<clang::NamedDecl *> *m_decls_already_deported; - ClangASTImporter &m_master; - clang::ASTContext *m_source_ctx; - }; - - typedef std::shared_ptr<Minion> MinionSP; - typedef std::map<clang::ASTContext *, MinionSP> MinionMap; - typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap; - - struct ASTContextMetadata - { - ASTContextMetadata(clang::ASTContext *dst_ctx) : - m_dst_ctx (dst_ctx), - m_minions (), - m_origins (), - m_namespace_maps (), - m_map_completer (nullptr) - { - } - - clang::ASTContext *m_dst_ctx; - MinionMap m_minions; - OriginMap m_origins; - - NamespaceMetaMap m_namespace_maps; - MapCompleter *m_map_completer; - }; - - typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP; - typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap; - - ContextMetadataMap m_metadata_map; - - ASTContextMetadataSP - GetContextMetadata (clang::ASTContext *dst_ctx) - { - ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); - - if (context_md_iter == m_metadata_map.end()) - { - ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); - m_metadata_map[dst_ctx] = context_md; - return context_md; - } - else - { - return context_md_iter->second; - } - } - - ASTContextMetadataSP - MaybeGetContextMetadata (clang::ASTContext *dst_ctx) - { - ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); - - if (context_md_iter != m_metadata_map.end()) - return context_md_iter->second; - else - return ASTContextMetadataSP(); + void + InitDeportWorkQueues(std::set<clang::NamedDecl *> *decls_to_deport, + std::set<clang::NamedDecl *> *decls_already_deported); + void ExecuteDeportWorkQueues(); + + void ImportDefinitionTo(clang::Decl *to, clang::Decl *from); + + clang::Decl *Imported(clang::Decl *from, clang::Decl *to) override; + + clang::Decl *GetOriginalDecl(clang::Decl *To) override; + + std::set<clang::NamedDecl *> *m_decls_to_deport; + std::set<clang::NamedDecl *> *m_decls_already_deported; + ClangASTImporter &m_master; + clang::ASTContext *m_source_ctx; + }; + + typedef std::shared_ptr<Minion> MinionSP; + typedef std::map<clang::ASTContext *, MinionSP> MinionMap; + typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> + NamespaceMetaMap; + + struct ASTContextMetadata { + ASTContextMetadata(clang::ASTContext *dst_ctx) + : m_dst_ctx(dst_ctx), m_minions(), m_origins(), m_namespace_maps(), + m_map_completer(nullptr) {} + + clang::ASTContext *m_dst_ctx; + MinionMap m_minions; + OriginMap m_origins; + + NamespaceMetaMap m_namespace_maps; + MapCompleter *m_map_completer; + }; + + typedef std::shared_ptr<ASTContextMetadata> ASTContextMetadataSP; + typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> + ContextMetadataMap; + + ContextMetadataMap m_metadata_map; + + ASTContextMetadataSP GetContextMetadata(clang::ASTContext *dst_ctx) { + ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); + + if (context_md_iter == m_metadata_map.end()) { + ASTContextMetadataSP context_md = + ASTContextMetadataSP(new ASTContextMetadata(dst_ctx)); + m_metadata_map[dst_ctx] = context_md; + return context_md; + } else { + return context_md_iter->second; } - - MinionSP - GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) - { - ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); - - MinionMap &minions = context_md->m_minions; - MinionMap::iterator minion_iter = minions.find(src_ctx); - - if (minion_iter == minions.end()) - { - MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); - minions[src_ctx] = minion; - return minion; - } - else - { - return minion_iter->second; - } + } + + ASTContextMetadataSP MaybeGetContextMetadata(clang::ASTContext *dst_ctx) { + ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx); + + if (context_md_iter != m_metadata_map.end()) + return context_md_iter->second; + else + return ASTContextMetadataSP(); + } + + MinionSP GetMinion(clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx) { + ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx); + + MinionMap &minions = context_md->m_minions; + MinionMap::iterator minion_iter = minions.find(src_ctx); + + if (minion_iter == minions.end()) { + MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx)); + minions[src_ctx] = minion; + return minion; + } else { + return minion_iter->second; } - - DeclOrigin - GetDeclOrigin (const clang::Decl *decl); - - clang::FileManager m_file_manager; - typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap; - - RecordDeclToLayoutMap m_record_decl_to_layout_map; + } + + DeclOrigin GetDeclOrigin(const clang::Decl *decl); + + clang::FileManager m_file_manager; + typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> + RecordDeclToLayoutMap; + + RecordDeclToLayoutMap m_record_decl_to_layout_map; }; - + } // namespace lldb_private #endif // liblldb_ClangASTImporter_h_ diff --git a/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h index 5a00aa0072ab..61bbc122dd5f 100644 --- a/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h +++ b/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h @@ -15,139 +15,131 @@ // C++ Includes // Other libraries and framework includes -#include "llvm/ADT/DenseMap.h" #include "clang/AST/CharUnits.h" +#include "llvm/ADT/DenseMap.h" // Project includes -#include "lldb/lldb-enumerations.h" #include "lldb/Core/ClangForward.h" -#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/CompilerType.h" +#include "lldb/lldb-enumerations.h" namespace lldb_private { -class ClangExternalASTSourceCallbacks : public ClangExternalASTSourceCommon -{ +class ClangExternalASTSourceCallbacks : public ClangExternalASTSourceCommon { public: - typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); - typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *); - typedef void (*FindExternalVisibleDeclsByNameCallback)(void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results); - typedef bool (*LayoutRecordTypeCallback)( - void *baton, const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets); - - ClangExternalASTSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, - CompleteObjCInterfaceDeclCallback objc_decl_callback, - FindExternalVisibleDeclsByNameCallback find_by_name_callback, - LayoutRecordTypeCallback layout_record_type_callback, - void *callback_baton) : - m_callback_tag_decl (tag_decl_callback), - m_callback_objc_decl (objc_decl_callback), - m_callback_find_by_name (find_by_name_callback), - m_callback_layout_record_type (layout_record_type_callback), - m_callback_baton (callback_baton) - { - } - - //------------------------------------------------------------------ - // clang::ExternalASTSource - //------------------------------------------------------------------ - - clang::Decl * - GetExternalDecl(uint32_t ID) override - { - // This method only needs to be implemented if the AST source ever - // passes back decl sets as VisibleDeclaration objects. - return nullptr; - } - - clang::Stmt * - GetExternalDeclStmt(uint64_t Offset) override - { - // This operation is meant to be used via a LazyOffsetPtr. It only - // needs to be implemented if the AST source uses methods like - // FunctionDecl::setLazyBody when building decls. - return nullptr; - } - - clang::Selector - GetExternalSelector(uint32_t ID) override - { - // This operation only needs to be implemented if the AST source - // returns non-zero for GetNumKnownSelectors(). - return clang::Selector(); - } - - uint32_t - GetNumExternalSelectors() override - { - return 0; - } - - clang::CXXBaseSpecifier * - GetExternalCXXBaseSpecifiers(uint64_t Offset) override - { - return nullptr; - } - - virtual void - MaterializeVisibleDecls (const clang::DeclContext *decl_ctx) - { - } - - void - FindExternalLexicalDecls(const clang::DeclContext *DC, - llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, - llvm::SmallVectorImpl<clang::Decl *> &Result) override; - - bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName decl_name) override; - - void CompleteType(clang::TagDecl *tag_decl) override; - - void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override; - - bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, - llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, - llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets) override; - - void - SetExternalSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, - CompleteObjCInterfaceDeclCallback objc_decl_callback, - FindExternalVisibleDeclsByNameCallback find_by_name_callback, - LayoutRecordTypeCallback layout_record_type_callback, - void *callback_baton) - { - m_callback_tag_decl = tag_decl_callback; - m_callback_objc_decl = objc_decl_callback; - m_callback_find_by_name = find_by_name_callback; - m_callback_layout_record_type = layout_record_type_callback; - m_callback_baton = callback_baton; - } - - void - RemoveExternalSourceCallbacks (void *callback_baton) - { - if (callback_baton == m_callback_baton) - { - m_callback_tag_decl = nullptr; - m_callback_objc_decl = nullptr; - m_callback_find_by_name = nullptr; - m_callback_layout_record_type = nullptr; - } + typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); + typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, + clang::ObjCInterfaceDecl *); + typedef void (*FindExternalVisibleDeclsByNameCallback)( + void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, + llvm::SmallVectorImpl<clang::NamedDecl *> *results); + typedef bool (*LayoutRecordTypeCallback)( + void *baton, const clang::RecordDecl *Record, uint64_t &Size, + uint64_t &Alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &VirtualBaseOffsets); + + ClangExternalASTSourceCallbacks( + CompleteTagDeclCallback tag_decl_callback, + CompleteObjCInterfaceDeclCallback objc_decl_callback, + FindExternalVisibleDeclsByNameCallback find_by_name_callback, + LayoutRecordTypeCallback layout_record_type_callback, + void *callback_baton) + : m_callback_tag_decl(tag_decl_callback), + m_callback_objc_decl(objc_decl_callback), + m_callback_find_by_name(find_by_name_callback), + m_callback_layout_record_type(layout_record_type_callback), + m_callback_baton(callback_baton) {} + + //------------------------------------------------------------------ + // clang::ExternalASTSource + //------------------------------------------------------------------ + + clang::Decl *GetExternalDecl(uint32_t ID) override { + // This method only needs to be implemented if the AST source ever + // passes back decl sets as VisibleDeclaration objects. + return nullptr; + } + + clang::Stmt *GetExternalDeclStmt(uint64_t Offset) override { + // This operation is meant to be used via a LazyOffsetPtr. It only + // needs to be implemented if the AST source uses methods like + // FunctionDecl::setLazyBody when building decls. + return nullptr; + } + + clang::Selector GetExternalSelector(uint32_t ID) override { + // This operation only needs to be implemented if the AST source + // returns non-zero for GetNumKnownSelectors(). + return clang::Selector(); + } + + uint32_t GetNumExternalSelectors() override { return 0; } + + clang::CXXBaseSpecifier * + GetExternalCXXBaseSpecifiers(uint64_t Offset) override { + return nullptr; + } + + virtual void MaterializeVisibleDecls(const clang::DeclContext *decl_ctx) {} + + void FindExternalLexicalDecls( + const clang::DeclContext *DC, + llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, + llvm::SmallVectorImpl<clang::Decl *> &Result) override; + + bool + FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, + clang::DeclarationName decl_name) override; + + void CompleteType(clang::TagDecl *tag_decl) override; + + void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override; + + bool layoutRecordType( + const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &BaseOffsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> + &VirtualBaseOffsets) override; + + void SetExternalSourceCallbacks( + CompleteTagDeclCallback tag_decl_callback, + CompleteObjCInterfaceDeclCallback objc_decl_callback, + FindExternalVisibleDeclsByNameCallback find_by_name_callback, + LayoutRecordTypeCallback layout_record_type_callback, + void *callback_baton) { + m_callback_tag_decl = tag_decl_callback; + m_callback_objc_decl = objc_decl_callback; + m_callback_find_by_name = find_by_name_callback; + m_callback_layout_record_type = layout_record_type_callback; + m_callback_baton = callback_baton; + } + + void RemoveExternalSourceCallbacks(void *callback_baton) { + if (callback_baton == m_callback_baton) { + m_callback_tag_decl = nullptr; + m_callback_objc_decl = nullptr; + m_callback_find_by_name = nullptr; + m_callback_layout_record_type = nullptr; } + } protected: - //------------------------------------------------------------------ - // Classes that inherit from ClangExternalASTSourceCallbacks can see and modify these - //------------------------------------------------------------------ - CompleteTagDeclCallback m_callback_tag_decl; - CompleteObjCInterfaceDeclCallback m_callback_objc_decl; - FindExternalVisibleDeclsByNameCallback m_callback_find_by_name; - LayoutRecordTypeCallback m_callback_layout_record_type; - void * m_callback_baton; + //------------------------------------------------------------------ + // Classes that inherit from ClangExternalASTSourceCallbacks can see and + // modify these + //------------------------------------------------------------------ + CompleteTagDeclCallback m_callback_tag_decl; + CompleteObjCInterfaceDeclCallback m_callback_objc_decl; + FindExternalVisibleDeclsByNameCallback m_callback_find_by_name; + LayoutRecordTypeCallback m_callback_layout_record_type; + void *m_callback_baton; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ClangExternalASTSourceCommon.h b/include/lldb/Symbol/ClangExternalASTSourceCommon.h index 711be42c15fb..3e700ba2439c 100644 --- a/include/lldb/Symbol/ClangExternalASTSourceCommon.h +++ b/include/lldb/Symbol/ClangExternalASTSourceCommon.h @@ -10,7 +10,7 @@ #ifndef liblldb_ClangExternalASTSourceCommon_h #define liblldb_ClangExternalASTSourceCommon_h -// Clang headers like to use NDEBUG inside of them to enable/disable debug +// Clang headers like to use NDEBUG inside of them to enable/disable debug // related features using "#ifndef NDEBUG" preprocessor blocks to do one thing // or another. This is bad because it means that if clang was built in release // mode, it assumes that you are building in release mode which is not always @@ -40,150 +40,107 @@ #include "clang/AST/ExternalASTSource.h" // Project includes +#include "lldb/Core/dwarf.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" -#include "lldb/Core/dwarf.h" namespace lldb_private { -class ClangASTMetadata -{ +class ClangASTMetadata { public: - ClangASTMetadata () : - m_user_id(0), - m_union_is_user_id(false), - m_union_is_isa_ptr(false), - m_has_object_ptr(false), - m_is_self (false), - m_is_dynamic_cxx (true) - { - } - - bool - GetIsDynamicCXXType () const - { - return m_is_dynamic_cxx; - } - - void - SetIsDynamicCXXType (bool b) - { - m_is_dynamic_cxx = b; + ClangASTMetadata() + : m_user_id(0), m_union_is_user_id(false), m_union_is_isa_ptr(false), + m_has_object_ptr(false), m_is_self(false), m_is_dynamic_cxx(true) {} + + bool GetIsDynamicCXXType() const { return m_is_dynamic_cxx; } + + void SetIsDynamicCXXType(bool b) { m_is_dynamic_cxx = b; } + + void SetUserID(lldb::user_id_t user_id) { + m_user_id = user_id; + m_union_is_user_id = true; + m_union_is_isa_ptr = false; + } + + lldb::user_id_t GetUserID() const { + if (m_union_is_user_id) + return m_user_id; + else + return LLDB_INVALID_UID; + } + + void SetISAPtr(uint64_t isa_ptr) { + m_isa_ptr = isa_ptr; + m_union_is_user_id = false; + m_union_is_isa_ptr = true; + } + + uint64_t GetISAPtr() const { + if (m_union_is_isa_ptr) + return m_isa_ptr; + else + return 0; + } + + void SetObjectPtrName(const char *name) { + m_has_object_ptr = true; + if (strcmp(name, "self") == 0) + m_is_self = true; + else if (strcmp(name, "this") == 0) + m_is_self = false; + else + m_has_object_ptr = false; + } + + lldb::LanguageType GetObjectPtrLanguage() const { + if (m_has_object_ptr) { + if (m_is_self) + return lldb::eLanguageTypeObjC; + else + return lldb::eLanguageTypeC_plus_plus; } + return lldb::eLanguageTypeUnknown; + } - void - SetUserID (lldb::user_id_t user_id) - { - m_user_id = user_id; - m_union_is_user_id = true; - m_union_is_isa_ptr = false; - } + const char *GetObjectPtrName() const { + if (m_has_object_ptr) { + if (m_is_self) + return "self"; + else + return "this"; + } else + return nullptr; + } - lldb::user_id_t - GetUserID () const - { - if (m_union_is_user_id) - return m_user_id; - else - return LLDB_INVALID_UID; - } + bool HasObjectPtr() const { return m_has_object_ptr; } - void - SetISAPtr (uint64_t isa_ptr) - { - m_isa_ptr = isa_ptr; - m_union_is_user_id = false; - m_union_is_isa_ptr = true; - } - - uint64_t - GetISAPtr () const - { - if (m_union_is_isa_ptr) - return m_isa_ptr; - else - return 0; - } - - void - SetObjectPtrName(const char *name) - { - m_has_object_ptr = true; - if (strcmp (name, "self") == 0) - m_is_self = true; - else if (strcmp (name, "this") == 0) - m_is_self = false; - else - m_has_object_ptr = false; - } - - lldb::LanguageType - GetObjectPtrLanguage () const - { - if (m_has_object_ptr) - { - if (m_is_self) - return lldb::eLanguageTypeObjC; - else - return lldb::eLanguageTypeC_plus_plus; - } - return lldb::eLanguageTypeUnknown; - } + void Dump(Stream *s); - const char * - GetObjectPtrName() const - { - if (m_has_object_ptr) - { - if (m_is_self) - return "self"; - else - return "this"; - } - else - return nullptr; - } - - bool - HasObjectPtr() const - { - return m_has_object_ptr; - } - - void - Dump (Stream *s); - private: - union - { - lldb::user_id_t m_user_id; - uint64_t m_isa_ptr; - }; - - bool m_union_is_user_id : 1, - m_union_is_isa_ptr : 1, - m_has_object_ptr : 1, - m_is_self : 1, - m_is_dynamic_cxx : 1; + union { + lldb::user_id_t m_user_id; + uint64_t m_isa_ptr; + }; + + bool m_union_is_user_id : 1, m_union_is_isa_ptr : 1, m_has_object_ptr : 1, + m_is_self : 1, m_is_dynamic_cxx : 1; }; -class ClangExternalASTSourceCommon : public clang::ExternalASTSource -{ +class ClangExternalASTSourceCommon : public clang::ExternalASTSource { public: - ClangExternalASTSourceCommon(); - ~ClangExternalASTSourceCommon() override; - - ClangASTMetadata *GetMetadata(const void *object); - void SetMetadata(const void *object, ClangASTMetadata &metadata); - bool HasMetadata(const void *object); - - static ClangExternalASTSourceCommon * - Lookup(clang::ExternalASTSource *source); - -private: - typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap; - - MetadataMap m_metadata; + ClangExternalASTSourceCommon(); + ~ClangExternalASTSourceCommon() override; + + ClangASTMetadata *GetMetadata(const void *object); + void SetMetadata(const void *object, ClangASTMetadata &metadata); + bool HasMetadata(const void *object); + + static ClangExternalASTSourceCommon *Lookup(clang::ExternalASTSource *source); + +private: + typedef llvm::DenseMap<const void *, ClangASTMetadata> MetadataMap; + + MetadataMap m_metadata; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ClangUtil.h b/include/lldb/Symbol/ClangUtil.h index ee9ff5678d79..cb380221152a 100644 --- a/include/lldb/Symbol/ClangUtil.h +++ b/include/lldb/Symbol/ClangUtil.h @@ -16,21 +16,15 @@ #include "lldb/Symbol/CompilerType.h" -namespace lldb_private -{ -struct ClangUtil -{ - static bool - IsClangType(const CompilerType &ct); +namespace lldb_private { +struct ClangUtil { + static bool IsClangType(const CompilerType &ct); - static clang::QualType - GetQualType(const CompilerType &ct); + static clang::QualType GetQualType(const CompilerType &ct); - static clang::QualType - GetCanonicalQualType(const CompilerType &ct); + static clang::QualType GetCanonicalQualType(const CompilerType &ct); - static CompilerType - RemoveFastQualifiers(const CompilerType &ct); + static CompilerType RemoveFastQualifiers(const CompilerType &ct); }; } diff --git a/include/lldb/Symbol/CompactUnwindInfo.h b/include/lldb/Symbol/CompactUnwindInfo.h index 6bf65a223471..133a886812b3 100644 --- a/include/lldb/Symbol/CompactUnwindInfo.h +++ b/include/lldb/Symbol/CompactUnwindInfo.h @@ -21,141 +21,156 @@ namespace lldb_private { -// Compact Unwind info is an unwind format used on Darwin. The unwind instructions -// for typical compiler-generated functions can be expressed in a 32-bit encoding. -// The format includes a two-level index so the unwind information for a function +// Compact Unwind info is an unwind format used on Darwin. The unwind +// instructions +// for typical compiler-generated functions can be expressed in a 32-bit +// encoding. +// The format includes a two-level index so the unwind information for a +// function // can be found by two binary searches in the section. It can represent both // stack frames that use a frame-pointer register and frameless functions, on -// i386/x86_64 for instance. When a function is too complex to be represented in +// i386/x86_64 for instance. When a function is too complex to be represented +// in // the compact unwind format, it calls out to eh_frame unwind instructions. -// On Mac OS X / iOS, a function will have either a compact unwind representation -// or an eh_frame representation. If lldb is going to benefit from the compiler's -// description about saved register locations, it must be able to read both +// On Mac OS X / iOS, a function will have either a compact unwind +// representation +// or an eh_frame representation. If lldb is going to benefit from the +// compiler's +// description about saved register locations, it must be able to read both // sources of information. -class CompactUnwindInfo -{ +class CompactUnwindInfo { public: + CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP §ion); - CompactUnwindInfo (ObjectFile& objfile, - lldb::SectionSP& section); + ~CompactUnwindInfo(); - ~CompactUnwindInfo(); + bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan); - bool - GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwind_plan); - - bool - IsValid (const lldb::ProcessSP &process_sp); + bool IsValid(const lldb::ProcessSP &process_sp); private: - - - // The top level index entries of the compact unwind info - // (internal representation of struct unwind_info_section_header_index_entry) - // There are relatively few of these (one per 500/1000 functions, depending on format) so - // creating them on first scan will not be too costly. - struct UnwindIndex - { - uint32_t function_offset; // The offset of the first function covered by this index - uint32_t second_level; // The offset (inside unwind_info sect) to the second level page for this index - // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED) - uint32_t lsda_array_start;// The offset (inside unwind_info sect) LSDA array for this index - uint32_t lsda_array_end; // The offset to the LSDA array for the NEXT index - bool sentinal_entry; // There is an empty index at the end which provides the upper bound of - // function addresses that are described - - UnwindIndex() : - function_offset (0), - second_level (0), - lsda_array_start(0), - lsda_array_end(0), - sentinal_entry (false) - { } - - bool - operator< (const CompactUnwindInfo::UnwindIndex& rhs) const - { - return function_offset < rhs.function_offset; - } - - bool - operator== (const CompactUnwindInfo::UnwindIndex& rhs) const - { - return function_offset == rhs.function_offset; - } - - }; - - // An internal object used to store the information we retrieve about a function -- - // the encoding bits and possibly the LSDA/personality function. - struct FunctionInfo - { - uint32_t encoding; // compact encoding 32-bit value for this function - Address lsda_address; // the address of the LSDA data for this function - Address personality_ptr_address; // the address where the personality routine addr can be found - - uint32_t valid_range_offset_start; // first offset that this encoding is valid for (start of the function) - uint32_t valid_range_offset_end; // the offset of the start of the next function - FunctionInfo () : encoding(0), lsda_address(), personality_ptr_address(), valid_range_offset_start(0), valid_range_offset_end(0) { } - }; - - struct UnwindHeader - { - uint32_t version; - uint32_t common_encodings_array_offset; - uint32_t common_encodings_array_count; - uint32_t personality_array_offset; - uint32_t personality_array_count; - - UnwindHeader () : common_encodings_array_offset (0), common_encodings_array_count (0), personality_array_offset (0), personality_array_count (0) { } - }; - - void - ScanIndex(const lldb::ProcessSP &process_sp); - - bool - GetCompactUnwindInfoForFunction (Target &target, Address address, FunctionInfo &unwind_info); - - lldb::offset_t - BinarySearchRegularSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset); - + // The top level index entries of the compact unwind info + // (internal representation of struct + // unwind_info_section_header_index_entry) + // There are relatively few of these (one per 500/1000 functions, depending on + // format) so + // creating them on first scan will not be too costly. + struct UnwindIndex { + uint32_t function_offset; // The offset of the first function covered by + // this index + uint32_t second_level; // The offset (inside unwind_info sect) to the second + // level page for this index + // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED) + uint32_t lsda_array_start; // The offset (inside unwind_info sect) LSDA + // array for this index + uint32_t lsda_array_end; // The offset to the LSDA array for the NEXT index + bool sentinal_entry; // There is an empty index at the end which provides + // the upper bound of + // function addresses that are described + + UnwindIndex() + : function_offset(0), second_level(0), lsda_array_start(0), + lsda_array_end(0), sentinal_entry(false) {} + + bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const { + return function_offset < rhs.function_offset; + } + + bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const { + return function_offset == rhs.function_offset; + } + }; + + // An internal object used to store the information we retrieve about a + // function -- + // the encoding bits and possibly the LSDA/personality function. + struct FunctionInfo { + uint32_t encoding; // compact encoding 32-bit value for this function + Address lsda_address; // the address of the LSDA data for this function + Address personality_ptr_address; // the address where the personality + // routine addr can be found + + uint32_t valid_range_offset_start; // first offset that this encoding is + // valid for (start of the function) uint32_t - BinarySearchCompressedSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset_to_find, uint32_t function_offset_base, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset); - - uint32_t - GetLSDAForFunctionOffset (uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset); - - bool - CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); - - bool - CreateUnwindPlan_i386 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); - - bool - CreateUnwindPlan_arm64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); - - bool - CreateUnwindPlan_armv7 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); - - ObjectFile &m_objfile; - lldb::SectionSP m_section_sp; - lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is encrypted, read the sect contents - // out of live memory and cache them here - std::mutex m_mutex; - std::vector<UnwindIndex> m_indexes; - - LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the unwind info - // eLazyBoolNo means we cannot parse the unwind info & should not retry - // eLazyBoolCalculate means we haven't tried to parse it yet - - DataExtractor m_unwindinfo_data; - bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo data - - UnwindHeader m_unwind_header; + valid_range_offset_end; // the offset of the start of the next function + FunctionInfo() + : encoding(0), lsda_address(), personality_ptr_address(), + valid_range_offset_start(0), valid_range_offset_end(0) {} + }; + + struct UnwindHeader { + uint32_t version; + uint32_t common_encodings_array_offset; + uint32_t common_encodings_array_count; + uint32_t personality_array_offset; + uint32_t personality_array_count; + + UnwindHeader() + : common_encodings_array_offset(0), common_encodings_array_count(0), + personality_array_offset(0), personality_array_count(0) {} + }; + + void ScanIndex(const lldb::ProcessSP &process_sp); + + bool GetCompactUnwindInfoForFunction(Target &target, Address address, + FunctionInfo &unwind_info); + + lldb::offset_t + BinarySearchRegularSecondPage(uint32_t entry_page_offset, + uint32_t entry_count, uint32_t function_offset, + uint32_t *entry_func_start_offset, + uint32_t *entry_func_end_offset); + + uint32_t BinarySearchCompressedSecondPage(uint32_t entry_page_offset, + uint32_t entry_count, + uint32_t function_offset_to_find, + uint32_t function_offset_base, + uint32_t *entry_func_start_offset, + uint32_t *entry_func_end_offset); + + uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count, + uint32_t function_offset); + + bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info, + UnwindPlan &unwind_plan, + Address pc_or_function_start); + + bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info, + UnwindPlan &unwind_plan, + Address pc_or_function_start); + + bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info, + UnwindPlan &unwind_plan, + Address pc_or_function_start); + + bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info, + UnwindPlan &unwind_plan, + Address pc_or_function_start); + + ObjectFile &m_objfile; + lldb::SectionSP m_section_sp; + lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is + // encrypted, read the + // sect contents + // out of live memory and cache them here + std::mutex m_mutex; + std::vector<UnwindIndex> m_indexes; + + LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the + // unwind info + // eLazyBoolNo means we cannot parse the unwind info & should not retry + // eLazyBoolCalculate means we haven't tried to parse it yet + + DataExtractor m_unwindinfo_data; + bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo + // data + + UnwindHeader m_unwind_header; }; } // namespace lldb_private -#endif // liblldb_CompactUnwindInfo_h_ +#endif // liblldb_CompactUnwindInfo_h_ diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h index 2f596f89ec5f..8465f3bb5777 100644 --- a/include/lldb/Symbol/CompileUnit.h +++ b/include/lldb/Symbol/CompileUnit.h @@ -10,13 +10,13 @@ #ifndef liblldb_CompUnit_h_ #define liblldb_CompUnit_h_ -#include "lldb/lldb-enumerations.h" -#include "lldb/Symbol/DebugMacros.h" -#include "lldb/Symbol/Function.h" #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/Stream.h" #include "lldb/Core/UserID.h" +#include "lldb/Symbol/DebugMacros.h" +#include "lldb/Symbol/Function.h" +#include "lldb/lldb-enumerations.h" namespace lldb_private { //---------------------------------------------------------------------- @@ -32,445 +32,433 @@ namespace lldb_private { /// variables, support file list (include files and inlined source /// files), and a line table. //---------------------------------------------------------------------- -class CompileUnit : - public std::enable_shared_from_this<CompileUnit>, - public ModuleChild, - public FileSpec, - public UserID, - public SymbolContextScope -{ +class CompileUnit : public std::enable_shared_from_this<CompileUnit>, + public ModuleChild, + public FileSpec, + public UserID, + public SymbolContextScope { public: - //------------------------------------------------------------------ - /// Construct with a module, path, UID and language. - /// - /// Initialize the compile unit given the owning \a module, a path - /// to convert into a FileSpec, the SymbolFile plug-in supplied - /// \a uid, and the source language type. - /// - /// @param[in] module - /// The parent module that owns this compile unit. This value - /// must be a valid pointer value. - /// - /// @param[in] user_data - /// User data where the SymbolFile parser can store data. - /// - /// @param[in] pathname - /// The path to the source file for this compile unit. - /// - /// @param[in] uid - /// The user ID of the compile unit. This value is supplied by - /// the SymbolFile plug-in and should be a value that allows - /// the SymbolFile plug-in to easily locate and parse additional - /// information for the compile unit. - /// - /// @param[in] language - /// A language enumeration type that describes the main language - /// of this compile unit. - /// - /// @param[in] is_optimized - /// A value that can initialized with eLazyBoolYes, eLazyBoolNo - /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then - /// an extra call into SymbolVendor will be made to calculate if - /// the compile unit is optimized will be made when - /// CompileUnit::GetIsOptimized() is called. - /// - /// @see lldb::LanguageType - //------------------------------------------------------------------ - CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, - lldb::LanguageType language, lldb_private::LazyBool is_optimized); - - //------------------------------------------------------------------ - /// Construct with a module, file spec, UID and language. - /// - /// Initialize the compile unit given the owning \a module, a path - /// to convert into a FileSpec, the SymbolFile plug-in supplied - /// \a uid, and the source language type. - /// - /// @param[in] module - /// The parent module that owns this compile unit. This value - /// must be a valid pointer value. - /// - /// @param[in] user_data - /// User data where the SymbolFile parser can store data. - /// - /// @param[in] file_spec - /// The file specification for the source file of this compile - /// unit. - /// - /// @param[in] uid - /// The user ID of the compile unit. This value is supplied by - /// the SymbolFile plug-in and should be a value that allows - /// the plug-in to easily locate and parse - /// additional information for the compile unit. - /// - /// @param[in] language - /// A language enumeration type that describes the main language - /// of this compile unit. - /// - /// @param[in] is_optimized - /// A value that can initialized with eLazyBoolYes, eLazyBoolNo - /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then - /// an extra call into SymbolVendor will be made to calculate if - /// the compile unit is optimized will be made when - /// CompileUnit::GetIsOptimized() is called. - /// - /// @see lldb::LanguageType - //------------------------------------------------------------------ - CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, - lldb::LanguageType language, lldb_private::LazyBool is_optimized); - - //------------------------------------------------------------------ - /// Destructor - //------------------------------------------------------------------ - ~CompileUnit() override; - - //------------------------------------------------------------------ - /// Add a function to this compile unit. - /// - /// Typically called by the SymbolFile plug-ins as they partially - /// parse the debug information. - /// - /// @param[in] function_sp - /// A shared pointer to the Function object. - //------------------------------------------------------------------ - void - AddFunction(lldb::FunctionSP& function_sp); - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - CalculateSymbolContext(SymbolContext* sc) override; - - lldb::ModuleSP - CalculateSymbolContextModule() override; - - CompileUnit * - CalculateSymbolContextCompileUnit() override; - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - DumpSymbolContext(Stream *s) override; - - lldb::LanguageType - GetLanguage(); - - void - SetLanguage(lldb::LanguageType language) - { - m_flags.Set(flagsParsedLanguage); - m_language = language; - } - - void - GetDescription(Stream *s, lldb::DescriptionLevel level) const; - - //------------------------------------------------------------------ - /// Get a shared pointer to a function in this compile unit by - /// index. - /// - /// Typically called when iterating though all functions in a - /// compile unit after all functions have been parsed. This provides - /// raw access to the function shared pointer list and will not - /// cause the SymbolFile plug-in to parse any unparsed functions. - /// - /// @param[in] idx - /// An index into the function list. - /// - /// @return - /// A shared pointer to a function that might contain a NULL - /// Function class pointer. - //------------------------------------------------------------------ - lldb::FunctionSP - GetFunctionAtIndex (size_t idx); - - //------------------------------------------------------------------ - /// Dump the compile unit contents to the stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] show_context - /// If \b true, variables will dump their symbol context - /// information. - //------------------------------------------------------------------ - void - Dump (Stream *s, bool show_context) const; - - //------------------------------------------------------------------ - /// Find the line entry by line and optional inlined file spec. - /// - /// Finds the first line entry that has an index greater than - /// \a start_idx that matches \a line. If \a file_spec_ptr - /// is NULL, then the search matches line entries whose file matches - /// the file for the compile unit. If \a file_spec_ptr is - /// not NULL, line entries must match the specified file spec (for - /// inlined line table entries). - /// - /// Multiple calls to this function can find all entries that match - /// a given file and line by starting with \a start_idx equal to zero, - /// and calling this function back with the return value + 1. - /// - /// @param[in] start_idx - /// The zero based index at which to start looking for matches. - /// - /// @param[in] line - /// The line number to search for. - /// - /// @param[in] file_spec_ptr - /// If non-NULL search for entries that match this file spec, - /// else if NULL, search for line entries that match the compile - /// unit file. - /// - /// @param[in] exact - /// If \btrue match only if there is a line table entry for this line number. - /// If \bfalse, find the line table entry equal to or after this line number. - /// - /// @param[out] line_entry - /// If non-NULL, a copy of the line entry that was found. - /// - /// @return - /// The zero based index of a matching line entry, or UINT32_MAX - /// if no matching line entry is found. - //------------------------------------------------------------------ - uint32_t - FindLineEntry (uint32_t start_idx, - uint32_t line, - const FileSpec* file_spec_ptr, - bool exact, - LineEntry *line_entry); - - //------------------------------------------------------------------ - /// Get the line table for the compile unit. - /// - /// Called by clients and the SymbolFile plug-in. The SymbolFile - /// plug-ins use this function to determine if the line table has - /// be parsed yet. Clients use this function to get the line table - /// from a compile unit. - /// - /// @return - /// The line table object pointer, or NULL if this line table - /// hasn't been parsed yet. - //------------------------------------------------------------------ - LineTable* - GetLineTable (); - - DebugMacros* - GetDebugMacros (); - - //------------------------------------------------------------------ - /// Get the compile unit's support file list. - /// - /// The support file list is used by the line table, and any objects - /// that have valid Declaration objects. - /// - /// @return - /// A support file list object. - //------------------------------------------------------------------ - FileSpecList& - GetSupportFiles (); - - //------------------------------------------------------------------ - /// Get the compile unit's imported module list. - /// - /// This reports all the imports that the compile unit made, - /// including the current module. - /// - /// @return - /// A list of imported module names. - //------------------------------------------------------------------ - const std::vector<ConstString> & - GetImportedModules (); - - //------------------------------------------------------------------ - /// Get the SymbolFile plug-in user data. - /// - /// SymbolFile plug-ins can store user data to internal state or - /// objects to quickly allow them to parse more information for a - /// given object. - /// - /// @return - /// The user data stored with the CompileUnit when it was - /// constructed. - //------------------------------------------------------------------ - void * - GetUserData () const; - - //------------------------------------------------------------------ - /// Get the variable list for a compile unit. - /// - /// Called by clients to get the variable list for a compile unit. - /// The variable list will contain all global and static variables - /// that were defined at the compile unit level. - /// - /// @param[in] can_create - /// If \b true, the variable list will be parsed on demand. If - /// \b false, the current variable list will be returned even - /// if it contains a NULL VariableList object (typically - /// called by dumping routines that want to display only what - /// has currently been parsed). - /// - /// @return - /// A shared pointer to a variable list, that can contain NULL - /// VariableList pointer if there are no global or static - /// variables. - //------------------------------------------------------------------ - lldb::VariableListSP - GetVariableList (bool can_create); - - //------------------------------------------------------------------ - /// Finds a function by user ID. - /// - /// Typically used by SymbolFile plug-ins when partially parsing - /// the debug information to see if the function has been parsed - /// yet. - /// - /// @param[in] uid - /// The user ID of the function to find. This value is supplied - /// by the SymbolFile plug-in and should be a value that - /// allows the plug-in to easily locate and parse additional - /// information in the function. - /// - /// @return - /// A shared pointer to the function object that might contain - /// a NULL Function pointer. - //------------------------------------------------------------------ - lldb::FunctionSP - FindFunctionByUID (lldb::user_id_t uid); - - //------------------------------------------------------------------ - /// Set the line table for the compile unit. - /// - /// Called by the SymbolFile plug-in when if first parses the line - /// table and hands ownership of the line table to this object. The - /// compile unit owns the line table object and will delete the - /// object when it is deleted. - /// - /// @param[in] line_table - /// A line table object pointer that this object now owns. - //------------------------------------------------------------------ - void - SetLineTable(LineTable* line_table); - - void - SetDebugMacros(const DebugMacrosSP &debug_macros); - - //------------------------------------------------------------------ - /// Set accessor for the variable list. - /// - /// Called by the SymbolFile plug-ins after they have parsed the - /// variable lists and are ready to hand ownership of the list over - /// to this object. - /// - /// @param[in] variable_list_sp - /// A shared pointer to a VariableList. - //------------------------------------------------------------------ - void - SetVariableList (lldb::VariableListSP& variable_list_sp); - - //------------------------------------------------------------------ - /// Resolve symbol contexts by file and line. - /// - /// Given a file in \a file_spec, and a line number, find all - /// instances and append them to the supplied symbol context list - /// \a sc_list. - /// - /// @param[in] file_spec - /// A file specification. If \a file_spec contains no directory - /// information, only the basename will be used when matching - /// contexts. If the directory in \a file_spec is valid, a - /// complete file specification match will be performed. - /// - /// @param[in] line - /// The line number to match against the compile unit's line - /// tables. - /// - /// @param[in] check_inlines - /// If \b true this function will also match any inline - /// file and line matches. If \b false, the compile unit's - /// file specification must match \a file_spec for any matches - /// to be returned. - /// - /// @param[in] exact - /// If true, only resolve the context if \a line exists in the line table. - /// If false, resolve the context to the closest line greater than \a line - /// in the line table. - /// - /// @param[in] resolve_scope - /// For each matching line entry, this bitfield indicates what - /// values within each SymbolContext that gets added to \a - /// sc_list will be resolved. See the SymbolContext::Scope - /// enumeration for a list of all available bits that can be - /// resolved. Only SymbolContext entries that can be resolved - /// using a LineEntry base address will be able to be resolved. - /// - /// @param[out] sc_list - /// A SymbolContext list class that will get any matching - /// entries appended to. - /// - /// @return - /// The number of new matches that were added to \a sc_list. - /// - /// @see enum SymbolContext::Scope - //------------------------------------------------------------------ - uint32_t - ResolveSymbolContext (const FileSpec& file_spec, - uint32_t line, - bool check_inlines, - bool exact, - uint32_t resolve_scope, - SymbolContextList &sc_list); - - - //------------------------------------------------------------------ - /// Get whether compiler optimizations were enabled for this compile unit - /// - /// "optimized" means that the debug experience may be difficult - /// for the user to understand. Variables may not be available when - /// the developer would expect them, stepping through the source lines - /// in the function may appear strange, etc. - /// - /// @return - /// Returns 'true' if this compile unit was compiled with - /// optimization. 'false' indicates that either the optimization - /// is unknown, or this compile unit was built without optimization. - //------------------------------------------------------------------ - bool - GetIsOptimized (); + //------------------------------------------------------------------ + /// Construct with a module, path, UID and language. + /// + /// Initialize the compile unit given the owning \a module, a path + /// to convert into a FileSpec, the SymbolFile plug-in supplied + /// \a uid, and the source language type. + /// + /// @param[in] module + /// The parent module that owns this compile unit. This value + /// must be a valid pointer value. + /// + /// @param[in] user_data + /// User data where the SymbolFile parser can store data. + /// + /// @param[in] pathname + /// The path to the source file for this compile unit. + /// + /// @param[in] uid + /// The user ID of the compile unit. This value is supplied by + /// the SymbolFile plug-in and should be a value that allows + /// the SymbolFile plug-in to easily locate and parse additional + /// information for the compile unit. + /// + /// @param[in] language + /// A language enumeration type that describes the main language + /// of this compile unit. + /// + /// @param[in] is_optimized + /// A value that can initialized with eLazyBoolYes, eLazyBoolNo + /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then + /// an extra call into SymbolVendor will be made to calculate if + /// the compile unit is optimized will be made when + /// CompileUnit::GetIsOptimized() is called. + /// + /// @see lldb::LanguageType + //------------------------------------------------------------------ + CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, + const char *pathname, lldb::user_id_t uid, + lldb::LanguageType language, lldb_private::LazyBool is_optimized); + + //------------------------------------------------------------------ + /// Construct with a module, file spec, UID and language. + /// + /// Initialize the compile unit given the owning \a module, a path + /// to convert into a FileSpec, the SymbolFile plug-in supplied + /// \a uid, and the source language type. + /// + /// @param[in] module + /// The parent module that owns this compile unit. This value + /// must be a valid pointer value. + /// + /// @param[in] user_data + /// User data where the SymbolFile parser can store data. + /// + /// @param[in] file_spec + /// The file specification for the source file of this compile + /// unit. + /// + /// @param[in] uid + /// The user ID of the compile unit. This value is supplied by + /// the SymbolFile plug-in and should be a value that allows + /// the plug-in to easily locate and parse + /// additional information for the compile unit. + /// + /// @param[in] language + /// A language enumeration type that describes the main language + /// of this compile unit. + /// + /// @param[in] is_optimized + /// A value that can initialized with eLazyBoolYes, eLazyBoolNo + /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then + /// an extra call into SymbolVendor will be made to calculate if + /// the compile unit is optimized will be made when + /// CompileUnit::GetIsOptimized() is called. + /// + /// @see lldb::LanguageType + //------------------------------------------------------------------ + CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, + const FileSpec &file_spec, lldb::user_id_t uid, + lldb::LanguageType language, lldb_private::LazyBool is_optimized); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~CompileUnit() override; + + //------------------------------------------------------------------ + /// Add a function to this compile unit. + /// + /// Typically called by the SymbolFile plug-ins as they partially + /// parse the debug information. + /// + /// @param[in] function_sp + /// A shared pointer to the Function object. + //------------------------------------------------------------------ + void AddFunction(lldb::FunctionSP &function_sp); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void CalculateSymbolContext(SymbolContext *sc) override; + + lldb::ModuleSP CalculateSymbolContextModule() override; + + CompileUnit *CalculateSymbolContextCompileUnit() override; + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void DumpSymbolContext(Stream *s) override; + + lldb::LanguageType GetLanguage(); + + void SetLanguage(lldb::LanguageType language) { + m_flags.Set(flagsParsedLanguage); + m_language = language; + } + + void GetDescription(Stream *s, lldb::DescriptionLevel level) const; + + //------------------------------------------------------------------ + /// Get a shared pointer to a function in this compile unit by + /// index. + /// + /// Typically called when iterating though all functions in a + /// compile unit after all functions have been parsed. This provides + /// raw access to the function shared pointer list and will not + /// cause the SymbolFile plug-in to parse any unparsed functions. + /// + /// @param[in] idx + /// An index into the function list. + /// + /// @return + /// A shared pointer to a function that might contain a NULL + /// Function class pointer. + //------------------------------------------------------------------ + lldb::FunctionSP GetFunctionAtIndex(size_t idx); + + //------------------------------------------------------------------ + /// Dump the compile unit contents to the stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] show_context + /// If \b true, variables will dump their symbol context + /// information. + //------------------------------------------------------------------ + void Dump(Stream *s, bool show_context) const; + + //------------------------------------------------------------------ + /// Find the line entry by line and optional inlined file spec. + /// + /// Finds the first line entry that has an index greater than + /// \a start_idx that matches \a line. If \a file_spec_ptr + /// is NULL, then the search matches line entries whose file matches + /// the file for the compile unit. If \a file_spec_ptr is + /// not NULL, line entries must match the specified file spec (for + /// inlined line table entries). + /// + /// Multiple calls to this function can find all entries that match + /// a given file and line by starting with \a start_idx equal to zero, + /// and calling this function back with the return value + 1. + /// + /// @param[in] start_idx + /// The zero based index at which to start looking for matches. + /// + /// @param[in] line + /// The line number to search for. + /// + /// @param[in] file_spec_ptr + /// If non-NULL search for entries that match this file spec, + /// else if NULL, search for line entries that match the compile + /// unit file. + /// + /// @param[in] exact + /// If \btrue match only if there is a line table entry for this line + /// number. + /// If \bfalse, find the line table entry equal to or after this line + /// number. + /// + /// @param[out] line_entry + /// If non-NULL, a copy of the line entry that was found. + /// + /// @return + /// The zero based index of a matching line entry, or UINT32_MAX + /// if no matching line entry is found. + //------------------------------------------------------------------ + uint32_t FindLineEntry(uint32_t start_idx, uint32_t line, + const FileSpec *file_spec_ptr, bool exact, + LineEntry *line_entry); + + //------------------------------------------------------------------ + /// Get the line table for the compile unit. + /// + /// Called by clients and the SymbolFile plug-in. The SymbolFile + /// plug-ins use this function to determine if the line table has + /// be parsed yet. Clients use this function to get the line table + /// from a compile unit. + /// + /// @return + /// The line table object pointer, or NULL if this line table + /// hasn't been parsed yet. + //------------------------------------------------------------------ + LineTable *GetLineTable(); + + DebugMacros *GetDebugMacros(); + + //------------------------------------------------------------------ + /// Get the compile unit's support file list. + /// + /// The support file list is used by the line table, and any objects + /// that have valid Declaration objects. + /// + /// @return + /// A support file list object. + //------------------------------------------------------------------ + FileSpecList &GetSupportFiles(); + + //------------------------------------------------------------------ + /// Get the compile unit's imported module list. + /// + /// This reports all the imports that the compile unit made, + /// including the current module. + /// + /// @return + /// A list of imported module names. + //------------------------------------------------------------------ + const std::vector<ConstString> &GetImportedModules(); + + //------------------------------------------------------------------ + /// Get the SymbolFile plug-in user data. + /// + /// SymbolFile plug-ins can store user data to internal state or + /// objects to quickly allow them to parse more information for a + /// given object. + /// + /// @return + /// The user data stored with the CompileUnit when it was + /// constructed. + //------------------------------------------------------------------ + void *GetUserData() const; + + //------------------------------------------------------------------ + /// Get the variable list for a compile unit. + /// + /// Called by clients to get the variable list for a compile unit. + /// The variable list will contain all global and static variables + /// that were defined at the compile unit level. + /// + /// @param[in] can_create + /// If \b true, the variable list will be parsed on demand. If + /// \b false, the current variable list will be returned even + /// if it contains a NULL VariableList object (typically + /// called by dumping routines that want to display only what + /// has currently been parsed). + /// + /// @return + /// A shared pointer to a variable list, that can contain NULL + /// VariableList pointer if there are no global or static + /// variables. + //------------------------------------------------------------------ + lldb::VariableListSP GetVariableList(bool can_create); + + //------------------------------------------------------------------ + /// Finds a function by user ID. + /// + /// Typically used by SymbolFile plug-ins when partially parsing + /// the debug information to see if the function has been parsed + /// yet. + /// + /// @param[in] uid + /// The user ID of the function to find. This value is supplied + /// by the SymbolFile plug-in and should be a value that + /// allows the plug-in to easily locate and parse additional + /// information in the function. + /// + /// @return + /// A shared pointer to the function object that might contain + /// a NULL Function pointer. + //------------------------------------------------------------------ + lldb::FunctionSP FindFunctionByUID(lldb::user_id_t uid); + + //------------------------------------------------------------------ + /// Set the line table for the compile unit. + /// + /// Called by the SymbolFile plug-in when if first parses the line + /// table and hands ownership of the line table to this object. The + /// compile unit owns the line table object and will delete the + /// object when it is deleted. + /// + /// @param[in] line_table + /// A line table object pointer that this object now owns. + //------------------------------------------------------------------ + void SetLineTable(LineTable *line_table); + + void SetDebugMacros(const DebugMacrosSP &debug_macros); + + //------------------------------------------------------------------ + /// Set accessor for the variable list. + /// + /// Called by the SymbolFile plug-ins after they have parsed the + /// variable lists and are ready to hand ownership of the list over + /// to this object. + /// + /// @param[in] variable_list_sp + /// A shared pointer to a VariableList. + //------------------------------------------------------------------ + void SetVariableList(lldb::VariableListSP &variable_list_sp); + + //------------------------------------------------------------------ + /// Resolve symbol contexts by file and line. + /// + /// Given a file in \a file_spec, and a line number, find all + /// instances and append them to the supplied symbol context list + /// \a sc_list. + /// + /// @param[in] file_spec + /// A file specification. If \a file_spec contains no directory + /// information, only the basename will be used when matching + /// contexts. If the directory in \a file_spec is valid, a + /// complete file specification match will be performed. + /// + /// @param[in] line + /// The line number to match against the compile unit's line + /// tables. + /// + /// @param[in] check_inlines + /// If \b true this function will also match any inline + /// file and line matches. If \b false, the compile unit's + /// file specification must match \a file_spec for any matches + /// to be returned. + /// + /// @param[in] exact + /// If true, only resolve the context if \a line exists in the line table. + /// If false, resolve the context to the closest line greater than \a line + /// in the line table. + /// + /// @param[in] resolve_scope + /// For each matching line entry, this bitfield indicates what + /// values within each SymbolContext that gets added to \a + /// sc_list will be resolved. See the SymbolContext::Scope + /// enumeration for a list of all available bits that can be + /// resolved. Only SymbolContext entries that can be resolved + /// using a LineEntry base address will be able to be resolved. + /// + /// @param[out] sc_list + /// A SymbolContext list class that will get any matching + /// entries appended to. + /// + /// @return + /// The number of new matches that were added to \a sc_list. + /// + /// @see enum SymbolContext::Scope + //------------------------------------------------------------------ + uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, + bool check_inlines, bool exact, + uint32_t resolve_scope, + SymbolContextList &sc_list); + + //------------------------------------------------------------------ + /// Get whether compiler optimizations were enabled for this compile unit + /// + /// "optimized" means that the debug experience may be difficult + /// for the user to understand. Variables may not be available when + /// the developer would expect them, stepping through the source lines + /// in the function may appear strange, etc. + /// + /// @return + /// Returns 'true' if this compile unit was compiled with + /// optimization. 'false' indicates that either the optimization + /// is unknown, or this compile unit was built without optimization. + //------------------------------------------------------------------ + bool GetIsOptimized(); protected: - void *m_user_data; ///< User data for the SymbolFile parser to store information into. - lldb::LanguageType m_language; ///< The programming language enumeration value. - Flags m_flags; ///< Compile unit flags that help with partial parsing. - std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of shared pointers to functions - ///< that gets populated as functions get partially parsed. - std::vector<ConstString> m_imported_modules; ///< All modules, including the current module, imported by this - ///< compile unit. - FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations. - std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand. - DebugMacrosSP m_debug_macros_sp; ///< Debug macros that will get parsed on demand. - lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand. - lldb_private::LazyBool m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization. + void *m_user_data; ///< User data for the SymbolFile parser to store + ///information into. + lldb::LanguageType + m_language; ///< The programming language enumeration value. + Flags m_flags; ///< Compile unit flags that help with partial parsing. + std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of + ///shared pointers to functions + ///< that gets populated as functions get partially parsed. + std::vector<ConstString> m_imported_modules; ///< All modules, including the + ///current module, imported by + ///this + ///< compile unit. + FileSpecList m_support_files; ///< Files associated with this compile unit's + ///line table and declarations. + std::unique_ptr<LineTable> + m_line_table_ap; ///< Line table that will get parsed on demand. + DebugMacrosSP + m_debug_macros_sp; ///< Debug macros that will get parsed on demand. + lldb::VariableListSP m_variables; ///< Global and static variable list that + ///will get parsed on demand. + lldb_private::LazyBool m_is_optimized; /// eLazyBoolYes if this compile unit + /// was compiled with optimization. private: - enum - { - flagsParsedAllFunctions = (1u << 0), ///< Have we already parsed all our functions - flagsParsedVariables = (1u << 1), ///< Have we already parsed globals and statics? - flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support files for this compile unit? - flagsParsedLineTable = (1u << 3), ///< Have we parsed the line table already? - flagsParsedLanguage = (1u << 4), ///< Have we parsed the language already? - flagsParsedImportedModules = (1u << 5), ///< Have we parsed the imported modules already? - flagsParsedDebugMacros = (1u << 6) ///< Have we parsed the debug macros already? - }; - - DISALLOW_COPY_AND_ASSIGN (CompileUnit); + enum { + flagsParsedAllFunctions = + (1u << 0), ///< Have we already parsed all our functions + flagsParsedVariables = + (1u << 1), ///< Have we already parsed globals and statics? + flagsParsedSupportFiles = (1u << 2), ///< Have we already parsed the support + ///files for this compile unit? + flagsParsedLineTable = + (1u << 3), ///< Have we parsed the line table already? + flagsParsedLanguage = (1u << 4), ///< Have we parsed the language already? + flagsParsedImportedModules = + (1u << 5), ///< Have we parsed the imported modules already? + flagsParsedDebugMacros = + (1u << 6) ///< Have we parsed the debug macros already? + }; + + DISALLOW_COPY_AND_ASSIGN(CompileUnit); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/CompilerDecl.h b/include/lldb/Symbol/CompilerDecl.h index 19654ab165bb..a612fb689c81 100644 --- a/include/lldb/Symbol/CompilerDecl.h +++ b/include/lldb/Symbol/CompilerDecl.h @@ -10,120 +10,85 @@ #ifndef liblldb_CompilerDecl_h_ #define liblldb_CompilerDecl_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" #include "lldb/Symbol/CompilerType.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class CompilerDecl -{ +class CompilerDecl { public: - //---------------------------------------------------------------------- - // Constructors and Destructors - //---------------------------------------------------------------------- - CompilerDecl () : - m_type_system (nullptr), - m_opaque_decl (nullptr) - { - } - - CompilerDecl (TypeSystem *type_system, void *decl) : - m_type_system (type_system), - m_opaque_decl (decl) - { - } - - ~CompilerDecl () - { - } - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - explicit operator bool () const - { - return IsValid (); - } - - bool - operator < (const CompilerDecl &rhs) const - { - if (m_type_system == rhs.m_type_system) - return m_opaque_decl < rhs.m_opaque_decl; - return m_type_system < rhs.m_type_system; - } - - bool - IsValid () const - { - return m_type_system != nullptr && m_opaque_decl != nullptr; - } - - bool - IsClang () const; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - - TypeSystem * - GetTypeSystem() const - { - return m_type_system; - } - - void * - GetOpaqueDecl() const - { - return m_opaque_decl; - } - - void - SetDecl (TypeSystem* type_system, void* decl) - { - m_type_system = type_system; - m_opaque_decl = decl; - } - - void - Clear() - { - m_type_system = nullptr; - m_opaque_decl = nullptr; - } - - ConstString - GetName () const; - - ConstString - GetMangledName () const; - - CompilerDeclContext - GetDeclContext() const; - - // If this decl represents a function, return the return type - CompilerType - GetFunctionReturnType() const; - - // If this decl represents a function, return the number of arguments for the function - size_t - GetNumFunctionArguments() const; - - // If this decl represents a function, return the argument type given a zero based argument index - CompilerType - GetFunctionArgumentType (size_t arg_idx) const; + //---------------------------------------------------------------------- + // Constructors and Destructors + //---------------------------------------------------------------------- + CompilerDecl() : m_type_system(nullptr), m_opaque_decl(nullptr) {} + + CompilerDecl(TypeSystem *type_system, void *decl) + : m_type_system(type_system), m_opaque_decl(decl) {} + + ~CompilerDecl() {} + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + explicit operator bool() const { return IsValid(); } + + bool operator<(const CompilerDecl &rhs) const { + if (m_type_system == rhs.m_type_system) + return m_opaque_decl < rhs.m_opaque_decl; + return m_type_system < rhs.m_type_system; + } + + bool IsValid() const { + return m_type_system != nullptr && m_opaque_decl != nullptr; + } + + bool IsClang() const; + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + + TypeSystem *GetTypeSystem() const { return m_type_system; } + + void *GetOpaqueDecl() const { return m_opaque_decl; } + + void SetDecl(TypeSystem *type_system, void *decl) { + m_type_system = type_system; + m_opaque_decl = decl; + } + + void Clear() { + m_type_system = nullptr; + m_opaque_decl = nullptr; + } + + ConstString GetName() const; + + ConstString GetMangledName() const; + + CompilerDeclContext GetDeclContext() const; + + // If this decl represents a function, return the return type + CompilerType GetFunctionReturnType() const; + + // If this decl represents a function, return the number of arguments for the + // function + size_t GetNumFunctionArguments() const; + + // If this decl represents a function, return the argument type given a zero + // based argument index + CompilerType GetFunctionArgumentType(size_t arg_idx) const; private: - TypeSystem *m_type_system; - void *m_opaque_decl; + TypeSystem *m_type_system; + void *m_opaque_decl; }; - -bool operator == (const CompilerDecl &lhs, const CompilerDecl &rhs); -bool operator != (const CompilerDecl &lhs, const CompilerDecl &rhs); - +bool operator==(const CompilerDecl &lhs, const CompilerDecl &rhs); +bool operator!=(const CompilerDecl &lhs, const CompilerDecl &rhs); + } // namespace lldb_private #endif // #ifndef liblldb_CompilerDecl_h_ diff --git a/include/lldb/Symbol/CompilerDeclContext.h b/include/lldb/Symbol/CompilerDeclContext.h index 7432adac6133..e4f3e7459aa7 100644 --- a/include/lldb/Symbol/CompilerDeclContext.h +++ b/include/lldb/Symbol/CompilerDeclContext.h @@ -12,138 +12,102 @@ #include <vector> -#include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class CompilerDeclContext -{ +class CompilerDeclContext { public: - //---------------------------------------------------------------------- - // Constructors and Destructors - //---------------------------------------------------------------------- - CompilerDeclContext () : - m_type_system (nullptr), - m_opaque_decl_ctx (nullptr) - { - } - - CompilerDeclContext (TypeSystem *type_system, void *decl_ctx) : - m_type_system (type_system), - m_opaque_decl_ctx (decl_ctx) - { - } - - ~CompilerDeclContext() - { - } - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - explicit operator bool () const - { - return IsValid (); - } - - bool - operator < (const CompilerDeclContext &rhs) const - { - if (m_type_system == rhs.m_type_system) - return m_opaque_decl_ctx < rhs.m_opaque_decl_ctx; - return m_type_system < rhs.m_type_system; - } - - bool - IsValid () const - { - return m_type_system != nullptr && m_opaque_decl_ctx != nullptr; - } - - bool - IsClang () const; - - std::vector<CompilerDecl> - FindDeclByName (ConstString name, const bool ignore_using_decls); - - //---------------------------------------------------------------------- - /// Checks if this decl context represents a method of a class. - /// - /// @param[out] language_ptr - /// If non NULL and \b true is returned from this function, - /// this will indicate if the language that respresents the method. - /// - /// @param[out] is_instance_method_ptr - /// If non NULL and \b true is returned from this function, - /// this will indicate if the method is an instance function (true) - /// or a class method (false indicating the function is static, or - /// doesn't require an instance of the class to be called). - /// - /// @param[out] language_object_name_ptr - /// If non NULL and \b true is returned from this function, - /// this will indicate if implicit object name for the language - /// like "this" for C++, and "self" for Objective C. - /// - /// @return - /// Returns true if this is a decl context that represents a method - /// in a struct, union or class. - //---------------------------------------------------------------------- - bool - IsClassMethod (lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr); - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - - TypeSystem * - GetTypeSystem() const - { - return m_type_system; - } - - void * - GetOpaqueDeclContext() const - { - return m_opaque_decl_ctx; - } - - void - SetDeclContext (TypeSystem* type_system, void* decl_ctx) - { - m_type_system = type_system; - m_opaque_decl_ctx = decl_ctx; - } - - void - Clear() - { - m_type_system = nullptr; - m_opaque_decl_ctx = nullptr; - } - - ConstString - GetName () const; - - ConstString - GetScopeQualifiedName() const; - - bool - IsStructUnionOrClass () const; + //---------------------------------------------------------------------- + // Constructors and Destructors + //---------------------------------------------------------------------- + CompilerDeclContext() : m_type_system(nullptr), m_opaque_decl_ctx(nullptr) {} + + CompilerDeclContext(TypeSystem *type_system, void *decl_ctx) + : m_type_system(type_system), m_opaque_decl_ctx(decl_ctx) {} + + ~CompilerDeclContext() {} + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + explicit operator bool() const { return IsValid(); } + + bool operator<(const CompilerDeclContext &rhs) const { + if (m_type_system == rhs.m_type_system) + return m_opaque_decl_ctx < rhs.m_opaque_decl_ctx; + return m_type_system < rhs.m_type_system; + } + + bool IsValid() const { + return m_type_system != nullptr && m_opaque_decl_ctx != nullptr; + } + + bool IsClang() const; + + std::vector<CompilerDecl> FindDeclByName(ConstString name, + const bool ignore_using_decls); + + //---------------------------------------------------------------------- + /// Checks if this decl context represents a method of a class. + /// + /// @param[out] language_ptr + /// If non NULL and \b true is returned from this function, + /// this will indicate if the language that respresents the method. + /// + /// @param[out] is_instance_method_ptr + /// If non NULL and \b true is returned from this function, + /// this will indicate if the method is an instance function (true) + /// or a class method (false indicating the function is static, or + /// doesn't require an instance of the class to be called). + /// + /// @param[out] language_object_name_ptr + /// If non NULL and \b true is returned from this function, + /// this will indicate if implicit object name for the language + /// like "this" for C++, and "self" for Objective C. + /// + /// @return + /// Returns true if this is a decl context that represents a method + /// in a struct, union or class. + //---------------------------------------------------------------------- + bool IsClassMethod(lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, + ConstString *language_object_name_ptr); + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + + TypeSystem *GetTypeSystem() const { return m_type_system; } + + void *GetOpaqueDeclContext() const { return m_opaque_decl_ctx; } + + void SetDeclContext(TypeSystem *type_system, void *decl_ctx) { + m_type_system = type_system; + m_opaque_decl_ctx = decl_ctx; + } + + void Clear() { + m_type_system = nullptr; + m_opaque_decl_ctx = nullptr; + } + + ConstString GetName() const; + + ConstString GetScopeQualifiedName() const; + + bool IsStructUnionOrClass() const; private: - TypeSystem *m_type_system; - void *m_opaque_decl_ctx; - + TypeSystem *m_type_system; + void *m_opaque_decl_ctx; }; - -bool operator == (const CompilerDeclContext &lhs, const CompilerDeclContext &rhs); -bool operator != (const CompilerDeclContext &lhs, const CompilerDeclContext &rhs); - +bool operator==(const CompilerDeclContext &lhs, const CompilerDeclContext &rhs); +bool operator!=(const CompilerDeclContext &lhs, const CompilerDeclContext &rhs); + } // namespace lldb_private #endif // #ifndef liblldb_CompilerDeclContext_h_ diff --git a/include/lldb/Symbol/CompilerType.h b/include/lldb/Symbol/CompilerType.h index 36f6ef3ba6eb..68221609c0cb 100644 --- a/include/lldb/Symbol/CompilerType.h +++ b/include/lldb/Symbol/CompilerType.h @@ -18,562 +18,414 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" +#include "lldb/lldb-private.h" namespace lldb_private { //---------------------------------------------------------------------- -// A class that can carry around a clang ASTContext and a opaque clang +// A class that can carry around a clang ASTContext and a opaque clang // QualType. A clang::QualType can be easily reconstructed from an -// opaque clang type and often the ASTContext is needed when doing +// opaque clang type and often the ASTContext is needed when doing // various type related tasks, so this class allows both items to travel // in a single very lightweight class that can be used. There are many // static equivalents of the member functions that allow the ASTContext // and the opaque clang QualType to be specified for ease of use and // to avoid code duplication. //---------------------------------------------------------------------- -class CompilerType -{ +class CompilerType { public: - //---------------------------------------------------------------------- - // Constructors and Destructors - //---------------------------------------------------------------------- - CompilerType (TypeSystem *type_system, lldb::opaque_compiler_type_t type); - CompilerType (clang::ASTContext *ast_context, clang::QualType qual_type); - - CompilerType (const CompilerType &rhs) : - m_type (rhs.m_type), - m_type_system (rhs.m_type_system) - { - } - - CompilerType () : - m_type (nullptr), - m_type_system (nullptr) - { - } - - ~CompilerType(); - - //---------------------------------------------------------------------- - // Operators - //---------------------------------------------------------------------- - - const CompilerType & - operator= (const CompilerType &rhs) - { - m_type = rhs.m_type; - m_type_system = rhs.m_type_system; - return *this; - } - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - explicit operator bool () const - { - return m_type != nullptr && m_type_system != nullptr; - } - - bool - operator < (const CompilerType &rhs) const - { - if (m_type_system == rhs.m_type_system) - return m_type < rhs.m_type; - return m_type_system < rhs.m_type_system; - } - - bool - IsValid () const - { - return m_type != nullptr && m_type_system != nullptr; - } - - bool - IsArrayType (CompilerType *element_type, - uint64_t *size, - bool *is_incomplete) const; - - bool - IsVectorType (CompilerType *element_type, - uint64_t *size) const; - - bool - IsArrayOfScalarType () const; - - bool - IsAggregateType () const; - - bool - IsAnonymousType () const; - - bool - IsBeingDefined () const; - - bool - IsCharType () const; - - bool - IsCompleteType () const; - - bool - IsConst() const; - - bool - IsCStringType (uint32_t &length) const; - - bool - IsDefined() const; - - bool - IsFloatingPointType (uint32_t &count, bool &is_complex) const; - - bool - IsFunctionType(bool *is_variadic_ptr = nullptr) const; - - uint32_t - IsHomogeneousAggregate (CompilerType* base_type_ptr) const; - - size_t - GetNumberOfFunctionArguments () const; - - CompilerType - GetFunctionArgumentAtIndex (const size_t index) const; - - bool - IsVariadicFunctionType () const; - - bool - IsFunctionPointerType () const; - - bool - IsBlockPointerType (CompilerType *function_pointer_type_ptr) const; - - bool - IsIntegerType (bool &is_signed) const; - - bool - IsEnumerationType (bool &is_signed) const; - - bool - IsIntegerOrEnumerationType (bool &is_signed) const; - - bool - IsPolymorphicClass () const; - - bool - IsPossibleCPlusPlusDynamicType(CompilerType *target_type = nullptr) const - { - return IsPossibleDynamicType (target_type, true, false); - } - - bool - IsPossibleDynamicType(CompilerType *target_type, // Can pass nullptr - bool check_cplusplus, - bool check_objc) const; - - bool - IsPointerToScalarType () const; - - bool - IsRuntimeGeneratedType () const; - - bool - IsPointerType(CompilerType *pointee_type = nullptr) const; - - bool - IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; - - bool - IsReferenceType(CompilerType *pointee_type = nullptr, bool* is_rvalue = nullptr) const; - - bool - ShouldTreatScalarValueAsAddress () const; - - bool - IsScalarType () const; - - bool - IsTypedefType () const; - - bool - IsVoidType () const; - - //---------------------------------------------------------------------- - // Type Completion - //---------------------------------------------------------------------- - - bool - GetCompleteType () const; - - //---------------------------------------------------------------------- - // AST related queries - //---------------------------------------------------------------------- - - size_t - GetPointerByteSize () const; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - - TypeSystem * - GetTypeSystem() const - { - return m_type_system; - } - - ConstString - GetConstQualifiedTypeName () const; - - ConstString - GetConstTypeName () const; - - ConstString - GetTypeName () const; - - ConstString - GetDisplayTypeName () const; - - uint32_t - GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; - - lldb::LanguageType - GetMinimumLanguage (); - - lldb::opaque_compiler_type_t - GetOpaqueQualType() const - { - return m_type; - } - - lldb::TypeClass - GetTypeClass () const; - - void - SetCompilerType (TypeSystem* type_system, lldb::opaque_compiler_type_t type); - - void - SetCompilerType (clang::ASTContext *ast, clang::QualType qual_type); - - unsigned - GetTypeQualifiers() const; - - //---------------------------------------------------------------------- - // Creating related types - //---------------------------------------------------------------------- - - CompilerType - GetArrayElementType(uint64_t *stride = nullptr) const; - - CompilerType - GetCanonicalType () const; - - CompilerType - GetFullyUnqualifiedType () const; - - // Returns -1 if this isn't a function of if the function doesn't have a prototype - // Returns a value >= 0 if there is a prototype. - int - GetFunctionArgumentCount () const; - - CompilerType - GetFunctionArgumentTypeAtIndex (size_t idx) const; - - CompilerType - GetFunctionReturnType () const; - - size_t - GetNumMemberFunctions () const; - - TypeMemberFunctionImpl - GetMemberFunctionAtIndex (size_t idx); - - //---------------------------------------------------------------------- - // If this type is a reference to a type (L value or R value reference), - // return a new type with the reference removed, else return the current - // type itself. - //---------------------------------------------------------------------- - CompilerType - GetNonReferenceType () const; - - //---------------------------------------------------------------------- - // If this type is a pointer type, return the type that the pointer - // points to, else return an invalid type. - //---------------------------------------------------------------------- - CompilerType - GetPointeeType () const; - - //---------------------------------------------------------------------- - // Return a new CompilerType that is a pointer to this type - //---------------------------------------------------------------------- - CompilerType - GetPointerType () const; - - //---------------------------------------------------------------------- - // Return a new CompilerType that is a L value reference to this type if - // this type is valid and the type system supports L value references, - // else return an invalid type. - //---------------------------------------------------------------------- - CompilerType - GetLValueReferenceType () const; - - //---------------------------------------------------------------------- - // Return a new CompilerType that is a R value reference to this type if - // this type is valid and the type system supports R value references, - // else return an invalid type. - //---------------------------------------------------------------------- - CompilerType - GetRValueReferenceType () const; - - //---------------------------------------------------------------------- - // Return a new CompilerType adds a const modifier to this type if - // this type is valid and the type system supports const modifiers, - // else return an invalid type. - //---------------------------------------------------------------------- - CompilerType - AddConstModifier () const; - - //---------------------------------------------------------------------- - // Return a new CompilerType adds a volatile modifier to this type if - // this type is valid and the type system supports volatile modifiers, - // else return an invalid type. - //---------------------------------------------------------------------- - CompilerType - AddVolatileModifier () const; - - //---------------------------------------------------------------------- - // Return a new CompilerType adds a restrict modifier to this type if - // this type is valid and the type system supports restrict modifiers, - // else return an invalid type. - //---------------------------------------------------------------------- - CompilerType - AddRestrictModifier () const; - - //---------------------------------------------------------------------- - // Create a typedef to this type using "name" as the name of the typedef - // this type is valid and the type system supports typedefs, else return - // an invalid type. - //---------------------------------------------------------------------- - CompilerType - CreateTypedef (const char *name, const CompilerDeclContext &decl_ctx) const; - - // If the current object represents a typedef type, get the underlying type - CompilerType - GetTypedefedType () const; - - //---------------------------------------------------------------------- - // Create related types using the current type's AST - //---------------------------------------------------------------------- - CompilerType - GetBasicTypeFromAST (lldb::BasicType basic_type) const; - - //---------------------------------------------------------------------- - // Exploring the type - //---------------------------------------------------------------------- - - uint64_t - GetByteSize (ExecutionContextScope *exe_scope) const; - - uint64_t - GetBitSize (ExecutionContextScope *exe_scope) const; - - lldb::Encoding - GetEncoding (uint64_t &count) const; - - lldb::Format - GetFormat () const; - - size_t - GetTypeBitAlign () const; - - uint32_t - GetNumChildren (bool omit_empty_base_classes) const; - - lldb::BasicType - GetBasicTypeEnumeration () const; - - static lldb::BasicType - GetBasicTypeEnumeration (const ConstString &name); - - //---------------------------------------------------------------------- - // If this type is an enumeration, iterate through all of its enumerators - // using a callback. If the callback returns true, keep iterating, else - // abort the iteration. - //---------------------------------------------------------------------- - void - ForEachEnumerator (std::function <bool (const CompilerType &integer_type, - const ConstString &name, - const llvm::APSInt &value)> const &callback) const; - - uint32_t - GetNumFields () const; - - CompilerType - GetFieldAtIndex (size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) const; - - uint32_t - GetNumDirectBaseClasses () const; - - uint32_t - GetNumVirtualBaseClasses () const; - - CompilerType - GetDirectBaseClassAtIndex (size_t idx, - uint32_t *bit_offset_ptr) const; - - CompilerType - GetVirtualBaseClassAtIndex (size_t idx, - uint32_t *bit_offset_ptr) const; - - uint32_t - GetIndexOfFieldWithName(const char* name, - CompilerType* field_compiler_type = nullptr, - uint64_t *bit_offset_ptr = nullptr, - uint32_t *bitfield_bit_size_ptr = nullptr, - bool *is_bitfield_ptr = nullptr) const; - - CompilerType - GetChildCompilerTypeAtIndex (ExecutionContext *exe_ctx, - size_t idx, - bool transparent_pointers, - bool omit_empty_base_classes, - bool ignore_array_bounds, - std::string& child_name, - uint32_t &child_byte_size, - int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, - bool &child_is_deref_of_parent, - ValueObject *valobj, - uint64_t &language_flags) const; - - // Lookup a child given a name. This function will match base class names - // and member member names in "clang_type" only, not descendants. - uint32_t - GetIndexOfChildWithName (const char *name, - bool omit_empty_base_classes) const; - - // Lookup a child member given a name. This function will match member names - // only and will descend into "clang_type" children in search for the first - // member in this class, or any base class that matches "name". - // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>> - // so we catch all names that match a given child name, not just the first. - size_t - GetIndexOfChildMemberWithName (const char *name, - bool omit_empty_base_classes, - std::vector<uint32_t>& child_indexes) const; - - size_t - GetNumTemplateArguments () const; - - CompilerType - GetTemplateArgument (size_t idx, - lldb::TemplateArgumentKind &kind) const; - - CompilerType - GetTypeForFormatters () const; - - LazyBool - ShouldPrintAsOneLiner (ValueObject* valobj) const; - - bool - IsMeaninglessWithoutDynamicResolution () const; - - //------------------------------------------------------------------ - // Pointers & References - //------------------------------------------------------------------ - - // Converts "s" to a floating point value and place resulting floating - // point bytes in the "dst" buffer. - size_t - ConvertStringToFloatValue (const char *s, - uint8_t *dst, - size_t dst_size) const; - - //---------------------------------------------------------------------- - // Dumping types - //---------------------------------------------------------------------- - void - DumpValue (ExecutionContext *exe_ctx, - Stream *s, - lldb::Format format, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - bool show_types, - bool show_summary, - bool verbose, - uint32_t depth); - - bool - DumpTypeValue (Stream *s, - lldb::Format format, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope); - - void - DumpSummary (ExecutionContext *exe_ctx, - Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size); - - void - DumpTypeDescription () const; // Dump to stdout - - void - DumpTypeDescription (Stream *s) const; - - bool - GetValueAsScalar (const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - Scalar &value) const; - - bool - SetValueFromScalar (const Scalar &value, - Stream &strm); - - bool - ReadFromMemory (ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - DataExtractor &data); - - bool - WriteToMemory (ExecutionContext *exe_ctx, - lldb::addr_t addr, - AddressType address_type, - StreamString &new_value); - - void - Clear() - { - m_type = nullptr; - m_type_system = nullptr; - } + //---------------------------------------------------------------------- + // Constructors and Destructors + //---------------------------------------------------------------------- + CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type); + CompilerType(clang::ASTContext *ast_context, clang::QualType qual_type); + + CompilerType(const CompilerType &rhs) + : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {} + + CompilerType() : m_type(nullptr), m_type_system(nullptr) {} + + ~CompilerType(); + + //---------------------------------------------------------------------- + // Operators + //---------------------------------------------------------------------- + + const CompilerType &operator=(const CompilerType &rhs) { + m_type = rhs.m_type; + m_type_system = rhs.m_type_system; + return *this; + } + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + explicit operator bool() const { + return m_type != nullptr && m_type_system != nullptr; + } + + bool operator<(const CompilerType &rhs) const { + if (m_type_system == rhs.m_type_system) + return m_type < rhs.m_type; + return m_type_system < rhs.m_type_system; + } + + bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; } + + bool IsArrayType(CompilerType *element_type, uint64_t *size, + bool *is_incomplete) const; + + bool IsVectorType(CompilerType *element_type, uint64_t *size) const; + + bool IsArrayOfScalarType() const; + + bool IsAggregateType() const; + + bool IsAnonymousType() const; + + bool IsBeingDefined() const; + + bool IsCharType() const; + + bool IsCompleteType() const; + + bool IsConst() const; + + bool IsCStringType(uint32_t &length) const; + + bool IsDefined() const; + + bool IsFloatingPointType(uint32_t &count, bool &is_complex) const; + + bool IsFunctionType(bool *is_variadic_ptr = nullptr) const; + + uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const; + + size_t GetNumberOfFunctionArguments() const; + + CompilerType GetFunctionArgumentAtIndex(const size_t index) const; + + bool IsVariadicFunctionType() const; + + bool IsFunctionPointerType() const; + + bool IsBlockPointerType(CompilerType *function_pointer_type_ptr) const; + + bool IsIntegerType(bool &is_signed) const; + + bool IsEnumerationType(bool &is_signed) const; + + bool IsIntegerOrEnumerationType(bool &is_signed) const; + + bool IsPolymorphicClass() const; + + bool + IsPossibleCPlusPlusDynamicType(CompilerType *target_type = nullptr) const { + return IsPossibleDynamicType(target_type, true, false); + } + + bool IsPossibleDynamicType(CompilerType *target_type, // Can pass nullptr + bool check_cplusplus, bool check_objc) const; + + bool IsPointerToScalarType() const; + + bool IsRuntimeGeneratedType() const; + + bool IsPointerType(CompilerType *pointee_type = nullptr) const; + + bool IsPointerOrReferenceType(CompilerType *pointee_type = nullptr) const; + + bool IsReferenceType(CompilerType *pointee_type = nullptr, + bool *is_rvalue = nullptr) const; + + bool ShouldTreatScalarValueAsAddress() const; + + bool IsScalarType() const; + + bool IsTypedefType() const; + + bool IsVoidType() const; + + //---------------------------------------------------------------------- + // Type Completion + //---------------------------------------------------------------------- + + bool GetCompleteType() const; + + //---------------------------------------------------------------------- + // AST related queries + //---------------------------------------------------------------------- + + size_t GetPointerByteSize() const; + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + + TypeSystem *GetTypeSystem() const { return m_type_system; } + + ConstString GetConstQualifiedTypeName() const; + + ConstString GetConstTypeName() const; + + ConstString GetTypeName() const; + + ConstString GetDisplayTypeName() const; + + uint32_t + GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) const; + + lldb::LanguageType GetMinimumLanguage(); + + lldb::opaque_compiler_type_t GetOpaqueQualType() const { return m_type; } + + lldb::TypeClass GetTypeClass() const; + + void SetCompilerType(TypeSystem *type_system, + lldb::opaque_compiler_type_t type); + + void SetCompilerType(clang::ASTContext *ast, clang::QualType qual_type); + + unsigned GetTypeQualifiers() const; + + //---------------------------------------------------------------------- + // Creating related types + //---------------------------------------------------------------------- + + CompilerType GetArrayElementType(uint64_t *stride = nullptr) const; + + CompilerType GetArrayType(uint64_t size) const; + + CompilerType GetCanonicalType() const; + + CompilerType GetFullyUnqualifiedType() const; + + // Returns -1 if this isn't a function of if the function doesn't have a + // prototype + // Returns a value >= 0 if there is a prototype. + int GetFunctionArgumentCount() const; + + CompilerType GetFunctionArgumentTypeAtIndex(size_t idx) const; + + CompilerType GetFunctionReturnType() const; + + size_t GetNumMemberFunctions() const; + + TypeMemberFunctionImpl GetMemberFunctionAtIndex(size_t idx); + + //---------------------------------------------------------------------- + // If this type is a reference to a type (L value or R value reference), + // return a new type with the reference removed, else return the current + // type itself. + //---------------------------------------------------------------------- + CompilerType GetNonReferenceType() const; + + //---------------------------------------------------------------------- + // If this type is a pointer type, return the type that the pointer + // points to, else return an invalid type. + //---------------------------------------------------------------------- + CompilerType GetPointeeType() const; + + //---------------------------------------------------------------------- + // Return a new CompilerType that is a pointer to this type + //---------------------------------------------------------------------- + CompilerType GetPointerType() const; + + //---------------------------------------------------------------------- + // Return a new CompilerType that is a L value reference to this type if + // this type is valid and the type system supports L value references, + // else return an invalid type. + //---------------------------------------------------------------------- + CompilerType GetLValueReferenceType() const; + + //---------------------------------------------------------------------- + // Return a new CompilerType that is a R value reference to this type if + // this type is valid and the type system supports R value references, + // else return an invalid type. + //---------------------------------------------------------------------- + CompilerType GetRValueReferenceType() const; + + //---------------------------------------------------------------------- + // Return a new CompilerType adds a const modifier to this type if + // this type is valid and the type system supports const modifiers, + // else return an invalid type. + //---------------------------------------------------------------------- + CompilerType AddConstModifier() const; + + //---------------------------------------------------------------------- + // Return a new CompilerType adds a volatile modifier to this type if + // this type is valid and the type system supports volatile modifiers, + // else return an invalid type. + //---------------------------------------------------------------------- + CompilerType AddVolatileModifier() const; + + //---------------------------------------------------------------------- + // Return a new CompilerType adds a restrict modifier to this type if + // this type is valid and the type system supports restrict modifiers, + // else return an invalid type. + //---------------------------------------------------------------------- + CompilerType AddRestrictModifier() const; + + //---------------------------------------------------------------------- + // Create a typedef to this type using "name" as the name of the typedef + // this type is valid and the type system supports typedefs, else return + // an invalid type. + //---------------------------------------------------------------------- + CompilerType CreateTypedef(const char *name, + const CompilerDeclContext &decl_ctx) const; + + // If the current object represents a typedef type, get the underlying type + CompilerType GetTypedefedType() const; + + //---------------------------------------------------------------------- + // Create related types using the current type's AST + //---------------------------------------------------------------------- + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const; + + //---------------------------------------------------------------------- + // Exploring the type + //---------------------------------------------------------------------- + + uint64_t GetByteSize(ExecutionContextScope *exe_scope) const; + + uint64_t GetBitSize(ExecutionContextScope *exe_scope) const; + + lldb::Encoding GetEncoding(uint64_t &count) const; + + lldb::Format GetFormat() const; + + size_t GetTypeBitAlign() const; + + uint32_t GetNumChildren(bool omit_empty_base_classes) const; + + lldb::BasicType GetBasicTypeEnumeration() const; + + static lldb::BasicType GetBasicTypeEnumeration(const ConstString &name); + + //---------------------------------------------------------------------- + // If this type is an enumeration, iterate through all of its enumerators + // using a callback. If the callback returns true, keep iterating, else + // abort the iteration. + //---------------------------------------------------------------------- + void ForEachEnumerator( + std::function<bool(const CompilerType &integer_type, + const ConstString &name, + const llvm::APSInt &value)> const &callback) const; + + uint32_t GetNumFields() const; + + CompilerType GetFieldAtIndex(size_t idx, std::string &name, + uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) const; + + uint32_t GetNumDirectBaseClasses() const; + + uint32_t GetNumVirtualBaseClasses() const; + + CompilerType GetDirectBaseClassAtIndex(size_t idx, + uint32_t *bit_offset_ptr) const; + + CompilerType GetVirtualBaseClassAtIndex(size_t idx, + uint32_t *bit_offset_ptr) const; + + uint32_t GetIndexOfFieldWithName(const char *name, + CompilerType *field_compiler_type = nullptr, + uint64_t *bit_offset_ptr = nullptr, + uint32_t *bitfield_bit_size_ptr = nullptr, + bool *is_bitfield_ptr = nullptr) const; + + CompilerType GetChildCompilerTypeAtIndex( + ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers, + bool omit_empty_base_classes, bool ignore_array_bounds, + std::string &child_name, uint32_t &child_byte_size, + int32_t &child_byte_offset, uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, + bool &child_is_deref_of_parent, ValueObject *valobj, + uint64_t &language_flags) const; + + // Lookup a child given a name. This function will match base class names + // and member member names in "clang_type" only, not descendants. + uint32_t GetIndexOfChildWithName(const char *name, + bool omit_empty_base_classes) const; + + // Lookup a child member given a name. This function will match member names + // only and will descend into "clang_type" children in search for the first + // member in this class, or any base class that matches "name". + // TODO: Return all matches for a given name by returning a + // vector<vector<uint32_t>> + // so we catch all names that match a given child name, not just the first. + size_t + GetIndexOfChildMemberWithName(const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) const; + + size_t GetNumTemplateArguments() const; + + CompilerType GetTemplateArgument(size_t idx, + lldb::TemplateArgumentKind &kind) const; + + CompilerType GetTypeForFormatters() const; + + LazyBool ShouldPrintAsOneLiner(ValueObject *valobj) const; + + bool IsMeaninglessWithoutDynamicResolution() const; + + //------------------------------------------------------------------ + // Pointers & References + //------------------------------------------------------------------ + + // Converts "s" to a floating point value and place resulting floating + // point bytes in the "dst" buffer. + size_t ConvertStringToFloatValue(const char *s, uint8_t *dst, + size_t dst_size) const; + + //---------------------------------------------------------------------- + // Dumping types + //---------------------------------------------------------------------- + void DumpValue(ExecutionContext *exe_ctx, Stream *s, lldb::Format format, + const DataExtractor &data, lldb::offset_t data_offset, + size_t data_byte_size, uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, bool show_types, + bool show_summary, bool verbose, uint32_t depth); + + bool DumpTypeValue(Stream *s, lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope); + + void DumpSummary(ExecutionContext *exe_ctx, Stream *s, + const DataExtractor &data, lldb::offset_t data_offset, + size_t data_byte_size); + + void DumpTypeDescription() const; // Dump to stdout + + void DumpTypeDescription(Stream *s) const; + + bool GetValueAsScalar(const DataExtractor &data, lldb::offset_t data_offset, + size_t data_byte_size, Scalar &value) const; + + bool SetValueFromScalar(const Scalar &value, Stream &strm); + + bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, + AddressType address_type, DataExtractor &data); + + bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, + AddressType address_type, StreamString &new_value); + + void Clear() { + m_type = nullptr; + m_type_system = nullptr; + } private: - lldb::opaque_compiler_type_t m_type; - TypeSystem *m_type_system; + lldb::opaque_compiler_type_t m_type; + TypeSystem *m_type_system; }; - -bool operator == (const CompilerType &lhs, const CompilerType &rhs); -bool operator != (const CompilerType &lhs, const CompilerType &rhs); + +bool operator==(const CompilerType &lhs, const CompilerType &rhs); +bool operator!=(const CompilerType &lhs, const CompilerType &rhs); } // namespace lldb_private diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h index da7f87ced0a0..c221a36bd6c8 100644 --- a/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -32,138 +32,125 @@ namespace lldb_private { // eh_frame / debug_frame, and one to generate an UnwindPlan based // on the FDE in the eh_frame / debug_frame section. -class DWARFCallFrameInfo -{ +class DWARFCallFrameInfo { public: - - DWARFCallFrameInfo (ObjectFile& objfile, - lldb::SectionSP& section, - lldb::RegisterKind reg_kind, - bool is_eh_frame); - - ~DWARFCallFrameInfo(); - - // Locate an AddressRange that includes the provided Address in this - // object's eh_frame/debug_info - // Returns true if a range is found to cover that address. - bool - GetAddressRange (Address addr, AddressRange &range); - - // Return an UnwindPlan based on the call frame information encoded - // in the FDE of this DWARFCallFrameInfo section. - bool - GetUnwindPlan (Address addr, UnwindPlan& unwind_plan); - - typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector; - - //------------------------------------------------------------------ - // Build a vector of file address and size for all functions in this Module - // based on the eh_frame FDE entries. - // - // The eh_frame information can be a useful source of file address and size of - // the functions in a Module. Often a binary's non-exported symbols are stripped - // before shipping so lldb won't know the start addr / size of many functions - // in the Module. But the eh_frame can help to give the addresses of these - // stripped symbols, at least. - // - // @param[out] function_info - // A vector provided by the caller is filled out. May be empty if no FDEs/no eh_frame - // is present in this Module. - - void - GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info); - - void - ForEachFDEEntries(const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback); + DWARFCallFrameInfo(ObjectFile &objfile, lldb::SectionSP §ion, + lldb::RegisterKind reg_kind, bool is_eh_frame); + + ~DWARFCallFrameInfo(); + + // Locate an AddressRange that includes the provided Address in this + // object's eh_frame/debug_info + // Returns true if a range is found to cover that address. + bool GetAddressRange(Address addr, AddressRange &range); + + // Return an UnwindPlan based on the call frame information encoded + // in the FDE of this DWARFCallFrameInfo section. + bool GetUnwindPlan(Address addr, UnwindPlan &unwind_plan); + + typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector; + + //------------------------------------------------------------------ + // Build a vector of file address and size for all functions in this Module + // based on the eh_frame FDE entries. + // + // The eh_frame information can be a useful source of file address and size of + // the functions in a Module. Often a binary's non-exported symbols are + // stripped + // before shipping so lldb won't know the start addr / size of many functions + // in the Module. But the eh_frame can help to give the addresses of these + // stripped symbols, at least. + // + // @param[out] function_info + // A vector provided by the caller is filled out. May be empty if no + // FDEs/no eh_frame + // is present in this Module. + + void + GetFunctionAddressAndSizeVector(FunctionAddressAndSizeVector &function_info); + + void ForEachFDEEntries( + const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)> &callback); private: - enum - { - CFI_AUG_MAX_SIZE = 8, - CFI_HEADER_SIZE = 8 - }; - - struct CIE - { - dw_offset_t cie_offset; - uint8_t version; - char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very short. - uint32_t code_align; - int32_t data_align; - uint32_t return_addr_reg_num; - dw_offset_t inst_offset; // offset of CIE instructions in mCFIData - uint32_t inst_length; // length of CIE instructions in mCFIData - uint8_t ptr_encoding; - uint8_t lsda_addr_encoding; // The encoding of the LSDA address in the FDE augmentation data - lldb::addr_t personality_loc; // (file) address of the pointer to the personality routine - lldb_private::UnwindPlan::Row initial_row; - - CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0), - data_align (0), return_addr_reg_num (LLDB_INVALID_REGNUM), inst_offset (0), - inst_length (0), ptr_encoding (0), - lsda_addr_encoding (DW_EH_PE_omit), personality_loc (LLDB_INVALID_ADDRESS), - initial_row () - { - } - }; - - typedef std::shared_ptr<CIE> CIESP; - - typedef std::map<dw_offset_t, CIESP> cie_map_t; - - // Start address (file address), size, offset of FDE location - // used for finding an FDE for a given File address; the start address field is - // an offset into an individual Module. - typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap; - - bool - IsEHFrame() const; - - bool - GetFDEEntryByFileAddress (lldb::addr_t file_offset, FDEEntryMap::Entry& fde_entry); - - void - GetFDEIndex (); - - bool - FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan); - - const CIE* - GetCIE(dw_offset_t cie_offset); - - void - GetCFIData(); - - // Applies the specified DWARF opcode to the given row. This function handle the commands - // operates only on a single row (these are the ones what can appear both in CIE and in FDE). - // Returns true if the opcode is handled and false otherwise. - bool - HandleCommonDwarfOpcode(uint8_t primary_opcode, - uint8_t extended_opcode, - int32_t data_align, - lldb::offset_t& offset, - UnwindPlan::Row& row); - - ObjectFile& m_objfile; - lldb::SectionSP m_section_sp; - lldb::RegisterKind m_reg_kind; - Flags m_flags; - cie_map_t m_cie_map; - - DataExtractor m_cfi_data; - bool m_cfi_data_initialized; // only copy the section into the DE once - - FDEEntryMap m_fde_index; - bool m_fde_index_initialized; // only scan the section for FDEs once - std::mutex m_fde_index_mutex; // and isolate the thread that does it - - bool m_is_eh_frame; - - CIESP - ParseCIE (const uint32_t cie_offset); - + enum { CFI_AUG_MAX_SIZE = 8, CFI_HEADER_SIZE = 8 }; + + struct CIE { + dw_offset_t cie_offset; + uint8_t version; + char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very + // short. + uint32_t code_align; + int32_t data_align; + uint32_t return_addr_reg_num; + dw_offset_t inst_offset; // offset of CIE instructions in mCFIData + uint32_t inst_length; // length of CIE instructions in mCFIData + uint8_t ptr_encoding; + uint8_t lsda_addr_encoding; // The encoding of the LSDA address in the FDE + // augmentation data + lldb::addr_t personality_loc; // (file) address of the pointer to the + // personality routine + lldb_private::UnwindPlan::Row initial_row; + + CIE(dw_offset_t offset) + : cie_offset(offset), version(-1), code_align(0), data_align(0), + return_addr_reg_num(LLDB_INVALID_REGNUM), inst_offset(0), + inst_length(0), ptr_encoding(0), lsda_addr_encoding(DW_EH_PE_omit), + personality_loc(LLDB_INVALID_ADDRESS), initial_row() {} + }; + + typedef std::shared_ptr<CIE> CIESP; + + typedef std::map<dw_offset_t, CIESP> cie_map_t; + + // Start address (file address), size, offset of FDE location + // used for finding an FDE for a given File address; the start address field + // is + // an offset into an individual Module. + typedef RangeDataVector<lldb::addr_t, uint32_t, dw_offset_t> FDEEntryMap; + + bool IsEHFrame() const; + + bool GetFDEEntryByFileAddress(lldb::addr_t file_offset, + FDEEntryMap::Entry &fde_entry); + + void GetFDEIndex(); + + bool FDEToUnwindPlan(uint32_t offset, Address startaddr, + UnwindPlan &unwind_plan); + + const CIE *GetCIE(dw_offset_t cie_offset); + + void GetCFIData(); + + // Applies the specified DWARF opcode to the given row. This function handle + // the commands + // operates only on a single row (these are the ones what can appear both in + // CIE and in FDE). + // Returns true if the opcode is handled and false otherwise. + bool HandleCommonDwarfOpcode(uint8_t primary_opcode, uint8_t extended_opcode, + int32_t data_align, lldb::offset_t &offset, + UnwindPlan::Row &row); + + ObjectFile &m_objfile; + lldb::SectionSP m_section_sp; + lldb::RegisterKind m_reg_kind; + Flags m_flags; + cie_map_t m_cie_map; + + DataExtractor m_cfi_data; + bool m_cfi_data_initialized; // only copy the section into the DE once + + FDEEntryMap m_fde_index; + bool m_fde_index_initialized; // only scan the section for FDEs once + std::mutex m_fde_index_mutex; // and isolate the thread that does it + + bool m_is_eh_frame; + + CIESP + ParseCIE(const uint32_t cie_offset); }; } // namespace lldb_private -#endif // liblldb_DWARFCallFrameInfo_h_ +#endif // liblldb_DWARFCallFrameInfo_h_ diff --git a/include/lldb/Symbol/DebugMacros.h b/include/lldb/Symbol/DebugMacros.h index 24bf03a8c3b1..4d4a3273db64 100644 --- a/include/lldb/Symbol/DebugMacros.h +++ b/include/lldb/Symbol/DebugMacros.h @@ -17,8 +17,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -26,113 +26,75 @@ class CompileUnit; class DebugMacros; typedef std::shared_ptr<DebugMacros> DebugMacrosSP; -class DebugMacroEntry -{ +class DebugMacroEntry { public: - enum EntryType - { - INVALID, - DEFINE, - UNDEF, - START_FILE, - END_FILE, - INDIRECT - }; + enum EntryType { INVALID, DEFINE, UNDEF, START_FILE, END_FILE, INDIRECT }; public: - static DebugMacroEntry - CreateDefineEntry(uint32_t line, const char *str); + static DebugMacroEntry CreateDefineEntry(uint32_t line, const char *str); - static DebugMacroEntry - CreateUndefEntry(uint32_t line, const char *str); + static DebugMacroEntry CreateUndefEntry(uint32_t line, const char *str); - static DebugMacroEntry - CreateStartFileEntry(uint32_t line, uint32_t debug_line_file_idx); + static DebugMacroEntry CreateStartFileEntry(uint32_t line, + uint32_t debug_line_file_idx); - static DebugMacroEntry - CreateEndFileEntry(); + static DebugMacroEntry CreateEndFileEntry(); - static DebugMacroEntry - CreateIndirectEntry(const DebugMacrosSP &debug_macros_sp); + static DebugMacroEntry + CreateIndirectEntry(const DebugMacrosSP &debug_macros_sp); - DebugMacroEntry() : m_type(INVALID) { } + DebugMacroEntry() : m_type(INVALID) {} - ~DebugMacroEntry() = default; + ~DebugMacroEntry() = default; - EntryType - GetType() const - { - return m_type; - } + EntryType GetType() const { return m_type; } - uint64_t - GetLineNumber() const - { - return m_line; - } + uint64_t GetLineNumber() const { return m_line; } - ConstString - GetMacroString() const - { - return m_str; - } + ConstString GetMacroString() const { return m_str; } - const FileSpec& GetFileSpec(CompileUnit *comp_unit) const; + const FileSpec &GetFileSpec(CompileUnit *comp_unit) const; - DebugMacros * - GetIndirectDebugMacros() const - { - return m_debug_macros_sp.get(); - } + DebugMacros *GetIndirectDebugMacros() const { + return m_debug_macros_sp.get(); + } private: - DebugMacroEntry(EntryType type, - uint32_t line, - uint32_t debug_line_file_idx, - const char *str); - - DebugMacroEntry(EntryType type, - const DebugMacrosSP &debug_macros_sp); - - EntryType m_type:3; - uint32_t m_line:29; - uint32_t m_debug_line_file_idx; - ConstString m_str; - DebugMacrosSP m_debug_macros_sp; + DebugMacroEntry(EntryType type, uint32_t line, uint32_t debug_line_file_idx, + const char *str); + + DebugMacroEntry(EntryType type, const DebugMacrosSP &debug_macros_sp); + + EntryType m_type : 3; + uint32_t m_line : 29; + uint32_t m_debug_line_file_idx; + ConstString m_str; + DebugMacrosSP m_debug_macros_sp; }; -class DebugMacros -{ +class DebugMacros { public: - DebugMacros() = default; - - ~DebugMacros() = default; - - void - AddMacroEntry(const DebugMacroEntry &entry) - { - m_macro_entries.push_back(entry); - } - - size_t - GetNumMacroEntries() const - { - return m_macro_entries.size(); - } - - DebugMacroEntry - GetMacroEntryAtIndex(const size_t index) const - { - if (index < m_macro_entries.size()) - return m_macro_entries[index]; - else - return DebugMacroEntry(); - } + DebugMacros() = default; + + ~DebugMacros() = default; + + void AddMacroEntry(const DebugMacroEntry &entry) { + m_macro_entries.push_back(entry); + } + + size_t GetNumMacroEntries() const { return m_macro_entries.size(); } + + DebugMacroEntry GetMacroEntryAtIndex(const size_t index) const { + if (index < m_macro_entries.size()) + return m_macro_entries[index]; + else + return DebugMacroEntry(); + } private: - DISALLOW_COPY_AND_ASSIGN(DebugMacros); + DISALLOW_COPY_AND_ASSIGN(DebugMacros); - std::vector<DebugMacroEntry> m_macro_entries; + std::vector<DebugMacroEntry> m_macro_entries; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/DeclVendor.h b/include/lldb/Symbol/DeclVendor.h index ffba71c9299f..5ee8b19b6ed0 100644 --- a/include/lldb/Symbol/DeclVendor.h +++ b/include/lldb/Symbol/DeclVendor.h @@ -15,59 +15,50 @@ #include <vector> namespace lldb_private { - + //---------------------------------------------------------------------- // The Decl vendor class is intended as a generic interface to search // for named declarations that are not necessarily backed by a specific // symbol file. //---------------------------------------------------------------------- -class DeclVendor -{ +class DeclVendor { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - DeclVendor() - { - } - - virtual - ~DeclVendor() - { - } - - //------------------------------------------------------------------ - /// Look up the set of Decls that the DeclVendor currently knows about - /// matching a given name. - /// - /// @param[in] name - /// The name to look for. - /// - /// @param[in] append - /// If true, FindDecls will clear "decls" when it starts. - /// - /// @param[in] max_matches - /// The maximum number of Decls to return. UINT32_MAX means "as - /// many as possible." - /// - /// @return - /// The number of Decls added to decls; will not exceed - /// max_matches. - //------------------------------------------------------------------ - virtual uint32_t - FindDecls (const ConstString &name, - bool append, - uint32_t max_matches, - std::vector <clang::NamedDecl*> &decls) = 0; - + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + DeclVendor() {} + + virtual ~DeclVendor() {} + + //------------------------------------------------------------------ + /// Look up the set of Decls that the DeclVendor currently knows about + /// matching a given name. + /// + /// @param[in] name + /// The name to look for. + /// + /// @param[in] append + /// If true, FindDecls will clear "decls" when it starts. + /// + /// @param[in] max_matches + /// The maximum number of Decls to return. UINT32_MAX means "as + /// many as possible." + /// + /// @return + /// The number of Decls added to decls; will not exceed + /// max_matches. + //------------------------------------------------------------------ + virtual uint32_t FindDecls(const ConstString &name, bool append, + uint32_t max_matches, + std::vector<clang::NamedDecl *> &decls) = 0; + private: - //------------------------------------------------------------------ - // For DeclVendor only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (DeclVendor); + //------------------------------------------------------------------ + // For DeclVendor only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN(DeclVendor); }; - - + } // namespace lldb_private #endif diff --git a/include/lldb/Symbol/Declaration.h b/include/lldb/Symbol/Declaration.h index 73dede556eae..1846e2fdca82 100644 --- a/include/lldb/Symbol/Declaration.h +++ b/include/lldb/Symbol/Declaration.h @@ -10,8 +10,8 @@ #ifndef liblldb_Declaration_h_ #define liblldb_Declaration_h_ -#include "lldb/lldb-private.h" #include "lldb/Host/FileSpec.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -25,254 +25,216 @@ namespace lldb_private { /// functions, types, variables, any many other debug core objects were /// declared. //---------------------------------------------------------------------- -class Declaration -{ +class Declaration { public: - //------------------------------------------------------------------ - /// Default constructor. - //------------------------------------------------------------------ - Declaration () : - m_file (), - m_line (0) + //------------------------------------------------------------------ + /// Default constructor. + //------------------------------------------------------------------ + Declaration() + : m_file(), m_line(0) #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - ,m_column (0) + , + m_column(0) #endif - { - } - - - //------------------------------------------------------------------ - /// Construct with file specification, and optional line and column. - /// - /// @param[in] file_spec - /// The file specification that describes where this was - /// declared. - /// - /// @param[in] line - /// The line number that describes where this was declared. Set - /// to zero if there is no line number information. - /// - /// @param[in] column - /// The column number that describes where this was declared. - /// Set to zero if there is no column number information. - //------------------------------------------------------------------ - Declaration (const FileSpec& file_spec, uint32_t line = 0, uint32_t column = 0) : - m_file (file_spec), - m_line (line) + { + } + + //------------------------------------------------------------------ + /// Construct with file specification, and optional line and column. + /// + /// @param[in] file_spec + /// The file specification that describes where this was + /// declared. + /// + /// @param[in] line + /// The line number that describes where this was declared. Set + /// to zero if there is no line number information. + /// + /// @param[in] column + /// The column number that describes where this was declared. + /// Set to zero if there is no column number information. + //------------------------------------------------------------------ + Declaration(const FileSpec &file_spec, uint32_t line = 0, uint32_t column = 0) + : m_file(file_spec), m_line(line) #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - ,m_column (column) + , + m_column(column) #endif - { - } - - //------------------------------------------------------------------ - /// Construct with a reference to another Declaration object. - //------------------------------------------------------------------ - Declaration (const Declaration& rhs) : - m_file (rhs.m_file), - m_line (rhs.m_line) + { + } + + //------------------------------------------------------------------ + /// Construct with a reference to another Declaration object. + //------------------------------------------------------------------ + Declaration(const Declaration &rhs) + : m_file(rhs.m_file), m_line(rhs.m_line) #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - ,m_column (rhs.m_column) + , + m_column(rhs.m_column) #endif - { - - } - - //------------------------------------------------------------------ - /// Construct with a pointer to another Declaration object. - //------------------------------------------------------------------ - Declaration(const Declaration* decl_ptr) : - m_file(), - m_line(0) + { + } + + //------------------------------------------------------------------ + /// Construct with a pointer to another Declaration object. + //------------------------------------------------------------------ + Declaration(const Declaration *decl_ptr) + : m_file(), m_line(0) #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - ,m_column(0) + , + m_column(0) #endif - { - if (decl_ptr) - *this = *decl_ptr; - } - - //------------------------------------------------------------------ - /// Clear the object's state. - /// - /// Sets the file specification to be empty, and the line and column - /// to zero. - //------------------------------------------------------------------ - void - Clear () - { - m_file.Clear(); - m_line= 0; + { + if (decl_ptr) + *this = *decl_ptr; + } + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Sets the file specification to be empty, and the line and column + /// to zero. + //------------------------------------------------------------------ + void Clear() { + m_file.Clear(); + m_line = 0; #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - m_column = 0; + m_column = 0; #endif - } - - //------------------------------------------------------------------ - /// Compare two declaration objects. - /// - /// Compares the two file specifications from \a lhs and \a rhs. If - /// the file specifications are equal, then continue to compare the - /// line number and column numbers respectively. - /// - /// @param[in] lhs - /// The Left Hand Side const Declaration object reference. - /// - /// @param[in] rhs - /// The Right Hand Side const Declaration object reference. - /// - /// @return - /// @li -1 if lhs < rhs - /// @li 0 if lhs == rhs - /// @li 1 if lhs > rhs - //------------------------------------------------------------------ - static int - Compare (const Declaration& lhs, const Declaration& rhs); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of this object to the - /// supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - void - Dump (Stream *s, bool show_fullpaths) const; - - bool - DumpStopContext (Stream *s, bool show_fullpaths) const; - //------------------------------------------------------------------ - /// Get accessor for the declaration column number. - /// - /// @return - /// Non-zero indicates a valid column number, zero indicates no - /// column information is available. - //------------------------------------------------------------------ - uint32_t - GetColumn () const - { + } + + //------------------------------------------------------------------ + /// Compare two declaration objects. + /// + /// Compares the two file specifications from \a lhs and \a rhs. If + /// the file specifications are equal, then continue to compare the + /// line number and column numbers respectively. + /// + /// @param[in] lhs + /// The Left Hand Side const Declaration object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const Declaration object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int Compare(const Declaration &lhs, const Declaration &rhs); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + void Dump(Stream *s, bool show_fullpaths) const; + + bool DumpStopContext(Stream *s, bool show_fullpaths) const; + //------------------------------------------------------------------ + /// Get accessor for the declaration column number. + /// + /// @return + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + //------------------------------------------------------------------ + uint32_t GetColumn() const { #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - return m_column; + return m_column; #else - return 0; + return 0; #endif - } - - //------------------------------------------------------------------ - /// Get accessor for file specification. - /// - /// @return - /// A reference to the file specification object. - //------------------------------------------------------------------ - FileSpec& - GetFile () - { - return m_file; - } - - //------------------------------------------------------------------ - /// Get const accessor for file specification. - /// - /// @return - /// A const reference to the file specification object. - //------------------------------------------------------------------ - const FileSpec& - GetFile () const - { - return m_file; - } - - //------------------------------------------------------------------ - /// Get accessor for the declaration line number. - /// - /// @return - /// Non-zero indicates a valid line number, zero indicates no - /// line information is available. - //------------------------------------------------------------------ - uint32_t - GetLine () const - { - return m_line; - } - - - bool - IsValid() const - { - return m_file && m_line != 0; - } - - //------------------------------------------------------------------ - /// Get the memory cost of this object. - /// - /// @return - /// The number of bytes that this object occupies in memory. - /// The returned value does not include the bytes for any - /// shared string values. - /// - /// @see ConstString::StaticMemorySize () - //------------------------------------------------------------------ - size_t - MemorySize () const; - - //------------------------------------------------------------------ - /// Set accessor for the declaration column number. - /// - /// @param[in] column - /// Non-zero indicates a valid column number, zero indicates no - /// column information is available. - //------------------------------------------------------------------ - void - SetColumn (uint32_t column) - { + } + + //------------------------------------------------------------------ + /// Get accessor for file specification. + /// + /// @return + /// A reference to the file specification object. + //------------------------------------------------------------------ + FileSpec &GetFile() { return m_file; } + + //------------------------------------------------------------------ + /// Get const accessor for file specification. + /// + /// @return + /// A const reference to the file specification object. + //------------------------------------------------------------------ + const FileSpec &GetFile() const { return m_file; } + + //------------------------------------------------------------------ + /// Get accessor for the declaration line number. + /// + /// @return + /// Non-zero indicates a valid line number, zero indicates no + /// line information is available. + //------------------------------------------------------------------ + uint32_t GetLine() const { return m_line; } + + bool IsValid() const { return m_file && m_line != 0; } + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t MemorySize() const; + + //------------------------------------------------------------------ + /// Set accessor for the declaration column number. + /// + /// @param[in] column + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + //------------------------------------------------------------------ + void SetColumn(uint32_t column) { #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - m_column = col; + m_column = col; #endif - } - - //------------------------------------------------------------------ - /// Set accessor for the declaration file specification. - /// - /// @param[in] file_spec - /// The new declaration file specification. - //------------------------------------------------------------------ - void - SetFile (const FileSpec& file_spec) - { - m_file = file_spec; - } + } + + //------------------------------------------------------------------ + /// Set accessor for the declaration file specification. + /// + /// @param[in] file_spec + /// The new declaration file specification. + //------------------------------------------------------------------ + void SetFile(const FileSpec &file_spec) { m_file = file_spec; } + + //------------------------------------------------------------------ + /// Set accessor for the declaration line number. + /// + /// @param[in] line + /// Non-zero indicates a valid line number, zero indicates no + /// line information is available. + //------------------------------------------------------------------ + void SetLine(uint32_t line) { m_line = line; } - //------------------------------------------------------------------ - /// Set accessor for the declaration line number. - /// - /// @param[in] line - /// Non-zero indicates a valid line number, zero indicates no - /// line information is available. - //------------------------------------------------------------------ - void - SetLine (uint32_t line) - { - m_line = line; - } protected: - //------------------------------------------------------------------ - /// Member variables. - //------------------------------------------------------------------ - FileSpec m_file; ///< The file specification that points to the - ///< source file where the declaration occurred. - uint32_t m_line; ///< Non-zero values indicates a valid line number, - ///< zero indicates no line number information is available. + //------------------------------------------------------------------ + /// Member variables. + //------------------------------------------------------------------ + FileSpec m_file; ///< The file specification that points to the + ///< source file where the declaration occurred. + uint32_t m_line; ///< Non-zero values indicates a valid line number, + ///< zero indicates no line number information is available. #ifdef LLDB_ENABLE_DECLARATION_COLUMNS - uint32_t m_column; ///< Non-zero values indicates a valid column number, - ///< zero indicates no column information is available. + uint32_t m_column; ///< Non-zero values indicates a valid column number, + ///< zero indicates no column information is available. #endif }; -bool -operator == (const Declaration &lhs, const Declaration &rhs); +bool operator==(const Declaration &lhs, const Declaration &rhs); } // namespace lldb_private -#endif // liblldb_Declaration_h_ +#endif // liblldb_Declaration_h_ diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index 6d5991cc2b33..a5b9b801e033 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -5,157 +5,152 @@ #include <vector> #include "lldb/Core/AddressRange.h" -#include "lldb/Core/ArchSpec.h" #include "lldb/Core/AddressRange.h" +#include "lldb/Core/ArchSpec.h" namespace lldb_private { class UnwindTable; -class FuncUnwinders -{ +class FuncUnwinders { public: - // FuncUnwinders objects are used to track UnwindPlans for a function - // (named or not - really just an address range) - - // We'll record four different UnwindPlans for each address range: - // - // 1. Unwinding from a call site (a valid exception throw location) - // This is often sourced from the eh_frame exception handling info - // 2. Unwinding from a non-call site (any location in the function) - // This is often done by analyzing the function prologue assembly - // language instructions - // 3. A fast unwind method for this function which only retrieves a - // limited set of registers necessary to walk the stack - // 4. An architectural default unwind plan when none of the above are - // available for some reason. + // FuncUnwinders objects are used to track UnwindPlans for a function + // (named or not - really just an address range) - // Additionally, FuncUnwinds object can be asked where the prologue - // instructions are finished for migrating breakpoints past the - // stack frame setup instructions when we don't have line table information. + // We'll record four different UnwindPlans for each address range: + // + // 1. Unwinding from a call site (a valid exception throw location) + // This is often sourced from the eh_frame exception handling info + // 2. Unwinding from a non-call site (any location in the function) + // This is often done by analyzing the function prologue assembly + // language instructions + // 3. A fast unwind method for this function which only retrieves a + // limited set of registers necessary to walk the stack + // 4. An architectural default unwind plan when none of the above are + // available for some reason. - FuncUnwinders (lldb_private::UnwindTable& unwind_table, AddressRange range); + // Additionally, FuncUnwinds object can be asked where the prologue + // instructions are finished for migrating breakpoints past the + // stack frame setup instructions when we don't have line table information. - ~FuncUnwinders (); + FuncUnwinders(lldb_private::UnwindTable &unwind_table, AddressRange range); - // current_offset is the byte offset into the function. - // 0 means no instructions have executed yet. -1 means the offset is unknown. - // On architectures where the pc points to the next instruction that will execute, this - // offset value will have already been decremented by 1 to stay within the bounds of the - // correct function body. - lldb::UnwindPlanSP - GetUnwindPlanAtCallSite (Target &target, int current_offset); + ~FuncUnwinders(); - lldb::UnwindPlanSP - GetUnwindPlanAtNonCallSite (Target& target, lldb_private::Thread& thread, int current_offset); + // current_offset is the byte offset into the function. + // 0 means no instructions have executed yet. -1 means the offset is unknown. + // On architectures where the pc points to the next instruction that will + // execute, this + // offset value will have already been decremented by 1 to stay within the + // bounds of the + // correct function body. + lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, + int current_offset); - lldb::UnwindPlanSP - GetUnwindPlanFastUnwind (Target& target, lldb_private::Thread& thread); + lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target, + lldb_private::Thread &thread, + int current_offset); - lldb::UnwindPlanSP - GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread); + lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target, + lldb_private::Thread &thread); - lldb::UnwindPlanSP - GetUnwindPlanArchitectureDefaultAtFunctionEntry (lldb_private::Thread& thread); + lldb::UnwindPlanSP + GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread); - Address& - GetFirstNonPrologueInsn (Target& target); + lldb::UnwindPlanSP + GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread); - const Address& - GetFunctionStartAddress () const; + Address &GetFirstNonPrologueInsn(Target &target); - bool - ContainsAddress (const Address& addr) const - { - return m_range.ContainsFileAddress (addr); - } + const Address &GetFunctionStartAddress() const; - // A function may have a Language Specific Data Area specified -- a block of data in - // the object file which is used in the processing of an exception throw / catch. - // If any of the UnwindPlans have the address of the LSDA region for this function, - // this will return it. - Address - GetLSDAAddress (Target &target); + bool ContainsAddress(const Address &addr) const { + return m_range.ContainsFileAddress(addr); + } - // A function may have a Personality Routine associated with it -- used in the - // processing of throwing an exception. If any of the UnwindPlans have the - // address of the personality routine, this will return it. Read the target-pointer - // at this address to get the personality function address. - Address - GetPersonalityRoutinePtrAddress (Target &target); + // A function may have a Language Specific Data Area specified -- a block of + // data in + // the object file which is used in the processing of an exception throw / + // catch. + // If any of the UnwindPlans have the address of the LSDA region for this + // function, + // this will return it. + Address GetLSDAAddress(Target &target); + // A function may have a Personality Routine associated with it -- used in the + // processing of throwing an exception. If any of the UnwindPlans have the + // address of the personality routine, this will return it. Read the + // target-pointer + // at this address to get the personality function address. + Address GetPersonalityRoutinePtrAddress(Target &target); + // The following methods to retrieve specific unwind plans should rarely be + // used. + // Instead, clients should ask for the *behavior* they are looking for, using + // one + // of the above UnwindPlan retrieval methods. - // The following methods to retrieve specific unwind plans should rarely be used. - // Instead, clients should ask for the *behavior* they are looking for, using one - // of the above UnwindPlan retrieval methods. + lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread, + int current_offset); - lldb::UnwindPlanSP - GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset); + lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target, int current_offset); - lldb::UnwindPlanSP - GetEHFrameUnwindPlan (Target &target, int current_offset); + lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target, + Thread &thread, + int current_offset); - lldb::UnwindPlanSP - GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, int current_offset); + lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target, + int current_offset); - lldb::UnwindPlanSP - GetCompactUnwindUnwindPlan (Target &target, int current_offset); + lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target, int current_offset); - lldb::UnwindPlanSP - GetArmUnwindUnwindPlan (Target &target, int current_offset); + lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread); - lldb::UnwindPlanSP - GetArchDefaultUnwindPlan (Thread &thread); - - lldb::UnwindPlanSP - GetArchDefaultAtFuncEntryUnwindPlan (Thread &thread); + lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread); private: - - lldb::UnwindAssemblySP - GetUnwindAssemblyProfiler (Target& target); - - // Do a simplistic comparison for the register restore rule for getting - // the caller's pc value on two UnwindPlans -- returns LazyBoolYes if - // they have the same unwind rule for the pc, LazyBoolNo if they do not - // have the same unwind rule for the pc, and LazyBoolCalculate if it was - // unable to determine this for some reason. - lldb_private::LazyBool - CompareUnwindPlansForIdenticalInitialPCLocation (Thread& thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b); - - UnwindTable& m_unwind_table; - AddressRange m_range; - - std::recursive_mutex m_mutex; - - lldb::UnwindPlanSP m_unwind_plan_assembly_sp; - lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; - lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp; // augmented by assembly inspection so it's valid everywhere - std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind; - lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp; - lldb::UnwindPlanSP m_unwind_plan_fast_sp; - lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; - lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp; - - // Fetching the UnwindPlans can be expensive - if we've already attempted - // to get one & failed, don't try again. - bool m_tried_unwind_plan_assembly:1, - m_tried_unwind_plan_eh_frame:1, - m_tried_unwind_plan_eh_frame_augmented:1, - m_tried_unwind_plan_compact_unwind:1, - m_tried_unwind_plan_arm_unwind:1, - m_tried_unwind_fast:1, - m_tried_unwind_arch_default:1, - m_tried_unwind_arch_default_at_func_entry:1; - - Address m_first_non_prologue_insn; - - DISALLOW_COPY_AND_ASSIGN (FuncUnwinders); + lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target); + + // Do a simplistic comparison for the register restore rule for getting + // the caller's pc value on two UnwindPlans -- returns LazyBoolYes if + // they have the same unwind rule for the pc, LazyBoolNo if they do not + // have the same unwind rule for the pc, and LazyBoolCalculate if it was + // unable to determine this for some reason. + lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation( + Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b); + + UnwindTable &m_unwind_table; + AddressRange m_range; + + std::recursive_mutex m_mutex; + + lldb::UnwindPlanSP m_unwind_plan_assembly_sp; + lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; + lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp; // augmented by + // assembly inspection + // so it's valid + // everywhere + std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind; + lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp; + lldb::UnwindPlanSP m_unwind_plan_fast_sp; + lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; + lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp; + + // Fetching the UnwindPlans can be expensive - if we've already attempted + // to get one & failed, don't try again. + bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1, + m_tried_unwind_plan_eh_frame_augmented : 1, + m_tried_unwind_plan_compact_unwind : 1, + m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_fast : 1, + m_tried_unwind_arch_default : 1, + m_tried_unwind_arch_default_at_func_entry : 1; + + Address m_first_non_prologue_insn; + + DISALLOW_COPY_AND_ASSIGN(FuncUnwinders); }; // class FuncUnwinders } // namespace lldb_private - -#endif //liblldb_FuncUnwinders_h +#endif // liblldb_FuncUnwinders_h diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index 9892d620ce47..232d0790f492 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -11,11 +11,11 @@ #define liblldb_Function_h_ #include "lldb/Core/AddressRange.h" -#include "lldb/Symbol/Block.h" -#include "lldb/Symbol/Declaration.h" -#include "lldb/Expression/DWARFExpression.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/UserID.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Declaration.h" namespace lldb_private { @@ -26,281 +26,268 @@ namespace lldb_private { /// This provides generic function information that gets reused between /// inline functions and function types. //---------------------------------------------------------------------- -class FunctionInfo -{ +class FunctionInfo { public: - //------------------------------------------------------------------ - /// Construct with the function method name and optional declaration - /// information. - /// - /// @param[in] name - /// A C string name for the method name for this function. This - /// value should not be the mangled named, but the simple method - /// name. - /// - /// @param[in] decl_ptr - /// Optional declaration information that describes where the - /// function was declared. This can be NULL. - //------------------------------------------------------------------ - FunctionInfo (const char *name, const Declaration *decl_ptr); - - //------------------------------------------------------------------ - /// Construct with the function method name and optional declaration - /// information. - /// - /// @param[in] name - /// A name for the method name for this function. This value - /// should not be the mangled named, but the simple method name. - /// - /// @param[in] decl_ptr - /// Optional declaration information that describes where the - /// function was declared. This can be NULL. - //------------------------------------------------------------------ - FunctionInfo (const ConstString& name, const Declaration *decl_ptr); - - //------------------------------------------------------------------ - /// Destructor. - /// - /// The destructor is virtual since classes inherit from this class. - //------------------------------------------------------------------ - virtual - ~FunctionInfo (); - - //------------------------------------------------------------------ - /// Compare two function information objects. - /// - /// First compares the method names, and if equal, then compares - /// the declaration information. - /// - /// @param[in] lhs - /// The Left Hand Side const FunctionInfo object reference. - /// - /// @param[in] rhs - /// The Right Hand Side const FunctionInfo object reference. - /// - /// @return - /// @li -1 if lhs < rhs - /// @li 0 if lhs == rhs - /// @li 1 if lhs > rhs - //------------------------------------------------------------------ - static int - Compare (const FunctionInfo& lhs, const FunctionInfo& rhs); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of this object to the - /// supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - void - Dump (Stream *s, bool show_fullpaths) const; - - //------------------------------------------------------------------ - /// Get accessor for the declaration information. - /// - /// @return - /// A reference to the declaration object. - //------------------------------------------------------------------ - Declaration& - GetDeclaration (); - - //------------------------------------------------------------------ - /// Get const accessor for the declaration information. - /// - /// @return - /// A const reference to the declaration object. - //------------------------------------------------------------------ - const Declaration& - GetDeclaration () const; - - //------------------------------------------------------------------ - /// Get accessor for the method name. - /// - /// @return - /// A const reference to the method name object. - //------------------------------------------------------------------ - ConstString - GetName () const; - - //------------------------------------------------------------------ - /// Get the memory cost of this object. - /// - /// @return - /// The number of bytes that this object occupies in memory. - /// The returned value does not include the bytes for any - /// shared string values. - /// - /// @see ConstString::StaticMemorySize () - //------------------------------------------------------------------ - virtual size_t - MemorySize () const; + //------------------------------------------------------------------ + /// Construct with the function method name and optional declaration + /// information. + /// + /// @param[in] name + /// A C string name for the method name for this function. This + /// value should not be the mangled named, but the simple method + /// name. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + //------------------------------------------------------------------ + FunctionInfo(const char *name, const Declaration *decl_ptr); + + //------------------------------------------------------------------ + /// Construct with the function method name and optional declaration + /// information. + /// + /// @param[in] name + /// A name for the method name for this function. This value + /// should not be the mangled named, but the simple method name. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + //------------------------------------------------------------------ + FunctionInfo(const ConstString &name, const Declaration *decl_ptr); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since classes inherit from this class. + //------------------------------------------------------------------ + virtual ~FunctionInfo(); + + //------------------------------------------------------------------ + /// Compare two function information objects. + /// + /// First compares the method names, and if equal, then compares + /// the declaration information. + /// + /// @param[in] lhs + /// The Left Hand Side const FunctionInfo object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const FunctionInfo object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int Compare(const FunctionInfo &lhs, const FunctionInfo &rhs); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + void Dump(Stream *s, bool show_fullpaths) const; + + //------------------------------------------------------------------ + /// Get accessor for the declaration information. + /// + /// @return + /// A reference to the declaration object. + //------------------------------------------------------------------ + Declaration &GetDeclaration(); + + //------------------------------------------------------------------ + /// Get const accessor for the declaration information. + /// + /// @return + /// A const reference to the declaration object. + //------------------------------------------------------------------ + const Declaration &GetDeclaration() const; + + //------------------------------------------------------------------ + /// Get accessor for the method name. + /// + /// @return + /// A const reference to the method name object. + //------------------------------------------------------------------ + ConstString GetName() const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + virtual size_t MemorySize() const; protected: - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - ConstString m_name; ///< Function method name (not a mangled name). - Declaration m_declaration; ///< Information describing where this function information was defined. + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + ConstString m_name; ///< Function method name (not a mangled name). + Declaration m_declaration; ///< Information describing where this function + ///information was defined. }; //---------------------------------------------------------------------- /// @class InlineFunctionInfo Function.h "lldb/Symbol/Function.h" /// @brief A class that describes information for an inlined function. //---------------------------------------------------------------------- -class InlineFunctionInfo : public FunctionInfo -{ +class InlineFunctionInfo : public FunctionInfo { public: - //------------------------------------------------------------------ - /// Construct with the function method name, mangled name, and - /// optional declaration information. - /// - /// @param[in] name - /// A C string name for the method name for this function. This - /// value should not be the mangled named, but the simple method - /// name. - /// - /// @param[in] mangled - /// A C string name for the mangled name for this function. This - /// value can be NULL if there is no mangled information. - /// - /// @param[in] decl_ptr - /// Optional declaration information that describes where the - /// function was declared. This can be NULL. - /// - /// @param[in] call_decl_ptr - /// Optional calling location declaration information that - /// describes from where this inlined function was called. - //------------------------------------------------------------------ - InlineFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); - - //------------------------------------------------------------------ - /// Construct with the function method name, mangled name, and - /// optional declaration information. - /// - /// @param[in] name - /// A name for the method name for this function. This value - /// should not be the mangled named, but the simple method name. - /// - /// @param[in] mangled - /// A name for the mangled name for this function. This value - /// can be empty if there is no mangled information. - /// - /// @param[in] decl_ptr - /// Optional declaration information that describes where the - /// function was declared. This can be NULL. - /// - /// @param[in] call_decl_ptr - /// Optional calling location declaration information that - /// describes from where this inlined function was called. - //------------------------------------------------------------------ - InlineFunctionInfo(const ConstString& name, const Mangled &mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); - - //------------------------------------------------------------------ - /// Destructor. - //------------------------------------------------------------------ - ~InlineFunctionInfo() override; - - //------------------------------------------------------------------ - /// Compare two inlined function information objects. - /// - /// First compares the FunctionInfo objects, and if equal, - /// compares the mangled names. - /// - /// @param[in] lhs - /// The Left Hand Side const InlineFunctionInfo object - /// reference. - /// - /// @param[in] rhs - /// The Right Hand Side const InlineFunctionInfo object - /// reference. - /// - /// @return - /// @li -1 if lhs < rhs - /// @li 0 if lhs == rhs - /// @li 1 if lhs > rhs - //------------------------------------------------------------------ - int - Compare(const InlineFunctionInfo& lhs, const InlineFunctionInfo& rhs); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of this object to the - /// supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - void - Dump(Stream *s, bool show_fullpaths) const; - - void - DumpStopContext (Stream *s, lldb::LanguageType language) const; - - ConstString - GetName (lldb::LanguageType language) const; - - ConstString - GetDisplayName (lldb::LanguageType language) const; - - //------------------------------------------------------------------ - /// Get accessor for the call site declaration information. - /// - /// @return - /// A reference to the declaration object. - //------------------------------------------------------------------ - Declaration& - GetCallSite (); - - //------------------------------------------------------------------ - /// Get const accessor for the call site declaration information. - /// - /// @return - /// A const reference to the declaration object. - //------------------------------------------------------------------ - const Declaration& - GetCallSite () const; - - //------------------------------------------------------------------ - /// Get accessor for the mangled name object. - /// - /// @return - /// A reference to the mangled name object. - //------------------------------------------------------------------ - Mangled& - GetMangled(); - - //------------------------------------------------------------------ - /// Get const accessor for the mangled name object. - /// - /// @return - /// A const reference to the mangled name object. - //------------------------------------------------------------------ - const Mangled& - GetMangled() const; - - //------------------------------------------------------------------ - /// Get the memory cost of this object. - /// - /// @return - /// The number of bytes that this object occupies in memory. - /// The returned value does not include the bytes for any - /// shared string values. - /// - /// @see ConstString::StaticMemorySize () - //------------------------------------------------------------------ - size_t - MemorySize() const override; + //------------------------------------------------------------------ + /// Construct with the function method name, mangled name, and + /// optional declaration information. + /// + /// @param[in] name + /// A C string name for the method name for this function. This + /// value should not be the mangled named, but the simple method + /// name. + /// + /// @param[in] mangled + /// A C string name for the mangled name for this function. This + /// value can be NULL if there is no mangled information. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + //------------------------------------------------------------------ + InlineFunctionInfo(const char *name, const char *mangled, + const Declaration *decl_ptr, + const Declaration *call_decl_ptr); + + //------------------------------------------------------------------ + /// Construct with the function method name, mangled name, and + /// optional declaration information. + /// + /// @param[in] name + /// A name for the method name for this function. This value + /// should not be the mangled named, but the simple method name. + /// + /// @param[in] mangled + /// A name for the mangled name for this function. This value + /// can be empty if there is no mangled information. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + //------------------------------------------------------------------ + InlineFunctionInfo(const ConstString &name, const Mangled &mangled, + const Declaration *decl_ptr, + const Declaration *call_decl_ptr); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~InlineFunctionInfo() override; + + //------------------------------------------------------------------ + /// Compare two inlined function information objects. + /// + /// First compares the FunctionInfo objects, and if equal, + /// compares the mangled names. + /// + /// @param[in] lhs + /// The Left Hand Side const InlineFunctionInfo object + /// reference. + /// + /// @param[in] rhs + /// The Right Hand Side const InlineFunctionInfo object + /// reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + int Compare(const InlineFunctionInfo &lhs, const InlineFunctionInfo &rhs); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + void Dump(Stream *s, bool show_fullpaths) const; + + void DumpStopContext(Stream *s, lldb::LanguageType language) const; + + ConstString GetName(lldb::LanguageType language) const; + + ConstString GetDisplayName(lldb::LanguageType language) const; + + //------------------------------------------------------------------ + /// Get accessor for the call site declaration information. + /// + /// @return + /// A reference to the declaration object. + //------------------------------------------------------------------ + Declaration &GetCallSite(); + + //------------------------------------------------------------------ + /// Get const accessor for the call site declaration information. + /// + /// @return + /// A const reference to the declaration object. + //------------------------------------------------------------------ + const Declaration &GetCallSite() const; + + //------------------------------------------------------------------ + /// Get accessor for the mangled name object. + /// + /// @return + /// A reference to the mangled name object. + //------------------------------------------------------------------ + Mangled &GetMangled(); + + //------------------------------------------------------------------ + /// Get const accessor for the mangled name object. + /// + /// @return + /// A const reference to the mangled name object. + //------------------------------------------------------------------ + const Mangled &GetMangled() const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t MemorySize() const override; private: - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - Mangled m_mangled; ///< Mangled inlined function name (can be empty if there is no mangled information). - Declaration m_call_decl; + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + Mangled m_mangled; ///< Mangled inlined function name (can be empty if there + ///is no mangled information). + Declaration m_call_decl; }; //---------------------------------------------------------------------- @@ -327,369 +314,321 @@ private: /// The concrete information is the address range information and /// specific locations for an instance of this function. //---------------------------------------------------------------------- -class Function : - public UserID, - public SymbolContextScope -{ +class Function : public UserID, public SymbolContextScope { public: - //------------------------------------------------------------------ - /// Construct with a compile unit, function UID, function type UID, - /// optional mangled name, function type, and a section offset - /// based address range. - /// - /// @param[in] comp_unit - /// The compile unit to which this function belongs. - /// - /// @param[in] func_uid - /// The UID for this function. This value is provided by the - /// SymbolFile plug-in and can be any value that allows - /// the plug-in to quickly find and parse more detailed - /// information when and if more information is needed. - /// - /// @param[in] func_type_uid - /// The type UID for the function Type to allow for lazy type - /// parsing from the debug information. - /// - /// @param[in] mangled - /// The optional mangled name for this function. If empty, there - /// is no mangled information. - /// - /// @param[in] func_type - /// The optional function type. If NULL, the function type will - /// be parsed on demand when accessed using the - /// Function::GetType() function by asking the SymbolFile - /// plug-in to get the type for \a func_type_uid. - /// - /// @param[in] range - /// The section offset based address for this function. - //------------------------------------------------------------------ - Function ( - CompileUnit *comp_unit, - lldb::user_id_t func_uid, - lldb::user_id_t func_type_uid, - const Mangled &mangled, - Type * func_type, - const AddressRange& range); - - //------------------------------------------------------------------ - /// Construct with a compile unit, function UID, function type UID, - /// optional mangled name, function type, and a section offset - /// based address range. - /// - /// @param[in] comp_unit - /// The compile unit to which this function belongs. - /// - /// @param[in] func_uid - /// The UID for this function. This value is provided by the - /// SymbolFile plug-in and can be any value that allows - /// the plug-in to quickly find and parse more detailed - /// information when and if more information is needed. - /// - /// @param[in] func_type_uid - /// The type UID for the function Type to allow for lazy type - /// parsing from the debug information. - /// - /// @param[in] mangled - /// The optional mangled name for this function. If empty, there - /// is no mangled information. - /// - /// @param[in] func_type - /// The optional function type. If NULL, the function type will - /// be parsed on demand when accessed using the - /// Function::GetType() function by asking the SymbolFile - /// plug-in to get the type for \a func_type_uid. - /// - /// @param[in] range - /// The section offset based address for this function. - //------------------------------------------------------------------ - Function ( - CompileUnit *comp_unit, - lldb::user_id_t func_uid, - lldb::user_id_t func_type_uid, - const char *mangled, - Type * func_type, - const AddressRange& range); - - //------------------------------------------------------------------ - /// Destructor. - //------------------------------------------------------------------ - ~Function() override; - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - CalculateSymbolContext(SymbolContext* sc) override; - - lldb::ModuleSP - CalculateSymbolContextModule() override; - - CompileUnit * - CalculateSymbolContextCompileUnit() override; - - Function * - CalculateSymbolContextFunction() override; - - const AddressRange & - GetAddressRange() - { - return m_range; - } - - lldb::LanguageType - GetLanguage() const; - //------------------------------------------------------------------ - /// Find the file and line number of the source location of the start - /// of the function. This will use the declaration if present and fall - /// back on the line table if that fails. So there may NOT be a line - /// table entry for this source file/line combo. - /// - /// @param[out] source_file - /// The source file. - /// - /// @param[out] line_no - /// The line number. - //------------------------------------------------------------------ - void - GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no); - - //------------------------------------------------------------------ - /// Find the file and line number of the source location of the end - /// of the function. - /// - /// - /// @param[out] source_file - /// The source file. - /// - /// @param[out] line_no - /// The line number. - //------------------------------------------------------------------ - void - GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no); - - //------------------------------------------------------------------ - /// Get accessor for the block list. - /// - /// @return - /// The block list object that describes all lexical blocks - /// in the function. - /// - /// @see BlockList - //------------------------------------------------------------------ - Block& - GetBlock (bool can_create); - - //------------------------------------------------------------------ - /// Get accessor for the compile unit that owns this function. - /// - /// @return - /// A compile unit object pointer. - //------------------------------------------------------------------ - CompileUnit* - GetCompileUnit(); - - //------------------------------------------------------------------ - /// Get const accessor for the compile unit that owns this function. - /// - /// @return - /// A const compile unit object pointer. - //------------------------------------------------------------------ - const CompileUnit* - GetCompileUnit() const; - - void - GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target); - - //------------------------------------------------------------------ - /// Get accessor for the frame base location. - /// - /// @return - /// A location expression that describes the function frame - /// base. - //------------------------------------------------------------------ - DWARFExpression & - GetFrameBaseExpression() - { - return m_frame_base; - } - - //------------------------------------------------------------------ - /// Get const accessor for the frame base location. - /// - /// @return - /// A const compile unit object pointer. - //------------------------------------------------------------------ - const DWARFExpression & - GetFrameBaseExpression() const - { - return m_frame_base; - } - - ConstString - GetName() const; - - ConstString - GetNameNoArguments () const; - - ConstString - GetDisplayName () const; - - const Mangled & - GetMangled() const - { - return m_mangled; - } - - //------------------------------------------------------------------ - /// Get the DeclContext for this function, if available. - /// - /// @return - /// The DeclContext, or NULL if none exists. - //------------------------------------------------------------------ - CompilerDeclContext - GetDeclContext(); - - //------------------------------------------------------------------ - /// Get accessor for the type that describes the function - /// return value type, and parameter types. - /// - /// @return - /// A type object pointer. - //------------------------------------------------------------------ - Type* - GetType(); - - //------------------------------------------------------------------ - /// Get const accessor for the type that describes the function - /// return value type, and parameter types. - /// - /// @return - /// A const type object pointer. - //------------------------------------------------------------------ - const Type* - GetType() const; - - CompilerType - GetCompilerType (); - - //------------------------------------------------------------------ - /// Get the size of the prologue instructions for this function. The "prologue" - /// instructions include any instructions given line number 0 immediately following - /// the prologue end. - /// - /// @return - /// The size of the prologue. - //------------------------------------------------------------------ - uint32_t - GetPrologueByteSize (); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of this object to the - /// supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] show_context - /// If \b true, variables will dump their symbol context - /// information. - //------------------------------------------------------------------ - void - Dump(Stream *s, bool show_context) const; - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - DumpSymbolContext(Stream *s) override; - - //------------------------------------------------------------------ - /// Get the memory cost of this object. - /// - /// @return - /// The number of bytes that this object occupies in memory. - /// The returned value does not include the bytes for any - /// shared string values. - /// - /// @see ConstString::StaticMemorySize () - //------------------------------------------------------------------ - size_t - MemorySize () const; - - //------------------------------------------------------------------ - /// Get whether compiler optimizations were enabled for this function - /// - /// The debug information may provide information about whether this - /// function was compiled with optimization or not. In this case, - /// "optimized" means that the debug experience may be difficult - /// for the user to understand. Variables may not be available when - /// the developer would expect them, stepping through the source lines - /// in the function may appear strange, etc. - /// - /// @return - /// Returns 'true' if this function was compiled with - /// optimization. 'false' indicates that either the optimization - /// is unknown, or this function was built without optimization. - //------------------------------------------------------------------ - bool - GetIsOptimized (); - - //------------------------------------------------------------------ - /// Get whether this function represents a 'top-level' function - /// - /// The concept of a top-level function is language-specific, mostly - /// meant to represent the notion of scripting-style code that has - /// global visibility of the variables/symbols/functions/... - /// defined within the containing file/module - /// - /// If stopped in a top-level function, LLDB will expose global variables - /// as-if locals in the 'frame variable' command - /// - /// @return - /// Returns 'true' if this function is a top-level function, - /// 'false' otherwise. - //------------------------------------------------------------------ - bool - IsTopLevelFunction (); - - lldb::DisassemblerSP - GetInstructions (const ExecutionContext &exe_ctx, - const char *flavor, - bool prefer_file_cache); - - bool - GetDisassembly (const ExecutionContext &exe_ctx, - const char *flavor, - bool prefer_file_cache, - Stream &strm); + //------------------------------------------------------------------ + /// Construct with a compile unit, function UID, function type UID, + /// optional mangled name, function type, and a section offset + /// based address range. + /// + /// @param[in] comp_unit + /// The compile unit to which this function belongs. + /// + /// @param[in] func_uid + /// The UID for this function. This value is provided by the + /// SymbolFile plug-in and can be any value that allows + /// the plug-in to quickly find and parse more detailed + /// information when and if more information is needed. + /// + /// @param[in] func_type_uid + /// The type UID for the function Type to allow for lazy type + /// parsing from the debug information. + /// + /// @param[in] mangled + /// The optional mangled name for this function. If empty, there + /// is no mangled information. + /// + /// @param[in] func_type + /// The optional function type. If NULL, the function type will + /// be parsed on demand when accessed using the + /// Function::GetType() function by asking the SymbolFile + /// plug-in to get the type for \a func_type_uid. + /// + /// @param[in] range + /// The section offset based address for this function. + //------------------------------------------------------------------ + Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, + lldb::user_id_t func_type_uid, const Mangled &mangled, + Type *func_type, const AddressRange &range); + + //------------------------------------------------------------------ + /// Construct with a compile unit, function UID, function type UID, + /// optional mangled name, function type, and a section offset + /// based address range. + /// + /// @param[in] comp_unit + /// The compile unit to which this function belongs. + /// + /// @param[in] func_uid + /// The UID for this function. This value is provided by the + /// SymbolFile plug-in and can be any value that allows + /// the plug-in to quickly find and parse more detailed + /// information when and if more information is needed. + /// + /// @param[in] func_type_uid + /// The type UID for the function Type to allow for lazy type + /// parsing from the debug information. + /// + /// @param[in] mangled + /// The optional mangled name for this function. If empty, there + /// is no mangled information. + /// + /// @param[in] func_type + /// The optional function type. If NULL, the function type will + /// be parsed on demand when accessed using the + /// Function::GetType() function by asking the SymbolFile + /// plug-in to get the type for \a func_type_uid. + /// + /// @param[in] range + /// The section offset based address for this function. + //------------------------------------------------------------------ + Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, + lldb::user_id_t func_type_uid, const char *mangled, Type *func_type, + const AddressRange &range); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Function() override; + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void CalculateSymbolContext(SymbolContext *sc) override; + + lldb::ModuleSP CalculateSymbolContextModule() override; + + CompileUnit *CalculateSymbolContextCompileUnit() override; + + Function *CalculateSymbolContextFunction() override; + + const AddressRange &GetAddressRange() { return m_range; } + + lldb::LanguageType GetLanguage() const; + //------------------------------------------------------------------ + /// Find the file and line number of the source location of the start + /// of the function. This will use the declaration if present and fall + /// back on the line table if that fails. So there may NOT be a line + /// table entry for this source file/line combo. + /// + /// @param[out] source_file + /// The source file. + /// + /// @param[out] line_no + /// The line number. + //------------------------------------------------------------------ + void GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no); + + //------------------------------------------------------------------ + /// Find the file and line number of the source location of the end + /// of the function. + /// + /// + /// @param[out] source_file + /// The source file. + /// + /// @param[out] line_no + /// The line number. + //------------------------------------------------------------------ + void GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no); + + //------------------------------------------------------------------ + /// Get accessor for the block list. + /// + /// @return + /// The block list object that describes all lexical blocks + /// in the function. + /// + /// @see BlockList + //------------------------------------------------------------------ + Block &GetBlock(bool can_create); + + //------------------------------------------------------------------ + /// Get accessor for the compile unit that owns this function. + /// + /// @return + /// A compile unit object pointer. + //------------------------------------------------------------------ + CompileUnit *GetCompileUnit(); + + //------------------------------------------------------------------ + /// Get const accessor for the compile unit that owns this function. + /// + /// @return + /// A const compile unit object pointer. + //------------------------------------------------------------------ + const CompileUnit *GetCompileUnit() const; + + void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target); + + //------------------------------------------------------------------ + /// Get accessor for the frame base location. + /// + /// @return + /// A location expression that describes the function frame + /// base. + //------------------------------------------------------------------ + DWARFExpression &GetFrameBaseExpression() { return m_frame_base; } + + //------------------------------------------------------------------ + /// Get const accessor for the frame base location. + /// + /// @return + /// A const compile unit object pointer. + //------------------------------------------------------------------ + const DWARFExpression &GetFrameBaseExpression() const { return m_frame_base; } + + ConstString GetName() const; + + ConstString GetNameNoArguments() const; + + ConstString GetDisplayName() const; + + const Mangled &GetMangled() const { return m_mangled; } + + //------------------------------------------------------------------ + /// Get the DeclContext for this function, if available. + /// + /// @return + /// The DeclContext, or NULL if none exists. + //------------------------------------------------------------------ + CompilerDeclContext GetDeclContext(); + + //------------------------------------------------------------------ + /// Get accessor for the type that describes the function + /// return value type, and parameter types. + /// + /// @return + /// A type object pointer. + //------------------------------------------------------------------ + Type *GetType(); + + //------------------------------------------------------------------ + /// Get const accessor for the type that describes the function + /// return value type, and parameter types. + /// + /// @return + /// A const type object pointer. + //------------------------------------------------------------------ + const Type *GetType() const; + + CompilerType GetCompilerType(); + + //------------------------------------------------------------------ + /// Get the size of the prologue instructions for this function. The + /// "prologue" + /// instructions include any instructions given line number 0 immediately + /// following + /// the prologue end. + /// + /// @return + /// The size of the prologue. + //------------------------------------------------------------------ + uint32_t GetPrologueByteSize(); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] show_context + /// If \b true, variables will dump their symbol context + /// information. + //------------------------------------------------------------------ + void Dump(Stream *s, bool show_context) const; + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void DumpSymbolContext(Stream *s) override; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t MemorySize() const; + + //------------------------------------------------------------------ + /// Get whether compiler optimizations were enabled for this function + /// + /// The debug information may provide information about whether this + /// function was compiled with optimization or not. In this case, + /// "optimized" means that the debug experience may be difficult + /// for the user to understand. Variables may not be available when + /// the developer would expect them, stepping through the source lines + /// in the function may appear strange, etc. + /// + /// @return + /// Returns 'true' if this function was compiled with + /// optimization. 'false' indicates that either the optimization + /// is unknown, or this function was built without optimization. + //------------------------------------------------------------------ + bool GetIsOptimized(); + + //------------------------------------------------------------------ + /// Get whether this function represents a 'top-level' function + /// + /// The concept of a top-level function is language-specific, mostly + /// meant to represent the notion of scripting-style code that has + /// global visibility of the variables/symbols/functions/... + /// defined within the containing file/module + /// + /// If stopped in a top-level function, LLDB will expose global variables + /// as-if locals in the 'frame variable' command + /// + /// @return + /// Returns 'true' if this function is a top-level function, + /// 'false' otherwise. + //------------------------------------------------------------------ + bool IsTopLevelFunction(); + + lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, + const char *flavor, + bool prefer_file_cache); + + bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, + bool prefer_file_cache, Stream &strm); protected: - - enum - { - flagsCalculatedPrologueSize = (1 << 0) ///< Have we already tried to calculate the prologue size? - }; - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - CompileUnit *m_comp_unit; ///< The compile unit that owns this function. - lldb::user_id_t m_type_uid; ///< The user ID of for the prototype Type for this function. - Type * m_type; ///< The function prototype type for this function that include the function info (FunctionInfo), return type and parameters. - Mangled m_mangled; ///< The mangled function name if any, if empty, there is no mangled information. - Block m_block; ///< All lexical blocks contained in this function. - AddressRange m_range; ///< The function address range that covers the widest range needed to contain all blocks - DWARFExpression m_frame_base; ///< The frame base expression for variables that are relative to the frame pointer. - Flags m_flags; - uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it + enum { + flagsCalculatedPrologueSize = + (1 << 0) ///< Have we already tried to calculate the prologue size? + }; + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + CompileUnit *m_comp_unit; ///< The compile unit that owns this function. + lldb::user_id_t + m_type_uid; ///< The user ID of for the prototype Type for this function. + Type *m_type; ///< The function prototype type for this function that include + ///the function info (FunctionInfo), return type and parameters. + Mangled m_mangled; ///< The mangled function name if any, if empty, there is + ///no mangled information. + Block m_block; ///< All lexical blocks contained in this function. + AddressRange m_range; ///< The function address range that covers the widest + ///range needed to contain all blocks + DWARFExpression m_frame_base; ///< The frame base expression for variables + ///that are relative to the frame pointer. + Flags m_flags; + uint32_t + m_prologue_byte_size; ///< Compute the prologue size once and cache it private: - DISALLOW_COPY_AND_ASSIGN(Function); + DISALLOW_COPY_AND_ASSIGN(Function); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/GoASTContext.h b/include/lldb/Symbol/GoASTContext.h index ec0203bc3221..5530a35493dc 100644 --- a/include/lldb/Symbol/GoASTContext.h +++ b/include/lldb/Symbol/GoASTContext.h @@ -21,379 +21,408 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ConstString.h" -#include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/TypeSystem.h" -namespace lldb_private -{ +namespace lldb_private { class Declaration; class GoType; -class GoASTContext : public TypeSystem -{ - public: - GoASTContext(); - ~GoASTContext() override; - - //------------------------------------------------------------------ - // PluginInterface functions - //------------------------------------------------------------------ - ConstString - GetPluginName() override; - - uint32_t - GetPluginVersion() override; - - static ConstString - GetPluginNameStatic (); - - static lldb::TypeSystemSP - CreateInstance (lldb::LanguageType language, Module *module, Target *target); - - static void - EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types, std::set<lldb::LanguageType> &languages_for_expressions); - - static void - Initialize (); - - static void - Terminate (); - - DWARFASTParser *GetDWARFParser() override; - - void - SetAddressByteSize(int byte_size) - { - m_pointer_byte_size = byte_size; - } - - //------------------------------------------------------------------ - // llvm casting support - //------------------------------------------------------------------ - static bool classof(const TypeSystem *ts) - { - return ts->getKind() == TypeSystem::eKindGo; - } +class GoASTContext : public TypeSystem { +public: + GoASTContext(); + ~GoASTContext() override; - //---------------------------------------------------------------------- - // CompilerDecl functions - //---------------------------------------------------------------------- - ConstString - DeclGetName (void *opaque_decl) override - { - return ConstString(); - } + //------------------------------------------------------------------ + // PluginInterface functions + //------------------------------------------------------------------ + ConstString GetPluginName() override; - //---------------------------------------------------------------------- - // CompilerDeclContext functions - //---------------------------------------------------------------------- - - bool - DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override - { - return false; - } + uint32_t GetPluginVersion() override; - ConstString - DeclContextGetName(void *opaque_decl_ctx) override - { - return ConstString(); - } + static ConstString GetPluginNameStatic(); - ConstString - DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override - { - return ConstString(); - } + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Module *module, Target *target); - bool - DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override - { - return false; - } + static void EnumerateSupportedLanguages( + std::set<lldb::LanguageType> &languages_for_types, + std::set<lldb::LanguageType> &languages_for_expressions); - //---------------------------------------------------------------------- - // Creating Types - //---------------------------------------------------------------------- + static void Initialize(); - CompilerType CreateArrayType(const ConstString &name, const CompilerType &element_type, uint64_t length); + static void Terminate(); - CompilerType CreateBaseType(int go_kind, const ConstString &type_name_const_str, uint64_t byte_size); + DWARFASTParser *GetDWARFParser() override; - // For interface, map, chan. - CompilerType CreateTypedefType(int kind, const ConstString &name, CompilerType impl); + void SetAddressByteSize(int byte_size) { m_pointer_byte_size = byte_size; } - CompilerType CreateVoidType(const ConstString &name); - CompilerType CreateFunctionType(const lldb_private::ConstString &name, CompilerType *params, size_t params_count, - bool is_variadic); + //------------------------------------------------------------------ + // llvm casting support + //------------------------------------------------------------------ + static bool classof(const TypeSystem *ts) { + return ts->getKind() == TypeSystem::eKindGo; + } - CompilerType CreateStructType(int kind, const ConstString &name, uint32_t byte_size); + //---------------------------------------------------------------------- + // CompilerDecl functions + //---------------------------------------------------------------------- + ConstString DeclGetName(void *opaque_decl) override { return ConstString(); } - void CompleteStructType(const CompilerType &type); + //---------------------------------------------------------------------- + // CompilerDeclContext functions + //---------------------------------------------------------------------- - void AddFieldToStruct(const CompilerType &struct_type, const ConstString &name, const CompilerType &field_type, - uint32_t byte_offset); + bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override { + return false; + } - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- + ConstString DeclContextGetName(void *opaque_decl_ctx) override { + return ConstString(); + } - static bool IsGoString(const CompilerType &type); - static bool IsGoSlice(const CompilerType &type); - static bool IsGoInterface(const CompilerType &type); - static bool IsDirectIface(uint8_t kind); - static bool IsPointerKind(uint8_t kind); + ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override { + return ConstString(); + } - bool IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size, bool *is_incomplete) override; + bool + DeclContextIsClassMethod(void *opaque_decl_ctx, + lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, + ConstString *language_object_name_ptr) override { + return false; + } - bool IsAggregateType(lldb::opaque_compiler_type_t type) override; + //---------------------------------------------------------------------- + // Creating Types + //---------------------------------------------------------------------- - bool IsCharType(lldb::opaque_compiler_type_t type) override; + CompilerType CreateArrayType(const ConstString &name, + const CompilerType &element_type, + uint64_t length); - bool IsCompleteType(lldb::opaque_compiler_type_t type) override; + CompilerType CreateBaseType(int go_kind, + const ConstString &type_name_const_str, + uint64_t byte_size); - bool IsDefined(lldb::opaque_compiler_type_t type) override; + // For interface, map, chan. + CompilerType CreateTypedefType(int kind, const ConstString &name, + CompilerType impl); - bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override; + CompilerType CreateVoidType(const ConstString &name); + CompilerType CreateFunctionType(const lldb_private::ConstString &name, + CompilerType *params, size_t params_count, + bool is_variadic); - bool IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr = nullptr) override; + CompilerType CreateStructType(int kind, const ConstString &name, + uint32_t byte_size); - size_t GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; + void CompleteStructType(const CompilerType &type); - CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override; + void AddFieldToStruct(const CompilerType &struct_type, + const ConstString &name, const CompilerType &field_type, + uint32_t byte_offset); - bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - - bool IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- - bool IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override; + static bool IsGoString(const CompilerType &type); + static bool IsGoSlice(const CompilerType &type); + static bool IsGoInterface(const CompilerType &type); + static bool IsDirectIface(uint8_t kind); + static bool IsPointerKind(uint8_t kind); - bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, // Can pass nullptr - bool check_cplusplus, bool check_objc) override; + bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override; - bool IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override; + bool IsAggregateType(lldb::opaque_compiler_type_t type) override; - bool IsScalarType(lldb::opaque_compiler_type_t type) override; + bool IsCharType(lldb::opaque_compiler_type_t type) override; - bool IsVoidType(lldb::opaque_compiler_type_t type) override; + bool IsCompleteType(lldb::opaque_compiler_type_t type) override; - bool SupportsLanguage (lldb::LanguageType language) override; + bool IsDefined(lldb::opaque_compiler_type_t type) override; - //---------------------------------------------------------------------- - // Type Completion - //---------------------------------------------------------------------- + bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, + bool &is_complex) override; - bool GetCompleteType(lldb::opaque_compiler_type_t type) override; + bool IsFunctionType(lldb::opaque_compiler_type_t type, + bool *is_variadic_ptr = nullptr) override; - //---------------------------------------------------------------------- - // AST related queries - //---------------------------------------------------------------------- + size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; - uint32_t GetPointerByteSize() override; + CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) override; - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- + bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) override; - uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type = nullptr) override; + bool IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) override; - lldb::LanguageType GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, // Can pass nullptr + bool check_cplusplus, bool check_objc) override; - lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; + bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr) override; - //---------------------------------------------------------------------- - // Creating related types - //---------------------------------------------------------------------- + bool IsScalarType(lldb::opaque_compiler_type_t type) override; - CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride = nullptr) override; + bool IsVoidType(lldb::opaque_compiler_type_t type) override; - CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; + bool SupportsLanguage(lldb::LanguageType language) override; - // Returns -1 if this isn't a function of if the function doesn't have a prototype - // Returns a value >= 0 if there is a prototype. - int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; + //---------------------------------------------------------------------- + // Type Completion + //---------------------------------------------------------------------- - CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; + bool GetCompleteType(lldb::opaque_compiler_type_t type) override; - CompilerType GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; + //---------------------------------------------------------------------- + // AST related queries + //---------------------------------------------------------------------- - size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; + uint32_t GetPointerByteSize() override; - TypeMemberFunctionImpl GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- - CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; + ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; - CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; + uint32_t GetTypeInfo( + lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type = nullptr) override; - //---------------------------------------------------------------------- - // Exploring the type - //---------------------------------------------------------------------- + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; - uint64_t GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override; + lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; - lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; + //---------------------------------------------------------------------- + // Creating related types + //---------------------------------------------------------------------- - lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride = nullptr) override; - uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override; + CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; - lldb::BasicType GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; + // Returns -1 if this isn't a function of if the function doesn't have a + // prototype + // Returns a value >= 0 if there is a prototype. + int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; - CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override; + CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; - uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; + CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; - CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) override; + size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; - uint32_t - GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override - { - return 0; - } + TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; - uint32_t - GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override - { - return 0; - } + CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override - { - return CompilerType(); - } + CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override - { - return CompilerType(); - } + //---------------------------------------------------------------------- + // Exploring the type + //---------------------------------------------------------------------- - CompilerType GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, bool &child_is_base_class, - bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags) override; + uint64_t GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override; - // Lookup a child given a name. This function will match base class names - // and member member names in "clang_type" only, not descendants. - uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override; + lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, + uint64_t &count) override; - // Lookup a child member given a name. This function will match member names - // only and will descend into "clang_type" children in search for the first - // member in this class, or any base class that matches "name". - // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>> - // so we catch all names that match a given child name, not just the first. - size_t GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes, - std::vector<uint32_t> &child_indexes) override; + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - size_t - GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override - { - return 0; - } + uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes) override; - CompilerType - GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind) override - { - return CompilerType(); - } + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; - //---------------------------------------------------------------------- - // Dumping types - //---------------------------------------------------------------------- - void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, - const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary, - bool verbose, uint32_t depth) override; + CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) override; - bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override; + uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; - void DumpTypeDescription(lldb::opaque_compiler_type_t type) override; // Dump to stdout + CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) override; - void DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override; + uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override { + return 0; + } - //---------------------------------------------------------------------- - // TODO: These methods appear unused. Should they be removed? - //---------------------------------------------------------------------- + uint32_t + GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override { + return 0; + } - bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override { + return CompilerType(); + } - void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; + CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override { + return CompilerType(); + } - // Converts "s" to a floating point value and place resulting floating - // point bytes in the "dst" buffer. - size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override; + CompilerType GetChildCompilerTypeAtIndex( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags) override; - //---------------------------------------------------------------------- - // TODO: Determine if these methods should move to ClangASTContext. - //---------------------------------------------------------------------- + // Lookup a child given a name. This function will match base class names + // and member member names in "clang_type" only, not descendants. + uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, + const char *name, + bool omit_empty_base_classes) override; - bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; + // Lookup a child member given a name. This function will match member names + // only and will descend into "clang_type" children in search for the first + // member in this class, or any base class that matches "name". + // TODO: Return all matches for a given name by returning a + // vector<vector<uint32_t>> + // so we catch all names that match a given child name, not just the first. + size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, + const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) override; - unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override { + return 0; + } - bool IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override; + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override { + return CompilerType(); + } - size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + //---------------------------------------------------------------------- + // Dumping types + //---------------------------------------------------------------------- + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + bool show_types, bool show_summary, bool verbose, + uint32_t depth) override; - CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; + bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) override; - bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; + void DumpTypeDescription( + lldb::opaque_compiler_type_t type) override; // Dump to stdout - bool IsConst(lldb::opaque_compiler_type_t type) override; + void DumpTypeDescription(lldb::opaque_compiler_type_t type, + Stream *s) override; - uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override; + //---------------------------------------------------------------------- + // TODO: These methods appear unused. Should they be removed? + //---------------------------------------------------------------------- + + bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + + void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size) override; + + // Converts "s" to a floating point value and place resulting floating + // point bytes in the "dst" buffer. + size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, + const char *s, uint8_t *dst, + size_t dst_size) override; + + //---------------------------------------------------------------------- + // TODO: Determine if these methods should move to ClangASTContext. + //---------------------------------------------------------------------- + + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr) override; + + unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + + bool IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) override; + + size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; + + bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; + + bool IsConst(lldb::opaque_compiler_type_t type) override; + + uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) override; + + bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; - bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; + bool IsTypedefType(lldb::opaque_compiler_type_t type) override; + + // If the current object represents a typedef type, get the underlying type + CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; - bool IsTypedefType(lldb::opaque_compiler_type_t type) override; + bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) override; - // If the current object represents a typedef type, get the underlying type - CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; + CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; - bool IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size) override; + CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; - CompilerType GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; + bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr, + bool *is_rvalue = nullptr) override; - CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; +private: + typedef std::map<ConstString, std::unique_ptr<GoType>> TypeMap; + int m_pointer_byte_size; + int m_int_byte_size; + std::unique_ptr<TypeMap> m_types; + std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; - bool IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr, bool *is_rvalue = nullptr) override; - - private: - typedef std::map<ConstString, std::unique_ptr<GoType>> TypeMap; - int m_pointer_byte_size; - int m_int_byte_size; - std::unique_ptr<TypeMap> m_types; - std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; - - GoASTContext(const GoASTContext &) = delete; - const GoASTContext &operator=(const GoASTContext &) = delete; + GoASTContext(const GoASTContext &) = delete; + const GoASTContext &operator=(const GoASTContext &) = delete; }; -class GoASTContextForExpr : public GoASTContext -{ - public: - GoASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {} - UserExpression *GetUserExpression(const char *expr, const char *expr_prefix, lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) override; - - private: - lldb::TargetWP m_target_wp; +class GoASTContextForExpr : public GoASTContext { +public: + GoASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {} + UserExpression * + GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, + lldb::LanguageType language, + Expression::ResultType desired_type, + const EvaluateExpressionOptions &options) override; + +private: + lldb::TargetWP m_target_wp; }; } #endif // liblldb_GoASTContext_h_ diff --git a/include/lldb/Symbol/JavaASTContext.h b/include/lldb/Symbol/JavaASTContext.h index 7d5a37649f6f..6e97674847f4 100644 --- a/include/lldb/Symbol/JavaASTContext.h +++ b/include/lldb/Symbol/JavaASTContext.h @@ -21,365 +21,334 @@ #include "lldb/Core/ConstString.h" #include "lldb/Symbol/TypeSystem.h" -namespace lldb_private -{ +namespace lldb_private { -class JavaASTContext : public TypeSystem -{ +class JavaASTContext : public TypeSystem { public: - class JavaType; - typedef std::map<ConstString, std::unique_ptr<JavaType>> JavaTypeMap; + class JavaType; + typedef std::map<ConstString, std::unique_ptr<JavaType>> JavaTypeMap; - JavaASTContext(const ArchSpec &arch); - ~JavaASTContext() override; + JavaASTContext(const ArchSpec &arch); + ~JavaASTContext() override; - //------------------------------------------------------------------ - // PluginInterface functions - //------------------------------------------------------------------ - ConstString - GetPluginName() override; + //------------------------------------------------------------------ + // PluginInterface functions + //------------------------------------------------------------------ + ConstString GetPluginName() override; - uint32_t - GetPluginVersion() override; + uint32_t GetPluginVersion() override; - static ConstString - GetPluginNameStatic(); + static ConstString GetPluginNameStatic(); - static lldb::TypeSystemSP - CreateInstance(lldb::LanguageType language, Module *module, Target *target); + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Module *module, Target *target); - static void - EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types, - std::set<lldb::LanguageType> &languages_for_expressions); + static void EnumerateSupportedLanguages( + std::set<lldb::LanguageType> &languages_for_types, + std::set<lldb::LanguageType> &languages_for_expressions); - static void - Initialize(); + static void Initialize(); - static void - Terminate(); + static void Terminate(); - DWARFASTParser * - GetDWARFParser() override; + DWARFASTParser *GetDWARFParser() override; - uint32_t - GetPointerByteSize() override; + uint32_t GetPointerByteSize() override; - //---------------------------------------------------------------------- - // CompilerDecl functions - //---------------------------------------------------------------------- - ConstString - DeclGetName(void *opaque_decl) override; + //---------------------------------------------------------------------- + // CompilerDecl functions + //---------------------------------------------------------------------- + ConstString DeclGetName(void *opaque_decl) override; - //---------------------------------------------------------------------- - // CompilerDeclContext functions - //---------------------------------------------------------------------- + //---------------------------------------------------------------------- + // CompilerDeclContext functions + //---------------------------------------------------------------------- - std::vector<CompilerDecl> - DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls) override; + std::vector<CompilerDecl> + DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, + const bool ignore_imported_decls) override; - bool - DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override; + bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override; - ConstString - DeclContextGetName(void *opaque_decl_ctx) override; + ConstString DeclContextGetName(void *opaque_decl_ctx) override; - bool - DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override; + bool DeclContextIsClassMethod(void *opaque_decl_ctx, + lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, + ConstString *language_object_name_ptr) override; - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- - bool - IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size, - bool *is_incomplete) override; + bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override; - bool - IsAggregateType(lldb::opaque_compiler_type_t type) override; + bool IsAggregateType(lldb::opaque_compiler_type_t type) override; - bool - IsCharType(lldb::opaque_compiler_type_t type) override; + bool IsCharType(lldb::opaque_compiler_type_t type) override; - bool - IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override; + bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, + bool &is_complex) override; - bool - IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr = nullptr) override; + bool IsFunctionType(lldb::opaque_compiler_type_t type, + bool *is_variadic_ptr = nullptr) override; - size_t - GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; + size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; - CompilerType - GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override; + CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) override; - bool - IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - - bool - IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; + bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - bool - IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override; + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) override; - bool - IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, bool check_cplusplus, - bool check_objc) override; + bool IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) override; - bool - IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override; + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, bool check_cplusplus, + bool check_objc) override; - bool - IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr, - bool *is_rvalue = nullptr) override; + bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr) override; - bool - IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override; + bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr, + bool *is_rvalue = nullptr) override; - bool - IsScalarType(lldb::opaque_compiler_type_t type) override; + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr) override; - bool - IsVoidType(lldb::opaque_compiler_type_t type) override; + bool IsScalarType(lldb::opaque_compiler_type_t type) override; - bool - IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override; + bool IsVoidType(lldb::opaque_compiler_type_t type) override; - bool - IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + bool IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) override; - bool - IsTypedefType(lldb::opaque_compiler_type_t type) override; + bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; - bool - IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size) override; + bool IsTypedefType(lldb::opaque_compiler_type_t type) override; - bool - IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; + bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) override; - bool - IsCompleteType(lldb::opaque_compiler_type_t type) override; + bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; - bool - IsConst(lldb::opaque_compiler_type_t type) override; + bool IsCompleteType(lldb::opaque_compiler_type_t type) override; - bool - IsBeingDefined(lldb::opaque_compiler_type_t type) override; + bool IsConst(lldb::opaque_compiler_type_t type) override; - bool - IsDefined(lldb::opaque_compiler_type_t type) override; + bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; - uint32_t - IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override; + bool IsDefined(lldb::opaque_compiler_type_t type) override; - bool - SupportsLanguage(lldb::LanguageType language) override; + uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) override; - bool - GetCompleteType(lldb::opaque_compiler_type_t type) override; + bool SupportsLanguage(lldb::LanguageType language) override; - ConstString - GetTypeName(lldb::opaque_compiler_type_t type) override; + bool GetCompleteType(lldb::opaque_compiler_type_t type) override; - uint32_t - GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type = nullptr) override; + ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; - lldb::TypeClass - GetTypeClass(lldb::opaque_compiler_type_t type) override; + uint32_t GetTypeInfo( + lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type = nullptr) override; - lldb::LanguageType - GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; + lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; - CompilerType - GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride = nullptr) override; + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; - CompilerType - GetPointeeType(lldb::opaque_compiler_type_t type) override; + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride = nullptr) override; - CompilerType - GetPointerType(lldb::opaque_compiler_type_t type) override; + CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetCanonicalType(lldb::opaque_compiler_type_t type) override; + CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; + CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetNonReferenceType(lldb::opaque_compiler_type_t type) override; + CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetTypedefedType(lldb::opaque_compiler_type_t type) override; + CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetBasicTypeFromAST(lldb::BasicType basic_type) override; + CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; - CompilerType - GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override; + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; - size_t - GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) override; - lldb::BasicType - GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; + size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; - uint64_t - GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override; + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; - lldb::Encoding - GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; + uint64_t GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override; - lldb::Format - GetFormat(lldb::opaque_compiler_type_t type) override; + lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, + uint64_t &count) override; - unsigned - GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - size_t - GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; + unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; - CompilerType - GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind) override; + size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; - int - GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override; - CompilerType - GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; + int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; - CompilerType - GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; + CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; - size_t - GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; + CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; - TypeMemberFunctionImpl - GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; + size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; - uint32_t - GetNumFields(lldb::opaque_compiler_type_t type) override; + TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; - CompilerType - GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) override; + uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; - uint32_t - GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override; + CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) override; - uint32_t - GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; + uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes) override; - uint32_t - GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; + uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; - CompilerType - GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override; + uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; - CompilerType - GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override; + CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override; - size_t - ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override; + CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override; - void - DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, - const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) override; + size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, + const char *s, uint8_t *dst, + size_t dst_size) override; - bool - DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override; + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + bool show_types, bool show_summary, bool verbose, + uint32_t depth) override; - void - DumpTypeDescription(lldb::opaque_compiler_type_t type) override; + bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) override; - void - DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override; + void DumpTypeDescription(lldb::opaque_compiler_type_t type) override; - void - DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; + void DumpTypeDescription(lldb::opaque_compiler_type_t type, + Stream *s) override; - CompilerType - GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, - std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, - uint64_t &language_flags) override; + void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size) override; - uint32_t - GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override; + CompilerType GetChildCompilerTypeAtIndex( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags) override; - size_t - GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes, - std::vector<uint32_t> &child_indexes) override; + uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, + const char *name, + bool omit_empty_base_classes) override; - CompilerType - GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; + size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, + const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) override; - ConstString - DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx) override; + CompilerType + GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; - CompilerType - CreateBaseType(const ConstString &name); + ConstString DeclContextGetScopeQualifiedName( + lldb::opaque_compiler_type_t opaque_decl_ctx) override; - CompilerType - CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size); + CompilerType CreateBaseType(const ConstString &name); - CompilerType - CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type, - const DWARFExpression &length_expression, const lldb::addr_t data_offset); + CompilerType CreateObjectType(const ConstString &name, + const ConstString &linkage_name, + uint32_t byte_size); - CompilerType - CreateReferenceType(const CompilerType &pointee_type); + CompilerType CreateArrayType(const ConstString &linkage_name, + const CompilerType &element_type, + const DWARFExpression &length_expression, + const lldb::addr_t data_offset); - void - CompleteObjectType(const CompilerType &object_type); + CompilerType CreateReferenceType(const CompilerType &pointee_type); - void - AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type, uint32_t member_offset); + void CompleteObjectType(const CompilerType &object_type); - void - AddMemberToObject(const CompilerType &object_type, const ConstString &name, const CompilerType &member_type, - uint32_t member_offset); + void AddBaseClassToObject(const CompilerType &object_type, + const CompilerType &member_type, + uint32_t member_offset); - void - SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id); + void AddMemberToObject(const CompilerType &object_type, + const ConstString &name, + const CompilerType &member_type, + uint32_t member_offset); - static uint64_t - CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value); + void SetDynamicTypeId(const CompilerType &type, + const DWARFExpression &type_id); - static ConstString - GetLinkageName(const CompilerType &type); + static uint64_t CalculateDynamicTypeId(ExecutionContext *exe_ctx, + const CompilerType &type, + ValueObject &in_value); - static uint32_t - CalculateArraySize(const CompilerType &type, ValueObject &in_value); + static ConstString GetLinkageName(const CompilerType &type); - static uint64_t - CalculateArrayElementOffset(const CompilerType &type, size_t index); + static uint32_t CalculateArraySize(const CompilerType &type, + ValueObject &in_value); - //------------------------------------------------------------------ - // llvm casting support - //------------------------------------------------------------------ - static bool - classof(const TypeSystem *ts) - { - return ts->getKind() == TypeSystem::eKindJava; - } + static uint64_t CalculateArrayElementOffset(const CompilerType &type, + size_t index); + + //------------------------------------------------------------------ + // llvm casting support + //------------------------------------------------------------------ + static bool classof(const TypeSystem *ts) { + return ts->getKind() == TypeSystem::eKindJava; + } private: - uint32_t m_pointer_byte_size; - std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; - JavaTypeMap m_array_type_map; - JavaTypeMap m_base_type_map; - JavaTypeMap m_reference_type_map; - JavaTypeMap m_object_type_map; - - JavaASTContext(const JavaASTContext &) = delete; - const JavaASTContext & - operator=(const JavaASTContext &) = delete; + uint32_t m_pointer_byte_size; + std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; + JavaTypeMap m_array_type_map; + JavaTypeMap m_base_type_map; + JavaTypeMap m_reference_type_map; + JavaTypeMap m_object_type_map; + + JavaASTContext(const JavaASTContext &) = delete; + const JavaASTContext &operator=(const JavaASTContext &) = delete; }; } #endif // liblldb_JavaASTContext_h_ diff --git a/include/lldb/Symbol/LineEntry.h b/include/lldb/Symbol/LineEntry.h index e6a05c10a764..3076ec41d878 100644 --- a/include/lldb/Symbol/LineEntry.h +++ b/include/lldb/Symbol/LineEntry.h @@ -10,9 +10,9 @@ #ifndef liblldb_LineEntry_h_ #define liblldb_LineEntry_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/AddressRange.h" #include "lldb/Host/FileSpec.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -20,176 +20,167 @@ namespace lldb_private { /// @class LineEntry LineEntry.h "lldb/Symbol/LineEntry.h" /// @brief A line table entry class. //---------------------------------------------------------------------- -struct LineEntry -{ - //------------------------------------------------------------------ - /// Default constructor. - /// - /// Initialize all member variables to invalid values. - //------------------------------------------------------------------ - LineEntry (); - - LineEntry - ( - const lldb::SectionSP §ion_sp, - lldb::addr_t section_offset, - lldb::addr_t byte_size, - const FileSpec &file, - uint32_t _line, - uint16_t _column, - bool _is_start_of_statement, - bool _is_start_of_basic_block, - bool _is_prologue_end, - bool _is_epilogue_begin, - bool _is_terminal_entry - ); - - //------------------------------------------------------------------ - /// Clear the object's state. - /// - /// Clears all member variables to invalid values. - //------------------------------------------------------------------ - void - Clear (); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of this object to the - /// supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] comp_unit - /// The compile unit object that contains the support file - /// list so the line entry can dump the file name (since this - /// object contains a file index into the support file list). - /// - /// @param[in] show_file - /// If \b true, display the filename with the line entry which - /// requires that the compile unit object \a comp_unit be a - /// valid pointer. - /// - /// @param[in] style - /// The display style for the section offset address. - /// - /// @return - /// Returns \b true if the address was able to be displayed - /// using \a style. File and load addresses may be unresolved - /// and it may not be possible to display a valid address value. - /// Returns \b false if the address was not able to be properly - /// dumped. - /// - /// @see Address::DumpStyle - //------------------------------------------------------------------ - bool - Dump (Stream *s, Target *target, bool show_file, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_range) const; - - bool - GetDescription (Stream *s, - lldb::DescriptionLevel level, - CompileUnit* cu, - Target *target, - bool show_address_only) const; - - //------------------------------------------------------------------ - /// Dumps information specific to a process that stops at this - /// line entry to the supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] comp_unit - /// The compile unit object that contains the support file - /// list so the line entry can dump the file name (since this - /// object contains a file index into the support file list). - /// - /// @return - /// Returns \b true if the file and line were properly dumped, - /// \b false otherwise. - //------------------------------------------------------------------ - bool - DumpStopContext (Stream *s, bool show_fullpaths) const; - - //------------------------------------------------------------------ - /// Check if a line entry object is valid. - /// - /// @return - /// Returns \b true if the line entry contains a valid section - /// offset address, file index, and line number, \b false - /// otherwise. - //------------------------------------------------------------------ - bool - IsValid () const; - - //------------------------------------------------------------------ - /// Compare two LineEntry objects. - /// - /// @param[in] lhs - /// The Left Hand Side const LineEntry object reference. - /// - /// @param[in] rhs - /// The Right Hand Side const LineEntry object reference. - /// - /// @return - /// @li -1 if lhs < rhs - /// @li 0 if lhs == rhs - /// @li 1 if lhs > rhs - //------------------------------------------------------------------ - static int - Compare (const LineEntry& lhs, const LineEntry& rhs); - - //------------------------------------------------------------------ - /// Give the range for this LineEntry + any additional LineEntries for - /// this same source line that are contiguous. - /// - /// A compiler may emit multiple line entries for a single source line, - /// e.g. to indicate subexpressions at different columns. This method - /// will get the AddressRange for all of the LineEntries for this source - /// line that are contiguous. - // - /// Line entries with a line number of 0 are treated specially - these - /// are compiler-generated line table entries that the user did not - /// write in their source code, and we want to skip past in the debugger. - /// If this LineEntry is for line 32, and the following LineEntry is for - /// line 0, we will extend the range to include the AddressRange of the - /// line 0 LineEntry (and it will include the range of the following - /// LineEntries that match either 32 or 0.) - /// - /// If the initial LineEntry this method is called on is a line #0, only - /// the range of contiuous LineEntries with line #0 will be included in - /// the complete range. - /// - /// @return - /// The contiguous AddressRange for this source line. - //------------------------------------------------------------------ - AddressRange - GetSameLineContiguousAddressRange () const; - - //------------------------------------------------------------------ - /// Apply file mappings from target.source-map to the LineEntry's file. - /// - /// @param[in] target_sp - /// Shared pointer to the target this LineEntry belongs to. - //------------------------------------------------------------------ - - void - ApplyFileMappings(lldb::TargetSP target_sp); - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - AddressRange range; ///< The section offset address range for this line entry. - FileSpec file; ///< The source file, possibly mapped by the target.source-map setting - FileSpec original_file; ///< The original source file, from debug info. - uint32_t line; ///< The source line number, or zero if there is no line number information. - uint16_t column; ///< The column number of the source line, or zero if there is no column information. - uint16_t is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement. - is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block. - is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function. - is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function. - is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions. +struct LineEntry { + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize all member variables to invalid values. + //------------------------------------------------------------------ + LineEntry(); + + LineEntry(const lldb::SectionSP §ion_sp, lldb::addr_t section_offset, + lldb::addr_t byte_size, const FileSpec &file, uint32_t _line, + uint16_t _column, bool _is_start_of_statement, + bool _is_start_of_basic_block, bool _is_prologue_end, + bool _is_epilogue_begin, bool _is_terminal_entry); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Clears all member variables to invalid values. + //------------------------------------------------------------------ + void Clear(); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] comp_unit + /// The compile unit object that contains the support file + /// list so the line entry can dump the file name (since this + /// object contains a file index into the support file list). + /// + /// @param[in] show_file + /// If \b true, display the filename with the line entry which + /// requires that the compile unit object \a comp_unit be a + /// valid pointer. + /// + /// @param[in] style + /// The display style for the section offset address. + /// + /// @return + /// Returns \b true if the address was able to be displayed + /// using \a style. File and load addresses may be unresolved + /// and it may not be possible to display a valid address value. + /// Returns \b false if the address was not able to be properly + /// dumped. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + bool Dump(Stream *s, Target *target, bool show_file, Address::DumpStyle style, + Address::DumpStyle fallback_style, bool show_range) const; + + bool GetDescription(Stream *s, lldb::DescriptionLevel level, CompileUnit *cu, + Target *target, bool show_address_only) const; + + //------------------------------------------------------------------ + /// Dumps information specific to a process that stops at this + /// line entry to the supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] comp_unit + /// The compile unit object that contains the support file + /// list so the line entry can dump the file name (since this + /// object contains a file index into the support file list). + /// + /// @return + /// Returns \b true if the file and line were properly dumped, + /// \b false otherwise. + //------------------------------------------------------------------ + bool DumpStopContext(Stream *s, bool show_fullpaths) const; + + //------------------------------------------------------------------ + /// Check if a line entry object is valid. + /// + /// @return + /// Returns \b true if the line entry contains a valid section + /// offset address, file index, and line number, \b false + /// otherwise. + //------------------------------------------------------------------ + bool IsValid() const; + + //------------------------------------------------------------------ + /// Compare two LineEntry objects. + /// + /// @param[in] lhs + /// The Left Hand Side const LineEntry object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const LineEntry object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int Compare(const LineEntry &lhs, const LineEntry &rhs); + + //------------------------------------------------------------------ + /// Give the range for this LineEntry + any additional LineEntries for + /// this same source line that are contiguous. + /// + /// A compiler may emit multiple line entries for a single source line, + /// e.g. to indicate subexpressions at different columns. This method + /// will get the AddressRange for all of the LineEntries for this source + /// line that are contiguous. + // + /// Line entries with a line number of 0 are treated specially - these + /// are compiler-generated line table entries that the user did not + /// write in their source code, and we want to skip past in the debugger. + /// If this LineEntry is for line 32, and the following LineEntry is for + /// line 0, we will extend the range to include the AddressRange of the + /// line 0 LineEntry (and it will include the range of the following + /// LineEntries that match either 32 or 0.) + /// + /// If the initial LineEntry this method is called on is a line #0, only + /// the range of contiuous LineEntries with line #0 will be included in + /// the complete range. + /// + /// @return + /// The contiguous AddressRange for this source line. + //------------------------------------------------------------------ + AddressRange GetSameLineContiguousAddressRange() const; + + //------------------------------------------------------------------ + /// Apply file mappings from target.source-map to the LineEntry's file. + /// + /// @param[in] target_sp + /// Shared pointer to the target this LineEntry belongs to. + //------------------------------------------------------------------ + + void ApplyFileMappings(lldb::TargetSP target_sp); + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + AddressRange range; ///< The section offset address range for this line entry. + FileSpec file; ///< The source file, possibly mapped by the target.source-map + ///setting + FileSpec original_file; ///< The original source file, from debug info. + uint32_t line; ///< The source line number, or zero if there is no line number + ///information. + uint16_t column; ///< The column number of the source line, or zero if there + ///is no column information. + uint16_t is_start_of_statement : 1, ///< Indicates this entry is the beginning + ///of a statement. + is_start_of_basic_block : 1, ///< Indicates this entry is the beginning of + ///a basic block. + is_prologue_end : 1, ///< Indicates this entry is one (of possibly many) + ///where execution should be suspended for an entry + ///breakpoint of a function. + is_epilogue_begin : 1, ///< Indicates this entry is one (of possibly many) + ///where execution should be suspended for an exit + ///breakpoint of a function. + is_terminal_entry : 1; ///< Indicates this entry is that of the first byte + ///after the end of a sequence of target machine + ///instructions. }; //------------------------------------------------------------------ @@ -204,8 +195,8 @@ struct LineEntry /// @return /// Returns \b true if lhs < rhs, false otherwise. //------------------------------------------------------------------ -bool operator<(const LineEntry& lhs, const LineEntry& rhs); +bool operator<(const LineEntry &lhs, const LineEntry &rhs); } // namespace lldb_private -#endif // liblldb_LineEntry_h_ +#endif // liblldb_LineEntry_h_ diff --git a/include/lldb/Symbol/LineTable.h b/include/lldb/Symbol/LineTable.h index cbad9bf590c2..a55e797f7b16 100644 --- a/include/lldb/Symbol/LineTable.h +++ b/include/lldb/Symbol/LineTable.h @@ -16,11 +16,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" -#include "lldb/Symbol/LineEntry.h" #include "lldb/Core/ModuleChild.h" -#include "lldb/Core/Section.h" #include "lldb/Core/RangeMap.h" +#include "lldb/Core/Section.h" +#include "lldb/Symbol/LineEntry.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -28,392 +28,351 @@ namespace lldb_private { /// @class LineSequence LineTable.h "lldb/Symbol/LineTable.h" /// @brief An abstract base class used during symbol table creation. //---------------------------------------------------------------------- -class LineSequence -{ +class LineSequence { public: - LineSequence (); + LineSequence(); - virtual - ~LineSequence() = default; + virtual ~LineSequence() = default; - virtual void - Clear() = 0; + virtual void Clear() = 0; private: - DISALLOW_COPY_AND_ASSIGN (LineSequence); + DISALLOW_COPY_AND_ASSIGN(LineSequence); }; //---------------------------------------------------------------------- /// @class LineTable LineTable.h "lldb/Symbol/LineTable.h" /// @brief A line table class. //---------------------------------------------------------------------- -class LineTable -{ +class LineTable { public: - //------------------------------------------------------------------ - /// Construct with compile unit. - /// - /// @param[in] comp_unit - /// The compile unit to which this line table belongs. - //------------------------------------------------------------------ - LineTable (CompileUnit* comp_unit); - - //------------------------------------------------------------------ - /// Destructor. - //------------------------------------------------------------------ - ~LineTable (); - - //------------------------------------------------------------------ - /// Adds a new line entry to this line table. - /// - /// All line entries are maintained in file address order. - /// - /// @param[in] line_entry - /// A const reference to a new line_entry to add to this line - /// table. - /// - /// @see Address::DumpStyle - //------------------------------------------------------------------ -// void -// AddLineEntry (const LineEntry& line_entry); - - // Called when you can't guarantee the addresses are in increasing order - void - InsertLineEntry (lldb::addr_t file_addr, - uint32_t line, - uint16_t column, - uint16_t file_idx, - bool is_start_of_statement, - bool is_start_of_basic_block, - bool is_prologue_end, - bool is_epilogue_begin, - bool is_terminal_entry); - - // Used to instantiate the LineSequence helper class - LineSequence* - CreateLineSequenceContainer (); - - // Append an entry to a caller-provided collection that will later be - // inserted in this line table. - void - AppendLineEntryToSequence (LineSequence* sequence, - lldb::addr_t file_addr, - uint32_t line, - uint16_t column, - uint16_t file_idx, - bool is_start_of_statement, - bool is_start_of_basic_block, - bool is_prologue_end, - bool is_epilogue_begin, - bool is_terminal_entry); - - // Insert a sequence of entries into this line table. - void - InsertSequence (LineSequence* sequence); - - //------------------------------------------------------------------ - /// Dump all line entries in this line table to the stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] style - /// The display style for the address. - /// - /// @see Address::DumpStyle - //------------------------------------------------------------------ - void - Dump (Stream *s, Target *target, - Address::DumpStyle style, - Address::DumpStyle fallback_style, - bool show_line_ranges); - - void - GetDescription (Stream *s, - Target *target, - lldb::DescriptionLevel level); - - //------------------------------------------------------------------ - /// Find a line entry that contains the section offset address \a - /// so_addr. - /// - /// @param[in] so_addr - /// A section offset address object containing the address we - /// are searching for. - /// - /// @param[out] line_entry - /// A copy of the line entry that was found if \b true is - /// returned, otherwise \a entry is left unmodified. - /// - /// @param[out] index_ptr - /// A pointer to a 32 bit integer that will get the actual line - /// entry index if it is not nullptr. - /// - /// @return - /// Returns \b true if \a so_addr is contained in a line entry - /// in this line table, \b false otherwise. - //------------------------------------------------------------------ - bool - FindLineEntryByAddress(const Address &so_addr, LineEntry& line_entry, uint32_t *index_ptr = nullptr); - - //------------------------------------------------------------------ - /// Find a line entry index that has a matching file index and - /// source line number. - /// - /// Finds the next line entry that has a matching \a file_idx and - /// source line number \a line starting at the \a start_idx entries - /// into the line entry collection. - /// - /// @param[in] start_idx - /// The number of entries to skip when starting the search. - /// - /// @param[out] file_idx - /// The file index to search for that should be found prior - /// to calling this function using the following functions: - /// CompileUnit::GetSupportFiles() - /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const - /// - /// @param[in] line - /// The source line to match. - /// - /// @param[in] exact - /// If true, match only if you find a line entry exactly matching \a line. - /// If false, return the closest line entry greater than \a line. - /// - /// @param[out] line_entry - /// A reference to a line entry object that will get a copy of - /// the line entry if \b true is returned, otherwise \a - /// line_entry is left untouched. - /// - /// @return - /// Returns \b true if a matching line entry is found in this - /// line table, \b false otherwise. - /// - /// @see CompileUnit::GetSupportFiles() - /// @see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const - //------------------------------------------------------------------ - uint32_t - FindLineEntryIndexByFileIndex (uint32_t start_idx, - uint32_t file_idx, - uint32_t line, - bool exact, - LineEntry* line_entry_ptr); - - uint32_t - FindLineEntryIndexByFileIndex (uint32_t start_idx, - const std::vector<uint32_t> &file_indexes, - uint32_t line, - bool exact, - LineEntry* line_entry_ptr); - - size_t - FineLineEntriesForFileIndex (uint32_t file_idx, - bool append, - SymbolContextList &sc_list); - - //------------------------------------------------------------------ - /// Get the line entry from the line table at index \a idx. - /// - /// @param[in] idx - /// An index into the line table entry collection. - /// - /// @return - /// A valid line entry if \a idx is a valid index, or an invalid - /// line entry if \a idx is not valid. - /// - /// @see LineTable::GetSize() - /// @see LineEntry::IsValid() const - //------------------------------------------------------------------ - bool - GetLineEntryAtIndex(uint32_t idx, LineEntry& line_entry); - - //------------------------------------------------------------------ - /// Gets the size of the line table in number of line table entries. - /// - /// @return - /// The number of line table entries in this line table. - //------------------------------------------------------------------ - uint32_t - GetSize () const; - - typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32> FileAddressRanges; - - //------------------------------------------------------------------ - /// Gets all contiguous file address ranges for the entire line table. - /// - /// @param[out] file_ranges - /// A collection of file address ranges that will be filled in - /// by this function. - /// - /// @param[out] append - /// If \b true, then append to \a file_ranges, otherwise clear - /// \a file_ranges prior to adding any ranges. - /// - /// @return - /// The number of address ranges added to \a file_ranges - //------------------------------------------------------------------ - size_t - GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append); - - //------------------------------------------------------------------ - /// Given a file range link map, relink the current line table - /// and return a fixed up line table. - /// - /// @param[out] file_range_map - /// A collection of file ranges that maps to new file ranges - /// that will be used when linking the line table. - /// - /// @return - /// A new line table if at least one line table entry was able - /// to be mapped. - //------------------------------------------------------------------ - typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap; - - LineTable * - LinkLineTable (const FileRangeMap &file_range_map); + //------------------------------------------------------------------ + /// Construct with compile unit. + /// + /// @param[in] comp_unit + /// The compile unit to which this line table belongs. + //------------------------------------------------------------------ + LineTable(CompileUnit *comp_unit); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~LineTable(); + + //------------------------------------------------------------------ + /// Adds a new line entry to this line table. + /// + /// All line entries are maintained in file address order. + /// + /// @param[in] line_entry + /// A const reference to a new line_entry to add to this line + /// table. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + // void + // AddLineEntry (const LineEntry& line_entry); + + // Called when you can't guarantee the addresses are in increasing order + void InsertLineEntry(lldb::addr_t file_addr, uint32_t line, uint16_t column, + uint16_t file_idx, bool is_start_of_statement, + bool is_start_of_basic_block, bool is_prologue_end, + bool is_epilogue_begin, bool is_terminal_entry); + + // Used to instantiate the LineSequence helper class + LineSequence *CreateLineSequenceContainer(); + + // Append an entry to a caller-provided collection that will later be + // inserted in this line table. + void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr, + uint32_t line, uint16_t column, + uint16_t file_idx, bool is_start_of_statement, + bool is_start_of_basic_block, + bool is_prologue_end, bool is_epilogue_begin, + bool is_terminal_entry); + + // Insert a sequence of entries into this line table. + void InsertSequence(LineSequence *sequence); + + //------------------------------------------------------------------ + /// Dump all line entries in this line table to the stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] style + /// The display style for the address. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + void Dump(Stream *s, Target *target, Address::DumpStyle style, + Address::DumpStyle fallback_style, bool show_line_ranges); + + void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level); + + //------------------------------------------------------------------ + /// Find a line entry that contains the section offset address \a + /// so_addr. + /// + /// @param[in] so_addr + /// A section offset address object containing the address we + /// are searching for. + /// + /// @param[out] line_entry + /// A copy of the line entry that was found if \b true is + /// returned, otherwise \a entry is left unmodified. + /// + /// @param[out] index_ptr + /// A pointer to a 32 bit integer that will get the actual line + /// entry index if it is not nullptr. + /// + /// @return + /// Returns \b true if \a so_addr is contained in a line entry + /// in this line table, \b false otherwise. + //------------------------------------------------------------------ + bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry, + uint32_t *index_ptr = nullptr); + + //------------------------------------------------------------------ + /// Find a line entry index that has a matching file index and + /// source line number. + /// + /// Finds the next line entry that has a matching \a file_idx and + /// source line number \a line starting at the \a start_idx entries + /// into the line entry collection. + /// + /// @param[in] start_idx + /// The number of entries to skip when starting the search. + /// + /// @param[out] file_idx + /// The file index to search for that should be found prior + /// to calling this function using the following functions: + /// CompileUnit::GetSupportFiles() + /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const + /// + /// @param[in] line + /// The source line to match. + /// + /// @param[in] exact + /// If true, match only if you find a line entry exactly matching \a line. + /// If false, return the closest line entry greater than \a line. + /// + /// @param[out] line_entry + /// A reference to a line entry object that will get a copy of + /// the line entry if \b true is returned, otherwise \a + /// line_entry is left untouched. + /// + /// @return + /// Returns \b true if a matching line entry is found in this + /// line table, \b false otherwise. + /// + /// @see CompileUnit::GetSupportFiles() + /// @see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const + //------------------------------------------------------------------ + uint32_t FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, + uint32_t line, bool exact, + LineEntry *line_entry_ptr); + + uint32_t FindLineEntryIndexByFileIndex( + uint32_t start_idx, const std::vector<uint32_t> &file_indexes, + uint32_t line, bool exact, LineEntry *line_entry_ptr); + + size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append, + SymbolContextList &sc_list); + + //------------------------------------------------------------------ + /// Get the line entry from the line table at index \a idx. + /// + /// @param[in] idx + /// An index into the line table entry collection. + /// + /// @return + /// A valid line entry if \a idx is a valid index, or an invalid + /// line entry if \a idx is not valid. + /// + /// @see LineTable::GetSize() + /// @see LineEntry::IsValid() const + //------------------------------------------------------------------ + bool GetLineEntryAtIndex(uint32_t idx, LineEntry &line_entry); + + //------------------------------------------------------------------ + /// Gets the size of the line table in number of line table entries. + /// + /// @return + /// The number of line table entries in this line table. + //------------------------------------------------------------------ + uint32_t GetSize() const; + + typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32> + FileAddressRanges; + + //------------------------------------------------------------------ + /// Gets all contiguous file address ranges for the entire line table. + /// + /// @param[out] file_ranges + /// A collection of file address ranges that will be filled in + /// by this function. + /// + /// @param[out] append + /// If \b true, then append to \a file_ranges, otherwise clear + /// \a file_ranges prior to adding any ranges. + /// + /// @return + /// The number of address ranges added to \a file_ranges + //------------------------------------------------------------------ + size_t GetContiguousFileAddressRanges(FileAddressRanges &file_ranges, + bool append); + + //------------------------------------------------------------------ + /// Given a file range link map, relink the current line table + /// and return a fixed up line table. + /// + /// @param[out] file_range_map + /// A collection of file ranges that maps to new file ranges + /// that will be used when linking the line table. + /// + /// @return + /// A new line table if at least one line table entry was able + /// to be mapped. + //------------------------------------------------------------------ + typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> + FileRangeMap; + + LineTable *LinkLineTable(const FileRangeMap &file_range_map); protected: - struct Entry - { - Entry () : - file_addr (LLDB_INVALID_ADDRESS), - line (0), - column (0), - file_idx (0), - is_start_of_statement (false), - is_start_of_basic_block (false), - is_prologue_end (false), - is_epilogue_begin (false), - is_terminal_entry (false) - { - } - - Entry ( lldb::addr_t _file_addr, - uint32_t _line, - uint16_t _column, - uint16_t _file_idx, - bool _is_start_of_statement, - bool _is_start_of_basic_block, - bool _is_prologue_end, - bool _is_epilogue_begin, - bool _is_terminal_entry) : - file_addr (_file_addr), - line (_line), - column (_column), - file_idx (_file_idx), - is_start_of_statement (_is_start_of_statement), - is_start_of_basic_block (_is_start_of_basic_block), - is_prologue_end (_is_prologue_end), - is_epilogue_begin (_is_epilogue_begin), - is_terminal_entry (_is_terminal_entry) - { - } - - int - bsearch_compare (const void *key, const void *arrmem); - - void - Clear () - { - file_addr = LLDB_INVALID_ADDRESS; - line = 0; - column = 0; - file_idx = 0; - is_start_of_statement = false; - is_start_of_basic_block = false; - is_prologue_end = false; - is_epilogue_begin = false; - is_terminal_entry = false; - } - - static int - Compare (const Entry& lhs, const Entry& rhs) - { - // Compare the sections before calling - #define SCALAR_COMPARE(a,b) if (a < b) return -1; if (a > b) return +1 - SCALAR_COMPARE (lhs.file_addr, rhs.file_addr); - SCALAR_COMPARE (lhs.line, rhs.line); - SCALAR_COMPARE (lhs.column, rhs.column); - SCALAR_COMPARE (lhs.is_start_of_statement, rhs.is_start_of_statement); - SCALAR_COMPARE (lhs.is_start_of_basic_block, rhs.is_start_of_basic_block); - // rhs and lhs reversed on purpose below. - SCALAR_COMPARE (rhs.is_prologue_end, lhs.is_prologue_end); - SCALAR_COMPARE (lhs.is_epilogue_begin, rhs.is_epilogue_begin); - // rhs and lhs reversed on purpose below. - SCALAR_COMPARE (rhs.is_terminal_entry, lhs.is_terminal_entry); - SCALAR_COMPARE (lhs.file_idx, rhs.file_idx); - #undef SCALAR_COMPARE - return 0; - } - - class LessThanBinaryPredicate - { - public: - LessThanBinaryPredicate(LineTable *line_table); - bool operator() (const LineTable::Entry&, const LineTable::Entry&) const; - - protected: - LineTable *m_line_table; - }; - - static bool EntryAddressLessThan (const Entry& lhs, const Entry& rhs) - { - return lhs.file_addr < rhs.file_addr; - } - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - lldb::addr_t file_addr; ///< The file address for this line entry - uint32_t line; ///< The source line number, or zero if there is no line number information. - uint16_t column; ///< The column number of the source line, or zero if there is no column information. - uint16_t file_idx:11, ///< The file index into CompileUnit's file table, or zero if there is no file information. - is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement. - is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block. - is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function. - is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function. - is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions. - }; + struct Entry { + Entry() + : file_addr(LLDB_INVALID_ADDRESS), line(0), column(0), file_idx(0), + is_start_of_statement(false), is_start_of_basic_block(false), + is_prologue_end(false), is_epilogue_begin(false), + is_terminal_entry(false) {} + + Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column, + uint16_t _file_idx, bool _is_start_of_statement, + bool _is_start_of_basic_block, bool _is_prologue_end, + bool _is_epilogue_begin, bool _is_terminal_entry) + : file_addr(_file_addr), line(_line), column(_column), + file_idx(_file_idx), is_start_of_statement(_is_start_of_statement), + is_start_of_basic_block(_is_start_of_basic_block), + is_prologue_end(_is_prologue_end), + is_epilogue_begin(_is_epilogue_begin), + is_terminal_entry(_is_terminal_entry) {} + + int bsearch_compare(const void *key, const void *arrmem); + + void Clear() { + file_addr = LLDB_INVALID_ADDRESS; + line = 0; + column = 0; + file_idx = 0; + is_start_of_statement = false; + is_start_of_basic_block = false; + is_prologue_end = false; + is_epilogue_begin = false; + is_terminal_entry = false; + } + + static int Compare(const Entry &lhs, const Entry &rhs) { +// Compare the sections before calling +#define SCALAR_COMPARE(a, b) \ + if (a < b) \ + return -1; \ + if (a > b) \ + return +1 + SCALAR_COMPARE(lhs.file_addr, rhs.file_addr); + SCALAR_COMPARE(lhs.line, rhs.line); + SCALAR_COMPARE(lhs.column, rhs.column); + SCALAR_COMPARE(lhs.is_start_of_statement, rhs.is_start_of_statement); + SCALAR_COMPARE(lhs.is_start_of_basic_block, rhs.is_start_of_basic_block); + // rhs and lhs reversed on purpose below. + SCALAR_COMPARE(rhs.is_prologue_end, lhs.is_prologue_end); + SCALAR_COMPARE(lhs.is_epilogue_begin, rhs.is_epilogue_begin); + // rhs and lhs reversed on purpose below. + SCALAR_COMPARE(rhs.is_terminal_entry, lhs.is_terminal_entry); + SCALAR_COMPARE(lhs.file_idx, rhs.file_idx); +#undef SCALAR_COMPARE + return 0; + } + + class LessThanBinaryPredicate { + public: + LessThanBinaryPredicate(LineTable *line_table); + bool operator()(const LineTable::Entry &, const LineTable::Entry &) const; - struct EntrySearchInfo - { - LineTable* line_table; - lldb_private::Section *a_section; - Entry *a_entry; + protected: + LineTable *m_line_table; }; - //------------------------------------------------------------------ - // Types - //------------------------------------------------------------------ - typedef std::vector<lldb_private::Section*> section_collection; ///< The collection type for the sections. - typedef std::vector<Entry> entry_collection; ///< The collection type for the line entries. - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to. - entry_collection m_entries; ///< The collection of line entries in this line table. + static bool EntryAddressLessThan(const Entry &lhs, const Entry &rhs) { + return lhs.file_addr < rhs.file_addr; + } //------------------------------------------------------------------ - // Helper class + // Member variables. //------------------------------------------------------------------ - class LineSequenceImpl : public LineSequence - { - public: - LineSequenceImpl() = default; - - ~LineSequenceImpl() override = default; - - void - Clear() override; - - entry_collection m_entries; ///< The collection of line entries in this sequence. - }; - - bool - ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry); + lldb::addr_t file_addr; ///< The file address for this line entry + uint32_t line; ///< The source line number, or zero if there is no line + ///number information. + uint16_t column; ///< The column number of the source line, or zero if there + ///is no column information. + uint16_t file_idx : 11, ///< The file index into CompileUnit's file table, + ///or zero if there is no file information. + is_start_of_statement : 1, ///< Indicates this entry is the beginning of + ///a statement. + is_start_of_basic_block : 1, ///< Indicates this entry is the beginning + ///of a basic block. + is_prologue_end : 1, ///< Indicates this entry is one (of possibly many) + ///where execution should be suspended for an entry + ///breakpoint of a function. + is_epilogue_begin : 1, ///< Indicates this entry is one (of possibly + ///many) where execution should be suspended for + ///an exit breakpoint of a function. + is_terminal_entry : 1; ///< Indicates this entry is that of the first + ///byte after the end of a sequence of target + ///machine instructions. + }; + + struct EntrySearchInfo { + LineTable *line_table; + lldb_private::Section *a_section; + Entry *a_entry; + }; + + //------------------------------------------------------------------ + // Types + //------------------------------------------------------------------ + typedef std::vector<lldb_private::Section *> + section_collection; ///< The collection type for the sections. + typedef std::vector<Entry> + entry_collection; ///< The collection type for the line entries. + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + CompileUnit + *m_comp_unit; ///< The compile unit that this line table belongs to. + entry_collection + m_entries; ///< The collection of line entries in this line table. + + //------------------------------------------------------------------ + // Helper class + //------------------------------------------------------------------ + class LineSequenceImpl : public LineSequence { + public: + LineSequenceImpl() = default; + + ~LineSequenceImpl() override = default; + + void Clear() override; + + entry_collection + m_entries; ///< The collection of line entries in this sequence. + }; + + bool ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry); private: - DISALLOW_COPY_AND_ASSIGN (LineTable); + DISALLOW_COPY_AND_ASSIGN(LineTable); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/OCamlASTContext.h b/include/lldb/Symbol/OCamlASTContext.h new file mode 100644 index 000000000000..9560866d33e6 --- /dev/null +++ b/include/lldb/Symbol/OCamlASTContext.h @@ -0,0 +1,324 @@ +//===-- OCamlASTContext.h ------------------------------------------*- C++ +//-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_OCamlASTContext_h_ +#define liblldb_OCamlASTContext_h_ + +// C Includes +// C++ Includes +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ConstString.h" +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/TypeSystem.h" + +namespace lldb_private { + +class OCamlASTContext : public TypeSystem { +public: + class OCamlType; + typedef std::map<ConstString, std::unique_ptr<OCamlType>> OCamlTypeMap; + + OCamlASTContext(); + ~OCamlASTContext() override; + + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + + static ConstString GetPluginNameStatic(); + + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Module *module, Target *target); + + static void EnumerateSupportedLanguages( + std::set<lldb::LanguageType> &languages_for_types, + std::set<lldb::LanguageType> &languages_for_expressions); + + static void Initialize(); + + static void Terminate(); + + DWARFASTParser *GetDWARFParser() override; + + void SetAddressByteSize(int byte_size) { m_pointer_byte_size = byte_size; } + + static bool classof(const TypeSystem *ts) { + return ts->getKind() == TypeSystem::eKindOCaml; + } + + ConstString DeclGetName(void *opaque_decl) override { return ConstString(); } + + bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override { + return false; + } + + ConstString DeclContextGetName(void *opaque_decl_ctx) override { + return ConstString(); + } + + ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override { + return ConstString(); + } + + bool + DeclContextIsClassMethod(void *opaque_decl_ctx, + lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, + ConstString *language_object_name_ptr) override { + return false; + } + + bool SupportsLanguage(lldb::LanguageType language) override; + uint32_t GetPointerByteSize() override; + + bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override; + + bool IsAggregateType(lldb::opaque_compiler_type_t type) override; + + bool IsCharType(lldb::opaque_compiler_type_t type) override; + + bool IsCompleteType(lldb::opaque_compiler_type_t type) override; + + bool IsDefined(lldb::opaque_compiler_type_t type) override; + + bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, + bool &is_complex) override; + + bool IsFunctionType(lldb::opaque_compiler_type_t type, + bool *is_variadic_ptr = nullptr) override; + + size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; + + CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) override; + + bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; + + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) override; + + bool IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) override; + + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, bool check_cplusplus, + bool check_objc) override; + + bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr) override; + + bool IsScalarType(lldb::opaque_compiler_type_t type) override; + + bool IsVoidType(lldb::opaque_compiler_type_t type) override; + + bool GetCompleteType(lldb::opaque_compiler_type_t type) override; + + ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; + + uint32_t GetTypeInfo( + lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type = nullptr) override; + + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; + + lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; + + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride = nullptr) override; + + CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; + + int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; + + CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; + + CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; + + size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; + + TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override; + + CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; + + uint64_t GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override; + + lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, + uint64_t &count) override; + + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; + + uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes) override; + + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; + + CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) override; + + uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; + + CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) override; + + uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override { + return 0; + } + + uint32_t + GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override { + return 0; + } + + CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override { + return CompilerType(); + } + + CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override { + return CompilerType(); + } + + CompilerType GetChildCompilerTypeAtIndex( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags) override; + + uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, + const char *name, + bool omit_empty_base_classes) override; + + size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, + const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) override; + + size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override { + return 0; + } + + CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx, + lldb::TemplateArgumentKind &kind) override { + return CompilerType(); + } + + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + bool show_types, bool show_summary, bool verbose, + uint32_t depth) override; + + bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) override; + + void DumpTypeDescription(lldb::opaque_compiler_type_t type) override; + + void DumpTypeDescription(lldb::opaque_compiler_type_t type, + Stream *s) override; + + bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + + void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, + Stream *s, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size) override; + + size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, + const char *s, uint8_t *dst, + size_t dst_size) override; + + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr) override; + + unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + + bool IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) override; + + size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; + + bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; + + bool IsConst(lldb::opaque_compiler_type_t type) override; + + uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) override; + + bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; + + bool IsTypedefType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; + + bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) override; + + CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; + + CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; + + bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type = nullptr, + bool *is_rvalue = nullptr) override; + + CompilerType CreateBaseType(const ConstString &name, uint64_t); + +private: + int m_pointer_byte_size; + std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; + OCamlTypeMap m_base_type_map; + + OCamlASTContext(const OCamlASTContext &) = delete; + const OCamlASTContext &operator=(const OCamlASTContext &) = delete; +}; + +class OCamlASTContextForExpr : public OCamlASTContext { +public: + OCamlASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {} + +private: + lldb::TargetWP m_target_wp; +}; +} +#endif // liblldb_OCamlASTContext_h_ diff --git a/include/lldb/Symbol/ObjectContainer.h b/include/lldb/Symbol/ObjectContainer.h index eeda1c4ae19d..6f38b50ba567 100644 --- a/include/lldb/Symbol/ObjectContainer.h +++ b/include/lldb/Symbol/ObjectContainer.h @@ -14,12 +14,12 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/DataExtractor.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Host/Endian.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -34,197 +34,168 @@ namespace lldb_private { /// contain multiple named object files, and universal files that contain /// multiple architectures. //---------------------------------------------------------------------- -class ObjectContainer : - public PluginInterface, - public ModuleChild -{ +class ObjectContainer : public PluginInterface, public ModuleChild { public: - //------------------------------------------------------------------ - /// Construct with a parent module, offset, and header data. - /// - /// Object files belong to modules and a valid module must be - /// supplied upon construction. The at an offset within a file for - /// objects that contain more than one architecture or object. - //------------------------------------------------------------------ - ObjectContainer (const lldb::ModuleSP &module_sp, - const FileSpec *file, - lldb::offset_t file_offset, - lldb::offset_t length, - lldb::DataBufferSP& data_sp, - lldb::offset_t data_offset) : - ModuleChild (module_sp), - m_file (), // This file can be different than the module's file spec - m_offset (file_offset), - m_length (length), - m_data () - { - if (file) - m_file = *file; - if (data_sp) - m_data.SetData (data_sp, data_offset, length); - } - - //------------------------------------------------------------------ - /// Destructor. - /// - /// The destructor is virtual since this class is designed to be - /// inherited from by the plug-in instance. - //------------------------------------------------------------------ - ~ObjectContainer() override = default; - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the current contents of this object - /// to the supplied stream \a s. The dumping should include the - /// section list if it has been parsed, and the symbol table - /// if it has been parsed. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - virtual void - Dump (Stream *s) const = 0; - - //------------------------------------------------------------------ - /// Gets the architecture given an index. - /// - /// Copies the architecture specification for index \a idx. - /// - /// @param[in] idx - /// The architecture index to extract. - /// - /// @param[out] arch - /// A architecture object that will be filled in if \a idx is a - /// architecture valid index. - /// - /// @return - /// Returns \b true if \a idx is valid and \a arch has been - /// filled in, \b false otherwise. - /// - /// @see ObjectContainer::GetNumArchitectures() const - //------------------------------------------------------------------ - virtual bool - GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const - { - return false; - } - - //------------------------------------------------------------------ - /// Returns the offset into a file at which this object resides. - /// - /// Some files contain many object files, and this function allows - /// access to an object's offset within the file. - /// - /// @return - /// The offset in bytes into the file. Defaults to zero for - /// simple object files that a represented by an entire file. - //------------------------------------------------------------------ - virtual lldb::addr_t - GetOffset () const - { return m_offset; } - - virtual lldb::addr_t - GetByteSize () const - { return m_length; } - - //------------------------------------------------------------------ - /// Get the number of objects within this object file (archives). - /// - /// @return - /// Zero for object files that are not archives, or the number - /// of objects contained in the archive. - //------------------------------------------------------------------ - virtual size_t - GetNumObjects () const - { return 0; } - - //------------------------------------------------------------------ - /// Get the number of architectures in this object file. - /// - /// The default implementation returns 1 as for object files that - /// contain a single architecture. ObjectContainer instances that - /// contain more than one architecture should override this function - /// and return an appropriate value. - /// - /// @return - /// The number of architectures contained in this object file. - //------------------------------------------------------------------ - virtual size_t - GetNumArchitectures () const - { return 0; } - - //------------------------------------------------------------------ - /// Attempts to parse the object header. - /// - /// This function is used as a test to see if a given plug-in - /// instance can parse the header data already contained in - /// ObjectContainer::m_data. If an object file parser does not - /// recognize that magic bytes in a header, false should be returned - /// and the next plug-in can attempt to parse an object file. - /// - /// @return - /// Returns \b true if the header was parsed successfully, \b - /// false otherwise. - //------------------------------------------------------------------ - virtual bool - ParseHeader () = 0; - - //------------------------------------------------------------------ - /// Selects an architecture in an object file. - /// - /// Object files that contain a single architecture should verify - /// that the specified \a arch matches the architecture in in - /// object file and return \b true or \b false accordingly. - /// - /// Object files that contain more than one architecture should - /// attempt to select that architecture, and if successful, clear - /// out any previous state from any previously selected architecture - /// and prepare to return information for the new architecture. - /// - /// @return - /// Returns a pointer to the object file of the requested \a - /// arch and optional \a name. Returns nullptr of no such object - /// file exists in the container. - //------------------------------------------------------------------ - virtual lldb::ObjectFileSP - GetObjectFile (const FileSpec *file) = 0; - - virtual bool - ObjectAtIndexIsContainer (uint32_t object_idx) - { - return false; - } - - virtual ObjectFile * - GetObjectFileAtIndex (uint32_t object_idx) - { - return nullptr; - } - - virtual ObjectContainer * - GetObjectContainerAtIndex (uint32_t object_idx) - { - return nullptr; - } - - virtual const char * - GetObjectNameAtIndex (uint32_t object_idx) const - { - return nullptr; - } + //------------------------------------------------------------------ + /// Construct with a parent module, offset, and header data. + /// + /// Object files belong to modules and a valid module must be + /// supplied upon construction. The at an offset within a file for + /// objects that contain more than one architecture or object. + //------------------------------------------------------------------ + ObjectContainer(const lldb::ModuleSP &module_sp, const FileSpec *file, + lldb::offset_t file_offset, lldb::offset_t length, + lldb::DataBufferSP &data_sp, lldb::offset_t data_offset) + : ModuleChild(module_sp), + m_file(), // This file can be different than the module's file spec + m_offset(file_offset), m_length(length), m_data() { + if (file) + m_file = *file; + if (data_sp) + m_data.SetData(data_sp, data_offset, length); + } + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from by the plug-in instance. + //------------------------------------------------------------------ + ~ObjectContainer() override = default; + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the current contents of this object + /// to the supplied stream \a s. The dumping should include the + /// section list if it has been parsed, and the symbol table + /// if it has been parsed. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + virtual void Dump(Stream *s) const = 0; + + //------------------------------------------------------------------ + /// Gets the architecture given an index. + /// + /// Copies the architecture specification for index \a idx. + /// + /// @param[in] idx + /// The architecture index to extract. + /// + /// @param[out] arch + /// A architecture object that will be filled in if \a idx is a + /// architecture valid index. + /// + /// @return + /// Returns \b true if \a idx is valid and \a arch has been + /// filled in, \b false otherwise. + /// + /// @see ObjectContainer::GetNumArchitectures() const + //------------------------------------------------------------------ + virtual bool GetArchitectureAtIndex(uint32_t idx, ArchSpec &arch) const { + return false; + } + + //------------------------------------------------------------------ + /// Returns the offset into a file at which this object resides. + /// + /// Some files contain many object files, and this function allows + /// access to an object's offset within the file. + /// + /// @return + /// The offset in bytes into the file. Defaults to zero for + /// simple object files that a represented by an entire file. + //------------------------------------------------------------------ + virtual lldb::addr_t GetOffset() const { return m_offset; } + + virtual lldb::addr_t GetByteSize() const { return m_length; } + + //------------------------------------------------------------------ + /// Get the number of objects within this object file (archives). + /// + /// @return + /// Zero for object files that are not archives, or the number + /// of objects contained in the archive. + //------------------------------------------------------------------ + virtual size_t GetNumObjects() const { return 0; } + + //------------------------------------------------------------------ + /// Get the number of architectures in this object file. + /// + /// The default implementation returns 1 as for object files that + /// contain a single architecture. ObjectContainer instances that + /// contain more than one architecture should override this function + /// and return an appropriate value. + /// + /// @return + /// The number of architectures contained in this object file. + //------------------------------------------------------------------ + virtual size_t GetNumArchitectures() const { return 0; } + + //------------------------------------------------------------------ + /// Attempts to parse the object header. + /// + /// This function is used as a test to see if a given plug-in + /// instance can parse the header data already contained in + /// ObjectContainer::m_data. If an object file parser does not + /// recognize that magic bytes in a header, false should be returned + /// and the next plug-in can attempt to parse an object file. + /// + /// @return + /// Returns \b true if the header was parsed successfully, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool ParseHeader() = 0; + + //------------------------------------------------------------------ + /// Selects an architecture in an object file. + /// + /// Object files that contain a single architecture should verify + /// that the specified \a arch matches the architecture in in + /// object file and return \b true or \b false accordingly. + /// + /// Object files that contain more than one architecture should + /// attempt to select that architecture, and if successful, clear + /// out any previous state from any previously selected architecture + /// and prepare to return information for the new architecture. + /// + /// @return + /// Returns a pointer to the object file of the requested \a + /// arch and optional \a name. Returns nullptr of no such object + /// file exists in the container. + //------------------------------------------------------------------ + virtual lldb::ObjectFileSP GetObjectFile(const FileSpec *file) = 0; + + virtual bool ObjectAtIndexIsContainer(uint32_t object_idx) { return false; } + + virtual ObjectFile *GetObjectFileAtIndex(uint32_t object_idx) { + return nullptr; + } + + virtual ObjectContainer *GetObjectContainerAtIndex(uint32_t object_idx) { + return nullptr; + } + + virtual const char *GetObjectNameAtIndex(uint32_t object_idx) const { + return nullptr; + } protected: - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - FileSpec m_file; ///< The file that represents this container objects (which can be different from the module's file). - lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory - lldb::addr_t m_length; ///< The size in bytes if known (can be zero). - DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + FileSpec m_file; ///< The file that represents this container objects (which + ///can be different from the module's file). + lldb::addr_t + m_offset; ///< The offset in bytes into the file, or the address in memory + lldb::addr_t m_length; ///< The size in bytes if known (can be zero). + DataExtractor + m_data; ///< The data for this object file so things can be parsed lazily. private: - DISALLOW_COPY_AND_ASSIGN (ObjectContainer); + DISALLOW_COPY_AND_ASSIGN(ObjectContainer); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index 53f0f3c80517..e2e4500ace46 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -10,46 +10,35 @@ #ifndef liblldb_ObjectFile_h_ #define liblldb_ObjectFile_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/DataExtractor.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Core/FileSpecList.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Host/Endian.h" +#include "lldb/Host/FileSpec.h" #include "lldb/Symbol/Symtab.h" #include "lldb/Symbol/UnwindTable.h" +#include "lldb/lldb-private.h" namespace lldb_private { - -class ObjectFileJITDelegate -{ + +class ObjectFileJITDelegate { public: - ObjectFileJITDelegate () - { - } - - virtual - ~ObjectFileJITDelegate() - { - } - - virtual lldb::ByteOrder - GetByteOrder () const = 0; - - virtual uint32_t - GetAddressByteSize () const = 0; - - virtual void - PopulateSymtab (lldb_private::ObjectFile *obj_file, - lldb_private::Symtab &symtab) = 0; - - virtual void - PopulateSectionList (lldb_private::ObjectFile *obj_file, - lldb_private::SectionList §ion_list) = 0; - - virtual bool - GetArchitecture (lldb_private::ArchSpec &arch) = 0; + ObjectFileJITDelegate() {} + + virtual ~ObjectFileJITDelegate() {} + + virtual lldb::ByteOrder GetByteOrder() const = 0; + + virtual uint32_t GetAddressByteSize() const = 0; + + virtual void PopulateSymtab(lldb_private::ObjectFile *obj_file, + lldb_private::Symtab &symtab) = 0; + + virtual void PopulateSectionList(lldb_private::ObjectFile *obj_file, + lldb_private::SectionList §ion_list) = 0; + + virtual bool GetArchitecture(lldb_private::ArchSpec &arch) = 0; }; //---------------------------------------------------------------------- @@ -68,849 +57,764 @@ public: /// Once an architecture is selected the object file information can be /// extracted from this abstract class. //---------------------------------------------------------------------- -class ObjectFile: - public std::enable_shared_from_this<ObjectFile>, - public PluginInterface, - public ModuleChild -{ -friend class lldb_private::Module; +class ObjectFile : public std::enable_shared_from_this<ObjectFile>, + public PluginInterface, + public ModuleChild { + friend class lldb_private::Module; public: - typedef enum - { - eTypeInvalid = 0, - eTypeCoreFile, /// A core file that has a checkpoint of a program's execution state - eTypeExecutable, /// A normal executable - eTypeDebugInfo, /// An object file that contains only debug information - eTypeDynamicLinker, /// The platform's dynamic linker executable - eTypeObjectFile, /// An intermediate object file - eTypeSharedLibrary, /// A shared library that can be used during execution - eTypeStubLibrary, /// A library that can be linked against but not used for execution - eTypeJIT, /// JIT code that has symbols, sections and possibly debug info - eTypeUnknown - } Type; - - typedef enum - { - eStrataInvalid = 0, - eStrataUnknown, - eStrataUser, - eStrataKernel, - eStrataRawImage, - eStrataJIT - } Strata; - - //------------------------------------------------------------------ - /// Construct with a parent module, offset, and header data. - /// - /// Object files belong to modules and a valid module must be - /// supplied upon construction. The at an offset within a file for - /// objects that contain more than one architecture or object. - //------------------------------------------------------------------ - ObjectFile (const lldb::ModuleSP &module_sp, - const FileSpec *file_spec_ptr, - lldb::offset_t file_offset, - lldb::offset_t length, - const lldb::DataBufferSP& data_sp, - lldb::offset_t data_offset); - - ObjectFile (const lldb::ModuleSP &module_sp, - const lldb::ProcessSP &process_sp, - lldb::addr_t header_addr, - lldb::DataBufferSP& data_sp); - - //------------------------------------------------------------------ - /// Destructor. - /// - /// The destructor is virtual since this class is designed to be - /// inherited from by the plug-in instance. - //------------------------------------------------------------------ - ~ObjectFile() override; - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the current contents of this object - /// to the supplied stream \a s. The dumping should include the - /// section list if it has been parsed, and the symbol table - /// if it has been parsed. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - virtual void - Dump (Stream *s) = 0; - - //------------------------------------------------------------------ - /// Find a ObjectFile plug-in that can parse \a file_spec. - /// - /// Scans all loaded plug-in interfaces that implement versions of - /// the ObjectFile plug-in interface and returns the first - /// instance that can parse the file. - /// - /// @param[in] module - /// The parent module that owns this object file. - /// - /// @param[in] file_spec - /// A file specification that indicates which file to use as the - /// object file. - /// - /// @param[in] file_offset - /// The offset into the file at which to start parsing the - /// object. This is for files that contain multiple - /// architectures or objects. - /// - /// @param[in] file_size - /// The size of the current object file if it can be determined - /// or if it is known. This can be zero. - /// - /// @see ObjectFile::ParseHeader() - //------------------------------------------------------------------ - static lldb::ObjectFileSP - FindPlugin (const lldb::ModuleSP &module_sp, - const FileSpec* file_spec, - lldb::offset_t file_offset, - lldb::offset_t file_size, - lldb::DataBufferSP &data_sp, - lldb::offset_t &data_offset); - - //------------------------------------------------------------------ - /// Find a ObjectFile plug-in that can parse a file in memory. - /// - /// Scans all loaded plug-in interfaces that implement versions of - /// the ObjectFile plug-in interface and returns the first - /// instance that can parse the file. - /// - /// @param[in] module - /// The parent module that owns this object file. - /// - /// @param[in] process_sp - /// A shared pointer to the process whose memory space contains - /// an object file. This will be stored as a std::weak_ptr. - /// - /// @param[in] header_addr - /// The address of the header for the object file in memory. - //------------------------------------------------------------------ - static lldb::ObjectFileSP - FindPlugin (const lldb::ModuleSP &module_sp, - const lldb::ProcessSP &process_sp, - lldb::addr_t header_addr, - lldb::DataBufferSP &file_data_sp); - - - static size_t - GetModuleSpecifications (const FileSpec &file, - lldb::offset_t file_offset, - lldb::offset_t file_size, - ModuleSpecList &specs); - - static size_t - GetModuleSpecifications (const lldb_private::FileSpec& file, - lldb::DataBufferSP& data_sp, - lldb::offset_t data_offset, - lldb::offset_t file_offset, - lldb::offset_t file_size, - lldb_private::ModuleSpecList &specs); - //------------------------------------------------------------------ - /// Split a path into a file path with object name. - /// - /// For paths like "/tmp/foo.a(bar.o)" we often need to split a path - /// up into the actual path name and into the object name so we can - /// make a valid object file from it. - /// - /// @param[in] path_with_object - /// A path that might contain an archive path with a .o file - /// specified in parens in the basename of the path. - /// - /// @param[out] archive_file - /// If \b true is returned, \a file_spec will be filled in with - /// the path to the archive. - /// - /// @param[out] archive_object - /// If \b true is returned, \a object will be filled in with - /// the name of the object inside the archive. - /// - /// @return - /// \b true if the path matches the pattern of archive + object - /// and \a archive_file and \a archive_object are modified, - /// \b false otherwise and \a archive_file and \a archive_object - /// are guaranteed to be remain unchanged. - //------------------------------------------------------------------ - static bool - SplitArchivePathWithObject (const char *path_with_object, - lldb_private::FileSpec &archive_file, - lldb_private::ConstString &archive_object, - bool must_exist); - - //------------------------------------------------------------------ - /// Gets the address size in bytes for the current object file. - /// - /// @return - /// The size of an address in bytes for the currently selected - /// architecture (and object for archives). Returns zero if no - /// architecture or object has been selected. - //------------------------------------------------------------------ - virtual uint32_t - GetAddressByteSize () const = 0; - - //------------------------------------------------------------------ - /// Get the address type given a file address in an object file. - /// - /// Many binary file formats know what kinds - /// This is primarily for ARM binaries, though it can be applied to - /// any executable file format that supports different opcode types - /// within the same binary. ARM binaries support having both ARM and - /// Thumb within the same executable container. We need to be able - /// to get - /// @return - /// The size of an address in bytes for the currently selected - /// architecture (and object for archives). Returns zero if no - /// architecture or object has been selected. - //------------------------------------------------------------------ - virtual lldb::AddressClass - GetAddressClass (lldb::addr_t file_addr); - - //------------------------------------------------------------------ - /// Extract the dependent modules from an object file. - /// - /// If an object file has information about which other images it - /// depends on (such as shared libraries), this function will - /// provide the list. Since many executables or shared libraries - /// may depend on the same files, - /// FileSpecList::AppendIfUnique(const FileSpec &) should be - /// used to make sure any files that are added are not already in - /// the list. - /// - /// @param[out] file_list - /// A list of file specification objects that gets dependent - /// files appended to. - /// - /// @return - /// The number of new files that were appended to \a file_list. - /// - /// @see FileSpecList::AppendIfUnique(const FileSpec &) - //------------------------------------------------------------------ - virtual uint32_t - GetDependentModules (FileSpecList& file_list) = 0; - - //------------------------------------------------------------------ - /// Tells whether this object file is capable of being the main executable - /// for a process. - /// - /// @return - /// \b true if it is, \b false otherwise. - //------------------------------------------------------------------ - virtual bool - IsExecutable () const = 0; - - //------------------------------------------------------------------ - /// Returns the offset into a file at which this object resides. - /// - /// Some files contain many object files, and this function allows - /// access to an object's offset within the file. - /// - /// @return - /// The offset in bytes into the file. Defaults to zero for - /// simple object files that a represented by an entire file. - //------------------------------------------------------------------ - virtual lldb::addr_t - GetFileOffset () const - { return m_file_offset; } - - virtual lldb::addr_t - GetByteSize () const - { return m_length; } - - //------------------------------------------------------------------ - /// Get accessor to the object file specification. - /// - /// @return - /// The file specification object pointer if there is one, or - /// NULL if this object is only from memory. - //------------------------------------------------------------------ - virtual FileSpec& - GetFileSpec() { return m_file; } - - //------------------------------------------------------------------ - /// Get const accessor to the object file specification. - /// - /// @return - /// The const file specification object pointer if there is one, - /// or NULL if this object is only from memory. - //------------------------------------------------------------------ - virtual const FileSpec& - GetFileSpec() const { return m_file; } - - //------------------------------------------------------------------ - /// Get the name of the cpu, vendor and OS for this object file. - /// - /// This value is a string that represents the target triple where - /// the cpu type, the vendor and the OS are encoded into a string. - /// - /// @param[out] target_triple - /// The string value of the target triple. - /// - /// @return - /// \b True if the target triple was able to be computed, \b - /// false otherwise. - //------------------------------------------------------------------ - virtual bool - GetArchitecture (ArchSpec &arch) = 0; - - //------------------------------------------------------------------ - /// Gets the section list for the currently selected architecture - /// (and object for archives). - /// - /// Section list parsing can be deferred by ObjectFile instances - /// until this accessor is called the first time. - /// - /// @return - /// The list of sections contained in this object file. - //------------------------------------------------------------------ - virtual SectionList * - GetSectionList (bool update_module_section_list = true); - - virtual void - CreateSections (SectionList &unified_section_list) = 0; - - //------------------------------------------------------------------ - /// Notify the ObjectFile that the file addresses in the Sections - /// for this module have been changed. - //------------------------------------------------------------------ - virtual void - SectionFileAddressesChanged () - { - } - - //------------------------------------------------------------------ - /// Gets the symbol table for the currently selected architecture - /// (and object for archives). - /// - /// Symbol table parsing can be deferred by ObjectFile instances - /// until this accessor is called the first time. - /// - /// @return - /// The symbol table for this object file. - //------------------------------------------------------------------ - virtual Symtab * - GetSymtab () = 0; - - //------------------------------------------------------------------ - /// Appends a Symbol for the specified so_addr to the symbol table. - /// - /// If verify_unique is false, the symbol table is not searched - /// to determine if a Symbol found at this address has already been - /// added to the symbol table. When verify_unique is true, this - /// method resolves the Symbol as the first match in the SymbolTable - /// and appends a Symbol only if required/found. - /// - /// @return - /// The resolved symbol or nullptr. Returns nullptr if a - /// a Symbol could not be found for the specified so_addr. - //------------------------------------------------------------------ - virtual Symbol * - ResolveSymbolForAddress(const Address &so_addr, bool verify_unique) - { - // Typically overridden to lazily add stripped symbols recoverable from - // the exception handling unwind information (i.e. without parsing - // the entire eh_frame section. - // - // The availability of LC_FUNCTION_STARTS allows ObjectFileMachO - // to efficiently add stripped symbols when the symbol table is - // first constructed. Poorer cousins are PECoff and ELF. - return nullptr; - } - - //------------------------------------------------------------------ - /// Detect if this object file has been stripped of local symbols. - //------------------------------------------------------------------ - /// Detect if this object file has been stripped of local symbols. - /// - /// @return - /// Return \b true if the object file has been stripped of local - /// symbols. - //------------------------------------------------------------------ - virtual bool - IsStripped () = 0; - - //------------------------------------------------------------------ - /// Frees the symbol table. - /// - /// This function should only be used when an object file is - /// - /// @param[in] flags - /// eSymtabFromUnifiedSectionList: Whether to clear symbol table - /// for unified module section list, or object file. - /// - /// @return - /// The symbol table for this object file. - //------------------------------------------------------------------ - virtual void - ClearSymtab (); - - //------------------------------------------------------------------ - /// Gets the UUID for this object file. - /// - /// If the object file format contains a UUID, the value should be - /// returned. Else ObjectFile instances should return the MD5 - /// checksum of all of the bytes for the object file (or memory for - /// memory based object files). - /// - /// @return - /// Returns \b true if a UUID was successfully extracted into - /// \a uuid, \b false otherwise. - //------------------------------------------------------------------ - virtual bool - GetUUID (lldb_private::UUID* uuid) = 0; - - //------------------------------------------------------------------ - /// Gets the symbol file spec list for this object file. - /// - /// If the object file format contains a debug symbol file link, - /// the values will be returned in the FileSpecList. - /// - /// @return - /// Returns filespeclist. - //------------------------------------------------------------------ - virtual lldb_private::FileSpecList - GetDebugSymbolFilePaths() - { - return FileSpecList(); - } - - //------------------------------------------------------------------ - /// Gets the file spec list of libraries re-exported by this object file. - /// - /// If the object file format has the notion of one library re-exporting the symbols from another, - /// the re-exported libraries will be returned in the FileSpecList. - /// - /// @return - /// Returns filespeclist. - //------------------------------------------------------------------ - virtual lldb_private::FileSpecList - GetReExportedLibraries () - { - return FileSpecList(); - } - - //------------------------------------------------------------------ - /// Sets the load address for an entire module, assuming a rigid - /// slide of sections, if possible in the implementation. - /// - /// @return - /// Returns true iff any section's load address changed. - //------------------------------------------------------------------ - virtual bool - SetLoadAddress(Target &target, - lldb::addr_t value, - bool value_is_offset) - { - return false; + typedef enum { + eTypeInvalid = 0, + eTypeCoreFile, /// A core file that has a checkpoint of a program's + /// execution state + eTypeExecutable, /// A normal executable + eTypeDebugInfo, /// An object file that contains only debug information + eTypeDynamicLinker, /// The platform's dynamic linker executable + eTypeObjectFile, /// An intermediate object file + eTypeSharedLibrary, /// A shared library that can be used during execution + eTypeStubLibrary, /// A library that can be linked against but not used for + /// execution + eTypeJIT, /// JIT code that has symbols, sections and possibly debug info + eTypeUnknown + } Type; + + typedef enum { + eStrataInvalid = 0, + eStrataUnknown, + eStrataUser, + eStrataKernel, + eStrataRawImage, + eStrataJIT + } Strata; + + //------------------------------------------------------------------ + /// Construct with a parent module, offset, and header data. + /// + /// Object files belong to modules and a valid module must be + /// supplied upon construction. The at an offset within a file for + /// objects that contain more than one architecture or object. + //------------------------------------------------------------------ + ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, + lldb::offset_t file_offset, lldb::offset_t length, + const lldb::DataBufferSP &data_sp, lldb::offset_t data_offset); + + ObjectFile(const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr, lldb::DataBufferSP &data_sp); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from by the plug-in instance. + //------------------------------------------------------------------ + ~ObjectFile() override; + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the current contents of this object + /// to the supplied stream \a s. The dumping should include the + /// section list if it has been parsed, and the symbol table + /// if it has been parsed. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + virtual void Dump(Stream *s) = 0; + + //------------------------------------------------------------------ + /// Find a ObjectFile plug-in that can parse \a file_spec. + /// + /// Scans all loaded plug-in interfaces that implement versions of + /// the ObjectFile plug-in interface and returns the first + /// instance that can parse the file. + /// + /// @param[in] module + /// The parent module that owns this object file. + /// + /// @param[in] file_spec + /// A file specification that indicates which file to use as the + /// object file. + /// + /// @param[in] file_offset + /// The offset into the file at which to start parsing the + /// object. This is for files that contain multiple + /// architectures or objects. + /// + /// @param[in] file_size + /// The size of the current object file if it can be determined + /// or if it is known. This can be zero. + /// + /// @see ObjectFile::ParseHeader() + //------------------------------------------------------------------ + static lldb::ObjectFileSP + FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file_spec, + lldb::offset_t file_offset, lldb::offset_t file_size, + lldb::DataBufferSP &data_sp, lldb::offset_t &data_offset); + + //------------------------------------------------------------------ + /// Find a ObjectFile plug-in that can parse a file in memory. + /// + /// Scans all loaded plug-in interfaces that implement versions of + /// the ObjectFile plug-in interface and returns the first + /// instance that can parse the file. + /// + /// @param[in] module + /// The parent module that owns this object file. + /// + /// @param[in] process_sp + /// A shared pointer to the process whose memory space contains + /// an object file. This will be stored as a std::weak_ptr. + /// + /// @param[in] header_addr + /// The address of the header for the object file in memory. + //------------------------------------------------------------------ + static lldb::ObjectFileSP FindPlugin(const lldb::ModuleSP &module_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr, + lldb::DataBufferSP &file_data_sp); + + static size_t GetModuleSpecifications(const FileSpec &file, + lldb::offset_t file_offset, + lldb::offset_t file_size, + ModuleSpecList &specs); + + static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, + lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, + lldb::offset_t file_offset, + lldb::offset_t file_size, + lldb_private::ModuleSpecList &specs); + //------------------------------------------------------------------ + /// Split a path into a file path with object name. + /// + /// For paths like "/tmp/foo.a(bar.o)" we often need to split a path + /// up into the actual path name and into the object name so we can + /// make a valid object file from it. + /// + /// @param[in] path_with_object + /// A path that might contain an archive path with a .o file + /// specified in parens in the basename of the path. + /// + /// @param[out] archive_file + /// If \b true is returned, \a file_spec will be filled in with + /// the path to the archive. + /// + /// @param[out] archive_object + /// If \b true is returned, \a object will be filled in with + /// the name of the object inside the archive. + /// + /// @return + /// \b true if the path matches the pattern of archive + object + /// and \a archive_file and \a archive_object are modified, + /// \b false otherwise and \a archive_file and \a archive_object + /// are guaranteed to be remain unchanged. + //------------------------------------------------------------------ + static bool SplitArchivePathWithObject( + const char *path_with_object, lldb_private::FileSpec &archive_file, + lldb_private::ConstString &archive_object, bool must_exist); + + //------------------------------------------------------------------ + /// Gets the address size in bytes for the current object file. + /// + /// @return + /// The size of an address in bytes for the currently selected + /// architecture (and object for archives). Returns zero if no + /// architecture or object has been selected. + //------------------------------------------------------------------ + virtual uint32_t GetAddressByteSize() const = 0; + + //------------------------------------------------------------------ + /// Get the address type given a file address in an object file. + /// + /// Many binary file formats know what kinds + /// This is primarily for ARM binaries, though it can be applied to + /// any executable file format that supports different opcode types + /// within the same binary. ARM binaries support having both ARM and + /// Thumb within the same executable container. We need to be able + /// to get + /// @return + /// The size of an address in bytes for the currently selected + /// architecture (and object for archives). Returns zero if no + /// architecture or object has been selected. + //------------------------------------------------------------------ + virtual lldb::AddressClass GetAddressClass(lldb::addr_t file_addr); + + //------------------------------------------------------------------ + /// Extract the dependent modules from an object file. + /// + /// If an object file has information about which other images it + /// depends on (such as shared libraries), this function will + /// provide the list. Since many executables or shared libraries + /// may depend on the same files, + /// FileSpecList::AppendIfUnique(const FileSpec &) should be + /// used to make sure any files that are added are not already in + /// the list. + /// + /// @param[out] file_list + /// A list of file specification objects that gets dependent + /// files appended to. + /// + /// @return + /// The number of new files that were appended to \a file_list. + /// + /// @see FileSpecList::AppendIfUnique(const FileSpec &) + //------------------------------------------------------------------ + virtual uint32_t GetDependentModules(FileSpecList &file_list) = 0; + + //------------------------------------------------------------------ + /// Tells whether this object file is capable of being the main executable + /// for a process. + /// + /// @return + /// \b true if it is, \b false otherwise. + //------------------------------------------------------------------ + virtual bool IsExecutable() const = 0; + + //------------------------------------------------------------------ + /// Returns the offset into a file at which this object resides. + /// + /// Some files contain many object files, and this function allows + /// access to an object's offset within the file. + /// + /// @return + /// The offset in bytes into the file. Defaults to zero for + /// simple object files that a represented by an entire file. + //------------------------------------------------------------------ + virtual lldb::addr_t GetFileOffset() const { return m_file_offset; } + + virtual lldb::addr_t GetByteSize() const { return m_length; } + + //------------------------------------------------------------------ + /// Get accessor to the object file specification. + /// + /// @return + /// The file specification object pointer if there is one, or + /// NULL if this object is only from memory. + //------------------------------------------------------------------ + virtual FileSpec &GetFileSpec() { return m_file; } + + //------------------------------------------------------------------ + /// Get const accessor to the object file specification. + /// + /// @return + /// The const file specification object pointer if there is one, + /// or NULL if this object is only from memory. + //------------------------------------------------------------------ + virtual const FileSpec &GetFileSpec() const { return m_file; } + + //------------------------------------------------------------------ + /// Get the name of the cpu, vendor and OS for this object file. + /// + /// This value is a string that represents the target triple where + /// the cpu type, the vendor and the OS are encoded into a string. + /// + /// @param[out] target_triple + /// The string value of the target triple. + /// + /// @return + /// \b True if the target triple was able to be computed, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool GetArchitecture(ArchSpec &arch) = 0; + + //------------------------------------------------------------------ + /// Gets the section list for the currently selected architecture + /// (and object for archives). + /// + /// Section list parsing can be deferred by ObjectFile instances + /// until this accessor is called the first time. + /// + /// @return + /// The list of sections contained in this object file. + //------------------------------------------------------------------ + virtual SectionList *GetSectionList(bool update_module_section_list = true); + + virtual void CreateSections(SectionList &unified_section_list) = 0; + + //------------------------------------------------------------------ + /// Notify the ObjectFile that the file addresses in the Sections + /// for this module have been changed. + //------------------------------------------------------------------ + virtual void SectionFileAddressesChanged() {} + + //------------------------------------------------------------------ + /// Gets the symbol table for the currently selected architecture + /// (and object for archives). + /// + /// Symbol table parsing can be deferred by ObjectFile instances + /// until this accessor is called the first time. + /// + /// @return + /// The symbol table for this object file. + //------------------------------------------------------------------ + virtual Symtab *GetSymtab() = 0; + + //------------------------------------------------------------------ + /// Appends a Symbol for the specified so_addr to the symbol table. + /// + /// If verify_unique is false, the symbol table is not searched + /// to determine if a Symbol found at this address has already been + /// added to the symbol table. When verify_unique is true, this + /// method resolves the Symbol as the first match in the SymbolTable + /// and appends a Symbol only if required/found. + /// + /// @return + /// The resolved symbol or nullptr. Returns nullptr if a + /// a Symbol could not be found for the specified so_addr. + //------------------------------------------------------------------ + virtual Symbol *ResolveSymbolForAddress(const Address &so_addr, + bool verify_unique) { + // Typically overridden to lazily add stripped symbols recoverable from + // the exception handling unwind information (i.e. without parsing + // the entire eh_frame section. + // + // The availability of LC_FUNCTION_STARTS allows ObjectFileMachO + // to efficiently add stripped symbols when the symbol table is + // first constructed. Poorer cousins are PECoff and ELF. + return nullptr; + } + + //------------------------------------------------------------------ + /// Detect if this object file has been stripped of local symbols. + //------------------------------------------------------------------ + /// Detect if this object file has been stripped of local symbols. + /// + /// @return + /// Return \b true if the object file has been stripped of local + /// symbols. + //------------------------------------------------------------------ + virtual bool IsStripped() = 0; + + //------------------------------------------------------------------ + /// Frees the symbol table. + /// + /// This function should only be used when an object file is + /// + /// @param[in] flags + /// eSymtabFromUnifiedSectionList: Whether to clear symbol table + /// for unified module section list, or object file. + /// + /// @return + /// The symbol table for this object file. + //------------------------------------------------------------------ + virtual void ClearSymtab(); + + //------------------------------------------------------------------ + /// Gets the UUID for this object file. + /// + /// If the object file format contains a UUID, the value should be + /// returned. Else ObjectFile instances should return the MD5 + /// checksum of all of the bytes for the object file (or memory for + /// memory based object files). + /// + /// @return + /// Returns \b true if a UUID was successfully extracted into + /// \a uuid, \b false otherwise. + //------------------------------------------------------------------ + virtual bool GetUUID(lldb_private::UUID *uuid) = 0; + + //------------------------------------------------------------------ + /// Gets the symbol file spec list for this object file. + /// + /// If the object file format contains a debug symbol file link, + /// the values will be returned in the FileSpecList. + /// + /// @return + /// Returns filespeclist. + //------------------------------------------------------------------ + virtual lldb_private::FileSpecList GetDebugSymbolFilePaths() { + return FileSpecList(); + } + + //------------------------------------------------------------------ + /// Gets the file spec list of libraries re-exported by this object file. + /// + /// If the object file format has the notion of one library re-exporting the + /// symbols from another, + /// the re-exported libraries will be returned in the FileSpecList. + /// + /// @return + /// Returns filespeclist. + //------------------------------------------------------------------ + virtual lldb_private::FileSpecList GetReExportedLibraries() { + return FileSpecList(); + } + + //------------------------------------------------------------------ + /// Sets the load address for an entire module, assuming a rigid + /// slide of sections, if possible in the implementation. + /// + /// @return + /// Returns true iff any section's load address changed. + //------------------------------------------------------------------ + virtual bool SetLoadAddress(Target &target, lldb::addr_t value, + bool value_is_offset) { + return false; + } + + //------------------------------------------------------------------ + /// Gets whether endian swapping should occur when extracting data + /// from this object file. + /// + /// @return + /// Returns \b true if endian swapping is needed, \b false + /// otherwise. + //------------------------------------------------------------------ + virtual lldb::ByteOrder GetByteOrder() const = 0; + + //------------------------------------------------------------------ + /// Attempts to parse the object header. + /// + /// This function is used as a test to see if a given plug-in + /// instance can parse the header data already contained in + /// ObjectFile::m_data. If an object file parser does not + /// recognize that magic bytes in a header, false should be returned + /// and the next plug-in can attempt to parse an object file. + /// + /// @return + /// Returns \b true if the header was parsed successfully, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool ParseHeader() = 0; + + //------------------------------------------------------------------ + /// Returns a reference to the UnwindTable for this ObjectFile + /// + /// The UnwindTable contains FuncUnwinders objects for any function in + /// this ObjectFile. 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 object file. + //------------------------------------------------------------------ + virtual lldb_private::UnwindTable &GetUnwindTable() { return m_unwind_table; } + + //------------------------------------------------------------------ + /// Returns if the function bounds for symbols in this symbol file + /// are likely accurate. + /// + /// The unwinder can emulate the instructions of functions to understand + /// prologue/epilogue code sequences, where registers are spilled on + /// the stack, etc. This feature relies on having the correct start + /// addresses of all functions. If the ObjectFile has a way to tell + /// that symbols have been stripped and there's no way to reconstruct + /// start addresses (e.g. LC_FUNCTION_STARTS on Mach-O, or eh_frame + /// unwind info), the ObjectFile should indicate that assembly emulation + /// should not be used for this module. + /// + /// It is uncommon for this to return false. An ObjectFile needs to + /// be sure that symbol start addresses are unavailable before false + /// is returned. If it is unclear, this should return true. + /// + /// @return + /// Returns true if assembly emulation should be used for this + /// module. + /// Only returns false if the ObjectFile is sure that symbol + /// addresses are insufficient for accurate assembly emulation. + //------------------------------------------------------------------ + virtual bool AllowAssemblyEmulationUnwindPlans() { return true; } + + //------------------------------------------------------------------ + /// Similar to Process::GetImageInfoAddress(). + /// + /// Some platforms embed auxiliary structures useful to debuggers in the + /// address space of the inferior process. This method returns the address + /// of such a structure if the information can be resolved via entries in + /// the object file. ELF, for example, provides a means to hook into the + /// runtime linker so that a debugger may monitor the loading and unloading + /// of shared libraries. + /// + /// @return + /// The address of any auxiliary tables, or an invalid address if this + /// object file format does not support or contain such information. + virtual lldb_private::Address GetImageInfoAddress(Target *target) { + return Address(); + } + + //------------------------------------------------------------------ + /// Returns the address of the Entry Point in this object file - if + /// the object file doesn't have an entry point (because it is not an + /// executable file) then an invalid address is returned. + /// + /// @return + /// Returns the entry address for this module. + //------------------------------------------------------------------ + virtual lldb_private::Address GetEntryPointAddress() { return Address(); } + + //------------------------------------------------------------------ + /// Returns the address that represents the header of this object + /// file. + /// + /// The header address is defined as where the header for the object + /// file is that describes the content of the file. If the header + /// doesn't appear in a section that is defined in the object file, + /// an address with no section is returned that has the file offset + /// set in the m_file_offset member of the lldb_private::Address object. + /// + /// @return + /// Returns the entry address for this module. + //------------------------------------------------------------------ + virtual lldb_private::Address GetHeaderAddress() { + return Address(m_memory_addr); + } + + virtual uint32_t GetNumThreadContexts() { return 0; } + + virtual lldb::RegisterContextSP + GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) { + return lldb::RegisterContextSP(); + } + + //------------------------------------------------------------------ + /// The object file should be able to calculate its type by looking + /// at its file header and possibly the sections or other data in + /// the object file. The file type is used in the debugger to help + /// select the correct plug-ins for the job at hand, so this is + /// important to get right. If any eTypeXXX definitions do not match + /// up with the type of file you are loading, please feel free to + /// add a new enumeration value. + /// + /// @return + /// The calculated file type for the current object file. + //------------------------------------------------------------------ + virtual Type CalculateType() = 0; + + //------------------------------------------------------------------ + /// In cases where the type can't be calculated (elf files), this + /// routine allows someone to explicitly set it. As an example, + /// SymbolVendorELF uses this routine to set eTypeDebugInfo when + /// loading debug link files. + virtual void SetType(Type type) { m_type = type; } + + //------------------------------------------------------------------ + /// The object file should be able to calculate the strata of the + /// object file. + /// + /// Many object files for platforms might be for either user space + /// debugging or for kernel debugging. If your object file subclass + /// can figure this out, it will help with debugger plug-in selection + /// when it comes time to debug. + /// + /// @return + /// The calculated object file strata for the current object + /// file. + //------------------------------------------------------------------ + virtual Strata CalculateStrata() = 0; + + //------------------------------------------------------------------ + /// Get the object file version numbers. + /// + /// Many object files have a set of version numbers that describe + /// the version of the executable or shared library. Typically there + /// are major, minor and build, but there may be more. This function + /// will extract the versions from object files if they are available. + /// + /// If \a versions is NULL, or if \a num_versions is 0, the return + /// value will indicate how many version numbers are available in + /// this object file. Then a subsequent call can be made to this + /// function with a value of \a versions and \a num_versions that + /// has enough storage to store some or all version numbers. + /// + /// @param[out] versions + /// A pointer to an array of uint32_t types that is \a num_versions + /// long. If this value is NULL, the return value will indicate + /// how many version numbers are required for a subsequent call + /// to this function so that all versions can be retrieved. If + /// the value is non-NULL, then at most \a num_versions of the + /// existing versions numbers will be filled into \a versions. + /// If there is no version information available, \a versions + /// will be filled with \a num_versions UINT32_MAX values + /// and zero will be returned. + /// + /// @param[in] num_versions + /// The maximum number of entries to fill into \a versions. If + /// this value is zero, then the return value will indicate + /// how many version numbers there are in total so another call + /// to this function can be make with adequate storage in + /// \a versions to get all of the version numbers. If \a + /// num_versions is less than the actual number of version + /// numbers in this object file, only \a num_versions will be + /// filled into \a versions (if \a versions is non-NULL). + /// + /// @return + /// This function always returns the number of version numbers + /// that this object file has regardless of the number of + /// version numbers that were copied into \a versions. + //------------------------------------------------------------------ + virtual uint32_t GetVersion(uint32_t *versions, uint32_t num_versions) { + if (versions && num_versions) { + for (uint32_t i = 0; i < num_versions; ++i) + versions[i] = UINT32_MAX; } - - //------------------------------------------------------------------ - /// Gets whether endian swapping should occur when extracting data - /// from this object file. - /// - /// @return - /// Returns \b true if endian swapping is needed, \b false - /// otherwise. - //------------------------------------------------------------------ - virtual lldb::ByteOrder - GetByteOrder () const = 0; - - //------------------------------------------------------------------ - /// Attempts to parse the object header. - /// - /// This function is used as a test to see if a given plug-in - /// instance can parse the header data already contained in - /// ObjectFile::m_data. If an object file parser does not - /// recognize that magic bytes in a header, false should be returned - /// and the next plug-in can attempt to parse an object file. - /// - /// @return - /// Returns \b true if the header was parsed successfully, \b - /// false otherwise. - //------------------------------------------------------------------ - virtual bool - ParseHeader () = 0; - - //------------------------------------------------------------------ - /// Returns a reference to the UnwindTable for this ObjectFile - /// - /// The UnwindTable contains FuncUnwinders objects for any function in - /// this ObjectFile. 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 object file. - //------------------------------------------------------------------ - virtual lldb_private::UnwindTable& - GetUnwindTable () { return m_unwind_table; } - - //------------------------------------------------------------------ - /// Returns if the function bounds for symbols in this symbol file - /// are likely accurate. - /// - /// The unwinder can emulate the instructions of functions to understand - /// prologue/epilogue code sequences, where registers are spilled on - /// the stack, etc. This feature relies on having the correct start - /// addresses of all functions. If the ObjectFile has a way to tell - /// that symbols have been stripped and there's no way to reconstruct - /// start addresses (e.g. LC_FUNCTION_STARTS on Mach-O, or eh_frame - /// unwind info), the ObjectFile should indicate that assembly emulation - /// should not be used for this module. - /// - /// It is uncommon for this to return false. An ObjectFile needs to - /// be sure that symbol start addresses are unavailable before false - /// is returned. If it is unclear, this should return true. - /// - /// @return - /// Returns true if assembly emulation should be used for this - /// module. - /// Only returns false if the ObjectFile is sure that symbol - /// addresses are insufficient for accurate assembly emulation. - //------------------------------------------------------------------ - virtual bool - AllowAssemblyEmulationUnwindPlans () - { - return true; - } - - //------------------------------------------------------------------ - /// Similar to Process::GetImageInfoAddress(). - /// - /// Some platforms embed auxiliary structures useful to debuggers in the - /// address space of the inferior process. This method returns the address - /// of such a structure if the information can be resolved via entries in - /// the object file. ELF, for example, provides a means to hook into the - /// runtime linker so that a debugger may monitor the loading and unloading - /// of shared libraries. - /// - /// @return - /// The address of any auxiliary tables, or an invalid address if this - /// object file format does not support or contain such information. - virtual lldb_private::Address - GetImageInfoAddress (Target *target) { return Address(); } - - //------------------------------------------------------------------ - /// Returns the address of the Entry Point in this object file - if - /// the object file doesn't have an entry point (because it is not an - /// executable file) then an invalid address is returned. - /// - /// @return - /// Returns the entry address for this module. - //------------------------------------------------------------------ - virtual lldb_private::Address - GetEntryPointAddress () { return Address();} - - //------------------------------------------------------------------ - /// Returns the address that represents the header of this object - /// file. - /// - /// The header address is defined as where the header for the object - /// file is that describes the content of the file. If the header - /// doesn't appear in a section that is defined in the object file, - /// an address with no section is returned that has the file offset - /// set in the m_file_offset member of the lldb_private::Address object. - /// - /// @return - /// Returns the entry address for this module. - //------------------------------------------------------------------ - virtual lldb_private::Address - GetHeaderAddress () { return Address(m_memory_addr);} - - virtual uint32_t - GetNumThreadContexts () - { - return 0; - } - - virtual lldb::RegisterContextSP - GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &thread) - { - return lldb::RegisterContextSP(); - } - - //------------------------------------------------------------------ - /// The object file should be able to calculate its type by looking - /// at its file header and possibly the sections or other data in - /// the object file. The file type is used in the debugger to help - /// select the correct plug-ins for the job at hand, so this is - /// important to get right. If any eTypeXXX definitions do not match - /// up with the type of file you are loading, please feel free to - /// add a new enumeration value. - /// - /// @return - /// The calculated file type for the current object file. - //------------------------------------------------------------------ - virtual Type - CalculateType() = 0; - - //------------------------------------------------------------------ - /// In cases where the type can't be calculated (elf files), this - /// routine allows someone to explicitly set it. As an example, - /// SymbolVendorELF uses this routine to set eTypeDebugInfo when - /// loading debug link files. - virtual void - SetType (Type type) - { - m_type = type; - } - - //------------------------------------------------------------------ - /// The object file should be able to calculate the strata of the - /// object file. - /// - /// Many object files for platforms might be for either user space - /// debugging or for kernel debugging. If your object file subclass - /// can figure this out, it will help with debugger plug-in selection - /// when it comes time to debug. - /// - /// @return - /// The calculated object file strata for the current object - /// file. - //------------------------------------------------------------------ - virtual Strata - CalculateStrata() = 0; - - //------------------------------------------------------------------ - /// Get the object file version numbers. - /// - /// Many object files have a set of version numbers that describe - /// the version of the executable or shared library. Typically there - /// are major, minor and build, but there may be more. This function - /// will extract the versions from object files if they are available. - /// - /// If \a versions is NULL, or if \a num_versions is 0, the return - /// value will indicate how many version numbers are available in - /// this object file. Then a subsequent call can be made to this - /// function with a value of \a versions and \a num_versions that - /// has enough storage to store some or all version numbers. - /// - /// @param[out] versions - /// A pointer to an array of uint32_t types that is \a num_versions - /// long. If this value is NULL, the return value will indicate - /// how many version numbers are required for a subsequent call - /// to this function so that all versions can be retrieved. If - /// the value is non-NULL, then at most \a num_versions of the - /// existing versions numbers will be filled into \a versions. - /// If there is no version information available, \a versions - /// will be filled with \a num_versions UINT32_MAX values - /// and zero will be returned. - /// - /// @param[in] num_versions - /// The maximum number of entries to fill into \a versions. If - /// this value is zero, then the return value will indicate - /// how many version numbers there are in total so another call - /// to this function can be make with adequate storage in - /// \a versions to get all of the version numbers. If \a - /// num_versions is less than the actual number of version - /// numbers in this object file, only \a num_versions will be - /// filled into \a versions (if \a versions is non-NULL). - /// - /// @return - /// This function always returns the number of version numbers - /// that this object file has regardless of the number of - /// version numbers that were copied into \a versions. - //------------------------------------------------------------------ - virtual uint32_t - GetVersion (uint32_t *versions, uint32_t num_versions) - { - if (versions && num_versions) - { - for (uint32_t i=0; i<num_versions; ++i) - versions[i] = UINT32_MAX; - } - return 0; - } - - //------------------------------------------------------------------ - /// Get the minimum OS version this object file can run on. - /// - /// Some object files have information that specifies the minimum OS - /// version that they can be used on. - /// - /// If \a versions is NULL, or if \a num_versions is 0, the return - /// value will indicate how many version numbers are available in - /// this object file. Then a subsequent call can be made to this - /// function with a value of \a versions and \a num_versions that - /// has enough storage to store some or all version numbers. - /// - /// @param[out] versions - /// A pointer to an array of uint32_t types that is \a num_versions - /// long. If this value is NULL, the return value will indicate - /// how many version numbers are required for a subsequent call - /// to this function so that all versions can be retrieved. If - /// the value is non-NULL, then at most \a num_versions of the - /// existing versions numbers will be filled into \a versions. - /// If there is no version information available, \a versions - /// will be filled with \a num_versions UINT32_MAX values - /// and zero will be returned. - /// - /// @param[in] num_versions - /// The maximum number of entries to fill into \a versions. If - /// this value is zero, then the return value will indicate - /// how many version numbers there are in total so another call - /// to this function can be make with adequate storage in - /// \a versions to get all of the version numbers. If \a - /// num_versions is less than the actual number of version - /// numbers in this object file, only \a num_versions will be - /// filled into \a versions (if \a versions is non-NULL). - /// - /// @return - /// This function always returns the number of version numbers - /// that this object file has regardless of the number of - /// version numbers that were copied into \a versions. - //------------------------------------------------------------------ - virtual uint32_t - GetMinimumOSVersion (uint32_t *versions, uint32_t num_versions) - { - if (versions && num_versions) - { - for (uint32_t i=0; i<num_versions; ++i) - versions[i] = UINT32_MAX; - } - return 0; + return 0; + } + + //------------------------------------------------------------------ + /// Get the minimum OS version this object file can run on. + /// + /// Some object files have information that specifies the minimum OS + /// version that they can be used on. + /// + /// If \a versions is NULL, or if \a num_versions is 0, the return + /// value will indicate how many version numbers are available in + /// this object file. Then a subsequent call can be made to this + /// function with a value of \a versions and \a num_versions that + /// has enough storage to store some or all version numbers. + /// + /// @param[out] versions + /// A pointer to an array of uint32_t types that is \a num_versions + /// long. If this value is NULL, the return value will indicate + /// how many version numbers are required for a subsequent call + /// to this function so that all versions can be retrieved. If + /// the value is non-NULL, then at most \a num_versions of the + /// existing versions numbers will be filled into \a versions. + /// If there is no version information available, \a versions + /// will be filled with \a num_versions UINT32_MAX values + /// and zero will be returned. + /// + /// @param[in] num_versions + /// The maximum number of entries to fill into \a versions. If + /// this value is zero, then the return value will indicate + /// how many version numbers there are in total so another call + /// to this function can be make with adequate storage in + /// \a versions to get all of the version numbers. If \a + /// num_versions is less than the actual number of version + /// numbers in this object file, only \a num_versions will be + /// filled into \a versions (if \a versions is non-NULL). + /// + /// @return + /// This function always returns the number of version numbers + /// that this object file has regardless of the number of + /// version numbers that were copied into \a versions. + //------------------------------------------------------------------ + virtual uint32_t GetMinimumOSVersion(uint32_t *versions, + uint32_t num_versions) { + if (versions && num_versions) { + for (uint32_t i = 0; i < num_versions; ++i) + versions[i] = UINT32_MAX; } - - //------------------------------------------------------------------ - /// Get the SDK OS version this object file was built with. - /// - /// The versions arguments and returns values are the same as the - /// GetMinimumOSVersion() - //------------------------------------------------------------------ - virtual uint32_t - GetSDKVersion (uint32_t *versions, uint32_t num_versions) - { - if (versions && num_versions) - { - for (uint32_t i=0; i<num_versions; ++i) - versions[i] = UINT32_MAX; - } - return 0; - } - - //------------------------------------------------------------------ - /// Return true if this file is a dynamic link editor (dyld) - /// - /// Often times dyld has symbols that mirror symbols in libc and - /// other shared libraries (like "malloc" and "free") and the user - /// does _not_ want to stop in these shared libraries by default. - /// We can ask the ObjectFile if it is such a file and should be - /// avoided for things like settings breakpoints and doing function - /// lookups for expressions. - //------------------------------------------------------------------ - virtual bool - GetIsDynamicLinkEditor() - { - return false; - } - - //------------------------------------------------------------------ - // Member Functions - //------------------------------------------------------------------ - Type - GetType () - { - if (m_type == eTypeInvalid) - m_type = CalculateType(); - return m_type; + return 0; + } + + //------------------------------------------------------------------ + /// Get the SDK OS version this object file was built with. + /// + /// The versions arguments and returns values are the same as the + /// GetMinimumOSVersion() + //------------------------------------------------------------------ + virtual uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) { + if (versions && num_versions) { + for (uint32_t i = 0; i < num_versions; ++i) + versions[i] = UINT32_MAX; } - - Strata - GetStrata () - { - if (m_strata == eStrataInvalid) - m_strata = CalculateStrata(); - return m_strata; - } - - // When an object file is in memory, subclasses should try and lock - // the process weak pointer. If the process weak pointer produces a - // valid ProcessSP, then subclasses can call this function to read - // memory. - static lldb::DataBufferSP - ReadMemory (const lldb::ProcessSP &process_sp, - lldb::addr_t addr, - size_t byte_size); - - size_t - GetData (lldb::offset_t offset, size_t length, DataExtractor &data) const; - - size_t - CopyData (lldb::offset_t offset, size_t length, void *dst) const; - - virtual size_t - ReadSectionData (const Section *section, - lldb::offset_t section_offset, - void *dst, - size_t dst_len) const; - - virtual size_t - ReadSectionData (const Section *section, - DataExtractor& section_data) const; - - size_t - MemoryMapSectionData (const Section *section, - DataExtractor& section_data) const; - - bool - IsInMemory () const - { - return m_memory_addr != LLDB_INVALID_ADDRESS; - } - - // Strip linker annotations (such as @@VERSION) from symbol names. - virtual std::string - StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const - { - return symbol_name.str(); - } - - static lldb::SymbolType - GetSymbolTypeFromName (llvm::StringRef name, - lldb::SymbolType symbol_type_hint = lldb::eSymbolTypeUndefined); + return 0; + } + + //------------------------------------------------------------------ + /// Return true if this file is a dynamic link editor (dyld) + /// + /// Often times dyld has symbols that mirror symbols in libc and + /// other shared libraries (like "malloc" and "free") and the user + /// does _not_ want to stop in these shared libraries by default. + /// We can ask the ObjectFile if it is such a file and should be + /// avoided for things like settings breakpoints and doing function + /// lookups for expressions. + //------------------------------------------------------------------ + virtual bool GetIsDynamicLinkEditor() { return false; } + + //------------------------------------------------------------------ + // Member Functions + //------------------------------------------------------------------ + Type GetType() { + if (m_type == eTypeInvalid) + m_type = CalculateType(); + return m_type; + } + + Strata GetStrata() { + if (m_strata == eStrataInvalid) + m_strata = CalculateStrata(); + return m_strata; + } + + // When an object file is in memory, subclasses should try and lock + // the process weak pointer. If the process weak pointer produces a + // valid ProcessSP, then subclasses can call this function to read + // memory. + static lldb::DataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, + lldb::addr_t addr, size_t byte_size); + + size_t GetData(lldb::offset_t offset, size_t length, + DataExtractor &data) const; + + size_t CopyData(lldb::offset_t offset, size_t length, void *dst) const; + + virtual size_t ReadSectionData(const Section *section, + lldb::offset_t section_offset, void *dst, + size_t dst_len) const; + + virtual size_t ReadSectionData(const Section *section, + DataExtractor §ion_data) const; + + size_t MemoryMapSectionData(const Section *section, + DataExtractor §ion_data) const; + + bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; } + + // Strip linker annotations (such as @@VERSION) from symbol names. + virtual std::string + StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { + return symbol_name.str(); + } + + static lldb::SymbolType GetSymbolTypeFromName( + llvm::StringRef name, + lldb::SymbolType symbol_type_hint = lldb::eSymbolTypeUndefined); protected: - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - FileSpec m_file; - Type m_type; - Strata m_strata; - lldb::addr_t m_file_offset; ///< The offset in bytes into the file, or the address in memory - lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined). - DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. - lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions - lldb::ProcessWP m_process_wp; - const lldb::addr_t m_memory_addr; - std::unique_ptr<lldb_private::SectionList> m_sections_ap; - std::unique_ptr<lldb_private::Symtab> m_symtab_ap; - uint32_t m_synthetic_symbol_idx; - - //------------------------------------------------------------------ - /// Sets the architecture for a module. At present the architecture - /// can only be set if it is invalid. It is not allowed to switch from - /// one concrete architecture to another. - /// - /// @param[in] new_arch - /// The architecture this module will be set to. - /// - /// @return - /// Returns \b true if the architecture was changed, \b - /// false otherwise. - //------------------------------------------------------------------ - bool - SetModulesArchitecture (const ArchSpec &new_arch); - - ConstString - GetNextSyntheticSymbolName(); + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + FileSpec m_file; + Type m_type; + Strata m_strata; + lldb::addr_t m_file_offset; ///< The offset in bytes into the file, or the + ///address in memory + lldb::addr_t m_length; ///< The length of this object file if it is known (can + ///be zero if length is unknown or can't be + ///determined). + DataExtractor + m_data; ///< The data for this object file so things can be parsed lazily. + lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects + /// created for this ObjectFile's + /// functions + lldb::ProcessWP m_process_wp; + const lldb::addr_t m_memory_addr; + std::unique_ptr<lldb_private::SectionList> m_sections_ap; + std::unique_ptr<lldb_private::Symtab> m_symtab_ap; + uint32_t m_synthetic_symbol_idx; + + //------------------------------------------------------------------ + /// Sets the architecture for a module. At present the architecture + /// can only be set if it is invalid. It is not allowed to switch from + /// one concrete architecture to another. + /// + /// @param[in] new_arch + /// The architecture this module will be set to. + /// + /// @return + /// Returns \b true if the architecture was changed, \b + /// false otherwise. + //------------------------------------------------------------------ + bool SetModulesArchitecture(const ArchSpec &new_arch); + + ConstString GetNextSyntheticSymbolName(); private: - DISALLOW_COPY_AND_ASSIGN (ObjectFile); + DISALLOW_COPY_AND_ASSIGN(ObjectFile); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index 43f29f368d92..3f12b9a99b04 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -10,407 +10,272 @@ #ifndef liblldb_Symbol_h_ #define liblldb_Symbol_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/UserID.h" #include "lldb/Symbol/SymbolContextScope.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class Symbol : - public SymbolContextScope -{ +class Symbol : public SymbolContextScope { public: - // ObjectFile readers can classify their symbol table entries and searches can be made - // on specific types where the symbol values will have drastically different meanings - // and sorting requirements. - Symbol(); - - Symbol (uint32_t symID, - const char *name, - bool name_is_mangled, - lldb::SymbolType type, - bool external, - bool is_debug, - bool is_trampoline, - bool is_artificial, - const lldb::SectionSP §ion_sp, - lldb::addr_t value, - lldb::addr_t size, - bool size_is_valid, - bool contains_linker_annotations, - uint32_t flags); - - Symbol (uint32_t symID, - const Mangled &mangled, - lldb::SymbolType type, - bool external, - bool is_debug, - bool is_trampoline, - bool is_artificial, - const AddressRange &range, - bool size_is_valid, - bool contains_linker_annotations, - uint32_t flags); - - Symbol (const Symbol& rhs); - - const Symbol& - operator= (const Symbol& rhs); - - void - Clear(); - - bool - Compare (const ConstString& name, lldb::SymbolType type) const; - - void - Dump (Stream *s, Target *target, uint32_t index) const; - - bool - ValueIsAddress() const; - - //------------------------------------------------------------------ - // The GetAddressRef() accessor functions should only be called if - // you previously call ValueIsAddress() otherwise you might get an - // reference to an Address object that contains an constant integer - // value in m_addr_range.m_base_addr.m_offset which could be - // incorrectly used to represent an absolute address since it has - // no section. - //------------------------------------------------------------------ - Address & - GetAddressRef() - { - return m_addr_range.GetBaseAddress(); + // ObjectFile readers can classify their symbol table entries and searches can + // be made + // on specific types where the symbol values will have drastically different + // meanings + // and sorting requirements. + Symbol(); + + Symbol(uint32_t symID, const char *name, bool name_is_mangled, + lldb::SymbolType type, bool external, bool is_debug, + bool is_trampoline, bool is_artificial, + const lldb::SectionSP §ion_sp, lldb::addr_t value, + lldb::addr_t size, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags); + + Symbol(uint32_t symID, const Mangled &mangled, lldb::SymbolType type, + bool external, bool is_debug, bool is_trampoline, bool is_artificial, + const AddressRange &range, bool size_is_valid, + bool contains_linker_annotations, uint32_t flags); + + Symbol(const Symbol &rhs); + + const Symbol &operator=(const Symbol &rhs); + + void Clear(); + + bool Compare(const ConstString &name, lldb::SymbolType type) const; + + void Dump(Stream *s, Target *target, uint32_t index) const; + + bool ValueIsAddress() const; + + //------------------------------------------------------------------ + // The GetAddressRef() accessor functions should only be called if + // you previously call ValueIsAddress() otherwise you might get an + // reference to an Address object that contains an constant integer + // value in m_addr_range.m_base_addr.m_offset which could be + // incorrectly used to represent an absolute address since it has + // no section. + //------------------------------------------------------------------ + Address &GetAddressRef() { return m_addr_range.GetBaseAddress(); } + + const Address &GetAddressRef() const { return m_addr_range.GetBaseAddress(); } + + //------------------------------------------------------------------ + // Makes sure the symbol's value is an address and returns the file + // address. Returns LLDB_INVALID_ADDRESS if the symbol's value isn't + // an address. + //------------------------------------------------------------------ + lldb::addr_t GetFileAddress() const; + + //------------------------------------------------------------------ + // Makes sure the symbol's value is an address and gets the load + // address using \a target if it is. Returns LLDB_INVALID_ADDRESS + // if the symbol's value isn't an address or if the section isn't + // loaded in \a target. + //------------------------------------------------------------------ + lldb::addr_t GetLoadAddress(Target *target) const; + + //------------------------------------------------------------------ + // Access the address value. Do NOT hand out the AddressRange as an + // object as the byte size of the address range may not be filled in + // and it should be accessed via GetByteSize(). + //------------------------------------------------------------------ + Address GetAddress() const { + // Make sure the our value is an address before we hand a copy out. + // We use the Address inside m_addr_range to contain the value for + // symbols that are not address based symbols so we are using it + // for more than just addresses. For example undefined symbols on + // MacOSX have a nlist.n_value of 0 (zero) and this will get placed + // into m_addr_range.m_base_addr.m_offset and it will have no section. + // So in the GetAddress() accessor, we need to hand out an invalid + // address if the symbol's value isn't an address. + if (ValueIsAddress()) + return m_addr_range.GetBaseAddress(); + else + return Address(); + } + + // When a symbol's value isn't an address, we need to access the raw + // value. This function will ensure this symbol's value isn't an address + // and return the integer value if this checks out, otherwise it will + // return "fail_value" if the symbol is an address value. + uint64_t GetIntegerValue(uint64_t fail_value = 0) const { + if (ValueIsAddress()) { + // This symbol's value is an address. Use Symbol::GetAddress() to get the + // address. + return fail_value; + } else { + // The value is stored in the base address' offset + return m_addr_range.GetBaseAddress().GetOffset(); } + } - const Address & - GetAddressRef() const - { - return m_addr_range.GetBaseAddress(); - } + lldb::addr_t ResolveCallableAddress(Target &target) const; - //------------------------------------------------------------------ - // Makes sure the symbol's value is an address and returns the file - // address. Returns LLDB_INVALID_ADDRESS if the symbol's value isn't - // an address. - //------------------------------------------------------------------ - lldb::addr_t - GetFileAddress () const; - - //------------------------------------------------------------------ - // Makes sure the symbol's value is an address and gets the load - // address using \a target if it is. Returns LLDB_INVALID_ADDRESS - // if the symbol's value isn't an address or if the section isn't - // loaded in \a target. - //------------------------------------------------------------------ - lldb::addr_t - GetLoadAddress (Target *target) const; - - //------------------------------------------------------------------ - // Access the address value. Do NOT hand out the AddressRange as an - // object as the byte size of the address range may not be filled in - // and it should be accessed via GetByteSize(). - //------------------------------------------------------------------ - Address - GetAddress() const - { - // Make sure the our value is an address before we hand a copy out. - // We use the Address inside m_addr_range to contain the value for - // symbols that are not address based symbols so we are using it - // for more than just addresses. For example undefined symbols on - // MacOSX have a nlist.n_value of 0 (zero) and this will get placed - // into m_addr_range.m_base_addr.m_offset and it will have no section. - // So in the GetAddress() accessor, we need to hand out an invalid - // address if the symbol's value isn't an address. - if (ValueIsAddress()) - return m_addr_range.GetBaseAddress(); - else - return Address(); - } + ConstString GetName() const; - // When a symbol's value isn't an address, we need to access the raw - // value. This function will ensure this symbol's value isn't an address - // and return the integer value if this checks out, otherwise it will - // return "fail_value" if the symbol is an address value. - uint64_t - GetIntegerValue (uint64_t fail_value = 0) const - { - if (ValueIsAddress()) - { - // This symbol's value is an address. Use Symbol::GetAddress() to get the address. - return fail_value; - } - else - { - // The value is stored in the base address' offset - return m_addr_range.GetBaseAddress().GetOffset(); - } - } + ConstString GetNameNoArguments() const; - lldb::addr_t - ResolveCallableAddress(Target &target) const; + ConstString GetDisplayName() const; - ConstString - GetName () const; + uint32_t GetID() const { return m_uid; } - ConstString - GetNameNoArguments () const; + lldb::LanguageType GetLanguage() const { + // TODO: See if there is a way to determine the language for a symbol + // somehow, for now just return our best guess + return m_mangled.GuessLanguage(); + } - ConstString - GetDisplayName () const; - - uint32_t - GetID() const - { - return m_uid; - } + void SetID(uint32_t uid) { m_uid = uid; } - lldb::LanguageType - GetLanguage() const - { - // TODO: See if there is a way to determine the language for a symbol somehow, for now just return our best guess - return m_mangled.GuessLanguage(); - } + Mangled &GetMangled() { return m_mangled; } - void - SetID(uint32_t uid) - { - m_uid = uid; - } + const Mangled &GetMangled() const { return m_mangled; } - Mangled& - GetMangled () - { - return m_mangled; - } + ConstString GetReExportedSymbolName() const; - const Mangled& - GetMangled () const - { - return m_mangled; - } + FileSpec GetReExportedSymbolSharedLibrary() const; - ConstString - GetReExportedSymbolName() const; + void SetReExportedSymbolName(const ConstString &name); - FileSpec - GetReExportedSymbolSharedLibrary () const; - - void - SetReExportedSymbolName(const ConstString &name); + bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec); - bool - SetReExportedSymbolSharedLibrary (const FileSpec &fspec); - - Symbol * - ResolveReExportedSymbol (Target &target) const; + Symbol *ResolveReExportedSymbol(Target &target) const; - uint32_t - GetSiblingIndex () const; + uint32_t GetSiblingIndex() const; - lldb::SymbolType - GetType () const - { - return (lldb::SymbolType)m_type; - } + lldb::SymbolType GetType() const { return (lldb::SymbolType)m_type; } - void - SetType (lldb::SymbolType type) - { - m_type = (lldb::SymbolType)type; - } + void SetType(lldb::SymbolType type) { m_type = (lldb::SymbolType)type; } - const char * - GetTypeAsString () const; + const char *GetTypeAsString() const; - uint32_t - GetFlags () const - { - return m_flags; - } + uint32_t GetFlags() const { return m_flags; } - void - SetFlags (uint32_t flags) - { - m_flags = flags; - } + void SetFlags(uint32_t flags) { m_flags = flags; } - void - GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const; + void GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target) const; - bool - IsSynthetic () const - { - return m_is_synthetic; - } + bool IsSynthetic() const { return m_is_synthetic; } - void - SetIsSynthetic (bool b) - { - m_is_synthetic = b; - } + void SetIsSynthetic(bool b) { m_is_synthetic = b; } - - bool - GetSizeIsSynthesized() const - { - return m_size_is_synthesized; - } - - void - SetSizeIsSynthesized(bool b) - { - m_size_is_synthesized = b; - } + bool GetSizeIsSynthesized() const { return m_size_is_synthesized; } - bool - IsDebug () const - { - return m_is_debug; - } + void SetSizeIsSynthesized(bool b) { m_size_is_synthesized = b; } - void - SetDebug (bool b) - { - m_is_debug = b; - } + bool IsDebug() const { return m_is_debug; } - bool - IsExternal () const - { - return m_is_external; - } + void SetDebug(bool b) { m_is_debug = b; } - void - SetExternal (bool b) - { - m_is_external = b; - } + bool IsExternal() const { return m_is_external; } - bool - IsTrampoline () const; + void SetExternal(bool b) { m_is_external = b; } - bool - IsIndirect () const; + bool IsTrampoline() const; - bool - GetByteSizeIsValid () const - { - return m_size_is_valid; - } + bool IsIndirect() const; - lldb::addr_t - GetByteSize () const; - - void - SetByteSize (lldb::addr_t size) - { - m_size_is_valid = size > 0; - m_addr_range.SetByteSize(size); - } + bool GetByteSizeIsValid() const { return m_size_is_valid; } - bool - GetSizeIsSibling () const - { - return m_size_is_sibling; - } + lldb::addr_t GetByteSize() const; - void - SetSizeIsSibling (bool b) - { - m_size_is_sibling = b; - } + void SetByteSize(lldb::addr_t size) { + m_size_is_valid = size > 0; + m_addr_range.SetByteSize(size); + } - // If m_type is "Code" or "Function" then this will return the prologue size - // in bytes, else it will return zero. - uint32_t - GetPrologueByteSize (); + bool GetSizeIsSibling() const { return m_size_is_sibling; } - bool - GetDemangledNameIsSynthesized() const - { - return m_demangled_is_synthesized; - } + void SetSizeIsSibling(bool b) { m_size_is_sibling = b; } - void - SetDemangledNameIsSynthesized(bool b) - { - m_demangled_is_synthesized = b; - } + // If m_type is "Code" or "Function" then this will return the prologue size + // in bytes, else it will return zero. + uint32_t GetPrologueByteSize(); - bool - ContainsLinkerAnnotations() const - { - return m_contains_linker_annotations; - } - void - SetContainsLinkerAnnotations(bool b) - { - m_contains_linker_annotations = b; - } - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - CalculateSymbolContext(SymbolContext *sc) override; - - lldb::ModuleSP - CalculateSymbolContextModule() override; - - Symbol * - CalculateSymbolContextSymbol() override; - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - DumpSymbolContext(Stream *s) override; - - lldb::DisassemblerSP - GetInstructions (const ExecutionContext &exe_ctx, - const char *flavor, - bool prefer_file_cache); - - bool - GetDisassembly (const ExecutionContext &exe_ctx, - const char *flavor, - bool prefer_file_cache, - Stream &strm); - - bool - ContainsFileAddress (lldb::addr_t file_addr) const; + bool GetDemangledNameIsSynthesized() const { + return m_demangled_is_synthesized; + } + + void SetDemangledNameIsSynthesized(bool b) { m_demangled_is_synthesized = b; } + + bool ContainsLinkerAnnotations() const { + return m_contains_linker_annotations; + } + void SetContainsLinkerAnnotations(bool b) { + m_contains_linker_annotations = b; + } + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void CalculateSymbolContext(SymbolContext *sc) override; + + lldb::ModuleSP CalculateSymbolContextModule() override; + + Symbol *CalculateSymbolContextSymbol() override; + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void DumpSymbolContext(Stream *s) override; + + lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, + const char *flavor, + bool prefer_file_cache); + + bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, + bool prefer_file_cache, Stream &strm); + + bool ContainsFileAddress(lldb::addr_t file_addr) const; protected: - // This is the internal guts of ResolveReExportedSymbol, it assumes reexport_name is not null, and that module_spec - // is valid. We track the modules we've already seen to make sure we don't get caught in a cycle. - - Symbol * - ResolveReExportedSymbolInModuleSpec (Target &target, - ConstString &reexport_name, - lldb_private::ModuleSpec &module_spec, - lldb_private::ModuleList &seen_modules) const; - - uint32_t m_uid; // User ID (usually the original symbol table index) - uint16_t m_type_data; // data specific to m_type - uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated - m_is_synthetic:1, // non-zero if this symbol is not actually in the symbol table, but synthesized from other info in the object file. - m_is_debug:1, // non-zero if this symbol is debug information in a symbol - m_is_external:1, // non-zero if this symbol is globally visible - m_size_is_sibling:1, // m_size contains the index of this symbol's sibling - m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next - m_size_is_valid:1, - m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups - m_contains_linker_annotations:1, // The symbol name contains linker annotations, which are optional when doing name lookups - m_type:7; - Mangled m_mangled; // uniqued symbol name/mangled name pair - AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any) - uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these + // This is the internal guts of ResolveReExportedSymbol, it assumes + // reexport_name is not null, and that module_spec + // is valid. We track the modules we've already seen to make sure we don't + // get caught in a cycle. + + Symbol *ResolveReExportedSymbolInModuleSpec( + Target &target, ConstString &reexport_name, + lldb_private::ModuleSpec &module_spec, + lldb_private::ModuleList &seen_modules) const; + + uint32_t m_uid; // User ID (usually the original symbol table index) + uint16_t m_type_data; // data specific to m_type + uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has + // already been calculated + m_is_synthetic : 1, // non-zero if this symbol is not actually in the + // symbol table, but synthesized from other info in + // the object file. + m_is_debug : 1, // non-zero if this symbol is debug information in a + // symbol + m_is_external : 1, // non-zero if this symbol is globally visible + m_size_is_sibling : 1, // m_size contains the index of this symbol's + // sibling + m_size_is_synthesized : 1, // non-zero if this symbol's size was + // calculated using a delta between this symbol + // and the next + m_size_is_valid : 1, + m_demangled_is_synthesized : 1, // The demangled name was created should + // not be used for expressions or other + // lookups + m_contains_linker_annotations : 1, // The symbol name contains linker + // annotations, which are optional when + // doing name lookups + m_type : 7; + Mangled m_mangled; // uniqued symbol name/mangled name pair + AddressRange m_addr_range; // Contains the value, or the section offset + // address when the value is an address in a + // section, and the size (if any) + uint32_t m_flags; // A copy of the flags from the original symbol table, the + // ObjectFile plug-in can interpret these }; } // namespace lldb_private diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index f0e8e3590a8a..2ca3fdb71286 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -18,11 +18,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/Address.h" #include "lldb/Core/Mangled.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Utility/Iterable.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -39,409 +39,380 @@ class SymbolContextScope; /// queries include /// @li Looking up a load address. //---------------------------------------------------------------------- -class SymbolContext -{ +class SymbolContext { public: - //------------------------------------------------------------------ - /// Default constructor. - /// - /// Initialize all pointer members to nullptr and all struct members - /// to their default state. - //------------------------------------------------------------------ - SymbolContext (); - - //------------------------------------------------------------------ - /// Construct with an object that knows how to reconstruct its - /// symbol context. - /// - /// @param[in] sc_scope - /// A symbol context scope object that knows how to reconstruct - /// it's context. - //------------------------------------------------------------------ - explicit - SymbolContext (SymbolContextScope *sc_scope); - - //------------------------------------------------------------------ - /// Construct with module, and optional compile unit, function, - /// block, line table, line entry and symbol. - /// - /// Initialize all pointer to the specified values. - /// - /// @param[in] module - /// A Module pointer to the module for this context. - /// - /// @param[in] comp_unit - /// A CompileUnit pointer to the compile unit for this context. - /// - /// @param[in] function - /// A Function pointer to the function for this context. - /// - /// @param[in] block - /// A Block pointer to the deepest block for this context. - /// - /// @param[in] line_entry - /// A LineEntry pointer to the line entry for this context. - /// - /// @param[in] symbol - /// A Symbol pointer to the symbol for this context. - //------------------------------------------------------------------ - explicit - SymbolContext(const lldb::TargetSP &target_sp, - const lldb::ModuleSP &module_sp, - CompileUnit *comp_unit = nullptr, - Function *function = nullptr, - Block *block = nullptr, - LineEntry *line_entry = nullptr, - Symbol *symbol = nullptr); - - // This version sets the target to a NULL TargetSP if you don't know it. - explicit - SymbolContext(const lldb::ModuleSP &module_sp, - CompileUnit *comp_unit = nullptr, - Function *function = nullptr, - Block *block = nullptr, - LineEntry *line_entry = nullptr, - Symbol *symbol = nullptr); - - //------------------------------------------------------------------ - /// Copy constructor - /// - /// Makes a copy of the another SymbolContext object \a rhs. - /// - /// @param[in] rhs - /// A const SymbolContext object reference to copy. - //------------------------------------------------------------------ - SymbolContext (const SymbolContext& rhs); - - ~SymbolContext (); - - //------------------------------------------------------------------ - /// Assignment operator. - /// - /// Copies the address value from another SymbolContext object \a - /// rhs into \a this object. - /// - /// @param[in] rhs - /// A const SymbolContext object reference to copy. - /// - /// @return - /// A const SymbolContext object reference to \a this. - //------------------------------------------------------------------ - const SymbolContext& - operator= (const SymbolContext& rhs); - - //------------------------------------------------------------------ - /// Clear the object's state. - /// - /// Resets all pointer members to nullptr, and clears any class objects - /// to their default state. - //------------------------------------------------------------------ - void - Clear (bool clear_target); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of this object to the - /// supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - void - Dump (Stream *s, Target *target) const; - - //------------------------------------------------------------------ - /// Dump the stop context in this object to a Stream. - /// - /// Dump the best description of this object to the stream. The - /// information displayed depends on the amount and quality of the - /// information in this context. If a module, function, file and - /// line number are available, they will be dumped. If only a - /// module and function or symbol name with offset is available, - /// that will be output. Else just the address at which the target - /// was stopped will be displayed. - /// - /// @param[in] s - /// The stream to which to dump the object description. - /// - /// @param[in] so_addr - /// The resolved section offset address. - /// - /// @param[in] show_fullpaths - /// When printing file paths (with the Module), whether the - /// base name of the Module should be printed or the full path. - /// - /// @param[in] show_module - /// Whether the module name should be printed followed by a - /// grave accent "`" character. - /// - /// @param[in] show_inlined_frames - /// If a given pc is in inlined function(s), whether the inlined - /// functions should be printed on separate lines in addition to - /// the concrete function containing the pc. - /// - /// @param[in] show_function_arguments - /// If false, this method will try to elide the function argument - /// types when printing the function name. This may be ambiguous - /// for languages that have function overloading - but it may - /// make the "function name" too long to include all the argument - /// types. - /// - /// @param[in] show_function_name - /// Normally this should be true - the function/symbol name should - /// be printed. In disassembly formatting, where we want a format - /// like "<*+36>", this should be false and "*" will be printed - /// instead. - //------------------------------------------------------------------ - bool - DumpStopContext (Stream *s, - ExecutionContextScope *exe_scope, - const Address &so_addr, - bool show_fullpaths, - bool show_module, - bool show_inlined_frames, - bool show_function_arguments, - bool show_function_name) const; - - //------------------------------------------------------------------ - /// Get the address range contained within a symbol context. - /// - /// Address range priority is as follows: - /// - line_entry address range if line_entry is valid and eSymbolContextLineEntry is set in \a scope - /// - block address range if block is not nullptr and eSymbolContextBlock is set in \a scope - /// - function address range if function is not nullptr and eSymbolContextFunction is set in \a scope - /// - symbol address range if symbol is not nullptr and eSymbolContextSymbol is set in \a scope - /// - /// @param[in] scope - /// A mask of symbol context bits telling this function which - /// address ranges it can use when trying to extract one from - /// the valid (non-nullptr) symbol context classes. - /// - /// @param[in] range_idx - /// The address range index to grab. Since many functions and - /// blocks are not always contiguous, they may have more than - /// one address range. - /// - /// @param[in] use_inline_block_range - /// If \a scope has the eSymbolContextBlock bit set, and there - /// is a valid block in the symbol context, return the block - /// address range for the containing inline function block, not - /// the deepest most block. This allows us to extract information - /// for the address range of the inlined function block, not - /// the deepest lexical block. - /// - /// @param[out] range - /// An address range object that will be filled in if \b true - /// is returned. - /// - /// @return - /// \b True if this symbol context contains items that describe - /// an address range, \b false otherwise. - //------------------------------------------------------------------ - bool - GetAddressRange (uint32_t scope, - uint32_t range_idx, - bool use_inline_block_range, - AddressRange &range) const; - - bool - GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Error &error); - - void - GetDescription(Stream *s, - lldb::DescriptionLevel level, - Target *target) const; - - uint32_t - GetResolvedMask () const; - - lldb::LanguageType - GetLanguage () const; - - //------------------------------------------------------------------ - /// Find a block that defines the function represented by this - /// symbol context. - /// - /// If this symbol context points to a block that is an inlined - /// function, or is contained within an inlined function, the block - /// that defines the inlined function is returned. - /// - /// If this symbol context has no block in it, or the block is not - /// itself an inlined function block or contained within one, we - /// return the top level function block. - /// - /// This is a handy function to call when you want to get the block - /// whose variable list will include the arguments for the function - /// that is represented by this symbol context (whether the function - /// is an inline function or not). - /// - /// @return - /// The block object pointer that defines the function that is - /// represented by this symbol context object, nullptr otherwise. - //------------------------------------------------------------------ - Block * - GetFunctionBlock (); - - //------------------------------------------------------------------ - /// If this symbol context represents a function that is a method, - /// return true and provide information about the method. - /// - /// @param[out] language - /// If \b true is returned, the language for the method. - /// - /// @param[out] is_instance_method - /// If \b true is returned, \b true if this is a instance method, - /// \b false if this is a static/class function. - /// - /// @param[out] language_object_name - /// If \b true is returned, the name of the artificial variable - /// for the language ("this" for C++, "self" for ObjC). - /// - /// @return - /// \b True if this symbol context represents a function that - /// is a method of a class, \b false otherwise. - //------------------------------------------------------------------ - bool - GetFunctionMethodInfo (lldb::LanguageType &language, - bool &is_instance_method, - ConstString &language_object_name); - - //------------------------------------------------------------------ - /// Sorts the types in TypeMap according to SymbolContext - /// to TypeList - /// - //------------------------------------------------------------------ - void - SortTypeList(TypeMap &type_map, TypeList &type_list) const; - - //------------------------------------------------------------------ - /// Find a name of the innermost function for the symbol context. - /// - /// For instance, if the symbol context contains an inlined block, - /// it will return the inlined function name. - /// - /// @param[in] prefer_mangled - /// if \btrue, then the mangled name will be returned if there - /// is one. Otherwise the unmangled name will be returned if it - /// is available. - /// - /// @return - /// The name of the function represented by this symbol context. - //------------------------------------------------------------------ - ConstString - GetFunctionName (Mangled::NamePreference preference = Mangled::ePreferDemangled) const; - - //------------------------------------------------------------------ - /// Get the line entry that corresponds to the function. - /// - /// If the symbol context contains an inlined block, the line entry - /// for the start address of the inlined function will be returned, - /// otherwise the line entry for the start address of the function - /// will be returned. This can be used after doing a - /// Module::FindFunctions(...) or ModuleList::FindFunctions(...) - /// call in order to get the correct line table information for - /// the symbol context. - /// it will return the inlined function name. - /// - /// @param[in] prefer_mangled - /// if \btrue, then the mangled name will be returned if there - /// is one. Otherwise the unmangled name will be returned if it - /// is available. - /// - /// @return - /// The name of the function represented by this symbol context. - //------------------------------------------------------------------ - LineEntry - GetFunctionStartLineEntry () const; - - //------------------------------------------------------------------ - /// Find the block containing the inlined block that contains this block. - /// - /// For instance, if the symbol context contains an inlined block, - /// it will return the inlined function name. - /// - /// @param[in] curr_frame_pc - /// The address within the block of this object. - /// - /// @param[out] next_frame_sc - /// A new symbol context that does what the title says it does. - /// - /// @param[out] next_frame_addr - /// This is what you should report as the PC in \a next_frame_sc. - /// - /// @return - /// \b true if this SymbolContext specifies a block contained in an - /// inlined block. If this returns \b true, \a next_frame_sc and - /// \a next_frame_addr will be filled in correctly. - //------------------------------------------------------------------ - bool - GetParentOfInlinedScope (const Address &curr_frame_pc, - SymbolContext &next_frame_sc, - Address &inlined_frame_addr) const; - - //------------------------------------------------------------------ - // Member variables - //------------------------------------------------------------------ - lldb::TargetSP target_sp; ///< The Target for a given query - lldb::ModuleSP module_sp; ///< The Module for a given query - CompileUnit * comp_unit; ///< The CompileUnit for a given query - Function * function; ///< The Function for a given query - Block * block; ///< The Block for a given query - LineEntry line_entry; ///< The LineEntry for a given query - Symbol * symbol; ///< The Symbol for a given query - Variable * variable; ///< The global variable matching the given query + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize all pointer members to nullptr and all struct members + /// to their default state. + //------------------------------------------------------------------ + SymbolContext(); + + //------------------------------------------------------------------ + /// Construct with an object that knows how to reconstruct its + /// symbol context. + /// + /// @param[in] sc_scope + /// A symbol context scope object that knows how to reconstruct + /// it's context. + //------------------------------------------------------------------ + explicit SymbolContext(SymbolContextScope *sc_scope); + + //------------------------------------------------------------------ + /// Construct with module, and optional compile unit, function, + /// block, line table, line entry and symbol. + /// + /// Initialize all pointer to the specified values. + /// + /// @param[in] module + /// A Module pointer to the module for this context. + /// + /// @param[in] comp_unit + /// A CompileUnit pointer to the compile unit for this context. + /// + /// @param[in] function + /// A Function pointer to the function for this context. + /// + /// @param[in] block + /// A Block pointer to the deepest block for this context. + /// + /// @param[in] line_entry + /// A LineEntry pointer to the line entry for this context. + /// + /// @param[in] symbol + /// A Symbol pointer to the symbol for this context. + //------------------------------------------------------------------ + explicit SymbolContext(const lldb::TargetSP &target_sp, + const lldb::ModuleSP &module_sp, + CompileUnit *comp_unit = nullptr, + Function *function = nullptr, Block *block = nullptr, + LineEntry *line_entry = nullptr, + Symbol *symbol = nullptr); + + // This version sets the target to a NULL TargetSP if you don't know it. + explicit SymbolContext(const lldb::ModuleSP &module_sp, + CompileUnit *comp_unit = nullptr, + Function *function = nullptr, Block *block = nullptr, + LineEntry *line_entry = nullptr, + Symbol *symbol = nullptr); + + //------------------------------------------------------------------ + /// Copy constructor + /// + /// Makes a copy of the another SymbolContext object \a rhs. + /// + /// @param[in] rhs + /// A const SymbolContext object reference to copy. + //------------------------------------------------------------------ + SymbolContext(const SymbolContext &rhs); + + ~SymbolContext(); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies the address value from another SymbolContext object \a + /// rhs into \a this object. + /// + /// @param[in] rhs + /// A const SymbolContext object reference to copy. + /// + /// @return + /// A const SymbolContext object reference to \a this. + //------------------------------------------------------------------ + const SymbolContext &operator=(const SymbolContext &rhs); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Resets all pointer members to nullptr, and clears any class objects + /// to their default state. + //------------------------------------------------------------------ + void Clear(bool clear_target); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + void Dump(Stream *s, Target *target) const; + + //------------------------------------------------------------------ + /// Dump the stop context in this object to a Stream. + /// + /// Dump the best description of this object to the stream. The + /// information displayed depends on the amount and quality of the + /// information in this context. If a module, function, file and + /// line number are available, they will be dumped. If only a + /// module and function or symbol name with offset is available, + /// that will be output. Else just the address at which the target + /// was stopped will be displayed. + /// + /// @param[in] s + /// The stream to which to dump the object description. + /// + /// @param[in] so_addr + /// The resolved section offset address. + /// + /// @param[in] show_fullpaths + /// When printing file paths (with the Module), whether the + /// base name of the Module should be printed or the full path. + /// + /// @param[in] show_module + /// Whether the module name should be printed followed by a + /// grave accent "`" character. + /// + /// @param[in] show_inlined_frames + /// If a given pc is in inlined function(s), whether the inlined + /// functions should be printed on separate lines in addition to + /// the concrete function containing the pc. + /// + /// @param[in] show_function_arguments + /// If false, this method will try to elide the function argument + /// types when printing the function name. This may be ambiguous + /// for languages that have function overloading - but it may + /// make the "function name" too long to include all the argument + /// types. + /// + /// @param[in] show_function_name + /// Normally this should be true - the function/symbol name should + /// be printed. In disassembly formatting, where we want a format + /// like "<*+36>", this should be false and "*" will be printed + /// instead. + //------------------------------------------------------------------ + bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, + const Address &so_addr, bool show_fullpaths, + bool show_module, bool show_inlined_frames, + bool show_function_arguments, + bool show_function_name) const; + + //------------------------------------------------------------------ + /// Get the address range contained within a symbol context. + /// + /// Address range priority is as follows: + /// - line_entry address range if line_entry is valid and + /// eSymbolContextLineEntry is set in \a scope + /// - block address range if block is not nullptr and eSymbolContextBlock + /// is set in \a scope + /// - function address range if function is not nullptr and + /// eSymbolContextFunction is set in \a scope + /// - symbol address range if symbol is not nullptr and + /// eSymbolContextSymbol is set in \a scope + /// + /// @param[in] scope + /// A mask of symbol context bits telling this function which + /// address ranges it can use when trying to extract one from + /// the valid (non-nullptr) symbol context classes. + /// + /// @param[in] range_idx + /// The address range index to grab. Since many functions and + /// blocks are not always contiguous, they may have more than + /// one address range. + /// + /// @param[in] use_inline_block_range + /// If \a scope has the eSymbolContextBlock bit set, and there + /// is a valid block in the symbol context, return the block + /// address range for the containing inline function block, not + /// the deepest most block. This allows us to extract information + /// for the address range of the inlined function block, not + /// the deepest lexical block. + /// + /// @param[out] range + /// An address range object that will be filled in if \b true + /// is returned. + /// + /// @return + /// \b True if this symbol context contains items that describe + /// an address range, \b false otherwise. + //------------------------------------------------------------------ + bool GetAddressRange(uint32_t scope, uint32_t range_idx, + bool use_inline_block_range, AddressRange &range) const; + + bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, + Error &error); + + void GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target) const; + + uint32_t GetResolvedMask() const; + + lldb::LanguageType GetLanguage() const; + + //------------------------------------------------------------------ + /// Find a block that defines the function represented by this + /// symbol context. + /// + /// If this symbol context points to a block that is an inlined + /// function, or is contained within an inlined function, the block + /// that defines the inlined function is returned. + /// + /// If this symbol context has no block in it, or the block is not + /// itself an inlined function block or contained within one, we + /// return the top level function block. + /// + /// This is a handy function to call when you want to get the block + /// whose variable list will include the arguments for the function + /// that is represented by this symbol context (whether the function + /// is an inline function or not). + /// + /// @return + /// The block object pointer that defines the function that is + /// represented by this symbol context object, nullptr otherwise. + //------------------------------------------------------------------ + Block *GetFunctionBlock(); + + //------------------------------------------------------------------ + /// If this symbol context represents a function that is a method, + /// return true and provide information about the method. + /// + /// @param[out] language + /// If \b true is returned, the language for the method. + /// + /// @param[out] is_instance_method + /// If \b true is returned, \b true if this is a instance method, + /// \b false if this is a static/class function. + /// + /// @param[out] language_object_name + /// If \b true is returned, the name of the artificial variable + /// for the language ("this" for C++, "self" for ObjC). + /// + /// @return + /// \b True if this symbol context represents a function that + /// is a method of a class, \b false otherwise. + //------------------------------------------------------------------ + bool GetFunctionMethodInfo(lldb::LanguageType &language, + bool &is_instance_method, + ConstString &language_object_name); + + //------------------------------------------------------------------ + /// Sorts the types in TypeMap according to SymbolContext + /// to TypeList + /// + //------------------------------------------------------------------ + void SortTypeList(TypeMap &type_map, TypeList &type_list) const; + + //------------------------------------------------------------------ + /// Find a name of the innermost function for the symbol context. + /// + /// For instance, if the symbol context contains an inlined block, + /// it will return the inlined function name. + /// + /// @param[in] prefer_mangled + /// if \btrue, then the mangled name will be returned if there + /// is one. Otherwise the unmangled name will be returned if it + /// is available. + /// + /// @return + /// The name of the function represented by this symbol context. + //------------------------------------------------------------------ + ConstString GetFunctionName( + Mangled::NamePreference preference = Mangled::ePreferDemangled) const; + + //------------------------------------------------------------------ + /// Get the line entry that corresponds to the function. + /// + /// If the symbol context contains an inlined block, the line entry + /// for the start address of the inlined function will be returned, + /// otherwise the line entry for the start address of the function + /// will be returned. This can be used after doing a + /// Module::FindFunctions(...) or ModuleList::FindFunctions(...) + /// call in order to get the correct line table information for + /// the symbol context. + /// it will return the inlined function name. + /// + /// @param[in] prefer_mangled + /// if \btrue, then the mangled name will be returned if there + /// is one. Otherwise the unmangled name will be returned if it + /// is available. + /// + /// @return + /// The name of the function represented by this symbol context. + //------------------------------------------------------------------ + LineEntry GetFunctionStartLineEntry() const; + + //------------------------------------------------------------------ + /// Find the block containing the inlined block that contains this block. + /// + /// For instance, if the symbol context contains an inlined block, + /// it will return the inlined function name. + /// + /// @param[in] curr_frame_pc + /// The address within the block of this object. + /// + /// @param[out] next_frame_sc + /// A new symbol context that does what the title says it does. + /// + /// @param[out] next_frame_addr + /// This is what you should report as the PC in \a next_frame_sc. + /// + /// @return + /// \b true if this SymbolContext specifies a block contained in an + /// inlined block. If this returns \b true, \a next_frame_sc and + /// \a next_frame_addr will be filled in correctly. + //------------------------------------------------------------------ + bool GetParentOfInlinedScope(const Address &curr_frame_pc, + SymbolContext &next_frame_sc, + Address &inlined_frame_addr) const; + + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + lldb::TargetSP target_sp; ///< The Target for a given query + lldb::ModuleSP module_sp; ///< The Module for a given query + CompileUnit *comp_unit; ///< The CompileUnit for a given query + Function *function; ///< The Function for a given query + Block *block; ///< The Block for a given query + LineEntry line_entry; ///< The LineEntry for a given query + Symbol *symbol; ///< The Symbol for a given query + Variable *variable; ///< The global variable matching the given query }; -class SymbolContextSpecifier -{ +class SymbolContextSpecifier { public: - typedef enum SpecificationType - { - eNothingSpecified = 0, - eModuleSpecified = 1 << 0, - eFileSpecified = 1 << 1, - eLineStartSpecified = 1 << 2, - eLineEndSpecified = 1 << 3, - eFunctionSpecified = 1 << 4, - eClassOrNamespaceSpecified = 1 << 5, - eAddressRangeSpecified = 1 << 6 - } SpecificationType; - - // This one produces a specifier that matches everything... - SymbolContextSpecifier (const lldb::TargetSP& target_sp); - - ~SymbolContextSpecifier(); - - bool - AddSpecification (const char *spec_string, SpecificationType type); - - bool - AddLineSpecification (uint32_t line_no, SpecificationType type); - - void - Clear(); - - bool - SymbolContextMatches(SymbolContext &sc); - - bool - AddressMatches(lldb::addr_t addr); - - void - GetDescription (Stream *s, lldb::DescriptionLevel level) const; + typedef enum SpecificationType { + eNothingSpecified = 0, + eModuleSpecified = 1 << 0, + eFileSpecified = 1 << 1, + eLineStartSpecified = 1 << 2, + eLineEndSpecified = 1 << 3, + eFunctionSpecified = 1 << 4, + eClassOrNamespaceSpecified = 1 << 5, + eAddressRangeSpecified = 1 << 6 + } SpecificationType; + + // This one produces a specifier that matches everything... + SymbolContextSpecifier(const lldb::TargetSP &target_sp); + + ~SymbolContextSpecifier(); + + bool AddSpecification(const char *spec_string, SpecificationType type); + + bool AddLineSpecification(uint32_t line_no, SpecificationType type); + + void Clear(); + + bool SymbolContextMatches(SymbolContext &sc); + + bool AddressMatches(lldb::addr_t addr); + + void GetDescription(Stream *s, lldb::DescriptionLevel level) const; private: - lldb::TargetSP m_target_sp; - std::string m_module_spec; - lldb::ModuleSP m_module_sp; - std::unique_ptr<FileSpec> m_file_spec_ap; - size_t m_start_line; - size_t m_end_line; - std::string m_function_spec; - std::string m_class_name; - std::unique_ptr<AddressRange> m_address_range_ap; - uint32_t m_type; // Or'ed bits from SpecificationType + lldb::TargetSP m_target_sp; + std::string m_module_spec; + lldb::ModuleSP m_module_sp; + std::unique_ptr<FileSpec> m_file_spec_ap; + size_t m_start_line; + size_t m_end_line; + std::string m_function_spec; + std::string m_class_name; + std::unique_ptr<AddressRange> m_address_range_ap; + uint32_t m_type; // Or'ed bits from SpecificationType }; //---------------------------------------------------------------------- @@ -454,165 +425,143 @@ private: /// @li Looking up a function by name. /// @li Finding all addresses for a specified file and line number. //---------------------------------------------------------------------- -class SymbolContextList -{ +class SymbolContextList { public: - //------------------------------------------------------------------ - /// Default constructor. - /// - /// Initialize with an empty list. - //------------------------------------------------------------------ - SymbolContextList (); - - //------------------------------------------------------------------ - /// Destructor. - //------------------------------------------------------------------ - ~SymbolContextList (); - - //------------------------------------------------------------------ - /// Append a new symbol context to the list. - /// - /// @param[in] sc - /// A symbol context to append to the list. - //------------------------------------------------------------------ - void - Append (const SymbolContext& sc); - - void - Append (const SymbolContextList& sc_list); - - bool - AppendIfUnique (const SymbolContext& sc, - bool merge_symbol_into_function); - - bool - MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc, - uint32_t start_idx = 0, - uint32_t stop_idx = UINT32_MAX); - - uint32_t - AppendIfUnique (const SymbolContextList& sc_list, - bool merge_symbol_into_function); - - //------------------------------------------------------------------ - /// Clear the object's state. - /// - /// Clears the symbol context list. - //------------------------------------------------------------------ - void - Clear(); - - //------------------------------------------------------------------ - /// Dump a description of this object to a Stream. - /// - /// Dump a description of the contents of each symbol context in - /// the list to the supplied stream \a s. - /// - /// @param[in] s - /// The stream to which to dump the object description. - //------------------------------------------------------------------ - void - Dump(Stream *s, Target *target) const; - - //------------------------------------------------------------------ - /// Get accessor for a symbol context at index \a idx. - /// - /// Dump a description of the contents of each symbol context in - /// the list to the supplied stream \a s. - /// - /// @param[in] idx - /// The zero based index into the symbol context list. - /// - /// @param[out] sc - /// A reference to the symbol context to fill in. - /// - /// @return - /// Returns \b true if \a idx was a valid index into this - /// symbol context list and \a sc was filled in, \b false - /// otherwise. - //------------------------------------------------------------------ - bool - GetContextAtIndex(size_t idx, SymbolContext& sc) const; - - //------------------------------------------------------------------ - /// Direct reference accessor for a symbol context at index \a idx. - /// - /// The index \a idx must be a valid index, no error checking will - /// be done to ensure that it is valid. - /// - /// @param[in] idx - /// The zero based index into the symbol context list. - /// - /// @return - /// A const reference to the symbol context to fill in. - //------------------------------------------------------------------ - SymbolContext& - operator [] (size_t idx) - { - return m_symbol_contexts[idx]; - } - - const SymbolContext& - operator [] (size_t idx) const - { - return m_symbol_contexts[idx]; - } - - //------------------------------------------------------------------ - /// Get accessor for the last symbol context in the list. - /// - /// @param[out] sc - /// A reference to the symbol context to fill in. - /// - /// @return - /// Returns \b true if \a sc was filled in, \b false if the - /// list is empty. - //------------------------------------------------------------------ - bool - GetLastContext(SymbolContext& sc) const; - - bool - RemoveContextAtIndex (size_t idx); - - //------------------------------------------------------------------ - /// Get accessor for a symbol context list size. - /// - /// @return - /// Returns the number of symbol context objects in the list. - //------------------------------------------------------------------ - uint32_t - GetSize() const; - - uint32_t - NumLineEntriesWithLine (uint32_t line) const; - - void - GetDescription(Stream *s, - lldb::DescriptionLevel level, - Target *target) const; + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize with an empty list. + //------------------------------------------------------------------ + SymbolContextList(); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~SymbolContextList(); + + //------------------------------------------------------------------ + /// Append a new symbol context to the list. + /// + /// @param[in] sc + /// A symbol context to append to the list. + //------------------------------------------------------------------ + void Append(const SymbolContext &sc); + + void Append(const SymbolContextList &sc_list); + + bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function); + + bool MergeSymbolContextIntoFunctionContext(const SymbolContext &symbol_sc, + uint32_t start_idx = 0, + uint32_t stop_idx = UINT32_MAX); + + uint32_t AppendIfUnique(const SymbolContextList &sc_list, + bool merge_symbol_into_function); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Clears the symbol context list. + //------------------------------------------------------------------ + void Clear(); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of each symbol context in + /// the list to the supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object description. + //------------------------------------------------------------------ + void Dump(Stream *s, Target *target) const; + + //------------------------------------------------------------------ + /// Get accessor for a symbol context at index \a idx. + /// + /// Dump a description of the contents of each symbol context in + /// the list to the supplied stream \a s. + /// + /// @param[in] idx + /// The zero based index into the symbol context list. + /// + /// @param[out] sc + /// A reference to the symbol context to fill in. + /// + /// @return + /// Returns \b true if \a idx was a valid index into this + /// symbol context list and \a sc was filled in, \b false + /// otherwise. + //------------------------------------------------------------------ + bool GetContextAtIndex(size_t idx, SymbolContext &sc) const; + + //------------------------------------------------------------------ + /// Direct reference accessor for a symbol context at index \a idx. + /// + /// The index \a idx must be a valid index, no error checking will + /// be done to ensure that it is valid. + /// + /// @param[in] idx + /// The zero based index into the symbol context list. + /// + /// @return + /// A const reference to the symbol context to fill in. + //------------------------------------------------------------------ + SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; } + + const SymbolContext &operator[](size_t idx) const { + return m_symbol_contexts[idx]; + } + + //------------------------------------------------------------------ + /// Get accessor for the last symbol context in the list. + /// + /// @param[out] sc + /// A reference to the symbol context to fill in. + /// + /// @return + /// Returns \b true if \a sc was filled in, \b false if the + /// list is empty. + //------------------------------------------------------------------ + bool GetLastContext(SymbolContext &sc) const; + + bool RemoveContextAtIndex(size_t idx); + + //------------------------------------------------------------------ + /// Get accessor for a symbol context list size. + /// + /// @return + /// Returns the number of symbol context objects in the list. + //------------------------------------------------------------------ + uint32_t GetSize() const; + + uint32_t NumLineEntriesWithLine(uint32_t line) const; + + void GetDescription(Stream *s, lldb::DescriptionLevel level, + Target *target) const; protected: - typedef std::vector<SymbolContext> collection; ///< The collection type for the list. + typedef std::vector<SymbolContext> + collection; ///< The collection type for the list. - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - collection m_symbol_contexts; ///< The list of symbol contexts. + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + collection m_symbol_contexts; ///< The list of symbol contexts. public: - typedef AdaptedIterable<collection, SymbolContext, vector_adapter> SymbolContextIterable; - SymbolContextIterable - SymbolContexts() - { - return SymbolContextIterable(m_symbol_contexts); - } + typedef AdaptedIterable<collection, SymbolContext, vector_adapter> + SymbolContextIterable; + SymbolContextIterable SymbolContexts() { + return SymbolContextIterable(m_symbol_contexts); + } }; -bool operator== (const SymbolContext& lhs, const SymbolContext& rhs); -bool operator!= (const SymbolContext& lhs, const SymbolContext& rhs); +bool operator==(const SymbolContext &lhs, const SymbolContext &rhs); +bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs); -bool operator== (const SymbolContextList& lhs, const SymbolContextList& rhs); -bool operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs); +bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs); +bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs); } // namespace lldb_private diff --git a/include/lldb/Symbol/SymbolContextScope.h b/include/lldb/Symbol/SymbolContextScope.h index 212d8e6df233..926e34bc03a2 100644 --- a/include/lldb/Symbol/SymbolContextScope.h +++ b/include/lldb/Symbol/SymbolContextScope.h @@ -19,16 +19,17 @@ namespace lldb_private { //---------------------------------------------------------------------- -/// @class SymbolContextScope SymbolContextScope.h "lldb/Symbol/SymbolContextScope.h" +/// @class SymbolContextScope SymbolContextScope.h +/// "lldb/Symbol/SymbolContextScope.h" /// @brief Inherit from this if your object is part of a symbol context /// and can reconstruct its symbol context. /// /// Many objects that are part of a symbol context that have pointers -/// back to parent objects that own them. Any members of a symbol +/// back to parent objects that own them. Any members of a symbol /// context that, once they are built, will not go away, can inherit /// from this pure virtual class and can then reconstruct their symbol -/// context without having to keep a complete SymbolContext object in -/// the object. +/// context without having to keep a complete SymbolContext object in +/// the object. /// /// Examples of these objects include: /// @li Module @@ -38,7 +39,7 @@ namespace lldb_private { /// @li Symbol /// /// Other objects can store a "SymbolContextScope *" using any pointers -/// to one of the above objects. This allows clients to hold onto a +/// to one of the above objects. This allows clients to hold onto a /// pointer that uniquely will identify a symbol context. Those clients /// can then always reconstruct the symbol context using the pointer, or /// use it to uniquely identify a symbol context for an object. @@ -53,12 +54,12 @@ namespace lldb_private { /// in which the variable is defined. Function arguments can use /// the Function object as their scope. The SymbolFile parsers /// will set these correctly as the variables are parsed. -/// @li Type objects that know exactly in which scope they +/// @li Type objects that know exactly in which scope they /// originated much like the variables above. -/// @li StackID objects that are able to know that if the CFA -/// (stack pointer at the beginning of a function) and the +/// @li StackID objects that are able to know that if the CFA +/// (stack pointer at the beginning of a function) and the /// start PC for the function/symbol and the SymbolContextScope -/// pointer (a unique pointer that identifies a symbol context +/// pointer (a unique pointer that identifies a symbol context /// location) match within the same thread, that the stack /// frame is the same as the previous stack frame. /// @@ -68,67 +69,45 @@ namespace lldb_private { /// and object pairs that allow large collections of objects to be /// passed around with minimal overhead. //---------------------------------------------------------------------- -class SymbolContextScope -{ +class SymbolContextScope { public: - virtual - ~SymbolContextScope() = default; + virtual ~SymbolContextScope() = default; - //------------------------------------------------------------------ - /// Reconstruct the object's symbol context into \a sc. - /// - /// The object should fill in as much of the SymbolContext as it - /// can so function calls that require a symbol context can be made - /// for the given object. - /// - /// @param[out] sc - /// A symbol context object pointer that gets filled in. - //------------------------------------------------------------------ - virtual void - CalculateSymbolContext (SymbolContext *sc) = 0; + //------------------------------------------------------------------ + /// Reconstruct the object's symbol context into \a sc. + /// + /// The object should fill in as much of the SymbolContext as it + /// can so function calls that require a symbol context can be made + /// for the given object. + /// + /// @param[out] sc + /// A symbol context object pointer that gets filled in. + //------------------------------------------------------------------ + virtual void CalculateSymbolContext(SymbolContext *sc) = 0; - virtual lldb::ModuleSP - CalculateSymbolContextModule () - { - return lldb::ModuleSP(); - } + virtual lldb::ModuleSP CalculateSymbolContextModule() { + return lldb::ModuleSP(); + } - virtual CompileUnit * - CalculateSymbolContextCompileUnit () - { - return nullptr; - } + virtual CompileUnit *CalculateSymbolContextCompileUnit() { return nullptr; } - virtual Function * - CalculateSymbolContextFunction () - { - return nullptr; - } + virtual Function *CalculateSymbolContextFunction() { return nullptr; } - virtual Block * - CalculateSymbolContextBlock () - { - return nullptr; - } + virtual Block *CalculateSymbolContextBlock() { return nullptr; } - virtual Symbol * - CalculateSymbolContextSymbol () - { - return nullptr; - } + virtual Symbol *CalculateSymbolContextSymbol() { return nullptr; } - //------------------------------------------------------------------ - /// Dump the object's symbol context to the stream \a s. - /// - /// The object should dump its symbol context to the stream \a s. - /// This function is widely used in the DumpDebug and verbose output - /// for lldb objects. - /// - /// @param[in] s - /// The stream to which to dump the object's symbol context. - //------------------------------------------------------------------ - virtual void - DumpSymbolContext (Stream *s) = 0; + //------------------------------------------------------------------ + /// Dump the object's symbol context to the stream \a s. + /// + /// The object should dump its symbol context to the stream \a s. + /// This function is widely used in the DumpDebug and verbose output + /// for lldb objects. + /// + /// @param[in] s + /// The stream to which to dump the object's symbol context. + //------------------------------------------------------------------ + virtual void DumpSymbolContext(Stream *s) = 0; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h index db97ab4f9b65..34ae8d76e195 100644 --- a/include/lldb/Symbol/SymbolFile.h +++ b/include/lldb/Symbol/SymbolFile.h @@ -10,184 +10,201 @@ #ifndef liblldb_SymbolFile_h_ #define liblldb_SymbolFile_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" +#include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" namespace lldb_private { -class SymbolFile : - public PluginInterface -{ +class SymbolFile : public PluginInterface { public: - //------------------------------------------------------------------ - // Symbol file ability bits. - // - // Each symbol file can claim to support one or more symbol file - // abilities. These get returned from SymbolFile::GetAbilities(). - // These help us to determine which plug-in will be best to load - // the debug information found in files. - //------------------------------------------------------------------ - enum Abilities - { - CompileUnits = (1u << 0), - LineTables = (1u << 1), - Functions = (1u << 2), - Blocks = (1u << 3), - GlobalVariables = (1u << 4), - LocalVariables = (1u << 5), - VariableTypes = (1u << 6), - kAllAbilities =((1u << 7) - 1u) - }; - - static SymbolFile * - FindPlugin (ObjectFile* obj_file); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - SymbolFile(ObjectFile* obj_file) : - m_obj_file(obj_file), - m_abilities(0), - m_calculated_abilities(false) - { - } - - ~SymbolFile() override - { + //------------------------------------------------------------------ + // Symbol file ability bits. + // + // Each symbol file can claim to support one or more symbol file + // abilities. These get returned from SymbolFile::GetAbilities(). + // These help us to determine which plug-in will be best to load + // the debug information found in files. + //------------------------------------------------------------------ + enum Abilities { + CompileUnits = (1u << 0), + LineTables = (1u << 1), + Functions = (1u << 2), + Blocks = (1u << 3), + GlobalVariables = (1u << 4), + LocalVariables = (1u << 5), + VariableTypes = (1u << 6), + kAllAbilities = ((1u << 7) - 1u) + }; + + static SymbolFile *FindPlugin(ObjectFile *obj_file); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFile(ObjectFile *obj_file) + : m_obj_file(obj_file), m_abilities(0), m_calculated_abilities(false) {} + + ~SymbolFile() override {} + + //------------------------------------------------------------------ + /// Get a mask of what this symbol file supports for the object file + /// that it was constructed with. + /// + /// Each symbol file gets to respond with a mask of abilities that + /// it supports for each object file. This happens when we are + /// trying to figure out which symbol file plug-in will get used + /// for a given object file. The plug-in that responds with the + /// best mix of "SymbolFile::Abilities" bits set, will get chosen to + /// be the symbol file parser. This allows each plug-in to check for + /// sections that contain data a symbol file plug-in would need. For + /// example the DWARF plug-in requires DWARF sections in a file that + /// contain debug information. If the DWARF plug-in doesn't find + /// these sections, it won't respond with many ability bits set, and + /// we will probably fall back to the symbol table SymbolFile plug-in + /// which uses any information in the symbol table. Also, plug-ins + /// might check for some specific symbols in a symbol table in the + /// case where the symbol table contains debug information (STABS + /// and COFF). Not a lot of work should happen in these functions + /// as the plug-in might not get selected due to another plug-in + /// having more abilities. Any initialization work should be saved + /// for "void SymbolFile::InitializeObject()" which will get called + /// on the SymbolFile object with the best set of abilities. + /// + /// @return + /// A uint32_t mask containing bits from the SymbolFile::Abilities + /// enumeration. Any bits that are set represent an ability that + /// this symbol plug-in can parse from the object file. + ///------------------------------------------------------------------ + uint32_t GetAbilities() { + if (!m_calculated_abilities) { + m_abilities = CalculateAbilities(); + m_calculated_abilities = true; } - //------------------------------------------------------------------ - /// Get a mask of what this symbol file supports for the object file - /// that it was constructed with. - /// - /// Each symbol file gets to respond with a mask of abilities that - /// it supports for each object file. This happens when we are - /// trying to figure out which symbol file plug-in will get used - /// for a given object file. The plug-in that responds with the - /// best mix of "SymbolFile::Abilities" bits set, will get chosen to - /// be the symbol file parser. This allows each plug-in to check for - /// sections that contain data a symbol file plug-in would need. For - /// example the DWARF plug-in requires DWARF sections in a file that - /// contain debug information. If the DWARF plug-in doesn't find - /// these sections, it won't respond with many ability bits set, and - /// we will probably fall back to the symbol table SymbolFile plug-in - /// which uses any information in the symbol table. Also, plug-ins - /// might check for some specific symbols in a symbol table in the - /// case where the symbol table contains debug information (STABS - /// and COFF). Not a lot of work should happen in these functions - /// as the plug-in might not get selected due to another plug-in - /// having more abilities. Any initialization work should be saved - /// for "void SymbolFile::InitializeObject()" which will get called - /// on the SymbolFile object with the best set of abilities. - /// - /// @return - /// A uint32_t mask containing bits from the SymbolFile::Abilities - /// enumeration. Any bits that are set represent an ability that - /// this symbol plug-in can parse from the object file. - ///------------------------------------------------------------------ - uint32_t GetAbilities () - { - if (!m_calculated_abilities) - { - m_abilities = CalculateAbilities(); - m_calculated_abilities = true; - } - - return m_abilities; - } - - virtual uint32_t CalculateAbilities() = 0; - - //------------------------------------------------------------------ - /// Initialize the SymbolFile object. - /// - /// The SymbolFile object with the best set of abilities (detected - /// in "uint32_t SymbolFile::GetAbilities()) will have this function - /// called if it is chosen to parse an object file. More complete - /// initialization can happen in this function which will get called - /// prior to any other functions in the SymbolFile protocol. - //------------------------------------------------------------------ - virtual void InitializeObject() {} - - //------------------------------------------------------------------ - // Compile Unit function calls - //------------------------------------------------------------------ - // Approach 1 - iterator - virtual uint32_t GetNumCompileUnits() = 0; - virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0; - - virtual lldb::LanguageType ParseCompileUnitLanguage (const SymbolContext& sc) = 0; - virtual size_t ParseCompileUnitFunctions (const SymbolContext& sc) = 0; - virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0; - virtual bool ParseCompileUnitDebugMacros (const SymbolContext& sc) = 0; - virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0; - virtual bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) - { - return false; - } - virtual bool ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) = 0; - virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0; - virtual size_t ParseTypes (const SymbolContext& sc) = 0; - virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0; - virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0; - virtual bool CompleteType (CompilerType &compiler_type) = 0; - virtual void ParseDeclsForContext (CompilerDeclContext decl_ctx) {} - virtual CompilerDecl GetDeclForUID (lldb::user_id_t uid) { return CompilerDecl(); } - virtual CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) { return CompilerDeclContext(); } - virtual CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) { return CompilerDeclContext(); } - virtual uint32_t ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0; - virtual uint32_t ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list); - virtual uint32_t FindGlobalVariables (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, VariableList& variables); - virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables); - virtual uint32_t FindFunctions (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list); - virtual uint32_t FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list); - virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types); - virtual size_t FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types); - - virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names); -// virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0; - virtual TypeList * GetTypeList (); - virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, - lldb_private::TypeList &type_list) = 0; - - virtual lldb_private::TypeSystem * - GetTypeSystemForLanguage (lldb::LanguageType language); - - virtual CompilerDeclContext - FindNamespace (const SymbolContext& sc, - const ConstString &name, - const CompilerDeclContext *parent_decl_ctx) - { - return CompilerDeclContext(); - } - - ObjectFile* GetObjectFile() { return m_obj_file; } - const ObjectFile* GetObjectFile() const { return m_obj_file; } - - //------------------------------------------------------------------ - /// Notify the SymbolFile that the file addresses in the Sections - /// for this module have been changed. - //------------------------------------------------------------------ - virtual void - SectionFileAddressesChanged () - { - } + return m_abilities; + } + + virtual uint32_t CalculateAbilities() = 0; + + //------------------------------------------------------------------ + /// Initialize the SymbolFile object. + /// + /// The SymbolFile object with the best set of abilities (detected + /// in "uint32_t SymbolFile::GetAbilities()) will have this function + /// called if it is chosen to parse an object file. More complete + /// initialization can happen in this function which will get called + /// prior to any other functions in the SymbolFile protocol. + //------------------------------------------------------------------ + virtual void InitializeObject() {} + + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + // Approach 1 - iterator + virtual uint32_t GetNumCompileUnits() = 0; + virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0; + + virtual lldb::LanguageType + ParseCompileUnitLanguage(const SymbolContext &sc) = 0; + virtual size_t ParseCompileUnitFunctions(const SymbolContext &sc) = 0; + virtual bool ParseCompileUnitLineTable(const SymbolContext &sc) = 0; + virtual bool ParseCompileUnitDebugMacros(const SymbolContext &sc) = 0; + virtual bool ParseCompileUnitSupportFiles(const SymbolContext &sc, + FileSpecList &support_files) = 0; + virtual bool + ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) { + return false; + } + virtual bool + ParseImportedModules(const SymbolContext &sc, + std::vector<ConstString> &imported_modules) = 0; + virtual size_t ParseFunctionBlocks(const SymbolContext &sc) = 0; + virtual size_t ParseTypes(const SymbolContext &sc) = 0; + virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0; + virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0; + virtual bool CompleteType(CompilerType &compiler_type) = 0; + virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {} + virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { + return CompilerDecl(); + } + virtual CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) { + return CompilerDeclContext(); + } + virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) { + return CompilerDeclContext(); + } + virtual uint32_t ResolveSymbolContext(const Address &so_addr, + uint32_t resolve_scope, + SymbolContext &sc) = 0; + virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, + uint32_t line, bool check_inlines, + uint32_t resolve_scope, + SymbolContextList &sc_list); + virtual uint32_t + FindGlobalVariables(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, bool append, + uint32_t max_matches, VariableList &variables); + virtual uint32_t FindGlobalVariables(const RegularExpression ®ex, + bool append, uint32_t max_matches, + VariableList &variables); + virtual uint32_t FindFunctions(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + uint32_t name_type_mask, bool include_inlines, + bool append, SymbolContextList &sc_list); + virtual uint32_t FindFunctions(const RegularExpression ®ex, + bool include_inlines, bool append, + SymbolContextList &sc_list); + virtual uint32_t + FindTypes(const SymbolContext &sc, const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, bool append, + uint32_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, + TypeMap &types); + virtual size_t FindTypes(const std::vector<CompilerContext> &context, + bool append, TypeMap &types); + + virtual void + GetMangledNamesForFunction(const std::string &scope_qualified_name, + std::vector<ConstString> &mangled_names); + // virtual uint32_t FindTypes (const SymbolContext& sc, const + // RegularExpression& regex, bool append, uint32_t max_matches, TypeList& + // types) = 0; + virtual TypeList *GetTypeList(); + virtual size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, + uint32_t type_mask, + lldb_private::TypeList &type_list) = 0; + + virtual lldb_private::TypeSystem * + GetTypeSystemForLanguage(lldb::LanguageType language); + + virtual CompilerDeclContext + FindNamespace(const SymbolContext &sc, const ConstString &name, + const CompilerDeclContext *parent_decl_ctx) { + return CompilerDeclContext(); + } + + ObjectFile *GetObjectFile() { return m_obj_file; } + const ObjectFile *GetObjectFile() const { return m_obj_file; } + + //------------------------------------------------------------------ + /// Notify the SymbolFile that the file addresses in the Sections + /// for this module have been changed. + //------------------------------------------------------------------ + virtual void SectionFileAddressesChanged() {} protected: - ObjectFile* m_obj_file; // The object file that symbols can be extracted from. - uint32_t m_abilities; - bool m_calculated_abilities; + ObjectFile *m_obj_file; // The object file that symbols can be extracted from. + uint32_t m_abilities; + bool m_calculated_abilities; private: - DISALLOW_COPY_AND_ASSIGN (SymbolFile); + DISALLOW_COPY_AND_ASSIGN(SymbolFile); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h index e992c5cde607..7db3de6e690c 100644 --- a/include/lldb/Symbol/SymbolVendor.h +++ b/include/lldb/Symbol/SymbolVendor.h @@ -12,11 +12,11 @@ #include <vector> -#include "lldb/lldb-private.h" #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" +#include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" namespace lldb_private { @@ -31,197 +31,146 @@ namespace lldb_private { // objects) to provide the information and only parse as deep as needed // in order to provide the information that is requested. //---------------------------------------------------------------------- -class SymbolVendor : - public ModuleChild, - public PluginInterface -{ +class SymbolVendor : public ModuleChild, public PluginInterface { public: - static SymbolVendor* - FindPlugin (const lldb::ModuleSP &module_sp, - Stream *feedback_strm); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - SymbolVendor(const lldb::ModuleSP &module_sp); - - ~SymbolVendor() override; - - void - AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp); - - virtual void - Dump(Stream *s); - - virtual lldb::LanguageType - ParseCompileUnitLanguage (const SymbolContext& sc); - - virtual size_t - ParseCompileUnitFunctions (const SymbolContext& sc); - - virtual bool - ParseCompileUnitLineTable (const SymbolContext& sc); - - virtual bool - ParseCompileUnitDebugMacros (const SymbolContext& sc); - - virtual bool - ParseCompileUnitSupportFiles (const SymbolContext& sc, - FileSpecList& support_files); - - virtual bool - ParseCompileUnitIsOptimized(const SymbolContext &sc); - - virtual bool - ParseImportedModules (const SymbolContext &sc, - std::vector<ConstString> &imported_modules); - - virtual size_t - ParseFunctionBlocks (const SymbolContext& sc); - - virtual size_t - ParseTypes (const SymbolContext& sc); - - virtual size_t - ParseVariablesForContext (const SymbolContext& sc); - - virtual Type* - ResolveTypeUID(lldb::user_id_t type_uid); - - virtual uint32_t - ResolveSymbolContext (const Address& so_addr, - uint32_t resolve_scope, - SymbolContext& sc); - - virtual uint32_t - ResolveSymbolContext (const FileSpec& file_spec, - uint32_t line, - bool check_inlines, - uint32_t resolve_scope, - SymbolContextList& sc_list); - - virtual size_t - FindGlobalVariables (const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - bool append, - size_t max_matches, - VariableList& variables); - - virtual size_t - FindGlobalVariables (const RegularExpression& regex, - bool append, - size_t max_matches, - VariableList& variables); - - virtual size_t - FindFunctions (const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, - bool include_inlines, - bool append, - SymbolContextList& sc_list); - - virtual size_t - FindFunctions (const RegularExpression& regex, - bool include_inlines, - bool append, - SymbolContextList& sc_list); - - virtual size_t - FindTypes (const SymbolContext& sc, - const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - bool append, - size_t max_matches, - llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, - TypeMap& types); - - virtual size_t - FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types); - - virtual CompilerDeclContext - FindNamespace (const SymbolContext& sc, - const ConstString &name, - const CompilerDeclContext *parent_decl_ctx); - - virtual size_t - GetNumCompileUnits(); - - virtual bool - SetCompileUnitAtIndex (size_t cu_idx, - const lldb::CompUnitSP &cu_sp); - - virtual lldb::CompUnitSP - GetCompileUnitAtIndex(size_t idx); - - TypeList& - GetTypeList() - { - return m_type_list; - } - - const TypeList& - GetTypeList() const - { - return m_type_list; - } - - virtual size_t - GetTypes (SymbolContextScope *sc_scope, - uint32_t type_mask, - TypeList &type_list); - - SymbolFile * - GetSymbolFile() - { - return m_sym_file_ap.get(); - } - - FileSpec - GetMainFileSpec() const; - - // Get module unified section list symbol table. - virtual Symtab * - GetSymtab (); - - // Clear module unified section list symbol table. - virtual void - ClearSymtab (); - - //------------------------------------------------------------------ - /// Notify the SymbolVendor that the file addresses in the Sections - /// for this module have been changed. - //------------------------------------------------------------------ - virtual void - SectionFileAddressesChanged (); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - ConstString - GetPluginName() override; - - uint32_t - GetPluginVersion() override; + static SymbolVendor *FindPlugin(const lldb::ModuleSP &module_sp, + Stream *feedback_strm); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolVendor(const lldb::ModuleSP &module_sp); + + ~SymbolVendor() override; + + void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp); + + virtual void Dump(Stream *s); + + virtual lldb::LanguageType ParseCompileUnitLanguage(const SymbolContext &sc); + + virtual size_t ParseCompileUnitFunctions(const SymbolContext &sc); + + virtual bool ParseCompileUnitLineTable(const SymbolContext &sc); + + virtual bool ParseCompileUnitDebugMacros(const SymbolContext &sc); + + virtual bool ParseCompileUnitSupportFiles(const SymbolContext &sc, + FileSpecList &support_files); + + virtual bool ParseCompileUnitIsOptimized(const SymbolContext &sc); + + virtual bool ParseImportedModules(const SymbolContext &sc, + std::vector<ConstString> &imported_modules); + + virtual size_t ParseFunctionBlocks(const SymbolContext &sc); + + virtual size_t ParseTypes(const SymbolContext &sc); + + virtual size_t ParseVariablesForContext(const SymbolContext &sc); + + virtual Type *ResolveTypeUID(lldb::user_id_t type_uid); + + virtual uint32_t ResolveSymbolContext(const Address &so_addr, + uint32_t resolve_scope, + SymbolContext &sc); + + virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, + uint32_t line, bool check_inlines, + uint32_t resolve_scope, + SymbolContextList &sc_list); + + virtual size_t FindGlobalVariables(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + bool append, size_t max_matches, + VariableList &variables); + + virtual size_t FindGlobalVariables(const RegularExpression ®ex, + bool append, size_t max_matches, + VariableList &variables); + + virtual size_t FindFunctions(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + uint32_t name_type_mask, bool include_inlines, + bool append, SymbolContextList &sc_list); + + virtual size_t FindFunctions(const RegularExpression ®ex, + bool include_inlines, bool append, + SymbolContextList &sc_list); + + virtual size_t + FindTypes(const SymbolContext &sc, const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, bool append, + size_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, + TypeMap &types); + + virtual size_t FindTypes(const std::vector<CompilerContext> &context, + bool append, TypeMap &types); + + virtual CompilerDeclContext + FindNamespace(const SymbolContext &sc, const ConstString &name, + const CompilerDeclContext *parent_decl_ctx); + + virtual size_t GetNumCompileUnits(); + + virtual bool SetCompileUnitAtIndex(size_t cu_idx, + const lldb::CompUnitSP &cu_sp); + + virtual lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx); + + TypeList &GetTypeList() { return m_type_list; } + + const TypeList &GetTypeList() const { return m_type_list; } + + virtual size_t GetTypes(SymbolContextScope *sc_scope, uint32_t type_mask, + TypeList &type_list); + + SymbolFile *GetSymbolFile() { return m_sym_file_ap.get(); } + + FileSpec GetMainFileSpec() const; + + // Get module unified section list symbol table. + virtual Symtab *GetSymtab(); + + // Clear module unified section list symbol table. + virtual void ClearSymtab(); + + //------------------------------------------------------------------ + /// Notify the SymbolVendor that the file addresses in the Sections + /// for this module have been changed. + //------------------------------------------------------------------ + virtual void SectionFileAddressesChanged(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; protected: - //------------------------------------------------------------------ - // Classes that inherit from SymbolVendor can see and modify these - //------------------------------------------------------------------ - typedef std::vector<lldb::CompUnitSP> CompileUnits; - typedef CompileUnits::iterator CompileUnitIter; - typedef CompileUnits::const_iterator CompileUnitConstIter; - - TypeList m_type_list; // Uniqued types for all parsers owned by this module - CompileUnits m_compile_units; // The current compile units - lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in case it isn't the same as the module object file (debug symbols in a separate file) - std::unique_ptr<SymbolFile> m_sym_file_ap; // A single symbol file. Subclasses can add more of these if needed. + //------------------------------------------------------------------ + // Classes that inherit from SymbolVendor can see and modify these + //------------------------------------------------------------------ + typedef std::vector<lldb::CompUnitSP> CompileUnits; + typedef CompileUnits::iterator CompileUnitIter; + typedef CompileUnits::const_iterator CompileUnitConstIter; + + TypeList m_type_list; // Uniqued types for all parsers owned by this module + CompileUnits m_compile_units; // The current compile units + lldb::ObjectFileSP m_objfile_sp; // Keep a reference to the object file in + // case it isn't the same as the module + // object file (debug symbols in a separate + // file) + std::unique_ptr<SymbolFile> m_sym_file_ap; // A single symbol file. Subclasses + // can add more of these if needed. private: - //------------------------------------------------------------------ - // For SymbolVendor only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (SymbolVendor); + //------------------------------------------------------------------ + // For SymbolVendor only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN(SymbolVendor); }; } // namespace lldb_private diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h index 4203a3f7599a..6a8d62cea8b7 100644 --- a/include/lldb/Symbol/Symtab.h +++ b/include/lldb/Symbol/Symtab.h @@ -7,169 +7,198 @@ // //===----------------------------------------------------------------------===// - #ifndef liblldb_Symtab_h_ #define liblldb_Symtab_h_ #include <mutex> #include <vector> -#include "lldb/lldb-private.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/Symbol.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class Symtab -{ +class Symtab { public: - typedef std::vector<uint32_t> IndexCollection; - typedef UniqueCStringMap<uint32_t> NameToIndexMap; - - typedef enum Debug { - eDebugNo, // Not a debug symbol - eDebugYes, // A debug symbol - eDebugAny - } Debug; - - typedef enum Visibility { - eVisibilityAny, - eVisibilityExtern, - eVisibilityPrivate - } Visibility; - - Symtab(ObjectFile *objfile); - ~Symtab(); - - void Reserve (size_t count); - Symbol * Resize (size_t count); - uint32_t AddSymbol(const Symbol& symbol); - size_t GetNumSymbols() const; - void SectionFileAddressesChanged (); - void Dump(Stream *s, Target *target, SortOrder sort_type); - void Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const; - uint32_t GetIndexForSymbol (const Symbol *symbol) const; - std::recursive_mutex & - GetMutex() - { - return m_mutex; - } - Symbol * FindSymbolByID (lldb::user_id_t uid) const; - Symbol * SymbolAtIndex (size_t idx); - const Symbol * SymbolAtIndex (size_t idx) const; - Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx); - //---------------------------------------------------------------------- - /// Get the parent symbol for the given symbol. - /// - /// Many symbols in symbol tables are scoped by other symbols that - /// contain one or more symbol. This function will look for such a - /// containing symbol and return it if there is one. - //---------------------------------------------------------------------- - const Symbol * GetParent (Symbol *symbol) const; - uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; - uint32_t AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; - uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const; - uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& matches); - uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches); - uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, std::vector<uint32_t>& matches); - uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches); - uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes); - uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes); - size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes); - size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes); - size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes); - Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility); - Symbol * FindSymbolAtFileAddress (lldb::addr_t file_addr); - Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr); - void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback); - size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list); - void CalculateSymbolSizes (); - - void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const; - - static void DumpSymbolHeader (Stream *s); - - - void Finalize () - { - // Shrink to fit the symbols so we don't waste memory - if (m_symbols.capacity() > m_symbols.size()) - { - collection new_symbols (m_symbols.begin(), m_symbols.end()); - m_symbols.swap (new_symbols); - } - } - - void AppendSymbolNamesToMap (const IndexCollection &indexes, - bool add_demangled, - bool add_mangled, - NameToIndexMap &name_to_index_map) const; - - ObjectFile * GetObjectFile() - { - return m_objfile; - } + typedef std::vector<uint32_t> IndexCollection; + typedef UniqueCStringMap<uint32_t> NameToIndexMap; + + typedef enum Debug { + eDebugNo, // Not a debug symbol + eDebugYes, // A debug symbol + eDebugAny + } Debug; + + typedef enum Visibility { + eVisibilityAny, + eVisibilityExtern, + eVisibilityPrivate + } Visibility; + + Symtab(ObjectFile *objfile); + ~Symtab(); + + void Reserve(size_t count); + Symbol *Resize(size_t count); + uint32_t AddSymbol(const Symbol &symbol); + size_t GetNumSymbols() const; + void SectionFileAddressesChanged(); + void Dump(Stream *s, Target *target, SortOrder sort_type); + void Dump(Stream *s, Target *target, std::vector<uint32_t> &indexes) const; + uint32_t GetIndexForSymbol(const Symbol *symbol) const; + std::recursive_mutex &GetMutex() { return m_mutex; } + Symbol *FindSymbolByID(lldb::user_id_t uid) const; + Symbol *SymbolAtIndex(size_t idx); + const Symbol *SymbolAtIndex(size_t idx) const; + Symbol *FindSymbolWithType(lldb::SymbolType symbol_type, + Debug symbol_debug_type, + Visibility symbol_visibility, uint32_t &start_idx); + //---------------------------------------------------------------------- + /// Get the parent symbol for the given symbol. + /// + /// Many symbols in symbol tables are scoped by other symbols that + /// contain one or more symbol. This function will look for such a + /// containing symbol and return it if there is one. + //---------------------------------------------------------------------- + const Symbol *GetParent(Symbol *symbol) const; + uint32_t AppendSymbolIndexesWithType(lldb::SymbolType symbol_type, + std::vector<uint32_t> &indexes, + uint32_t start_idx = 0, + uint32_t end_index = UINT32_MAX) const; + uint32_t AppendSymbolIndexesWithTypeAndFlagsValue( + lldb::SymbolType symbol_type, uint32_t flags_value, + std::vector<uint32_t> &indexes, uint32_t start_idx = 0, + uint32_t end_index = UINT32_MAX) const; + uint32_t AppendSymbolIndexesWithType(lldb::SymbolType symbol_type, + Debug symbol_debug_type, + Visibility symbol_visibility, + std::vector<uint32_t> &matches, + uint32_t start_idx = 0, + uint32_t end_index = UINT32_MAX) const; + uint32_t AppendSymbolIndexesWithName(const ConstString &symbol_name, + std::vector<uint32_t> &matches); + uint32_t AppendSymbolIndexesWithName(const ConstString &symbol_name, + Debug symbol_debug_type, + Visibility symbol_visibility, + std::vector<uint32_t> &matches); + uint32_t AppendSymbolIndexesWithNameAndType(const ConstString &symbol_name, + lldb::SymbolType symbol_type, + std::vector<uint32_t> &matches); + uint32_t AppendSymbolIndexesWithNameAndType(const ConstString &symbol_name, + lldb::SymbolType symbol_type, + Debug symbol_debug_type, + Visibility symbol_visibility, + std::vector<uint32_t> &matches); + uint32_t + AppendSymbolIndexesMatchingRegExAndType(const RegularExpression ®ex, + lldb::SymbolType symbol_type, + std::vector<uint32_t> &indexes); + uint32_t AppendSymbolIndexesMatchingRegExAndType( + const RegularExpression ®ex, lldb::SymbolType symbol_type, + Debug symbol_debug_type, Visibility symbol_visibility, + std::vector<uint32_t> &indexes); + size_t FindAllSymbolsWithNameAndType(const ConstString &name, + lldb::SymbolType symbol_type, + std::vector<uint32_t> &symbol_indexes); + size_t FindAllSymbolsWithNameAndType(const ConstString &name, + lldb::SymbolType symbol_type, + Debug symbol_debug_type, + Visibility symbol_visibility, + std::vector<uint32_t> &symbol_indexes); + size_t FindAllSymbolsMatchingRexExAndType( + const RegularExpression ®ex, lldb::SymbolType symbol_type, + Debug symbol_debug_type, Visibility symbol_visibility, + std::vector<uint32_t> &symbol_indexes); + Symbol *FindFirstSymbolWithNameAndType(const ConstString &name, + lldb::SymbolType symbol_type, + Debug symbol_debug_type, + Visibility symbol_visibility); + Symbol *FindSymbolAtFileAddress(lldb::addr_t file_addr); + Symbol *FindSymbolContainingFileAddress(lldb::addr_t file_addr); + void ForEachSymbolContainingFileAddress( + lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback); + size_t FindFunctionSymbols(const ConstString &name, uint32_t name_type_mask, + SymbolContextList &sc_list); + void CalculateSymbolSizes(); + + void SortSymbolIndexesByValue(std::vector<uint32_t> &indexes, + bool remove_duplicates) const; + + static void DumpSymbolHeader(Stream *s); + + void Finalize() { + // Shrink to fit the symbols so we don't waste memory + if (m_symbols.capacity() > m_symbols.size()) { + collection new_symbols(m_symbols.begin(), m_symbols.end()); + m_symbols.swap(new_symbols); + } + } + + void AppendSymbolNamesToMap(const IndexCollection &indexes, + bool add_demangled, bool add_mangled, + NameToIndexMap &name_to_index_map) const; + + ObjectFile *GetObjectFile() { return m_objfile; } + protected: - typedef std::vector<Symbol> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; - typedef RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> FileRangeToIndexMap; - void InitNameIndexes (); - void InitAddressIndexes (); - - ObjectFile * m_objfile; - collection m_symbols; - FileRangeToIndexMap m_file_addr_to_index; - UniqueCStringMap<uint32_t> m_name_to_index; - UniqueCStringMap<uint32_t> m_basename_to_index; - UniqueCStringMap<uint32_t> m_method_to_index; - UniqueCStringMap<uint32_t> m_selector_to_index; - mutable std::recursive_mutex m_mutex; // Provide thread safety for this symbol table - bool m_file_addr_to_index_computed:1, - m_name_indexes_computed:1; + typedef std::vector<Symbol> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + typedef RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> + FileRangeToIndexMap; + void InitNameIndexes(); + void InitAddressIndexes(); + + ObjectFile *m_objfile; + collection m_symbols; + FileRangeToIndexMap m_file_addr_to_index; + UniqueCStringMap<uint32_t> m_name_to_index; + UniqueCStringMap<uint32_t> m_basename_to_index; + UniqueCStringMap<uint32_t> m_method_to_index; + UniqueCStringMap<uint32_t> m_selector_to_index; + mutable std::recursive_mutex + m_mutex; // Provide thread safety for this symbol table + bool m_file_addr_to_index_computed : 1, m_name_indexes_computed : 1; + private: + bool CheckSymbolAtIndex(size_t idx, Debug symbol_debug_type, + Visibility symbol_visibility) const { + switch (symbol_debug_type) { + case eDebugNo: + if (m_symbols[idx].IsDebug() == true) + return false; + break; - bool - CheckSymbolAtIndex (size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const - { - switch (symbol_debug_type) - { - case eDebugNo: - if (m_symbols[idx].IsDebug() == true) - return false; - break; - - case eDebugYes: - if (m_symbols[idx].IsDebug() == false) - return false; - break; - - case eDebugAny: - break; - } - - switch (symbol_visibility) - { - case eVisibilityAny: - return true; - - case eVisibilityExtern: - return m_symbols[idx].IsExternal(); - - case eVisibilityPrivate: - return !m_symbols[idx].IsExternal(); - } + case eDebugYes: + if (m_symbols[idx].IsDebug() == false) return false; + break; + + case eDebugAny: + break; + } + + switch (symbol_visibility) { + case eVisibilityAny: + return true; + + case eVisibilityExtern: + return m_symbols[idx].IsExternal(); + + case eVisibilityPrivate: + return !m_symbols[idx].IsExternal(); } + return false; + } - void - SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, - SymbolContextList &sc_list); + void SymbolIndicesToSymbolContextList(std::vector<uint32_t> &symbol_indexes, + SymbolContextList &sc_list); - DISALLOW_COPY_AND_ASSIGN (Symtab); + DISALLOW_COPY_AND_ASSIGN(Symtab); }; } // namespace lldb_private -#endif // liblldb_Symtab_h_ +#endif // liblldb_Symtab_h_ diff --git a/include/lldb/Symbol/TaggedASTType.h b/include/lldb/Symbol/TaggedASTType.h index 82431a562287..eabd41ebbf29 100644 --- a/include/lldb/Symbol/TaggedASTType.h +++ b/include/lldb/Symbol/TaggedASTType.h @@ -12,50 +12,33 @@ #include "lldb/Symbol/CompilerType.h" -namespace lldb_private -{ +namespace lldb_private { // For cases in which there are multiple classes of types that are not // interchangeable, to allow static type checking. -template <unsigned int C> class TaggedASTType : public CompilerType -{ +template <unsigned int C> class TaggedASTType : public CompilerType { public: - TaggedASTType (const CompilerType &compiler_type) : - CompilerType(compiler_type) - { - } - - TaggedASTType (lldb::opaque_compiler_type_t type, TypeSystem * type_system) : - CompilerType(type_system, type) - { - } - - TaggedASTType (const TaggedASTType<C> &tw) : - CompilerType(tw) - { - } - - TaggedASTType () : - CompilerType() - { - } - - virtual - ~TaggedASTType() - { - } - - TaggedASTType<C> &operator= (const TaggedASTType<C> &tw) - { - CompilerType::operator= (tw); - return *this; - } + TaggedASTType(const CompilerType &compiler_type) + : CompilerType(compiler_type) {} + + TaggedASTType(lldb::opaque_compiler_type_t type, TypeSystem *type_system) + : CompilerType(type_system, type) {} + + TaggedASTType(const TaggedASTType<C> &tw) : CompilerType(tw) {} + + TaggedASTType() : CompilerType() {} + + virtual ~TaggedASTType() {} + + TaggedASTType<C> &operator=(const TaggedASTType<C> &tw) { + CompilerType::operator=(tw); + return *this; + } }; // Commonly-used tagged types, so code using them is interoperable -typedef TaggedASTType<0> TypeFromParser; -typedef TaggedASTType<1> TypeFromUser; - +typedef TaggedASTType<0> TypeFromParser; +typedef TaggedASTType<1> TypeFromUser; } #endif diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index 9158f28998e3..13c95e71ffeb 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -10,13 +10,13 @@ #ifndef liblldb_Type_h_ #define liblldb_Type_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/ClangForward.h" #include "lldb/Core/ConstString.h" #include "lldb/Core/UserID.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Declaration.h" +#include "lldb/lldb-private.h" #include "llvm/ADT/APSInt.h" @@ -28,989 +28,647 @@ namespace lldb_private { // CompilerContext allows an array of these items to be passed to // perform detailed lookups in SymbolVendor and SymbolFile functions. //---------------------------------------------------------------------- -struct CompilerContext -{ - CompilerContext (CompilerContextKind t, const ConstString &n) : - type(t), - name(n) - { - } - - bool - operator == (const CompilerContext &rhs) const - { - return type == rhs.type && name == rhs.name; - } - - void - Dump () const; - - CompilerContextKind type; - ConstString name; +struct CompilerContext { + CompilerContext(CompilerContextKind t, const ConstString &n) + : type(t), name(n) {} + + bool operator==(const CompilerContext &rhs) const { + return type == rhs.type && name == rhs.name; + } + + void Dump() const; + + CompilerContextKind type; + ConstString name; }; -class SymbolFileType : - public std::enable_shared_from_this<SymbolFileType>, - public UserID - { - public: - SymbolFileType (SymbolFile &symbol_file, lldb::user_id_t uid) : - UserID (uid), - m_symbol_file (symbol_file) - { - } - - SymbolFileType (SymbolFile &symbol_file, const lldb::TypeSP &type_sp); - - - ~SymbolFileType () - { - } - - Type * - operator->() - { - return GetType (); - } - - Type * - GetType (); - - protected: - SymbolFile &m_symbol_file; - lldb::TypeSP m_type_sp; - }; - -class Type : - public std::enable_shared_from_this<Type>, - public UserID -{ +class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, + public UserID { public: - typedef enum EncodingDataTypeTag - { - eEncodingInvalid, - eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid - eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid with the const qualifier added - eEncodingIsRestrictUID, ///< This type is the type whose UID is m_encoding_uid with the restrict qualifier added - eEncodingIsVolatileUID, ///< This type is the type whose UID is m_encoding_uid with the volatile qualifier added - eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is m_encoding_uid - eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is m_encoding_uid - eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type whose UID is m_encoding_uid - eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type whose UID is m_encoding_uid - eEncodingIsSyntheticUID - } EncodingDataType; - - // We must force the underlying type of the enum to be unsigned here. Not all compilers - // behave the same with regards to the default underlying type of an enum, but because - // this enum is used in an enum bitfield and integer comparisons are done with the value - // we need to guarantee that it's always unsigned so that, for example, eResolveStateFull - // doesn't compare less than eResolveStateUnresolved when used in a 2-bit bitfield. - typedef enum ResolveStateTag : unsigned - { - eResolveStateUnresolved = 0, - eResolveStateForward = 1, - eResolveStateLayout = 2, - eResolveStateFull = 3 - } ResolveState; - - Type (lldb::user_id_t uid, - SymbolFile* symbol_file, - const ConstString &name, - uint64_t byte_size, - SymbolContextScope *context, - lldb::user_id_t encoding_uid, - EncodingDataType encoding_uid_type, - const Declaration& decl, - const CompilerType &compiler_qual_type, - ResolveState compiler_type_resolve_state); - - // This makes an invalid type. Used for functions that return a Type when they - // get an error. - Type(); - - Type (const Type &rhs); - - const Type& - operator= (const Type& rhs); - - void - Dump(Stream *s, bool show_context); - - void - DumpTypeName(Stream *s); - - // Since Type instances only keep a "SymbolFile *" internally, other classes - // like TypeImpl need make sure the module is still around before playing with - // Type instances. They can store a weak pointer to the Module; - lldb::ModuleSP - GetModule(); - - void - GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_name); - - SymbolFile * - GetSymbolFile() - { - return m_symbol_file; - } - const SymbolFile * - GetSymbolFile() const - { - return m_symbol_file; - } - - TypeList* - GetTypeList(); - - const ConstString& - GetName(); - - uint64_t - GetByteSize(); - - uint32_t - GetNumChildren (bool omit_empty_base_classes); - - bool - IsAggregateType (); - - bool - IsValidType () - { - return m_encoding_uid_type != eEncodingInvalid; - } - - bool - IsTypedef () - { - return m_encoding_uid_type == eEncodingIsTypedefUID; - } - - lldb::TypeSP - GetTypedefType(); - - const ConstString & - GetName () const - { - return m_name; - } - - ConstString - GetQualifiedName (); - - void - DumpValue(ExecutionContext *exe_ctx, - Stream *s, - const DataExtractor &data, - uint32_t data_offset, - bool show_type, - bool show_summary, - bool verbose, - lldb::Format format = lldb::eFormatDefault); - - bool - DumpValueInMemory(ExecutionContext *exe_ctx, - Stream *s, - lldb::addr_t address, - AddressType address_type, - bool show_types, - bool show_summary, - bool verbose); - - bool - ReadFromMemory (ExecutionContext *exe_ctx, - lldb::addr_t address, - AddressType address_type, - DataExtractor &data); - - bool - WriteToMemory (ExecutionContext *exe_ctx, - lldb::addr_t address, - AddressType address_type, - DataExtractor &data); - - bool - GetIsDeclaration() const; - - void - SetIsDeclaration(bool b); - - bool - GetIsExternal() const; - - void - SetIsExternal(bool b); - - lldb::Format - GetFormat (); - - lldb::Encoding - GetEncoding (uint64_t &count); - - SymbolContextScope * - GetSymbolContextScope() - { - return m_context; - } - const SymbolContextScope * - GetSymbolContextScope() const - { - return m_context; - } - void - SetSymbolContextScope(SymbolContextScope *context) - { - m_context = context; - } - - const lldb_private::Declaration & - GetDeclaration () const; - - // Get the clang type, and resolve definitions for any - // class/struct/union/enum types completely. - CompilerType - GetFullCompilerType (); - - // Get the clang type, and resolve definitions enough so that the type could - // have layout performed. This allows ptrs and refs to class/struct/union/enum - // types remain forward declarations. - CompilerType - GetLayoutCompilerType (); - - // Get the clang type and leave class/struct/union/enum types as forward - // declarations if they haven't already been fully defined. - CompilerType - GetForwardCompilerType (); - - static int - Compare(const Type &a, const Type &b); - - // From a fully qualified typename, split the type into the type basename - // and the remaining type scope (namespaces/classes). - static bool - GetTypeScopeAndBasename (const char* &name_cstr, - std::string &scope, - std::string &basename, - lldb::TypeClass &type_class); - void - SetEncodingType (Type *encoding_type) - { - m_encoding_type = encoding_type; - } - - uint32_t - GetEncodingMask (); - - bool - IsCompleteObjCClass() - { - return m_flags.is_complete_objc_class; - } - - void - SetIsCompleteObjCClass(bool is_complete_objc_class) - { - m_flags.is_complete_objc_class = is_complete_objc_class; - } + SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid) + : UserID(uid), m_symbol_file(symbol_file) {} + + SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp); + + ~SymbolFileType() {} + + Type *operator->() { return GetType(); } + + Type *GetType(); + +protected: + SymbolFile &m_symbol_file; + lldb::TypeSP m_type_sp; +}; + +class Type : public std::enable_shared_from_this<Type>, public UserID { +public: + typedef enum EncodingDataTypeTag { + eEncodingInvalid, + eEncodingIsUID, ///< This type is the type whose UID is m_encoding_uid + eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid + ///with the const qualifier added + eEncodingIsRestrictUID, ///< This type is the type whose UID is + ///m_encoding_uid with the restrict qualifier added + eEncodingIsVolatileUID, ///< This type is the type whose UID is + ///m_encoding_uid with the volatile qualifier added + eEncodingIsTypedefUID, ///< This type is pointer to a type whose UID is + ///m_encoding_uid + eEncodingIsPointerUID, ///< This type is pointer to a type whose UID is + ///m_encoding_uid + eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type + ///whose UID is m_encoding_uid + eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type + ///whose UID is m_encoding_uid + eEncodingIsSyntheticUID + } EncodingDataType; + + // We must force the underlying type of the enum to be unsigned here. Not all + // compilers + // behave the same with regards to the default underlying type of an enum, but + // because + // this enum is used in an enum bitfield and integer comparisons are done with + // the value + // we need to guarantee that it's always unsigned so that, for example, + // eResolveStateFull + // doesn't compare less than eResolveStateUnresolved when used in a 2-bit + // bitfield. + typedef enum ResolveStateTag : unsigned { + eResolveStateUnresolved = 0, + eResolveStateForward = 1, + eResolveStateLayout = 2, + eResolveStateFull = 3 + } ResolveState; + + Type(lldb::user_id_t uid, SymbolFile *symbol_file, const ConstString &name, + uint64_t byte_size, SymbolContextScope *context, + lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, + const Declaration &decl, const CompilerType &compiler_qual_type, + ResolveState compiler_type_resolve_state); + + // This makes an invalid type. Used for functions that return a Type when + // they + // get an error. + Type(); + + Type(const Type &rhs); + + const Type &operator=(const Type &rhs); + + void Dump(Stream *s, bool show_context); + + void DumpTypeName(Stream *s); + + // Since Type instances only keep a "SymbolFile *" internally, other classes + // like TypeImpl need make sure the module is still around before playing with + // Type instances. They can store a weak pointer to the Module; + lldb::ModuleSP GetModule(); + + void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name); + + SymbolFile *GetSymbolFile() { return m_symbol_file; } + const SymbolFile *GetSymbolFile() const { return m_symbol_file; } + + TypeList *GetTypeList(); + + const ConstString &GetName(); + + uint64_t GetByteSize(); + + uint32_t GetNumChildren(bool omit_empty_base_classes); + + bool IsAggregateType(); + + bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; } + + bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; } + + lldb::TypeSP GetTypedefType(); + + const ConstString &GetName() const { return m_name; } + + ConstString GetQualifiedName(); + + void DumpValue(ExecutionContext *exe_ctx, Stream *s, + const DataExtractor &data, uint32_t data_offset, + bool show_type, bool show_summary, bool verbose, + lldb::Format format = lldb::eFormatDefault); + + bool DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s, + lldb::addr_t address, AddressType address_type, + bool show_types, bool show_summary, bool verbose); + + bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address, + AddressType address_type, DataExtractor &data); + + bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address, + AddressType address_type, DataExtractor &data); + + bool GetIsDeclaration() const; + + void SetIsDeclaration(bool b); + + bool GetIsExternal() const; + + void SetIsExternal(bool b); + + lldb::Format GetFormat(); + + lldb::Encoding GetEncoding(uint64_t &count); + + SymbolContextScope *GetSymbolContextScope() { return m_context; } + const SymbolContextScope *GetSymbolContextScope() const { return m_context; } + void SetSymbolContextScope(SymbolContextScope *context) { + m_context = context; + } + + const lldb_private::Declaration &GetDeclaration() const; + + // Get the clang type, and resolve definitions for any + // class/struct/union/enum types completely. + CompilerType GetFullCompilerType(); + + // Get the clang type, and resolve definitions enough so that the type could + // have layout performed. This allows ptrs and refs to class/struct/union/enum + // types remain forward declarations. + CompilerType GetLayoutCompilerType(); + + // Get the clang type and leave class/struct/union/enum types as forward + // declarations if they haven't already been fully defined. + CompilerType GetForwardCompilerType(); + + static int Compare(const Type &a, const Type &b); + + // From a fully qualified typename, split the type into the type basename + // and the remaining type scope (namespaces/classes). + static bool GetTypeScopeAndBasename(const char *&name_cstr, + std::string &scope, std::string &basename, + lldb::TypeClass &type_class); + void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } + + uint32_t GetEncodingMask(); + + bool IsCompleteObjCClass() { return m_flags.is_complete_objc_class; } + + void SetIsCompleteObjCClass(bool is_complete_objc_class) { + m_flags.is_complete_objc_class = is_complete_objc_class; + } protected: - ConstString m_name; - SymbolFile *m_symbol_file; - SymbolContextScope *m_context; // The symbol context in which this type is defined - Type *m_encoding_type; - lldb::user_id_t m_encoding_uid; - EncodingDataType m_encoding_uid_type; - uint64_t m_byte_size; - Declaration m_decl; - CompilerType m_compiler_type; - - struct Flags { + ConstString m_name; + SymbolFile *m_symbol_file; + SymbolContextScope + *m_context; // The symbol context in which this type is defined + Type *m_encoding_type; + lldb::user_id_t m_encoding_uid; + EncodingDataType m_encoding_uid_type; + uint64_t m_byte_size; + Declaration m_decl; + CompilerType m_compiler_type; + + struct Flags { #ifdef __GNUC__ - // using unsigned type here to work around a very noisy gcc warning - unsigned compiler_type_resolve_state : 2; + // using unsigned type here to work around a very noisy gcc warning + unsigned compiler_type_resolve_state : 2; #else - ResolveState compiler_type_resolve_state : 2; + ResolveState compiler_type_resolve_state : 2; #endif - bool is_complete_objc_class : 1; - } m_flags; - - Type * - GetEncodingType (); - - bool - ResolveClangType (ResolveState compiler_type_resolve_state); + bool is_complete_objc_class : 1; + } m_flags; + + Type *GetEncodingType(); + + bool ResolveClangType(ResolveState compiler_type_resolve_state); }; // these classes are used to back the SBType* objects -class TypePair -{ +class TypePair { public: - TypePair () : - compiler_type(), - type_sp() - { - } - - TypePair (CompilerType type) : - compiler_type(type), - type_sp() - { - } - - TypePair (lldb::TypeSP type) : - compiler_type(), - type_sp(type) - { - compiler_type = type_sp->GetForwardCompilerType (); - } - - bool - IsValid () const - { - return compiler_type.IsValid() || (type_sp.get() != nullptr); - } - - explicit operator bool () const - { - return IsValid(); - } - - bool - operator == (const TypePair& rhs) const - { - return compiler_type == rhs.compiler_type && - type_sp.get() == rhs.type_sp.get(); - } - - bool - operator != (const TypePair& rhs) const - { - return compiler_type != rhs.compiler_type || - type_sp.get() != rhs.type_sp.get(); - } - - void - Clear () - { - compiler_type.Clear(); - type_sp.reset(); - } - - ConstString - GetName () const - { - if (type_sp) - return type_sp->GetName(); - if (compiler_type) - return compiler_type.GetTypeName(); - return ConstString (); - } - - ConstString - GetDisplayTypeName () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetDisplayTypeName(); - if (compiler_type) - return compiler_type.GetDisplayTypeName(); - return ConstString(); - } - - void - SetType (CompilerType type) - { - type_sp.reset(); - compiler_type = type; - } - - void - SetType (lldb::TypeSP type) - { - type_sp = type; - if (type_sp) - compiler_type = type_sp->GetForwardCompilerType (); - else - compiler_type.Clear(); - } - - lldb::TypeSP - GetTypeSP () const - { - return type_sp; - } - - CompilerType - GetCompilerType () const - { - return compiler_type; - } - - CompilerType - GetPointerType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType().GetPointerType(); - return compiler_type.GetPointerType(); - } - - CompilerType - GetPointeeType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetPointeeType(); - return compiler_type.GetPointeeType(); - } - - CompilerType - GetReferenceType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetLValueReferenceType(); - else - return compiler_type.GetLValueReferenceType(); - } - - CompilerType - GetTypedefedType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetTypedefedType(); - else - return compiler_type.GetTypedefedType(); - } - - CompilerType - GetDereferencedType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetNonReferenceType(); - else - return compiler_type.GetNonReferenceType(); - } - - CompilerType - GetUnqualifiedType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetFullyUnqualifiedType(); - else - return compiler_type.GetFullyUnqualifiedType(); - } - - CompilerType - GetCanonicalType () const - { - if (type_sp) - return type_sp->GetForwardCompilerType ().GetCanonicalType(); - return compiler_type.GetCanonicalType(); - } - - TypeSystem * - GetTypeSystem () const - { - return compiler_type.GetTypeSystem(); - } - - lldb::ModuleSP - GetModule () const - { - if (type_sp) - return type_sp->GetModule(); - return lldb::ModuleSP(); - } + TypePair() : compiler_type(), type_sp() {} + + TypePair(CompilerType type) : compiler_type(type), type_sp() {} + + TypePair(lldb::TypeSP type) : compiler_type(), type_sp(type) { + compiler_type = type_sp->GetForwardCompilerType(); + } + + bool IsValid() const { + return compiler_type.IsValid() || (type_sp.get() != nullptr); + } + + explicit operator bool() const { return IsValid(); } + + bool operator==(const TypePair &rhs) const { + return compiler_type == rhs.compiler_type && + type_sp.get() == rhs.type_sp.get(); + } + + bool operator!=(const TypePair &rhs) const { + return compiler_type != rhs.compiler_type || + type_sp.get() != rhs.type_sp.get(); + } + + void Clear() { + compiler_type.Clear(); + type_sp.reset(); + } + + ConstString GetName() const { + if (type_sp) + return type_sp->GetName(); + if (compiler_type) + return compiler_type.GetTypeName(); + return ConstString(); + } + + ConstString GetDisplayTypeName() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetDisplayTypeName(); + if (compiler_type) + return compiler_type.GetDisplayTypeName(); + return ConstString(); + } + + void SetType(CompilerType type) { + type_sp.reset(); + compiler_type = type; + } + + void SetType(lldb::TypeSP type) { + type_sp = type; + if (type_sp) + compiler_type = type_sp->GetForwardCompilerType(); + else + compiler_type.Clear(); + } + + lldb::TypeSP GetTypeSP() const { return type_sp; } + + CompilerType GetCompilerType() const { return compiler_type; } + + CompilerType GetPointerType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetPointerType(); + return compiler_type.GetPointerType(); + } + + CompilerType GetPointeeType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetPointeeType(); + return compiler_type.GetPointeeType(); + } + + CompilerType GetReferenceType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetLValueReferenceType(); + else + return compiler_type.GetLValueReferenceType(); + } + + CompilerType GetTypedefedType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetTypedefedType(); + else + return compiler_type.GetTypedefedType(); + } + + CompilerType GetDereferencedType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetNonReferenceType(); + else + return compiler_type.GetNonReferenceType(); + } + + CompilerType GetUnqualifiedType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetFullyUnqualifiedType(); + else + return compiler_type.GetFullyUnqualifiedType(); + } + + CompilerType GetCanonicalType() const { + if (type_sp) + return type_sp->GetForwardCompilerType().GetCanonicalType(); + return compiler_type.GetCanonicalType(); + } + + TypeSystem *GetTypeSystem() const { return compiler_type.GetTypeSystem(); } + + lldb::ModuleSP GetModule() const { + if (type_sp) + return type_sp->GetModule(); + return lldb::ModuleSP(); + } + protected: - CompilerType compiler_type; - lldb::TypeSP type_sp; + CompilerType compiler_type; + lldb::TypeSP type_sp; }; - + // the two classes here are used by the public API as a backend to // the SBType and SBTypeList classes - -class TypeImpl -{ + +class TypeImpl { public: - - TypeImpl(); - - ~TypeImpl () {} - - TypeImpl(const TypeImpl& rhs); - - TypeImpl (const lldb::TypeSP &type_sp); - - TypeImpl (const CompilerType &compiler_type); - - TypeImpl (const lldb::TypeSP &type_sp, const CompilerType &dynamic); - - TypeImpl (const CompilerType &compiler_type, const CompilerType &dynamic); - - TypeImpl (const TypePair &pair, const CompilerType &dynamic); - - void - SetType (const lldb::TypeSP &type_sp); - - void - SetType (const CompilerType &compiler_type); - - void - SetType (const lldb::TypeSP &type_sp, const CompilerType &dynamic); - - void - SetType (const CompilerType &compiler_type, const CompilerType &dynamic); - - void - SetType (const TypePair &pair, const CompilerType &dynamic); - - TypeImpl& - operator = (const TypeImpl& rhs); - - bool - operator == (const TypeImpl& rhs) const; - - bool - operator != (const TypeImpl& rhs) const; - - bool - IsValid() const; - - explicit operator bool () const; - - void Clear(); - - ConstString - GetName () const; - - ConstString - GetDisplayTypeName () const; - - TypeImpl - GetPointerType () const; - - TypeImpl - GetPointeeType () const; - - TypeImpl - GetReferenceType () const; - - TypeImpl - GetTypedefedType () const; - - TypeImpl - GetDereferencedType () const; - - TypeImpl - GetUnqualifiedType() const; - - TypeImpl - GetCanonicalType() const; - - CompilerType - GetCompilerType (bool prefer_dynamic); - - TypeSystem * - GetTypeSystem (bool prefer_dynamic); - - bool - GetDescription (lldb_private::Stream &strm, - lldb::DescriptionLevel description_level); - + TypeImpl(); + + ~TypeImpl() {} + + TypeImpl(const TypeImpl &rhs); + + TypeImpl(const lldb::TypeSP &type_sp); + + TypeImpl(const CompilerType &compiler_type); + + TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic); + + TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic); + + TypeImpl(const TypePair &pair, const CompilerType &dynamic); + + void SetType(const lldb::TypeSP &type_sp); + + void SetType(const CompilerType &compiler_type); + + void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic); + + void SetType(const CompilerType &compiler_type, const CompilerType &dynamic); + + void SetType(const TypePair &pair, const CompilerType &dynamic); + + TypeImpl &operator=(const TypeImpl &rhs); + + bool operator==(const TypeImpl &rhs) const; + + bool operator!=(const TypeImpl &rhs) const; + + bool IsValid() const; + + explicit operator bool() const; + + void Clear(); + + ConstString GetName() const; + + ConstString GetDisplayTypeName() const; + + TypeImpl GetPointerType() const; + + TypeImpl GetPointeeType() const; + + TypeImpl GetReferenceType() const; + + TypeImpl GetTypedefedType() const; + + TypeImpl GetDereferencedType() const; + + TypeImpl GetUnqualifiedType() const; + + TypeImpl GetCanonicalType() const; + + CompilerType GetCompilerType(bool prefer_dynamic); + + TypeSystem *GetTypeSystem(bool prefer_dynamic); + + bool GetDescription(lldb_private::Stream &strm, + lldb::DescriptionLevel description_level); + private: - - bool - CheckModule (lldb::ModuleSP &module_sp) const; + bool CheckModule(lldb::ModuleSP &module_sp) const; - lldb::ModuleWP m_module_wp; - TypePair m_static_type; - CompilerType m_dynamic_type; + lldb::ModuleWP m_module_wp; + TypePair m_static_type; + CompilerType m_dynamic_type; }; -class TypeListImpl -{ +class TypeListImpl { public: - TypeListImpl() : - m_content() - { - } - - void - Append (const lldb::TypeImplSP& type) - { - m_content.push_back(type); - } - - class AppendVisitor - { - public: - AppendVisitor(TypeListImpl &type_list) : - m_type_list(type_list) - { - } - - void - operator() (const lldb::TypeImplSP& type) - { - m_type_list.Append(type); - } - - private: - TypeListImpl &m_type_list; - }; - - void - Append (const lldb_private::TypeList &type_list); - - lldb::TypeImplSP - GetTypeAtIndex(size_t idx) - { - lldb::TypeImplSP type_sp; - if (idx < GetSize()) - type_sp = m_content[idx]; - return type_sp; - } - - size_t - GetSize() - { - return m_content.size(); - } - + TypeListImpl() : m_content() {} + + void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); } + + class AppendVisitor { + public: + AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {} + + void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); } + + private: + TypeListImpl &m_type_list; + }; + + void Append(const lldb_private::TypeList &type_list); + + lldb::TypeImplSP GetTypeAtIndex(size_t idx) { + lldb::TypeImplSP type_sp; + if (idx < GetSize()) + type_sp = m_content[idx]; + return type_sp; + } + + size_t GetSize() { return m_content.size(); } + private: - std::vector<lldb::TypeImplSP> m_content; + std::vector<lldb::TypeImplSP> m_content; }; - -class TypeMemberImpl -{ + +class TypeMemberImpl { public: - TypeMemberImpl () : - m_type_impl_sp (), - m_bit_offset (0), - m_name (), - m_bitfield_bit_size (0), - m_is_bitfield (false) - - { - } - - TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp, - uint64_t bit_offset, - const ConstString &name, - uint32_t bitfield_bit_size = 0, - bool is_bitfield = false) : - m_type_impl_sp (type_impl_sp), - m_bit_offset (bit_offset), - m_name (name), - m_bitfield_bit_size (bitfield_bit_size), - m_is_bitfield (is_bitfield) - { - } - - TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp, - uint64_t bit_offset): - m_type_impl_sp (type_impl_sp), - m_bit_offset (bit_offset), - m_name (), - m_bitfield_bit_size (0), - m_is_bitfield (false) - { - if (m_type_impl_sp) - m_name = m_type_impl_sp->GetName(); - } - - const lldb::TypeImplSP & - GetTypeImpl () - { - return m_type_impl_sp; - } - - const ConstString & - GetName () const - { - return m_name; - } - - uint64_t - GetBitOffset () const - { - return m_bit_offset; - } - - uint32_t - GetBitfieldBitSize () const - { - return m_bitfield_bit_size; - } - - void - SetBitfieldBitSize (uint32_t bitfield_bit_size) - { - m_bitfield_bit_size = bitfield_bit_size; - } - - bool - GetIsBitfield () const - { - return m_is_bitfield; - } - - void - SetIsBitfield (bool is_bitfield) - { - m_is_bitfield = is_bitfield; - } + TypeMemberImpl() + : m_type_impl_sp(), m_bit_offset(0), m_name(), m_bitfield_bit_size(0), + m_is_bitfield(false) + + {} + + TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset, + const ConstString &name, uint32_t bitfield_bit_size = 0, + bool is_bitfield = false) + : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name), + m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {} + + TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset) + : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(), + m_bitfield_bit_size(0), m_is_bitfield(false) { + if (m_type_impl_sp) + m_name = m_type_impl_sp->GetName(); + } + + const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; } + + const ConstString &GetName() const { return m_name; } + + uint64_t GetBitOffset() const { return m_bit_offset; } + + uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; } + + void SetBitfieldBitSize(uint32_t bitfield_bit_size) { + m_bitfield_bit_size = bitfield_bit_size; + } + + bool GetIsBitfield() const { return m_is_bitfield; } + + void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; } protected: - lldb::TypeImplSP m_type_impl_sp; - uint64_t m_bit_offset; - ConstString m_name; - uint32_t m_bitfield_bit_size; // Bit size for bitfield members only - bool m_is_bitfield; + lldb::TypeImplSP m_type_impl_sp; + uint64_t m_bit_offset; + ConstString m_name; + uint32_t m_bitfield_bit_size; // Bit size for bitfield members only + bool m_is_bitfield; }; - /// -/// Sometimes you can find the name of the type corresponding to an object, but we don't have debug -/// information for it. If that is the case, you can return one of these objects, and then if it -/// has a full type, you can use that, but if not at least you can print the name for informational +/// Sometimes you can find the name of the type corresponding to an object, but +/// we don't have debug +/// information for it. If that is the case, you can return one of these +/// objects, and then if it +/// has a full type, you can use that, but if not at least you can print the +/// name for informational /// purposes. /// -class TypeAndOrName -{ +class TypeAndOrName { public: - TypeAndOrName (); - TypeAndOrName (lldb::TypeSP &type_sp); - TypeAndOrName (const CompilerType &compiler_type); - TypeAndOrName (const char *type_str); - TypeAndOrName (const TypeAndOrName &rhs); - TypeAndOrName (ConstString &type_const_string); - - TypeAndOrName & - operator= (const TypeAndOrName &rhs); - - bool - operator==(const TypeAndOrName &other) const; - - bool - operator!=(const TypeAndOrName &other) const; - - ConstString GetName () const; - - lldb::TypeSP - GetTypeSP () const - { - return m_type_pair.GetTypeSP(); - } - - CompilerType - GetCompilerType () const - { - return m_type_pair.GetCompilerType(); - } - - void - SetName (const ConstString &type_name); - - void - SetName (const char *type_name_cstr); - - void - SetTypeSP (lldb::TypeSP type_sp); - - void - SetCompilerType (CompilerType compiler_type); - - bool - IsEmpty () const; - - bool - HasName () const; - - bool - HasTypeSP () const; - - bool - HasCompilerType () const; - - bool - HasType () const - { - return HasTypeSP() || HasCompilerType(); - } - - void - Clear (); - - explicit operator bool () - { - return !IsEmpty(); - } - + TypeAndOrName(); + TypeAndOrName(lldb::TypeSP &type_sp); + TypeAndOrName(const CompilerType &compiler_type); + TypeAndOrName(const char *type_str); + TypeAndOrName(const TypeAndOrName &rhs); + TypeAndOrName(ConstString &type_const_string); + + TypeAndOrName &operator=(const TypeAndOrName &rhs); + + bool operator==(const TypeAndOrName &other) const; + + bool operator!=(const TypeAndOrName &other) const; + + ConstString GetName() const; + + lldb::TypeSP GetTypeSP() const { return m_type_pair.GetTypeSP(); } + + CompilerType GetCompilerType() const { return m_type_pair.GetCompilerType(); } + + void SetName(const ConstString &type_name); + + void SetName(const char *type_name_cstr); + + void SetTypeSP(lldb::TypeSP type_sp); + + void SetCompilerType(CompilerType compiler_type); + + bool IsEmpty() const; + + bool HasName() const; + + bool HasTypeSP() const; + + bool HasCompilerType() const; + + bool HasType() const { return HasTypeSP() || HasCompilerType(); } + + void Clear(); + + explicit operator bool() { return !IsEmpty(); } + private: - TypePair m_type_pair; - ConstString m_type_name; + TypePair m_type_pair; + ConstString m_type_name; }; - -class TypeMemberFunctionImpl -{ + +class TypeMemberFunctionImpl { public: - TypeMemberFunctionImpl() : - m_type (), - m_decl (), - m_name(), - m_kind (lldb::eMemberFunctionKindUnknown) - { - } - - TypeMemberFunctionImpl (const CompilerType& type, - const CompilerDecl& decl, - const std::string& name, - const lldb::MemberFunctionKind& kind) : - m_type (type), - m_decl (decl), - m_name(name), - m_kind (kind) - { - } - - bool - IsValid (); - - ConstString - GetName () const; - - ConstString - GetMangledName () const; - - CompilerType - GetType () const; - - CompilerType - GetReturnType () const; - - size_t - GetNumArguments () const; - - CompilerType - GetArgumentAtIndex (size_t idx) const; - - lldb::MemberFunctionKind - GetKind () const; - - bool - GetDescription (Stream& stream); - + TypeMemberFunctionImpl() + : m_type(), m_decl(), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) { + } + + TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, + const std::string &name, + const lldb::MemberFunctionKind &kind) + : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {} + + bool IsValid(); + + ConstString GetName() const; + + ConstString GetMangledName() const; + + CompilerType GetType() const; + + CompilerType GetReturnType() const; + + size_t GetNumArguments() const; + + CompilerType GetArgumentAtIndex(size_t idx) const; + + lldb::MemberFunctionKind GetKind() const; + + bool GetDescription(Stream &stream); + protected: - std::string - GetPrintableTypeName (); + std::string GetPrintableTypeName(); private: - CompilerType m_type; - CompilerDecl m_decl; - ConstString m_name; - lldb::MemberFunctionKind m_kind; + CompilerType m_type; + CompilerDecl m_decl; + ConstString m_name; + lldb::MemberFunctionKind m_kind; }; -class TypeEnumMemberImpl -{ +class TypeEnumMemberImpl { public: - TypeEnumMemberImpl () : - m_integer_type_sp(), - m_name("<invalid>"), - m_value(), - m_valid(false) - { - } - - TypeEnumMemberImpl (const lldb::TypeImplSP &integer_type_sp, - const ConstString &name, - const llvm::APSInt &value); - - TypeEnumMemberImpl (const TypeEnumMemberImpl& rhs) : - m_integer_type_sp(rhs.m_integer_type_sp), - m_name(rhs.m_name), - m_value(rhs.m_value), - m_valid(rhs.m_valid) - { - } - - TypeEnumMemberImpl& - operator = (const TypeEnumMemberImpl& rhs); - - bool - IsValid () - { - return m_valid; - } - - const ConstString & - GetName () const - { - return m_name; - } - - const lldb::TypeImplSP & - GetIntegerType () const - { - return m_integer_type_sp; - } - - uint64_t - GetValueAsUnsigned () const - { - return m_value.getZExtValue(); - } - - int64_t - GetValueAsSigned () const - { - return m_value.getSExtValue(); - } + TypeEnumMemberImpl() + : m_integer_type_sp(), m_name("<invalid>"), m_value(), m_valid(false) {} + + TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, + const ConstString &name, const llvm::APSInt &value); + + TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) + : m_integer_type_sp(rhs.m_integer_type_sp), m_name(rhs.m_name), + m_value(rhs.m_value), m_valid(rhs.m_valid) {} + + TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs); + + bool IsValid() { return m_valid; } + + const ConstString &GetName() const { return m_name; } + + const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; } + + uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); } + + int64_t GetValueAsSigned() const { return m_value.getSExtValue(); } protected: - lldb::TypeImplSP m_integer_type_sp; - ConstString m_name; - llvm::APSInt m_value; - bool m_valid; + lldb::TypeImplSP m_integer_type_sp; + ConstString m_name; + llvm::APSInt m_value; + bool m_valid; }; -class TypeEnumMemberListImpl -{ +class TypeEnumMemberListImpl { public: - TypeEnumMemberListImpl() : - m_content() - { - } - - void - Append (const lldb::TypeEnumMemberImplSP& type) - { - m_content.push_back(type); - } - - void - Append (const lldb_private::TypeEnumMemberListImpl& type_list); - - lldb::TypeEnumMemberImplSP - GetTypeEnumMemberAtIndex(size_t idx) - { - lldb::TypeEnumMemberImplSP enum_member; - if (idx < GetSize()) - enum_member = m_content[idx]; - return enum_member; - } - - size_t - GetSize() - { - return m_content.size(); - } + TypeEnumMemberListImpl() : m_content() {} + + void Append(const lldb::TypeEnumMemberImplSP &type) { + m_content.push_back(type); + } + + void Append(const lldb_private::TypeEnumMemberListImpl &type_list); + + lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) { + lldb::TypeEnumMemberImplSP enum_member; + if (idx < GetSize()) + enum_member = m_content[idx]; + return enum_member; + } + + size_t GetSize() { return m_content.size(); } private: - std::vector<lldb::TypeEnumMemberImplSP> m_content; + std::vector<lldb::TypeEnumMemberImplSP> m_content; }; } // namespace lldb_private -#endif // liblldb_Type_h_ - +#endif // liblldb_Type_h_ diff --git a/include/lldb/Symbol/TypeList.h b/include/lldb/Symbol/TypeList.h index f3642576ddcb..b6a4e41ff301 100644 --- a/include/lldb/Symbol/TypeList.h +++ b/include/lldb/Symbol/TypeList.h @@ -10,84 +10,66 @@ #ifndef liblldb_TypeList_h_ #define liblldb_TypeList_h_ -#include "lldb/lldb-private.h" #include "lldb/Symbol/Type.h" #include "lldb/Utility/Iterable.h" -#include <vector> +#include "lldb/lldb-private.h" #include <functional> +#include <vector> namespace lldb_private { -class TypeList -{ +class TypeList { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - TypeList(); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + TypeList(); + + virtual ~TypeList(); - virtual - ~TypeList(); + void Clear(); - void - Clear(); + void Dump(Stream *s, bool show_context); - void - Dump(Stream *s, bool show_context); + // lldb::TypeSP + // FindType(lldb::user_id_t uid); -// lldb::TypeSP -// FindType(lldb::user_id_t uid); + TypeList FindTypes(const ConstString &name); - TypeList - FindTypes(const ConstString &name); + void Insert(const lldb::TypeSP &type); - void - Insert (const lldb::TypeSP& type); + uint32_t GetSize() const; - uint32_t - GetSize() const; + lldb::TypeSP GetTypeAtIndex(uint32_t idx); - lldb::TypeSP - GetTypeAtIndex(uint32_t idx); - - typedef std::vector<lldb::TypeSP> collection; - typedef AdaptedIterable<collection, lldb::TypeSP, vector_adapter> TypeIterable; - - TypeIterable - Types () - { - return TypeIterable(m_types); - } + typedef std::vector<lldb::TypeSP> collection; + typedef AdaptedIterable<collection, lldb::TypeSP, vector_adapter> + TypeIterable; - void - ForEach (std::function <bool(const lldb::TypeSP &type_sp)> const &callback) const; + TypeIterable Types() { return TypeIterable(m_types); } - void - ForEach (std::function <bool(lldb::TypeSP &type_sp)> const &callback); + void ForEach( + std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const; + void ForEach(std::function<bool(lldb::TypeSP &type_sp)> const &callback); - void - RemoveMismatchedTypes (const char *qualified_typename, - bool exact_match); + void RemoveMismatchedTypes(const char *qualified_typename, bool exact_match); - void - RemoveMismatchedTypes (const std::string &type_scope, - const std::string &type_basename, - lldb::TypeClass type_class, - bool exact_match); + void RemoveMismatchedTypes(const std::string &type_scope, + const std::string &type_basename, + lldb::TypeClass type_class, bool exact_match); - void - RemoveMismatchedTypes (lldb::TypeClass type_class); + void RemoveMismatchedTypes(lldb::TypeClass type_class); private: - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; - collection m_types; + collection m_types; - DISALLOW_COPY_AND_ASSIGN (TypeList); + DISALLOW_COPY_AND_ASSIGN(TypeList); }; } // namespace lldb_private -#endif // liblldb_TypeList_h_ +#endif // liblldb_TypeList_h_ diff --git a/include/lldb/Symbol/TypeMap.h b/include/lldb/Symbol/TypeMap.h index 4398acd789ae..6bf9831c1389 100644 --- a/include/lldb/Symbol/TypeMap.h +++ b/include/lldb/Symbol/TypeMap.h @@ -10,89 +10,68 @@ #ifndef liblldb_TypeMap_h_ #define liblldb_TypeMap_h_ -#include "lldb/lldb-private.h" #include "lldb/Symbol/Type.h" #include "lldb/Utility/Iterable.h" -#include <map> +#include "lldb/lldb-private.h" #include <functional> +#include <map> namespace lldb_private { -class TypeMap -{ +class TypeMap { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - TypeMap(); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + TypeMap(); + + virtual ~TypeMap(); + + void Clear(); - virtual - ~TypeMap(); + void Dump(Stream *s, bool show_context); - void - Clear(); + TypeMap FindTypes(const ConstString &name); - void - Dump(Stream *s, bool show_context); + void Insert(const lldb::TypeSP &type); - TypeMap - FindTypes(const ConstString &name); + bool Empty() const; - void - Insert (const lldb::TypeSP& type); + bool InsertUnique(const lldb::TypeSP &type); - bool - Empty() const; + uint32_t GetSize() const; - bool - InsertUnique (const lldb::TypeSP& type); + lldb::TypeSP GetTypeAtIndex(uint32_t idx); - uint32_t - GetSize() const; + typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection; + typedef AdaptedIterable<collection, lldb::TypeSP, map_adapter> TypeIterable; - lldb::TypeSP - GetTypeAtIndex(uint32_t idx); - - typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection; - typedef AdaptedIterable<collection, lldb::TypeSP, map_adapter> TypeIterable; - - TypeIterable - Types () - { - return TypeIterable(m_types); - } + TypeIterable Types() { return TypeIterable(m_types); } - void - ForEach (std::function <bool(const lldb::TypeSP &type_sp)> const &callback) const; + void ForEach( + std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const; - void - ForEach (std::function <bool(lldb::TypeSP &type_sp)> const &callback); + void ForEach(std::function<bool(lldb::TypeSP &type_sp)> const &callback); - bool - Remove (const lldb::TypeSP &type_sp); + bool Remove(const lldb::TypeSP &type_sp); - void - RemoveMismatchedTypes (const char *qualified_typename, - bool exact_match); + void RemoveMismatchedTypes(const char *qualified_typename, bool exact_match); - void - RemoveMismatchedTypes (const std::string &type_scope, - const std::string &type_basename, - lldb::TypeClass type_class, - bool exact_match); + void RemoveMismatchedTypes(const std::string &type_scope, + const std::string &type_basename, + lldb::TypeClass type_class, bool exact_match); - void - RemoveMismatchedTypes (lldb::TypeClass type_class); + void RemoveMismatchedTypes(lldb::TypeClass type_class); private: - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; - collection m_types; + collection m_types; - DISALLOW_COPY_AND_ASSIGN (TypeMap); + DISALLOW_COPY_AND_ASSIGN(TypeMap); }; } // namespace lldb_private -#endif // liblldb_TypeMap_h_ +#endif // liblldb_TypeMap_h_ diff --git a/include/lldb/Symbol/TypeSystem.h b/include/lldb/Symbol/TypeSystem.h index 466699366f0a..b4f84c0dd67c 100644 --- a/include/lldb/Symbol/TypeSystem.h +++ b/include/lldb/Symbol/TypeSystem.h @@ -22,606 +22,517 @@ #include "llvm/Support/Casting.h" // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Expression/Expression.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/lldb-private.h" class DWARFDIE; class DWARFASTParser; namespace lldb_private { - + //---------------------------------------------------------------------- // Interface for representing the Type Systems in different languages. //---------------------------------------------------------------------- -class TypeSystem : public PluginInterface -{ +class TypeSystem : public PluginInterface { public: - //---------------------------------------------------------------------- - // Intrusive type system that allows us to use llvm casting. - // - // To add a new type system: - // - // 1 - Add a new enumeration for llvm casting below for your TypeSystem - // subclass, here we will use eKindFoo - // - // 2 - Your TypeSystem subclass will inherit from TypeSystem and needs - // to implement a static classof() function that returns your - // enumeration: - // - // class Foo : public lldb_private::TypeSystem - // { - // static bool classof(const TypeSystem *ts) - // { - // return ts->getKind() == TypeSystem::eKindFoo; - // } - // }; - // - // 3 - Contruct your TypeSystem subclass with the enumeration from below - // - // Foo() : - // TypeSystem(TypeSystem::eKindFoo), - // ... - // { - // } - // - // Then you can use the llvm casting on any "TypeSystem *" to get an - // instance of your subclass. - //---------------------------------------------------------------------- - enum LLVMCastKind { - eKindClang, - eKindSwift, - eKindGo, - eKindJava, - kNumKinds - }; - - //---------------------------------------------------------------------- - // Constructors and Destructors - //---------------------------------------------------------------------- - TypeSystem(LLVMCastKind kind); - - ~TypeSystem() override; - - LLVMCastKind getKind() const { return m_kind; } - - static lldb::TypeSystemSP - CreateInstance (lldb::LanguageType language, Module *module); - - static lldb::TypeSystemSP - CreateInstance (lldb::LanguageType language, Target *target); - - - // Free up any resources associated with this TypeSystem. Done before removing - // all the TypeSystems from the TypeSystemMap. - virtual void - Finalize() {} - - virtual DWARFASTParser * - GetDWARFParser() - { - return nullptr; - } - - virtual SymbolFile * - GetSymbolFile () const - { - return m_sym_file; - } - - // Returns true if the symbol file changed during the set accessor. - virtual void - SetSymbolFile (SymbolFile *sym_file) - { - m_sym_file = sym_file; - } - - //---------------------------------------------------------------------- - // CompilerDecl functions - //---------------------------------------------------------------------- - virtual ConstString - DeclGetName (void *opaque_decl) = 0; - - virtual ConstString - DeclGetMangledName (void *opaque_decl); - - virtual CompilerDeclContext - DeclGetDeclContext (void *opaque_decl); - - virtual CompilerType - DeclGetFunctionReturnType(void *opaque_decl); - - virtual size_t - DeclGetFunctionNumArguments(void *opaque_decl); - - virtual CompilerType - DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx); - - //---------------------------------------------------------------------- - // CompilerDeclContext functions - //---------------------------------------------------------------------- - - virtual std::vector<CompilerDecl> - DeclContextFindDeclByName (void *opaque_decl_ctx, - ConstString name, - const bool ignore_imported_decls); - - virtual bool - DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) = 0; - - virtual ConstString - DeclContextGetName (void *opaque_decl_ctx) = 0; - - virtual ConstString - DeclContextGetScopeQualifiedName (void *opaque_decl_ctx) = 0; - - virtual bool - DeclContextIsClassMethod (void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) = 0; - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - virtual bool - IsArrayType (lldb::opaque_compiler_type_t type, - CompilerType *element_type, - uint64_t *size, - bool *is_incomplete) = 0; - - virtual bool - IsAggregateType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsAnonymousType (lldb::opaque_compiler_type_t type); - - virtual bool - IsCharType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsCompleteType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsDefined(lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsFloatingPointType (lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) = 0; - - virtual bool - IsFunctionType (lldb::opaque_compiler_type_t type, bool *is_variadic_ptr) = 0; - - virtual size_t - GetNumberOfFunctionArguments (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetFunctionArgumentAtIndex (lldb::opaque_compiler_type_t type, const size_t index) = 0; - - virtual bool - IsFunctionPointerType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) = 0; - - virtual bool - IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) = 0; - - virtual bool - IsEnumerationType (lldb::opaque_compiler_type_t type, bool &is_signed) - { - is_signed = false; - return false; - } - - virtual bool - IsPossibleDynamicType (lldb::opaque_compiler_type_t type, - CompilerType *target_type, // Can pass NULL - bool check_cplusplus, - bool check_objc) = 0; - - virtual bool - IsPointerType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type) = 0; - - virtual bool - IsScalarType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsVoidType (lldb::opaque_compiler_type_t type) = 0; - - // TypeSystems can support more than one language - virtual bool - SupportsLanguage (lldb::LanguageType language) = 0; - - //---------------------------------------------------------------------- - // Type Completion - //---------------------------------------------------------------------- - - virtual bool - GetCompleteType (lldb::opaque_compiler_type_t type) = 0; - - //---------------------------------------------------------------------- - // AST related queries - //---------------------------------------------------------------------- - - virtual uint32_t - GetPointerByteSize () = 0; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - - virtual ConstString - GetTypeName (lldb::opaque_compiler_type_t type) = 0; - - virtual uint32_t - GetTypeInfo (lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type) = 0; - - virtual lldb::LanguageType - GetMinimumLanguage (lldb::opaque_compiler_type_t type) = 0; - - virtual lldb::TypeClass - GetTypeClass (lldb::opaque_compiler_type_t type) = 0; - - //---------------------------------------------------------------------- - // Creating related types - //---------------------------------------------------------------------- - - virtual CompilerType - GetArrayElementType (lldb::opaque_compiler_type_t type, uint64_t *stride) = 0; - - virtual CompilerType - GetCanonicalType (lldb::opaque_compiler_type_t type) = 0; - - // Returns -1 if this isn't a function of if the function doesn't have a prototype - // Returns a value >= 0 if there is a prototype. - virtual int - GetFunctionArgumentCount (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetFunctionArgumentTypeAtIndex (lldb::opaque_compiler_type_t type, size_t idx) = 0; - - virtual CompilerType - GetFunctionReturnType (lldb::opaque_compiler_type_t type) = 0; - - virtual size_t - GetNumMemberFunctions (lldb::opaque_compiler_type_t type) = 0; - - virtual TypeMemberFunctionImpl - GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, size_t idx) = 0; - - virtual CompilerType - GetPointeeType (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetPointerType (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetLValueReferenceType (lldb::opaque_compiler_type_t type); - - virtual CompilerType - GetRValueReferenceType (lldb::opaque_compiler_type_t type); - - virtual CompilerType - AddConstModifier (lldb::opaque_compiler_type_t type); - - virtual CompilerType - AddVolatileModifier (lldb::opaque_compiler_type_t type); - - virtual CompilerType - AddRestrictModifier (lldb::opaque_compiler_type_t type); - - virtual CompilerType - CreateTypedef (lldb::opaque_compiler_type_t type, const char *name, const CompilerDeclContext &decl_ctx); - - //---------------------------------------------------------------------- - // Exploring the type - //---------------------------------------------------------------------- - - virtual uint64_t - GetBitSize (lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) = 0; - - virtual lldb::Encoding - GetEncoding (lldb::opaque_compiler_type_t type, uint64_t &count) = 0; - - virtual lldb::Format - GetFormat (lldb::opaque_compiler_type_t type) = 0; - - virtual uint32_t - GetNumChildren (lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) = 0; - - virtual CompilerType - GetBuiltinTypeByName (const ConstString &name); - - virtual lldb::BasicType - GetBasicTypeEnumeration (lldb::opaque_compiler_type_t type) = 0; - - virtual void - ForEachEnumerator (lldb::opaque_compiler_type_t type, std::function <bool (const CompilerType &integer_type, const ConstString &name, const llvm::APSInt &value)> const &callback) - { - } - - virtual uint32_t - GetNumFields (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetFieldAtIndex (lldb::opaque_compiler_type_t type, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) = 0; - - virtual uint32_t - GetNumDirectBaseClasses (lldb::opaque_compiler_type_t type) = 0; - - virtual uint32_t - GetNumVirtualBaseClasses (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetDirectBaseClassAtIndex (lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) = 0; - - virtual CompilerType - GetVirtualBaseClassAtIndex (lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) = 0; - - virtual CompilerType - GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, - size_t idx, - bool transparent_pointers, - bool omit_empty_base_classes, - bool ignore_array_bounds, - std::string& child_name, - uint32_t &child_byte_size, - int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, - bool &child_is_deref_of_parent, - ValueObject *valobj, - uint64_t &language_flags) = 0; - - // Lookup a child given a name. This function will match base class names - // and member member names in "clang_type" only, not descendants. - virtual uint32_t - GetIndexOfChildWithName (lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) = 0; - - // Lookup a child member given a name. This function will match member names - // only and will descend into "clang_type" children in search for the first - // member in this class, or any base class that matches "name". - // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>> - // so we catch all names that match a given child name, not just the first. - virtual size_t - GetIndexOfChildMemberWithName (lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes, - std::vector<uint32_t>& child_indexes) = 0; - - virtual size_t - GetNumTemplateArguments (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetTemplateArgument (lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) = 0; - - //---------------------------------------------------------------------- - // Dumping types - //---------------------------------------------------------------------- - - virtual void - DumpValue (lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, - Stream *s, - lldb::Format format, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - bool show_types, - bool show_summary, - bool verbose, - uint32_t depth) = 0; - - virtual bool - DumpTypeValue (lldb::opaque_compiler_type_t type, - Stream *s, - lldb::Format format, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) = 0; - - virtual void - DumpTypeDescription (lldb::opaque_compiler_type_t type) = 0; // Dump to stdout - - virtual void - DumpTypeDescription (lldb::opaque_compiler_type_t type, Stream *s) = 0; - - //---------------------------------------------------------------------- - // TODO: These methods appear unused. Should they be removed? - //---------------------------------------------------------------------- - - virtual bool - IsRuntimeGeneratedType (lldb::opaque_compiler_type_t type) = 0; - - virtual void - DumpSummary (lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, - Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) = 0; - - // Converts "s" to a floating point value and place resulting floating - // point bytes in the "dst" buffer. - virtual size_t - ConvertStringToFloatValue (lldb::opaque_compiler_type_t type, - const char *s, - uint8_t *dst, - size_t dst_size) = 0; - - //---------------------------------------------------------------------- - // TODO: Determine if these methods should move to ClangASTContext. - //---------------------------------------------------------------------- - - virtual bool - IsPointerOrReferenceType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type) = 0; - - virtual unsigned - GetTypeQualifiers(lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsCStringType (lldb::opaque_compiler_type_t type, uint32_t &length) = 0; - - virtual size_t - GetTypeBitAlign (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetBasicTypeFromAST (lldb::BasicType basic_type) = 0; - - virtual CompilerType - GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) = 0; - - virtual bool - IsBeingDefined (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsConst(lldb::opaque_compiler_type_t type) = 0; - - virtual uint32_t - IsHomogeneousAggregate (lldb::opaque_compiler_type_t type, CompilerType* base_type_ptr) = 0; - - virtual bool - IsPolymorphicClass (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsTypedefType (lldb::opaque_compiler_type_t type) = 0; - - // If the current object represents a typedef type, get the underlying type - virtual CompilerType - GetTypedefedType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsVectorType (lldb::opaque_compiler_type_t type, - CompilerType *element_type, - uint64_t *size) = 0; - - virtual CompilerType - GetFullyUnqualifiedType (lldb::opaque_compiler_type_t type) = 0; - - virtual CompilerType - GetNonReferenceType (lldb::opaque_compiler_type_t type) = 0; - - virtual bool - IsReferenceType (lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool* is_rvalue) = 0; - - virtual bool - ShouldTreatScalarValueAsAddress (lldb::opaque_compiler_type_t type) - { - return IsPointerOrReferenceType(type, nullptr); - } - - virtual UserExpression * - GetUserExpression (const char *expr, - const char *expr_prefix, - lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) - { - return nullptr; - } - - virtual FunctionCaller * - GetFunctionCaller (const CompilerType &return_type, - const Address& function_address, - const ValueList &arg_value_list, - const char *name) - { - return nullptr; - } - - virtual UtilityFunction * - GetUtilityFunction(const char *text, const char *name) - { - return nullptr; - } - - virtual PersistentExpressionState * - GetPersistentExpressionState() - { - return nullptr; - } - - virtual CompilerType - GetTypeForFormatters (void* type); - - virtual LazyBool - ShouldPrintAsOneLiner (void* type, ValueObject* valobj); - - // Type systems can have types that are placeholder types, which are meant to indicate - // the presence of a type, but offer no actual information about said types, and leave - // the burden of actually figuring type information out to dynamic type resolution. For instance - // a language with a generics system, can use placeholder types to indicate "type argument goes here", - // without promising uniqueness of the placeholder, nor attaching any actually idenfiable information - // to said placeholder. This API allows type systems to tell LLDB when such a type has been encountered - // In response, the debugger can react by not using this type as a cache entry in any type-specific way - // For instance, LLDB will currently not cache any formatters that are discovered on such a type as - // attributable to the meaningless type itself, instead preferring to use the dynamic type - virtual bool - IsMeaninglessWithoutDynamicResolution (void* type); - -protected: - const LLVMCastKind m_kind; // Support for llvm casting - SymbolFile *m_sym_file; + //---------------------------------------------------------------------- + // Intrusive type system that allows us to use llvm casting. + // + // To add a new type system: + // + // 1 - Add a new enumeration for llvm casting below for your TypeSystem + // subclass, here we will use eKindFoo + // + // 2 - Your TypeSystem subclass will inherit from TypeSystem and needs + // to implement a static classof() function that returns your + // enumeration: + // + // class Foo : public lldb_private::TypeSystem + // { + // static bool classof(const TypeSystem *ts) + // { + // return ts->getKind() == TypeSystem::eKindFoo; + // } + // }; + // + // 3 - Contruct your TypeSystem subclass with the enumeration from below + // + // Foo() : + // TypeSystem(TypeSystem::eKindFoo), + // ... + // { + // } + // + // Then you can use the llvm casting on any "TypeSystem *" to get an + // instance of your subclass. + //---------------------------------------------------------------------- + enum LLVMCastKind { + eKindClang, + eKindSwift, + eKindGo, + eKindJava, + eKindOCaml, + kNumKinds + }; + + //---------------------------------------------------------------------- + // Constructors and Destructors + //---------------------------------------------------------------------- + TypeSystem(LLVMCastKind kind); + + ~TypeSystem() override; + + LLVMCastKind getKind() const { return m_kind; } + + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Module *module); + + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Target *target); + + // Free up any resources associated with this TypeSystem. Done before + // removing + // all the TypeSystems from the TypeSystemMap. + virtual void Finalize() {} + + virtual DWARFASTParser *GetDWARFParser() { return nullptr; } + + virtual SymbolFile *GetSymbolFile() const { return m_sym_file; } + + // Returns true if the symbol file changed during the set accessor. + virtual void SetSymbolFile(SymbolFile *sym_file) { m_sym_file = sym_file; } + + //---------------------------------------------------------------------- + // CompilerDecl functions + //---------------------------------------------------------------------- + virtual ConstString DeclGetName(void *opaque_decl) = 0; + + virtual ConstString DeclGetMangledName(void *opaque_decl); + + virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl); + + virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl); + + virtual size_t DeclGetFunctionNumArguments(void *opaque_decl); + + virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, + size_t arg_idx); + + //---------------------------------------------------------------------- + // CompilerDeclContext functions + //---------------------------------------------------------------------- + + virtual std::vector<CompilerDecl> + DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, + const bool ignore_imported_decls); + + virtual bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) = 0; + + virtual ConstString DeclContextGetName(void *opaque_decl_ctx) = 0; + + virtual ConstString + DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) = 0; + + virtual bool DeclContextIsClassMethod( + void *opaque_decl_ctx, lldb::LanguageType *language_ptr, + bool *is_instance_method_ptr, ConstString *language_object_name_ptr) = 0; + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + virtual bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) = 0; + + virtual bool IsAggregateType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type); + + virtual bool IsCharType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsCompleteType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsDefined(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsFloatingPointType(lldb::opaque_compiler_type_t type, + uint32_t &count, bool &is_complex) = 0; + + virtual bool IsFunctionType(lldb::opaque_compiler_type_t type, + bool *is_variadic_ptr) = 0; + + virtual size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType + GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) = 0; + + virtual bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsBlockPointerType(lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) = 0; + + virtual bool IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) = 0; + + virtual bool IsEnumerationType(lldb::opaque_compiler_type_t type, + bool &is_signed) { + is_signed = false; + return false; + } + + virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, // Can pass NULL + bool check_cplusplus, bool check_objc) = 0; + + virtual bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) = 0; + + virtual bool IsScalarType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsVoidType(lldb::opaque_compiler_type_t type) = 0; + + // TypeSystems can support more than one language + virtual bool SupportsLanguage(lldb::LanguageType language) = 0; + + //---------------------------------------------------------------------- + // Type Completion + //---------------------------------------------------------------------- + + virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0; + + //---------------------------------------------------------------------- + // AST related queries + //---------------------------------------------------------------------- + + virtual uint32_t GetPointerByteSize() = 0; + + //---------------------------------------------------------------------- + // Accessors + //---------------------------------------------------------------------- + + virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type) = 0; + + virtual uint32_t + GetTypeInfo(lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type) = 0; + + virtual lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) = 0; + + virtual lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) = 0; + + //---------------------------------------------------------------------- + // Creating related types + //---------------------------------------------------------------------- + + virtual CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + uint64_t *stride) = 0; + virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, + uint64_t size); + + virtual CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) = 0; + + // Returns -1 if this isn't a function of if the function doesn't have a + // prototype + // Returns a value >= 0 if there is a prototype. + virtual int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType + GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) = 0; + + virtual CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) = 0; + + virtual size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) = 0; + + virtual TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) = 0; + + virtual CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType GetPointerType(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType + GetLValueReferenceType(lldb::opaque_compiler_type_t type); + + virtual CompilerType + GetRValueReferenceType(lldb::opaque_compiler_type_t type); + + virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type); + + virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type); + + virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type); + + virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, + const char *name, + const CompilerDeclContext &decl_ctx); + + //---------------------------------------------------------------------- + // Exploring the type + //---------------------------------------------------------------------- + + virtual uint64_t GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) = 0; + + virtual lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, + uint64_t &count) = 0; + + virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0; + + virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes) = 0; + + virtual CompilerType GetBuiltinTypeByName(const ConstString &name); + + virtual lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) = 0; + + virtual void ForEachEnumerator( + lldb::opaque_compiler_type_t type, + std::function<bool(const CompilerType &integer_type, + const ConstString &name, + const llvm::APSInt &value)> const &callback) {} + + virtual uint32_t GetNumFields(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, std::string &name, + uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) = 0; + + virtual uint32_t + GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) = 0; + + virtual uint32_t + GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType + GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + uint32_t *bit_offset_ptr) = 0; + + virtual CompilerType + GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + uint32_t *bit_offset_ptr) = 0; + + virtual CompilerType GetChildCompilerTypeAtIndex( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags) = 0; + + // Lookup a child given a name. This function will match base class names + // and member member names in "clang_type" only, not descendants. + virtual uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, + const char *name, + bool omit_empty_base_classes) = 0; + + // Lookup a child member given a name. This function will match member names + // only and will descend into "clang_type" children in search for the first + // member in this class, or any base class that matches "name". + // TODO: Return all matches for a given name by returning a + // vector<vector<uint32_t>> + // so we catch all names that match a given child name, not just the first. + virtual size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, + const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) = 0; + + virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType + GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, + lldb::TemplateArgumentKind &kind) = 0; + + //---------------------------------------------------------------------- + // Dumping types + //---------------------------------------------------------------------- + + virtual void DumpValue(lldb::opaque_compiler_type_t type, + ExecutionContext *exe_ctx, Stream *s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, bool show_types, + bool show_summary, bool verbose, uint32_t depth) = 0; + + virtual bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) = 0; + + virtual void + DumpTypeDescription(lldb::opaque_compiler_type_t type) = 0; // Dump to stdout + + virtual void DumpTypeDescription(lldb::opaque_compiler_type_t type, + Stream *s) = 0; + + //---------------------------------------------------------------------- + // TODO: These methods appear unused. Should they be removed? + //---------------------------------------------------------------------- + + virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0; + + virtual void DumpSummary(lldb::opaque_compiler_type_t type, + ExecutionContext *exe_ctx, Stream *s, + const DataExtractor &data, + lldb::offset_t data_offset, + size_t data_byte_size) = 0; + + // Converts "s" to a floating point value and place resulting floating + // point bytes in the "dst" buffer. + virtual size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, + const char *s, uint8_t *dst, + size_t dst_size) = 0; + + //---------------------------------------------------------------------- + // TODO: Determine if these methods should move to ClangASTContext. + //---------------------------------------------------------------------- + + virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) = 0; + + virtual unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsCStringType(lldb::opaque_compiler_type_t type, + uint32_t &length) = 0; + + virtual size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) = 0; + + virtual CompilerType + GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) = 0; + + virtual bool IsBeingDefined(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsConst(lldb::opaque_compiler_type_t type) = 0; + + virtual uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) = 0; + + virtual bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsTypedefType(lldb::opaque_compiler_type_t type) = 0; + + // If the current object represents a typedef type, get the underlying type + virtual CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) = 0; + + virtual CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) = 0; + + virtual CompilerType + GetNonReferenceType(lldb::opaque_compiler_type_t type) = 0; + + virtual bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type, bool *is_rvalue) = 0; + + virtual bool + ShouldTreatScalarValueAsAddress(lldb::opaque_compiler_type_t type) { + return IsPointerOrReferenceType(type, nullptr); + } + + virtual UserExpression * + GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, + lldb::LanguageType language, + Expression::ResultType desired_type, + const EvaluateExpressionOptions &options) { + return nullptr; + } + + virtual FunctionCaller *GetFunctionCaller(const CompilerType &return_type, + const Address &function_address, + const ValueList &arg_value_list, + const char *name) { + return nullptr; + } + + virtual UtilityFunction *GetUtilityFunction(const char *text, + const char *name) { + return nullptr; + } + + virtual PersistentExpressionState *GetPersistentExpressionState() { + return nullptr; + } + + virtual CompilerType GetTypeForFormatters(void *type); + + virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj); + + // Type systems can have types that are placeholder types, which are meant to + // indicate + // the presence of a type, but offer no actual information about said types, + // and leave + // the burden of actually figuring type information out to dynamic type + // resolution. For instance + // a language with a generics system, can use placeholder types to indicate + // "type argument goes here", + // without promising uniqueness of the placeholder, nor attaching any actually + // idenfiable information + // to said placeholder. This API allows type systems to tell LLDB when such a + // type has been encountered + // In response, the debugger can react by not using this type as a cache entry + // in any type-specific way + // For instance, LLDB will currently not cache any formatters that are + // discovered on such a type as + // attributable to the meaningless type itself, instead preferring to use the + // dynamic type + virtual bool IsMeaninglessWithoutDynamicResolution(void *type); + +protected: + const LLVMCastKind m_kind; // Support for llvm casting + SymbolFile *m_sym_file; }; - class TypeSystemMap - { - public: - TypeSystemMap (); - ~TypeSystemMap(); - - // Clear calls Finalize on all the TypeSystems managed by this map, and then - // empties the map. - void - Clear (); - - // Iterate through all of the type systems that are created. Return true - // from callback to keep iterating, false to stop iterating. - void - ForEach (std::function <bool(TypeSystem *)> const &callback); - - TypeSystem * - GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create); - - TypeSystem * - GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create); - - protected: - // This function does not take the map mutex, and should only be called from - // functions that do take the mutex. - void - AddToMap (lldb::LanguageType language, lldb::TypeSystemSP const &type_system_sp); - - typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection; - mutable std::mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. - collection m_map; - bool m_clear_in_progress; - }; +class TypeSystemMap { +public: + TypeSystemMap(); + ~TypeSystemMap(); + + // Clear calls Finalize on all the TypeSystems managed by this map, and then + // empties the map. + void Clear(); + + // Iterate through all of the type systems that are created. Return true + // from callback to keep iterating, false to stop iterating. + void ForEach(std::function<bool(TypeSystem *)> const &callback); + + TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language, + Module *module, bool can_create); + + TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language, + Target *target, bool can_create); + +protected: + // This function does not take the map mutex, and should only be called from + // functions that do take the mutex. + void AddToMap(lldb::LanguageType language, + lldb::TypeSystemSP const &type_system_sp); + + typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection; + mutable std::mutex m_mutex; ///< A mutex to keep this object happy in + ///multi-threaded environments. + collection m_map; + bool m_clear_in_progress; +}; } // namespace lldb_private diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h index 64c00bf12c27..dfcf55bc8864 100644 --- a/include/lldb/Symbol/UnwindPlan.h +++ b/include/lldb/Symbol/UnwindPlan.h @@ -18,10 +18,10 @@ // Other libraries and framework includes // Project includes -#include "lldb/lldb-private.h" #include "lldb/Core/AddressRange.h" -#include "lldb/Core/Stream.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/Stream.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -39,673 +39,455 @@ namespace lldb_private { // Internally, the UnwindPlan is structured as a vector of register locations // organized by code address in the function, showing which registers have been -// saved at that point and where they are saved. -// It can be thought of as the expanded table form of the DWARF CFI +// saved at that point and where they are saved. +// It can be thought of as the expanded table form of the DWARF CFI // encoded information. // Other unwind information sources will be converted into UnwindPlans before -// being added to a FuncUnwinders object. The unwind source may be -// an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based +// being added to a FuncUnwinders object. The unwind source may be +// an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based // prologue analysis. // The UnwindPlan is the canonical form of this information that the unwinder // code will use when walking the stack. class UnwindPlan { public: - class Row { + class Row { + public: + class RegisterLocation { public: - class RegisterLocation - { - public: - enum RestoreType - { - unspecified, // not specified, we may be able to assume this - // is the same register. gcc doesn't specify all - // initial values so we really don't know... - undefined, // reg is not available, e.g. volatile reg - same, // reg is unchanged - atCFAPlusOffset, // reg = deref(CFA + offset) - isCFAPlusOffset, // reg = CFA + offset - inOtherRegister, // reg = other reg - atDWARFExpression, // reg = deref(eval(dwarf_expr)) - isDWARFExpression // reg = eval(dwarf_expr) - }; - - RegisterLocation() : - m_type(unspecified), - m_location() - { - } - - bool - operator == (const RegisterLocation& rhs) const; - - bool - operator != (const RegisterLocation &rhs) const - { - return !(*this == rhs); - } - - void - SetUnspecified() - { - m_type = unspecified; - } - - void - SetUndefined() - { - m_type = undefined; - } - - void - SetSame() - { - m_type = same; - } - - bool - IsSame () const - { - return m_type == same; - } - - bool - IsUnspecified () const - { - return m_type == unspecified; - } - - bool - IsUndefined () const - { - return m_type == undefined; - } - - bool - IsCFAPlusOffset () const - { - return m_type == isCFAPlusOffset; - } - - bool - IsAtCFAPlusOffset () const - { - return m_type == atCFAPlusOffset; - } - - bool - IsInOtherRegister () const - { - return m_type == inOtherRegister; - } - - bool - IsAtDWARFExpression () const - { - return m_type == atDWARFExpression; - } - - bool - IsDWARFExpression () const - { - return m_type == isDWARFExpression; - } - - void - SetAtCFAPlusOffset (int32_t offset) - { - m_type = atCFAPlusOffset; - m_location.offset = offset; - } - - void - SetIsCFAPlusOffset (int32_t offset) - { - m_type = isCFAPlusOffset; - m_location.offset = offset; - } - - void - SetInRegister (uint32_t reg_num) - { - m_type = inOtherRegister; - m_location.reg_num = reg_num; - } - - uint32_t - GetRegisterNumber () const - { - if (m_type == inOtherRegister) - return m_location.reg_num; - return LLDB_INVALID_REGNUM; - } - - RestoreType - GetLocationType () const - { - return m_type; - } - - int32_t - GetOffset () const - { - if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset) - return m_location.offset; - return 0; - } - - void - GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const - { - if (m_type == atDWARFExpression || m_type == isDWARFExpression) - { - *opcodes = m_location.expr.opcodes; - len = m_location.expr.length; - } - else - { - *opcodes = nullptr; - len = 0; - } - } - - void - SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len); - - void - SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len); - - const uint8_t * - GetDWARFExpressionBytes () - { - if (m_type == atDWARFExpression || m_type == isDWARFExpression) - return m_location.expr.opcodes; - return nullptr; - } - - int - GetDWARFExpressionLength () - { - if (m_type == atDWARFExpression || m_type == isDWARFExpression) - return m_location.expr.length; - return 0; - } - - void - Dump (Stream &s, - const UnwindPlan* unwind_plan, - const UnwindPlan::Row* row, - Thread* thread, - bool verbose) const; - - private: - RestoreType m_type; // How do we locate this register? - union - { - // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset - int32_t offset; - // For m_type == inOtherRegister - uint32_t reg_num; // The register number - // For m_type == atDWARFExpression or m_type == isDWARFExpression - struct { - const uint8_t *opcodes; - uint16_t length; - } expr; - } m_location; - }; - - class CFAValue - { - public: - enum ValueType - { - unspecified, // not specified - isRegisterPlusOffset, // CFA = register + offset - isRegisterDereferenced, // CFA = [reg] - isDWARFExpression // CFA = eval(dwarf_expr) - }; - - CFAValue() : - m_type(unspecified), - m_value() - { - } - - bool - operator == (const CFAValue& rhs) const; - - bool - operator != (const CFAValue &rhs) const - { - return !(*this == rhs); - } - - void - SetUnspecified() - { - m_type = unspecified; - } - - bool - IsUnspecified () const - { - return m_type == unspecified; - } - - bool - IsRegisterPlusOffset () const - { - return m_type == isRegisterPlusOffset; - } - - void - SetIsRegisterPlusOffset (uint32_t reg_num, int32_t offset) - { - m_type = isRegisterPlusOffset; - m_value.reg.reg_num = reg_num; - m_value.reg.offset = offset; - } - - bool - IsRegisterDereferenced () const - { - return m_type == isRegisterDereferenced; - } - - void - SetIsRegisterDereferenced (uint32_t reg_num) - { - m_type = isRegisterDereferenced; - m_value.reg.reg_num = reg_num; - } - - bool - IsDWARFExpression () const - { - return m_type == isDWARFExpression; - } - - void - SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len) - { - m_type = isDWARFExpression; - m_value.expr.opcodes = opcodes; - m_value.expr.length = len; - } - - uint32_t - GetRegisterNumber () const - { - if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset) - return m_value.reg.reg_num; - return LLDB_INVALID_REGNUM; - } - - ValueType - GetValueType () const - { - return m_type; - } - - int32_t - GetOffset () const - { - if (m_type == isRegisterPlusOffset) - return m_value.reg.offset; - return 0; - } - - void IncOffset (int32_t delta) - { - if (m_type == isRegisterPlusOffset) - m_value.reg.offset += delta; - } - - void SetOffset (int32_t offset) - { - if (m_type == isRegisterPlusOffset) - m_value.reg.offset = offset; - } - - void - GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const - { - if (m_type == isDWARFExpression) - { - *opcodes = m_value.expr.opcodes; - len = m_value.expr.length; - } - else - { - *opcodes = nullptr; - len = 0; - } - } - - const uint8_t * - GetDWARFExpressionBytes () - { - if (m_type == isDWARFExpression) - return m_value.expr.opcodes; - return nullptr; - } - - int - GetDWARFExpressionLength () - { - if (m_type == isDWARFExpression) - return m_value.expr.length; - return 0; - } - - void - Dump (Stream &s, - const UnwindPlan* unwind_plan, - Thread* thread) const; - - private: - ValueType m_type; // How do we compute CFA value? - union - { - struct { - // For m_type == isRegisterPlusOffset or m_type == isRegisterDereferenced - uint32_t reg_num; // The register number - // For m_type == isRegisterPlusOffset - int32_t offset; - } reg; - // For m_type == isDWARFExpression - struct { - const uint8_t *opcodes; - uint16_t length; - } expr; - } m_value; - }; // class CFAValue + enum RestoreType { + unspecified, // not specified, we may be able to assume this + // is the same register. gcc doesn't specify all + // initial values so we really don't know... + undefined, // reg is not available, e.g. volatile reg + same, // reg is unchanged + atCFAPlusOffset, // reg = deref(CFA + offset) + isCFAPlusOffset, // reg = CFA + offset + inOtherRegister, // reg = other reg + atDWARFExpression, // reg = deref(eval(dwarf_expr)) + isDWARFExpression // reg = eval(dwarf_expr) + }; - public: - Row (); + RegisterLocation() : m_type(unspecified), m_location() {} - Row (const UnwindPlan::Row& rhs) = default; + bool operator==(const RegisterLocation &rhs) const; - bool - operator == (const Row &rhs) const; + bool operator!=(const RegisterLocation &rhs) const { + return !(*this == rhs); + } - bool - GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const; - - void - SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location); + void SetUnspecified() { m_type = unspecified; } - void - RemoveRegisterInfo (uint32_t reg_num); + void SetUndefined() { m_type = undefined; } - lldb::addr_t - GetOffset() const - { - return m_offset; - } + void SetSame() { m_type = same; } - void - SetOffset(lldb::addr_t offset) - { - m_offset = offset; - } + bool IsSame() const { return m_type == same; } - void - SlideOffset(lldb::addr_t offset) - { - m_offset += offset; - } + bool IsUnspecified() const { return m_type == unspecified; } + + bool IsUndefined() const { return m_type == undefined; } + + bool IsCFAPlusOffset() const { return m_type == isCFAPlusOffset; } + + bool IsAtCFAPlusOffset() const { return m_type == atCFAPlusOffset; } + + bool IsInOtherRegister() const { return m_type == inOtherRegister; } + + bool IsAtDWARFExpression() const { return m_type == atDWARFExpression; } + + bool IsDWARFExpression() const { return m_type == isDWARFExpression; } + + void SetAtCFAPlusOffset(int32_t offset) { + m_type = atCFAPlusOffset; + m_location.offset = offset; + } + + void SetIsCFAPlusOffset(int32_t offset) { + m_type = isCFAPlusOffset; + m_location.offset = offset; + } + + void SetInRegister(uint32_t reg_num) { + m_type = inOtherRegister; + m_location.reg_num = reg_num; + } - CFAValue& GetCFAValue() - { - return m_cfa_value; + uint32_t GetRegisterNumber() const { + if (m_type == inOtherRegister) + return m_location.reg_num; + return LLDB_INVALID_REGNUM; + } + + RestoreType GetLocationType() const { return m_type; } + + int32_t GetOffset() const { + if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset) + return m_location.offset; + return 0; + } + + void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const { + if (m_type == atDWARFExpression || m_type == isDWARFExpression) { + *opcodes = m_location.expr.opcodes; + len = m_location.expr.length; + } else { + *opcodes = nullptr; + len = 0; + } + } + + void SetAtDWARFExpression(const uint8_t *opcodes, uint32_t len); + + void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len); + + const uint8_t *GetDWARFExpressionBytes() { + if (m_type == atDWARFExpression || m_type == isDWARFExpression) + return m_location.expr.opcodes; + return nullptr; + } + + int GetDWARFExpressionLength() { + if (m_type == atDWARFExpression || m_type == isDWARFExpression) + return m_location.expr.length; + return 0; + } + + void Dump(Stream &s, const UnwindPlan *unwind_plan, + const UnwindPlan::Row *row, Thread *thread, bool verbose) const; + + private: + RestoreType m_type; // How do we locate this register? + union { + // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset + int32_t offset; + // For m_type == inOtherRegister + uint32_t reg_num; // The register number + // For m_type == atDWARFExpression or m_type == isDWARFExpression + struct { + const uint8_t *opcodes; + uint16_t length; + } expr; + } m_location; + }; + + class CFAValue { + public: + enum ValueType { + unspecified, // not specified + isRegisterPlusOffset, // CFA = register + offset + isRegisterDereferenced, // CFA = [reg] + isDWARFExpression // CFA = eval(dwarf_expr) + }; + + CFAValue() : m_type(unspecified), m_value() {} + + bool operator==(const CFAValue &rhs) const; + + bool operator!=(const CFAValue &rhs) const { return !(*this == rhs); } + + void SetUnspecified() { m_type = unspecified; } + + bool IsUnspecified() const { return m_type == unspecified; } + + bool IsRegisterPlusOffset() const { + return m_type == isRegisterPlusOffset; + } + + void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset) { + m_type = isRegisterPlusOffset; + m_value.reg.reg_num = reg_num; + m_value.reg.offset = offset; + } + + bool IsRegisterDereferenced() const { + return m_type == isRegisterDereferenced; + } + + void SetIsRegisterDereferenced(uint32_t reg_num) { + m_type = isRegisterDereferenced; + m_value.reg.reg_num = reg_num; + } + + bool IsDWARFExpression() const { return m_type == isDWARFExpression; } + + void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len) { + m_type = isDWARFExpression; + m_value.expr.opcodes = opcodes; + m_value.expr.length = len; + } + + uint32_t GetRegisterNumber() const { + if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset) + return m_value.reg.reg_num; + return LLDB_INVALID_REGNUM; + } + + ValueType GetValueType() const { return m_type; } + + int32_t GetOffset() const { + if (m_type == isRegisterPlusOffset) + return m_value.reg.offset; + return 0; + } + + void IncOffset(int32_t delta) { + if (m_type == isRegisterPlusOffset) + m_value.reg.offset += delta; + } + + void SetOffset(int32_t offset) { + if (m_type == isRegisterPlusOffset) + m_value.reg.offset = offset; + } + + void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const { + if (m_type == isDWARFExpression) { + *opcodes = m_value.expr.opcodes; + len = m_value.expr.length; + } else { + *opcodes = nullptr; + len = 0; } + } + + const uint8_t *GetDWARFExpressionBytes() { + if (m_type == isDWARFExpression) + return m_value.expr.opcodes; + return nullptr; + } + + int GetDWARFExpressionLength() { + if (m_type == isDWARFExpression) + return m_value.expr.length; + return 0; + } + + void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const; + + private: + ValueType m_type; // How do we compute CFA value? + union { + struct { + // For m_type == isRegisterPlusOffset or m_type == + // isRegisterDereferenced + uint32_t reg_num; // The register number + // For m_type == isRegisterPlusOffset + int32_t offset; + } reg; + // For m_type == isDWARFExpression + struct { + const uint8_t *opcodes; + uint16_t length; + } expr; + } m_value; + }; // class CFAValue + + public: + Row(); + + Row(const UnwindPlan::Row &rhs) = default; + + bool operator==(const Row &rhs) const; + + bool GetRegisterInfo(uint32_t reg_num, + RegisterLocation ®ister_location) const; + + void SetRegisterInfo(uint32_t reg_num, + const RegisterLocation register_location); + + void RemoveRegisterInfo(uint32_t reg_num); + + lldb::addr_t GetOffset() const { return m_offset; } - bool - SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, - int32_t offset, + void SetOffset(lldb::addr_t offset) { m_offset = offset; } + + void SlideOffset(lldb::addr_t offset) { m_offset += offset; } + + CFAValue &GetCFAValue() { return m_cfa_value; } + + bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace); - bool - SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num, - int32_t offset, + bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace); - bool - SetRegisterLocationToUndefined (uint32_t reg_num, - bool can_replace, + bool SetRegisterLocationToUndefined(uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified); - bool - SetRegisterLocationToUnspecified (uint32_t reg_num, - bool can_replace); + bool SetRegisterLocationToUnspecified(uint32_t reg_num, bool can_replace); - bool - SetRegisterLocationToRegister (uint32_t reg_num, - uint32_t other_reg_num, + bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace); - bool - SetRegisterLocationToSame (uint32_t reg_num, - bool must_replace); + bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace); - void - Clear (); + void Clear(); - void - Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, lldb::addr_t base_addr) const; + void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, + lldb::addr_t base_addr) const; - protected: - typedef std::map<uint32_t, RegisterLocation> collection; - lldb::addr_t m_offset; // Offset into the function for this row + protected: + typedef std::map<uint32_t, RegisterLocation> collection; + lldb::addr_t m_offset; // Offset into the function for this row - CFAValue m_cfa_value; - collection m_register_locations; - }; // class Row + CFAValue m_cfa_value; + collection m_register_locations; + }; // class Row public: - typedef std::shared_ptr<Row> RowSP; - - UnwindPlan (lldb::RegisterKind reg_kind) : - m_row_list (), - m_plan_valid_address_range (), - m_register_kind (reg_kind), - m_return_addr_register (LLDB_INVALID_REGNUM), - m_source_name (), - m_plan_is_sourced_from_compiler (eLazyBoolCalculate), - m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate), - m_lsda_address (), - m_personality_func_addr () - { - } - - // Performs a deep copy of the plan, including all the rows (expensive). - UnwindPlan (const UnwindPlan &rhs) : - m_plan_valid_address_range (rhs.m_plan_valid_address_range), - m_register_kind (rhs.m_register_kind), - m_return_addr_register (rhs.m_return_addr_register), - m_source_name (rhs.m_source_name), - m_plan_is_sourced_from_compiler (rhs.m_plan_is_sourced_from_compiler), - m_plan_is_valid_at_all_instruction_locations (rhs.m_plan_is_valid_at_all_instruction_locations), - m_lsda_address (rhs.m_lsda_address), - m_personality_func_addr (rhs.m_personality_func_addr) - { - m_row_list.reserve (rhs.m_row_list.size()); - for (const RowSP &row_sp: rhs.m_row_list) - m_row_list.emplace_back (new Row (*row_sp)); - } - - ~UnwindPlan() = default; - - void - Dump (Stream& s, Thread* thread, lldb::addr_t base_addr) const; - - void - AppendRow (const RowSP& row_sp); - - void - InsertRow (const RowSP& row_sp, bool replace_existing = false); - - // Returns a pointer to the best row for the given offset into the function's instructions. - // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned. - // In practice, the UnwindPlan for a function with no known start address will be the architectural default - // UnwindPlan which will only have one row. - UnwindPlan::RowSP - GetRowForFunctionOffset (int offset) const; - - lldb::RegisterKind - GetRegisterKind () const - { - return m_register_kind; - } - - void - SetRegisterKind (lldb::RegisterKind kind) - { - m_register_kind = kind; - } - - void - SetReturnAddressRegister (uint32_t regnum) - { - m_return_addr_register = regnum; - } - - uint32_t - GetReturnAddressRegister (void) - { - return m_return_addr_register; - } - - uint32_t - GetInitialCFARegister () const - { - if (m_row_list.empty()) - return LLDB_INVALID_REGNUM; - return m_row_list.front()->GetCFAValue().GetRegisterNumber(); - } - - // This UnwindPlan may not be valid at every address of the function span. - // For instance, a FastUnwindPlan will not be valid at the prologue setup - // instructions - only in the body of the function. - void - SetPlanValidAddressRange (const AddressRange& range); - - const AddressRange & - GetAddressRange () const - { - return m_plan_valid_address_range; - } - - bool - PlanValidAtAddress (Address addr); - - bool - IsValidRowIndex (uint32_t idx) const; - - const UnwindPlan::RowSP - GetRowAtIndex (uint32_t idx) const; - - const UnwindPlan::RowSP - GetLastRow () const; - - lldb_private::ConstString - GetSourceName () const; - - void - SetSourceName (const char *); - - // Was this UnwindPlan emitted by a compiler? - lldb_private::LazyBool - GetSourcedFromCompiler () const - { - return m_plan_is_sourced_from_compiler; - } - - // Was this UnwindPlan emitted by a compiler? - void - SetSourcedFromCompiler (lldb_private::LazyBool from_compiler) - { - m_plan_is_sourced_from_compiler = from_compiler; - } - - // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites, - // e.g. for exception handling. - lldb_private::LazyBool - GetUnwindPlanValidAtAllInstructions () const - { - return m_plan_is_valid_at_all_instruction_locations; - } - - // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites, - // e.g. for exception handling. - void - SetUnwindPlanValidAtAllInstructions (lldb_private::LazyBool valid_at_all_insn) - { - m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn; - } - - int - GetRowCount () const; - - void - Clear() - { - m_row_list.clear(); - m_plan_valid_address_range.Clear(); - m_register_kind = lldb::eRegisterKindDWARF; - m_source_name.Clear(); - m_plan_is_sourced_from_compiler = eLazyBoolCalculate; - m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate; - m_lsda_address.Clear(); - m_personality_func_addr.Clear(); - } - - const RegisterInfo * - GetRegisterInfo (Thread* thread, uint32_t reg_num) const; - - Address - GetLSDAAddress () const - { - return m_lsda_address; - } - - void - SetLSDAAddress (Address lsda_addr) - { - m_lsda_address = lsda_addr; - } - - Address - GetPersonalityFunctionPtr () const - { - return m_personality_func_addr; - } - - void - SetPersonalityFunctionPtr (Address presonality_func_ptr) - { - m_personality_func_addr = presonality_func_ptr; - } + typedef std::shared_ptr<Row> RowSP; + + UnwindPlan(lldb::RegisterKind reg_kind) + : m_row_list(), m_plan_valid_address_range(), m_register_kind(reg_kind), + m_return_addr_register(LLDB_INVALID_REGNUM), m_source_name(), + m_plan_is_sourced_from_compiler(eLazyBoolCalculate), + m_plan_is_valid_at_all_instruction_locations(eLazyBoolCalculate), + m_lsda_address(), m_personality_func_addr() {} + + // Performs a deep copy of the plan, including all the rows (expensive). + UnwindPlan(const UnwindPlan &rhs) + : m_plan_valid_address_range(rhs.m_plan_valid_address_range), + m_register_kind(rhs.m_register_kind), + m_return_addr_register(rhs.m_return_addr_register), + m_source_name(rhs.m_source_name), + m_plan_is_sourced_from_compiler(rhs.m_plan_is_sourced_from_compiler), + m_plan_is_valid_at_all_instruction_locations( + rhs.m_plan_is_valid_at_all_instruction_locations), + m_lsda_address(rhs.m_lsda_address), + m_personality_func_addr(rhs.m_personality_func_addr) { + m_row_list.reserve(rhs.m_row_list.size()); + for (const RowSP &row_sp : rhs.m_row_list) + m_row_list.emplace_back(new Row(*row_sp)); + } + + ~UnwindPlan() = default; + + void Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const; + + void AppendRow(const RowSP &row_sp); + + void InsertRow(const RowSP &row_sp, bool replace_existing = false); + + // Returns a pointer to the best row for the given offset into the function's + // instructions. + // If offset is -1 it indicates that the function start is unknown - the final + // row in the UnwindPlan is returned. + // In practice, the UnwindPlan for a function with no known start address will + // be the architectural default + // UnwindPlan which will only have one row. + UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const; + + lldb::RegisterKind GetRegisterKind() const { return m_register_kind; } + + void SetRegisterKind(lldb::RegisterKind kind) { m_register_kind = kind; } + + void SetReturnAddressRegister(uint32_t regnum) { + m_return_addr_register = regnum; + } + + uint32_t GetReturnAddressRegister(void) { return m_return_addr_register; } + + uint32_t GetInitialCFARegister() const { + if (m_row_list.empty()) + return LLDB_INVALID_REGNUM; + return m_row_list.front()->GetCFAValue().GetRegisterNumber(); + } + + // This UnwindPlan may not be valid at every address of the function span. + // For instance, a FastUnwindPlan will not be valid at the prologue setup + // instructions - only in the body of the function. + void SetPlanValidAddressRange(const AddressRange &range); + + const AddressRange &GetAddressRange() const { + return m_plan_valid_address_range; + } + + bool PlanValidAtAddress(Address addr); + + bool IsValidRowIndex(uint32_t idx) const; + + const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const; + + const UnwindPlan::RowSP GetLastRow() const; + + lldb_private::ConstString GetSourceName() const; + + void SetSourceName(const char *); + + // Was this UnwindPlan emitted by a compiler? + lldb_private::LazyBool GetSourcedFromCompiler() const { + return m_plan_is_sourced_from_compiler; + } + + // Was this UnwindPlan emitted by a compiler? + void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler) { + m_plan_is_sourced_from_compiler = from_compiler; + } + + // Is this UnwindPlan valid at all instructions? If not, then it is assumed + // valid at call sites, + // e.g. for exception handling. + lldb_private::LazyBool GetUnwindPlanValidAtAllInstructions() const { + return m_plan_is_valid_at_all_instruction_locations; + } + + // Is this UnwindPlan valid at all instructions? If not, then it is assumed + // valid at call sites, + // e.g. for exception handling. + void SetUnwindPlanValidAtAllInstructions( + lldb_private::LazyBool valid_at_all_insn) { + m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn; + } + + int GetRowCount() const; + + void Clear() { + m_row_list.clear(); + m_plan_valid_address_range.Clear(); + m_register_kind = lldb::eRegisterKindDWARF; + m_source_name.Clear(); + m_plan_is_sourced_from_compiler = eLazyBoolCalculate; + m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate; + m_lsda_address.Clear(); + m_personality_func_addr.Clear(); + } + + const RegisterInfo *GetRegisterInfo(Thread *thread, uint32_t reg_num) const; + + Address GetLSDAAddress() const { return m_lsda_address; } + + void SetLSDAAddress(Address lsda_addr) { m_lsda_address = lsda_addr; } + + Address GetPersonalityFunctionPtr() const { return m_personality_func_addr; } + + void SetPersonalityFunctionPtr(Address presonality_func_ptr) { + m_personality_func_addr = presonality_func_ptr; + } private: - typedef std::vector<RowSP> collection; - collection m_row_list; - AddressRange m_plan_valid_address_range; - lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be - // translated to lldb native reg nums at unwind time - uint32_t m_return_addr_register; // The register that has the return address for the caller frame - // e.g. the lr on arm - lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from - lldb_private::LazyBool m_plan_is_sourced_from_compiler; - lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations; - - Address m_lsda_address; // Where the language specific data area exists in the module - used - // in exception handling. - Address m_personality_func_addr; // The address of a pointer to the personality function - used in - // exception handling. -}; // class UnwindPlan + typedef std::vector<RowSP> collection; + collection m_row_list; + AddressRange m_plan_valid_address_range; + lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers + // are in terms of - will need to be + // translated to lldb native reg nums at unwind time + uint32_t m_return_addr_register; // The register that has the return address + // for the caller frame + // e.g. the lr on arm + lldb_private::ConstString + m_source_name; // for logging, where this UnwindPlan originated from + lldb_private::LazyBool m_plan_is_sourced_from_compiler; + lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations; + + Address m_lsda_address; // Where the language specific data area exists in the + // module - used + // in exception handling. + Address m_personality_func_addr; // The address of a pointer to the + // personality function - used in + // exception handling. +}; // class UnwindPlan } // namespace lldb_private diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h index cb0080aff881..e730454b04d1 100644 --- a/include/lldb/Symbol/UnwindTable.h +++ b/include/lldb/Symbol/UnwindTable.h @@ -7,14 +7,13 @@ // //===----------------------------------------------------------------------===// - #ifndef liblldb_UnwindTable_h #define liblldb_UnwindTable_h #include <map> #include <mutex> -#include "lldb/lldb-private.h" +#include "lldb/lldb-private.h" namespace lldb_private { @@ -22,62 +21,61 @@ namespace lldb_private { // The UnwindTable is populated with FuncUnwinders objects lazily during // the debug session. -class UnwindTable -{ +class UnwindTable { public: - UnwindTable(ObjectFile& objfile); - ~UnwindTable(); + UnwindTable(ObjectFile &objfile); + ~UnwindTable(); - lldb_private::DWARFCallFrameInfo * - GetEHFrameInfo (); + lldb_private::DWARFCallFrameInfo *GetEHFrameInfo(); - lldb_private::CompactUnwindInfo * - GetCompactUnwindInfo (); + lldb_private::CompactUnwindInfo *GetCompactUnwindInfo(); - ArmUnwindInfo * - GetArmUnwindInfo (); + ArmUnwindInfo *GetArmUnwindInfo(); - lldb::FuncUnwindersSP - GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); + lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress(const Address &addr, + SymbolContext &sc); - bool - GetAllowAssemblyEmulationUnwindPlans (); + bool GetAllowAssemblyEmulationUnwindPlans(); -// Normally when we create a new FuncUnwinders object we track it in this UnwindTable so it can -// be reused later. But for the target modules show-unwind we want to create brand new -// UnwindPlans for the function of interest - so ignore any existing FuncUnwinders for that -// function and don't add this new one to our UnwindTable. -// This FuncUnwinders object does have a reference to the UnwindTable but the lifetime of this -// uncached FuncUnwinders is expected to be short so in practice this will not be a problem. - lldb::FuncUnwindersSP - GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); + // Normally when we create a new FuncUnwinders object we track it in this + // UnwindTable so it can + // be reused later. But for the target modules show-unwind we want to create + // brand new + // UnwindPlans for the function of interest - so ignore any existing + // FuncUnwinders for that + // function and don't add this new one to our UnwindTable. + // This FuncUnwinders object does have a reference to the UnwindTable but the + // lifetime of this + // uncached FuncUnwinders is expected to be short so in practice this will not + // be a problem. + lldb::FuncUnwindersSP + GetUncachedFuncUnwindersContainingAddress(const Address &addr, + SymbolContext &sc); - bool - GetArchitecture (lldb_private::ArchSpec &arch); + bool GetArchitecture(lldb_private::ArchSpec &arch); private: - void - Dump (Stream &s); - - void Initialize (); + void Dump(Stream &s); + + void Initialize(); - typedef std::map<lldb::addr_t, lldb::FuncUnwindersSP> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + typedef std::map<lldb::addr_t, lldb::FuncUnwindersSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; - ObjectFile& m_object_file; - collection m_unwinds; + ObjectFile &m_object_file; + collection m_unwinds; - bool m_initialized; // delay some initialization until ObjectFile is set up - std::mutex m_mutex; + bool m_initialized; // delay some initialization until ObjectFile is set up + std::mutex m_mutex; - std::unique_ptr<DWARFCallFrameInfo> m_eh_frame_up; - std::unique_ptr<CompactUnwindInfo> m_compact_unwind_up; - std::unique_ptr<ArmUnwindInfo> m_arm_unwind_up; + std::unique_ptr<DWARFCallFrameInfo> m_eh_frame_up; + std::unique_ptr<CompactUnwindInfo> m_compact_unwind_up; + std::unique_ptr<ArmUnwindInfo> m_arm_unwind_up; - DISALLOW_COPY_AND_ASSIGN (UnwindTable); + DISALLOW_COPY_AND_ASSIGN(UnwindTable); }; } // namespace lldb_private -#endif // liblldb_UnwindTable_h +#endif // liblldb_UnwindTable_h diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h index 00761424d107..33249891d36b 100644 --- a/include/lldb/Symbol/Variable.h +++ b/include/lldb/Symbol/Variable.h @@ -1,5 +1,4 @@ -//===-- Variable.h ----------------------------------------------*- C++ -//-*-===// +//===-- Variable.h -----------------------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -14,193 +13,129 @@ #include <memory> #include <vector> -#include "lldb/lldb-private.h" -#include "lldb/lldb-enumerations.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/UserID.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/Declaration.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class Variable : public UserID, - public std::enable_shared_from_this<Variable> -{ +class Variable : public UserID, public std::enable_shared_from_this<Variable> { public: - typedef RangeVector<lldb::addr_t, lldb::addr_t> RangeList; - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - Variable (lldb::user_id_t uid, - const char *name, - const char *mangled, // The mangled or fully qualified name of the variable. - const lldb::SymbolFileTypeSP &symfile_type_sp, - lldb::ValueType scope, - SymbolContextScope *owner_scope, - const RangeList& scope_range, - Declaration* decl, - const DWARFExpression& location, - bool external, - bool artificial, - bool static_member = false); - - virtual - ~Variable(); - - void - Dump(Stream *s, bool show_context) const; - - bool - DumpDeclaration (Stream *s, - bool show_fullpaths, - bool show_module); - - const Declaration& - GetDeclaration() const - { - return m_declaration; - } - - ConstString - GetName() const; - - ConstString - GetUnqualifiedName() const; - - SymbolContextScope * - GetSymbolContextScope() const - { - return m_owner_scope; - } - - // Since a variable can have a basename "i" and also a mangled - // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name - // "(anonymous namespace)::i", this function will allow a generic match - // function that can be called by commands and expression parsers to make - // sure we match anything we come across. - bool - NameMatches (const ConstString &name) const; - - bool - NameMatches (const RegularExpression& regex) const; - - Type * - GetType(); - - lldb::LanguageType - GetLanguage () const; - - lldb::ValueType - GetScope() const - { - return m_scope; - } - - bool - IsExternal() const - { - return m_external; - } - - bool - IsArtificial() const - { - return m_artificial; - } - - bool IsStaticMember() const - { - return m_static_member; - } - - DWARFExpression & - LocationExpression() - { - return m_location; - } - - const DWARFExpression & - LocationExpression() const - { - return m_location; - } - - bool - DumpLocationForAddress (Stream *s, - const Address &address); - - size_t - MemorySize() const; - - void - CalculateSymbolContext (SymbolContext *sc); - - bool - IsInScope (StackFrame *frame); - - bool - LocationIsValidForFrame (StackFrame *frame); - - bool - LocationIsValidForAddress (const Address &address); - - bool - GetLocationIsConstantValueData () const - { - return m_loc_is_const_data; - } - - void - SetLocationIsConstantValueData (bool b) - { - m_loc_is_const_data = b; - } - - typedef size_t (*GetVariableCallback) (void *baton, - const char *name, - VariableList &var_list); - - - static Error - GetValuesForVariableExpressionPath (const char *variable_expr_path, - ExecutionContextScope *scope, - GetVariableCallback callback, - void *baton, - VariableList &variable_list, - ValueObjectList &valobj_list); - - static size_t - AutoComplete (const ExecutionContext &exe_ctx, - const char *name, - StringList &matches, - bool &word_complete); - - CompilerDeclContext - GetDeclContext (); - - CompilerDecl - GetDecl (); + typedef RangeVector<lldb::addr_t, lldb::addr_t> RangeList; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + Variable(lldb::user_id_t uid, const char *name, + const char + *mangled, // The mangled or fully qualified name of the variable. + const lldb::SymbolFileTypeSP &symfile_type_sp, + lldb::ValueType scope, SymbolContextScope *owner_scope, + const RangeList &scope_range, Declaration *decl, + const DWARFExpression &location, bool external, bool artificial, + bool static_member = false); + + virtual ~Variable(); + + void Dump(Stream *s, bool show_context) const; + + bool DumpDeclaration(Stream *s, bool show_fullpaths, bool show_module); + + const Declaration &GetDeclaration() const { return m_declaration; } + + ConstString GetName() const; + + ConstString GetUnqualifiedName() const; + + SymbolContextScope *GetSymbolContextScope() const { return m_owner_scope; } + + // Since a variable can have a basename "i" and also a mangled + // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name + // "(anonymous namespace)::i", this function will allow a generic match + // function that can be called by commands and expression parsers to make + // sure we match anything we come across. + bool NameMatches(const ConstString &name) const; + + bool NameMatches(const RegularExpression ®ex) const; + + Type *GetType(); + + lldb::LanguageType GetLanguage() const; + + lldb::ValueType GetScope() const { return m_scope; } + + bool IsExternal() const { return m_external; } + + bool IsArtificial() const { return m_artificial; } + + bool IsStaticMember() const { return m_static_member; } + + DWARFExpression &LocationExpression() { return m_location; } + + const DWARFExpression &LocationExpression() const { return m_location; } + + bool DumpLocationForAddress(Stream *s, const Address &address); + + size_t MemorySize() const; + + void CalculateSymbolContext(SymbolContext *sc); + + bool IsInScope(StackFrame *frame); + + bool LocationIsValidForFrame(StackFrame *frame); + + bool LocationIsValidForAddress(const Address &address); + + bool GetLocationIsConstantValueData() const { return m_loc_is_const_data; } + + void SetLocationIsConstantValueData(bool b) { m_loc_is_const_data = b; } + + typedef size_t (*GetVariableCallback)(void *baton, const char *name, + VariableList &var_list); + + static Error GetValuesForVariableExpressionPath( + llvm::StringRef variable_expr_path, ExecutionContextScope *scope, + GetVariableCallback callback, void *baton, VariableList &variable_list, + ValueObjectList &valobj_list); + + static size_t AutoComplete(const ExecutionContext &exe_ctx, + llvm::StringRef name, StringList &matches, + bool &word_complete); + + CompilerDeclContext GetDeclContext(); + + CompilerDecl GetDecl(); protected: - ConstString m_name; // The basename of the variable (no namespaces) - Mangled m_mangled; // The mangled name of the variable - lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable (int, struct, class, etc) - lldb::ValueType m_scope; // global, parameter, local - SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in - RangeList m_scope_range; // The list of ranges inside the owner's scope where this variable is valid - Declaration m_declaration; // Declaration location for this item. - DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() - uint8_t m_external:1, // Visible outside the containing compile unit? - m_artificial:1, // Non-zero if the variable is not explicitly declared in source - m_loc_is_const_data:1, // The m_location expression contains the constant variable value data, not a DWARF location - m_static_member:1; // Non-zero if variable is static member of a class or struct. + ConstString m_name; // The basename of the variable (no namespaces) + Mangled m_mangled; // The mangled name of the variable + lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable + // (int, struct, class, etc) + lldb::ValueType m_scope; // global, parameter, local + SymbolContextScope + *m_owner_scope; // The symbol file scope that this variable was defined in + RangeList m_scope_range; // The list of ranges inside the owner's scope where + // this variable is valid + Declaration m_declaration; // Declaration location for this item. + DWARFExpression m_location; // The location of this variable that can be fed + // to DWARFExpression::Evaluate() + uint8_t m_external : 1, // Visible outside the containing compile unit? + m_artificial : 1, // Non-zero if the variable is not explicitly declared + // in source + m_loc_is_const_data : 1, // The m_location expression contains the + // constant variable value data, not a DWARF + // location + m_static_member : 1; // Non-zero if variable is static member of a class + // or struct. private: - Variable(const Variable& rhs); - Variable& operator=(const Variable& rhs); + Variable(const Variable &rhs); + Variable &operator=(const Variable &rhs); }; } // namespace lldb_private -#endif // liblldb_Variable_h_ +#endif // liblldb_Variable_h_ diff --git a/include/lldb/Symbol/VariableList.h b/include/lldb/Symbol/VariableList.h index 1c1d5dfefb9e..c9e0be89a3bc 100644 --- a/include/lldb/Symbol/VariableList.h +++ b/include/lldb/Symbol/VariableList.h @@ -10,92 +10,77 @@ #ifndef liblldb_VariableList_h_ #define liblldb_VariableList_h_ -#include "lldb/lldb-private.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Variable.h" +#include "lldb/lldb-private.h" namespace lldb_private { -class VariableList -{ +class VariableList { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ -// VariableList(const SymbolContext &symbol_context); - VariableList(); - virtual ~VariableList(); - - void - AddVariable (const lldb::VariableSP &var_sp); - - bool - AddVariableIfUnique (const lldb::VariableSP &var_sp); - - void - AddVariables (VariableList *variable_list); - - void - Clear(); - - void - Dump(Stream *s, bool show_context) const; - - lldb::VariableSP - GetVariableAtIndex(size_t idx) const; - - lldb::VariableSP - RemoveVariableAtIndex (size_t idx); - - lldb::VariableSP - FindVariable (const ConstString& name, bool include_static_members = true); - - lldb::VariableSP - FindVariable (const ConstString& name, lldb::ValueType value_type, bool include_static_members = true); - - uint32_t - FindVariableIndex (const lldb::VariableSP &var_sp); - - size_t - AppendVariablesIfUnique(VariableList &var_list); - - // Returns the actual number of unique variables that were added to the - // list. "total_matches" will get updated with the actually number of - // matches that were found regardless of whether they were unique or not - // to allow for error conditions when nothing is found, versus conditions - // where any variables that match "regex" were already in "var_list". - size_t - AppendVariablesIfUnique (const RegularExpression& regex, - VariableList &var_list, - size_t& total_matches); - - size_t - AppendVariablesWithScope (lldb::ValueType type, - VariableList &var_list, - bool if_unique = true); - - uint32_t - FindIndexForVariable (Variable* variable); - - size_t - MemorySize() const; - - size_t - GetSize() const; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + // VariableList(const SymbolContext &symbol_context); + VariableList(); + virtual ~VariableList(); + + void AddVariable(const lldb::VariableSP &var_sp); + + bool AddVariableIfUnique(const lldb::VariableSP &var_sp); + + void AddVariables(VariableList *variable_list); + + void Clear(); + + void Dump(Stream *s, bool show_context) const; + + lldb::VariableSP GetVariableAtIndex(size_t idx) const; + + lldb::VariableSP RemoveVariableAtIndex(size_t idx); + + lldb::VariableSP FindVariable(const ConstString &name, + bool include_static_members = true); + + lldb::VariableSP FindVariable(const ConstString &name, + lldb::ValueType value_type, + bool include_static_members = true); + + uint32_t FindVariableIndex(const lldb::VariableSP &var_sp); + + size_t AppendVariablesIfUnique(VariableList &var_list); + + // Returns the actual number of unique variables that were added to the + // list. "total_matches" will get updated with the actually number of + // matches that were found regardless of whether they were unique or not + // to allow for error conditions when nothing is found, versus conditions + // where any variables that match "regex" were already in "var_list". + size_t AppendVariablesIfUnique(const RegularExpression ®ex, + VariableList &var_list, size_t &total_matches); + + size_t AppendVariablesWithScope(lldb::ValueType type, VariableList &var_list, + bool if_unique = true); + + uint32_t FindIndexForVariable(Variable *variable); + + size_t MemorySize() const; + + size_t GetSize() const; protected: - typedef std::vector<lldb::VariableSP> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; + typedef std::vector<lldb::VariableSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + collection m_variables; - collection m_variables; private: - //------------------------------------------------------------------ - // For VariableList only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (VariableList); + //------------------------------------------------------------------ + // For VariableList only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN(VariableList); }; } // namespace lldb_private -#endif // liblldb_VariableList_h_ +#endif // liblldb_VariableList_h_ diff --git a/include/lldb/Symbol/VerifyDecl.h b/include/lldb/Symbol/VerifyDecl.h index 228e635652e6..f4b61e6355ce 100644 --- a/include/lldb/Symbol/VerifyDecl.h +++ b/include/lldb/Symbol/VerifyDecl.h @@ -12,9 +12,8 @@ #include "lldb/Core/ClangForward.h" -namespace lldb_private -{ - void VerifyDecl (clang::Decl *decl); +namespace lldb_private { +void VerifyDecl(clang::Decl *decl); } #endif |