Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:51

0001 //===-- Block.h -------------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_SYMBOL_BLOCK_H
0010 #define LLDB_SYMBOL_BLOCK_H
0011 
0012 #include "lldb/Core/AddressRange.h"
0013 #include "lldb/Symbol/CompilerType.h"
0014 #include "lldb/Symbol/LineEntry.h"
0015 #include "lldb/Symbol/SymbolContext.h"
0016 #include "lldb/Symbol/SymbolContextScope.h"
0017 #include "lldb/Utility/RangeMap.h"
0018 #include "lldb/Utility/Stream.h"
0019 #include "lldb/Utility/UserID.h"
0020 #include "lldb/lldb-private.h"
0021 #include <vector>
0022 
0023 namespace lldb_private {
0024 
0025 /// \class Block Block.h "lldb/Symbol/Block.h"
0026 /// A class that describes a single lexical block.
0027 ///
0028 /// A Function object owns a BlockList object which owns one or more
0029 /// Block objects. The BlockList object contains a section offset address
0030 /// range, and Block objects contain one or more ranges which are offsets into
0031 /// that range. Blocks are can have discontiguous ranges within the BlockList
0032 /// address range, and each block can contain child blocks each with their own
0033 /// sets of ranges.
0034 ///
0035 /// Each block has a variable list that represents local, argument, and static
0036 /// variables that are scoped to the block.
0037 ///
0038 /// Inlined functions are represented by attaching a InlineFunctionInfo shared
0039 /// pointer object to a block. Inlined functions are represented as named
0040 /// blocks.
0041 class Block : public UserID, public SymbolContextScope {
0042 public:
0043   typedef RangeVector<int32_t, uint32_t, 1> RangeList;
0044   typedef RangeList::Entry Range;
0045 
0046   // Creates a block representing the whole function. Only meant to be used from
0047   // the Function class.
0048   Block(Function &function, lldb::user_id_t function_uid);
0049 
0050   ~Block() override;
0051 
0052   /// Creates a block with the specified UID \a uid.
0053   ///
0054   /// \param[in] uid
0055   ///     The UID for a given block. This value is given by the
0056   ///     SymbolFile plug-in and can be any value that helps the
0057   ///     SymbolFile plug-in to match this block back to the debug
0058   ///     information data that it parses for further or more in
0059   ///     depth parsing. Common values would be the index into a
0060   ///     table, or an offset into the debug information.
0061   lldb::BlockSP CreateChild(lldb::user_id_t uid);
0062 
0063   /// Add a new offset range to this block.
0064   void AddRange(const Range &range);
0065 
0066   void FinalizeRanges();
0067 
0068   /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
0069   ///
0070   /// \see SymbolContextScope
0071   void CalculateSymbolContext(SymbolContext *sc) override;
0072 
0073   lldb::ModuleSP CalculateSymbolContextModule() override;
0074 
0075   CompileUnit *CalculateSymbolContextCompileUnit() override;
0076 
0077   Function *CalculateSymbolContextFunction() override;
0078 
0079   Block *CalculateSymbolContextBlock() override;
0080 
0081   /// Check if an offset is in one of the block offset ranges.
0082   ///
0083   /// \param[in] range_offset
0084   ///     An offset into the Function's address range.
0085   ///
0086   /// \return
0087   ///     Returns \b true if \a range_offset falls in one of this
0088   ///     block's ranges, \b false otherwise.
0089   bool Contains(lldb::addr_t range_offset) const;
0090 
0091   /// Check if a offset range is in one of the block offset ranges.
0092   ///
0093   /// \param[in] range
0094   ///     An offset range into the Function's address range.
0095   ///
0096   /// \return
0097   ///     Returns \b true if \a range falls in one of this
0098   ///     block's ranges, \b false otherwise.
0099   bool Contains(const Range &range) const;
0100 
0101   /// Check if this object contains "block" as a child block at any depth.
0102   ///
0103   /// \param[in] block
0104   ///     A potential child block.
0105   ///
0106   /// \return
0107   ///     Returns \b true if \a block is a child of this block, \b
0108   ///     false otherwise.
0109   bool Contains(const Block *block) const;
0110 
0111   /// Dump the block contents.
0112   ///
0113   /// \param[in] s
0114   ///     The stream to which to dump the object description.
0115   ///
0116   /// \param[in] base_addr
0117   ///     The resolved start address of the Function's address
0118   ///     range. This should be resolved as the file or load address
0119   ///     prior to passing the value into this function for dumping.
0120   ///
0121   /// \param[in] depth
0122   ///     Limit the number of levels deep that this function should
0123   ///     print as this block can contain child blocks. Specify
0124   ///     INT_MAX to dump all child blocks.
0125   ///
0126   /// \param[in] show_context
0127   ///     If \b true, variables will dump their context information.
0128   void Dump(Stream *s, lldb::addr_t base_addr, int32_t depth,
0129             bool show_context) const;
0130 
0131   /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
0132   ///
0133   /// \see SymbolContextScope
0134   void DumpSymbolContext(Stream *s) override;
0135 
0136   void DumpAddressRanges(Stream *s, lldb::addr_t base_addr);
0137 
0138   void GetDescription(Stream *s, Function *function,
0139                       lldb::DescriptionLevel level, Target *target) const;
0140 
0141   /// Get the parent block.
0142   ///
0143   /// \return
0144   ///     The parent block pointer, or nullptr if this block has no
0145   ///     parent.
0146   Block *GetParent() const;
0147 
0148   /// Get the inlined block that contains this block.
0149   ///
0150   /// \return
0151   ///     If this block contains inlined function info, it will return
0152   ///     this block, else parent blocks will be searched to see if
0153   ///     any contain this block. nullptr will be returned if this block
0154   ///     nor any parent blocks are inlined function blocks.
0155   Block *GetContainingInlinedBlock();
0156 
0157   /// Get the inlined parent block for this block.
0158   ///
0159   /// \return
0160   ///     The parent block pointer, or nullptr if this block has no
0161   ///     parent.
0162   Block *GetInlinedParent();
0163 
0164   //------------------------------------------------------------------
0165   /// Get the inlined block at the given call site that contains this block.
0166   ///
0167   /// @param[in] find_call_site
0168   ///     a declaration with the file and line of the call site to find.
0169   ///
0170   /// @return
0171   ///     If this block contains inlined function info and is at the call
0172   ///     site given by the file and line at the given \b declaration, then
0173   ///     it will return this block, otherwise the parent blocks will be
0174   ///     searched to see if any is at the call site. nullptr will be returned
0175   ///     if no block is found at the call site.
0176   //------------------------------------------------------------------
0177   Block *
0178   GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site);
0179 
0180   /// Get the sibling block for this block.
0181   ///
0182   /// \return
0183   ///     The sibling block pointer, or nullptr if this block has no
0184   ///     sibling.
0185   Block *GetSibling() const;
0186 
0187   /// Get the first child block.
0188   ///
0189   /// \return
0190   ///     The first child block pointer, or nullptr if this block has no
0191   ///     children.
0192   Block *GetFirstChild() const {
0193     return (m_children.empty() ? nullptr : m_children.front().get());
0194   }
0195 
0196   /// Get the variable list for this block only.
0197   ///
0198   /// \param[in] can_create
0199   ///     If \b true, the variables can be parsed if they already
0200   ///     haven't been, else the current state of the block will be
0201   ///     returned.
0202   ///
0203   /// \return
0204   ///     A variable list shared pointer that contains all variables
0205   ///     for this block.
0206   lldb::VariableListSP GetBlockVariableList(bool can_create);
0207 
0208   /// Get the variable list for this block and optionally all child blocks if
0209   /// \a get_child_variables is \b true.
0210   ///
0211   /// \param[in] can_create
0212   ///     If \b true, the variables can be parsed if they already
0213   ///     haven't been, else the current state of the block will be
0214   ///     returned. Passing \b true for this parameter can be used
0215   ///     to see the current state of what has been parsed up to this
0216   ///     point.
0217   ///
0218   /// \param[in] get_child_block_variables
0219   ///     If \b true, all variables from all child blocks will be
0220   ///     added to the variable list.
0221   ///
0222   /// \return
0223   ///     A variable list shared pointer that contains all variables
0224   ///     for this block.
0225   uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables,
0226                                 bool stop_if_child_block_is_inlined_function,
0227                                 const std::function<bool(Variable *)> &filter,
0228                                 VariableList *variable_list);
0229 
0230   /// Appends the variables from this block, and optionally from all parent
0231   /// blocks, to \a variable_list.
0232   ///
0233   /// \param[in] can_create
0234   ///     If \b true, the variables can be parsed if they already
0235   ///     haven't been, else the current state of the block will be
0236   ///     returned. Passing \b true for this parameter can be used
0237   ///     to see the current state of what has been parsed up to this
0238   ///     point.
0239   ///
0240   /// \param[in] get_parent_variables
0241   ///     If \b true, all variables from all parent blocks will be
0242   ///     added to the variable list.
0243   ///
0244   /// \param[in] stop_if_block_is_inlined_function
0245   ///     If \b true, all variables from all parent blocks will be
0246   ///     added to the variable list until there are no parent blocks
0247   ///     or the parent block has inlined function info.
0248   ///
0249   /// \param[in,out] variable_list
0250   ///     All variables in this block, and optionally all parent
0251   ///     blocks will be added to this list.
0252   ///
0253   /// \return
0254   ///     The number of variable that were appended to \a
0255   ///     variable_list.
0256   uint32_t AppendVariables(bool can_create, bool get_parent_variables,
0257                            bool stop_if_block_is_inlined_function,
0258                            const std::function<bool(Variable *)> &filter,
0259                            VariableList *variable_list);
0260 
0261   /// Get const accessor for any inlined function information.
0262   ///
0263   /// \return
0264   ///     A const pointer to any inlined function information, or nullptr
0265   ///     if this is a regular block.
0266   const InlineFunctionInfo *GetInlinedFunctionInfo() const {
0267     return m_inlineInfoSP.get();
0268   }
0269 
0270   /// Get the symbol file which contains debug info for this block's
0271   /// symbol context module.
0272   ///
0273   /// \return A pointer to the symbol file or nullptr.
0274   SymbolFile *GetSymbolFile();
0275 
0276   CompilerDeclContext GetDeclContext();
0277 
0278   /// Get the memory cost of this object.
0279   ///
0280   /// Returns the cost of this object plus any owned objects from the ranges,
0281   /// variables, and inline function information.
0282   ///
0283   /// \return
0284   ///     The number of bytes that this object occupies in memory.
0285   size_t MemorySize() const;
0286 
0287   /// Set accessor for any inlined function information.
0288   ///
0289   /// \param[in] name
0290   ///     The method name for the inlined function. This value should
0291   ///     not be nullptr.
0292   ///
0293   /// \param[in] mangled
0294   ///     The mangled method name for the inlined function. This can
0295   ///     be nullptr if there is no mangled name for an inlined function
0296   ///     or if the name is the same as \a name.
0297   ///
0298   /// \param[in] decl_ptr
0299   ///     A optional pointer to declaration information for the
0300   ///     inlined function information. This value can be nullptr to
0301   ///     indicate that no declaration information is available.
0302   ///
0303   /// \param[in] call_decl_ptr
0304   ///     Optional calling location declaration information that
0305   ///     describes from where this inlined function was called.
0306   void SetInlinedFunctionInfo(const char *name, const char *mangled,
0307                               const Declaration *decl_ptr,
0308                               const Declaration *call_decl_ptr);
0309 
0310   /// Set accessor for the variable list.
0311   ///
0312   /// Called by the SymbolFile plug-ins after they have parsed the variable
0313   /// lists and are ready to hand ownership of the list over to this object.
0314   ///
0315   /// \param[in] variable_list_sp
0316   ///     A shared pointer to a VariableList.
0317   void SetVariableList(lldb::VariableListSP &variable_list_sp) {
0318     m_variable_list_sp = variable_list_sp;
0319   }
0320 
0321   bool BlockInfoHasBeenParsed() const { return m_parsed_block_info; }
0322 
0323   void SetBlockInfoHasBeenParsed(bool b, bool set_children);
0324 
0325   Block *FindBlockByID(lldb::user_id_t block_id);
0326 
0327   Block *FindInnermostBlockByOffset(const lldb::addr_t offset);
0328 
0329   size_t GetNumRanges() const { return m_ranges.GetSize(); }
0330 
0331   bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range);
0332 
0333   bool GetRangeContainingAddress(const Address &addr, AddressRange &range);
0334 
0335   bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target,
0336                                      AddressRange &range);
0337 
0338   uint32_t GetRangeIndexContainingAddress(const Address &addr);
0339 
0340   // Since blocks might have multiple discontiguous address ranges, we need to
0341   // be able to get at any of the address ranges in a block.
0342   bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range);
0343 
0344   AddressRanges GetRanges();
0345 
0346   bool GetStartAddress(Address &addr);
0347 
0348   void SetDidParseVariables(bool b, bool set_children);
0349 
0350 protected:
0351   typedef std::vector<lldb::BlockSP> collection;
0352   // Member variables.
0353   SymbolContextScope &m_parent_scope;
0354   collection m_children;
0355   RangeList m_ranges;
0356   lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information.
0357   lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local,
0358                                            ///static and parameter variables
0359                                            ///scoped to this block.
0360   bool m_parsed_block_info : 1, ///< Set to true if this block and it's children
0361                                 ///have all been parsed
0362       m_parsed_block_variables : 1, m_parsed_child_blocks : 1;
0363 
0364   // A parent of child blocks can be asked to find a sibling block given
0365   // one of its child blocks
0366   Block *GetSiblingForChild(const Block *child_block) const;
0367 
0368 private:
0369   Block(const Block &) = delete;
0370   const Block &operator=(const Block &) = delete;
0371 
0372   Block(lldb::user_id_t uid, SymbolContextScope &parent_scope);
0373 };
0374 
0375 } // namespace lldb_private
0376 
0377 #endif // LLDB_SYMBOL_BLOCK_H