xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Core/FormatEntity.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- FormatEntity.h ------------------------------------------*- C++ -*-===//
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 #ifndef LLDB_CORE_FORMATENTITY_H
10 #define LLDB_CORE_FORMATENTITY_H
11 
12 #include "lldb/lldb-enumerations.h"
13 #include "lldb/lldb-types.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include <algorithm>
16 #include <cstddef>
17 #include <cstdint>
18 #include <string>
19 #include <vector>
20 
21 namespace lldb_private {
22 class Address;
23 class CompletionRequest;
24 class ExecutionContext;
25 class FileSpec;
26 class Status;
27 class Stream;
28 class StringList;
29 class SymbolContext;
30 class ValueObject;
31 }
32 
33 namespace llvm {
34 class StringRef;
35 }
36 
37 namespace lldb_private {
38 namespace FormatEntity {
39 struct Entry {
40   enum class Type {
41     Invalid,
42     ParentNumber,
43     ParentString,
44     EscapeCode,
45     Root,
46     String,
47     Scope,
48     Variable,
49     VariableSynthetic,
50     ScriptVariable,
51     ScriptVariableSynthetic,
52     AddressLoad,
53     AddressFile,
54     AddressLoadOrFile,
55     ProcessID,
56     ProcessFile,
57     ScriptProcess,
58     ThreadID,
59     ThreadProtocolID,
60     ThreadIndexID,
61     ThreadName,
62     ThreadQueue,
63     ThreadStopReason,
64     ThreadStopReasonRaw,
65     ThreadReturnValue,
66     ThreadCompletedExpression,
67     ScriptThread,
68     ThreadInfo,
69     TargetArch,
70     TargetFile,
71     ScriptTarget,
72     ModuleFile,
73     File,
74     Lang,
75     FrameIndex,
76     FrameNoDebug,
77     FrameRegisterPC,
78     FrameRegisterSP,
79     FrameRegisterFP,
80     FrameRegisterFlags,
81     FrameRegisterByName,
82     FrameIsArtificial,
83     ScriptFrame,
84     FunctionID,
85     FunctionDidChange,
86     FunctionInitialFunction,
87     FunctionName,
88     FunctionNameWithArgs,
89     FunctionNameNoArgs,
90     FunctionMangledName,
91     FunctionPrefix,
92     FunctionScope,
93     FunctionBasename,
94     FunctionTemplateArguments,
95     FunctionFormattedArguments,
96     FunctionReturnLeft,
97     FunctionReturnRight,
98     FunctionQualifiers,
99     FunctionSuffix,
100     FunctionAddrOffset,
101     FunctionAddrOffsetConcrete,
102     FunctionLineOffset,
103     FunctionPCOffset,
104     FunctionInitial,
105     FunctionChanged,
106     FunctionIsOptimized,
107     FunctionIsInlined,
108     LineEntryFile,
109     LineEntryLineNumber,
110     LineEntryColumn,
111     LineEntryStartAddress,
112     LineEntryEndAddress,
113     CurrentPCArrow,
114     ProgressCount,
115     ProgressMessage,
116     Separator,
117   };
118 
119   struct Definition {
120     /// The name/string placeholder that corresponds to this definition.
121     const char *name;
122     /// Insert this exact string into the output
123     const char *string = nullptr;
124     /// Entry::Type corresponding to this definition.
125     const Entry::Type type;
126     /// Data that is returned as the value of the format string.
127     const uint64_t data = 0;
128     /// The number of children of this node in the tree of format strings.
129     const uint32_t num_children = 0;
130     /// An array of "num_children" Definition entries.
131     const Definition *children = nullptr;
132     /// Whether the separator is kept during parsing or not.  It's used
133     /// for entries with parameters.
134     const bool keep_separator = false;
135 
DefinitionEntry::Definition136     constexpr Definition(const char *name, const FormatEntity::Entry::Type t)
137         : name(name), type(t) {}
138 
DefinitionEntry::Definition139     constexpr Definition(const char *name, const char *string)
140         : name(name), string(string), type(Entry::Type::EscapeCode) {}
141 
DefinitionEntry::Definition142     constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
143                          const uint64_t data)
144         : name(name), type(t), data(data) {}
145 
146     constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
147                          const uint64_t num_children,
148                          const Definition *children,
149                          const bool keep_separator = false)
nameEntry::Definition150         : name(name), type(t), num_children(num_children), children(children),
151           keep_separator(keep_separator) {}
152   };
153 
154   template <size_t N>
155   static constexpr Definition
156   DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t,
157                          const Definition (&children)[N],
158                          bool keep_separator = false) {
159     return Definition(name, t, N, children, keep_separator);
160   }
161 
162   Entry(Type t = Type::Invalid, const char *s = nullptr,
163         const char *f = nullptr);
164   Entry(llvm::StringRef s);
165   Entry(char ch);
166 
167   void AppendChar(char ch);
168 
169   void AppendText(const llvm::StringRef &s);
170 
171   void AppendText(const char *cstr);
172 
173   void AppendEntry(const Entry &&entry);
174 
175   void StartAlternative();
176 
ClearEntry177   void Clear() {
178     string.clear();
179     printf_format.clear();
180     children_stack.clear();
181     children_stack.emplace_back();
182     type = Type::Invalid;
183     fmt = lldb::eFormatDefault;
184     number = 0;
185     level = 0;
186     deref = false;
187   }
188 
189   static const char *TypeToCString(Type t);
190 
191   void Dump(Stream &s, int depth = 0) const;
192 
193   bool operator==(const Entry &rhs) const {
194     if (string != rhs.string)
195       return false;
196     if (printf_format != rhs.printf_format)
197       return false;
198     if (children_stack != rhs.children_stack)
199       return false;
200     if (type != rhs.type)
201       return false;
202     if (fmt != rhs.fmt)
203       return false;
204     if (deref != rhs.deref)
205       return false;
206     return true;
207   }
208 
209   operator bool() const { return type != Type::Invalid; }
210 
211   std::vector<Entry> &GetChildren();
212 
213   std::string string;
214   std::string printf_format;
215 
216   /// A stack of children entries, used by Scope entries to provide alterantive
217   /// children. All other entries have a stack of size 1.
218   /// @{
219   llvm::SmallVector<std::vector<Entry>, 1> children_stack;
220   size_t level = 0;
221   /// @}
222 
223   Type type = Type::Invalid;
224   lldb::Format fmt = lldb::eFormatDefault;
225   lldb::addr_t number = 0;
226   bool deref = false;
227 };
228 
229 bool Format(const Entry &entry, Stream &s, const SymbolContext *sc,
230             const ExecutionContext *exe_ctx, const Address *addr,
231             ValueObject *valobj, bool function_changed, bool initial_function);
232 
233 bool FormatStringRef(const llvm::StringRef &format, Stream &s,
234                      const SymbolContext *sc, const ExecutionContext *exe_ctx,
235                      const Address *addr, ValueObject *valobj,
236                      bool function_changed, bool initial_function);
237 
238 Status Parse(const llvm::StringRef &format, Entry &entry);
239 
240 Status ExtractVariableInfo(llvm::StringRef &format_str,
241                            llvm::StringRef &variable_name,
242                            llvm::StringRef &variable_format);
243 
244 void AutoComplete(lldb_private::CompletionRequest &request);
245 
246 // Format the current elements into the stream \a s.
247 //
248 // The root element will be stripped off and the format str passed in will be
249 // either an empty string (print a description of this object), or contain a
250 // `.`-separated series like a domain name that identifies further
251 //  sub-elements to display.
252 bool FormatFileSpec(const FileSpec &file, Stream &s, llvm::StringRef elements,
253                     llvm::StringRef element_format);
254 
255 /// For each variable in 'args' this function writes the variable
256 /// name and it's pretty-printed value representation to 'out_stream'
257 /// in following format:
258 ///
259 /// \verbatim
260 /// name_1=repr_1, name_2=repr_2 ...
261 /// \endverbatim
262 void PrettyPrintFunctionArguments(Stream &out_stream, VariableList const &args,
263                                   ExecutionContextScope *exe_scope);
264 } // namespace FormatEntity
265 } // namespace lldb_private
266 
267 #endif // LLDB_CORE_FORMATENTITY_H
268