class Type;
class Typed_identifier;
class Typed_identifier_list;
+class Channel_type;
class Function_type;
class Block;
class Expression;
// break or continue statement with no label.
typedef std::vector<std::pair<Statement*, Label*> > Bc_stack;
+ // Map from type switch variables to the variables they mask, so
+ // that a use of the type switch variable can become a use of the
+ // real variable.
+ typedef Unordered_map(Named_object*, Named_object*) Type_switch_vars;
+
// Parser nonterminals.
void identifier_list(Typed_identifier_list*);
- Expression_list* expression_list(Expression*, bool may_be_sink);
+ Expression_list* expression_list(Expression*, bool may_be_sink,
+ bool may_be_composite_lit);
bool qualified_ident(std::string*, Named_object**);
Type* type();
bool type_may_start_here();
Expression*, bool is_coloneq,
Location);
Named_object* init_var(const Typed_identifier&, Type*, Expression*,
- bool is_coloneq, bool type_from_init, bool* is_new);
+ bool is_coloneq, bool type_from_init, bool* is_new,
+ Expression_list* vars, Expression_list* vals);
Named_object* create_dummy_global(Type*, Expression*, Location);
+ void finish_init_vars(Expression_list* vars, Expression_list* vals,
+ Location);
void simple_var_decl_or_assignment(const std::string&, Location,
+ bool may_be_composite_lit,
Range_clause*, Type_switch*);
void function_decl();
Typed_identifier* receiver();
bool expression_may_start_here();
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch);
+ Type* reassociate_chan_direction(Channel_type*, Location);
Expression* qualified_expr(Expression*, Location);
Expression* id_to_expression(const std::string&, Location);
void statement(Label*);
void expression_stat(Expression*);
void send_stmt(Expression*);
void inc_dec_stat(Expression*);
- void assignment(Expression*, Range_clause*);
- void tuple_assignment(Expression_list*, Range_clause*);
+ void assignment(Expression*, bool may_be_composite_lit, Range_clause*);
+ void tuple_assignment(Expression_list*, bool may_be_composite_lit,
+ Range_clause*);
void send();
void go_or_defer_stat();
void return_stat();
Statement*
find_bc_statement(const Bc_stack*, const std::string&) const;
+ // Mark a variable as used.
+ void
+ mark_var_used(Named_object*);
+
// The lexer output we are parsing.
Lex* lex_;
// The current token.
Token unget_token_;
// Whether unget_token_ is valid.
bool unget_token_valid_;
+ // Whether the function we are parsing had errors in the signature.
+ bool is_erroneous_function_;
// The code we are generating.
Gogo* gogo_;
// A stack of statements for which break may be used.
// References from the local function to variables defined in
// enclosing functions.
Enclosing_vars enclosing_vars_;
+ // Map from type switch variables to real variables.
+ Type_switch_vars type_switch_vars_;
};