aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/gcc/go/gofrontend/statements.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.1/gcc/go/gofrontend/statements.h')
-rw-r--r--gcc-4.8.1/gcc/go/gofrontend/statements.h1570
1 files changed, 0 insertions, 1570 deletions
diff --git a/gcc-4.8.1/gcc/go/gofrontend/statements.h b/gcc-4.8.1/gcc/go/gofrontend/statements.h
deleted file mode 100644
index c59957107..000000000
--- a/gcc-4.8.1/gcc/go/gofrontend/statements.h
+++ /dev/null
@@ -1,1570 +0,0 @@
-// statements.h -- Go frontend statements. -*- C++ -*-
-
-// Copyright 2009 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_STATEMENTS_H
-#define GO_STATEMENTS_H
-
-#include "operator.h"
-
-class Gogo;
-class Traverse;
-class Statement_inserter;
-class Block;
-class Function;
-class Unnamed_label;
-class Temporary_statement;
-class Variable_declaration_statement;
-class Return_statement;
-class Thunk_statement;
-class Label_statement;
-class For_statement;
-class For_range_statement;
-class Switch_statement;
-class Type_switch_statement;
-class Send_statement;
-class Select_statement;
-class Variable;
-class Named_object;
-class Label;
-class Translate_context;
-class Expression;
-class Expression_list;
-class Struct_type;
-class Call_expression;
-class Map_index_expression;
-class Receive_expression;
-class Case_clauses;
-class Type_case_clauses;
-class Select_clauses;
-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.
-
-class Traverse_assignments
-{
- public:
- Traverse_assignments()
- { }
-
- virtual ~Traverse_assignments()
- { }
-
- // This is called for a variable initialization.
- virtual void
- initialize_variable(Named_object*) = 0;
-
- // This is called for each assignment made by the statement. PLHS
- // points to the left hand side, and PRHS points to the right hand
- // side. PRHS may be NULL if there is no associated expression, as
- // in the bool set by a non-blocking receive.
- virtual void
- assignment(Expression** plhs, Expression** prhs) = 0;
-
- // This is called for each expression which is not passed to the
- // assignment function. This is used for some of the statements
- // which assign two values, for which there is no expression which
- // describes the value. For ++ and -- the value is passed to both
- // the assignment method and the rhs method. IS_STORED is true if
- // this value is being stored directly. It is false if the value is
- // computed but not stored. IS_LOCAL is true if the value is being
- // stored in a local variable or this is being called by a return
- // statement.
- virtual void
- value(Expression**, bool is_stored, bool is_local) = 0;
-};
-
-// A single statement.
-
-class Statement
-{
- public:
- // The types of statements.
- enum Statement_classification
- {
- STATEMENT_ERROR,
- STATEMENT_VARIABLE_DECLARATION,
- STATEMENT_TEMPORARY,
- STATEMENT_ASSIGNMENT,
- STATEMENT_EXPRESSION,
- STATEMENT_BLOCK,
- STATEMENT_GO,
- STATEMENT_DEFER,
- STATEMENT_RETURN,
- STATEMENT_BREAK_OR_CONTINUE,
- STATEMENT_GOTO,
- STATEMENT_GOTO_UNNAMED,
- STATEMENT_LABEL,
- STATEMENT_UNNAMED_LABEL,
- STATEMENT_IF,
- STATEMENT_CONSTANT_SWITCH,
- STATEMENT_SEND,
- STATEMENT_SELECT,
-
- // These statements types are created by the parser, but they
- // disappear during the lowering pass.
- STATEMENT_ASSIGNMENT_OPERATION,
- STATEMENT_TUPLE_ASSIGNMENT,
- STATEMENT_TUPLE_MAP_ASSIGNMENT,
- STATEMENT_MAP_ASSIGNMENT,
- STATEMENT_TUPLE_RECEIVE_ASSIGNMENT,
- STATEMENT_TUPLE_TYPE_GUARD_ASSIGNMENT,
- STATEMENT_INCDEC,
- STATEMENT_FOR,
- STATEMENT_FOR_RANGE,
- STATEMENT_SWITCH,
- STATEMENT_TYPE_SWITCH
- };
-
- Statement(Statement_classification, Location);
-
- virtual ~Statement();
-
- // Make a variable declaration.
- static Statement*
- make_variable_declaration(Named_object*);
-
- // Make a statement which creates a temporary variable and
- // initializes it to an expression. The block is used if the
- // temporary variable has to be explicitly destroyed; the variable
- // must still be added to the block. References to the temporary
- // variable may be constructed using make_temporary_reference.
- // Either the type or the initialization expression may be NULL, but
- // not both.
- static Temporary_statement*
- make_temporary(Type*, Expression*, Location);
-
- // Make an assignment statement.
- static Statement*
- make_assignment(Expression*, Expression*, Location);
-
- // Make an assignment operation (+=, etc.).
- static Statement*
- make_assignment_operation(Operator, Expression*, Expression*,
- Location);
-
- // Make a tuple assignment statement.
- static Statement*
- make_tuple_assignment(Expression_list*, Expression_list*, Location);
-
- // Make an assignment from a map index to a pair of variables.
- static Statement*
- make_tuple_map_assignment(Expression* val, Expression* present,
- Expression*, Location);
-
- // Make a statement which assigns a pair of values to a map.
- static Statement*
- make_map_assignment(Expression*, Expression* val,
- Expression* should_set, Location);
-
- // Make an assignment from a nonblocking receive to a pair of
- // variables.
- static Statement*
- make_tuple_receive_assignment(Expression* val, Expression* closed,
- Expression* channel, Location);
-
- // Make an assignment from a type guard to a pair of variables.
- static Statement*
- make_tuple_type_guard_assignment(Expression* val, Expression* ok,
- Expression* expr, Type* type,
- Location);
-
- // Make an expression statement from an Expression. IS_IGNORED is
- // true if the value is being explicitly ignored, as in an
- // assignment to _.
- static Statement*
- make_statement(Expression*, bool is_ignored);
-
- // Make a block statement from a Block. This is an embedded list of
- // statements which may also include variable definitions.
- static Statement*
- make_block_statement(Block*, Location);
-
- // Make an increment statement.
- static Statement*
- make_inc_statement(Expression*);
-
- // Make a decrement statement.
- static Statement*
- make_dec_statement(Expression*);
-
- // Make a go statement.
- static Statement*
- make_go_statement(Call_expression* call, Location);
-
- // Make a defer statement.
- static Statement*
- make_defer_statement(Call_expression* call, Location);
-
- // Make a return statement.
- static Return_statement*
- make_return_statement(Expression_list*, Location);
-
- // Make a break statement.
- static Statement*
- make_break_statement(Unnamed_label* label, Location);
-
- // Make a continue statement.
- static Statement*
- make_continue_statement(Unnamed_label* label, Location);
-
- // Make a goto statement.
- static Statement*
- make_goto_statement(Label* label, Location);
-
- // Make a goto statement to an unnamed label.
- static Statement*
- make_goto_unnamed_statement(Unnamed_label* label, Location);
-
- // Make a label statement--where the label is defined.
- static Statement*
- make_label_statement(Label* label, Location);
-
- // Make an unnamed label statement--where the label is defined.
- static Statement*
- make_unnamed_label_statement(Unnamed_label* label);
-
- // Make an if statement.
- static Statement*
- make_if_statement(Expression* cond, Block* then_block, Block* else_block,
- Location);
-
- // Make a switch statement.
- static Switch_statement*
- make_switch_statement(Expression* switch_val, Location);
-
- // Make a type switch statement.
- static Type_switch_statement*
- make_type_switch_statement(Named_object* var, Expression*, Location);
-
- // Make a send statement.
- static Send_statement*
- make_send_statement(Expression* channel, Expression* val, Location);
-
- // Make a select statement.
- static Select_statement*
- make_select_statement(Location);
-
- // Make a for statement.
- static For_statement*
- make_for_statement(Block* init, Expression* cond, Block* post,
- Location location);
-
- // Make a for statement with a range clause.
- static For_range_statement*
- make_for_range_statement(Expression* index_var, Expression* value_var,
- Expression* range, Location);
-
- // Return the statement classification.
- Statement_classification
- classification() const
- { return this->classification_; }
-
- // Get the statement location.
- Location
- location() const
- { return this->location_; }
-
- // Traverse the tree.
- int
- traverse(Block*, size_t* index, Traverse*);
-
- // Traverse the contents of this statement--the expressions and
- // statements which it contains.
- int
- traverse_contents(Traverse*);
-
- // If this statement assigns some values, it calls a function for
- // each value to which this statement assigns a value, and returns
- // true. If this statement does not assign any values, it returns
- // false.
- bool
- traverse_assignments(Traverse_assignments* tassign);
-
- // Lower a statement. This is called immediately after parsing to
- // simplify statements for further processing. It returns the same
- // Statement or a new one. FUNCTION is the function containing this
- // statement. BLOCK is the block containing this statement.
- // INSERTER can be used to insert new statements before this one.
- Statement*
- lower(Gogo* gogo, Named_object* function, Block* block,
- Statement_inserter* inserter)
- { return this->do_lower(gogo, function, block, inserter); }
-
- // Set type information for unnamed constants.
- void
- determine_types();
-
- // Check types in a statement. This simply checks that any
- // expressions used by the statement have the right type.
- void
- check_types(Gogo* gogo)
- { this->do_check_types(gogo); }
-
- // Return whether this is a block statement.
- bool
- is_block_statement() const
- { return this->classification_ == STATEMENT_BLOCK; }
-
- // If this is a variable declaration statement, return it.
- // Otherwise return NULL.
- Variable_declaration_statement*
- variable_declaration_statement()
- {
- return this->convert<Variable_declaration_statement,
- STATEMENT_VARIABLE_DECLARATION>();
- }
-
- // If this is a return statement, return it. Otherwise return NULL.
- Return_statement*
- return_statement()
- { return this->convert<Return_statement, STATEMENT_RETURN>(); }
-
- // If this is a thunk statement (a go or defer statement), return
- // it. Otherwise return NULL.
- Thunk_statement*
- thunk_statement();
-
- // If this is a label statement, return it. Otherwise return NULL.
- Label_statement*
- label_statement()
- { return this->convert<Label_statement, STATEMENT_LABEL>(); }
-
- // If this is a for statement, return it. Otherwise return NULL.
- For_statement*
- for_statement()
- { return this->convert<For_statement, STATEMENT_FOR>(); }
-
- // If this is a for statement over a range clause, return it.
- // Otherwise return NULL.
- For_range_statement*
- for_range_statement()
- { return this->convert<For_range_statement, STATEMENT_FOR_RANGE>(); }
-
- // If this is a switch statement, return it. Otherwise return NULL.
- Switch_statement*
- switch_statement()
- { return this->convert<Switch_statement, STATEMENT_SWITCH>(); }
-
- // If this is a type switch statement, return it. Otherwise return
- // NULL.
- Type_switch_statement*
- type_switch_statement()
- { return this->convert<Type_switch_statement, STATEMENT_TYPE_SWITCH>(); }
-
- // If this is a select statement, return it. Otherwise return NULL.
- Select_statement*
- select_statement()
- { return this->convert<Select_statement, STATEMENT_SELECT>(); }
-
- // Return true if this statement may fall through--if after
- // executing this statement we may go on to execute the following
- // statement, if any.
- bool
- may_fall_through() const
- { return this->do_may_fall_through(); }
-
- // Convert the statement to the backend representation.
- 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
- do_traverse(Traverse*) = 0;
-
- // Implemented by child class: traverse assignments. Any statement
- // which includes an assignment should implement this.
- virtual bool
- do_traverse_assignments(Traverse_assignments*)
- { return false; }
-
- // Implemented by the child class: lower this statement to a simpler
- // one.
- virtual Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
- { return this; }
-
- // Implemented by child class: set type information for unnamed
- // constants. Any statement which includes an expression needs to
- // implement this.
- virtual void
- do_determine_types()
- { }
-
- // Implemented by child class: check types of expressions used in a
- // statement.
- virtual void
- do_check_types(Gogo*)
- { }
-
- // Implemented by child class: return true if this statement may
- // fall through.
- virtual bool
- do_may_fall_through() const
- { return true; }
-
- // Implemented by child class: convert to backend representation.
- 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**);
-
- // Traverse an expression list in a statement. The Expression_list
- // may be NULL.
- int
- traverse_expression_list(Traverse*, Expression_list*);
-
- // Traverse a type in a statement.
- int
- traverse_type(Traverse*, Type*);
-
- // For children to call when they detect that they are in error.
- void
- set_is_error();
-
- // For children to call to report an error conveniently.
- void
- report_error(const char*);
-
- // For children to return an error statement from lower().
- static Statement*
- make_error_statement(Location);
-
- private:
- // Convert to the desired statement classification, or return NULL.
- // This is a controlled dynamic cast.
- template<typename Statement_class, Statement_classification sc>
- Statement_class*
- convert()
- {
- return (this->classification_ == sc
- ? static_cast<Statement_class*>(this)
- : NULL);
- }
-
- template<typename Statement_class, Statement_classification sc>
- const Statement_class*
- convert() const
- {
- return (this->classification_ == sc
- ? static_cast<const Statement_class*>(this)
- : NULL);
- }
-
- // The statement classification.
- Statement_classification classification_;
- // The location in the input file of the start of this statement.
- Location location_;
-};
-
-// A statement which creates and initializes a temporary variable.
-
-class Temporary_statement : public Statement
-{
- public:
- Temporary_statement(Type* type, Expression* init, Location location)
- : Statement(STATEMENT_TEMPORARY, location),
- type_(type), init_(init), bvariable_(NULL), are_hidden_fields_ok_(false),
- is_address_taken_(false)
- { }
-
- // Return the type of the temporary variable.
- Type*
- type() const;
-
- // Return the initializer if there is one.
- Expression*
- init() const
- { return this->init_; }
-
- // Note that it is OK for this statement to set hidden fields.
- void
- set_hidden_fields_are_ok()
- { this->are_hidden_fields_ok_ = true; }
-
- // Record that something takes the address of this temporary
- // variable.
- void
- set_is_address_taken()
- { this->is_address_taken_ = true; }
-
- // Return the temporary variable. This should not be called until
- // after the statement itself has been converted.
- Bvariable*
- get_backend_variable(Translate_context*) const;
-
- protected:
- int
- do_traverse(Traverse*);
-
- bool
- do_traverse_assignments(Traverse_assignments*);
-
- void
- do_determine_types();
-
- void
- do_check_types(Gogo*);
-
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-
- private:
- // The type of the temporary variable.
- Type* type_;
- // The initial value of the temporary variable. This may be NULL.
- Expression* init_;
- // The backend representation of the temporary variable.
- Bvariable* bvariable_;
- // True if this statement may set hidden fields when assigning the
- // value to the temporary. This is used for generated method stubs.
- bool are_hidden_fields_ok_;
- // True if something takes the address of this temporary variable.
- bool is_address_taken_;
-};
-
-// A variable declaration. This marks the point in the code where a
-// variable is declared. The Variable is also attached to a Block.
-
-class Variable_declaration_statement : public Statement
-{
- public:
- Variable_declaration_statement(Named_object* var);
-
- // The variable being declared.
- Named_object*
- var()
- { return this->var_; }
-
- protected:
- int
- do_traverse(Traverse*);
-
- bool
- do_traverse_assignments(Traverse_assignments*);
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-
- private:
- Named_object* var_;
-};
-
-// A return statement.
-
-class Return_statement : public Statement
-{
- public:
- Return_statement(Expression_list* vals, Location location)
- : Statement(STATEMENT_RETURN, location),
- vals_(vals), are_hidden_fields_ok_(false), is_lowered_(false)
- { }
-
- // The list of values being returned. This may be NULL.
- const Expression_list*
- vals() const
- { return this->vals_; }
-
- // Note that it is OK for this return statement to set hidden
- // fields.
- void
- set_hidden_fields_are_ok()
- { this->are_hidden_fields_ok_ = true; }
-
- protected:
- int
- do_traverse(Traverse* traverse)
- { return this->traverse_expression_list(traverse, this->vals_); }
-
- bool
- do_traverse_assignments(Traverse_assignments*);
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- bool
- do_may_fall_through() const
- { return false; }
-
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-
- private:
- // Return values. This may be NULL.
- Expression_list* vals_;
- // True if this statement may pass hidden fields in the return
- // value. This is used for generated method stubs.
- bool are_hidden_fields_ok_;
- // True if this statement has been lowered.
- bool is_lowered_;
-};
-
-// A send statement.
-
-class Send_statement : public Statement
-{
- public:
- Send_statement(Expression* channel, Expression* val,
- Location location)
- : Statement(STATEMENT_SEND, location),
- channel_(channel), val_(val)
- { }
-
- protected:
- int
- do_traverse(Traverse* traverse);
-
- void
- do_determine_types();
-
- void
- do_check_types(Gogo*);
-
- 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_;
- // The value to send.
- Expression* val_;
-};
-
-// Select_clauses holds the clauses of a select statement. This is
-// built by the parser.
-
-class Select_clauses
-{
- public:
- Select_clauses()
- : clauses_()
- { }
-
- // Add a new clause. IS_SEND is true if this is a send clause,
- // false for a receive clause. For a send clause CHANNEL is the
- // channel and VAL is the value to send. For a receive clause
- // CHANNEL is the channel, VAL is either NULL or a Var_expression
- // for the variable to set, and CLOSED is either NULL or a
- // Var_expression to set to whether the channel is closed. If VAL
- // is NULL, VAR may be a variable to be initialized with the
- // received value, and CLOSEDVAR ma be a variable to be initialized
- // with whether the channel is closed. IS_DEFAULT is true if this
- // is the default clause. STATEMENTS is the list of statements to
- // execute.
- void
- add(bool is_send, Expression* channel, Expression* val, Expression* closed,
- Named_object* var, Named_object* closedvar, bool is_default,
- Block* statements, Location location)
- {
- int index = static_cast<int>(this->clauses_.size());
- this->clauses_.push_back(Select_clause(index, is_send, channel, val,
- closed, var, closedvar, is_default,
- statements, location));
- }
-
- size_t
- size() const
- { return this->clauses_.size(); }
-
- // Traverse the select clauses.
- int
- traverse(Traverse*);
-
- // Lower statements.
- void
- lower(Gogo*, Named_object*, Block*, Temporary_statement*);
-
- // Determine types.
- void
- determine_types();
-
- // Check types.
- void
- check_types();
-
- // Whether the select clauses may fall through to the statement
- // which follows the overall select statement.
- bool
- may_fall_through() const;
-
- // Convert to the backend representation.
- Bstatement*
- get_backend(Translate_context*, Temporary_statement* sel,
- Unnamed_label* break_label, Location);
-
- // Dump AST representation.
- void
- dump_clauses(Ast_dump_context*) const;
-
- private:
- // A single clause.
- class Select_clause
- {
- public:
- Select_clause()
- : channel_(NULL), val_(NULL), closed_(NULL), var_(NULL),
- closedvar_(NULL), statements_(NULL), is_send_(false),
- is_default_(false)
- { }
-
- Select_clause(int index, bool is_send, Expression* channel,
- Expression* val, Expression* closed, Named_object* var,
- Named_object* closedvar, bool is_default, Block* statements,
- Location location)
- : index_(index), channel_(channel), val_(val), closed_(closed),
- var_(var), closedvar_(closedvar), statements_(statements),
- location_(location), is_send_(is_send), is_default_(is_default),
- is_lowered_(false)
- { go_assert(is_default ? channel == NULL : channel != NULL); }
-
- // Return the index of this clause.
- int
- index() const
- { return this->index_; }
-
- // Traverse the select clause.
- int
- traverse(Traverse*);
-
- // Lower statements.
- void
- lower(Gogo*, Named_object*, Block*, Temporary_statement*);
-
- // Determine types.
- void
- determine_types();
-
- // Check types.
- void
- check_types();
-
- // Return true if this is the default clause.
- bool
- is_default() const
- { return this->is_default_; }
-
- // Return the channel. This will return NULL for the default
- // clause.
- Expression*
- channel() const
- { return this->channel_; }
-
- // Return true for a send, false for a receive.
- bool
- is_send() const
- {
- go_assert(!this->is_default_);
- return this->is_send_;
- }
-
- // Return the statements.
- const Block*
- statements() const
- { return this->statements_; }
-
- // Return the location.
- Location
- location() const
- { return this->location_; }
-
- // Whether this clause may fall through to the statement which
- // follows the overall select statement.
- bool
- may_fall_through() const;
-
- // Convert the statements to the backend representation.
- Bstatement*
- get_statements_backend(Translate_context*);
-
- // Dump AST representation.
- void
- dump_clause(Ast_dump_context*) const;
-
- private:
- void
- lower_default(Block*, Expression*, Expression*);
-
- void
- lower_send(Block*, Expression*, Expression*, Expression*);
-
- void
- lower_recv(Gogo*, Named_object*, Block*, Expression*, Expression*,
- Expression*);
-
- // The index of this case in the generated switch statement.
- int index_;
- // The channel.
- Expression* channel_;
- // The value to send or the lvalue to receive into.
- Expression* val_;
- // The lvalue to set to whether the channel is closed on a
- // receive.
- Expression* closed_;
- // The variable to initialize, for "case a := <-ch".
- Named_object* var_;
- // The variable to initialize to whether the channel is closed,
- // for "case a, c := <-ch".
- Named_object* closedvar_;
- // The statements to execute.
- Block* statements_;
- // The location of this clause.
- Location location_;
- // Whether this is a send or a receive.
- bool is_send_;
- // Whether this is the default.
- bool is_default_;
- // Whether this has been lowered.
- bool is_lowered_;
- };
-
- typedef std::vector<Select_clause> Clauses;
-
- Clauses clauses_;
-};
-
-// A select statement.
-
-class Select_statement : public Statement
-{
- public:
- Select_statement(Location location)
- : Statement(STATEMENT_SELECT, location),
- clauses_(NULL), sel_(NULL), break_label_(NULL), is_lowered_(false)
- { }
-
- // Add the clauses.
- void
- add_clauses(Select_clauses* clauses)
- {
- go_assert(this->clauses_ == NULL);
- this->clauses_ = clauses;
- }
-
- // Return the break label for this select statement.
- Unnamed_label*
- break_label();
-
- protected:
- int
- do_traverse(Traverse* traverse)
- { return this->clauses_->traverse(traverse); }
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- void
- do_determine_types()
- { this->clauses_->determine_types(); }
-
- void
- do_check_types(Gogo*)
- { this->clauses_->check_types(); }
-
- bool
- do_may_fall_through() const
- { return this->clauses_->may_fall_through(); }
-
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-
- private:
- // The select clauses.
- Select_clauses* clauses_;
- // A temporary which holds the select structure we build up at runtime.
- Temporary_statement* sel_;
- // The break label.
- Unnamed_label* break_label_;
- // Whether this statement has been lowered.
- bool is_lowered_;
-};
-
-// A statement which requires a thunk: go or defer.
-
-class Thunk_statement : public Statement
-{
- public:
- Thunk_statement(Statement_classification, Call_expression*,
- Location);
-
- // Return the call expression.
- Expression*
- call() const
- { return this->call_; }
-
- // Simplify a go or defer statement so that it only uses a single
- // parameter.
- bool
- simplify_statement(Gogo*, Named_object*, Block*);
-
- protected:
- int
- do_traverse(Traverse* traverse);
-
- bool
- do_traverse_assignments(Traverse_assignments*);
-
- void
- do_determine_types();
-
- void
- do_check_types(Gogo*);
-
- // Return the function and argument for the call.
- bool
- get_fn_and_arg(Expression** pfn, Expression** parg);
-
- private:
- // Return whether this is a simple go statement.
- bool
- is_simple(Function_type*) const;
-
- // Return whether the thunk function is a constant.
- bool
- is_constant_function() const;
-
- // Build the struct to use for a complex case.
- Struct_type*
- build_struct(Function_type* fntype);
-
- // Build the thunk.
- void
- build_thunk(Gogo*, const std::string&);
-
- // Set the name to use for thunk field N.
- void
- thunk_field_param(int n, char* buf, size_t buflen);
-
- // The function call to be executed in a separate thread (go) or
- // later (defer).
- Expression* call_;
- // The type used for a struct to pass to a thunk, if this is not a
- // simple call.
- Struct_type* struct_type_;
-};
-
-// A go statement.
-
-class Go_statement : public Thunk_statement
-{
- public:
- Go_statement(Call_expression* call, Location location)
- : Thunk_statement(STATEMENT_GO, call, location)
- { }
-
- protected:
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-};
-
-// A defer statement.
-
-class Defer_statement : public Thunk_statement
-{
- public:
- Defer_statement(Call_expression* call, Location location)
- : Thunk_statement(STATEMENT_DEFER, call, location)
- { }
-
- protected:
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-};
-
-// A label statement.
-
-class Label_statement : public Statement
-{
- public:
- Label_statement(Label* label, Location location)
- : Statement(STATEMENT_LABEL, location),
- label_(label)
- { }
-
- // Return the label itself.
- const Label*
- label() const
- { return this->label_; }
-
- protected:
- int
- do_traverse(Traverse*);
-
- Bstatement*
- do_get_backend(Translate_context*);
-
- void
- do_dump_statement(Ast_dump_context*) const;
-
- private:
- // The label.
- Label* label_;
-};
-
-// A for statement.
-
-class For_statement : public Statement
-{
- public:
- For_statement(Block* init, Expression* cond, Block* post,
- Location location)
- : Statement(STATEMENT_FOR, location),
- init_(init), cond_(cond), post_(post), statements_(NULL),
- break_label_(NULL), continue_label_(NULL)
- { }
-
- // Add the statements.
- void
- add_statements(Block* statements)
- {
- go_assert(this->statements_ == NULL);
- this->statements_ = statements;
- }
-
- // Return the break label for this for statement.
- Unnamed_label*
- break_label();
-
- // Return the continue label for this for statement.
- Unnamed_label*
- continue_label();
-
- // Set the break and continue labels for this statement.
- void
- set_break_continue_labels(Unnamed_label* break_label,
- Unnamed_label* continue_label);
-
- protected:
- int
- do_traverse(Traverse*);
-
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- Bstatement*
- 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_;
- // The condition. This may be NULL.
- Expression* cond_;
- // The statements to run after each iteration. This may be NULL.
- Block* post_;
- // The statements in the loop itself.
- Block* statements_;
- // The break label, if needed.
- Unnamed_label* break_label_;
- // The continue label, if needed.
- Unnamed_label* continue_label_;
-};
-
-// A for statement over a range clause.
-
-class For_range_statement : public Statement
-{
- public:
- For_range_statement(Expression* index_var, Expression* value_var,
- Expression* range, Location location)
- : Statement(STATEMENT_FOR_RANGE, location),
- index_var_(index_var), value_var_(value_var), range_(range),
- statements_(NULL), break_label_(NULL), continue_label_(NULL)
- { }
-
- // Add the statements.
- void
- add_statements(Block* statements)
- {
- go_assert(this->statements_ == NULL);
- this->statements_ = statements;
- }
-
- // Return the break label for this for statement.
- Unnamed_label*
- break_label();
-
- // Return the continue label for this for statement.
- Unnamed_label*
- continue_label();
-
- protected:
- int
- do_traverse(Traverse*);
-
- bool
- do_traverse_assignments(Traverse_assignments*)
- { go_unreachable(); }
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- Bstatement*
- do_get_backend(Translate_context*)
- { go_unreachable(); }
-
- void
- do_dump_statement(Ast_dump_context*) const;
-
- private:
- Expression*
- make_range_ref(Named_object*, Temporary_statement*, Location);
-
- Expression*
- call_builtin(Gogo*, const char* funcname, Expression* arg, Location);
-
- void
- lower_range_array(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
- Temporary_statement*, Temporary_statement*,
- Block**, Expression**, Block**, Block**);
-
- void
- lower_range_slice(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
- Temporary_statement*, Temporary_statement*,
- Block**, Expression**, Block**, Block**);
-
- void
- lower_range_string(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
- Temporary_statement*, Temporary_statement*,
- Block**, Expression**, Block**, Block**);
-
- void
- lower_range_map(Gogo*, Block*, Block*, Named_object*, Temporary_statement*,
- Temporary_statement*, Temporary_statement*,
- Block**, Expression**, Block**, Block**);
-
- void
- lower_range_channel(Gogo*, Block*, Block*, Named_object*,
- Temporary_statement*, Temporary_statement*,
- Temporary_statement*, Block**, Expression**, Block**,
- Block**);
-
- // The variable which is set to the index value.
- Expression* index_var_;
- // The variable which is set to the element value. This may be
- // NULL.
- Expression* value_var_;
- // The expression we are ranging over.
- Expression* range_;
- // The statements in the block.
- Block* statements_;
- // The break label, if needed.
- Unnamed_label* break_label_;
- // The continue label, if needed.
- Unnamed_label* continue_label_;
-};
-
-// Class Case_clauses holds the clauses of a switch statement. This
-// is built by the parser.
-
-class Case_clauses
-{
- public:
- Case_clauses()
- : clauses_()
- { }
-
- // Add a new clause. CASES is a list of case expressions; it may be
- // NULL. IS_DEFAULT is true if this is the default case.
- // STATEMENTS is a block of statements. IS_FALLTHROUGH is true if
- // after the statements the case clause should fall through to the
- // next clause.
- void
- add(Expression_list* cases, bool is_default, Block* statements,
- bool is_fallthrough, Location location)
- {
- this->clauses_.push_back(Case_clause(cases, is_default, statements,
- is_fallthrough, location));
- }
-
- // Return whether there are no clauses.
- bool
- empty() const
- { return this->clauses_.empty(); }
-
- // Traverse the case clauses.
- int
- traverse(Traverse*);
-
- // Lower for a nonconstant switch.
- void
- lower(Block*, Temporary_statement*, Unnamed_label*) const;
-
- // Determine types of expressions. The Type parameter is the type
- // of the switch value.
- void
- determine_types(Type*);
-
- // Check types. The Type parameter is the type of the switch value.
- bool
- check_types(Type*);
-
- // Return true if all the clauses are constant values.
- bool
- is_constant() const;
-
- // Return true if these clauses may fall through to the statements
- // following the switch statement.
- bool
- may_fall_through() const;
-
- // Return the body of a SWITCH_EXPR when all the clauses are
- // constants.
- void
- get_backend(Translate_context*, Unnamed_label* break_label,
- 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.
- class Hash_integer_value;
- class Eq_integer_value;
- typedef Unordered_set_hash(Expression*, Hash_integer_value,
- Eq_integer_value) Case_constants;
-
- // One case clause.
- class Case_clause
- {
- public:
- Case_clause()
- : cases_(NULL), statements_(NULL), is_default_(false),
- is_fallthrough_(false), location_(UNKNOWN_LOCATION)
- { }
-
- Case_clause(Expression_list* cases, bool is_default, Block* statements,
- bool is_fallthrough, Location location)
- : cases_(cases), statements_(statements), is_default_(is_default),
- is_fallthrough_(is_fallthrough), location_(location)
- { }
-
- // Whether this clause falls through to the next clause.
- bool
- is_fallthrough() const
- { return this->is_fallthrough_; }
-
- // Whether this is the default.
- bool
- is_default() const
- { return this->is_default_; }
-
- // The location of this clause.
- Location
- location() const
- { return this->location_; }
-
- // Traversal.
- int
- traverse(Traverse*);
-
- // Lower for a nonconstant switch.
- void
- lower(Block*, Temporary_statement*, Unnamed_label*, Unnamed_label*) const;
-
- // Determine types.
- void
- determine_types(Type*);
-
- // Check types.
- bool
- check_types(Type*);
-
- // Return true if all the case expressions are constant.
- bool
- is_constant() const;
-
- // Return true if this clause may fall through to execute the
- // statements following the switch statement. This is not the
- // same as whether this clause falls through to the next clause.
- bool
- may_fall_through() const;
-
- // Convert the case values and statements to the backend
- // representation.
- Bstatement*
- 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_;
- // The statements to execute.
- Block* statements_;
- // Whether this is the default case.
- bool is_default_;
- // Whether this falls through after the statements.
- bool is_fallthrough_;
- // The location of this case clause.
- Location location_;
- };
-
- friend class Case_clause;
-
- // The type of the list of clauses.
- typedef std::vector<Case_clause> Clauses;
-
- // All the case clauses.
- Clauses clauses_;
-};
-
-// A switch statement.
-
-class Switch_statement : public Statement
-{
- public:
- Switch_statement(Expression* val, Location location)
- : Statement(STATEMENT_SWITCH, location),
- val_(val), clauses_(NULL), break_label_(NULL)
- { }
-
- // Add the clauses.
- void
- add_clauses(Case_clauses* clauses)
- {
- go_assert(this->clauses_ == NULL);
- this->clauses_ = clauses;
- }
-
- // Return the break label for this switch statement.
- Unnamed_label*
- break_label();
-
- protected:
- int
- do_traverse(Traverse*);
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- Bstatement*
- 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_;
- // The case clauses.
- Case_clauses* clauses_;
- // The break label, if needed.
- Unnamed_label* break_label_;
-};
-
-// Class Type_case_clauses holds the clauses of a type switch
-// statement. This is built by the parser.
-
-class Type_case_clauses
-{
- public:
- Type_case_clauses()
- : clauses_()
- { }
-
- // Add a new clause. TYPE is the type for this clause; it may be
- // NULL. IS_FALLTHROUGH is true if this falls through to the next
- // clause; in this case STATEMENTS will be NULL. IS_DEFAULT is true
- // if this is the default case. STATEMENTS is a block of
- // statements; it may be NULL.
- void
- add(Type* type, bool is_fallthrough, bool is_default, Block* statements,
- Location location)
- {
- this->clauses_.push_back(Type_case_clause(type, is_fallthrough, is_default,
- statements, location));
- }
-
- // Return whether there are no clauses.
- bool
- empty() const
- { return this->clauses_.empty(); }
-
- // Traverse the type case clauses.
- int
- traverse(Traverse*);
-
- // Check for duplicates.
- void
- check_duplicates() const;
-
- // Lower to if and goto statements.
- void
- lower(Type*, 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
- {
- public:
- Type_case_clause()
- : type_(NULL), statements_(NULL), is_default_(false),
- location_(UNKNOWN_LOCATION)
- { }
-
- Type_case_clause(Type* type, bool is_fallthrough, bool is_default,
- Block* statements, Location location)
- : type_(type), statements_(statements), is_fallthrough_(is_fallthrough),
- is_default_(is_default), location_(location)
- { }
-
- // The type.
- Type*
- type() const
- { return this->type_; }
-
- // Whether this is the default.
- bool
- is_default() const
- { return this->is_default_; }
-
- // The location of this type clause.
- Location
- location() const
- { return this->location_; }
-
- // Traversal.
- int
- traverse(Traverse*);
-
- // Lower to if and goto statements.
- void
- lower(Type*, 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_;
- // The statements to execute.
- Block* statements_;
- // Whether this falls through--this is true for "case T1, T2".
- bool is_fallthrough_;
- // Whether this is the default case.
- bool is_default_;
- // The location of this type case clause.
- Location location_;
- };
-
- friend class Type_case_clause;
-
- // The type of the list of type clauses.
- typedef std::vector<Type_case_clause> Type_clauses;
-
- // All the type case clauses.
- Type_clauses clauses_;
-};
-
-// A type switch statement.
-
-class Type_switch_statement : public Statement
-{
- public:
- Type_switch_statement(Named_object* var, Expression* expr,
- Location location)
- : Statement(STATEMENT_TYPE_SWITCH, location),
- var_(var), expr_(expr), clauses_(NULL), break_label_(NULL)
- { go_assert(var == NULL || expr == NULL); }
-
- // Add the clauses.
- void
- add_clauses(Type_case_clauses* clauses)
- {
- go_assert(this->clauses_ == NULL);
- this->clauses_ = clauses;
- }
-
- // Return the break label for this type switch statement.
- Unnamed_label*
- break_label();
-
- protected:
- int
- do_traverse(Traverse*);
-
- Statement*
- do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
-
- Bstatement*
- 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_;
- // The expression we are switching on if there is no variable.
- Expression* expr_;
- // The type case clauses.
- Type_case_clauses* clauses_;
- // The break label, if needed.
- Unnamed_label* break_label_;
-};
-
-#endif // !defined(GO_STATEMENTS_H)