labath updated this revision to Diff 194705.
labath added a comment.

After trying to use this in new code, I realized that the CRTP is not really
needed for what I am trying to achieve here. The same can be achieved through
more standard virtual functions.

This updates the patch to use virtual functions, which may be 0.01% slower, but
that certainly does not matter here. I also rename the function arguments from
"node" to more descriptive names.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60410/new/

https://reviews.llvm.org/D60410

Files:
  source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp

Index: source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
===================================================================
--- source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
+++ source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
@@ -25,12 +25,11 @@
 
 namespace {
 
-class FPOProgramNode;
-class FPOProgramASTVisitor;
-
 class NodeAllocator {
 public:
   template <typename T, typename... Args> T *makeNode(Args &&... args) {
+    static_assert(std::is_trivially_destructible<T>::value,
+                  "This object will not be destroyed!");
     void *new_node_mem = m_alloc.Allocate(sizeof(T), alignof(T));
     return new (new_node_mem) T(std::forward<Args>(args)...);
   }
@@ -53,9 +52,6 @@
   FPOProgramNode(Kind kind) : m_token_kind(kind) {}
 
 public:
-  virtual ~FPOProgramNode() = default;
-  virtual void Accept(FPOProgramASTVisitor &visitor) = 0;
-
   Kind GetKind() const { return m_token_kind; }
 
 private:
@@ -67,8 +63,6 @@
   FPOProgramNodeSymbol(llvm::StringRef name)
       : FPOProgramNode(Symbol), m_name(name) {}
 
-  void Accept(FPOProgramASTVisitor &visitor) override;
-
   llvm::StringRef GetName() const { return m_name; }
 
   static bool classof(const FPOProgramNode *node) {
@@ -84,8 +78,6 @@
   FPOProgramNodeRegisterRef(uint32_t lldb_reg_num)
       : FPOProgramNode(Register), m_lldb_reg_num(lldb_reg_num) {}
 
-  void Accept(FPOProgramASTVisitor &visitor) override;
-
   uint32_t GetLLDBRegNum() const { return m_lldb_reg_num; }
 
   static bool classof(const FPOProgramNode *node) {
@@ -101,8 +93,6 @@
   FPOProgramNodeIntegerLiteral(uint32_t value)
       : FPOProgramNode(IntegerLiteral), m_value(value) {}
 
-  void Accept(FPOProgramASTVisitor &visitor) override;
-
   uint32_t GetValue() const { return m_value; }
 
   static bool classof(const FPOProgramNode *node) {
@@ -126,8 +116,6 @@
       : FPOProgramNode(BinaryOp), m_op_type(op_type), m_left(&left),
         m_right(&right) {}
 
-  void Accept(FPOProgramASTVisitor &visitor) override;
-
   OpType GetOpType() const { return m_op_type; }
 
   const FPOProgramNode *Left() const { return m_left; }
@@ -155,8 +143,6 @@
   FPOProgramNodeUnaryOp(OpType op_type, FPOProgramNode &operand)
       : FPOProgramNode(UnaryOp), m_op_type(op_type), m_operand(&operand) {}
 
-  void Accept(FPOProgramASTVisitor &visitor) override;
-
   OpType GetOpType() const { return m_op_type; }
 
   const FPOProgramNode *Operand() const { return m_operand; }
@@ -171,84 +157,108 @@
   FPOProgramNode *m_operand;
 };
 
+template <typename ResultT = void>
 class FPOProgramASTVisitor {
-public:
-  virtual ~FPOProgramASTVisitor() = default;
+protected:
+  virtual ResultT Visit(FPOProgramNodeBinaryOp &binary,
+                        FPOProgramNode *&ref) = 0;
+  virtual ResultT Visit(FPOProgramNodeUnaryOp &unary, FPOProgramNode *&ref) = 0;
+  virtual ResultT Visit(FPOProgramNodeRegisterRef &reg, FPOProgramNode *&) = 0;
+  virtual ResultT Visit(FPOProgramNodeIntegerLiteral &integer,
+                        FPOProgramNode *&) = 0;
+  virtual ResultT Visit(FPOProgramNodeSymbol &symbol, FPOProgramNode *&ref) = 0;
+
+  ResultT Dispatch(FPOProgramNode *&node) {
+    switch (node->GetKind()) {
+    case FPOProgramNode::Register:
+      return Visit(llvm::cast<FPOProgramNodeRegisterRef>(*node), node);
+    case FPOProgramNode::Symbol:
+      return Visit(llvm::cast<FPOProgramNodeSymbol>(*node), node);
+
+    case FPOProgramNode::IntegerLiteral:
+      return Visit(llvm::cast<FPOProgramNodeIntegerLiteral>(*node), node);
+    case FPOProgramNode::UnaryOp:
+      return Visit(llvm::cast<FPOProgramNodeUnaryOp>(*node), node);
+    case FPOProgramNode::BinaryOp:
+      return Visit(llvm::cast<FPOProgramNodeBinaryOp>(*node), node);
+    }
+    llvm_unreachable("Fully covered switch!");
+  }
 
-  virtual void Visit(FPOProgramNodeSymbol &node) {}
-  virtual void Visit(FPOProgramNodeRegisterRef &node) {}
-  virtual void Visit(FPOProgramNodeIntegerLiteral &node) {}
-  virtual void Visit(FPOProgramNodeBinaryOp &node) {}
-  virtual void Visit(FPOProgramNodeUnaryOp &node) {}
 };
 
-void FPOProgramNodeSymbol::Accept(FPOProgramASTVisitor &visitor) {
-  visitor.Visit(*this);
-}
-
-void FPOProgramNodeRegisterRef::Accept(FPOProgramASTVisitor &visitor) {
-  visitor.Visit(*this);
-}
+class FPOProgramASTVisitorMergeDependent : public FPOProgramASTVisitor<> {
+public:
+  void Visit(FPOProgramNodeBinaryOp &binary, FPOProgramNode *&) override {
+    Dispatch(binary.Left());
+    Dispatch(binary.Right());
+  }
 
-void FPOProgramNodeIntegerLiteral::Accept(FPOProgramASTVisitor &visitor) {
-  visitor.Visit(*this);
-}
+  void Visit(FPOProgramNodeUnaryOp &unary, FPOProgramNode *&) override {
+    Dispatch(unary.Operand());
+  }
 
-void FPOProgramNodeBinaryOp::Accept(FPOProgramASTVisitor &visitor) {
-  visitor.Visit(*this);
-}
+  void Visit(FPOProgramNodeRegisterRef &, FPOProgramNode *&) override {}
+  void Visit(FPOProgramNodeIntegerLiteral &, FPOProgramNode *&) override {}
+  void Visit(FPOProgramNodeSymbol &symbol, FPOProgramNode *&ref) override;
 
-void FPOProgramNodeUnaryOp::Accept(FPOProgramASTVisitor &visitor) {
-  visitor.Visit(*this);
-}
+  static void Merge(const llvm::DenseMap<llvm::StringRef, FPOProgramNode *>
+                        &dependent_programs,
+                    FPOProgramNode *&ast) {
+    FPOProgramASTVisitorMergeDependent(dependent_programs).Dispatch(ast);
+  }
 
-class FPOProgramASTVisitorMergeDependent : public FPOProgramASTVisitor {
-public:
+private:
   FPOProgramASTVisitorMergeDependent(
       const llvm::DenseMap<llvm::StringRef, FPOProgramNode *>
           &dependent_programs)
       : m_dependent_programs(dependent_programs) {}
 
-  void Merge(FPOProgramNode *&node_ref);
-
-private:
-  void Visit(FPOProgramNodeBinaryOp &node) override;
-  void Visit(FPOProgramNodeUnaryOp &node) override;
-
-  void TryReplace(FPOProgramNode *&node_ref) const;
-
-private:
   const llvm::DenseMap<llvm::StringRef, FPOProgramNode *> &m_dependent_programs;
 };
 
-void FPOProgramASTVisitorMergeDependent::Merge(FPOProgramNode *&node_ref) {
-  TryReplace(node_ref);
-  node_ref->Accept(*this);
-}
+void FPOProgramASTVisitorMergeDependent::Visit(FPOProgramNodeSymbol &symbol,
+                                               FPOProgramNode *&ref) {
 
-void FPOProgramASTVisitorMergeDependent::Visit(FPOProgramNodeBinaryOp &node) {
-  Merge(node.Left());
-  Merge(node.Right());
-}
-void FPOProgramASTVisitorMergeDependent::Visit(FPOProgramNodeUnaryOp &node) {
-  Merge(node.Operand());
+  auto it = m_dependent_programs.find(symbol.GetName());
+  if (it == m_dependent_programs.end())
+    return;
+
+  ref = it->second;
+  Dispatch(ref);
 }
 
-void FPOProgramASTVisitorMergeDependent::TryReplace(
-    FPOProgramNode *&node_ref) const {
+class FPOProgramASTVisitorResolveRegisterRefs
+    : public FPOProgramASTVisitor<bool> {
+public:
+  static bool Resolve(const llvm::DenseMap<llvm::StringRef, FPOProgramNode *>
+                          &dependent_programs,
+                      llvm::Triple::ArchType arch_type, NodeAllocator &alloc,
+                      FPOProgramNode *&ast) {
+    return FPOProgramASTVisitorResolveRegisterRefs(dependent_programs,
+                                                   arch_type, alloc)
+        .Dispatch(ast);
+  }
 
-  while (auto *symbol = llvm::dyn_cast<FPOProgramNodeSymbol>(node_ref)) {
-    auto it = m_dependent_programs.find(symbol->GetName());
-    if (it == m_dependent_programs.end()) {
-      break;
-    }
+  bool Visit(FPOProgramNodeBinaryOp &binary, FPOProgramNode *&) override {
+    return Dispatch(binary.Left()) && Dispatch(binary.Right());
+  }
 
-    node_ref = it->second;
+  bool Visit(FPOProgramNodeUnaryOp &unary, FPOProgramNode *&) override {
+    return Dispatch(unary.Operand());
   }
-}
 
-class FPOProgramASTVisitorResolveRegisterRefs : public FPOProgramASTVisitor {
-public:
+  bool Visit(FPOProgramNodeRegisterRef &, FPOProgramNode *&) override {
+    return true;
+  }
+
+  bool Visit(FPOProgramNodeIntegerLiteral &, FPOProgramNode *&) override {
+    return true;
+  }
+
+  bool Visit(FPOProgramNodeSymbol &symbol, FPOProgramNode *&ref) override;
+
+private:
   FPOProgramASTVisitorResolveRegisterRefs(
       const llvm::DenseMap<llvm::StringRef, FPOProgramNode *>
           &dependent_programs,
@@ -256,27 +266,11 @@
       : m_dependent_programs(dependent_programs), m_arch_type(arch_type),
         m_alloc(alloc) {}
 
-  bool Resolve(FPOProgramNode *&program);
-
-private:
-  void Visit(FPOProgramNodeBinaryOp &node) override;
-  void Visit(FPOProgramNodeUnaryOp &node) override;
-
-  bool TryReplace(FPOProgramNode *&node_ref);
-
   const llvm::DenseMap<llvm::StringRef, FPOProgramNode *> &m_dependent_programs;
   llvm::Triple::ArchType m_arch_type;
   NodeAllocator &m_alloc;
-  bool m_no_error_flag = true;
 };
 
-bool FPOProgramASTVisitorResolveRegisterRefs::Resolve(FPOProgramNode *&program) {
-  if (!TryReplace(program))
-    return false;
-  program->Accept(*this);
-  return m_no_error_flag;
-}
-
 static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) {
   // lookup register name to get lldb register number
   llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names =
@@ -294,62 +288,49 @@
   return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
 }
 
-bool FPOProgramASTVisitorResolveRegisterRefs::TryReplace(
-    FPOProgramNode *&node_ref) {
-  auto *symbol = llvm::dyn_cast<FPOProgramNodeSymbol>(node_ref);
-  if (!symbol)
-    return true;
-
+bool FPOProgramASTVisitorResolveRegisterRefs::Visit(
+    FPOProgramNodeSymbol &symbol, FPOProgramNode *&ref) {
   // Look up register reference as lvalue in preceding assignments.
-  auto it = m_dependent_programs.find(symbol->GetName());
+  auto it = m_dependent_programs.find(symbol.GetName());
   if (it != m_dependent_programs.end()) {
     // Dependent programs are handled elsewhere.
     return true;
   }
 
   uint32_t reg_num =
-      ResolveLLDBRegisterNum(symbol->GetName().drop_front(1), m_arch_type);
+      ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), m_arch_type);
 
   if (reg_num == LLDB_INVALID_REGNUM)
     return false;
 
-  node_ref = m_alloc.makeNode<FPOProgramNodeRegisterRef>(reg_num);
+  ref = m_alloc.makeNode<FPOProgramNodeRegisterRef>(reg_num);
   return true;
 }
 
-void FPOProgramASTVisitorResolveRegisterRefs::Visit(
-    FPOProgramNodeBinaryOp &node) {
-  m_no_error_flag = Resolve(node.Left()) && Resolve(node.Right());
-}
-
-void FPOProgramASTVisitorResolveRegisterRefs::Visit(
-    FPOProgramNodeUnaryOp &node) {
-  m_no_error_flag = Resolve(node.Operand());
-}
-
-class FPOProgramASTVisitorDWARFCodegen : public FPOProgramASTVisitor {
+class FPOProgramASTVisitorDWARFCodegen : public FPOProgramASTVisitor<> {
 public:
-  FPOProgramASTVisitorDWARFCodegen(Stream &stream) : m_out_stream(stream) {}
+  static void Emit(Stream &stream, FPOProgramNode *&ast) {
+    FPOProgramASTVisitorDWARFCodegen(stream).Dispatch(ast);
+  }
 
-  void Emit(FPOProgramNode &program);
+  void Visit(FPOProgramNodeRegisterRef &reg, FPOProgramNode *&);
+  void Visit(FPOProgramNodeBinaryOp &binary, FPOProgramNode *&);
+  void Visit(FPOProgramNodeUnaryOp &unary, FPOProgramNode *&);
+  void Visit(FPOProgramNodeSymbol &symbol, FPOProgramNode *&) {
+    llvm_unreachable("Symbols should have been resolved by now!");
+  }
+  void Visit(FPOProgramNodeIntegerLiteral &integer, FPOProgramNode *&);
 
 private:
-  void Visit(FPOProgramNodeRegisterRef &node) override;
-  void Visit(FPOProgramNodeIntegerLiteral &node) override;
-  void Visit(FPOProgramNodeBinaryOp &node) override;
-  void Visit(FPOProgramNodeUnaryOp &node) override;
+  FPOProgramASTVisitorDWARFCodegen(Stream &stream) : m_out_stream(stream) {}
 
-private:
   Stream &m_out_stream;
 };
 
-void FPOProgramASTVisitorDWARFCodegen::Emit(FPOProgramNode &program) {
-  program.Accept(*this);
-}
-
-void FPOProgramASTVisitorDWARFCodegen::Visit(FPOProgramNodeRegisterRef &node) {
+void FPOProgramASTVisitorDWARFCodegen::Visit(FPOProgramNodeRegisterRef &reg,
+                                             FPOProgramNode *&) {
 
-  uint32_t reg_num = node.GetLLDBRegNum();
+  uint32_t reg_num = reg.GetLLDBRegNum();
   lldbassert(reg_num != LLDB_INVALID_REGNUM);
 
   if (reg_num > 31) {
@@ -362,18 +343,18 @@
 }
 
 void FPOProgramASTVisitorDWARFCodegen::Visit(
-    FPOProgramNodeIntegerLiteral &node) {
-  uint32_t value = node.GetValue();
+    FPOProgramNodeIntegerLiteral &integer, FPOProgramNode *&) {
+  uint32_t value = integer.GetValue();
   m_out_stream.PutHex8(DW_OP_constu);
   m_out_stream.PutULEB128(value);
 }
 
-void FPOProgramASTVisitorDWARFCodegen::Visit(FPOProgramNodeBinaryOp &node) {
+void FPOProgramASTVisitorDWARFCodegen::Visit(FPOProgramNodeBinaryOp &binary,
+                                             FPOProgramNode *&) {
+  Dispatch(binary.Left());
+  Dispatch(binary.Right());
 
-  Emit(*node.Left());
-  Emit(*node.Right());
-
-  switch (node.GetOpType()) {
+  switch (binary.GetOpType()) {
   case FPOProgramNodeBinaryOp::Plus:
     m_out_stream.PutHex8(DW_OP_plus);
     // NOTE: can be optimized by using DW_OP_plus_uconst opcpode
@@ -395,10 +376,11 @@
   }
 }
 
-void FPOProgramASTVisitorDWARFCodegen::Visit(FPOProgramNodeUnaryOp &node) {
-  Emit(*node.Operand());
+void FPOProgramASTVisitorDWARFCodegen::Visit(FPOProgramNodeUnaryOp &unary,
+                                             FPOProgramNode *&) {
+  Dispatch(unary.Operand());
 
-  switch (node.GetOpType()) {
+  switch (unary.GetOpType()) {
   case FPOProgramNodeUnaryOp::Deref:
     m_out_stream.PutHex8(DW_OP_deref);
     break;
@@ -523,19 +505,16 @@
     lldbassert(rvalue_ast);
 
     // check & resolve assignment program
-    FPOProgramASTVisitorResolveRegisterRefs resolver(dependent_programs,
-                                                     arch_type, alloc);
-    if (!resolver.Resolve(rvalue_ast)) {
+    if (!FPOProgramASTVisitorResolveRegisterRefs::Resolve(
+            dependent_programs, arch_type, alloc, rvalue_ast))
       return nullptr;
-    }
 
     if (lvalue_name == register_name) {
       // found target assignment program - no need to parse further
 
       // emplace valid dependent subtrees to make target assignment independent
       // from predecessors
-      FPOProgramASTVisitorMergeDependent merger(dependent_programs);
-      merger.Merge(rvalue_ast);
+      FPOProgramASTVisitorMergeDependent::Merge(dependent_programs, rvalue_ast);
 
       return rvalue_ast;
     }
@@ -557,7 +536,6 @@
     return false;
   }
 
-  FPOProgramASTVisitorDWARFCodegen codegen(stream);
-  codegen.Emit(*target_program);
+  FPOProgramASTVisitorDWARFCodegen::Emit(stream, target_program);
   return true;
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to