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
23namespace lldb_private {
24
25class 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.
34class SymbolContext {
35public:
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      std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
162
163  /// Get the address range contained within a symbol context.
164  ///
165  /// Address range priority is as follows:
166  ///     - line_entry address range if line_entry is valid and
167  ///     eSymbolContextLineEntry is set in \a scope
168  ///     - block address range if block is not nullptr and eSymbolContextBlock
169  ///     is set in \a scope
170  ///     - function address range if function is not nullptr and
171  ///     eSymbolContextFunction is set in \a scope
172  ///     - symbol address range if symbol is not nullptr and
173  ///     eSymbolContextSymbol is set in \a scope
174  ///
175  /// \param[in] scope
176  ///     A mask of symbol context bits telling this function which
177  ///     address ranges it can use when trying to extract one from
178  ///     the valid (non-nullptr) symbol context classes.
179  ///
180  /// \param[in] range_idx
181  ///     The address range index to grab. Since many functions and
182  ///     blocks are not always contiguous, they may have more than
183  ///     one address range.
184  ///
185  /// \param[in] use_inline_block_range
186  ///     If \a scope has the eSymbolContextBlock bit set, and there
187  ///     is a valid block in the symbol context, return the block
188  ///     address range for the containing inline function block, not
189  ///     the deepest most block. This allows us to extract information
190  ///     for the address range of the inlined function block, not
191  ///     the deepest lexical block.
192  ///
193  /// \param[out] range
194  ///     An address range object that will be filled in if \b true
195  ///     is returned.
196  ///
197  /// \return
198  ///     \b True if this symbol context contains items that describe
199  ///     an address range, \b false otherwise.
200  bool GetAddressRange(uint32_t scope, uint32_t range_idx,
201                       bool use_inline_block_range, AddressRange &range) const;
202
203  bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range,
204                                        Status &error);
205
206  /// Find the best global data symbol visible from this context.
207  ///
208  /// Symbol priority is:
209  ///     - extern symbol in the current module if there is one
210  ///     - non-extern symbol in the current module if there is one
211  ///     - extern symbol in the target
212  ///     - non-extern symbol in the target
213  /// It is an error if the highest-priority result is ambiguous.
214  ///
215  /// \param[in] name
216  ///     The name of the symbol to search for.
217  ///
218  /// \param[out] error
219  ///     An error that will be populated with a message if there was an
220  ///     ambiguous result.  The error will not be populated if no result
221  ///     was found.
222  ///
223  /// \return
224  ///     The symbol that was found, or \b nullptr if none was found.
225  const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error);
226
227  void GetDescription(
228      Stream *s, lldb::DescriptionLevel level, Target *target,
229      std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
230
231  uint32_t GetResolvedMask() const;
232
233  lldb::LanguageType GetLanguage() const;
234
235  /// Find a block that defines the function represented by this symbol
236  /// context.
237  ///
238  /// If this symbol context points to a block that is an inlined function, or
239  /// is contained within an inlined function, the block that defines the
240  /// inlined function is returned.
241  ///
242  /// If this symbol context has no block in it, or the block is not itself an
243  /// inlined function block or contained within one, we return the top level
244  /// function block.
245  ///
246  /// This is a handy function to call when you want to get the block whose
247  /// variable list will include the arguments for the function that is
248  /// represented by this symbol context (whether the function is an inline
249  /// function or not).
250  ///
251  /// \return
252  ///     The block object pointer that defines the function that is
253  ///     represented by this symbol context object, nullptr otherwise.
254  Block *GetFunctionBlock();
255
256  /// Determines the name of the instance variable for the this decl context.
257  ///
258  /// For C++ the name is "this", for Objective-C the name is "self".
259  ///
260  /// \return
261  ///     Returns a StringRef for the name of the instance variable.
262  llvm::StringRef GetInstanceVariableName();
263
264  /// Sorts the types in TypeMap according to SymbolContext to TypeList
265  ///
266  void SortTypeList(TypeMap &type_map, TypeList &type_list) const;
267
268  /// Find a name of the innermost function for the symbol context.
269  ///
270  /// For instance, if the symbol context contains an inlined block, it will
271  /// return the inlined function name.
272  ///
273  /// \return
274  ///     The name of the function represented by this symbol context.
275  ConstString GetFunctionName(
276      Mangled::NamePreference preference = Mangled::ePreferDemangled) const;
277
278  /// Get the line entry that corresponds to the function.
279  ///
280  /// If the symbol context contains an inlined block, the line entry for the
281  /// start address of the inlined function will be returned, otherwise the
282  /// line entry for the start address of the function will be returned. This
283  /// can be used after doing a Module::FindFunctions(...) or
284  /// ModuleList::FindFunctions(...) call in order to get the correct line
285  /// table information for the symbol context. it will return the inlined
286  /// function name.
287  LineEntry GetFunctionStartLineEntry() const;
288
289  /// Find the block containing the inlined block that contains this block.
290  ///
291  /// For instance, if the symbol context contains an inlined block, it will
292  /// return the inlined function name.
293  ///
294  /// \param[in] curr_frame_pc
295  ///    The address within the block of this object.
296  ///
297  /// \param[out] next_frame_sc
298  ///     A new symbol context that does what the title says it does.
299  ///
300  /// \param[out] inlined_frame_addr
301  ///     This is what you should report as the PC in \a next_frame_sc.
302  ///
303  /// \return
304  ///     \b true if this SymbolContext specifies a block contained in an
305  ///     inlined block.  If this returns \b true, \a next_frame_sc and
306  ///     \a inlined_frame_addr will be filled in correctly.
307  bool GetParentOfInlinedScope(const Address &curr_frame_pc,
308                               SymbolContext &next_frame_sc,
309                               Address &inlined_frame_addr) const;
310
311  // Member variables
312  lldb::TargetSP target_sp; ///< The Target for a given query
313  lldb::ModuleSP module_sp; ///< The Module for a given query
314  CompileUnit *comp_unit = nullptr; ///< The CompileUnit for a given query
315  Function *function = nullptr;     ///< The Function for a given query
316  Block *block = nullptr;           ///< The Block for a given query
317  LineEntry line_entry;     ///< The LineEntry for a given query
318  Symbol *symbol = nullptr; ///< The Symbol for a given query
319  Variable *variable =
320      nullptr; ///< The global variable matching the given query
321};
322
323class SymbolContextSpecifier {
324public:
325  enum SpecificationType {
326    eNothingSpecified = 0,
327    eModuleSpecified = 1 << 0,
328    eFileSpecified = 1 << 1,
329    eLineStartSpecified = 1 << 2,
330    eLineEndSpecified = 1 << 3,
331    eFunctionSpecified = 1 << 4,
332    eClassOrNamespaceSpecified = 1 << 5,
333    eAddressRangeSpecified = 1 << 6
334  };
335
336  // This one produces a specifier that matches everything...
337  SymbolContextSpecifier(const lldb::TargetSP &target_sp);
338
339  ~SymbolContextSpecifier();
340
341  bool AddSpecification(const char *spec_string, SpecificationType type);
342
343  bool AddLineSpecification(uint32_t line_no, SpecificationType type);
344
345  void Clear();
346
347  bool SymbolContextMatches(const SymbolContext &sc);
348
349  bool AddressMatches(lldb::addr_t addr);
350
351  void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
352
353private:
354  lldb::TargetSP m_target_sp;
355  std::string m_module_spec;
356  lldb::ModuleSP m_module_sp;
357  std::unique_ptr<FileSpec> m_file_spec_up;
358  size_t m_start_line;
359  size_t m_end_line;
360  std::string m_function_spec;
361  std::string m_class_name;
362  std::unique_ptr<AddressRange> m_address_range_up;
363  uint32_t m_type; // Or'ed bits from SpecificationType
364};
365
366/// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h"
367/// Defines a list of symbol context objects.
368///
369/// This class provides a common structure that can be used to contain the
370/// result of a query that can contain a multiple results. Examples of such
371/// queries include:
372///     \li Looking up a function by name.
373///     \li Finding all addresses for a specified file and line number.
374class SymbolContextList {
375public:
376  /// Default constructor.
377  ///
378  /// Initialize with an empty list.
379  SymbolContextList();
380
381  /// Destructor.
382  ~SymbolContextList();
383
384  /// Append a new symbol context to the list.
385  ///
386  /// \param[in] sc
387  ///     A symbol context to append to the list.
388  void Append(const SymbolContext &sc);
389
390  void Append(const SymbolContextList &sc_list);
391
392  bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function);
393
394  uint32_t AppendIfUnique(const SymbolContextList &sc_list,
395                          bool merge_symbol_into_function);
396
397  /// Clear the object's state.
398  ///
399  /// Clears the symbol context list.
400  void Clear();
401
402  /// Dump a description of this object to a Stream.
403  ///
404  /// Dump a description of the contents of each symbol context in the list to
405  /// the supplied stream \a s.
406  ///
407  /// \param[in] s
408  ///     The stream to which to dump the object description.
409  void Dump(Stream *s, Target *target) const;
410
411  /// Get accessor for a symbol context at index \a idx.
412  ///
413  /// Dump a description of the contents of each symbol context in the list to
414  /// the supplied stream \a s.
415  ///
416  /// \param[in] idx
417  ///     The zero based index into the symbol context list.
418  ///
419  /// \param[out] sc
420  ///     A reference to the symbol context to fill in.
421  ///
422  /// \return
423  ///     Returns \b true if \a idx was a valid index into this
424  ///     symbol context list and \a sc was filled in, \b false
425  ///     otherwise.
426  bool GetContextAtIndex(size_t idx, SymbolContext &sc) const;
427
428  /// Direct reference accessor for a symbol context at index \a idx.
429  ///
430  /// The index \a idx must be a valid index, no error checking will be done
431  /// to ensure that it is valid.
432  ///
433  /// \param[in] idx
434  ///     The zero based index into the symbol context list.
435  ///
436  /// \return
437  ///     A const reference to the symbol context to fill in.
438  SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; }
439
440  const SymbolContext &operator[](size_t idx) const {
441    return m_symbol_contexts[idx];
442  }
443
444  bool RemoveContextAtIndex(size_t idx);
445
446  /// Get accessor for a symbol context list size.
447  ///
448  /// \return
449  ///     Returns the number of symbol context objects in the list.
450  uint32_t GetSize() const;
451
452  bool IsEmpty() const;
453
454  uint32_t NumLineEntriesWithLine(uint32_t line) const;
455
456  void GetDescription(Stream *s, lldb::DescriptionLevel level,
457                      Target *target) const;
458
459protected:
460  typedef std::vector<SymbolContext>
461      collection; ///< The collection type for the list.
462  typedef collection::const_iterator const_iterator;
463
464  // Member variables.
465  collection m_symbol_contexts; ///< The list of symbol contexts.
466
467public:
468  const_iterator begin() const { return m_symbol_contexts.begin(); }
469  const_iterator end() const { return m_symbol_contexts.end(); }
470
471  typedef AdaptedIterable<collection, SymbolContext, vector_adapter>
472      SymbolContextIterable;
473  SymbolContextIterable SymbolContexts() {
474    return SymbolContextIterable(m_symbol_contexts);
475  }
476};
477
478bool operator==(const SymbolContext &lhs, const SymbolContext &rhs);
479bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs);
480
481bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs);
482bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs);
483
484} // namespace lldb_private
485
486#endif // LLDB_SYMBOL_SYMBOLCONTEXT_H
487