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 bool show_function_display_name,
77 std::optional<Stream::HighlightSettings> settings) const {
78 bool dumped_something = false;
79 if (show_module && module_sp) {
80 if (show_fullpaths)
81 *s << module_sp->GetFileSpec();
82 else
83 *s << module_sp->GetFileSpec().GetFilename();
84 s->PutChar('`');
85 dumped_something = true;
86 }
87 if (function != nullptr) {
88 SymbolContext inline_parent_sc;
89 Address inline_parent_addr;
90 if (!show_function_name) {
91 s->Printf("<");
92 dumped_something = true;
93 } else {
94 ConstString name;
95 if (!show_function_arguments)
97 if (!name && show_function_display_name)
98 name = function->GetDisplayName();
99 if (!name)
100 name = function->GetName();
101 if (name)
102 s->PutCStringColorHighlighted(name.GetStringRef(), settings);
103 }
104
105 if (addr_t file_addr = addr.GetFileAddress();
106 file_addr != LLDB_INVALID_ADDRESS) {
107 const addr_t function_offset =
108 file_addr - function->GetAddress().GetFileAddress();
109 if (!show_function_name) {
110 // Print +offset even if offset is 0
111 dumped_something = true;
112 s->Printf("+%" PRIu64 ">", function_offset);
113 } else if (function_offset) {
114 dumped_something = true;
115 s->Printf(" + %" PRIu64, function_offset);
116 }
117 }
118
119 if (GetParentOfInlinedScope(addr, inline_parent_sc, inline_parent_addr)) {
120 dumped_something = true;
121 Block *inlined_block = block->GetContainingInlinedBlock();
122 const InlineFunctionInfo *inlined_block_info =
123 inlined_block->GetInlinedFunctionInfo();
124 s->Printf(" [inlined] %s", inlined_block_info->GetName().GetCString());
125
126 lldb_private::AddressRange block_range;
127 if (inlined_block->GetRangeContainingAddress(addr, block_range)) {
128 const addr_t inlined_function_offset =
129 addr.GetFileAddress() -
130 block_range.GetBaseAddress().GetFileAddress();
131 if (inlined_function_offset) {
132 s->Printf(" + %" PRIu64, inlined_function_offset);
133 }
134 }
135 // "line_entry" will always be valid as GetParentOfInlinedScope(...) will
136 // fill it in correctly with the calling file and line. Previous code
137 // was extracting the calling file and line from inlined_block_info and
138 // using it right away which is not correct. On the first call to this
139 // function "line_entry" will contain the actual line table entry. On
140 // susequent calls "line_entry" will contain the calling file and line
141 // from the previous inline info.
142 if (line_entry.IsValid()) {
143 s->PutCString(" at ");
144 line_entry.DumpStopContext(s, show_fullpaths);
145 }
146
147 if (show_inlined_frames) {
148 s->EOL();
149 s->Indent();
150 const bool show_function_name = true;
151 return inline_parent_sc.DumpStopContext(
152 s, exe_scope, inline_parent_addr, show_fullpaths, show_module,
153 show_inlined_frames, show_function_arguments, show_function_name,
154 show_function_display_name);
155 }
156 } else {
157 if (line_entry.IsValid()) {
158 dumped_something = true;
159 s->PutCString(" at ");
160 if (line_entry.DumpStopContext(s, show_fullpaths))
161 dumped_something = true;
162 }
163 }
164 } else if (symbol != nullptr) {
165 if (!show_function_name) {
166 s->Printf("<");
167 dumped_something = true;
168 } else if (symbol->GetName()) {
169 dumped_something = true;
171 s->PutCString("symbol stub for: ");
172 ConstString name;
173 if (show_function_display_name)
174 name = symbol->GetDisplayName();
175 if (!name)
176 name = symbol->GetName();
177 s->PutCStringColorHighlighted(name.GetStringRef(), settings);
178 }
179
180 if (addr.IsValid() && symbol->ValueIsAddress()) {
181 const addr_t symbol_offset =
183 if (!show_function_name) {
184 // Print +offset even if offset is 0
185 dumped_something = true;
186 s->Printf("+%" PRIu64 ">", symbol_offset);
187 } else if (symbol_offset) {
188 dumped_something = true;
189 s->Printf(" + %" PRIu64, symbol_offset);
190 }
191 }
192 } else if (addr.IsValid()) {
194 dumped_something = true;
195 }
196 return dumped_something;
197}
198
200 Stream *s, lldb::DescriptionLevel level, Target *target,
201 std::optional<Stream::HighlightSettings> settings) const {
202 if (module_sp) {
203 s->Indent(" Module: file = \"");
204 module_sp->GetFileSpec().Dump(s->AsRawOstream());
205 *s << '"';
206 if (module_sp->GetArchitecture().IsValid())
207 s->Printf(", arch = \"%s\"",
208 module_sp->GetArchitecture().GetArchitectureName());
209 s->EOL();
210 }
211
212 if (comp_unit != nullptr) {
213 s->Indent("CompileUnit: ");
214 comp_unit->GetDescription(s, level);
215 s->EOL();
216 }
217
218 if (function != nullptr) {
219 s->Indent(" Function: ");
220 function->GetDescription(s, level, target);
221 s->EOL();
222
223 Type *func_type = function->GetType();
224 if (func_type) {
225 s->Indent(" FuncType: ");
226 func_type->GetDescription(s, level, false, target);
227 s->EOL();
228 }
229 }
230
231 if (block != nullptr) {
232 std::vector<Block *> blocks;
233 blocks.push_back(block);
234 Block *parent_block = block->GetParent();
235
236 while (parent_block) {
237 blocks.push_back(parent_block);
238 parent_block = parent_block->GetParent();
239 }
240 std::vector<Block *>::reverse_iterator pos;
241 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
242 std::vector<Block *>::reverse_iterator end = blocks.rend();
243 for (pos = begin; pos != end; ++pos) {
244 if (pos == begin)
245 s->Indent(" Blocks: ");
246 else
247 s->Indent(" ");
248 (*pos)->GetDescription(s, function, level, target);
249 s->EOL();
250 }
251 }
252
253 if (line_entry.IsValid()) {
254 s->Indent(" LineEntry: ");
255 line_entry.GetDescription(s, level, comp_unit, target, false);
256 s->EOL();
257 }
258
259 if (symbol != nullptr) {
260 s->Indent(" Symbol: ");
261 symbol->GetDescription(s, level, target, settings);
262 s->EOL();
263 }
264
265 if (variable != nullptr) {
266 s->Indent(" Variable: ");
267
268 s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID());
269
270 switch (variable->GetScope()) {
272 s->PutCString("kind = global, ");
273 break;
274
276 s->PutCString("kind = static, ");
277 break;
278
280 s->PutCString("kind = argument, ");
281 break;
282
284 s->PutCString("kind = local, ");
285 break;
286
288 s->PutCString("kind = thread local, ");
289 break;
290
291 default:
292 break;
293 }
294
295 s->Printf("name = \"%s\"\n", variable->GetName().GetCString());
296 }
297}
298
300 uint32_t resolved_mask = 0;
301 if (target_sp)
302 resolved_mask |= eSymbolContextTarget;
303 if (module_sp)
304 resolved_mask |= eSymbolContextModule;
305 if (comp_unit)
306 resolved_mask |= eSymbolContextCompUnit;
307 if (function)
308 resolved_mask |= eSymbolContextFunction;
309 if (block)
310 resolved_mask |= eSymbolContextBlock;
311 if (line_entry.IsValid())
312 resolved_mask |= eSymbolContextLineEntry;
313 if (symbol)
314 resolved_mask |= eSymbolContextSymbol;
315 if (variable)
316 resolved_mask |= eSymbolContextVariable;
317 return resolved_mask;
318}
319
321 const SymbolContext &rhs) {
322 return lhs.function == rhs.function && lhs.symbol == rhs.symbol &&
323 lhs.module_sp.get() == rhs.module_sp.get() &&
324 lhs.comp_unit == rhs.comp_unit &&
325 lhs.target_sp.get() == rhs.target_sp.get() &&
327 lhs.variable == rhs.variable;
328}
329
331 const SymbolContext &rhs) {
332 return !(lhs == rhs);
333}
334
335bool SymbolContext::GetAddressRange(uint32_t scope, uint32_t range_idx,
336 bool use_inline_block_range,
337 AddressRange &range) const {
338 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) {
339 range = line_entry.range;
340 return true;
341 }
342
343 if ((scope & eSymbolContextBlock) && (block != nullptr)) {
344 if (use_inline_block_range) {
345 Block *inline_block = block->GetContainingInlinedBlock();
346 if (inline_block)
347 return inline_block->GetRangeAtIndex(range_idx, range);
348 } else {
349 return block->GetRangeAtIndex(range_idx, range);
350 }
351 }
352
353 if ((scope & eSymbolContextFunction) && (function != nullptr)) {
354 if (range_idx == 0) {
355 range = function->GetAddressRange();
356 return true;
357 }
358 }
359
360 if ((scope & eSymbolContextSymbol) && (symbol != nullptr)) {
361 if (range_idx == 0) {
362 if (symbol->ValueIsAddress()) {
365 return true;
366 }
367 }
368 }
369 range.Clear();
370 return false;
371}
372
374 LanguageType lang;
375 if (function && (lang = function->GetLanguage()) != eLanguageTypeUnknown) {
376 return lang;
377 } else if (variable &&
379 return lang;
380 } else if (symbol && (lang = symbol->GetLanguage()) != eLanguageTypeUnknown) {
381 return lang;
382 } else if (comp_unit &&
384 return lang;
385 } else if (symbol) {
386 // If all else fails, try to guess the language from the name.
387 return symbol->GetMangled().GuessLanguage();
388 }
390}
391
393 SymbolContext &next_frame_sc,
394 Address &next_frame_pc) const {
395 next_frame_sc.Clear(false);
396 next_frame_pc.Clear();
397
398 if (block) {
399 // const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
400
401 // In order to get the parent of an inlined function we first need to see
402 // if we are in an inlined block as "this->block" could be an inlined
403 // block, or a parent of "block" could be. So lets check if this block or
404 // one of this blocks parents is an inlined function.
405 Block *curr_inlined_block = block->GetContainingInlinedBlock();
406 if (curr_inlined_block) {
407 // "this->block" is contained in an inline function block, so to get the
408 // scope above the inlined block, we get the parent of the inlined block
409 // itself
410 Block *next_frame_block = curr_inlined_block->GetParent();
411 // Now calculate the symbol context of the containing block
412 next_frame_block->CalculateSymbolContext(&next_frame_sc);
413
414 // If we get here we weren't able to find the return line entry using the
415 // nesting of the blocks and the line table. So just use the call site
416 // info from our inlined block.
417
418 AddressRange range;
419 if (curr_inlined_block->GetRangeContainingAddress(curr_frame_pc, range)) {
420 // To see there this new frame block it, we need to look at the call
421 // site information from
422 const InlineFunctionInfo *curr_inlined_block_inlined_info =
423 curr_inlined_block->GetInlinedFunctionInfo();
424 next_frame_pc = range.GetBaseAddress();
425 next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
426 next_frame_sc.line_entry.file_sp = std::make_shared<SupportFile>(
427 curr_inlined_block_inlined_info->GetCallSite().GetFile());
428 next_frame_sc.line_entry.original_file_sp =
429 std::make_shared<SupportFile>(
430 curr_inlined_block_inlined_info->GetCallSite().GetFile());
431 next_frame_sc.line_entry.line =
432 curr_inlined_block_inlined_info->GetCallSite().GetLine();
433 next_frame_sc.line_entry.column =
434 curr_inlined_block_inlined_info->GetCallSite().GetColumn();
435 return true;
436 } else {
438
439 if (log) {
440 LLDB_LOGF(
441 log,
442 "warning: inlined block 0x%8.8" PRIx64
443 " doesn't have a range that contains file address 0x%" PRIx64,
444 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
445 }
446#ifdef LLDB_CONFIGURATION_DEBUG
447 else {
448 ObjectFile *objfile = nullptr;
449 if (module_sp) {
450 if (SymbolFile *symbol_file = module_sp->GetSymbolFile())
451 objfile = symbol_file->GetObjectFile();
452 }
453 if (objfile) {
454 Debugger::ReportWarning(llvm::formatv(
455 "inlined block {0:x} doesn't have a range that contains file "
456 "address {1:x} in {2}",
457 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress(),
458 objfile->GetFileSpec().GetPath()));
459 } else {
460 Debugger::ReportWarning(llvm::formatv(
461 "inlined block {0:x} doesn't have a range that contains file "
462 "address {1:x}",
463 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()));
464 }
465 }
466#endif
467 }
468 }
469 }
470
471 return false;
472}
473
475 if (function) {
476 if (block) {
477 // If this symbol context has a block, check to see if this block is
478 // itself, or is contained within a block with inlined function
479 // information. If so, then the inlined block is the block that defines
480 // the function.
481 Block *inlined_block = block->GetContainingInlinedBlock();
482 if (inlined_block)
483 return inlined_block;
484
485 // The block in this symbol context is not inside an inlined block, so
486 // the block that defines the function is the function's top level block,
487 // which is returned below.
488 }
489
490 // There is no block information in this symbol context, so we must assume
491 // that the block that is desired is the top level block of the function
492 // itself.
493 return &function->GetBlock(true);
494 }
495 return nullptr;
496}
497
500
501 if (Block *function_block = GetFunctionBlock())
502 if (CompilerDeclContext decl_ctx = function_block->GetDeclContext())
503 lang_type = decl_ctx.GetLanguage();
504
505 if (lang_type == eLanguageTypeUnknown)
506 lang_type = GetLanguage();
507
508 if (auto *lang = Language::FindPlugin(lang_type))
509 return lang->GetInstanceVariableName();
510
511 return {};
512}
513
514void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const {
515 Block *curr_block = block;
516 bool isInlinedblock = false;
517 if (curr_block != nullptr &&
518 curr_block->GetContainingInlinedBlock() != nullptr)
519 isInlinedblock = true;
520
521 // Find all types that match the current block if we have one and put them
522 // first in the list. Keep iterating up through all blocks.
523 while (curr_block != nullptr && !isInlinedblock) {
524 type_map.ForEach(
525 [curr_block, &type_list](const lldb::TypeSP &type_sp) -> bool {
526 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
527 if (scs && curr_block == scs->CalculateSymbolContextBlock())
528 type_list.Insert(type_sp);
529 return true; // Keep iterating
530 });
531
532 // Remove any entries that are now in "type_list" from "type_map" since we
533 // can't remove from type_map while iterating
534 type_list.ForEach([&type_map](const lldb::TypeSP &type_sp) -> bool {
535 type_map.Remove(type_sp);
536 return true; // Keep iterating
537 });
538 curr_block = curr_block->GetParent();
539 }
540 // Find all types that match the current function, if we have onem, and put
541 // them next in the list.
542 if (function != nullptr && !type_map.Empty()) {
543 const size_t old_type_list_size = type_list.GetSize();
544 type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
545 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
546 if (scs && function == scs->CalculateSymbolContextFunction())
547 type_list.Insert(type_sp);
548 return true; // Keep iterating
549 });
550
551 // Remove any entries that are now in "type_list" from "type_map" since we
552 // can't remove from type_map while iterating
553 const size_t new_type_list_size = type_list.GetSize();
554 if (new_type_list_size > old_type_list_size) {
555 for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
556 type_map.Remove(type_list.GetTypeAtIndex(i));
557 }
558 }
559 // Find all types that match the current compile unit, if we have one, and
560 // put them next in the list.
561 if (comp_unit != nullptr && !type_map.Empty()) {
562 const size_t old_type_list_size = type_list.GetSize();
563
564 type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
565 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
566 if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit())
567 type_list.Insert(type_sp);
568 return true; // Keep iterating
569 });
570
571 // Remove any entries that are now in "type_list" from "type_map" since we
572 // can't remove from type_map while iterating
573 const size_t new_type_list_size = type_list.GetSize();
574 if (new_type_list_size > old_type_list_size) {
575 for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
576 type_map.Remove(type_list.GetTypeAtIndex(i));
577 }
578 }
579 // Find all types that match the current module, if we have one, and put them
580 // next in the list.
581 if (module_sp && !type_map.Empty()) {
582 const size_t old_type_list_size = type_list.GetSize();
583 type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool {
584 SymbolContextScope *scs = type_sp->GetSymbolContextScope();
585 if (scs && module_sp == scs->CalculateSymbolContextModule())
586 type_list.Insert(type_sp);
587 return true; // Keep iterating
588 });
589 // Remove any entries that are now in "type_list" from "type_map" since we
590 // can't remove from type_map while iterating
591 const size_t new_type_list_size = type_list.GetSize();
592 if (new_type_list_size > old_type_list_size) {
593 for (size_t i = old_type_list_size; i < new_type_list_size; ++i)
594 type_map.Remove(type_list.GetTypeAtIndex(i));
595 }
596 }
597 // Any types that are left get copied into the list an any order.
598 if (!type_map.Empty()) {
599 type_map.ForEach([&type_list](const lldb::TypeSP &type_sp) -> bool {
600 type_list.Insert(type_sp);
601 return true; // Keep iterating
602 });
603 }
604}
605
608 if (function) {
609 if (block) {
610 Block *inlined_block = block->GetContainingInlinedBlock();
611
612 if (inlined_block) {
613 const InlineFunctionInfo *inline_info =
614 inlined_block->GetInlinedFunctionInfo();
615 if (inline_info)
616 return inline_info->GetName();
617 }
618 }
619 return function->GetMangled().GetName(preference);
620 } else if (symbol && symbol->ValueIsAddress()) {
621 return symbol->GetMangled().GetName(preference);
622 } else {
623 // No function, return an empty string.
624 return ConstString();
625 }
626}
627
630 Address start_addr;
631 if (block) {
632 Block *inlined_block = block->GetContainingInlinedBlock();
633 if (inlined_block) {
634 if (inlined_block->GetStartAddress(start_addr)) {
636 return line_entry;
637 }
638 return LineEntry();
639 }
640 }
641
642 if (function) {
644 return line_entry;
645 }
646 return LineEntry();
647}
648
649llvm::Error
651 AddressRange &range) {
652 if (!line_entry.IsValid()) {
653 return llvm::createStringError("Symbol context has no line table.");
654 }
655
656 range = line_entry.range;
657 if (line_entry.line > end_line) {
658 return llvm::createStringError(
659 "end line option %d must be after the current line: %d", end_line,
661 }
662
663 uint32_t line_index = 0;
664 bool found = false;
665 while (true) {
666 LineEntry this_line;
667 line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr,
668 false, &this_line);
669 if (line_index == UINT32_MAX)
670 break;
671 if (LineEntry::Compare(this_line, line_entry) == 0) {
672 found = true;
673 break;
674 }
675 }
676
677 LineEntry end_entry;
678 if (!found) {
679 // Can't find the index of the SymbolContext's line entry in the
680 // SymbolContext's CompUnit.
681 return llvm::createStringError(
682 "Can't find the current line entry in the CompUnit - can't process "
683 "the end-line option");
684 }
685
686 line_index = comp_unit->FindLineEntry(line_index, end_line, nullptr, false,
687 &end_entry);
688 if (line_index == UINT32_MAX) {
689 return llvm::createStringError(
690 "could not find a line table entry corresponding "
691 "to end line number %d",
692 end_line);
693 }
694
695 Block *func_block = GetFunctionBlock();
696 if (func_block && func_block->GetRangeIndexContainingAddress(
697 end_entry.range.GetBaseAddress()) == UINT32_MAX) {
698 return llvm::createStringError(
699 "end line number %d is not contained within the current function.",
700 end_line);
701 }
702
703 lldb::addr_t range_size = end_entry.range.GetBaseAddress().GetFileAddress() -
705 range.SetByteSize(range_size);
706 return llvm::Error::success();
707}
708
710 Status &error) {
711 error.Clear();
712
713 if (!target_sp) {
714 return nullptr;
715 }
716
717 Target &target = *target_sp;
718 Module *module = module_sp.get();
719
720 auto ProcessMatches = [this, &name, &target,
721 module](const SymbolContextList &sc_list,
722 Status &error) -> const Symbol * {
723 llvm::SmallVector<const Symbol *, 1> external_symbols;
724 llvm::SmallVector<const Symbol *, 1> internal_symbols;
725 for (const SymbolContext &sym_ctx : sc_list) {
726 if (sym_ctx.symbol) {
727 const Symbol *symbol = sym_ctx.symbol;
728 const Address sym_address = symbol->GetAddress();
729
730 if (sym_address.IsValid()) {
731 switch (symbol->GetType()) {
732 case eSymbolTypeData:
739 // If the demangled name was synthesized, then don't use it for
740 // expressions. Only let the symbol match if the mangled named
741 // matches for these symbols.
742 if (symbol->GetMangled().GetMangledName() != name)
743 break;
744 }
745 if (symbol->IsExternal()) {
746 external_symbols.push_back(symbol);
747 } else {
748 internal_symbols.push_back(symbol);
749 }
750 break;
752 ConstString reexport_name = symbol->GetReExportedSymbolName();
753 if (reexport_name) {
754 ModuleSP reexport_module_sp;
755 ModuleSpec reexport_module_spec;
756 reexport_module_spec.GetPlatformFileSpec() =
758 if (reexport_module_spec.GetPlatformFileSpec()) {
759 reexport_module_sp =
760 target.GetImages().FindFirstModule(reexport_module_spec);
761 if (!reexport_module_sp) {
762 reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
763 reexport_module_sp =
764 target.GetImages().FindFirstModule(reexport_module_spec);
765 }
766 }
767 // Don't allow us to try and resolve a re-exported symbol if it
768 // is the same as the current symbol
769 if (name == symbol->GetReExportedSymbolName() &&
770 module == reexport_module_sp.get())
771 return nullptr;
772
774 error);
775 }
776 } break;
777
778 case eSymbolTypeCode: // We already lookup functions elsewhere
780 case eSymbolTypeLocal:
781 case eSymbolTypeParam:
789 case eSymbolTypeBlock:
800 break;
801 }
802 }
803 }
804 }
805
806 if (external_symbols.size() > 1) {
807 StreamString ss;
808 ss.Printf("Multiple external symbols found for '%s'\n", name.AsCString());
809 for (const Symbol *symbol : external_symbols) {
811 }
812 ss.PutChar('\n');
814 return nullptr;
815 } else if (external_symbols.size()) {
816 return external_symbols[0];
817 } else if (internal_symbols.size() > 1) {
818 StreamString ss;
819 ss.Printf("Multiple internal symbols found for '%s'\n", name.AsCString());
820 for (const Symbol *symbol : internal_symbols) {
822 ss.PutChar('\n');
823 }
825 return nullptr;
826 } else if (internal_symbols.size()) {
827 return internal_symbols[0];
828 } else {
829 return nullptr;
830 }
831 };
832
833 if (module) {
834 SymbolContextList sc_list;
835 module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
836 const Symbol *const module_symbol = ProcessMatches(sc_list, error);
837
838 if (!error.Success()) {
839 return nullptr;
840 } else if (module_symbol) {
841 return module_symbol;
842 }
843 }
844
845 {
846 SymbolContextList sc_list;
848 sc_list);
849 const Symbol *const target_symbol = ProcessMatches(sc_list, error);
850
851 if (!error.Success()) {
852 return nullptr;
853 } else if (target_symbol) {
854 return target_symbol;
855 }
856 }
857
858 return nullptr; // no error; we just didn't find anything
859}
860
861//
862// SymbolContextSpecifier
863//
864
866 : m_target_sp(target_sp), m_module_spec(), m_module_sp(), m_file_spec_up(),
867 m_start_line(0), m_end_line(0), m_function_spec(), m_class_name(),
868 m_address_range_up(), m_type(eNothingSpecified) {}
869
871
873 SpecificationType type) {
874 bool return_value = true;
875 switch (type) {
877 Clear();
878 break;
880 m_start_line = line_no;
882 break;
884 m_end_line = line_no;
886 break;
887 default:
888 return_value = false;
889 break;
890 }
891 return return_value;
892}
893
894bool SymbolContextSpecifier::AddSpecification(const char *spec_string,
895 SpecificationType type) {
896 bool return_value = true;
897 switch (type) {
899 Clear();
900 break;
901 case eModuleSpecified: {
902 // See if we can find the Module, if so stick it in the SymbolContext.
903 FileSpec module_file_spec(spec_string);
904 ModuleSpec module_spec(module_file_spec);
905 lldb::ModuleSP module_sp =
906 m_target_sp ? m_target_sp->GetImages().FindFirstModule(module_spec)
907 : nullptr;
909 if (module_sp)
910 m_module_sp = module_sp;
911 else
912 m_module_spec.assign(spec_string);
913 } break;
914 case eFileSpecified:
915 // CompUnits can't necessarily be resolved here, since an inlined function
916 // might show up in a number of CompUnits. Instead we just convert to a
917 // FileSpec and store it away.
918 m_file_spec_up = std::make_unique<FileSpec>(spec_string);
920 break;
922 if ((return_value = llvm::to_integer(spec_string, m_start_line)))
924 break;
926 if ((return_value = llvm::to_integer(spec_string, m_end_line)))
928 break;
930 m_function_spec.assign(spec_string);
932 break;
934 Clear();
935 m_class_name.assign(spec_string);
937 break;
939 // Not specified yet...
940 break;
941 }
942
943 return return_value;
944}
945
947 m_module_spec.clear();
948 m_file_spec_up.reset();
949 m_function_spec.clear();
950 m_class_name.clear();
951 m_start_line = 0;
952 m_end_line = 0;
953 m_address_range_up.reset();
954
956}
957
960 return true;
961
962 // Only compare targets if this specifier has one and it's not the Dummy
963 // target. Otherwise if a specifier gets made in the dummy target and
964 // copied over we'll artificially fail the comparision.
965 if (m_target_sp && !m_target_sp->IsDummyTarget() &&
967 return false;
968
969 if (m_type & eModuleSpecified) {
970 if (sc.module_sp) {
971 if (m_module_sp.get() != nullptr) {
972 if (m_module_sp.get() != sc.module_sp.get())
973 return false;
974 } else {
975 FileSpec module_file_spec(m_module_spec);
976 if (!FileSpec::Match(module_file_spec, sc.module_sp->GetFileSpec()))
977 return false;
978 }
979 }
980 }
981 if (m_type & eFileSpecified) {
982 if (m_file_spec_up) {
983 // If we don't have a block or a comp_unit, then we aren't going to match
984 // a source file.
985 if (sc.block == nullptr && sc.comp_unit == nullptr)
986 return false;
987
988 // Check if the block is present, and if so is it inlined:
989 bool was_inlined = false;
990 if (sc.block != nullptr) {
991 const InlineFunctionInfo *inline_info =
993 if (inline_info != nullptr) {
994 was_inlined = true;
996 inline_info->GetDeclaration().GetFile()))
997 return false;
998 }
999 }
1000
1001 // Next check the comp unit, but only if the SymbolContext was not
1002 // inlined.
1003 if (!was_inlined && sc.comp_unit != nullptr) {
1005 return false;
1006 }
1007 }
1008 }
1011 return false;
1012 }
1013
1014 if (m_type & eFunctionSpecified) {
1015 // First check the current block, and if it is inlined, get the inlined
1016 // function name:
1017 bool was_inlined = false;
1018 ConstString func_name(m_function_spec.c_str());
1019
1020 if (sc.block != nullptr) {
1021 const InlineFunctionInfo *inline_info =
1023 if (inline_info != nullptr) {
1024 was_inlined = true;
1025 const Mangled &name = inline_info->GetMangled();
1026 if (!name.NameMatches(func_name))
1027 return false;
1028 }
1029 }
1030 // If it wasn't inlined, check the name in the function or symbol:
1031 if (!was_inlined) {
1032 if (sc.function != nullptr) {
1033 if (!sc.function->GetMangled().NameMatches(func_name))
1034 return false;
1035 } else if (sc.symbol != nullptr) {
1036 if (!sc.symbol->GetMangled().NameMatches(func_name))
1037 return false;
1038 }
1039 }
1040 }
1041
1042 return true;
1043}
1044
1047
1048 } else {
1049 Address match_address(addr, nullptr);
1050 SymbolContext sc;
1051 m_target_sp->GetImages().ResolveSymbolContextForAddress(
1052 match_address, eSymbolContextEverything, sc);
1053 return SymbolContextMatches(sc);
1054 }
1055 return true;
1056}
1057
1059 Stream *s, lldb::DescriptionLevel level) const {
1060 char path_str[PATH_MAX + 1];
1061
1062 if (m_type == eNothingSpecified) {
1063 s->Printf("Nothing specified.\n");
1064 }
1065
1066 if (m_type == eModuleSpecified) {
1067 s->Indent();
1068 if (m_module_sp) {
1069 m_module_sp->GetFileSpec().GetPath(path_str, PATH_MAX);
1070 s->Printf("Module: %s\n", path_str);
1071 } else
1072 s->Printf("Module: %s\n", m_module_spec.c_str());
1073 }
1074
1075 if (m_type == eFileSpecified && m_file_spec_up != nullptr) {
1076 m_file_spec_up->GetPath(path_str, PATH_MAX);
1077 s->Indent();
1078 s->Printf("File: %s", path_str);
1079 if (m_type == eLineStartSpecified) {
1080 s->Printf(" from line %" PRIu64 "", (uint64_t)m_start_line);
1082 s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
1083 else
1084 s->Printf("to end");
1085 } else if (m_type == eLineEndSpecified) {
1086 s->Printf(" from start to line %" PRIu64 "", (uint64_t)m_end_line);
1087 }
1088 s->Printf(".\n");
1089 }
1090
1091 if (m_type == eLineStartSpecified) {
1092 s->Indent();
1093 s->Printf("From line %" PRIu64 "", (uint64_t)m_start_line);
1095 s->Printf("to line %" PRIu64 "", (uint64_t)m_end_line);
1096 else
1097 s->Printf("to end");
1098 s->Printf(".\n");
1099 } else if (m_type == eLineEndSpecified) {
1100 s->Printf("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line);
1101 }
1102
1103 if (m_type == eFunctionSpecified) {
1104 s->Indent();
1105 s->Printf("Function: %s.\n", m_function_spec.c_str());
1106 }
1107
1109 s->Indent();
1110 s->Printf("Class name: %s.\n", m_class_name.c_str());
1111 }
1112
1113 if (m_type == eAddressRangeSpecified && m_address_range_up != nullptr) {
1114 s->Indent();
1115 s->PutCString("Address range: ");
1116 m_address_range_up->Dump(s, m_target_sp.get(),
1119 s->PutCString("\n");
1120 }
1121}
1122
1123//
1124// SymbolContextList
1125//
1126
1128
1130
1132 m_symbol_contexts.push_back(sc);
1133}
1134
1136 collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1137 for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
1138 m_symbol_contexts.push_back(*pos);
1139}
1140
1142 bool merge_symbol_into_function) {
1143 uint32_t unique_sc_add_count = 0;
1144 collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
1145 for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) {
1146 if (AppendIfUnique(*pos, merge_symbol_into_function))
1147 ++unique_sc_add_count;
1148 }
1149 return unique_sc_add_count;
1150}
1151
1153 bool merge_symbol_into_function) {
1154 collection::iterator pos, end = m_symbol_contexts.end();
1155 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1156 if (*pos == sc)
1157 return false;
1158 }
1159 if (merge_symbol_into_function && sc.symbol != nullptr &&
1160 sc.comp_unit == nullptr && sc.function == nullptr &&
1161 sc.block == nullptr && !sc.line_entry.IsValid()) {
1162 if (sc.symbol->ValueIsAddress()) {
1163 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1164 // Don't merge symbols into inlined function symbol contexts
1165 if (pos->block && pos->block->GetContainingInlinedBlock())
1166 continue;
1167
1168 if (pos->function) {
1169 if (pos->function->GetAddress() == sc.symbol->GetAddressRef()) {
1170 // Do we already have a function with this symbol?
1171 if (pos->symbol == sc.symbol)
1172 return false;
1173 if (pos->symbol == nullptr) {
1174 pos->symbol = sc.symbol;
1175 return false;
1176 }
1177 }
1178 }
1179 }
1180 }
1181 }
1182 m_symbol_contexts.push_back(sc);
1183 return true;
1184}
1185
1187
1188void SymbolContextList::Dump(Stream *s, Target *target) const {
1189
1190 *s << this << ": ";
1191 s->Indent();
1192 s->PutCString("SymbolContextList");
1193 s->EOL();
1194 s->IndentMore();
1195
1196 collection::const_iterator pos, end = m_symbol_contexts.end();
1197 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) {
1198 // pos->Dump(s, target);
1199 pos->GetDescription(s, eDescriptionLevelVerbose, target);
1200 }
1201 s->IndentLess();
1202}
1203
1205 if (idx < m_symbol_contexts.size()) {
1206 sc = m_symbol_contexts[idx];
1207 return true;
1208 }
1209 return false;
1210}
1211
1213 if (idx < m_symbol_contexts.size()) {
1214 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1215 return true;
1216 }
1217 return false;
1218}
1219
1220uint32_t SymbolContextList::GetSize() const { return m_symbol_contexts.size(); }
1221
1222bool SymbolContextList::IsEmpty() const { return m_symbol_contexts.empty(); }
1223
1224uint32_t SymbolContextList::NumLineEntriesWithLine(uint32_t line) const {
1225 uint32_t match_count = 0;
1226 const size_t size = m_symbol_contexts.size();
1227 for (size_t idx = 0; idx < size; ++idx) {
1228 if (m_symbol_contexts[idx].line_entry.line == line)
1229 ++match_count;
1230 }
1231 return match_count;
1232}
1233
1235 Target *target) const {
1236 const size_t size = m_symbol_contexts.size();
1237 for (size_t idx = 0; idx < size; ++idx)
1238 m_symbol_contexts[idx].GetDescription(s, level, target);
1239}
1240
1242 const SymbolContextList &rhs) {
1243 const uint32_t size = lhs.GetSize();
1244 if (size != rhs.GetSize())
1245 return false;
1246
1247 SymbolContext lhs_sc;
1248 SymbolContext rhs_sc;
1249 for (uint32_t i = 0; i < size; ++i) {
1250 lhs.GetContextAtIndex(i, lhs_sc);
1251 rhs.GetContextAtIndex(i, rhs_sc);
1252 if (lhs_sc != rhs_sc)
1253 return false;
1254 }
1255 return true;
1256}
1257
1259 const SymbolContextList &rhs) {
1260 return !(lhs == rhs);
1261}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition: Log.h:376
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:211
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:239
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:407
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:292
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:137
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
Definition: Block.cpp:200
bool GetRangeAtIndex(uint32_t range_idx, AddressRange &range)
Definition: Block.cpp:296
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Definition: Block.h:266
bool GetRangeContainingAddress(const Address &addr, AddressRange &range)
Definition: Block.cpp:242
Block * GetParent() const
Get the parent block.
Definition: Block.cpp:196
bool GetStartAddress(Address &addr)
Definition: Block.cpp:326
uint32_t GetRangeIndexContainingAddress(const Address &addr)
Definition: Block.cpp:279
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.
Definition: CompileUnit.h:232
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:216
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:1622
uint32_t GetLine() const
Get accessor for the declaration line number.
Definition: Declaration.h:124
uint16_t GetColumn() const
Get accessor for the declaration column number.
Definition: Declaration.h:131
FileSpec & GetFile()
Get accessor for file specification.
Definition: Declaration.h:111
"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
const Address & GetAddress() const
Return the address of the function (its entry point).
Definition: Function.h:455
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target)
Definition: Function.cpp:415
const AddressRange & GetAddressRange()
DEPRECATED: Use GetAddressRanges instead.
Definition: Function.h:448
ConstString GetName() const
Definition: Function.cpp:719
const Mangled & GetMangled() const
Definition: Function.h:542
Type * GetType()
Get accessor for the type that describes the function return value type, and parameter types.
Definition: Function.cpp:566
lldb::LanguageType GetLanguage() const
Definition: Function.cpp:708
ConstString GetDisplayName() const
Definition: Function.cpp:548
ConstString GetNameNoArguments() const
Definition: Function.cpp:723
Block & GetBlock(bool can_create)
Get accessor for the block list.
Definition: Function.cpp:396
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:84
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:393
ConstString & GetMangledName()
Mangled name get accessor.
Definition: Mangled.h:145
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition: Mangled.cpp:337
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:89
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list)
Definition: Module.cpp:1307
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:275
An error handling class.
Definition: Status.h:118
static Status FromErrorString(const char *str)
Definition: Status.h:141
const char * GetData() const
Definition: StreamString.h:45
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
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
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.
uint32_t GetResolvedMask() const
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.
SymbolContext()
Default constructor.
Provides public interface for all SymbolFiles.
Definition: SymbolFile.h:50
bool ValueIsAddress() const
Definition: Symbol.cpp:165
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:173
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Definition: Symbol.cpp:225
lldb::addr_t GetByteSize() const
Definition: Symbol.cpp:468
ConstString GetName() const
Definition: Symbol.cpp:548
lldb::SymbolType GetType() const
Definition: Symbol.h:168
Address GetAddress() const
Definition: Symbol.h:88
FileSpec GetReExportedSymbolSharedLibrary() const
Definition: Symbol.cpp:187
ConstString GetDisplayName() const
Definition: Symbol.cpp:169
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:997
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:304
ConstString GetName() const
Definition: Variable.cpp:73
lldb::LanguageType GetLanguage() const
Definition: Variable.cpp:56
lldb::ValueType GetScope() const
Definition: Variable.h:66
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:82
#define UINT32_MAX
Definition: lldb-defines.h:19
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: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:462
@ 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:80
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:449
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:374
@ 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
void Clear()
Clear the object's state.
Definition: LineEntry.cpp:22
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.
Definition: LineEntry.cpp:147
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
bool GetDescription(Stream *s, lldb::DescriptionLevel level, CompileUnit *cu, Target *target, bool show_address_only) const
Definition: LineEntry.cpp:95
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:39
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