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 | 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 | |
323 | class SymbolContextSpecifier { |
324 | public: |
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 | |
353 | private: |
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. |
374 | class SymbolContextList { |
375 | public: |
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 | |
459 | protected: |
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 | |
467 | public: |
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 | |
478 | bool operator==(const SymbolContext &lhs, const SymbolContext &rhs); |
479 | bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs); |
480 | |
481 | bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs); |
482 | bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs); |
483 | |
484 | } // namespace lldb_private |
485 | |
486 | #endif // LLDB_SYMBOL_SYMBOLCONTEXT_H |
487 | |