15ffd83dbSDimitry Andric //===-- OptionGroupValueObjectDisplay.cpp ---------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
100b57cec5SDimitry Andric
110b57cec5SDimitry Andric #include "lldb/DataFormatters/ValueObjectPrinter.h"
120b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
130b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
140b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
150b57cec5SDimitry Andric #include "lldb/Target/Target.h"
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric using namespace lldb;
200b57cec5SDimitry Andric using namespace lldb_private;
210b57cec5SDimitry Andric
220b57cec5SDimitry Andric static const OptionDefinition g_option_table[] = {
230b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "dynamic-type", 'd',
240b57cec5SDimitry Andric OptionParser::eRequiredArgument, nullptr, GetDynamicValueTypes(), 0,
250b57cec5SDimitry Andric eArgTypeNone, "Show the object as its full dynamic type, not its static "
260b57cec5SDimitry Andric "type, if available."},
270b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "synthetic-type", 'S',
280b57cec5SDimitry Andric OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
290b57cec5SDimitry Andric "Show the object obeying its synthetic provider, if available."},
300b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "depth", 'D', OptionParser::eRequiredArgument,
310b57cec5SDimitry Andric nullptr, {}, 0, eArgTypeCount, "Set the max recurse depth when dumping "
320b57cec5SDimitry Andric "aggregate types (default is infinity)."},
330b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "flat", 'F', OptionParser::eNoArgument, nullptr,
340b57cec5SDimitry Andric {}, 0, eArgTypeNone, "Display results in a flat format that uses "
350b57cec5SDimitry Andric "expression paths for each variable or member."},
360b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "location", 'L', OptionParser::eNoArgument, nullptr,
370b57cec5SDimitry Andric {}, 0, eArgTypeNone, "Show variable location information."},
380b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "object-description", 'O',
390b57cec5SDimitry Andric OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone,
40480093f4SDimitry Andric "Display using a language-specific description API, if possible."},
410b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "ptr-depth", 'P', OptionParser::eRequiredArgument,
420b57cec5SDimitry Andric nullptr, {}, 0, eArgTypeCount, "The number of pointers to be traversed "
430b57cec5SDimitry Andric "when dumping values (default is zero)."},
440b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "show-types", 'T', OptionParser::eNoArgument,
450b57cec5SDimitry Andric nullptr, {}, 0, eArgTypeNone,
460b57cec5SDimitry Andric "Show variable types when dumping values."},
470b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "no-summary-depth", 'Y',
480b57cec5SDimitry Andric OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeCount,
490b57cec5SDimitry Andric "Set the depth at which omitting summary information stops (default is "
500b57cec5SDimitry Andric "1)."},
510b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument,
520b57cec5SDimitry Andric nullptr, {}, 0, eArgTypeNone, "Don't use formatting options."},
530b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument,
540b57cec5SDimitry Andric nullptr, {}, 0, eArgTypeNone,
550b57cec5SDimitry Andric "Ignore the upper bound on the number of children to show."},
560b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument,
570b57cec5SDimitry Andric nullptr, {}, 0, eArgTypeBoolean, "Show results of type validators."},
580b57cec5SDimitry Andric {LLDB_OPT_SET_1, false, "element-count", 'Z',
590b57cec5SDimitry Andric OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount,
600b57cec5SDimitry Andric "Treat the result of the expression as if its type is an array of this "
610b57cec5SDimitry Andric "many values."}};
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition>
GetDefinitions()640b57cec5SDimitry Andric OptionGroupValueObjectDisplay::GetDefinitions() {
65*bdd1243dSDimitry Andric return llvm::ArrayRef(g_option_table);
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)680b57cec5SDimitry Andric Status OptionGroupValueObjectDisplay::SetOptionValue(
690b57cec5SDimitry Andric uint32_t option_idx, llvm::StringRef option_arg,
700b57cec5SDimitry Andric ExecutionContext *execution_context) {
710b57cec5SDimitry Andric Status error;
720b57cec5SDimitry Andric const int short_option = g_option_table[option_idx].short_option;
730b57cec5SDimitry Andric bool success = false;
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric switch (short_option) {
760b57cec5SDimitry Andric case 'd': {
770b57cec5SDimitry Andric int32_t result;
780b57cec5SDimitry Andric result = OptionArgParser::ToOptionEnum(option_arg, GetDynamicValueTypes(),
790b57cec5SDimitry Andric 2, error);
800b57cec5SDimitry Andric if (error.Success())
810b57cec5SDimitry Andric use_dynamic = (lldb::DynamicValueType)result;
820b57cec5SDimitry Andric } break;
830b57cec5SDimitry Andric case 'T':
840b57cec5SDimitry Andric show_types = true;
850b57cec5SDimitry Andric break;
860b57cec5SDimitry Andric case 'L':
870b57cec5SDimitry Andric show_location = true;
880b57cec5SDimitry Andric break;
890b57cec5SDimitry Andric case 'F':
900b57cec5SDimitry Andric flat_output = true;
910b57cec5SDimitry Andric break;
920b57cec5SDimitry Andric case 'O':
930b57cec5SDimitry Andric use_objc = true;
940b57cec5SDimitry Andric break;
950b57cec5SDimitry Andric case 'R':
960b57cec5SDimitry Andric be_raw = true;
970b57cec5SDimitry Andric break;
980b57cec5SDimitry Andric case 'A':
990b57cec5SDimitry Andric ignore_cap = true;
1000b57cec5SDimitry Andric break;
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric case 'D':
1030b57cec5SDimitry Andric if (option_arg.getAsInteger(0, max_depth)) {
1040b57cec5SDimitry Andric max_depth = UINT32_MAX;
1050b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid max depth '%s'",
1060b57cec5SDimitry Andric option_arg.str().c_str());
10781ad6265SDimitry Andric } else {
10881ad6265SDimitry Andric max_depth_is_default = false;
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric break;
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric case 'Z':
1130b57cec5SDimitry Andric if (option_arg.getAsInteger(0, elem_count)) {
1140b57cec5SDimitry Andric elem_count = UINT32_MAX;
1150b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid element count '%s'",
1160b57cec5SDimitry Andric option_arg.str().c_str());
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric break;
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric case 'P':
1210b57cec5SDimitry Andric if (option_arg.getAsInteger(0, ptr_depth)) {
1220b57cec5SDimitry Andric ptr_depth = 0;
1230b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid pointer depth '%s'",
1240b57cec5SDimitry Andric option_arg.str().c_str());
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric break;
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric case 'Y':
1290b57cec5SDimitry Andric if (option_arg.empty())
1300b57cec5SDimitry Andric no_summary_depth = 1;
1310b57cec5SDimitry Andric else if (option_arg.getAsInteger(0, no_summary_depth)) {
1320b57cec5SDimitry Andric no_summary_depth = 0;
1330b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid pointer depth '%s'",
1340b57cec5SDimitry Andric option_arg.str().c_str());
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric break;
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric case 'S':
1390b57cec5SDimitry Andric use_synth = OptionArgParser::ToBoolean(option_arg, true, &success);
1400b57cec5SDimitry Andric if (!success)
1410b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid synthetic-type '%s'",
1420b57cec5SDimitry Andric option_arg.str().c_str());
1430b57cec5SDimitry Andric break;
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andric case 'V':
1460b57cec5SDimitry Andric run_validator = OptionArgParser::ToBoolean(option_arg, true, &success);
1470b57cec5SDimitry Andric if (!success)
1480b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid validate '%s'",
1490b57cec5SDimitry Andric option_arg.str().c_str());
1500b57cec5SDimitry Andric break;
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric default:
1539dba64beSDimitry Andric llvm_unreachable("Unimplemented option");
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric return error;
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)1590b57cec5SDimitry Andric void OptionGroupValueObjectDisplay::OptionParsingStarting(
1600b57cec5SDimitry Andric ExecutionContext *execution_context) {
1610b57cec5SDimitry Andric // If these defaults change, be sure to modify AnyOptionWasSet().
1620b57cec5SDimitry Andric show_types = false;
1630b57cec5SDimitry Andric no_summary_depth = 0;
1640b57cec5SDimitry Andric show_location = false;
1650b57cec5SDimitry Andric flat_output = false;
1660b57cec5SDimitry Andric use_objc = false;
1670b57cec5SDimitry Andric max_depth = UINT32_MAX;
16881ad6265SDimitry Andric max_depth_is_default = true;
1690b57cec5SDimitry Andric ptr_depth = 0;
1700b57cec5SDimitry Andric elem_count = 0;
1710b57cec5SDimitry Andric use_synth = true;
1720b57cec5SDimitry Andric be_raw = false;
1730b57cec5SDimitry Andric ignore_cap = false;
1740b57cec5SDimitry Andric run_validator = false;
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric TargetSP target_sp =
1770b57cec5SDimitry Andric execution_context ? execution_context->GetTargetSP() : TargetSP();
17881ad6265SDimitry Andric if (target_sp) {
1790b57cec5SDimitry Andric use_dynamic = target_sp->GetPreferDynamicValue();
18081ad6265SDimitry Andric auto max_depth_config = target_sp->GetMaximumDepthOfChildrenToDisplay();
18181ad6265SDimitry Andric max_depth = std::get<uint32_t>(max_depth_config);
18281ad6265SDimitry Andric max_depth_is_default = std::get<bool>(max_depth_config);
18381ad6265SDimitry Andric } else {
1840b57cec5SDimitry Andric // If we don't have any targets, then dynamic values won't do us much good.
1850b57cec5SDimitry Andric use_dynamic = lldb::eNoDynamicValues;
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric
GetAsDumpOptions(LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity,lldb::Format format,lldb::TypeSummaryImplSP summary_sp)1890b57cec5SDimitry Andric DumpValueObjectOptions OptionGroupValueObjectDisplay::GetAsDumpOptions(
1900b57cec5SDimitry Andric LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity,
1910b57cec5SDimitry Andric lldb::Format format, lldb::TypeSummaryImplSP summary_sp) {
1920b57cec5SDimitry Andric DumpValueObjectOptions options;
1930b57cec5SDimitry Andric options.SetMaximumPointerDepth(
1940b57cec5SDimitry Andric {DumpValueObjectOptions::PointerDepth::Mode::Always, ptr_depth});
1950b57cec5SDimitry Andric if (use_objc)
1960b57cec5SDimitry Andric options.SetShowSummary(false);
1970b57cec5SDimitry Andric else
1980b57cec5SDimitry Andric options.SetOmitSummaryDepth(no_summary_depth);
19981ad6265SDimitry Andric options.SetMaximumDepth(max_depth, max_depth_is_default)
2000b57cec5SDimitry Andric .SetShowTypes(show_types)
2010b57cec5SDimitry Andric .SetShowLocation(show_location)
2020b57cec5SDimitry Andric .SetUseObjectiveC(use_objc)
2030b57cec5SDimitry Andric .SetUseDynamicType(use_dynamic)
2040b57cec5SDimitry Andric .SetUseSyntheticValue(use_synth)
2050b57cec5SDimitry Andric .SetFlatOutput(flat_output)
2060b57cec5SDimitry Andric .SetIgnoreCap(ignore_cap)
2070b57cec5SDimitry Andric .SetFormat(format)
2080b57cec5SDimitry Andric .SetSummary(summary_sp);
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric if (lang_descr_verbosity ==
2110b57cec5SDimitry Andric eLanguageRuntimeDescriptionDisplayVerbosityCompact)
2120b57cec5SDimitry Andric options.SetHideRootType(use_objc).SetHideName(use_objc).SetHideValue(
2130b57cec5SDimitry Andric use_objc);
2140b57cec5SDimitry Andric
2150b57cec5SDimitry Andric if (be_raw)
2160b57cec5SDimitry Andric options.SetRawDisplay();
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric options.SetRunValidator(run_validator);
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric options.SetElementCount(elem_count);
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andric return options;
2230b57cec5SDimitry Andric }
224