xref: /freebsd/contrib/llvm-project/lldb/include/lldb/ValueObject/DILAST.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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