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::makeArrayRef(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     }
108     break;
109 
110   case 'Z':
111     if (option_arg.getAsInteger(0, elem_count)) {
112       elem_count = UINT32_MAX;
113       error.SetErrorStringWithFormat("invalid element count '%s'",
114                                      option_arg.str().c_str());
115     }
116     break;
117 
118   case 'P':
119     if (option_arg.getAsInteger(0, ptr_depth)) {
120       ptr_depth = 0;
121       error.SetErrorStringWithFormat("invalid pointer depth '%s'",
122                                      option_arg.str().c_str());
123     }
124     break;
125 
126   case 'Y':
127     if (option_arg.empty())
128       no_summary_depth = 1;
129     else if (option_arg.getAsInteger(0, no_summary_depth)) {
130       no_summary_depth = 0;
131       error.SetErrorStringWithFormat("invalid pointer depth '%s'",
132                                      option_arg.str().c_str());
133     }
134     break;
135 
136   case 'S':
137     use_synth = OptionArgParser::ToBoolean(option_arg, true, &success);
138     if (!success)
139       error.SetErrorStringWithFormat("invalid synthetic-type '%s'",
140                                      option_arg.str().c_str());
141     break;
142 
143   case 'V':
144     run_validator = OptionArgParser::ToBoolean(option_arg, true, &success);
145     if (!success)
146       error.SetErrorStringWithFormat("invalid validate '%s'",
147                                      option_arg.str().c_str());
148     break;
149 
150   default:
151     llvm_unreachable("Unimplemented option");
152   }
153 
154   return error;
155 }
156 
157 void OptionGroupValueObjectDisplay::OptionParsingStarting(
158     ExecutionContext *execution_context) {
159   // If these defaults change, be sure to modify AnyOptionWasSet().
160   show_types = false;
161   no_summary_depth = 0;
162   show_location = false;
163   flat_output = false;
164   use_objc = false;
165   max_depth = UINT32_MAX;
166   ptr_depth = 0;
167   elem_count = 0;
168   use_synth = true;
169   be_raw = false;
170   ignore_cap = false;
171   run_validator = false;
172 
173   TargetSP target_sp =
174       execution_context ? execution_context->GetTargetSP() : TargetSP();
175   if (target_sp)
176     use_dynamic = target_sp->GetPreferDynamicValue();
177   else {
178     // If we don't have any targets, then dynamic values won't do us much good.
179     use_dynamic = lldb::eNoDynamicValues;
180   }
181 }
182 
183 DumpValueObjectOptions OptionGroupValueObjectDisplay::GetAsDumpOptions(
184     LanguageRuntimeDescriptionDisplayVerbosity lang_descr_verbosity,
185     lldb::Format format, lldb::TypeSummaryImplSP summary_sp) {
186   DumpValueObjectOptions options;
187   options.SetMaximumPointerDepth(
188       {DumpValueObjectOptions::PointerDepth::Mode::Always, ptr_depth});
189   if (use_objc)
190     options.SetShowSummary(false);
191   else
192     options.SetOmitSummaryDepth(no_summary_depth);
193   options.SetMaximumDepth(max_depth)
194       .SetShowTypes(show_types)
195       .SetShowLocation(show_location)
196       .SetUseObjectiveC(use_objc)
197       .SetUseDynamicType(use_dynamic)
198       .SetUseSyntheticValue(use_synth)
199       .SetFlatOutput(flat_output)
200       .SetIgnoreCap(ignore_cap)
201       .SetFormat(format)
202       .SetSummary(summary_sp);
203 
204   if (lang_descr_verbosity ==
205       eLanguageRuntimeDescriptionDisplayVerbosityCompact)
206     options.SetHideRootType(use_objc).SetHideName(use_objc).SetHideValue(
207         use_objc);
208 
209   if (be_raw)
210     options.SetRawDisplay();
211 
212   options.SetRunValidator(run_validator);
213 
214   options.SetElementCount(elem_count);
215 
216   return options;
217 }
218