LLDB mainline
StackFrame.cpp
Go to the documentation of this file.
1//===-- StackFrame.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#include "lldb/Core/Debugger.h"
13#include "lldb/Core/Mangled.h"
14#include "lldb/Core/Module.h"
15#include "lldb/Core/Value.h"
18#include "lldb/Symbol/Symbol.h"
21#include "lldb/Symbol/Type.h"
23#include "lldb/Target/ABI.h"
26#include "lldb/Target/Process.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Target/Thread.h"
32#include "lldb/Utility/Log.h"
40
42
43#include <memory>
44
45using namespace lldb;
46using namespace lldb_private;
47
48// LLVM RTTI support.
50
51// The first bits in the flags are reserved for the SymbolContext::Scope bits
52// so we know if we have tried to look up information in our internal symbol
53// context (m_sc) already.
54#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextLastItem) << 1)
55#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
56#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
57#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
58#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
59
60StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
61 user_id_t unwind_frame_index, addr_t cfa,
62 bool cfa_is_valid, addr_t pc, StackFrame::Kind kind,
63 bool artificial, bool behaves_like_zeroth_frame,
64 const SymbolContext *sc_ptr)
65 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
66 m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
67 m_id(pc, cfa, nullptr, thread_sp->GetProcess().get()),
69 m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
70 m_stack_frame_kind(kind), m_artificial(artificial),
71 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
74 // If we don't have a CFA value, use the frame index for our StackID so that
75 // recursive functions properly aren't confused with one another on a history
76 // stack.
77 if (IsHistorical() && !m_cfa_is_valid) {
78 m_id.SetCFA(m_frame_index, thread_sp->GetProcess().get());
79 }
80
81 if (sc_ptr != nullptr) {
82 m_sc = *sc_ptr;
83 m_flags.Set(m_sc.GetResolvedMask());
84 }
85}
86
87StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
88 user_id_t unwind_frame_index,
89 const RegisterContextSP &reg_context_sp, addr_t cfa,
90 addr_t pc, bool behaves_like_zeroth_frame,
91 const SymbolContext *sc_ptr)
92 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
93 m_concrete_frame_index(unwind_frame_index),
94 m_reg_context_sp(reg_context_sp),
95 m_id(pc, cfa, nullptr, thread_sp->GetProcess().get()),
99 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
102 if (sc_ptr != nullptr) {
103 m_sc = *sc_ptr;
104 m_flags.Set(m_sc.GetResolvedMask());
105 }
106
107 if (reg_context_sp && !m_sc.target_sp) {
108 m_sc.target_sp = reg_context_sp->CalculateTarget();
109 if (m_sc.target_sp)
110 m_flags.Set(eSymbolContextTarget);
111 }
112}
113
114StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx,
115 user_id_t unwind_frame_index,
116 const RegisterContextSP &reg_context_sp, addr_t cfa,
117 const Address &pc_addr, bool behaves_like_zeroth_frame,
118 const SymbolContext *sc_ptr)
119 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
120 m_concrete_frame_index(unwind_frame_index),
121 m_reg_context_sp(reg_context_sp),
122 m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
123 nullptr, thread_sp->GetProcess().get()),
124 m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
127 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
130 if (sc_ptr != nullptr) {
131 m_sc = *sc_ptr;
132 m_flags.Set(m_sc.GetResolvedMask());
133 }
134
135 if (!m_sc.target_sp && reg_context_sp) {
136 m_sc.target_sp = reg_context_sp->CalculateTarget();
137 if (m_sc.target_sp)
138 m_flags.Set(eSymbolContextTarget);
139 }
140
141 ModuleSP pc_module_sp(pc_addr.GetModule());
142 if (!m_sc.module_sp || m_sc.module_sp != pc_module_sp) {
143 if (pc_module_sp) {
144 m_sc.module_sp = pc_module_sp;
145 m_flags.Set(eSymbolContextModule);
146 } else {
147 m_sc.module_sp.reset();
148 }
149 }
150}
151
152StackFrame::~StackFrame() = default;
153
155 std::lock_guard<std::recursive_mutex> guard(m_mutex);
156 // Make sure we have resolved the StackID object's symbol context scope if we
157 // already haven't looked it up.
158
160 if (m_id.GetSymbolContextScope()) {
161 // We already have a symbol context scope, we just don't have our flag
162 // bit set.
164 } else {
165 // Calculate the frame block and use this for the stack ID symbol context
166 // scope if we have one.
168 if (scope == nullptr) {
169 // We don't have a block, so use the symbol
170 if (m_flags.IsClear(eSymbolContextSymbol))
171 GetSymbolContext(eSymbolContextSymbol);
172
173 // It is ok if m_sc.symbol is nullptr here
174 scope = m_sc.symbol;
175 }
176 // Set the symbol context scope (the accessor will set the
177 // RESOLVED_FRAME_ID_SYMBOL_SCOPE bit in m_flags).
179 }
180 }
181 return m_id;
182}
183
185 ThreadSP thread_sp = GetThread();
186 if (thread_sp)
187 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
189 else
190 return m_frame_index;
191}
192
194 std::lock_guard<std::recursive_mutex> guard(m_mutex);
196 m_id.SetSymbolContextScope(symbol_scope);
197}
198
200 std::lock_guard<std::recursive_mutex> guard(m_mutex);
201 if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) &&
202 !m_frame_code_addr.IsSectionOffset()) {
204
205 // Resolve the PC into a temporary address because if ResolveLoadAddress
206 // fails to resolve the address, it will clear the address object...
207 ThreadSP thread_sp(GetThread());
208 if (thread_sp) {
209 TargetSP target_sp(thread_sp->CalculateTarget());
210 if (target_sp) {
211 const bool allow_section_end = true;
212 if (m_frame_code_addr.SetOpcodeLoadAddress(
213 m_frame_code_addr.GetOffset(), target_sp.get(),
214 AddressClass::eCode, allow_section_end)) {
215 ModuleSP module_sp(m_frame_code_addr.GetModule());
216 if (module_sp) {
217 m_sc.module_sp = module_sp;
218 m_flags.Set(eSymbolContextModule);
219 }
220 }
221 }
222 }
223 }
224 return m_frame_code_addr;
225}
226
227// This can't be rewritten into a call to
228// RegisterContext::GetPCForSymbolication because this
229// StackFrame may have been constructed with a special pc,
230// e.g. tail-call artificial frames.
232 Address lookup_addr(GetFrameCodeAddress());
233 if (!lookup_addr.IsValid())
234 return lookup_addr;
236 return lookup_addr;
237
238 addr_t offset = lookup_addr.GetOffset();
239 if (offset > 0) {
240 lookup_addr.Slide(-1);
241 } else {
242 // lookup_addr is the start of a section. We need do the math on the
243 // actual load address and re-compute the section. We're working with
244 // a 'noreturn' function at the end of a section.
245 TargetSP target_sp = CalculateTarget();
246 if (target_sp) {
247 addr_t addr_minus_one = lookup_addr.GetOpcodeLoadAddress(
248 target_sp.get(), AddressClass::eCode) -
249 1;
250 lookup_addr.SetOpcodeLoadAddress(addr_minus_one, target_sp.get());
251 }
252 }
253 return lookup_addr;
254}
255
257 std::lock_guard<std::recursive_mutex> guard(m_mutex);
258 // We can't change the pc value of a history stack frame - it is immutable.
259 if (IsHistorical())
260 return false;
261 m_frame_code_addr.SetRawAddress(pc);
262 m_sc.Clear(false);
263 m_flags.Reset(0);
264 ThreadSP thread_sp(GetThread());
265 if (thread_sp)
266 thread_sp->ClearStackFrames();
267 return true;
268}
269
271 std::lock_guard<std::recursive_mutex> guard(m_mutex);
272
273 if (!m_disassembly.Empty())
274 return m_disassembly.GetData();
275
276 ExecutionContext exe_ctx(shared_from_this());
277 if (Target *target = exe_ctx.GetTargetPtr()) {
278 Disassembler::Disassemble(target->GetDebugger(), target->GetArchitecture(),
279 *this, m_disassembly);
280 }
281
282 return m_disassembly.Empty() ? nullptr : m_disassembly.GetData();
283}
284
286 if (m_sc.block == nullptr && m_flags.IsClear(eSymbolContextBlock))
287 GetSymbolContext(eSymbolContextBlock);
288
289 if (m_sc.block) {
290 Block *inline_block = m_sc.block->GetContainingInlinedBlock();
291 if (inline_block) {
292 // Use the block with the inlined function info as the frame block we
293 // want this frame to have only the variables for the inlined function
294 // and its non-inlined block child blocks.
295 return inline_block;
296 } else {
297 // This block is not contained within any inlined function blocks with so
298 // we want to use the top most function block.
299 return &m_sc.function->GetBlock(false);
300 }
301 }
302 return nullptr;
303}
304
306 Block *frame_block = GetFrameBlock();
307 Block *addr_block = addr.CalculateSymbolContextBlock();
308 if (!frame_block || !addr_block)
309 return false;
310 // Do they represent the same concrete function?
311 if (addr_block->CalculateSymbolContextFunction() !=
312 frame_block->CalculateSymbolContextFunction())
313 return false;
314
315 // Do they represent the same inlined function?
316 return addr_block->GetContainingInlinedBlock() ==
317 frame_block->GetContainingInlinedBlock();
318}
319
320// Get the symbol context if we already haven't done so by resolving the
321// PC address as much as possible. This way when we pass around a
322// StackFrame object, everyone will have as much information as possible and no
323// one will ever have to look things up manually.
324const SymbolContext &
325StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
326 std::lock_guard<std::recursive_mutex> guard(m_mutex);
327 // Copy our internal symbol context into "sc".
328 if ((m_flags.Get() & resolve_scope) != resolve_scope) {
329 uint32_t resolved = 0;
330
331 // If the target was requested add that:
332 if (!m_sc.target_sp) {
333 m_sc.target_sp = CalculateTarget();
334 if (m_sc.target_sp)
335 resolved |= eSymbolContextTarget;
336 }
337
338 // Resolve our PC to section offset if we haven't already done so and if we
339 // don't have a module. The resolved address section will contain the
340 // module to which it belongs
341 if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR))
343
344 // If this is not frame zero, then we need to subtract 1 from the PC value
345 // when doing address lookups since the PC will be on the instruction
346 // following the function call instruction...
348
349 // For PC-less frames (e.g., scripted frames), skip PC-based symbol
350 // resolution and preserve any already-populated SymbolContext fields.
351 if (!lookup_addr.IsValid()) {
352 m_flags.Set(resolve_scope | resolved);
353 return m_sc;
354 }
355
356 if (m_sc.module_sp) {
357 // We have something in our stack frame symbol context, lets check if we
358 // haven't already tried to lookup one of those things. If we haven't
359 // then we will do the query.
360
361 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
362
363 if (resolve_scope & eSymbolContextCompUnit) {
364 if (m_flags.IsClear(eSymbolContextCompUnit)) {
365 if (m_sc.comp_unit)
366 resolved |= eSymbolContextCompUnit;
367 else
368 actual_resolve_scope |= eSymbolContextCompUnit;
369 }
370 }
371
372 if (resolve_scope & eSymbolContextFunction) {
373 if (m_flags.IsClear(eSymbolContextFunction)) {
374 if (m_sc.function)
375 resolved |= eSymbolContextFunction;
376 else
377 actual_resolve_scope |= eSymbolContextFunction;
378 }
379 }
380
381 if (resolve_scope & eSymbolContextBlock) {
382 if (m_flags.IsClear(eSymbolContextBlock)) {
383 if (m_sc.block)
384 resolved |= eSymbolContextBlock;
385 else
386 actual_resolve_scope |= eSymbolContextBlock;
387 }
388 }
389
390 if (resolve_scope & eSymbolContextSymbol) {
391 if (m_flags.IsClear(eSymbolContextSymbol)) {
392 if (m_sc.symbol)
393 resolved |= eSymbolContextSymbol;
394 else
395 actual_resolve_scope |= eSymbolContextSymbol;
396 }
397 }
398
399 if (resolve_scope & eSymbolContextLineEntry) {
400 if (m_flags.IsClear(eSymbolContextLineEntry)) {
401 if (m_sc.line_entry.IsValid())
402 resolved |= eSymbolContextLineEntry;
403 else
404 actual_resolve_scope |= eSymbolContextLineEntry;
405 }
406 }
407
408 if (actual_resolve_scope) {
409 // We might be resolving less information than what is already in our
410 // current symbol context so resolve into a temporary symbol context
411 // "sc" so we don't clear out data we have already found in "m_sc"
412 SymbolContext sc;
413 // Set flags that indicate what we have tried to resolve
414 resolved |= m_sc.module_sp->ResolveSymbolContextForAddress(
415 lookup_addr, actual_resolve_scope, sc);
416 // Only replace what we didn't already have as we may have information
417 // for an inlined function scope that won't match what a standard
418 // lookup by address would match
419 if ((resolved & eSymbolContextCompUnit) && m_sc.comp_unit == nullptr)
420 m_sc.comp_unit = sc.comp_unit;
421 if ((resolved & eSymbolContextFunction) && m_sc.function == nullptr)
422 m_sc.function = sc.function;
423 if ((resolved & eSymbolContextBlock) && m_sc.block == nullptr)
424 m_sc.block = sc.block;
425 if ((resolved & eSymbolContextSymbol) && m_sc.symbol == nullptr)
426 m_sc.symbol = sc.symbol;
427 if ((resolved & eSymbolContextLineEntry) &&
428 !m_sc.line_entry.IsValid()) {
429 m_sc.line_entry = sc.line_entry;
430 m_sc.line_entry.ApplyFileMappings(m_sc.target_sp);
431 }
432 }
433 } else {
434 // If we don't have a module, then we can't have the compile unit,
435 // function, block, line entry or symbol, so we can safely call
436 // ResolveSymbolContextForAddress with our symbol context member m_sc.
437 if (m_sc.target_sp) {
438 resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
439 lookup_addr, resolve_scope, m_sc);
440 }
441 }
442
443 // Update our internal flags so we remember what we have tried to locate so
444 // we don't have to keep trying when more calls to this function are made.
445 // We might have dug up more information that was requested (for example if
446 // we were asked to only get the block, we will have gotten the compile
447 // unit, and function) so set any additional bits that we resolved
448 m_flags.Set(resolve_scope | resolved);
449 }
450
451 // Return the symbol context with everything that was possible to resolve
452 // resolved.
453 return m_sc;
454}
455
457 bool include_synthetic_vars,
458 Status *error_ptr) {
459 // We don't have 'synthetic variables' in the base stack frame.
460 (void)include_synthetic_vars;
461
462 std::lock_guard<std::recursive_mutex> guard(m_mutex);
463 if (m_flags.IsClear(RESOLVED_VARIABLES)) {
465 m_variable_list_sp = std::make_shared<VariableList>();
466
467 Block *frame_block = GetFrameBlock();
468
469 if (frame_block) {
470 const bool get_child_variables = true;
471 const bool can_create = true;
472 const bool stop_if_child_block_is_inlined_function = true;
473 frame_block->AppendBlockVariables(
474 can_create, get_child_variables,
475 stop_if_child_block_is_inlined_function,
476 [](Variable *v) { return true; }, m_variable_list_sp.get());
477 }
478 }
479
480 if (m_flags.IsClear(RESOLVED_GLOBAL_VARIABLES) && get_file_globals) {
482
483 if (m_flags.IsClear(eSymbolContextCompUnit))
484 GetSymbolContext(eSymbolContextCompUnit);
485
486 if (m_sc.comp_unit) {
487 VariableListSP global_variable_list_sp(
488 m_sc.comp_unit->GetVariableList(true));
490 m_variable_list_sp->AddVariables(global_variable_list_sp.get());
491 else
492 m_variable_list_sp = global_variable_list_sp;
493 }
494 }
495
496 if (error_ptr && m_variable_list_sp->GetSize() == 0) {
497 // Check with the symbol file to check if there is an error for why we
498 // don't have variables that the user might need to know about.
499 GetSymbolContext(eSymbolContextEverything);
500 if (m_sc.module_sp) {
501 SymbolFile *sym_file = m_sc.module_sp->GetSymbolFile();
502 if (sym_file)
503 *error_ptr = sym_file->GetFrameVariableError(*this);
504 }
505 }
506
507 return m_variable_list_sp.get();
508}
509
512 bool include_synthetic_vars,
513 bool must_have_valid_location) {
514 // We don't have synthetic variables in the base stack frame.
515 (void)include_synthetic_vars;
516
517 std::lock_guard<std::recursive_mutex> guard(m_mutex);
518 // We can't fetch variable information for a history stack frame.
519 if (IsHistorical())
520 return VariableListSP();
521
522 VariableListSP var_list_sp(new VariableList);
523 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextBlock);
524
525 if (m_sc.block) {
526 const bool can_create = true;
527 const bool get_parent_variables = true;
528 const bool stop_if_block_is_inlined_function = true;
529 m_sc.block->AppendVariables(
530 can_create, get_parent_variables, stop_if_block_is_inlined_function,
531 [this, must_have_valid_location](Variable *v) {
532 return v->IsInScope(this) && (!must_have_valid_location ||
533 v->LocationIsValidForFrame(this));
534 },
535 var_list_sp.get());
536 }
537
538 if (m_sc.comp_unit && get_file_globals) {
539 VariableListSP global_variable_list_sp(
540 m_sc.comp_unit->GetVariableList(true));
541 if (global_variable_list_sp)
542 var_list_sp->AddVariables(global_variable_list_sp.get());
543 }
544
545 return var_list_sp;
546}
547
549 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
550 VariableSP &var_sp, Status &error, lldb::DILMode mode) {
551 ExecutionContext exe_ctx;
553 bool use_DIL = exe_ctx.GetTargetRef().GetUseDIL(&exe_ctx);
554 if (use_DIL)
555 return DILGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
556 var_sp, error, mode);
557
558 return LegacyGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
559 var_sp, error);
560}
561
563 llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
564 uint32_t options, lldb::VariableSP &var_sp, Status &error,
565 lldb::DILMode mode) {
566
567 // Lex the expression.
568 auto lex_or_err = dil::DILLexer::Create(var_expr, mode);
569 if (!lex_or_err) {
570 error = Status::FromError(lex_or_err.takeError());
571 return ValueObjectConstResult::Create(nullptr, error.Clone());
572 }
573
574 // Parse the expression.
575 ExecutionContext exe_ctx;
577 auto tree_or_error = dil::DILParser::Parse(
578 exe_ctx, var_expr, std::move(*lex_or_err), use_dynamic, mode);
579 if (!tree_or_error) {
580 error = Status::FromError(tree_or_error.takeError());
581 return ValueObjectConstResult::Create(nullptr, error.Clone());
582 }
583
584 // Evaluate the parsed expression.
585 dil::Interpreter interpreter(exe_ctx, var_expr, use_dynamic, options);
586
587 auto valobj_or_error = interpreter.EvaluateTree(*tree_or_error);
588 if (!valobj_or_error) {
589 error = Status::FromError(valobj_or_error.takeError());
590 return ValueObjectConstResult::Create(nullptr, error.Clone());
591 }
592
593 var_sp = (*valobj_or_error)->GetVariable();
594 return *valobj_or_error;
595}
596
598 llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
599 VariableSP &var_sp, Status &error) {
600 llvm::StringRef original_var_expr = var_expr;
601 // We can't fetch variable information for a history stack frame.
602 if (IsHistorical())
603 return ValueObjectSP();
604
605 if (var_expr.empty()) {
606 error = Status::FromErrorStringWithFormatv("invalid variable path '{0}'",
607 var_expr);
608 return ValueObjectSP();
609 }
610
611 const bool check_ptr_vs_member =
613 const bool no_synth_child =
615 error.Clear();
616 bool deref = false;
617 bool address_of = false;
618 ValueObjectSP valobj_sp;
619 const bool get_file_globals = true;
620 // When looking up a variable for an expression, we need only consider the
621 // variables that are in scope.
622 VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
623 VariableList *variable_list = var_list_sp.get();
624
625 if (!variable_list)
626 return ValueObjectSP();
627
628 // If first character is a '*', then show pointer contents
629 std::string var_expr_storage;
630 if (var_expr[0] == '*') {
631 deref = true;
632 var_expr = var_expr.drop_front(); // Skip the '*'
633 } else if (var_expr[0] == '&') {
634 address_of = true;
635 var_expr = var_expr.drop_front(); // Skip the '&'
636 }
637
638 size_t separator_idx = var_expr.find_first_of(".-[=+~|&^%#@!/?,<>{}");
639 StreamString var_expr_path_strm;
640
641 ConstString name_const_string(var_expr.substr(0, separator_idx));
642
643 var_sp = variable_list->FindVariable(name_const_string, false);
644
645 bool synthetically_added_instance_object = false;
646
647 if (var_sp) {
648 var_expr = var_expr.drop_front(name_const_string.GetLength());
649 }
650
651 if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
652 // Check for direct ivars access which helps us with implicit access to
653 // ivars using "this" or "self".
654 GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
655 llvm::StringRef instance_name = m_sc.GetInstanceName();
656 if (!instance_name.empty()) {
657 var_sp = variable_list->FindVariable(ConstString(instance_name));
658 if (var_sp) {
659 separator_idx = 0;
660 if (Type *var_type = var_sp->GetType())
661 if (auto compiler_type = var_type->GetForwardCompilerType())
662 if (!compiler_type.IsPointerType())
663 var_expr_storage = ".";
664
665 if (var_expr_storage.empty())
666 var_expr_storage = "->";
667 var_expr_storage += var_expr;
668 var_expr = var_expr_storage;
669 synthetically_added_instance_object = true;
670 }
671 }
672 }
673
674 if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
675 // Check if any anonymous unions are there which contain a variable with
676 // the name we need
677 for (const VariableSP &variable_sp : *variable_list) {
678 if (!variable_sp)
679 continue;
680 if (!variable_sp->GetName().IsEmpty())
681 continue;
682
683 Type *var_type = variable_sp->GetType();
684 if (!var_type)
685 continue;
686
687 if (!var_type->GetForwardCompilerType().IsAnonymousType())
688 continue;
689 valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
690 if (!valobj_sp)
691 return valobj_sp;
692 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
693 if (valobj_sp)
694 break;
695 }
696 }
697
698 if (var_sp && !valobj_sp) {
699 valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
700 if (!valobj_sp)
701 return valobj_sp;
702 }
703 if (!valobj_sp) {
705 "no variable named '{0}' found in this frame", name_const_string);
706 return ValueObjectSP();
707 }
708
709 // We are dumping at least one child
710 while (!var_expr.empty()) {
711 // Calculate the next separator index ahead of time
712 ValueObjectSP child_valobj_sp;
713 const char separator_type = var_expr[0];
714 bool expr_is_ptr = false;
715 switch (separator_type) {
716 case '-':
717 expr_is_ptr = true;
718 // A '-' only continues the path as the first character of "->"; a
719 // trailing '-' with no operand, or any other next character, is
720 // malformed.
721 if (var_expr.size() < 2 || var_expr[1] != '>')
722 return ValueObjectSP();
723
724 // If we have a non-pointer type with a synthetic value then lets check if
725 // we have a synthetic dereference specified.
726 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
727 Status deref_error;
728 if (ValueObjectSP synth_deref_sp =
729 valobj_sp->GetSyntheticValue()->Dereference(deref_error);
730 synth_deref_sp && deref_error.Success()) {
731 valobj_sp = std::move(synth_deref_sp);
732 }
733 if (!valobj_sp || deref_error.Fail()) {
735 "Failed to dereference synthetic value: {0}", deref_error);
736 return ValueObjectSP();
737 }
738
739 // Some synthetic plug-ins fail to set the error in Dereference
740 if (!valobj_sp) {
741 error =
742 Status::FromErrorString("Failed to dereference synthetic value");
743 return ValueObjectSP();
744 }
745 expr_is_ptr = false;
746 }
747
748 var_expr = var_expr.drop_front(); // Remove the '-'
749 [[fallthrough]];
750 case '.': {
751 var_expr = var_expr.drop_front(); // Remove the '.' or '>'
752 separator_idx = var_expr.find_first_of(".-[");
753 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
754
755 if (check_ptr_vs_member) {
756 // We either have a pointer type and need to verify valobj_sp is a
757 // pointer, or we have a member of a class/union/struct being accessed
758 // with the . syntax and need to verify we don't have a pointer.
759 const bool actual_is_ptr = valobj_sp->IsPointerType();
760
761 if (actual_is_ptr != expr_is_ptr) {
762 // Incorrect use of "." with a pointer, or "->" with a
763 // class/union/struct instance or reference.
764 valobj_sp->GetExpressionPath(var_expr_path_strm);
765 if (actual_is_ptr)
767 "\"%s\" is a pointer and . was used to attempt to access "
768 "\"%s\". Did you mean \"%s->%s\"?",
769 var_expr_path_strm.GetData(), child_name.GetCString(),
770 var_expr_path_strm.GetData(), var_expr.str().c_str());
771 else
773 "\"%s\" is not a pointer and -> was used to attempt to "
774 "access \"%s\". Did you mean \"%s.%s\"?",
775 var_expr_path_strm.GetData(), child_name.GetCString(),
776 var_expr_path_strm.GetData(), var_expr.str().c_str());
777 return ValueObjectSP();
778 }
779 }
780 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
781 if (!child_valobj_sp) {
782 if (!no_synth_child) {
783 child_valobj_sp = valobj_sp->GetSyntheticValue();
784 if (child_valobj_sp)
785 child_valobj_sp =
786 child_valobj_sp->GetChildMemberWithName(child_name);
787 }
788
789 if (no_synth_child || !child_valobj_sp) {
790 // No child member with name "child_name"
791 if (synthetically_added_instance_object) {
792 // We added a "this->" or "self->" to the beginning of the
793 // expression and this is the first pointer ivar access, so just
794 // return the normal error
796 "no variable or instance variable named '%s' found in "
797 "this frame",
798 name_const_string.GetCString());
799 } else {
800 valobj_sp->GetExpressionPath(var_expr_path_strm);
801 if (child_name) {
803 "\"%s\" is not a member of \"(%s) %s\"",
804 child_name.GetCString(),
805 valobj_sp->GetTypeName().AsCString("<invalid type>"),
806 var_expr_path_strm.GetData());
807 } else {
809 "incomplete expression path after \"%s\" in \"%s\"",
810 var_expr_path_strm.GetData(),
811 original_var_expr.str().c_str());
812 }
813 }
814 return ValueObjectSP();
815 }
816 }
817 synthetically_added_instance_object = false;
818 // Remove the child name from the path
819 var_expr = var_expr.drop_front(child_name.GetLength());
820 if (use_dynamic != eNoDynamicValues) {
821 ValueObjectSP dynamic_value_sp(
822 child_valobj_sp->GetDynamicValue(use_dynamic));
823 if (dynamic_value_sp)
824 child_valobj_sp = dynamic_value_sp;
825 }
826 } break;
827
828 case '[': {
829 // Array member access, or treating pointer as an array Need at least two
830 // brackets and a number
831 if (var_expr.size() <= 2) {
833 "invalid square bracket encountered after \"%s\" in \"%s\"",
834 var_expr_path_strm.GetData(), var_expr.str().c_str());
835 return ValueObjectSP();
836 }
837
838 // Drop the open brace.
839 var_expr = var_expr.drop_front();
840 long child_index = 0;
841
842 // If there's no closing brace, this is an invalid expression.
843 size_t end_pos = var_expr.find_first_of(']');
844 if (end_pos == llvm::StringRef::npos) {
846 "missing closing square bracket in expression \"%s\"",
847 var_expr_path_strm.GetData());
848 return ValueObjectSP();
849 }
850 llvm::StringRef index_expr = var_expr.take_front(end_pos);
851 llvm::StringRef original_index_expr = index_expr;
852 // Drop all of "[index_expr]"
853 var_expr = var_expr.drop_front(end_pos + 1);
854
855 if (index_expr.consumeInteger(0, child_index)) {
856 // If there was no integer anywhere in the index expression, this is
857 // erroneous expression.
859 "invalid index expression \"%s\"", index_expr.str().c_str());
860 return ValueObjectSP();
861 }
862
863 if (index_expr.empty()) {
864 // The entire index expression was a single integer.
865
866 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
867 // what we have is *ptr[low]. the most similar C++ syntax is to deref
868 // ptr and extract bit low out of it. reading array item low would be
869 // done by saying ptr[low], without a deref * sign
870 Status deref_error;
871 ValueObjectSP temp(valobj_sp->Dereference(deref_error));
872 if (!temp || deref_error.Fail()) {
873 valobj_sp->GetExpressionPath(var_expr_path_strm);
875 "could not dereference \"(%s) %s\"",
876 valobj_sp->GetTypeName().AsCString("<invalid type>"),
877 var_expr_path_strm.GetData());
878 return ValueObjectSP();
879 }
880 valobj_sp = temp;
881 deref = false;
882 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
883 deref) {
884 // what we have is *arr[low]. the most similar C++ syntax is to get
885 // arr[0] (an operation that is equivalent to deref-ing arr) and
886 // extract bit low out of it. reading array item low would be done by
887 // saying arr[low], without a deref * sign
888 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0));
889 if (!temp) {
890 valobj_sp->GetExpressionPath(var_expr_path_strm);
892 "could not get item 0 for \"(%s) %s\"",
893 valobj_sp->GetTypeName().AsCString("<invalid type>"),
894 var_expr_path_strm.GetData());
895 return ValueObjectSP();
896 }
897 valobj_sp = temp;
898 deref = false;
899 }
900
901 bool is_incomplete_array = false;
902 if (valobj_sp->IsPointerType()) {
903 bool is_objc_pointer = true;
904
905 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
907 is_objc_pointer = false;
908 else if (!valobj_sp->GetCompilerType().IsPointerType())
909 is_objc_pointer = false;
910
911 if (no_synth_child && is_objc_pointer) {
913 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
914 "subscripted",
915 valobj_sp->GetTypeName().AsCString("<invalid type>"),
916 var_expr_path_strm.GetData());
917
918 return ValueObjectSP();
919 } else if (is_objc_pointer) {
920 // dereferencing ObjC variables is not valid.. so let's try and
921 // recur to synthetic children
922 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
923 if (!synthetic /* no synthetic */
924 || synthetic == valobj_sp) /* synthetic is the same as
925 the original object */
926 {
927 valobj_sp->GetExpressionPath(var_expr_path_strm);
929 "\"(%s) %s\" is not an array type",
930 valobj_sp->GetTypeName().AsCString("<invalid type>"),
931 var_expr_path_strm.GetData());
932 } else if (static_cast<uint32_t>(child_index) >=
933 synthetic
934 ->GetNumChildrenIgnoringErrors() /* synthetic does
935 not have that
936 many values */) {
937 valobj_sp->GetExpressionPath(var_expr_path_strm);
939 "array index %ld is not valid for \"(%s) %s\"", child_index,
940 valobj_sp->GetTypeName().AsCString("<invalid type>"),
941 var_expr_path_strm.GetData());
942 } else {
943 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
944 if (!child_valobj_sp) {
945 valobj_sp->GetExpressionPath(var_expr_path_strm);
947 "array index %ld is not valid for \"(%s) %s\"", child_index,
948 valobj_sp->GetTypeName().AsCString("<invalid type>"),
949 var_expr_path_strm.GetData());
950 }
951 }
952 } else {
953 child_valobj_sp =
954 valobj_sp->GetSyntheticArrayMember(child_index, true);
955 if (!child_valobj_sp) {
956 valobj_sp->GetExpressionPath(var_expr_path_strm);
958 "failed to use pointer as array for index %ld for "
959 "\"(%s) %s\"",
960 child_index,
961 valobj_sp->GetTypeName().AsCString("<invalid type>"),
962 var_expr_path_strm.GetData());
963 }
964 }
965 } else if (valobj_sp->GetCompilerType().IsArrayType(
966 nullptr, nullptr, &is_incomplete_array)) {
967 // Pass false to dynamic_value here so we can tell the difference
968 // between no dynamic value and no member of this type...
969 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
970 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
971 child_valobj_sp =
972 valobj_sp->GetSyntheticArrayMember(child_index, true);
973
974 if (!child_valobj_sp) {
975 valobj_sp->GetExpressionPath(var_expr_path_strm);
977 "array index %ld is not valid for \"(%s) %s\"", child_index,
978 valobj_sp->GetTypeName().AsCString("<invalid type>"),
979 var_expr_path_strm.GetData());
980 }
981 } else if (valobj_sp->GetCompilerType().IsScalarType()) {
982 // this is a bitfield asking to display just one bit
983 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
984 child_index, child_index, true);
985 if (!child_valobj_sp) {
986 valobj_sp->GetExpressionPath(var_expr_path_strm);
988 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
989 child_index, child_index,
990 valobj_sp->GetTypeName().AsCString("<invalid type>"),
991 var_expr_path_strm.GetData());
992 }
993 } else {
994 ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
995 if (no_synth_child /* synthetic is forbidden */ ||
996 !synthetic /* no synthetic */
997 || synthetic == valobj_sp) /* synthetic is the same as the
998 original object */
999 {
1000 valobj_sp->GetExpressionPath(var_expr_path_strm);
1002 "\"(%s) %s\" is not an array type",
1003 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1004 var_expr_path_strm.GetData());
1005 } else if (static_cast<uint32_t>(child_index) >=
1006 synthetic->GetNumChildrenIgnoringErrors() /* synthetic
1007 does not have that many values */) {
1008 valobj_sp->GetExpressionPath(var_expr_path_strm);
1010 "array index %ld is not valid for \"(%s) %s\"", child_index,
1011 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1012 var_expr_path_strm.GetData());
1013 } else {
1014 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
1015 if (!child_valobj_sp) {
1016 valobj_sp->GetExpressionPath(var_expr_path_strm);
1018 "array index %ld is not valid for \"(%s) %s\"", child_index,
1019 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1020 var_expr_path_strm.GetData());
1021 }
1022 }
1023 }
1024
1025 if (!child_valobj_sp) {
1026 // Invalid array index...
1027 return ValueObjectSP();
1028 }
1029
1030 if (use_dynamic != eNoDynamicValues) {
1031 ValueObjectSP dynamic_value_sp(
1032 child_valobj_sp->GetDynamicValue(use_dynamic));
1033 if (dynamic_value_sp)
1034 child_valobj_sp = dynamic_value_sp;
1035 }
1036 // Break out early from the switch since we were able to find the child
1037 // member
1038 break;
1039 }
1040
1041 // this is most probably a BitField, let's take a look
1042 if (index_expr.front() != '-') {
1044 "invalid range expression \"'%s'\"",
1045 original_index_expr.str().c_str());
1046 return ValueObjectSP();
1047 }
1048
1049 index_expr = index_expr.drop_front();
1050 long final_index = 0;
1051 if (index_expr.getAsInteger(0, final_index)) {
1053 "invalid range expression \"'%s'\"",
1054 original_index_expr.str().c_str());
1055 return ValueObjectSP();
1056 }
1057
1058 // if the format given is [high-low], swap range
1059 if (child_index > final_index) {
1060 long temp = child_index;
1061 child_index = final_index;
1062 final_index = temp;
1063 }
1064
1065 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
1066 // what we have is *ptr[low-high]. the most similar C++ syntax is to
1067 // deref ptr and extract bits low thru high out of it. reading array
1068 // items low thru high would be done by saying ptr[low-high], without a
1069 // deref * sign
1070 Status deref_error;
1071 ValueObjectSP temp(valobj_sp->Dereference(deref_error));
1072 if (!temp || deref_error.Fail()) {
1073 valobj_sp->GetExpressionPath(var_expr_path_strm);
1075 "could not dereference \"(%s) %s\"",
1076 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1077 var_expr_path_strm.GetData());
1078 return ValueObjectSP();
1079 }
1080 valobj_sp = temp;
1081 deref = false;
1082 } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1083 // what we have is *arr[low-high]. the most similar C++ syntax is to
1084 // get arr[0] (an operation that is equivalent to deref-ing arr) and
1085 // extract bits low thru high out of it. reading array items low thru
1086 // high would be done by saying arr[low-high], without a deref * sign
1087 ValueObjectSP temp(valobj_sp->GetChildAtIndex(0));
1088 if (!temp) {
1089 valobj_sp->GetExpressionPath(var_expr_path_strm);
1091 "could not get item 0 for \"(%s) %s\"",
1092 valobj_sp->GetTypeName().AsCString("<invalid type>"),
1093 var_expr_path_strm.GetData());
1094 return ValueObjectSP();
1095 }
1096 valobj_sp = temp;
1097 deref = false;
1098 }
1099
1100 child_valobj_sp =
1101 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
1102 if (!child_valobj_sp) {
1103 valobj_sp->GetExpressionPath(var_expr_path_strm);
1105 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1106 final_index, valobj_sp->GetTypeName().AsCString("<invalid type>"),
1107 var_expr_path_strm.GetData());
1108 }
1109
1110 if (!child_valobj_sp) {
1111 // Invalid bitfield range...
1112 return ValueObjectSP();
1113 }
1114
1115 if (use_dynamic != eNoDynamicValues) {
1116 ValueObjectSP dynamic_value_sp(
1117 child_valobj_sp->GetDynamicValue(use_dynamic));
1118 if (dynamic_value_sp)
1119 child_valobj_sp = dynamic_value_sp;
1120 }
1121 // Break out early from the switch since we were able to find the child
1122 // member
1123 break;
1124 }
1125 default:
1126 // Failure...
1127 {
1128 valobj_sp->GetExpressionPath(var_expr_path_strm);
1130 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1131 separator_type, var_expr_path_strm.GetData(),
1132 var_expr.str().c_str());
1133
1134 return ValueObjectSP();
1135 }
1136 }
1137
1138 if (child_valobj_sp)
1139 valobj_sp = child_valobj_sp;
1140 }
1141 if (valobj_sp) {
1142 if (deref) {
1143 ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
1144 if (!deref_valobj_sp && !no_synth_child) {
1145 if (ValueObjectSP synth_obj_sp = valobj_sp->GetSyntheticValue()) {
1146 error.Clear();
1147 deref_valobj_sp = synth_obj_sp->Dereference(error);
1148 }
1149 }
1150 valobj_sp = deref_valobj_sp;
1151 } else if (address_of) {
1152 ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
1153 valobj_sp = address_of_valobj_sp;
1154 }
1155 }
1156 return valobj_sp;
1157}
1158
1159llvm::Error StackFrame::GetFrameBaseValue(Scalar &frame_base) {
1160 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1161 if (!m_cfa_is_valid) {
1163 "No frame base available for this historical stack frame.");
1164 return m_frame_base_error.ToError();
1165 }
1166
1167 if (m_flags.IsClear(GOT_FRAME_BASE)) {
1168 if (m_sc.function) {
1169 m_frame_base.Clear();
1170 m_frame_base_error.Clear();
1171
1173 ExecutionContext exe_ctx(shared_from_this());
1174 addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
1175 if (!m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
1176 loclist_base_addr =
1177 m_sc.function->GetAddress().GetLoadAddress(exe_ctx.GetTargetPtr());
1178
1179 llvm::Expected<Value> expr_value =
1180 m_sc.function->GetFrameBaseExpression().Evaluate(
1181 &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr);
1182 if (!expr_value)
1183 m_frame_base_error = Status::FromError(expr_value.takeError());
1184 else
1185 m_frame_base = expr_value->GetScalar();
1186 } else {
1188 Status::FromErrorString("No function in symbol context.");
1189 }
1190 }
1191
1192 if (m_frame_base_error.Fail())
1193 return m_frame_base_error.ToError();
1194
1195 frame_base = m_frame_base;
1196 return llvm::Error::success();
1197}
1198
1200 if (!m_sc.function) {
1201 if (error_ptr) {
1202 *error_ptr = Status::FromErrorString("No function in symbol context.");
1203 }
1204 return nullptr;
1205 }
1206
1207 return &m_sc.function->GetFrameBaseExpression();
1208}
1209
1211 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1212 if (!m_reg_context_sp) {
1213 ThreadSP thread_sp(GetThread());
1214 if (thread_sp)
1215 m_reg_context_sp = thread_sp->CreateRegisterContextForFrame(this);
1216 }
1217 return m_reg_context_sp;
1218}
1219
1221 GetSymbolContext(eSymbolContextLineEntry);
1222 return m_sc.line_entry.IsValid();
1223}
1224
1227 DynamicValueType use_dynamic) {
1228 ValueObjectSP valobj_sp;
1229 { // Scope for stack frame mutex. We need to drop this mutex before we figure
1230 // out the dynamic value. That will require converting the StackID in the
1231 // VO back to a StackFrame, which will in turn require locking the
1232 // StackFrameList. If we still hold the StackFrame mutex, we could suffer
1233 // lock inversion against the pattern of getting the StackFrameList and
1234 // then the stack frame, which is fairly common.
1235 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1236 if (IsHistorical()) {
1237 return valobj_sp;
1238 }
1239 VariableList *var_list = GetVariableList(
1240 /*get_file_globals=*/true, /*include_synthetic_vars=*/true, nullptr);
1241 if (var_list) {
1242 // Make sure the variable is a frame variable
1243 const uint32_t var_idx =
1244 var_list->FindIndexForVariable(variable_sp.get());
1245 const uint32_t num_variables = var_list->GetSize();
1246 if (var_idx < num_variables) {
1247 valobj_sp =
1248 m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
1249 if (!valobj_sp) {
1250 if (m_variable_list_value_objects.GetSize() < num_variables)
1251 m_variable_list_value_objects.Resize(num_variables);
1252 valobj_sp = ValueObjectVariable::Create(this, variable_sp);
1253 m_variable_list_value_objects.SetValueObjectAtIndex(var_idx,
1254 valobj_sp);
1255 }
1256 }
1257 }
1258 } // End of StackFrame mutex scope.
1259 if (use_dynamic != eNoDynamicValues && valobj_sp) {
1260 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1261 if (dynamic_sp)
1262 return dynamic_sp;
1263 }
1264 return valobj_sp;
1265}
1266
1268 if (m_sc.block == nullptr)
1269 GetSymbolContext(eSymbolContextBlock);
1270 if (m_sc.block)
1271 return m_sc.block->GetContainingInlinedBlock() != nullptr;
1272 return false;
1273}
1274
1278
1282
1284
1286 if (auto recognized_frame_sp = GetRecognizedFrame())
1287 return recognized_frame_sp->ShouldHide();
1288 return false;
1289}
1290
1292 auto process_sp = CalculateProcess();
1293 SourceLanguage language = GetLanguage();
1294 if (!language)
1295 return {};
1296 if (auto runtime_sp =
1297 process_sp->GetLanguageRuntime(language.AsLanguageType()))
1298 return runtime_sp->GetLanguageSpecificData(
1299 GetSymbolContext(eSymbolContextFunction));
1300 return {};
1301}
1302
1304 const char *name = nullptr;
1306 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1307 if (sc.block) {
1308 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1309 if (inlined_block) {
1310 const InlineFunctionInfo *inlined_info =
1311 inlined_block->GetInlinedFunctionInfo();
1312 if (inlined_info)
1313 name = inlined_info->GetName().AsCString(nullptr);
1314 }
1315 }
1316
1317 if (name == nullptr) {
1318 if (sc.function)
1319 name = sc.function->GetName().GetCString();
1320 }
1321
1322 if (name == nullptr) {
1323 if (sc.symbol)
1324 name = sc.symbol->GetName().GetCString();
1325 }
1326
1327 return name;
1328}
1329
1331 const char *name = nullptr;
1333 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1334 if (sc.block) {
1335 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1336 if (inlined_block) {
1337 const InlineFunctionInfo *inlined_info =
1338 inlined_block->GetInlinedFunctionInfo();
1339 if (inlined_info)
1340 name = inlined_info->GetDisplayName().AsCString(nullptr);
1341 }
1342 }
1343
1344 if (name == nullptr) {
1345 if (sc.function)
1346 name = sc.function->GetDisplayName().GetCString();
1347 }
1348
1349 if (name == nullptr) {
1350 if (sc.symbol)
1351 name = sc.symbol->GetDisplayName().GetCString();
1352 }
1353 return name;
1354}
1355
1357 CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
1358 if (cu)
1359 return SourceLanguage{cu->GetLanguage()};
1360 return {};
1361}
1362
1364 SourceLanguage lang_type = GetLanguage();
1365
1366 if (!lang_type) {
1367 SymbolContext sc =
1368 GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol);
1369 if (sc.function)
1370 lang_type = SourceLanguage(sc.function->GetMangled().GuessLanguage());
1371 else if (sc.symbol)
1372 lang_type = SourceLanguage(sc.symbol->GetMangled().GuessLanguage());
1373 }
1374
1375 return lang_type;
1376}
1377
1378namespace {
1379std::pair<const Instruction::Operand *, int64_t>
1380GetBaseExplainingValue(const Instruction::Operand &operand,
1381 RegisterContext &register_context, lldb::addr_t value) {
1382 switch (operand.m_type) {
1387 // These are not currently interesting
1388 return std::make_pair(nullptr, 0);
1390 const Instruction::Operand *immediate_child = nullptr;
1391 const Instruction::Operand *variable_child = nullptr;
1392 if (operand.m_children[0].m_type == Instruction::Operand::Type::Immediate) {
1393 immediate_child = &operand.m_children[0];
1394 variable_child = &operand.m_children[1];
1395 } else if (operand.m_children[1].m_type ==
1397 immediate_child = &operand.m_children[1];
1398 variable_child = &operand.m_children[0];
1399 }
1400 if (!immediate_child) {
1401 return std::make_pair(nullptr, 0);
1402 }
1403 lldb::addr_t adjusted_value = value;
1404 if (immediate_child->m_negative) {
1405 adjusted_value += immediate_child->m_immediate;
1406 } else {
1407 adjusted_value -= immediate_child->m_immediate;
1408 }
1409 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1410 GetBaseExplainingValue(*variable_child, register_context,
1411 adjusted_value);
1412 if (!base_and_offset.first) {
1413 return std::make_pair(nullptr, 0);
1414 }
1415 if (immediate_child->m_negative) {
1416 base_and_offset.second -= immediate_child->m_immediate;
1417 } else {
1418 base_and_offset.second += immediate_child->m_immediate;
1419 }
1420 return base_and_offset;
1421 }
1423 const RegisterInfo *info =
1424 register_context.GetRegisterInfoByName(operand.m_register);
1425 if (!info) {
1426 return std::make_pair(nullptr, 0);
1427 }
1428 RegisterValue reg_value;
1429 if (!register_context.ReadRegister(info, reg_value)) {
1430 return std::make_pair(nullptr, 0);
1431 }
1432 if (reg_value.GetAsUInt64() == value) {
1433 return std::make_pair(&operand, 0);
1434 } else {
1435 return std::make_pair(nullptr, 0);
1436 }
1437 }
1438 }
1439 return std::make_pair(nullptr, 0);
1440}
1441
1442std::pair<const Instruction::Operand *, int64_t>
1443GetBaseExplainingDereference(const Instruction::Operand &operand,
1444 RegisterContext &register_context,
1445 lldb::addr_t addr) {
1447 return GetBaseExplainingValue(operand.m_children[0], register_context,
1448 addr);
1449 }
1450 return std::make_pair(nullptr, 0);
1451}
1452} // namespace
1453
1455 TargetSP target_sp = CalculateTarget();
1456
1457 const ArchSpec &target_arch = target_sp->GetArchitecture();
1458
1459 AddressRange pc_range;
1460 pc_range.GetBaseAddress() = GetFrameCodeAddress();
1461 pc_range.SetByteSize(target_arch.GetMaximumOpcodeByteSize());
1462
1463 const char *plugin_name = nullptr;
1464 const char *flavor = nullptr;
1465 const char *cpu = nullptr;
1466 const char *features = nullptr;
1467 const bool force_live_memory = true;
1468
1470 target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
1471 force_live_memory);
1472
1473 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1474 return ValueObjectSP();
1475 }
1476
1477 InstructionSP instruction_sp =
1478 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1479
1480 llvm::SmallVector<Instruction::Operand, 3> operands;
1481
1482 if (!instruction_sp->ParseOperands(operands)) {
1483 return ValueObjectSP();
1484 }
1485
1486 RegisterContextSP register_context_sp = GetRegisterContext();
1487
1488 if (!register_context_sp) {
1489 return ValueObjectSP();
1490 }
1491
1492 for (const Instruction::Operand &operand : operands) {
1493 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1494 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1495
1496 if (!base_and_offset.first) {
1497 continue;
1498 }
1499
1500 switch (base_and_offset.first->m_type) {
1503 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1504 base_and_offset.second,
1505 addr)) {
1506 auto c_type_system_or_err =
1507 target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
1508 if (auto err = c_type_system_or_err.takeError()) {
1509 LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(err),
1510 "Unable to guess value for given address: {0}");
1511 return ValueObjectSP();
1512 } else {
1513 auto ts = *c_type_system_or_err;
1514 if (!ts)
1515 return {};
1516 CompilerType void_ptr_type =
1518 .GetPointerType();
1519 return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
1520 }
1521 } else {
1522 return ValueObjectSP();
1523 }
1524 break;
1525 }
1527 return GuessValueForRegisterAndOffset(base_and_offset.first->m_register,
1528 base_and_offset.second);
1529 }
1530 default:
1531 return ValueObjectSP();
1532 }
1533 }
1534
1535 return ValueObjectSP();
1536}
1537
1538namespace {
1539ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent,
1540 int64_t offset) {
1541 if (offset < 0 ||
1542 uint64_t(offset) >=
1543 llvm::expectedToOptional(parent->GetByteSize()).value_or(0)) {
1544 return ValueObjectSP();
1545 }
1546
1547 if (parent->IsPointerOrReferenceType()) {
1548 return parent;
1549 }
1550
1551 for (int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1552 ++ci) {
1553 ValueObjectSP child_sp = parent->GetChildAtIndex(ci);
1554
1555 if (!child_sp) {
1556 return ValueObjectSP();
1557 }
1558
1559 int64_t child_offset = child_sp->GetByteOffset();
1560 int64_t child_size =
1561 llvm::expectedToOptional(child_sp->GetByteSize()).value_or(0);
1562
1563 if (offset >= child_offset && offset < (child_offset + child_size)) {
1564 return GetValueForOffset(frame, child_sp, offset - child_offset);
1565 }
1566 }
1567
1568 if (offset == 0) {
1569 return parent;
1570 } else {
1571 return ValueObjectSP();
1572 }
1573}
1574
1575ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
1576 ValueObjectSP &base,
1577 int64_t offset) {
1578 // base is a pointer to something
1579 // offset is the thing to add to the pointer We return the most sensible
1580 // ValueObject for the result of *(base+offset)
1581
1582 if (!base->IsPointerOrReferenceType()) {
1583 return ValueObjectSP();
1584 }
1585
1586 Status error;
1587 ValueObjectSP pointee = base->Dereference(error);
1588
1589 if (!pointee) {
1590 return ValueObjectSP();
1591 }
1592
1593 if (offset >= 0 &&
1594 uint64_t(offset) >=
1595 llvm::expectedToOptional(pointee->GetByteSize()).value_or(0)) {
1596 uint64_t size =
1597 llvm::expectedToOptional(pointee->GetByteSize()).value_or(1);
1598 int64_t index = offset / size;
1599 offset = offset % size;
1600 const bool can_create = true;
1601 pointee = base->GetSyntheticArrayMember(index, can_create);
1602 }
1603
1604 if (!pointee || error.Fail()) {
1605 return ValueObjectSP();
1606 }
1607
1608 return GetValueForOffset(frame, pointee, offset);
1609}
1610
1611/// Attempt to reconstruct the ValueObject for the address contained in a
1612/// given register plus an offset.
1613///
1614/// \param [in] frame
1615/// The current stack frame.
1616///
1617/// \param [in] reg
1618/// The register.
1619///
1620/// \param [in] offset
1621/// The offset from the register.
1622///
1623/// \param [in] disassembler
1624/// A disassembler containing instructions valid up to the current PC.
1625///
1626/// \param [in] variables
1627/// The variable list from the current frame,
1628///
1629/// \param [in] pc
1630/// The program counter for the instruction considered the 'user'.
1631///
1632/// \return
1633/// A string describing the base for the ExpressionPath. This could be a
1634/// variable, a register value, an argument, or a function return value.
1635/// The ValueObject if found. If valid, it has a valid ExpressionPath.
1636lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, llvm::StringRef reg,
1637 int64_t offset, Disassembler &disassembler,
1638 VariableList &variables, const Address &pc) {
1639 // Example of operation for Intel:
1640 //
1641 // +14: movq -0x8(%rbp), %rdi
1642 // +18: movq 0x8(%rdi), %rdi
1643 // +22: addl 0x4(%rdi), %eax
1644 //
1645 // f, a pointer to a struct, is known to be at -0x8(%rbp).
1646 //
1647 // DoGuessValueAt(frame, rdi, 4, dis, vars, 0x22) finds the instruction at
1648 // +18 that assigns to rdi, and calls itself recursively for that dereference
1649 // DoGuessValueAt(frame, rdi, 8, dis, vars, 0x18) finds the instruction at
1650 // +14 that assigns to rdi, and calls itself recursively for that
1651 // dereference
1652 // DoGuessValueAt(frame, rbp, -8, dis, vars, 0x14) finds "f" in the
1653 // variable list.
1654 // Returns a ValueObject for f. (That's what was stored at rbp-8 at +14)
1655 // Returns a ValueObject for *(f+8) or f->b (That's what was stored at rdi+8
1656 // at +18)
1657 // Returns a ValueObject for *(f->b+4) or f->b->a (That's what was stored at
1658 // rdi+4 at +22)
1659
1660 // First, check the variable list to see if anything is at the specified
1661 // location.
1662
1663 using namespace OperandMatchers;
1664
1665 const RegisterInfo *reg_info =
1666 frame.GetRegisterContext()->GetRegisterInfoByName(reg);
1667 if (!reg_info) {
1668 return ValueObjectSP();
1669 }
1670
1676 : Instruction::Operand::BuildDereference(
1677 Instruction::Operand::BuildRegister(reg));
1678
1679 for (VariableSP var_sp : variables) {
1680 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1682 }
1683
1684 const uint32_t current_inst =
1685 disassembler.GetInstructionList().GetIndexOfInstructionAtAddress(pc);
1686 if (current_inst == UINT32_MAX) {
1687 return ValueObjectSP();
1688 }
1689
1690 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1691 // This is not an exact algorithm, and it sacrifices accuracy for
1692 // generality. Recognizing "mov" and "ld" instructions –– and which
1693 // are their source and destination operands -- is something the
1694 // disassembler should do for us.
1695 InstructionSP instruction_sp =
1696 disassembler.GetInstructionList().GetInstructionAtIndex(ii);
1697
1698 if (instruction_sp->IsCall()) {
1699 ABISP abi_sp = frame.CalculateProcess()->GetABI();
1700 if (!abi_sp) {
1701 continue;
1702 }
1703
1704 const char *return_register_name;
1705 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1706 continue;
1707 }
1708
1709 const RegisterInfo *return_register_info =
1710 frame.GetRegisterContext()->GetRegisterInfoByName(
1711 return_register_name);
1712 if (!return_register_info) {
1713 continue;
1714 }
1715
1716 int64_t offset = 0;
1717
1719 MatchRegOp(*return_register_info))(op) &&
1720 !MatchUnaryOp(
1723 MatchRegOp(*return_register_info),
1724 FetchImmOp(offset)))(op)) {
1725 continue;
1726 }
1727
1728 llvm::SmallVector<Instruction::Operand, 1> operands;
1729 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1730 continue;
1731 }
1732
1733 switch (operands[0].m_type) {
1734 default:
1735 break;
1737 SymbolContext sc;
1738 if (!pc.GetModule())
1739 break;
1740 Address address(operands[0].m_immediate,
1741 pc.GetModule()->GetSectionList());
1742 if (!address.IsValid())
1743 break;
1744 frame.CalculateTarget()->GetImages().ResolveSymbolContextForAddress(
1745 address, eSymbolContextFunction, sc);
1746 if (!sc.function) {
1747 break;
1748 }
1749 CompilerType function_type = sc.function->GetCompilerType();
1750 if (!function_type.IsFunctionType()) {
1751 break;
1752 }
1753 CompilerType return_type = function_type.GetFunctionReturnType();
1754 RegisterValue return_value;
1755 if (!frame.GetRegisterContext()->ReadRegister(return_register_info,
1756 return_value)) {
1757 break;
1758 }
1759 std::string name_str(
1760 sc.function->GetName().AsCString("<unknown function>"));
1761 name_str.append("()");
1762 Address return_value_address(return_value.GetAsUInt64());
1763 ValueObjectSP return_value_sp = ValueObjectMemory::Create(
1764 &frame, name_str, return_value_address, return_type);
1765 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1766 }
1767 }
1768
1769 continue;
1770 }
1771
1772 llvm::SmallVector<Instruction::Operand, 2> operands;
1773 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1774 continue;
1775 }
1776
1777 Instruction::Operand *origin_operand = nullptr;
1778 auto clobbered_reg_matcher = [reg_info](const Instruction::Operand &op) {
1779 return MatchRegOp(*reg_info)(op) && op.m_clobbered;
1780 };
1781
1782 if (clobbered_reg_matcher(operands[0])) {
1783 origin_operand = &operands[1];
1784 } else if (clobbered_reg_matcher(operands[1])) {
1785 origin_operand = &operands[0];
1786 } else {
1787 continue;
1788 }
1789
1790 // We have an origin operand. Can we track its value down?
1791 ValueObjectSP source_path;
1792 std::string origin_register;
1793 int64_t origin_offset = 0;
1794
1795 if (FetchRegOp(origin_register)(*origin_operand)) {
1796 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1797 variables, instruction_sp->GetAddress());
1798 } else if (MatchUnaryOp(
1800 FetchRegOp(origin_register))(*origin_operand) ||
1804 FetchRegOp(origin_register),
1805 FetchImmOp(origin_offset)))(*origin_operand)) {
1806 source_path =
1807 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1808 variables, instruction_sp->GetAddress());
1809 if (!source_path) {
1810 continue;
1811 }
1812 source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1813 }
1814
1815 if (source_path) {
1816 return source_path;
1817 }
1818 }
1819
1820 return ValueObjectSP();
1821}
1822} // namespace
1823
1826 int64_t offset) {
1827 TargetSP target_sp = CalculateTarget();
1828
1829 const ArchSpec &target_arch = target_sp->GetArchitecture();
1830
1831 Block *frame_block = GetFrameBlock();
1832
1833 if (!frame_block) {
1834 return ValueObjectSP();
1835 }
1836
1837 Function *function = frame_block->CalculateSymbolContextFunction();
1838 if (!function) {
1839 return ValueObjectSP();
1840 }
1841
1842 AddressRange unused_range;
1843 if (!function->GetRangeContainingLoadAddress(
1844 GetFrameCodeAddress().GetLoadAddress(target_sp.get()), *target_sp,
1845 unused_range))
1846 return ValueObjectSP();
1847
1848 const char *plugin_name = nullptr;
1849 const char *flavor = nullptr;
1850 const char *cpu = nullptr;
1851 const char *features = nullptr;
1852 const bool force_live_memory = true;
1854 target_arch, plugin_name, flavor, cpu, features, *target_sp,
1855 function->GetAddressRanges(), force_live_memory);
1856
1857 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1858 return ValueObjectSP();
1859 }
1860
1861 const bool get_file_globals = false;
1862 // Keep this as 'false' here because if we're inspecting a register, it's
1863 // HIGHLY unlikely that we have an synthetic variable. Indeed, since we're not
1864 // in a synthetic frame, it's probably actually impossible here.
1865 const bool include_synthetic_vars = false;
1866 VariableList *variables =
1867 GetVariableList(get_file_globals, include_synthetic_vars, nullptr);
1868
1869 if (!variables) {
1870 return ValueObjectSP();
1871 }
1872
1873 return DoGuessValueAt(*this, reg, offset, *disassembler_sp, *variables,
1875}
1876
1878 ValueObjectSP value_sp;
1879
1880 if (!name)
1881 return value_sp;
1882
1883 TargetSP target_sp = CalculateTarget();
1884 ProcessSP process_sp = CalculateProcess();
1885
1886 if (!target_sp && !process_sp)
1887 return value_sp;
1888
1889 VariableList variable_list;
1890 VariableSP var_sp;
1891 SymbolContext sc(GetSymbolContext(eSymbolContextBlock));
1892
1893 if (sc.block) {
1894 const bool can_create = true;
1895 const bool get_parent_variables = true;
1896 const bool stop_if_block_is_inlined_function = true;
1897
1898 if (sc.block->AppendVariables(
1899 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1900 [this](Variable *v) { return v->IsInScope(this); },
1901 &variable_list)) {
1902 var_sp = variable_list.FindVariable(name);
1903 }
1904
1905 if (var_sp)
1907 }
1908
1909 return value_sp;
1910}
1911
1913 TargetSP target_sp;
1914 ThreadSP thread_sp(GetThread());
1915 if (thread_sp) {
1916 ProcessSP process_sp(thread_sp->CalculateProcess());
1917 if (process_sp)
1918 target_sp = process_sp->CalculateTarget();
1919 }
1920 return target_sp;
1921}
1922
1924 ProcessSP process_sp;
1925 ThreadSP thread_sp(GetThread());
1926 if (thread_sp)
1927 process_sp = thread_sp->CalculateProcess();
1928 return process_sp;
1929}
1930
1932
1933StackFrameSP StackFrame::CalculateStackFrame() { return shared_from_this(); }
1934
1936 exe_ctx.SetContext(shared_from_this());
1937}
1938
1940 const FormatEntity::Entry *format,
1941 llvm::StringRef frame_marker) {
1942 GetSymbolContext(eSymbolContextEverything);
1943 ExecutionContext exe_ctx(shared_from_this());
1944 StreamString s;
1945 s.PutCString(frame_marker);
1946
1947 if (format && FormatEntity::Formatter(&m_sc, &exe_ctx, nullptr, false, false)
1948 .Format(*format, s)) {
1949 strm.PutCString(s.GetString());
1950 return true;
1951 }
1952 return false;
1953}
1954
1955void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique,
1956 const llvm::StringRef frame_marker) {
1957 if (strm == nullptr)
1958 return;
1959
1960 ExecutionContext exe_ctx(shared_from_this());
1961
1962 const FormatEntity::Entry *frame_format = nullptr;
1963 FormatEntity::Entry format_entry;
1964 Target *target = exe_ctx.GetTargetPtr();
1965 if (target) {
1966 if (show_unique) {
1967 format_entry = target->GetDebugger().GetFrameFormatUnique();
1968 frame_format = &format_entry;
1969 } else {
1970 format_entry = target->GetDebugger().GetFrameFormat();
1971 frame_format = &format_entry;
1972 }
1973 }
1974 if (!DumpUsingFormat(*strm, frame_format, frame_marker)) {
1975 Dump(strm, true, false);
1976 strm->EOL();
1977 }
1978}
1979
1980void StackFrame::Dump(Stream *strm, bool show_frame_index,
1981 bool show_fullpaths) {
1982 if (strm == nullptr)
1983 return;
1984
1985 if (show_frame_index)
1986 strm->Printf("frame #%u: ", m_frame_index);
1987 ExecutionContext exe_ctx(shared_from_this());
1988 Target *target = exe_ctx.GetTargetPtr();
1989 strm->Printf("0x%0*" PRIx64 " ",
1990 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
1991 : 16,
1992 GetFrameCodeAddress().GetLoadAddress(target));
1993 GetSymbolContext(eSymbolContextEverything);
1994 const bool show_module = true;
1995 const bool show_inline = true;
1996 const bool show_function_arguments = true;
1997 const bool show_function_name = true;
1998 m_sc.DumpStopContext(strm, exe_ctx.GetBestExecutionContextScope(),
1999 GetFrameCodeAddress(), show_fullpaths, show_module,
2000 show_inline, show_function_arguments,
2001 show_function_name);
2002}
2003
2005 std::lock_guard<std::recursive_mutex> guard(m_mutex);
2006 assert(GetStackID() ==
2007 prev_frame.GetStackID()); // TODO: remove this after some testing
2010 if (!m_disassembly.GetString().empty()) {
2011 m_disassembly.Clear();
2012 m_disassembly.PutCString(prev_frame.m_disassembly.GetString());
2013 }
2014}
2015
2017 std::lock_guard<std::recursive_mutex> guard(m_mutex);
2018 assert(GetStackID() ==
2019 curr_frame.GetStackID()); // TODO: remove this after some testing
2020 m_id.SetPC(
2021 curr_frame.m_id.GetPC(),
2022 curr_frame.CalculateProcess().get()); // Update the Stack ID PC value
2023 assert(GetThread() == curr_frame.GetThread());
2024 m_frame_index = curr_frame.m_frame_index;
2029 assert(!m_sc.target_sp || !curr_frame.m_sc.target_sp ||
2030 m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get());
2031 assert(!m_sc.module_sp || !curr_frame.m_sc.module_sp ||
2032 m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get());
2033 assert(m_sc.comp_unit == nullptr || curr_frame.m_sc.comp_unit == nullptr ||
2034 m_sc.comp_unit == curr_frame.m_sc.comp_unit);
2035 assert(m_sc.function == nullptr || curr_frame.m_sc.function == nullptr ||
2036 m_sc.function == curr_frame.m_sc.function);
2037 m_sc = curr_frame.m_sc;
2038 m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything);
2039 m_flags.Set(m_sc.GetResolvedMask());
2040 m_frame_base.Clear();
2041 m_frame_base_error.Clear();
2042}
2043
2046 return true;
2047 if (m_variable_list_value_objects.GetSize() > 0)
2048 return true;
2049 if (!m_disassembly.GetString().empty())
2050 return true;
2051 return false;
2052}
2053
2054bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
2055 bool show_unique,
2056 const llvm::StringRef frame_marker) {
2057 if (show_frame_info) {
2058 strm.Indent();
2059 DumpUsingSettingsFormat(&strm, show_unique, frame_marker);
2060 }
2061
2062 if (show_source) {
2063 ExecutionContext exe_ctx(shared_from_this());
2064 bool have_source = false, have_debuginfo = false;
2066 Target *target = exe_ctx.GetTargetPtr();
2067 if (target) {
2068 Debugger &debugger = target->GetDebugger();
2069 const uint32_t source_lines_before =
2070 debugger.GetStopSourceLineCount(true);
2071 const uint32_t source_lines_after =
2072 debugger.GetStopSourceLineCount(false);
2073 disasm_display = debugger.GetStopDisassemblyDisplay();
2074
2075 GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
2076 if (m_sc.comp_unit || m_sc.line_entry.IsValid()) {
2077 have_debuginfo = true;
2078 if (source_lines_before > 0 || source_lines_after > 0) {
2079 SupportFileNSP source_file_sp = m_sc.line_entry.file_sp;
2080 uint32_t start_line = m_sc.line_entry.line;
2081 if (!start_line && m_sc.function) {
2082 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2083 }
2084
2085 size_t num_lines =
2087 source_file_sp, start_line, m_sc.line_entry.column,
2088 source_lines_before, source_lines_after, "->", &strm,
2089 /*bp_locs=*/nullptr, GetLanguage().AsLanguageType());
2090 if (num_lines != 0)
2091 have_source = true;
2092 // TODO: Give here a one time warning if source file is missing.
2093 if (!m_sc.line_entry.line)
2094 strm << "note: This address is not associated with a specific line "
2095 "of code. This may be due to compiler optimizations.\n";
2096 }
2097 }
2098 switch (disasm_display) {
2100 break;
2101
2103 if (have_debuginfo)
2104 break;
2105 [[fallthrough]];
2106
2108 if (have_source)
2109 break;
2110 [[fallthrough]];
2111
2113 if (target) {
2114 const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
2115 if (disasm_lines > 0) {
2116 const ArchSpec &target_arch = target->GetArchitecture();
2117 const char *plugin_name = nullptr;
2118 const char *flavor = nullptr;
2119 const bool mixed_source_and_assembly = false;
2121 target->GetDebugger(), target_arch, plugin_name, flavor,
2122 target->GetDisassemblyCPU(), target->GetDisassemblyFeatures(),
2123 exe_ctx, GetFrameCodeAddress(),
2124 {Disassembler::Limit::Instructions, disasm_lines},
2125 mixed_source_and_assembly, 0,
2127 }
2128 }
2129 break;
2130 }
2131 }
2132 }
2133 return true;
2134}
2135
2137 auto process = GetThread()->GetProcess();
2138 if (!process)
2139 return {};
2140 // If recognizer list has been modified, discard cache.
2141 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2142 auto new_generation = manager.GetGeneration();
2143 if (m_frame_recognizer_generation != new_generation)
2144 m_recognized_frame_sp.reset();
2145 m_frame_recognizer_generation = new_generation;
2146 if (!m_recognized_frame_sp.has_value())
2147 m_recognized_frame_sp = manager.RecognizeFrame(CalculateStackFrame());
2148 return m_recognized_frame_sp.value();
2149}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
#define GOT_FRAME_BASE
#define RESOLVED_GLOBAL_VARIABLES
#define RESOLVED_FRAME_ID_SYMBOL_SCOPE
#define RESOLVED_FRAME_CODE_ADDR
#define RESOLVED_VARIABLES
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
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
lldb::addr_t GetOpcodeLoadAddress(Target *target, AddressClass addr_class=AddressClass::eInvalid) const
Get the load address as an opcode load address.
Definition Address.cpp:360
bool SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, AddressClass addr_class=AddressClass::eInvalid, bool allow_section_end=false)
Definition Address.cpp:371
bool Slide(int64_t offset)
Definition Address.h:446
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:275
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
Block * CalculateSymbolContextBlock() const
Definition Address.cpp:874
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:894
uint32_t GetMaximumOpcodeByteSize() const
A class that describes a single lexical block.
Definition Block.h:41
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
Definition Block.cpp:206
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Definition Block.h:268
Function * CalculateSymbolContextFunction() override
Definition Block.cpp:150
uint32_t AppendVariables(bool can_create, bool get_parent_variables, bool stop_if_block_is_inlined_function, const std::function< bool(Variable *)> &filter, VariableList *variable_list)
Appends the variables from this block, and optionally from all parent blocks, to variable_list.
Definition Block.cpp:426
uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables, bool stop_if_child_block_is_inlined_function, const std::function< bool(Variable *)> &filter, VariableList *variable_list)
Get the variable list for this block and optionally all child blocks if get_child_variables is true.
Definition Block.cpp:396
A class that describes a compilation unit.
Definition CompileUnit.h:43
lldb::LanguageType GetLanguage()
Generic representation of a type in a programming language.
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
CompilerType GetFunctionReturnType() const
A uniqued constant string class.
Definition ConstString.h:40
size_t GetLength() const
Get the length in bytes of string value.
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
A class to manage flag bits.
Definition Debugger.h:101
uint64_t GetDisassemblyLineCount() const
Definition Debugger.cpp:769
FormatEntity::Entry GetFrameFormatUnique() const
Definition Debugger.cpp:402
uint64_t GetStopSourceLineCount(bool before) const
Definition Debugger.cpp:755
FormatEntity::Entry GetFrameFormat() const
Definition Debugger.cpp:397
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
Definition Debugger.cpp:762
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, const char *flavor, const char *cpu, const char *features, Target &target, llvm::ArrayRef< AddressRange > disasm_ranges, bool force_live_memory=false)
static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const char *cpu, const char *features, const ExecutionContext &exe_ctx, const Address &start, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm)
InstructionList & GetInstructionList()
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
void SetContext(const lldb::TargetSP &target_sp, bool get_process)
Target * GetTargetPtr() const
Returns a pointer to the target object.
Target & GetTargetRef() const
Returns a reference to the target object.
A class that describes a function.
Definition Function.h:386
CompilerType GetCompilerType()
Definition Function.cpp:585
bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, AddressRange &range)
Definition Function.h:441
ConstString GetName() const
Definition Function.cpp:724
const Mangled & GetMangled() const
Definition Function.h:541
AddressRanges GetAddressRanges()
Definition Function.h:434
ConstString GetDisplayName() const
Definition Function.cpp:546
A class that describes information for an inlined function.
Definition Function.h:120
ConstString GetDisplayName() const
Definition Function.cpp:99
ConstString GetName() const
Definition Function.cpp:93
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:409
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
size_t DisplaySourceLinesWithLineNumbers(SupportFileNSP support_file_nsp, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr, lldb::LanguageType language_type=lldb::eLanguageTypeUnknown)
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error, lldb::DILMode mode=lldb::eDILModeFull)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
uint16_t m_frame_recognizer_generation
Definition StackFrame.h:622
lldb::VariableListSP m_variable_list_sp
Definition StackFrame.h:637
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
bool m_artificial
Is this an artificial stack frame (e.g.
Definition StackFrame.h:629
lldb::ThreadSP GetThread() const
Definition StackFrame.h:135
Address m_frame_code_addr
The frame code address (might not be the same as the actual PC for inlined frames) as a section/offse...
Definition StackFrame.h:617
@ eExpressionPathOptionsInspectAnonymousUnions
Definition StackFrame.h:57
@ eExpressionPathOptionsAllowDirectIVarAccess
Definition StackFrame.h:56
virtual const char * GetFunctionName()
Get the frame's demangled name.
virtual bool IsHidden()
Query whether this frame should be hidden from backtraces.
virtual lldb::ValueObjectSP GuessValueForRegisterAndOffset(llvm::StringRef reg, int64_t offset)
Attempt to reconstruct the ValueObject for the address contained in a given register plus an offset.
virtual bool IsSynthetic() const
Query whether this frame is synthetic.
virtual DWARFExpressionList * GetFrameBaseExpression(Status *error_ptr)
Get the DWARFExpressionList corresponding to the Canonical Frame Address.
void UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame)
ValueObjectList m_variable_list_value_objects
Value objects for each variable in m_variable_list_sp.
Definition StackFrame.h:639
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
Definition StackFrame.h:624
virtual llvm::Error GetFrameBaseValue(Scalar &value)
Return the Canonical Frame Address (DWARF term) for this frame.
lldb::ThreadWP m_thread_wp
For StackFrame and derived classes only.
Definition StackFrame.h:608
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
Definition StackFrame.h:640
virtual bool IsInlined()
Query whether this frame is a concrete frame on the call stack, or if it is an inlined frame derived ...
lldb::ValueObjectSP DILGetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error, lldb::DILMode mode=lldb::eDILModeFull)
virtual SourceLanguage GuessLanguage()
Similar to GetLanguage(), but is allowed to take a potentially incorrect guess if exact information i...
virtual lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
bool IsAddressInFrameScope(const Address &addr)
Let F be this frame's function.
lldb::RegisterContextSP m_reg_context_sp
Definition StackFrame.h:611
static char ID
LLVM RTTI support.
Definition StackFrame.h:48
virtual StructuredData::ObjectSP GetLanguageSpecificData()
Language plugins can use this API to report language-specific runtime information about this compile ...
virtual Address GetFrameCodeAddressForSymbolication()
Get the current code Address suitable for symbolication, may not be the same as GetFrameCodeAddress()...
@ History
A historical stack frame – possibly without CFA or registers or local variables.
Definition StackFrame.h:68
@ Regular
A regular stack frame with access to registers and local variables.
Definition StackFrame.h:64
@ Synthetic
An synthetic stack frame (e.g.
Definition StackFrame.h:72
bool m_behaves_like_zeroth_frame
Whether this frame behaves like the zeroth frame, in the sense that its pc value might not immediatel...
Definition StackFrame.h:635
virtual StackID & GetStackID()
virtual lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr)
Attempt to econstruct the ValueObject for a given raw address touched by the current instruction.
virtual bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, bool show_unique=false, const llvm::StringRef frame_marker="")
Print a description of this stack frame and/or the source context/assembly for this stack frame.
virtual bool ChangePC(lldb::addr_t pc)
Change the pc value for a given thread.
lldb::ValueObjectSP LegacyGetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Private methods, called from GetValueForVariableExpressionPath.
lldb::ThreadSP CalculateThread() override
virtual SourceLanguage GetLanguage()
Query this frame to determine what the default language should be when parsing expressions given the ...
virtual lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
virtual VariableList * GetVariableList(bool get_file_globals, bool include_synthetic_vars, Status *error_ptr)
Retrieve the list of variables whose scope either:
StreamString m_disassembly
Definition StackFrame.h:641
lldb::StackFrameSP CalculateStackFrame() override
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual const char * GetDisplayFunctionName()
Get the frame's demangled display name.
virtual bool IsHistorical() const
Query whether this frame is part of a historical backtrace.
virtual const char * Disassemble()
Return the disassembly for the instructions of this StackFrame's function as a single C string.
virtual bool IsArtificial() const
Query whether this frame is artificial (e.g a synthesized result of inferring missing tail call frame...
void CalculateExecutionContext(ExecutionContext &exe_ctx) override
Reconstruct the object's execution context into sc.
virtual void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths)
Print a description for this frame using a default format.
virtual uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
virtual bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
virtual void DumpUsingSettingsFormat(Stream *strm, bool show_unique=false, const llvm::StringRef frame_marker="")
Print a description for this frame using the frame-format formatter settings.
virtual lldb::VariableListSP GetInScopeVariableList(bool get_file_globals, bool include_synthetic_vars=true, bool must_have_valid_location=false)
Retrieve the list of variables that are in scope at this StackFrame's pc.
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, bool artificial, bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr)
Construct a StackFrame object without supplying a RegisterContextSP.
virtual Block * GetFrameBlock()
Get the current lexical scope block for this StackFrame, if possible.
virtual bool DumpUsingFormat(Stream &strm, const lldb_private::FormatEntity::Entry *format, llvm::StringRef frame_marker={})
Print a description of this frame using the provided frame format.
lldb::ProcessSP CalculateProcess() override
virtual lldb::RecognizedStackFrameSP GetRecognizedFrame()
std::recursive_mutex m_mutex
Definition StackFrame.h:642
virtual lldb::ValueObjectSP FindVariable(ConstString name)
Attempt to reconstruct the ValueObject for a variable with a given name from within the current Stack...
virtual const Address & GetFrameCodeAddress()
Get an Address for the current pc value in this StackFrame.
lldb::TargetSP CalculateTarget() override
lldb::addr_t GetPC() const
Definition StackID.h:27
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
bool Success() const
Test for success condition.
Definition Status.cpp:303
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
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:63
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
std::shared_ptr< Object > ObjectSP
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
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.
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.
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
Status GetFrameVariableError(StackFrame &frame)
Get an error that describes why variables might be missing for a given symbol context.
Definition SymbolFile.h:282
Mangled & GetMangled()
Definition Symbol.h:162
ConstString GetName() const
Definition Symbol.cpp:612
ConstString GetDisplayName() const
Definition Symbol.cpp:199
const char * GetDisassemblyFeatures() const
Definition Target.cpp:5410
const char * GetDisassemblyCPU() const
Definition Target.cpp:5403
bool GetUseDIL(ExecutionContext *exe_ctx) const
Definition Target.cpp:5249
SourceManager & GetSourceManager()
Definition Target.cpp:3169
Debugger & GetDebugger() const
Definition Target.h:1362
const ArchSpec & GetArchitecture() const
Definition Target.h:1321
CompilerType GetForwardCompilerType()
Definition Type.cpp:791
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS, ValueObjectManager *manager=nullptr)
These routines create ValueObjectConstResult ValueObjects from various data sources.
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp, ValueObject *parent=nullptr)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
uint32_t FindIndexForVariable(Variable *variable)
lldb::VariableSP FindVariable(ConstString name, bool include_static_members=true) const
bool IsInScope(StackFrame *frame)
Definition Variable.cpp:286
bool LocationIsValidForFrame(StackFrame *frame)
Definition Variable.cpp:228
static llvm::Expected< DILLexer > Create(llvm::StringRef expr, lldb::DILMode mode=lldb::eDILModeFull)
Lexes all the tokens in expr and calls the private constructor with the lexed tokens.
Definition DILLexer.cpp:200
static llvm::Expected< ASTNodeUP > Parse(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr, DILLexer lexer, lldb::DynamicValueType use_dynamic, lldb::DILMode mode)
Parse the lexed tokens.
Definition DILParser.cpp:92
llvm::Expected< lldb::ValueObjectSP > EvaluateTree(const ASTNodeUP &tree)
Evaluate an ASTNode tree.
Definition DILEval.cpp:485
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
std::function< bool(const Instruction::Operand &)> FetchRegOp(std::string &reg)
std::function< bool(const Instruction::Operand &)> MatchRegOp(const RegisterInfo &info)
std::function< bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm)
std::function< bool(const Instruction::Operand &)> MatchOpType(Instruction::Operand::Type type)
std::function< bool(const Instruction::Operand &)> MatchBinaryOp(std::function< bool(const Instruction::Operand &)> base, std::function< bool(const Instruction::Operand &)> left, std::function< bool(const Instruction::Operand &)> right)
std::function< bool(const Instruction::Operand &)> MatchUnaryOp(std::function< bool(const Instruction::Operand &)> base, std::function< bool(const Instruction::Operand &)> child)
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:338
NonNullSharedPtr< lldb_private::SupportFile > SupportFileNSP
Definition SupportFile.h:80
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::RecognizedStackFrame > RecognizedStackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
std::shared_ptr< lldb_private::Instruction > InstructionSP
std::shared_ptr< lldb_private::Process > ProcessSP
StopDisassemblyType
Used to determine when to show disassembly.
@ eStopDisassemblyTypeNever
@ eStopDisassemblyTypeNoSource
@ eStopDisassemblyTypeAlways
@ eStopDisassemblyTypeNoDebugInfo
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::Variable > VariableSP
uint64_t user_id_t
Definition lldb-types.h:83
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
DILMode
Data Inspection Language (DIL) evaluation modes.
std::shared_ptr< lldb_private::Module > ModuleSP
enum lldb_private::Instruction::Operand::Type m_type
static Operand BuildImmediate(lldb::addr_t imm, bool neg)
static Operand BuildDereference(const Operand &ref)
std::vector< Operand > m_children
static Operand BuildRegister(llvm::StringRef r)
static Operand BuildSum(const Operand &lhs, const Operand &rhs)
Every register is described in detail including its name, alternate name (optional),...
A type-erased pair of llvm::dwarf::SourceLanguageName and version.
lldb::LanguageType AsLanguageType() const
Definition Language.cpp:628