OSDN Git Service

Fixup whitespace a litte
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index ef7ed3a..21ef001 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -361,8 +361,8 @@ pop_label (tree label, tree old_value)
          /* Avoid crashing later.  */
          define_label (location, DECL_NAME (label));
        }
-      else if (warn_unused_label && !TREE_USED (label))
-       warning (0, "label %q+D defined but not used", label);
+      else if (!TREE_USED (label))
+       warning (OPT_Wunused_label, "label %q+D defined but not used", label);
     }
 
   SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), old_value);
@@ -556,7 +556,7 @@ poplevel (int keep, int reverse, int functionbody)
          && ! TREE_USED (decl)
          && ! DECL_IN_SYSTEM_HEADER (decl)
          && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
-       warning (0, "unused variable %q+D", decl);
+       warning (OPT_Wunused_variable, "unused variable %q+D", decl);
 
   /* Remove declarations for all the DECLs in this level.  */
   for (link = decls; link; link = TREE_CHAIN (link))
@@ -1119,10 +1119,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
             bad choice of name.  */
          if (! TREE_PUBLIC (newdecl))
            {
-             if (warn_shadow)
-               warning (0, "shadowing %s function %q#D",
-                        DECL_BUILT_IN (olddecl) ? "built-in" : "library",
-                        olddecl);
+             warning (OPT_Wshadow, "shadowing %s function %q#D",
+                      DECL_BUILT_IN (olddecl) ? "built-in" : "library",
+                      olddecl);
              /* Discard the old built-in function.  */
              return NULL_TREE;
            }
@@ -1192,8 +1191,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
                  warning (0, "ambiguates built-in declaration %q#D",
                           olddecl);
                }
-             else if (warn_shadow)
-               warning (0, "shadowing %s function %q#D",
+             else
+               warning (OPT_Wshadow, "shadowing %s function %q#D",
                         DECL_BUILT_IN (olddecl) ? "built-in" : "library",
                         olddecl);
            }
@@ -1504,8 +1503,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
          /* Don't warn about friends, let add_friend take care of it.  */
          && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl)))
        {
-         warning (0, "redundant redeclaration of %qD in same scope", newdecl);
-         warning (0, "previous declaration of %q+D", olddecl);
+         warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
+         warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
        }
     }
 
@@ -1977,7 +1976,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
         constructs like "typedef struct foo { ... } foo"
         would look like an erroneous redeclaration.  */
       if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
-       return 0;
+       return NULL;
       else
        return "redefinition of %q#D";
     }
@@ -1988,7 +1987,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
         abort()).  Don't complain about redefinition in this case.  */
       if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl)
          && DECL_INITIAL (olddecl) == NULL_TREE)
-       return 0;
+       return NULL;
 
       /* If both functions come from different namespaces, this is not
         a redeclaration - this is a conflict with a used function.  */
@@ -2009,7 +2008,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
          else
            return "redefinition of %q#D";
        }
-      return 0;
+      return NULL;
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
@@ -2056,7 +2055,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* Objects declared at top level:  */
       /* If at least one is a reference, it's ok.  */
       if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
-       return 0;
+       return NULL;
       /* Reject two definitions.  */
       return "redefinition of %q#D";
     }
@@ -2067,7 +2066,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
         together with an external reference.  */
       if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)))
        return "redeclaration of %q#D";
-      return 0;
+      return NULL;
     }
 }
 \f
@@ -2673,7 +2672,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
                                        TREE_OPERAND (fullname, 1),
                                        NULL_TREE, context,
                                        /*entering_scope=*/0,
-                                       tf_error | tf_warning | tf_user);
+                                       tf_warning_or_error | tf_user);
        }
       else
        {
@@ -3198,7 +3197,8 @@ cp_make_fname_decl (tree id, int type_dep)
       while (b->level_chain->kind != sk_function_parms)
        b = b->level_chain;
       pushdecl_with_scope (decl, b, /*is_friend=*/false);
-      cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+      cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE, 
+                     LOOKUP_ONLYCONVERTING);
     }
   else
     pushdecl_top_level_and_finish (decl, init);
@@ -4856,14 +4856,15 @@ initialize_artificial_var (tree decl, tree init)
    If the length of an array type is not known before,
    it must be determined now, from the initial value, or it is an error.
 
-   INIT holds the value of an initializer that should be allowed to escape
-   the normal rules.
+   INIT is the initializer (if any) for DECL.  If INIT_CONST_EXPR_P is
+   true, then INIT is an integral constant expression.
 
    FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
    if the (init) syntax was used.  */
 
 void
-cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
+cp_finish_decl (tree decl, tree init, bool init_const_expr_p, 
+               tree asmspec_tree, int flags)
 {
   tree type;
   tree cleanup;
@@ -4915,7 +4916,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
        add_decl_expr (decl);
 
       if (init && DECL_INITIAL (decl))
-       DECL_INITIAL (decl) = init;
+       {
+         DECL_INITIAL (decl) = init;
+         if (init_const_expr_p)
+           {
+             DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+             if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+               TREE_CONSTANT (decl) = 1;
+           }
+       }
+
       if (TREE_CODE (decl) == VAR_DECL
          && !DECL_PRETTY_FUNCTION_P (decl)
          && !dependent_type_p (TREE_TYPE (decl)))
@@ -4976,7 +4986,15 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          && (!DECL_EXTERNAL (decl) || init))
        {
          if (init)
-           DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+           {
+             DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+             if (init_const_expr_p)
+               {
+                 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+                 if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+                   TREE_CONSTANT (decl) = 1;
+               }
+           }
          init = check_initializer (decl, init, flags, &cleanup);
          /* Thread-local storage cannot be dynamically initialized.  */
          if (DECL_THREAD_LOCAL_P (decl) && init)
@@ -5128,7 +5146,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 void
 finish_decl (tree decl, tree init, tree asmspec_tree)
 {
-  cp_finish_decl (decl, init, asmspec_tree, 0);
+  cp_finish_decl (decl, init, /*init_const_expr_p=*/false, asmspec_tree, 0);
 }
 
 /* Returns a declaration for a VAR_DECL as if:
@@ -5153,7 +5171,7 @@ declare_global_var (tree name, tree type)
      library), then it is possible that our declaration will be merged
      with theirs by pushdecl.  */
   decl = pushdecl (decl);
-  cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
+  finish_decl (decl, NULL_TREE, NULL_TREE);
   pop_from_top_level ();
 
   return decl;
@@ -6275,9 +6293,13 @@ check_static_variable_definition (tree decl, tree type)
 tree
 compute_array_index_type (tree name, tree size)
 {
-  tree type = TREE_TYPE (size);
+  tree type;
   tree itype;
 
+  if (error_operand_p (size))
+    return error_mark_node;
+
+  type = TREE_TYPE (size);
   /* The array bound must be an integer type.  */
   if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
     {
@@ -6663,7 +6685,6 @@ grokdeclarator (const cp_declarator *declarator,
      this value will be NULL_TREE, even if the entity is located at
      namespace scope.  */
   tree in_namespace = NULL_TREE;
-  cp_decl_spec ds;
   cp_storage_class storage_class;
   bool unsigned_p, signed_p, short_p, long_p, thread_p;
   bool type_was_error_mark_node = false;
@@ -6672,6 +6693,7 @@ grokdeclarator (const cp_declarator *declarator,
   unsigned_p = declspecs->specs[(int)ds_unsigned];
   short_p = declspecs->specs[(int)ds_short];
   long_p = declspecs->specs[(int)ds_long];
+  longlong = declspecs->specs[(int)ds_long] >= 2;
   thread_p = declspecs->specs[(int)ds_thread];
 
   if (decl_context == FUNCDEF)
@@ -6746,6 +6768,7 @@ grokdeclarator (const cp_declarator *declarator,
 
                  type = TREE_OPERAND (decl, 0);
                  name = IDENTIFIER_POINTER (constructor_name (type));
+                 dname = decl;
                }
                break;
 
@@ -6815,7 +6838,7 @@ grokdeclarator (const cp_declarator *declarator,
      a function declarator.  */
 
   if (funcdef_flag && innermost_code != cdk_function)
-    return 0;
+    return NULL_TREE;
 
   if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
       && innermost_code != cdk_function
@@ -6884,45 +6907,6 @@ grokdeclarator (const cp_declarator *declarator,
   explicit_int = declspecs->explicit_int_p;
   explicit_char = declspecs->explicit_char_p;
 
-  /* Check for repeated decl-specifiers.  */
-  for (ds = ds_first; ds != ds_last; ++ds)
-    {
-      unsigned count = declspecs->specs[(int)ds];
-      if (count < 2)
-       continue;
-      /* The "long" specifier is a special case because of
-        "long long".  */
-      if (ds == ds_long)
-       {
-         if (count > 2)
-           error ("%<long long long%> is too long for GCC");
-         else if (pedantic && !in_system_header && warn_long_long)
-           pedwarn ("ISO C++ does not support %<long long%>");
-         else
-           longlong = 1;
-       }
-      else if (declspecs->specs[(int)ds] > 1)
-       {
-         static const char *const decl_spec_names[] = {
-           "signed",
-           "unsigned",
-           "short",
-           "long",
-           "const",
-           "volatile",
-           "restrict",
-           "inline",
-           "virtual",
-           "explicit",
-           "friend",
-           "typedef",
-           "__complex",
-           "__thread"
-         };
-         error ("duplicate %qs", decl_spec_names[(int)ds]);
-       }
-    }
-
 #if 0
   /* See the code below that used this.  */
   if (typedef_decl)
@@ -7036,8 +7020,7 @@ grokdeclarator (const cp_declarator *declarator,
             `signed int' cannot be so controlled.  */
          && !(typedef_decl
               && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))
-         && (TREE_CODE (type) == INTEGER_TYPE
-             || TREE_CODE (type) == CHAR_TYPE)
+         && TREE_CODE (type) == INTEGER_TYPE
          && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
     {
       if (longlong)
@@ -7114,7 +7097,7 @@ grokdeclarator (const cp_declarator *declarator,
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
     (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
-                        ? tf_ignore_bad_quals : 0) | tf_error | tf_warning));
+                        ? tf_ignore_bad_quals : 0) | tf_warning_or_error));
   /* We might have ignored or rejected some of the qualifiers.  */
   type_quals = cp_type_quals (type);
 
@@ -7130,6 +7113,7 @@ grokdeclarator (const cp_declarator *declarator,
   if (virtualp && staticp == 2)
     {
       error ("member %qD cannot be declared both virtual and static", dname);
+      storage_class = sc_none;
       staticp = 0;
     }
   friendp = !! declspecs->specs[(int)ds_friend];
@@ -8734,7 +8718,7 @@ copy_fn_p (tree d)
 
 void grok_special_member_properties (tree decl)
 {
-  if (!DECL_NONSTATIC_MEMBER_FUNCTION_P(decl))
+  if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
     ; /* Not special.  */
   else if (DECL_CONSTRUCTOR_P (decl))
     {
@@ -8844,13 +8828,15 @@ grok_op_properties (tree decl, bool complain)
   tree name = DECL_NAME (decl);
   enum tree_code operator_code;
   int arity;
+  bool ellipsis_p;
   tree class_type;
 
-  /* Count the number of arguments.  */
+  /* Count the number of arguments and check for ellipsis.  */
   for (argtype = argtypes, arity = 0;
        argtype && argtype != void_list_node;
        argtype = TREE_CHAIN (argtype))
     ++arity;
+  ellipsis_p = !argtype;
 
   class_type = DECL_CONTEXT (decl);
   if (class_type && !CLASS_TYPE_P (class_type))
@@ -9012,15 +8998,18 @@ grok_op_properties (tree decl, bool complain)
            }
 
          if (what)
-           warning (0, "conversion to %s%s will never use a type "
+           warning (OPT_Wconversion, "conversion to %s%s will never use a type "
                     "conversion operator",
                     ref ? "a reference to " : "", what);
        }
+
       if (operator_code == COND_EXPR)
        {
          /* 13.4.0.3 */
          error ("ISO C++ prohibits overloading operator ?:");
        }
+      else if (ellipsis_p)
+       error ("%qD must not have variable number of arguments", decl);
       else if (ambi_op_p (operator_code))
        {
          if (arity == 1)
@@ -9103,13 +9092,13 @@ grok_op_properties (tree decl, bool complain)
                  if (TREE_CODE (ret) != REFERENCE_TYPE
                      || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
                                       arg))
-                   warning (0, "prefix %qD should return %qT", decl,
+                   warning (OPT_Weffc__, "prefix %qD should return %qT", decl,
                             build_reference_type (arg));
                }
              else
                {
                  if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg))
-                   warning (0, "postfix %qD should return %qT", decl, arg);
+                   warning (OPT_Weffc__, "postfix %qD should return %qT", decl, arg);
                }
            }
        }
@@ -9138,7 +9127,7 @@ grok_op_properties (tree decl, bool complain)
              && (operator_code == TRUTH_ANDIF_EXPR
                  || operator_code == TRUTH_ORIF_EXPR
                  || operator_code == COMPOUND_EXPR))
-           warning (0, "user-defined %qD always evaluates both arguments",
+           warning (OPT_Weffc__, "user-defined %qD always evaluates both arguments",
                     decl);
        }
 
@@ -9152,7 +9141,7 @@ grok_op_properties (tree decl, bool complain)
              || operator_code == MULT_EXPR
              || operator_code == TRUNC_MOD_EXPR)
          && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE)
-       warning (0, "%qD should return by value", decl);
+       warning (OPT_Weffc__, "%qD should return by value", decl);
 
       /* [over.oper]/8 */
       for (; argtypes && argtypes != void_list_node;
@@ -10183,7 +10172,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
   if (warn_ecpp
       && DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
       && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
-    warning (0, "%<operator=%> should return a reference to %<*this%>");
+    warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>");
 
   /* Make the init_value nonzero so pushdecl knows this is not tentative.
      error_mark_node is replaced below (in poplevel) with the BLOCK.  */
@@ -10940,7 +10929,7 @@ finish_function (int flags)
       /* Structor return values (if any) are set by the compiler.  */
       && !DECL_CONSTRUCTOR_P (fndecl)
       && !DECL_DESTRUCTOR_P (fndecl))
-    warning (0, "no return statement in function returning non-void");
+    warning (OPT_Wreturn_type, "no return statement in function returning non-void");
 
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
@@ -11042,7 +11031,7 @@ start_method (cp_decl_specifier_seq *declspecs,
   if (DECL_IN_AGGR_P (fndecl))
     {
       if (DECL_CONTEXT (fndecl)
-         && TREE_CODEDECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
+         && TREE_CODE (DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
        error ("%qD is already defined in class %qT", fndecl,
               DECL_CONTEXT (fndecl));
       return error_mark_node;
@@ -11072,7 +11061,7 @@ start_method (cp_decl_specifier_seq *declspecs,
       grok_special_member_properties (fndecl);
     }
 
-  cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
+  finish_decl (fndecl, NULL_TREE, NULL_TREE);
 
   /* Make a place for the parms.  */
   begin_scope (sk_function_parms, fndecl);