OSDN Git Service

gccgo: fixes to ast-dump, refactoring of export and ast-dump
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 Aug 2011 19:22:44 +0000 (19:22 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 Aug 2011 19:22:44 +0000 (19:22 +0000)
        to implement a common interface for writing basic
        type literals and added flags for optimization.

* lang.opt: Add fgo-optimize-.
* go-lang.c (go_langhook_handle_option): Handle OPT_fgo_optimize.
* go-c.h (go_enable_optimize): Declare.
* Make-lang.in (GO_OBJS): Add go/go-optimize.o.
(GO_EXPORT_H): Define.
(GO_IMPORT_H): Add $(GO_EXPORT_H).
(GO_AST_DUMP_H): Define.
(go/ast-dump.o, go/statements.o): Use GO_AST_DUMP_H.
(go/export.o, go/gogo.o, go/import.o): Use GO_EXPORT_H.
(go/types.o): Likewise.
(go/expressions.o): Use GO_AST_DUMP_H and GO_EXPORT_H.
(go/go-optimize.o): New target.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178046 138bc75d-0d04-0410-961f-82ee72b054a4

14 files changed:
gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/go-c.h
gcc/go/go-lang.c
gcc/go/gofrontend/ast-dump.cc
gcc/go/gofrontend/ast-dump.h
gcc/go/gofrontend/export.h
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/go-optimize.cc [new file with mode: 0644]
gcc/go/gofrontend/go-optimize.h [new file with mode: 0644]
gcc/go/gofrontend/statements.cc
gcc/go/gofrontend/string-dump.h [new file with mode: 0644]
gcc/go/lang.opt

index 16b24ac..3802fa8 100644 (file)
@@ -1,3 +1,18 @@
+2011-08-24  Roberto Lublinerman  <rluble@gmail.com>
+
+       * lang.opt: Add fgo-optimize-.
+       * go-lang.c (go_langhook_handle_option): Handle OPT_fgo_optimize.
+       * go-c.h (go_enable_optimize): Declare.
+       * Make-lang.in (GO_OBJS): Add go/go-optimize.o.
+       (GO_EXPORT_H): Define.
+       (GO_IMPORT_H): Add $(GO_EXPORT_H).
+       (GO_AST_DUMP_H): Define.
+       (go/ast-dump.o, go/statements.o): Use GO_AST_DUMP_H.
+       (go/export.o, go/gogo.o, go/import.o): Use GO_EXPORT_H.
+       (go/types.o): Likewise.
+       (go/expressions.o): Use GO_AST_DUMP_H and GO_EXPORT_H.
+       (go/go-optimize.o): New target.
+
 2011-08-24  Joseph Myers  <joseph@codesourcery.com>
 
        * Make-lang.in (CFLAGS-go/go-lang.o): New.
index fc43612..d7ae7ae 100644 (file)
@@ -54,6 +54,7 @@ GO_OBJS = \
        go/go-dump.o \
        go/go-gcc.o \
        go/go-lang.o \
+       go/go-optimize.o \
        go/go.o \
        go/gogo-tree.o \
        go/gogo.o \
@@ -222,8 +223,10 @@ GO_GOGO_H = go/gofrontend/gogo.h
 GO_TYPES_H = go/gofrontend/types.h
 GO_STATEMENTS_H = go/gofrontend/statements.h go/gofrontend/operator.h
 GO_EXPRESSIONS_H = go/gofrontend/expressions.h go/gofrontend/operator.h
-GO_IMPORT_H = go/gofrontend/import.h go/gofrontend/export.h
+GO_EXPORT_H = go/gofrontend/export.h go/gofrontend/string-dump.h
+GO_IMPORT_H = go/gofrontend/import.h $(GO_EXPORT_H)
 GO_RUNTIME_H = go/gofrontend/runtime.h go/gofrontend/runtime.def
+GO_AST_DUMP_H = go/gofrontend/ast-dump.h go/gofrontend/string-dump.h
 
 go/go-backend.o: go/go-backend.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
        $(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) output.h $(TARGET_H) \
@@ -249,22 +252,24 @@ go/%.o: go/gofrontend/%.cc
 
 go/ast-dump.o: go/gofrontend/ast-dump.cc $(GO_SYSTME_H) $(GO_GOGO_H) \
        $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_TYPES_H) \
-       go/gofrontend/ast-dump.h $(GO_C_H) go/gofrontend/go-dump.h
+       $(GO_AST_DUMP_H) $(GO_C_H) go/gofrontend/go-dump.h
 go/dataflow.o: go/gofrontend/dataflow.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \
        $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) go/gofrontend/dataflow.h
 go/export.o: go/gofrontend/export.cc $(GO_SYSTEM_H) \
        $(srcdir)/../include/sha1.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
-       $(GO_STATEMENTS_H) go/gofrontend/export.h
+       $(GO_STATEMENTS_H) $(GO_EXPORT_H)
 go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
        intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \
        realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
-       go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
+       $(GO_EXPORT_H) $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
        $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H) \
-       go/gofrontend/ast-dump.h
+       $(GO_AST_DUMP_H)
 go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
        $(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
        go/gofrontend/go-dump.h
+go/go-optimize.o: go/gofrontend/go-optimize.cc $(GO_SYSTEM_H) $(GO_C_H) \
+       go/gofrontend/go-optimize.h
 go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
        $(TREE_H) $(GIMPLE_H) tree-iterator.h $(CGRAPH_H) langhooks.h \
        convert.h output.h $(DIAGNOSTIC_H) $(GO_TYPES_H) \
@@ -273,12 +278,10 @@ go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
 go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) $(GO_C_H) \
        go/gofrontend/go-dump.h $(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) \
        $(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_RUNTIME_H) \
-       $(GO_IMPORT_H) go/gofrontend/export.h go/gofrontend/backend.h \
-       $(GO_GOGO_H)
+       $(GO_IMPORT_H) $(GO_EXPORT_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \
        $(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \
-       $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) go/gofrontend/export.h \
-       $(GO_IMPORT_H)
+       $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) $(GO_EXPORT_H) $(GO_IMPORT_H)
 go/import-archive.o: go/gofrontend/import-archive.cc $(GO_SYSTEM_H) \
        $(GO_IMPORT_H)
 go/lex.o: go/gofrontend/lex.cc $(GO_LEX_H) $(GO_SYSTEM_H)
@@ -290,11 +293,10 @@ go/runtime.o: go/gofrontend/runtime.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \
 go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) \
        $(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \
        $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H) \
-       go/gofrontend/ast-dump.h
+       $(GO_AST_DUMP_H)
 go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \
        $(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \
        go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \
-       go/gofrontend/export.h $(GO_IMPORT_H) go/gofrontend/backend.h \
-       $(GO_TYPES_H)
+       $(GO_EXPORT_H) $(GO_IMPORT_H) go/gofrontend/backend.h $(GO_TYPES_H)
 go/unsafe.o: go/gofrontend/unsafe.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_TYPES_H) \
        $(GO_GOGO_H)
index f70f1ad..f5ecbeb 100644 (file)
@@ -37,6 +37,7 @@ extern "C"
    interface.  */
 
 extern int go_enable_dump (const char*);
+extern int go_enable_optimize (const char*);
 extern void go_set_prefix (const char*);
 
 extern void go_add_search_path (const char*);
index 6abe3b8..7d2de44 100644 (file)
@@ -223,6 +223,10 @@ go_langhook_handle_option (
       ret = go_enable_dump (arg) ? true : false;
       break;
 
+    case OPT_fgo_optimize_:
+      ret = go_enable_optimize (arg) ? true : false;
+      break;
+
     case OPT_fgo_prefix_:
       go_set_prefix (arg);
       break;
index d52d367..850e31a 100644 (file)
@@ -19,9 +19,9 @@
 
 // The -fgo-dump-ast flag to activate AST dumps.
 
-Go_dump ast_dump_context_flag("ast");
+Go_dump ast_dump_flag("ast");
 
-// This class is used to traverse the tree to look for blocks and 
+// This class is used to traverse the tree to look for blocks and
 // function headers.
 
 class Ast_dump_traverse_blocks_and_functions : public Traverse
@@ -33,9 +33,9 @@ class Ast_dump_traverse_blocks_and_functions : public Traverse
   { }
 
  protected:
-  int 
+  int
   block(Block*);
+
   int
   function(Named_object*);
 
@@ -79,7 +79,7 @@ int Ast_dump_traverse_blocks_and_functions::block(Block * block)
 
   return TRAVERSE_SKIP_COMPONENTS;
 }
+
 // Dump each traversed statement.
 
 int
@@ -87,7 +87,7 @@ Ast_dump_traverse_statements::statement(Block* block, size_t* pindex,
                                         Statement* statement)
 {
   statement->dump_statement(this->ast_dump_context_);
+
   if (statement->is_block_statement())
     {
       Ast_dump_traverse_blocks_and_functions adtbf(this->ast_dump_context_);
@@ -103,49 +103,51 @@ int
 Ast_dump_traverse_blocks_and_functions::function(Named_object* no)
 {
   this->ast_dump_context_->ostream() << no->name();
+
   go_assert(no->is_function());
   Function* func = no->func_value();
-  
-  this->ast_dump_context_->ostream() << "("; 
+
+  this->ast_dump_context_->ostream() << "(";
   this->ast_dump_context_->dump_typed_identifier_list(
                               func->type()->parameters());
-  
-  this->ast_dump_context_->ostream() << ")"; 
-  
+
+  this->ast_dump_context_->ostream() << ")";
+
   Function::Results* res = func->result_variables();
   if (res != NULL && !res->empty())
-    {  
-      this->ast_dump_context_->ostream() << " ("; 
-      
-      for (Function::Results::const_iterator it = res->begin(); 
-          it != res->end(); 
+    {
+      this->ast_dump_context_->ostream() << " (";
+
+      for (Function::Results::const_iterator it = res->begin();
+          it != res->end();
           it++)
         {
           if (it != res->begin())
             this->ast_dump_context_->ostream() << ",";
           Named_object* no = (*it);
-          
+
           this->ast_dump_context_->ostream() << no->name() << " ";
           go_assert(no->is_result_variable());
           Result_variable* resvar = no->result_var_value();
-          
+
           this->ast_dump_context_->dump_type(resvar->type());
-        
+
         }
       this->ast_dump_context_->ostream() << ")";
     }
-    
+
   this->ast_dump_context_->ostream() << " : ";
   this->ast_dump_context_->dump_type(func->type());
   this->ast_dump_context_->ostream() << std::endl;
-  
+
   return TRAVERSE_CONTINUE;
 }
 
 // Class Ast_dump_context.
 
-Ast_dump_context::Ast_dump_context() : ostream_(NULL)
+Ast_dump_context::Ast_dump_context(std::ostream* out /* = NULL */,
+                                  bool dump_subblocks /* = true */)
+  :  indent_(0), dump_subblocks_(dump_subblocks), ostream_(out), gogo_(NULL)
 {
 }
 
@@ -168,8 +170,7 @@ Ast_dump_context::dump(Gogo* gogo, const char* basename)
       error("cannot open %s:%m, -fgo-dump-ast ignored", dumpname.c_str());
       return;
     }
-  
-  this->indent_ = 0;
+
   this->gogo_ = gogo;
   this->ostream_ = out;
 
@@ -188,9 +189,10 @@ Ast_dump_context::dump_type(const Type* t)
   if (t == NULL)
     this->ostream() << "(nil type)";
   else
-    // FIXME: write a type pretty printer instead of 
+    // FIXME: write a type pretty printer instead of
     // using mangled names.
-    this->ostream() << "(" << t->mangled_name(this->gogo_) <<  ")"; 
+    if (this->gogo_ != NULL)
+      this->ostream() << "(" << t->mangled_name(this->gogo_) <<  ")";
 }
 
 // Dump a textual representation of a block to the
@@ -216,18 +218,28 @@ Ast_dump_context::dump_expression(const Expression* e)
 // the dump file.
 
 void
-Ast_dump_context::dump_expression_list(const Expression_list* el)
+Ast_dump_context::dump_expression_list(const Expression_list* el,
+                                      bool as_pairs /* = false */)
 {
   if (el == NULL)
     return;
-  
-  for (std::vector<Expression*>::const_iterator it = el->begin(); 
+
+  for (std::vector<Expression*>::const_iterator it = el->begin();
        it != el->end();
        it++)
     {
       if ( it != el->begin())
         this->ostream() << ",";
-      (*it)->dump_expression(this);
+      if (*it != NULL)
+       (*it)->dump_expression(this);
+      else
+        this->ostream() << "NULL";
+      if (as_pairs)
+        {
+         this->ostream() << ":";
+         ++it;
+         (*it)->dump_expression(this);
+        }
     }
 }
 
@@ -246,13 +258,13 @@ Ast_dump_context::dump_typed_identifier(const Typed_identifier* ti)
 
 void
 Ast_dump_context::dump_typed_identifier_list(
-    const Typed_identifier_list* ti_list)         
+    const Typed_identifier_list* ti_list)
 {
   if (ti_list == NULL)
     return;
-  
-  for (Typed_identifier_list::const_iterator it = ti_list->begin(); 
-       it != ti_list->end(); 
+
+  for (Typed_identifier_list::const_iterator it = ti_list->begin();
+       it != ti_list->end();
        it++)
     {
       if (it != ti_list->begin())
@@ -300,6 +312,8 @@ op_string(Operator op)
       return "!";
     case OPERATOR_XOR:
       return "^";
+    case OPERATOR_OR:
+      return "|";
     case OPERATOR_AND:
       return "&";
     case OPERATOR_MULT:
@@ -415,9 +429,41 @@ Ast_dump_context::print_indent()
 
 void Gogo::dump_ast(const char* basename)
 {
-  if (ast_dump_context_flag.is_enabled())
+  if (::ast_dump_flag.is_enabled())
     {
       Ast_dump_context adc;
       adc.dump(this, basename);
     }
 }
+
+// Implementation of String_dump interface.
+
+void
+Ast_dump_context::write_c_string(const char* s)
+{
+  this->ostream() << s;
+}
+
+void
+Ast_dump_context::write_string(const std::string& s)
+{
+  this->ostream() << s;
+}
+
+// Dump statment to stream.
+
+void
+Ast_dump_context::dump_to_stream(const Statement* stm, std::ostream* out)
+{
+  Ast_dump_context adc(out, false);
+  stm->dump_statement(&adc);
+}
+
+// Dump expression to stream.
+
+void
+Ast_dump_context::dump_to_stream(const Expression* expr, std::ostream* out)
+{
+  Ast_dump_context adc(out, false);
+  expr->dump_expression(&adc);
+}
\ No newline at end of file
index 92a4915..55c9369 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef GO_AST_DUMP_H
 #define GO_AST_DUMP_H
 
+#include "string-dump.h"
+
 class Expression;
 class Expression_list;
 class Named_object;
@@ -16,10 +18,10 @@ class Gogo;
 // This class implements fgo-dump-ast. the
 // Abstract syntax tree dump of the Go program.
 
-class Ast_dump_context 
+class Ast_dump_context : public String_dump
 {
  public:
-  Ast_dump_context();
+  Ast_dump_context(std::ostream* out = NULL, bool dump_subblocks = true);
 
   // Initialize the dump context.
   void
@@ -28,38 +30,43 @@ class Ast_dump_context
   // Dump spaces to dumpfile as indentation.
   void
   print_indent();
-  
+
   // Increase current indentation for print_indent().
   void
-  indent() 
+  indent()
   { ++this->indent_;}
 
   // Decrease current indentation for print_indent().
   void
-  unindent() 
+  unindent()
   { --this->indent_;}
 
+  // Whether subblocks should be dumped or not.
+  bool
+  dump_subblocks()
+  { return this->dump_subblocks_; }
+
   // Get dump output stream.
-  std::ostream& 
-  ostream() 
+  std::ostream&
+  ostream()
   { return *this->ostream_;}
 
   // Dump a Block to dump file.
-  void 
+  void
   dump_block(Block*);
-  
+
   // Dump a type to dump file.
-  void 
+  void
   dump_type(const Type*);
-  
+
   // Dump an expression to dump file.
-  void 
+  void
   dump_expression(const Expression*);
 
   // Dump an expression list to dump file.
-  void 
-  dump_expression_list(const Expression_list*);
-  
+  void
+  dump_expression_list(const Expression_list*, bool as_pairs = false);
+
   // Dump a typed identifier to dump file.
   void
   dump_typed_identifier(const  Typed_identifier*);
@@ -67,7 +74,7 @@ class Ast_dump_context
   // Dump a typed identifier list to dump file.
   void
   dump_typed_identifier_list(const Typed_identifier_list*);
-  
+
   // Dump temporary variable name to dump file.
   void
   dump_temp_variable_name(const Statement*);
@@ -79,17 +86,36 @@ class Ast_dump_context
   // Dump operator symbol to dump file.
   void
   dump_operator(Operator);
-    
+
+  // Implementation of String_dump interface.
+  void
+  write_c_string(const char*);
+
+  // Implements the String_dump interface.
+  void
+  write_string(const std::string& s);
+
+  // Dump statement to stream.
+  static void
+  dump_to_stream(const Statement*, std::ostream*);
+
+  // Dump expression to stream.
+  static void
+  dump_to_stream(const Expression* expr, std::ostream* out);
+
  private:
    // Current indent level.
   int indent_;
-  
+
   // Indentation offset.
   static const int offset_;
-  
+
+  // Whether subblocks of composite statements should be dumped or not.
+  bool dump_subblocks_;
+
   // Stream on output dump file.
   std::ostream* ostream_;
-    
+
   Gogo* gogo_;
 };
 
index ef24977..1f8278f 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef GO_EXPORT_H
 #define GO_EXPORT_H
 
+#include "string-dump.h"
+
 struct sha1_ctx;
 class Gogo;
 class Import_init;
@@ -45,7 +47,7 @@ enum Builtin_code
 // loop of exporting.  A pointer to this class is also passed to the
 // various specific export implementations.
 
-class Export
+class Export : public String_dump
 {
  public:
   // The Stream class is an interface used to output the exported
@@ -57,12 +59,12 @@ class Export
     Stream();
     virtual ~Stream();
 
-    // Write a string.
+    // Write a string. Implements the String_dump interface.
     void
     write_string(const std::string& s)
     { this->write_and_sum_bytes(s.data(), s.length()); }
 
-    // Write a nul terminated string.
+    // Write a nul terminated string. Implements the String_dump interface.
     void
     write_c_string(const char* s)
     { this->write_and_sum_bytes(s, strlen(s)); }
index 8053456..a082012 100644 (file)
@@ -1345,7 +1345,13 @@ Func_expression::do_get_tree(Translate_context* context)
 void
 Func_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  ast_dump_context->ostream() << this->function_->name() ;
+  ast_dump_context->ostream() << this->function_->name();
+  if (this->closure_ != NULL)
+    {
+      ast_dump_context->ostream() << " {closure =  ";
+      this->closure_->dump_expression(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
 }
 
 // Make a reference to a function in an expression.
@@ -1423,7 +1429,6 @@ Unknown_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
   ast_dump_context->ostream() << "_Unknown_(" << this->named_object_->name()
                              << ")";
-   
 }
 
 // Make a reference to an unknown name.
@@ -1563,16 +1568,17 @@ String_expression::do_get_tree(Translate_context* context)
   return context->gogo()->go_string_constant_tree(this->val_);
 }
 
-// Export a string expression.
+ // Write string literal to string dump.
 
 void
-String_expression::do_export(Export* exp) const
+String_expression::export_string(String_dump* exp,
+                                const String_expression* str)
 {
   std::string s;
-  s.reserve(this->val_.length() * 4 + 2);
+  s.reserve(str->val_.length() * 4 + 2);
   s += '"';
-  for (std::string::const_iterator p = this->val_.begin();
-       p != this->val_.end();
+  for (std::string::const_iterator p = str->val_.begin();
+       p != str->val_.end();
        ++p)
     {
       if (*p == '\\' || *p == '"')
@@ -1600,6 +1606,14 @@ String_expression::do_export(Export* exp) const
   exp->write_string(s);
 }
 
+// Export a string expression.
+
+void
+String_expression::do_export(Export* exp) const
+{
+  String_expression::export_string(exp, this);
+}
+
 // Import a string expression.
 
 Expression*
@@ -1647,8 +1661,7 @@ String_expression::do_import(Import* imp)
 void
 String_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  // FIXME: Do proper backshlash quoting for this->val_
-  ast_dump_context->ostream() << "\"" << this->val_ << "\"";
+  String_expression::export_string(ast_dump_context, this);
 }
 
 // Make a string expression.
@@ -1676,9 +1689,9 @@ class Integer_expression : public Expression
   static bool
   check_constant(mpz_t val, Type*, source_location);
 
-  // Write VAL to export data.
+  // Write VAL to string dump.
   static void
-  export_integer(Export* exp, const mpz_t val);
+  export_integer(String_dump* exp, const mpz_t val);
 
   // Write VAL to dump context.
   static void
@@ -1861,7 +1874,7 @@ Integer_expression::do_get_tree(Translate_context* context)
 // Write VAL to export data.
 
 void
-Integer_expression::export_integer(Export* exp, const mpz_t val)
+Integer_expression::export_integer(String_dump* exp, const mpz_t val)
 {
   char* s = mpz_get_str(NULL, 10, val);
   exp->write_c_string(s);
@@ -1962,27 +1975,12 @@ Integer_expression::do_import(Import* imp)
       return ret;
     }
 }
-
-// Write integer to dump context.
-
-void
-Integer_expression::dump_integer(Ast_dump_context* ast_dump_context, 
-                                 const mpz_t val)
-{
-  // FIXME: refactor this code so that is used both by dump and export. Extract
-  // a common interface for Ast_dump_context and Export.
-  char* s = mpz_get_str(NULL, 10, val);
-  ast_dump_context->ostream() << s ;
-  free(s);
-}
-
-
 // Ast dump for integer expression.
 
 void
 Integer_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  Integer_expression::dump_integer(ast_dump_context, this->val_);
+  Integer_expression::export_integer(ast_dump_context, this->val_);
 }
 
 // Build a new integer value.
@@ -2016,8 +2014,8 @@ class Float_expression : public Expression
 
   // Write VAL to export data.
   static void
-  export_float(Export* exp, const mpfr_t val);
-  
+  export_float(String_dump* exp, const mpfr_t val);
+
   // Write VAL to dump file.
   static void
   dump_float(Ast_dump_context* ast_dump_context, const mpfr_t val);
@@ -2203,10 +2201,10 @@ Float_expression::do_get_tree(Translate_context* context)
   return Expression::float_constant_tree(this->val_, type);
 }
 
-// Write a floating point number to export data.
+// Write a floating point number to a string dump.
 
 void
-Float_expression::export_float(Export *exp, const mpfr_t val)
+Float_expression::export_float(String_dump *exp, const mpfr_t val)
 {
   mp_exp_t exponent;
   char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
@@ -2230,33 +2228,12 @@ Float_expression::do_export(Export* exp) const
   exp->write_c_string(" ");
 }
 
-// Write  a floating point number to a dump context.
-
-void
-Float_expression::dump_float(Ast_dump_context* ast_dump_context, 
-                                  const mpfr_t val)
-{
-  // FIXME: this code should be refactored so that the same code is used here
-  // and in export_float.
-
-  mp_exp_t exponent;
-  char* s = mpfr_get_str(NULL, &exponent, 10, 0, val, GMP_RNDN);
-  if (*s == '-')
-    ast_dump_context->ostream() << "-";
-  ast_dump_context->ostream() << "0.";
-  ast_dump_context->ostream() << (*s == '-' ? s + 1 : s);
-  mpfr_free_str(s);
-  char buf[30];
-  snprintf(buf, sizeof buf, "E%ld", exponent);
-  ast_dump_context->ostream()  << buf;
-}
-
 // Dump a floating point number to the dump file.
 
 void
 Float_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  Float_expression::dump_float(ast_dump_context, this->val_);
+  Float_expression::export_float(ast_dump_context, this->val_);
 }
 
 // Make a float expression.
@@ -2289,9 +2266,9 @@ class Complex_expression : public Expression
   static bool
   check_constant(mpfr_t real, mpfr_t imag, Type*, source_location);
 
-  // Write REAL/IMAG to export data.
+  // Write REAL/IMAG to string dump.
   static void
-  export_complex(Export* exp, const mpfr_t real, const mpfr_t val);
+  export_complex(String_dump* exp, const mpfr_t real, const mpfr_t val);
 
   // Write REAL/IMAG to dump context.
   static void
@@ -2477,7 +2454,7 @@ Complex_expression::do_get_tree(Translate_context* context)
 // Write REAL/IMAG to export data.
 
 void
-Complex_expression::export_complex(Export* exp, const mpfr_t real,
+Complex_expression::export_complex(String_dump* exp, const mpfr_t real,
                                   const mpfr_t imag)
 {
   if (!mpfr_zero_p(real))
@@ -2500,30 +2477,12 @@ Complex_expression::do_export(Export* exp) const
   exp->write_c_string(" ");
 }
 
-// Write a complex number to a dump context.
-
-void
-Complex_expression::dump_complex(Ast_dump_context* ast_dump_context,
-                                    const mpfr_t real, const mpfr_t imag) 
-{
-  // FIXME: this code should be refactored so that it is used both here
-  // and by export _complex
-  if (!mpfr_zero_p(real))
-    {
-      Float_expression::dump_float(ast_dump_context, real);
-      if (mpfr_sgn(imag) > 0)
-        ast_dump_context->ostream() << "+";
-    }
-  Float_expression::dump_float(ast_dump_context, imag);
-  ast_dump_context->ostream() << "i";
-}
-
 // Dump a complex expression to the dump file.
 
 void
 Complex_expression::do_dump_expression(Ast_dump_context* ast_dump_context) const
 {
-  Complex_expression::dump_complex(ast_dump_context, 
+  Complex_expression::export_complex(ast_dump_context,
                                       this->real_,
                                       this->imag_);
 }
@@ -11622,7 +11581,6 @@ void
 Struct_construction_expression::do_dump_expression(
     Ast_dump_context* ast_dump_context) const
 {
-
   ast_dump_context->dump_type(this->type_);
   ast_dump_context->ostream() << "{";
   ast_dump_context->dump_expression_list(this->vals_);
@@ -11875,6 +11833,15 @@ void
 Array_construction_expression::do_dump_expression(
     Ast_dump_context* ast_dump_context) const
 {
+  Expression* length = this->type_->array_type() != NULL ?
+                        this->type_->array_type()->length() : NULL;
+
+  ast_dump_context->ostream() << "[" ;
+  if (length != NULL)
+    {
+      ast_dump_context->dump_expression(length);
+    }
+  ast_dump_context->ostream() << "]" ;
   ast_dump_context->dump_type(this->type_);
   ast_dump_context->ostream() << "{" ;
   ast_dump_context->dump_expression_list(this->vals_);
@@ -11910,6 +11877,9 @@ class Fixed_array_construction_expression :
 
   tree
   do_get_tree(Translate_context*);
+
+  void
+  do_dump_expression(Ast_dump_context*);
 };
 
 // Return a tree for constructing a fixed array.
@@ -11922,6 +11892,22 @@ Fixed_array_construction_expression::do_get_tree(Translate_context* context)
   return this->get_constructor_tree(context, type_to_tree(btype));
 }
 
+// Dump ast representation of an array construction expressin.
+
+void
+Fixed_array_construction_expression::do_dump_expression(
+    Ast_dump_context* ast_dump_context)
+{
+
+  ast_dump_context->ostream() << "[";
+  ast_dump_context->dump_expression (this->type()->array_type()->length());
+  ast_dump_context->ostream() << "]";
+  ast_dump_context->dump_type(this->type());
+  ast_dump_context->ostream() << "{";
+  ast_dump_context->dump_expression_list(this->vals());
+  ast_dump_context->ostream() << "}";
+
+}
 // Construct an open array.
 
 class Open_array_construction_expression : public Array_construction_expression
@@ -12410,9 +12396,8 @@ void
 Map_construction_expression::do_dump_expression(
     Ast_dump_context* ast_dump_context) const
 {
-  // FIXME: We should print key:value pairs here.
   ast_dump_context->ostream() << "{" ;
-  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->dump_expression_list(this->vals_, true);
   ast_dump_context->ostream() << "}";
 }
 
@@ -12866,11 +12851,10 @@ void
 Composite_literal_expression::do_dump_expression(
                                Ast_dump_context* ast_dump_context) const
 {
-  // FIXME: We should print colons if this->has_keys_ is true
-  ast_dump_context->ostream() << "composite_literal(" ;
+  ast_dump_context->ostream() << "composite(";
   ast_dump_context->dump_type(this->type_);
   ast_dump_context->ostream() << ", {";
-  ast_dump_context->dump_expression_list(this->vals_);
+  ast_dump_context->dump_expression_list(this->vals_, this->has_keys_);
   ast_dump_context->ostream() << "})";
 }
 
index 6f74f73..ec59846 100644 (file)
@@ -43,6 +43,7 @@ class Import;
 class Temporary_statement;
 class Label;
 class Ast_dump_context;
+class String_dump;
 
 // The base class for all expressions.
 
@@ -1043,6 +1044,10 @@ class String_expression : public Expression
   tree
   do_get_tree(Translate_context*);
 
+  // Write string literal to a string dump.
+  static void
+  export_string(String_dump* exp, const String_expression* str);
+
   void
   do_export(Export*) const;
 
diff --git a/gcc/go/gofrontend/go-optimize.cc b/gcc/go/gofrontend/go-optimize.cc
new file mode 100644 (file)
index 0000000..6da934f
--- /dev/null
@@ -0,0 +1,53 @@
+// go-optimize.cc -- Go frontend optimizer flags.
+
+// Copyright 2011 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.
+
+#include "go-system.h"
+
+#include "go-c.h"
+#include "go-optimize.h"
+
+namespace {
+
+// The list of optimizations.
+
+Go_optimize* optimizations;
+
+} // End empty namespace.
+
+// Create a new optimization.
+
+Go_optimize::Go_optimize(const char* name)
+  : next_(optimizations), name_(name), is_enabled_(false)
+{
+  optimizations = this;
+}
+
+// Enable an optimization by name.
+
+bool
+Go_optimize::enable_by_name(const char* name)
+{
+  bool is_all = strcmp(name, "all") == 0;
+  bool found = false;
+  for (Go_optimize* p = optimizations; p != NULL; p = p->next_)
+    {
+      if (is_all || strcmp(name, p->name_) == 0)
+       {
+         p->is_enabled_ = true;
+         found = true;
+       }
+    }
+  return found;
+}
+
+// Enable an optimization.  Return 1 if this is a real name, 0 if not.
+
+GO_EXTERN_C
+int
+go_enable_optimize(const char* name)
+{
+  return Go_optimize::enable_by_name(name) ? 1 : 0;
+}
diff --git a/gcc/go/gofrontend/go-optimize.h b/gcc/go/gofrontend/go-optimize.h
new file mode 100644 (file)
index 0000000..8638498
--- /dev/null
@@ -0,0 +1,38 @@
+// go-optimize.h -- Go frontend optimizer flags.    -*- C++ -*-
+
+// Copyright 2011 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_OPTIMIZE_H
+#define GO_OPTIMIZE_H
+
+// This class manages different arguments to -fgo-optimize-XXX.  If you
+// want to create a new optimization, create a variable of this type with the
+// name to use for XXX.  You can then use is_enabled to see whether
+// the -fgo-optimize-XXX option was used on the command line.
+
+class Go_optimize
+{
+ public:
+  Go_optimize(const char* name);
+
+  // Whether this optimizaiton was enabled.
+  bool
+  is_enabled() const
+  { return this->is_enabled_; }
+
+  // Enable an optimization by name.  Return true if found.
+  static bool
+  enable_by_name(const char*);
+
+ private:
+  // The next optimize flag.  These are not in any order.
+  Go_optimize* next_;
+  // The name of this optimization pass.
+  const char* name_;
+  // Whether this dump was enabled.
+  bool is_enabled_;
+};
+
+#endif // !defined(GO_OPTIMIZE_H)
index c6d2ace..f653ef6 100644 (file)
@@ -308,11 +308,11 @@ Variable_declaration_statement::do_dump_statement(
     Ast_dump_context* ast_dump_context) const
 {
   ast_dump_context->print_indent();
-  
+
   go_assert(var_->is_variable());
   ast_dump_context->ostream() << "var " << this->var_->name() <<  " ";
   Variable* var = this->var_->var_value();
-  if (var->has_type()) 
+  if (var->has_type())
     {
       ast_dump_context->dump_type(var->type());
       ast_dump_context->ostream() << " ";
@@ -478,7 +478,6 @@ Temporary_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
     {
       ast_dump_context->ostream() << " ";
       ast_dump_context->dump_type(this->type_);
-      
     }
   if (this->init_ != NULL)
     {
@@ -797,7 +796,7 @@ Assignment_operation_statement::do_dump_statement(
 {
   ast_dump_context->print_indent();
   ast_dump_context->dump_expression(this->lhs_);
-  ast_dump_context->dump_operator(this->op_); 
+  ast_dump_context->dump_operator(this->op_);
   ast_dump_context->dump_expression(this->rhs_);
   ast_dump_context->ostream() << std::endl;
 }
@@ -1548,7 +1547,7 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(
 
 // Dump the AST representation for a tuple type guard statement.
 
-void 
+void
 Tuple_type_guard_assignment_statement::do_dump_statement(
     Ast_dump_context* ast_dump_context) const
 {
@@ -1652,7 +1651,7 @@ Expression_statement::do_get_backend(Translate_context* context)
 
 // Dump the AST representation for an expression statement
 
-void 
+void
 Expression_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
     const
 {
@@ -2269,7 +2268,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
 
   // For a defer statement, start with a call to
   // __go_set_defer_retaddr.  */
-  Label* retaddr_label = NULL; 
+  Label* retaddr_label = NULL;
   if (may_call_recover)
     {
       retaddr_label = gogo->add_label_reference("retaddr");
@@ -2757,12 +2756,12 @@ Bc_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << (this->is_break_ ? "break" : "continue");
-  if (this->label_ != NULL) 
+  if (this->label_ != NULL)
     {
-      ast_dump_context->ostream() << " "; 
+      ast_dump_context->ostream() << " ";
       ast_dump_context->dump_label_name(this->label_);
     }
-  ast_dump_context->ostream() << std::endl; 
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a break statement.
@@ -3098,12 +3097,15 @@ If_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
   ast_dump_context->ostream() << "if ";
   ast_dump_context->dump_expression(this->cond_);
   ast_dump_context->ostream() << std::endl;
-  ast_dump_context->dump_block(this->then_block_);
-  if (this->else_block_ != NULL) 
+  if (ast_dump_context->dump_subblocks())
     {
-      ast_dump_context->print_indent();
-      ast_dump_context->ostream() << "else" << std::endl;
-      ast_dump_context->dump_block(this->else_block_);
+      ast_dump_context->dump_block(this->then_block_);
+      if (this->else_block_ != NULL)
+       {
+         ast_dump_context->print_indent();
+         ast_dump_context->ostream() << "else" << std::endl;
+         ast_dump_context->dump_block(this->else_block_);
+       }
     }
 }
 
@@ -3401,7 +3403,7 @@ Case_clauses::Case_clause::get_backend(Translate_context* context,
 // Dump the AST representation for a case clause
 
 void
-Case_clauses::Case_clause::dump_clause(Ast_dump_context* ast_dump_context) 
+Case_clauses::Case_clause::dump_clause(Ast_dump_context* ast_dump_context)
     const
 {
   ast_dump_context->print_indent();
@@ -3508,7 +3510,6 @@ Case_clauses::lower(Block* b, Temporary_statement* val_temp,
   if (default_case != NULL)
     default_case->lower(b, val_temp, default_start_label,
                        default_finish_label);
-      
 }
 
 // Determine types.
@@ -3592,7 +3593,7 @@ Case_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
 {
   for (Clauses::const_iterator p = this->clauses_.begin();
        p != this->clauses_.end();
-       ++p)    
+       ++p)
     p->dump_clause(ast_dump_context);
 }
 
@@ -3716,9 +3717,15 @@ Constant_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << "switch ";
   ast_dump_context->dump_expression(this->val_);
-  ast_dump_context->ostream() << " {" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->ostream() << "}" << std::endl;
+
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
+
+   ast_dump_context->ostream() << std::endl;
 }
 
 // Class Switch_statement.
@@ -3806,12 +3813,15 @@ Switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
   if (this->val_ != NULL)
     {
       ast_dump_context->dump_expression(this->val_);
-      ast_dump_context->ostream() << " ";
     }
-  ast_dump_context->ostream() << "{" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "}" << std::endl;
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a switch statement.
@@ -3951,7 +3961,7 @@ Type_case_clauses::Type_case_clause::dump_clause(
     }
   else
     {
-      ast_dump_context->ostream() << "case "; 
+      ast_dump_context->ostream() << "case ";
       ast_dump_context->dump_type(this->type_);
       ast_dump_context->ostream() << ":" ;
     }
@@ -4040,7 +4050,7 @@ Type_case_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
 {
   for (Type_clauses::const_iterator p = this->clauses_.begin();
        p != this->clauses_.end();
-       ++p)    
+       ++p)
     p->dump_clause(ast_dump_context);
 }
 
@@ -4150,15 +4160,20 @@ Type_switch_statement::break_label()
 // Dump the AST representation for a type switch statement
 
 void
-Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context) 
+Type_switch_statement::do_dump_statement(Ast_dump_context* ast_dump_context)
     const
 {
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << "switch " << this->var_->name() << " = ";
   ast_dump_context->dump_expression(this->expr_);
-  ast_dump_context->ostream() << " .(type) {" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->ostream() << "}" << std::endl;
+  ast_dump_context->ostream() << " .(type)";
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a type switch statement.
@@ -4554,7 +4569,7 @@ Select_clauses::Select_clause::dump_clause(
           ast_dump_context->ostream() << " <- " ;
           ast_dump_context->dump_expression(this->val_);
         }
-      else 
+      else
         {
          if (this->val_ != NULL)
            ast_dump_context->dump_expression(this->val_);
@@ -4567,7 +4582,7 @@ Select_clauses::Select_clause::dump_clause(
           if (this->closedvar_ != NULL ||
               this->var_ != NULL)
             ast_dump_context->ostream() << " := " ;
-            
+
           ast_dump_context->ostream() << " <- " ;
           ast_dump_context->dump_expression(this->channel_);
         }
@@ -4842,7 +4857,7 @@ Select_clauses::add_clause_backend(
                          ? clause->location()
                          : clause->statements()->end_location());
   Bstatement* g = bottom_label->get_goto(context, gloc);
-                               
+
   if (s == NULL)
     (*clauses)[index] = g;
   else
@@ -4856,7 +4871,7 @@ Select_clauses::dump_clauses(Ast_dump_context* ast_dump_context) const
 {
   for (Clauses::const_iterator p = this->clauses_.begin();
        p != this->clauses_.end();
-       ++p)    
+       ++p)
     p->dump_clause(ast_dump_context);
 }
 
@@ -4902,13 +4917,18 @@ Select_statement::do_get_backend(Translate_context* context)
 
 // Dump the AST representation for a select statement.
 
-void 
+void
 Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
   ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "select {" << std::endl;
-  this->clauses_->dump_clauses(ast_dump_context);
-  ast_dump_context->ostream() << "}" << std::endl;
+  ast_dump_context->ostream() << "select";
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
+      this->clauses_->dump_clauses(ast_dump_context);
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a select statement.
@@ -5051,7 +5071,7 @@ For_statement::set_break_continue_labels(Unnamed_label* break_label,
 void
 For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
-  if (this->init_ != NULL)
+  if (this->init_ != NULL && ast_dump_context->dump_subblocks())
     {
       ast_dump_context->print_indent();
       ast_dump_context->indent();
@@ -5063,19 +5083,24 @@ For_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
   ast_dump_context->ostream() << "for ";
   if (this->cond_ != NULL)
     ast_dump_context->dump_expression(this->cond_);
-  ast_dump_context->ostream() << " {" << std::endl;
-  ast_dump_context->indent();
 
-  ast_dump_context->dump_block(this->statements_);
-  if (this->init_ != NULL)
+  if (ast_dump_context->dump_subblocks())
     {
+      ast_dump_context->ostream() << " {" << std::endl;
+      ast_dump_context->dump_block(this->statements_);
+      if (this->init_ != NULL)
+       {
+         ast_dump_context->print_indent();
+         ast_dump_context->ostream() << "// POST " << std::endl;
+         ast_dump_context->dump_block(this->post_);
+       }
+      ast_dump_context->unindent();
+
       ast_dump_context->print_indent();
-      ast_dump_context->ostream() << "// POST " << std::endl;
-      ast_dump_context->dump_block(this->post_);
+      ast_dump_context->ostream() << "}";
     }
-  ast_dump_context->unindent();
-  ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "}" << std::endl;
+
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a for statement.
@@ -5701,7 +5726,7 @@ For_range_statement::continue_label()
 void
 For_range_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
 {
-  
+
   ast_dump_context->print_indent();
   ast_dump_context->ostream() << "for ";
   ast_dump_context->dump_expression(this->index_var_);
@@ -5710,17 +5735,22 @@ For_range_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
       ast_dump_context->ostream() << ", ";
       ast_dump_context->dump_expression(this->value_var_);
     }
-    
-  ast_dump_context->ostream() << " = range ";      
+
+  ast_dump_context->ostream() << " = range ";
   ast_dump_context->dump_expression(this->range_);
-  ast_dump_context->ostream() << " {" << std::endl;
-  ast_dump_context->indent();
+  if (ast_dump_context->dump_subblocks())
+    {
+      ast_dump_context->ostream() << " {" << std::endl;
 
-  ast_dump_context->dump_block(this->statements_);
+      ast_dump_context->indent();
 
-  ast_dump_context->unindent();
-  ast_dump_context->print_indent();
-  ast_dump_context->ostream() << "}" << std::endl;
+      ast_dump_context->dump_block(this->statements_);
+
+      ast_dump_context->unindent();
+      ast_dump_context->print_indent();
+      ast_dump_context->ostream() << "}";
+    }
+  ast_dump_context->ostream() << std::endl;
 }
 
 // Make a for statement with a range clause.
diff --git a/gcc/go/gofrontend/string-dump.h b/gcc/go/gofrontend/string-dump.h
new file mode 100644 (file)
index 0000000..fe4807d
--- /dev/null
@@ -0,0 +1,25 @@
+// string-dump.h -- Abstract base class for dumping strings.    -*- C++ -*-
+
+// Copyright 2011 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_STRING_DUMP_H
+#define GO_STRING_DUMP_H
+
+// This abstract class provides an interface strings for whatever purpose.
+// Used for example for exporting and dumping objects.
+
+class String_dump 
+{
+ public:
+  // Write a string. Implements the String_dump interface.
+  virtual void
+  write_string(const std::string& s) = 0;
+
+  // Implementors should override this member, to dump a formatted c string.
+  virtual void
+  write_c_string(const char*) = 0;
+};
+
+#endif  // GO_STRING_DUMP_H
index 9d9b1ff..96c8d73 100644 (file)
@@ -1,6 +1,6 @@
 ; lang.opt -- Options for the gcc Go front end.
 
-; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
 ;
 ; This file is part of GCC.
 ;
@@ -41,6 +41,10 @@ fgo-dump-
 Go Joined RejectNegative
 -fgo-dump-<type>       Dump Go frontend internal information
 
+fgo-optimize-
+Go Joined RejectNegative
+-fgo-optimize-<type>   Turn on optimization passes in the frontend
+
 fgo-prefix=
 Go Joined RejectNegative
 -fgo-prefix=<string>   Set package-specific prefix for exported Go names