From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/go/gofrontend/parse.h | 308 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 gcc/go/gofrontend/parse.h (limited to 'gcc/go/gofrontend/parse.h') diff --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h new file mode 100644 index 000000000..6f2ac64b1 --- /dev/null +++ b/gcc/go/gofrontend/parse.h @@ -0,0 +1,308 @@ +// parse.h -- Go frontend parser. -*- 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_PARSE_H +#define GO_PARSE_H + +class Set_iota_traverse; +class Lex; +class Gogo; +class Named_object; +class Type; +class Typed_identifier; +class Typed_identifier_list; +class Function_type; +class Block; +class Expression; +class Expression_list; +class Struct_field_list; +class Case_clauses; +class Type_case_clauses; +class Select_clauses; +class Statement; +class Label; + +// Parse the program. + +class Parse +{ + public: + Parse(Lex*, Gogo*); + + // Parse a program. + void + program(); + + private: + // Precedence values. + enum Precedence + { + PRECEDENCE_INVALID = -1, + PRECEDENCE_NORMAL = 0, + PRECEDENCE_OROR, + PRECEDENCE_ANDAND, + PRECEDENCE_CHANOP, + PRECEDENCE_RELOP, + PRECEDENCE_ADDOP, + PRECEDENCE_MULOP + }; + + // We use this when parsing the range clause of a for statement. + struct Range_clause + { + // Set to true if we found a range clause. + bool found; + // The index expression. + Expression* index; + // The value expression. + Expression* value; + // The range expression. + Expression* range; + + Range_clause() + : found(false), index(NULL), value(NULL), range(NULL) + { } + }; + + // We use this when parsing the statement at the start of a switch, + // in order to recognize type switches. + struct Type_switch + { + // Set to true if we find a type switch. + bool found; + // The variable name. + std::string name; + // The location of the variable. + source_location location; + // The expression. + Expression* expr; + + Type_switch() + : found(false), name(), location(UNKNOWN_LOCATION), expr(NULL) + { } + }; + + // A variable defined in an enclosing function referenced by the + // current function. + class Enclosing_var + { + public: + Enclosing_var(Named_object* var, Named_object* in_function, + unsigned int index) + : var_(var), in_function_(in_function), index_(index) + { } + + // We put these in a vector, so we need a default constructor. + Enclosing_var() + : var_(NULL), in_function_(NULL), index_(-1U) + { } + + Named_object* + var() const + { return this->var_; } + + Named_object* + in_function() const + { return this->in_function_; } + + unsigned int + index() const + { return this->index_; } + + private: + // The variable which is being referred to. + Named_object* var_; + // The function where the variable is defined. + Named_object* in_function_; + // The index of the field in this function's closure struct for + // this variable. + unsigned int index_; + }; + + // We store Enclosing_var entries in a set, so we need a comparator. + struct Enclosing_var_comparison + { + bool + operator()(const Enclosing_var&, const Enclosing_var&); + }; + + // A set of Enclosing_var entries. + typedef std::set Enclosing_vars; + + // Peek at the current token from the lexer. + const Token* + peek_token(); + + // Consume the current token, return the next one. + const Token* + advance_token(); + + // Push a token back on the input stream. + void + unget_token(const Token&); + + // The location of the current token. + source_location + location(); + + // For break and continue we keep a stack of statements with + // associated labels (if any). The top of the stack is used for a + // break or continue statement with no label. + typedef std::vector > Bc_stack; + + // Parser nonterminals. + void identifier_list(Typed_identifier_list*); + Expression_list* expression_list(Expression*, bool may_be_sink); + bool qualified_ident(std::string*, Named_object**); + Type* type(); + bool type_may_start_here(); + Type* type_name(bool issue_error); + Type* array_type(bool may_use_ellipsis); + Type* map_type(); + Type* struct_type(); + void field_decl(Struct_field_list*); + Type* pointer_type(); + Type* channel_type(); + Function_type* signature(Typed_identifier*, source_location); + bool parameters(Typed_identifier_list**, bool* is_varargs); + Typed_identifier_list* parameter_list(bool* is_varargs); + void parameter_decl(bool, Typed_identifier_list*, bool*, bool*); + bool result(Typed_identifier_list**); + source_location block(); + Type* interface_type(); + void method_spec(Typed_identifier_list*); + void declaration(); + bool declaration_may_start_here(); + void decl(void (Parse::*)(void*), void*); + void list(void (Parse::*)(void*), void*, bool); + void const_decl(); + void const_spec(Type**, Expression_list**); + void type_decl(); + void type_spec(void*); + void var_decl(); + void var_spec(void*); + void init_vars(const Typed_identifier_list*, Type*, Expression_list*, + bool is_coloneq, source_location); + bool init_vars_from_call(const Typed_identifier_list*, Type*, Expression*, + bool is_coloneq, source_location); + bool init_vars_from_map(const Typed_identifier_list*, Type*, Expression*, + bool is_coloneq, source_location); + bool init_vars_from_receive(const Typed_identifier_list*, Type*, + Expression*, bool is_coloneq, source_location); + bool init_vars_from_type_guard(const Typed_identifier_list*, Type*, + Expression*, bool is_coloneq, + source_location); + Named_object* init_var(const Typed_identifier&, Type*, Expression*, + bool is_coloneq, bool type_from_init, bool* is_new); + Named_object* create_dummy_global(Type*, Expression*, source_location); + void simple_var_decl_or_assignment(const std::string&, source_location, + Range_clause*, Type_switch*); + void function_decl(); + Typed_identifier* receiver(); + Expression* operand(bool may_be_sink); + Expression* enclosing_var_reference(Named_object*, Named_object*, + source_location); + Expression* composite_lit(Type*, int depth, source_location); + Expression* function_lit(); + Expression* create_closure(Named_object* function, Enclosing_vars*, + source_location); + Expression* primary_expr(bool may_be_sink, bool may_be_composite_lit, + bool* is_type_switch); + Expression* selector(Expression*, bool* is_type_switch); + Expression* index(Expression*); + Expression* call(Expression*); + Expression* expression(Precedence, bool may_be_sink, + bool may_be_composite_lit, bool* is_type_switch); + bool expression_may_start_here(); + Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit, + bool* is_type_switch); + Expression* qualified_expr(Expression*, source_location); + Expression* id_to_expression(const std::string&, source_location); + void statement(const Label*); + bool statement_may_start_here(); + void labeled_stmt(const std::string&, source_location); + Expression* simple_stat(bool, bool, Range_clause*, Type_switch*); + bool simple_stat_may_start_here(); + void statement_list(); + bool statement_list_may_start_here(); + void expression_stat(Expression*); + void inc_dec_stat(Expression*); + void assignment(Expression*, Range_clause*); + void tuple_assignment(Expression_list*, Range_clause*); + void send(); + void go_or_defer_stat(); + void return_stat(); + void if_stat(); + void switch_stat(const Label*); + Statement* expr_switch_body(const Label*, Expression*, source_location); + void expr_case_clause(Case_clauses*, bool* saw_default); + Expression_list* expr_switch_case(bool*); + Statement* type_switch_body(const Label*, const Type_switch&, + source_location); + void type_case_clause(Named_object*, Type_case_clauses*, bool* saw_default); + void type_switch_case(std::vector*, bool*); + void select_stat(const Label*); + void comm_clause(Select_clauses*, bool* saw_default); + bool comm_case(bool*, Expression**, Expression**, std::string*, bool*); + bool send_or_recv_expr(bool*, Expression**, Expression**, std::string*); + void for_stat(const Label*); + void for_clause(Expression**, Block**); + void range_clause_decl(const Typed_identifier_list*, Range_clause*); + void range_clause_expr(const Expression_list*, Range_clause*); + void push_break_statement(Statement*, const Label*); + void push_continue_statement(Statement*, const Label*); + void pop_break_statement(); + void pop_continue_statement(); + Statement* find_bc_statement(const Bc_stack*, const std::string&); + void break_stat(); + void continue_stat(); + void goto_stat(); + void package_clause(); + void import_decl(); + void import_spec(void*); + + void reset_iota(); + int iota_value(); + void increment_iota(); + + // Skip past an error looking for a semicolon or OP. Return true if + // all is well, false if we found EOF. + bool + skip_past_error(Operator op); + + // Verify that an expression is not a sink, and return either the + // expression or an error. + Expression* + verify_not_sink(Expression*); + + // Return the statement associated with a label in a Bc_stack, or + // NULL. + Statement* + find_bc_statement(const Bc_stack*, const std::string&) const; + + // The lexer output we are parsing. + Lex* lex_; + // The current token. + Token token_; + // A token pushed back on the input stream. + Token unget_token_; + // Whether unget_token_ is valid. + bool unget_token_valid_; + // The code we are generating. + Gogo* gogo_; + // A stack of statements for which break may be used. + Bc_stack* break_stack_; + // A stack of statements for which continue may be used. + Bc_stack* continue_stack_; + // The current iota value. + int iota_; + // References from the local function to variables defined in + // enclosing functions. + Enclosing_vars enclosing_vars_; +}; + + +#endif // !defined(GO_PARSE_H) -- cgit v1.2.3