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