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