labath updated this revision to Diff 197086.
labath added a comment.
s/CFA/InitialValue/
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D61183/new/
https://reviews.llvm.org/D61183
Files:
include/lldb/Symbol/PostfixExpression.h
source/Symbol/PostfixExpression.cpp
unittests/Symbol/PostfixExpressionTest.cpp
Index: unittests/Symbol/PostfixExpressionTest.cpp
===================================================================
--- unittests/Symbol/PostfixExpressionTest.cpp
+++ unittests/Symbol/PostfixExpressionTest.cpp
@@ -44,6 +44,8 @@
Dispatch(binary.Left()), Dispatch(binary.Right()));
}
+ std::string Visit(InitialValueNode &, Node *&) override { return "InitialValue"; }
+
std::string Visit(IntegerNode &integer, Node *&) override {
return llvm::formatv("int({0})", integer.GetValue());
}
@@ -105,6 +107,9 @@
if (!ast)
return "Parse failed.";
if (!ResolveSymbols(ast, [&](SymbolNode &symbol) -> Node * {
+ if (symbol.GetName() == "INIT")
+ return MakeNode<InitialValueNode>(alloc);
+
uint32_t num;
if (to_integer(symbol.GetName().drop_front(), num))
return MakeNode<RegisterNode>(alloc, num);
@@ -138,6 +143,17 @@
EXPECT_EQ("DW_OP_bregx 65 0", ParseAndGenerateDWARF("R65"));
+ EXPECT_EQ("DW_OP_pick 0x00", ParseAndGenerateDWARF("INIT"));
+
+ EXPECT_EQ("DW_OP_pick 0x00, DW_OP_pick 0x01, DW_OP_plus ",
+ ParseAndGenerateDWARF("INIT INIT +"));
+
+ EXPECT_EQ("DW_OP_breg1 +0, DW_OP_pick 0x01, DW_OP_plus ",
+ ParseAndGenerateDWARF("R1 INIT +"));
+
+ EXPECT_EQ("DW_OP_constu 0x1, DW_OP_pick 0x01, DW_OP_deref , DW_OP_plus ",
+ ParseAndGenerateDWARF("1 INIT ^ +"));
+
EXPECT_EQ("DW_OP_constu 0x4, DW_OP_constu 0x5, DW_OP_plus ",
ParseAndGenerateDWARF("4 5 +"));
Index: source/Symbol/PostfixExpression.cpp
===================================================================
--- source/Symbol/PostfixExpression.cpp
+++ source/Symbol/PostfixExpression.cpp
@@ -96,8 +96,9 @@
return Dispatch(binary.Left()) && Dispatch(binary.Right());
}
- bool Visit(IntegerNode &integer, Node *&) override { return true; }
- bool Visit(RegisterNode ®, Node *&) override { return true; }
+ bool Visit(InitialValueNode &, Node *&) override { return true; }
+ bool Visit(IntegerNode &, Node *&) override { return true; }
+ bool Visit(RegisterNode &, Node *&) override { return true; }
bool Visit(SymbolNode &symbol, Node *&ref) override {
if (Node *replacement = m_replacer(symbol)) {
@@ -125,9 +126,12 @@
private:
void Visit(BinaryOpNode &binary, Node *&);
+ void Visit(InitialValueNode &val, Node *&);
+
void Visit(IntegerNode &integer, Node *&) {
m_out_stream.PutHex8(DW_OP_constu);
m_out_stream.PutULEB128(integer.GetValue());
+ ++m_stack_depth;
}
void Visit(RegisterNode ®, Node *&);
@@ -139,6 +143,14 @@
void Visit(UnaryOpNode &unary, Node *&);
Stream &m_out_stream;
+
+ /// The number keeping track of the evaluation stack depth at any given
+ /// moment. Used for implementing InitialValueNodes. If we have
+ /// InitialValueNodes in our input expression, we assume the initial stack
+ /// will contain their value (hence we start with m_stack_depth = 1). If we
+ /// don't have InitialValueNodes, this value is not used, and so its starting
+ /// value does not matter.
+ size_t m_stack_depth = 1;
};
} // namespace
@@ -166,6 +178,16 @@
m_out_stream.PutHex8(DW_OP_and);
break;
}
+ --m_stack_depth; // Two pops, one push.
+}
+
+void DWARFCodegen::Visit(InitialValueNode &, Node *&) {
+ // We never go below the initial stack, so we can pick the initial value from
+ // the bottom of the stack at any moment.
+ assert(m_stack_depth >= 1);
+ m_out_stream.PutHex8(DW_OP_pick);
+ m_out_stream.PutHex8(m_stack_depth - 1);
+ ++m_stack_depth;
}
void DWARFCodegen::Visit(RegisterNode ®, Node *&) {
@@ -179,6 +201,7 @@
m_out_stream.PutHex8(DW_OP_breg0 + reg_num);
m_out_stream.PutSLEB128(0);
+ ++m_stack_depth;
}
void DWARFCodegen::Visit(UnaryOpNode &unary, Node *&) {
@@ -189,6 +212,7 @@
m_out_stream.PutHex8(DW_OP_deref);
break;
}
+ // Stack depth unchanged.
}
bool postfix::ResolveSymbols(
Index: include/lldb/Symbol/PostfixExpression.h
===================================================================
--- include/lldb/Symbol/PostfixExpression.h
+++ include/lldb/Symbol/PostfixExpression.h
@@ -29,6 +29,7 @@
public:
enum Kind {
BinaryOp,
+ InitialValue,
Integer,
Register,
Symbol,
@@ -73,6 +74,16 @@
Node *m_right;
};
+/// A node representing the canonical frame address.
+class InitialValueNode: public Node {
+public:
+ InitialValueNode() : Node(InitialValue) {}
+
+ static bool classof(const Node *node) {
+ return node->GetKind() == InitialValue;
+ }
+};
+
/// A node representing an integer literal.
class IntegerNode : public Node {
public:
@@ -153,6 +164,7 @@
virtual ~Visitor() = default;
virtual ResultT Visit(BinaryOpNode &binary, Node *&ref) = 0;
+ virtual ResultT Visit(InitialValueNode &val, Node *&ref) = 0;
virtual ResultT Visit(IntegerNode &integer, Node *&) = 0;
virtual ResultT Visit(RegisterNode ®, Node *&) = 0;
virtual ResultT Visit(SymbolNode &symbol, Node *&ref) = 0;
@@ -164,6 +176,8 @@
switch (node->GetKind()) {
case Node::BinaryOp:
return Visit(llvm::cast<BinaryOpNode>(*node), node);
+ case Node::InitialValue:
+ return Visit(llvm::cast<InitialValueNode>(*node), node);
case Node::Integer:
return Visit(llvm::cast<IntegerNode>(*node), node);
case Node::Register:
@@ -200,7 +214,10 @@
Node *Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc);
/// Serialize the given expression tree as DWARF. The result is written into the
-/// given stream. The AST should not contain any SymbolNodes.
+/// given stream. The AST should not contain any SymbolNodes. If the expression
+/// contains InitialValueNodes, the generated expression will assume that their
+/// value will be provided as the top value of the initial evaluation stack (as
+/// is the case with the CFA value in register eh_unwind rules).
void ToDWARF(Node &node, Stream &stream);
} // namespace postfix
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits