Commit 16c57fe2 by Roberto Lublinerman Committed by Ian Lance Taylor

gccgo: Added code to dump the AST tree.

gccgo:	Added code to dump the AST tree. The AST dump is
	activated with -fgo-dump-ast.
	Initial version, it only dumps (most) constructs that
	are expected after the lowering transformation.

	* Make-lang.in (GO_OBJS): Add go/ast-dump.o.
	(go/ast-dump.o): New target.
	(go/expressions.o): Depend on go/gofrontend/ast-dump.h.
	(go/statements.o): Likewise.

From-SVN: r177225
parent 44e7bfcb
2011-08-02 Roberto Lublinerman <rluble@gmail.com>
* Make-lang.in (GO_OBJS): Add go/ast-dump.o.
(go/ast-dump.o): New target.
(go/expressions.o): Depend on go/gofrontend/ast-dump.h.
(go/statements.o): Likewise.
2011-07-06 Richard Guenther <rguenther@suse.de> 2011-07-06 Richard Guenther <rguenther@suse.de>
* go-lang.c (go_langhook_init): * go-lang.c (go_langhook_init):
......
...@@ -45,6 +45,7 @@ gccgo$(exeext): $(GCCGO_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS) ...@@ -45,6 +45,7 @@ gccgo$(exeext): $(GCCGO_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
go-warn = $(STRICT_WARN) go-warn = $(STRICT_WARN)
GO_OBJS = \ GO_OBJS = \
go/ast-dump.o \
go/dataflow.o \ go/dataflow.o \
go/export.o \ go/export.o \
go/expressions.o \ go/expressions.o \
...@@ -247,6 +248,9 @@ go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H) $(TREE_H) tree-iterator.h \ ...@@ -247,6 +248,9 @@ go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H) $(TREE_H) tree-iterator.h \
go/%.o: go/gofrontend/%.cc go/%.o: go/gofrontend/%.cc
$(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION) $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
go/ast-dump.o: go/gofrontend/ast-dump.cc $(GO_SYSTME_H) $(GO_GOGO_H) \
$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_TYPES_H) \
go/gofrontend/ast-dump.h $(GO_C_H) go/gofrontend/go-dump.h
go/dataflow.o: go/gofrontend/dataflow.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \ go/dataflow.o: go/gofrontend/dataflow.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \
$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) go/gofrontend/dataflow.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) go/gofrontend/dataflow.h
go/export.o: go/gofrontend/export.cc $(GO_SYSTEM_H) \ go/export.o: go/gofrontend/export.cc $(GO_SYSTEM_H) \
...@@ -256,7 +260,8 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \ ...@@ -256,7 +260,8 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \ intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \
realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \ realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \ go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H) $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H) \
go/gofrontend/ast-dump.h
go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \ go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
$(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H) $(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H)
go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \ go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
...@@ -285,7 +290,8 @@ go/runtime.o: go/gofrontend/runtime.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \ ...@@ -285,7 +290,8 @@ go/runtime.o: go/gofrontend/runtime.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \
go/gofrontend/runtime.def go/gofrontend/runtime.def
go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) \ go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) \
$(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \ $(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \
$(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H) $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H) \
go/gofrontend/ast-dump.h
go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \ go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \
$(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \ $(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \
go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \ go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \
......
// ast-dump.cc -- AST debug dump. -*- C++ -*-
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go-system.h"
#include <iostream>
#include <fstream>
#include "gogo.h"
#include "expressions.h"
#include "statements.h"
#include "types.h"
#include "ast-dump.h"
#include "go-c.h"
#include "go-dump.h"
// The -fgo-dump-ast flag to activate AST dumps.
Go_dump ast_dump_context_flag("ast");
// This class is used to traverse the tree to look for blocks and
// function headers.
class Ast_dump_traverse_blocks_and_functions : public Traverse
{
public:
Ast_dump_traverse_blocks_and_functions(Ast_dump_context* ast_dump_context)
: Traverse(traverse_blocks | traverse_functions),
ast_dump_context_(ast_dump_context)
{ }
protected:
int
block(Block*);
int
function(Named_object*);
private:
Ast_dump_context* ast_dump_context_;
};
// This class is used to traverse the tree to look for statements.
class Ast_dump_traverse_statements : public Traverse
{
public:
Ast_dump_traverse_statements(Ast_dump_context* ast_dump_context)
: Traverse(traverse_statements),
ast_dump_context_(ast_dump_context)
{ }
protected:
int
statement(Block*, size_t* pindex, Statement*);
private:
Ast_dump_context* ast_dump_context_;
};
// For each block we enclose it in brackets.
int Ast_dump_traverse_blocks_and_functions::block(Block * block)
{
this->ast_dump_context_->print_indent();
this->ast_dump_context_->ostream() << "{" << std::endl;
this->ast_dump_context_->indent();
// Dump statememts.
Ast_dump_traverse_statements adts(this->ast_dump_context_);
block->traverse(&adts);
this->ast_dump_context_->unindent();
this->ast_dump_context_->print_indent();
this->ast_dump_context_->ostream() << "}" << std::endl;
return TRAVERSE_SKIP_COMPONENTS;
}
// Dump each traversed statement.
int
Ast_dump_traverse_statements::statement(Block* block, size_t* pindex,
Statement* statement)
{
statement->dump_statement(this->ast_dump_context_);
if (statement->is_block_statement())
{
Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
statement->traverse(block, pindex, &adtbf);
}
return TRAVERSE_SKIP_COMPONENTS;
}
// Dump the function header.
int
Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
{
this->ast_dump_context_->ostream() << no->name();
go_assert(no->is_function());
Function* func = no->func_value();
this->ast_dump_context_->ostream() << "(";
this->ast_dump_context_->dump_typed_identifier_list(
func->type()->parameters());
this->ast_dump_context_->ostream() << ")";
Function::Results* res = func->result_variables();
if (res != NULL && !res->empty())
{
this->ast_dump_context_->ostream() << " (";
for (Function::Results::const_iterator it = res->begin();
it != res->end();
it++)
{
if (it != res->begin())
this->ast_dump_context_->ostream() << ",";
Named_object* no = (*it);
this->ast_dump_context_->ostream() << no->name() << " ";
go_assert(no->is_result_variable());
Result_variable* resvar = no->result_var_value();
this->ast_dump_context_->dump_type(resvar->type());
}
this->ast_dump_context_->ostream() << ")";
}
this->ast_dump_context_->ostream() << " : ";
this->ast_dump_context_->dump_type(func->type());
this->ast_dump_context_->ostream() << std::endl;
return TRAVERSE_CONTINUE;
}
// Class Ast_dump_context.
Ast_dump_context::Ast_dump_context() : ostream_(NULL)
{
}
// Dump files will be named %basename%.dump.ast
const char* kAstDumpFileExtension = ".dump.ast";
// Dump the internal representation.
void
Ast_dump_context::dump(Gogo* gogo, const char* basename)
{
std::ofstream* out = new std::ofstream();
std::string dumpname(basename);
dumpname += ".dump.ast";
out->open(dumpname.c_str());
if (out->fail())
{
error("cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
return;
}
this->indent_ = 0;
this->gogo_ = gogo;
this->ostream_ = out;
Ast_dump_traverse_blocks_and_functions adtbf(this);
gogo->traverse(&adtbf);
out->close();
}
// Dump a textual representation of a type to the
// the dump file.
void
Ast_dump_context::dump_type(const Type* t)
{
if (t == NULL)
this->ostream() << "(nil type)";
else
// FIXME: write a type pretty printer instead of
// using mangled names.
this->ostream() << "(" << t->mangled_name(this->gogo_) << ")";
}
// Dump a textual representation of a block to the
// the dump file.
void
Ast_dump_context::dump_block(Block* b)
{
Ast_dump_traverse_blocks_and_functions adtbf(this);
b->traverse(&adtbf);
}
// Dump a textual representation of an expression to the
// the dump file.
void
Ast_dump_context::dump_expression(const Expression* e)
{
e->dump_expression(this);
}
// Dump a textual representation of an expression list to the
// the dump file.
void
Ast_dump_context::dump_expression_list(const Expression_list* el)
{
if (el == NULL)
return;
for (std::vector<Expression*>::const_iterator it = el->begin();
it != el->end();
it++)
{
if ( it != el->begin())
this->ostream() << ",";
(*it)->dump_expression(this);
}
}
// Dump a textual representation of a typed identifier to the
// the dump file.
void
Ast_dump_context::dump_typed_identifier(const Typed_identifier* ti)
{
this->ostream() << ti->name() << " ";
this->dump_type(ti->type());
}
// Dump a textual representation of a typed identifier list to the
// the dump file.
void
Ast_dump_context::dump_typed_identifier_list(
const Typed_identifier_list* ti_list)
{
if (ti_list == NULL)
return;
for (Typed_identifier_list::const_iterator it = ti_list->begin();
it != ti_list->end();
it++)
{
if (it != ti_list->begin())
this->ostream() << ",";
this->dump_typed_identifier(&(*it));
}
}
// Dump a textual representation of a temporary variable to the
// the dump file.
void
Ast_dump_context::dump_temp_variable_name(const Statement* s)
{
go_assert(s->classification() == Statement::STATEMENT_TEMPORARY);
// Use the statement address as part of the name for the temporary variable.
this->ostream() << "tmp." << (uintptr_t) s;
}
// Dump a textual representation of a label to the
// the dump file.
void
Ast_dump_context::dump_label_name(const Unnamed_label* l)
{
// Use the unnamed label address as part of the name for the temporary
// variable.
this->ostream() << "label." << (uintptr_t) l;
}
// Produce a textual representation of an operator symbol.
static const char*
op_string(Operator op)
{
// FIXME: This should be in line with symbols that are parsed,
// exported and/or imported.
switch (op)
{
case OPERATOR_PLUS:
return "+";
case OPERATOR_MINUS:
return "-";
case OPERATOR_NOT:
return "!";
case OPERATOR_XOR:
return "^";
case OPERATOR_AND:
return "&";
case OPERATOR_MULT:
return "*";
case OPERATOR_OROR:
return "||";
case OPERATOR_ANDAND:
return "&&";
case OPERATOR_EQEQ:
return "==";
case OPERATOR_NOTEQ:
return "!=";
case OPERATOR_LT:
return "<";
case OPERATOR_LE:
return "<=";
case OPERATOR_GT:
return ">";
case OPERATOR_GE:
return ">=";
case OPERATOR_DIV:
return "/";
case OPERATOR_MOD:
return "%";
case OPERATOR_LSHIFT:
return "<<";
case OPERATOR_RSHIFT:
return "//";
case OPERATOR_BITCLEAR:
return "&^";
case OPERATOR_CHANOP:
return "<-";
case OPERATOR_PLUSEQ:
return "+=";
case OPERATOR_MINUSEQ:
return "-=";
case OPERATOR_OREQ:
return "|=";
case OPERATOR_XOREQ:
return "^=";
case OPERATOR_MULTEQ:
return "*=";
case OPERATOR_DIVEQ:
return "/=";
case OPERATOR_MODEQ:
return "%=";
case OPERATOR_LSHIFTEQ:
return "<<=";
case OPERATOR_RSHIFTEQ:
return ">>=";
case OPERATOR_ANDEQ:
return "&=";
case OPERATOR_BITCLEAREQ:
return "&^=";
case OPERATOR_PLUSPLUS:
return "++";
case OPERATOR_MINUSMINUS:
return "--";
case OPERATOR_COLON:
return ":";
case OPERATOR_COLONEQ:
return ":=";
case OPERATOR_SEMICOLON:
return ";";
case OPERATOR_DOT:
return ".";
case OPERATOR_ELLIPSIS:
return "...";
case OPERATOR_COMMA:
return ",";
case OPERATOR_LPAREN:
return "(";
case OPERATOR_RPAREN:
return ")";
case OPERATOR_LCURLY:
return "{";
case OPERATOR_RCURLY:
return "}";
case OPERATOR_LSQUARE:
return "[";
case OPERATOR_RSQUARE:
return "]";
default:
go_unreachable();
}
return NULL;
}
// Dump a textual representation of an operator to the
// the dump file.
void
Ast_dump_context::dump_operator(Operator op)
{
this->ostream() << op_string(op);
}
// Size of a single indent.
const int Ast_dump_context::offset_ = 2;
// Print indenting spaces to dump file.
void
Ast_dump_context::print_indent()
{
for (int i = 0; i < this->indent_ * this->offset_; i++)
this->ostream() << " ";
}
// Dump a textual representation of the ast to the
// the dump file.
void Gogo::dump_ast(const char* basename)
{
if (ast_dump_context_flag.is_enabled())
{
Ast_dump_context adc;
adc.dump(this, basename);
}
}
// ast-dump.h -- AST debug dump. -*- C++ -*-
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#ifndef GO_AST_DUMP_H
#define GO_AST_DUMP_H
class Expression;
class Expression_list;
class Named_object;
class Statement;
class Gogo;
// This class implements fgo-dump-ast. the
// Abstract syntax tree dump of the Go program.
class Ast_dump_context
{
public:
Ast_dump_context();
// Initialize the dump context.
void
dump(Gogo*, const char* basename);
// Dump spaces to dumpfile as indentation.
void
print_indent();
// Increase current indentation for print_indent().
void
indent()
{ ++this->indent_;}
// Decrease current indentation for print_indent().
void
unindent()
{ --this->indent_;}
// Get dump output stream.
std::ostream&
ostream()
{ return *this->ostream_;}
// Dump a Block to dump file.
void
dump_block(Block*);
// Dump a type to dump file.
void
dump_type(const Type*);
// Dump an expression to dump file.
void
dump_expression(const Expression*);
// Dump an expression list to dump file.
void
dump_expression_list(const Expression_list*);
// Dump a typed identifier to dump file.
void
dump_typed_identifier(const Typed_identifier*);
// Dump a typed identifier list to dump file.
void
dump_typed_identifier_list(const Typed_identifier_list*);
// Dump temporary variable name to dump file.
void
dump_temp_variable_name(const Statement*);
// Dump unamed lable name to dump file.
void
dump_label_name(const Unnamed_label*);
// Dump operator symbol to dump file.
void
dump_operator(Operator);
private:
// Current indent level.
int indent_;
// Indentation offset.
static const int offset_;
// Stream on output dump file.
std::ostream* ostream_;
Gogo* gogo_;
};
#endif // GO_AST_DUMP_H
...@@ -36,6 +36,7 @@ extern "C" ...@@ -36,6 +36,7 @@ extern "C"
#include "runtime.h" #include "runtime.h"
#include "backend.h" #include "backend.h"
#include "expressions.h" #include "expressions.h"
#include "ast-dump.h"
// Class Expression. // Class Expression.
...@@ -790,6 +791,12 @@ Expression::check_bounds(tree val, tree bound_type, tree sofar, ...@@ -790,6 +791,12 @@ Expression::check_bounds(tree val, tree bound_type, tree sofar,
sofar, ret); sofar, ret);
} }
void
Expression::dump_expression(Ast_dump_context* ast_dump_context) const
{
this->do_dump_expression(ast_dump_context);
}
// Error expressions. This are used to avoid cascading errors. // Error expressions. This are used to avoid cascading errors.
class Error_expression : public Expression class Error_expression : public Expression
...@@ -849,8 +856,19 @@ class Error_expression : public Expression ...@@ -849,8 +856,19 @@ class Error_expression : public Expression
tree tree
do_get_tree(Translate_context*) do_get_tree(Translate_context*)
{ return error_mark_node; } { return error_mark_node; }
void
do_dump_expression(Ast_dump_context*) const;
}; };
// Dump the ast representation for an error expression to a dump context.
void
Error_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "_Error_" ;
}
Expression* Expression*
Expression::make_error(source_location location) Expression::make_error(source_location location)
{ {
...@@ -894,11 +912,19 @@ Type_expression : public Expression ...@@ -894,11 +912,19 @@ Type_expression : public Expression
do_get_tree(Translate_context*) do_get_tree(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void do_dump_expression(Ast_dump_context*) const;
private: private:
// The type which we are representing as an expression. // The type which we are representing as an expression.
Type* type_; Type* type_;
}; };
void
Type_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_type(this->type_);
}
Expression* Expression*
Expression::make_type(Type* type, source_location location) Expression::make_type(Type* type, source_location location)
{ {
...@@ -1018,6 +1044,14 @@ Var_expression::do_get_tree(Translate_context* context) ...@@ -1018,6 +1044,14 @@ Var_expression::do_get_tree(Translate_context* context)
return ret; return ret;
} }
// Ast dump for variable expression.
void
Var_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << this->variable_->name() ;
}
// Make a reference to a variable in an expression. // Make a reference to a variable in an expression.
Expression* Expression*
...@@ -1076,6 +1110,15 @@ Temporary_reference_expression::do_get_tree(Translate_context* context) ...@@ -1076,6 +1110,15 @@ Temporary_reference_expression::do_get_tree(Translate_context* context)
return ret; return ret;
} }
// Ast dump for temporary reference.
void
Temporary_reference_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_temp_variable_name(this->statement_);
}
// Make a reference to a temporary variable. // Make a reference to a temporary variable.
Temporary_reference_expression* Temporary_reference_expression*
...@@ -1113,6 +1156,9 @@ class Sink_expression : public Expression ...@@ -1113,6 +1156,9 @@ class Sink_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type of this sink variable. // The type of this sink variable.
Type* type_; Type* type_;
...@@ -1154,6 +1200,14 @@ Sink_expression::do_get_tree(Translate_context* context) ...@@ -1154,6 +1200,14 @@ Sink_expression::do_get_tree(Translate_context* context)
return this->var_; return this->var_;
} }
// Ast dump for sink expression.
void
Sink_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "_" ;
}
// Make a sink expression. // Make a sink expression.
Expression* Expression*
...@@ -1286,6 +1340,14 @@ Func_expression::do_get_tree(Translate_context* context) ...@@ -1286,6 +1340,14 @@ Func_expression::do_get_tree(Translate_context* context)
return gogo->make_trampoline(fnaddr, closure_tree, this->location()); return gogo->make_trampoline(fnaddr, closure_tree, this->location());
} }
// Ast dump for function.
void
Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << this->function_->name() ;
}
// Make a reference to a function in an expression. // Make a reference to a function in an expression.
Expression* Expression*
...@@ -1354,6 +1416,16 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int) ...@@ -1354,6 +1416,16 @@ Unknown_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
} }
} }
// Dump the ast representation for an unknown expression to a dump context.
void
Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
<< ")";
}
// Make a reference to an unknown name. // Make a reference to an unknown name.
Expression* Expression*
...@@ -1399,6 +1471,10 @@ class Boolean_expression : public Expression ...@@ -1399,6 +1471,10 @@ class Boolean_expression : public Expression
do_export(Export* exp) const do_export(Export* exp) const
{ exp->write_c_string(this->val_ ? "true" : "false"); } { exp->write_c_string(this->val_ ? "true" : "false"); }
void
do_dump_expression(Ast_dump_context* ast_dump_context) const
{ ast_dump_context->ostream() << (this->val_ ? "true" : "false"); }
private: private:
// The constant. // The constant.
bool val_; bool val_;
...@@ -1566,6 +1642,15 @@ String_expression::do_import(Import* imp) ...@@ -1566,6 +1642,15 @@ String_expression::do_import(Import* imp)
return Expression::make_string(val, imp->location()); return Expression::make_string(val, imp->location());
} }
// Ast dump for string expression.
void
String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
// FIXME: Do proper backshlash quoting for this->val_
ast_dump_context->ostream() << "\"" << this->val_ << "\"";
}
// Make a string expression. // Make a string expression.
Expression* Expression*
...@@ -1595,6 +1680,10 @@ class Integer_expression : public Expression ...@@ -1595,6 +1680,10 @@ class Integer_expression : public Expression
static void static void
export_integer(Export* exp, const mpz_t val); export_integer(Export* exp, const mpz_t val);
// Write VAL to dump context.
static void
dump_integer(Ast_dump_context* ast_dump_context, const mpz_t val);
protected: protected:
bool bool
do_is_constant() const do_is_constant() const
...@@ -1623,6 +1712,9 @@ class Integer_expression : public Expression ...@@ -1623,6 +1712,9 @@ class Integer_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The integer value. // The integer value.
mpz_t val_; mpz_t val_;
...@@ -1871,6 +1963,28 @@ Integer_expression::do_import(Import* imp) ...@@ -1871,6 +1963,28 @@ Integer_expression::do_import(Import* imp)
} }
} }
// Write integer to dump context.
void
Integer_expression::dump_integer(Ast_dump_context* ast_dump_context,
const mpz_t val)
{
// FIXME: refactor this code so that is used both by dump and export. Extract
// a common interface for Ast_dump_context and Export.
char* s = mpz_get_str(NULL, 10, val);
ast_dump_context->ostream() << s ;
free(s);
}
// Ast dump for integer expression.
void
Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
Integer_expression::dump_integer(ast_dump_context, this->val_);
}
// Build a new integer value. // Build a new integer value.
Expression* Expression*
...@@ -1903,6 +2017,10 @@ class Float_expression : public Expression ...@@ -1903,6 +2017,10 @@ class Float_expression : public Expression
// Write VAL to export data. // Write VAL to export data.
static void static void
export_float(Export* exp, const mpfr_t val); export_float(Export* exp, const mpfr_t val);
// Write VAL to dump file.
static void
dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
protected: protected:
bool bool
...@@ -1932,6 +2050,9 @@ class Float_expression : public Expression ...@@ -1932,6 +2050,9 @@ class Float_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The floating point value. // The floating point value.
mpfr_t val_; mpfr_t val_;
...@@ -2109,6 +2230,35 @@ Float_expression::do_export(Export* exp) const ...@@ -2109,6 +2230,35 @@ Float_expression::do_export(Export* exp) const
exp->write_c_string(" "); exp->write_c_string(" ");
} }
// Write a floating point number to a dump context.
void
Float_expression::dump_float(Ast_dump_context* ast_dump_context,
const mpfr_t val)
{
// FIXME: this code should be refactored so that the same code is used here
// and in export_float.
mp_exp_t exponent;
char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
if (*s == '-')
ast_dump_context->ostream() << "-";
ast_dump_context->ostream() << "0.";
ast_dump_context->ostream() << (*s == '-' ? s + 1 : s);
mpfr_free_str(s);
char buf[30];
snprintf(buf, sizeof buf, "E%ld", exponent);
ast_dump_context->ostream() << buf;
}
// Dump a floating point number to the dump file.
void
Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
Float_expression::dump_float(ast_dump_context, this->val_);
}
// Make a float expression. // Make a float expression.
Expression* Expression*
...@@ -2143,6 +2293,11 @@ class Complex_expression : public Expression ...@@ -2143,6 +2293,11 @@ class Complex_expression : public Expression
static void static void
export_complex(Export* exp, const mpfr_t real, const mpfr_t val); export_complex(Export* exp, const mpfr_t real, const mpfr_t val);
// Write REAL/IMAG to dump context.
static void
dump_complex(Ast_dump_context* ast_dump_context,
const mpfr_t real, const mpfr_t val);
protected: protected:
bool bool
do_is_constant() const do_is_constant() const
...@@ -2173,6 +2328,9 @@ class Complex_expression : public Expression ...@@ -2173,6 +2328,9 @@ class Complex_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The real part. // The real part.
mpfr_t real_; mpfr_t real_;
...@@ -2342,6 +2500,34 @@ Complex_expression::do_export(Export* exp) const ...@@ -2342,6 +2500,34 @@ Complex_expression::do_export(Export* exp) const
exp->write_c_string(" "); exp->write_c_string(" ");
} }
// Write a complex number to a dump context.
void
Complex_expression::dump_complex(Ast_dump_context* ast_dump_context,
const mpfr_t real, const mpfr_t imag)
{
// FIXME: this code should be refactored so that it is used both here
// and by export _complex
if (!mpfr_zero_p(real))
{
Float_expression::dump_float(ast_dump_context, real);
if (mpfr_sgn(imag) > 0)
ast_dump_context->ostream() << "+";
}
Float_expression::dump_float(ast_dump_context, imag);
ast_dump_context->ostream() << "i";
}
// Dump a complex expression to the dump file.
void
Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
Complex_expression::dump_complex(ast_dump_context,
this->real_,
this->imag_);
}
// Make a complex expression. // Make a complex expression.
Expression* Expression*
...@@ -2443,6 +2629,9 @@ class Const_expression : public Expression ...@@ -2443,6 +2629,9 @@ class Const_expression : public Expression
do_export(Export* exp) const do_export(Export* exp) const
{ this->constant_->const_value()->expr()->export_expression(exp); } { this->constant_->const_value()->expr()->export_expression(exp); }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The constant. // The constant.
Named_object* constant_; Named_object* constant_;
...@@ -2824,6 +3013,14 @@ Const_expression::do_get_tree(Translate_context* context) ...@@ -2824,6 +3013,14 @@ Const_expression::do_get_tree(Translate_context* context)
return ret; return ret;
} }
// Dump ast representation for constant expression.
void
Const_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << this->constant_->name();
}
// Make a reference to a constant in an expression. // Make a reference to a constant in an expression.
Expression* Expression*
...@@ -2905,6 +3102,10 @@ class Nil_expression : public Expression ...@@ -2905,6 +3102,10 @@ class Nil_expression : public Expression
void void
do_export(Export* exp) const do_export(Export* exp) const
{ exp->write_c_string("nil"); } { exp->write_c_string("nil"); }
void
do_dump_expression(Ast_dump_context* ast_dump_context) const
{ ast_dump_context->ostream() << "nil"; }
}; };
// Import a nil expression. // Import a nil expression.
...@@ -2945,6 +3146,10 @@ class Iota_expression : public Parser_expression ...@@ -2945,6 +3146,10 @@ class Iota_expression : public Parser_expression
Expression* Expression*
do_copy() do_copy()
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_expression(Ast_dump_context* ast_dump_context) const
{ ast_dump_context->ostream() << "iota"; }
}; };
// Make an iota expression. This is only called for one case: the // Make an iota expression. This is only called for one case: the
...@@ -3040,6 +3245,9 @@ class Type_conversion_expression : public Expression ...@@ -3040,6 +3245,9 @@ class Type_conversion_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type to convert to. // The type to convert to.
Type* type_; Type* type_;
...@@ -3570,6 +3778,18 @@ Type_conversion_expression::do_import(Import* imp) ...@@ -3570,6 +3778,18 @@ Type_conversion_expression::do_import(Import* imp)
return Expression::make_cast(type, val, imp->location()); return Expression::make_cast(type, val, imp->location());
} }
// Dump ast representation for a type conversion expression.
void
Type_conversion_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << "(";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << ") ";
}
// Make a type cast expression. // Make a type cast expression.
Expression* Expression*
...@@ -3614,6 +3834,9 @@ class Unsafe_type_conversion_expression : public Expression ...@@ -3614,6 +3834,9 @@ class Unsafe_type_conversion_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type to convert to. // The type to convert to.
Type* type_; Type* type_;
...@@ -3698,6 +3921,18 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context) ...@@ -3698,6 +3921,18 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
return fold_convert_loc(loc, type_tree, expr_tree); return fold_convert_loc(loc, type_tree, expr_tree);
} }
// Dump ast representation for an unsafe type conversion expression.
void
Unsafe_type_conversion_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << "(";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << ") ";
}
// Make an unsafe type conversion expression. // Make an unsafe type conversion expression.
Expression* Expression*
...@@ -3801,6 +4036,9 @@ class Unary_expression : public Expression ...@@ -3801,6 +4036,9 @@ class Unary_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The unary operator to apply. // The unary operator to apply.
Operator op_; Operator op_;
...@@ -4412,6 +4650,17 @@ Unary_expression::do_import(Import* imp) ...@@ -4412,6 +4650,17 @@ Unary_expression::do_import(Import* imp)
return Expression::make_unary(op, expr, imp->location()); return Expression::make_unary(op, expr, imp->location());
} }
// Dump ast representation of an unary expression.
void
Unary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_operator(this->op_);
ast_dump_context->ostream() << "(";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << ") ";
}
// Make a unary expression. // Make a unary expression.
Expression* Expression*
...@@ -6311,6 +6560,20 @@ Binary_expression::do_import(Import* imp) ...@@ -6311,6 +6560,20 @@ Binary_expression::do_import(Import* imp)
return Expression::make_binary(op, left, right, imp->location()); return Expression::make_binary(op, left, right, imp->location());
} }
// Dump ast representation of a binary expression.
void
Binary_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "(";
ast_dump_context->dump_expression(this->left_);
ast_dump_context->ostream() << " ";
ast_dump_context->dump_operator(this->op_);
ast_dump_context->ostream() << " ";
ast_dump_context->dump_expression(this->right_);
ast_dump_context->ostream() << ") ";
}
// Make a binary expression. // Make a binary expression.
Expression* Expression*
...@@ -6643,6 +6906,26 @@ Bound_method_expression::do_get_tree(Translate_context*) ...@@ -6643,6 +6906,26 @@ Bound_method_expression::do_get_tree(Translate_context*)
return error_mark_node; return error_mark_node;
} }
// Dump ast representation of a bound method expression.
void
Bound_method_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
if (this->expr_type_ != NULL)
ast_dump_context->ostream() << "(";
ast_dump_context->dump_expression(this->expr_);
if (this->expr_type_ != NULL)
{
ast_dump_context->ostream() << ":";
ast_dump_context->dump_type(this->expr_type_);
ast_dump_context->ostream() << ")";
}
ast_dump_context->ostream() << ".";
ast_dump_context->dump_expression(method_);
}
// Make a method expression. // Make a method expression.
Bound_method_expression* Bound_method_expression*
...@@ -9298,6 +9581,19 @@ Call_expression::set_results(Translate_context* context, tree call_tree) ...@@ -9298,6 +9581,19 @@ Call_expression::set_results(Translate_context* context, tree call_tree)
return save_expr(stmt_list); return save_expr(stmt_list);
} }
// Dump ast representation for a call expressin.
void
Call_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
this->fn_->dump_expression(ast_dump_context);
ast_dump_context->ostream() << "(";
if (args_ != NULL)
ast_dump_context->dump_expression_list(this->args_);
ast_dump_context->ostream() << ") ";
}
// Make a call expression. // Make a call expression.
Call_expression* Call_expression*
...@@ -9344,6 +9640,9 @@ class Call_result_expression : public Expression ...@@ -9344,6 +9640,9 @@ class Call_result_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The underlying call expression. // The underlying call expression.
Expression* call_; Expression* call_;
...@@ -9443,6 +9742,19 @@ Call_result_expression::do_get_tree(Translate_context* context) ...@@ -9443,6 +9742,19 @@ Call_result_expression::do_get_tree(Translate_context* context)
return ref->get_tree(context); return ref->get_tree(context);
} }
// Dump ast representation for a call result expression.
void
Call_result_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
// FIXME: Wouldn't it be better if the call is assigned to a temporary
// (struct) and the fields are referenced instead.
ast_dump_context->ostream() << this->index_ << "@(";
ast_dump_context->dump_expression(this->call_);
ast_dump_context->ostream() << ")";
}
// Make a reference to a single result of a call which returns // Make a reference to a single result of a call which returns
// multiple results. // multiple results.
...@@ -9519,6 +9831,36 @@ Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int) ...@@ -9519,6 +9831,36 @@ Index_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
} }
} }
// Write an indexed expression (expr[expr:expr] or expr[expr]) to a
// dump context
void
Index_expression::dump_index_expression(Ast_dump_context* ast_dump_context,
const Expression* expr,
const Expression* start,
const Expression* end)
{
expr->dump_expression(ast_dump_context);
ast_dump_context->ostream() << "[";
start->dump_expression(ast_dump_context);
if (end != NULL)
{
ast_dump_context->ostream() << ":";
end->dump_expression(ast_dump_context);
}
ast_dump_context->ostream() << "]";
}
// Dump ast representation for an index expression.
void
Index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
Index_expression::dump_index_expression(ast_dump_context, this->left_,
this->start_, this->end_);
}
// Make an index expression. // Make an index expression.
Expression* Expression*
...@@ -9573,6 +9915,9 @@ class Array_index_expression : public Expression ...@@ -9573,6 +9915,9 @@ class Array_index_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The array we are getting a value from. // The array we are getting a value from.
Expression* array_; Expression* array_;
...@@ -9922,6 +10267,16 @@ Array_index_expression::do_get_tree(Translate_context* context) ...@@ -9922,6 +10267,16 @@ Array_index_expression::do_get_tree(Translate_context* context)
constructor); constructor);
} }
// Dump ast representation for an array index expression.
void
Array_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
Index_expression::dump_index_expression(ast_dump_context, this->array_,
this->start_, this->end_);
}
// Make an array index expression. END may be NULL. // Make an array index expression. END may be NULL.
Expression* Expression*
...@@ -9976,6 +10331,9 @@ class String_index_expression : public Expression ...@@ -9976,6 +10331,9 @@ class String_index_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The string we are getting a value from. // The string we are getting a value from.
Expression* string_; Expression* string_;
...@@ -10176,6 +10534,16 @@ String_index_expression::do_get_tree(Translate_context* context) ...@@ -10176,6 +10534,16 @@ String_index_expression::do_get_tree(Translate_context* context)
} }
} }
// Dump ast representation for a string index expression.
void
String_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
Index_expression::dump_index_expression(ast_dump_context, this->string_,
this->start_, this->end_);
}
// Make a string index expression. END may be NULL. // Make a string index expression. END may be NULL.
Expression* Expression*
...@@ -10390,6 +10758,16 @@ Map_index_expression::get_value_pointer(Translate_context* context, ...@@ -10390,6 +10758,16 @@ Map_index_expression::get_value_pointer(Translate_context* context,
return ret; return ret;
} }
// Dump ast representation for a map index expression
void
Map_index_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
Index_expression::dump_index_expression(ast_dump_context,
this->map_, this->index_, NULL);
}
// Make a map index expression. // Make a map index expression.
Map_index_expression* Map_index_expression*
...@@ -10456,6 +10834,16 @@ Field_reference_expression::do_get_tree(Translate_context* context) ...@@ -10456,6 +10834,16 @@ Field_reference_expression::do_get_tree(Translate_context* context)
NULL_TREE); NULL_TREE);
} }
// Dump ast representation for a field reference expression.
void
Field_reference_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
this->expr_->dump_expression(ast_dump_context);
ast_dump_context->ostream() << "." << this->field_index_;
}
// Make a reference to a qualified identifier in an expression. // Make a reference to a qualified identifier in an expression.
Field_reference_expression* Field_reference_expression*
...@@ -10602,6 +10990,16 @@ Interface_field_reference_expression::do_get_tree(Translate_context*) ...@@ -10602,6 +10990,16 @@ Interface_field_reference_expression::do_get_tree(Translate_context*)
go_unreachable(); go_unreachable();
} }
// Dump ast representation for an interface field reference.
void
Interface_field_reference_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
this->expr_->dump_expression(ast_dump_context);
ast_dump_context->ostream() << "." << this->name_;
}
// Make a reference to a field in an interface. // Make a reference to a field in an interface.
Expression* Expression*
...@@ -10639,6 +11037,9 @@ class Selector_expression : public Parser_expression ...@@ -10639,6 +11037,9 @@ class Selector_expression : public Parser_expression
this->location()); this->location());
} }
void
do_dump_expression(Ast_dump_context* ast_dump_context) const;
private: private:
Expression* Expression*
lower_method_expression(Gogo*); lower_method_expression(Gogo*);
...@@ -10859,6 +11260,17 @@ Selector_expression::lower_method_expression(Gogo* gogo) ...@@ -10859,6 +11260,17 @@ Selector_expression::lower_method_expression(Gogo* gogo)
return Expression::make_func_reference(no, NULL, location); return Expression::make_func_reference(no, NULL, location);
} }
// Dump the ast for a selector expression.
void
Selector_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->dump_expression(this->left_);
ast_dump_context->ostream() << ".";
ast_dump_context->ostream() << this->name_;
}
// Make a selector expression. // Make a selector expression.
Expression* Expression*
...@@ -10898,6 +11310,9 @@ class Allocation_expression : public Expression ...@@ -10898,6 +11310,9 @@ class Allocation_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type we are allocating. // The type we are allocating.
Type* type_; Type* type_;
...@@ -10919,6 +11334,17 @@ Allocation_expression::do_get_tree(Translate_context* context) ...@@ -10919,6 +11334,17 @@ Allocation_expression::do_get_tree(Translate_context* context)
return fold_convert(build_pointer_type(type_tree), space); return fold_convert(build_pointer_type(type_tree), space);
} }
// Dump ast representation for an allocation expression.
void
Allocation_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->ostream() << "new(";
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << ")";
}
// Make an allocation expression. // Make an allocation expression.
Expression* Expression*
...@@ -10973,6 +11399,9 @@ class Struct_construction_expression : public Expression ...@@ -10973,6 +11399,9 @@ class Struct_construction_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type of the struct to construct. // The type of the struct to construct.
Type* type_; Type* type_;
...@@ -11185,6 +11614,19 @@ Struct_construction_expression::do_export(Export* exp) const ...@@ -11185,6 +11614,19 @@ Struct_construction_expression::do_export(Export* exp) const
exp->write_c_string(")"); exp->write_c_string(")");
} }
// Dump ast representation of a struct construction expression.
void
Struct_construction_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << "{";
ast_dump_context->dump_expression_list(this->vals_);
ast_dump_context->ostream() << "}";
}
// Make a struct composite literal. This used by the thunk code. // Make a struct composite literal. This used by the thunk code.
Expression* Expression*
...@@ -11249,6 +11691,9 @@ protected: ...@@ -11249,6 +11691,9 @@ protected:
tree tree
get_constructor_tree(Translate_context* context, tree type_tree); get_constructor_tree(Translate_context* context, tree type_tree);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type of the array to construct. // The type of the array to construct.
Type* type_; Type* type_;
...@@ -11422,6 +11867,19 @@ Array_construction_expression::do_export(Export* exp) const ...@@ -11422,6 +11867,19 @@ Array_construction_expression::do_export(Export* exp) const
exp->write_c_string(")"); exp->write_c_string(")");
} }
// Dump ast representation of an array construction expressin.
void
Array_construction_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << "{" ;
ast_dump_context->dump_expression_list(this->vals_);
ast_dump_context->ostream() << "}" ;
}
// Construct a fixed array. // Construct a fixed array.
class Fixed_array_construction_expression : class Fixed_array_construction_expression :
...@@ -11688,6 +12146,9 @@ class Map_construction_expression : public Expression ...@@ -11688,6 +12146,9 @@ class Map_construction_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type of the map to construct. // The type of the map to construct.
Type* type_; Type* type_;
...@@ -11941,6 +12402,18 @@ Map_construction_expression::do_export(Export* exp) const ...@@ -11941,6 +12402,18 @@ Map_construction_expression::do_export(Export* exp) const
exp->write_c_string(")"); exp->write_c_string(")");
} }
// Dump ast representation for a map construction expression.
void
Map_construction_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
// FIXME: We should print key:value pairs here.
ast_dump_context->ostream() << "{" ;
ast_dump_context->dump_expression_list(this->vals_);
ast_dump_context->ostream() << "}";
}
// A general composite literal. This is lowered to a type specific // A general composite literal. This is lowered to a type specific
// version. // version.
...@@ -11971,6 +12444,9 @@ class Composite_literal_expression : public Parser_expression ...@@ -11971,6 +12444,9 @@ class Composite_literal_expression : public Parser_expression
this->location()); this->location());
} }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
Expression* Expression*
lower_struct(Gogo*, Type*); lower_struct(Gogo*, Type*);
...@@ -12382,6 +12858,20 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function, ...@@ -12382,6 +12858,20 @@ Composite_literal_expression::lower_map(Gogo* gogo, Named_object* function,
return new Map_construction_expression(type, this->vals_, location); return new Map_construction_expression(type, this->vals_, location);
} }
// Dump ast representation for a composite literal expression.
void
Composite_literal_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
// FIXME: We should print colons if this->has_keys_ is true
ast_dump_context->ostream() << "composite_literal(" ;
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << ", {";
ast_dump_context->dump_expression_list(this->vals_);
ast_dump_context->ostream() << "})";
}
// Make a composite literal expression. // Make a composite literal expression.
Expression* Expression*
...@@ -12556,6 +13046,17 @@ Type_guard_expression::do_get_tree(Translate_context* context) ...@@ -12556,6 +13046,17 @@ Type_guard_expression::do_get_tree(Translate_context* context)
this->location()); this->location());
} }
// Dump ast representation for a type guard expression.
void
Type_guard_expression::do_dump_expression(Ast_dump_context* ast_dump_context)
const
{
this->expr_->dump_expression(ast_dump_context);
ast_dump_context->ostream() << ".";
ast_dump_context->dump_type(this->type_);
}
// Make a type guard expression. // Make a type guard expression.
Expression* Expression*
...@@ -12607,6 +13108,9 @@ class Heap_composite_expression : public Expression ...@@ -12607,6 +13108,9 @@ class Heap_composite_expression : public Expression
do_export(Export*) const do_export(Export*) const
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The composite literal which is being put on the heap. // The composite literal which is being put on the heap.
Expression* expr_; Expression* expr_;
...@@ -12635,6 +13139,17 @@ Heap_composite_expression::do_get_tree(Translate_context* context) ...@@ -12635,6 +13139,17 @@ Heap_composite_expression::do_get_tree(Translate_context* context)
return ret; return ret;
} }
// Dump ast representation for a heap composite expression.
void
Heap_composite_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "&(";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << ")";
}
// Allocate a composite literal on the heap. // Allocate a composite literal on the heap.
Expression* Expression*
...@@ -12702,6 +13217,15 @@ Receive_expression::do_get_tree(Translate_context* context) ...@@ -12702,6 +13217,15 @@ Receive_expression::do_get_tree(Translate_context* context)
this->for_select_, this->location()); this->for_select_, this->location());
} }
// Dump ast representation for a receive expression.
void
Receive_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << " <- " ;
ast_dump_context->dump_expression(channel_);
}
// Make a receive expression. // Make a receive expression.
Receive_expression* Receive_expression*
...@@ -12741,11 +13265,23 @@ class Type_descriptor_expression : public Expression ...@@ -12741,11 +13265,23 @@ class Type_descriptor_expression : public Expression
this->location()); this->location());
} }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type for which this is the descriptor. // The type for which this is the descriptor.
Type* type_; Type* type_;
}; };
// Dump ast representation for a type descriptor expression.
void
Type_descriptor_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->dump_type(this->type_);
}
// Make a type descriptor expression. // Make a type descriptor expression.
Expression* Expression*
...@@ -12783,6 +13319,9 @@ class Type_info_expression : public Expression ...@@ -12783,6 +13319,9 @@ class Type_info_expression : public Expression
tree tree
do_get_tree(Translate_context* context); do_get_tree(Translate_context* context);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type for which we are getting information. // The type for which we are getting information.
Type* type_; Type* type_;
...@@ -12834,6 +13373,23 @@ Type_info_expression::do_get_tree(Translate_context* context) ...@@ -12834,6 +13373,23 @@ Type_info_expression::do_get_tree(Translate_context* context)
} }
} }
// Dump ast representation for a type info expression.
void
Type_info_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "typeinfo(";
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << ",";
ast_dump_context->ostream() <<
(this->type_info_ == TYPE_INFO_ALIGNMENT ? "alignment"
: this->type_info_ == TYPE_INFO_FIELD_ALIGNMENT ? "field alignment"
: this->type_info_ == TYPE_INFO_SIZE ? "size "
: "unknown");
ast_dump_context->ostream() << ")";
}
// Make a type info expression. // Make a type info expression.
Expression* Expression*
...@@ -12870,6 +13426,9 @@ class Struct_field_offset_expression : public Expression ...@@ -12870,6 +13426,9 @@ class Struct_field_offset_expression : public Expression
tree tree
do_get_tree(Translate_context* context); do_get_tree(Translate_context* context);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type of the struct. // The type of the struct.
Struct_type* type_; Struct_type* type_;
...@@ -12906,6 +13465,17 @@ Struct_field_offset_expression::do_get_tree(Translate_context* context) ...@@ -12906,6 +13465,17 @@ Struct_field_offset_expression::do_get_tree(Translate_context* context)
byte_position(struct_field_tree)); byte_position(struct_field_tree));
} }
// Dump ast representation for a struct field offset expression.
void
Struct_field_offset_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "unsafe.Offsetof(";
ast_dump_context->ostream() << this->field_->field_name();
ast_dump_context->ostream() << ")";
}
// Make an expression for a struct field offset. // Make an expression for a struct field offset.
Expression* Expression*
...@@ -12946,11 +13516,25 @@ class Map_descriptor_expression : public Expression ...@@ -12946,11 +13516,25 @@ class Map_descriptor_expression : public Expression
this->location()); this->location());
} }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The type for which this is the descriptor. // The type for which this is the descriptor.
Map_type* type_; Map_type* type_;
}; };
// Dump ast representation for a map descriptor expression.
void
Map_descriptor_expression::do_dump_expression(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << "map_descriptor(";
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << ")";
}
// Make a map descriptor expression. // Make a map descriptor expression.
Expression* Expression*
...@@ -12988,6 +13572,10 @@ class Label_addr_expression : public Expression ...@@ -12988,6 +13572,10 @@ class Label_addr_expression : public Expression
return expr_to_tree(this->label_->get_addr(context, this->location())); return expr_to_tree(this->label_->get_addr(context, this->location()));
} }
void
do_dump_expression(Ast_dump_context* ast_dump_context) const
{ ast_dump_context->ostream() << this->label_->name(); }
private: private:
// The label whose address we are taking. // The label whose address we are taking.
Label* label_; Label* label_;
......
...@@ -42,6 +42,7 @@ class Export; ...@@ -42,6 +42,7 @@ class Export;
class Import; class Import;
class Temporary_statement; class Temporary_statement;
class Label; class Label;
class Ast_dump_context;
// The base class for all expressions. // The base class for all expressions.
...@@ -635,6 +636,10 @@ class Expression ...@@ -635,6 +636,10 @@ class Expression
static tree static tree
check_bounds(tree val, tree bound_type, tree sofar, source_location); check_bounds(tree val, tree bound_type, tree sofar, source_location);
// Dump an expression to a dump constext.
void
dump_expression(Ast_dump_context*) const;
protected: protected:
// May be implemented by child class: traverse the expressions. // May be implemented by child class: traverse the expressions.
virtual int virtual int
...@@ -731,6 +736,10 @@ class Expression ...@@ -731,6 +736,10 @@ class Expression
void void
report_error(const char*); report_error(const char*);
// Child class implements dumping to a dump context.
virtual void
do_dump_expression(Ast_dump_context*) const = 0;
private: private:
// Convert to the desired statement classification, or return NULL. // Convert to the desired statement classification, or return NULL.
// This is a controlled dynamic cast. // This is a controlled dynamic cast.
...@@ -934,6 +943,9 @@ class Var_expression : public Expression ...@@ -934,6 +943,9 @@ class Var_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The variable we are referencing. // The variable we are referencing.
Named_object* variable_; Named_object* variable_;
...@@ -978,6 +990,9 @@ class Temporary_reference_expression : public Expression ...@@ -978,6 +990,9 @@ class Temporary_reference_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The statement where the temporary variable is defined. // The statement where the temporary variable is defined.
Temporary_statement* statement_; Temporary_statement* statement_;
...@@ -1031,6 +1046,9 @@ class String_expression : public Expression ...@@ -1031,6 +1046,9 @@ class String_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The string value. This is immutable. // The string value. This is immutable.
const std::string val_; const std::string val_;
...@@ -1154,6 +1172,9 @@ class Binary_expression : public Expression ...@@ -1154,6 +1172,9 @@ class Binary_expression : public Expression
void void
do_export(Export*) const; do_export(Export*) const;
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The binary operator to apply. // The binary operator to apply.
Operator op_; Operator op_;
...@@ -1290,6 +1311,9 @@ class Call_expression : public Expression ...@@ -1290,6 +1311,9 @@ class Call_expression : public Expression
bool bool
determining_types(); determining_types();
void
do_dump_expression(Ast_dump_context*) const;
private: private:
bool bool
check_argument_type(int, const Type*, const Type*, source_location, bool); check_argument_type(int, const Type*, const Type*, source_location, bool);
...@@ -1384,6 +1408,9 @@ class Func_expression : public Expression ...@@ -1384,6 +1408,9 @@ class Func_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The function itself. // The function itself.
Named_object* function_; Named_object* function_;
...@@ -1432,6 +1459,9 @@ class Unknown_expression : public Parser_expression ...@@ -1432,6 +1459,9 @@ class Unknown_expression : public Parser_expression
do_copy() do_copy()
{ return new Unknown_expression(this->named_object_, this->location()); } { return new Unknown_expression(this->named_object_, this->location()); }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The unknown name. // The unknown name.
Named_object* named_object_; Named_object* named_object_;
...@@ -1456,6 +1486,12 @@ class Index_expression : public Parser_expression ...@@ -1456,6 +1486,12 @@ class Index_expression : public Parser_expression
set_is_lvalue() set_is_lvalue()
{ this->is_lvalue_ = true; } { this->is_lvalue_ = true; }
// Dump an index expression, i.e. an expression of the form
// expr[expr] or expr[expr:expr], to a dump context.
static void
dump_index_expression(Ast_dump_context*, const Expression* expr,
const Expression* start, const Expression* end);
protected: protected:
int int
do_traverse(Traverse*); do_traverse(Traverse*);
...@@ -1473,6 +1509,9 @@ class Index_expression : public Parser_expression ...@@ -1473,6 +1509,9 @@ class Index_expression : public Parser_expression
this->location()); this->location());
} }
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The expression being indexed. // The expression being indexed.
Expression* left_; Expression* left_;
...@@ -1572,6 +1611,9 @@ class Map_index_expression : public Expression ...@@ -1572,6 +1611,9 @@ class Map_index_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The map we are looking into. // The map we are looking into.
Expression* map_; Expression* map_;
...@@ -1641,6 +1683,9 @@ class Bound_method_expression : public Expression ...@@ -1641,6 +1683,9 @@ class Bound_method_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The object used to find the method. This is passed to the method // The object used to find the method. This is passed to the method
// as the first argument. // as the first argument.
...@@ -1712,6 +1757,9 @@ class Field_reference_expression : public Expression ...@@ -1712,6 +1757,9 @@ class Field_reference_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The expression we are looking into. This should have a type of // The expression we are looking into. This should have a type of
// struct. // struct.
...@@ -1777,6 +1825,9 @@ class Interface_field_reference_expression : public Expression ...@@ -1777,6 +1825,9 @@ class Interface_field_reference_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The expression for the interface object. This should have a type // The expression for the interface object. This should have a type
// of interface or pointer to interface. // of interface or pointer to interface.
...@@ -1830,6 +1881,9 @@ class Type_guard_expression : public Expression ...@@ -1830,6 +1881,9 @@ class Type_guard_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The expression to convert. // The expression to convert.
Expression* expr_; Expression* expr_;
...@@ -1889,6 +1943,9 @@ class Receive_expression : public Expression ...@@ -1889,6 +1943,9 @@ class Receive_expression : public Expression
tree tree
do_get_tree(Translate_context*); do_get_tree(Translate_context*);
void
do_dump_expression(Ast_dump_context*) const;
private: private:
// The channel from which we are receiving. // The channel from which we are receiving.
Expression* channel_; Expression* channel_;
......
...@@ -133,6 +133,9 @@ go_parse_input_files(const char** filenames, unsigned int filename_count, ...@@ -133,6 +133,9 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
// Convert complicated go and defer statements into simpler ones. // Convert complicated go and defer statements into simpler ones.
::gogo->simplify_thunk_statements(); ::gogo->simplify_thunk_statements();
// Dump ast, use filename[0] as the base name
::gogo->dump_ast(filenames[0]);
} }
// Write out globals. // Write out globals.
......
...@@ -422,6 +422,10 @@ class Gogo ...@@ -422,6 +422,10 @@ class Gogo
void void
simplify_thunk_statements(); simplify_thunk_statements();
// Dump AST if -fgo-dump-ast is set
void
dump_ast(const char* basename);
// Convert named types to the backend representation. // Convert named types to the backend representation.
void void
convert_named_types(); convert_named_types();
...@@ -512,7 +516,6 @@ class Gogo ...@@ -512,7 +516,6 @@ class Gogo
receive_as_64bit_integer(tree type, tree channel, bool blocking, receive_as_64bit_integer(tree type, tree channel, bool blocking,
bool for_select); bool for_select);
// Make a trampoline which calls FNADDR passing CLOSURE. // Make a trampoline which calls FNADDR passing CLOSURE.
tree tree
make_trampoline(tree fnaddr, tree closure, source_location); make_trampoline(tree fnaddr, tree closure, source_location);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "runtime.h" #include "runtime.h"
#include "backend.h" #include "backend.h"
#include "statements.h" #include "statements.h"
#include "ast-dump.h"
// Class Statement. // Class Statement.
...@@ -142,6 +143,14 @@ Statement::get_backend(Translate_context* context) ...@@ -142,6 +143,14 @@ Statement::get_backend(Translate_context* context)
return this->do_get_backend(context); return this->do_get_backend(context);
} }
// Dump AST representation for a statement to a dump context.
void
Statement::dump_statement(Ast_dump_context* ast_dump_context) const
{
this->do_dump_statement(ast_dump_context);
}
// Note that this statement is erroneous. This is called by children // Note that this statement is erroneous. This is called by children
// when they discover an error. // when they discover an error.
...@@ -178,8 +187,20 @@ class Error_statement : public Statement ...@@ -178,8 +187,20 @@ class Error_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
}; };
// Dump the AST representation for an error statement.
void
Error_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "Error statement" << std::endl;
}
// Make an error statement. // Make an error statement.
Statement* Statement*
...@@ -280,6 +301,30 @@ Variable_declaration_statement::do_get_backend(Translate_context* context) ...@@ -280,6 +301,30 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
return context->backend()->statement_list(stats); return context->backend()->statement_list(stats);
} }
// Dump the AST representation for a variable declaration.
void
Variable_declaration_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
go_assert(var_->is_variable());
ast_dump_context->ostream() << "var " << this->var_->name() << " ";
Variable* var = this->var_->var_value();
if (var->has_type())
{
ast_dump_context->dump_type(var->type());
ast_dump_context->ostream() << " ";
}
if (var->init() != NULL)
{
ast_dump_context->ostream() << "= ";
ast_dump_context->dump_expression(var->init());
}
ast_dump_context->ostream() << std::endl;
}
// Make a variable declaration. // Make a variable declaration.
Statement* Statement*
...@@ -422,6 +467,27 @@ Temporary_statement::get_backend_variable(Translate_context* context) const ...@@ -422,6 +467,27 @@ Temporary_statement::get_backend_variable(Translate_context* context) const
return this->bvariable_; return this->bvariable_;
} }
// Dump the AST represemtation for a temporary statement
void
Temporary_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_temp_variable_name(this);
if (this->type_ != NULL)
{
ast_dump_context->ostream() << " ";
ast_dump_context->dump_type(this->type_);
}
if (this->init_ != NULL)
{
ast_dump_context->ostream() << " = ";
ast_dump_context->dump_expression(this->init_);
}
ast_dump_context->ostream() << std::endl;
}
// Make and initialize a temporary variable in BLOCK. // Make and initialize a temporary variable in BLOCK.
Temporary_statement* Temporary_statement*
...@@ -458,6 +524,9 @@ class Assignment_statement : public Statement ...@@ -458,6 +524,9 @@ class Assignment_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// Left hand side--the lvalue. // Left hand side--the lvalue.
Expression* lhs_; Expression* lhs_;
...@@ -542,6 +611,19 @@ Assignment_statement::do_get_backend(Translate_context* context) ...@@ -542,6 +611,19 @@ Assignment_statement::do_get_backend(Translate_context* context)
this->location()); this->location());
} }
// Dump the AST representation for an assignment statement.
void
Assignment_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->lhs_);
ast_dump_context->ostream() << " = " ;
ast_dump_context->dump_expression(this->rhs_);
ast_dump_context->ostream() << std::endl;
}
// Make an assignment statement. // Make an assignment statement.
Statement* Statement*
...@@ -614,6 +696,9 @@ class Assignment_operation_statement : public Statement ...@@ -614,6 +696,9 @@ class Assignment_operation_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The operator (OPERATOR_PLUSEQ, etc.). // The operator (OPERATOR_PLUSEQ, etc.).
Operator op_; Operator op_;
...@@ -704,6 +789,19 @@ Assignment_operation_statement::do_lower(Gogo*, Named_object*, ...@@ -704,6 +789,19 @@ Assignment_operation_statement::do_lower(Gogo*, Named_object*,
} }
} }
// Dump the AST representation for an assignment operation statement
void
Assignment_operation_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->lhs_);
ast_dump_context->dump_operator(this->op_);
ast_dump_context->dump_expression(this->rhs_);
ast_dump_context->ostream() << std::endl;
}
// Make an assignment operation statement. // Make an assignment operation statement.
Statement* Statement*
...@@ -741,6 +839,9 @@ class Tuple_assignment_statement : public Statement ...@@ -741,6 +839,9 @@ class Tuple_assignment_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// Left hand side--a list of lvalues. // Left hand side--a list of lvalues.
Expression_list* lhs_; Expression_list* lhs_;
...@@ -768,7 +869,7 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, ...@@ -768,7 +869,7 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
source_location loc = this->location(); source_location loc = this->location();
Block* b = new Block(enclosing, loc); Block* b = new Block(enclosing, loc);
// First move out any subexpressions on the left hand side. The // First move out any subexpressions on the left hand side. The
// right hand side will be evaluated in the required order anyhow. // right hand side will be evaluated in the required order anyhow.
Move_ordered_evals moe(b); Move_ordered_evals moe(b);
...@@ -832,6 +933,19 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, ...@@ -832,6 +933,19 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
return Statement::make_block_statement(b, loc); return Statement::make_block_statement(b, loc);
} }
// Dump the AST representation for a tuple assignment statement.
void
Tuple_assignment_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression_list(this->lhs_);
ast_dump_context->ostream() << " = ";
ast_dump_context->dump_expression_list(this->rhs_);
ast_dump_context->ostream() << std::endl;
}
// Make a tuple assignment statement. // Make a tuple assignment statement.
Statement* Statement*
...@@ -869,6 +983,9 @@ public: ...@@ -869,6 +983,9 @@ public:
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// Lvalue which receives the value from the map. // Lvalue which receives the value from the map.
Expression* val_; Expression* val_;
...@@ -960,6 +1077,21 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*, ...@@ -960,6 +1077,21 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*,
return Statement::make_block_statement(b, loc); return Statement::make_block_statement(b, loc);
} }
// Dump the AST representation for a tuple map assignment statement.
void
Tuple_map_assignment_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << ", ";
ast_dump_context->dump_expression(this->present_);
ast_dump_context->ostream() << " = ";
ast_dump_context->dump_expression(this->map_index_);
ast_dump_context->ostream() << std::endl;
}
// Make a map assignment statement which returns a pair of values. // Make a map assignment statement which returns a pair of values.
Statement* Statement*
...@@ -998,6 +1130,9 @@ class Map_assignment_statement : public Statement ...@@ -998,6 +1130,9 @@ class Map_assignment_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// A reference to the map index which should be set or deleted. // A reference to the map index which should be set or deleted.
Expression* map_index_; Expression* map_index_;
...@@ -1076,6 +1211,21 @@ Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, ...@@ -1076,6 +1211,21 @@ Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
return Statement::make_block_statement(b, loc); return Statement::make_block_statement(b, loc);
} }
// Dump the AST representation for a map assignment statement.
void
Map_assignment_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->map_index_);
ast_dump_context->ostream() << " = ";
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << ", ";
ast_dump_context->dump_expression(this->should_set_);
ast_dump_context->ostream() << std::endl;
}
// Make a statement which assigns a pair of entries to a map. // Make a statement which assigns a pair of entries to a map.
Statement* Statement*
...@@ -1113,6 +1263,9 @@ class Tuple_receive_assignment_statement : public Statement ...@@ -1113,6 +1263,9 @@ class Tuple_receive_assignment_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// Lvalue which receives the value from the channel. // Lvalue which receives the value from the channel.
Expression* val_; Expression* val_;
...@@ -1200,6 +1353,21 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, ...@@ -1200,6 +1353,21 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
return Statement::make_block_statement(b, loc); return Statement::make_block_statement(b, loc);
} }
// Dump the AST representation for a tuple receive statement.
void
Tuple_receive_assignment_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << ", ";
ast_dump_context->dump_expression(this->closed_);
ast_dump_context->ostream() << " <- ";
ast_dump_context->dump_expression(this->channel_);
ast_dump_context->ostream() << std::endl;
}
// Make a nonblocking receive statement. // Make a nonblocking receive statement.
Statement* Statement*
...@@ -1240,6 +1408,9 @@ class Tuple_type_guard_assignment_statement : public Statement ...@@ -1240,6 +1408,9 @@ class Tuple_type_guard_assignment_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Call_expression* Call_expression*
lower_to_type(Runtime::Function); lower_to_type(Runtime::Function);
...@@ -1375,6 +1546,23 @@ Tuple_type_guard_assignment_statement::lower_to_object_type( ...@@ -1375,6 +1546,23 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
b->add_statement(s); b->add_statement(s);
} }
// Dump the AST representation for a tuple type guard statement.
void
Tuple_type_guard_assignment_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << ", ";
ast_dump_context->dump_expression(this->ok_);
ast_dump_context->ostream() << " = ";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << " . ";
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << std::endl;
}
// Make an assignment from a type guard to a pair of variables. // Make an assignment from a type guard to a pair of variables.
Statement* Statement*
...@@ -1415,6 +1603,9 @@ class Expression_statement : public Statement ...@@ -1415,6 +1603,9 @@ class Expression_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context* context); do_get_backend(Translate_context* context);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Expression* expr_; Expression* expr_;
}; };
...@@ -1459,6 +1650,17 @@ Expression_statement::do_get_backend(Translate_context* context) ...@@ -1459,6 +1650,17 @@ Expression_statement::do_get_backend(Translate_context* context)
return context->backend()->expression_statement(tree_to_expr(expr_tree)); return context->backend()->expression_statement(tree_to_expr(expr_tree));
} }
// Dump the AST representation for an expression statement
void
Expression_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(expr_);
ast_dump_context->ostream() << std::endl;
}
// Make an expression statement from an Expression. // Make an expression statement from an Expression.
Statement* Statement*
...@@ -1494,6 +1696,9 @@ class Block_statement : public Statement ...@@ -1494,6 +1696,9 @@ class Block_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context* context); do_get_backend(Translate_context* context);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Block* block_; Block* block_;
}; };
...@@ -1507,6 +1712,14 @@ Block_statement::do_get_backend(Translate_context* context) ...@@ -1507,6 +1712,14 @@ Block_statement::do_get_backend(Translate_context* context)
return context->backend()->block_statement(bblock); return context->backend()->block_statement(bblock);
} }
// Dump the AST for a block statement
void
Block_statement::do_dump_statement(Ast_dump_context*) const
{
// block statement braces are dumped when traversing.
}
// Make a block statement. // Make a block statement.
Statement* Statement*
...@@ -1541,6 +1754,9 @@ class Inc_dec_statement : public Statement ...@@ -1541,6 +1754,9 @@ class Inc_dec_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The l-value to increment or decrement. // The l-value to increment or decrement.
Expression* expr_; Expression* expr_;
...@@ -1564,6 +1780,16 @@ Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*) ...@@ -1564,6 +1780,16 @@ Inc_dec_statement::do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
return Statement::make_assignment_operation(op, this->expr_, oexpr, loc); return Statement::make_assignment_operation(op, this->expr_, oexpr, loc);
} }
// Dump the AST representation for a inc/dec statement.
void
Inc_dec_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(expr_);
ast_dump_context->ostream() << (is_inc_? "++": "--") << std::endl;
}
// Make an increment statement. // Make an increment statement.
Statement* Statement*
...@@ -2233,6 +2459,17 @@ Go_statement::do_get_backend(Translate_context* context) ...@@ -2233,6 +2459,17 @@ Go_statement::do_get_backend(Translate_context* context)
return context->backend()->expression_statement(call_bexpr); return context->backend()->expression_statement(call_bexpr);
} }
// Dump the AST representation for go statement.
void
Go_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "go ";
ast_dump_context->dump_expression(this->call());
ast_dump_context->ostream() << std::endl;
}
// Make a go statement. // Make a go statement.
Statement* Statement*
...@@ -2261,6 +2498,17 @@ Defer_statement::do_get_backend(Translate_context* context) ...@@ -2261,6 +2498,17 @@ Defer_statement::do_get_backend(Translate_context* context)
return context->backend()->expression_statement(call_bexpr); return context->backend()->expression_statement(call_bexpr);
} }
// Dump the AST representation for defer statement.
void
Defer_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "defer ";
ast_dump_context->dump_expression(this->call());
ast_dump_context->ostream() << std::endl;
}
// Make a defer statement. // Make a defer statement.
Statement* Statement*
...@@ -2445,6 +2693,17 @@ Return_statement::do_get_backend(Translate_context* context) ...@@ -2445,6 +2693,17 @@ Return_statement::do_get_backend(Translate_context* context)
retvals, loc); retvals, loc);
} }
// Dump the AST representation for a return statement.
void
Return_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "return " ;
ast_dump_context->dump_expression_list(this->vals_);
ast_dump_context->ostream() << std::endl;
}
// Make a return statement. // Make a return statement.
Statement* Statement*
...@@ -2481,6 +2740,9 @@ class Bc_statement : public Statement ...@@ -2481,6 +2740,9 @@ class Bc_statement : public Statement
do_get_backend(Translate_context* context) do_get_backend(Translate_context* context)
{ return this->label_->get_goto(context, this->location()); } { return this->label_->get_goto(context, this->location()); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The label that this branches to. // The label that this branches to.
Unnamed_label* label_; Unnamed_label* label_;
...@@ -2488,6 +2750,21 @@ class Bc_statement : public Statement ...@@ -2488,6 +2750,21 @@ class Bc_statement : public Statement
bool is_break_; bool is_break_;
}; };
// Dump the AST representation for a break/continue statement
void
Bc_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << (this->is_break_ ? "break" : "continue");
if (this->label_ != NULL)
{
ast_dump_context->ostream() << " ";
ast_dump_context->dump_label_name(this->label_);
}
ast_dump_context->ostream() << std::endl;
}
// Make a break statement. // Make a break statement.
Statement* Statement*
...@@ -2530,6 +2807,9 @@ class Goto_statement : public Statement ...@@ -2530,6 +2807,9 @@ class Goto_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Label* label_; Label* label_;
}; };
...@@ -2557,6 +2837,15 @@ Goto_statement::do_get_backend(Translate_context* context) ...@@ -2557,6 +2837,15 @@ Goto_statement::do_get_backend(Translate_context* context)
return context->backend()->goto_statement(blabel, this->location()); return context->backend()->goto_statement(blabel, this->location());
} }
// Dump the AST representation for a goto statement.
void
Goto_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "goto " << this->label_->name() << std::endl;
}
// Make a goto statement. // Make a goto statement.
Statement* Statement*
...@@ -2588,10 +2877,25 @@ class Goto_unnamed_statement : public Statement ...@@ -2588,10 +2877,25 @@ class Goto_unnamed_statement : public Statement
do_get_backend(Translate_context* context) do_get_backend(Translate_context* context)
{ return this->label_->get_goto(context, this->location()); } { return this->label_->get_goto(context, this->location()); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Unnamed_label* label_; Unnamed_label* label_;
}; };
// Dump the AST representation for an unnamed goto statement
void
Goto_unnamed_statement::do_dump_statement(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "goto ";
ast_dump_context->dump_label_name(this->label_);
ast_dump_context->ostream() << std::endl;
}
// Make a goto statement to an unnamed label. // Make a goto statement to an unnamed label.
Statement* Statement*
...@@ -2621,6 +2925,15 @@ Label_statement::do_get_backend(Translate_context* context) ...@@ -2621,6 +2925,15 @@ Label_statement::do_get_backend(Translate_context* context)
return context->backend()->label_definition_statement(blabel); return context->backend()->label_definition_statement(blabel);
} }
// Dump the AST for a label definition statement.
void
Label_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << this->label_->name() << ":" << std::endl;
}
// Make a label statement. // Make a label statement.
Statement* Statement*
...@@ -2648,11 +2961,25 @@ class Unnamed_label_statement : public Statement ...@@ -2648,11 +2961,25 @@ class Unnamed_label_statement : public Statement
do_get_backend(Translate_context* context) do_get_backend(Translate_context* context)
{ return this->label_->get_definition(context); } { return this->label_->get_definition(context); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The label. // The label.
Unnamed_label* label_; Unnamed_label* label_;
}; };
// Dump the AST representation for an unnamed label definition statement.
void
Unnamed_label_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->print_indent();
ast_dump_context->dump_label_name(this->label_);
ast_dump_context->ostream() << ":" << std::endl;
}
// Make an unnamed label statement. // Make an unnamed label statement.
Statement* Statement*
...@@ -2688,6 +3015,9 @@ class If_statement : public Statement ...@@ -2688,6 +3015,9 @@ class If_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Expression* cond_; Expression* cond_;
Block* then_block_; Block* then_block_;
...@@ -2759,6 +3089,24 @@ If_statement::do_get_backend(Translate_context* context) ...@@ -2759,6 +3089,24 @@ If_statement::do_get_backend(Translate_context* context)
else_block, this->location()); else_block, this->location());
} }
// Dump the AST representation for an if statement
void
If_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "if ";
ast_dump_context->dump_expression(this->cond_);
ast_dump_context->ostream() << std::endl;
ast_dump_context->dump_block(this->then_block_);
if (this->else_block_ != NULL)
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "else" << std::endl;
ast_dump_context->dump_block(this->else_block_);
}
}
// Make an if statement. // Make an if statement.
Statement* Statement*
...@@ -3050,6 +3398,31 @@ Case_clauses::Case_clause::get_backend(Translate_context* context, ...@@ -3050,6 +3398,31 @@ Case_clauses::Case_clause::get_backend(Translate_context* context,
return context->backend()->compound_statement(statements, break_stat); return context->backend()->compound_statement(statements, break_stat);
} }
// Dump the AST representation for a case clause
void
Case_clauses::Case_clause::dump_clause(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->print_indent();
if (this->is_default_)
{
ast_dump_context->ostream() << "default:";
}
else
{
ast_dump_context->ostream() << "case ";
ast_dump_context->dump_expression_list(this->cases_);
ast_dump_context->ostream() << ":" ;
}
ast_dump_context->dump_block(this->statements_);
if (this->is_fallthrough_)
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << " (fallthrough)" << std::endl;
}
}
// Class Case_clauses. // Class Case_clauses.
// Traversal. // Traversal.
...@@ -3212,6 +3585,17 @@ Case_clauses::get_backend(Translate_context* context, ...@@ -3212,6 +3585,17 @@ Case_clauses::get_backend(Translate_context* context,
} }
} }
// Dump the AST representation for case clauses (from a switch statement)
void
Case_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
{
for (Clauses::const_iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
p->dump_clause(ast_dump_context);
}
// A constant switch statement. A Switch_statement is lowered to this // A constant switch statement. A Switch_statement is lowered to this
// when all the cases are constants. // when all the cases are constants.
...@@ -3241,6 +3625,9 @@ class Constant_switch_statement : public Statement ...@@ -3241,6 +3625,9 @@ class Constant_switch_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The value to switch on. // The value to switch on.
Expression* val_; Expression* val_;
...@@ -3320,6 +3707,20 @@ Constant_switch_statement::do_get_backend(Translate_context* context) ...@@ -3320,6 +3707,20 @@ Constant_switch_statement::do_get_backend(Translate_context* context)
return context->backend()->compound_statement(switch_statement, ldef); return context->backend()->compound_statement(switch_statement, ldef);
} }
// Dump the AST representation for a constant switch statement.
void
Constant_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "switch ";
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << " {" << std::endl;
this->clauses_->dump_clauses(ast_dump_context);
ast_dump_context->ostream() << "}" << std::endl;
}
// Class Switch_statement. // Class Switch_statement.
// Traversal. // Traversal.
...@@ -3395,6 +3796,24 @@ Switch_statement::break_label() ...@@ -3395,6 +3796,24 @@ Switch_statement::break_label()
return this->break_label_; return this->break_label_;
} }
// Dump the AST representation for a switch statement.
void
Switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "switch ";
if (this->val_ != NULL)
{
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << " ";
}
ast_dump_context->ostream() << "{" << std::endl;
this->clauses_->dump_clauses(ast_dump_context);
ast_dump_context->print_indent();
ast_dump_context->ostream() << "}" << std::endl;
}
// Make a switch statement. // Make a switch statement.
Switch_statement* Switch_statement*
...@@ -3519,6 +3938,31 @@ Type_case_clauses::Type_case_clause::lower(Block* b, ...@@ -3519,6 +3938,31 @@ Type_case_clauses::Type_case_clause::lower(Block* b,
} }
} }
// Dump the AST representation for a type case clause
void
Type_case_clauses::Type_case_clause::dump_clause(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
if (this->is_default_)
{
ast_dump_context->ostream() << "default:";
}
else
{
ast_dump_context->ostream() << "case ";
ast_dump_context->dump_type(this->type_);
ast_dump_context->ostream() << ":" ;
}
ast_dump_context->dump_block(this->statements_);
if (this->is_fallthrough_)
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << " (fallthrough)" << std::endl;
}
}
// Class Type_case_clauses. // Class Type_case_clauses.
// Traversal. // Traversal.
...@@ -3589,6 +4033,17 @@ Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp, ...@@ -3589,6 +4033,17 @@ Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
default_case->lower(b, descriptor_temp, break_label, NULL); default_case->lower(b, descriptor_temp, break_label, NULL);
} }
// Dump the AST representation for case clauses (from a switch statement)
void
Type_case_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
{
for (Type_clauses::const_iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
p->dump_clause(ast_dump_context);
}
// Class Type_switch_statement. // Class Type_switch_statement.
// Traversal. // Traversal.
...@@ -3692,6 +4147,20 @@ Type_switch_statement::break_label() ...@@ -3692,6 +4147,20 @@ Type_switch_statement::break_label()
return this->break_label_; return this->break_label_;
} }
// Dump the AST representation for a type switch statement
void
Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "switch " << this->var_->name() << " = ";
ast_dump_context->dump_expression(this->expr_);
ast_dump_context->ostream() << " .(type) {" << std::endl;
this->clauses_->dump_clauses(ast_dump_context);
ast_dump_context->ostream() << "}" << std::endl;
}
// Make a type switch statement. // Make a type switch statement.
Type_switch_statement* Type_switch_statement*
...@@ -3862,6 +4331,18 @@ Send_statement::do_get_backend(Translate_context* context) ...@@ -3862,6 +4331,18 @@ Send_statement::do_get_backend(Translate_context* context)
return context->backend()->compound_statement(btemp, s); return context->backend()->compound_statement(btemp, s);
} }
// Dump the AST representation for a send statement
void
Send_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->dump_expression(this->channel_);
ast_dump_context->ostream() << " <- ";
ast_dump_context->dump_expression(this->val_);
ast_dump_context->ostream() << std::endl;
}
// Make a send statement. // Make a send statement.
Send_statement* Send_statement*
...@@ -4053,6 +4534,48 @@ Select_clauses::Select_clause::get_statements_backend( ...@@ -4053,6 +4534,48 @@ Select_clauses::Select_clause::get_statements_backend(
return context->backend()->block_statement(bblock); return context->backend()->block_statement(bblock);
} }
// Dump the AST representation for a select case clause
void
Select_clauses::Select_clause::dump_clause(
Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
if (this->is_default_)
{
ast_dump_context->ostream() << "default:";
}
else
{
ast_dump_context->ostream() << "case " ;
if (this->is_send_)
{
ast_dump_context->dump_expression(this->channel_);
ast_dump_context->ostream() << " <- " ;
ast_dump_context->dump_expression(this->val_);
}
else
{
if (this->val_ != NULL)
ast_dump_context->dump_expression(this->val_);
if (this->closed_ != NULL)
{
// FIXME: can val_ == NULL and closed_ ! = NULL?
ast_dump_context->ostream() << " , " ;
ast_dump_context->dump_expression(this->closed_);
}
if (this->closedvar_ != NULL ||
this->var_ != NULL)
ast_dump_context->ostream() << " := " ;
ast_dump_context->ostream() << " <- " ;
ast_dump_context->dump_expression(this->channel_);
}
ast_dump_context->ostream() << ":" ;
}
ast_dump_context->dump_block(this->statements_);
}
// Class Select_clauses. // Class Select_clauses.
// Traversal. // Traversal.
...@@ -4326,6 +4849,17 @@ Select_clauses::add_clause_backend( ...@@ -4326,6 +4849,17 @@ Select_clauses::add_clause_backend(
(*clauses)[index] = context->backend()->compound_statement(s, g); (*clauses)[index] = context->backend()->compound_statement(s, g);
} }
// Dump the AST representation for select clauses.
void
Select_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
{
for (Clauses::const_iterator p = this->clauses_.begin();
p != this->clauses_.end();
++p)
p->dump_clause(ast_dump_context);
}
// Class Select_statement. // Class Select_statement.
// Return the break label for this switch statement, creating it if // Return the break label for this switch statement, creating it if
...@@ -4366,6 +4900,17 @@ Select_statement::do_get_backend(Translate_context* context) ...@@ -4366,6 +4900,17 @@ Select_statement::do_get_backend(Translate_context* context)
this->location()); this->location());
} }
// Dump the AST representation for a select statement.
void
Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "select {" << std::endl;
this->clauses_->dump_clauses(ast_dump_context);
ast_dump_context->ostream() << "}" << std::endl;
}
// Make a select statement. // Make a select statement.
Select_statement* Select_statement*
...@@ -4501,6 +5046,38 @@ For_statement::set_break_continue_labels(Unnamed_label* break_label, ...@@ -4501,6 +5046,38 @@ For_statement::set_break_continue_labels(Unnamed_label* break_label,
this->continue_label_ = continue_label; this->continue_label_ = continue_label;
} }
// Dump the AST representation for a for statement.
void
For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
if (this->init_ != NULL)
{
ast_dump_context->print_indent();
ast_dump_context->indent();
ast_dump_context->ostream() << "// INIT " << std::endl;
ast_dump_context->dump_block(this->init_);
ast_dump_context->unindent();
}
ast_dump_context->print_indent();
ast_dump_context->ostream() << "for ";
if (this->cond_ != NULL)
ast_dump_context->dump_expression(this->cond_);
ast_dump_context->ostream() << " {" << std::endl;
ast_dump_context->indent();
ast_dump_context->dump_block(this->statements_);
if (this->init_ != NULL)
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "// POST " << std::endl;
ast_dump_context->dump_block(this->post_);
}
ast_dump_context->unindent();
ast_dump_context->print_indent();
ast_dump_context->ostream() << "}" << std::endl;
}
// Make a for statement. // Make a for statement.
For_statement* For_statement*
...@@ -5119,6 +5696,33 @@ For_range_statement::continue_label() ...@@ -5119,6 +5696,33 @@ For_range_statement::continue_label()
return this->continue_label_; return this->continue_label_;
} }
// Dump the AST representation for a for range statement.
void
For_range_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->print_indent();
ast_dump_context->ostream() << "for ";
ast_dump_context->dump_expression(this->index_var_);
if (this->value_var_ != NULL)
{
ast_dump_context->ostream() << ", ";
ast_dump_context->dump_expression(this->value_var_);
}
ast_dump_context->ostream() << " = range ";
ast_dump_context->dump_expression(this->range_);
ast_dump_context->ostream() << " {" << std::endl;
ast_dump_context->indent();
ast_dump_context->dump_block(this->statements_);
ast_dump_context->unindent();
ast_dump_context->print_indent();
ast_dump_context->ostream() << "}" << std::endl;
}
// Make a for statement with a range clause. // Make a for statement with a range clause.
For_range_statement* For_range_statement*
......
...@@ -43,6 +43,7 @@ class Typed_identifier_list; ...@@ -43,6 +43,7 @@ class Typed_identifier_list;
class Bexpression; class Bexpression;
class Bstatement; class Bstatement;
class Bvariable; class Bvariable;
class Ast_dump_context;
// This class is used to traverse assignments made by a statement // This class is used to traverse assignments made by a statement
// which makes assignments. // which makes assignments.
...@@ -374,6 +375,10 @@ class Statement ...@@ -374,6 +375,10 @@ class Statement
Bstatement* Bstatement*
get_backend(Translate_context*); get_backend(Translate_context*);
// Dump AST representation of a statement to a dump context.
void
dump_statement(Ast_dump_context*) const;
protected: protected:
// Implemented by child class: traverse the tree. // Implemented by child class: traverse the tree.
virtual int virtual int
...@@ -414,6 +419,10 @@ class Statement ...@@ -414,6 +419,10 @@ class Statement
virtual Bstatement* virtual Bstatement*
do_get_backend(Translate_context*) = 0; do_get_backend(Translate_context*) = 0;
// Implemented by child class: dump ast representation.
virtual void
do_dump_statement(Ast_dump_context*) const = 0;
// Traverse an expression in a statement. // Traverse an expression in a statement.
int int
traverse_expression(Traverse*, Expression**); traverse_expression(Traverse*, Expression**);
...@@ -507,6 +516,9 @@ class Temporary_statement : public Statement ...@@ -507,6 +516,9 @@ class Temporary_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The type of the temporary variable. // The type of the temporary variable.
Type* type_; Type* type_;
...@@ -544,6 +556,9 @@ class Variable_declaration_statement : public Statement ...@@ -544,6 +556,9 @@ class Variable_declaration_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Named_object* var_; Named_object* var_;
}; };
...@@ -581,6 +596,9 @@ class Return_statement : public Statement ...@@ -581,6 +596,9 @@ class Return_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// Return values. This may be NULL. // Return values. This may be NULL.
Expression_list* vals_; Expression_list* vals_;
...@@ -617,6 +635,9 @@ class Send_statement : public Statement ...@@ -617,6 +635,9 @@ class Send_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The channel on which to send the value. // The channel on which to send the value.
Expression* channel_; Expression* channel_;
...@@ -678,6 +699,10 @@ class Select_clauses ...@@ -678,6 +699,10 @@ class Select_clauses
Bstatement* Bstatement*
get_backend(Translate_context*, Unnamed_label* break_label, source_location); get_backend(Translate_context*, Unnamed_label* break_label, source_location);
// Dump AST representation.
void
dump_clauses(Ast_dump_context*) const;
private: private:
// A single clause. // A single clause.
class Select_clause class Select_clause
...@@ -748,6 +773,10 @@ class Select_clauses ...@@ -748,6 +773,10 @@ class Select_clauses
Bstatement* Bstatement*
get_statements_backend(Translate_context*); get_statements_backend(Translate_context*);
// Dump AST representation.
void
dump_clause(Ast_dump_context*) const;
private: private:
// The channel. // The channel.
Expression* channel_; Expression* channel_;
...@@ -825,6 +854,9 @@ class Select_statement : public Statement ...@@ -825,6 +854,9 @@ class Select_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The select clauses. // The select clauses.
Select_clauses* clauses_; Select_clauses* clauses_;
...@@ -844,7 +876,7 @@ class Thunk_statement : public Statement ...@@ -844,7 +876,7 @@ class Thunk_statement : public Statement
// Return the call expression. // Return the call expression.
Expression* Expression*
call() call() const
{ return this->call_; } { return this->call_; }
// Simplify a go or defer statement so that it only uses a single // Simplify a go or defer statement so that it only uses a single
...@@ -914,6 +946,9 @@ class Go_statement : public Thunk_statement ...@@ -914,6 +946,9 @@ class Go_statement : public Thunk_statement
protected: protected:
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
}; };
// A defer statement. // A defer statement.
...@@ -928,6 +963,9 @@ class Defer_statement : public Thunk_statement ...@@ -928,6 +963,9 @@ class Defer_statement : public Thunk_statement
protected: protected:
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
}; };
// A label statement. // A label statement.
...@@ -952,6 +990,9 @@ class Label_statement : public Statement ...@@ -952,6 +990,9 @@ class Label_statement : public Statement
Bstatement* Bstatement*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The label. // The label.
Label* label_; Label* label_;
...@@ -1005,6 +1046,9 @@ class For_statement : public Statement ...@@ -1005,6 +1046,9 @@ class For_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The initialization statements. This may be NULL. // The initialization statements. This may be NULL.
Block* init_; Block* init_;
...@@ -1063,6 +1107,9 @@ class For_range_statement : public Statement ...@@ -1063,6 +1107,9 @@ class For_range_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
Expression* Expression*
make_range_ref(Named_object*, Temporary_statement*, source_location); make_range_ref(Named_object*, Temporary_statement*, source_location);
...@@ -1167,6 +1214,10 @@ class Case_clauses ...@@ -1167,6 +1214,10 @@ class Case_clauses
std::vector<std::vector<Bexpression*> >* all_cases, std::vector<std::vector<Bexpression*> >* all_cases,
std::vector<Bstatement*>* all_statements) const; std::vector<Bstatement*>* all_statements) const;
// Dump the AST representation to a dump context.
void
dump_clauses(Ast_dump_context*) const;
private: private:
// For a constant switch we need to keep a record of constants we // For a constant switch we need to keep a record of constants we
// have already seen. // have already seen.
...@@ -1237,6 +1288,10 @@ class Case_clauses ...@@ -1237,6 +1288,10 @@ class Case_clauses
get_backend(Translate_context*, Unnamed_label* break_label, get_backend(Translate_context*, Unnamed_label* break_label,
Case_constants*, std::vector<Bexpression*>* cases) const; Case_constants*, std::vector<Bexpression*>* cases) const;
// Dump the AST representation to a dump context.
void
dump_clause(Ast_dump_context*) const;
private: private:
// The list of case expressions. // The list of case expressions.
Expression_list* cases_; Expression_list* cases_;
...@@ -1292,6 +1347,9 @@ class Switch_statement : public Statement ...@@ -1292,6 +1347,9 @@ class Switch_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The value to switch on. This may be NULL. // The value to switch on. This may be NULL.
Expression* val_; Expression* val_;
...@@ -1342,6 +1400,10 @@ class Type_case_clauses ...@@ -1342,6 +1400,10 @@ class Type_case_clauses
lower(Block*, Temporary_statement* descriptor_temp, lower(Block*, Temporary_statement* descriptor_temp,
Unnamed_label* break_label) const; Unnamed_label* break_label) const;
// Dump the AST representation to a dump context.
void
dump_clauses(Ast_dump_context*) const;
private: private:
// One type case clause. // One type case clause.
class Type_case_clause class Type_case_clause
...@@ -1382,6 +1444,10 @@ class Type_case_clauses ...@@ -1382,6 +1444,10 @@ class Type_case_clauses
lower(Block*, Temporary_statement* descriptor_temp, lower(Block*, Temporary_statement* descriptor_temp,
Unnamed_label* break_label, Unnamed_label** stmts_label) const; Unnamed_label* break_label, Unnamed_label** stmts_label) const;
// Dump the AST representation to a dump context.
void
dump_clause(Ast_dump_context*) const;
private: private:
// The type for this type clause. // The type for this type clause.
Type* type_; Type* type_;
...@@ -1438,6 +1504,9 @@ class Type_switch_statement : public Statement ...@@ -1438,6 +1504,9 @@ class Type_switch_statement : public Statement
do_get_backend(Translate_context*) do_get_backend(Translate_context*)
{ go_unreachable(); } { go_unreachable(); }
void
do_dump_statement(Ast_dump_context*) const;
private: private:
// The variable holding the value we are switching on. // The variable holding the value we are switching on.
Named_object* var_; Named_object* var_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment