Bug Summary

File:tools/lldb/include/lldb/Interpreter/CommandObject.h
Warning:line 81, column 10
Excessive padding in 'struct lldb_private::CommandObject::ArgumentTableEntry' (8 padding bytes, where 0 is optimal). Optimal fields order: arg_name, help_text, help_function, arg_type, completion_type, consider reordering the fields or adding explicit padding members

Annotated Source Code

1//===-- CommandObject.h -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_CommandObject_h_
11#define liblldb_CommandObject_h_
12
13// C Includes
14// C++ Includes
15#include <map>
16#include <string>
17#include <vector>
18
19// Other libraries and framework includes
20// Project includes
21#include "lldb/Utility/Flags.h"
22
23#include "lldb/Core/StringList.h"
24#include "lldb/Interpreter/Args.h"
25#include "lldb/Interpreter/CommandCompletions.h"
26#include "lldb/Target/ExecutionContext.h"
27#include "lldb/lldb-private.h"
28
29namespace lldb_private {
30
31// This function really deals with CommandObjectLists, but we didn't make a
32// CommandObjectList class, so I'm sticking it here. But we really should have
33// such a class. Anyway, it looks up the commands in the map that match the
34// partial
35// string cmd_str, inserts the matches into matches, and returns the number
36// added.
37
38template <typename ValueType>
39int AddNamesMatchingPartialString(const std::map<std::string, ValueType> &in_map,
40 llvm::StringRef cmd_str, StringList &matches) {
41 int number_added = 0;
42
43 const bool add_all = cmd_str.empty();
44
45 for (auto iter = in_map.begin(), end = in_map.end(); iter != end; iter++) {
46 if (add_all || (iter->first.find(cmd_str, 0) == 0)) {
47 ++number_added;
48 matches.AppendString(iter->first.c_str());
49 }
50 }
51
52 return number_added;
53}
54
55template <typename ValueType>
56size_t FindLongestCommandWord(std::map<std::string, ValueType> &dict) {
57 auto end = dict.end();
58 size_t max_len = 0;
59
60 for (auto pos = dict.begin(); pos != end; ++pos) {
61 size_t len = pos->first.size();
62 if (max_len < len)
63 max_len = len;
64 }
65 return max_len;
66}
67
68class CommandObject {
69public:
70 typedef llvm::StringRef(ArgumentHelpCallbackFunction)();
71
72 struct ArgumentHelpCallback {
73 ArgumentHelpCallbackFunction *help_callback;
74 bool self_formatting;
75
76 llvm::StringRef operator()() const { return (*help_callback)(); }
77
78 explicit operator bool() const { return (help_callback != nullptr); }
79 };
80
81 struct ArgumentTableEntry // Entries in the main argument information table
Excessive padding in 'struct lldb_private::CommandObject::ArgumentTableEntry' (8 padding bytes, where 0 is optimal). Optimal fields order: arg_name, help_text, help_function, arg_type, completion_type, consider reordering the fields or adding explicit padding members
82 {
83 lldb::CommandArgumentType arg_type;
84 const char *arg_name;
85 CommandCompletions::CommonCompletionTypes completion_type;
86 ArgumentHelpCallback help_function;
87 const char *help_text;
88 };
89
90 struct CommandArgumentData // Used to build individual command argument lists
91 {
92 lldb::CommandArgumentType arg_type;
93 ArgumentRepetitionType arg_repetition;
94 uint32_t arg_opt_set_association; // This arg might be associated only with
95 // some particular option set(s).
96 CommandArgumentData()
97 : arg_type(lldb::eArgTypeNone), arg_repetition(eArgRepeatPlain),
98 arg_opt_set_association(LLDB_OPT_SET_ALL0xFFFFFFFFU) // By default, the arg
99 // associates to all option
100 // sets.
101 {}
102 };
103
104 typedef std::vector<CommandArgumentData>
105 CommandArgumentEntry; // Used to build individual command argument lists
106
107 static ArgumentTableEntry g_arguments_data
108 [lldb::eArgTypeLastArg]; // Main argument information table
109
110 typedef std::map<std::string, lldb::CommandObjectSP> CommandMap;
111
112 CommandObject(CommandInterpreter &interpreter, llvm::StringRef name,
113 llvm::StringRef help = "", llvm::StringRef syntax = "",
114 uint32_t flags = 0);
115
116 virtual ~CommandObject();
117
118 static const char *
119 GetArgumentTypeAsCString(const lldb::CommandArgumentType arg_type);
120
121 static const char *
122 GetArgumentDescriptionAsCString(const lldb::CommandArgumentType arg_type);
123
124 CommandInterpreter &GetCommandInterpreter() { return m_interpreter; }
125
126 virtual llvm::StringRef GetHelp();
127
128 virtual llvm::StringRef GetHelpLong();
129
130 virtual llvm::StringRef GetSyntax();
131
132 llvm::StringRef GetCommandName() const;
133
134 virtual void SetHelp(llvm::StringRef str);
135
136 virtual void SetHelpLong(llvm::StringRef str);
137
138 void SetSyntax(llvm::StringRef str);
139
140 // override this to return true if you want to enable the user to delete
141 // the Command object from the Command dictionary (aliases have their own
142 // deletion scheme, so they do not need to care about this)
143 virtual bool IsRemovable() const { return false; }
144
145 virtual bool IsMultiwordObject() { return false; }
146
147 virtual CommandObjectMultiword *GetAsMultiwordCommand() { return nullptr; }
148
149 virtual bool IsAlias() { return false; }
150
151 // override this to return true if your command is somehow a "dash-dash"
152 // form of some other command (e.g. po is expr -O --); this is a powerful
153 // hint to the help system that one cannot pass options to this command
154 virtual bool IsDashDashCommand() { return false; }
155
156 virtual lldb::CommandObjectSP GetSubcommandSP(llvm::StringRef sub_cmd,
157 StringList *matches = nullptr) {
158 return lldb::CommandObjectSP();
159 }
160
161 virtual CommandObject *GetSubcommandObject(llvm::StringRef sub_cmd,
162 StringList *matches = nullptr) {
163 return nullptr;
164 }
165
166 virtual void AproposAllSubCommands(llvm::StringRef prefix,
167 llvm::StringRef search_word,
168 StringList &commands_found,
169 StringList &commands_help) {}
170
171 void FormatLongHelpText(Stream &output_strm, llvm::StringRef long_help);
172
173 void GenerateHelpText(CommandReturnObject &result);
174
175 virtual void GenerateHelpText(Stream &result);
176
177 // this is needed in order to allow the SBCommand class to
178 // transparently try and load subcommands - it will fail on
179 // anything but a multiword command, but it avoids us doing
180 // type checkings and casts
181 virtual bool LoadSubCommand(llvm::StringRef cmd_name,
182 const lldb::CommandObjectSP &command_obj) {
183 return false;
184 }
185
186 virtual bool WantsRawCommandString() = 0;
187
188 // By default, WantsCompletion = !WantsRawCommandString.
189 // Subclasses who want raw command string but desire, for example,
190 // argument completion should override this method to return true.
191 virtual bool WantsCompletion() { return !WantsRawCommandString(); }
192
193 virtual Options *GetOptions();
194
195 static const ArgumentTableEntry *GetArgumentTable();
196
197 static lldb::CommandArgumentType LookupArgumentName(llvm::StringRef arg_name);
198
199 static const ArgumentTableEntry *
200 FindArgumentDataByType(lldb::CommandArgumentType arg_type);
201
202 int GetNumArgumentEntries();
203
204 CommandArgumentEntry *GetArgumentEntryAtIndex(int idx);
205
206 static void GetArgumentHelp(Stream &str, lldb::CommandArgumentType arg_type,
207 CommandInterpreter &interpreter);
208
209 static const char *GetArgumentName(lldb::CommandArgumentType arg_type);
210
211 // Generates a nicely formatted command args string for help command output.
212 // By default, all possible args are taken into account, for example,
213 // '<expr | variable-name>'. This can be refined by passing a second arg
214 // specifying which option set(s) we are interested, which could then, for
215 // example, produce either '<expr>' or '<variable-name>'.
216 void GetFormattedCommandArguments(Stream &str,
217 uint32_t opt_set_mask = LLDB_OPT_SET_ALL0xFFFFFFFFU);
218
219 bool IsPairType(ArgumentRepetitionType arg_repeat_type);
220
221 bool ParseOptions(Args &args, CommandReturnObject &result);
222
223 void SetCommandName(llvm::StringRef name);
224
225 //------------------------------------------------------------------
226 /// The input array contains a parsed version of the line. The insertion
227 /// point is given by cursor_index (the index in input of the word containing
228 /// the cursor) and cursor_char_position (the position of the cursor in that
229 /// word.)
230 /// This default version handles calling option argument completions and then
231 /// calls
232 /// HandleArgumentCompletion if the cursor is on an argument, not an option.
233 /// Don't override this method, override HandleArgumentCompletion instead
234 /// unless
235 /// you have special reasons.
236 ///
237 /// @param[in] interpreter
238 /// The command interpreter doing the completion.
239 ///
240 /// @param[in] input
241 /// The command line parsed into words
242 ///
243 /// @param[in] cursor_index
244 /// The index in \ainput of the word in which the cursor lies.
245 ///
246 /// @param[in] cursor_char_pos
247 /// The character position of the cursor in its argument word.
248 ///
249 /// @param[in] match_start_point
250 /// @param[in] match_return_elements
251 /// FIXME: Not yet implemented... If there is a match that is expensive
252 /// to compute, these are
253 /// here to allow you to compute the completions in batches. Start the
254 /// completion from \amatch_start_point,
255 /// and return \amatch_return_elements elements.
256 ///
257 /// @param[out] word_complete
258 /// \btrue if this is a complete option value (a space will be inserted
259 /// after the
260 /// completion.) \bfalse otherwise.
261 ///
262 /// @param[out] matches
263 /// The array of matches returned.
264 ///
265 /// FIXME: This is the wrong return value, since we also need to make a
266 /// distinction between
267 /// total number of matches, and the window the user wants returned.
268 ///
269 /// @return
270 /// \btrue if we were in an option, \bfalse otherwise.
271 //------------------------------------------------------------------
272 virtual int HandleCompletion(Args &input, int &cursor_index,
273 int &cursor_char_position, int match_start_point,
274 int max_return_elements, bool &word_complete,
275 StringList &matches);
276
277 //------------------------------------------------------------------
278 /// The input array contains a parsed version of the line. The insertion
279 /// point is given by cursor_index (the index in input of the word containing
280 /// the cursor) and cursor_char_position (the position of the cursor in that
281 /// word.)
282 /// We've constructed the map of options and their arguments as well if that
283 /// is
284 /// helpful for the completion.
285 ///
286 /// @param[in] interpreter
287 /// The command interpreter doing the completion.
288 ///
289 /// @param[in] input
290 /// The command line parsed into words
291 ///
292 /// @param[in] cursor_index
293 /// The index in \ainput of the word in which the cursor lies.
294 ///
295 /// @param[in] cursor_char_pos
296 /// The character position of the cursor in its argument word.
297 ///
298 /// @param[in] opt_element_vector
299 /// The results of the options parse of \a input.
300 ///
301 /// @param[in] match_start_point
302 /// @param[in] match_return_elements
303 /// See CommandObject::HandleCompletions for a description of how these
304 /// work.
305 ///
306 /// @param[out] word_complete
307 /// \btrue if this is a complete option value (a space will be inserted
308 /// after the
309 /// completion.) \bfalse otherwise.
310 ///
311 /// @param[out] matches
312 /// The array of matches returned.
313 ///
314 /// FIXME: This is the wrong return value, since we also need to make a
315 /// distinction between
316 /// total number of matches, and the window the user wants returned.
317 ///
318 /// @return
319 /// The number of completions.
320 //------------------------------------------------------------------
321 virtual int HandleArgumentCompletion(
322 Args &input, int &cursor_index, int &cursor_char_position,
323 OptionElementVector &opt_element_vector, int match_start_point,
324 int max_return_elements, bool &word_complete, StringList &matches) {
325 return 0;
326 }
327
328 bool HelpTextContainsWord(llvm::StringRef search_word,
329 bool search_short_help = true,
330 bool search_long_help = true,
331 bool search_syntax = true,
332 bool search_options = true);
333
334 //------------------------------------------------------------------
335 /// The flags accessor.
336 ///
337 /// @return
338 /// A reference to the Flags member variable.
339 //------------------------------------------------------------------
340 Flags &GetFlags() { return m_flags; }
341
342 //------------------------------------------------------------------
343 /// The flags const accessor.
344 ///
345 /// @return
346 /// A const reference to the Flags member variable.
347 //------------------------------------------------------------------
348 const Flags &GetFlags() const { return m_flags; }
349
350 //------------------------------------------------------------------
351 /// Get the command that appropriate for a "repeat" of the current command.
352 ///
353 /// @param[in] current_command_line
354 /// The complete current command line.
355 ///
356 /// @return
357 /// nullptr if there is no special repeat command - it will use the
358 /// current command line.
359 /// Otherwise a pointer to the command to be repeated.
360 /// If the returned string is the empty string, the command won't be
361 /// repeated.
362 //------------------------------------------------------------------
363 virtual const char *GetRepeatCommand(Args &current_command_args,
364 uint32_t index) {
365 return nullptr;
366 }
367
368 bool HasOverrideCallback() const {
369 return m_command_override_callback ||
370 m_deprecated_command_override_callback;
371 }
372
373 void SetOverrideCallback(lldb::CommandOverrideCallback callback,
374 void *baton) {
375 m_deprecated_command_override_callback = callback;
376 m_command_override_baton = baton;
377 }
378
379 void SetOverrideCallback(lldb::CommandOverrideCallbackWithResult callback,
380 void *baton) {
381 m_command_override_callback = callback;
382 m_command_override_baton = baton;
383 }
384
385 bool InvokeOverrideCallback(const char **argv, CommandReturnObject &result) {
386 if (m_command_override_callback)
387 return m_command_override_callback(m_command_override_baton, argv,
388 result);
389 else if (m_deprecated_command_override_callback)
390 return m_deprecated_command_override_callback(m_command_override_baton,
391 argv);
392 else
393 return false;
394 }
395
396 virtual bool Execute(const char *args_string,
397 CommandReturnObject &result) = 0;
398
399protected:
400 virtual const char *GetInvalidTargetDescription() {
401 return "invalid target, create a target using the 'target create' command";
402 }
403
404 virtual const char *GetInvalidProcessDescription() {
405 return "invalid process";
406 }
407
408 virtual const char *GetInvalidThreadDescription() { return "invalid thread"; }
409
410 virtual const char *GetInvalidFrameDescription() { return "invalid frame"; }
411
412 virtual const char *GetInvalidRegContextDescription() {
413 return "invalid frame, no registers";
414 }
415
416 // This is for use in the command interpreter, when you either want the
417 // selected target, or if no target
418 // is present you want to prime the dummy target with entities that will be
419 // copied over to new targets.
420 Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
421 Target *GetDummyTarget();
422
423 // If a command needs to use the "current" thread, use this call.
424 // Command objects will have an ExecutionContext to use, and that may or may
425 // not have a thread in it. If it
426 // does, you should use that by default, if not, then use the
427 // ExecutionContext's target's selected thread, etc...
428 // This call insulates you from the details of this calculation.
429 Thread *GetDefaultThread();
430
431 //------------------------------------------------------------------
432 /// Check the command to make sure anything required by this
433 /// command is available.
434 ///
435 /// @param[out] result
436 /// A command result object, if it is not okay to run the command
437 /// this will be filled in with a suitable error.
438 ///
439 /// @return
440 /// \b true if it is okay to run this command, \b false otherwise.
441 //------------------------------------------------------------------
442 bool CheckRequirements(CommandReturnObject &result);
443
444 void Cleanup();
445
446 CommandInterpreter &m_interpreter;
447 ExecutionContext m_exe_ctx;
448 std::unique_lock<std::recursive_mutex> m_api_locker;
449 std::string m_cmd_name;
450 std::string m_cmd_help_short;
451 std::string m_cmd_help_long;
452 std::string m_cmd_syntax;
453 Flags m_flags;
454 std::vector<CommandArgumentEntry> m_arguments;
455 lldb::CommandOverrideCallback m_deprecated_command_override_callback;
456 lldb::CommandOverrideCallbackWithResult m_command_override_callback;
457 void *m_command_override_baton;
458
459 // Helper function to populate IDs or ID ranges as the command argument data
460 // to the specified command argument entry.
461 static void AddIDsArgumentData(CommandArgumentEntry &arg,
462 lldb::CommandArgumentType ID,
463 lldb::CommandArgumentType IDRange);
464};
465
466class CommandObjectParsed : public CommandObject {
467public:
468 CommandObjectParsed(CommandInterpreter &interpreter, const char *name,
469 const char *help = nullptr, const char *syntax = nullptr,
470 uint32_t flags = 0)
471 : CommandObject(interpreter, name, help, syntax, flags) {}
472
473 ~CommandObjectParsed() override = default;
474
475 bool Execute(const char *args_string, CommandReturnObject &result) override;
476
477protected:
478 virtual bool DoExecute(Args &command, CommandReturnObject &result) = 0;
479
480 bool WantsRawCommandString() override { return false; }
481};
482
483class CommandObjectRaw : public CommandObject {
484public:
485 CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name,
486 llvm::StringRef help = "", llvm::StringRef syntax = "",
487 uint32_t flags = 0)
488 : CommandObject(interpreter, name, help, syntax, flags) {}
489
490 ~CommandObjectRaw() override = default;
491
492 bool Execute(const char *args_string, CommandReturnObject &result) override;
493
494protected:
495 virtual bool DoExecute(const char *command, CommandReturnObject &result) = 0;
496
497 bool WantsRawCommandString() override { return true; }
498};
499
500} // namespace lldb_private
501
502#endif // liblldb_CommandObject_h_