17#include "llvm/ADT/StringExtras.h"
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();
59 stack.push_back(MakeNode<BinaryOpNode>(alloc, *op_type, *left, *right));
68 Node *operand = stack.pop_back_val();
69 stack.push_back(MakeNode<UnaryOpNode>(alloc, *op_type, *operand));
74 if (to_integer(token, value, 10)) {
76 stack.push_back(MakeNode<IntegerNode>(alloc, value));
80 stack.push_back(MakeNode<SymbolNode>(alloc, token));
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) {}
127 if (
Node *replacement = m_replacer(symbol)) {
129 if (replacement != &symbol)
143class DWARFCodegen :
public Visitor<> {
145 DWARFCodegen(
Stream &stream) : m_out_stream(stream) {}
155 m_out_stream.PutHex8(DW_OP_consts);
156 m_out_stream.PutSLEB128(
integer.GetValue());
163 llvm_unreachable(
"Symbols should have been resolved by now!");
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);
211 assert(m_stack_depth >= 1);
212 m_out_stream.PutHex8(DW_OP_pick);
213 m_out_stream.PutHex8(m_stack_depth - 1);
222 m_out_stream.PutHex8(DW_OP_bregx);
223 m_out_stream.PutULEB128(reg_num);
225 m_out_stream.PutHex8(DW_OP_breg0 + reg_num);
227 m_out_stream.PutSLEB128(0);
236 m_out_stream.PutHex8(DW_OP_deref);
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.
A node representing a binary expression.
const Node * Right() const
const Node * Left() const
A node representing the canonical frame address.
A node representing an integer literal.
The base class for all nodes in the parsed postfix tree.
A node representing the value of a register with the given register number.
uint32_t GetRegNum() const
A node representing a symbolic reference to a named entity.
A node representing a unary operation.
const Node * Operand() const
A template class implementing a visitor pattern, but with a couple of twists:
virtual ResultT Visit(BinaryOpNode &binary, Node *&ref)=0
ResultT Dispatch(Node *&node)
Invoke the correct Visit function based on the dynamic type of the given node.
#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.
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.