LLDB mainline
SymbolContext.cpp
Go to the documentation of this file.
1//===-- SymbolContext.cpp -------------------------------------------------===//
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
10
11#include "lldb/Core/Address.h"
12#include "lldb/Core/Debugger.h"
14#include "lldb/Core/Module.h"
16#include "lldb/Host/Host.h"
17#include "lldb/Symbol/Block.h"
20#include "lldb/Symbol/Symbol.h"
25#include "lldb/Target/Target.h"
27#include "lldb/Utility/Log.h"
28#include "lldb/Utility/Stream.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
36
38 Block *b, LineEntry *le, Symbol *s)
39 : target_sp(), module_sp(m), comp_unit(cu), function(f), block(b),
40 line_entry(), symbol(s) {
41 if (le)
42 line_entry = *le;
43}
44
46 CompileUnit *cu, Function *f, Block *b,
47 LineEntry *le, Symbol *s)
48 : target_sp(t), module_sp(m), comp_unit(cu), function(f), block(b),
49 line_entry(), symbol(s) {
50 if (le)
51 line_entry = *le;
52}
53
58
60
61void SymbolContext::Clear(bool clear_target) {
62 if (clear_target)
63 target_sp.reset();
64 module_sp.reset();
65 comp_unit = nullptr;
66 function = nullptr;
67 block = nullptr;
68 line_entry.Clear();
69 symbol = nullptr;
70 variable = nullptr;
71}
72
74 Stream *s, ExecutionContextScope *exe_scope, const Address &addr,
75 bool show_fullpaths, bool show_module, bool show_inlined_frames,
76 bool show_function_arguments, bool show_function_name,
77 bool show_function_display_name,
78 std::optional<Stream::HighlightSettings> settings) const {
79 bool dumped_something = false;
80 if (show_module && module_sp) {
81 if (show_fullpaths)
82 *s << module_sp->GetFileSpec();
83 else
84 *s << module_sp->GetFileSpec().GetFilename();
85 s->PutChar('`');
86 dumped_something = true;
87 }
88 if (function != nullptr) {
89 SymbolContext inline_parent_sc;
90 Address inline_parent_addr;
91 if (!show_function_name) {
92 s->Printf("<");
93 dumped_something = true;
94 } else {
95 ConstString name;
96 if (!show_function_arguments)
97 name = function->GetNameNoArguments();
98 if (!name && show_function_display_name)
99 name = function->GetDisplayName();
100 if (!name)
101 name = function->GetName();
102 if (name)
103 s->PutCStringColorHighlighted(name.GetStringRef(), settings);
104 }
105
106 if (addr_t file_addr = addr.GetFileAddress();
107 file_addr != LLDB_INVALID_ADDRESS) {
108 // Avoiding signed arithmetic due to UB in -INT_MAX.
109 const char sign =
110 file_addr >= function->GetAddress().GetFileAddress() ? '+' : '-';
111 addr_t offset = file_addr - function->GetAddress().GetFileAddress();
112 if (sign == '-')
113 offset = -offset;
114 if (!show_function_name) {
115 // Print +offset even if offset is 0
116 dumped_something = true;
117 s->Format("{0}{1}>", sign, offset);
118 } else if (offset) {
119 dumped_something = true;
120 s->Format(" {0} {1}", sign, offset);
121 }
122 }
123
124 if (GetParentOfInlinedScope(addr, inline_parent_sc, inline_parent_addr)) {
125 dumped_something = true;
126 Block *inlined_block = block->GetContainingInlinedBlock();
127 const InlineFunctionInfo *inlined_block_info =
128 inlined_block->GetInlinedFunctionInfo();
129 s->Printf(" [inlined] %s", inlined_block_info->GetName().GetCString());
130
131 lldb_private::AddressRange block_range;
132 if (inlined_block->GetRangeContainingAddress(addr, block_range)) {
133 const addr_t inlined_function_offset =
134 addr.GetFileAddress() -
135 block_range.GetBaseAddress().GetFileAddress();
136 if (inlined_function_offset) {
137 s->Printf(" + %" PRIu64, inlined_function_offset);
138 }
139 }
140 // "line_entry" will always be valid as GetParentOfInlinedScope(...) will
141 // fill it in correctly with the calling file and line. Previous code
142 // was extracting the calling file and line from inlined_block_info and
143 // using it right away which is not correct. On the first call to this
144 // function "line_entry" will contain the actual line table entry. On
145 // susequent calls "line_entry" will contain the calling file and line
146 // from the previous inline info.
147 if (line_entry.IsValid()) {
148 s->PutCString(" at ");
149 line_entry.DumpStopContext(s, show_fullpaths);
150 }
151
152 if (show_inlined_frames) {
153 s->EOL();
154 s->Indent();
155 const bool show_function_name = true;
156 return inline_parent_sc.DumpStopContext(
157 s, exe_scope, inline_parent_addr, show_fullpaths, show_module,
158 show_inlined_frames, show_function_arguments, show_function_name,
159 show_function_display_name);
160 }
161 } else {
162 if (line_entry.IsValid()) {
163 dumped_something = true;
164 s->PutCString(" at ");
165 if (line_entry.DumpStopContext(s, show_fullpaths))
166 dumped_something = true;
167 }
168 }
169 } else if (symbol != nullptr) {
170 if (!show_function_name) {
171 s->Printf("<");
172 dumped_something = true;
173 } else if (symbol->GetName()) {
174 dumped_something = true;
175 if (symbol->GetType() == eSymbolTypeTrampoline)
176 s->PutCString("symbol stub for: ");
177 ConstString name;
178 if (show_function_display_name)
179 name = symbol->GetDisplayName();
180 if (!name)
181 name = symbol->GetName();
182 s->PutCStringColorHighlighted(name.GetStringRef(), settings);
183 }
184
185 if (addr.IsValid() && symbol->ValueIsAddress()) {
186 const addr_t symbol_offset =
187 addr.GetOffset() - symbol->GetAddressRef().GetOffset();
188 if (!show_function_name) {
189 // Print +offset even if offset is 0
190 dumped_something = true;
191 s->Printf("+%" PRIu64 ">", symbol_offset);
192 } else if (symbol_offset) {
193 dumped_something = true;
194 s->Printf(" + %" PRIu64, symbol_offset);
195 }
196 }
197 } else if (addr.IsValid()) {
199 dumped_something = true;
200 }
201 return dumped_something;
202}
203
205 Stream *s, lldb::DescriptionLevel level, Target *target,
206 std::optional<Stream::HighlightSettings> settings) const {
207 if (module_sp) {
208 s->Indent(" Module: file = \"");
209 module_sp->GetFileSpec().Dump(s->AsRawOstream());
210 *s << '"';
211 if (module_sp->GetArchitecture().IsValid())
212 s->Printf(", arch = \"%s\"",
213 module_sp->GetArchitecture().GetArchitectureName());
214 s->EOL();
215 }
216
217 if (comp_unit != nullptr) {
218 s->Indent("CompileUnit: ");
219 comp_unit->GetDescription(s, level);
220 s->EOL();
221 }
222
223 if (function != nullptr) {
224 s->Indent(" Function: ");
225 function->GetDescription(s, level, target);
226 s->EOL();
227
228 Type *func_type = function->GetType();
229 if (func_type) {
230 s->Indent(" FuncType: ");
231 func_type->GetDescription(s, level, false, target);
232 s->EOL();
233 }
234 }
235
236 if (block != nullptr) {
237 std::vector<Block *> blocks;
238 blocks.push_back(block);
239 Block *parent_block = block->GetParent();
240
241 while (parent_block) {
242 blocks.push_back(parent_block);
243 parent_block = parent_block->GetParent();
244 }
245 std::vector<Block *>::reverse_iterator pos;
246 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
247 std::vector<Block *>::reverse_iterator end = blocks.rend();
248 for (pos = begin; pos != end; ++pos) {
249 if (pos == begin)
250 s->Indent(" Blocks: ");
251 else
252 s->Indent(" ");
253 (*pos)->GetDescription(s, function, level, target);
254 s->EOL();
255 }
256 }
257
258 if (line_entry.IsValid()) {
259 s->Indent(" LineEntry: ");
260 line_entry.GetDescription(s, level, comp_unit, target, false);
261 s->EOL();
262 }
263
264 if (symbol != nullptr) {
265 s->Indent(" Symbol: ");
266 symbol->GetDescription(s, level, target, settings);
267 s->EOL();
268 }
269
270 if (variable != nullptr) {
271 s->Indent(" Variable: ");
272
273 s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
274
275 switch (variable->GetScope()) {
277 s->PutCString("kind = global, ");
278 break;
279
281 s->PutCString("kind = static, ");
282 break;
283
285 s->PutCString("kind = argument, ");
286 break;
287
289 s->PutCString("kind = local, ");
290 break;
291
293 s->PutCString("kind = thread local, ");
294 break;
295
296 default:
297 break;
298 }
299
300 s->Printf("name = \"%s\"\n", variable->GetName().GetCString());
301 }
302}
303
305 uint32_t resolved_mask = 0;
306 if (target_sp)
307 resolved_mask |= eSymbolContextTarget;
308 if (module_sp)
309 resolved_mask |= eSymbolContextModule;
310 if (comp_unit)
311 resolved_mask |= eSymbolContextCompUnit;
312 if (function)
313 resolved_mask |= eSymbolContextFunction;
314 if (block)
315 resolved_mask |= eSymbolContextBlock;
316 if (line_entry.IsValid())
317 resolved_mask |= eSymbolContextLineEntry;
318 if (symbol)
319 resolved_mask |= eSymbolContextSymbol;
320 if (variable)
321 resolved_mask |= eSymbolContextVariable;
322 return resolved_mask;
323}
324
326 const SymbolContext &rhs) {
327 return lhs.function == rhs.function && lhs.symbol == rhs.symbol &&
328 lhs.module_sp.get() == rhs.module_sp.get() &&
329 lhs.comp_unit == rhs.comp_unit &&
330 lhs.target_sp.get() == rhs.target_sp.get() &&
332 lhs.variable == rhs.variable;
333}
334
336 const SymbolContext &rhs) {
337 return !(lhs == rhs);
338}
339
340bool SymbolContext::GetAddressRange(uint32_t scope, uint32_t range_idx,
341 bool use_inline_block_range,
342 AddressRange &range) const {
343 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) {
344 range = line_entry.range;
345 return true;
346 }
347
348 if ((scope & eSymbolContextBlock) && (block != nullptr)) {
349 if (use_inline_block_range) {
350 Block *inline_block = block->GetContainingInlinedBlock();
351 if (inline_block)
352 return inline_block->GetRangeAtIndex(range_idx, range);
353 } else {
354 return block->GetRangeAtIndex(range_idx, range);
355 }
356 }
357
358 if ((scope & eSymbolContextFunction) && (function != nullptr)) {
359 if (range_idx < function->GetAddressRanges().size()) {
360 range = function->GetAddressRanges()[range_idx];
361 return true;
362 }
363 }
364
365 if ((scope & eSymbolContextSymbol) && (symbol != nullptr)) {
366 if (range_idx == 0) {
367 if (symbol->ValueIsAddress()) {
368 range.GetBaseAddress() = symbol->GetAddressRef();
369 range.SetByteSize(symbol->GetByteSize());
370 return true;
371 }
372 }
373 }
374 range.Clear();
375 return false;
376}
377
379 if (function)
380 return function->GetAddress();
381
382 if (symbol)
383 return symbol->GetAddress();
384
385 return Address();
386}
387
389 LanguageType lang;
390 if (function && (lang = function->GetLanguage()) != eLanguageTypeUnknown) {
391 return lang;
392 } else if (variable &&
393 (lang = variable->GetLanguage()) != eLanguageTypeUnknown) {
394 return lang;
395 } else if (symbol && (lang = symbol->GetLanguage()) != eLanguageTypeUnknown) {
396 return lang;
397 } else if (comp_unit &&
398 (lang = comp_unit->GetLanguage()) != eLanguageTypeUnknown) {
399 return lang;
400 } else if (symbol) {
401 // If all else fails, try to guess the language from the name.
402 return symbol->GetMangled().GuessLanguage();
403 }
405}
406
408 SymbolContext &next_frame_sc,
409 Address &next_frame_pc) const {
410 next_frame_sc.Clear(false);
411 next_frame_pc.Clear();
412
413 if (block) {
414 // const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
415
416 // In order to get the parent of an inlined function we first need to see
417 // if we are in an inlined block as "this->block" could be an inlined
418 // block, or a parent of "block" could be. So lets check if this block or
419 // one of this blocks parents is an inlined function.
420 Block *curr_inlined_block = block->GetContainingInlinedBlock();
421 if (curr_inlined_block) {
422 // "this->block" is contained in an inline function block, so to get the
423 // scope above the inlined block, we get the parent of the inlined block
424 // itself
425 Block *next_frame_block = curr_inlined_block->GetParent();
426 // Now calculate the symbol context of the containing block
427 next_frame_block->CalculateSymbolContext(&next_frame_sc);
428
429 // If we get here we weren't able to find the return line entry using the
430 // nesting of the blocks and the line table. So just use the call site
431 // info from our inlined block.
432
433 AddressRange range;
434 if (curr_inlined_block->GetRangeContainingAddress(curr_frame_pc, range)) {
435 // To see there this new frame block it, we need to look at the call
436 // site information from
437 const InlineFunctionInfo *curr_inlined_block_inlined_info =
438 curr_inlined_block->GetInlinedFunctionInfo();
439 next_frame_pc = range.GetBaseAddress();
440 next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
441 next_frame_sc.line_entry.file_sp = std::make_shared<SupportFile>(
442 curr_inlined_block_inlined_info->GetCallSite().GetFile());
443 next_frame_sc.line_entry.original_file_sp =
444 std::make_shared<SupportFile>(
445 curr_inlined_block_inlined_info->GetCallSite().GetFile());
446 next_frame_sc.line_entry.line =
447 curr_inlined_block_inlined_info->GetCallSite().GetLine();
448 next_frame_sc.line_entry.column =
449 curr_inlined_block_inlined_info->GetCallSite().GetColumn();
450 return true;
451 } else {
453
454 if (log) {
455 LLDB_LOGF(
456 log,
457 "warning: inlined block 0x%8.8" PRIx64
458 " doesn't have a range that contains file address 0x%" PRIx64,
459 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
460 }
461#ifdef LLDB_CONFIGURATION_DEBUG
462 else {
463 ObjectFile *objfile = nullptr;
464 if (module_sp) {
465 if (SymbolFile *symbol_file = module_sp->GetSymbolFile())
466 objfile = symbol_file->GetObjectFile();
467 }
468 if (objfile) {
469 Debugger::ReportWarning(llvm::formatv(
470 "inlined block {0:x} doesn't have a range that contains file "
471 "address {1:x} in {2}",
472 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress(),
473 objfile->GetFileSpec().GetPath()));
474 } else {
475 Debugger::ReportWarning(llvm::formatv(
476 "inlined block {0:x} doesn't have a range that contains file "
477 "address {1:x}",
478 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()));
479 }
480 }
481#endif
482 }
483 }
484 }
485
486 return false;
487}
488
490 if (function) {
491 if (block) {
492 // If this symbol context has a block, check to see if this block is
493 // itself, or is contained within a block with inlined function
494 // information. If so, then the inlined block is the block that defines
495 // the function.
496 Block *inlined_block = block->GetContainingInlinedBlock();
497 if (inlined_block)
498 return inlined_block;
499
500 // The block in this symbol context is not inside an inlined block, so
501 // the block that defines the function is the function's top level block,
502 // which is returned below.
503 }
504
505 // There is no block information in this symbol context, so we must assume
506 // that the block that is desired is the top level block of the function
507 // itself.
508 return &function->GetBlock(true);
509 }
510 return nullptr;
511}
512
515
516 if (Block *function_block = GetFunctionBlock())
517 if (CompilerDeclContext decl_ctx = function_block->GetDeclContext())
518 lang_type = decl_ctx.GetLanguage();
519
520 if (lang_type == eLanguageTypeUnknown)
521 lang_type = GetLanguage();
522
523 if (auto *lang = Language::FindPlugin(lang_type))
524 return lang->GetInstanceVariableName();
525
526 return {};
527}
528
529void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
530 Block *curr_block = block;
531 bool isInlinedblock = false;
532 if (curr_block != nullptr &&
533 curr_block->GetContainingInlinedBlock() != nullptr)
534 isInlinedblock = true;
535
536 // Find all types that match the current block if we have one and put them
537 // first in the list. Keep iterating up through all blocks.
538 while (curr_block != nullptr && !isInlinedblock) {
539 type_map.ForEach(
540 [curr_block, &type_list](const lldb::TypeSP &type_sp) -> bool {
541 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
542 if (scs && curr_block == scs->CalculateSymbolContextBlock())
543 type_list.Insert(type_sp);
544 return true; // Keep iterating
545 });
546
547 // Remove any entries that are now in "type_list" from "type_map" since we
548 // can't remove from type_map while iterating
549 type_list.ForEach([&type_map](const lldb::TypeSP &type_sp) -> bool {
550 type_map.Remove(type_sp);
551 return true; // Keep iterating
552 });
553 curr_block = curr_block->GetParent();
554 }
555 // Find all types that match the current function, if we have onem, and put
556 // them next in the list.
557 if (function != nullptr && !type_map.Empty()) {
558 const size_t old_type_list_size = type_list.GetSize();
559 type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
560 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
561 if (scs && function == scs->CalculateSymbolContextFunction())
562 type_list.Insert(type_sp);
563 return true; // Keep iterating
564 });
565
566 // Remove any entries that are now in "type_list" from "type_map" since we
567 // can't remove from type_map while iterating
568 const size_t new_type_list_size = type_list.GetSize();
569 if (new_type_list_size > old_type_list_size) {
570 for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
571 type_map.Remove(type_list.GetTypeAtIndex(i));
572 }
573 }
574 // Find all types that match the current compile unit, if we have one, and
575 // put them next in the list.
576 if (comp_unit != nullptr && !type_map.Empty()) {
577 const size_t old_type_list_size = type_list.GetSize();
578
579 type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
580 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
581 if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit())
582 type_list.Insert(type_sp);
583 return true; // Keep iterating
584 });
585
586 // Remove any entries that are now in "type_list" from "type_map" since we
587 // can't remove from type_map while iterating
588 const size_t new_type_list_size = type_list.GetSize();
589 if (new_type_list_size > old_type_list_size) {
590 for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
591 type_map.Remove(type_list.GetTypeAtIndex(i));
592 }
593 }
594 // Find all types that match the current module, if we have one, and put them
595 // next in the list.
596 if (module_sp && !type_map.Empty()) {
597 const size_t old_type_list_size = type_list.GetSize();
598 type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
599 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
600 if (scs && module_sp == scs->CalculateSymbolContextModule())
601 type_list.Insert(type_sp);
602 return true; // Keep iterating
603 });
604 // Remove any entries that are now in "type_list" from "type_map" since we
605 // can't remove from type_map while iterating
606 const size_t new_type_list_size = type_list.GetSize();
607 if (new_type_list_size > old_type_list_size) {
608 for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
609 type_map.Remove(type_list.GetTypeAtIndex(i));
610 }
611 }
612 // Any types that are left get copied into the list an any order.
613 if (!type_map.Empty()) {
614 type_map.ForEach([&type_list](const lldb::TypeSP &type_sp) -> bool {
615 type_list.Insert(type_sp);
616 return true; // Keep iterating
617 });
618 }
619}
620
623 if (function) {
624 if (block) {
625 Block *inlined_block = block->GetContainingInlinedBlock();
626
627 if (inlined_block) {
628 const InlineFunctionInfo *inline_info =
629 inlined_block->GetInlinedFunctionInfo();
630 if (inline_info)
631 return inline_info->GetName();
632 }
633 }
634 return function->GetMangled().GetName(preference);
635 } else if (symbol && symbol->ValueIsAddress()) {
636 return symbol->GetMangled().GetName(preference);
637 } else {
638 // No function, return an empty string.
639 return ConstString();
640 }
641}
642
645 Address start_addr;
646 if (block) {
647 Block *inlined_block = block->GetContainingInlinedBlock();
648 if (inlined_block) {
649 if (inlined_block->GetStartAddress(start_addr)) {
651 return line_entry;
652 }
653 return LineEntry();
654 }
655 }
656
657 if (function) {
658 if (function->GetAddress().CalculateSymbolContextLineEntry(line_entry))
659 return line_entry;
660 }
661 return LineEntry();
662}
663
664llvm::Error
666 AddressRange &range) {
667 if (!line_entry.IsValid()) {
668 return llvm::createStringError("Symbol context has no line table.");
669 }
670
671 range = line_entry.range;
672 if (line_entry.line > end_line) {
673 return llvm::createStringError(
674 "end line option %d must be after the current line: %d", end_line,
675 line_entry.line);
676 }
677
678 uint32_t line_index = 0;
679 bool found = false;
680 while (true) {
681 LineEntry this_line;
682 line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr,
683 false, &this_line);
684 if (line_index == UINT32_MAX)
685 break;
686 if (LineEntry::Compare(this_line, line_entry) == 0) {
687 found = true;
688 break;
689 }
690 }
691
692 LineEntry end_entry;
693 if (!found) {
694 // Can't find the index of the SymbolContext's line entry in the
695 // SymbolContext's CompUnit.
696 return llvm::createStringError(
697 "Can't find the current line entry in the CompUnit - can't process "
698 "the end-line option");
699 }
700
701 line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false,
702 &end_entry);
703 if (line_index == UINT32_MAX) {
704 return llvm::createStringError(
705 "could not find a line table entry corresponding "
706 "to end line number %d",
707 end_line);
708 }
709
710 Block *func_block = GetFunctionBlock();
711 if (func_block && func_block->GetRangeIndexContainingAddress(
712 end_entry.range.GetBaseAddress()) == UINT32_MAX) {
713 return llvm::createStringError(
714 "end line number %d is not contained within the current function.",
715 end_line);
716 }
717
718 lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress() -
720 range.SetByteSize(range_size);
721 return llvm::Error::success();
722}
723
725 Status &error) {
726 error.Clear();
727
728 if (!target_sp) {
729 return nullptr;
730 }
731
732 Target &target = *target_sp;
733 Module *module = module_sp.get();
734
735 auto ProcessMatches = [this, &name, &target,
736 module](const SymbolContextList &sc_list,
737 Status &error) -> const Symbol * {
738 llvm::SmallVector<const Symbol *, 1> external_symbols;
739 llvm::SmallVector<const Symbol *, 1> internal_symbols;
740 for (const SymbolContext &sym_ctx : sc_list) {
741 if (sym_ctx.symbol) {
742 const Symbol *symbol = sym_ctx.symbol;
743 const Address sym_address = symbol->GetAddress();
744
745 if (sym_address.IsValid()) {
746 switch (symbol->GetType()) {
747 case eSymbolTypeData:
753 if (symbol->GetDemangledNameIsSynthesized()) {
754 // If the demangled name was synthesized, then don't use it for
755 // expressions. Only let the symbol match if the mangled named
756 // matches for these symbols.
757 if (symbol->GetMangled().GetMangledName() != name)
758 break;
759 }
760 if (symbol->IsExternal()) {
761 external_symbols.push_back(symbol);
762 } else {
763 internal_symbols.push_back(symbol);
764 }
765 break;
767 ConstString reexport_name = symbol->GetReExportedSymbolName();
768 if (reexport_name) {
769 ModuleSP reexport_module_sp;
770 ModuleSpec reexport_module_spec;
771 reexport_module_spec.GetPlatformFileSpec() =
772 symbol->GetReExportedSymbolSharedLibrary();
773 if (reexport_module_spec.GetPlatformFileSpec()) {
774 reexport_module_sp =
775 target.GetImages().FindFirstModule(reexport_module_spec);
776 if (!reexport_module_sp) {
777 reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
778 reexport_module_sp =
779 target.GetImages().FindFirstModule(reexport_module_spec);
780 }
781 }
782 // Don't allow us to try and resolve a re-exported symbol if it
783 // is the same as the current symbol
784 if (name == symbol->GetReExportedSymbolName() &&
785 module == reexport_module_sp.get())
786 return nullptr;
787
788 return FindBestGlobalDataSymbol(symbol->GetReExportedSymbolName(),
789 error);
790 }
791 } break;
792
793 case eSymbolTypeCode: // We already lookup functions elsewhere
795 case eSymbolTypeLocal:
796 case eSymbolTypeParam:
804 case eSymbolTypeBlock:
815 break;
816 }
817 }
818 }
819 }
820
821 if (external_symbols.size() > 1) {
822 StreamString ss;
823 ss.Printf("Multiple external symbols found for '%s'\n", name.AsCString());
824 for (const Symbol *symbol : external_symbols) {
825 symbol->GetDescription(&ss, eDescriptionLevelFull, &target);
826 }
827 ss.PutChar('\n');
829 return nullptr;
830 } else if (external_symbols.size()) {
831 return external_symbols[0];
832 } else if (internal_symbols.size() > 1) {
833 StreamString ss;
834 ss.Printf("Multiple internal symbols found for '%s'\n", name.AsCString());
835 for (const Symbol *symbol : internal_symbols) {
836 symbol->GetDescription(&ss, eDescriptionLevelVerbose, &target);
837 ss.PutChar('\n');
838 }
840 return nullptr;
841 } else if (internal_symbols.size()) {
842 return internal_symbols[0];
843 } else {
844 return nullptr;
845 }
846 };
847
848 if (module) {
849 SymbolContextList sc_list;
850 module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
851 const Symbol *const module_symbol = ProcessMatches(sc_list, error);
852
853 if (!error.Success()) {
854 return nullptr;
855 } else if (module_symbol) {
856 return module_symbol;
857 }
858 }
859
860 {
861 SymbolContextList sc_list;
863 sc_list);
864 const Symbol *const target_symbol = ProcessMatches(sc_list, error);
865
866 if (!error.Success()) {
867 return nullptr;
868 } else if (target_symbol) {
869 return target_symbol;
870 }
871 }
872
873 return nullptr; // no error; we just didn't find anything
874}
875
877 auto get_mangled = [this]() {
878 if (function)
879 return function->GetMangled();
880
881 if (symbol)
882 return symbol->GetMangled();
883
884 return Mangled{};
885 };
886
887 if (!block)
888 return get_mangled();
889
890 const Block *inline_block = block->GetContainingInlinedBlock();
891 if (!inline_block)
892 return get_mangled();
893
894 const InlineFunctionInfo *inline_info =
895 inline_block->GetInlinedFunctionInfo();
896 if (!inline_info)
897 return get_mangled();
898
899 // If we do have an inlined frame name, return that.
900 if (const Mangled &inline_name = inline_info->GetMangled())
901 return inline_name;
902
903 // Sometimes an inline frame may not have mangling information,
904 // but does have a valid name.
905 return Mangled{inline_info->GetName().AsCString()};
906}
907
908//
909// SymbolContextSpecifier
910//
911
916
918
920 SpecificationType type) {
921 bool return_value = true;
922 switch (type) {
924 Clear();
925 break;
927 m_start_line = line_no;
929 break;
931 m_end_line = line_no;
933 break;
934 default:
935 return_value = false;
936 break;
937 }
938 return return_value;
939}
940
941bool SymbolContextSpecifier::AddSpecification(const char *spec_string,
942 SpecificationType type) {
943 bool return_value = true;
944 switch (type) {
946 Clear();
947 break;
948 case eModuleSpecified: {
949 // See if we can find the Module, if so stick it in the SymbolContext.
950 FileSpec module_file_spec(spec_string);
951 ModuleSpec module_spec(module_file_spec);
952 lldb::ModuleSP module_sp =
953 m_target_sp ? m_target_sp->GetImages().FindFirstModule(module_spec)
954 : nullptr;
956 if (module_sp)
957 m_module_sp = module_sp;
958 else
959 m_module_spec.assign(spec_string);
960 } break;
961 case eFileSpecified:
962 // CompUnits can't necessarily be resolved here, since an inlined function
963 // might show up in a number of CompUnits. Instead we just convert to a
964 // FileSpec and store it away.
965 m_file_spec_up = std::make_unique<FileSpec>(spec_string);
967 break;
969 if ((return_value = llvm::to_integer(spec_string, m_start_line)))
971 break;
973 if ((return_value = llvm::to_integer(spec_string, m_end_line)))
975 break;
977 m_function_spec.assign(spec_string);
979 break;
981 Clear();
982 m_class_name.assign(spec_string);
984 break;
986 // Not specified yet...
987 break;
988 }
989
990 return return_value;
991}
992
994 m_module_spec.clear();
995 m_file_spec_up.reset();
996 m_function_spec.clear();
997 m_class_name.clear();
998 m_start_line = 0;
999 m_end_line = 0;
1000 m_address_range_up.reset();
1001
1003}
1004
1007 return true;
1008
1009 // Only compare targets if this specifier has one and it's not the Dummy
1010 // target. Otherwise if a specifier gets made in the dummy target and
1011 // copied over we'll artificially fail the comparision.
1012 if (m_target_sp && !m_target_sp->IsDummyTarget() &&
1013 m_target_sp != sc.target_sp)
1014 return false;
1015
1016 if (m_type & eModuleSpecified) {
1017 if (sc.module_sp) {
1018 if (m_module_sp.get() != nullptr) {
1019 if (m_module_sp.get() != sc.module_sp.get())
1020 return false;
1021 } else {
1022 FileSpec module_file_spec(m_module_spec);
1023 if (!FileSpec::Match(module_file_spec, sc.module_sp->GetFileSpec()))
1024 return false;
1025 }
1026 }
1027 }
1028 if (m_type & eFileSpecified) {
1029 if (m_file_spec_up) {
1030 // If we don't have a block or a comp_unit, then we aren't going to match
1031 // a source file.
1032 if (sc.block == nullptr && sc.comp_unit == nullptr)
1033 return false;
1034
1035 // Check if the block is present, and if so is it inlined:
1036 bool was_inlined = false;
1037 if (sc.block != nullptr) {
1038 const InlineFunctionInfo *inline_info =
1040 if (inline_info != nullptr) {
1041 was_inlined = true;
1043 inline_info->GetDeclaration().GetFile()))
1044 return false;
1045 }
1046 }
1047
1048 // Next check the comp unit, but only if the SymbolContext was not
1049 // inlined.
1050 if (!was_inlined && sc.comp_unit != nullptr) {
1052 return false;
1053 }
1054 }
1055 }
1058 return false;
1059 }
1060
1061 if (m_type & eFunctionSpecified) {
1062 // First check the current block, and if it is inlined, get the inlined
1063 // function name:
1064 bool was_inlined = false;
1065 ConstString func_name(m_function_spec.c_str());
1066
1067 if (sc.block != nullptr) {
1068 const InlineFunctionInfo *inline_info =
1070 if (inline_info != nullptr) {
1071 was_inlined = true;
1072 const Mangled &name = inline_info->GetMangled();
1073 if (!name.NameMatches(func_name))
1074 return false;
1075 }
1076 }
1077 // If it wasn't inlined, check the name in the function or symbol:
1078 if (!was_inlined) {
1079 if (sc.function != nullptr) {
1080 if (!sc.function->GetMangled().NameMatches(func_name))
1081 return false;
1082 } else if (sc.symbol != nullptr) {
1083 if (!sc.symbol->GetMangled().NameMatches(func_name))
1084 return false;
1085 }
1086 }
1087 }
1088
1089 return true;
1090}
1091
1094
1095 } else {
1096 Address match_address(addr, nullptr);
1097 SymbolContext sc;
1098 m_target_sp->GetImages().ResolveSymbolContextForAddress(
1099 match_address, eSymbolContextEverything, sc);
1100 return SymbolContextMatches(sc);
1101 }
1102 return true;
1103}
1104
1106 Stream *s, lldb::DescriptionLevel level) const {
1107 char path_str[PATH_MAX + 1];
1108
1109 if (m_type == eNothingSpecified) {
1110 s->Printf("Nothing specified.\n");
1111 }
1112
1113 if (m_type == eModuleSpecified) {
1114 s->Indent();
1115 if (m_module_sp) {
1116 m_module_sp->GetFileSpec().GetPath(path_str, PATH_MAX);
1117 s->Printf("Module: %s\n", path_str);
1118 } else
1119 s->Printf("Module: %s\n", m_module_spec.c_str());
1120 }
1121
1122 if (m_type == eFileSpecified && m_file_spec_up != nullptr) {
1123 m_file_spec_up->GetPath(path_str, PATH_MAX);
1124 s->Indent();
1125 s->Printf("File: %s", path_str);
1126 if (m_type == eLineStartSpecified) {
1127 s->Printf(" from line %" PRIu64 "", (uint64_t)m_start_line);
1129 s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
1130 else
1131 s->Printf("to end");
1132 } else if (m_type == eLineEndSpecified) {
1133 s->Printf(" from start to line %" PRIu64 "", (uint64_t)m_end_line);
1134 }
1135 s->Printf(".\n");
1136 }
1137
1138 if (m_type == eLineStartSpecified) {
1139 s->Indent();
1140 s->Printf("From line %" PRIu64 "", (uint64_t)m_start_line);
1142 s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
1143 else
1144 s->Printf("to end");
1145 s->Printf(".\n");
1146 } else if (m_type == eLineEndSpecified) {
1147 s->Printf("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
1148 }
1149
1150 if (m_type == eFunctionSpecified) {
1151 s->Indent();
1152 s->Printf("Function: %s.\n", m_function_spec.c_str());
1153 }
1154
1156 s->Indent();
1157 s->Printf("Class name: %s.\n", m_class_name.c_str());
1158 }
1159
1160 if (m_type == eAddressRangeSpecified && m_address_range_up != nullptr) {
1161 s->Indent();
1162 s->PutCString("Address range: ");
1163 m_address_range_up->Dump(s, m_target_sp.get(),
1166 s->PutCString("\n");
1167 }
1168}
1169
1170//
1171// SymbolContextList
1172//
1173
1175
1177
1179 m_symbol_contexts.push_back(sc);
1180}
1181
1183 collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1184 for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
1185 m_symbol_contexts.push_back(*pos);
1186}
1187
1189 bool merge_symbol_into_function) {
1190 uint32_t unique_sc_add_count = 0;
1191 collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1192 for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) {
1193 if (AppendIfUnique(*pos, merge_symbol_into_function))
1194 ++unique_sc_add_count;
1195 }
1196 return unique_sc_add_count;
1197}
1198
1200 bool merge_symbol_into_function) {
1201 collection::iterator pos, end = m_symbol_contexts.end();
1202 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1203 if (*pos == sc)
1204 return false;
1205 }
1206 if (merge_symbol_into_function && sc.symbol != nullptr &&
1207 sc.comp_unit == nullptr && sc.function == nullptr &&
1208 sc.block == nullptr && !sc.line_entry.IsValid()) {
1209 if (sc.symbol->ValueIsAddress()) {
1210 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1211 // Don't merge symbols into inlined function symbol contexts
1212 if (pos->block && pos->block->GetContainingInlinedBlock())
1213 continue;
1214
1215 if (pos->function) {
1216 if (pos->function->GetAddress() == sc.symbol->GetAddressRef()) {
1217 // Do we already have a function with this symbol?
1218 if (pos->symbol == sc.symbol)
1219 return false;
1220 if (pos->symbol == nullptr) {
1221 pos->symbol = sc.symbol;
1222 return false;
1223 }
1224 }
1225 }
1226 }
1227 }
1228 }
1229 m_symbol_contexts.push_back(sc);
1230 return true;
1231}
1232
1234
1235void SymbolContextList::Dump(Stream *s, Target *target) const {
1236
1237 *s << this << ": ";
1238 s->Indent();
1239 s->PutCString("SymbolContextList");
1240 s->EOL();
1241 s->IndentMore();
1242
1243 collection::const_iterator pos, end = m_symbol_contexts.end();
1244 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1245 // pos->Dump(s, target);
1246 pos->GetDescription(s, eDescriptionLevelVerbose, target);
1247 }
1248 s->IndentLess();
1249}
1250
1252 if (idx < m_symbol_contexts.size()) {
1253 sc = m_symbol_contexts[idx];
1254 return true;
1255 }
1256 return false;
1257}
1258
1260 if (idx < m_symbol_contexts.size()) {
1261 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1262 return true;
1263 }
1264 return false;
1265}
1266
1267uint32_t SymbolContextList::GetSize() const { return m_symbol_contexts.size(); }
1268
1269bool SymbolContextList::IsEmpty() const { return m_symbol_contexts.empty(); }
1270
1271uint32_t SymbolContextList::NumLineEntriesWithLine(uint32_t line) const {
1272 uint32_t match_count = 0;
1273 const size_t size = m_symbol_contexts.size();
1274 for (size_t idx = 0; idx < size; ++idx) {
1275 if (m_symbol_contexts[idx].line_entry.line == line)
1276 ++match_count;
1277 }
1278 return match_count;
1279}
1280
1282 Target *target) const {
1283 const size_t size = m_symbol_contexts.size();
1284 for (size_t idx = 0; idx < size; ++idx)
1285 m_symbol_contexts[idx].GetDescription(s, level, target);
1286}
1287
1289 const SymbolContextList &rhs) {
1290 const uint32_t size = lhs.GetSize();
1291 if (size != rhs.GetSize())
1292 return false;
1293
1294 SymbolContext lhs_sc;
1295 SymbolContext rhs_sc;
1296 for (uint32_t i = 0; i < size; ++i) {
1297 lhs.GetContextAtIndex(i, lhs_sc);
1298 rhs.GetContextAtIndex(i, rhs_sc);
1299 if (lhs_sc != rhs_sc)
1300 return false;
1301 }
1302 return true;
1303}
1304
1306 const SymbolContextList &rhs) {
1307 return !(lhs == rhs);
1308}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition Log.h:376
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
void Clear()
Clear the object's state.
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
A section + offset based address class.
Definition Address.h:62
void Clear()
Clear the object's state.
Definition Address.h:181
@ DumpStyleFileAddress
Display as the file address (if any).
Definition Address.h:87
@ DumpStyleModuleWithFileAddress
Display as the file address with the module name prepended (if any).
Definition Address.h:93
@ DumpStyleLoadAddress
Display as the load address (if resolved).
Definition Address.h:99
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
Definition Address.cpp:396
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
lldb::addr_t GetOffset() const
Get the section relative offset value.
Definition Address.h:329
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const
Definition Address.cpp:902
A class that describes a single lexical block.
Definition Block.h:41
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object's symbol context into sc.
Definition Block.cpp:137
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
Definition Block.cpp:206
bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range)
Definition Block.cpp:294
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Definition Block.h:268
bool GetRangeContainingAddress(const Address &addr, AddressRange &range)
Definition Block.cpp:248
Block * GetParent() const
Get the parent block.
Definition Block.cpp:202
bool GetStartAddress(Address &addr)
Definition Block.cpp:317
uint32_t GetRangeIndexContainingAddress(const Address &addr)
Definition Block.cpp:274
A class that describes a compilation unit.
Definition CompileUnit.h:43
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
Represents a generic declaration context in a program.
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
uint32_t GetLine() const
Get accessor for the declaration line number.
uint16_t GetColumn() const
Get accessor for the declaration column number.
FileSpec & GetFile()
Get accessor for file specification.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
A file utility class.
Definition FileSpec.h:57
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
Definition FileSpec.cpp:301
void ClearDirectory()
Clear the directory in this object.
Definition FileSpec.cpp:367
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
Declaration & GetDeclaration()
Get accessor for the declaration information.
Definition Function.cpp:53
A class that describes a function.
Definition Function.h:400
const Mangled & GetMangled() const
Definition Function.h:534
A class that describes information for an inlined function.
Definition Function.h:126
Declaration & GetCallSite()
Get accessor for the call site declaration information.
Definition Function.cpp:108
ConstString GetName() const
Definition Function.cpp:96
Mangled & GetMangled()
Get accessor for the mangled name object.
Definition Function.cpp:114
static Language * FindPlugin(lldb::LanguageType language)
Definition Language.cpp:84
A class that handles mangled names.
Definition Mangled.h:34
bool NameMatches(ConstString name) const
Check if "name" matches either the mangled or demangled name.
Definition Mangled.h:178
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:65
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:90
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:45
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:281
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
const char * GetData() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Definition Stream.h:352
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:400
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
size_t PutChar(char ch)
Definition Stream.cpp:131
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
Definition Stream.cpp:75
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition Stream.cpp:198
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:195
Defines a list of symbol context objects.
collection m_symbol_contexts
The list of symbol contexts.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
const_iterator end() const
bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function)
void Dump(Stream *s, Target *target) const
Dump a description of this object to a Stream.
uint32_t NumLineEntriesWithLine(uint32_t line) const
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
void Clear()
Clear the object's state.
SymbolContextList()
Default constructor.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
virtual Function * CalculateSymbolContextFunction()
virtual CompileUnit * CalculateSymbolContextCompileUnit()
virtual void CalculateSymbolContext(SymbolContext *sc)=0
Reconstruct the object's symbol context into sc.
virtual Block * CalculateSymbolContextBlock()
virtual lldb::ModuleSP CalculateSymbolContextModule()
void GetDescription(Stream *s, lldb::DescriptionLevel level) const
std::unique_ptr< AddressRange > m_address_range_up
std::unique_ptr< FileSpec > m_file_spec_up
bool AddLineSpecification(uint32_t line_no, SpecificationType type)
bool AddSpecification(const char *spec_string, SpecificationType type)
bool SymbolContextMatches(const SymbolContext &sc)
SymbolContextSpecifier(const lldb::TargetSP &target_sp)
Defines a symbol context baton that can be handed other debug core functions.
LineEntry GetFunctionStartLineEntry() const
Get the line entry that corresponds to the function.
const Symbol * FindBestGlobalDataSymbol(ConstString name, Status &error)
Find the best global data symbol visible from this context.
lldb::LanguageType GetLanguage() const
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
llvm::Error GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range)
Function * function
The Function for a given query.
Block * GetFunctionBlock()
Find a block that defines the function represented by this symbol context.
llvm::StringRef GetInstanceVariableName()
Determines the name of the instance variable for the this decl context.
bool GetParentOfInlinedScope(const Address &curr_frame_pc, SymbolContext &next_frame_sc, Address &inlined_frame_addr) const
Find the block containing the inlined block that contains this block.
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
void SortTypeList(TypeMap &type_map, TypeList &type_list) const
Sorts the types in TypeMap according to SymbolContext to TypeList.
Block * block
The Block for a given query.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, bool show_function_arguments, bool show_function_name, bool show_function_display_name=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump the stop context in this object to a Stream.
void Clear(bool clear_target)
Clear the object's state.
Variable * variable
The global variable matching the given query.
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
Symbol * symbol
The Symbol for a given query.
lldb::TargetSP target_sp
The Target for a given query.
LineEntry line_entry
The LineEntry for a given query.
Mangled GetPossiblyInlinedFunctionName() const
If available, will return the function name according to the specified mangling preference.
Address GetFunctionOrSymbolAddress() const
Get the address of the function or symbol represented by this symbol context.
SymbolContext()
Default constructor.
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
bool ValueIsAddress() const
Definition Symbol.cpp:165
Mangled & GetMangled()
Definition Symbol.h:147
Address & GetAddressRef()
Definition Symbol.h:73
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1014
uint32_t GetSize() const
Definition TypeList.cpp:60
void ForEach(std::function< bool(const lldb::TypeSP &type_sp)> const &callback) const
Definition TypeList.cpp:78
lldb::TypeSP GetTypeAtIndex(uint32_t idx)
Definition TypeList.cpp:66
void Insert(const lldb::TypeSP &type)
Definition TypeList.cpp:27
bool Empty() const
Definition TypeMap.cpp:77
bool Remove(const lldb::TypeSP &type_sp)
Definition TypeMap.cpp:116
void ForEach(std::function< bool(const lldb::TypeSP &type_sp)> const &callback) const
Definition TypeMap.cpp:100
void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name, ExecutionContextScope *exe_scope)
Definition Type.cpp:305
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
bool operator!=(const Address &lhs, const Address &rhs)
Definition Address.cpp:1017
bool operator==(const Address &lhs, const Address &rhs)
Definition Address.cpp:1011
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelFull
@ eDescriptionLevelVerbose
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::Type > TypeSP
@ eSymbolTypeUndefined
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeReExported
@ eSymbolTypeObjCClass
@ eSymbolTypeObjectFile
@ eSymbolTypeTrampoline
@ eSymbolTypeResolver
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeHeaderFile
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::Module > ModuleSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
A line table entry class.
Definition LineEntry.h:21
uint16_t column
The column number of the source line, or zero if there is no column information.
Definition LineEntry.h:151
lldb::SupportFileSP original_file_sp
The original source file, from debug info.
Definition LineEntry.h:143
bool IsValid() const
Check if a line entry object is valid.
Definition LineEntry.cpp:35
static int Compare(const LineEntry &lhs, const LineEntry &rhs)
Compare two LineEntry objects.
AddressRange range
The section offset address range for this line entry.
Definition LineEntry.h:137
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
Definition LineEntry.h:147
lldb::SupportFileSP file_sp
The source file, possibly mapped by the target.source-map setting.
Definition LineEntry.h:140
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition UserID.h:47
#define PATH_MAX