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

source code of lldb/include/lldb/Core/FormatEntity.h