Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / go / gofrontend / ast-dump.cc
blobeca0bf1fad2dcd40b234bd06e61219f2eb06f1bd
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>
11 #include <sstream>
13 #include "gogo.h"
14 #include "expressions.h"
15 #include "statements.h"
16 #include "types.h"
17 #include "ast-dump.h"
18 #include "go-c.h"
19 #include "go-dump.h"
20 #include "go-diagnostics.h"
22 // The -fgo-dump-ast flag to activate AST dumps.
24 Go_dump ast_dump_flag("ast");
26 // This class is used to traverse the tree to look for blocks and
27 // function headers.
29 class Ast_dump_traverse_blocks_and_functions : public Traverse
31 public:
32 Ast_dump_traverse_blocks_and_functions(Ast_dump_context* ast_dump_context)
33 : Traverse(traverse_blocks | traverse_functions | traverse_variables),
34 ast_dump_context_(ast_dump_context)
35 { }
37 protected:
38 int
39 block(Block*);
41 int
42 function(Named_object*);
44 int
45 variable(Named_object*);
47 private:
48 Ast_dump_context* ast_dump_context_;
51 // This class is used to traverse the tree to look for statements.
53 class Ast_dump_traverse_statements : public Traverse
55 public:
56 Ast_dump_traverse_statements(Ast_dump_context* ast_dump_context)
57 : Traverse(traverse_statements),
58 ast_dump_context_(ast_dump_context)
59 { }
61 protected:
62 int
63 statement(Block*, size_t* pindex, Statement*);
65 private:
66 Ast_dump_context* ast_dump_context_;
69 // For each block we enclose it in brackets.
71 int Ast_dump_traverse_blocks_and_functions::block(Block * block)
73 if (block == NULL)
75 this->ast_dump_context_->ostream() << std::endl;
76 return TRAVERSE_EXIT;
79 this->ast_dump_context_->print_indent();
80 this->ast_dump_context_->ostream() << "{" << std::endl;
81 this->ast_dump_context_->indent();
83 // Dump statememts.
84 Ast_dump_traverse_statements adts(this->ast_dump_context_);
85 block->traverse(&adts);
87 this->ast_dump_context_->unindent();
88 this->ast_dump_context_->print_indent();
89 this->ast_dump_context_->ostream() << "}" << std::endl;
91 return TRAVERSE_SKIP_COMPONENTS;
94 // Dump each traversed statement.
96 int
97 Ast_dump_traverse_statements::statement(Block* block, size_t* pindex,
98 Statement* statement)
100 statement->dump_statement(this->ast_dump_context_);
102 if (statement->is_block_statement())
104 Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
105 statement->traverse(block, pindex, &adtbf);
108 return TRAVERSE_SKIP_COMPONENTS;
111 // Dump the function header.
114 Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
116 this->ast_dump_context_->ostream() << no->name();
118 go_assert(no->is_function());
119 Function* func = no->func_value();
121 this->ast_dump_context_->ostream() << "(";
122 this->ast_dump_context_->dump_typed_identifier_list(
123 func->type()->parameters());
125 this->ast_dump_context_->ostream() << ")";
127 Function::Results* res = func->result_variables();
128 if (res != NULL && !res->empty())
130 this->ast_dump_context_->ostream() << " (";
132 for (Function::Results::const_iterator it = res->begin();
133 it != res->end();
134 it++)
136 if (it != res->begin())
137 this->ast_dump_context_->ostream() << ",";
138 Named_object* rno = (*it);
140 this->ast_dump_context_->ostream() << rno->name() << " ";
141 go_assert(rno->is_result_variable());
142 Result_variable* resvar = rno->result_var_value();
144 this->ast_dump_context_->dump_type(resvar->type());
147 this->ast_dump_context_->ostream() << ")";
150 this->ast_dump_context_->ostream() << " : ";
151 this->ast_dump_context_->dump_type(func->type());
152 this->ast_dump_context_->ostream() << std::endl;
154 return TRAVERSE_CONTINUE;
157 // Dump variable preinits
160 Ast_dump_traverse_blocks_and_functions::variable(Named_object* no)
162 if (!no->is_variable())
163 return TRAVERSE_CONTINUE;
165 Variable* var = no->var_value();
166 if (var->has_pre_init())
168 this->ast_dump_context_->ostream() << "// preinit block for var "
169 << no->message_name() << "\n";
170 var->preinit()->traverse(this);
173 return TRAVERSE_CONTINUE;
178 // Class Ast_dump_context.
180 Ast_dump_context::Ast_dump_context(std::ostream* out /* = NULL */,
181 bool dump_subblocks /* = true */)
182 : indent_(0), dump_subblocks_(dump_subblocks), ostream_(out), gogo_(NULL)
186 // Dump files will be named %basename%.dump.ast
188 const char* kAstDumpFileExtension = ".dump.ast";
190 // Dump the internal representation.
192 void
193 Ast_dump_context::dump(Gogo* gogo, const char* basename)
195 std::ofstream out;
196 std::string dumpname(basename);
197 dumpname += ".dump.ast";
198 out.open(dumpname.c_str());
200 if (out.fail())
202 go_error_at(Linemap::unknown_location(),
203 "cannot open %s:%m; %<-fgo-dump-ast%> ignored",
204 dumpname.c_str());
205 return;
208 this->gogo_ = gogo;
209 this->ostream_ = &out;
211 Ast_dump_traverse_blocks_and_functions adtbf(this);
212 gogo->traverse(&adtbf);
214 out.close();
217 // Dump a textual representation of a type to the
218 // the dump file.
220 void
221 Ast_dump_context::dump_type(const Type* t)
223 if (t == NULL)
224 this->ostream() << "(nil type)";
225 else
226 // FIXME: write a type pretty printer instead of
227 // using mangled names.
228 if (this->gogo_ != NULL)
230 Backend_name bname;
231 t->backend_name(this->gogo_, &bname);
232 this->ostream() << "(" << bname.name() << ")";
236 // Dump a textual representation of a block to the
237 // the dump file.
239 void
240 Ast_dump_context::dump_block(Block* b)
242 Ast_dump_traverse_blocks_and_functions adtbf(this);
243 b->traverse(&adtbf);
246 // Dump a textual representation of an expression to the
247 // the dump file.
249 void
250 Ast_dump_context::dump_expression(const Expression* e)
252 e->dump_expression(this);
255 // Dump a textual representation of an expression list to the
256 // the dump file.
258 void
259 Ast_dump_context::dump_expression_list(const Expression_list* el,
260 bool as_pairs /* = false */)
262 if (el == NULL)
263 return;
265 for (std::vector<Expression*>::const_iterator it = el->begin();
266 it != el->end();
267 it++)
269 if ( it != el->begin())
270 this->ostream() << ",";
271 if (*it != NULL)
272 (*it)->dump_expression(this);
273 else
274 this->ostream() << "NULL";
275 if (as_pairs)
277 this->ostream() << ":";
278 ++it;
279 (*it)->dump_expression(this);
284 // Dump a textual representation of a typed identifier to the
285 // the dump file.
287 void
288 Ast_dump_context::dump_typed_identifier(const Typed_identifier* ti)
290 this->ostream() << ti->name() << " ";
291 this->dump_type(ti->type());
294 // Dump a textual representation of a typed identifier list to the
295 // the dump file.
297 void
298 Ast_dump_context::dump_typed_identifier_list(
299 const Typed_identifier_list* ti_list)
301 if (ti_list == NULL)
302 return;
304 for (Typed_identifier_list::const_iterator it = ti_list->begin();
305 it != ti_list->end();
306 it++)
308 if (it != ti_list->begin())
309 this->ostream() << ",";
310 this->dump_typed_identifier(&(*it));
314 // Dump a textual representation of a temporary variable to the
315 // the dump file.
317 void
318 Ast_dump_context::dump_temp_variable_name(const Statement* s)
320 go_assert(s->classification() == Statement::STATEMENT_TEMPORARY);
321 // Use the statement address as part of the name for the temporary variable.
322 this->ostream() << "tmp." << (uintptr_t) s;
325 // Dump a textual representation of a label to the
326 // the dump file.
328 void
329 Ast_dump_context::dump_label_name(const Unnamed_label* l)
331 // Use the unnamed label address as part of the name for the temporary
332 // variable.
333 this->ostream() << "label." << (uintptr_t) l;
336 // Produce a textual representation of an operator symbol.
338 static const char*
339 op_string(Operator op)
341 // FIXME: This should be in line with symbols that are parsed,
342 // exported and/or imported.
343 switch (op)
345 case OPERATOR_PLUS:
346 return "+";
347 case OPERATOR_MINUS:
348 return "-";
349 case OPERATOR_NOT:
350 return "!";
351 case OPERATOR_XOR:
352 return "^";
353 case OPERATOR_OR:
354 return "|";
355 case OPERATOR_AND:
356 return "&";
357 case OPERATOR_MULT:
358 return "*";
359 case OPERATOR_OROR:
360 return "||";
361 case OPERATOR_ANDAND:
362 return "&&";
363 case OPERATOR_EQEQ:
364 return "==";
365 case OPERATOR_NOTEQ:
366 return "!=";
367 case OPERATOR_LT:
368 return "<";
369 case OPERATOR_LE:
370 return "<=";
371 case OPERATOR_GT:
372 return ">";
373 case OPERATOR_GE:
374 return ">=";
375 case OPERATOR_DIV:
376 return "/";
377 case OPERATOR_MOD:
378 return "%";
379 case OPERATOR_LSHIFT:
380 return "<<";
381 case OPERATOR_RSHIFT:
382 return "//";
383 case OPERATOR_BITCLEAR:
384 return "&^";
385 case OPERATOR_CHANOP:
386 return "<-";
387 case OPERATOR_PLUSEQ:
388 return "+=";
389 case OPERATOR_MINUSEQ:
390 return "-=";
391 case OPERATOR_OREQ:
392 return "|=";
393 case OPERATOR_XOREQ:
394 return "^=";
395 case OPERATOR_MULTEQ:
396 return "*=";
397 case OPERATOR_DIVEQ:
398 return "/=";
399 case OPERATOR_MODEQ:
400 return "%=";
401 case OPERATOR_LSHIFTEQ:
402 return "<<=";
403 case OPERATOR_RSHIFTEQ:
404 return ">>=";
405 case OPERATOR_ANDEQ:
406 return "&=";
407 case OPERATOR_BITCLEAREQ:
408 return "&^=";
409 case OPERATOR_PLUSPLUS:
410 return "++";
411 case OPERATOR_MINUSMINUS:
412 return "--";
413 case OPERATOR_COLON:
414 return ":";
415 case OPERATOR_COLONEQ:
416 return ":=";
417 case OPERATOR_SEMICOLON:
418 return ";";
419 case OPERATOR_DOT:
420 return ".";
421 case OPERATOR_ELLIPSIS:
422 return "...";
423 case OPERATOR_COMMA:
424 return ",";
425 case OPERATOR_LPAREN:
426 return "(";
427 case OPERATOR_RPAREN:
428 return ")";
429 case OPERATOR_LCURLY:
430 return "{";
431 case OPERATOR_RCURLY:
432 return "}";
433 case OPERATOR_LSQUARE:
434 return "[";
435 case OPERATOR_RSQUARE:
436 return "]";
437 default:
438 go_unreachable();
440 return NULL;
443 // Dump a textual representation of an operator to the
444 // the dump file.
446 void
447 Ast_dump_context::dump_operator(Operator op)
449 this->ostream() << op_string(op);
452 // Size of a single indent.
454 const int Ast_dump_context::offset_ = 2;
456 // Print indenting spaces to dump file.
458 void
459 Ast_dump_context::print_indent()
461 for (int i = 0; i < this->indent_ * this->offset_; i++)
462 this->ostream() << " ";
465 // Dump a textual representation of the ast to the
466 // the dump file.
468 void Gogo::dump_ast(const char* basename)
470 if (::ast_dump_flag.is_enabled())
472 Ast_dump_context adc;
473 adc.dump(this, basename);
477 // Implementation of String_dump interface.
479 void
480 Ast_dump_context::write_c_string(const char* s)
482 this->ostream() << s;
485 void
486 Ast_dump_context::write_string(const std::string& s)
488 this->ostream() << s;
491 // Dump statement to stream.
493 void
494 Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
496 Ast_dump_context adc(out, false);
497 stm->dump_statement(&adc);
500 // Dump expression to stream.
502 void
503 Ast_dump_context::dump_to_stream(const Expression* expr, std::ostream* out)
505 Ast_dump_context adc(out, false);
506 expr->dump_expression(&adc);
509 // Dump an expression to std::cerr. This is intended to be used
510 // from within a debugging session.
512 void
513 debug_go_expression(const Expression* expr)
515 if (expr == NULL)
516 std::cerr << "<null>";
517 else
519 Ast_dump_context::dump_to_stream(expr, &std::cerr);
520 std::string lstr = Linemap::location_to_string(expr->location());
521 std::cerr << " // loc " << lstr << std::endl;
525 // Shallow dump of stmt to std::cerr. This is intended to be used
526 // from within a debugging session.
528 void
529 debug_go_statement(const Statement* stmt)
531 if (stmt == NULL)
532 std::cerr << "<null>\n";
533 else
535 std::string lstr = Linemap::location_to_string(stmt->location());
536 Statement *ncstmt = const_cast<Statement*>(stmt);
537 Block_statement* bs = ncstmt->block_statement();
538 if (bs != NULL)
539 std::cerr << "Block " << bs->block()
540 << " // location: " << lstr << std::endl;
541 else
542 Ast_dump_context::dump_to_stream(stmt, &std::cerr);
546 // Deep dump of statement to std::cerr. This is intended to be used
547 // from within a debugging session.
549 void
550 debug_go_statement_deep(const Statement* statement)
552 Ast_dump_context adc(&std::cerr, true);
553 statement->dump_statement(&adc);
556 // Shallow dump of a block to std::cerr. This is intended to be used
557 // from within a debugging session.
559 void
560 debug_go_block(const Block* block)
562 if (block == NULL)
563 std::cerr << "<null>";
564 else
566 std::cerr << "Block " << block
567 << " (enclosing " << block->enclosing() << "):\n";
568 const std::vector<Statement*>* stmts = block->statements();
569 if (stmts != NULL)
571 for (size_t i = 0; i < stmts->size(); ++i)
573 debug_go_statement(stmts->at(i));
579 // Deep dump of a block to std:cerr. This is intended to be used
580 // from within a debugging session.
582 void
583 debug_go_block_deep(const Block* block)
585 Ast_dump_context adc(&std::cerr, true);
586 Block* ncblock = const_cast<Block*>(block);
587 adc.dump_block(ncblock);
590 class Type_dumper
592 typedef Unordered_map(const Type*, unsigned) idx_map;
593 public:
594 Type_dumper(const Type* type)
595 : top_(type), ntypes_(0)
597 this->worklist_.push_back(type);
600 void visit();
602 std::string stringResult() { return ss_.str(); }
604 private:
605 void emitpre(unsigned tag, const Type* addr);
606 void typeref(const char*, const Type*, const char *);
607 void visit_forward_declaration_type(const Forward_declaration_type* fdt);
608 void visit_function_type(const Function_type* ft);
609 void visit_struct_type(const Struct_type* st);
610 void visit_array_type(const Array_type* at);
611 void visit_map_type(const Map_type* mt);
612 void visit_channel_type(const Channel_type* mt);
613 void visit_interface_type(const Interface_type* mt);
614 void visit_methods(const Typed_identifier_list* methods,
615 const char *tag);
616 std::pair<bool, unsigned> lookup(const Type*);
618 static const unsigned notag = 0xffffffff;
620 private:
621 const Type* top_;
622 idx_map types_;
623 unsigned ntypes_;
624 std::list<const Type*> worklist_;
625 std::ostringstream ss_;
628 // Look up a type, installing it in 'types_'. Return is <found, N>
629 // where 'found' is true if type had been previously recorded, and N
630 // is the index/tag assigned to N. The input argument is appended to
631 // the work list if this is the first time we've seen it.
633 std::pair<bool, unsigned> Type_dumper::lookup(const Type* t)
635 std::pair<const Type*, unsigned> entry = std::make_pair(t, this->ntypes_);
636 std::pair<idx_map::iterator, bool> ins = this->types_.insert(entry);
637 if (ins.second)
639 this->ntypes_++;
640 if (t != this->top_)
641 this->worklist_.push_back(t);
643 return std::make_pair(ins.second, ins.first->second);
646 // Emit preamble prior to dumping a type, including the type
647 // pointer itself and the tag we've assigned it. If no
648 // tag is specified (via special "notag" value) and/or the
649 // pointer is null, then just emit an equivalent amount
650 // of spaces.
652 void Type_dumper::emitpre(unsigned tag, const Type* ptr)
654 char tbuf[50], pbuf[50], buf[200];
656 tbuf[0] = '\0';
657 if (tag != notag)
658 snprintf(tbuf, sizeof tbuf, "T%u", tag);
660 pbuf[0] = '\0';
661 if (ptr != NULL)
662 snprintf(pbuf, sizeof pbuf, "%p", (const void*) ptr);
664 snprintf(buf, sizeof buf, "%8s %16s ", tbuf, pbuf);
665 this->ss_ << buf;
668 // Emit a reference to a type into the dump buffer. In most cases this means
669 // just the type tag, but for named types we also emit the name, and for
670 // simple/primitive types (ex: int64) we emit the type itself. If "pref" is
671 // non-NULL, emit the string prior to the reference, and if "suf" is non-NULL,
672 // emit it following the reference.
674 void Type_dumper::typeref(const char* pref, const Type* t, const char* suf)
676 if (pref != NULL)
677 this->ss_ << pref;
678 std::pair<bool, unsigned> p = this->lookup(t);
679 unsigned tag = p.second;
680 switch (t->classification())
682 case Type::TYPE_NAMED:
684 const Named_type* nt = t->named_type();
685 const Named_object* no = nt->named_object();
686 this->ss_ << "'" << no->message_name() << "' -> ";
687 const Type* underlying = nt->real_type();
688 this->typeref(NULL, underlying, NULL);
689 break;
691 case Type::TYPE_POINTER:
692 this->typeref("*", t->points_to(), NULL);
693 break;
694 case Type::TYPE_ERROR:
695 this->ss_ << "error_type";
696 break;
697 case Type::TYPE_INTEGER:
699 const Integer_type* it = t->integer_type();
700 if (it->is_abstract())
701 this->ss_ << "abstract_int";
702 else
703 this->ss_ << (it->is_unsigned() ? "u" : "") << "int" << it->bits();
704 break;
706 case Type::TYPE_FLOAT:
708 const Float_type* ft = t->float_type();
709 if (ft->is_abstract())
710 this->ss_ << "abstract_float";
711 else
712 this->ss_ << "float" << ft->bits();
713 break;
715 case Type::TYPE_COMPLEX:
717 const Complex_type* ct = t->complex_type();
718 if (ct->is_abstract())
719 this->ss_ << "abstract_complex";
720 else
721 this->ss_ << "complex" << ct->bits();
722 break;
724 case Type::TYPE_BOOLEAN:
725 this->ss_ << "bool";
726 break;
727 case Type::TYPE_STRING:
728 this->ss_ << "string";
729 break;
730 case Type::TYPE_NIL:
731 this->ss_ << "nil_type";
732 break;
733 case Type::TYPE_VOID:
734 this->ss_ << "void_type";
735 break;
736 case Type::TYPE_FUNCTION:
737 case Type::TYPE_STRUCT:
738 case Type::TYPE_ARRAY:
739 case Type::TYPE_MAP:
740 case Type::TYPE_CHANNEL:
741 case Type::TYPE_FORWARD:
742 case Type::TYPE_INTERFACE:
743 this->ss_ << "T" << tag;
744 break;
746 default:
747 // This is a debugging routine, so instead of a go_unreachable()
748 // issue a warning/error, to allow for the possibility that the
749 // compiler we're debugging is in a bad state.
750 this->ss_ << "<??? " << ((unsigned)t->classification()) << "> "
751 << "T" << tag;
753 if (suf != NULL)
754 this->ss_ << suf;
757 void Type_dumper::visit_forward_declaration_type(const Forward_declaration_type* fdt)
759 this->ss_ << "forward_declaration_type ";
760 if (fdt->is_defined())
761 this->typeref("-> ", fdt->real_type(), NULL);
762 else
763 this->ss_ << "'" << fdt->name() << "'";
764 this->ss_ << "\n";
767 void Type_dumper::visit_function_type(const Function_type* ft)
769 this->ss_ << "function\n";
770 const Typed_identifier* rec = ft->receiver();
771 if (rec != NULL)
773 this->emitpre(notag, NULL);
774 this->typeref("receiver ", rec->type(), "\n");
776 const Typed_identifier_list* parameters = ft->parameters();
777 if (parameters != NULL)
779 for (Typed_identifier_list::const_iterator p = parameters->begin();
780 p != parameters->end();
781 ++p)
783 this->emitpre(notag, NULL);
784 this->typeref(" param ", p->type(), "\n");
787 const Typed_identifier_list* results = ft->results();
788 if (results != NULL)
790 for (Typed_identifier_list::const_iterator p = results->begin();
791 p != results->end();
792 ++p)
794 this->emitpre(notag, NULL);
795 this->typeref(" result ", p->type(), "\n");
800 void Type_dumper::visit_struct_type(const Struct_type* st)
802 this->ss_ << "struct\n";
803 const Struct_field_list* fields = st->fields();
804 if (fields != NULL)
806 for (Struct_field_list::const_iterator p = fields->begin();
807 p != fields->end();
808 ++p)
810 this->emitpre(notag, NULL);
811 this->typeref(" field ", p->type(), "\n");
816 void Type_dumper::visit_array_type(const Array_type* at)
818 this->ss_ << "array [";
819 if (at->length() != NULL)
821 int64_t len = 0;
822 if (at->int_length(&len))
823 this->ss_ << len;
825 this->typeref("] ", at->element_type(), "\n");
828 void Type_dumper::visit_map_type(const Map_type* mt)
830 this->ss_ << "map [";
831 this->typeref(NULL, mt->key_type(), NULL);
832 this->typeref("] ", mt->val_type(), "\n");
835 void Type_dumper::visit_methods(const Typed_identifier_list* methods,
836 const char *tag)
838 if (tag != NULL)
840 this->emitpre(notag, NULL);
841 this->ss_ << tag << "\n";
843 for (Typed_identifier_list::const_iterator p = methods->begin();
844 p != methods->end();
845 ++p)
847 this->emitpre(notag, NULL);
848 if (p->name().empty())
849 this->typeref(" embedded method ", p->type(), "\n");
850 else
852 this->ss_ << " method '" << p->name() << "' ";
853 this->typeref(NULL, p->type(), "\n");
858 void Type_dumper::visit_interface_type(const Interface_type* it)
860 const Typed_identifier_list* methods =
861 (it->methods_are_finalized() ? it->methods() : it->local_methods());
862 if (methods == NULL)
864 this->ss_ << "empty_interface\n";
865 return;
867 this->ss_ << "interface";
868 if (! it->methods_are_finalized())
870 this->ss_ << " [unfinalized]\n";
871 visit_methods(it->local_methods(), NULL);
873 else
875 this->ss_ << "\n";
876 visit_methods(it->local_methods(), "[parse_methods]");
877 visit_methods(it->methods(), "[all_methods]");
881 void Type_dumper::visit_channel_type(const Channel_type* ct)
883 this->ss_ << "channel {";
884 if (ct->may_send())
885 this->ss_ << " send";
886 if (ct->may_receive())
887 this->ss_ << " receive";
888 this->typeref(" } ", ct->element_type(), "\n");
891 void Type_dumper::visit()
893 while (! this->worklist_.empty()) {
894 const Type* t = this->worklist_.front();
895 this->worklist_.pop_front();
897 std::pair<bool, unsigned> p = this->lookup(t);
898 unsigned tag = p.second;
899 this->emitpre(tag, t);
901 switch(t->classification())
903 case Type::TYPE_ERROR:
904 case Type::TYPE_INTEGER:
905 case Type::TYPE_FLOAT:
906 case Type::TYPE_COMPLEX:
907 case Type::TYPE_BOOLEAN:
908 case Type::TYPE_STRING:
909 case Type::TYPE_VOID:
910 case Type::TYPE_POINTER:
911 case Type::TYPE_NIL:
912 case Type::TYPE_NAMED:
913 this->typeref(NULL, t, "\n");
914 break;
915 case Type::TYPE_FORWARD:
916 this->visit_forward_declaration_type(t->forward_declaration_type());
917 break;
919 case Type::TYPE_FUNCTION:
920 this->visit_function_type(t->function_type());
921 break;
922 case Type::TYPE_STRUCT:
923 this->visit_struct_type(t->struct_type());
924 break;
925 case Type::TYPE_ARRAY:
926 this->visit_array_type(t->array_type());
927 break;
928 case Type::TYPE_MAP:
929 this->visit_map_type(t->map_type());
930 break;
931 case Type::TYPE_CHANNEL:
932 this->visit_channel_type(t->channel_type());
933 break;
934 case Type::TYPE_INTERFACE:
935 this->visit_interface_type(t->interface_type());
936 break;
937 default:
938 // This is a debugging routine, so instead of a go_unreachable()
939 // issue a warning/error, to allow for the possibility that the
940 // compiler we're debugging is in a bad state.
941 this->ss_ << "<unknown/unrecognized classification "
942 << ((unsigned)t->classification()) << ">\n";
947 // Dump a Go type for debugging purposes. This is a deep as opposed
948 // to shallow dump; all of the types reachable from the specified
949 // type will be dumped in addition to the type itself.
951 void debug_go_type(const Type* type)
953 if (type == NULL)
955 std::cerr << "<NULL type>\n";
956 return;
958 Type_dumper dumper(type);
959 dumper.visit();
960 std::cerr << dumper.stringResult();
963 void debug_go_type(Type* type)
965 const Type* ctype = type;
966 debug_go_type(ctype);