FormatEntity.h revision 360784
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 liblldb_FormatEntity_h_
10#define liblldb_FormatEntity_h_
11
12#include "lldb/Utility/CompletionRequest.h"
13#include "lldb/Utility/FileSpec.h"
14#include "lldb/Utility/Status.h"
15#include "lldb/lldb-enumerations.h"
16#include "lldb/lldb-types.h"
17#include <algorithm>
18#include <stddef.h>
19#include <stdint.h>
20
21#include <string>
22#include <vector>
23
24namespace lldb_private {
25class Address;
26class ExecutionContext;
27class Stream;
28class StringList;
29class SymbolContext;
30class ValueObject;
31}
32namespace llvm {
33class StringRef;
34}
35
36namespace lldb_private {
37class FormatEntity {
38public:
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      ThreadReturnValue,
65      ThreadCompletedExpression,
66      ScriptThread,
67      ThreadInfo,
68      TargetArch,
69      ScriptTarget,
70      ModuleFile,
71      File,
72      Lang,
73      FrameIndex,
74      FrameNoDebug,
75      FrameRegisterPC,
76      FrameRegisterSP,
77      FrameRegisterFP,
78      FrameRegisterFlags,
79      FrameRegisterByName,
80      FrameIsArtificial,
81      ScriptFrame,
82      FunctionID,
83      FunctionDidChange,
84      FunctionInitialFunction,
85      FunctionName,
86      FunctionNameWithArgs,
87      FunctionNameNoArgs,
88      FunctionMangledName,
89      FunctionAddrOffset,
90      FunctionAddrOffsetConcrete,
91      FunctionLineOffset,
92      FunctionPCOffset,
93      FunctionInitial,
94      FunctionChanged,
95      FunctionIsOptimized,
96      LineEntryFile,
97      LineEntryLineNumber,
98      LineEntryColumn,
99      LineEntryStartAddress,
100      LineEntryEndAddress,
101      CurrentPCArrow
102    };
103
104    struct Definition {
105      const char *name;
106      const char *string; // Insert this exact string into the output
107      Entry::Type type;
108      uint64_t data;
109      uint32_t num_children;
110      Definition *children; // An array of "num_children" Definition entries,
111      bool keep_separator;
112    };
113
114    Entry(Type t = Type::Invalid, const char *s = nullptr,
115          const char *f = nullptr)
116        : string(s ? s : ""), printf_format(f ? f : ""), children(),
117          definition(nullptr), type(t), fmt(lldb::eFormatDefault), number(0),
118          deref(false) {}
119
120    Entry(llvm::StringRef s);
121    Entry(char ch);
122
123    void AppendChar(char ch);
124
125    void AppendText(const llvm::StringRef &s);
126
127    void AppendText(const char *cstr);
128
129    void AppendEntry(const Entry &&entry) { children.push_back(entry); }
130
131    void Clear() {
132      string.clear();
133      printf_format.clear();
134      children.clear();
135      definition = nullptr;
136      type = Type::Invalid;
137      fmt = lldb::eFormatDefault;
138      number = 0;
139      deref = false;
140    }
141
142    static const char *TypeToCString(Type t);
143
144    void Dump(Stream &s, int depth = 0) const;
145
146    bool operator==(const Entry &rhs) const {
147      if (string != rhs.string)
148        return false;
149      if (printf_format != rhs.printf_format)
150        return false;
151      const size_t n = children.size();
152      const size_t m = rhs.children.size();
153      for (size_t i = 0; i < std::min<size_t>(n, m); ++i) {
154        if (!(children[i] == rhs.children[i]))
155          return false;
156      }
157      if (children != rhs.children)
158        return false;
159      if (definition != rhs.definition)
160        return false;
161      if (type != rhs.type)
162        return false;
163      if (fmt != rhs.fmt)
164        return false;
165      if (deref != rhs.deref)
166        return false;
167      return true;
168    }
169
170    std::string string;
171    std::string printf_format;
172    std::vector<Entry> children;
173    Definition *definition;
174    Type type;
175    lldb::Format fmt;
176    lldb::addr_t number;
177    bool deref;
178  };
179
180  static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc,
181                     const ExecutionContext *exe_ctx, const Address *addr,
182                     ValueObject *valobj, bool function_changed,
183                     bool initial_function);
184
185  static bool FormatStringRef(const llvm::StringRef &format, Stream &s,
186                              const SymbolContext *sc,
187                              const ExecutionContext *exe_ctx,
188                              const Address *addr, ValueObject *valobj,
189                              bool function_changed, bool initial_function);
190
191  static bool FormatCString(const char *format, Stream &s,
192                            const SymbolContext *sc,
193                            const ExecutionContext *exe_ctx,
194                            const Address *addr, ValueObject *valobj,
195                            bool function_changed, bool initial_function);
196
197  static Status Parse(const llvm::StringRef &format, Entry &entry);
198
199  static Status ExtractVariableInfo(llvm::StringRef &format_str,
200                                    llvm::StringRef &variable_name,
201                                    llvm::StringRef &variable_format);
202
203  static void AutoComplete(lldb_private::CompletionRequest &request);
204
205  // Format the current elements into the stream \a s.
206  //
207  // The root element will be stripped off and the format str passed in will be
208  // either an empty string (print a description of this object), or contain a
209  // `.`-separated series like a domain name that identifies further
210  //  sub-elements to display.
211  static bool FormatFileSpec(const FileSpec &file, Stream &s,
212                             llvm::StringRef elements,
213                             llvm::StringRef element_format);
214
215protected:
216  static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
217                              uint32_t depth);
218};
219} // namespace lldb_private
220
221#endif // liblldb_FormatEntity_h_
222