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 &reg, 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 &reg, 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 &reg, 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 &reg, 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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to