Index: source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp =================================================================== --- source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp +++ source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -27,9 +27,21 @@ class FPOProgramNode; class FPOProgramASTVisitor; +class NodeAllocator { +public: + template T *makeNode(Args &&... args) { + void *new_node_mem = m_alloc.Allocate(sizeof(T), alignof(T)); + return new (new_node_mem) T(std::forward(args)...); + } + +private: + llvm::BumpPtrAllocator m_alloc; +}; + class FPOProgramNode { public: enum Kind { + Symbol, Register, IntegerLiteral, BinaryOp, @@ -49,46 +61,31 @@ Kind m_token_kind; }; -class FPOProgramNodeRegisterRef : public FPOProgramNode { +class FPOProgramNodeSymbol: public FPOProgramNode { public: - FPOProgramNodeRegisterRef(llvm::StringRef name) - : FPOProgramNode(Register), m_name(name) {} + FPOProgramNodeSymbol(llvm::StringRef name) + : FPOProgramNode(Symbol), m_name(name) {} void Accept(FPOProgramASTVisitor *visitor) override; llvm::StringRef GetName() const { return m_name; } - uint32_t GetLLDBRegNum() const { return m_lldb_reg_num; } - - bool ResolveLLDBRegisterNum(llvm::Triple::ArchType arch_type); private: llvm::StringRef m_name; - uint32_t m_lldb_reg_num = LLDB_INVALID_REGNUM; }; -bool FPOProgramNodeRegisterRef::ResolveLLDBRegisterNum( - llvm::Triple::ArchType arch_type) { - - llvm::StringRef reg_name = m_name.slice(1, m_name.size()); - - // lookup register name to get lldb register number - llvm::ArrayRef> register_names = - llvm::codeview::getRegisterNames(); - auto it = llvm::find_if( - register_names, - [®_name](const llvm::EnumEntry ®ister_entry) { - return reg_name.compare_lower(register_entry.Name) == 0; - }); +class FPOProgramNodeRegisterRef : public FPOProgramNode { +public: + FPOProgramNodeRegisterRef(uint32_t lldb_reg_num) + : FPOProgramNode(Register), m_lldb_reg_num(lldb_reg_num) {} - if (it == register_names.end()) { - return false; - } + void Accept(FPOProgramASTVisitor *visitor) override; - auto reg_id = static_cast(it->Value); - m_lldb_reg_num = npdb::GetLLDBRegisterNumber(arch_type, reg_id); + uint32_t GetLLDBRegNum() const { return m_lldb_reg_num; } - return m_lldb_reg_num != LLDB_INVALID_REGNUM; -} +private: + uint32_t m_lldb_reg_num; +}; class FPOProgramNodeIntegerLiteral : public FPOProgramNode { public: @@ -157,12 +154,17 @@ public: virtual ~FPOProgramASTVisitor() = default; + 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); } @@ -216,11 +218,10 @@ void FPOProgramASTVisitorMergeDependent::TryReplace( FPOProgramNode *&node_ref) const { - while (node_ref->GetKind() == FPOProgramNode::Register) { - auto *node_register_ref = - static_cast(node_ref); + while (node_ref->GetKind() == FPOProgramNode::Symbol) { + auto *node_symbol_ref = static_cast(node_ref); - auto it = m_dependent_programs.find(node_register_ref->GetName()); + auto it = m_dependent_programs.find(node_symbol_ref->GetName()); if (it == m_dependent_programs.end()) { break; } @@ -234,39 +235,70 @@ FPOProgramASTVisitorResolveRegisterRefs( const llvm::DenseMap &dependent_programs, - llvm::Triple::ArchType arch_type) - : m_dependent_programs(dependent_programs), m_arch_type(arch_type) {} + llvm::Triple::ArchType arch_type, NodeAllocator &alloc) + : m_dependent_programs(dependent_programs), m_arch_type(arch_type), + m_alloc(alloc) {} - bool Resolve(FPOProgramNode *program); + bool Resolve(FPOProgramNode *&program); private: - void Visit(FPOProgramNodeRegisterRef *node) override; - void Visit(FPOProgramNodeIntegerLiteral *node) override {} void Visit(FPOProgramNodeBinaryOp *node) override; void Visit(FPOProgramNodeUnaryOp *node) override; -private: + bool TryReplace(FPOProgramNode *&node_ref); + const llvm::DenseMap &m_dependent_programs; llvm::Triple::ArchType m_arch_type; + NodeAllocator &m_alloc; bool m_no_error_flag = true; }; -bool FPOProgramASTVisitorResolveRegisterRefs::Resolve(FPOProgramNode *program) { +bool FPOProgramASTVisitorResolveRegisterRefs::Resolve(FPOProgramNode *&program) { + if (!TryReplace(program)) + return false; program->Accept(this); return m_no_error_flag; } -void FPOProgramASTVisitorResolveRegisterRefs::Visit( - FPOProgramNodeRegisterRef *node) { +static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) { + // lookup register name to get lldb register number + llvm::ArrayRef> register_names = + llvm::codeview::getRegisterNames(); + auto it = llvm::find_if( + register_names, + [®_name](const llvm::EnumEntry ®ister_entry) { + return reg_name.compare_lower(register_entry.Name) == 0; + }); + + if (it == register_names.end()) + return LLDB_INVALID_REGNUM; + + auto reg_id = static_cast(it->Value); + return npdb::GetLLDBRegisterNumber(arch_type, reg_id); +} - // lookup register reference as lvalue in predecedent assignments - auto it = m_dependent_programs.find(node->GetName()); +bool FPOProgramASTVisitorResolveRegisterRefs::TryReplace( + FPOProgramNode *&node_ref) { + if (node_ref->GetKind() != FPOProgramNode::Symbol) + return true; + + auto *symbol = static_cast(node_ref); + + // lookup register reference as lvalue in preceding assignments + auto it = m_dependent_programs.find(symbol->GetName()); if (it != m_dependent_programs.end()) { - // dependent programs are already resolved and valid - return; + // dependent programs are handled elsewhere + return true; } - // try to resolve register reference as lldb register name - m_no_error_flag = node->ResolveLLDBRegisterNum(m_arch_type); + + uint32_t reg_num = + ResolveLLDBRegisterNum(symbol->GetName().drop_front(1), m_arch_type); + + if (reg_num == LLDB_INVALID_REGNUM) + return false; + + node_ref = m_alloc.makeNode(reg_num); + return true; } void FPOProgramASTVisitorResolveRegisterRefs::Visit( @@ -357,17 +389,6 @@ } } -class NodeAllocator { -public: - template T *makeNode(Args &&... args) { - void *new_node_mem = m_alloc.Allocate(sizeof(T), alignof(T)); - return new (new_node_mem) T(std::forward(args)...); - } - -private: - llvm::BumpPtrAllocator m_alloc; -}; - } // namespace static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program, @@ -427,8 +448,7 @@ } if (cur.startswith("$")) { - // token is register ref - eval_stack.push_back(alloc.makeNode(cur)); + eval_stack.push_back(alloc.makeNode(cur)); continue; } @@ -488,7 +508,7 @@ // check & resolve assignment program FPOProgramASTVisitorResolveRegisterRefs resolver(dependent_programs, - arch_type); + arch_type, alloc); if (!resolver.Resolve(rvalue_ast)) { return nullptr; }