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