Store warnings and errors in a parser state infolog.
[mesa.git] / ir_print_visitor.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <cstdio>
24 #include "ir_print_visitor.h"
25 #include "glsl_types.h"
26 #include "glsl_parser_extras.h"
27
28 static void print_type(const glsl_type *t);
29
30 void
31 _mesa_print_ir(exec_list *instructions,
32 struct _mesa_glsl_parse_state *state)
33 {
34 for (unsigned i = 0; i < state->num_user_structures; i++) {
35 const glsl_type *const s = state->user_structures[i];
36
37 printf("(structure (%s) (%s@%p) (%u) (\n",
38 s->name, s->name, s, s->length);
39
40 for (unsigned j = 0; j < s->length; j++) {
41 printf("\t((");
42 print_type(s->fields.structure[j].type);
43 printf(")(%s))\n", s->fields.structure[j].name);
44 }
45
46 printf(")\n");
47 }
48
49 printf("(\n");
50 foreach_iter(exec_list_iterator, iter, *instructions) {
51 ir_print_visitor v;
52
53 ((ir_instruction *)iter.get())->accept(& v);
54 printf("\n");
55 }
56 printf("\n)");
57 }
58
59 static void
60 print_type(const glsl_type *t)
61 {
62 if (t->base_type == GLSL_TYPE_ARRAY) {
63 printf("(array ");
64 print_type(t->fields.array);
65 printf(" %u)", t->length);
66 } else if ((t->base_type == GLSL_TYPE_STRUCT)
67 && (strncmp("gl_", t->name, 3) != 0)) {
68 printf("%s@%p", t->name, t);
69 } else {
70 printf("%s", t->name);
71 }
72 }
73
74
75 void ir_print_visitor::visit(ir_variable *ir)
76 {
77 if (deref_depth) {
78 printf("%s", ir->name);
79 } else {
80 printf("(declare ");
81
82 const char *const cent = (ir->centroid) ? "centroid " : "";
83 const char *const inv = (ir->invariant) ? "invariant " : "";
84 const char *const mode[] = { "", "uniform ", "in ", "out ", "inout " };
85 const char *const interp[] = { "", "flat", "noperspective" };
86
87 printf("(%s%s%s%s) ",
88 cent, inv, mode[ir->mode], interp[ir->interpolation]);
89
90 print_type(ir->type);
91 printf(" %s)", ir->name);
92 }
93 }
94
95
96 void ir_print_visitor::visit(ir_function_signature *ir)
97 {
98 printf("(signature ");
99 print_type(ir->return_type);
100 printf("\n (parameters\n");
101 foreach_iter(exec_list_iterator, iter, ir->parameters) {
102 ir_variable *const inst = (ir_variable *) iter.get();
103
104 inst->accept(this);
105 printf("\n");
106 }
107 printf(" )\n(");
108
109 foreach_iter(exec_list_iterator, iter, ir->body) {
110 ir_instruction *const inst = (ir_instruction *) iter.get();
111
112 inst->accept(this);
113 printf("\n");
114 }
115 printf("))\n");
116 }
117
118
119 void ir_print_visitor::visit(ir_function *ir)
120 {
121 printf("(function %s\n", ir->name);
122 foreach_iter(exec_list_iterator, iter, *ir) {
123 ir_function_signature *const sig = (ir_function_signature *) iter.get();
124
125 sig->accept(this);
126 printf("\n");
127 }
128
129 printf(")\n");
130 }
131
132
133 void ir_print_visitor::visit(ir_expression *ir)
134 {
135 printf("(expression ");
136
137 print_type(ir->type);
138
139 printf(" %s ", ir->operator_string());
140
141 if (ir->operands[0])
142 ir->operands[0]->accept(this);
143
144 if (ir->operands[1])
145 ir->operands[1]->accept(this);
146 printf(") ");
147 }
148
149
150 void ir_print_visitor::visit(ir_swizzle *ir)
151 {
152 const unsigned swiz[4] = {
153 ir->mask.x,
154 ir->mask.y,
155 ir->mask.z,
156 ir->mask.w,
157 };
158
159 printf("(swiz ");
160 for (unsigned i = 0; i < ir->mask.num_components; i++) {
161 printf("%c", "xyzw"[swiz[i]]);
162 }
163 printf(" ");
164 ir->val->accept(this);
165 printf(")");
166 }
167
168
169 void ir_print_visitor::visit(ir_dereference *ir)
170 {
171 deref_depth++;
172
173 switch (ir->mode) {
174 case ir_dereference::ir_reference_variable: {
175 printf("(var_ref ");
176 ir->var->accept(this);
177 printf(") ");
178 break;
179 }
180 case ir_dereference::ir_reference_array:
181 printf("(array_ref ");
182 ir->var->accept(this);
183 ir->selector.array_index->accept(this);
184 printf(") ");
185 break;
186 case ir_dereference::ir_reference_record:
187 printf("(record_ref ");
188 ir->var->accept(this);
189 printf("(%s)) ", ir->selector.field);
190 break;
191 }
192
193 deref_depth--;
194 }
195
196
197 void ir_print_visitor::visit(ir_assignment *ir)
198 {
199 printf("(assign ");
200
201 if (ir->condition)
202 ir->condition->accept(this);
203 else
204 printf("(constant bool (1))");
205
206 printf(" ");
207
208 ir->lhs->accept(this);
209
210 printf(" ");
211
212 ir->rhs->accept(this);
213 printf(") ");
214 }
215
216
217 void ir_print_visitor::visit(ir_constant *ir)
218 {
219 const glsl_type *const base_type = ir->type->get_base_type();
220
221 printf("(constant ");
222 print_type(ir->type);
223 printf(" (");
224
225 for (unsigned i = 0; i < ir->type->components(); i++) {
226 if (i != 0)
227 printf(", ");
228
229 switch (base_type->base_type) {
230 case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
231 case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
232 case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
233 case GLSL_TYPE_BOOL: printf("%d", ir->value.b[i]); break;
234 default: assert(0);
235 }
236 }
237 printf(")) ");
238 }
239
240
241 void
242 ir_print_visitor::visit(ir_call *ir)
243 {
244 printf("(call %s (", ir->callee_name());
245 foreach_iter(exec_list_iterator, iter, *ir) {
246 ir_instruction *const inst = (ir_instruction *) iter.get();
247
248 inst->accept(this);
249 }
250 printf("))\n");
251 }
252
253
254 void
255 ir_print_visitor::visit(ir_return *ir)
256 {
257 printf("(return");
258
259 ir_rvalue *const value = ir->get_value();
260 if (value) {
261 printf(" ");
262 value->accept(this);
263 }
264
265 printf(")");
266 }
267
268
269 void
270 ir_print_visitor::visit(ir_if *ir)
271 {
272 printf("(if ");
273 ir->condition->accept(this);
274
275 printf("(\n");
276 foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
277 ir_instruction *const inst = (ir_instruction *) iter.get();
278
279 inst->accept(this);
280 printf("\n");
281 }
282 printf(")\n");
283
284 printf("(\n");
285 foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
286 ir_instruction *const inst = (ir_instruction *) iter.get();
287
288 inst->accept(this);
289 printf("\n");
290 }
291 printf("))\n");
292 }
293
294
295 void
296 ir_print_visitor::visit(ir_loop *ir)
297 {
298 printf("(loop (");
299 if (ir->counter != NULL)
300 ir->counter->accept(this);
301 printf(") (");
302 if (ir->from != NULL)
303 ir->from->accept(this);
304 printf(") (");
305 if (ir->to != NULL)
306 ir->to->accept(this);
307 printf(") (");
308 if (ir->increment != NULL)
309 ir->increment->accept(this);
310 printf(") (\n");
311 foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
312 ir_instruction *const inst = (ir_instruction *) iter.get();
313
314 inst->accept(this);
315 printf("\n");
316 }
317 printf("))\n");
318 }
319
320
321 void
322 ir_print_visitor::visit(ir_loop_jump *ir)
323 {
324 printf("%s", ir->is_break() ? "break" : "continue");
325 }