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