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"
105 Definition(
"flags", EntryType::FrameRegisterFlags),
106 Definition(
"no-debug", EntryType::FrameNoDebug),
109 Definition(
"is-artificial", EntryType::FrameIsArtificial),
115 Definition(
"name-without-args", EntryType::FunctionNameNoArgs),
116 Definition(
"name-with-args", EntryType::FunctionNameWithArgs),
117 Definition(
"mangled-name", EntryType::FunctionMangledName),
118 Definition(
"addr-offset", EntryType::FunctionAddrOffset),
119 Definition(
"concrete-only-addr-offset-no-padding",
120 EntryType::FunctionAddrOffsetConcrete),
121 Definition(
"line-offset", EntryType::FunctionLineOffset),
122 Definition(
"pc-offset", EntryType::FunctionPCOffset),
123 Definition(
"initial-function", EntryType::FunctionInitial),
124 Definition(
"changed", EntryType::FunctionChanged),
125 Definition(
"is-optimized", EntryType::FunctionIsOptimized)};
130 Definition(
"number", EntryType::LineEntryLineNumber),
131 Definition(
"column", EntryType::LineEntryColumn),
132 Definition(
"start-addr", EntryType::LineEntryStartAddress),
133 Definition(
"end-addr", EntryType::LineEntryEndAddress),
153 Definition(
"protocol_id", EntryType::ThreadProtocolID),
154 Definition(
"index", EntryType::ThreadIndexID),
159 Definition(
"stop-reason", EntryType::ThreadStopReason),
160 Definition(
"stop-reason-raw", EntryType::ThreadStopReasonRaw),
161 Definition(
"return-value", EntryType::ThreadReturnValue),
162 Definition(
"completed-expression", EntryType::ThreadCompletedExpression)};
167#define _TO_STR2(_val) #_val
168#define _TO_STR(_val) _TO_STR2(_val)
225 Definition(
"process", EntryType::ScriptProcess),
226 Definition(
"target", EntryType::ScriptTarget),
227 Definition(
"thread", EntryType::ScriptThread),
229 Definition(
"svar", EntryType::ScriptVariableSynthetic),
230 Definition(
"thread", EntryType::ScriptThread)};
235 Definition(
"addr-file-or-load", EntryType::AddressLoadOrFile),
237 Definition(
"current-pc-arrow", EntryType::CurrentPCArrow),
266 : string(s.
data(), s.size()), printf_format(), children(),
267 type(
Type::String) {}
270 : string(1, ch), printf_format(), children(), type(
Type::String) {}
274 children.push_back(
Entry(ch));
276 children.back().string.append(1, ch);
281 children.push_back(
Entry(s));
283 children.back().string.append(s.data(), s.size());
287 return AppendText(llvm::StringRef(cstr));
290#define ENUM_TO_CSTR(eee) \
291 case FormatEntity::Entry::Type::eee: \
365 s.
Printf(
"%*.*s%-20s: ", depth * 2, depth * 2,
"", TypeToCString(type));
369 s.
Printf(
"string = \"%s\"",
string.c_str());
370 if (!printf_format.empty())
371 s.
Printf(
"printf_format = \"%s\"", printf_format.c_str());
373 s.
Printf(
"number = %" PRIu64
" (0x%" PRIx64
"), ", number, number);
375 s.
Printf(
"deref = true, ");
377 for (
const auto &child : children) {
378 child.Dump(s, depth + 1);
385 const char *script_function_name) {
391 if (script_interpreter) {
393 std::string script_output;
396 script_output,
error) &&
398 s.
Printf(
"%s", script_output.c_str());
411 bool print_file_addr_or_load_addr) {
421 if (exe_ctx && target) {
426 if (print_file_addr_or_load_addr) {
433 s.
Printf(
"0x%*.*" PRIx64, addr_width, addr_width, vaddr);
443 bool concrete_only,
bool no_padding,
444 bool print_zero_offsets) {
451 if (sc->
block && !concrete_only) {
458 format_addr, inline_range))
466 const char *addr_offset_padding = no_padding ?
"" :
" ";
471 if (addr_file_addr > func_file_addr ||
472 (addr_file_addr == func_file_addr && print_zero_offsets)) {
473 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
474 addr_file_addr - func_file_addr);
475 }
else if (addr_file_addr < func_file_addr) {
476 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
477 func_file_addr - addr_file_addr);
485 if (addr_load_addr > func_load_addr ||
486 (addr_load_addr == func_load_addr && print_zero_offsets)) {
487 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
488 addr_load_addr - func_load_addr);
489 }
else if (addr_load_addr < func_load_addr) {
490 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
491 func_load_addr - addr_load_addr);
502 size_t &close_bracket_index,
503 const char *&var_name_final_if_array_range,
504 int64_t &index_lower, int64_t &index_higher) {
506 close_bracket_index = llvm::StringRef::npos;
507 const size_t open_bracket_index = subpath.find(
'[');
508 if (open_bracket_index == llvm::StringRef::npos) {
510 "[ScanBracketedRange] no bracketed range, skipping entirely");
514 close_bracket_index = subpath.find(
']', open_bracket_index + 1);
516 if (close_bracket_index == llvm::StringRef::npos) {
518 "[ScanBracketedRange] no bracketed range, skipping entirely");
521 var_name_final_if_array_range = subpath.data() + open_bracket_index;
523 if (close_bracket_index - open_bracket_index == 1) {
526 "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
529 const size_t separator_index = subpath.find(
'-', open_bracket_index + 1);
531 if (separator_index == llvm::StringRef::npos) {
532 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
533 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
534 index_higher = index_lower;
536 "[ScanBracketedRange] [%" PRId64
537 "] detected, high index is same",
540 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
541 const char *index_higher_cstr = subpath.data() + separator_index + 1;
542 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
543 index_higher = ::strtoul(index_higher_cstr,
nullptr, 0);
545 "[ScanBracketedRange] [%" PRId64
"-%" PRId64
"] detected",
546 index_lower, index_higher);
548 if (index_lower > index_higher && index_higher > 0) {
549 LLDB_LOGF(log,
"[ScanBracketedRange] swapping indices");
550 const int64_t temp = index_lower;
551 index_lower = index_higher;
561 case FileKind::FileError:
564 case FileKind::Basename:
571 case FileKind::Dirname:
578 case FileKind::Fullpath:
589 uint32_t reg_num,
Format format) {
594 const uint32_t lldb_reg_num =
613 bool deref_pointer) {
615 std::string name_to_deref = llvm::formatv(
"[{0}]", index);
616 LLDB_LOG(log,
"[ExpandIndexedExpression] name to deref: {0}", name_to_deref);
624 name_to_deref, &reason_to_stop, &final_value_type, options, &what_next);
627 "[ExpandIndexedExpression] ERROR: why stopping = %d,"
628 " final_value_type %d",
629 reason_to_stop, final_value_type);
632 "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
633 " final_value_type %d",
634 reason_to_stop, final_value_type);
668 std::string formatted;
669 std::string llvm_format = (
"{0:" + options +
"}").str();
673 if (type_info & eTypeIsSigned) {
674 bool success =
false;
677 formatted = llvm::formatv(llvm_format.data(),
integer);
679 bool success =
false;
682 formatted = llvm::formatv(llvm_format.data(),
integer);
686 if (formatted.empty())
689 s.
Write(formatted.data(), formatted.size());
696 if (valobj ==
nullptr)
706 bool do_deref_pointer = entry.
deref;
707 bool is_script =
false;
708 switch (entry.
type) {
714 custom_format = entry.
fmt;
722 custom_format = entry.
fmt;
726 if (valobj ==
nullptr)
744 SyntheticChildrenTraversal::Both);
746 const char *var_name_final_if_array_range =
nullptr;
747 size_t close_bracket_index = llvm::StringRef::npos;
748 int64_t index_lower = -1;
749 int64_t index_higher = -1;
750 bool is_array_range =
false;
751 bool was_plain_var =
false;
752 bool was_var_format =
false;
753 bool was_var_indexed =
false;
763 auto split = llvm::StringRef(entry.
string).split(
':');
764 auto subpath = split.first;
765 auto llvm_format = split.second;
768 if (subpath.empty()) {
771 was_plain_var =
true;
773 was_var_format =
true;
777 if (subpath[0] ==
'[')
778 was_var_indexed =
true;
780 var_name_final_if_array_range, index_lower,
785 LLDB_LOG(log,
"[Debugger::FormatPrompt] symbol to expand: {0}", subpath);
790 &final_value_type, options, &what_next)
795 "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
796 " final_value_type %d",
797 reason_to_stop, final_value_type);
801 "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
802 " final_value_type %d",
803 reason_to_stop, final_value_type);
820 if (do_deref_pointer && !is_array_range) {
827 LLDB_LOGF(log,
"[Debugger::FormatPrompt] ERROR: %s\n",
828 error.AsCString(
"unknown"));
831 do_deref_pointer =
false;
835 LLDB_LOGF(log,
"[Debugger::FormatPrompt] could not calculate target for "
836 "prompt expression");
843 if (target->
IsBitfield() && was_var_indexed) {
848 auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
850 if (val_obj_display ==
857 const uint32_t type_info_flags =
859 bool is_array = (type_info_flags & eTypeIsArray) != 0;
860 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
863 if ((is_array || is_pointer) && (!is_array_range) &&
872 "[Debugger::FormatPrompt] I am into array || pointer && !range");
878 str_temp, val_obj_display, custom_format);
879 LLDB_LOGF(log,
"[Debugger::FormatPrompt] special cases did%s match",
880 success ?
"" :
"n't");
890 }
else if (is_pointer)
893 s, val_obj_display, custom_format,
902 if (is_aggregate && was_plain_var) {
913 s <<
"<invalid use of aggregate type>";
917 if (!is_array_range) {
918 if (!llvm_format.empty()) {
920 LLDB_LOGF(log,
"dumping using llvm format");
925 "empty output using llvm format '{0}' - with type info flags {1}",
929 LLDB_LOGF(log,
"dumping ordinary printable output");
934 "[Debugger::FormatPrompt] checking if I can handle as array");
935 if (!is_array && !is_pointer)
937 LLDB_LOGF(log,
"[Debugger::FormatPrompt] handle as array");
939 llvm::StringRef special_directions;
940 if (close_bracket_index != llvm::StringRef::npos &&
941 subpath.size() > close_bracket_index) {
942 ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
943 special_directions_stream.
Printf(
"${%svar%s", do_deref_pointer ?
"*" :
"",
947 const char format_char =
949 if (format_char !=
'\0')
950 special_directions_stream.
Printf(
"%%%c", format_char);
952 const char *format_cstr =
954 special_directions_stream.
Printf(
"%%%s", format_cstr);
956 }
else if (entry.
number != 0) {
960 special_directions_stream.
Printf(
"%%%c", style_char);
962 special_directions_stream.
PutChar(
'}');
964 llvm::StringRef(special_directions_stream.
GetString());
970 if (index_higher < 0)
973 uint32_t max_num_children =
974 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
977 for (int64_t index = index_lower; index <= index_higher; ++index) {
982 "[Debugger::FormatPrompt] ERROR in getting child item at "
988 "[Debugger::FormatPrompt] special_directions for child item: %s",
989 special_directions.data() ? special_directions.data() :
"");
992 if (special_directions.empty()) {
997 special_directions, s, sc, exe_ctx,
nullptr, item,
false,
false);
1000 if (--max_num_children == 0) {
1005 if (index < index_higher)
1036 llvm::StringRef path(entry.
string);
1039 thread_info_dictionary->GetObjectForDotSeparatedPath(path);
1043 const char *token_format =
"0x%4.4" PRIx64;
1046 s.
Printf(token_format, value->GetUnsignedIntegerValue());
1049 s.
Printf(
"%f", value->GetAsFloat()->GetValue());
1052 s.
Format(
"{0}", value->GetAsString()->GetValue());
1055 if (value->GetAsArray()->GetSize() > 0) {
1056 s.
Printf(
"%zu", value->GetAsArray()->GetSize());
1061 value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1069static inline bool IsToken(
const char *var_name_begin,
const char *var) {
1070 return (::strncmp(var_name_begin, var, strlen(var)) == 0);
1080static std::pair<char const *, char const *>
1082 const char *open_paren = strchr(full_name,
'(');
1083 const char *close_paren =
nullptr;
1084 const char *
generic = strchr(full_name,
'<');
1088 if (generic && open_paren && generic < open_paren) {
1089 int generic_depth = 1;
1091 for (; *
generic && generic_depth > 0;
generic++) {
1092 if (*generic ==
'<')
1094 if (*generic ==
'>')
1098 open_paren = strchr(generic,
'(');
1100 open_paren =
nullptr;
1104 if (
IsToken(open_paren,
"(anonymous namespace)")) {
1105 open_paren = strchr(open_paren + strlen(
"(anonymous namespace)"),
'(');
1107 close_paren = strchr(open_paren,
')');
1109 close_paren = strchr(open_paren,
')');
1112 return {open_paren, close_paren};
1119 char const *full_name,
1124 out_stream.
Write(full_name, open_paren - full_name + 1);
1146 inline_info->GetName().Dump(&out_stream);
1155 bool function_changed,
1156 bool initial_function) {
1157 if (!format_str.empty()) {
1160 if (
error.Success()) {
1162 function_changed, initial_function);
1172 bool function_changed,
bool initial_function) {
1173 if (format && format[0]) {
1175 llvm::StringRef format_str(format);
1177 if (
error.Success()) {
1179 function_changed, initial_function);
1189 bool initial_function) {
1190 switch (entry.
type) {
1200 Debugger &debugger = target->GetDebugger();
1210 for (
const auto &child : entry.
children) {
1211 if (!
Format(child, s, sc, exe_ctx, addr, valobj, function_changed,
1212 initial_function)) {
1224 bool success =
false;
1225 for (
const auto &child : entry.
children) {
1226 success =
Format(child, scope_stream, sc, exe_ctx, addr, valobj,
1227 function_changed, initial_function);
1242 return DumpValue(s, sc, exe_ctx, entry, valobj);
1248 addr !=
nullptr && addr->
IsValid() &&
1256 const char *format =
"%" PRIu64;
1291 const char *format =
"0x%4.4" PRIx64;
1300 llvm::Triple::OSType ostype = arch.
IsValid()
1302 : llvm::Triple::UnknownOS;
1303 if (ostype == llvm::Triple::FreeBSD ||
1304 ostype == llvm::Triple::Linux ||
1305 ostype == llvm::Triple::NetBSD ||
1306 ostype == llvm::Triple::OpenBSD) {
1307 format =
"%" PRIu64;
1323 const char *format =
"0x%4.4" PRIx64;
1336 const char *format =
"%" PRIu32;
1349 const char *cstr = thread->
GetName();
1350 if (cstr && cstr[0]) {
1363 if (cstr && cstr[0]) {
1374 std::string stop_description = thread->GetStopDescription();
1375 if (!stop_description.empty()) {
1386 std::string stop_description = thread->GetStopDescriptionRaw();
1387 if (!stop_description.empty()) {
1400 if (stop_info_sp && stop_info_sp->IsValid()) {
1403 if (return_valobj_sp) {
1404 if (llvm::Error
error = return_valobj_sp->Dump(s)) {
1420 if (stop_info_sp && stop_info_sp->IsValid()) {
1423 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1424 if (llvm::Error
error =
1425 expression_var_sp->GetValueObject()->Dump(s)) {
1505 const char *lang_name =
1519 const char *format =
"%" PRIu32;
1597 return frame->IsArtificial();
1623 return function_changed;
1626 return initial_function;
1632 Language *language_plugin =
nullptr;
1633 bool language_plugin_handled =
false;
1641 if (language_plugin)
1645 if (language_plugin_handled) {
1649 const char *name =
nullptr;
1668 Language *language_plugin =
nullptr;
1669 bool language_plugin_handled =
false;
1676 if (language_plugin)
1681 if (language_plugin_handled) {
1703 Language *language_plugin =
nullptr;
1704 bool language_plugin_handled =
false;
1711 if (language_plugin)
1715 if (language_plugin_handled) {
1727 bool get_function_vars =
true;
1732 get_function_vars =
false;
1739 if (get_function_vars) {
1751 if (variable_list_sp)
1776 const char *name =
nullptr;
1827 return function_changed;
1830 bool is_optimized =
false;
1832 is_optimized =
true;
1834 return is_optimized;
1838 return initial_function;
1852 const char *format =
"%" PRIu32;
1862 const char *format =
"%" PRIu32;
1887 addr_t pc_loadaddr = reg_ctx->GetPC();
1909 for (
size_t i = 0; i < n; ++i) {
1923 const size_t sep_pos = format_str.find_first_of(
".[:");
1924 const char sep_char =
1925 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
1926 llvm::StringRef key = format_str.substr(0, sep_pos);
1929 for (
size_t i = 0; i < n; ++i) {
1931 if (key == entry_def->
name || entry_def->
name[0] ==
'*') {
1932 llvm::StringRef value;
1935 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
1936 switch (entry_def->
type) {
1938 entry.
string = format_str.str();
1955 if (value.empty()) {
1959 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
1960 "access one of its children: ",
1963 error.SetErrorStringWithFormat(
"%s", error_strm.
GetData());
1964 }
else if (sep_char ==
':') {
1970 error.SetErrorStringWithFormat(
"%s",
"invalid entry definitions");
1976 }
else if (sep_char ==
':') {
1980 entry.
string = value.str();
1982 error.SetErrorStringWithFormat(
1983 "'%s' followed by '%s' but it has no children", key.str().c_str(),
1984 value.str().c_str());
1993 "invalid top level item '%s'. Valid top level items are: ",
1996 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
1997 key.str().c_str(), parent->
name);
1999 error.SetErrorStringWithFormat(
"%s", error_strm.
GetData());
2005 llvm::StringRef &remainder) {
2008 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2010 for (
size_t i = 0; i < n; ++i) {
2012 if (p.first == entry_def->
name || entry_def->
name[0] ==
'*') {
2013 if (p.second.empty()) {
2014 if (format_str.back() ==
'.')
2015 remainder = format_str.drop_front(format_str.size() - 1);
2017 remainder = llvm::StringRef();
2021 return FindEntry(p.second, entry_def, remainder);
2023 remainder = p.second;
2029 remainder = format_str;
2036 while (!format.empty() &&
error.Success()) {
2037 const size_t non_special_chars = format.find_first_of(
"${}\\");
2039 if (non_special_chars == llvm::StringRef::npos) {
2045 if (non_special_chars > 0) {
2048 parent_entry.
AppendText(format.substr(0, non_special_chars));
2049 format = format.drop_front(non_special_chars);
2052 switch (format[0]) {
2057 format = format.drop_front();
2067 error.SetErrorString(
"unmatched '}' character");
2075 format = format.drop_front();
2076 if (format.empty()) {
2077 error.SetErrorString(
2078 "'\\' character was not followed by another character");
2082 const char desens_char = format[0];
2083 format = format.drop_front();
2084 switch (desens_char) {
2117 char oct_str[5] = {0, 0, 0, 0, 0};
2120 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2121 oct_str[i] = format[i];
2126 format = format.drop_front(i);
2127 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2128 if (octal_value <= UINT8_MAX) {
2131 error.SetErrorString(
"octal number is larger than a single byte");
2139 if (isxdigit(format[0])) {
2142 char hex_str[3] = {0, 0, 0};
2143 hex_str[0] = format[0];
2145 format = format.drop_front();
2147 if (isxdigit(format[0])) {
2148 hex_str[1] = format[0];
2149 format = format.drop_front();
2152 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2153 if (hex_value <= UINT8_MAX) {
2156 error.SetErrorString(
"hex number is larger than a single byte");
2173 format = format.drop_front();
2174 if (format.empty() || format.front() !=
'{') {
2178 format = format.drop_front();
2180 llvm::StringRef variable, variable_format;
2185 bool verify_is_thread_id =
false;
2187 if (!variable_format.empty()) {
2199 bool clear_printf =
false;
2206 clear_printf =
true;
2212 clear_printf =
true;
2217 clear_printf =
true;
2222 clear_printf =
true;
2227 clear_printf =
true;
2231 clear_printf =
true;
2235 clear_printf =
true;
2240 clear_printf =
true;
2248 clear_printf =
true;
2250 verify_is_thread_id =
true;
2252 error.SetErrorStringWithFormat(
"invalid format: '%s'",
2266 if (variable[0] ==
'*') {
2268 variable = variable.drop_front();
2275 llvm::StringRef entry_string(entry.
string);
2276 if (entry_string.contains(
':')) {
2277 auto [_, llvm_format] = entry_string.split(
':');
2279 error.SetErrorStringWithFormat(
"invalid llvm format: '%s'",
2280 llvm_format.data());
2285 if (verify_is_thread_id) {
2288 error.SetErrorString(
"the 'tid' format can only be used on "
2289 "${thread.id} and ${thread.protocol_id}");
2293 switch (entry.
type) {
2297 if (entry.
string.empty())
2308 error.SetErrorStringWithFormat(
2309 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2310 variable.str().c_str());
2323 llvm::StringRef &variable_name,
2324 llvm::StringRef &variable_format) {
2326 variable_name = llvm::StringRef();
2327 variable_format = llvm::StringRef();
2329 const size_t paren_pos = format_str.find(
'}');
2330 if (paren_pos != llvm::StringRef::npos) {
2331 const size_t percent_pos = format_str.find(
'%');
2332 if (percent_pos < paren_pos) {
2333 if (percent_pos > 0) {
2334 if (percent_pos > 1)
2335 variable_name = format_str.substr(0, percent_pos);
2337 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2340 variable_name = format_str.substr(0, paren_pos);
2343 format_str = format_str.substr(paren_pos + 1);
2345 error.SetErrorStringWithFormat(
2346 "missing terminating '}' character for '${%s'",
2347 format_str.str().c_str());
2353 llvm::StringRef variable_name,
2354 llvm::StringRef variable_format) {
2355 if (variable_name.empty() || variable_name ==
".fullpath") {
2358 }
else if (variable_name ==
".basename") {
2361 }
else if (variable_name ==
".dirname") {
2369 const char *suffix) {
2370 std::string match(prefix.str());
2371 match.append(suffix);
2376 const llvm::StringRef &match_prefix,
2380 for (
size_t i = 0; i < n; ++i) {
2381 std::string match = prefix.str();
2382 if (match_prefix.empty())
2384 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2385 match_prefix.size()) == 0)
2395 const size_t dollar_pos = str.rfind(
'$');
2396 if (dollar_pos == llvm::StringRef::npos)
2400 if (dollar_pos == str.size() - 1) {
2401 std::string match = str.str();
2407 if (str[dollar_pos + 1] !=
'{')
2410 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2411 if (close_pos != llvm::StringRef::npos)
2414 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2415 if (format_pos != llvm::StringRef::npos)
2418 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2419 if (partial_variable.empty()) {
2428 llvm::StringRef remainder;
2435 if (remainder.empty()) {
2444 }
else if (remainder ==
".") {
2447 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2453 AddMatches(entry_def, str, remainder, new_matches);
2461 const size_t num_args = args.
GetSize();
2462 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
2468 llvm::StringRef var_representation;
2469 const char *var_name = var_value_sp->GetName().GetCString();
2470 if (var_value_sp->GetCompilerType().IsValid()) {
2472 var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
2474 ->TargetProperties::GetPreferDynamicValue(),
2476 ->TargetProperties::GetEnableSyntheticValue());
2477 if (var_value_sp->GetCompilerType().IsAggregateType() &&
2480 .SetHideItemNames(
false)
2481 .SetShowMembersOneLiner(
true),
2484 var_representation = buffer;
2486 var_value_sp->DumpPrintableRepresentation(
2489 eValueObjectRepresentationStyleSummary,
2498 if (var_value_sp->GetError().Success()) {
2499 if (!var_representation.empty())
2500 out_stream.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
2502 out_stream.
Printf(
"%s=%s at %s", var_name,
2503 var_value_sp->GetTypeName().GetCString(),
2504 var_value_sp->GetLocationAsCString());
2506 out_stream.
Printf(
"%s=<unavailable>", var_name);
2513 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.
lldb::SectionSP GetSection() const
Get const accessor for the section.
@ 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::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.
An abstract base class for files.
bool GetIsOptimized()
Get whether compiler optimizations were enabled for this function.
const AddressRange & GetAddressRange()
ConstString GetName() const
const Mangled & GetMangled() const
lldb::LanguageType GetLanguage() const
ConstString GetNameNoArguments() const
Block & GetBlock(bool can_create)
Get accessor for the block list.
A class that describes information for an inlined function.
ConstString GetName() const
static Language * FindPlugin(lldb::LanguageType language)
static const char * GetNameForLanguageType(lldb::LanguageType language)
virtual bool GetFunctionDisplayName(const SymbolContext *sc, const ExecutionContext *exe_ctx, FunctionNameRepresentation representation, Stream &s)
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.
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 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.
bool ValueIsAddress() const
lldb::LanguageType GetLanguage() const
Address & GetAddressRef()
ConstString GetName() const
ConstString GetNameNoArguments() const
Module * GetExecutableModulePointer()
static Target * GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr)
SectionLoadList & GetSectionLoadList()
const ArchSpec & GetArchitecture() const
virtual lldb::user_id_t GetProtocolID() const
virtual const char * GetQueueName()
Retrieve the Queue name for the queue currently using this Thread.
uint32_t GetIndexID() const
StructuredData::ObjectSP GetExtendedInfo()
Retrieve a dictionary of information about this thread.
virtual const char * GetName()
lldb::ProcessSP GetProcess() const
lldb::StopInfoSP GetStopInfo()
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
std::vector< Entry > children
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
void AppendEntry(const Entry &&entry)
static const char * TypeToCString(Type t)
@ FunctionAddrOffsetConcrete
@ FunctionInitialFunction
@ ThreadCompletedExpression
@ ScriptVariableSynthetic
Entry(Type t=Type::Invalid, const char *s=nullptr, const char *f=nullptr)
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),...
llvm::ArrayRef< uint8_t > data(const uint8_t *context_base) const
lldb::user_id_t GetID() const
Get accessor for the user ID.
GetValueForExpressionPathOptions & SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse)
GetValueForExpressionPathOptions & DoAllowFragileIVar()
GetValueForExpressionPathOptions & DontCheckDotVsArrowSyntax()
GetValueForExpressionPathOptions & DoAllowBitfieldSyntax()