]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/decl.c
c-common.h (add_stmt): Change prototype.
[gcc.git] / gcc / cp / decl.c
index e84264df391e7b429b22be3ff948c82ad52a5ab6..9ac30e40832cd282c65534dceda13f58c7751747 100644 (file)
@@ -129,7 +129,6 @@ static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
 static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
 static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
                                  int));
-static void lang_print_error_function PARAMS ((const char *));
 static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct binding_level*));
 static void check_for_uninitialized_const_var PARAMS ((tree));
 static unsigned long typename_hash PARAMS ((hash_table_key));
@@ -170,8 +169,8 @@ static void mark_binding_level PARAMS ((void *));
 static void mark_named_label_lists PARAMS ((void *, void *));
 static void mark_cp_function_context PARAMS ((struct function *));
 static void mark_saved_scope PARAMS ((void *));
-static void mark_lang_function PARAMS ((struct language_function *));
-static void mark_stmt_tree PARAMS ((struct stmt_tree *));
+static void mark_lang_function PARAMS ((struct cp_language_function *));
+static void mark_stmt_tree PARAMS ((stmt_tree));
 static void save_function_data PARAMS ((tree));
 static void check_function_type PARAMS ((tree));
 static void destroy_local_var PARAMS ((tree));
@@ -188,6 +187,7 @@ static tree check_special_function_return_type
   PARAMS ((special_function_kind, tree, tree, tree));
 static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
 static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
+static int case_compare PARAMS ((splay_tree_key, splay_tree_key));
 
 #if defined (DEBUG_CP_BINDING_LEVELS)
 static void indent PARAMS ((void));
@@ -201,7 +201,6 @@ tree error_mark_list;
 
    C++ extensions
        tree wchar_decl_node;
-       tree void_zero_node;
 
        tree vtable_entry_type;
        tree delta_type_node;
@@ -270,13 +269,6 @@ int in_std;
 /* Expect only namespace names now. */
 static int only_namespace_names;
 
-/* If original DECL_RESULT of current function was a register,
-   but due to being an addressable named return value, would up
-   on the stack, this variable holds the named return value's
-   original location.  */
-
-#define original_result_rtx cp_function_chain->x_result_rtx
-
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
@@ -345,6 +337,15 @@ int flag_isoc94;
 
 int flag_isoc99;
 
+/* Nonzero means we are a hosted implementation for code shared with C.  */
+
+int flag_hosted = 1;
+
+/* Nonzero means add default format_arg attributes for functions not
+   in ISO C.  */
+
+int flag_noniso_default_format_attributes = 1;
+
 /* Nonzero means give `double' the same size as `float'.  */
 
 extern int flag_short_double;
@@ -2452,7 +2453,7 @@ struct saved_scope *scope_chain;
 
 static void
 mark_stmt_tree (st)
-     struct stmt_tree *st;
+     stmt_tree st;
 {
   ggc_mark_tree (st->x_last_stmt);
   ggc_mark_tree (st->x_last_expr_type);
@@ -3463,7 +3464,7 @@ duplicate_decls (newdecl, olddecl)
        DECL_VIRTUAL_CONTEXT (newdecl) = DECL_VIRTUAL_CONTEXT (olddecl);
       if (DECL_CONTEXT (olddecl))
        DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
-      if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0)
+      if (DECL_PENDING_INLINE_INFO (newdecl) == 0)
        DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);
       DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
       DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
@@ -3844,7 +3845,7 @@ pushdecl (x)
              nesting.  */
          && !(TREE_CODE (x) == FUNCTION_DECL && !DECL_INITIAL (x))
          /* A local declaration for an `extern' variable is in the
-            scoped of the current namespace, not the current
+            scope of the current namespace, not the current
             function.  */
          && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
          && !DECL_CONTEXT (x))
@@ -3863,20 +3864,40 @@ pushdecl (x)
   name = DECL_NAME (x);
   if (name)
     {
-#if 0
-      /* Not needed...see below.  */
-      char *file;
-      int line;
-#endif
+      int different_binding_level = 0;
+
       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        name = TREE_OPERAND (name, 0);
 
-      /* Namespace-scoped variables are not found in the current level. */
-      if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x))
+      /* In case this decl was explicitly namespace-qualified, look it
+        up in its namespace context.  */
+      if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x)
+         && namespace_bindings_p ())
        t = namespace_binding (name, DECL_CONTEXT (x));
       else
        t = lookup_name_current_level (name);
 
+      /* [basic.link] If there is a visible declaration of an entity
+        with linkage having the same name and type, ignoring entities
+        declared outside the innermost enclosing namespace scope, the
+        block scope declaration declares that same entity and
+        receives the linkage of the previous declaration.  */
+      if (! t && current_function_decl && x != current_function_decl
+         && (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+         && DECL_EXTERNAL (x))
+       {
+         /* Look in block scope.  */
+         t = IDENTIFIER_VALUE (name);
+         /* Or in the innermost namespace.  */
+         if (! t)
+           t = namespace_binding (name, DECL_CONTEXT (x));
+         /* Does it have linkage?  */
+         if (t && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+           t = NULL_TREE;
+         if (t)
+           different_binding_level = 1;
+       }
+
       /* If we are declaring a function, and the result of name-lookup
         was an OVERLOAD, look for an overloaded instance that is
         actually the same as the function we are declaring.  (If
@@ -3911,7 +3932,16 @@ pushdecl (x)
        }
       else if (t != NULL_TREE)
        {
-         if (TREE_CODE (t) == PARM_DECL)
+         if (different_binding_level)
+           {
+             if (decls_match (x, t))
+               /* The standard only says that the local extern
+                  inherits linkage from the previous decl; in
+                  particular, default args are not shared.  It would
+                  be nice to propagate inlining info, though.  FIXME.  */
+               TREE_PUBLIC (x) = TREE_PUBLIC (t);
+           }
+         else if (TREE_CODE (t) == PARM_DECL)
            {
              if (DECL_CONTEXT (t) == NULL_TREE)
                fatal ("parse errors have confused me too much");
@@ -5147,17 +5177,52 @@ struct cp_switch
 {
   struct binding_level *level;
   struct cp_switch *next;
+  /* The SWITCH_STMT being built.  */
+  tree switch_stmt;
+  /* A splay-tree mapping the low element of a case range to the high
+     element, or NULL_TREE if there is no high element.  Used to
+     determine whether or not a new case label duplicates an old case
+     label.  We need a tree, rather than simply a hash table, because
+     of the GNU case range extension.  */
+  splay_tree cases;
 };
 
+/* A stack of the currently active switch statements.  The innermost
+   switch statement is on the top of the stack.  There is no need to
+   mark the stack for garbage collection because it is only active
+   during the processing of the body of a function, and we never
+   collect at that point.  */
+   
 static struct cp_switch *switch_stack;
 
+static int
+case_compare (k1, k2)
+     splay_tree_key k1;
+     splay_tree_key k2;
+{
+  /* Consider a NULL key (such as arises with a `default' label) to be
+     smaller than anything else.  */
+  if (!k1)
+    return k2 ? -1 : 0;
+  else if (!k2)
+    return k1 ? 1 : 0;
+
+  return tree_int_cst_compare ((tree) k1, (tree) k2);
+}
+
+/* Called right after a switch-statement condition is parsed.
+   SWITCH_STMT is the switch statement being parsed.  */
+
 void
-push_switch ()
+push_switch (switch_stmt)
+     tree switch_stmt;
 {
   struct cp_switch *p
     = (struct cp_switch *) xmalloc (sizeof (struct cp_switch));
   p->level = current_binding_level;
   p->next = switch_stack;
+  p->switch_stmt = switch_stmt;
+  p->cases = splay_tree_new (case_compare, NULL, NULL);
   switch_stack = p;
 }
 
@@ -5167,6 +5232,7 @@ pop_switch ()
   struct cp_switch *cs;
   
   cs = switch_stack;
+  splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
   free (cs);
 }
@@ -5175,14 +5241,150 @@ pop_switch ()
    is a bad place for one.  */
 
 void
-define_case_label ()
+finish_case_label (low_value, high_value)
+     tree low_value;
+     tree high_value;
 {
-  tree cleanup = last_cleanup_this_contour ();
+  tree label;
+  tree cleanup;
+  tree type;
+  tree cond;
+  tree case_label;
+  splay_tree_node node;
 
   if (! switch_stack)
-    /* Don't crash; we'll complain in do_case.  */
+    {
+      if (high_value)
+       error ("case label not within a switch statement");
+      else if (low_value)
+       cp_error ("case label `%E' not within a switch statement", 
+                 low_value);
+      else
+       error ("`default' label not within a switch statement");
+      return;
+    }
+
+  label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+  if (processing_template_decl)
+    {
+      /* For templates, just add the case label; we'll do semantic
+        analysis at instantiation-time.  */
+      add_stmt (build_case_label (low_value, high_value, label));
+      return;
+    }
+
+  /* Find the condition on which this switch statement depends.  */
+  cond = SWITCH_COND (switch_stack->switch_stmt);
+  if (cond && TREE_CODE (cond) == TREE_LIST)
+    cond = TREE_VALUE (cond);
+  /* If there was an error processing the switch condition, bail now
+     before we get more confused.  */
+  if (!cond || cond == error_mark_node)
     return;
+  type = TREE_TYPE (cond);
+
+  if ((low_value && TREE_TYPE (low_value) 
+       && POINTER_TYPE_P (TREE_TYPE (low_value))) 
+      || (high_value && TREE_TYPE (high_value)
+         && POINTER_TYPE_P (TREE_TYPE (high_value))))
+    error ("pointers are not permitted as case values");
 
+  /* Case ranges are a GNU extension.  */
+  if (high_value && pedantic)
+    pedwarn ("ISO C++ forbids range expressions in switch statement");
+
+  if (low_value)
+    {
+      low_value = check_case_value (low_value);
+      low_value = convert_and_check (type, low_value);
+    }
+  if (high_value)
+    {
+      high_value = check_case_value (high_value);
+      high_value = convert_and_check (type, high_value);
+    }
+
+  /* If an error has occurred, bail out now.  */
+  if (low_value == error_mark_node || high_value == error_mark_node)
+    return;
+
+  /* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
+     really a case range, even though it was written that way.  Remove
+     the HIGH_VALUE to simplify later processing.  */
+  if (tree_int_cst_equal (low_value, high_value))
+    high_value = NULL_TREE;
+  if (low_value && high_value 
+      && !tree_int_cst_lt (low_value, high_value)) 
+    warning ("empty range specified");
+
+  /* Look up the LOW_VALUE in the table of case labels we already
+     have.  */
+  node = splay_tree_lookup (switch_stack->cases, (splay_tree_key) low_value);
+  /* If there was not an exact match, check for overlapping ranges.
+     There's no need to do this if there's no LOW_VALUE or HIGH_VALUE;
+     that's a `default' label and the only overlap is an exact match.  */
+  if (!node && (low_value || high_value))
+    {
+      splay_tree_node low_bound;
+      splay_tree_node high_bound;
+
+      /* Even though there wasn't an exact match, there might be an
+        overlap between this case range and another case range.
+        Since we've (inductively) not allowed any overlapping case
+        ranges, we simply need to find the greatest low case label
+        that is smaller that LOW_VALUE, and the smallest low case
+        label that is greater than LOW_VALUE.  If there is an overlap
+        it will occur in one of these two ranges.  */
+      low_bound = splay_tree_predecessor (switch_stack->cases,
+                                         (splay_tree_key) low_value);
+      high_bound = splay_tree_successor (switch_stack->cases,
+                                        (splay_tree_key) low_value);
+
+      /* Check to see if the LOW_BOUND overlaps.  It is smaller than
+        the LOW_VALUE, so there is no need to check unless the
+        LOW_BOUND is in fact itself a case range.  */
+      if (low_bound
+         && CASE_HIGH ((tree) low_bound->value)
+         && tree_int_cst_compare (CASE_HIGH ((tree) low_bound->value),
+                                   low_value) >= 0)
+       node = low_bound;
+      /* Check to see if the HIGH_BOUND overlaps.  The low end of that
+        range is bigger than the low end of the current range, so we
+        are only interested if the current range is a real range, and
+        not an ordinary case label.  */
+      else if (high_bound 
+              && high_value
+              && (tree_int_cst_compare ((tree) high_bound->key,
+                                        high_value)
+                  <= 0))
+       node = high_bound;
+    }
+  /* If there was an overlap, issue an error.  */
+  if (node)
+    {
+      tree duplicate = CASE_LABEL_DECL ((tree) node->value);
+
+      if (high_value)
+       {
+         error ("duplicate (or overlapping) case value");
+         cp_error_at ("this is the first entry overlapping that value",
+                      duplicate);
+       }
+      else if (low_value)
+       {
+         cp_error ("duplicate case value `%E'", low_value) ;
+         cp_error_at ("previously used here", duplicate);
+       }
+      else
+       {
+         error ("multiple default labels in one switch");
+         cp_error_at ("this is the first default label", duplicate);
+       }
+      return;
+    }
+
+  cleanup = last_cleanup_this_contour ();
   if (cleanup)
     {
       static int explained = 0;
@@ -5190,8 +5392,7 @@ define_case_label ()
       warning ("where case label appears here");
       if (!explained)
        {
-         warning ("(enclose actions of previous case statements requiring");
-         warning ("destructors in their own binding contours.)");
+         warning ("(enclose actions of previous case statements requiring destructors in their own scope.)");
          explained = 1;
        }
     }
@@ -5200,9 +5401,18 @@ define_case_label ()
 
   /* After labels, make any new cleanups go into their
      own new (temporary) binding contour.  */
-
   current_binding_level->more_cleanups_ok = 0;
   current_function_return_value = NULL_TREE;
+
+  /* Add a representation for the case label to the statement
+     tree.  */
+  case_label = build_case_label (low_value, high_value, label);
+  add_stmt (case_label);
+
+  /* Register this case label in the splay tree.  */
+  splay_tree_insert (switch_stack->cases, 
+                    (splay_tree_key) low_value,
+                    (splay_tree_value) case_label);
 }
 \f
 /* Return the list of declarations of the current level.
@@ -5888,7 +6098,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
            }
          else if (! IS_AGGR_TYPE (type)
                   || TREE_CODE (type) == TEMPLATE_TYPE_PARM
-                  || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
+                  || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
                   || TREE_CODE (type) == TYPENAME_TYPE)
            /* Someone else will give an error about this if needed.  */
            val = NULL_TREE;
@@ -6119,7 +6329,7 @@ end_only_namespace_names ()
 }
 \f
 /* Push the declarations of builtin types into the namespace.
-   RID_INDEX, if < CP_RID_MAX is the index of the builtin type
+   RID_INDEX is the index of the builtin type
    in the array RID_POINTERS.  NAME is the name used when looking
    up the builtin type.  TYPE is the _TYPE node for the builtin type.  */
 
@@ -6132,7 +6342,7 @@ record_builtin_type (rid_index, name, type)
   tree rname = NULL_TREE, tname = NULL_TREE;
   tree tdecl = NULL_TREE;
 
-  if ((int) rid_index < (int) CP_RID_MAX)
+  if ((int) rid_index < (int) RID_MAX)
     rname = ridpointers[(int) rid_index];
   if (name)
     tname = get_identifier (name);
@@ -6143,7 +6353,7 @@ record_builtin_type (rid_index, name, type)
     {
       tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
       set_identifier_type_value (tname, NULL_TREE);
-      if ((int) rid_index < (int) CP_RID_MAX)
+      if ((int) rid_index < (int) RID_MAX)
        /* Built-in types live in the global namespace. */
        SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
     }
@@ -6186,7 +6396,7 @@ record_builtin_java_type (name, size)
       TYPE_PRECISION (type) = - size;
       layout_type (type);
     }
-  record_builtin_type (CP_RID_MAX, name, type);
+  record_builtin_type (RID_MAX, name, type);
   decl = TYPE_NAME (type);
 
   /* Suppress generate debug symbol entries for these types,
@@ -6342,27 +6552,27 @@ init_decl_processing ()
   record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node);
   record_builtin_type (RID_LONG, "long int", long_integer_type_node);
   record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
-  record_builtin_type (CP_RID_MAX, "long unsigned int",
+  record_builtin_type (RID_MAX, "long unsigned int",
                       long_unsigned_type_node);
-  record_builtin_type (CP_RID_MAX, "unsigned long", long_unsigned_type_node);
-  record_builtin_type (CP_RID_MAX, "long long int",
+  record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
+  record_builtin_type (RID_MAX, "long long int",
                       long_long_integer_type_node);
-  record_builtin_type (CP_RID_MAX, "long long unsigned int",
+  record_builtin_type (RID_MAX, "long long unsigned int",
                       long_long_unsigned_type_node);
-  record_builtin_type (CP_RID_MAX, "long long unsigned",
+  record_builtin_type (RID_MAX, "long long unsigned",
                       long_long_unsigned_type_node);
   record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
-  record_builtin_type (CP_RID_MAX, "short unsigned int",
+  record_builtin_type (RID_MAX, "short unsigned int",
                       short_unsigned_type_node); 
-  record_builtin_type (CP_RID_MAX, "unsigned short",
+  record_builtin_type (RID_MAX, "unsigned short",
                       short_unsigned_type_node);
 
   ptrdiff_type_node
     = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
 
   /* Define both `signed char' and `unsigned char'.  */
-  record_builtin_type (CP_RID_MAX, "signed char", signed_char_type_node);
-  record_builtin_type (CP_RID_MAX, "unsigned char", unsigned_char_type_node);
+  record_builtin_type (RID_MAX, "signed char", signed_char_type_node);
+  record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node);
 
   /* `unsigned long' is the standard type for sizeof.
      Note that stddef.h uses `unsigned long',
@@ -6425,7 +6635,7 @@ init_decl_processing ()
   signed_size_zero_node = build_int_2 (0, 0);
   record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node);
   record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node);
-  record_builtin_type (CP_RID_MAX, "long double", long_double_type_node);
+  record_builtin_type (RID_MAX, "long double", long_double_type_node);
 
   pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
                        complex_integer_type_node));
@@ -6442,17 +6652,13 @@ init_decl_processing ()
   void_list_node = build_tree_list (NULL_TREE, void_type_node);
   TREE_PARMLIST (void_list_node) = 1;
 
-  /* Used for expressions that do nothing, but are not errors.  */
-  void_zero_node = build_int_2 (0, 0);
-  TREE_TYPE (void_zero_node) = void_type_node;
-
   string_type_node = build_pointer_type (char_type_node);
   const_string_type_node
     = build_pointer_type (build_qualified_type (char_type_node,
                                                TYPE_QUAL_CONST));
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
 #if 0
-  record_builtin_type (CP_RID_MAX, NULL_PTR, string_type_node);
+  record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
 #endif
 
   /* Make a type to be the domain of a few array types
@@ -6567,16 +6773,16 @@ init_decl_processing ()
       vtable_entry_type = build_qualified_type (vtable_entry_type,
                                                TYPE_QUAL_CONST);
     }
-  record_builtin_type (CP_RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
+  record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
 
   vtbl_type_node
     = build_cplus_array_type (vtable_entry_type, NULL_TREE);
   layout_type (vtbl_type_node);
   vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
-  record_builtin_type (CP_RID_MAX, NULL_PTR, vtbl_type_node);
+  record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node);
   vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
   layout_type (vtbl_ptr_type_node);
-  record_builtin_type (CP_RID_MAX, NULL_PTR, vtbl_ptr_type_node);
+  record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node);
 
   std_node = build_decl (NAMESPACE_DECL,
                         flag_honor_std 
@@ -6634,6 +6840,10 @@ init_decl_processing ()
     flag_weak = 0;
 
   /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__.  */
+  function_id_node = get_identifier ("__FUNCTION__");
+  pretty_function_id_node = get_identifier ("__PRETTY_FUNCTION__");
+  func_id_node = get_identifier ("__func__");
+
   make_fname_decl = cp_make_fname_decl;
   declare_function_name ();
 
@@ -6643,7 +6853,6 @@ init_decl_processing ()
   /* Show we use EH for cleanups.  */
   using_eh_for_cleanups ();
 
-  print_error_function = lang_print_error_function;
   valid_lang_attribute = cp_valid_lang_attribute;
 
   /* Maintain consistency.  Perhaps we should just complain if they
@@ -6737,16 +6946,6 @@ cp_make_fname_decl (id, name, type_dep)
   return decl;
 }
 
-/* Function to print any language-specific context for an error message.  */
-
-static void
-lang_print_error_function (file)
-     const char *file;
-{
-  default_print_error_function (file);
-  maybe_print_template_context ();
-}
-
 /* Entry point for the benefit of c_common_nodes_and_builtins.
 
    Make a definition for a builtin function named NAME and whose data type
@@ -7940,15 +8139,12 @@ initialize_local_var (decl, init, flags)
        {
          int saved_stmts_are_full_exprs_p;
 
-         emit_line_note (DECL_SOURCE_FILE (decl),
-                         DECL_SOURCE_LINE (decl));
+         my_friendly_assert (building_stmt_tree (), 20000906);
          saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
-         current_stmt_tree->stmts_are_full_exprs_p = 1;
-         if (building_stmt_tree ())
-           finish_expr_stmt (build_aggr_init (decl, init, flags));
-         else
-           genrtl_expr_stmt (build_aggr_init (decl, init, flags));
-         current_stmt_tree->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
+         current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+         finish_expr_stmt (build_aggr_init (decl, init, flags));
+         current_stmt_tree ()->stmts_are_full_exprs_p = 
+           saved_stmts_are_full_exprs_p;
        }
 
       /* Set this to 0 so we can tell whether an aggregate which was
@@ -8063,7 +8259,9 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
     return;
   
   /* Add this declaration to the statement-tree.  */
-  if (building_stmt_tree () && at_function_scope_p ())
+  if (building_stmt_tree () 
+      && at_function_scope_p ()
+      && TREE_CODE (decl) != RESULT_DECL)
     add_decl_stmt (decl);
 
   if (TYPE_HAS_MUTABLE_P (type))
@@ -8186,8 +8384,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
            {
              /* If we're not building RTL, then we need to do so
                 now.  */
-             if (!building_stmt_tree ())
-               emit_local_var (decl);
+             my_friendly_assert (building_stmt_tree (), 20000906);
              /* Initialize the variable.  */
              initialize_local_var (decl, init, flags);
              /* Clean up the variable.  */
@@ -8705,11 +8902,11 @@ member_function_or_else (ctype, cur_type, flags)
   if (ctype && ctype != cur_type)
     {
       if (flags == DTOR_FLAG)
-       error ("destructor for alien class `%s' cannot be a member",
-              TYPE_NAME_STRING (ctype));
+       cp_error ("destructor for alien class `%T' cannot be a member",
+                 ctype);
       else
-       error ("constructor for alien class `%s' cannot be a member",
-              TYPE_NAME_STRING (ctype));
+       cp_error ("constructor for alien class `%T' cannot be a member",
+                 ctype);
       return 0;
     }
   return 1;
@@ -8822,8 +9019,11 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
        error ("cannot declare `::main' to be a template");
       if (inlinep)
        error ("cannot declare `::main' to be inline");
-      else if (! publicp)
+      if (!publicp)
        error ("cannot declare `::main' to be static");
+      if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
+                       integer_type_node))
+       error ("`main' must return `int'");
       inlinep = 0;
       publicp = 1;
     }
@@ -9796,7 +9996,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
            next = 0;
 
-           if (is_rid (dname))
+           if (C_IS_RESERVED_WORD (dname))
              {
                cp_error ("declarator-id missing; using reserved word `%D'",
                          dname);
@@ -9840,7 +10040,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                       && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
                ctype = cname;
              else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
-                      || TREE_CODE (cname) == TEMPLATE_TEMPLATE_PARM)
+                      || TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
                {
                  cp_error ("`%T::%D' is not a valid declarator", cname,
                            TREE_OPERAND (decl, 1));
@@ -11220,6 +11420,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              cp_error ("`inline' specified for friend class declaration");
              inlinep = 0;
            }
+         if (!current_aggr && TREE_CODE (type) != TYPENAME_TYPE)
+           {
+             if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+               cp_error ("template parameters cannot be friends");
+             else
+               cp_error ("friend declaration requires `%#T'", type);
+           }
 
          /* Only try to do this stuff if we didn't already give up.  */
          if (type != integer_type_node)
@@ -11228,8 +11435,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
              if (current_class_type)
                make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
              else
-               error ("trying to make class `%s' a friend of global scope",
-                      TYPE_NAME_STRING (type));
+               cp_error ("trying to make class `%T' a friend of global scope",
+                         type);
              type = void_type_node;
            }
        }
@@ -11906,7 +12113,8 @@ check_default_argument (decl, arg)
 
      The keyword `this' shall not be used in a default argument of a
      member function.  */
-  var = walk_tree (&arg, local_variable_p_walkfn, NULL);
+  var = walk_tree_without_duplicates (&arg, local_variable_p_walkfn, 
+                                     NULL);
   if (var)
     {
       cp_error ("default argument `%E' uses local variable `%D'",
@@ -12421,7 +12629,7 @@ grok_op_properties (decl, virtualp, friendp)
                    if (IS_AGGR_TYPE (arg)
                        || TREE_CODE (arg) == ENUMERAL_TYPE
                        || TREE_CODE (arg) == TEMPLATE_TYPE_PARM
-                       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+                       || TREE_CODE (arg) == BOUND_TEMPLATE_TEMPLATE_PARM)
                      goto foundaggr;
                  }
              cp_error
@@ -12728,7 +12936,7 @@ xref_tag (code_type_node, name, globalize)
     t = IDENTIFIER_TYPE_VALUE (name);
 
   if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
-      && TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM)
+      && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
     t = NULL_TREE;
 
   if (! globalize)
@@ -12974,7 +13182,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
          || (TREE_CODE (basetype) != RECORD_TYPE
              && TREE_CODE (basetype) != TYPENAME_TYPE
              && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
-             && TREE_CODE (basetype) != TEMPLATE_TEMPLATE_PARM))
+             && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
        {
          cp_error ("base type `%T' fails to be a struct or class type",
                    TREE_VALUE (binfo));
@@ -13210,7 +13418,7 @@ finish_enum (enumtype)
     {
       tree scope = current_scope ();
       if (scope && TREE_CODE (scope) == FUNCTION_DECL)
-       add_tree (build_min (TAG_DEFN, enumtype));
+       add_stmt (build_min (TAG_DEFN, enumtype));
     }
   else
     {
@@ -13575,7 +13783,7 @@ start_function (declspecs, declarator, attrs, flags)
   if (flags & SF_INCLASS_INLINE)
     maybe_begin_member_template_processing (decl1);
 
-  /* Effective C++ rule 15.  See also c_expand_return.  */
+  /* Effective C++ rule 15.  */
   if (warn_ecpp
       && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
       && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
@@ -13798,10 +14006,11 @@ start_function (declspecs, declarator, attrs, flags)
     cplus_decl_attributes (decl1, NULL_TREE, attrs);
 
   if (!building_stmt_tree ())
-    {
-      GNU_xref_function (decl1, current_function_parms);
-      make_function_rtl (decl1);
-    }
+    GNU_xref_function (decl1, current_function_parms);
+
+  /* We need to do this even if we aren't expanding yet so that
+     assemble_external works.  */
+  make_function_rtl (decl1);
 
   /* Promote the value to int before returning it.  */
   if (C_PROMOTING_INTEGER_TYPE_P (restype))
@@ -13993,31 +14202,6 @@ store_parm_decls ()
     current_eh_spec_try_block = expand_start_eh_spec ();
 }
 
-/* Bind a name and initialization to the return value of
-   the current function.  */
-
-void
-store_return_init (decl)
-     tree decl;
-{
-  /* If this named return value comes in a register, put it in a
-     pseudo-register.  */
-  if (DECL_REGISTER (decl))
-    {
-      original_result_rtx = DECL_RTL (decl);
-      /* Note that the mode of the old DECL_RTL may be wider than the
-        mode of DECL_RESULT, depending on the calling conventions for
-        the processor.  For example, on the Alpha, a 32-bit integer
-        is returned in a DImode register -- the DECL_RESULT has
-        SImode but the DECL_RTL for the DECL_RESULT has DImode.  So,
-        here, we use the mode the back-end has already assigned for
-        the return value.  */
-      DECL_RTL (decl) = gen_reg_rtx (GET_MODE (original_result_rtx));
-      if (TREE_ADDRESSABLE (decl))
-       put_var_into_stack (decl);
-    }
-}
-
 \f
 /* We have finished doing semantic analysis on DECL, but have not yet
    generated RTL for its body.  Save away our current state, so that
@@ -14027,7 +14211,7 @@ static void
 save_function_data (decl)
      tree decl;
 {
-  struct language_function *f;
+  struct cp_language_function *f;
 
   /* Save the language-specific per-function data so that we can
      get it back when we really expand this function.  */
@@ -14035,15 +14219,15 @@ save_function_data (decl)
                      19990908);
 
   /* Make a copy.  */
-  f = ((struct language_function *)
-       xmalloc (sizeof (struct language_function)));
+  f = ((struct cp_language_function *)
+       xmalloc (sizeof (struct cp_language_function)));
   bcopy ((char *) cp_function_chain, (char *) f,
-        sizeof (struct language_function));
+        sizeof (struct cp_language_function));
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
-  f->x_stmt_tree.x_last_stmt = NULL_TREE;
-  f->x_stmt_tree.x_last_expr_type = NULL_TREE;
+  f->base.x_stmt_tree.x_last_stmt = NULL_TREE;
+  f->base.x_stmt_tree.x_last_expr_type = NULL_TREE;
   f->x_result_rtx = NULL_RTX;
   f->x_named_label_uses = NULL;
   f->bindings = NULL;
@@ -14065,7 +14249,7 @@ finish_constructor_body ()
 {
   /* Any return from a constructor will end up here.  */
   if (ctor_label)
-    add_tree (build_stmt (LABEL_STMT, ctor_label));
+    add_stmt (build_stmt (LABEL_STMT, ctor_label));
 
   /* Clear CTOR_LABEL so that finish_return_stmt knows to really
      generate the return, rather than a goto to CTOR_LABEL.  */
@@ -14074,7 +14258,7 @@ finish_constructor_body ()
      constructor to a return of `this'.  */
   finish_return_stmt (NULL_TREE);
   /* Mark the end of the constructor.  */
-  add_tree (build_stmt (CTOR_STMT));
+  add_stmt (build_stmt (CTOR_STMT));
 }
 
 /* At the end of every destructor we generate code to restore virtual
@@ -14093,7 +14277,7 @@ finish_destructor_body ()
   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
 
   /* Any return from a destructor will end up here.  */
-  add_tree (build_stmt (LABEL_STMT, dtor_label));
+  add_stmt (build_stmt (LABEL_STMT, dtor_label));
 
   /* Generate the code to call destructor on base class.  If this
      destructor belongs to a class with virtual functions, then set
@@ -14469,6 +14653,18 @@ finish_function (flags)
        note_debug_info_needed (ctype);
 #endif
 
+      /* If this function is marked with the constructor attribute,
+        add it to the list of functions to be called along with
+        constructors from static duration objects.  */
+      if (DECL_STATIC_CONSTRUCTOR (fndecl))
+       static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
+
+      /* If this function is marked with the destructor attribute,
+        add it to the list of functions to be called along with
+        destructors from static duration objects.  */
+      if (DECL_STATIC_DESTRUCTOR (fndecl))
+       static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
+
       if (DECL_NAME (DECL_RESULT (fndecl)))
        returns_value |= can_reach_end;
       else
@@ -14524,11 +14720,6 @@ finish_function (flags)
        DECL_RTL (t) = DECL_INCOMING_RTL (t) = NULL_RTX;
     }
 
-  if (DECL_STATIC_CONSTRUCTOR (fndecl))
-    static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
-  if (DECL_STATIC_DESTRUCTOR (fndecl))
-    static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
-
   /* Clean up.  */
   if (! nested)
     {
@@ -14590,8 +14781,8 @@ start_method (declspecs, declarator, attrlist)
        {
          if (DECL_CONTEXT (fndecl)
              && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
-           cp_error ("`%D' is already defined in class %s", fndecl,
-                            TYPE_NAME_STRING (DECL_CONTEXT (fndecl)));
+           cp_error ("`%D' is already defined in class `%T'", fndecl,
+                     DECL_CONTEXT (fndecl));
        }
       return void_type_node;
     }
@@ -14879,10 +15070,10 @@ static void
 push_cp_function_context (f)
      struct function *f;
 {
-  struct language_function *p
-    = ((struct language_function *)
-       xcalloc (1, sizeof (struct language_function)));
-  f->language = p;
+  struct cp_language_function *p
+    = ((struct cp_language_function *)
+       xcalloc (1, sizeof (struct cp_language_function)));
+  f->language = (struct language_function *) p;
 
   /* It takes an explicit call to expand_body to generate RTL for a
      function.  */
@@ -14890,7 +15081,7 @@ push_cp_function_context (f)
 
   /* Whenever we start a new function, we destroy temporaries in the
      usual way.  */
-  current_stmt_tree->stmts_are_full_exprs_p = 1;
+  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
 }
 
 /* Free the language-specific parts of F, now that we've finished
@@ -14909,7 +15100,7 @@ pop_cp_function_context (f)
 
 static void
 mark_lang_function (p)
-     struct language_function *p;
+     struct cp_language_function *p;
 {
   if (!p)
     return;
@@ -14924,7 +15115,7 @@ mark_lang_function (p)
   ggc_mark_rtx (p->x_result_rtx);
 
   mark_named_label_lists (&p->x_named_labels, &p->x_named_label_uses);
-  mark_stmt_tree (&p->x_stmt_tree);
+  mark_stmt_tree (&p->base.x_stmt_tree);
   mark_binding_level (&p->bindings);
 }
 
@@ -14934,7 +15125,7 @@ static void
 mark_cp_function_context (f)
      struct function *f;
 {
-  mark_lang_function (f->language);
+  mark_lang_function ((struct cp_language_function *) f->language);
 }
 
 void
This page took 0.061388 seconds and 5 git commands to generate.