1 //===-- DILAST.h ------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_VALUEOBJECT_DILAST_H 10 #define LLDB_VALUEOBJECT_DILAST_H 11 12 #include "lldb/ValueObject/ValueObject.h" 13 #include "llvm/Support/Error.h" 14 #include <cstdint> 15 #include <string> 16 17 namespace lldb_private::dil { 18 19 /// The various types DIL AST nodes (used by the DIL parser). 20 enum class NodeKind { 21 eArraySubscriptNode, 22 eBitExtractionNode, 23 eErrorNode, 24 eIdentifierNode, 25 eMemberOfNode, 26 eUnaryOpNode, 27 }; 28 29 /// The Unary operators recognized by DIL. 30 enum class UnaryOpKind { 31 AddrOf, // "&" 32 Deref, // "*" 33 }; 34 35 /// Forward declaration, for use in DIL AST nodes. Definition is at the very 36 /// end of this file. 37 class Visitor; 38 39 /// The rest of the classes in this file, except for the Visitor class at the 40 /// very end, define all the types of AST nodes used by the DIL parser and 41 /// expression evaluator. The DIL parser parses the input string and creates 42 /// the AST parse tree from the AST nodes. The resulting AST node tree gets 43 /// passed to the DIL expression evaluator, which evaluates the DIL AST nodes 44 /// and creates/returns a ValueObjectSP containing the result. 45 46 /// Base class for AST nodes used by the Data Inspection Language (DIL) parser. 47 /// All of the specialized types of AST nodes inherit from this (virtual) base 48 /// class. 49 class ASTNode { 50 public: ASTNode(uint32_t location,NodeKind kind)51 ASTNode(uint32_t location, NodeKind kind) 52 : m_location(location), m_kind(kind) {} 53 virtual ~ASTNode() = default; 54 55 virtual llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const = 0; 56 GetLocation()57 uint32_t GetLocation() const { return m_location; } GetKind()58 NodeKind GetKind() const { return m_kind; } 59 60 private: 61 uint32_t m_location; 62 const NodeKind m_kind; 63 }; 64 65 using ASTNodeUP = std::unique_ptr<ASTNode>; 66 67 class ErrorNode : public ASTNode { 68 public: ErrorNode()69 ErrorNode() : ASTNode(0, NodeKind::eErrorNode) {} 70 llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override; 71 classof(const ASTNode * node)72 static bool classof(const ASTNode *node) { 73 return node->GetKind() == NodeKind::eErrorNode; 74 } 75 }; 76 77 class IdentifierNode : public ASTNode { 78 public: IdentifierNode(uint32_t location,std::string name)79 IdentifierNode(uint32_t location, std::string name) 80 : ASTNode(location, NodeKind::eIdentifierNode), m_name(std::move(name)) {} 81 82 llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override; 83 GetName()84 std::string GetName() const { return m_name; } 85 classof(const ASTNode * node)86 static bool classof(const ASTNode *node) { 87 return node->GetKind() == NodeKind::eIdentifierNode; 88 } 89 90 private: 91 std::string m_name; 92 }; 93 94 class MemberOfNode : public ASTNode { 95 public: MemberOfNode(uint32_t location,ASTNodeUP base,bool is_arrow,std::string name)96 MemberOfNode(uint32_t location, ASTNodeUP base, bool is_arrow, 97 std::string name) 98 : ASTNode(location, NodeKind::eMemberOfNode), m_base(std::move(base)), 99 m_is_arrow(is_arrow), m_field_name(std::move(name)) {} 100 101 llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override; 102 GetBase()103 ASTNode *GetBase() const { return m_base.get(); } GetIsArrow()104 bool GetIsArrow() const { return m_is_arrow; } GetFieldName()105 llvm::StringRef GetFieldName() const { return llvm::StringRef(m_field_name); } 106 classof(const ASTNode * node)107 static bool classof(const ASTNode *node) { 108 return node->GetKind() == NodeKind::eMemberOfNode; 109 } 110 111 private: 112 ASTNodeUP m_base; 113 bool m_is_arrow; 114 std::string m_field_name; 115 }; 116 117 class UnaryOpNode : public ASTNode { 118 public: UnaryOpNode(uint32_t location,UnaryOpKind kind,ASTNodeUP operand)119 UnaryOpNode(uint32_t location, UnaryOpKind kind, ASTNodeUP operand) 120 : ASTNode(location, NodeKind::eUnaryOpNode), m_kind(kind), 121 m_operand(std::move(operand)) {} 122 123 llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override; 124 GetKind()125 UnaryOpKind GetKind() const { return m_kind; } GetOperand()126 ASTNode *GetOperand() const { return m_operand.get(); } 127 classof(const ASTNode * node)128 static bool classof(const ASTNode *node) { 129 return node->GetKind() == NodeKind::eUnaryOpNode; 130 } 131 132 private: 133 UnaryOpKind m_kind; 134 ASTNodeUP m_operand; 135 }; 136 137 class ArraySubscriptNode : public ASTNode { 138 public: ArraySubscriptNode(uint32_t location,ASTNodeUP base,int64_t index)139 ArraySubscriptNode(uint32_t location, ASTNodeUP base, int64_t index) 140 : ASTNode(location, NodeKind::eArraySubscriptNode), 141 m_base(std::move(base)), m_index(index) {} 142 143 llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override; 144 GetBase()145 ASTNode *GetBase() const { return m_base.get(); } GetIndex()146 int64_t GetIndex() const { return m_index; } 147 classof(const ASTNode * node)148 static bool classof(const ASTNode *node) { 149 return node->GetKind() == NodeKind::eArraySubscriptNode; 150 } 151 152 private: 153 ASTNodeUP m_base; 154 int64_t m_index; 155 }; 156 157 class BitFieldExtractionNode : public ASTNode { 158 public: BitFieldExtractionNode(uint32_t location,ASTNodeUP base,int64_t first_index,int64_t last_index)159 BitFieldExtractionNode(uint32_t location, ASTNodeUP base, int64_t first_index, 160 int64_t last_index) 161 : ASTNode(location, NodeKind::eBitExtractionNode), 162 m_base(std::move(base)), m_first_index(first_index), 163 m_last_index(last_index) {} 164 165 llvm::Expected<lldb::ValueObjectSP> Accept(Visitor *v) const override; 166 GetBase()167 ASTNode *GetBase() const { return m_base.get(); } GetFirstIndex()168 int64_t GetFirstIndex() const { return m_first_index; } GetLastIndex()169 int64_t GetLastIndex() const { return m_last_index; } 170 classof(const ASTNode * node)171 static bool classof(const ASTNode *node) { 172 return node->GetKind() == NodeKind::eBitExtractionNode; 173 } 174 175 private: 176 ASTNodeUP m_base; 177 int64_t m_first_index; 178 int64_t m_last_index; 179 }; 180 181 /// This class contains one Visit method for each specialized type of 182 /// DIL AST node. The Visit methods are used to dispatch a DIL AST node to 183 /// the correct function in the DIL expression evaluator for evaluating that 184 /// type of AST node. 185 class Visitor { 186 public: 187 virtual ~Visitor() = default; 188 virtual llvm::Expected<lldb::ValueObjectSP> 189 Visit(const IdentifierNode *node) = 0; 190 virtual llvm::Expected<lldb::ValueObjectSP> 191 Visit(const MemberOfNode *node) = 0; 192 virtual llvm::Expected<lldb::ValueObjectSP> 193 Visit(const UnaryOpNode *node) = 0; 194 virtual llvm::Expected<lldb::ValueObjectSP> 195 Visit(const ArraySubscriptNode *node) = 0; 196 virtual llvm::Expected<lldb::ValueObjectSP> 197 Visit(const BitFieldExtractionNode *node) = 0; 198 }; 199 200 } // namespace lldb_private::dil 201 202 #endif // LLDB_VALUEOBJECT_DILAST_H 203