xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolContext.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- SymbolContext.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_SYMBOLCONTEXT_H
10 #define LLDB_SYMBOL_SYMBOLCONTEXT_H
11 
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include "lldb/Core/Address.h"
17 #include "lldb/Core/Mangled.h"
18 #include "lldb/Symbol/LineEntry.h"
19 #include "lldb/Utility/Iterable.h"
20 #include "lldb/Utility/Stream.h"
21 #include "lldb/lldb-private.h"
22 
23 namespace lldb_private {
24 
25 class SymbolContextScope;
26 
27 /// \class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" Defines
28 /// a symbol context baton that can be handed other debug core functions.
29 ///
30 /// Many debugger functions require a context when doing lookups. This class
31 /// provides a common structure that can be used as the result of a query that
32 /// can contain a single result. Examples of such queries include
33 ///     \li Looking up a load address.
34 class SymbolContext {
35 public:
36   /// Default constructor.
37   ///
38   /// Initialize all pointer members to nullptr and all struct members to
39   /// their default state.
40   SymbolContext();
41 
42   /// Construct with an object that knows how to reconstruct its symbol
43   /// context.
44   ///
45   /// \param[in] sc_scope
46   ///     A symbol context scope object that knows how to reconstruct
47   ///     it's context.
48   explicit SymbolContext(SymbolContextScope *sc_scope);
49 
50   /// Construct with module, and optional compile unit, function, block, line
51   /// table, line entry and symbol.
52   ///
53   /// Initialize all pointer to the specified values.
54   ///
55   /// \param[in] module_sp
56   ///     A Module pointer to the module for this context.
57   ///
58   /// \param[in] comp_unit
59   ///     A CompileUnit pointer to the compile unit for this context.
60   ///
61   /// \param[in] function
62   ///     A Function pointer to the function for this context.
63   ///
64   /// \param[in] block
65   ///     A Block pointer to the deepest block for this context.
66   ///
67   /// \param[in] line_entry
68   ///     A LineEntry pointer to the line entry for this context.
69   ///
70   /// \param[in] symbol
71   ///     A Symbol pointer to the symbol for this context.
72   explicit SymbolContext(const lldb::TargetSP &target_sp,
73                          const lldb::ModuleSP &module_sp,
74                          CompileUnit *comp_unit = nullptr,
75                          Function *function = nullptr, Block *block = nullptr,
76                          LineEntry *line_entry = nullptr,
77                          Symbol *symbol = nullptr);
78 
79   // This version sets the target to a NULL TargetSP if you don't know it.
80   explicit SymbolContext(const lldb::ModuleSP &module_sp,
81                          CompileUnit *comp_unit = nullptr,
82                          Function *function = nullptr, Block *block = nullptr,
83                          LineEntry *line_entry = nullptr,
84                          Symbol *symbol = nullptr);
85 
86   ~SymbolContext();
87 
88   /// Clear the object's state.
89   ///
90   /// Resets all pointer members to nullptr, and clears any class objects to
91   /// their default state.
92   void Clear(bool clear_target);
93 
94   /// Dump a description of this object to a Stream.
95   ///
96   /// Dump a description of the contents of this object to the supplied stream
97   /// \a s.
98   ///
99   /// \param[in] s
100   ///     The stream to which to dump the object description.
101   void Dump(Stream *s, Target *target) const;
102 
103   /// Dump the stop context in this object to a Stream.
104   ///
105   /// Dump the best description of this object to the stream. The information
106   /// displayed depends on the amount and quality of the information in this
107   /// context. If a module, function, file and line number are available, they
108   /// will be dumped. If only a module and function or symbol name with offset
109   /// is available, that will be output. Else just the address at which the
110   /// target was stopped will be displayed.
111   ///
112   /// \param[in] s
113   ///     The stream to which to dump the object description.
114   ///
115   /// \param[in] so_addr
116   ///     The resolved section offset address.
117   ///
118   /// \param[in] show_fullpaths
119   ///     When printing file paths (with the Module), whether the
120   ///     base name of the Module should be printed or the full path.
121   ///
122   /// \param[in] show_module
123   ///     Whether the module name should be printed followed by a
124   ///     grave accent "`" character.
125   ///
126   /// \param[in] show_inlined_frames
127   ///     If a given pc is in inlined function(s), whether the inlined
128   ///     functions should be printed on separate lines in addition to
129   ///     the concrete function containing the pc.
130   ///
131   /// \param[in] show_function_arguments
132   ///     If false, this method will try to elide the function argument
133   ///     types when printing the function name.  This may be ambiguous
134   ///     for languages that have function overloading - but it may
135   ///     make the "function name" too long to include all the argument
136   ///     types.
137   ///
138   /// \param[in] show_function_name
139   ///     Normally this should be true - the function/symbol name should
140   ///     be printed.  In disassembly formatting, where we want a format
141   ///     like "<*+36>", this should be false and "*" will be printed
142   ///     instead.
143   ///
144   /// \param[in] show_inline_callsite_line_info
145   ///     When processing an inline block, the line info of the callsite
146   ///     is dumped if this flag is \b true, otherwise the line info
147   ///     of the actual inlined function is dumped.
148   ///
149   /// \param[in] pattern
150   ///     An optional regex pattern to match against the stop context
151   ///     description. If specified, parts of the description matching this
152   ///     pattern may be highlighted or processed differently. If this parameter
153   ///     is an empty string or not provided, no highlighting is applied.
154   ///
155   /// \return
156   ///     \b true if some text was dumped, \b false otherwise.
157   bool DumpStopContext(
158       Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr,
159       bool show_fullpaths, bool show_module, bool show_inlined_frames,
160       bool show_function_arguments, bool show_function_name,
161       bool show_function_display_name = false,
162       std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
163 
164   /// Get the address range contained within a symbol context.
165   ///
166   /// Address range priority is as follows:
167   ///     - line_entry address range if line_entry is valid and
168   ///     eSymbolContextLineEntry is set in \a scope
169   ///     - block address range if block is not nullptr and eSymbolContextBlock
170   ///     is set in \a scope
171   ///     - function address range if function is not nullptr and
172   ///     eSymbolContextFunction is set in \a scope
173   ///     - symbol address range if symbol is not nullptr and
174   ///     eSymbolContextSymbol is set in \a scope
175   ///
176   /// \param[in] scope
177   ///     A mask of symbol context bits telling this function which
178   ///     address ranges it can use when trying to extract one from
179   ///     the valid (non-nullptr) symbol context classes.
180   ///
181   /// \param[in] range_idx
182   ///     The address range index to grab. Since many functions and
183   ///     blocks are not always contiguous, they may have more than
184   ///     one address range.
185   ///
186   /// \param[in] use_inline_block_range
187   ///     If \a scope has the eSymbolContextBlock bit set, and there
188   ///     is a valid block in the symbol context, return the block
189   ///     address range for the containing inline function block, not
190   ///     the deepest most block. This allows us to extract information
191   ///     for the address range of the inlined function block, not
192   ///     the deepest lexical block.
193   ///
194   /// \param[out] range
195   ///     An address range object that will be filled in if \b true
196   ///     is returned.
197   ///
198   /// \return
199   ///     \b True if this symbol context contains items that describe
200   ///     an address range, \b false otherwise.
201   bool GetAddressRange(uint32_t scope, uint32_t range_idx,
202                        bool use_inline_block_range, AddressRange &range) const;
203 
204   bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range,
205                                         Status &error);
206 
207   /// Find the best global data symbol visible from this context.
208   ///
209   /// Symbol priority is:
210   ///     - extern symbol in the current module if there is one
211   ///     - non-extern symbol in the current module if there is one
212   ///     - extern symbol in the target
213   ///     - non-extern symbol in the target
214   /// It is an error if the highest-priority result is ambiguous.
215   ///
216   /// \param[in] name
217   ///     The name of the symbol to search for.
218   ///
219   /// \param[out] error
220   ///     An error that will be populated with a message if there was an
221   ///     ambiguous result.  The error will not be populated if no result
222   ///     was found.
223   ///
224   /// \return
225   ///     The symbol that was found, or \b nullptr if none was found.
226   const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error);
227 
228   void GetDescription(
229       Stream *s, lldb::DescriptionLevel level, Target *target,
230       std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
231 
232   uint32_t GetResolvedMask() const;
233 
234   lldb::LanguageType GetLanguage() const;
235 
236   /// Find a block that defines the function represented by this symbol
237   /// context.
238   ///
239   /// If this symbol context points to a block that is an inlined function, or
240   /// is contained within an inlined function, the block that defines the
241   /// inlined function is returned.
242   ///
243   /// If this symbol context has no block in it, or the block is not itself an
244   /// inlined function block or contained within one, we return the top level
245   /// function block.
246   ///
247   /// This is a handy function to call when you want to get the block whose
248   /// variable list will include the arguments for the function that is
249   /// represented by this symbol context (whether the function is an inline
250   /// function or not).
251   ///
252   /// \return
253   ///     The block object pointer that defines the function that is
254   ///     represented by this symbol context object, nullptr otherwise.
255   Block *GetFunctionBlock();
256 
257   /// Determines the name of the instance variable for the this decl context.
258   ///
259   /// For C++ the name is "this", for Objective-C the name is "self".
260   ///
261   /// \return
262   ///     Returns a StringRef for the name of the instance variable.
263   llvm::StringRef GetInstanceVariableName();
264 
265   /// Sorts the types in TypeMap according to SymbolContext to TypeList
266   ///
267   void SortTypeList(TypeMap &type_map, TypeList &type_list) const;
268 
269   /// Find a name of the innermost function for the symbol context.
270   ///
271   /// For instance, if the symbol context contains an inlined block, it will
272   /// return the inlined function name.
273   ///
274   /// \return
275   ///     The name of the function represented by this symbol context.
276   ConstString GetFunctionName(
277       Mangled::NamePreference preference = Mangled::ePreferDemangled) const;
278 
279   /// Get the line entry that corresponds to the function.
280   ///
281   /// If the symbol context contains an inlined block, the line entry for the
282   /// start address of the inlined function will be returned, otherwise the
283   /// line entry for the start address of the function will be returned. This
284   /// can be used after doing a Module::FindFunctions(...) or
285   /// ModuleList::FindFunctions(...) call in order to get the correct line
286   /// table information for the symbol context. it will return the inlined
287   /// function name.
288   LineEntry GetFunctionStartLineEntry() const;
289 
290   /// Find the block containing the inlined block that contains this block.
291   ///
292   /// For instance, if the symbol context contains an inlined block, it will
293   /// return the inlined function name.
294   ///
295   /// \param[in] curr_frame_pc
296   ///    The address within the block of this object.
297   ///
298   /// \param[out] next_frame_sc
299   ///     A new symbol context that does what the title says it does.
300   ///
301   /// \param[out] inlined_frame_addr
302   ///     This is what you should report as the PC in \a next_frame_sc.
303   ///
304   /// \return
305   ///     \b true if this SymbolContext specifies a block contained in an
306   ///     inlined block.  If this returns \b true, \a next_frame_sc and
307   ///     \a inlined_frame_addr will be filled in correctly.
308   bool GetParentOfInlinedScope(const Address &curr_frame_pc,
309                                SymbolContext &next_frame_sc,
310                                Address &inlined_frame_addr) const;
311 
312   // Member variables
313   lldb::TargetSP target_sp; ///< The Target for a given query
314   lldb::ModuleSP module_sp; ///< The Module for a given query
315   CompileUnit *comp_unit = nullptr; ///< The CompileUnit for a given query
316   Function *function = nullptr;     ///< The Function for a given query
317   Block *block = nullptr;           ///< The Block for a given query
318   LineEntry line_entry;     ///< The LineEntry for a given query
319   Symbol *symbol = nullptr; ///< The Symbol for a given query
320   Variable *variable =
321       nullptr; ///< The global variable matching the given query
322 };
323 
324 class SymbolContextSpecifier {
325 public:
326   enum SpecificationType {
327     eNothingSpecified = 0,
328     eModuleSpecified = 1 << 0,
329     eFileSpecified = 1 << 1,
330     eLineStartSpecified = 1 << 2,
331     eLineEndSpecified = 1 << 3,
332     eFunctionSpecified = 1 << 4,
333     eClassOrNamespaceSpecified = 1 << 5,
334     eAddressRangeSpecified = 1 << 6
335   };
336 
337   // This one produces a specifier that matches everything...
338   SymbolContextSpecifier(const lldb::TargetSP &target_sp);
339 
340   ~SymbolContextSpecifier();
341 
342   bool AddSpecification(const char *spec_string, SpecificationType type);
343 
344   bool AddLineSpecification(uint32_t line_no, SpecificationType type);
345 
346   void Clear();
347 
348   bool SymbolContextMatches(const SymbolContext &sc);
349 
350   bool AddressMatches(lldb::addr_t addr);
351 
352   void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
353 
354 private:
355   lldb::TargetSP m_target_sp;
356   std::string m_module_spec;
357   lldb::ModuleSP m_module_sp;
358   std::unique_ptr<FileSpec> m_file_spec_up;
359   size_t m_start_line;
360   size_t m_end_line;
361   std::string m_function_spec;
362   std::string m_class_name;
363   std::unique_ptr<AddressRange> m_address_range_up;
364   uint32_t m_type; // Or'ed bits from SpecificationType
365 };
366 
367 /// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
368 /// Defines a list of symbol context objects.
369 ///
370 /// This class provides a common structure that can be used to contain the
371 /// result of a query that can contain a multiple results. Examples of such
372 /// queries include:
373 ///     \li Looking up a function by name.
374 ///     \li Finding all addresses for a specified file and line number.
375 class SymbolContextList {
376 public:
377   /// Default constructor.
378   ///
379   /// Initialize with an empty list.
380   SymbolContextList();
381 
382   /// Destructor.
383   ~SymbolContextList();
384 
385   /// Append a new symbol context to the list.
386   ///
387   /// \param[in] sc
388   ///     A symbol context to append to the list.
389   void Append(const SymbolContext &sc);
390 
391   void Append(const SymbolContextList &sc_list);
392 
393   bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function);
394 
395   uint32_t AppendIfUnique(const SymbolContextList &sc_list,
396                           bool merge_symbol_into_function);
397 
398   /// Clear the object's state.
399   ///
400   /// Clears the symbol context list.
401   void Clear();
402 
403   /// Dump a description of this object to a Stream.
404   ///
405   /// Dump a description of the contents of each symbol context in the list to
406   /// the supplied stream \a s.
407   ///
408   /// \param[in] s
409   ///     The stream to which to dump the object description.
410   void Dump(Stream *s, Target *target) const;
411 
412   /// Get accessor for a symbol context at index \a idx.
413   ///
414   /// Dump a description of the contents of each symbol context in the list to
415   /// the supplied stream \a s.
416   ///
417   /// \param[in] idx
418   ///     The zero based index into the symbol context list.
419   ///
420   /// \param[out] sc
421   ///     A reference to the symbol context to fill in.
422   ///
423   /// \return
424   ///     Returns \b true if \a idx was a valid index into this
425   ///     symbol context list and \a sc was filled in, \b false
426   ///     otherwise.
427   bool GetContextAtIndex(size_t idx, SymbolContext &sc) const;
428 
429   /// Direct reference accessor for a symbol context at index \a idx.
430   ///
431   /// The index \a idx must be a valid index, no error checking will be done
432   /// to ensure that it is valid.
433   ///
434   /// \param[in] idx
435   ///     The zero based index into the symbol context list.
436   ///
437   /// \return
438   ///     A const reference to the symbol context to fill in.
439   SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; }
440 
441   const SymbolContext &operator[](size_t idx) const {
442     return m_symbol_contexts[idx];
443   }
444 
445   bool RemoveContextAtIndex(size_t idx);
446 
447   /// Get accessor for a symbol context list size.
448   ///
449   /// \return
450   ///     Returns the number of symbol context objects in the list.
451   uint32_t GetSize() const;
452 
453   bool IsEmpty() const;
454 
455   uint32_t NumLineEntriesWithLine(uint32_t line) const;
456 
457   void GetDescription(Stream *s, lldb::DescriptionLevel level,
458                       Target *target) const;
459 
460 protected:
461   typedef std::vector<SymbolContext>
462       collection; ///< The collection type for the list.
463   typedef collection::const_iterator const_iterator;
464 
465   // Member variables.
466   collection m_symbol_contexts; ///< The list of symbol contexts.
467 
468 public:
begin()469   const_iterator begin() const { return m_symbol_contexts.begin(); }
end()470   const_iterator end() const { return m_symbol_contexts.end(); }
471 
472   typedef AdaptedIterable<collection, SymbolContext, vector_adapter>
473       SymbolContextIterable;
SymbolContexts()474   SymbolContextIterable SymbolContexts() {
475     return SymbolContextIterable(m_symbol_contexts);
476   }
477 };
478 
479 bool operator==(const SymbolContext &lhs, const SymbolContext &rhs);
480 bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs);
481 
482 bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs);
483 bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs);
484 
485 } // namespace lldb_private
486 
487 #endif // LLDB_SYMBOL_SYMBOLCONTEXT_H
488