* auto-profile.c (afdo_annotate_cfg): Use update_max_bb_count.
[official-gcc.git] / gcc / go / gofrontend / ast-dump.cc
blob94bf5ef4369309d0e9e361b1db7bb49c72191f56
1 // ast-dump.cc -- AST debug dump. -*- C++ -*-
3 // Copyright 2011 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 #include "go-system.h"
9 #include <iostream>
10 #include <fstream>
12 #include "gogo.h"
13 #include "expressions.h"
14 #include "statements.h"
15 #include "types.h"
16 #include "ast-dump.h"
17 #include "go-c.h"
18 #include "go-dump.h"
19 #include "go-diagnostics.h"
21 // The -fgo-dump-ast flag to activate AST dumps.
23 Go_dump ast_dump_flag("ast");
25 // This class is used to traverse the tree to look for blocks and
26 // function headers.
28 class Ast_dump_traverse_blocks_and_functions : public Traverse
30 public:
31 Ast_dump_traverse_blocks_and_functions(Ast_dump_context* ast_dump_context)
32 : Traverse(traverse_blocks | traverse_functions),
33 ast_dump_context_(ast_dump_context)
34 { }
36 protected:
37 int
38 block(Block*);
40 int
41 function(Named_object*);
43 private:
44 Ast_dump_context* ast_dump_context_;
47 // This class is used to traverse the tree to look for statements.
49 class Ast_dump_traverse_statements : public Traverse
51 public:
52 Ast_dump_traverse_statements(Ast_dump_context* ast_dump_context)
53 : Traverse(traverse_statements),
54 ast_dump_context_(ast_dump_context)
55 { }
57 protected:
58 int
59 statement(Block*, size_t* pindex, Statement*);
61 private:
62 Ast_dump_context* ast_dump_context_;
65 // For each block we enclose it in brackets.
67 int Ast_dump_traverse_blocks_and_functions::block(Block * block)
69 if (block == NULL)
71 this->ast_dump_context_->ostream() << std::endl;
72 return TRAVERSE_EXIT;
75 this->ast_dump_context_->print_indent();
76 this->ast_dump_context_->ostream() << "{" << std::endl;
77 this->ast_dump_context_->indent();
79 // Dump statememts.
80 Ast_dump_traverse_statements adts(this->ast_dump_context_);
81 block->traverse(&adts);
83 this->ast_dump_context_->unindent();
84 this->ast_dump_context_->print_indent();
85 this->ast_dump_context_->ostream() << "}" << std::endl;
87 return TRAVERSE_SKIP_COMPONENTS;
90 // Dump each traversed statement.
92 int
93 Ast_dump_traverse_statements::statement(Block* block, size_t* pindex,
94 Statement* statement)
96 statement->dump_statement(this->ast_dump_context_);
98 if (statement->is_block_statement())
100 Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
101 statement->traverse(block, pindex, &adtbf);
104 return TRAVERSE_SKIP_COMPONENTS;
107 // Dump the function header.
110 Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
112 this->ast_dump_context_->ostream() << no->name();
114 go_assert(no->is_function());
115 Function* func = no->func_value();
117 this->ast_dump_context_->ostream() << "(";
118 this->ast_dump_context_->dump_typed_identifier_list(
119 func->type()->parameters());
121 this->ast_dump_context_->ostream() << ")";
123 Function::Results* res = func->result_variables();
124 if (res != NULL && !res->empty())
126 this->ast_dump_context_->ostream() << " (";
128 for (Function::Results::const_iterator it = res->begin();
129 it != res->end();
130 it++)
132 if (it != res->begin())
133 this->ast_dump_context_->ostream() << ",";
134 Named_object* no = (*it);
136 this->ast_dump_context_->ostream() << no->name() << " ";
137 go_assert(no->is_result_variable());
138 Result_variable* resvar = no->result_var_value();
140 this->ast_dump_context_->dump_type(resvar->type());
143 this->ast_dump_context_->ostream() << ")";
146 this->ast_dump_context_->ostream() << " : ";
147 this->ast_dump_context_->dump_type(func->type());
148 this->ast_dump_context_->ostream() << std::endl;
150 return TRAVERSE_CONTINUE;
153 // Class Ast_dump_context.
155 Ast_dump_context::Ast_dump_context(std::ostream* out /* = NULL */,
156 bool dump_subblocks /* = true */)
157 : indent_(0), dump_subblocks_(dump_subblocks), ostream_(out), gogo_(NULL)
161 // Dump files will be named %basename%.dump.ast
163 const char* kAstDumpFileExtension = ".dump.ast";
165 // Dump the internal representation.
167 void
168 Ast_dump_context::dump(Gogo* gogo, const char* basename)
170 std::ofstream out;
171 std::string dumpname(basename);
172 dumpname += ".dump.ast";
173 out.open(dumpname.c_str());
175 if (out.fail())
177 go_error_at(Linemap::unknown_location(),
178 "cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
179 return;
182 this->gogo_ = gogo;
183 this->ostream_ = &out;
185 Ast_dump_traverse_blocks_and_functions adtbf(this);
186 gogo->traverse(&adtbf);
188 out.close();
191 // Dump a textual representation of a type to the
192 // the dump file.
194 void
195 Ast_dump_context::dump_type(const Type* t)
197 if (t == NULL)
198 this->ostream() << "(nil type)";
199 else
200 // FIXME: write a type pretty printer instead of
201 // using mangled names.
202 if (this->gogo_ != NULL)
203 this->ostream() << "(" << t->mangled_name(this->gogo_) << ")";
206 // Dump a textual representation of a block to the
207 // the dump file.
209 void
210 Ast_dump_context::dump_block(Block* b)
212 Ast_dump_traverse_blocks_and_functions adtbf(this);
213 b->traverse(&adtbf);
216 // Dump a textual representation of an expression to the
217 // the dump file.
219 void
220 Ast_dump_context::dump_expression(const Expression* e)
222 e->dump_expression(this);
225 // Dump a textual representation of an expression list to the
226 // the dump file.
228 void
229 Ast_dump_context::dump_expression_list(const Expression_list* el,
230 bool as_pairs /* = false */)
232 if (el == NULL)
233 return;
235 for (std::vector<Expression*>::const_iterator it = el->begin();
236 it != el->end();
237 it++)
239 if ( it != el->begin())
240 this->ostream() << ",";
241 if (*it != NULL)
242 (*it)->dump_expression(this);
243 else
244 this->ostream() << "NULL";
245 if (as_pairs)
247 this->ostream() << ":";
248 ++it;
249 (*it)->dump_expression(this);
254 // Dump a textual representation of a typed identifier to the
255 // the dump file.
257 void
258 Ast_dump_context::dump_typed_identifier(const Typed_identifier* ti)
260 this->ostream() << ti->name() << " ";
261 this->dump_type(ti->type());
264 // Dump a textual representation of a typed identifier list to the
265 // the dump file.
267 void
268 Ast_dump_context::dump_typed_identifier_list(
269 const Typed_identifier_list* ti_list)
271 if (ti_list == NULL)
272 return;
274 for (Typed_identifier_list::const_iterator it = ti_list->begin();
275 it != ti_list->end();
276 it++)
278 if (it != ti_list->begin())
279 this->ostream() << ",";
280 this->dump_typed_identifier(&(*it));
284 // Dump a textual representation of a temporary variable to the
285 // the dump file.
287 void
288 Ast_dump_context::dump_temp_variable_name(const Statement* s)
290 go_assert(s->classification() == Statement::STATEMENT_TEMPORARY);
291 // Use the statement address as part of the name for the temporary variable.
292 this->ostream() << "tmp." << (uintptr_t) s;
295 // Dump a textual representation of a label to the
296 // the dump file.
298 void
299 Ast_dump_context::dump_label_name(const Unnamed_label* l)
301 // Use the unnamed label address as part of the name for the temporary
302 // variable.
303 this->ostream() << "label." << (uintptr_t) l;
306 // Produce a textual representation of an operator symbol.
308 static const char*
309 op_string(Operator op)
311 // FIXME: This should be in line with symbols that are parsed,
312 // exported and/or imported.
313 switch (op)
315 case OPERATOR_PLUS:
316 return "+";
317 case OPERATOR_MINUS:
318 return "-";
319 case OPERATOR_NOT:
320 return "!";
321 case OPERATOR_XOR:
322 return "^";
323 case OPERATOR_OR:
324 return "|";
325 case OPERATOR_AND:
326 return "&";
327 case OPERATOR_MULT:
328 return "*";
329 case OPERATOR_OROR:
330 return "||";
331 case OPERATOR_ANDAND:
332 return "&&";
333 case OPERATOR_EQEQ:
334 return "==";
335 case OPERATOR_NOTEQ:
336 return "!=";
337 case OPERATOR_LT:
338 return "<";
339 case OPERATOR_LE:
340 return "<=";
341 case OPERATOR_GT:
342 return ">";
343 case OPERATOR_GE:
344 return ">=";
345 case OPERATOR_DIV:
346 return "/";
347 case OPERATOR_MOD:
348 return "%";
349 case OPERATOR_LSHIFT:
350 return "<<";
351 case OPERATOR_RSHIFT:
352 return "//";
353 case OPERATOR_BITCLEAR:
354 return "&^";
355 case OPERATOR_CHANOP:
356 return "<-";
357 case OPERATOR_PLUSEQ:
358 return "+=";
359 case OPERATOR_MINUSEQ:
360 return "-=";
361 case OPERATOR_OREQ:
362 return "|=";
363 case OPERATOR_XOREQ:
364 return "^=";
365 case OPERATOR_MULTEQ:
366 return "*=";
367 case OPERATOR_DIVEQ:
368 return "/=";
369 case OPERATOR_MODEQ:
370 return "%=";
371 case OPERATOR_LSHIFTEQ:
372 return "<<=";
373 case OPERATOR_RSHIFTEQ:
374 return ">>=";
375 case OPERATOR_ANDEQ:
376 return "&=";
377 case OPERATOR_BITCLEAREQ:
378 return "&^=";
379 case OPERATOR_PLUSPLUS:
380 return "++";
381 case OPERATOR_MINUSMINUS:
382 return "--";
383 case OPERATOR_COLON:
384 return ":";
385 case OPERATOR_COLONEQ:
386 return ":=";
387 case OPERATOR_SEMICOLON:
388 return ";";
389 case OPERATOR_DOT:
390 return ".";
391 case OPERATOR_ELLIPSIS:
392 return "...";
393 case OPERATOR_COMMA:
394 return ",";
395 case OPERATOR_LPAREN:
396 return "(";
397 case OPERATOR_RPAREN:
398 return ")";
399 case OPERATOR_LCURLY:
400 return "{";
401 case OPERATOR_RCURLY:
402 return "}";
403 case OPERATOR_LSQUARE:
404 return "[";
405 case OPERATOR_RSQUARE:
406 return "]";
407 default:
408 go_unreachable();
410 return NULL;
413 // Dump a textual representation of an operator to the
414 // the dump file.
416 void
417 Ast_dump_context::dump_operator(Operator op)
419 this->ostream() << op_string(op);
422 // Size of a single indent.
424 const int Ast_dump_context::offset_ = 2;
426 // Print indenting spaces to dump file.
428 void
429 Ast_dump_context::print_indent()
431 for (int i = 0; i < this->indent_ * this->offset_; i++)
432 this->ostream() << " ";
435 // Dump a textual representation of the ast to the
436 // the dump file.
438 void Gogo::dump_ast(const char* basename)
440 if (::ast_dump_flag.is_enabled())
442 Ast_dump_context adc;
443 adc.dump(this, basename);
447 // Implementation of String_dump interface.
449 void
450 Ast_dump_context::write_c_string(const char* s)
452 this->ostream() << s;
455 void
456 Ast_dump_context::write_string(const std::string& s)
458 this->ostream() << s;
461 // Dump statment to stream.
463 void
464 Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
466 Ast_dump_context adc(out, false);
467 stm->dump_statement(&adc);
470 // Dump expression to stream.
472 void
473 Ast_dump_context::dump_to_stream(const Expression* expr, std::ostream* out)
475 Ast_dump_context adc(out, false);
476 expr->dump_expression(&adc);