xref: /llvm-project/lldb/source/Commands/CommandOptionArgumentTable.cpp (revision 7ced9fff95473c1794b51a3cfd099b4fea3d1a58)
1*7ced9fffSJonas Devlieghere //===-- CommandOptionArgumentTable.cpp ------------------------------------===//
2*7ced9fffSJonas Devlieghere //
3*7ced9fffSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*7ced9fffSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information.
5*7ced9fffSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*7ced9fffSJonas Devlieghere //
7*7ced9fffSJonas Devlieghere //===----------------------------------------------------------------------===//
8*7ced9fffSJonas Devlieghere 
9*7ced9fffSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h"
10*7ced9fffSJonas Devlieghere #include "lldb/DataFormatters/FormatManager.h"
11*7ced9fffSJonas Devlieghere #include "lldb/Target/Language.h"
12*7ced9fffSJonas Devlieghere #include "lldb/Utility/StreamString.h"
13*7ced9fffSJonas Devlieghere 
14*7ced9fffSJonas Devlieghere using namespace lldb;
15*7ced9fffSJonas Devlieghere using namespace lldb_private;
16*7ced9fffSJonas Devlieghere 
17*7ced9fffSJonas Devlieghere namespace lldb_private {
RegisterNameHelpTextCallback()18*7ced9fffSJonas Devlieghere llvm::StringRef RegisterNameHelpTextCallback() {
19*7ced9fffSJonas Devlieghere   return "Register names can be specified using the architecture specific "
20*7ced9fffSJonas Devlieghere          "names.  "
21*7ced9fffSJonas Devlieghere          "They can also be specified using generic names.  Not all generic "
22*7ced9fffSJonas Devlieghere          "entities have "
23*7ced9fffSJonas Devlieghere          "registers backing them on all architectures.  When they don't the "
24*7ced9fffSJonas Devlieghere          "generic name "
25*7ced9fffSJonas Devlieghere          "will return an error.\n"
26*7ced9fffSJonas Devlieghere          "The generic names defined in lldb are:\n"
27*7ced9fffSJonas Devlieghere          "\n"
28*7ced9fffSJonas Devlieghere          "pc       - program counter register\n"
29*7ced9fffSJonas Devlieghere          "ra       - return address register\n"
30*7ced9fffSJonas Devlieghere          "fp       - frame pointer register\n"
31*7ced9fffSJonas Devlieghere          "sp       - stack pointer register\n"
32*7ced9fffSJonas Devlieghere          "flags    - the flags register\n"
33*7ced9fffSJonas Devlieghere          "arg{1-6} - integer argument passing registers.\n";
34*7ced9fffSJonas Devlieghere }
35*7ced9fffSJonas Devlieghere 
BreakpointIDHelpTextCallback()36*7ced9fffSJonas Devlieghere llvm::StringRef BreakpointIDHelpTextCallback() {
37*7ced9fffSJonas Devlieghere   return "Breakpoints are identified using major and minor numbers; the major "
38*7ced9fffSJonas Devlieghere          "number corresponds to the single entity that was created with a "
39*7ced9fffSJonas Devlieghere          "'breakpoint "
40*7ced9fffSJonas Devlieghere          "set' command; the minor numbers correspond to all the locations that "
41*7ced9fffSJonas Devlieghere          "were "
42*7ced9fffSJonas Devlieghere          "actually found/set based on the major breakpoint.  A full breakpoint "
43*7ced9fffSJonas Devlieghere          "ID might "
44*7ced9fffSJonas Devlieghere          "look like 3.14, meaning the 14th location set for the 3rd "
45*7ced9fffSJonas Devlieghere          "breakpoint.  You "
46*7ced9fffSJonas Devlieghere          "can specify all the locations of a breakpoint by just indicating the "
47*7ced9fffSJonas Devlieghere          "major "
48*7ced9fffSJonas Devlieghere          "breakpoint number. A valid breakpoint ID consists either of just the "
49*7ced9fffSJonas Devlieghere          "major "
50*7ced9fffSJonas Devlieghere          "number, or the major number followed by a dot and the location "
51*7ced9fffSJonas Devlieghere          "number (e.g. "
52*7ced9fffSJonas Devlieghere          "3 or 3.2 could both be valid breakpoint IDs.)";
53*7ced9fffSJonas Devlieghere }
54*7ced9fffSJonas Devlieghere 
BreakpointIDRangeHelpTextCallback()55*7ced9fffSJonas Devlieghere llvm::StringRef BreakpointIDRangeHelpTextCallback() {
56*7ced9fffSJonas Devlieghere   return "A 'breakpoint ID list' is a manner of specifying multiple "
57*7ced9fffSJonas Devlieghere          "breakpoints. "
58*7ced9fffSJonas Devlieghere          "This can be done through several mechanisms.  The easiest way is to "
59*7ced9fffSJonas Devlieghere          "just "
60*7ced9fffSJonas Devlieghere          "enter a space-separated list of breakpoint IDs.  To specify all the "
61*7ced9fffSJonas Devlieghere          "breakpoint locations under a major breakpoint, you can use the major "
62*7ced9fffSJonas Devlieghere          "breakpoint number followed by '.*', eg. '5.*' means all the "
63*7ced9fffSJonas Devlieghere          "locations under "
64*7ced9fffSJonas Devlieghere          "breakpoint 5.  You can also indicate a range of breakpoints by using "
65*7ced9fffSJonas Devlieghere          "<start-bp-id> - <end-bp-id>.  The start-bp-id and end-bp-id for a "
66*7ced9fffSJonas Devlieghere          "range can "
67*7ced9fffSJonas Devlieghere          "be any valid breakpoint IDs.  It is not legal, however, to specify a "
68*7ced9fffSJonas Devlieghere          "range "
69*7ced9fffSJonas Devlieghere          "using specific locations that cross major breakpoint numbers.  I.e. "
70*7ced9fffSJonas Devlieghere          "3.2 - 3.7"
71*7ced9fffSJonas Devlieghere          " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
72*7ced9fffSJonas Devlieghere }
73*7ced9fffSJonas Devlieghere 
BreakpointNameHelpTextCallback()74*7ced9fffSJonas Devlieghere llvm::StringRef BreakpointNameHelpTextCallback() {
75*7ced9fffSJonas Devlieghere   return "A name that can be added to a breakpoint when it is created, or "
76*7ced9fffSJonas Devlieghere          "later "
77*7ced9fffSJonas Devlieghere          "on with the \"breakpoint name add\" command.  "
78*7ced9fffSJonas Devlieghere          "Breakpoint names can be used to specify breakpoints in all the "
79*7ced9fffSJonas Devlieghere          "places breakpoint IDs "
80*7ced9fffSJonas Devlieghere          "and breakpoint ID ranges can be used.  As such they provide a "
81*7ced9fffSJonas Devlieghere          "convenient way to group breakpoints, "
82*7ced9fffSJonas Devlieghere          "and to operate on breakpoints you create without having to track the "
83*7ced9fffSJonas Devlieghere          "breakpoint number.  "
84*7ced9fffSJonas Devlieghere          "Note, the attributes you set when using a breakpoint name in a "
85*7ced9fffSJonas Devlieghere          "breakpoint command don't "
86*7ced9fffSJonas Devlieghere          "adhere to the name, but instead are set individually on all the "
87*7ced9fffSJonas Devlieghere          "breakpoints currently tagged with that "
88*7ced9fffSJonas Devlieghere          "name.  Future breakpoints "
89*7ced9fffSJonas Devlieghere          "tagged with that name will not pick up the attributes previously "
90*7ced9fffSJonas Devlieghere          "given using that name.  "
91*7ced9fffSJonas Devlieghere          "In order to distinguish breakpoint names from breakpoint IDs and "
92*7ced9fffSJonas Devlieghere          "ranges, "
93*7ced9fffSJonas Devlieghere          "names must start with a letter from a-z or A-Z and cannot contain "
94*7ced9fffSJonas Devlieghere          "spaces, \".\" or \"-\".  "
95*7ced9fffSJonas Devlieghere          "Also, breakpoint names can only be applied to breakpoints, not to "
96*7ced9fffSJonas Devlieghere          "breakpoint locations.";
97*7ced9fffSJonas Devlieghere }
98*7ced9fffSJonas Devlieghere 
GDBFormatHelpTextCallback()99*7ced9fffSJonas Devlieghere llvm::StringRef GDBFormatHelpTextCallback() {
100*7ced9fffSJonas Devlieghere   return "A GDB format consists of a repeat count, a format letter and a size "
101*7ced9fffSJonas Devlieghere          "letter. "
102*7ced9fffSJonas Devlieghere          "The repeat count is optional and defaults to 1. The format letter is "
103*7ced9fffSJonas Devlieghere          "optional "
104*7ced9fffSJonas Devlieghere          "and defaults to the previous format that was used. The size letter "
105*7ced9fffSJonas Devlieghere          "is optional "
106*7ced9fffSJonas Devlieghere          "and defaults to the previous size that was used.\n"
107*7ced9fffSJonas Devlieghere          "\n"
108*7ced9fffSJonas Devlieghere          "Format letters include:\n"
109*7ced9fffSJonas Devlieghere          "o - octal\n"
110*7ced9fffSJonas Devlieghere          "x - hexadecimal\n"
111*7ced9fffSJonas Devlieghere          "d - decimal\n"
112*7ced9fffSJonas Devlieghere          "u - unsigned decimal\n"
113*7ced9fffSJonas Devlieghere          "t - binary\n"
114*7ced9fffSJonas Devlieghere          "f - float\n"
115*7ced9fffSJonas Devlieghere          "a - address\n"
116*7ced9fffSJonas Devlieghere          "i - instruction\n"
117*7ced9fffSJonas Devlieghere          "c - char\n"
118*7ced9fffSJonas Devlieghere          "s - string\n"
119*7ced9fffSJonas Devlieghere          "T - OSType\n"
120*7ced9fffSJonas Devlieghere          "A - float as hex\n"
121*7ced9fffSJonas Devlieghere          "\n"
122*7ced9fffSJonas Devlieghere          "Size letters include:\n"
123*7ced9fffSJonas Devlieghere          "b - 1 byte  (byte)\n"
124*7ced9fffSJonas Devlieghere          "h - 2 bytes (halfword)\n"
125*7ced9fffSJonas Devlieghere          "w - 4 bytes (word)\n"
126*7ced9fffSJonas Devlieghere          "g - 8 bytes (giant)\n"
127*7ced9fffSJonas Devlieghere          "\n"
128*7ced9fffSJonas Devlieghere          "Example formats:\n"
129*7ced9fffSJonas Devlieghere          "32xb - show 32 1 byte hexadecimal integer values\n"
130*7ced9fffSJonas Devlieghere          "16xh - show 16 2 byte hexadecimal integer values\n"
131*7ced9fffSJonas Devlieghere          "64   - show 64 2 byte hexadecimal integer values (format and size "
132*7ced9fffSJonas Devlieghere          "from the last format)\n"
133*7ced9fffSJonas Devlieghere          "dw   - show 1 4 byte decimal integer value\n";
134*7ced9fffSJonas Devlieghere }
135*7ced9fffSJonas Devlieghere 
FormatHelpTextCallback()136*7ced9fffSJonas Devlieghere llvm::StringRef FormatHelpTextCallback() {
137*7ced9fffSJonas Devlieghere   static std::string help_text;
138*7ced9fffSJonas Devlieghere 
139*7ced9fffSJonas Devlieghere   if (!help_text.empty())
140*7ced9fffSJonas Devlieghere     return help_text;
141*7ced9fffSJonas Devlieghere 
142*7ced9fffSJonas Devlieghere   StreamString sstr;
143*7ced9fffSJonas Devlieghere   sstr << "One of the format names (or one-character names) that can be used "
144*7ced9fffSJonas Devlieghere           "to show a variable's value:\n";
145*7ced9fffSJonas Devlieghere   for (Format f = eFormatDefault; f < kNumFormats; f = Format(f + 1)) {
146*7ced9fffSJonas Devlieghere     if (f != eFormatDefault)
147*7ced9fffSJonas Devlieghere       sstr.PutChar('\n');
148*7ced9fffSJonas Devlieghere 
149*7ced9fffSJonas Devlieghere     char format_char = FormatManager::GetFormatAsFormatChar(f);
150*7ced9fffSJonas Devlieghere     if (format_char)
151*7ced9fffSJonas Devlieghere       sstr.Printf("'%c' or ", format_char);
152*7ced9fffSJonas Devlieghere 
153*7ced9fffSJonas Devlieghere     sstr.Printf("\"%s\"", FormatManager::GetFormatAsCString(f));
154*7ced9fffSJonas Devlieghere   }
155*7ced9fffSJonas Devlieghere 
156*7ced9fffSJonas Devlieghere   sstr.Flush();
157*7ced9fffSJonas Devlieghere 
158*7ced9fffSJonas Devlieghere   help_text = std::string(sstr.GetString());
159*7ced9fffSJonas Devlieghere 
160*7ced9fffSJonas Devlieghere   return help_text;
161*7ced9fffSJonas Devlieghere }
162*7ced9fffSJonas Devlieghere 
LanguageTypeHelpTextCallback()163*7ced9fffSJonas Devlieghere llvm::StringRef LanguageTypeHelpTextCallback() {
164*7ced9fffSJonas Devlieghere   static std::string help_text;
165*7ced9fffSJonas Devlieghere 
166*7ced9fffSJonas Devlieghere   if (!help_text.empty())
167*7ced9fffSJonas Devlieghere     return help_text;
168*7ced9fffSJonas Devlieghere 
169*7ced9fffSJonas Devlieghere   StreamString sstr;
170*7ced9fffSJonas Devlieghere   sstr << "One of the following languages:\n";
171*7ced9fffSJonas Devlieghere 
172*7ced9fffSJonas Devlieghere   Language::PrintAllLanguages(sstr, "  ", "\n");
173*7ced9fffSJonas Devlieghere 
174*7ced9fffSJonas Devlieghere   sstr.Flush();
175*7ced9fffSJonas Devlieghere 
176*7ced9fffSJonas Devlieghere   help_text = std::string(sstr.GetString());
177*7ced9fffSJonas Devlieghere 
178*7ced9fffSJonas Devlieghere   return help_text;
179*7ced9fffSJonas Devlieghere }
180*7ced9fffSJonas Devlieghere 
SummaryStringHelpTextCallback()181*7ced9fffSJonas Devlieghere llvm::StringRef SummaryStringHelpTextCallback() {
182*7ced9fffSJonas Devlieghere   return "A summary string is a way to extract information from variables in "
183*7ced9fffSJonas Devlieghere          "order to present them using a summary.\n"
184*7ced9fffSJonas Devlieghere          "Summary strings contain static text, variables, scopes and control "
185*7ced9fffSJonas Devlieghere          "sequences:\n"
186*7ced9fffSJonas Devlieghere          "  - Static text can be any sequence of non-special characters, i.e. "
187*7ced9fffSJonas Devlieghere          "anything but '{', '}', '$', or '\\'.\n"
188*7ced9fffSJonas Devlieghere          "  - Variables are sequences of characters beginning with ${, ending "
189*7ced9fffSJonas Devlieghere          "with } and that contain symbols in the format described below.\n"
190*7ced9fffSJonas Devlieghere          "  - Scopes are any sequence of text between { and }. Anything "
191*7ced9fffSJonas Devlieghere          "included in a scope will only appear in the output summary if there "
192*7ced9fffSJonas Devlieghere          "were no errors.\n"
193*7ced9fffSJonas Devlieghere          "  - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus "
194*7ced9fffSJonas Devlieghere          "'\\$', '\\{' and '\\}'.\n"
195*7ced9fffSJonas Devlieghere          "A summary string works by copying static text verbatim, turning "
196*7ced9fffSJonas Devlieghere          "control sequences into their character counterpart, expanding "
197*7ced9fffSJonas Devlieghere          "variables and trying to expand scopes.\n"
198*7ced9fffSJonas Devlieghere          "A variable is expanded by giving it a value other than its textual "
199*7ced9fffSJonas Devlieghere          "representation, and the way this is done depends on what comes after "
200*7ced9fffSJonas Devlieghere          "the ${ marker.\n"
201*7ced9fffSJonas Devlieghere          "The most common sequence if ${var followed by an expression path, "
202*7ced9fffSJonas Devlieghere          "which is the text one would type to access a member of an aggregate "
203*7ced9fffSJonas Devlieghere          "types, given a variable of that type"
204*7ced9fffSJonas Devlieghere          " (e.g. if type T has a member named x, which has a member named y, "
205*7ced9fffSJonas Devlieghere          "and if t is of type T, the expression path would be .x.y and the way "
206*7ced9fffSJonas Devlieghere          "to fit that into a summary string would be"
207*7ced9fffSJonas Devlieghere          " ${var.x.y}). You can also use ${*var followed by an expression path "
208*7ced9fffSJonas Devlieghere          "and in that case the object referred by the path will be "
209*7ced9fffSJonas Devlieghere          "dereferenced before being displayed."
210*7ced9fffSJonas Devlieghere          " If the object is not a pointer, doing so will cause an error. For "
211*7ced9fffSJonas Devlieghere          "additional details on expression paths, you can type 'help "
212*7ced9fffSJonas Devlieghere          "expr-path'. \n"
213*7ced9fffSJonas Devlieghere          "By default, summary strings attempt to display the summary for any "
214*7ced9fffSJonas Devlieghere          "variable they reference, and if that fails the value. If neither can "
215*7ced9fffSJonas Devlieghere          "be shown, nothing is displayed."
216*7ced9fffSJonas Devlieghere          "In a summary string, you can also use an array index [n], or a "
217*7ced9fffSJonas Devlieghere          "slice-like range [n-m]. This can have two different meanings "
218*7ced9fffSJonas Devlieghere          "depending on what kind of object the expression"
219*7ced9fffSJonas Devlieghere          " path refers to:\n"
220*7ced9fffSJonas Devlieghere          "  - if it is a scalar type (any basic type like int, float, ...) the "
221*7ced9fffSJonas Devlieghere          "expression is a bitfield, i.e. the bits indicated by the indexing "
222*7ced9fffSJonas Devlieghere          "operator are extracted out of the number"
223*7ced9fffSJonas Devlieghere          " and displayed as an individual variable\n"
224*7ced9fffSJonas Devlieghere          "  - if it is an array or pointer the array items indicated by the "
225*7ced9fffSJonas Devlieghere          "indexing operator are shown as the result of the variable. if the "
226*7ced9fffSJonas Devlieghere          "expression is an array, real array items are"
227*7ced9fffSJonas Devlieghere          " printed; if it is a pointer, the pointer-as-array syntax is used to "
228*7ced9fffSJonas Devlieghere          "obtain the values (this means, the latter case can have no range "
229*7ced9fffSJonas Devlieghere          "checking)\n"
230*7ced9fffSJonas Devlieghere          "If you are trying to display an array for which the size is known, "
231*7ced9fffSJonas Devlieghere          "you can also use [] instead of giving an exact range. This has the "
232*7ced9fffSJonas Devlieghere          "effect of showing items 0 thru size - 1.\n"
233*7ced9fffSJonas Devlieghere          "Additionally, a variable can contain an (optional) format code, as "
234*7ced9fffSJonas Devlieghere          "in ${var.x.y%code}, where code can be any of the valid formats "
235*7ced9fffSJonas Devlieghere          "described in 'help format', or one of the"
236*7ced9fffSJonas Devlieghere          " special symbols only allowed as part of a variable:\n"
237*7ced9fffSJonas Devlieghere          "    %V: show the value of the object by default\n"
238*7ced9fffSJonas Devlieghere          "    %S: show the summary of the object by default\n"
239*7ced9fffSJonas Devlieghere          "    %@: show the runtime-provided object description (for "
240*7ced9fffSJonas Devlieghere          "Objective-C, it calls NSPrintForDebugger; for C/C++ it does "
241*7ced9fffSJonas Devlieghere          "nothing)\n"
242*7ced9fffSJonas Devlieghere          "    %L: show the location of the object (memory address or a "
243*7ced9fffSJonas Devlieghere          "register name)\n"
244*7ced9fffSJonas Devlieghere          "    %#: show the number of children of the object\n"
245*7ced9fffSJonas Devlieghere          "    %T: show the type of the object\n"
246*7ced9fffSJonas Devlieghere          "Another variable that you can use in summary strings is ${svar . "
247*7ced9fffSJonas Devlieghere          "This sequence works exactly like ${var, including the fact that "
248*7ced9fffSJonas Devlieghere          "${*svar is an allowed sequence, but uses"
249*7ced9fffSJonas Devlieghere          " the object's synthetic children provider instead of the actual "
250*7ced9fffSJonas Devlieghere          "objects. For instance, if you are using STL synthetic children "
251*7ced9fffSJonas Devlieghere          "providers, the following summary string would"
252*7ced9fffSJonas Devlieghere          " count the number of actual elements stored in an std::list:\n"
253*7ced9fffSJonas Devlieghere          "type summary add -s \"${svar%#}\" -x \"std::list<\"";
254*7ced9fffSJonas Devlieghere }
255*7ced9fffSJonas Devlieghere 
ExprPathHelpTextCallback()256*7ced9fffSJonas Devlieghere llvm::StringRef ExprPathHelpTextCallback() {
257*7ced9fffSJonas Devlieghere   return "An expression path is the sequence of symbols that is used in C/C++ "
258*7ced9fffSJonas Devlieghere          "to access a member variable of an aggregate object (class).\n"
259*7ced9fffSJonas Devlieghere          "For instance, given a class:\n"
260*7ced9fffSJonas Devlieghere          "  class foo {\n"
261*7ced9fffSJonas Devlieghere          "      int a;\n"
262*7ced9fffSJonas Devlieghere          "      int b; .\n"
263*7ced9fffSJonas Devlieghere          "      foo* next;\n"
264*7ced9fffSJonas Devlieghere          "  };\n"
265*7ced9fffSJonas Devlieghere          "the expression to read item b in the item pointed to by next for foo "
266*7ced9fffSJonas Devlieghere          "aFoo would be aFoo.next->b.\n"
267*7ced9fffSJonas Devlieghere          "Given that aFoo could just be any object of type foo, the string "
268*7ced9fffSJonas Devlieghere          "'.next->b' is the expression path, because it can be attached to any "
269*7ced9fffSJonas Devlieghere          "foo instance to achieve the effect.\n"
270*7ced9fffSJonas Devlieghere          "Expression paths in LLDB include dot (.) and arrow (->) operators, "
271*7ced9fffSJonas Devlieghere          "and most commands using expression paths have ways to also accept "
272*7ced9fffSJonas Devlieghere          "the star (*) operator.\n"
273*7ced9fffSJonas Devlieghere          "The meaning of these operators is the same as the usual one given to "
274*7ced9fffSJonas Devlieghere          "them by the C/C++ standards.\n"
275*7ced9fffSJonas Devlieghere          "LLDB also has support for indexing ([ ]) in expression paths, and "
276*7ced9fffSJonas Devlieghere          "extends the traditional meaning of the square brackets operator to "
277*7ced9fffSJonas Devlieghere          "allow bitfield extraction:\n"
278*7ced9fffSJonas Devlieghere          "for objects of native types (int, float, char, ...) saying '[n-m]' "
279*7ced9fffSJonas Devlieghere          "as an expression path (where n and m are any positive integers, e.g. "
280*7ced9fffSJonas Devlieghere          "[3-5]) causes LLDB to extract"
281*7ced9fffSJonas Devlieghere          " bits n thru m from the value of the variable. If n == m, [n] is "
282*7ced9fffSJonas Devlieghere          "also allowed as a shortcut syntax. For arrays and pointers, "
283*7ced9fffSJonas Devlieghere          "expression paths can only contain one index"
284*7ced9fffSJonas Devlieghere          " and the meaning of the operation is the same as the one defined by "
285*7ced9fffSJonas Devlieghere          "C/C++ (item extraction). Some commands extend bitfield-like syntax "
286*7ced9fffSJonas Devlieghere          "for arrays and pointers with the"
287*7ced9fffSJonas Devlieghere          " meaning of array slicing (taking elements n thru m inside the array "
288*7ced9fffSJonas Devlieghere          "or pointed-to memory).";
289*7ced9fffSJonas Devlieghere }
290*7ced9fffSJonas Devlieghere 
arch_helper()291*7ced9fffSJonas Devlieghere llvm::StringRef arch_helper() {
292*7ced9fffSJonas Devlieghere   static StreamString g_archs_help;
293*7ced9fffSJonas Devlieghere   if (g_archs_help.Empty()) {
294*7ced9fffSJonas Devlieghere     StringList archs;
295*7ced9fffSJonas Devlieghere 
296*7ced9fffSJonas Devlieghere     ArchSpec::ListSupportedArchNames(archs);
297*7ced9fffSJonas Devlieghere     g_archs_help.Printf("These are the supported architecture names:\n");
298*7ced9fffSJonas Devlieghere     archs.Join("\n", g_archs_help);
299*7ced9fffSJonas Devlieghere   }
300*7ced9fffSJonas Devlieghere   return g_archs_help.GetString();
301*7ced9fffSJonas Devlieghere }
302*7ced9fffSJonas Devlieghere 
303*7ced9fffSJonas Devlieghere template <int I> struct TableValidator : TableValidator<I + 1> {
304*7ced9fffSJonas Devlieghere   static_assert(
305*7ced9fffSJonas Devlieghere       g_argument_table[I].arg_type == I,
306*7ced9fffSJonas Devlieghere       "g_argument_table order doesn't match CommandArgumentType enumeration");
307*7ced9fffSJonas Devlieghere };
308*7ced9fffSJonas Devlieghere 
309*7ced9fffSJonas Devlieghere template <> struct TableValidator<eArgTypeLastArg> {};
310*7ced9fffSJonas Devlieghere 
311*7ced9fffSJonas Devlieghere TableValidator<0> validator;
312*7ced9fffSJonas Devlieghere 
313*7ced9fffSJonas Devlieghere } // namespace lldb_private
314