xref: /llvm-project/lldb/include/lldb/Core/FormatEntity.h (revision 06c54bc1a200fd87bbf4b81db70f52159c79f5bf)
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 <algorithm>
15 #include <cstddef>
16 #include <cstdint>
17 
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     FunctionAddrOffset,
92     FunctionAddrOffsetConcrete,
93     FunctionLineOffset,
94     FunctionPCOffset,
95     FunctionInitial,
96     FunctionChanged,
97     FunctionIsOptimized,
98     LineEntryFile,
99     LineEntryLineNumber,
100     LineEntryColumn,
101     LineEntryStartAddress,
102     LineEntryEndAddress,
103     CurrentPCArrow
104   };
105 
106   struct Definition {
107     /// The name/string placeholder that corresponds to this definition.
108     const char *name;
109     /// Insert this exact string into the output
110     const char *string = nullptr;
111     /// Entry::Type corresponding to this definition.
112     const Entry::Type type;
113     /// Data that is returned as the value of the format string.
114     const uint64_t data = 0;
115     /// The number of children of this node in the tree of format strings.
116     const uint32_t num_children = 0;
117     /// An array of "num_children" Definition entries.
118     const Definition *children = nullptr;
119     /// Whether the separator is kept during parsing or not.  It's used
120     /// for entries with parameters.
121     const bool keep_separator = false;
122 
123     constexpr Definition(const char *name, const FormatEntity::Entry::Type t)
124         : name(name), type(t) {}
125 
126     constexpr Definition(const char *name, const char *string)
127         : name(name), string(string), type(Entry::Type::EscapeCode) {}
128 
129     constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
130                          const uint64_t data)
131         : name(name), type(t), data(data) {}
132 
133     constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
134                          const uint64_t num_children,
135                          const Definition *children,
136                          const bool keep_separator = false)
137         : name(name), type(t), num_children(num_children), children(children),
138           keep_separator(keep_separator) {}
139   };
140 
141   template <size_t N>
142   static constexpr Definition
143   DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t,
144                          const Definition (&children)[N],
145                          bool keep_separator = false) {
146     return Definition(name, t, N, children, keep_separator);
147   }
148 
149   Entry(Type t = Type::Invalid, const char *s = nullptr,
150         const char *f = nullptr)
151       : string(s ? s : ""), printf_format(f ? f : ""), type(t) {}
152 
153   Entry(llvm::StringRef s);
154   Entry(char ch);
155 
156   void AppendChar(char ch);
157 
158   void AppendText(const llvm::StringRef &s);
159 
160   void AppendText(const char *cstr);
161 
162   void AppendEntry(const Entry &&entry) { children.push_back(entry); }
163 
164   void Clear() {
165     string.clear();
166     printf_format.clear();
167     children.clear();
168     type = Type::Invalid;
169     fmt = lldb::eFormatDefault;
170     number = 0;
171     deref = false;
172   }
173 
174   static const char *TypeToCString(Type t);
175 
176   void Dump(Stream &s, int depth = 0) const;
177 
178   bool operator==(const Entry &rhs) const {
179     if (string != rhs.string)
180       return false;
181     if (printf_format != rhs.printf_format)
182       return false;
183     const size_t n = children.size();
184     const size_t m = rhs.children.size();
185     for (size_t i = 0; i < std::min<size_t>(n, m); ++i) {
186       if (!(children[i] == rhs.children[i]))
187         return false;
188     }
189     if (children != rhs.children)
190       return false;
191     if (type != rhs.type)
192       return false;
193     if (fmt != rhs.fmt)
194       return false;
195     if (deref != rhs.deref)
196       return false;
197     return true;
198   }
199 
200   std::string string;
201   std::string printf_format;
202   std::vector<Entry> children;
203   Type type;
204   lldb::Format fmt = lldb::eFormatDefault;
205   lldb::addr_t number = 0;
206   bool deref = false;
207 };
208 
209 bool Format(const Entry &entry, Stream &s, const SymbolContext *sc,
210             const ExecutionContext *exe_ctx, const Address *addr,
211             ValueObject *valobj, bool function_changed, bool initial_function);
212 
213 bool FormatStringRef(const llvm::StringRef &format, Stream &s,
214                      const SymbolContext *sc, const ExecutionContext *exe_ctx,
215                      const Address *addr, ValueObject *valobj,
216                      bool function_changed, bool initial_function);
217 
218 bool FormatCString(const char *format, Stream &s, const SymbolContext *sc,
219                    const ExecutionContext *exe_ctx, const Address *addr,
220                    ValueObject *valobj, bool function_changed,
221                    bool initial_function);
222 
223 Status Parse(const llvm::StringRef &format, Entry &entry);
224 
225 Status ExtractVariableInfo(llvm::StringRef &format_str,
226                            llvm::StringRef &variable_name,
227                            llvm::StringRef &variable_format);
228 
229 void AutoComplete(lldb_private::CompletionRequest &request);
230 
231 // Format the current elements into the stream \a s.
232 //
233 // The root element will be stripped off and the format str passed in will be
234 // either an empty string (print a description of this object), or contain a
235 // `.`-separated series like a domain name that identifies further
236 //  sub-elements to display.
237 bool FormatFileSpec(const FileSpec &file, Stream &s, llvm::StringRef elements,
238                     llvm::StringRef element_format);
239 
240 /// For each variable in 'args' this function writes the variable
241 /// name and it's pretty-printed value representation to 'out_stream'
242 /// in following format:
243 ///
244 /// \verbatim
245 /// name_1=repr_1, name_2=repr_2 ...
246 /// \endverbatim
247 void PrettyPrintFunctionArguments(Stream &out_stream, VariableList const &args,
248                                   ExecutionContextScope *exe_scope);
249 } // namespace FormatEntity
250 } // namespace lldb_private
251 
252 #endif // LLDB_CORE_FORMATENTITY_H
253