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