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)
63 bool artificial,
bool behaves_like_zeroth_frame,
67 m_id(
pc, cfa, nullptr, thread_sp->GetProcess().get()),
81 if (sc_ptr !=
nullptr) {
90 addr_t pc,
bool behaves_like_zeroth_frame,
95 m_id(
pc, cfa, nullptr, thread_sp->GetProcess().get()),
102 if (sc_ptr !=
nullptr) {
107 if (reg_context_sp && !
m_sc.target_sp) {
108 m_sc.target_sp = reg_context_sp->CalculateTarget();
110 m_flags.Set(eSymbolContextTarget);
117 const Address &pc_addr,
bool behaves_like_zeroth_frame,
123 nullptr, thread_sp->GetProcess().get()),
130 if (sc_ptr !=
nullptr) {
135 if (!
m_sc.target_sp && reg_context_sp) {
136 m_sc.target_sp = reg_context_sp->CalculateTarget();
138 m_flags.Set(eSymbolContextTarget);
142 if (!
m_sc.module_sp ||
m_sc.module_sp != pc_module_sp) {
144 m_sc.module_sp = pc_module_sp;
145 m_flags.Set(eSymbolContextModule);
147 m_sc.module_sp.reset();
155 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
160 if (
m_id.GetSymbolContextScope()) {
168 if (scope ==
nullptr) {
170 if (
m_flags.IsClear(eSymbolContextSymbol))
187 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
194 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
196 m_id.SetSymbolContextScope(symbol_scope);
200 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
209 TargetSP target_sp(thread_sp->CalculateTarget());
211 const bool allow_section_end =
true;
217 m_sc.module_sp = module_sp;
218 m_flags.Set(eSymbolContextModule);
240 lookup_addr.
Slide(-1);
257 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
266 thread_sp->ClearStackFrames();
271 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
286 if (
m_sc.block ==
nullptr &&
m_flags.IsClear(eSymbolContextBlock))
290 Block *inline_block =
m_sc.block->GetContainingInlinedBlock();
299 return &
m_sc.function->GetBlock(
false);
311 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
313 if ((
m_flags.Get() & resolve_scope) != resolve_scope) {
314 uint32_t resolved = 0;
317 if (!
m_sc.target_sp) {
320 resolved |= eSymbolContextTarget;
337 m_flags.Set(resolve_scope | resolved);
341 if (
m_sc.module_sp) {
346 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
348 if (resolve_scope & eSymbolContextCompUnit) {
349 if (
m_flags.IsClear(eSymbolContextCompUnit)) {
351 resolved |= eSymbolContextCompUnit;
353 actual_resolve_scope |= eSymbolContextCompUnit;
357 if (resolve_scope & eSymbolContextFunction) {
358 if (
m_flags.IsClear(eSymbolContextFunction)) {
360 resolved |= eSymbolContextFunction;
362 actual_resolve_scope |= eSymbolContextFunction;
366 if (resolve_scope & eSymbolContextBlock) {
367 if (
m_flags.IsClear(eSymbolContextBlock)) {
369 resolved |= eSymbolContextBlock;
371 actual_resolve_scope |= eSymbolContextBlock;
375 if (resolve_scope & eSymbolContextSymbol) {
376 if (
m_flags.IsClear(eSymbolContextSymbol)) {
378 resolved |= eSymbolContextSymbol;
380 actual_resolve_scope |= eSymbolContextSymbol;
384 if (resolve_scope & eSymbolContextLineEntry) {
385 if (
m_flags.IsClear(eSymbolContextLineEntry)) {
386 if (
m_sc.line_entry.IsValid())
387 resolved |= eSymbolContextLineEntry;
389 actual_resolve_scope |= eSymbolContextLineEntry;
393 if (actual_resolve_scope) {
399 resolved |=
m_sc.module_sp->ResolveSymbolContextForAddress(
400 lookup_addr, actual_resolve_scope, sc);
404 if ((resolved & eSymbolContextCompUnit) &&
m_sc.comp_unit ==
nullptr)
406 if ((resolved & eSymbolContextFunction) &&
m_sc.function ==
nullptr)
408 if ((resolved & eSymbolContextBlock) &&
m_sc.block ==
nullptr)
410 if ((resolved & eSymbolContextSymbol) &&
m_sc.symbol ==
nullptr)
412 if ((resolved & eSymbolContextLineEntry) &&
413 !
m_sc.line_entry.IsValid()) {
415 m_sc.line_entry.ApplyFileMappings(
m_sc.target_sp);
422 if (
m_sc.target_sp) {
423 resolved |=
m_sc.target_sp->GetImages().ResolveSymbolContextForAddress(
424 lookup_addr, resolve_scope,
m_sc);
433 m_flags.Set(resolve_scope | resolved);
442 bool include_synthetic_vars,
445 (void)include_synthetic_vars;
447 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
455 const bool get_child_variables =
true;
456 const bool can_create =
true;
457 const bool stop_if_child_block_is_inlined_function =
true;
459 can_create, get_child_variables,
460 stop_if_child_block_is_inlined_function,
468 if (
m_flags.IsClear(eSymbolContextCompUnit))
471 if (
m_sc.comp_unit) {
473 m_sc.comp_unit->GetVariableList(
true));
485 if (
m_sc.module_sp) {
497 bool include_synthetic_vars,
498 bool must_have_valid_location) {
500 (void)include_synthetic_vars;
502 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
511 const bool can_create =
true;
512 const bool get_parent_variables =
true;
513 const bool stop_if_block_is_inlined_function =
true;
514 m_sc.block->AppendVariables(
515 can_create, get_parent_variables, stop_if_block_is_inlined_function,
516 [
this, must_have_valid_location](
Variable *v) {
517 return v->
IsInScope(
this) && (!must_have_valid_location ||
523 if (
m_sc.comp_unit && get_file_globals) {
525 m_sc.comp_unit->GetVariableList(
true));
526 if (global_variable_list_sp)
527 var_list_sp->AddVariables(global_variable_list_sp.get());
541 var_sp,
error, mode);
561 var_expr, std::move(*lex_or_err), shared_from_this(), use_dynamic, mode);
562 if (!tree_or_error) {
570 use_dynamic, options);
572 auto valobj_or_error = interpreter.
Evaluate(**tree_or_error);
573 if (!valobj_or_error) {
578 var_sp = (*valobj_or_error)->GetVariable();
579 return *valobj_or_error;
585 llvm::StringRef original_var_expr = var_expr;
590 if (var_expr.empty()) {
596 const bool check_ptr_vs_member =
598 const bool no_fragile_ivar =
600 const bool no_synth_child =
606 bool address_of =
false;
608 const bool get_file_globals =
true;
618 std::string var_expr_storage;
619 if (var_expr[0] ==
'*') {
621 var_expr = var_expr.drop_front();
622 }
else if (var_expr[0] ==
'&') {
624 var_expr = var_expr.drop_front();
627 size_t separator_idx = var_expr.find_first_of(
".-[=+~|&^%#@!/?,<>{}");
630 ConstString name_const_string(var_expr.substr(0, separator_idx));
632 var_sp = variable_list->
FindVariable(name_const_string,
false);
634 bool synthetically_added_instance_object =
false;
637 var_expr = var_expr.drop_front(name_const_string.
GetLength());
644 llvm::StringRef instance_var_name =
m_sc.GetInstanceVariableName();
645 if (!instance_var_name.empty()) {
649 if (
Type *var_type = var_sp->GetType())
650 if (
auto compiler_type = var_type->GetForwardCompilerType())
651 if (!compiler_type.IsPointerType())
652 var_expr_storage =
".";
654 if (var_expr_storage.empty())
655 var_expr_storage =
"->";
656 var_expr_storage += var_expr;
657 var_expr = var_expr_storage;
658 synthetically_added_instance_object =
true;
666 for (
const VariableSP &variable_sp : *variable_list) {
669 if (!variable_sp->GetName().IsEmpty())
672 Type *var_type = variable_sp->GetType();
681 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
687 if (var_sp && !valobj_sp) {
694 "no variable named '{0}' found in this frame", name_const_string);
699 while (!var_expr.empty()) {
702 const char separator_type = var_expr[0];
703 bool expr_is_ptr =
false;
704 switch (separator_type) {
707 if (var_expr.size() >= 2 && var_expr[1] !=
'>')
710 if (no_fragile_ivar) {
713 const uint32_t pointer_type_flags =
714 valobj_sp->GetCompilerType().GetTypeInfo(
nullptr);
715 if ((pointer_type_flags & eTypeIsObjC) &&
716 (pointer_type_flags & eTypeIsPointer)) {
725 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
728 valobj_sp->GetSyntheticValue()->Dereference(deref_error);
729 synth_deref_sp && deref_error.
Success()) {
730 valobj_sp = std::move(synth_deref_sp);
732 if (!valobj_sp || deref_error.
Fail()) {
734 "Failed to dereference synthetic value: {0}", deref_error);
747 var_expr = var_expr.drop_front();
750 var_expr = var_expr.drop_front();
751 separator_idx = var_expr.find_first_of(
".-[");
752 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(
".-[")));
754 if (check_ptr_vs_member) {
758 const bool actual_is_ptr = valobj_sp->IsPointerType();
760 if (actual_is_ptr != expr_is_ptr) {
763 valobj_sp->GetExpressionPath(var_expr_path_strm);
766 "\"%s\" is a pointer and . was used to attempt to access "
767 "\"%s\". Did you mean \"%s->%s\"?",
769 var_expr_path_strm.
GetData(), var_expr.str().c_str());
772 "\"%s\" is not a pointer and -> was used to attempt to "
773 "access \"%s\". Did you mean \"%s.%s\"?",
775 var_expr_path_strm.
GetData(), var_expr.str().c_str());
779 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
780 if (!child_valobj_sp) {
781 if (!no_synth_child) {
782 child_valobj_sp = valobj_sp->GetSyntheticValue();
785 child_valobj_sp->GetChildMemberWithName(child_name);
788 if (no_synth_child || !child_valobj_sp) {
790 if (synthetically_added_instance_object) {
795 "no variable or instance variable named '%s' found in "
799 valobj_sp->GetExpressionPath(var_expr_path_strm);
802 "\"%s\" is not a member of \"(%s) %s\"",
804 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
808 "incomplete expression path after \"%s\" in \"%s\"",
810 original_var_expr.str().c_str());
816 synthetically_added_instance_object =
false;
818 var_expr = var_expr.drop_front(child_name.
GetLength());
821 child_valobj_sp->GetDynamicValue(use_dynamic));
822 if (dynamic_value_sp)
823 child_valobj_sp = dynamic_value_sp;
830 if (var_expr.size() <= 2) {
832 "invalid square bracket encountered after \"%s\" in \"%s\"",
833 var_expr_path_strm.
GetData(), var_expr.str().c_str());
838 var_expr = var_expr.drop_front();
839 long child_index = 0;
842 size_t end_pos = var_expr.find_first_of(
']');
843 if (end_pos == llvm::StringRef::npos) {
845 "missing closing square bracket in expression \"%s\"",
849 llvm::StringRef index_expr = var_expr.take_front(end_pos);
850 llvm::StringRef original_index_expr = index_expr;
852 var_expr = var_expr.drop_front(end_pos + 1);
854 if (index_expr.consumeInteger(0, child_index)) {
858 "invalid index expression \"%s\"", index_expr.str().c_str());
862 if (index_expr.empty()) {
865 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
871 if (!temp || deref_error.
Fail()) {
872 valobj_sp->GetExpressionPath(var_expr_path_strm);
874 "could not dereference \"(%s) %s\"",
875 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
881 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
889 valobj_sp->GetExpressionPath(var_expr_path_strm);
891 "could not get item 0 for \"(%s) %s\"",
892 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
900 bool is_incomplete_array =
false;
901 if (valobj_sp->IsPointerType()) {
902 bool is_objc_pointer =
true;
904 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
906 is_objc_pointer =
false;
907 else if (!valobj_sp->GetCompilerType().IsPointerType())
908 is_objc_pointer =
false;
910 if (no_synth_child && is_objc_pointer) {
912 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
914 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
918 }
else if (is_objc_pointer) {
923 || synthetic == valobj_sp)
926 valobj_sp->GetExpressionPath(var_expr_path_strm);
928 "\"(%s) %s\" is not an array type",
929 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
931 }
else if (
static_cast<uint32_t
>(child_index) >=
933 ->GetNumChildrenIgnoringErrors()
936 valobj_sp->GetExpressionPath(var_expr_path_strm);
938 "array index %ld is not valid for \"(%s) %s\"", child_index,
939 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
942 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
943 if (!child_valobj_sp) {
944 valobj_sp->GetExpressionPath(var_expr_path_strm);
946 "array index %ld is not valid for \"(%s) %s\"", child_index,
947 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
953 valobj_sp->GetSyntheticArrayMember(child_index,
true);
954 if (!child_valobj_sp) {
955 valobj_sp->GetExpressionPath(var_expr_path_strm);
957 "failed to use pointer as array for index %ld for "
960 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
964 }
else if (valobj_sp->GetCompilerType().IsArrayType(
965 nullptr,
nullptr, &is_incomplete_array)) {
968 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
969 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
971 valobj_sp->GetSyntheticArrayMember(child_index,
true);
973 if (!child_valobj_sp) {
974 valobj_sp->GetExpressionPath(var_expr_path_strm);
976 "array index %ld is not valid for \"(%s) %s\"", child_index,
977 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
980 }
else if (valobj_sp->GetCompilerType().IsScalarType()) {
982 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
983 child_index, child_index,
true);
984 if (!child_valobj_sp) {
985 valobj_sp->GetExpressionPath(var_expr_path_strm);
987 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
988 child_index, child_index,
989 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
994 if (no_synth_child ||
996 || synthetic == valobj_sp)
999 valobj_sp->GetExpressionPath(var_expr_path_strm);
1001 "\"(%s) %s\" is not an array type",
1002 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1003 var_expr_path_strm.
GetData());
1004 }
else if (
static_cast<uint32_t
>(child_index) >=
1005 synthetic->GetNumChildrenIgnoringErrors()
1007 valobj_sp->GetExpressionPath(var_expr_path_strm);
1009 "array index %ld is not valid for \"(%s) %s\"", child_index,
1010 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1011 var_expr_path_strm.
GetData());
1013 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
1014 if (!child_valobj_sp) {
1015 valobj_sp->GetExpressionPath(var_expr_path_strm);
1017 "array index %ld is not valid for \"(%s) %s\"", child_index,
1018 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1019 var_expr_path_strm.
GetData());
1024 if (!child_valobj_sp) {
1031 child_valobj_sp->GetDynamicValue(use_dynamic));
1032 if (dynamic_value_sp)
1033 child_valobj_sp = dynamic_value_sp;
1041 if (index_expr.front() !=
'-') {
1043 "invalid range expression \"'%s'\"",
1044 original_index_expr.str().c_str());
1048 index_expr = index_expr.drop_front();
1049 long final_index = 0;
1050 if (index_expr.getAsInteger(0, final_index)) {
1052 "invalid range expression \"'%s'\"",
1053 original_index_expr.str().c_str());
1058 if (child_index > final_index) {
1059 long temp = child_index;
1060 child_index = final_index;
1064 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
1071 if (!temp || deref_error.
Fail()) {
1072 valobj_sp->GetExpressionPath(var_expr_path_strm);
1074 "could not dereference \"(%s) %s\"",
1075 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1076 var_expr_path_strm.
GetData());
1081 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1088 valobj_sp->GetExpressionPath(var_expr_path_strm);
1090 "could not get item 0 for \"(%s) %s\"",
1091 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1092 var_expr_path_strm.
GetData());
1100 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index,
true);
1101 if (!child_valobj_sp) {
1102 valobj_sp->GetExpressionPath(var_expr_path_strm);
1104 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1105 final_index, valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1106 var_expr_path_strm.
GetData());
1109 if (!child_valobj_sp) {
1116 child_valobj_sp->GetDynamicValue(use_dynamic));
1117 if (dynamic_value_sp)
1118 child_valobj_sp = dynamic_value_sp;
1127 valobj_sp->GetExpressionPath(var_expr_path_strm);
1129 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1130 separator_type, var_expr_path_strm.
GetData(),
1131 var_expr.str().c_str());
1137 if (child_valobj_sp)
1138 valobj_sp = child_valobj_sp;
1143 if (!deref_valobj_sp && !no_synth_child) {
1144 if (
ValueObjectSP synth_obj_sp = valobj_sp->GetSyntheticValue()) {
1146 deref_valobj_sp = synth_obj_sp->Dereference(
error);
1149 valobj_sp = deref_valobj_sp;
1150 }
else if (address_of) {
1152 valobj_sp = address_of_valobj_sp;
1159 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1162 "No frame base available for this historical stack frame.");
1167 if (
m_sc.function) {
1174 if (!
m_sc.function->GetFrameBaseExpression().IsAlwaysValidSingleExpr())
1178 llvm::Expected<Value> expr_value =
1179 m_sc.function->GetFrameBaseExpression().Evaluate(
1180 &exe_ctx,
nullptr, loclist_base_addr,
nullptr,
nullptr);
1195 return llvm::Error::success();
1199 if (!
m_sc.function) {
1206 return &
m_sc.function->GetFrameBaseExpression();
1210 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1221 return m_sc.line_entry.IsValid();
1234 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1239 true,
true,
nullptr);
1242 const uint32_t var_idx =
1244 const uint32_t num_variables = var_list->
GetSize();
1245 if (var_idx < num_variables) {
1259 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1267 if (
m_sc.block ==
nullptr)
1270 return m_sc.block->GetContainingInlinedBlock() !=
nullptr;
1286 return recognized_frame_sp->ShouldHide();
1295 if (
auto runtime_sp =
1297 return runtime_sp->GetLanguageSpecificData(
1303 const char *name =
nullptr;
1305 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1308 if (inlined_block) {
1316 if (name ==
nullptr) {
1321 if (name ==
nullptr) {
1330 const char *name =
nullptr;
1332 eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol);
1335 if (inlined_block) {
1343 if (name ==
nullptr) {
1348 if (name ==
nullptr) {
1378std::pair<const Instruction::Operand *, int64_t>
1381 switch (operand.
m_type) {
1387 return std::make_pair(
nullptr, 0);
1399 if (!immediate_child) {
1400 return std::make_pair(
nullptr, 0);
1408 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1409 GetBaseExplainingValue(*variable_child, register_context,
1411 if (!base_and_offset.first) {
1412 return std::make_pair(
nullptr, 0);
1415 base_and_offset.second -= immediate_child->
m_immediate;
1417 base_and_offset.second += immediate_child->
m_immediate;
1419 return base_and_offset;
1425 return std::make_pair(
nullptr, 0);
1429 return std::make_pair(
nullptr, 0);
1432 return std::make_pair(&operand, 0);
1434 return std::make_pair(
nullptr, 0);
1438 return std::make_pair(
nullptr, 0);
1441std::pair<const Instruction::Operand *, int64_t>
1446 return GetBaseExplainingValue(operand.
m_children[0], register_context,
1449 return std::make_pair(
nullptr, 0);
1456 const ArchSpec &target_arch = target_sp->GetArchitecture();
1462 const char *plugin_name =
nullptr;
1463 const char *flavor =
nullptr;
1464 const char *cpu =
nullptr;
1465 const char *features =
nullptr;
1466 const bool force_live_memory =
true;
1469 target_arch, plugin_name, flavor, cpu, features, *target_sp, pc_range,
1472 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1477 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1479 llvm::SmallVector<Instruction::Operand, 3> operands;
1481 if (!instruction_sp->ParseOperands(operands)) {
1487 if (!register_context_sp) {
1492 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1493 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1495 if (!base_and_offset.first) {
1499 switch (base_and_offset.first->m_type) {
1502 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1503 base_and_offset.second,
1505 auto c_type_system_or_err =
1507 if (
auto err = c_type_system_or_err.takeError()) {
1509 "Unable to guess value for given address: {0}");
1512 auto ts = *c_type_system_or_err;
1527 base_and_offset.second);
1542 llvm::expectedToOptional(parent->GetByteSize()).value_or(0)) {
1546 if (parent->IsPointerOrReferenceType()) {
1550 for (
int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1558 int64_t child_offset = child_sp->GetByteOffset();
1559 int64_t child_size =
1560 llvm::expectedToOptional(child_sp->GetByteSize()).value_or(0);
1562 if (offset >= child_offset && offset < (child_offset + child_size)) {
1563 return GetValueForOffset(frame, child_sp, offset - child_offset);
1581 if (!base->IsPointerOrReferenceType()) {
1594 llvm::expectedToOptional(pointee->GetByteSize()).value_or(0)) {
1596 llvm::expectedToOptional(pointee->GetByteSize()).value_or(1);
1597 int64_t index = offset / size;
1598 offset = offset % size;
1599 const bool can_create =
true;
1600 pointee = base->GetSyntheticArrayMember(index, can_create);
1603 if (!pointee ||
error.Fail()) {
1607 return GetValueForOffset(frame, pointee, offset);
1679 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1683 const uint32_t current_inst =
1689 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1697 if (instruction_sp->IsCall()) {
1703 const char *return_register_name;
1704 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1710 return_register_name);
1711 if (!return_register_info) {
1727 llvm::SmallVector<Instruction::Operand, 1> operands;
1728 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1732 switch (operands[0].m_type) {
1737 if (!
pc.GetModule())
1739 Address address(operands[0].m_immediate,
1740 pc.GetModule()->GetSectionList());
1741 if (!address.IsValid())
1744 address, eSymbolContextFunction, sc);
1758 std::string name_str(
1760 name_str.append(
"()");
1763 &frame, name_str, return_value_address, return_type);
1764 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1771 llvm::SmallVector<Instruction::Operand, 2> operands;
1772 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1781 if (clobbered_reg_matcher(operands[0])) {
1782 origin_operand = &operands[1];
1783 }
else if (clobbered_reg_matcher(operands[1])) {
1784 origin_operand = &operands[0];
1792 int64_t origin_offset = 0;
1794 if (
FetchRegOp(origin_register)(*origin_operand)) {
1795 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1796 variables, instruction_sp->GetAddress());
1799 FetchRegOp(origin_register))(*origin_operand) ||
1804 FetchImmOp(origin_offset)))(*origin_operand)) {
1806 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1807 variables, instruction_sp->GetAddress());
1811 source_path = GetValueForDereferincingOffset(frame, source_path, offset);
1827 const ArchSpec &target_arch = target_sp->GetArchitecture();
1846 const char *plugin_name =
nullptr;
1847 const char *flavor =
nullptr;
1848 const char *cpu =
nullptr;
1849 const char *features =
nullptr;
1850 const bool force_live_memory =
true;
1852 target_arch, plugin_name, flavor, cpu, features, *target_sp,
1855 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1859 const bool get_file_globals =
false;
1863 const bool include_synthetic_vars =
false;
1871 return DoGuessValueAt(*
this, reg, offset, *disassembler_sp, *variables,
1884 if (!target_sp && !process_sp)
1892 const bool can_create =
true;
1893 const bool get_parent_variables =
true;
1894 const bool stop_if_block_is_inlined_function =
true;
1897 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1898 [
this](
Variable *v) { return v->IsInScope(this); },
1914 ProcessSP process_sp(thread_sp->CalculateProcess());
1916 target_sp = process_sp->CalculateTarget();
1925 process_sp = thread_sp->CalculateProcess();
1939 llvm::StringRef frame_marker) {
1954 const llvm::StringRef frame_marker) {
1955 if (strm ==
nullptr)
1966 frame_format = &format_entry;
1969 frame_format = &format_entry;
1973 Dump(strm,
true,
false);
1979 bool show_fullpaths) {
1980 if (strm ==
nullptr)
1983 if (show_frame_index)
1987 strm->
Printf(
"0x%0*" PRIx64
" ",
1992 const bool show_module =
true;
1993 const bool show_inline =
true;
1994 const bool show_function_arguments =
true;
1995 const bool show_function_name =
true;
1998 show_inline, show_function_arguments,
1999 show_function_name);
2003 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
2015 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
2054 const llvm::StringRef frame_marker) {
2055 if (show_frame_info) {
2062 bool have_source =
false, have_debuginfo =
false;
2067 const uint32_t source_lines_before =
2069 const uint32_t source_lines_after =
2074 if (
m_sc.comp_unit ||
m_sc.line_entry.IsValid()) {
2075 have_debuginfo =
true;
2076 if (source_lines_before > 0 || source_lines_after > 0) {
2078 uint32_t start_line =
m_sc.line_entry.line;
2079 if (!start_line &&
m_sc.function) {
2080 m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
2085 source_file_sp, start_line,
m_sc.line_entry.column,
2086 source_lines_before, source_lines_after,
"->", &strm,
2091 if (!
m_sc.line_entry.line)
2092 strm <<
"note: This address is not associated with a specific line "
2093 "of code. This may be due to compiler optimizations.\n";
2096 switch (disasm_display) {
2113 if (disasm_lines > 0) {
2115 const char *plugin_name =
nullptr;
2116 const char *flavor =
nullptr;
2117 const bool mixed_source_and_assembly =
false;
2119 target->
GetDebugger(), target_arch, plugin_name, flavor,
2123 mixed_source_and_assembly, 0,
2135 auto process =
GetThread()->GetProcess();
2139 auto &manager = process->GetTarget().GetFrameRecognizerManager();
2140 auto new_generation = manager.GetGeneration();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
#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.
lldb::addr_t GetOpcodeLoadAddress(Target *target, AddressClass addr_class=AddressClass::eInvalid) const
Get the load address as an opcode load address.
bool SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, AddressClass addr_class=AddressClass::eInvalid, bool allow_section_end=false)
bool Slide(int64_t offset)
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
lldb::addr_t GetOffset() const
Get the section relative offset value.
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
uint32_t GetMaximumOpcodeByteSize() const
A class that describes a single lexical block.
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
Function * CalculateSymbolContextFunction() override
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.
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.
A class that describes a compilation unit.
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.
bool IsAnonymousType() const
bool IsFunctionType() const
CompilerType GetFunctionReturnType() const
A uniqued constant string class.
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.
uint64_t GetDisassemblyLineCount() const
FormatEntity::Entry GetFrameFormatUnique() const
uint64_t GetStopSourceLineCount(bool before) const
FormatEntity::Entry GetFrameFormat() const
lldb::StopDisassemblyType GetStopDisassemblyDisplay() const
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.
CompilerType GetCompilerType()
bool GetRangeContainingLoadAddress(lldb::addr_t load_addr, Target &target, AddressRange &range)
ConstString GetName() const
const Mangled & GetMangled() const
AddressRanges GetAddressRanges()
ConstString GetDisplayName() const
A class that describes information for an inlined function.
ConstString GetDisplayName() const
ConstString GetName() const
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_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.
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
lldb::VariableListSP m_variable_list_sp
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
bool m_artificial
Is this an artificial stack frame (e.g.
lldb::ThreadSP GetThread() const
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...
@ eExpressionPathOptionsNoFragileObjcIvar
@ eExpressionPathOptionCheckPtrVsMember
@ eExpressionPathOptionsInspectAnonymousUnions
@ eExpressionPathOptionsAllowDirectIVarAccess
@ eExpressionPathOptionsNoSyntheticChildren
virtual const char * GetFunctionName()
Get the frame's demangled name.
virtual bool IsHidden()
Query whether this frame should be hidden from backtraces.
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.
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
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.
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
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.
lldb::RegisterContextSP m_reg_context_sp
static char ID
LLVM RTTI support.
virtual lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
Attempt to reconstruct the ValueObject for the address contained in a given register plus an offset.
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.
@ Regular
A regular stack frame with access to registers and local variables.
@ Synthetic
An synthetic stack frame (e.g.
uint32_t m_concrete_frame_index
bool m_behaves_like_zeroth_frame
Whether this frame behaves like the zeroth frame, in the sense that its pc value might not immediatel...
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:
bool HasCachedData() const
StreamString m_disassembly
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.
Status m_frame_base_error
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
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
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
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.
Status GetFrameVariableError(StackFrame &frame)
Get an error that describes why variables might be missing for a given symbol context.
ConstString GetName() const
ConstString GetDisplayName() const
const char * GetDisassemblyFeatures() const
const char * GetDisassemblyCPU() const
bool GetUseDIL(ExecutionContext *exe_ctx) const
SourceManager & GetSourceManager()
Debugger & GetDebugger() const
const ArchSpec & GetArchitecture() const
CompilerType GetForwardCompilerType()
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
lldb::VariableSP FindVariable(ConstString name, bool include_static_members=true)
uint32_t FindIndexForVariable(Variable *variable)
bool IsInScope(StackFrame *frame)
bool LocationIsValidForFrame(StackFrame *frame)
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.
static llvm::Expected< ASTNodeUP > Parse(llvm::StringRef dil_input_expr, DILLexer lexer, std::shared_ptr< StackFrame > frame_sp, lldb::DynamicValueType use_dynamic, lldb::DILMode mode)
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
#define LLDB_INVALID_ADDRESS
std::function< bool(const Instruction::Operand &)> MatchRegOp(const RegisterInfo &info)
std::function< bool(const Instruction::Operand &)> FetchRegOp(ConstString ®)
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.
NonNullSharedPtr< lldb_private::SupportFile > SupportFileNSP
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
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 BuildSum(const Operand &lhs, const Operand &rhs)
static Operand BuildRegister(ConstString &r)
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