22#include "ir-tree-macros.h"
23#include "ir/gen-tree-macro.h"
24#include "lib/castable.h"
25#include "lib/cstring.h"
26#include "lib/exceptions.h"
27#include "lib/source_file.h"
31struct Visitor_Context;
56template <
class,
class =
void>
69 virtual const Node *getNode()
const = 0;
70 virtual Node *getNode() = 0;
72 virtual cstring node_type_name()
const = 0;
73 virtual void validate()
const {}
77 std::enable_if_t<!has_static_type_name_v<T>,
const T *> checkedTo()
const {
84 std::enable_if_t<has_static_type_name_v<T>,
const T *> checkedTo()
const {
85 const auto *result =
to<T>();
86 BUG_CHECK(result,
"Cast failed: %1% with type %2% is not a %3%.",
this, node_type_name(),
87 T::static_type_name());
91 DECLARE_TYPEINFO_WITH_TYPEID(
INode, NodeKind::INode);
96 virtual bool apply_visitor_preorder(
Modifier &v);
97 virtual void apply_visitor_postorder(
Modifier &v);
98 virtual void apply_visitor_revisit(
Modifier &v,
const Node *n)
const;
99 virtual void apply_visitor_loop_revisit(
Modifier &v)
const;
100 virtual bool apply_visitor_preorder(
Inspector &v)
const;
101 virtual void apply_visitor_postorder(
Inspector &v)
const;
102 virtual void apply_visitor_revisit(
Inspector &v)
const;
103 virtual void apply_visitor_loop_revisit(
Inspector &v)
const;
106 virtual void apply_visitor_revisit(
Transform &v,
const Node *n)
const;
107 virtual void apply_visitor_loop_revisit(
Transform &v)
const;
108 Node &operator=(
const Node &) =
default;
112 static int currentId;
113 void traceVisit(
const char *visitor)
const;
114 friend class ::P4::Visitor;
115 friend class ::P4::Inspector;
116 friend class ::P4::Modifier;
117 friend class ::P4::Transform;
119 unsigned *columnNumber)
const;
125 void traceCreation()
const;
126 Node() : id(currentId++), clone_id(
id) { traceCreation(); }
130 Node(
const Node &other) : srcInfo(other.srcInfo), id(currentId++), clone_id(other.clone_id) {
136 return apply(v, ctxt);
138 virtual Node *clone()
const = 0;
139 void dbprint(std::ostream &out)
const override;
140 virtual void dump_fields(std::ostream &)
const {}
141 const Node *getNode()
const final {
return this; }
142 Node *getNode()
final {
return this; }
144 cstring node_type_name()
const override {
return "Node"_cs; }
145 static cstring static_type_name() {
return "Node"_cs; }
146 virtual int num_children() {
return 0; }
148 cstring toString()
const override {
return node_type_name(); }
154 virtual bool operator==(
const Node &a)
const {
return this->
typeId() == a.
typeId(); }
157 virtual bool equiv(
const Node &a)
const {
return this->
typeId() == a.
typeId(); }
158#define DEFINE_OPEQ_FUNC(CLASS, BASE) \
159 virtual bool operator==(const CLASS &) const { return false; }
160 IRNODE_ALL_SUBCLASSES(DEFINE_OPEQ_FUNC)
161#undef DEFINE_OPEQ_FUNC
162 virtual void visit_children(
Visitor &) {}
163 virtual void visit_children(
Visitor &)
const {}
165 bool operator!=(
const Node &n)
const {
return !operator==(n); }
170 template <
typename Sink>
172 sink.Append(n->toString());
175 DECLARE_TYPEINFO_WITH_TYPEID(
Node, NodeKind::Node,
INode);
181inline bool equal(
const Node *a,
const Node *b) {
return a == b || (a && b && *a == *b); }
182inline bool equal(
const INode *a,
const INode *b) {
183 return a == b || (a && b && *a->getNode() == *b->getNode());
185inline bool equiv(
const Node *a,
const Node *b) {
return a == b || (a && b && a->equiv(*b)); }
186inline bool equiv(
const INode *a,
const INode *b) {
187 return a == b || (a && b && a->getNode()->equiv(*b->getNode()));
191#define IRNODE_SUBCLASS(T) \
193 T *clone() const override { return new T(*this); } \
194 IRNODE_COMMON_SUBCLASS(T)
195#define IRNODE_ABSTRACT_SUBCLASS(T) \
197 T *clone() const override = 0; \
198 IRNODE_COMMON_SUBCLASS(T)
201#define IRNODE_COMMON_SUBCLASS(T) \
203 using Node::operator==; \
204 bool apply_visitor_preorder(Modifier &v) override; \
205 void apply_visitor_postorder(Modifier &v) override; \
206 void apply_visitor_revisit(Modifier &v, const Node *n) const override; \
207 void apply_visitor_loop_revisit(Modifier &v) const override; \
208 bool apply_visitor_preorder(Inspector &v) const override; \
209 void apply_visitor_postorder(Inspector &v) const override; \
210 void apply_visitor_revisit(Inspector &v) const override; \
211 void apply_visitor_loop_revisit(Inspector &v) const override; \
212 const Node *apply_visitor_preorder(Transform &v) override; \
213 const Node *apply_visitor_postorder(Transform &v) override; \
214 void apply_visitor_revisit(Transform &v, const Node *n) const override; \
215 void apply_visitor_loop_revisit(Transform &v) const override;
220#define IRNODE_DECLARE_APPLY_OVERLOAD(T) \
221 const T *apply(Visitor &v, const Visitor_Context *ctxt = nullptr) const; \
222 const T *apply(Visitor &&v, const Visitor_Context *ctxt = nullptr) const { \
223 return apply(v, ctxt); \
225#define IRNODE_DEFINE_APPLY_OVERLOAD(CLASS, TEMPLATE, TT) \
227 const IR::CLASS TT *IR::CLASS TT::apply(Visitor &v, const Visitor_Context *ctxt) const { \
228 const CLASS *tmp = this; \
229 auto prof = v.init_apply(tmp, ctxt); \
const T * checkedTo() const
Performs a checked cast. A BUG occurs if the cast fails.
Definition castable.h:54
Definition stringify.h:33
friend void AbslStringify(Sink &sink, const IR::Node *n)
Definition node.h:171
Definition json_generator.h:36
Definition json_loader.h:38
Definition source_file.h:227
Definition source_file.h:131
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
T * to() noexcept
Definition rtti.h:226
virtual TypeId typeId() const noexcept=0