1 //===-- FormatEntity.h ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_FormatEntity_h_ 11 #define liblldb_FormatEntity_h_ 12 13 #include "lldb/Utility/CompletionRequest.h" 14 #include "lldb/Utility/FileSpec.h" 15 #include "lldb/Utility/Status.h" 16 #include "lldb/lldb-enumerations.h" 17 #include "lldb/lldb-types.h" 18 #include <algorithm> 19 #include <stddef.h> 20 #include <stdint.h> 21 22 #include <string> 23 #include <vector> 24 25 namespace lldb_private { 26 class Address; 27 } 28 namespace lldb_private { 29 class ExecutionContext; 30 } 31 namespace lldb_private { 32 class Stream; 33 } 34 namespace lldb_private { 35 class StringList; 36 } 37 namespace lldb_private { 38 class SymbolContext; 39 } 40 namespace lldb_private { 41 class ValueObject; 42 } 43 namespace llvm { 44 class StringRef; 45 } 46 47 namespace lldb_private { 48 class FormatEntity { 49 public: 50 struct Entry { 51 enum class Type { 52 Invalid, 53 ParentNumber, 54 ParentString, 55 InsertString, 56 Root, 57 String, 58 Scope, 59 Variable, 60 VariableSynthetic, 61 ScriptVariable, 62 ScriptVariableSynthetic, 63 AddressLoad, 64 AddressFile, 65 AddressLoadOrFile, 66 ProcessID, 67 ProcessFile, 68 ScriptProcess, 69 ThreadID, 70 ThreadProtocolID, 71 ThreadIndexID, 72 ThreadName, 73 ThreadQueue, 74 ThreadStopReason, 75 ThreadReturnValue, 76 ThreadCompletedExpression, 77 ScriptThread, 78 ThreadInfo, 79 TargetArch, 80 ScriptTarget, 81 ModuleFile, 82 File, 83 Lang, 84 FrameIndex, 85 FrameNoDebug, 86 FrameRegisterPC, 87 FrameRegisterSP, 88 FrameRegisterFP, 89 FrameRegisterFlags, 90 FrameRegisterByName, 91 FrameIsArtificial, 92 ScriptFrame, 93 FunctionID, 94 FunctionDidChange, 95 FunctionInitialFunction, 96 FunctionName, 97 FunctionNameWithArgs, 98 FunctionNameNoArgs, 99 FunctionAddrOffset, 100 FunctionAddrOffsetConcrete, 101 FunctionLineOffset, 102 FunctionPCOffset, 103 FunctionInitial, 104 FunctionChanged, 105 FunctionIsOptimized, 106 LineEntryFile, 107 LineEntryLineNumber, 108 LineEntryColumn, 109 LineEntryStartAddress, 110 LineEntryEndAddress, 111 CurrentPCArrow 112 }; 113 114 enum FormatType { None, UInt32, UInt64, CString }; 115 116 struct Definition { 117 const char *name; 118 const char *string; // Insert this exact string into the output 119 Entry::Type type; 120 FormatType format_type; // uint32_t, uint64_t, cstr, or anything that can 121 // be formatted by printf or lldb::Format 122 uint64_t data; 123 uint32_t num_children; 124 Definition *children; // An array of "num_children" Definition entries, 125 bool keep_separator; 126 }; 127 128 Entry(Type t = Type::Invalid, const char *s = nullptr, 129 const char *f = nullptr) 130 : string(s ? s : ""), printf_format(f ? f : ""), children(), 131 definition(nullptr), type(t), fmt(lldb::eFormatDefault), number(0), 132 deref(false) {} 133 134 Entry(llvm::StringRef s); 135 Entry(char ch); 136 137 void AppendChar(char ch); 138 139 void AppendText(const llvm::StringRef &s); 140 141 void AppendText(const char *cstr); 142 AppendEntryEntry143 void AppendEntry(const Entry &&entry) { children.push_back(entry); } 144 ClearEntry145 void Clear() { 146 string.clear(); 147 printf_format.clear(); 148 children.clear(); 149 definition = nullptr; 150 type = Type::Invalid; 151 fmt = lldb::eFormatDefault; 152 number = 0; 153 deref = false; 154 } 155 156 static const char *TypeToCString(Type t); 157 158 void Dump(Stream &s, int depth = 0) const; 159 160 bool operator==(const Entry &rhs) const { 161 if (string != rhs.string) 162 return false; 163 if (printf_format != rhs.printf_format) 164 return false; 165 const size_t n = children.size(); 166 const size_t m = rhs.children.size(); 167 for (size_t i = 0; i < std::min<size_t>(n, m); ++i) { 168 if (!(children[i] == rhs.children[i])) 169 return false; 170 } 171 if (children != rhs.children) 172 return false; 173 if (definition != rhs.definition) 174 return false; 175 if (type != rhs.type) 176 return false; 177 if (fmt != rhs.fmt) 178 return false; 179 if (deref != rhs.deref) 180 return false; 181 return true; 182 } 183 184 std::string string; 185 std::string printf_format; 186 std::vector<Entry> children; 187 Definition *definition; 188 Type type; 189 lldb::Format fmt; 190 lldb::addr_t number; 191 bool deref; 192 }; 193 194 static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, 195 const ExecutionContext *exe_ctx, const Address *addr, 196 ValueObject *valobj, bool function_changed, 197 bool initial_function); 198 199 static bool FormatStringRef(const llvm::StringRef &format, Stream &s, 200 const SymbolContext *sc, 201 const ExecutionContext *exe_ctx, 202 const Address *addr, ValueObject *valobj, 203 bool function_changed, bool initial_function); 204 205 static bool FormatCString(const char *format, Stream &s, 206 const SymbolContext *sc, 207 const ExecutionContext *exe_ctx, 208 const Address *addr, ValueObject *valobj, 209 bool function_changed, bool initial_function); 210 211 static Status Parse(const llvm::StringRef &format, Entry &entry); 212 213 static Status ExtractVariableInfo(llvm::StringRef &format_str, 214 llvm::StringRef &variable_name, 215 llvm::StringRef &variable_format); 216 217 static size_t AutoComplete(lldb_private::CompletionRequest &request); 218 219 //---------------------------------------------------------------------- 220 // Format the current elements into the stream \a s. 221 // 222 // The root element will be stripped off and the format str passed in will be 223 // either an empty string (print a description of this object), or contain a 224 // `.`-separated series like a domain name that identifies further 225 // sub-elements to display. 226 //---------------------------------------------------------------------- 227 static bool FormatFileSpec(const FileSpec &file, Stream &s, 228 llvm::StringRef elements, 229 llvm::StringRef element_format); 230 231 protected: 232 static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry, 233 uint32_t depth); 234 }; 235 } // namespace lldb_private 236 237 #endif // liblldb_FormatEntity_h_ 238