blob: ecae8500df40d6978feffd3aad72bbe11ba46161 [file] [log] [blame]
//===-- FormatEntity.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_CORE_FORMATENTITY_H
#define LLDB_CORE_FORMATENTITY_H
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-types.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>
namespace lldb_private {
class Address;
class CompletionRequest;
class ExecutionContext;
class FileSpec;
class Status;
class Stream;
class StringList;
class SymbolContext;
class ValueObject;
}
namespace llvm {
class StringRef;
}
namespace lldb_private {
class FormatEntity {
public:
struct Entry {
enum class Type {
Invalid,
ParentNumber,
ParentString,
EscapeCode,
Root,
String,
Scope,
Variable,
VariableSynthetic,
ScriptVariable,
ScriptVariableSynthetic,
AddressLoad,
AddressFile,
AddressLoadOrFile,
ProcessID,
ProcessFile,
ScriptProcess,
ThreadID,
ThreadProtocolID,
ThreadIndexID,
ThreadName,
ThreadQueue,
ThreadStopReason,
ThreadStopReasonRaw,
ThreadReturnValue,
ThreadCompletedExpression,
ScriptThread,
ThreadInfo,
TargetArch,
ScriptTarget,
ModuleFile,
File,
Lang,
FrameIndex,
FrameNoDebug,
FrameRegisterPC,
FrameRegisterSP,
FrameRegisterFP,
FrameRegisterFlags,
FrameRegisterByName,
FrameIsArtificial,
ScriptFrame,
FunctionID,
FunctionDidChange,
FunctionInitialFunction,
FunctionName,
FunctionNameWithArgs,
FunctionNameNoArgs,
FunctionMangledName,
FunctionAddrOffset,
FunctionAddrOffsetConcrete,
FunctionLineOffset,
FunctionPCOffset,
FunctionInitial,
FunctionChanged,
FunctionIsOptimized,
LineEntryFile,
LineEntryLineNumber,
LineEntryColumn,
LineEntryStartAddress,
LineEntryEndAddress,
CurrentPCArrow
};
struct Definition {
/// The name/string placeholder that corresponds to this definition.
const char *name;
/// Insert this exact string into the output
const char *string = nullptr;
/// Entry::Type corresponding to this definition.
const Entry::Type type;
/// Data that is returned as the value of the format string.
const uint64_t data = 0;
/// The number of children of this node in the tree of format strings.
const uint32_t num_children = 0;
/// An array of "num_children" Definition entries.
const Definition *children = nullptr;
/// Whether the separator is kept during parsing or not. It's used
/// for entries with parameters.
const bool keep_separator = false;
constexpr Definition(const char *name, const FormatEntity::Entry::Type t)
: name(name), type(t) {}
constexpr Definition(const char *name, const char *string)
: name(name), string(string), type(Entry::Type::EscapeCode) {}
constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
const uint64_t data)
: name(name), type(t), data(data) {}
constexpr Definition(const char *name, const FormatEntity::Entry::Type t,
const uint64_t num_children,
const Definition *children,
const bool keep_separator = false)
: name(name), type(t), num_children(num_children), children(children),
keep_separator(keep_separator) {}
};
template <size_t N>
static constexpr Definition
DefinitionWithChildren(const char *name, const FormatEntity::Entry::Type t,
const Definition (&children)[N],
bool keep_separator = false) {
return Definition(name, t, N, children, keep_separator);
}
Entry(Type t = Type::Invalid, const char *s = nullptr,
const char *f = nullptr)
: string(s ? s : ""), printf_format(f ? f : ""), children(), type(t) {}
Entry(llvm::StringRef s);
Entry(char ch);
void AppendChar(char ch);
void AppendText(const llvm::StringRef &s);
void AppendText(const char *cstr);
void AppendEntry(const Entry &&entry) { children.push_back(entry); }
void Clear() {
string.clear();
printf_format.clear();
children.clear();
type = Type::Invalid;
fmt = lldb::eFormatDefault;
number = 0;
deref = false;
}
static const char *TypeToCString(Type t);
void Dump(Stream &s, int depth = 0) const;
bool operator==(const Entry &rhs) const {
if (string != rhs.string)
return false;
if (printf_format != rhs.printf_format)
return false;
const size_t n = children.size();
const size_t m = rhs.children.size();
for (size_t i = 0; i < std::min<size_t>(n, m); ++i) {
if (!(children[i] == rhs.children[i]))
return false;
}
if (children != rhs.children)
return false;
if (type != rhs.type)
return false;
if (fmt != rhs.fmt)
return false;
if (deref != rhs.deref)
return false;
return true;
}
std::string string;
std::string printf_format;
std::vector<Entry> children;
Type type;
lldb::Format fmt = lldb::eFormatDefault;
lldb::addr_t number = 0;
bool deref = false;
};
static bool Format(const Entry &entry, Stream &s, const SymbolContext *sc,
const ExecutionContext *exe_ctx, const Address *addr,
ValueObject *valobj, bool function_changed,
bool initial_function);
static bool FormatStringRef(const llvm::StringRef &format, Stream &s,
const SymbolContext *sc,
const ExecutionContext *exe_ctx,
const Address *addr, ValueObject *valobj,
bool function_changed, bool initial_function);
static bool FormatCString(const char *format, Stream &s,
const SymbolContext *sc,
const ExecutionContext *exe_ctx,
const Address *addr, ValueObject *valobj,
bool function_changed, bool initial_function);
static Status Parse(const llvm::StringRef &format, Entry &entry);
static Status ExtractVariableInfo(llvm::StringRef &format_str,
llvm::StringRef &variable_name,
llvm::StringRef &variable_format);
static void AutoComplete(lldb_private::CompletionRequest &request);
// Format the current elements into the stream \a s.
//
// The root element will be stripped off and the format str passed in will be
// either an empty string (print a description of this object), or contain a
// `.`-separated series like a domain name that identifies further
// sub-elements to display.
static bool FormatFileSpec(const FileSpec &file, Stream &s,
llvm::StringRef elements,
llvm::StringRef element_format);
protected:
static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
uint32_t depth);
};
} // namespace lldb_private
#endif // LLDB_CORE_FORMATENTITY_H