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::FrameRegisterTypeFlags),
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());
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) &&
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 llvm::StringRef additional_data(
1008 subpath.drop_front(close_bracket_index + 1));
1009 special_directions_stream
1011 << llvm::formatv(
"{0}var{1}", do_deref_pointer ?
"*" :
"",
1015 const char format_char =
1017 if (format_char !=
'\0')
1018 special_directions_stream.
Printf(
"%%%c", format_char);
1020 const char *format_cstr =
1022 special_directions_stream.
Printf(
"%%%s", format_cstr);
1024 }
else if (entry.
number != 0) {
1028 special_directions_stream.
Printf(
"%%%c", style_char);
1030 special_directions_stream.
PutChar(
'}');
1031 special_directions =
1032 llvm::StringRef(special_directions_stream.
GetString());
1038 if (index_higher < 0)
1041 uint32_t max_num_children =
1042 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1044 bool success =
true;
1045 for (int64_t index = index_lower; index <= index_higher; ++index) {
1050 "[Debugger::FormatPrompt] ERROR in getting child item at "
1056 "[Debugger::FormatPrompt] special_directions for child item: %s",
1057 special_directions.data() ? special_directions.data() :
"");
1060 if (special_directions.empty()) {
1067 if (--max_num_children == 0) {
1072 if (index < index_higher)
1103 llvm::StringRef path(entry.
string);
1106 thread_info_dictionary->GetObjectForDotSeparatedPath(path);
1110 const char *token_format =
"0x%4.4" PRIx64;
1113 s.
Printf(token_format, value->GetUnsignedIntegerValue());
1116 s.
Printf(
"%f", value->GetAsFloat()->GetValue());
1119 s.
Format(
"{0}", value->GetAsString()->GetValue());
1122 if (value->GetAsArray()->GetSize() > 0) {
1123 s.
Printf(
"%zu", value->GetAsArray()->GetSize());
1128 value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1136static inline bool IsToken(
const char *var_name_begin,
const char *var) {
1137 return (::strncmp(var_name_begin, var, strlen(var)) == 0);
1147static std::pair<char const *, char const *>
1149 const char *open_paren = strchr(full_name,
'(');
1150 const char *close_paren =
nullptr;
1151 const char *
generic = strchr(full_name,
'<');
1155 if (generic && open_paren && generic < open_paren) {
1156 int generic_depth = 1;
1158 for (; *
generic && generic_depth > 0;
generic++) {
1159 if (*generic ==
'<')
1161 if (*generic ==
'>')
1165 open_paren = strchr(generic,
'(');
1167 open_paren =
nullptr;
1171 if (
IsToken(open_paren,
"(anonymous namespace)")) {
1172 open_paren = strchr(open_paren + strlen(
"(anonymous namespace)"),
'(');
1174 close_paren = strchr(open_paren,
')');
1176 close_paren = strchr(open_paren,
')');
1179 return {open_paren, close_paren};
1186 char const *full_name,
1191 out_stream.
Write(full_name, open_paren - full_name + 1);
1210 return inline_block->GetBlockVariableList(
true);
1246 Language *language_plugin =
nullptr;
1247 bool language_plugin_handled =
false;
1254 if (language_plugin)
1258 if (language_plugin_handled) {
1281 Language *language_plugin =
nullptr;
1284 else if (
m_sc->symbol)
1287 if (!language_plugin)
1297 const bool success =
Format(format, name_stream,
nullptr);
1306 if (!format_str.empty()) {
1309 if (
error.Success()) {
1310 return Format(root, s, valobj);
1320 "Error: detected recursive format entity: {0}",
1327 switch (entry.
type) {
1336 Debugger &debugger = target->GetDebugger();
1346 if (!
Format(child, s, valobj)) {
1358 auto format_children = [&](
const std::vector<Entry> &children) {
1359 scope_stream.
Clear();
1360 for (
const auto &child : children) {
1361 if (!
Format(child, scope_stream, valobj))
1368 if (format_children(children)) {
1396 const char *format =
"%" PRIu64;
1431 const char *format =
"0x%4.4" PRIx64;
1438 Target &target = thread->GetProcess()->GetTarget();
1440 llvm::Triple::OSType ostype = arch.
IsValid()
1442 : llvm::Triple::UnknownOS;
1443 if (ostype == llvm::Triple::FreeBSD ||
1444 ostype == llvm::Triple::Linux ||
1445 ostype == llvm::Triple::NetBSD ||
1446 ostype == llvm::Triple::OpenBSD) {
1447 format =
"%" PRIu64;
1453 s.
Printf(format, thread->GetID());
1463 const char *format =
"0x%4.4" PRIx64;
1466 s.
Printf(format, thread->GetProtocolID());
1476 const char *format =
"%" PRIu32;
1479 s.
Printf(format, thread->GetIndexID());
1489 const char *cstr = thread->GetName();
1490 if (cstr && cstr[0]) {
1502 const char *cstr = thread->GetQueueName();
1503 if (cstr && cstr[0]) {
1514 std::string stop_description = thread->GetStopDescription();
1515 if (!stop_description.empty()) {
1526 std::string stop_description = thread->GetStopDescriptionRaw();
1527 if (!stop_description.empty()) {
1539 StopInfoSP stop_info_sp = thread->GetStopInfo();
1540 if (stop_info_sp && stop_info_sp->IsValid()) {
1543 if (return_valobj_sp) {
1545 if (return_valobj_sp->IsDynamic())
1547 if (return_valobj_sp->DoesProvideSyntheticValue())
1549 if (llvm::Error
error = return_valobj_sp->Dump(s, options)) {
1564 StopInfoSP stop_info_sp = thread->GetStopInfo();
1565 if (stop_info_sp && stop_info_sp->IsValid()) {
1568 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1569 if (llvm::Error
error =
1570 expression_var_sp->GetValueObject()->Dump(s)) {
1621 if (
Module *exe_module = target->GetExecutableModulePointer()) {
1662 const char *lang_name =
1676 const char *format =
"%" PRIu32;
1753 return frame->IsArtificial();
1760 if (frame->IsSynthetic())
1762 else if (frame->IsHistorical())
1773 llvm::dyn_cast<BorrowedStackFrame>(frame)) {
1775 borrowed_frame->GetBorrowedFrame()) {
1776 s.
Printf(
" [borrowed from frame #%u]",
1777 borrowed_from_sp->GetFrameIndex());
1796 if (
m_sc->function) {
1797 s.
Printf(
"function{0x%8.8" PRIx64
"}",
m_sc->function->GetID());
1799 }
else if (
m_sc->symbol) {
1800 s.
Printf(
"symbol[%u]",
m_sc->symbol->GetID());
1814 Language *language_plugin =
nullptr;
1815 bool language_plugin_handled =
false;
1820 else if (
m_sc->symbol)
1823 if (language_plugin)
1827 if (language_plugin_handled) {
1832 const char *name =
m_sc->GetPossiblyInlinedFunctionName()
1834 .AsCString(
nullptr);
1857 Language *language_plugin =
nullptr;
1858 bool language_plugin_handled =
false;
1862 else if (
m_sc->symbol)
1865 if (language_plugin)
1870 if (language_plugin_handled) {
1876 m_sc->GetPossiblyInlinedFunctionName()
1879 .AsCString(
nullptr);
1910 Language *language_plugin =
nullptr;
1913 else if (
m_sc->symbol)
1916 if (!language_plugin)
1949 const char *name =
m_sc->GetPossiblyInlinedFunctionName()
1951 .AsCString(
nullptr);
1997 bool is_optimized =
false;
1998 if (
m_sc &&
m_sc->function &&
m_sc->function->GetIsOptimized()) {
1999 is_optimized =
true;
2001 return is_optimized;
2005 return m_sc &&
m_sc->block &&
m_sc->block->GetInlinedFunctionInfo();
2012 if (
m_sc &&
m_sc->line_entry.IsValid()) {
2019 if (
m_sc &&
m_sc->line_entry.IsValid()) {
2020 const char *format =
"%" PRIu32;
2029 if (
m_sc &&
m_sc->line_entry.IsValid() &&
m_sc->line_entry.column) {
2030 const char *format =
"%" PRIu32;
2040 if (
m_sc &&
m_sc->line_entry.range.GetBaseAddress().IsValid()) {
2041 Address addr =
m_sc->line_entry.range.GetBaseAddress();
2044 addr.
Slide(
m_sc->line_entry.range.GetByteSize());
2053 m_exe_ctx->GetFramePtr()->GetRegisterContextSP();
2055 addr_t pc_loadaddr = reg_ctx->GetPC();
2058 pc.SetLoadAddress(pc_loadaddr,
m_exe_ctx->GetTargetPtr());
2072 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2074 s.
Format(
"[{0:N}/{1:N}]", progress->completed, progress->total);
2083 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2092 s << target->GetDebugger().GetSeparator();
2105 for (
size_t i = 0; i < n; ++i) {
2119 const size_t sep_pos = format_str.find_first_of(
".[:");
2120 const char sep_char =
2121 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
2122 llvm::StringRef key = format_str.substr(0, sep_pos);
2125 for (
size_t i = 0; i < n; ++i) {
2127 if (key == entry_def->
name || entry_def->
name[0] ==
'*') {
2128 llvm::StringRef value;
2131 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
2132 switch (entry_def->
type) {
2134 entry.
string = format_str.str();
2151 if (value.empty()) {
2155 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
2156 "access one of its children: ",
2161 }
else if (sep_char ==
':') {
2168 "%s",
"invalid entry definitions");
2174 }
else if (sep_char ==
':') {
2178 entry.
string = value.str();
2181 "'%s' followed by '%s' but it has no children", key.str().c_str(),
2182 value.str().c_str());
2191 "invalid top level item '%s'. Valid top level items are: ",
2194 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
2195 key.str().c_str(), parent->
name);
2203 llvm::StringRef &remainder) {
2206 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2208 for (
size_t i = 0; i < n; ++i) {
2210 if (p.first == entry_def->
name || entry_def->
name[0] ==
'*') {
2211 if (p.second.empty()) {
2212 if (format_str.back() ==
'.')
2213 remainder = format_str.drop_front(format_str.size() - 1);
2215 remainder = llvm::StringRef();
2219 return FindEntry(p.second, entry_def, remainder);
2221 remainder = p.second;
2227 remainder = format_str;
2234 while (!format.empty() &&
error.Success()) {
2235 const size_t non_special_chars = format.find_first_of(
"${}\\|");
2237 if (non_special_chars == llvm::StringRef::npos) {
2243 if (non_special_chars > 0) {
2246 parent_entry.
AppendText(format.substr(0, non_special_chars));
2247 format = format.drop_front(non_special_chars);
2250 switch (format[0]) {
2255 format = format.drop_front();
2273 format = format.drop_front();
2281 format = format.drop_front();
2282 if (format.empty()) {
2284 "'\\' character was not followed by another character");
2288 const char desens_char = format[0];
2289 format = format.drop_front();
2290 switch (desens_char) {
2323 char oct_str[5] = {0, 0, 0, 0, 0};
2326 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2327 oct_str[i] = format[i];
2332 format = format.drop_front(i);
2333 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2334 if (octal_value <= UINT8_MAX) {
2338 "octal number is larger than a single byte");
2346 if (isxdigit(format[0])) {
2349 char hex_str[3] = {0, 0, 0};
2350 hex_str[0] = format[0];
2352 format = format.drop_front();
2354 if (isxdigit(format[0])) {
2355 hex_str[1] = format[0];
2356 format = format.drop_front();
2359 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2360 if (hex_value <= UINT8_MAX) {
2364 "hex number is larger than a single byte");
2381 format = format.drop_front();
2382 if (format.empty() || format.front() !=
'{') {
2386 format = format.drop_front();
2388 llvm::StringRef variable, variable_format;
2393 bool verify_is_thread_id =
false;
2395 if (!variable_format.empty()) {
2407 bool clear_printf =
false;
2412 entry.
number = ValueObject::
2413 eValueObjectRepresentationStyleLanguageSpecific;
2414 clear_printf =
true;
2420 clear_printf =
true;
2425 clear_printf =
true;
2430 clear_printf =
true;
2435 clear_printf =
true;
2439 clear_printf =
true;
2443 clear_printf =
true;
2448 clear_printf =
true;
2456 clear_printf =
true;
2458 verify_is_thread_id =
true;
2474 if (variable[0] ==
'*') {
2476 variable = variable.drop_front();
2483 llvm::StringRef entry_string(entry.
string);
2484 if (entry_string.contains(
':')) {
2485 auto [_, llvm_format] = entry_string.split(
':');
2488 "invalid llvm format: '%s'", llvm_format.data());
2493 if (verify_is_thread_id) {
2497 "the 'tid' format can only be used on "
2498 "${thread.id} and ${thread.protocol_id}");
2502 switch (entry.
type) {
2506 if (entry.
string.empty())
2518 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2519 variable.str().c_str());
2532 llvm::StringRef &variable_name,
2533 llvm::StringRef &variable_format) {
2535 variable_name = llvm::StringRef();
2536 variable_format = llvm::StringRef();
2538 const size_t paren_pos = format_str.find(
'}');
2539 if (paren_pos != llvm::StringRef::npos) {
2540 const size_t percent_pos = format_str.find(
'%');
2541 if (percent_pos < paren_pos) {
2542 if (percent_pos > 0) {
2543 if (percent_pos > 1)
2544 variable_name = format_str.substr(0, percent_pos);
2546 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2549 variable_name = format_str.substr(0, paren_pos);
2552 format_str = format_str.substr(paren_pos + 1);
2555 "missing terminating '}' character for '${%s'",
2556 format_str.str().c_str());
2562 llvm::StringRef variable_name,
2563 llvm::StringRef variable_format) {
2564 if (variable_name.empty() || variable_name ==
".fullpath") {
2567 }
else if (variable_name ==
".basename") {
2570 }
else if (variable_name ==
".dirname") {
2578 const char *suffix) {
2579 std::string match(prefix.str());
2580 match.append(suffix);
2585 const llvm::StringRef &match_prefix,
2589 for (
size_t i = 0; i < n; ++i) {
2590 if (match_prefix.empty())
2592 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2593 match_prefix.size()) == 0)
2603 const size_t dollar_pos = str.rfind(
'$');
2604 if (dollar_pos == llvm::StringRef::npos)
2608 if (dollar_pos == str.size() - 1) {
2609 std::string match = str.str();
2615 if (str[dollar_pos + 1] !=
'{')
2618 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2619 if (close_pos != llvm::StringRef::npos)
2622 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2623 if (format_pos != llvm::StringRef::npos)
2626 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2627 if (partial_variable.empty()) {
2636 llvm::StringRef remainder;
2643 if (remainder.empty()) {
2652 }
else if (remainder ==
".") {
2655 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2661 AddMatches(entry_def, str, remainder, new_matches);
2669 const size_t num_args = args.
GetSize();
2670 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
2676 llvm::StringRef var_representation;
2677 const char *var_name = var_value_sp->GetName().GetCString();
2678 if (var_value_sp->GetCompilerType().IsValid()) {
2680 var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
2682 ->TargetProperties::GetPreferDynamicValue(),
2684 ->TargetProperties::GetEnableSyntheticValue());
2685 if (var_value_sp->GetCompilerType().IsAggregateType() &&
2688 .SetHideItemNames(
false)
2689 .SetShowMembersOneLiner(
true),
2692 var_representation = buffer;
2694 var_value_sp->DumpPrintableRepresentation(
2697 eValueObjectRepresentationStyleSummary,
2706 if (var_value_sp->GetError().Success()) {
2707 if (!var_representation.empty())
2708 out_stream.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
2710 out_stream.
Printf(
"%s=%s at %s", var_name,
2711 var_value_sp->GetTypeName().GetCString(),
2712 var_value_sp->GetLocationAsCString());
2714 out_stream.
Printf(
"%s=<unavailable>", var_name);
2721 llvm::StringRef modifiable_format(format_str);
2732 static constexpr std::array s_permitted_recursive_entities = {
2735 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
const char * AsCString(const char *value_if_empty) 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={})
DumpValueObjectOptions & SetUseSyntheticValue(bool use_synthetic=true)
DumpValueObjectOptions & SetUseDynamicType(lldb::DynamicValueType dyn=lldb::eNoDynamicValues)
"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
llvm::StringRef GetFilename() const
Filename string const get accessor.
llvm::StringRef 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)
Forwards the arguments to llvm::formatv and writes to the stream.
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)
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)
CompilerType GetCompilerType()
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.
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_type=false, lldb::TargetSP target_sp=nullptr)
std::string toString(FormatterBytecode::OpCodes op)
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
@ eValueTypeVariableArgument
function argument variables
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
@ eStructuredDataTypeFloat
@ eStructuredDataTypeDictionary
@ eStructuredDataTypeInteger
@ eStructuredDataTypeArray
@ eStructuredDataTypeString
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
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()