17#include "llvm/ADT/StringExtras.h"
22using namespace llvm::dwarf;
24static std::optional<BinaryOpNode::OpType>
26 if (token.size() != 1)
39static std::optional<UnaryOpNode::OpType>
47 llvm::BumpPtrAllocator &alloc) {
48 llvm::SmallVector<Node *, 4> stack;
50 llvm::StringRef token;
51 while (std::tie(token, expr) = getToken(expr), !token.empty()) {
57 Node *right = stack.pop_back_val();
58 Node *left = stack.pop_back_val();
68 Node *operand = stack.pop_back_val();
74 if (to_integer(token, value, 10)) {
83 if (stack.size() != 1)
89std::vector<std::pair<llvm::StringRef, Node *>>
91 llvm::SmallVector<llvm::StringRef, 4> exprs;
92 prog.split(exprs,
'=');
93 if (exprs.empty() || !exprs.back().trim().empty())
97 std::vector<std::pair<llvm::StringRef, Node *>> result;
98 for (llvm::StringRef expr : exprs) {
100 std::tie(lhs, expr) = getToken(expr);
104 result.emplace_back(lhs, rhs);
110class SymbolResolver :
public Visitor<bool> {
112 SymbolResolver(llvm::function_ref<
Node *(
SymbolNode &symbol)> replacer)
113 : m_replacer(replacer) {}
119 return Dispatch(binary.
Left()) && Dispatch(binary.
Right());
122 bool Visit(InitialValueNode &, Node *&)
override {
return true; }
123 bool Visit(IntegerNode &, Node *&)
override {
return true; }
124 bool Visit(RegisterNode &, Node *&)
override {
return true; }
126 bool Visit(SymbolNode &symbol, Node *&ref)
override {
127 if (Node *replacement = m_replacer(symbol)) {
129 if (replacement != &symbol)
130 return Dispatch(ref);
136 bool Visit(UnaryOpNode &unary, Node *&)
override {
137 return Dispatch(unary.
Operand());
140 llvm::function_ref<Node *(SymbolNode &symbol)> m_replacer;
143class DWARFCodegen :
public Visitor<> {
145 DWARFCodegen(Stream &stream) : m_out_stream(stream) {}
147 using Visitor<>::Dispatch;
150 void Visit(BinaryOpNode &binary, Node *&)
override;
152 void Visit(InitialValueNode &val, Node *&)
override;
154 void Visit(IntegerNode &
integer, Node *&)
override {
155 m_out_stream.PutHex8(DW_OP_consts);
156 m_out_stream.PutSLEB128(
integer.GetValue());
160 void Visit(RegisterNode ®, Node *&)
override;
162 void Visit(SymbolNode &symbol, Node *&)
override {
163 llvm_unreachable(
"Symbols should have been resolved by now!");
166 void Visit(UnaryOpNode &unary, Node *&)
override;
168 Stream &m_out_stream;
177 size_t m_stack_depth = 1;
182 Dispatch(binary.
Left());
183 Dispatch(binary.
Right());
187 m_out_stream.
PutHex8(DW_OP_plus);
192 m_out_stream.
PutHex8(DW_OP_minus);
198 m_out_stream.
PutHex8(DW_OP_lit1);
199 m_out_stream.
PutHex8(DW_OP_minus);
200 m_out_stream.
PutHex8(DW_OP_not);
202 m_out_stream.
PutHex8(DW_OP_and);
208void DWARFCodegen::Visit(InitialValueNode &, Node *&) {
211 assert(m_stack_depth >= 1);
212 m_out_stream.
PutHex8(DW_OP_pick);
213 m_out_stream.
PutHex8(m_stack_depth - 1);
217void DWARFCodegen::Visit(RegisterNode ®, Node *&) {
222 m_out_stream.
PutHex8(DW_OP_bregx);
225 m_out_stream.
PutHex8(DW_OP_breg0 + reg_num);
231void DWARFCodegen::Visit(UnaryOpNode &unary, Node *&) {
236 m_out_stream.
PutHex8(DW_OP_deref);
243 Node *&node, llvm::function_ref<Node *(SymbolNode &)> replacer) {
244 return SymbolResolver(replacer).Dispatch(node);
249 DWARFCodegen(stream).Dispatch(ptr);
static std::optional< UnaryOpNode::OpType > GetUnaryOpType(llvm::StringRef token)
static std::optional< BinaryOpNode::OpType > GetBinaryOpType(llvm::StringRef token)
A stream class that can stream formatted output to a file.
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
size_t PutULEB128(uint64_t uval)
Output a ULEB128 number to the stream.
size_t PutSLEB128(int64_t uval)
Output a SLEB128 number to the stream.
A node representing a binary expression.
const Node * Right() const
const Node * Left() const
The base class for all nodes in the parsed postfix tree.
uint32_t GetRegNum() const
A node representing a symbolic reference to a named entity.
const Node * Operand() const
A template class implementing a visitor pattern, but with a couple of twists:
#define LLDB_INVALID_REGNUM
Node * ParseOneExpression(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc)
Parse the given postfix expression.
void ToDWARF(Node &node, Stream &stream)
Serialize the given expression tree as DWARF.
bool ResolveSymbols(Node *&node, llvm::function_ref< Node *(SymbolNode &symbol)> replacer)
A utility function for "resolving" SymbolNodes.
T * MakeNode(llvm::BumpPtrAllocator &alloc, Args &&... args)
std::vector< std::pair< llvm::StringRef, Node * > > ParseFPOProgram(llvm::StringRef prog, llvm::BumpPtrAllocator &alloc)
A class that represents a running process on the host machine.