1 //===-- Block.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef liblldb_Block_h_ 10 #define liblldb_Block_h_ 11 12 #include "lldb/Core/AddressRange.h" 13 #include "lldb/Symbol/CompilerType.h" 14 #include "lldb/Symbol/LineEntry.h" 15 #include "lldb/Symbol/SymbolContext.h" 16 #include "lldb/Symbol/SymbolContextScope.h" 17 #include "lldb/Utility/RangeMap.h" 18 #include "lldb/Utility/Stream.h" 19 #include "lldb/Utility/UserID.h" 20 #include "lldb/lldb-private.h" 21 #include <vector> 22 23 namespace lldb_private { 24 25 /// \class Block Block.h "lldb/Symbol/Block.h" 26 /// A class that describes a single lexical block. 27 /// 28 /// A Function object owns a BlockList object which owns one or more 29 /// Block objects. The BlockList object contains a section offset address 30 /// range, and Block objects contain one or more ranges which are offsets into 31 /// that range. Blocks are can have discontiguous ranges within the BlockList 32 /// address range, and each block can contain child blocks each with their own 33 /// sets of ranges. 34 /// 35 /// Each block has a variable list that represents local, argument, and static 36 /// variables that are scoped to the block. 37 /// 38 /// Inlined functions are represented by attaching a InlineFunctionInfo shared 39 /// pointer object to a block. Inlined functions are represented as named 40 /// blocks. 41 class Block : public UserID, public SymbolContextScope { 42 public: 43 typedef RangeArray<uint32_t, uint32_t, 1> RangeList; 44 typedef RangeList::Entry Range; 45 46 /// Construct with a User ID \a uid, \a depth. 47 /// 48 /// Initialize this block with the specified UID \a uid. The \a depth in the 49 /// \a block_list is used to represent the parent, sibling, and child block 50 /// information and also allows for partial parsing at the block level. 51 /// 52 /// \param[in] uid 53 /// The UID for a given block. This value is given by the 54 /// SymbolFile plug-in and can be any value that helps the 55 /// SymbolFile plug-in to match this block back to the debug 56 /// information data that it parses for further or more in 57 /// depth parsing. Common values would be the index into a 58 /// table, or an offset into the debug information. 59 /// 60 /// \param[in] depth 61 /// The integer depth of this block in the block list hierarchy. 62 /// 63 /// \param[in] block_list 64 /// The block list that this object belongs to. 65 /// 66 /// \see BlockList 67 Block(lldb::user_id_t uid); 68 69 /// Destructor. 70 ~Block() override; 71 72 /// Add a child to this object. 73 /// 74 /// \param[in] child_block_sp 75 /// A shared pointer to a child block that will get added to 76 /// this block. 77 void AddChild(const lldb::BlockSP &child_block_sp); 78 79 /// Add a new offset range to this block. 80 /// 81 /// \param[in] start_offset 82 /// An offset into this Function's address range that 83 /// describes the start address of a range for this block. 84 /// 85 /// \param[in] end_offset 86 /// An offset into this Function's address range that 87 /// describes the end address of a range for this block. 88 void AddRange(const Range &range); 89 90 void FinalizeRanges(); 91 92 /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) 93 /// 94 /// \see SymbolContextScope 95 void CalculateSymbolContext(SymbolContext *sc) override; 96 97 lldb::ModuleSP CalculateSymbolContextModule() override; 98 99 CompileUnit *CalculateSymbolContextCompileUnit() override; 100 101 Function *CalculateSymbolContextFunction() override; 102 103 Block *CalculateSymbolContextBlock() override; 104 105 /// Check if an offset is in one of the block offset ranges. 106 /// 107 /// \param[in] range_offset 108 /// An offset into the Function's address range. 109 /// 110 /// \return 111 /// Returns \b true if \a range_offset falls in one of this 112 /// block's ranges, \b false otherwise. 113 bool Contains(lldb::addr_t range_offset) const; 114 115 /// Check if a offset range is in one of the block offset ranges. 116 /// 117 /// \param[in] range 118 /// An offset range into the Function's address range. 119 /// 120 /// \return 121 /// Returns \b true if \a range falls in one of this 122 /// block's ranges, \b false otherwise. 123 bool Contains(const Range &range) const; 124 125 /// Check if this object contains "block" as a child block at any depth. 126 /// 127 /// \param[in] block 128 /// A potential child block. 129 /// 130 /// \return 131 /// Returns \b true if \a block is a child of this block, \b 132 /// false otherwise. 133 bool Contains(const Block *block) const; 134 135 /// Dump the block contents. 136 /// 137 /// \param[in] s 138 /// The stream to which to dump the object description. 139 /// 140 /// \param[in] base_addr 141 /// The resolved start address of the Function's address 142 /// range. This should be resolved as the file or load address 143 /// prior to passing the value into this function for dumping. 144 /// 145 /// \param[in] depth 146 /// Limit the number of levels deep that this function should 147 /// print as this block can contain child blocks. Specify 148 /// INT_MAX to dump all child blocks. 149 /// 150 /// \param[in] show_context 151 /// If \b true, variables will dump their context information. 152 void Dump(Stream *s, lldb::addr_t base_addr, int32_t depth, 153 bool show_context) const; 154 155 /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*) 156 /// 157 /// \see SymbolContextScope 158 void DumpSymbolContext(Stream *s) override; 159 160 void DumpAddressRanges(Stream *s, lldb::addr_t base_addr); 161 162 void GetDescription(Stream *s, Function *function, 163 lldb::DescriptionLevel level, Target *target) const; 164 165 /// Get the parent block. 166 /// 167 /// \return 168 /// The parent block pointer, or nullptr if this block has no 169 /// parent. 170 Block *GetParent() const; 171 172 /// Get the inlined block that contains this block. 173 /// 174 /// \return 175 /// If this block contains inlined function info, it will return 176 /// this block, else parent blocks will be searched to see if 177 /// any contain this block. nullptr will be returned if this block 178 /// nor any parent blocks are inlined function blocks. 179 Block *GetContainingInlinedBlock(); 180 181 /// Get the inlined parent block for this block. 182 /// 183 /// \return 184 /// The parent block pointer, or nullptr if this block has no 185 /// parent. 186 Block *GetInlinedParent(); 187 188 //------------------------------------------------------------------ 189 /// Get the inlined block at the given call site that contains this block. 190 /// 191 /// @param[in] find_call_site 192 /// a declaration with the file and line of the call site to find. 193 /// 194 /// @return 195 /// If this block contains inlined function info and is at the call 196 /// site given by the file and line at the given \b declaration, then 197 /// it will return this block, otherwise the parent blocks will be 198 /// searched to see if any is at the call site. nullptr will be returned 199 /// if no block is found at the call site. 200 //------------------------------------------------------------------ 201 Block * 202 GetContainingInlinedBlockWithCallSite(const Declaration &find_call_site); 203 204 /// Get the sibling block for this block. 205 /// 206 /// \return 207 /// The sibling block pointer, or nullptr if this block has no 208 /// sibling. 209 Block *GetSibling() const; 210 211 /// Get the first child block. 212 /// 213 /// \return 214 /// The first child block pointer, or nullptr if this block has no 215 /// children. 216 Block *GetFirstChild() const { 217 return (m_children.empty() ? nullptr : m_children.front().get()); 218 } 219 220 /// Get the variable list for this block only. 221 /// 222 /// \param[in] can_create 223 /// If \b true, the variables can be parsed if they already 224 /// haven't been, else the current state of the block will be 225 /// returned. 226 /// 227 /// \return 228 /// A variable list shared pointer that contains all variables 229 /// for this block. 230 lldb::VariableListSP GetBlockVariableList(bool can_create); 231 232 /// Get the variable list for this block and optionally all child blocks if 233 /// \a get_child_variables is \b true. 234 /// 235 /// \param[in] get_child_variables 236 /// If \b true, all variables from all child blocks will be 237 /// added to the variable list. 238 /// 239 /// \param[in] can_create 240 /// If \b true, the variables can be parsed if they already 241 /// haven't been, else the current state of the block will be 242 /// returned. Passing \b true for this parameter can be used 243 /// to see the current state of what has been parsed up to this 244 /// point. 245 /// 246 /// \param[in] add_inline_child_block_variables 247 /// If this is \b false, no child variables of child blocks 248 /// that are inlined functions will be gotten. If \b true then 249 /// all child variables will be added regardless of whether they 250 /// come from inlined functions or not. 251 /// 252 /// \return 253 /// A variable list shared pointer that contains all variables 254 /// for this block. 255 uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables, 256 bool stop_if_child_block_is_inlined_function, 257 const std::function<bool(Variable *)> &filter, 258 VariableList *variable_list); 259 260 /// Appends the variables from this block, and optionally from all parent 261 /// blocks, to \a variable_list. 262 /// 263 /// \param[in] can_create 264 /// If \b true, the variables can be parsed if they already 265 /// haven't been, else the current state of the block will be 266 /// returned. Passing \b true for this parameter can be used 267 /// to see the current state of what has been parsed up to this 268 /// point. 269 /// 270 /// \param[in] get_parent_variables 271 /// If \b true, all variables from all parent blocks will be 272 /// added to the variable list. 273 /// 274 /// \param[in] stop_if_block_is_inlined_function 275 /// If \b true, all variables from all parent blocks will be 276 /// added to the variable list until there are no parent blocks 277 /// or the parent block has inlined function info. 278 /// 279 /// \param[in,out] variable_list 280 /// All variables in this block, and optionally all parent 281 /// blocks will be added to this list. 282 /// 283 /// \return 284 /// The number of variable that were appended to \a 285 /// variable_list. 286 uint32_t AppendVariables(bool can_create, bool get_parent_variables, 287 bool stop_if_block_is_inlined_function, 288 const std::function<bool(Variable *)> &filter, 289 VariableList *variable_list); 290 291 /// Get const accessor for any inlined function information. 292 /// 293 /// \return 294 /// A const pointer to any inlined function information, or nullptr 295 /// if this is a regular block. 296 const InlineFunctionInfo *GetInlinedFunctionInfo() const { 297 return m_inlineInfoSP.get(); 298 } 299 300 /// Get the symbol file which contains debug info for this block's 301 /// symbol context module. 302 /// 303 /// \return A pointer to the symbol file or nullptr. 304 SymbolFile *GetSymbolFile(); 305 306 CompilerDeclContext GetDeclContext(); 307 308 /// Get the memory cost of this object. 309 /// 310 /// Returns the cost of this object plus any owned objects from the ranges, 311 /// variables, and inline function information. 312 /// 313 /// \return 314 /// The number of bytes that this object occupies in memory. 315 size_t MemorySize() const; 316 317 /// Set accessor for any inlined function information. 318 /// 319 /// \param[in] name 320 /// The method name for the inlined function. This value should 321 /// not be nullptr. 322 /// 323 /// \param[in] mangled 324 /// The mangled method name for the inlined function. This can 325 /// be nullptr if there is no mangled name for an inlined function 326 /// or if the name is the same as \a name. 327 /// 328 /// \param[in] decl_ptr 329 /// A optional pointer to declaration information for the 330 /// inlined function information. This value can be nullptr to 331 /// indicate that no declaration information is available. 332 /// 333 /// \param[in] call_decl_ptr 334 /// Optional calling location declaration information that 335 /// describes from where this inlined function was called. 336 void SetInlinedFunctionInfo(const char *name, const char *mangled, 337 const Declaration *decl_ptr, 338 const Declaration *call_decl_ptr); 339 340 void SetParentScope(SymbolContextScope *parent_scope) { 341 m_parent_scope = parent_scope; 342 } 343 344 /// Set accessor for the variable list. 345 /// 346 /// Called by the SymbolFile plug-ins after they have parsed the variable 347 /// lists and are ready to hand ownership of the list over to this object. 348 /// 349 /// \param[in] variable_list_sp 350 /// A shared pointer to a VariableList. 351 void SetVariableList(lldb::VariableListSP &variable_list_sp) { 352 m_variable_list_sp = variable_list_sp; 353 } 354 355 bool BlockInfoHasBeenParsed() const { return m_parsed_block_info; } 356 357 void SetBlockInfoHasBeenParsed(bool b, bool set_children); 358 359 Block *FindBlockByID(lldb::user_id_t block_id); 360 361 size_t GetNumRanges() const { return m_ranges.GetSize(); } 362 363 bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range); 364 365 bool GetRangeContainingAddress(const Address &addr, AddressRange &range); 366 367 bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, 368 AddressRange &range); 369 370 uint32_t GetRangeIndexContainingAddress(const Address &addr); 371 372 // Since blocks might have multiple discontiguous address ranges, we need to 373 // be able to get at any of the address ranges in a block. 374 bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range); 375 376 bool GetStartAddress(Address &addr); 377 378 void SetDidParseVariables(bool b, bool set_children); 379 380 protected: 381 typedef std::vector<lldb::BlockSP> collection; 382 // Member variables. 383 SymbolContextScope *m_parent_scope; 384 collection m_children; 385 RangeList m_ranges; 386 lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. 387 lldb::VariableListSP m_variable_list_sp; ///< The variable list for all local, 388 ///static and parameter variables 389 ///scoped to this block. 390 bool m_parsed_block_info : 1, ///< Set to true if this block and it's children 391 ///have all been parsed 392 m_parsed_block_variables : 1, m_parsed_child_blocks : 1; 393 394 // A parent of child blocks can be asked to find a sibling block given 395 // one of its child blocks 396 Block *GetSiblingForChild(const Block *child_block) const; 397 398 private: 399 DISALLOW_COPY_AND_ASSIGN(Block); 400 }; 401 402 } // namespace lldb_private 403 404 #endif // liblldb_Block_h_ 405