OSDN Git Service

Rewrite conversion of named types to backend representation.
[pf3gnuchains/gcc-fork.git] / gcc / go / gofrontend / gogo-tree.cc
index e43f64d..722a23a 100644 (file)
@@ -22,7 +22,6 @@ extern "C"
 #include "convert.h"
 #include "output.h"
 #include "diagnostic.h"
-#include "rtl.h"
 
 #ifndef ENABLE_BUILD_WITH_CXX
 }
@@ -162,7 +161,7 @@ Gogo::get_init_fn_name()
   if (this->init_fn_name_.empty())
     {
       gcc_assert(this->package_ != NULL);
-      if (this->package_name() == "main")
+      if (this->is_main_package())
        {
          // Use a name which the runtime knows.
          this->init_fn_name_ = "__go_init_main";
@@ -187,7 +186,7 @@ Gogo::get_init_fn_name()
 void
 Gogo::init_imports(tree* init_stmt_list)
 {
-  gcc_assert(this->package_name() == "main");
+  gcc_assert(this->is_main_package());
 
   if (this->imported_init_fns_.empty())
     return;
@@ -385,7 +384,7 @@ Gogo::write_initialization_function(tree fndecl, tree init_stmt_list)
 {
   // Make sure that we thought we needed an initialization function,
   // as otherwise we will not have reported it in the export data.
-  gcc_assert(this->package_name() == "main" || this->need_init_fn_);
+  gcc_assert(this->is_main_package() || this->need_init_fn_);
 
   if (fndecl == NULL_TREE)
     fndecl = this->initialization_function_decl();
@@ -641,6 +640,9 @@ sort_var_inits(Var_inits* var_inits)
 void
 Gogo::write_globals()
 {
+  this->convert_named_types();
+  this->build_interface_method_tables();
+
   Bindings* bindings = this->current_bindings();
   size_t count = bindings->size_definitions();
 
@@ -649,7 +651,7 @@ Gogo::write_globals()
   tree init_fndecl = NULL_TREE;
   tree init_stmt_list = NULL_TREE;
 
-  if (this->package_name() == "main")
+  if (this->is_main_package())
     this->init_imports(&init_stmt_list);
 
   // A list of variable initializations.
@@ -757,7 +759,7 @@ Gogo::write_globals()
              pop_cfun();
            }
 
-         if (var_init_tree != NULL_TREE)
+         if (var_init_tree != NULL_TREE && var_init_tree != error_mark_node)
            {
              if (no->var_value()->init() == NULL
                  && !no->var_value()->has_pre_init())
@@ -805,22 +807,11 @@ Gogo::write_globals()
   // This will be called if this package is imported.
   if (init_stmt_list != NULL_TREE
       || this->need_init_fn_
-      || this->package_name() == "main")
+      || this->is_main_package())
     this->write_initialization_function(init_fndecl, init_stmt_list);
 
   // Pass everything back to the middle-end.
 
-  if (this->imported_unsafe_)
-    {
-      // Importing the "unsafe" package automatically disables TBAA.
-      flag_strict_aliasing = false;
-
-      // This is a real hack.  init_varasm_once has already grabbed an
-      // alias set, which we don't want when we aren't going strict
-      // aliasing.  We reinitialize to make it do it again.  FIXME.
-      init_varasm_once();
-    }
-
   wrapup_global_declarations(vec, count);
 
   cgraph_finalize_compilation_unit();
@@ -1209,10 +1200,13 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, tree var_decl)
 
   Translate_context context(gogo, function, NULL, NULL_TREE);
   tree block_tree = this->preinit_->get_tree(&context);
+  if (block_tree == error_mark_node)
+    return error_mark_node;
   gcc_assert(TREE_CODE(block_tree) == BIND_EXPR);
   tree statements = BIND_EXPR_BODY(block_tree);
-  while (TREE_CODE(statements) == TRY_FINALLY_EXPR
-        || TREE_CODE(statements) == TRY_CATCH_EXPR)
+  while (statements != NULL_TREE
+        && (TREE_CODE(statements) == TRY_FINALLY_EXPR
+            || TREE_CODE(statements) == TRY_CATCH_EXPR))
     statements = TREE_OPERAND(statements, 0);
 
   // It's possible to have pre-init statements without an initializer
@@ -1220,6 +1214,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, tree var_decl)
   if (this->init_ != NULL)
     {
       tree rhs_tree = this->init_->get_tree(&context);
+      if (rhs_tree == error_mark_node)
+       return error_mark_node;
       if (var_decl == NULL_TREE)
        append_to_statement_list(rhs_tree, &statements);
       else
@@ -1228,6 +1224,8 @@ Variable::get_init_block(Gogo* gogo, Named_object* function, tree var_decl)
                                                        this->init_->type(),
                                                        rhs_tree,
                                                        this->location());
+         if (val == error_mark_node)
+           return error_mark_node;
          tree set = fold_build2_loc(this->location(), MODIFY_EXPR,
                                     void_type_node, var_decl, val);
          append_to_statement_list(set, &statements);
@@ -1257,14 +1255,15 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
 
          this->fndecl_ = decl;
 
-         gcc_assert(no->package() == NULL);
-         if (this->enclosing_ != NULL || Gogo::is_thunk(no))
+         if (no->package() != NULL)
+           ;
+         else if (this->enclosing_ != NULL || Gogo::is_thunk(no))
            ;
          else if (Gogo::unpack_hidden_name(no->name()) == "init"
                   && !this->type_->is_method())
            ;
          else if (Gogo::unpack_hidden_name(no->name()) == "main"
-                  && gogo->package_name() == "main")
+                  && gogo->is_main_package())
            TREE_PUBLIC(decl) = 1;
          // Methods have to be public even if they are hidden because
          // they can be pulled into type descriptors when using
@@ -2349,6 +2348,8 @@ Gogo::map_descriptor(Map_type* maptype)
   Map_descriptors::iterator p = ins.first;
   if (!ins.second)
     {
+      if (p->second == error_mark_node)
+       return error_mark_node;
       gcc_assert(p->second != NULL_TREE && DECL_P(p->second));
       return build_fold_addr_expr(p->second);
     }
@@ -2378,7 +2379,10 @@ Gogo::map_descriptor(Map_type* maptype)
                                        "__val",
                                        valtype->get_tree(this));
   if (map_entry_type == error_mark_node)
-    return error_mark_node;
+    {
+      p->second = error_mark_node;
+      return error_mark_node;
+    }
 
   tree map_entry_key_field = DECL_CHAIN(TYPE_FIELDS(map_entry_type));
   gcc_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(map_entry_key_field)),
@@ -2633,26 +2637,14 @@ Gogo::build_type_descriptor_decl(const Type* type, Expression* initializer,
 
   DECL_INITIAL(decl) = constructor;
 
-  if (type_descriptor_location == TYPE_DESCRIPTOR_COMMON)
+  if (type_descriptor_location == TYPE_DESCRIPTOR_DEFINED)
+    TREE_PUBLIC(decl) = 1;
+  else
     {
+      gcc_assert(type_descriptor_location == TYPE_DESCRIPTOR_COMMON);
       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
       resolve_unique_section(decl, 1, 0);
     }
-  else
-    {
-#ifdef OBJECT_FORMAT_ELF
-      // Give the decl protected visibility.  This avoids out-of-range
-      // references with shared libraries with the x86_64 small model
-      // when the type descriptor gets a COPY reloc into the main
-      // executable.  There is no need to have unique pointers to type
-      // descriptors, as the runtime code compares reflection strings
-      // if necessary.
-      DECL_VISIBILITY(decl) = VISIBILITY_PROTECTED;
-      DECL_VISIBILITY_SPECIFIED(decl) = 1;
-#endif
-
-      TREE_PUBLIC(decl) = 1;
-    }
 
   rest_of_decl_compilation(decl, 1, 0);
 }
@@ -2764,17 +2756,7 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
   // definition of the table.  Otherwise it is a comdat table which
   // may be defined in multiple packages.
   if (has_hidden_methods)
-    {
-#ifdef OBJECT_FORMAT_ELF
-      // Give the decl protected visibility.  This avoids out-of-range
-      // references with shared libraries with the x86_64 small model
-      // when the table gets a COPY reloc into the main executable.
-      DECL_VISIBILITY(decl) = VISIBILITY_PROTECTED;
-      DECL_VISIBILITY_SPECIFIED(decl) = 1;
-#endif
-
-      TREE_PUBLIC(decl) = 1;
-    }
+    TREE_PUBLIC(decl) = 1;
   else
     {
       make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
@@ -2820,7 +2802,11 @@ Gogo::call_builtin(tree* pdecl, source_location location, const char* name,
       types[i] = va_arg(ap, tree);
       args[i] = va_arg(ap, tree);
       if (types[i] == error_mark_node || args[i] == error_mark_node)
-       return error_mark_node;
+       {
+         delete[] types;
+         delete[] args;
+         return error_mark_node;
+       }
     }
   va_end(ap);
 
@@ -2888,6 +2874,9 @@ tree
 Gogo::send_on_channel(tree channel, tree val, bool blocking, bool for_select,
                      source_location location)
 {
+  if (channel == error_mark_node || val == error_mark_node)
+    return error_mark_node;
+
   if (int_size_in_bytes(TREE_TYPE(val)) <= 8
       && !AGGREGATE_TYPE_P(TREE_TYPE(val))
       && !FLOAT_TYPE_P(TREE_TYPE(val)))
@@ -3022,6 +3011,9 @@ tree
 Gogo::receive_from_channel(tree type_tree, tree channel, bool for_select,
                           source_location location)
 {
+  if (type_tree == error_mark_node || channel == error_mark_node)
+    return error_mark_node;
+
   if (int_size_in_bytes(type_tree) <= 8
       && !AGGREGATE_TYPE_P(type_tree)
       && !FLOAT_TYPE_P(type_tree))