OSDN Git Service

2005-10-20 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 91d76ba..2431877 100644 (file)
@@ -1542,6 +1542,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        {
          DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
          DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
+         DECL_NONTRIVIALLY_INITIALIZED_P (newdecl) 
+           |= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl);
          DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
            |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
        }
@@ -2148,16 +2150,15 @@ decl_jump_unsafe (tree decl)
   if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
     return 0;
 
-  if (DECL_INITIAL (decl) == NULL_TREE
-      && pod_type_p (TREE_TYPE (decl)))
+  if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
+      || DECL_NONTRIVIALLY_INITIALIZED_P (decl))
+    return 2;
+
+  if (pod_type_p (TREE_TYPE (decl)))
     return 0;
 
-  /* This is really only important if we're crossing an initialization.
-     The POD stuff is just pedantry; why should it matter if the class
+  /* The POD stuff is just pedantry; why should it matter if the class
      contains a field of pointer to member type?  */
-  if (DECL_INITIAL (decl)
-      || (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
-    return 2;
   return 1;
 }
 
@@ -2414,9 +2415,10 @@ pop_switch (void)
     switch_location = EXPR_LOCATION (cs->switch_stmt);
   else
     switch_location = input_location;
-  c_do_switch_warnings (cs->cases, switch_location,
-                       SWITCH_STMT_TYPE (cs->switch_stmt),
-                       SWITCH_STMT_COND (cs->switch_stmt));
+  if (!processing_template_decl)
+    c_do_switch_warnings (cs->cases, switch_location,
+                         SWITCH_STMT_TYPE (cs->switch_stmt),
+                         SWITCH_STMT_COND (cs->switch_stmt));
 
   splay_tree_delete (cs->cases);
   switch_stack = switch_stack->next;
@@ -4932,6 +4934,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
             is *not* defined.  */
          && (!DECL_EXTERNAL (decl) || init))
        {
+         if (init)
+           DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
          init = check_initializer (decl, init, flags, &cleanup);
          /* Thread-local storage cannot be dynamically initialized.  */
          if (DECL_THREAD_LOCAL_P (decl) && init)
@@ -7566,7 +7570,7 @@ grokdeclarator (const cp_declarator *declarator,
        }
 
       if (ctype == current_class_type)
-       pedwarn ("extra qualification %<%T::%> on member %qs ignored",
+       pedwarn ("extra qualification %<%T::%> on member %qs",
                 ctype, name);
       else if (TREE_CODE (type) == FUNCTION_TYPE)
        {
@@ -8017,15 +8021,25 @@ grokdeclarator (const cp_declarator *declarator,
              }
 
            /* Check that the name used for a destructor makes sense.  */
-           if (sfk == sfk_destructor
-               && !same_type_p (TREE_OPERAND
-                                (id_declarator->u.id.unqualified_name, 0),
-                                ctype))
+           if (sfk == sfk_destructor)
              {
-               error ("declaration of %qD as member of %qT",
-                      id_declarator->u.id.unqualified_name,
-                      ctype);
-               return error_mark_node;
+               if (!ctype)
+                 {
+                   gcc_assert (friendp);
+                   error ("expected qualified name in friend declaration "
+                          "for destructor %qD",
+                          id_declarator->u.id.unqualified_name);
+                   return error_mark_node;
+                 }
+
+               if (!same_type_p (TREE_OPERAND
+                                 (id_declarator->u.id.unqualified_name, 0),
+                                 ctype))
+                 {
+                   error ("declaration of %qD as member of %qT",
+                          id_declarator->u.id.unqualified_name, ctype);
+                   return error_mark_node;
+                 }
              }
 
            /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
@@ -8449,13 +8463,6 @@ check_default_argument (tree decl, tree arg)
        deal with it after the class is complete.  */
     return arg;
 
-  if (processing_template_decl || uses_template_parms (arg))
-    /* We don't do anything checking until instantiation-time.  Note
-       that there may be uninstantiated arguments even for an
-       instantiated function, since default arguments are not
-       instantiated until they are needed.  */
-    return arg;
-
   if (TYPE_P (decl))
     {
       decl_type = decl;
@@ -8597,10 +8604,10 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms)
                       decl, ptr ? "pointer" : "reference", t);
            }
 
-         if (!any_error && init)
-           init = check_default_argument (decl, init);
-         else
+         if (any_error)
            init = NULL_TREE;
+         else if (init && !processing_template_decl)
+           init = check_default_argument (decl, init);
        }
 
       TREE_CHAIN (decl) = decls;
@@ -9747,6 +9754,8 @@ finish_enum (tree enumtype)
 
          /* Update the minimum and maximum values, if appropriate.  */
          value = DECL_INITIAL (decl);
+         if (value == error_mark_node)
+           value = integer_zero_node;
          /* Figure out what the minimum and maximum values of the
             enumerators are.  */
          if (!minnode)
@@ -9849,9 +9858,14 @@ finish_enum (tree enumtype)
      type of the enumeration.  */
   for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
     {
+      location_t saved_location;
+
       decl = TREE_VALUE (values);
+      saved_location = input_location;
+      input_location = DECL_SOURCE_LOCATION (decl);
       value = perform_implicit_conversion (underlying_type,
                                           DECL_INITIAL (decl));
+      input_location = saved_location;
 
       /* Do not clobber shared ints.  */
       value = copy_node (value);
@@ -9941,7 +9955,10 @@ build_enumerator (tree name, tree value, tree enumtype)
              overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value));
 
              if (overflowed)
-               error ("overflow in enumeration values at %qD", name);
+               {
+                 error ("overflow in enumeration values at %qD", name);
+                 value = error_mark_node;
+               }
            }
          else
            value = integer_zero_node;
@@ -10012,25 +10029,20 @@ check_function_type (tree decl, tree current_function_parms)
     return;
   if (!COMPLETE_OR_VOID_TYPE_P (return_type))
     {
-      error ("return type %q#T is incomplete", TREE_TYPE (fntype));
+      tree args = TYPE_ARG_TYPES (fntype);
+         
+      error ("return type %q#T is incomplete", return_type);
 
-      /* Make it return void instead, but don't change the
-        type of the DECL_RESULT, in case we have a named return value.  */
+      /* Make it return void instead.  */
       if (TREE_CODE (fntype) == METHOD_TYPE)
-       {
-         tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)));
-         TREE_TYPE (decl)
-           = build_method_type_directly (ctype,
-                                         void_type_node,
-                                         FUNCTION_ARG_CHAIN (decl));
-       }
+       fntype = build_method_type_directly (TREE_TYPE (TREE_VALUE (args)),
+                                            void_type_node,
+                                            TREE_CHAIN (args));
       else
-       TREE_TYPE (decl)
-         = build_function_type (void_type_node,
-                                TYPE_ARG_TYPES (TREE_TYPE (decl)));
+       fntype = build_function_type (void_type_node, args);
       TREE_TYPE (decl)
        = build_exception_variant (fntype,
-                                  TYPE_RAISES_EXCEPTIONS (fntype));
+                                  TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)));
     }
   else
     abstract_virtuals_error (decl, TREE_TYPE (fntype));
@@ -10991,7 +11003,7 @@ start_method (cp_decl_specifier_seq *declspecs,
          && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
        error ("%qD is already defined in class %qT", fndecl,
               DECL_CONTEXT (fndecl));
-      return void_type_node;
+      return error_mark_node;
     }
 
   check_template_shadow (fndecl);