[Lldb-commits] [lldb] r369894 - Postfix: move more code out of the PDB plugin

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Aug 26 04:44:14 PDT 2019


Author: labath
Date: Mon Aug 26 04:44:14 2019
New Revision: 369894

URL: http://llvm.org/viewvc/llvm-project?rev=369894&view=rev
Log:
Postfix: move more code out of the PDB plugin

Summary:
Previously we moved the code which parses a single expression out of the PDB
plugin, because that was useful for DWARF expressions in breakpad. However, FPO
programs are used in breakpad files too (when unwinding on windows), so this
completes the job, and moves the rest of the FPO parser too.

Reviewers: amccarth, aleksandr.urakov

Subscribers: aprantl, markmentovai, rnk, lldb-commits

Differential Revision: https://reviews.llvm.org/D66634

Modified:
    lldb/trunk/include/lldb/Symbol/PostfixExpression.h
    lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
    lldb/trunk/source/Symbol/PostfixExpression.cpp
    lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp

Modified: lldb/trunk/include/lldb/Symbol/PostfixExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/PostfixExpression.h?rev=369894&r1=369893&r2=369894&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/PostfixExpression.h (original)
+++ lldb/trunk/include/lldb/Symbol/PostfixExpression.h Mon Aug 26 04:44:14 2019
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include <vector>
 
 namespace lldb_private {
 
@@ -211,7 +212,10 @@ inline T *MakeNode(llvm::BumpPtrAllocato
 
 /// Parse the given postfix expression. The parsed nodes are placed into the
 /// provided allocator.
-Node *Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc);
+Node *ParseOneExpression(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc);
+
+std::vector<std::pair<llvm::StringRef, Node *>>
+ParseFPOProgram(llvm::StringRef prog, 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. If the expression

Modified: lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp?rev=369894&r1=369893&r2=369894&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp Mon Aug 26 04:44:14 2019
@@ -430,7 +430,7 @@ bool SymbolFileBreakpad::ParseUnwindRow(
   while (auto rule = GetRule(unwind_rules)) {
     node_alloc.Reset();
     llvm::StringRef lhs = rule->first;
-    postfix::Node *rhs = postfix::Parse(rule->second, node_alloc);
+    postfix::Node *rhs = postfix::ParseOneExpression(rule->second, node_alloc);
     if (!rhs) {
       LLDB_LOG(log, "Could not parse `{0}` as unwind rhs.", rule->second);
       return false;

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp?rev=369894&r1=369893&r2=369894&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp Mon Aug 26 04:44:14 2019
@@ -51,54 +51,23 @@ static uint32_t ResolveLLDBRegisterNum(l
   return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
 }
 
-static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
-                                            llvm::BumpPtrAllocator &alloc,
-                                            llvm::StringRef &register_name,
-                                            Node *&ast) {
-  // lvalue of assignment is always first token
-  // rvalue program goes next
-  std::tie(register_name, program) = getToken(program);
-  if (register_name.empty())
-    return false;
-
-  ast = Parse(program, alloc);
-  return ast != nullptr;
-}
-
-static Node *ParseFPOProgram(llvm::StringRef program,
+static Node *ResolveFPOProgram(llvm::StringRef program,
                              llvm::StringRef register_name,
                              llvm::Triple::ArchType arch_type,
                              llvm::BumpPtrAllocator &alloc) {
-  llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;
-
-  size_t cur = 0;
-  while (true) {
-    size_t assign_index = program.find('=', cur);
-    if (assign_index == llvm::StringRef::npos) {
-      llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
-      if (!tail.trim().empty()) {
-        // missing assign operator
-        return nullptr;
-      }
-      break;
-    }
-    llvm::StringRef assignment_program = program.slice(cur, assign_index);
-
-    llvm::StringRef lvalue_name;
-    Node *rvalue_ast = nullptr;
-    if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
-                                         rvalue_ast)) {
-      return nullptr;
-    }
-
-    lldbassert(rvalue_ast);
+  std::vector<std::pair<llvm::StringRef, Node *>> parsed =
+      postfix::ParseFPOProgram(program, alloc);
 
+  for (auto it = parsed.begin(), end = parsed.end(); it != end; ++it) {
     // Emplace valid dependent subtrees to make target assignment independent
     // from predecessors. Resolve all other SymbolNodes as registers.
     bool success =
-        ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
-          if (Node *node = dependent_programs.lookup(symbol.GetName()))
-            return node;
+        ResolveSymbols(it->second, [&](SymbolNode &symbol) -> Node * {
+          for (const auto &pair : llvm::make_range(parsed.begin(), it)) {
+            if (pair.first == symbol.GetName())
+              return pair.second;
+          }
+
           uint32_t reg_num =
               ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);
 
@@ -110,13 +79,10 @@ static Node *ParseFPOProgram(llvm::Strin
     if (!success)
       return nullptr;
 
-    if (lvalue_name == register_name) {
+    if (it->first == register_name) {
       // found target assignment program - no need to parse further
-      return rvalue_ast;
+      return it->second;
     }
-
-    dependent_programs[lvalue_name] = rvalue_ast;
-    cur = assign_index + 1;
   }
 
   return nullptr;
@@ -127,7 +93,7 @@ bool lldb_private::npdb::TranslateFPOPro
     llvm::Triple::ArchType arch_type, Stream &stream) {
   llvm::BumpPtrAllocator node_alloc;
   Node *target_program =
-      ParseFPOProgram(program, register_name, arch_type, node_alloc);
+      ResolveFPOProgram(program, register_name, arch_type, node_alloc);
   if (target_program == nullptr) {
     return false;
   }

Modified: lldb/trunk/source/Symbol/PostfixExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/PostfixExpression.cpp?rev=369894&r1=369893&r2=369894&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/PostfixExpression.cpp (original)
+++ lldb/trunk/source/Symbol/PostfixExpression.cpp Mon Aug 26 04:44:14 2019
@@ -41,7 +41,8 @@ GetUnaryOpType(llvm::StringRef token) {
   return llvm::None;
 }
 
-Node *postfix::Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc) {
+Node *postfix::ParseOneExpression(llvm::StringRef expr,
+                                  llvm::BumpPtrAllocator &alloc) {
   llvm::SmallVector<Node *, 4> stack;
 
   llvm::StringRef token;
@@ -83,6 +84,26 @@ Node *postfix::Parse(llvm::StringRef exp
   return stack.back();
 }
 
+std::vector<std::pair<llvm::StringRef, Node *>>
+postfix::ParseFPOProgram(llvm::StringRef prog, llvm::BumpPtrAllocator &alloc) {
+  llvm::SmallVector<llvm::StringRef, 4> exprs;
+  prog.split(exprs, '=');
+  if (exprs.empty() || !exprs.back().trim().empty())
+    return {};
+  exprs.pop_back();
+
+  std::vector<std::pair<llvm::StringRef, Node *>> result;
+  for (llvm::StringRef expr : exprs) {
+    llvm::StringRef lhs;
+    std::tie(lhs, expr) = getToken(expr);
+    Node *rhs = ParseOneExpression(expr, alloc);
+    if (!rhs)
+      return {};
+    result.emplace_back(lhs, rhs);
+  }
+  return result;
+}
+
 namespace {
 class SymbolResolver : public Visitor<bool> {
 public:

Modified: lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp?rev=369894&r1=369893&r2=369894&view=diff
==============================================================================
--- lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp (original)
+++ lldb/trunk/unittests/Symbol/PostfixExpressionTest.cpp Mon Aug 26 04:44:14 2019
@@ -12,6 +12,7 @@
 #include "lldb/Utility/StreamString.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/raw_ostream.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 using namespace lldb_private;
@@ -71,40 +72,68 @@ public:
   }
 };
 
-static std::string ParseAndStringify(llvm::StringRef expr) {
+static std::string ParseOneAndStringify(llvm::StringRef expr) {
   llvm::BumpPtrAllocator alloc;
-  return ASTPrinter::Print(Parse(expr, alloc));
+  return ASTPrinter::Print(ParseOneExpression(expr, alloc));
 }
 
-TEST(PostfixExpression, Parse) {
-  EXPECT_EQ("int(47)", ParseAndStringify("47"));
-  EXPECT_EQ("$foo", ParseAndStringify("$foo"));
-  EXPECT_EQ("+(int(1), int(2))", ParseAndStringify("1 2 +"));
-  EXPECT_EQ("-(int(1), int(2))", ParseAndStringify("1 2 -"));
-  EXPECT_EQ("@(int(1), int(2))", ParseAndStringify("1 2 @"));
-  EXPECT_EQ("+(int(1), +(int(2), int(3)))", ParseAndStringify("1 2 3 + +"));
-  EXPECT_EQ("+(+(int(1), int(2)), int(3))", ParseAndStringify("1 2 + 3 +"));
-  EXPECT_EQ("^(int(1))", ParseAndStringify("1 ^"));
-  EXPECT_EQ("^(^(int(1)))", ParseAndStringify("1 ^ ^"));
-  EXPECT_EQ("^(+(int(1), ^(int(2))))", ParseAndStringify("1 2 ^ + ^"));
-  EXPECT_EQ("-($foo, int(47))", ParseAndStringify("$foo 47 -"));
-  EXPECT_EQ("+(int(47), int(-42))", ParseAndStringify("47 -42 +"));
-
-  EXPECT_EQ("nullptr", ParseAndStringify("+"));
-  EXPECT_EQ("nullptr", ParseAndStringify("^"));
-  EXPECT_EQ("nullptr", ParseAndStringify("1 +"));
-  EXPECT_EQ("nullptr", ParseAndStringify("1 2 ^"));
-  EXPECT_EQ("nullptr", ParseAndStringify("1 2 3 +"));
-  EXPECT_EQ("nullptr", ParseAndStringify("^ 1"));
-  EXPECT_EQ("nullptr", ParseAndStringify("+ 1 2"));
-  EXPECT_EQ("nullptr", ParseAndStringify("1 + 2"));
-  EXPECT_EQ("nullptr", ParseAndStringify("1 2"));
-  EXPECT_EQ("nullptr", ParseAndStringify(""));
+TEST(PostfixExpression, ParseOneExpression) {
+  EXPECT_EQ("int(47)", ParseOneAndStringify("47"));
+  EXPECT_EQ("$foo", ParseOneAndStringify("$foo"));
+  EXPECT_EQ("+(int(1), int(2))", ParseOneAndStringify("1 2 +"));
+  EXPECT_EQ("-(int(1), int(2))", ParseOneAndStringify("1 2 -"));
+  EXPECT_EQ("@(int(1), int(2))", ParseOneAndStringify("1 2 @"));
+  EXPECT_EQ("+(int(1), +(int(2), int(3)))", ParseOneAndStringify("1 2 3 + +"));
+  EXPECT_EQ("+(+(int(1), int(2)), int(3))", ParseOneAndStringify("1 2 + 3 +"));
+  EXPECT_EQ("^(int(1))", ParseOneAndStringify("1 ^"));
+  EXPECT_EQ("^(^(int(1)))", ParseOneAndStringify("1 ^ ^"));
+  EXPECT_EQ("^(+(int(1), ^(int(2))))", ParseOneAndStringify("1 2 ^ + ^"));
+  EXPECT_EQ("-($foo, int(47))", ParseOneAndStringify("$foo 47 -"));
+  EXPECT_EQ("+(int(47), int(-42))", ParseOneAndStringify("47 -42 +"));
+
+  EXPECT_EQ("nullptr", ParseOneAndStringify("+"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("^"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("1 +"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("1 2 ^"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("1 2 3 +"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("^ 1"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("+ 1 2"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("1 + 2"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify("1 2"));
+  EXPECT_EQ("nullptr", ParseOneAndStringify(""));
+}
+
+static std::vector<std::pair<std::string, std::string>>
+ParseFPOAndStringify(llvm::StringRef prog) {
+  llvm::BumpPtrAllocator alloc;
+  std::vector<std::pair<llvm::StringRef, Node *>> parsed =
+      ParseFPOProgram(prog, alloc);
+  auto range = llvm::map_range(
+      parsed, [](const std::pair<llvm::StringRef, Node *> &pair) {
+        return std::make_pair(pair.first, ASTPrinter::Print(pair.second));
+      });
+  return std::vector<std::pair<std::string, std::string>>(range.begin(),
+                                                          range.end());
+}
+
+TEST(PostfixExpression, ParseFPOProgram) {
+  EXPECT_THAT(ParseFPOAndStringify("a 1 ="),
+              testing::ElementsAre(std::make_pair("a", "int(1)")));
+  EXPECT_THAT(ParseFPOAndStringify("a 1 = b 2 3 + ="),
+              testing::ElementsAre(std::make_pair("a", "int(1)"),
+                                   std::make_pair("b", "+(int(2), int(3))")));
+
+  EXPECT_THAT(ParseFPOAndStringify(""), testing::IsEmpty());
+  EXPECT_THAT(ParseFPOAndStringify("="), testing::IsEmpty());
+  EXPECT_THAT(ParseFPOAndStringify("a 1"), testing::IsEmpty());
+  EXPECT_THAT(ParseFPOAndStringify("a 1 = ="), testing::IsEmpty());
+  EXPECT_THAT(ParseFPOAndStringify("a 1 + ="), testing::IsEmpty());
+  EXPECT_THAT(ParseFPOAndStringify("= a 1 ="), testing::IsEmpty());
 }
 
 static std::string ParseAndGenerateDWARF(llvm::StringRef expr) {
   llvm::BumpPtrAllocator alloc;
-  Node *ast = Parse(expr, alloc);
+  Node *ast = ParseOneExpression(expr, alloc);
   if (!ast)
     return "Parse failed.";
   if (!ResolveSymbols(ast, [&](SymbolNode &symbol) -> Node * {




More information about the lldb-commits mailing list