OSDN Git Service

compiler: Fix a, b, c := b, a, 1 when a and b already exist.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / parse.h
1 // parse.h -- Go frontend parser.     -*- C++ -*-
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 #ifndef GO_PARSE_H
8 #define GO_PARSE_H
9
10 class Set_iota_traverse;
11 class Lex;
12 class Gogo;
13 class Named_object;
14 class Type;
15 class Typed_identifier;
16 class Typed_identifier_list;
17 class Channel_type;
18 class Function_type;
19 class Block;
20 class Expression;
21 class Expression_list;
22 class Struct_field_list;
23 class Case_clauses;
24 class Type_case_clauses;
25 class Select_clauses;
26 class Statement;
27 class Label;
28
29 // Parse the program.
30
31 class Parse
32 {
33  public:
34   Parse(Lex*, Gogo*);
35
36   // Parse a program.
37   void
38   program();
39
40  private:
41   // Precedence values.
42   enum Precedence
43   {
44     PRECEDENCE_INVALID = -1,
45     PRECEDENCE_NORMAL = 0,
46     PRECEDENCE_OROR,
47     PRECEDENCE_ANDAND,
48     PRECEDENCE_RELOP,
49     PRECEDENCE_ADDOP,
50     PRECEDENCE_MULOP
51   };
52
53   // We use this when parsing the range clause of a for statement.
54   struct Range_clause
55   {
56     // Set to true if we found a range clause.
57     bool found;
58     // The index expression.
59     Expression* index;
60     // The value expression.
61     Expression* value;
62     // The range expression.
63     Expression* range;
64
65     Range_clause()
66       : found(false), index(NULL), value(NULL), range(NULL)
67     { }
68   };
69
70   // We use this when parsing the statement at the start of a switch,
71   // in order to recognize type switches.
72   struct Type_switch
73   {
74     // Set to true if we find a type switch.
75     bool found;
76     // The variable name.
77     std::string name;
78     // The location of the variable.
79     Location location;
80     // The expression.
81     Expression* expr;
82
83     Type_switch()
84       : found(false), name(), location(UNKNOWN_LOCATION), expr(NULL)
85     { }
86   };
87
88   // A variable defined in an enclosing function referenced by the
89   // current function.
90   class Enclosing_var
91   {
92    public:
93     Enclosing_var(Named_object* var, Named_object* in_function,
94                   unsigned int index)
95       : var_(var), in_function_(in_function), index_(index)
96     { }
97
98     // We put these in a vector, so we need a default constructor.
99     Enclosing_var()
100       : var_(NULL), in_function_(NULL), index_(-1U)
101     { }
102
103     Named_object*
104     var() const
105     { return this->var_; }
106
107     Named_object*
108     in_function() const
109     { return this->in_function_; }
110
111     unsigned int
112     index() const
113     { return this->index_; }
114
115    private:
116     // The variable which is being referred to.
117     Named_object* var_;
118     // The function where the variable is defined.
119     Named_object* in_function_;
120     // The index of the field in this function's closure struct for
121     // this variable.
122     unsigned int index_;
123   };
124
125   // We store Enclosing_var entries in a set, so we need a comparator.
126   struct Enclosing_var_comparison
127   {
128     bool
129     operator()(const Enclosing_var&, const Enclosing_var&);
130   };
131
132   // A set of Enclosing_var entries.
133   typedef std::set<Enclosing_var, Enclosing_var_comparison> Enclosing_vars;
134
135   // Used to detect duplicate parameter/result names.
136   typedef std::map<std::string, const Typed_identifier*> Names;
137
138   // Peek at the current token from the lexer.
139   const Token*
140   peek_token();
141
142   // Consume the current token, return the next one.
143   const Token*
144   advance_token();
145
146   // Push a token back on the input stream.
147   void
148   unget_token(const Token&);
149
150   // The location of the current token.
151   Location
152   location();
153
154   // For break and continue we keep a stack of statements with
155   // associated labels (if any).  The top of the stack is used for a
156   // break or continue statement with no label.
157   typedef std::vector<std::pair<Statement*, Label*> > Bc_stack;
158
159   // Map from type switch variables to the variables they mask, so
160   // that a use of the type switch variable can become a use of the
161   // real variable.
162   typedef Unordered_map(Named_object*, Named_object*) Type_switch_vars;
163
164   // Parser nonterminals.
165   void identifier_list(Typed_identifier_list*);
166   Expression_list* expression_list(Expression*, bool may_be_sink,
167                                    bool may_be_composite_lit);
168   bool qualified_ident(std::string*, Named_object**);
169   Type* type();
170   bool type_may_start_here();
171   Type* type_name(bool issue_error);
172   Type* array_type(bool may_use_ellipsis);
173   Type* map_type();
174   Type* struct_type();
175   void field_decl(Struct_field_list*);
176   Type* pointer_type();
177   Type* channel_type();
178   void check_signature_names(const Typed_identifier_list*, Names*);
179   Function_type* signature(Typed_identifier*, Location);
180   bool parameters(Typed_identifier_list**, bool* is_varargs);
181   Typed_identifier_list* parameter_list(bool* is_varargs);
182   void parameter_decl(bool, Typed_identifier_list*, bool*, bool*);
183   bool result(Typed_identifier_list**);
184   Location block();
185   Type* interface_type();
186   void method_spec(Typed_identifier_list*);
187   void declaration();
188   bool declaration_may_start_here();
189   void decl(void (Parse::*)(void*), void*);
190   void list(void (Parse::*)(void*), void*, bool);
191   void const_decl();
192   void const_spec(Type**, Expression_list**);
193   void type_decl();
194   void type_spec(void*);
195   void var_decl();
196   void var_spec(void*);
197   void init_vars(const Typed_identifier_list*, Type*, Expression_list*,
198                  bool is_coloneq, Location);
199   bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*,
200                            bool is_coloneq, Location);
201   bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*,
202                           bool is_coloneq, Location);
203   bool init_vars_from_receive(const Typed_identifier_list*, Type*,
204                               Expression*, bool is_coloneq, Location);
205   bool init_vars_from_type_guard(const Typed_identifier_list*, Type*,
206                                  Expression*, bool is_coloneq,
207                                  Location);
208   Named_object* init_var(const Typed_identifier&, Type*, Expression*,
209                          bool is_coloneq, bool type_from_init, bool* is_new,
210                          Expression_list* vars, Expression_list* vals);
211   Named_object* create_dummy_global(Type*, Expression*, Location);
212   void finish_init_vars(Expression_list* vars, Expression_list* vals,
213                         Location);
214   void simple_var_decl_or_assignment(const std::string&, Location,
215                                      bool may_be_composite_lit,
216                                      Range_clause*, Type_switch*);
217   void function_decl();
218   Typed_identifier* receiver();
219   Expression* operand(bool may_be_sink);
220   Expression* enclosing_var_reference(Named_object*, Named_object*,
221                                       Location);
222   Expression* composite_lit(Type*, int depth, Location);
223   Expression* function_lit();
224   Expression* create_closure(Named_object* function, Enclosing_vars*,
225                              Location);
226   Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit,
227                            bool* is_type_switch);
228   Expression* selector(Expression*, bool* is_type_switch);
229   Expression* index(Expression*);
230   Expression* call(Expression*);
231   Expression* expression(Precedence, bool may_be_sink,
232                          bool may_be_composite_lit, bool* is_type_switch);
233   bool expression_may_start_here();
234   Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
235                          bool* is_type_switch);
236   Type* reassociate_chan_direction(Channel_type*, Location);
237   Expression* qualified_expr(Expression*, Location);
238   Expression* id_to_expression(const std::string&, Location);
239   void statement(Label*);
240   bool statement_may_start_here();
241   void labeled_stmt(const std::string&, Location);
242   Expression* simple_stat(bool, bool*, Range_clause*, Type_switch*);
243   bool simple_stat_may_start_here();
244   void statement_list();
245   bool statement_list_may_start_here();
246   void expression_stat(Expression*);
247   void send_stmt(Expression*);
248   void inc_dec_stat(Expression*);
249   void assignment(Expression*, bool may_be_composite_lit, Range_clause*);
250   void tuple_assignment(Expression_list*, bool may_be_composite_lit,
251                         Range_clause*);
252   void send();
253   void go_or_defer_stat();
254   void return_stat();
255   void if_stat();
256   void switch_stat(Label*);
257   Statement* expr_switch_body(Label*, Expression*, Location);
258   void expr_case_clause(Case_clauses*, bool* saw_default);
259   Expression_list* expr_switch_case(bool*);
260   Statement* type_switch_body(Label*, const Type_switch&, Location);
261   void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default);
262   void type_switch_case(std::vector<Type*>*, bool*);
263   void select_stat(Label*);
264   void comm_clause(Select_clauses*, bool* saw_default);
265   bool comm_case(bool*, Expression**, Expression**, Expression**,
266                  std::string*, std::string*, bool*);
267   bool send_or_recv_stmt(bool*, Expression**, Expression**, Expression**,
268                          std::string*, std::string*);
269   void for_stat(Label*);
270   void for_clause(Expression**, Block**);
271   void range_clause_decl(const Typed_identifier_list*, Range_clause*);
272   void range_clause_expr(const Expression_list*, Range_clause*);
273   void push_break_statement(Statement*, Label*);
274   void push_continue_statement(Statement*, Label*);
275   void pop_break_statement();
276   void pop_continue_statement();
277   Statement* find_bc_statement(const Bc_stack*, const std::string&);
278   void break_stat();
279   void continue_stat();
280   void goto_stat();
281   void package_clause();
282   void import_decl();
283   void import_spec(void*);
284
285   void reset_iota();
286   int iota_value();
287   void increment_iota();
288
289   // Skip past an error looking for a semicolon or OP.  Return true if
290   // all is well, false if we found EOF.
291   bool
292   skip_past_error(Operator op);
293
294   // Verify that an expression is not a sink, and return either the
295   // expression or an error.
296   Expression*
297   verify_not_sink(Expression*);
298
299   // Return the statement associated with a label in a Bc_stack, or
300   // NULL.
301   Statement*
302   find_bc_statement(const Bc_stack*, const std::string&) const;
303
304   // Mark a variable as used.
305   void
306   mark_var_used(Named_object*);
307
308   // The lexer output we are parsing.
309   Lex* lex_;
310   // The current token.
311   Token token_;
312   // A token pushed back on the input stream.
313   Token unget_token_;
314   // Whether unget_token_ is valid.
315   bool unget_token_valid_;
316   // Whether the function we are parsing had errors in the signature.
317   bool is_erroneous_function_;
318   // The code we are generating.
319   Gogo* gogo_;
320   // A stack of statements for which break may be used.
321   Bc_stack* break_stack_;
322   // A stack of statements for which continue may be used.
323   Bc_stack* continue_stack_;
324   // The current iota value.
325   int iota_;
326   // References from the local function to variables defined in
327   // enclosing functions.
328   Enclosing_vars enclosing_vars_;
329   // Map from type switch variables to real variables.
330   Type_switch_vars type_switch_vars_;
331 };
332
333
334 #endif // !defined(GO_PARSE_H)