57 #include "llvm/ADT/STLExtras.h"
58 #include "llvm/ADT/StringRef.h"
59 #include "llvm/ADT/Triple.h"
60 #include "llvm/Support/Compiler.h"
68 #include <type_traits>
104 Definition(
"flags", EntryType::FrameRegisterFlags),
105 Definition(
"no-debug", EntryType::FrameNoDebug),
108 Definition(
"is-artificial", EntryType::FrameIsArtificial),
114 Definition(
"name-without-args", EntryType::FunctionNameNoArgs),
115 Definition(
"name-with-args", EntryType::FunctionNameWithArgs),
116 Definition(
"mangled-name", EntryType::FunctionMangledName),
117 Definition(
"addr-offset", EntryType::FunctionAddrOffset),
118 Definition(
"concrete-only-addr-offset-no-padding",
119 EntryType::FunctionAddrOffsetConcrete),
120 Definition(
"line-offset", EntryType::FunctionLineOffset),
121 Definition(
"pc-offset", EntryType::FunctionPCOffset),
122 Definition(
"initial-function", EntryType::FunctionInitial),
123 Definition(
"changed", EntryType::FunctionChanged),
124 Definition(
"is-optimized", EntryType::FunctionIsOptimized)};
129 Definition(
"number", EntryType::LineEntryLineNumber),
130 Definition(
"column", EntryType::LineEntryColumn),
131 Definition(
"start-addr", EntryType::LineEntryStartAddress),
132 Definition(
"end-addr", EntryType::LineEntryEndAddress),
152 Definition(
"protocol_id", EntryType::ThreadProtocolID),
153 Definition(
"index", EntryType::ThreadIndexID),
158 Definition(
"stop-reason", EntryType::ThreadStopReason),
159 Definition(
"stop-reason-raw", EntryType::ThreadStopReasonRaw),
160 Definition(
"return-value", EntryType::ThreadReturnValue),
161 Definition(
"completed-expression", EntryType::ThreadCompletedExpression)};
166 #define _TO_STR2(_val) #_val
167 #define _TO_STR(_val) _TO_STR2(_val)
224 Definition(
"process", EntryType::ScriptProcess),
225 Definition(
"target", EntryType::ScriptTarget),
226 Definition(
"thread", EntryType::ScriptThread),
228 Definition(
"svar", EntryType::ScriptVariableSynthetic),
229 Definition(
"thread", EntryType::ScriptThread)};
234 Definition(
"addr-file-or-load", EntryType::AddressLoadOrFile),
236 Definition(
"current-pc-arrow", EntryType::CurrentPCArrow),
265 :
string(s.data(), s.size()), printf_format(), children(),
266 type(
Type::String) {}
269 :
string(1, ch), printf_format(), children(), type(
Type::String) {}
273 children.push_back(
Entry(ch));
275 children.back().string.append(1, ch);
280 children.push_back(
Entry(s));
282 children.back().string.append(s.data(), s.size());
286 return AppendText(llvm::StringRef(cstr));
292 llvm::StringRef modifiable_format(format_str);
296 #define ENUM_TO_CSTR(eee) \
297 case FormatEntity::Entry::Type::eee: \
371 s.
Printf(
"%*.*s%-20s: ", depth * 2, depth * 2,
"", TypeToCString(type));
375 s.
Printf(
"string = \"%s\"",
string.c_str());
376 if (!printf_format.empty())
377 s.
Printf(
"printf_format = \"%s\"", printf_format.c_str());
379 s.
Printf(
"number = %" PRIu64
" (0x%" PRIx64
"), ", number, number);
381 s.
Printf(
"deref = true, ");
383 for (
const auto &child : children) {
384 child.Dump(s, depth + 1);
388 template <
typename T>
391 const char *script_function_name) {
397 if (script_interpreter) {
402 script_output,
error) &&
404 s.
Printf(
"%s", script_output.c_str());
417 bool print_file_addr_or_load_addr) {
427 if (exe_ctx && target) {
432 if (print_file_addr_or_load_addr) {
439 s.
Printf(
"0x%*.*" PRIx64, addr_width, addr_width, vaddr);
449 bool concrete_only,
bool no_padding,
450 bool print_zero_offsets) {
457 if (sc->
block && !concrete_only) {
464 format_addr, inline_range))
472 const char *addr_offset_padding = no_padding ?
"" :
" ";
477 if (addr_file_addr > func_file_addr ||
478 (addr_file_addr == func_file_addr && print_zero_offsets)) {
479 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
480 addr_file_addr - func_file_addr);
481 }
else if (addr_file_addr < func_file_addr) {
482 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
483 func_file_addr - addr_file_addr);
491 if (addr_load_addr > func_load_addr ||
492 (addr_load_addr == func_load_addr && print_zero_offsets)) {
493 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
494 addr_load_addr - func_load_addr);
495 }
else if (addr_load_addr < func_load_addr) {
496 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
497 func_load_addr - addr_load_addr);
508 size_t &close_bracket_index,
509 const char *&var_name_final_if_array_range,
510 int64_t &index_lower, int64_t &index_higher) {
512 close_bracket_index = llvm::StringRef::npos;
513 const size_t open_bracket_index = subpath.find(
'[');
514 if (open_bracket_index == llvm::StringRef::npos) {
516 "[ScanBracketedRange] no bracketed range, skipping entirely");
520 close_bracket_index = subpath.find(
']', open_bracket_index + 1);
522 if (close_bracket_index == llvm::StringRef::npos) {
524 "[ScanBracketedRange] no bracketed range, skipping entirely");
527 var_name_final_if_array_range = subpath.data() + open_bracket_index;
529 if (close_bracket_index - open_bracket_index == 1) {
532 "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
535 const size_t separator_index = subpath.find(
'-', open_bracket_index + 1);
537 if (separator_index == llvm::StringRef::npos) {
538 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
539 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
540 index_higher = index_lower;
542 "[ScanBracketedRange] [%" PRId64
543 "] detected, high index is same",
546 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
547 const char *index_higher_cstr = subpath.data() + separator_index + 1;
548 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
549 index_higher = ::strtoul(index_higher_cstr,
nullptr, 0);
551 "[ScanBracketedRange] [%" PRId64
"-%" PRId64
"] detected",
552 index_lower, index_higher);
554 if (index_lower > index_higher && index_higher > 0) {
555 LLDB_LOGF(log,
"[ScanBracketedRange] swapping indices");
556 const int64_t temp = index_lower;
557 index_lower = index_higher;
603 const RegisterInfo *reg_info =
619 bool deref_pointer) {
621 const char *ptr_deref_format =
"[%d]";
623 ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
624 LLDB_LOGF(log,
"[ExpandIndexedExpression] name to deref: %s",
625 ptr_deref_buffer.c_str());
633 ptr_deref_buffer.c_str(), &reason_to_stop, &final_value_type, options,
637 "[ExpandIndexedExpression] ERROR: why stopping = %d,"
638 " final_value_type %d",
639 reason_to_stop, final_value_type);
642 "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
643 " final_value_type %d",
644 reason_to_stop, final_value_type);
675 if (valobj ==
nullptr)
685 bool do_deref_pointer = entry.
deref;
686 bool is_script =
false;
687 switch (entry.
type) {
693 custom_format = entry.
fmt;
701 custom_format = entry.
fmt;
705 if (valobj ==
nullptr)
714 if (valobj ==
nullptr)
726 SyntheticChildrenTraversal::Both);
728 const char *var_name_final_if_array_range =
nullptr;
729 size_t close_bracket_index = llvm::StringRef::npos;
730 int64_t index_lower = -1;
731 int64_t index_higher = -1;
732 bool is_array_range =
false;
733 bool was_plain_var =
false;
734 bool was_var_format =
false;
735 bool was_var_indexed =
false;
745 llvm::StringRef subpath(entry.
string);
747 if (entry.
string.empty()) {
750 was_plain_var =
true;
752 was_var_format =
true;
756 if (entry.
string[0] ==
'[')
757 was_var_indexed =
true;
759 var_name_final_if_array_range, index_lower,
766 LLDB_LOGF(log,
"[Debugger::FormatPrompt] symbol to expand: %s",
772 &final_value_type, options, &what_next)
777 "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
778 " final_value_type %d",
779 reason_to_stop, final_value_type);
783 "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
784 " final_value_type %d",
785 reason_to_stop, final_value_type);
802 if (do_deref_pointer && !is_array_range) {
809 LLDB_LOGF(log,
"[Debugger::FormatPrompt] ERROR: %s\n",
810 error.AsCString(
"unknown"));
813 do_deref_pointer =
false;
817 LLDB_LOGF(log,
"[Debugger::FormatPrompt] could not calculate target for "
818 "prompt expression");
825 if (target->
IsBitfield() && was_var_indexed) {
830 auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
832 if (val_obj_display ==
841 bool is_array = (type_info_flags & eTypeIsArray) != 0;
842 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
845 if ((is_array || is_pointer) && (!is_array_range) &&
854 "[Debugger::FormatPrompt] I am into array || pointer && !range");
860 str_temp, val_obj_display, custom_format);
861 LLDB_LOGF(log,
"[Debugger::FormatPrompt] special cases did%s match",
862 success ?
"" :
"n't");
872 }
else if (is_pointer)
875 s, val_obj_display, custom_format,
884 if (is_aggregate && was_plain_var) {
895 s <<
"<invalid use of aggregate type>";
899 if (!is_array_range) {
901 "[Debugger::FormatPrompt] dumping ordinary printable output");
906 "[Debugger::FormatPrompt] checking if I can handle as array");
907 if (!is_array && !is_pointer)
909 LLDB_LOGF(log,
"[Debugger::FormatPrompt] handle as array");
911 llvm::StringRef special_directions;
912 if (close_bracket_index != llvm::StringRef::npos &&
913 subpath.size() > close_bracket_index) {
914 ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
915 special_directions_stream.
Printf(
"${%svar%s", do_deref_pointer ?
"*" :
"",
919 const char format_char =
921 if (format_char !=
'\0')
922 special_directions_stream.
Printf(
"%%%c", format_char);
924 const char *format_cstr =
926 special_directions_stream.
Printf(
"%%%s", format_cstr);
928 }
else if (entry.
number != 0) {
932 special_directions_stream.
Printf(
"%%%c", style_char);
934 special_directions_stream.
PutChar(
'}');
936 llvm::StringRef(special_directions_stream.
GetString());
942 if (index_higher < 0)
946 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
949 for (int64_t index = index_lower; index <= index_higher; ++index) {
954 "[Debugger::FormatPrompt] ERROR in getting child item at "
960 "[Debugger::FormatPrompt] special_directions for child item: %s",
961 special_directions.data() ? special_directions.data() :
"");
964 if (special_directions.empty()) {
969 special_directions, s, sc, exe_ctx,
nullptr, item,
false,
false);
972 if (--max_num_children == 0) {
977 if (index < index_higher)
1008 llvm::StringRef path(entry.
string);
1011 thread_info_dictionary->GetObjectForDotSeparatedPath(path);
1015 const char *token_format =
"0x%4.4" PRIx64;
1018 s.
Printf(token_format, value->GetAsInteger()->GetValue());
1021 s.
Printf(
"%f", value->GetAsFloat()->GetValue());
1024 s.
Format(
"{0}", value->GetAsString()->GetValue());
1027 if (value->GetAsArray()->GetSize() > 0) {
1028 s.
Printf(
"%zu", value->GetAsArray()->GetSize());
1033 value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1041 static inline bool IsToken(
const char *var_name_begin,
const char *var) {
1042 return (::strncmp(var_name_begin, var, strlen(var)) == 0);
1049 bool function_changed,
1050 bool initial_function) {
1051 if (!format_str.empty()) {
1054 if (
error.Success()) {
1056 function_changed, initial_function);
1066 bool function_changed,
bool initial_function) {
1067 if (format && format[0]) {
1069 llvm::StringRef format_str(format);
1071 if (
error.Success()) {
1073 function_changed, initial_function);
1083 bool initial_function) {
1084 switch (entry.
type) {
1094 Debugger &debugger = target->GetDebugger();
1104 for (
const auto &child : entry.
children) {
1105 if (!
Format(child, s, sc, exe_ctx, addr, valobj, function_changed,
1106 initial_function)) {
1118 bool success =
false;
1119 for (
const auto &child : entry.
children) {
1120 success =
Format(child, scope_stream, sc, exe_ctx, addr, valobj,
1121 function_changed, initial_function);
1136 return DumpValue(s, sc, exe_ctx, entry, valobj);
1142 addr !=
nullptr && addr->
IsValid() &&
1150 const char *format =
"%" PRIu64;
1185 const char *format =
"0x%4.4" PRIx64;
1194 llvm::Triple::OSType ostype = arch.
IsValid()
1196 : llvm::Triple::UnknownOS;
1197 if ((ostype == llvm::Triple::FreeBSD) ||
1198 (ostype == llvm::Triple::Linux) ||
1199 (ostype == llvm::Triple::NetBSD)) {
1200 format =
"%" PRIu64;
1216 const char *format =
"0x%4.4" PRIx64;
1229 const char *format =
"%" PRIu32;
1242 const char *cstr = thread->
GetName();
1243 if (cstr && cstr[0]) {
1256 if (cstr && cstr[0]) {
1267 std::string stop_description = thread->GetStopDescription();
1268 if (!stop_description.empty()) {
1279 std::string stop_description = thread->GetStopDescriptionRaw();
1280 if (!stop_description.empty()) {
1293 if (stop_info_sp && stop_info_sp->IsValid()) {
1294 ValueObjectSP return_valobj_sp =
1296 if (return_valobj_sp) {
1297 return_valobj_sp->Dump(s);
1310 if (stop_info_sp && stop_info_sp->IsValid()) {
1311 ExpressionVariableSP expression_var_sp =
1313 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1314 expression_var_sp->GetValueObject()->Dump(s);
1391 const char *lang_name =
1405 const char *format =
"%" PRIu32;
1483 return frame->IsArtificial();
1509 return function_changed;
1512 return initial_function;
1518 Language *language_plugin =
nullptr;
1519 bool language_plugin_handled =
false;
1527 if (language_plugin)
1531 if (language_plugin_handled) {
1535 const char *name =
nullptr;
1565 Language *language_plugin =
nullptr;
1566 bool language_plugin_handled =
false;
1573 if (language_plugin)
1578 if (language_plugin_handled) {
1599 Language *language_plugin =
nullptr;
1600 bool language_plugin_handled =
false;
1607 if (language_plugin)
1611 if (language_plugin_handled) {
1622 VariableListSP variable_list_sp;
1623 bool get_function_vars =
true;
1628 get_function_vars =
false;
1635 if (get_function_vars) {
1647 if (variable_list_sp)
1651 const char *open_paren = strchr(cstr,
'(');
1652 const char *close_paren =
nullptr;
1653 const char *
generic = strchr(cstr,
'<');
1657 if (
generic && open_paren &&
generic < open_paren) {
1658 int generic_depth = 1;
1660 for (; *
generic && generic_depth > 0;
generic++) {
1661 if (*
generic ==
'<')
1663 if (*
generic ==
'>')
1667 open_paren = strchr(
generic,
'(');
1669 open_paren =
nullptr;
1672 if (
IsToken(open_paren,
"(anonymous namespace)")) {
1674 strchr(open_paren + strlen(
"(anonymous namespace)"),
'(');
1676 close_paren = strchr(open_paren,
')');
1678 close_paren = strchr(open_paren,
')');
1682 s.
Write(cstr, open_paren - cstr + 1);
1687 const size_t num_args = args.
GetSize();
1688 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
1692 ValueObjectSP var_value_sp(
1695 llvm::StringRef var_representation;
1696 const char *var_name = var_value_sp->GetName().GetCString();
1697 if (var_value_sp->GetCompilerType().IsValid()) {
1700 var_value_sp->GetQualifiedRepresentationIfAvailable(
1702 ->TargetProperties::GetPreferDynamicValue(),
1704 ->TargetProperties::GetEnableSyntheticValue());
1705 if (var_value_sp->GetCompilerType().IsAggregateType() &&
1709 .SetHideItemNames(
false)
1710 .SetShowMembersOneLiner(
true),
1714 var_representation = buffer;
1716 var_value_sp->DumpPrintableRepresentation(
1719 eValueObjectRepresentationStyleSummary,
1729 if (var_value_sp->GetError().Success()) {
1730 if (!var_representation.empty())
1731 s.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
1733 s.
Printf(
"%s=%s at %s", var_name,
1734 var_value_sp->GetTypeName().GetCString(),
1735 var_value_sp->GetLocationAsCString());
1737 s.
Printf(
"%s=<unavailable>", var_name);
1765 const char *name =
nullptr;
1771 .GetName(Mangled::ePreferMangled)
1782 inline_info->GetName().Dump(&s);
1823 return function_changed;
1826 bool is_optimized =
false;
1828 is_optimized =
true;
1830 return is_optimized;
1834 return initial_function;
1848 const char *format =
"%" PRIu32;
1858 const char *format =
"%" PRIu32;
1880 RegisterContextSP reg_ctx =
1883 addr_t pc_loadaddr = reg_ctx->GetPC();
1905 for (
size_t i = 0; i < n; ++i) {
1919 const size_t sep_pos = format_str.find_first_of(
".[:");
1920 const char sep_char =
1921 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
1922 llvm::StringRef key = format_str.substr(0, sep_pos);
1925 for (
size_t i = 0; i < n; ++i) {
1927 if (key.equals(entry_def->
name) || entry_def->
name[0] ==
'*') {
1928 llvm::StringRef value;
1931 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
1932 switch (entry_def->
type) {
1934 entry.
string = format_str.str();
1951 if (value.empty()) {
1955 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
1956 "access one of its children: ",
1959 error.SetErrorStringWithFormat(
"%s", error_strm.
GetData());
1960 }
else if (sep_char ==
':') {
1966 error.SetErrorStringWithFormat(
"%s",
"invalid entry definitions");
1972 }
else if (sep_char ==
':') {
1976 entry.
string = value.str();
1978 error.SetErrorStringWithFormat(
1979 "'%s' followed by '%s' but it has no children", key.str().c_str(),
1980 value.str().c_str());
1989 "invalid top level item '%s'. Valid top level items are: ",
1992 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
1993 key.str().c_str(), parent->
name);
1995 error.SetErrorStringWithFormat(
"%s", error_strm.
GetData());
2001 llvm::StringRef &remainder) {
2004 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2006 for (
size_t i = 0; i < n; ++i) {
2008 if (p.first.equals(entry_def->
name) || entry_def->
name[0] ==
'*') {
2009 if (p.second.empty()) {
2010 if (format_str.back() ==
'.')
2011 remainder = format_str.drop_front(format_str.size() - 1);
2013 remainder = llvm::StringRef();
2017 return FindEntry(p.second, entry_def, remainder);
2019 remainder = p.second;
2025 remainder = format_str;
2032 while (!format.empty() &&
error.Success()) {
2033 const size_t non_special_chars = format.find_first_of(
"${}\\");
2035 if (non_special_chars == llvm::StringRef::npos) {
2041 if (non_special_chars > 0) {
2044 parent_entry.
AppendText(format.substr(0, non_special_chars));
2045 format = format.drop_front(non_special_chars);
2048 switch (format[0]) {
2053 format = format.drop_front();
2063 error.SetErrorString(
"unmatched '}' character");
2071 format = format.drop_front();
2072 if (format.empty()) {
2073 error.SetErrorString(
2074 "'\\' character was not followed by another character");
2078 const char desens_char = format[0];
2079 format = format.drop_front();
2080 switch (desens_char) {
2113 char oct_str[5] = {0, 0, 0, 0, 0};
2116 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2117 oct_str[i] = format[i];
2122 format = format.drop_front(i);
2123 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2124 if (octal_value <= UINT8_MAX) {
2127 error.SetErrorString(
"octal number is larger than a single byte");
2135 if (isxdigit(format[0])) {
2138 char hex_str[3] = {0, 0, 0};
2139 hex_str[0] = format[0];
2141 format = format.drop_front();
2143 if (isxdigit(format[0])) {
2144 hex_str[1] = format[0];
2145 format = format.drop_front();
2148 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2149 if (hex_value <= UINT8_MAX) {
2152 error.SetErrorString(
"hex number is larger than a single byte");
2169 if (format.size() == 1) {
2173 format = format.drop_front();
2175 if (format[0] ==
'{') {
2176 format = format.drop_front();
2178 llvm::StringRef variable, variable_format;
2183 bool verify_is_thread_id =
false;
2185 if (!variable_format.empty()) {
2197 bool clear_printf =
false;
2202 clear_printf =
true;
2208 clear_printf =
true;
2214 clear_printf =
true;
2219 clear_printf =
true;
2224 clear_printf =
true;
2229 clear_printf =
true;
2234 clear_printf =
true;
2239 clear_printf =
true;
2244 clear_printf =
true;
2247 error.SetErrorStringWithFormat(
"invalid format: '%s'",
2253 clear_printf =
true;
2255 verify_is_thread_id =
true;
2257 error.SetErrorStringWithFormat(
"invalid format: '%s'",
2270 if (variable[0] ==
'*') {
2272 variable = variable.drop_front();
2279 if (verify_is_thread_id) {
2282 error.SetErrorString(
"the 'tid' format can only be used on "
2283 "${thread.id} and ${thread.protocol_id}");
2287 switch (entry.
type) {
2291 if (entry.
string.empty())
2303 error.SetErrorStringWithFormat(
2304 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2305 variable.str().c_str());
2319 llvm::StringRef &variable_name,
2320 llvm::StringRef &variable_format) {
2322 variable_name = llvm::StringRef();
2323 variable_format = llvm::StringRef();
2325 const size_t paren_pos = format_str.find(
'}');
2326 if (paren_pos != llvm::StringRef::npos) {
2327 const size_t percent_pos = format_str.find(
'%');
2328 if (percent_pos < paren_pos) {
2329 if (percent_pos > 0) {
2330 if (percent_pos > 1)
2331 variable_name = format_str.substr(0, percent_pos);
2333 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2336 variable_name = format_str.substr(0, paren_pos);
2339 format_str = format_str.substr(paren_pos + 1);
2341 error.SetErrorStringWithFormat(
2342 "missing terminating '}' character for '${%s'",
2343 format_str.str().c_str());
2349 llvm::StringRef variable_name,
2350 llvm::StringRef variable_format) {
2351 if (variable_name.empty() || variable_name.equals(
".fullpath")) {
2354 }
else if (variable_name.equals(
".basename")) {
2357 }
else if (variable_name.equals(
".dirname")) {
2365 const char *suffix) {
2367 match.append(suffix);
2372 const llvm::StringRef &match_prefix,
2376 for (
size_t i = 0; i < n; ++i) {
2378 if (match_prefix.empty())
2380 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2381 match_prefix.size()) == 0)
2391 const size_t dollar_pos = str.rfind(
'$');
2392 if (dollar_pos == llvm::StringRef::npos)
2396 if (dollar_pos == str.size() - 1) {
2403 if (str[dollar_pos + 1] !=
'{')
2406 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2407 if (close_pos != llvm::StringRef::npos)
2410 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2411 if (format_pos != llvm::StringRef::npos)
2414 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2415 if (partial_variable.empty()) {
2424 llvm::StringRef remainder;
2431 if (remainder.empty()) {
2440 }
else if (remainder.equals(
".")) {
2443 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2449 AddMatches(entry_def, str, remainder, new_matches);