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;
828 auto split = llvm::StringRef(entry.
string).split(
':');
829 auto subpath = split.first;
830 auto llvm_format = split.second;
833 if (subpath.empty()) {
836 was_plain_var =
true;
838 was_var_format =
true;
842 if (subpath[0] ==
'[')
843 was_var_indexed =
true;
845 var_name_final_if_array_range, index_lower,
850 LLDB_LOG(log,
"[Debugger::FormatPrompt] symbol to expand: {0}", subpath);
855 &final_value_type, options, &what_next)
860 "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
861 " final_value_type %d",
862 reason_to_stop, final_value_type);
866 "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
867 " final_value_type %d",
868 reason_to_stop, final_value_type);
885 if (do_deref_pointer && !is_array_range) {
892 LLDB_LOGF(log,
"[Debugger::FormatPrompt] ERROR: %s\n",
893 error.AsCString(
"unknown"));
896 do_deref_pointer =
false;
900 LLDB_LOGF(log,
"[Debugger::FormatPrompt] could not calculate target for "
901 "prompt expression");
908 if (target->
IsBitfield() && was_var_indexed) {
913 auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
915 if (val_obj_display ==
922 const uint32_t type_info_flags =
924 bool is_array = (type_info_flags & eTypeIsArray) != 0;
925 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
928 if ((is_array || is_pointer) && (!is_array_range) &&
937 "[Debugger::FormatPrompt] I am into array || pointer && !range");
943 str_temp, val_obj_display, custom_format);
944 LLDB_LOGF(log,
"[Debugger::FormatPrompt] special cases did%s match",
945 success ?
"" :
"n't");
955 }
else if (is_pointer)
958 s, val_obj_display, custom_format,
967 if (is_aggregate && was_plain_var) {
978 s <<
"<invalid use of aggregate type>";
982 if (!is_array_range) {
983 if (!llvm_format.empty()) {
985 LLDB_LOGF(log,
"dumping using llvm format");
990 "empty output using llvm format '{0}' - with type info flags {1}",
994 LLDB_LOGF(log,
"dumping ordinary printable output");
999 "[Debugger::FormatPrompt] checking if I can handle as array");
1000 if (!is_array && !is_pointer)
1002 LLDB_LOGF(log,
"[Debugger::FormatPrompt] handle as array");
1004 llvm::StringRef special_directions;
1005 if (close_bracket_index != llvm::StringRef::npos &&
1006 subpath.size() > close_bracket_index) {
1007 ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
1008 special_directions_stream.
Printf(
"${%svar%s", do_deref_pointer ?
"*" :
"",
1012 const char format_char =
1014 if (format_char !=
'\0')
1015 special_directions_stream.
Printf(
"%%%c", format_char);
1017 const char *format_cstr =
1019 special_directions_stream.
Printf(
"%%%s", format_cstr);
1021 }
else if (entry.
number != 0) {
1025 special_directions_stream.
Printf(
"%%%c", style_char);
1027 special_directions_stream.
PutChar(
'}');
1028 special_directions =
1029 llvm::StringRef(special_directions_stream.
GetString());
1035 if (index_higher < 0)
1038 uint32_t max_num_children =
1039 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1041 bool success =
true;
1042 for (int64_t index = index_lower; index <= index_higher; ++index) {
1047 "[Debugger::FormatPrompt] ERROR in getting child item at "
1053 "[Debugger::FormatPrompt] special_directions for child item: %s",
1054 special_directions.data() ? special_directions.data() :
"");
1057 if (special_directions.empty()) {
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) {
1278 Language *language_plugin =
nullptr;
1281 else if (
m_sc->symbol)
1284 if (!language_plugin)
1294 const bool success =
Format(format, name_stream,
nullptr);
1303 if (!format_str.empty()) {
1306 if (
error.Success()) {
1307 return Format(root, s, valobj);
1317 "Error: detected recursive format entity: {0}",
1324 switch (entry.
type) {
1333 Debugger &debugger = target->GetDebugger();
1343 if (!
Format(child, s, valobj)) {
1355 auto format_children = [&](
const std::vector<Entry> &children) {
1356 scope_stream.
Clear();
1357 for (
const auto &child : children) {
1358 if (!
Format(child, scope_stream, valobj))
1365 if (format_children(children)) {
1393 const char *format =
"%" PRIu64;
1428 const char *format =
"0x%4.4" PRIx64;
1435 Target &target = thread->GetProcess()->GetTarget();
1437 llvm::Triple::OSType ostype = arch.
IsValid()
1439 : llvm::Triple::UnknownOS;
1440 if (ostype == llvm::Triple::FreeBSD ||
1441 ostype == llvm::Triple::Linux ||
1442 ostype == llvm::Triple::NetBSD ||
1443 ostype == llvm::Triple::OpenBSD) {
1444 format =
"%" PRIu64;
1450 s.
Printf(format, thread->GetID());
1460 const char *format =
"0x%4.4" PRIx64;
1463 s.
Printf(format, thread->GetProtocolID());
1473 const char *format =
"%" PRIu32;
1476 s.
Printf(format, thread->GetIndexID());
1486 const char *cstr = thread->GetName();
1487 if (cstr && cstr[0]) {
1499 const char *cstr = thread->GetQueueName();
1500 if (cstr && cstr[0]) {
1511 std::string stop_description = thread->GetStopDescription();
1512 if (!stop_description.empty()) {
1523 std::string stop_description = thread->GetStopDescriptionRaw();
1524 if (!stop_description.empty()) {
1536 StopInfoSP stop_info_sp = thread->GetStopInfo();
1537 if (stop_info_sp && stop_info_sp->IsValid()) {
1540 if (return_valobj_sp) {
1541 if (llvm::Error
error = return_valobj_sp->Dump(s)) {
1556 StopInfoSP stop_info_sp = thread->GetStopInfo();
1557 if (stop_info_sp && stop_info_sp->IsValid()) {
1560 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1561 if (llvm::Error
error =
1562 expression_var_sp->GetValueObject()->Dump(s)) {
1613 if (
Module *exe_module = target->GetExecutableModulePointer()) {
1654 const char *lang_name =
1668 const char *format =
"%" PRIu32;
1745 return frame->IsArtificial();
1752 if (frame->IsSynthetic())
1754 else if (frame->IsHistorical())
1765 llvm::dyn_cast<BorrowedStackFrame>(frame)) {
1767 borrowed_frame->GetBorrowedFrame()) {
1768 s.
Printf(
" [borrowed from frame #%u]",
1769 borrowed_from_sp->GetFrameIndex());
1788 if (
m_sc->function) {
1789 s.
Printf(
"function{0x%8.8" PRIx64
"}",
m_sc->function->GetID());
1791 }
else if (
m_sc->symbol) {
1792 s.
Printf(
"symbol[%u]",
m_sc->symbol->GetID());
1806 Language *language_plugin =
nullptr;
1807 bool language_plugin_handled =
false;
1812 else if (
m_sc->symbol)
1815 if (language_plugin)
1819 if (language_plugin_handled) {
1824 const char *name =
m_sc->GetPossiblyInlinedFunctionName()
1849 Language *language_plugin =
nullptr;
1850 bool language_plugin_handled =
false;
1854 else if (
m_sc->symbol)
1857 if (language_plugin)
1862 if (language_plugin_handled) {
1868 m_sc->GetPossiblyInlinedFunctionName()
1902 Language *language_plugin =
nullptr;
1905 else if (
m_sc->symbol)
1908 if (!language_plugin)
1941 const char *name =
m_sc->GetPossiblyInlinedFunctionName()
1989 bool is_optimized =
false;
1990 if (
m_sc &&
m_sc->function &&
m_sc->function->GetIsOptimized()) {
1991 is_optimized =
true;
1993 return is_optimized;
1997 return m_sc &&
m_sc->block &&
m_sc->block->GetInlinedFunctionInfo();
2004 if (
m_sc &&
m_sc->line_entry.IsValid()) {
2011 if (
m_sc &&
m_sc->line_entry.IsValid()) {
2012 const char *format =
"%" PRIu32;
2021 if (
m_sc &&
m_sc->line_entry.IsValid() &&
m_sc->line_entry.column) {
2022 const char *format =
"%" PRIu32;
2032 if (
m_sc &&
m_sc->line_entry.range.GetBaseAddress().IsValid()) {
2033 Address addr =
m_sc->line_entry.range.GetBaseAddress();
2036 addr.
Slide(
m_sc->line_entry.range.GetByteSize());
2045 m_exe_ctx->GetFramePtr()->GetRegisterContextSP();
2047 addr_t pc_loadaddr = reg_ctx->GetPC();
2050 pc.SetLoadAddress(pc_loadaddr,
m_exe_ctx->GetTargetPtr());
2064 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2066 s.
Format(
"[{0:N}/{1:N}]", progress->completed, progress->total);
2075 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2084 s << target->GetDebugger().GetSeparator();
2097 for (
size_t i = 0; i < n; ++i) {
2111 const size_t sep_pos = format_str.find_first_of(
".[:");
2112 const char sep_char =
2113 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
2114 llvm::StringRef key = format_str.substr(0, sep_pos);
2117 for (
size_t i = 0; i < n; ++i) {
2119 if (key == entry_def->
name || entry_def->
name[0] ==
'*') {
2120 llvm::StringRef value;
2123 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
2124 switch (entry_def->
type) {
2126 entry.
string = format_str.str();
2143 if (value.empty()) {
2147 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
2148 "access one of its children: ",
2153 }
else if (sep_char ==
':') {
2160 "%s",
"invalid entry definitions");
2166 }
else if (sep_char ==
':') {
2170 entry.
string = value.str();
2173 "'%s' followed by '%s' but it has no children", key.str().c_str(),
2174 value.str().c_str());
2183 "invalid top level item '%s'. Valid top level items are: ",
2186 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
2187 key.str().c_str(), parent->
name);
2195 llvm::StringRef &remainder) {
2198 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2200 for (
size_t i = 0; i < n; ++i) {
2202 if (p.first == entry_def->
name || entry_def->
name[0] ==
'*') {
2203 if (p.second.empty()) {
2204 if (format_str.back() ==
'.')
2205 remainder = format_str.drop_front(format_str.size() - 1);
2207 remainder = llvm::StringRef();
2211 return FindEntry(p.second, entry_def, remainder);
2213 remainder = p.second;
2219 remainder = format_str;
2226 while (!format.empty() &&
error.Success()) {
2227 const size_t non_special_chars = format.find_first_of(
"${}\\|");
2229 if (non_special_chars == llvm::StringRef::npos) {
2235 if (non_special_chars > 0) {
2238 parent_entry.
AppendText(format.substr(0, non_special_chars));
2239 format = format.drop_front(non_special_chars);
2242 switch (format[0]) {
2247 format = format.drop_front();
2265 format = format.drop_front();
2273 format = format.drop_front();
2274 if (format.empty()) {
2276 "'\\' character was not followed by another character");
2280 const char desens_char = format[0];
2281 format = format.drop_front();
2282 switch (desens_char) {
2315 char oct_str[5] = {0, 0, 0, 0, 0};
2318 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2319 oct_str[i] = format[i];
2324 format = format.drop_front(i);
2325 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2326 if (octal_value <= UINT8_MAX) {
2330 "octal number is larger than a single byte");
2338 if (isxdigit(format[0])) {
2341 char hex_str[3] = {0, 0, 0};
2342 hex_str[0] = format[0];
2344 format = format.drop_front();
2346 if (isxdigit(format[0])) {
2347 hex_str[1] = format[0];
2348 format = format.drop_front();
2351 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2352 if (hex_value <= UINT8_MAX) {
2356 "hex number is larger than a single byte");
2373 format = format.drop_front();
2374 if (format.empty() || format.front() !=
'{') {
2378 format = format.drop_front();
2380 llvm::StringRef variable, variable_format;
2385 bool verify_is_thread_id =
false;
2387 if (!variable_format.empty()) {
2399 bool clear_printf =
false;
2404 entry.
number = ValueObject::
2405 eValueObjectRepresentationStyleLanguageSpecific;
2406 clear_printf =
true;
2412 clear_printf =
true;
2417 clear_printf =
true;
2422 clear_printf =
true;
2427 clear_printf =
true;
2431 clear_printf =
true;
2435 clear_printf =
true;
2440 clear_printf =
true;
2448 clear_printf =
true;
2450 verify_is_thread_id =
true;
2466 if (variable[0] ==
'*') {
2468 variable = variable.drop_front();
2475 llvm::StringRef entry_string(entry.
string);
2476 if (entry_string.contains(
':')) {
2477 auto [_, llvm_format] = entry_string.split(
':');
2480 "invalid llvm format: '%s'", llvm_format.data());
2485 if (verify_is_thread_id) {
2489 "the 'tid' format can only be used on "
2490 "${thread.id} and ${thread.protocol_id}");
2494 switch (entry.
type) {
2498 if (entry.
string.empty())
2510 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2511 variable.str().c_str());
2524 llvm::StringRef &variable_name,
2525 llvm::StringRef &variable_format) {
2527 variable_name = llvm::StringRef();
2528 variable_format = llvm::StringRef();
2530 const size_t paren_pos = format_str.find(
'}');
2531 if (paren_pos != llvm::StringRef::npos) {
2532 const size_t percent_pos = format_str.find(
'%');
2533 if (percent_pos < paren_pos) {
2534 if (percent_pos > 0) {
2535 if (percent_pos > 1)
2536 variable_name = format_str.substr(0, percent_pos);
2538 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2541 variable_name = format_str.substr(0, paren_pos);
2544 format_str = format_str.substr(paren_pos + 1);
2547 "missing terminating '}' character for '${%s'",
2548 format_str.str().c_str());
2554 llvm::StringRef variable_name,
2555 llvm::StringRef variable_format) {
2556 if (variable_name.empty() || variable_name ==
".fullpath") {
2559 }
else if (variable_name ==
".basename") {
2562 }
else if (variable_name ==
".dirname") {
2570 const char *suffix) {
2571 std::string match(prefix.str());
2572 match.append(suffix);
2577 const llvm::StringRef &match_prefix,
2581 for (
size_t i = 0; i < n; ++i) {
2582 if (match_prefix.empty())
2584 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2585 match_prefix.size()) == 0)
2595 const size_t dollar_pos = str.rfind(
'$');
2596 if (dollar_pos == llvm::StringRef::npos)
2600 if (dollar_pos == str.size() - 1) {
2601 std::string match = str.str();
2607 if (str[dollar_pos + 1] !=
'{')
2610 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2611 if (close_pos != llvm::StringRef::npos)
2614 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2615 if (format_pos != llvm::StringRef::npos)
2618 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2619 if (partial_variable.empty()) {
2628 llvm::StringRef remainder;
2635 if (remainder.empty()) {
2644 }
else if (remainder ==
".") {
2647 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2653 AddMatches(entry_def, str, remainder, new_matches);
2661 const size_t num_args = args.
GetSize();
2662 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
2668 llvm::StringRef var_representation;
2669 const char *var_name = var_value_sp->GetName().GetCString();
2670 if (var_value_sp->GetCompilerType().IsValid()) {
2672 var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
2674 ->TargetProperties::GetPreferDynamicValue(),
2676 ->TargetProperties::GetEnableSyntheticValue());
2677 if (var_value_sp->GetCompilerType().IsAggregateType() &&
2680 .SetHideItemNames(
false)
2681 .SetShowMembersOneLiner(
true),
2684 var_representation = buffer;
2686 var_value_sp->DumpPrintableRepresentation(
2689 eValueObjectRepresentationStyleSummary,
2698 if (var_value_sp->GetError().Success()) {
2699 if (!var_representation.empty())
2700 out_stream.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
2702 out_stream.
Printf(
"%s=%s at %s", var_name,
2703 var_value_sp->GetTypeName().GetCString(),
2704 var_value_sp->GetLocationAsCString());
2706 out_stream.
Printf(
"%s=<unavailable>", var_name);
2713 llvm::StringRef modifiable_format(format_str);
2724 static constexpr std::array s_permitted_recursive_entities = {
2727 if (llvm::is_contained(s_permitted_recursive_entities, type))
#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.
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.
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
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.
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.
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.
Symbol * symbol
The Symbol 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
Every register is described in detail including its name, alternate name (optional),...
GetValueForExpressionPathOptions & SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse)
GetValueForExpressionPathOptions & DoAllowFragileIVar()
GetValueForExpressionPathOptions & DontCheckDotVsArrowSyntax()
GetValueForExpressionPathOptions & DoAllowBitfieldSyntax()