OSDN Git Service

Change Bound_method_expression to refer to a constant method.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / statements.h
index 5199981..0a87a8b 100644 (file)
@@ -11,6 +11,7 @@
 
 class Gogo;
 class Traverse;
+class Statement_inserter;
 class Block;
 class Function;
 class Unnamed_label;
@@ -39,6 +40,10 @@ 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.
@@ -200,8 +205,7 @@ class Statement
 
   // Make a return statement.
   static Statement*
-  make_return_statement(const Typed_identifier_list*, Expression_list*,
-                       source_location);
+  make_return_statement(Expression_list*, source_location);
 
   // Make a break statement.
   static Statement*
@@ -288,9 +292,11 @@ class Statement
   // 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)
-  { return this->do_lower(gogo, function, block); }
+  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
@@ -365,9 +371,13 @@ class Statement
   may_fall_through() const
   { return this->do_may_fall_through(); }
 
-  // Return the tree for a statement.  BLOCK is the enclosing block.
-  tree
-  get_tree(Translate_context*);
+  // 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.
@@ -383,7 +393,7 @@ class Statement
   // Implemented by the child class: lower this statement to a simpler
   // one.
   virtual Statement*
-  do_lower(Gogo*, Named_object*, Block*)
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*)
   { return this; }
 
   // Implemented by child class: set type information for unnamed
@@ -405,9 +415,13 @@ class Statement
   do_may_fall_through() const
   { return true; }
 
-  // Implemented by child class: return a tree.
-  virtual tree
-  do_get_tree(Translate_context*) = 0;
+  // 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
@@ -422,12 +436,6 @@ class Statement
   int
   traverse_type(Traverse*, Type*);
 
-  // Build a tree node with one operand, setting the location.  The
-  // first operand really has type "enum tree_code", but that enum is
-  // not defined here.
-  tree
-  build_stmt_1(int tree_code_value, tree);
-
   // For children to call when they detect that they are in error.
   void
   set_is_error();
@@ -474,28 +482,23 @@ class Temporary_statement : public Statement
  public:
   Temporary_statement(Type* type, Expression* init, source_location location)
     : Statement(STATEMENT_TEMPORARY, location),
-      type_(type), init_(init), decl_(NULL), is_address_taken_(false)
+      type_(type), init_(init), bvariable_(NULL), is_address_taken_(false)
   { }
 
   // Return the type of the temporary variable.
   Type*
   type() const;
 
-  // Return the initialization expression.
-  Expression*
-  init() const
-  { return this->init_; }
-
   // Record that something takes the address of this temporary
   // variable.
   void
   set_is_address_taken()
   { this->is_address_taken_ = true; }
 
-  // Return the tree for the temporary variable itself.  This should
-  // not be called until after the statement itself has been expanded.
-  tree
-  get_decl() const;
+  // 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
@@ -510,16 +513,19 @@ class Temporary_statement : public Statement
   void
   do_check_types(Gogo*);
 
-  tree
-  do_get_tree(Translate_context*);
+  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 DECL for the temporary variable.
-  tree decl_;
+  // The backend representation of the temporary variable.
+  Bvariable* bvariable_;
   // True if something takes the address of this temporary variable.
   bool is_address_taken_;
 };
@@ -544,8 +550,14 @@ class Variable_declaration_statement : public Statement
   bool
   do_traverse_assignments(Traverse_assignments*);
 
-  tree
-  do_get_tree(Translate_context*);
+  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_;
@@ -556,10 +568,9 @@ class Variable_declaration_statement : public Statement
 class Return_statement : public Statement
 {
  public:
-  Return_statement(const Typed_identifier_list* results, Expression_list* vals,
-                  source_location location)
+  Return_statement(Expression_list* vals, source_location location)
     : Statement(STATEMENT_RETURN, location),
-      results_(results), vals_(vals)
+      vals_(vals), is_lowered_(false)
   { }
 
   // The list of values being returned.  This may be NULL.
@@ -576,28 +587,23 @@ class Return_statement : public Statement
   do_traverse_assignments(Traverse_assignments*);
 
   Statement*
-  do_lower(Gogo*, Named_object*, Block*);
-
-  void
-  do_determine_types();
-
-  void
-  do_check_types(Gogo*);
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
   bool
   do_may_fall_through() const
   { return false; }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bstatement*
+  do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
-  // The result types of the function we are returning from.  This is
-  // here because in some of the traversals it is inconvenient to get
-  // it.
-  const Typed_identifier_list* results_;
   // Return values.  This may be NULL.
   Expression_list* vals_;
+  // True if this statement has been lowered.
+  bool is_lowered_;
 };
 
 // A send statement.
@@ -626,8 +632,11 @@ class Send_statement : public Statement
   void
   do_check_types(Gogo*);
 
-  tree
-  do_get_tree(Translate_context*);
+  Bstatement*
+  do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
   // The channel on which to send the value.
@@ -686,9 +695,13 @@ class Select_clauses
   bool
   may_fall_through() const;
 
-  // Return a tree implementing the select statement.
-  tree
-  get_tree(Translate_context*, Unnamed_label* break_label, source_location);
+  // Convert to the backend representation.
+  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.
@@ -708,7 +721,7 @@ class Select_clauses
       : 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)
-    { gcc_assert(is_default ? channel == NULL : channel != NULL); }
+    { go_assert(is_default ? channel == NULL : channel != NULL); }
 
     // Traverse the select clause.
     int
@@ -737,7 +750,7 @@ class Select_clauses
     bool
     is_send() const
     {
-      gcc_assert(!this->is_default_);
+      go_assert(!this->is_default_);
       return this->is_send_;
     }
 
@@ -756,9 +769,13 @@ class Select_clauses
     bool
     may_fall_through() const;
 
-    // Return a tree for the statements to execute.
-    tree
-    get_statements_tree(Translate_context*);
+    // Convert the statements to the backend representation.
+    Bstatement*
+    get_statements_backend(Translate_context*);
+
+    // Dump AST representation.
+    void
+    dump_clause(Ast_dump_context*) const;
 
    private:
     // The channel.
@@ -786,8 +803,10 @@ class Select_clauses
   };
 
   void
-  add_clause_tree(Translate_context*, int, Select_clause*, Unnamed_label*,
-                 tree*);
+  add_clause_backend(Translate_context*, source_location, int index,
+                    int case_value, Select_clause*, Unnamed_label*,
+                    std::vector<std::vector<Bexpression*> >* cases,
+                    std::vector<Bstatement*>* clauses);
 
   typedef std::vector<Select_clause> Clauses;
 
@@ -808,7 +827,7 @@ class Select_statement : public Statement
   void
   add_clauses(Select_clauses* clauses)
   {
-    gcc_assert(this->clauses_ == NULL);
+    go_assert(this->clauses_ == NULL);
     this->clauses_ = clauses;
   }
 
@@ -822,7 +841,7 @@ class Select_statement : public Statement
   { return this->clauses_->traverse(traverse); }
 
   Statement*
-  do_lower(Gogo*, Named_object*, Block*);
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
   void
   do_determine_types()
@@ -832,8 +851,11 @@ class Select_statement : public Statement
   do_may_fall_through() const
   { return this->clauses_->may_fall_through(); }
 
-  tree
-  do_get_tree(Translate_context*);
+  Bstatement*
+  do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
   // The select clauses.
@@ -854,13 +876,13 @@ 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
   // parameter.
   bool
-  simplify_statement(Gogo*, Block*);
+  simplify_statement(Gogo*, Named_object*, Block*);
 
  protected:
   int
@@ -875,30 +897,26 @@ class Thunk_statement : public Statement
   void
   do_check_types(Gogo*);
 
-  // Return the function and argument trees for the call.
-  void
-  get_fn_and_arg(Translate_context*, tree* pfn, tree* parg);
+  // 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&, Function_type* fntype);
-
-  // The field name used in the thunk structure for the function
-  // pointer.
-  static const char* const thunk_field_fn;
-
-  // The field name used in the thunk structure for the receiver, if
-  // there is one.
-  static const char* const thunk_field_receiver;
+  build_thunk(Gogo*, const std::string&);
 
   // Set the name to use for thunk field N.
   void
@@ -922,8 +940,11 @@ class Go_statement : public Thunk_statement
   { }
 
  protected:
-  tree
-  do_get_tree(Translate_context*);
+  Bstatement*
+  do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 };
 
 // A defer statement.
@@ -936,8 +957,11 @@ class Defer_statement : public Thunk_statement
   { }
 
  protected:
-  tree
-  do_get_tree(Translate_context*);
+  Bstatement*
+  do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 };
 
 // A label statement.
@@ -959,8 +983,11 @@ class Label_statement : public Statement
   int
   do_traverse(Traverse*);
 
-  tree
-  do_get_tree(Translate_context*);
+  Bstatement*
+  do_get_backend(Translate_context*);
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
   // The label.
@@ -983,7 +1010,7 @@ class For_statement : public Statement
   void
   add_statements(Block* statements)
   {
-    gcc_assert(this->statements_ == NULL);
+    go_assert(this->statements_ == NULL);
     this->statements_ = statements;
   }
 
@@ -1006,14 +1033,17 @@ class For_statement : public Statement
 
   bool
   do_traverse_assignments(Traverse_assignments*)
-  { gcc_unreachable(); }
+  { go_unreachable(); }
 
   Statement*
-  do_lower(Gogo*, Named_object*, Block*);
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
-  tree
-  do_get_tree(Translate_context*)
-  { gcc_unreachable(); }
+  Bstatement*
+  do_get_backend(Translate_context*)
+  { go_unreachable(); }
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
   // The initialization statements.  This may be NULL.
@@ -1046,7 +1076,7 @@ class For_range_statement : public Statement
   void
   add_statements(Block* statements)
   {
-    gcc_assert(this->statements_ == NULL);
+    go_assert(this->statements_ == NULL);
     this->statements_ = statements;
   }
 
@@ -1064,14 +1094,17 @@ class For_range_statement : public Statement
 
   bool
   do_traverse_assignments(Traverse_assignments*)
-  { gcc_unreachable(); }
+  { go_unreachable(); }
 
   Statement*
-  do_lower(Gogo*, Named_object*, Block*);
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
-  tree
-  do_get_tree(Translate_context*)
-  { gcc_unreachable(); }
+  Bstatement*
+  do_get_backend(Translate_context*)
+  { go_unreachable(); }
+
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
   Expression*
@@ -1172,13 +1205,22 @@ class Case_clauses
 
   // Return the body of a SWITCH_EXPR when all the clauses are
   // constants.
-  tree
-  get_constant_tree(Translate_context*, Unnamed_label* break_label) const;
+  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 tree we need to keep a record of constants we have
-  // already seen.  Note that INTEGER_CST trees are interned.
-  typedef Unordered_set(tree) Case_constants;
+  // 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
@@ -1236,12 +1278,16 @@ class Case_clauses
     bool
     may_fall_through() const;
 
-    // Build up the body of a SWITCH_EXPR when the case expressions
-    // are constant.
-    void
-    get_constant_tree(Translate_context*, Unnamed_label* break_label,
-                     Case_constants* case_constants, tree* stmt_list) 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_;
@@ -1278,7 +1324,7 @@ class Switch_statement : public Statement
   void
   add_clauses(Case_clauses* clauses)
   {
-    gcc_assert(this->clauses_ == NULL);
+    go_assert(this->clauses_ == NULL);
     this->clauses_ = clauses;
   }
 
@@ -1291,11 +1337,14 @@ class Switch_statement : public Statement
   do_traverse(Traverse*);
 
   Statement*
-  do_lower(Gogo*, Named_object*, Block*);
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
+
+  Bstatement*
+  do_get_backend(Translate_context*)
+  { go_unreachable(); }
 
-  tree
-  do_get_tree(Translate_context*)
-  { gcc_unreachable(); }
+  void
+  do_dump_statement(Ast_dump_context*) const;
 
  private:
   // The value to switch on.  This may be NULL.
@@ -1347,6 +1396,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
@@ -1387,6 +1440,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_;
@@ -1418,13 +1475,13 @@ class Type_switch_statement : public Statement
                        source_location location)
     : Statement(STATEMENT_TYPE_SWITCH, location),
       var_(var), expr_(expr), clauses_(NULL), break_label_(NULL)
-  { gcc_assert(var == NULL || expr == NULL); }
+  { go_assert(var == NULL || expr == NULL); }
 
   // Add the clauses.
   void
   add_clauses(Type_case_clauses* clauses)
   {
-    gcc_assert(this->clauses_ == NULL);
+    go_assert(this->clauses_ == NULL);
     this->clauses_ = clauses;
   }
 
@@ -1437,17 +1494,16 @@ class Type_switch_statement : public Statement
   do_traverse(Traverse*);
 
   Statement*
-  do_lower(Gogo*, Named_object*, Block*);
+  do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
-  tree
-  do_get_tree(Translate_context*)
-  { gcc_unreachable(); }
+  Bstatement*
+  do_get_backend(Translate_context*)
+  { go_unreachable(); }
 
- private:
-  // Get the type descriptor.
-  tree
-  get_type_descriptor(Translate_context*, Type*, tree);
+  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.