57#include "llvm/ADT/STLExtras.h"
58#include "llvm/ADT/StringRef.h"
59#include "llvm/Support/Compiler.h"
60#include "llvm/Support/Regex.h"
61#include "llvm/TargetParser/Triple.h"
106 Definition(
"flags", EntryType::FrameRegisterFlags),
107 Definition(
"no-debug", EntryType::FrameNoDebug),
110 Definition(
"is-artificial", EntryType::FrameIsArtificial),
117 Definition(
"name-without-args", EntryType::FunctionNameNoArgs),
118 Definition(
"name-with-args", EntryType::FunctionNameWithArgs),
119 Definition(
"mangled-name", EntryType::FunctionMangledName),
120 Definition(
"addr-offset", EntryType::FunctionAddrOffset),
121 Definition(
"concrete-only-addr-offset-no-padding",
122 EntryType::FunctionAddrOffsetConcrete),
123 Definition(
"line-offset", EntryType::FunctionLineOffset),
124 Definition(
"pc-offset", EntryType::FunctionPCOffset),
125 Definition(
"initial-function", EntryType::FunctionInitial),
126 Definition(
"changed", EntryType::FunctionChanged),
127 Definition(
"is-optimized", EntryType::FunctionIsOptimized),
128 Definition(
"is-inlined", EntryType::FunctionIsInlined),
129 Definition(
"prefix", EntryType::FunctionPrefix),
130 Definition(
"scope", EntryType::FunctionScope),
131 Definition(
"basename", EntryType::FunctionBasename),
132 Definition(
"name-qualifiers", EntryType::FunctionNameQualifiers),
133 Definition(
"template-arguments", EntryType::FunctionTemplateArguments),
134 Definition(
"formatted-arguments", EntryType::FunctionFormattedArguments),
135 Definition(
"return-left", EntryType::FunctionReturnLeft),
136 Definition(
"return-right", EntryType::FunctionReturnRight),
137 Definition(
"qualifiers", EntryType::FunctionQualifiers),
138 Definition(
"suffix", EntryType::FunctionSuffix),
144 Definition(
"number", EntryType::LineEntryLineNumber),
145 Definition(
"column", EntryType::LineEntryColumn),
146 Definition(
"start-addr", EntryType::LineEntryStartAddress),
147 Definition(
"end-addr", EntryType::LineEntryEndAddress),
167 Definition(
"protocol_id", EntryType::ThreadProtocolID),
168 Definition(
"index", EntryType::ThreadIndexID),
173 Definition(
"stop-reason", EntryType::ThreadStopReason),
174 Definition(
"stop-reason-raw", EntryType::ThreadStopReasonRaw),
175 Definition(
"return-value", EntryType::ThreadReturnValue),
176 Definition(
"completed-expression", EntryType::ThreadCompletedExpression)};
184 Definition(
"count", EntryType::ProgressCount),
185 Definition(
"message", EntryType::ProgressMessage)};
187#define _TO_STR2(_val) #_val
188#define _TO_STR(_val) _TO_STR2(_val)
245 Definition(
"process", EntryType::ScriptProcess),
246 Definition(
"target", EntryType::ScriptTarget),
247 Definition(
"thread", EntryType::ScriptThread),
249 Definition(
"svar", EntryType::ScriptVariableSynthetic),
250 Definition(
"thread", EntryType::ScriptThread)};
255 Definition(
"addr-file-or-load", EntryType::AddressLoadOrFile),
257 Definition(
"current-pc-arrow", EntryType::CurrentPCArrow),
283 Definition(
"separator", EntryType::Separator),
308 entries.push_back(
Entry(ch));
310 entries.back().string.append(1, ch);
316 entries.push_back(
Entry(s));
318 entries.back().string.append(s.data(), s.size());
327 entries.push_back(entry);
336#define ENUM_TO_CSTR(eee) \
337 case FormatEntity::Entry::Type::eee: \
431 s.
Printf(
"string = \"%s\"",
string.c_str());
437 s.
Printf(
"deref = true, ");
440 for (
const auto &child : children)
441 child.Dump(s, depth + 1);
448 const char *script_function_name) {
454 if (script_interpreter) {
456 std::string script_output;
459 script_output,
error) &&
461 s.
Printf(
"%s", script_output.c_str());
474 bool print_file_addr_or_load_addr) {
489 if (print_file_addr_or_load_addr) {
495 s.
Printf(
"0x%*.*" PRIx64, addr_width, addr_width, vaddr);
504 bool concrete_only,
bool no_padding,
505 bool print_zero_offsets) {
512 if (sc->
block && !concrete_only) {
519 format_addr, inline_range))
527 const char *addr_offset_padding = no_padding ?
"" :
" ";
532 if (addr_file_addr > func_file_addr ||
533 (addr_file_addr == func_file_addr && print_zero_offsets)) {
534 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
535 addr_file_addr - func_file_addr);
536 }
else if (addr_file_addr < func_file_addr) {
537 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
538 func_file_addr - addr_file_addr);
546 if (addr_load_addr > func_load_addr ||
547 (addr_load_addr == func_load_addr && print_zero_offsets)) {
548 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
549 addr_load_addr - func_load_addr);
550 }
else if (addr_load_addr < func_load_addr) {
551 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
552 func_load_addr - addr_load_addr);
563 size_t &close_bracket_index,
564 const char *&var_name_final_if_array_range,
565 int64_t &index_lower, int64_t &index_higher) {
567 close_bracket_index = llvm::StringRef::npos;
568 const size_t open_bracket_index = subpath.find(
'[');
569 if (open_bracket_index == llvm::StringRef::npos) {
571 "[ScanBracketedRange] no bracketed range, skipping entirely");
575 close_bracket_index = subpath.find(
']', open_bracket_index + 1);
577 if (close_bracket_index == llvm::StringRef::npos) {
579 "[ScanBracketedRange] no bracketed range, skipping entirely");
582 var_name_final_if_array_range = subpath.data() + open_bracket_index;
584 if (close_bracket_index - open_bracket_index == 1) {
587 "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
590 const size_t separator_index = subpath.find(
'-', open_bracket_index + 1);
592 if (separator_index == llvm::StringRef::npos) {
593 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
594 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
595 index_higher = index_lower;
597 "[ScanBracketedRange] [%" PRId64
598 "] detected, high index is same",
601 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
602 const char *index_higher_cstr = subpath.data() + separator_index + 1;
603 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
604 index_higher = ::strtoul(index_higher_cstr,
nullptr, 0);
606 "[ScanBracketedRange] [%" PRId64
"-%" PRId64
"] detected",
607 index_lower, index_higher);
609 if (index_lower > index_higher && index_higher > 0) {
610 LLDB_LOGF(log,
"[ScanBracketedRange] swapping indices");
611 const int64_t temp = index_lower;
612 index_lower = index_higher;
650 uint32_t reg_num,
Format format) {
655 const uint32_t lldb_reg_num =
674 bool deref_pointer) {
676 std::string name_to_deref = llvm::formatv(
"[{0}]", index);
677 LLDB_LOG(log,
"[ExpandIndexedExpression] name to deref: {0}", name_to_deref);
685 name_to_deref, &reason_to_stop, &final_value_type, options, &what_next);
688 "[ExpandIndexedExpression] ERROR: why stopping = %d,"
689 " final_value_type %d",
690 reason_to_stop, final_value_type);
693 "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
694 " final_value_type %d",
695 reason_to_stop, final_value_type);
729 std::string formatted;
730 std::string llvm_format = (
"{0:" + options +
"}").str();
734 if (type_info & eTypeIsSigned) {
735 bool success =
false;
738 formatted = llvm::formatv(llvm_format.data(),
integer);
740 bool success =
false;
743 formatted = llvm::formatv(llvm_format.data(),
integer);
747 if (formatted.empty())
750 s.
Write(formatted.data(), formatted.size());
757 if (valobj ==
nullptr)
767 bool do_deref_pointer = entry.
deref;
768 bool is_script =
false;
769 switch (entry.
type) {
775 custom_format = entry.
fmt;
783 custom_format = entry.
fmt;
787 if (valobj ==
nullptr)
805 SyntheticChildrenTraversal::Both);
807 const char *var_name_final_if_array_range =
nullptr;
808 size_t close_bracket_index = llvm::StringRef::npos;
809 int64_t index_lower = -1;
810 int64_t index_higher = -1;
811 bool is_array_range =
false;
812 bool was_plain_var =
false;
813 bool was_var_format =
false;
814 bool was_var_indexed =
false;
824 auto split = llvm::StringRef(entry.
string).split(
':');
825 auto subpath = split.first;
826 auto llvm_format = split.second;
829 if (subpath.empty()) {
832 was_plain_var =
true;
834 was_var_format =
true;
838 if (subpath[0] ==
'[')
839 was_var_indexed =
true;
841 var_name_final_if_array_range, index_lower,
846 LLDB_LOG(log,
"[Debugger::FormatPrompt] symbol to expand: {0}", subpath);
851 &final_value_type, options, &what_next)
856 "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
857 " final_value_type %d",
858 reason_to_stop, final_value_type);
862 "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
863 " final_value_type %d",
864 reason_to_stop, final_value_type);
881 if (do_deref_pointer && !is_array_range) {
888 LLDB_LOGF(log,
"[Debugger::FormatPrompt] ERROR: %s\n",
889 error.AsCString(
"unknown"));
892 do_deref_pointer =
false;
896 LLDB_LOGF(log,
"[Debugger::FormatPrompt] could not calculate target for "
897 "prompt expression");
904 if (target->
IsBitfield() && was_var_indexed) {
909 auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
911 if (val_obj_display ==
918 const uint32_t type_info_flags =
920 bool is_array = (type_info_flags & eTypeIsArray) != 0;
921 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
924 if ((is_array || is_pointer) && (!is_array_range) &&
933 "[Debugger::FormatPrompt] I am into array || pointer && !range");
939 str_temp, val_obj_display, custom_format);
940 LLDB_LOGF(log,
"[Debugger::FormatPrompt] special cases did%s match",
941 success ?
"" :
"n't");
951 }
else if (is_pointer)
954 s, val_obj_display, custom_format,
963 if (is_aggregate && was_plain_var) {
974 s <<
"<invalid use of aggregate type>";
978 if (!is_array_range) {
979 if (!llvm_format.empty()) {
981 LLDB_LOGF(log,
"dumping using llvm format");
986 "empty output using llvm format '{0}' - with type info flags {1}",
990 LLDB_LOGF(log,
"dumping ordinary printable output");
995 "[Debugger::FormatPrompt] checking if I can handle as array");
996 if (!is_array && !is_pointer)
998 LLDB_LOGF(log,
"[Debugger::FormatPrompt] handle as array");
1000 llvm::StringRef special_directions;
1001 if (close_bracket_index != llvm::StringRef::npos &&
1002 subpath.size() > close_bracket_index) {
1003 ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
1004 special_directions_stream.
Printf(
"${%svar%s", do_deref_pointer ?
"*" :
"",
1008 const char format_char =
1010 if (format_char !=
'\0')
1011 special_directions_stream.
Printf(
"%%%c", format_char);
1013 const char *format_cstr =
1015 special_directions_stream.
Printf(
"%%%s", format_cstr);
1017 }
else if (entry.
number != 0) {
1021 special_directions_stream.
Printf(
"%%%c", style_char);
1023 special_directions_stream.
PutChar(
'}');
1024 special_directions =
1025 llvm::StringRef(special_directions_stream.
GetString());
1031 if (index_higher < 0)
1034 uint32_t max_num_children =
1035 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1037 bool success =
true;
1038 for (int64_t index = index_lower; index <= index_higher; ++index) {
1043 "[Debugger::FormatPrompt] ERROR in getting child item at "
1049 "[Debugger::FormatPrompt] special_directions for child item: %s",
1050 special_directions.data() ? special_directions.data() :
"");
1053 if (special_directions.empty()) {
1058 special_directions, s, sc, exe_ctx,
nullptr, item,
false,
false);
1061 if (--max_num_children == 0) {
1066 if (index < index_higher)
1097 llvm::StringRef path(entry.
string);
1100 thread_info_dictionary->GetObjectForDotSeparatedPath(path);
1104 const char *token_format =
"0x%4.4" PRIx64;
1107 s.
Printf(token_format, value->GetUnsignedIntegerValue());
1110 s.
Printf(
"%f", value->GetAsFloat()->GetValue());
1113 s.
Format(
"{0}", value->GetAsString()->GetValue());
1116 if (value->GetAsArray()->GetSize() > 0) {
1117 s.
Printf(
"%zu", value->GetAsArray()->GetSize());
1122 value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1130static inline bool IsToken(
const char *var_name_begin,
const char *var) {
1131 return (::strncmp(var_name_begin, var, strlen(var)) == 0);
1141static std::pair<char const *, char const *>
1143 const char *open_paren = strchr(full_name,
'(');
1144 const char *close_paren =
nullptr;
1145 const char *
generic = strchr(full_name,
'<');
1149 if (generic && open_paren && generic < open_paren) {
1150 int generic_depth = 1;
1152 for (; *
generic && generic_depth > 0;
generic++) {
1153 if (*generic ==
'<')
1155 if (*generic ==
'>')
1159 open_paren = strchr(generic,
'(');
1161 open_paren =
nullptr;
1165 if (
IsToken(open_paren,
"(anonymous namespace)")) {
1166 open_paren = strchr(open_paren + strlen(
"(anonymous namespace)"),
'(');
1168 close_paren = strchr(open_paren,
')');
1170 close_paren = strchr(open_paren,
')');
1173 return {open_paren, close_paren};
1180 char const *full_name,
1185 out_stream.
Write(full_name, open_paren - full_name + 1);
1204 return inline_block->GetBlockVariableList(
true);
1240 Language *language_plugin =
nullptr;
1241 bool language_plugin_handled =
false;
1248 if (language_plugin)
1252 if (language_plugin_handled) {
1277 Language *language_plugin =
nullptr;
1283 if (!language_plugin)
1293 const bool success =
1307 bool function_changed,
1308 bool initial_function) {
1309 if (!format_str.empty()) {
1312 if (
error.Success()) {
1314 function_changed, initial_function);
1324 bool initial_function) {
1325 switch (entry.
type) {
1334 Debugger &debugger = target->GetDebugger();
1344 if (!
Format(child, s, sc, exe_ctx, addr, valobj, function_changed,
1345 initial_function)) {
1357 auto format_children = [&](
const std::vector<Entry> &children) {
1358 scope_stream.
Clear();
1359 for (
const auto &child : children) {
1360 if (!
Format(child, scope_stream, sc, exe_ctx, addr, valobj,
1361 function_changed, initial_function))
1368 if (format_children(children)) {
1382 return DumpValue(s, sc, exe_ctx, entry, valobj);
1388 addr !=
nullptr && addr->
IsValid() &&
1396 const char *format =
"%" PRIu64;
1431 const char *format =
"0x%4.4" PRIx64;
1438 Target &target = thread->GetProcess()->GetTarget();
1440 llvm::Triple::OSType ostype = arch.
IsValid()
1442 : llvm::Triple::UnknownOS;
1443 if (ostype == llvm::Triple::FreeBSD ||
1444 ostype == llvm::Triple::Linux ||
1445 ostype == llvm::Triple::NetBSD ||
1446 ostype == llvm::Triple::OpenBSD) {
1447 format =
"%" PRIu64;
1453 s.
Printf(format, thread->GetID());
1463 const char *format =
"0x%4.4" PRIx64;
1466 s.
Printf(format, thread->GetProtocolID());
1476 const char *format =
"%" PRIu32;
1479 s.
Printf(format, thread->GetIndexID());
1489 const char *cstr = thread->GetName();
1490 if (cstr && cstr[0]) {
1502 const char *cstr = thread->GetQueueName();
1503 if (cstr && cstr[0]) {
1514 std::string stop_description = thread->GetStopDescription();
1515 if (!stop_description.empty()) {
1526 std::string stop_description = thread->GetStopDescriptionRaw();
1527 if (!stop_description.empty()) {
1539 StopInfoSP stop_info_sp = thread->GetStopInfo();
1540 if (stop_info_sp && stop_info_sp->IsValid()) {
1543 if (return_valobj_sp) {
1544 if (llvm::Error
error = return_valobj_sp->Dump(s)) {
1559 StopInfoSP stop_info_sp = thread->GetStopInfo();
1560 if (stop_info_sp && stop_info_sp->IsValid()) {
1563 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1564 if (llvm::Error
error =
1565 expression_var_sp->GetValueObject()->Dump(s)) {
1615 if (
Module *exe_module = target->GetExecutableModulePointer()) {
1656 const char *lang_name =
1670 const char *format =
"%" PRIu32;
1748 return frame->IsArtificial();
1755 if (frame->IsSynthetic())
1757 else if (frame->IsHistorical())
1786 return function_changed;
1789 return initial_function;
1795 Language *language_plugin =
nullptr;
1796 bool language_plugin_handled =
false;
1804 if (language_plugin)
1808 if (language_plugin_handled) {
1828 Language *language_plugin =
nullptr;
1829 bool language_plugin_handled =
false;
1836 if (language_plugin)
1841 if (language_plugin_handled) {
1868 Language *language_plugin =
nullptr;
1874 if (!language_plugin)
1940 return function_changed;
1943 bool is_optimized =
false;
1945 is_optimized =
true;
1947 return is_optimized;
1955 return initial_function;
1969 const char *format =
"%" PRIu32;
1979 const char *format =
"%" PRIu32;
2004 addr_t pc_loadaddr = reg_ctx->GetPC();
2021 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2023 s.
Format(
"[{0:N}/{1:N}]", progress->completed, progress->total);
2032 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2041 s << target->GetDebugger().GetSeparator();
2054 for (
size_t i = 0; i < n; ++i) {
2068 const size_t sep_pos = format_str.find_first_of(
".[:");
2069 const char sep_char =
2070 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
2071 llvm::StringRef key = format_str.substr(0, sep_pos);
2074 for (
size_t i = 0; i < n; ++i) {
2076 if (key == entry_def->
name || entry_def->
name[0] ==
'*') {
2077 llvm::StringRef value;
2080 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
2081 switch (entry_def->
type) {
2083 entry.
string = format_str.str();
2100 if (value.empty()) {
2104 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
2105 "access one of its children: ",
2110 }
else if (sep_char ==
':') {
2117 "%s",
"invalid entry definitions");
2123 }
else if (sep_char ==
':') {
2127 entry.
string = value.str();
2130 "'%s' followed by '%s' but it has no children", key.str().c_str(),
2131 value.str().c_str());
2140 "invalid top level item '%s'. Valid top level items are: ",
2143 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
2144 key.str().c_str(), parent->
name);
2152 llvm::StringRef &remainder) {
2155 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2157 for (
size_t i = 0; i < n; ++i) {
2159 if (p.first == entry_def->
name || entry_def->
name[0] ==
'*') {
2160 if (p.second.empty()) {
2161 if (format_str.back() ==
'.')
2162 remainder = format_str.drop_front(format_str.size() - 1);
2164 remainder = llvm::StringRef();
2168 return FindEntry(p.second, entry_def, remainder);
2170 remainder = p.second;
2176 remainder = format_str;
2183 while (!format.empty() &&
error.Success()) {
2184 const size_t non_special_chars = format.find_first_of(
"${}\\|");
2186 if (non_special_chars == llvm::StringRef::npos) {
2192 if (non_special_chars > 0) {
2195 parent_entry.
AppendText(format.substr(0, non_special_chars));
2196 format = format.drop_front(non_special_chars);
2199 switch (format[0]) {
2204 format = format.drop_front();
2222 format = format.drop_front();
2230 format = format.drop_front();
2231 if (format.empty()) {
2233 "'\\' character was not followed by another character");
2237 const char desens_char = format[0];
2238 format = format.drop_front();
2239 switch (desens_char) {
2272 char oct_str[5] = {0, 0, 0, 0, 0};
2275 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2276 oct_str[i] = format[i];
2281 format = format.drop_front(i);
2282 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2283 if (octal_value <= UINT8_MAX) {
2287 "octal number is larger than a single byte");
2295 if (isxdigit(format[0])) {
2298 char hex_str[3] = {0, 0, 0};
2299 hex_str[0] = format[0];
2301 format = format.drop_front();
2303 if (isxdigit(format[0])) {
2304 hex_str[1] = format[0];
2305 format = format.drop_front();
2308 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2309 if (hex_value <= UINT8_MAX) {
2313 "hex number is larger than a single byte");
2330 format = format.drop_front();
2331 if (format.empty() || format.front() !=
'{') {
2335 format = format.drop_front();
2337 llvm::StringRef variable, variable_format;
2342 bool verify_is_thread_id =
false;
2344 if (!variable_format.empty()) {
2356 bool clear_printf =
false;
2361 entry.
number = ValueObject::
2362 eValueObjectRepresentationStyleLanguageSpecific;
2363 clear_printf =
true;
2369 clear_printf =
true;
2374 clear_printf =
true;
2379 clear_printf =
true;
2384 clear_printf =
true;
2388 clear_printf =
true;
2392 clear_printf =
true;
2397 clear_printf =
true;
2405 clear_printf =
true;
2407 verify_is_thread_id =
true;
2423 if (variable[0] ==
'*') {
2425 variable = variable.drop_front();
2432 llvm::StringRef entry_string(entry.
string);
2433 if (entry_string.contains(
':')) {
2434 auto [_, llvm_format] = entry_string.split(
':');
2437 "invalid llvm format: '%s'", llvm_format.data());
2442 if (verify_is_thread_id) {
2446 "the 'tid' format can only be used on "
2447 "${thread.id} and ${thread.protocol_id}");
2451 switch (entry.
type) {
2455 if (entry.
string.empty())
2467 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2468 variable.str().c_str());
2481 llvm::StringRef &variable_name,
2482 llvm::StringRef &variable_format) {
2484 variable_name = llvm::StringRef();
2485 variable_format = llvm::StringRef();
2487 const size_t paren_pos = format_str.find(
'}');
2488 if (paren_pos != llvm::StringRef::npos) {
2489 const size_t percent_pos = format_str.find(
'%');
2490 if (percent_pos < paren_pos) {
2491 if (percent_pos > 0) {
2492 if (percent_pos > 1)
2493 variable_name = format_str.substr(0, percent_pos);
2495 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2498 variable_name = format_str.substr(0, paren_pos);
2501 format_str = format_str.substr(paren_pos + 1);
2504 "missing terminating '}' character for '${%s'",
2505 format_str.str().c_str());
2511 llvm::StringRef variable_name,
2512 llvm::StringRef variable_format) {
2513 if (variable_name.empty() || variable_name ==
".fullpath") {
2516 }
else if (variable_name ==
".basename") {
2519 }
else if (variable_name ==
".dirname") {
2527 const char *suffix) {
2528 std::string match(prefix.str());
2529 match.append(suffix);
2534 const llvm::StringRef &match_prefix,
2538 for (
size_t i = 0; i < n; ++i) {
2539 if (match_prefix.empty())
2541 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2542 match_prefix.size()) == 0)
2552 const size_t dollar_pos = str.rfind(
'$');
2553 if (dollar_pos == llvm::StringRef::npos)
2557 if (dollar_pos == str.size() - 1) {
2558 std::string match = str.str();
2564 if (str[dollar_pos + 1] !=
'{')
2567 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2568 if (close_pos != llvm::StringRef::npos)
2571 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2572 if (format_pos != llvm::StringRef::npos)
2575 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2576 if (partial_variable.empty()) {
2585 llvm::StringRef remainder;
2592 if (remainder.empty()) {
2601 }
else if (remainder ==
".") {
2604 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2610 AddMatches(entry_def, str, remainder, new_matches);
2618 const size_t num_args = args.
GetSize();
2619 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
2625 llvm::StringRef var_representation;
2626 const char *var_name = var_value_sp->GetName().GetCString();
2627 if (var_value_sp->GetCompilerType().IsValid()) {
2629 var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
2631 ->TargetProperties::GetPreferDynamicValue(),
2633 ->TargetProperties::GetEnableSyntheticValue());
2634 if (var_value_sp->GetCompilerType().IsAggregateType() &&
2637 .SetHideItemNames(
false)
2638 .SetShowMembersOneLiner(
true),
2641 var_representation = buffer;
2643 var_value_sp->DumpPrintableRepresentation(
2646 eValueObjectRepresentationStyleSummary,
2655 if (var_value_sp->GetError().Success()) {
2656 if (!var_representation.empty())
2657 out_stream.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
2659 out_stream.
Printf(
"%s=%s at %s", var_name,
2660 var_value_sp->GetTypeName().GetCString(),
2661 var_value_sp->GetLocationAsCString());
2663 out_stream.
Printf(
"%s=<unavailable>", var_name);
2670 llvm::StringRef modifiable_format(format_str);
#define ANSI_BG_COLOR_PURPLE
#define ANSI_CTRL_UNDERLINE
#define ANSI_BG_COLOR_RED
#define ANSI_FG_COLOR_BLACK
#define ANSI_BG_COLOR_YELLOW
#define ANSI_BG_COLOR_BLACK
#define ANSI_FG_COLOR_YELLOW
#define ANSI_FG_COLOR_PURPLE
#define ANSI_BG_COLOR_CYAN
#define ANSI_BG_COLOR_GREEN
#define ANSI_CTRL_SLOW_BLINK
#define ANSI_FG_COLOR_RED
#define ANSI_BG_COLOR_BLUE
#define ANSI_FG_COLOR_CYAN
#define ANSI_CTRL_FAST_BLINK
#define ANSI_CTRL_CROSSED_OUT
#define ANSI_CTRL_IMAGE_NEGATIVE
#define ANSI_BG_COLOR_WHITE
#define ANSI_CTRL_CONCEAL
#define ANSI_FG_COLOR_GREEN
#define ANSI_FG_COLOR_BLUE
#define ANSI_FG_COLOR_WHITE
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
@ DumpStyleModuleWithFileAddress
Display as the file address with the module name prepended (if any).
@ DumpStyleLoadAddress
Display as the load address (if resolved).
bool Slide(int64_t offset)
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
lldb::addr_t GetFileAddress() const
Get the file address.
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.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A class that describes a single lexical block.
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
const InlineFunctionInfo * GetInlinedFunctionInfo() const
Get const accessor for any inlined function information.
bool GetRangeContainingAddress(const Address &addr, AddressRange &range)
A class that describes a compilation unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
lldb::LanguageType GetLanguage()
bool IsAggregateType() const
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
void AddCompletions(const StringList &completions)
Adds multiple possible completion strings.
llvm::StringRef GetCursorArgumentPrefix() const
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
static bool ShouldPrintAsOneLiner(ValueObject &valobj)
static lldb::TypeSummaryImplSP GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp)
A class to manage flag bits.
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual lldb::TargetSP CalculateTarget()=0
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
const ConstString & GetFilename() const
Filename string const get accessor.
const ConstString & GetDirectory() const
Directory string const get accessor.
void Dump(llvm::raw_ostream &s) const
Dump this object to a Stream.
bool GetIsOptimized()
Get whether compiler optimizations were enabled for this function.
const Address & GetAddress() const
Return the address of the function (its entry point).
lldb::LanguageType GetLanguage() const
Block & GetBlock(bool can_create)
Get accessor for the block list.
virtual bool HandleFrameFormatVariable(const SymbolContext &sc, const ExecutionContext *exe_ctx, FormatEntity::Entry::Type type, Stream &s)
static Language * FindPlugin(lldb::LanguageType language)
static const char * GetNameForLanguageType(lldb::LanguageType language)
Returns the internal LLDB name for the specified language.
virtual bool GetFunctionDisplayName(const SymbolContext &sc, const ExecutionContext *exe_ctx, FunctionNameRepresentation representation, Stream &s)
virtual FormatEntity::Entry GetFunctionNameFormat() const
@ ePreferDemangledWithoutArguments
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
A class that describes an executable image and its associated object and symbol files.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
A plug-in interface definition class for debugging a process.
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Target & GetTarget()
Get the target object pointer for this module.
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
virtual bool RunScriptFormatKeyword(const char *impl_function, Process *process, std::string &output, Status &error)
This base class provides an interface to stack frames.
bool IsSynthetic() const
Query whether this frame is synthetic.
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
const lldb::RegisterContextSP & GetRegisterContextSP() const
const Address & GetFrameCodeAddress()
Get an Address for the current pc value in this StackFrame.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static lldb::ExpressionVariableSP GetExpressionVariable(lldb::StopInfoSP &stop_info_sp)
static lldb::ValueObjectSP GetReturnValueObject(lldb::StopInfoSP &stop_info_sp)
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
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.
void AppendString(const std::string &s)
std::shared_ptr< Object > ObjectSP
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.
LineEntry line_entry
The LineEntry for a given query.
Mangled GetPossiblyInlinedFunctionName() const
If available, will return the function name according to the specified mangling preference.
bool ValueIsAddress() const
lldb::LanguageType GetLanguage() const
Address & GetAddressRef()
ConstString GetName() const
Module * GetExecutableModulePointer()
static Target * GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
Debugger & GetDebugger() const
const ArchSpec & GetArchitecture() const
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
virtual uint32_t GetBitfieldBitSize()
bool DumpPrintableRepresentation(Stream &s, ValueObjectRepresentationStyle val_obj_display=eValueObjectRepresentationStyleSummary, lldb::Format custom_format=lldb::eFormatInvalid, PrintableRepresentationSpecialCases special=PrintableRepresentationSpecialCases::eAllow, bool do_dump_error=true)
CompilerType GetCompilerType()
lldb::ValueObjectSP GetSyntheticValue()
ExpressionPathScanEndReason
@ eExpressionPathScanEndReasonEndOfString
Out of data to parse.
@ eExpressionPathAftermathNothing
Just return it.
@ eExpressionPathAftermathDereference
Dereference the target.
lldb::ValueObjectSP GetValueForExpressionPath(llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop=nullptr, ExpressionPathEndResultType *final_value_type=nullptr, const GetValueForExpressionPathOptions &options=GetValueForExpressionPathOptions::DefaultOptions(), ExpressionPathAftermath *final_task_on_target=nullptr)
virtual uint64_t GetValueAsUnsigned(uint64_t fail_value, bool *success=nullptr)
virtual ConstString GetTypeName()
lldb::DynamicValueType GetDynamicValueType()
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr)
lldb::ValueObjectSP GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue, bool synthValue)
lldb::TargetSP GetTargetSP() const
ExpressionPathEndResultType
@ eExpressionPathEndResultTypePlain
Anything but...
@ eExpressionPathEndResultTypeBoundedRange
A range [low-high].
@ eExpressionPathEndResultTypeUnboundedRange
A range [].
virtual lldb::ValueObjectSP Dereference(Status &error)
bool HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display, lldb::Format custom_format)
virtual const char * GetLocationAsCString()
virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success=nullptr)
ValueObjectRepresentationStyle
@ eValueObjectRepresentationStyleLocation
@ eValueObjectRepresentationStyleSummary
@ eValueObjectRepresentationStyleName
@ eValueObjectRepresentationStyleType
@ eValueObjectRepresentationStyleChildrenCount
@ eValueObjectRepresentationStyleExpressionPath
@ eValueObjectRepresentationStyleValue
@ eValueObjectRepresentationStyleLanguageSpecific
virtual bool IsSynthetic()
uint32_t GetNumChildrenIgnoringErrors(uint32_t max=UINT32_MAX)
Like GetNumChildren but returns 0 on error.
lldb::VariableSP GetVariableAtIndex(size_t idx) const
size_t AppendVariablesWithScope(lldb::ValueType type, VariableList &var_list, bool if_unique=true)
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_FP
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.
const char * toString(AppleArm64ExceptionClass EC)
void DumpRegisterValue(const RegisterValue ®_val, Stream &s, const RegisterInfo ®_info, bool prefix_with_name, bool prefix_with_alt_name, lldb::Format format, uint32_t reg_name_right_align_at=0, ExecutionContextScope *exe_scope=nullptr, bool print_flags=false, lldb::TargetSP target_sp=nullptr)
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
Format
Display format definitions.
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
@ eStructuredDataTypeFloat
@ eStructuredDataTypeDictionary
@ eStructuredDataTypeInteger
@ eStructuredDataTypeArray
@ eStructuredDataTypeString
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eValueTypeVariableArgument
function argument variables
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
const char * name
The name/string placeholder that corresponds to this definition.
const Definition * children
An array of "num_children" Definition entries.
const bool keep_separator
Whether the separator is kept during parsing or not.
const char * string
Insert this exact string into the output.
const uint64_t data
Data that is returned as the value of the format string.
const uint32_t num_children
The number of children of this node in the tree of format strings.
const Entry::Type type
Entry::Type corresponding to this definition.
void Dump(Stream &s, int depth=0) const
Entry(Type t=Type::Invalid, const char *s=nullptr, const char *f=nullptr)
void AppendText(const llvm::StringRef &s)
static constexpr Definition DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t, const Definition(&children)[N], bool keep_separator=false)
std::string printf_format
llvm::SmallVector< std::vector< Entry >, 1 > children_stack
A stack of children entries, used by Scope entries to provide alterantive children.
std::vector< Entry > & GetChildren()
static const char * TypeToCString(Type t)
void AppendEntry(const Entry &&entry)
@ FunctionAddrOffsetConcrete
@ FunctionInitialFunction
@ FunctionTemplateArguments
@ FunctionFormattedArguments
@ ThreadCompletedExpression
@ ScriptVariableSynthetic
uint16_t column
The column number of the source line, or zero if there is no column information.
bool IsValid() const
Check if a line entry object is valid.
AddressRange range
The section offset address range for this line entry.
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
const FileSpec & GetFile() const
Helper to access the file.
Every register is described in detail including its name, alternate name (optional),...
lldb::user_id_t GetID() const
Get accessor for the user ID.
GetValueForExpressionPathOptions & SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse)
GetValueForExpressionPathOptions & DoAllowFragileIVar()
GetValueForExpressionPathOptions & DontCheckDotVsArrowSyntax()
GetValueForExpressionPathOptions & DoAllowBitfieldSyntax()