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