This revision was automatically updated to reflect the committed changes.
Closed by commit rL359560: PostfixExpression: Introduce InitialValueNode
(authored by labath, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Changed prior to commit:
https://reviews.llvm.org/D61183?vs=197086&id=197311#toc
Repository:
rL LLVM
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D61183/new/
https://reviews.llvm.org/D61183
Files:
lldb/trunk/include/lldb/Symbol/PostfixExpression.h
lldb/trunk/source/Symbol/PostfixExpression.cpp
lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp
Index: lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp
===================================================================
--- lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp
+++ lldb/trunk/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: lldb/trunk/source/Symbol/PostfixExpression.cpp
===================================================================
--- lldb/trunk/source/Symbol/PostfixExpression.cpp
+++ lldb/trunk/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,15 @@
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. We start with
+ /// m_stack_depth = 1, assuming that the initial value is already on the
+ /// stack. This initial value will be the value of all InitialValueNodes. If
+ /// the expression does not contain InitialValueNodes, then m_stack_depth is
+ /// not used, and the generated expression will run correctly even without an
+ /// initial value.
+ size_t m_stack_depth = 1;
};
} // namespace
@@ -166,6 +179,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 +202,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 +213,7 @@
m_out_stream.PutHex8(DW_OP_deref);
break;
}
+ // Stack depth unchanged.
}
bool postfix::ResolveSymbols(
Index: lldb/trunk/include/lldb/Symbol/PostfixExpression.h
===================================================================
--- lldb/trunk/include/lldb/Symbol/PostfixExpression.h
+++ lldb/trunk/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