P4C
The P4 Compiler
Loading...
Searching...
No Matches
node.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef IR_NODE_H_
9#define IR_NODE_H_
10
11#include <iosfwd>
12
13#include "ir/gen-tree-macro.h"
14#include "ir/inode.h"
15#include "ir/ir-tree-macros.h"
16#include "lib/cstring.h"
17#include "lib/source_file.h"
18
19namespace P4 {
20class Visitor;
21struct Visitor_Context;
22class Inspector;
23class Modifier;
24class Transform;
25class JSONGenerator;
26class JSONLoader;
27} // namespace P4
28
29namespace P4::Util {
30class JsonObject;
31} // namespace P4::Util
32
33namespace P4::IR {
34
35using namespace P4::literals;
36
37class Node;
38class Annotation; // IWYU pragma: keep
39template <class T>
40class Vector; // IWYU pragma: keep
41template <class T>
42class IndexedVector; // IWYU pragma: keep
43
44class Node : public virtual INode {
45 public:
46 virtual bool apply_visitor_preorder(Modifier &v);
47 virtual void apply_visitor_postorder(Modifier &v);
48 virtual void apply_visitor_revisit(Modifier &v, const Node *n) const;
49 virtual void apply_visitor_loop_revisit(Modifier &v) const;
50 virtual bool apply_visitor_preorder(Inspector &v) const;
51 virtual void apply_visitor_postorder(Inspector &v) const;
52 virtual void apply_visitor_revisit(Inspector &v) const;
53 virtual void apply_visitor_loop_revisit(Inspector &v) const;
54 virtual const Node *apply_visitor_preorder(Transform &v);
55 virtual const Node *apply_visitor_postorder(Transform &v);
56 virtual void apply_visitor_revisit(Transform &v, const Node *n) const;
57 virtual void apply_visitor_loop_revisit(Transform &v) const;
58 Node &operator=(const Node &) = default;
59 Node &operator=(Node &&) = default;
60
61 protected:
62 static int currentId;
63 void traceVisit(const char *visitor) const;
64 friend class ::P4::Visitor;
65 friend class ::P4::Inspector;
66 friend class ::P4::Modifier;
67 friend class ::P4::Transform;
68 cstring prepareSourceInfoForJSON(Util::SourceInfo &si, unsigned *lineNumber,
69 unsigned *columnNumber) const;
70
71 public:
72 Util::SourceInfo srcInfo;
73 int id; // unique id for each node
74 int clone_id; // unique id this node was cloned from (recursively)
75 void traceCreation() const;
76 Node() : id(currentId++), clone_id(id) { traceCreation(); }
77 explicit Node(Util::SourceInfo si) : srcInfo(si), id(currentId++), clone_id(id) {
78 traceCreation();
79 }
80 Node(const Node &other) : srcInfo(other.srcInfo), id(currentId++), clone_id(other.clone_id) {
81 traceCreation();
82 }
83 virtual ~Node() {}
84 const Node *apply(Visitor &v, const Visitor_Context *ctxt = nullptr) const;
85 const Node *apply(Visitor &&v, const Visitor_Context *ctxt = nullptr) const {
86 return apply(v, ctxt);
87 }
88 virtual Node *clone() const = 0;
89 void dbprint(std::ostream &out) const override;
90 virtual void dump_fields(std::ostream &) const {}
91 const Node *getNode() const final { return this; }
92 Node *getNode() final { return this; }
93 Util::SourceInfo getSourceInfo() const override { return srcInfo; }
94 cstring node_type_name() const override { return "Node"_cs; }
95 static cstring static_type_name() { return "Node"_cs; }
96 virtual int num_children() { return 0; }
97 explicit Node(JSONLoader &json);
98 cstring toString() const override { return node_type_name(); }
99 void toJSON(JSONGenerator &json) const override;
100 void sourceInfoToJSON(JSONGenerator &json) const;
101 void sourceInfoFromJSON(JSONLoader &json);
102 Util::JsonObject *sourceInfoJsonObj() const;
103 /* operator== does a 'shallow' comparison, comparing two Node subclass objects for equality,
104 * and comparing pointers in the Node directly for equality */
105 virtual bool operator==(const Node &a) const { return this->typeId() == a.typeId(); }
106 /* 'equiv' does a deep-equals comparison, comparing all non-pointer fields and recursing
107 * though all Node subclass pointers to compare them with 'equiv' as well. */
108 virtual bool equiv(const Node &a) const { return this->typeId() == a.typeId(); }
109#define DEFINE_OPEQ_FUNC(CLASS, BASE) \
110 virtual bool operator==(const CLASS &) const { return false; }
111 IRNODE_ALL_SUBCLASSES(DEFINE_OPEQ_FUNC)
112#undef DEFINE_OPEQ_FUNC
113 virtual void visit_children(Visitor &, const char * /*name*/ = nullptr) {}
114 virtual void visit_children(Visitor &, const char * /*name*/ = nullptr) const {}
115
116 bool operator!=(const Node &n) const { return !operator==(n); }
117
121 template <typename Sink>
122 friend void AbslStringify(Sink &sink, const IR::Node *n) {
123 sink.Append(n->toString());
124 }
125
126 DECLARE_TYPEINFO_WITH_TYPEID(Node, NodeKind::Node, INode);
127};
128
129// simple version of dbprint
130cstring dbp(const INode *node);
131
132inline bool equal(const Node *a, const Node *b) { return a == b || (a && b && *a == *b); }
133inline bool equal(const INode *a, const INode *b) {
134 return a == b || (a && b && *a->getNode() == *b->getNode());
135}
136inline bool equiv(const Node *a, const Node *b) { return a == b || (a && b && a->equiv(*b)); }
137inline bool equiv(const INode *a, const INode *b) {
138 return a == b || (a && b && a->getNode()->equiv(*b->getNode()));
139}
140// NOLINTBEGIN(bugprone-macro-parentheses)
141/* common things that ALL Node subclasses must define */
142#define IRNODE_SUBCLASS(T) \
143 public: \
144 T *clone() const override { return new T(*this); } \
145 IRNODE_COMMON_SUBCLASS(T)
146#define IRNODE_ABSTRACT_SUBCLASS(T) \
147 public: \
148 T *clone() const override = 0; \
149 IRNODE_COMMON_SUBCLASS(T)
150
151// NOLINTEND(bugprone-macro-parentheses)
152#define IRNODE_COMMON_SUBCLASS(T) \
153 public: \
154 using Node::operator==; \
155 bool apply_visitor_preorder(Modifier &v) override; \
156 void apply_visitor_postorder(Modifier &v) override; \
157 void apply_visitor_revisit(Modifier &v, const Node *n) const override; \
158 void apply_visitor_loop_revisit(Modifier &v) const override; \
159 bool apply_visitor_preorder(Inspector &v) const override; \
160 void apply_visitor_postorder(Inspector &v) const override; \
161 void apply_visitor_revisit(Inspector &v) const override; \
162 void apply_visitor_loop_revisit(Inspector &v) const override; \
163 const Node *apply_visitor_preorder(Transform &v) override; \
164 const Node *apply_visitor_postorder(Transform &v) override; \
165 void apply_visitor_revisit(Transform &v, const Node *n) const override; \
166 void apply_visitor_loop_revisit(Transform &v) const override;
167
168/* only define 'apply' for a limited number of classes (those we want to call
169 * visitors directly on), as defining it and making it virtual would mean that
170 * NO Transform could transform the class into a sibling class */
171#define IRNODE_DECLARE_APPLY_OVERLOAD(T) \
172 const T *apply(Visitor &v, const Visitor_Context *ctxt = nullptr) const; \
173 const T *apply(Visitor &&v, const Visitor_Context *ctxt = nullptr) const { \
174 return apply(v, ctxt); \
175 }
176#define IRNODE_DEFINE_APPLY_OVERLOAD(CLASS, TEMPLATE, TT) \
177 TEMPLATE \
178 const IR::CLASS TT *IR::CLASS TT::apply(Visitor &v, const Visitor_Context *ctxt) const { \
179 const CLASS *tmp = this; \
180 auto prof = v.init_apply(tmp, ctxt); \
181 v.visit(tmp); \
182 v.end_apply(tmp); \
183 return tmp; \
184 }
185
186} // namespace P4::IR
187
188#endif /* IR_NODE_H_ */
Definition inode.h:42
Definition indexed_vector.h:31
Definition node.h:44
friend void AbslStringify(Sink &sink, const IR::Node *n)
Definition node.h:122
Definition ir/vector.h:50
Definition visitor.h:409
Definition json_generator.h:30
Definition json_loader.h:32
Definition visitor.h:376
Definition visitor.h:433
Definition lib/json.h:168
Definition source_file.h:123
Definition visitor.h:66
Definition cstring.h:76
Definition constantParsing.h:13
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
Definition bson.cpp:69
virtual TypeId typeId() const noexcept=0
Definition visitor.h:38