P4C
The P4 Compiler
Loading...
Searching...
No Matches
toP4.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 FRONTENDS_P4_TOP4_TOP4_H_
9#define FRONTENDS_P4_TOP4_TOP4_H_
10
11#include <filesystem>
12#include <iostream>
13#include <optional>
14#include <vector>
15
16#include "frontends/common/resolveReferences/resolveReferences.h"
17#include "ir/ir.h"
18#include "ir/visitor.h"
19#include "lib/sourceCodeBuilder.h"
20
21namespace P4 {
22
27class ToP4 : public Inspector, ResolutionContext {
28 protected:
30 int expressionPrecedence = DBPrint::Prec_Low;
31 bool isDeclaration = true;
32 bool showIR;
33 bool withinArgument = false;
34 bool noIncludes = false;
36
37 struct VecPrint {
38 cstring separator;
39 cstring terminator;
40
41 VecPrint(const char *sep, const char *term) : separator(sep), terminator(term) {}
42 };
43
44 struct ListPrint {
45 cstring start;
46 cstring end;
47
48 ListPrint(const char *start, const char *end) : start(start), end(end) {}
49 };
50
51 // maintained as stacks
52 std::vector<VecPrint> vectorSeparator;
53 size_t vectorSeparator_init_apply_size = 0;
54 std::vector<ListPrint> listTerminators;
55 size_t listTerminators_init_apply_size = 0;
56
57 void setVecSep(const char *sep, const char *term = nullptr) {
58 vectorSeparator.push_back(VecPrint(sep, term));
59 }
60 void doneVec() {
61 BUG_CHECK(!vectorSeparator.empty(), "Empty vectorSeparator");
62 vectorSeparator.pop_back();
63 }
64 VecPrint getSep() {
65 BUG_CHECK(!vectorSeparator.empty(), "Empty vectorSeparator");
66 return vectorSeparator.back();
67 }
68
69 void doneList() {
70 BUG_CHECK(!listTerminators.empty(), "Empty listTerminators");
71 listTerminators.pop_back();
72 }
74 std::optional<cstring> ifSystemFile(const IR::Node *node);
76 void dump(unsigned depth, const IR::Node *node = nullptr, unsigned adjDepth = 0);
77 unsigned curDepth() const;
78 bool printAnnotations(const IR::IAnnotated *ann);
79
80 public:
81 // Output is constructed here
82 Util::SourceCodeBuilder &builder;
83 /* FIXME -- simplify this by getting rid of the 'builder' object and just emitting
84 * directly to the ostream. The SourceCodeBuilder object does not appear to add any
85 * useful functionality the ostream does not already provide; it just serves to
86 * obfuscate the code */
87 std::ostream *outStream = nullptr;
91 std::optional<std::filesystem::path> mainFile;
92
93 ToP4(Util::SourceCodeBuilder &builder, bool showIR) : showIR(showIR), builder(builder) {
94 visitDagOnce = false;
95 setName("ToP4");
96 }
97
98 ToP4(std::ostream *outStream, bool showIR) : ToP4(*new Util::SourceCodeBuilder(), showIR) {
99 this->outStream = outStream;
100 }
101
102 ToP4(Util::SourceCodeBuilder &builder, bool showIR, std::filesystem::path mainFile)
103 : ToP4(builder, showIR) {
104 this->mainFile = mainFile;
105 }
106 ToP4(std::ostream *outStream, bool showIR, std::filesystem::path mainFile)
107 : ToP4(outStream, showIR) {
108 this->mainFile = mainFile;
109 }
110
111 ToP4() : ToP4(*new Util::SourceCodeBuilder(), false) {}
112
113 using Inspector::preorder;
114
115 void setnoIncludesArg(bool condition) { noIncludes = condition; }
116
117 void setListTerm(const char *start, const char *end) {
118 listTerminators.push_back(ListPrint(start, end));
119 }
120 Visitor::profile_t init_apply(const IR::Node *node) override;
121 void end_apply(const IR::Node *node) override;
122
123 bool process(const IR::Type_StructLike *t, const char *name);
124 // types
125 bool preorder(const IR::Type_Boolean *t) override;
126 bool preorder(const IR::Type_Varbits *t) override;
127 bool preorder(const IR::Type_Bits *t) override;
128 bool preorder(const IR::Type_InfInt *t) override;
129 bool preorder(const IR::Type_String *t) override;
130 bool preorder(const IR::Type_Var *t) override;
131 bool preorder(const IR::Type_Dontcare *t) override;
132 bool preorder(const IR::Type_Void *t) override;
133 bool preorder(const IR::Type_Error *t) override;
134 bool preorder(const IR::Type_Struct *t) override { return process(t, "struct"); }
135 bool preorder(const IR::Type_Header *t) override { return process(t, "header"); }
136 bool preorder(const IR::Type_HeaderUnion *t) override { return process(t, "header_union"); }
137 bool preorder(const IR::Type_Package *t) override;
138 bool preorder(const IR::Type_Parser *t) override;
139 bool preorder(const IR::Type_Control *t) override;
140 bool preorder(const IR::Type_Name *t) override;
141 bool preorder(const IR::Type_Array *t) override;
142 bool preorder(const IR::Type_Specialized *t) override;
143 bool preorder(const IR::Type_Enum *t) override;
144 bool preorder(const IR::Type_SerEnum *t) override;
145 bool preorder(const IR::Type_Typedef *t) override;
146 bool preorder(const IR::Type_Newtype *t) override;
147 bool preorder(const IR::Type_Extern *t) override;
148 bool preorder(const IR::Type_Unknown *t) override;
149 bool preorder(const IR::Type_BaseList *t) override;
150 bool preorder(const IR::Type *t) override {
151 builder.append(t->toString());
152 return false;
153 }
154 bool preorder(const IR::Type_SpecializedCanonical *t) override {
155 BUG("%1%: specialized canonical type in IR tree", t);
156 return false;
157 }
158
159 // declarations
160 bool preorder(const IR::Declaration_Constant *cst) override;
161 bool preorder(const IR::Declaration_Variable *v) override;
162 bool preorder(const IR::Declaration_Instance *t) override;
163 bool preorder(const IR::Declaration_MatchKind *d) override;
164
165 // expressions
166 bool preorder(const IR::Dots *e) override;
167 bool preorder(const IR::NamedDots *e) override;
168 bool preorder(const IR::Constant *c) override;
169 bool preorder(const IR::AbstractSlice *slice) override;
170 bool preorder(const IR::BoolLiteral *b) override;
171 bool preorder(const IR::StringLiteral *s) override;
172 bool preorder(const IR::PathExpression *p) override;
173 bool preorder(const IR::Cast *c) override;
174 bool preorder(const IR::Operation_Binary *b) override;
175 bool preorder(const IR::Operation_Unary *u) override;
176 bool preorder(const IR::ArrayIndex *a) override;
177 bool preorder(const IR::TypeNameExpression *e) override;
178 bool preorder(const IR::Mux *a) override;
179 bool preorder(const IR::ConstructorCallExpression *e) override;
180 bool preorder(const IR::Member *e) override;
181 bool preorder(const IR::SelectCase *e) override;
182 bool preorder(const IR::SelectExpression *e) override;
183 bool preorder(const IR::ListExpression *e) override;
184 bool preorder(const IR::P4ListExpression *e) override;
185 bool preorder(const IR::StructExpression *e) override;
186 bool preorder(const IR::Invalid *e) override;
187 bool preorder(const IR::InvalidHeader *e) override;
188 bool preorder(const IR::InvalidHeaderUnion *e) override;
189 bool preorder(const IR::ArrayExpression *e) override;
190 bool preorder(const IR::MethodCallExpression *e) override;
191 bool preorder(const IR::DefaultExpression *e) override;
192 bool preorder(const IR::This *e) override;
193
194 // vectors
195 bool preorder(const IR::Vector<IR::ActionListElement> *v) override;
196 bool preorder(const IR::Vector<IR::Annotation> *v) override;
197 bool preorder(const IR::Vector<IR::Entry> *v) override;
198 bool preorder(const IR::Vector<IR::Expression> *v) override;
199 bool preorder(const IR::Vector<IR::Argument> *v) override;
200 bool preorder(const IR::Vector<IR::KeyElement> *v) override;
201 bool preorder(const IR::Vector<IR::Method> *v) override;
202 bool preorder(const IR::Vector<IR::Node> *v) override;
203 bool preorder(const IR::Vector<IR::SelectCase> *v) override;
204 bool preorder(const IR::Vector<IR::SwitchCase> *v) override;
205 bool preorder(const IR::Vector<IR::Type> *v) override;
206 bool preorder(const IR::IndexedVector<IR::Declaration_ID> *v) override;
207 bool preorder(const IR::IndexedVector<IR::Declaration> *v) override;
208 bool preorder(const IR::IndexedVector<IR::Node> *v) override;
209 bool preorder(const IR::IndexedVector<IR::ParserState> *v) override;
210 bool preorder(const IR::IndexedVector<IR::StatOrDecl> *v) override;
211
212 // statements
213 bool preorder(const IR::AssignmentStatement *s) override;
214 bool preorder(const IR::OpAssignmentStatement *s) override;
215 bool preorder(const IR::BlockStatement *s) override;
216 bool preorder(const IR::MethodCallStatement *s) override;
217 bool preorder(const IR::EmptyStatement *s) override;
218 bool preorder(const IR::ReturnStatement *s) override;
219 bool preorder(const IR::BreakStatement *s) override;
220 bool preorder(const IR::ContinueStatement *s) override;
221 bool preorder(const IR::ExitStatement *s) override;
222 bool preorder(const IR::SwitchCase *s) override;
223 bool preorder(const IR::SwitchStatement *s) override;
224 bool preorder(const IR::IfStatement *s) override;
225 bool preorder(const IR::ForStatement *s) override;
226 bool preorder(const IR::ForInStatement *s) override;
227
228 // misc
229 bool preorder(const IR::NamedExpression *ne) override;
230 bool preorder(const IR::Argument *arg) override;
231 bool preorder(const IR::Path *p) override;
232 bool preorder(const IR::Parameter *p) override;
233 bool preorder(const IR::Annotation *a) override;
234 bool preorder(const IR::P4Program *program) override;
235 bool preorder(const IR::P4Control *c) override;
236 bool preorder(const IR::P4Action *c) override;
237 bool preorder(const IR::ParserState *s) override;
238 bool preorder(const IR::P4Parser *c) override;
239 bool preorder(const IR::TypeParameters *p) override;
240 bool preorder(const IR::ParameterList *p) override;
241 bool preorder(const IR::Method *p) override;
242 bool preorder(const IR::Function *function) override;
243
244 bool preorder(const IR::ExpressionValue *v) override;
245 bool preorder(const IR::ActionListElement *ale) override;
246 bool preorder(const IR::ActionList *v) override;
247 bool preorder(const IR::Key *v) override;
248 bool preorder(const IR::Property *p) override;
249 bool preorder(const IR::TableProperties *t) override;
250 bool preorder(const IR::EntriesList *l) override;
251 bool preorder(const IR::Entry *e) override;
252 bool preorder(const IR::P4Table *c) override;
253 bool preorder(const IR::P4ValueSet *c) override;
254
255 // in case it is accidentally called on a V1Program
256 bool preorder(const IR::V1Program *) override { return false; }
257};
258
259std::string toP4(const IR::INode *node);
260void dumpP4(const IR::INode *node);
261
262} // namespace P4
263
264#endif /* FRONTENDS_P4_TOP4_TOP4_H_ */
Definition inode.h:42
Definition visitor.h:409
Definition toP4.h:27
void dump(unsigned depth, const IR::Node *node=nullptr, unsigned adjDepth=0)
dump node IR tree up to depth - in the form of a comment
Definition toP4.cpp:121
bool noIncludes
if true we are within a method call argument
Definition toP4.h:34
bool showIR
current type is a declaration
Definition toP4.h:32
bool withinArgument
if true dump IR as comments
Definition toP4.h:33
std::optional< cstring > ifSystemFile(const IR::Node *node)
Definition toP4.cpp:39
int expressionPrecedence
precedence of current IR::Operation
Definition toP4.h:30
std::optional< std::filesystem::path > mainFile
Definition toP4.h:91
Definition sourceCodeBuilder.h:20
Definition cstring.h:76
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
Definition toP4.h:44
Definition toP4.h:37