1 //===-- OptionGroupValueObjectDisplay.cpp ---------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
10 
11 #include "lldb/DataFormatters/ValueObjectPrinter.h"
12 #include "lldb/Host/OptionParser.h"
13 #include "lldb/Interpreter/CommandInterpreter.h"
14 #include "lldb/Interpreter/OptionArgParser.h"
15 #include "lldb/Target/Target.h"
16 
17 #include "llvm/ADT/ArrayRef.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 static const OptionDefinition g_option_table[] = {
23     {LLDB_OPT_SET_1, false, "dynamic-type", 'd',
24      OptionParser::eRequiredArgument, nullptr, GetDynamicValueTypes(), 0,
25      eArgTypeNone, "Show the object as its full dynamic type, not its static "
26                    "type, if available."},
27     {LLDB_OPT_SET_1, false, "synthetic-type", 'S',
28      OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
29      "Show the object obeying its synthetic provider, if available."},
30     {LLDB_OPT_SET_1, false, "depth", 'D', OptionParser::eRequiredArgument,
31      nullptr, {}, 0, eArgTypeCount, "Set the max recurse depth when dumping "
32                                     "aggregate types (default is infinity)."},
33     {LLDB_OPT_SET_1, false, "flat", 'F', OptionParser::eNoArgument, nullptr,
34      {}, 0, eArgTypeNone, "Display results in a flat format that uses "
35                           "expression paths for each variable or member."},
36     {LLDB_OPT_SET_1, false, "location", 'L', OptionParser::eNoArgument, nullptr,
37      {}, 0, eArgTypeNone, "Show variable location information."},
38     {LLDB_OPT_SET_1, false, "object-description", 'O',
39      OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone,
40      "Display using a language-specific description API, if possible."},
41     {LLDB_OPT_SET_1, false, "ptr-depth", 'P', OptionParser::eRequiredArgument,
42      nullptr, {}, 0, eArgTypeCount, "The number of pointers to be traversed "
43                                     "when dumping values (default is zero)."},
44     {LLDB_OPT_SET_1, false, "show-types", 'T', OptionParser::eNoArgument,
45      nullptr, {}, 0, eArgTypeNone,
46      "Show variable types when dumping values."},
47     {LLDB_OPT_SET_1, false, "no-summary-depth", 'Y',
48      OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeCount,
49      "Set the depth at which omitting summary information stops (default is "
50      "1)."},
51     {LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument,
52      nullptr, {}, 0, eArgTypeNone, "Don't use formatting options."},
53     {LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument,
54      nullptr, {}, 0, eArgTypeNone,
55      "Ignore the upper bound on the number of children to show."},
56     {LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument,
57      nullptr, {}, 0, eArgTypeBoolean, "Show results of type validators."},
58     {LLDB_OPT_SET_1, false, "element-count", 'Z',
59      OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount,
60      "Treat the result of the expression as if its type is an array of this "
61      "many values."}};
62 
63 llvm::ArrayRef<OptionDefinition>
64 OptionGroupValueObjectDisplay::GetDefinitions() {
65   return llvm::ArrayRef(g_option_table);
66 }
67 
68 Status OptionGroupValueObjectDisplay::SetOptionValue(
69     uint32_t option_idx, llvm::StringRef option_arg,
70     ExecutionContext *execution_context) {
71   Status error;
72   const int short_option = g_option_table[option_idx].short_option;
73   bool success = false;
74 
75   switch (short_option) {
76   case 'd': {
77     int32_t result;
78     result = OptionArgParser::ToOptionEnum(option_arg, GetDynamicValueTypes(),
79                                            2, error);
80     if (error.Success())
81       use_dynamic = (lldb::DynamicValueType)result;
82   } break;
83   case 'T':
84     show_types = true;
85     break;
86   case 'L':
87     show_location = true;
88     break;
89   case 'F':
90     flat_output = true;
91     break;
92   case 'O':
93     use_objc = true;
94     break;
95   case 'R':
96     be_raw = true;
97     break;
98   case 'A':
99     ignore_cap = true;
100     break;
101 
102   case 'D':
103     if (option_arg.getAsInteger(0, max_depth)) {
104       max_depth = UINT32_MAX;
105       error.SetErrorStringWithFormat("invalid max depth '%s'",
106                                      option_arg.str().c_str());
107     } else {
108       max_depth_is_default = false;
109     }
110     break;
111 
112   case 'Z':
113     if (option_arg.getAsInteger(0, elem_count)) {
114       elem_count = UINT32_MAX;
115       error.SetErrorStringWithFormat("invalid element count '%s'",
116                                      option_arg.str().c_str());
117     }
118     break;
119 
120   case 'P':
121     if (option_arg.getAsInteger(0, ptr_depth)) {
122       ptr_depth = 0;
123       error.SetErrorStringWithFormat("invalid pointer depth '%s'",
124                                      option_arg.str().c_str());
125     }
126     break;
127 
128   case 'Y':
129     if (option_arg.empty())
130       no_summary_depth = 1;
131     else if (option_arg.getAsInteger(0, no_summary_depth)) {
132       no_summary_depth = 0;
133       error.SetErrorStringWithFormat("invalid pointer depth '%s'",
134                                      option_arg.str().c_str());
135     }
136     break;
137 
138   case 'S':
139     use_synth = OptionArgParser::ToBoolean(option_arg, true, &success);
140     if (!success)
141       error.SetErrorStringWithFormat("invalid synthetic-type '%s'",
142                                      option_arg.str().c_str());
143     break;
144 
145   case 'V':
146     run_validator = OptionArgParser::ToBoolean(option_arg, true, &success);
147     if (!success)
148       error.SetErrorStringWithFormat("invalid validate '%s'",
149                                      option_arg.str().c_str());
150     break;
151 
152   default:
153     llvm_unreachable("Unimplemented option");
154   }
155 
156   return error;
157 }
158 
159 void OptionGroupValueObjectDisplay::OptionParsingStarting(
160     ExecutionContext *execution_context) {
161   // If these defaults change, be sure to modify AnyOptionWasSet().
162   show_types = false;
163   no_summary_depth = 0;
164   show_location = false;
165   flat_output = false;
166   use_objc = false;
167   max_depth = UINT32_MAX;
168   max_depth_is_default = true;
169   ptr_depth = 0;
170   elem_count = 0;
171   use_synth = true;
172   be_raw = false;
173   ignore_cap = false;
174   run_validator = false;
175 
176   TargetSP target_sp =
177       execution_context ? execution_context->GetTargetSP() : TargetSP();
178   if (target_sp) {
179     use_dynamic = target_sp->GetPreferDynamicValue();
180     auto max_depth_config = target_sp->GetMaximumDepthOfChildrenToDisplay();
181     max_depth = std::get<uint32_t>(max_depth_config);
182     max_depth_is_default = std::get<bool>(max_depth_config);
183   } else {
184     // If we don't have any targets, then dynamic values won't do us much good.
185     use_dynamic = lldb::eNoDynamicValues;
186   }
187 }
188 
189 DumpValueObjectOptions OptionGroupValueObjectDisplay::GetAsDumpOptions(
190     LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity,
191     lldb::Format format, lldb::TypeSummaryImplSP summary_sp) {
192   DumpValueObjectOptions options;
193   options.SetMaximumPointerDepth(
194       {DumpValueObjectOptions::PointerDepth::Mode::Always, ptr_depth});
195   if (use_objc)
196     options.SetShowSummary(false);
197   else
198     options.SetOmitSummaryDepth(no_summary_depth);
199   options.SetMaximumDepth(max_depth, max_depth_is_default)
200       .SetShowTypes(show_types)
201       .SetShowLocation(show_location)
202       .SetUseObjectiveC(use_objc)
203       .SetUseDynamicType(use_dynamic)
204       .SetUseSyntheticValue(use_synth)
205       .SetFlatOutput(flat_output)
206       .SetIgnoreCap(ignore_cap)
207       .SetFormat(format)
208       .SetSummary(summary_sp);
209 
210   if (lang_descr_verbosity ==
211       eLanguageRuntimeDescriptionDisplayVerbosityCompact)
212     options.SetHideRootType(use_objc).SetHideName(use_objc).SetHideValue(
213         use_objc);
214 
215   if (be_raw)
216     options.SetRawDisplay();
217 
218   options.SetRunValidator(run_validator);
219 
220   options.SetElementCount(elem_count);
221 
222   return options;
223 }
224