57#include "llvm/ADT/STLExtras.h"
58#include "llvm/ADT/StringRef.h"
59#include "llvm/Support/Compiler.h"
60#include "llvm/Support/Regex.h"
61#include "llvm/TargetParser/Triple.h"
106 Definition(
"flags", EntryType::FrameRegisterTypeFlags),
107 Definition(
"no-debug", EntryType::FrameNoDebug),
110 Definition(
"is-artificial", EntryType::FrameIsArtificial),
112 Definition(
"borrowed-info", EntryType::FrameBorrowedInfo),
118 Definition(
"name-without-args", EntryType::FunctionNameNoArgs),
119 Definition(
"name-with-args", EntryType::FunctionNameWithArgs),
120 Definition(
"mangled-name", EntryType::FunctionMangledName),
121 Definition(
"addr-offset", EntryType::FunctionAddrOffset),
122 Definition(
"concrete-only-addr-offset-no-padding",
123 EntryType::FunctionAddrOffsetConcrete),
124 Definition(
"line-offset", EntryType::FunctionLineOffset),
125 Definition(
"pc-offset", EntryType::FunctionPCOffset),
126 Definition(
"initial-function", EntryType::FunctionInitial),
127 Definition(
"changed", EntryType::FunctionChanged),
128 Definition(
"is-optimized", EntryType::FunctionIsOptimized),
129 Definition(
"is-inlined", EntryType::FunctionIsInlined),
130 Definition(
"prefix", EntryType::FunctionPrefix),
131 Definition(
"scope", EntryType::FunctionScope),
132 Definition(
"basename", EntryType::FunctionBasename),
133 Definition(
"name-qualifiers", EntryType::FunctionNameQualifiers),
134 Definition(
"template-arguments", EntryType::FunctionTemplateArguments),
135 Definition(
"formatted-arguments", EntryType::FunctionFormattedArguments),
136 Definition(
"return-left", EntryType::FunctionReturnLeft),
137 Definition(
"return-right", EntryType::FunctionReturnRight),
138 Definition(
"qualifiers", EntryType::FunctionQualifiers),
139 Definition(
"suffix", EntryType::FunctionSuffix),
145 Definition(
"number", EntryType::LineEntryLineNumber),
146 Definition(
"column", EntryType::LineEntryColumn),
147 Definition(
"start-addr", EntryType::LineEntryStartAddress),
148 Definition(
"end-addr", EntryType::LineEntryEndAddress),
168 Definition(
"protocol_id", EntryType::ThreadProtocolID),
169 Definition(
"index", EntryType::ThreadIndexID),
174 Definition(
"stop-reason", EntryType::ThreadStopReason),
175 Definition(
"stop-reason-raw", EntryType::ThreadStopReasonRaw),
176 Definition(
"return-value", EntryType::ThreadReturnValue),
177 Definition(
"completed-expression", EntryType::ThreadCompletedExpression)};
185 Definition(
"count", EntryType::ProgressCount),
186 Definition(
"message", EntryType::ProgressMessage)};
188#define _TO_STR2(_val) #_val
189#define _TO_STR(_val) _TO_STR2(_val)
246 Definition(
"process", EntryType::ScriptProcess),
247 Definition(
"target", EntryType::ScriptTarget),
248 Definition(
"thread", EntryType::ScriptThread),
250 Definition(
"svar", EntryType::ScriptVariableSynthetic),
251 Definition(
"thread", EntryType::ScriptThread)};
256 Definition(
"addr-file-or-load", EntryType::AddressLoadOrFile),
258 Definition(
"current-pc-arrow", EntryType::CurrentPCArrow),
284 Definition(
"separator", EntryType::Separator),
309 entries.push_back(
Entry(ch));
311 entries.back().string.append(1, ch);
317 entries.push_back(
Entry(s));
319 entries.back().string.append(s.data(), s.size());
328 entries.push_back(entry);
337#define ENUM_TO_CSTR(eee) \
338 case FormatEntity::Entry::Type::eee: \
433 s.
Printf(
"string = \"%s\"",
string.c_str());
442 for (
const auto &child : children)
443 child.Dump(s, depth + 1);
450 const char *script_function_name) {
456 if (script_interpreter) {
458 std::string script_output;
461 script_output,
error) &&
476 bool print_file_addr_or_load_addr) {
491 if (print_file_addr_or_load_addr) {
497 s.
Printf(
"0x%*.*" PRIx64, addr_width, addr_width, vaddr);
506 bool concrete_only,
bool no_padding,
507 bool print_zero_offsets) {
514 if (sc->
block && !concrete_only) {
521 format_addr, inline_range))
529 const char *addr_offset_padding = no_padding ?
"" :
" ";
534 if (addr_file_addr > func_file_addr ||
535 (addr_file_addr == func_file_addr && print_zero_offsets)) {
536 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
537 addr_file_addr - func_file_addr);
538 }
else if (addr_file_addr < func_file_addr) {
539 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
540 func_file_addr - addr_file_addr);
548 if (addr_load_addr > func_load_addr ||
549 (addr_load_addr == func_load_addr && print_zero_offsets)) {
550 s.
Printf(
"%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
551 addr_load_addr - func_load_addr);
552 }
else if (addr_load_addr < func_load_addr) {
553 s.
Printf(
"%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
554 func_load_addr - addr_load_addr);
565 size_t &close_bracket_index,
566 const char *&var_name_final_if_array_range,
567 int64_t &index_lower, int64_t &index_higher) {
569 close_bracket_index = llvm::StringRef::npos;
570 const size_t open_bracket_index = subpath.find(
'[');
571 if (open_bracket_index == llvm::StringRef::npos) {
573 "[ScanBracketedRange] no bracketed range, skipping entirely");
577 close_bracket_index = subpath.find(
']', open_bracket_index + 1);
579 if (close_bracket_index == llvm::StringRef::npos) {
581 "[ScanBracketedRange] no bracketed range, skipping entirely");
584 var_name_final_if_array_range = subpath.data() + open_bracket_index;
586 if (close_bracket_index - open_bracket_index == 1) {
589 "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
592 const size_t separator_index = subpath.find(
'-', open_bracket_index + 1);
594 if (separator_index == llvm::StringRef::npos) {
595 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
596 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
597 index_higher = index_lower;
599 "[ScanBracketedRange] [%" PRId64
600 "] detected, high index is same",
603 const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
604 const char *index_higher_cstr = subpath.data() + separator_index + 1;
605 index_lower = ::strtoul(index_lower_cstr,
nullptr, 0);
606 index_higher = ::strtoul(index_higher_cstr,
nullptr, 0);
608 "[ScanBracketedRange] [%" PRId64
"-%" PRId64
"] detected",
609 index_lower, index_higher);
611 if (index_lower > index_higher && index_higher > 0) {
612 LLDB_LOGF(log,
"[ScanBracketedRange] swapping indices");
613 const int64_t temp = index_lower;
614 index_lower = index_higher;
652 uint32_t reg_num,
Format format) {
657 const uint32_t lldb_reg_num =
676 bool deref_pointer) {
678 std::string name_to_deref = llvm::formatv(
"[{0}]", index);
679 LLDB_LOG(log,
"[ExpandIndexedExpression] name to deref: {0}", name_to_deref);
687 name_to_deref, &reason_to_stop, &final_value_type, options, &what_next);
690 "[ExpandIndexedExpression] ERROR: why stopping = %d,"
691 " final_value_type %d",
692 reason_to_stop, final_value_type);
695 "[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
696 " final_value_type %d",
697 reason_to_stop, final_value_type);
731 std::string formatted;
732 std::string llvm_format = (
"{0:" + options +
"}").str();
736 if (type_info & eTypeIsSigned) {
737 bool success =
false;
740 formatted = llvm::formatv(llvm_format.data(),
integer);
742 bool success =
false;
745 formatted = llvm::formatv(llvm_format.data(),
integer);
749 if (formatted.empty())
752 s.
Write(formatted.data(), formatted.size());
759 if (valobj ==
nullptr)
769 bool do_deref_pointer = entry.
deref;
770 bool is_script =
false;
771 switch (entry.
type) {
777 custom_format = entry.
fmt;
785 custom_format = entry.
fmt;
789 if (valobj ==
nullptr)
807 SyntheticChildrenTraversal::Both);
809 const char *var_name_final_if_array_range =
nullptr;
810 size_t close_bracket_index = llvm::StringRef::npos;
811 int64_t index_lower = -1;
812 int64_t index_higher = -1;
813 bool is_array_range =
false;
814 bool was_plain_var =
false;
815 bool was_var_format =
false;
816 bool was_var_indexed =
false;
827 auto split = llvm::StringRef(entry.
string).split(
':');
828 auto subpath = split.first;
829 auto llvm_format = split.second;
832 if (subpath.empty()) {
835 was_plain_var =
true;
837 was_var_format =
true;
841 if (subpath[0] ==
'[')
842 was_var_indexed =
true;
844 var_name_final_if_array_range, index_lower,
849 LLDB_LOG(log,
"[Debugger::FormatPrompt] symbol to expand: {0}", subpath);
854 &final_value_type, options, &what_next)
859 "[Debugger::FormatPrompt] ERROR: why stopping = %d,"
860 " final_value_type %d",
861 reason_to_stop, final_value_type);
865 "[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
866 " final_value_type %d",
867 reason_to_stop, final_value_type);
884 if (do_deref_pointer && !is_array_range) {
891 LLDB_LOGF(log,
"[Debugger::FormatPrompt] ERROR: %s\n",
892 error.AsCString(
"unknown"));
895 do_deref_pointer =
false;
899 LLDB_LOGF(log,
"[Debugger::FormatPrompt] could not calculate target for "
900 "prompt expression");
907 if (target->
IsBitfield() && was_var_indexed) {
912 auto type_sp = std::make_shared<TypeNameSpecifierImpl>(
914 if (val_obj_display ==
921 const uint32_t type_info_flags =
923 bool is_array = (type_info_flags & eTypeIsArray) != 0;
924 bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
927 if ((is_array || is_pointer) && (!is_array_range) &&
936 "[Debugger::FormatPrompt] I am into array || pointer && !range");
942 str_temp, val_obj_display, custom_format);
943 LLDB_LOGF(log,
"[Debugger::FormatPrompt] special cases did%s match",
944 success ?
"" :
"n't");
954 }
else if (is_pointer)
957 s, val_obj_display, custom_format,
966 if (is_aggregate && was_plain_var) {
977 s <<
"<invalid use of aggregate type>";
981 if (!is_array_range) {
982 if (!llvm_format.empty()) {
984 LLDB_LOGF(log,
"dumping using llvm format");
989 "empty output using llvm format '{0}' - with type info flags {1}",
993 LLDB_LOGF(log,
"dumping ordinary printable output");
998 "[Debugger::FormatPrompt] checking if I can handle as array");
999 if (!is_array && !is_pointer)
1001 LLDB_LOGF(log,
"[Debugger::FormatPrompt] handle as array");
1003 llvm::StringRef special_directions;
1004 if (close_bracket_index != llvm::StringRef::npos &&
1005 subpath.size() > close_bracket_index) {
1006 llvm::StringRef additional_data(
1007 subpath.drop_front(close_bracket_index + 1));
1008 special_directions_stream
1010 << llvm::formatv(
"{0}var{1}", do_deref_pointer ?
"*" :
"",
1014 const char format_char =
1016 if (format_char !=
'\0')
1017 special_directions_stream.
Printf(
"%%%c", format_char);
1019 const char *format_cstr =
1021 special_directions_stream.
Printf(
"%%%s", format_cstr);
1023 }
else if (entry.
number != 0) {
1027 special_directions_stream.
Printf(
"%%%c", style_char);
1029 special_directions_stream.
PutChar(
'}');
1030 special_directions =
1031 llvm::StringRef(special_directions_stream.
GetString());
1037 if (index_higher < 0)
1040 uint32_t max_num_children =
1041 target->
GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
1043 bool success =
true;
1044 for (int64_t index = index_lower; index <= index_higher; ++index) {
1049 "[Debugger::FormatPrompt] ERROR in getting child item at "
1055 "[Debugger::FormatPrompt] special_directions for child item: %s",
1056 special_directions.data() ? special_directions.data() :
"");
1059 if (special_directions.empty()) {
1066 if (--max_num_children == 0) {
1071 if (index < index_higher)
1102 llvm::StringRef path(entry.
string);
1105 thread_info_dictionary->GetObjectForDotSeparatedPath(path);
1109 const char *token_format =
"0x%4.4" PRIx64;
1112 s.
Printf(token_format, value->GetUnsignedIntegerValue());
1115 s.
Printf(
"%f", value->GetAsFloat()->GetValue());
1118 s.
Format(
"{0}", value->GetAsString()->GetValue());
1121 if (value->GetAsArray()->GetSize() > 0) {
1122 s.
Printf(
"%zu", value->GetAsArray()->GetSize());
1127 value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
1135static inline bool IsToken(
const char *var_name_begin,
const char *var) {
1136 return (::strncmp(var_name_begin, var, strlen(var)) == 0);
1146static std::pair<char const *, char const *>
1148 const char *open_paren = strchr(full_name,
'(');
1149 const char *close_paren =
nullptr;
1150 const char *
generic = strchr(full_name,
'<');
1154 if (generic && open_paren && generic < open_paren) {
1155 int generic_depth = 1;
1157 for (; *
generic && generic_depth > 0;
generic++) {
1158 if (*generic ==
'<')
1160 if (*generic ==
'>')
1164 open_paren = strchr(generic,
'(');
1166 open_paren =
nullptr;
1170 if (
IsToken(open_paren,
"(anonymous namespace)")) {
1171 open_paren = strchr(open_paren + strlen(
"(anonymous namespace)"),
'(');
1173 close_paren = strchr(open_paren,
')');
1175 close_paren = strchr(open_paren,
')');
1178 return {open_paren, close_paren};
1185 char const *full_name,
1190 out_stream.
Write(full_name, open_paren - full_name + 1);
1209 return inline_block->GetBlockVariableList(
true);
1245 Language *language_plugin =
nullptr;
1246 bool language_plugin_handled =
false;
1253 if (language_plugin)
1257 if (language_plugin_handled) {
1280 Language *language_plugin =
nullptr;
1283 else if (
m_sc->symbol)
1286 if (!language_plugin)
1296 const bool success =
Format(format, name_stream,
nullptr);
1305 if (!format_str.empty()) {
1308 if (
error.Success()) {
1309 return Format(root, s, valobj);
1319 "Error: detected recursive format entity: {0}",
1326 switch (entry.
type) {
1335 Debugger &debugger = target->GetDebugger();
1345 if (!
Format(child, s, valobj)) {
1357 auto format_children = [&](
const std::vector<Entry> &children) {
1358 scope_stream.
Clear();
1359 for (
const auto &child : children) {
1360 if (!
Format(child, scope_stream, valobj))
1367 if (format_children(children)) {
1395 const char *format =
"%" PRIu64;
1430 const char *format =
"0x%4.4" PRIx64;
1437 Target &target = thread->GetProcess()->GetTarget();
1439 llvm::Triple::OSType ostype = arch.
IsValid()
1441 : llvm::Triple::UnknownOS;
1442 if (ostype == llvm::Triple::FreeBSD ||
1443 ostype == llvm::Triple::Linux ||
1444 ostype == llvm::Triple::NetBSD ||
1445 ostype == llvm::Triple::OpenBSD) {
1446 format =
"%" PRIu64;
1452 s.
Printf(format, thread->GetID());
1462 const char *format =
"0x%4.4" PRIx64;
1465 s.
Printf(format, thread->GetProtocolID());
1475 const char *format =
"%" PRIu32;
1478 s.
Printf(format, thread->GetIndexID());
1488 const char *cstr = thread->GetName();
1489 if (cstr && cstr[0]) {
1501 const char *cstr = thread->GetQueueName();
1502 if (cstr && cstr[0]) {
1513 std::string stop_description = thread->GetStopDescription();
1514 if (!stop_description.empty()) {
1525 std::string stop_description = thread->GetStopDescriptionRaw();
1526 if (!stop_description.empty()) {
1538 StopInfoSP stop_info_sp = thread->GetStopInfo();
1539 if (stop_info_sp && stop_info_sp->IsValid()) {
1542 if (return_valobj_sp) {
1543 if (llvm::Error
error = return_valobj_sp->Dump(s)) {
1558 StopInfoSP stop_info_sp = thread->GetStopInfo();
1559 if (stop_info_sp && stop_info_sp->IsValid()) {
1562 if (expression_var_sp && expression_var_sp->GetValueObject()) {
1563 if (llvm::Error
error =
1564 expression_var_sp->GetValueObject()->Dump(s)) {
1615 if (
Module *exe_module = target->GetExecutableModulePointer()) {
1656 const char *lang_name =
1670 const char *format =
"%" PRIu32;
1747 return frame->IsArtificial();
1754 if (frame->IsSynthetic())
1756 else if (frame->IsHistorical())
1767 llvm::dyn_cast<BorrowedStackFrame>(frame)) {
1769 borrowed_frame->GetBorrowedFrame()) {
1770 s.
Printf(
" [borrowed from frame #%u]",
1771 borrowed_from_sp->GetFrameIndex());
1790 if (
m_sc->function) {
1791 s.
Printf(
"function{0x%8.8" PRIx64
"}",
m_sc->function->GetID());
1793 }
else if (
m_sc->symbol) {
1794 s.
Printf(
"symbol[%u]",
m_sc->symbol->GetID());
1808 Language *language_plugin =
nullptr;
1809 bool language_plugin_handled =
false;
1814 else if (
m_sc->symbol)
1817 if (language_plugin)
1821 if (language_plugin_handled) {
1826 const char *name =
m_sc->GetPossiblyInlinedFunctionName()
1828 .AsCString(
nullptr);
1851 Language *language_plugin =
nullptr;
1852 bool language_plugin_handled =
false;
1856 else if (
m_sc->symbol)
1859 if (language_plugin)
1864 if (language_plugin_handled) {
1870 m_sc->GetPossiblyInlinedFunctionName()
1873 .AsCString(
nullptr);
1904 Language *language_plugin =
nullptr;
1907 else if (
m_sc->symbol)
1910 if (!language_plugin)
1943 const char *name =
m_sc->GetPossiblyInlinedFunctionName()
1945 .AsCString(
nullptr);
1991 bool is_optimized =
false;
1992 if (
m_sc &&
m_sc->function &&
m_sc->function->GetIsOptimized()) {
1993 is_optimized =
true;
1995 return is_optimized;
1999 return m_sc &&
m_sc->block &&
m_sc->block->GetInlinedFunctionInfo();
2006 if (
m_sc &&
m_sc->line_entry.IsValid()) {
2013 if (
m_sc &&
m_sc->line_entry.IsValid()) {
2014 const char *format =
"%" PRIu32;
2023 if (
m_sc &&
m_sc->line_entry.IsValid() &&
m_sc->line_entry.column) {
2024 const char *format =
"%" PRIu32;
2034 if (
m_sc &&
m_sc->line_entry.range.GetBaseAddress().IsValid()) {
2035 Address addr =
m_sc->line_entry.range.GetBaseAddress();
2038 addr.
Slide(
m_sc->line_entry.range.GetByteSize());
2047 m_exe_ctx->GetFramePtr()->GetRegisterContextSP();
2049 addr_t pc_loadaddr = reg_ctx->GetPC();
2052 pc.SetLoadAddress(pc_loadaddr,
m_exe_ctx->GetTargetPtr());
2066 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2068 s.
Format(
"[{0:N}/{1:N}]", progress->completed, progress->total);
2077 if (
auto progress = target->GetDebugger().GetCurrentProgressReport()) {
2086 s << target->GetDebugger().GetSeparator();
2099 for (
size_t i = 0; i < n; ++i) {
2113 const size_t sep_pos = format_str.find_first_of(
".[:");
2114 const char sep_char =
2115 (sep_pos == llvm::StringRef::npos) ?
'\0' : format_str[sep_pos];
2116 llvm::StringRef key = format_str.substr(0, sep_pos);
2119 for (
size_t i = 0; i < n; ++i) {
2121 if (key == entry_def->
name || entry_def->
name[0] ==
'*') {
2122 llvm::StringRef value;
2125 format_str.substr(sep_pos + (entry_def->
keep_separator ? 0 : 1));
2126 switch (entry_def->
type) {
2128 entry.
string = format_str.str();
2145 if (value.empty()) {
2149 error_strm.
Printf(
"'%s' can't be specified on its own, you must "
2150 "access one of its children: ",
2155 }
else if (sep_char ==
':') {
2162 "%s",
"invalid entry definitions");
2168 }
else if (sep_char ==
':') {
2172 entry.
string = value.str();
2175 "'%s' followed by '%s' but it has no children", key.str().c_str(),
2176 value.str().c_str());
2185 "invalid top level item '%s'. Valid top level items are: ",
2188 error_strm.
Printf(
"invalid member '%s' in '%s'. Valid members are: ",
2189 key.str().c_str(), parent->
name);
2197 llvm::StringRef &remainder) {
2200 std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split(
'.');
2202 for (
size_t i = 0; i < n; ++i) {
2204 if (p.first == entry_def->
name || entry_def->
name[0] ==
'*') {
2205 if (p.second.empty()) {
2206 if (format_str.back() ==
'.')
2207 remainder = format_str.drop_front(format_str.size() - 1);
2209 remainder = llvm::StringRef();
2213 return FindEntry(p.second, entry_def, remainder);
2215 remainder = p.second;
2221 remainder = format_str;
2228 while (!format.empty() &&
error.Success()) {
2229 const size_t non_special_chars = format.find_first_of(
"${}\\|");
2231 if (non_special_chars == llvm::StringRef::npos) {
2237 if (non_special_chars > 0) {
2240 parent_entry.
AppendText(format.substr(0, non_special_chars));
2241 format = format.drop_front(non_special_chars);
2244 switch (format[0]) {
2249 format = format.drop_front();
2267 format = format.drop_front();
2275 format = format.drop_front();
2276 if (format.empty()) {
2278 "'\\' character was not followed by another character");
2282 const char desens_char = format[0];
2283 format = format.drop_front();
2284 switch (desens_char) {
2317 char oct_str[5] = {0, 0, 0, 0, 0};
2320 for (i = 0; (format[i] >=
'0' && format[i] <=
'7') && i < 4; ++i)
2321 oct_str[i] = format[i];
2326 format = format.drop_front(i);
2327 unsigned long octal_value = ::strtoul(oct_str,
nullptr, 8);
2328 if (octal_value <= UINT8_MAX) {
2332 "octal number is larger than a single byte");
2340 if (isxdigit(format[0])) {
2343 char hex_str[3] = {0, 0, 0};
2344 hex_str[0] = format[0];
2346 format = format.drop_front();
2348 if (isxdigit(format[0])) {
2349 hex_str[1] = format[0];
2350 format = format.drop_front();
2353 unsigned long hex_value = strtoul(hex_str,
nullptr, 16);
2354 if (hex_value <= UINT8_MAX) {
2358 "hex number is larger than a single byte");
2375 format = format.drop_front();
2376 if (format.empty() || format.front() !=
'{') {
2380 format = format.drop_front();
2382 llvm::StringRef variable, variable_format;
2387 bool verify_is_thread_id =
false;
2389 if (!variable_format.empty()) {
2401 bool clear_printf =
false;
2406 entry.
number = ValueObject::
2407 eValueObjectRepresentationStyleLanguageSpecific;
2408 clear_printf =
true;
2414 clear_printf =
true;
2419 clear_printf =
true;
2424 clear_printf =
true;
2429 clear_printf =
true;
2433 clear_printf =
true;
2437 clear_printf =
true;
2442 clear_printf =
true;
2450 clear_printf =
true;
2452 verify_is_thread_id =
true;
2468 if (variable[0] ==
'*') {
2470 variable = variable.drop_front();
2477 llvm::StringRef entry_string(entry.
string);
2478 if (entry_string.contains(
':')) {
2479 auto [_, llvm_format] = entry_string.split(
':');
2482 "invalid llvm format: '%s'", llvm_format.data());
2487 if (verify_is_thread_id) {
2491 "the 'tid' format can only be used on "
2492 "${thread.id} and ${thread.protocol_id}");
2496 switch (entry.
type) {
2500 if (entry.
string.empty())
2512 "${%s} can't be dereferenced, only ${var} and ${svar} can.",
2513 variable.str().c_str());
2526 llvm::StringRef &variable_name,
2527 llvm::StringRef &variable_format) {
2529 variable_name = llvm::StringRef();
2530 variable_format = llvm::StringRef();
2532 const size_t paren_pos = format_str.find(
'}');
2533 if (paren_pos != llvm::StringRef::npos) {
2534 const size_t percent_pos = format_str.find(
'%');
2535 if (percent_pos < paren_pos) {
2536 if (percent_pos > 0) {
2537 if (percent_pos > 1)
2538 variable_name = format_str.substr(0, percent_pos);
2540 format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
2543 variable_name = format_str.substr(0, paren_pos);
2546 format_str = format_str.substr(paren_pos + 1);
2549 "missing terminating '}' character for '${%s'",
2550 format_str.str().c_str());
2556 llvm::StringRef variable_name,
2557 llvm::StringRef variable_format) {
2558 if (variable_name.empty() || variable_name ==
".fullpath") {
2561 }
else if (variable_name ==
".basename") {
2564 }
else if (variable_name ==
".dirname") {
2572 const char *suffix) {
2573 std::string match(prefix.str());
2574 match.append(suffix);
2579 const llvm::StringRef &match_prefix,
2583 for (
size_t i = 0; i < n; ++i) {
2584 if (match_prefix.empty())
2586 else if (strncmp(def->
children[i].
name, match_prefix.data(),
2587 match_prefix.size()) == 0)
2597 const size_t dollar_pos = str.rfind(
'$');
2598 if (dollar_pos == llvm::StringRef::npos)
2602 if (dollar_pos == str.size() - 1) {
2603 std::string match = str.str();
2609 if (str[dollar_pos + 1] !=
'{')
2612 const size_t close_pos = str.find(
'}', dollar_pos + 2);
2613 if (close_pos != llvm::StringRef::npos)
2616 const size_t format_pos = str.find(
'%', dollar_pos + 2);
2617 if (format_pos != llvm::StringRef::npos)
2620 llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
2621 if (partial_variable.empty()) {
2630 llvm::StringRef remainder;
2637 if (remainder.empty()) {
2646 }
else if (remainder ==
".") {
2649 AddMatches(entry_def, str, llvm::StringRef(), new_matches);
2655 AddMatches(entry_def, str, remainder, new_matches);
2663 const size_t num_args = args.
GetSize();
2664 for (
size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) {
2670 llvm::StringRef var_representation;
2671 const char *var_name = var_value_sp->GetName().GetCString();
2672 if (var_value_sp->GetCompilerType().IsValid()) {
2674 var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(
2676 ->TargetProperties::GetPreferDynamicValue(),
2678 ->TargetProperties::GetEnableSyntheticValue());
2679 if (var_value_sp->GetCompilerType().IsAggregateType() &&
2682 .SetHideItemNames(
false)
2683 .SetShowMembersOneLiner(
true),
2686 var_representation = buffer;
2688 var_value_sp->DumpPrintableRepresentation(
2691 eValueObjectRepresentationStyleSummary,
2700 if (var_value_sp->GetError().Success()) {
2701 if (!var_representation.empty())
2702 out_stream.
Printf(
"%s=%s", var_name, var_representation.str().c_str());
2704 out_stream.
Printf(
"%s=%s at %s", var_name,
2705 var_value_sp->GetTypeName().GetCString(),
2706 var_value_sp->GetLocationAsCString());
2708 out_stream.
Printf(
"%s=<unavailable>", var_name);
2715 llvm::StringRef modifiable_format(format_str);
2726 static constexpr std::array s_permitted_recursive_entities = {
2729 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={})
"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()