Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===-- SymbolContext.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_SYMBOLCONTEXT_H
0010 #define LLDB_SYMBOL_SYMBOLCONTEXT_H
0011 
0012 #include <memory>
0013 #include <string>
0014 #include <vector>
0015 
0016 #include "lldb/Core/Address.h"
0017 #include "lldb/Core/Mangled.h"
0018 #include "lldb/Symbol/LineEntry.h"
0019 #include "lldb/Utility/Iterable.h"
0020 #include "lldb/Utility/Stream.h"
0021 #include "lldb/lldb-private.h"
0022 
0023 namespace lldb_private {
0024 
0025 class SymbolContextScope;
0026 
0027 /// \class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" Defines
0028 /// a symbol context baton that can be handed other debug core functions.
0029 ///
0030 /// Many debugger functions require a context when doing lookups. This class
0031 /// provides a common structure that can be used as the result of a query that
0032 /// can contain a single result. Examples of such queries include
0033 ///     \li Looking up a load address.
0034 class SymbolContext {
0035 public:
0036   /// Default constructor.
0037   ///
0038   /// Initialize all pointer members to nullptr and all struct members to
0039   /// their default state.
0040   SymbolContext();
0041 
0042   /// Construct with an object that knows how to reconstruct its symbol
0043   /// context.
0044   ///
0045   /// \param[in] sc_scope
0046   ///     A symbol context scope object that knows how to reconstruct
0047   ///     it's context.
0048   explicit SymbolContext(SymbolContextScope *sc_scope);
0049 
0050   /// Construct with module, and optional compile unit, function, block, line
0051   /// table, line entry and symbol.
0052   ///
0053   /// Initialize all pointer to the specified values.
0054   ///
0055   /// \param[in] module_sp
0056   ///     A Module pointer to the module for this context.
0057   ///
0058   /// \param[in] comp_unit
0059   ///     A CompileUnit pointer to the compile unit for this context.
0060   ///
0061   /// \param[in] function
0062   ///     A Function pointer to the function for this context.
0063   ///
0064   /// \param[in] block
0065   ///     A Block pointer to the deepest block for this context.
0066   ///
0067   /// \param[in] line_entry
0068   ///     A LineEntry pointer to the line entry for this context.
0069   ///
0070   /// \param[in] symbol
0071   ///     A Symbol pointer to the symbol for this context.
0072   explicit SymbolContext(const lldb::TargetSP &target_sp,
0073                          const lldb::ModuleSP &module_sp,
0074                          CompileUnit *comp_unit = nullptr,
0075                          Function *function = nullptr, Block *block = nullptr,
0076                          LineEntry *line_entry = nullptr,
0077                          Symbol *symbol = nullptr);
0078 
0079   // This version sets the target to a NULL TargetSP if you don't know it.
0080   explicit SymbolContext(const lldb::ModuleSP &module_sp,
0081                          CompileUnit *comp_unit = nullptr,
0082                          Function *function = nullptr, Block *block = nullptr,
0083                          LineEntry *line_entry = nullptr,
0084                          Symbol *symbol = nullptr);
0085 
0086   ~SymbolContext();
0087 
0088   /// Clear the object's state.
0089   ///
0090   /// Resets all pointer members to nullptr, and clears any class objects to
0091   /// their default state.
0092   void Clear(bool clear_target);
0093 
0094   /// Dump the stop context in this object to a Stream.
0095   ///
0096   /// Dump the best description of this object to the stream. The information
0097   /// displayed depends on the amount and quality of the information in this
0098   /// context. If a module, function, file and line number are available, they
0099   /// will be dumped. If only a module and function or symbol name with offset
0100   /// is available, that will be output. Else just the address at which the
0101   /// target was stopped will be displayed.
0102   ///
0103   /// \param[in] s
0104   ///     The stream to which to dump the object description.
0105   ///
0106   /// \param[in] so_addr
0107   ///     The resolved section offset address.
0108   ///
0109   /// \param[in] show_fullpaths
0110   ///     When printing file paths (with the Module), whether the
0111   ///     base name of the Module should be printed or the full path.
0112   ///
0113   /// \param[in] show_module
0114   ///     Whether the module name should be printed followed by a
0115   ///     grave accent "`" character.
0116   ///
0117   /// \param[in] show_inlined_frames
0118   ///     If a given pc is in inlined function(s), whether the inlined
0119   ///     functions should be printed on separate lines in addition to
0120   ///     the concrete function containing the pc.
0121   ///
0122   /// \param[in] show_function_arguments
0123   ///     If false, this method will try to elide the function argument
0124   ///     types when printing the function name.  This may be ambiguous
0125   ///     for languages that have function overloading - but it may
0126   ///     make the "function name" too long to include all the argument
0127   ///     types.
0128   ///
0129   /// \param[in] show_function_name
0130   ///     Normally this should be true - the function/symbol name should
0131   ///     be printed.  In disassembly formatting, where we want a format
0132   ///     like "<*+36>", this should be false and "*" will be printed
0133   ///     instead.
0134   ///
0135   /// \param[in] show_inline_callsite_line_info
0136   ///     When processing an inline block, the line info of the callsite
0137   ///     is dumped if this flag is \b true, otherwise the line info
0138   ///     of the actual inlined function is dumped.
0139   ///
0140   /// \param[in] pattern
0141   ///     An optional regex pattern to match against the stop context
0142   ///     description. If specified, parts of the description matching this
0143   ///     pattern may be highlighted or processed differently. If this parameter
0144   ///     is an empty string or not provided, no highlighting is applied.
0145   ///
0146   /// \return
0147   ///     \b true if some text was dumped, \b false otherwise.
0148   bool DumpStopContext(
0149       Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr,
0150       bool show_fullpaths, bool show_module, bool show_inlined_frames,
0151       bool show_function_arguments, bool show_function_name,
0152       bool show_function_display_name = false,
0153       std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
0154 
0155   /// Get the address range contained within a symbol context.
0156   ///
0157   /// Address range priority is as follows:
0158   ///     - line_entry address range if line_entry is valid and
0159   ///     eSymbolContextLineEntry is set in \a scope
0160   ///     - block address range if block is not nullptr and eSymbolContextBlock
0161   ///     is set in \a scope
0162   ///     - function address range if function is not nullptr and
0163   ///     eSymbolContextFunction is set in \a scope
0164   ///     - symbol address range if symbol is not nullptr and
0165   ///     eSymbolContextSymbol is set in \a scope
0166   ///
0167   /// \param[in] scope
0168   ///     A mask of symbol context bits telling this function which
0169   ///     address ranges it can use when trying to extract one from
0170   ///     the valid (non-nullptr) symbol context classes.
0171   ///
0172   /// \param[in] range_idx
0173   ///     The address range index to grab. Since many functions and
0174   ///     blocks are not always contiguous, they may have more than
0175   ///     one address range.
0176   ///
0177   /// \param[in] use_inline_block_range
0178   ///     If \a scope has the eSymbolContextBlock bit set, and there
0179   ///     is a valid block in the symbol context, return the block
0180   ///     address range for the containing inline function block, not
0181   ///     the deepest most block. This allows us to extract information
0182   ///     for the address range of the inlined function block, not
0183   ///     the deepest lexical block.
0184   ///
0185   /// \param[out] range
0186   ///     An address range object that will be filled in if \b true
0187   ///     is returned.
0188   ///
0189   /// \return
0190   ///     \b True if this symbol context contains items that describe
0191   ///     an address range, \b false otherwise.
0192   bool GetAddressRange(uint32_t scope, uint32_t range_idx,
0193                        bool use_inline_block_range, AddressRange &range) const;
0194 
0195   llvm::Error GetAddressRangeFromHereToEndLine(uint32_t end_line,
0196                                                AddressRange &range);
0197 
0198   /// Find the best global data symbol visible from this context.
0199   ///
0200   /// Symbol priority is:
0201   ///     - extern symbol in the current module if there is one
0202   ///     - non-extern symbol in the current module if there is one
0203   ///     - extern symbol in the target
0204   ///     - non-extern symbol in the target
0205   /// It is an error if the highest-priority result is ambiguous.
0206   ///
0207   /// \param[in] name
0208   ///     The name of the symbol to search for.
0209   ///
0210   /// \param[out] error
0211   ///     An error that will be populated with a message if there was an
0212   ///     ambiguous result.  The error will not be populated if no result
0213   ///     was found.
0214   ///
0215   /// \return
0216   ///     The symbol that was found, or \b nullptr if none was found.
0217   const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error);
0218 
0219   void GetDescription(
0220       Stream *s, lldb::DescriptionLevel level, Target *target,
0221       std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
0222 
0223   uint32_t GetResolvedMask() const;
0224 
0225   lldb::LanguageType GetLanguage() const;
0226 
0227   /// Find a block that defines the function represented by this symbol
0228   /// context.
0229   ///
0230   /// If this symbol context points to a block that is an inlined function, or
0231   /// is contained within an inlined function, the block that defines the
0232   /// inlined function is returned.
0233   ///
0234   /// If this symbol context has no block in it, or the block is not itself an
0235   /// inlined function block or contained within one, we return the top level
0236   /// function block.
0237   ///
0238   /// This is a handy function to call when you want to get the block whose
0239   /// variable list will include the arguments for the function that is
0240   /// represented by this symbol context (whether the function is an inline
0241   /// function or not).
0242   ///
0243   /// \return
0244   ///     The block object pointer that defines the function that is
0245   ///     represented by this symbol context object, nullptr otherwise.
0246   Block *GetFunctionBlock();
0247 
0248   /// Determines the name of the instance variable for the this decl context.
0249   ///
0250   /// For C++ the name is "this", for Objective-C the name is "self".
0251   ///
0252   /// \return
0253   ///     Returns a StringRef for the name of the instance variable.
0254   llvm::StringRef GetInstanceVariableName();
0255 
0256   /// Sorts the types in TypeMap according to SymbolContext to TypeList
0257   ///
0258   void SortTypeList(TypeMap &type_map, TypeList &type_list) const;
0259 
0260   /// Find a name of the innermost function for the symbol context.
0261   ///
0262   /// For instance, if the symbol context contains an inlined block, it will
0263   /// return the inlined function name.
0264   ///
0265   /// \return
0266   ///     The name of the function represented by this symbol context.
0267   ConstString GetFunctionName(
0268       Mangled::NamePreference preference = Mangled::ePreferDemangled) const;
0269 
0270   /// Get the line entry that corresponds to the function.
0271   ///
0272   /// If the symbol context contains an inlined block, the line entry for the
0273   /// start address of the inlined function will be returned, otherwise the
0274   /// line entry for the start address of the function will be returned. This
0275   /// can be used after doing a Module::FindFunctions(...) or
0276   /// ModuleList::FindFunctions(...) call in order to get the correct line
0277   /// table information for the symbol context. it will return the inlined
0278   /// function name.
0279   LineEntry GetFunctionStartLineEntry() const;
0280 
0281   /// Find the block containing the inlined block that contains this block.
0282   ///
0283   /// For instance, if the symbol context contains an inlined block, it will
0284   /// return the inlined function name.
0285   ///
0286   /// \param[in] curr_frame_pc
0287   ///    The address within the block of this object.
0288   ///
0289   /// \param[out] next_frame_sc
0290   ///     A new symbol context that does what the title says it does.
0291   ///
0292   /// \param[out] inlined_frame_addr
0293   ///     This is what you should report as the PC in \a next_frame_sc.
0294   ///
0295   /// \return
0296   ///     \b true if this SymbolContext specifies a block contained in an
0297   ///     inlined block.  If this returns \b true, \a next_frame_sc and
0298   ///     \a inlined_frame_addr will be filled in correctly.
0299   bool GetParentOfInlinedScope(const Address &curr_frame_pc,
0300                                SymbolContext &next_frame_sc,
0301                                Address &inlined_frame_addr) const;
0302 
0303   // Member variables
0304   lldb::TargetSP target_sp; ///< The Target for a given query
0305   lldb::ModuleSP module_sp; ///< The Module for a given query
0306   CompileUnit *comp_unit = nullptr; ///< The CompileUnit for a given query
0307   Function *function = nullptr;     ///< The Function for a given query
0308   Block *block = nullptr;           ///< The Block for a given query
0309   LineEntry line_entry;     ///< The LineEntry for a given query
0310   Symbol *symbol = nullptr; ///< The Symbol for a given query
0311   Variable *variable =
0312       nullptr; ///< The global variable matching the given query
0313 };
0314 
0315 class SymbolContextSpecifier {
0316 public:
0317   enum SpecificationType {
0318     eNothingSpecified = 0,
0319     eModuleSpecified = 1 << 0,
0320     eFileSpecified = 1 << 1,
0321     eLineStartSpecified = 1 << 2,
0322     eLineEndSpecified = 1 << 3,
0323     eFunctionSpecified = 1 << 4,
0324     eClassOrNamespaceSpecified = 1 << 5,
0325     eAddressRangeSpecified = 1 << 6
0326   };
0327 
0328   // This one produces a specifier that matches everything...
0329   SymbolContextSpecifier(const lldb::TargetSP &target_sp);
0330 
0331   ~SymbolContextSpecifier();
0332 
0333   bool AddSpecification(const char *spec_string, SpecificationType type);
0334 
0335   bool AddLineSpecification(uint32_t line_no, SpecificationType type);
0336 
0337   void Clear();
0338 
0339   bool SymbolContextMatches(const SymbolContext &sc);
0340 
0341   bool AddressMatches(lldb::addr_t addr);
0342 
0343   void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
0344 
0345 private:
0346   lldb::TargetSP m_target_sp;
0347   std::string m_module_spec;
0348   lldb::ModuleSP m_module_sp;
0349   std::unique_ptr<FileSpec> m_file_spec_up;
0350   size_t m_start_line;
0351   size_t m_end_line;
0352   std::string m_function_spec;
0353   std::string m_class_name;
0354   std::unique_ptr<AddressRange> m_address_range_up;
0355   uint32_t m_type; // Or'ed bits from SpecificationType
0356 };
0357 
0358 /// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
0359 /// Defines a list of symbol context objects.
0360 ///
0361 /// This class provides a common structure that can be used to contain the
0362 /// result of a query that can contain a multiple results. Examples of such
0363 /// queries include:
0364 ///     \li Looking up a function by name.
0365 ///     \li Finding all addresses for a specified file and line number.
0366 class SymbolContextList {
0367 public:
0368   /// Default constructor.
0369   ///
0370   /// Initialize with an empty list.
0371   SymbolContextList();
0372 
0373   /// Destructor.
0374   ~SymbolContextList();
0375 
0376   /// Append a new symbol context to the list.
0377   ///
0378   /// \param[in] sc
0379   ///     A symbol context to append to the list.
0380   void Append(const SymbolContext &sc);
0381 
0382   void Append(const SymbolContextList &sc_list);
0383 
0384   bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function);
0385 
0386   uint32_t AppendIfUnique(const SymbolContextList &sc_list,
0387                           bool merge_symbol_into_function);
0388 
0389   /// Clear the object's state.
0390   ///
0391   /// Clears the symbol context list.
0392   void Clear();
0393 
0394   /// Dump a description of this object to a Stream.
0395   ///
0396   /// Dump a description of the contents of each symbol context in the list to
0397   /// the supplied stream \a s.
0398   ///
0399   /// \param[in] s
0400   ///     The stream to which to dump the object description.
0401   void Dump(Stream *s, Target *target) const;
0402 
0403   /// Get accessor for a symbol context at index \a idx.
0404   ///
0405   /// Dump a description of the contents of each symbol context in the list to
0406   /// the supplied stream \a s.
0407   ///
0408   /// \param[in] idx
0409   ///     The zero based index into the symbol context list.
0410   ///
0411   /// \param[out] sc
0412   ///     A reference to the symbol context to fill in.
0413   ///
0414   /// \return
0415   ///     Returns \b true if \a idx was a valid index into this
0416   ///     symbol context list and \a sc was filled in, \b false
0417   ///     otherwise.
0418   bool GetContextAtIndex(size_t idx, SymbolContext &sc) const;
0419 
0420   /// Direct reference accessor for a symbol context at index \a idx.
0421   ///
0422   /// The index \a idx must be a valid index, no error checking will be done
0423   /// to ensure that it is valid.
0424   ///
0425   /// \param[in] idx
0426   ///     The zero based index into the symbol context list.
0427   ///
0428   /// \return
0429   ///     A const reference to the symbol context to fill in.
0430   SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; }
0431 
0432   const SymbolContext &operator[](size_t idx) const {
0433     return m_symbol_contexts[idx];
0434   }
0435 
0436   bool RemoveContextAtIndex(size_t idx);
0437 
0438   /// Get accessor for a symbol context list size.
0439   ///
0440   /// \return
0441   ///     Returns the number of symbol context objects in the list.
0442   uint32_t GetSize() const;
0443 
0444   bool IsEmpty() const;
0445 
0446   uint32_t NumLineEntriesWithLine(uint32_t line) const;
0447 
0448   void GetDescription(Stream *s, lldb::DescriptionLevel level,
0449                       Target *target) const;
0450 
0451 protected:
0452   typedef std::vector<SymbolContext>
0453       collection; ///< The collection type for the list.
0454   typedef collection::const_iterator const_iterator;
0455 
0456   // Member variables.
0457   collection m_symbol_contexts; ///< The list of symbol contexts.
0458 
0459 public:
0460   const_iterator begin() const { return m_symbol_contexts.begin(); }
0461   const_iterator end() const { return m_symbol_contexts.end(); }
0462 
0463   typedef AdaptedIterable<collection, SymbolContext, vector_adapter>
0464       SymbolContextIterable;
0465   SymbolContextIterable SymbolContexts() {
0466     return SymbolContextIterable(m_symbol_contexts);
0467   }
0468 };
0469 
0470 bool operator==(const SymbolContext &lhs, const SymbolContext &rhs);
0471 bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs);
0472 
0473 bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs);
0474 bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs);
0475 
0476 } // namespace lldb_private
0477 
0478 #endif // LLDB_SYMBOL_SYMBOLCONTEXT_H