LLDB mainline
FormatEntity.h
Go to the documentation of this file.
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
13#include "lldb/lldb-types.h"
14#include "llvm/ADT/ScopeExit.h"
15#include "llvm/ADT/SmallVector.h"
16#include <algorithm>
17#include <cstddef>
18#include <cstdint>
19#include <string>
20#include <vector>
21
22namespace lldb_private {
23class Address;
26class FileSpec;
27class Status;
28class Stream;
29class StringList;
30class SymbolContext;
31class ValueObject;
32}
33
34namespace llvm {
35class StringRef;
36}
37
38namespace lldb_private {
39namespace FormatEntity {
40struct Entry {
41 enum class Type {
121 };
122
123 struct Definition {
124 /// The name/string placeholder that corresponds to this definition.
125 const char *name;
126 /// Insert this exact string into the output
127 const char *string = nullptr;
128 /// Entry::Type corresponding to this definition.
130 /// Data that is returned as the value of the format string.
131 const uint64_t data = 0;
132 /// The number of children of this node in the tree of format strings.
133 const uint32_t num_children = 0;
134 /// An array of "num_children" Definition entries.
135 const Definition *children = nullptr;
136 /// Whether the separator is kept during parsing or not. It's used
137 /// for entries with parameters.
138 const bool keep_separator = false;
139
140 constexpr Definition(const char *name, const FormatEntity::Entry::Type t)
141 : name(name), type(t) {}
142
143 constexpr Definition(const char *name, const char *string)
145
146 constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
147 const uint64_t data)
148 : name(name), type(t), data(data) {}
149
150 constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
151 const uint64_t num_children,
152 const Definition *children,
153 const bool keep_separator = false)
156 };
157
158 template <size_t N>
159 static constexpr Definition
161 const Definition (&children)[N],
162 bool keep_separator = false) {
163 return Definition(name, t, N, children, keep_separator);
164 }
165
166 Entry(Type t = Type::Invalid, const char *s = nullptr,
167 const char *f = nullptr);
168 Entry(llvm::StringRef s);
169 Entry(char ch);
170
171 void AppendChar(char ch);
172
173 void AppendText(const llvm::StringRef &s);
174
175 void AppendText(const char *cstr);
176
177 void AppendEntry(const Entry &&entry);
178
179 void StartAlternative();
180
181 void Clear() {
182 string.clear();
183 printf_format.clear();
184 children_stack.clear();
185 children_stack.emplace_back();
188 number = 0;
189 level = 0;
190 deref = false;
191 }
192
193 static const char *TypeToCString(Type t);
194
195 void Dump(Stream &s, int depth = 0) const;
196
197 bool operator==(const Entry &rhs) const {
198 if (string != rhs.string)
199 return false;
200 if (printf_format != rhs.printf_format)
201 return false;
203 return false;
204 if (type != rhs.type)
205 return false;
206 if (fmt != rhs.fmt)
207 return false;
208 if (deref != rhs.deref)
209 return false;
210 return true;
211 }
212
213 operator bool() const { return type != Type::Invalid; }
214
215 std::vector<Entry> &GetChildren();
216
217 std::string string;
218 std::string printf_format;
219
220 /// A stack of children entries, used by Scope entries to provide alterantive
221 /// children. All other entries have a stack of size 1.
222 /// @{
223 llvm::SmallVector<std::vector<Entry>, 1> children_stack;
224 size_t level = 0;
225 /// @}
226
230 bool deref = false;
231};
232
234public:
235 Formatter(const SymbolContext *sc, const ExecutionContext *exe_ctx,
236 const Address *addr, bool function_changed, bool initial_function)
237 : m_sc(sc), m_exe_ctx(exe_ctx), m_addr(addr),
238 m_function_changed(function_changed),
239 m_initial_function(initial_function) {}
240
241 bool Format(const Entry &entry, Stream &s, ValueObject *valobj = nullptr);
242
243 bool FormatStringRef(const llvm::StringRef &format, Stream &s,
244 ValueObject *valobj);
245
246private:
247 bool DumpValue(Stream &s, const FormatEntity::Entry &entry,
248 ValueObject *valobj);
249
251
252 /// Returns \c true if \a Format has been called for an \a Entry
253 /// with the specified \c type recusrively. Some types are permitted
254 /// to be formatted recursively, in which case this function returns
255 /// \c false.
257
258 /// While the returned \a llvm::scope_exit is alive, the specified \c type
259 /// is tracked by this \c Formatter object for recursion. Once the returned
260 /// scope guard is destructed, the entry stops being tracked.
262 m_entry_type_stack.push_back(type);
263 return llvm::scope_exit([this] {
264 assert(!m_entry_type_stack.empty());
265 m_entry_type_stack.pop_back();
266 });
267 }
268
269 const SymbolContext *const m_sc = nullptr;
270 const ExecutionContext *const m_exe_ctx = nullptr;
271 const Address *const m_addr = nullptr;
272 const bool m_function_changed = false;
273 const bool m_initial_function = false;
274
275 llvm::SmallVector<Entry::Type, 1> m_entry_type_stack;
276};
277
278Status Parse(const llvm::StringRef &format, Entry &entry);
279
280Status ExtractVariableInfo(llvm::StringRef &format_str,
281 llvm::StringRef &variable_name,
282 llvm::StringRef &variable_format);
283
285
286// Format the current elements into the stream \a s.
287//
288// The root element will be stripped off and the format str passed in will be
289// either an empty string (print a description of this object), or contain a
290// `.`-separated series like a domain name that identifies further
291// sub-elements to display.
292bool FormatFileSpec(const FileSpec &file, Stream &s, llvm::StringRef elements,
293 llvm::StringRef element_format);
294
295/// For each variable in 'args' this function writes the variable
296/// name and it's pretty-printed value representation to 'out_stream'
297/// in following format:
298///
299/// \verbatim
300/// name_1=repr_1, name_2=repr_2 ...
301/// \endverbatim
302void PrettyPrintFunctionArguments(Stream &out_stream, VariableList const &args,
303 ExecutionContextScope *exe_scope);
304} // namespace FormatEntity
305} // namespace lldb_private
306
307#endif // LLDB_CORE_FORMATENTITY_H
lldb_private::FormatEntity::Entry::Definition Definition
FormatEntity::Entry Entry
A section + offset based address class.
Definition Address.h:62
"lldb/Utility/ArgCompletionRequest.h"
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition FileSpec.h:57
const SymbolContext *const m_sc
auto PushEntryType(Entry::Type type)
While the returned llvm::scope_exit is alive, the specified type is tracked by this Formatter object ...
const ExecutionContext *const m_exe_ctx
llvm::SmallVector< Entry::Type, 1 > m_entry_type_stack
Formatter(const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, bool function_changed, bool initial_function)
bool Format(const Entry &entry, Stream &s, ValueObject *valobj=nullptr)
bool FormatStringRef(const llvm::StringRef &format, Stream &s, ValueObject *valobj)
bool IsInvalidRecursiveFormat(Entry::Type type)
Returns true if Format has been called for an Entry with the specified type recusrively.
bool DumpValue(Stream &s, const FormatEntity::Entry &entry, ValueObject *valobj)
An error handling class.
Definition Status.h:118
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Defines a symbol context baton that can be handed other debug core functions.
bool FormatFileSpec(const FileSpec &file, Stream &s, llvm::StringRef elements, llvm::StringRef element_format)
Status Parse(const llvm::StringRef &format, Entry &entry)
Status ExtractVariableInfo(llvm::StringRef &format_str, llvm::StringRef &variable_name, llvm::StringRef &variable_format)
void PrettyPrintFunctionArguments(Stream &out_stream, VariableList const &args, ExecutionContextScope *exe_scope)
For each variable in 'args' this function writes the variable name and it's pretty-printed value repr...
void AutoComplete(lldb_private::CompletionRequest &request)
A class that represents a running process on the host machine.
Format
Display format definitions.
uint64_t addr_t
Definition lldb-types.h:80
const char * name
The name/string placeholder that corresponds to this definition.
constexpr Definition(const char *name, const FormatEntity::Entry::Type t, const uint64_t data)
const Definition * children
An array of "num_children" Definition entries.
constexpr Definition(const char *name, const FormatEntity::Entry::Type t, const uint64_t num_children, const Definition *children, const bool keep_separator=false)
const bool keep_separator
Whether the separator is kept during parsing or not.
const char * string
Insert this exact string into the output.
const uint64_t data
Data that is returned as the value of the format string.
constexpr Definition(const char *name, const FormatEntity::Entry::Type t)
const uint32_t num_children
The number of children of this node in the tree of format strings.
const Entry::Type type
Entry::Type corresponding to this definition.
constexpr Definition(const char *name, const char *string)
void Dump(Stream &s, int depth=0) const
Entry(Type t=Type::Invalid, const char *s=nullptr, const char *f=nullptr)
void AppendText(const llvm::StringRef &s)
static constexpr Definition DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t, const Definition(&children)[N], bool keep_separator=false)
llvm::SmallVector< std::vector< Entry >, 1 > children_stack
A stack of children entries, used by Scope entries to provide alterantive children.
bool operator==(const Entry &rhs) const
std::vector< Entry > & GetChildren()
static const char * TypeToCString(Type t)
void AppendEntry(const Entry &&entry)