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
This commit is contained in:
parent
44e7bfcb6f
commit
16c57fe280
10 changed files with 1861 additions and 5 deletions
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
* go-lang.c (go_langhook_init):
|
||||
|
|
|
@ -45,6 +45,7 @@ gccgo$(exeext): $(GCCGO_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
|
|||
go-warn = $(STRICT_WARN)
|
||||
|
||||
GO_OBJS = \
|
||||
go/ast-dump.o \
|
||||
go/dataflow.o \
|
||||
go/export.o \
|
||||
go/expressions.o \
|
||||
|
@ -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
|
||||
$(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_EXPRESSIONS_H) $(GO_STATEMENTS_H) go/gofrontend/dataflow.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) \
|
|||
intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_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_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_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_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) \
|
|||
go/gofrontend/runtime.def
|
||||
go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_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) \
|
||||
$(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \
|
||||
go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \
|
||||
|
|
423
gcc/go/gofrontend/ast-dump.cc
Normal file
423
gcc/go/gofrontend/ast-dump.cc
Normal file
|
@ -0,0 +1,423 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
96
gcc/go/gofrontend/ast-dump.h
Normal file
96
gcc/go/gofrontend/ast-dump.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
// 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
|
File diff suppressed because it is too large
Load diff
|
@ -42,6 +42,7 @@ class Export;
|
|||
class Import;
|
||||
class Temporary_statement;
|
||||
class Label;
|
||||
class Ast_dump_context;
|
||||
|
||||
// The base class for all expressions.
|
||||
|
||||
|
@ -635,6 +636,10 @@ class Expression
|
|||
static tree
|
||||
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:
|
||||
// May be implemented by child class: traverse the expressions.
|
||||
virtual int
|
||||
|
@ -731,6 +736,10 @@ class Expression
|
|||
void
|
||||
report_error(const char*);
|
||||
|
||||
// Child class implements dumping to a dump context.
|
||||
virtual void
|
||||
do_dump_expression(Ast_dump_context*) const = 0;
|
||||
|
||||
private:
|
||||
// Convert to the desired statement classification, or return NULL.
|
||||
// This is a controlled dynamic cast.
|
||||
|
@ -934,6 +943,9 @@ class Var_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The variable we are referencing.
|
||||
Named_object* variable_;
|
||||
|
@ -978,6 +990,9 @@ class Temporary_reference_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The statement where the temporary variable is defined.
|
||||
Temporary_statement* statement_;
|
||||
|
@ -1031,6 +1046,9 @@ class String_expression : public Expression
|
|||
void
|
||||
do_export(Export*) const;
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The string value. This is immutable.
|
||||
const std::string val_;
|
||||
|
@ -1154,6 +1172,9 @@ class Binary_expression : public Expression
|
|||
void
|
||||
do_export(Export*) const;
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The binary operator to apply.
|
||||
Operator op_;
|
||||
|
@ -1290,6 +1311,9 @@ class Call_expression : public Expression
|
|||
bool
|
||||
determining_types();
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
bool
|
||||
check_argument_type(int, const Type*, const Type*, source_location, bool);
|
||||
|
@ -1384,6 +1408,9 @@ class Func_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The function itself.
|
||||
Named_object* function_;
|
||||
|
@ -1432,6 +1459,9 @@ class Unknown_expression : public Parser_expression
|
|||
do_copy()
|
||||
{ return new Unknown_expression(this->named_object_, this->location()); }
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The unknown name.
|
||||
Named_object* named_object_;
|
||||
|
@ -1456,6 +1486,12 @@ class Index_expression : public Parser_expression
|
|||
set_is_lvalue()
|
||||
{ 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:
|
||||
int
|
||||
do_traverse(Traverse*);
|
||||
|
@ -1473,6 +1509,9 @@ class Index_expression : public Parser_expression
|
|||
this->location());
|
||||
}
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The expression being indexed.
|
||||
Expression* left_;
|
||||
|
@ -1572,6 +1611,9 @@ class Map_index_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The map we are looking into.
|
||||
Expression* map_;
|
||||
|
@ -1641,6 +1683,9 @@ class Bound_method_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The object used to find the method. This is passed to the method
|
||||
// as the first argument.
|
||||
|
@ -1712,6 +1757,9 @@ class Field_reference_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The expression we are looking into. This should have a type of
|
||||
// struct.
|
||||
|
@ -1777,6 +1825,9 @@ class Interface_field_reference_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The expression for the interface object. This should have a type
|
||||
// of interface or pointer to interface.
|
||||
|
@ -1830,6 +1881,9 @@ class Type_guard_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The expression to convert.
|
||||
Expression* expr_;
|
||||
|
@ -1889,6 +1943,9 @@ class Receive_expression : public Expression
|
|||
tree
|
||||
do_get_tree(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_expression(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The channel from which we are receiving.
|
||||
Expression* channel_;
|
||||
|
|
|
@ -133,6 +133,9 @@ go_parse_input_files(const char** filenames, unsigned int filename_count,
|
|||
|
||||
// Convert complicated go and defer statements into simpler ones.
|
||||
::gogo->simplify_thunk_statements();
|
||||
|
||||
// Dump ast, use filename[0] as the base name
|
||||
::gogo->dump_ast(filenames[0]);
|
||||
}
|
||||
|
||||
// Write out globals.
|
||||
|
|
|
@ -422,6 +422,10 @@ class Gogo
|
|||
void
|
||||
simplify_thunk_statements();
|
||||
|
||||
// Dump AST if -fgo-dump-ast is set
|
||||
void
|
||||
dump_ast(const char* basename);
|
||||
|
||||
// Convert named types to the backend representation.
|
||||
void
|
||||
convert_named_types();
|
||||
|
@ -512,7 +516,6 @@ class Gogo
|
|||
receive_as_64bit_integer(tree type, tree channel, bool blocking,
|
||||
bool for_select);
|
||||
|
||||
|
||||
// Make a trampoline which calls FNADDR passing CLOSURE.
|
||||
tree
|
||||
make_trampoline(tree fnaddr, tree closure, source_location);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "runtime.h"
|
||||
#include "backend.h"
|
||||
#include "statements.h"
|
||||
#include "ast-dump.h"
|
||||
|
||||
// Class Statement.
|
||||
|
||||
|
@ -142,6 +143,14 @@ Statement::get_backend(Translate_context* 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
|
||||
// when they discover an error.
|
||||
|
||||
|
@ -178,8 +187,20 @@ class Error_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*)
|
||||
{ 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.
|
||||
|
||||
Statement*
|
||||
|
@ -280,6 +301,30 @@ Variable_declaration_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -422,6 +467,27 @@ Temporary_statement::get_backend_variable(Translate_context* context) const
|
|||
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.
|
||||
|
||||
Temporary_statement*
|
||||
|
@ -458,6 +524,9 @@ class Assignment_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// Left hand side--the lvalue.
|
||||
Expression* lhs_;
|
||||
|
@ -542,6 +611,19 @@ Assignment_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -614,6 +696,9 @@ class Assignment_operation_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The operator (OPERATOR_PLUSEQ, etc.).
|
||||
Operator op_;
|
||||
|
@ -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.
|
||||
|
||||
Statement*
|
||||
|
@ -741,6 +839,9 @@ class Tuple_assignment_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// Left hand side--a list of lvalues.
|
||||
Expression_list* lhs_;
|
||||
|
@ -768,7 +869,7 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
|
|||
source_location loc = this->location();
|
||||
|
||||
Block* b = new Block(enclosing, loc);
|
||||
|
||||
|
||||
// First move out any subexpressions on the left hand side. The
|
||||
// right hand side will be evaluated in the required order anyhow.
|
||||
Move_ordered_evals moe(b);
|
||||
|
@ -832,6 +933,19 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -869,6 +983,9 @@ public:
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// Lvalue which receives the value from the map.
|
||||
Expression* val_;
|
||||
|
@ -960,6 +1077,21 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*,
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -998,6 +1130,9 @@ class Map_assignment_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// A reference to the map index which should be set or deleted.
|
||||
Expression* map_index_;
|
||||
|
@ -1076,6 +1211,21 @@ Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing,
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -1113,6 +1263,9 @@ class Tuple_receive_assignment_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// Lvalue which receives the value from the channel.
|
||||
Expression* val_;
|
||||
|
@ -1200,6 +1353,21 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*,
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -1240,6 +1408,9 @@ class Tuple_type_guard_assignment_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Call_expression*
|
||||
lower_to_type(Runtime::Function);
|
||||
|
@ -1375,6 +1546,23 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -1415,6 +1603,9 @@ class Expression_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context* context);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Expression* expr_;
|
||||
};
|
||||
|
@ -1459,6 +1650,17 @@ Expression_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -1494,6 +1696,9 @@ class Block_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context* context);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Block* block_;
|
||||
};
|
||||
|
@ -1507,6 +1712,14 @@ Block_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -1541,6 +1754,9 @@ class Inc_dec_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The l-value to increment or decrement.
|
||||
Expression* expr_;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
Statement*
|
||||
|
@ -2233,6 +2459,17 @@ Go_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2261,6 +2498,17 @@ Defer_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2445,6 +2693,17 @@ Return_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2481,6 +2740,9 @@ class Bc_statement : public Statement
|
|||
do_get_backend(Translate_context* context)
|
||||
{ return this->label_->get_goto(context, this->location()); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The label that this branches to.
|
||||
Unnamed_label* label_;
|
||||
|
@ -2488,6 +2750,21 @@ class Bc_statement : public Statement
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2530,6 +2807,9 @@ class Goto_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Label* label_;
|
||||
};
|
||||
|
@ -2557,6 +2837,15 @@ Goto_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2588,10 +2877,25 @@ class Goto_unnamed_statement : public Statement
|
|||
do_get_backend(Translate_context* context)
|
||||
{ return this->label_->get_goto(context, this->location()); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2621,6 +2925,15 @@ Label_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -2648,11 +2961,25 @@ class Unnamed_label_statement : public Statement
|
|||
do_get_backend(Translate_context* context)
|
||||
{ return this->label_->get_definition(context); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The 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.
|
||||
|
||||
Statement*
|
||||
|
@ -2688,6 +3015,9 @@ class If_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Expression* cond_;
|
||||
Block* then_block_;
|
||||
|
@ -2759,6 +3089,24 @@ If_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Statement*
|
||||
|
@ -3050,6 +3398,31 @@ Case_clauses::Case_clause::get_backend(Translate_context* context,
|
|||
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.
|
||||
|
||||
// Traversal.
|
||||
|
@ -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
|
||||
// when all the cases are constants.
|
||||
|
||||
|
@ -3241,6 +3625,9 @@ class Constant_switch_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The value to switch on.
|
||||
Expression* val_;
|
||||
|
@ -3320,6 +3707,20 @@ Constant_switch_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
// Traversal.
|
||||
|
@ -3395,6 +3796,24 @@ Switch_statement::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.
|
||||
|
||||
Switch_statement*
|
||||
|
@ -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.
|
||||
|
||||
// Traversal.
|
||||
|
@ -3589,6 +4033,17 @@ Type_case_clauses::lower(Block* b, Temporary_statement* descriptor_temp,
|
|||
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.
|
||||
|
||||
// Traversal.
|
||||
|
@ -3692,6 +4147,20 @@ Type_switch_statement::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.
|
||||
|
||||
Type_switch_statement*
|
||||
|
@ -3862,6 +4331,18 @@ Send_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Send_statement*
|
||||
|
@ -4053,6 +4534,48 @@ Select_clauses::Select_clause::get_statements_backend(
|
|||
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.
|
||||
|
||||
// Traversal.
|
||||
|
@ -4326,6 +4849,17 @@ Select_clauses::add_clause_backend(
|
|||
(*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.
|
||||
|
||||
// Return the break label for this switch statement, creating it if
|
||||
|
@ -4366,6 +4900,17 @@ Select_statement::do_get_backend(Translate_context* context)
|
|||
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.
|
||||
|
||||
Select_statement*
|
||||
|
@ -4501,6 +5046,38 @@ For_statement::set_break_continue_labels(Unnamed_label* break_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.
|
||||
|
||||
For_statement*
|
||||
|
@ -5119,6 +5696,33 @@ For_range_statement::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.
|
||||
|
||||
For_range_statement*
|
||||
|
|
|
@ -43,6 +43,7 @@ class Typed_identifier_list;
|
|||
class Bexpression;
|
||||
class Bstatement;
|
||||
class Bvariable;
|
||||
class Ast_dump_context;
|
||||
|
||||
// This class is used to traverse assignments made by a statement
|
||||
// which makes assignments.
|
||||
|
@ -374,6 +375,10 @@ class Statement
|
|||
Bstatement*
|
||||
get_backend(Translate_context*);
|
||||
|
||||
// Dump AST representation of a statement to a dump context.
|
||||
void
|
||||
dump_statement(Ast_dump_context*) const;
|
||||
|
||||
protected:
|
||||
// Implemented by child class: traverse the tree.
|
||||
virtual int
|
||||
|
@ -414,6 +419,10 @@ class Statement
|
|||
virtual Bstatement*
|
||||
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.
|
||||
int
|
||||
traverse_expression(Traverse*, Expression**);
|
||||
|
@ -507,6 +516,9 @@ class Temporary_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The type of the temporary variable.
|
||||
Type* type_;
|
||||
|
@ -544,6 +556,9 @@ class Variable_declaration_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Named_object* var_;
|
||||
};
|
||||
|
@ -581,6 +596,9 @@ class Return_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// Return values. This may be NULL.
|
||||
Expression_list* vals_;
|
||||
|
@ -617,6 +635,9 @@ class Send_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The channel on which to send the value.
|
||||
Expression* channel_;
|
||||
|
@ -678,6 +699,10 @@ class Select_clauses
|
|||
Bstatement*
|
||||
get_backend(Translate_context*, Unnamed_label* break_label, source_location);
|
||||
|
||||
// Dump AST representation.
|
||||
void
|
||||
dump_clauses(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// A single clause.
|
||||
class Select_clause
|
||||
|
@ -748,6 +773,10 @@ class Select_clauses
|
|||
Bstatement*
|
||||
get_statements_backend(Translate_context*);
|
||||
|
||||
// Dump AST representation.
|
||||
void
|
||||
dump_clause(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The channel.
|
||||
Expression* channel_;
|
||||
|
@ -825,6 +854,9 @@ class Select_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The select clauses.
|
||||
Select_clauses* clauses_;
|
||||
|
@ -844,7 +876,7 @@ class Thunk_statement : public Statement
|
|||
|
||||
// Return the call expression.
|
||||
Expression*
|
||||
call()
|
||||
call() const
|
||||
{ return this->call_; }
|
||||
|
||||
// Simplify a go or defer statement so that it only uses a single
|
||||
|
@ -914,6 +946,9 @@ class Go_statement : public Thunk_statement
|
|||
protected:
|
||||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
};
|
||||
|
||||
// A defer statement.
|
||||
|
@ -928,6 +963,9 @@ class Defer_statement : public Thunk_statement
|
|||
protected:
|
||||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
};
|
||||
|
||||
// A label statement.
|
||||
|
@ -952,6 +990,9 @@ class Label_statement : public Statement
|
|||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The label.
|
||||
Label* label_;
|
||||
|
@ -1005,6 +1046,9 @@ class For_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The initialization statements. This may be NULL.
|
||||
Block* init_;
|
||||
|
@ -1063,6 +1107,9 @@ class For_range_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
Expression*
|
||||
make_range_ref(Named_object*, Temporary_statement*, source_location);
|
||||
|
@ -1167,6 +1214,10 @@ class Case_clauses
|
|||
std::vector<std::vector<Bexpression*> >* all_cases,
|
||||
std::vector<Bstatement*>* all_statements) const;
|
||||
|
||||
// Dump the AST representation to a dump context.
|
||||
void
|
||||
dump_clauses(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// For a constant switch we need to keep a record of constants we
|
||||
// have already seen.
|
||||
|
@ -1237,6 +1288,10 @@ class Case_clauses
|
|||
get_backend(Translate_context*, Unnamed_label* break_label,
|
||||
Case_constants*, std::vector<Bexpression*>* cases) const;
|
||||
|
||||
// Dump the AST representation to a dump context.
|
||||
void
|
||||
dump_clause(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The list of case expressions.
|
||||
Expression_list* cases_;
|
||||
|
@ -1292,6 +1347,9 @@ class Switch_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The value to switch on. This may be NULL.
|
||||
Expression* val_;
|
||||
|
@ -1342,6 +1400,10 @@ class Type_case_clauses
|
|||
lower(Block*, Temporary_statement* descriptor_temp,
|
||||
Unnamed_label* break_label) const;
|
||||
|
||||
// Dump the AST representation to a dump context.
|
||||
void
|
||||
dump_clauses(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// One type case clause.
|
||||
class Type_case_clause
|
||||
|
@ -1382,6 +1444,10 @@ class Type_case_clauses
|
|||
lower(Block*, Temporary_statement* descriptor_temp,
|
||||
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:
|
||||
// The type for this type clause.
|
||||
Type* type_;
|
||||
|
@ -1438,6 +1504,9 @@ class Type_switch_statement : public Statement
|
|||
do_get_backend(Translate_context*)
|
||||
{ go_unreachable(); }
|
||||
|
||||
void
|
||||
do_dump_statement(Ast_dump_context*) const;
|
||||
|
||||
private:
|
||||
// The variable holding the value we are switching on.
|
||||
Named_object* var_;
|
||||
|
|
Loading…
Add table
Reference in a new issue