58#include "llvm/ADT/STLExtras.h"
59#include "llvm/ADT/StringRef.h"
60#include "llvm/Support/Compiler.h"
61#include "llvm/Support/Regex.h"
62#include "llvm/TargetParser/Triple.h"
107 Definition(
"flags", EntryType::FrameRegisterFlags),
108 Definition(
"no-debug", EntryType::FrameNoDebug),
111 Definition(
"is-artificial", EntryType::FrameIsArtificial),
113 Definition(
"borrowed-info", EntryType::FrameBorrowedInfo),
119 Definition(
"name-without-args", EntryType::FunctionNameNoArgs),
120 Definition(
"name-with-args", EntryType::FunctionNameWithArgs),
121 Definition(
"mangled-name", EntryType::FunctionMangledName),
122 Definition(
"addr-offset", EntryType::FunctionAddrOffset),
123 Definition(
"concrete-only-addr-offset-no-padding",
124 EntryType::FunctionAddrOffsetConcrete),
125 Definition(
"line-offset", EntryType::FunctionLineOffset),
126 Definition(
"pc-offset", EntryType::FunctionPCOffset),
127 Definition(
"initial-function", EntryType::FunctionInitial),
128 Definition(
"changed", EntryType::FunctionChanged),
129 Definition(
"is-optimized", EntryType::FunctionIsOptimized),
130 Definition(
"is-inlined", EntryType::FunctionIsInlined),
131 Definition(
"prefix", EntryType::FunctionPrefix),
132 Definition(
"scope", EntryType::FunctionScope),
133 Definition(
"basename", EntryType::FunctionBasename),
134 Definition(
"name-qualifiers", EntryType::FunctionNameQualifiers),
135 Definition(
"template-arguments", EntryType::FunctionTemplateArguments),
136 Definition(
"formatted-arguments", EntryType::FunctionFormattedArguments),
137 Definition(
"return-left", EntryType::FunctionReturnLeft),
138 Definition(
"return-right", EntryType::FunctionReturnRight),
139 Definition(
"qualifiers", EntryType::FunctionQualifiers),
140 Definition(
"suffix", EntryType::FunctionSuffix),
146 Definition(
"number", EntryType::LineEntryLineNumber),
147 Definition(
"column", EntryType::LineEntryColumn),
148 Definition(
"start-addr", EntryType::LineEntryStartAddress),
149 Definition(
"end-addr", EntryType::LineEntryEndAddress),
169 Definition(
"protocol_id", EntryType::ThreadProtocolID),
170 Definition(
"index", EntryType::ThreadIndexID),
175 Definition(
"stop-reason", EntryType::ThreadStopReason),
176 Definition(
"stop-reason-raw", EntryType::ThreadStopReasonRaw),
177 Definition(
"return-value", EntryType::ThreadReturnValue),
178 Definition(
"completed-expression", EntryType::ThreadCompletedExpression)};
186 Definition(
"count", EntryType::ProgressCount),
187 Definition(
"message", EntryType::ProgressMessage)};
189#define _TO_STR2(_val) #_val
190#define _TO_STR(_val) _TO_STR2(_val)
247 Definition(
"process", EntryType::ScriptProcess),
248 Definition(
"target", EntryType::ScriptTarget),
249 Definition(
"thread", EntryType::ScriptThread),
251 Definition(
"svar", EntryType::ScriptVariableSynthetic),
252 Definition(
"thread", EntryType::ScriptThread)};
257 Definition(
"addr-file-or-load", EntryType::AddressLoadOrFile),
259 Definition(
"current-pc-arrow", EntryType::CurrentPCArrow),
285 Definition(
"separator", EntryType::Separator),
310 entries.push_back(
Entry(ch));
312 entries.back().string.append(1, ch);
318 entries.push_back(
Entry(s));
320 entries.back().string.append(s.data(), s.size());
329 entries.push_back(entry);
338#define ENUM_TO_CSTR(eee) \
339 case FormatEntity::Entry::Type::eee: \
434 s.
Printf(
"string = \"%s\"",
string.c_str());
440 s.
Printf(
"deref = true, ");
443 for (
const auto &child : children)
444 child.Dump(s, depth + 1);
451 const char *script_function_name) {
457 if (script_interpreter) {
459 std::string script_output;
462 script_output,
error) &&
464 s.
Printf(
"%s", script_output.c_str());
477 bool print_file_addr_or_load_addr) {
492 if (print_file_addr_or_load_addr) {
498 s.
Printf(
"0x%*.*" PRIx64, addr_width, addr_width, vaddr);
507 bool concrete_only,
bool no_padding,
508 bool print_zero_offsets) {
515 if (sc->
block && !concrete_only) {
522 format_addr, inline_range))
530 const char *addr_offset_padding = no_padding ?
"" :
" ";
535 if (addr_file_addr > func_file_addr ||
536 (addr_file_addr == func_file_addr && print_zero_offsets)) {
537 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
538 addr_file_addr - func_file_addr);
539 }
else if (addr_file_addr < func_file_addr) {
540 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
541 func_file_addr - addr_file_addr);
549 if (addr_load_addr > func_load_addr ||
550 (addr_load_addr == func_load_addr && print_zero_offsets)) {
551 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
552 addr_load_addr - func_load_addr);
553 }
else if (addr_load_addr < func_load_addr) {
554 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
555 func_load_addr - addr_load_addr);
566 size_t &close_bracket_index,
567 const char *&var_name_final_if_array_range,
568 int64_t &index_lower, int64_t &index_higher) {
570 close_bracket_index = llvm::StringRef::npos;
571 const size_t open_bracket_index = subpath.find(
'[');
572 if (open_bracket_index == llvm::StringRef::npos) {
574 "[ScanBracketedRange] no bracketed range, skipping entirely");
578 close_bracket_index = subpath.find(
']', open_bracket_index + 1);
580 if (close_bracket_index == llvm::StringRef::npos) {
582 "[ScanBracketedRange] no bracketed range, skipping entirely");
585 var_name_final_if_array_range = subpath.data() + open_bracket_index;
587 if (close_bracket_index - open_bracket_index == 1) {
590 "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
593 const size_t separator_index = subpath.find(
'-', open_bracket_index + 1);
595 if (separator_index == llvm::StringRef::npos) {
596 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
597 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
598 index_higher = index_lower;
600 "[ScanBracketedRange] [%" PRId64
601 "] detected, high index is same",
604 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
605 const char *index_higher_cstr = subpath.data() + separator_index + 1;
606 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
607 index_higher = ::strtoul(index_higher_cstr,
nullptr, 0);
609 "[ScanBracketedRange] [%" PRId64
"-%" PRId64
"] detected",
610 index_lower, index_higher);
612 if (index_lower > index_higher && index_higher > 0) {
613 LLDB_LOGF(log,
"[ScanBracketedRange] swapping indices");
614 const int64_t temp = index_lower;
615 index_lower = index_higher;
653 uint32_t reg_num,
Format format) {
658 const uint32_t lldb_reg_num =
677 bool deref_pointer) {
679 std::string name_to_deref = llvm::formatv(
"[{0}]", index);
680 LLDB_LOG(log,
"[ExpandIndexedExpression] name to deref: {0}", name_to_deref);
688 name_to_deref, &reason_to_stop, &final_value_type, options, &what_next);
691 "[ExpandIndexedExpression] ERROR: why stopping = %d,"
692 " final_value_type %d",
693 reason_to_stop, final_value_type);
696 "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
697 " final_value_type %d",
698 reason_to_stop, final_value_type);
732 std::string formatted;
733 std::string llvm_format = (
"{0:" + options +
"}").str();
737 if (type_info & eTypeIsSigned) {
738 bool success =
false;
741 formatted = llvm::formatv(llvm_format.data(),
integer);
743 bool success =
false;
746 formatted = llvm::formatv(llvm_format.data(),
integer);
750 if (formatted.empty())
753 s.
Write(formatted.data(), formatted.size());
760 if (valobj ==
nullptr)
770 bool do_deref_pointer = entry.
deref;
771 bool is_script =
false;
772 switch (entry.
type) {
778 custom_format = entry.
fmt;
786 custom_format = entry.
fmt;
790 if (valobj ==
nullptr)
808 SyntheticChildrenTraversal::Both);
810 const char *var_name_final_if_array_range =
nullptr;
811 size_t close_bracket_index = llvm::StringRef::npos;
812 int64_t index_lower = -1;
813 int64_t index_higher = -1;
814 bool is_array_range =
false;
815 bool was_plain_var =
false;
816 bool was_var_format =
false;
817 bool was_var_indexed =
false;
827 auto split = llvm::StringRef(entry.
string).split(
':');
828 auto subpath = split.first;
829 auto llvm_format = split.second;
832 if (subpath.empty()) {
835 was_plain_var =
true;
837 was_var_format =
true;
841 if (subpath[0] ==
'[')
842 was_var_indexed =
true;
844 var_name_final_if_array_range, index_lower,
849 LLDB_LOG(log,
"[Debugger::FormatPrompt] symbol to expand: {0}", subpath);
854 &final_value_type, options, &what_next)
859 "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
860 " final_value_type %d",
861 reason_to_stop, final_value_type);
865 "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
866 " final_value_type %d",
867 reason_to_stop, final_value_type);
884 if (do_deref_pointer && !is_array_range) {
891 LLDB_LOGF(log,
"[Debugger::FormatPrompt] ERROR: %s\n",
892 error.AsCString(
"unknown"));
895 do_deref_pointer =
false;
899 LLDB_LOGF(log,
"[Debugger::FormatPrompt] could not calculate target for "
900 "prompt expression");
907 if (target->
IsBitfield() && was_var_indexed) {
912 auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
914 if (val_obj_display ==
921 const uint32_t type_info_flags =
923 bool is_array = (type_info_flags & eTypeIsArray) != 0;
924 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
927 if ((is_array || is_pointer) && (!is_array_range) &&
936 "[Debugger::FormatPrompt] I am into array || pointer && !range");
942 str_temp, val_obj_display, custom_format);
943 LLDB_LOGF(log,
"[Debugger::FormatPrompt] special cases did%s match",
944 success ?
"" :
"n't");
954 }
else if (is_pointer)
957 s, val_obj_display, custom_format,
966 if (is_aggregate && was_plain_var) {
977 s <<
"<invalid use of aggregate type>";
981 if (!is_array_range) {
982 if (!llvm_format.empty()) {
984 LLDB_LOGF(log,
"dumping using llvm format");
989 "empty output using llvm format '{0}' - with type info flags {1}",
993 LLDB_LOGF(log,
"dumping ordinary printable output");
998 "[Debugger::FormatPrompt] checking if I can handle as array");
999 if (!is_array && !is_pointer)
1001 LLDB_LOGF(log,
"[Debugger::FormatPrompt] handle as array");
1003 llvm::StringRef special_directions;
1004 if (close_bracket_index != llvm::StringRef::npos &&
1005 subpath.size() > close_bracket_index) {
1006 ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
1007 special_directions_stream.
Printf(
"${%svar%s", do_deref_pointer ?
"*" :
"",
1011 const char format_char =
1013 if (format_char !=
'\0')
1014 special_directions_stream.
Printf(
"%%%c", format_char);
1016 const char *format_cstr =
1018 special_directions_stream.
Printf(
"%%%s", format_cstr);
1020 }
else if (entry.
number != 0) {
1024 special_directions_stream.
Printf(
"%%%c", style_char);
1026 special_directions_stream.
PutChar(
'}');
1027 special_directions =
1028 llvm::StringRef(special_directions_stream.
GetString());
1034 if (index_higher < 0)
1037 uint32_t max_num_children =
1038 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1040 bool success =
true;
1041 for (int64_t index = index_lower; index <= index_higher; ++index) {
1046 "[Debugger::FormatPrompt] ERROR in getting child item at "
1052 "[Debugger::FormatPrompt] special_directions for child item: %s",
1053 special_directions.data() ? special_directions.data() :
"");
1056 if (special_directions.empty()) {
1061 special_directions, s, sc, exe_ctx,
nullptr, item,
false,
false);
1064 if (--max_num_children == 0) {
1069 if (index < index_higher)
1100 llvm::StringRef path(entry.
string);
1103 thread_info_dictionary->GetObjectForDotSeparatedPath(path);
1107 const char *token_format =
"0x%4.4" PRIx64;
1110 s.
Printf(token_format, value->GetUnsignedIntegerValue());
1113 s.
Printf(
"%f", value->GetAsFloat()->GetValue());
1116 s.
Format(
"{0}", value->GetAsString()->GetValue());
1119 if (value->GetAsArray()->GetSize() > 0) {
1120 s.
Printf(
"%zu", value->GetAsArray()->GetSize());
1125 value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1133static inline bool IsToken(
const char *var_name_begin,
const char *var) {
1134 return (::strncmp(var_name_begin, var, strlen(var)) == 0);
1144static std::pair<char const *, char const *>
1146 const char *open_paren = strchr(full_name,
'(');
1147 const char *close_paren =
nullptr;
1148 const char *
generic = strchr(full_name,
'<');
1152 if (generic && open_paren && generic < open_paren) {
1153 int generic_depth = 1;
1155 for (; *
generic && generic_depth > 0;
generic++) {
1156 if (*generic ==
'<')
1158 if (*generic ==
'>')
1162 open_paren = strchr(generic,
'(');
1164 open_paren =
nullptr;
1168 if (
IsToken(open_paren,
"(anonymous namespace)")) {
1169 open_paren = strchr(open_paren + strlen(
"(anonymous namespace)"),
'(');
1171 close_paren = strchr(open_paren,
')');
1173 close_paren = strchr(open_paren,
')');
1176 return {open_paren, close_paren};
1183 char const *full_name,
1188 out_stream.
Write(full_name, open_paren - full_name + 1);
1207 return inline_block->GetBlockVariableList(
true);
1243 Language *language_plugin =
nullptr;
1244 bool language_plugin_handled =
false;
1251 if (language_plugin)
1255 if (language_plugin_handled) {
1280 Language *language_plugin =
nullptr;
1286 if (!language_plugin)
1296 const bool success =
1310 bool function_changed,
1311 bool initial_function) {
1312 if (!format_str.empty()) {
1315 if (
error.Success()) {
1317 function_changed, initial_function);
1327 bool initial_function) {
1328 switch (entry.
type) {
1337 Debugger &debugger = target->GetDebugger();
1347 if (!
Format(child, s, sc, exe_ctx, addr, valobj, function_changed,
1348 initial_function)) {
1360 auto format_children = [&](
const std::vector<Entry> &children) {
1361 scope_stream.
Clear();
1362 for (
const auto &child : children) {
1363 if (!
Format(child, scope_stream, sc, exe_ctx, addr, valobj,
1364 function_changed, initial_function))
1371 if (format_children(children)) {
1385 return DumpValue(s, sc, exe_ctx, entry, valobj);
1391 addr !=
nullptr && addr->
IsValid() &&
1399 const char *format =
"%" PRIu64;
1434 const char *format =
"0x%4.4" PRIx64;
1441 Target &target = thread->GetProcess()->GetTarget();
1443 llvm::Triple::OSType ostype = arch.
IsValid()
1445 : llvm::Triple::UnknownOS;
1446 if (ostype == llvm::Triple::FreeBSD ||
1447 ostype == llvm::Triple::Linux ||
1448 ostype == llvm::Triple::NetBSD ||
1449 ostype == llvm::Triple::OpenBSD) {
1450 format =
"%" PRIu64;
1456 s.
Printf(format, thread->GetID());
1466 const char *format =
"0x%4.4" PRIx64;
1469 s.
Printf(format, thread->GetProtocolID());
1479 const char *format =
"%" PRIu32;
1482 s.
Printf(format, thread->GetIndexID());
1492 const char *cstr = thread->GetName();
1493 if (cstr && cstr[0]) {
1505 const char *cstr = thread->GetQueueName();
1506 if (cstr && cstr[0]) {
1517 std::string stop_description = thread->GetStopDescription();
1518 if (!stop_description.empty()) {
1529 std::string stop_description = thread->GetStopDescriptionRaw();
1530 if (!stop_description.empty()) {
1542 StopInfoSP stop_info_sp = thread->GetStopInfo();
1543 if (stop_info_sp && stop_info_sp->IsValid()) {
1546 if (return_valobj_sp) {
1547 if (llvm::Error
error = return_valobj_sp->Dump(s)) {
1562 StopInfoSP stop_info_sp = thread->GetStopInfo();
1563 if (stop_info_sp && stop_info_sp->IsValid()) {
1566 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1567 if (llvm::Error
error =
1568 expression_var_sp->GetValueObject()->Dump(s)) {
1618 if (
Module *exe_module = target->GetExecutableModulePointer()) {
1659 const char *lang_name =
1673 const char *format =
"%" PRIu32;
1750 return frame->IsArtificial();
1757 if (frame->IsSynthetic())
1759 else if (frame->IsHistorical())
1770 llvm::dyn_cast<BorrowedStackFrame>(frame)) {
1772 borrowed_frame->GetBorrowedFrame()) {
1773 s.
Printf(
" [borrowed from frame #%u]",
1774 borrowed_from_sp->GetFrameIndex());
1804 return function_changed;
1807 return initial_function;
1811 Language *language_plugin =
nullptr;
1812 bool language_plugin_handled =
false;
1820 if (language_plugin)
1824 if (language_plugin_handled) {
1854 Language *language_plugin =
nullptr;
1855 bool language_plugin_handled =
false;
1862 if (language_plugin)
1867 if (language_plugin_handled) {
1907 Language *language_plugin =
nullptr;
1913 if (!language_plugin)
1991 return function_changed;
1994 bool is_optimized =
false;
1996 is_optimized =
true;
1998 return is_optimized;
2006 return initial_function;
2017 const char *format =
"%" PRIu32;
2027 const char *format =
"%" PRIu32;
2052 addr_t pc_loadaddr = reg_ctx->GetPC();
2069 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2071 s.
Format(
"[{0:N}/{1:N}]", progress->completed, progress->total);
2080 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2089 s << target->GetDebugger().GetSeparator();
2102 for (
size_t i = 0; i < n; ++i) {
2116 const size_t sep_pos = format_str.find_first_of(
".[:");
2117 const char sep_char =
2118 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
2119 llvm::StringRef key = format_str.substr(0, sep_pos);
2122 for (
size_t i = 0; i < n; ++i) {
2124 if (key == entry_def->
name || entry_def->
name[0] ==
'*') {
2125 llvm::StringRef value;
2128 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
2129 switch (entry_def->
type) {
2131 entry.
string = format_str.str();
2148 if (value.empty()) {
2152 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
2153 "access one of its children: ",
2158 }
else if (sep_char ==
':') {
2165 "%s",
"invalid entry definitions");
2171 }
else if (sep_char ==
':') {
2175 entry.
string = value.str();
2178 "'%s' followed by '%s' but it has no children", key.str().c_str(),
2179 value.str().c_str());
2188 "invalid top level item '%s'. Valid top level items are: ",
2191 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
2192 key.str().c_str(), parent->
name);
2200 llvm::StringRef &remainder) {
2203 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2205 for (
size_t i = 0; i < n; ++i) {
2207 if (p.first == entry_def->
name || entry_def->
name[0] ==
'*') {
2208 if (p.second.empty()) {
2209 if (format_str.back() ==
'.')
2210 remainder = format_str.drop_front(format_str.size() - 1);
2212 remainder = llvm::StringRef();
2216 return FindEntry(p.second, entry_def, remainder);
2218 remainder = p.second;
2224 remainder = format_str;
2231 while (!format.empty() &&
error.Success()) {
2232 const size_t non_special_chars = format.find_first_of(
"${}\\|");
2234 if (non_special_chars == llvm::StringRef::npos) {
2240 if (non_special_chars > 0) {
2243 parent_entry.
AppendText(format.substr(0, non_special_chars));
2244 format = format.drop_front(non_special_chars);
2247 switch (format[0]) {
2252 format = format.drop_front();
2270 format = format.drop_front();
2278 format = format.drop_front();
2279 if (format.empty()) {
2281 "'\\' character was not followed by another character");
2285 const char desens_char = format[0];
2286 format = format.drop_front();
2287 switch (desens_char) {
2320 char oct_str[5] = {0, 0, 0, 0, 0};
2323 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2324 oct_str[i] = format[i];
2329 format = format.drop_front(i);
2330 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2331 if (octal_value <= UINT8_MAX) {
2335 "octal number is larger than a single byte");
2343 if (isxdigit(format[0])) {
2346 char hex_str[3] = {0, 0, 0};
2347 hex_str[0] = format[0];
2349 format = format.drop_front();
2351 if (isxdigit(format[0])) {
2352 hex_str[1] = format[0];
2353 format = format.drop_front();
2356 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2357 if (hex_value <= UINT8_MAX) {
2361 "hex number is larger than a single byte");
2378 format = format.drop_front();
2379 if (format.empty() || format.front() !=
'{') {
2383 format = format.drop_front();
2385 llvm::StringRef variable, variable_format;
2390 bool verify_is_thread_id =
false;
2392 if (!variable_format.empty()) {
2404 bool clear_printf =
false;
2409 entry.
number = ValueObject::
2410 eValueObjectRepresentationStyleLanguageSpecific;
2411 clear_printf =
true;
2417 clear_printf =
true;
2422 clear_printf =
true;
2427 clear_printf =
true;
2432 clear_printf =
true;
2436 clear_printf =
true;
2440 clear_printf =
true;
2445 clear_printf =
true;
2453 clear_printf =
true;
2455 verify_is_thread_id =
true;
2471 if (variable[0] ==
'*') {
2473 variable = variable.drop_front();
2480 llvm::StringRef entry_string(entry.
string);
2481 if (entry_string.contains(
':')) {
2482 auto [_, llvm_format] = entry_string.split(
':');
2485 "invalid llvm format: '%s'", llvm_format.data());
2490 if (verify_is_thread_id) {
2494 "the 'tid' format can only be used on "
2495 "${thread.id} and ${thread.protocol_id}");
2499 switch (entry.
type) {
2503 if (entry.
string.empty())
2515 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2516 variable.str().c_str());
2529 llvm::StringRef &variable_name,
2530 llvm::StringRef &variable_format) {
2532 variable_name = llvm::StringRef();
2533 variable_format = llvm::StringRef();
2535 const size_t paren_pos = format_str.find(
'}');
2536 if (paren_pos != llvm::StringRef::npos) {
2537 const size_t percent_pos = format_str.find(
'%');
2538 if (percent_pos < paren_pos) {
2539 if (percent_pos > 0) {
2540 if (percent_pos > 1)
2541 variable_name = format_str.substr(0, percent_pos);
2543 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2546 variable_name = format_str.substr(0, paren_pos);
2549 format_str = format_str.substr(paren_pos + 1);
2552 "missing terminating '}' character for '${%s'",
2553 format_str.str().c_str());
2559 llvm::StringRef variable_name,
2560 llvm::StringRef variable_format) {
2561 if (variable_name.empty() || variable_name ==
".fullpath") {
2564 }
else if (variable_name ==
".basename") {
2567 }
else if (variable_name ==
".dirname") {
2575 const char *suffix) {
2576 std::string match(prefix.str());
2577 match.append(suffix);
2582 const llvm::StringRef &match_prefix,
2586 for (
size_t i = 0; i < n; ++i) {
2587 if (match_prefix.empty())
2589 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2590 match_prefix.size()) == 0)
2600 const size_t dollar_pos = str.rfind(
'$');
2601 if (dollar_pos == llvm::StringRef::npos)
2605 if (dollar_pos == str.size() - 1) {
2606 std::string match = str.str();
2612 if (str[dollar_pos + 1] !=
'{')
2615 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2616 if (close_pos != llvm::StringRef::npos)
2619 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2620 if (format_pos != llvm::StringRef::npos)
2623 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2624 if (partial_variable.empty()) {
2633 llvm::StringRef remainder;
2640 if (remainder.empty()) {
2649 }
else if (remainder ==
".") {
2652 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2658 AddMatches(entry_def, str, remainder, new_matches);
2666 const size_t num_args = args.
GetSize();
2667 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
2673 llvm::StringRef var_representation;
2674 const char *var_name = var_value_sp->GetName().GetCString();
2675 if (var_value_sp->GetCompilerType().IsValid()) {
2677 var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
2679 ->TargetProperties::GetPreferDynamicValue(),
2681 ->TargetProperties::GetEnableSyntheticValue());
2682 if (var_value_sp->GetCompilerType().IsAggregateType() &&
2685 .SetHideItemNames(
false)
2686 .SetShowMembersOneLiner(
true),
2689 var_representation = buffer;
2691 var_value_sp->DumpPrintableRepresentation(
2694 eValueObjectRepresentationStyleSummary,
2703 if (var_value_sp->GetError().Success()) {
2704 if (!var_representation.empty())
2705 out_stream.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
2707 out_stream.
Printf(
"%s=%s at %s", var_name,
2708 var_value_sp->GetTypeName().GetCString(),
2709 var_value_sp->GetLocationAsCString());
2711 out_stream.
Printf(
"%s=<unavailable>", var_name);
2718 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)
"lldb/Target/BorrowedStackFrame.h"
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.
virtual const char * GetFunctionName()
Get the frame's demangled name.
virtual lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
virtual const char * GetDisplayFunctionName()
Get the frame's demangled display name.
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.
const lldb::RegisterContextSP & GetRegisterContextSP() const
virtual 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::StackFrame > StackFrameSP
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()