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/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 24 namespace lldb_private { 25 class Address; 26 class ExecutionContext; 27 class Stream; 28 class StringList; 29 class SymbolContext; 30 class ValueObject; 31 } 32 namespace llvm { 33 class StringRef; 34 } 35 36 namespace lldb_private { 37 class FormatEntity { 38 public: 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 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 const char *name; 107 const char *string; // Insert this exact string into the output 108 Entry::Type type; 109 uint64_t data; 110 uint32_t num_children; 111 Definition *children; // An array of "num_children" Definition entries, 112 bool keep_separator; 113 }; 114 115 Entry(Type t = Type::Invalid, const char *s = nullptr, 116 const char *f = nullptr) 117 : string(s ? s : ""), printf_format(f ? f : ""), children(), 118 definition(nullptr), type(t), fmt(lldb::eFormatDefault), number(0), 119 deref(false) {} 120 121 Entry(llvm::StringRef s); 122 Entry(char ch); 123 124 void AppendChar(char ch); 125 126 void AppendText(const llvm::StringRef &s); 127 128 void AppendText(const char *cstr); 129 AppendEntryEntry130 void AppendEntry(const Entry &&entry) { children.push_back(entry); } 131 ClearEntry132 void Clear() { 133 string.clear(); 134 printf_format.clear(); 135 children.clear(); 136 definition = nullptr; 137 type = Type::Invalid; 138 fmt = lldb::eFormatDefault; 139 number = 0; 140 deref = false; 141 } 142 143 static const char *TypeToCString(Type t); 144 145 void Dump(Stream &s, int depth = 0) const; 146 147 bool operator==(const Entry &rhs) const { 148 if (string != rhs.string) 149 return false; 150 if (printf_format != rhs.printf_format) 151 return false; 152 const size_t n = children.size(); 153 const size_t m = rhs.children.size(); 154 for (size_t i = 0; i < std::min<size_t>(n, m); ++i) { 155 if (!(children[i] == rhs.children[i])) 156 return false; 157 } 158 if (children != rhs.children) 159 return false; 160 if (definition != rhs.definition) 161 return false; 162 if (type != rhs.type) 163 return false; 164 if (fmt != rhs.fmt) 165 return false; 166 if (deref != rhs.deref) 167 return false; 168 return true; 169 } 170 171 std::string string; 172 std::string printf_format; 173 std::vector<Entry> children; 174 Definition *definition; 175 Type type; 176 lldb::Format fmt; 177 lldb::addr_t number; 178 bool deref; 179 }; 180 181 static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, 182 const ExecutionContext *exe_ctx, const Address *addr, 183 ValueObject *valobj, bool function_changed, 184 bool initial_function); 185 186 static bool FormatStringRef(const llvm::StringRef &format, Stream &s, 187 const SymbolContext *sc, 188 const ExecutionContext *exe_ctx, 189 const Address *addr, ValueObject *valobj, 190 bool function_changed, bool initial_function); 191 192 static bool FormatCString(const char *format, Stream &s, 193 const SymbolContext *sc, 194 const ExecutionContext *exe_ctx, 195 const Address *addr, ValueObject *valobj, 196 bool function_changed, bool initial_function); 197 198 static Status Parse(const llvm::StringRef &format, Entry &entry); 199 200 static Status ExtractVariableInfo(llvm::StringRef &format_str, 201 llvm::StringRef &variable_name, 202 llvm::StringRef &variable_format); 203 204 static void AutoComplete(lldb_private::CompletionRequest &request); 205 206 // Format the current elements into the stream \a s. 207 // 208 // The root element will be stripped off and the format str passed in will be 209 // either an empty string (print a description of this object), or contain a 210 // `.`-separated series like a domain name that identifies further 211 // sub-elements to display. 212 static bool FormatFileSpec(const FileSpec &file, Stream &s, 213 llvm::StringRef elements, 214 llvm::StringRef element_format); 215 216 protected: 217 static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry, 218 uint32_t depth); 219 }; 220 } // namespace lldb_private 221 222 #endif // LLDB_CORE_FORMATENTITY_H 223