OSDN Git Service

PR c++/20073
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl.c
index 07d8543..a224efc 100644 (file)
@@ -61,10 +61,6 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, tree *);
-static tree grokfndecl (tree, tree, tree, tree, tree, int,
-                       enum overload_flags, cp_cv_quals,
-                       tree, int, int, int, int, int, int, tree, 
-                       tree *);
 static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
                         int, int, tree);
 static void record_unknown_type (tree, const char *);
@@ -84,8 +80,6 @@ static tree record_builtin_java_type (const char *, int);
 static const char *tag_name (enum tag_types);
 static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
 static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
-static int walk_globals_r (tree, void*);
-static int walk_vtables_r (tree, void*);
 static tree make_label_decl (tree, int);
 static void use_label (tree);
 static void check_previous_goto_1 (tree, struct cp_binding_level *, tree,
@@ -746,29 +740,6 @@ poplevel (int keep, int reverse, int functionbody)
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);
 }
 
-/* Delete the node BLOCK from the current binding level.
-   This is used for the block inside a stmt expr ({...})
-   so that the block can be reinserted where appropriate.  */
-
-void
-delete_block (tree block)
-{
-  tree t;
-  if (current_binding_level->blocks == block)
-    current_binding_level->blocks = TREE_CHAIN (block);
-  for (t = current_binding_level->blocks; t;)
-    {
-      if (TREE_CHAIN (t) == block)
-       TREE_CHAIN (t) = TREE_CHAIN (block);
-      else
-       t = TREE_CHAIN (t);
-    }
-  TREE_CHAIN (block) = NULL_TREE;
-  /* Clear TREE_USED which is always set by poplevel.
-     The flag is set again if insert_block is called.  */
-  TREE_USED (block) = 0;
-}
-
 /* Insert BLOCK at the end of the list of subblocks of the
    current binding level.  This is used when a BIND_EXPR is expanded,
    to handle the BLOCK node inside the BIND_EXPR.  */
@@ -781,64 +752,6 @@ insert_block (tree block)
     = chainon (current_binding_level->blocks, block);
 }
 
-/* Returns nonzero if T is a virtual function table.  */
-
-int
-vtable_decl_p (tree t, void* data ATTRIBUTE_UNUSED )
-{
-  return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t));
-}
-
-/* Returns nonzero if T is a TYPE_DECL for a type with virtual
-   functions.  */
-
-int
-vtype_decl_p (tree t, void *data ATTRIBUTE_UNUSED )
-{
-  return (TREE_CODE (t) == TYPE_DECL
-         && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
-         && TYPE_POLYMORPHIC_P (TREE_TYPE (t)));
-}
-
-struct walk_globals_data {
-  walk_globals_pred p;
-  walk_globals_fn f;
-  void *data;
-};
-
-/* Walk the vtable declarations in NAMESPACE.  Whenever one is found
-   for which P returns nonzero, call F with its address.  If any call
-   to F returns a nonzero value, return a nonzero value.  */
-
-static int
-walk_vtables_r (tree namespace, void* data)
-{
-  struct walk_globals_data* wgd = (struct walk_globals_data *) data;
-  walk_globals_fn f = wgd->f;
-  void *d = wgd->data;
-  tree decl = NAMESPACE_LEVEL (namespace)->vtables;
-  int result = 0;
-
-  for (; decl ; decl = TREE_CHAIN (decl))
-    result |= (*f) (&decl, d);
-
-  return result;
-}
-
-/* Walk the vtable declarations.  Whenever one is found for which P
-   returns nonzero, call F with its address.  If any call to F
-   returns a nonzero value, return a nonzero value.  */
-bool
-walk_vtables (walk_globals_pred p, walk_globals_fn f, void *data)
-{
-  struct walk_globals_data wgd;
-  wgd.p = p;
-  wgd.f = f;
-  wgd.data = data;
-
-  return walk_namespaces (walk_vtables_r, &wgd);
-}
-
 /* Walk all the namespaces contained NAMESPACE, including NAMESPACE
    itself, calling F for each.  The DATA is passed to F as well.  */
 
@@ -865,53 +778,6 @@ walk_namespaces (walk_namespaces_fn f, void* data)
   return walk_namespaces_r (global_namespace, f, data);
 }
 
-/* Walk the global declarations in NAMESPACE.  Whenever one is found
-   for which P returns nonzero, call F with its address.  If any call
-   to F returns a nonzero value, return a nonzero value.  */
-
-static int
-walk_globals_r (tree namespace, void* data)
-{
-  struct walk_globals_data* wgd = (struct walk_globals_data *) data;
-  walk_globals_pred p = wgd->p;
-  walk_globals_fn f = wgd->f;
-  void *d = wgd->data;
-  tree *t;
-  int result = 0;
-
-  t = &NAMESPACE_LEVEL (namespace)->names;
-
-  while (*t)
-    {
-      tree glbl = *t;
-
-      if ((*p) (glbl, d))
-       result |= (*f) (t, d);
-
-      /* If F changed *T, then *T still points at the next item to
-        examine.  */
-      if (*t == glbl)
-       t = &TREE_CHAIN (*t);
-    }
-
-  return result;
-}
-
-/* Walk the global declarations.  Whenever one is found for which P
-   returns true, call F with its address.  If any call to F
-   returns true, return true.  */
-
-bool
-walk_globals (walk_globals_pred p, walk_globals_fn f, void *data)
-{
-  struct walk_globals_data wgd;
-  wgd.p = p;
-  wgd.f = f;
-  wgd.data = data;
-
-  return walk_namespaces (walk_globals_r, &wgd);
-}
-
 /* Call wrapup_globals_declarations for the globals in NAMESPACE.  If
    DATA is non-NULL, this is the last time we will call
    wrapup_global_declarations for this NAMESPACE.  */
@@ -1803,6 +1669,13 @@ duplicate_decls (tree newdecl, tree olddecl)
       DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
       DECL_TEMPLATE_INSTANTIATED (newdecl)
        |= DECL_TEMPLATE_INSTANTIATED (olddecl);
+      /* If the OLDDECL is an implicit instantiation, then the NEWDECL
+        must be too.  But, it may not yet be marked as such if the
+        caller has created NEWDECL, but has not yet figured out that
+        it is a redeclaration.  */
+      if (DECL_IMPLICIT_INSTANTIATION (olddecl)
+         && !DECL_USE_TEMPLATE (newdecl))
+       SET_DECL_IMPLICIT_INSTANTIATION (newdecl);
       /* Don't really know how much of the language-specific
         values we should copy from old to new.  */
       DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
@@ -2040,7 +1913,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* If this is a pure function, its olddecl will actually be
         the original initialization to `0' (which we force to call
         abort()).  Don't complain about redefinition in this case.  */
-      if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl))
+      if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl)
+         && DECL_INITIAL (olddecl) == NULL_TREE)
        return 0;
 
       /* If both functions come from different namespaces, this is not
@@ -2517,7 +2391,7 @@ finish_case_label (tree low_value, tree high_value)
     }
 
   /* Find the condition on which this switch statement depends.  */
-  cond = SWITCH_COND (switch_stack->switch_stmt);
+  cond = SWITCH_STMT_COND (switch_stack->switch_stmt);
   if (cond && TREE_CODE (cond) == TREE_LIST)
     cond = TREE_VALUE (cond);
 
@@ -3832,7 +3706,12 @@ start_decl (const cp_declarator *declarator,
       if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
          || CLASSTYPE_TEMPLATE_INSTANTIATION (context))
        {
-         SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+         /* Do not mark DECL as an explicit specialization if it was
+            not already marked as an instantiation; a declaration
+            should never be marked as a specialization unless we know
+            what template is being specialized.  */ 
+         if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
+           SET_DECL_TEMPLATE_SPECIALIZATION (decl);
          /* [temp.expl.spec] An explicit specialization of a static data
             member of a template is a definition if the declaration
             includes an initializer; otherwise, it is a declaration.
@@ -4474,10 +4353,15 @@ reshape_init (tree type, tree *initp)
        new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);
     }
 
-  /* If this was a brace-enclosed initializer and all of the
-     initializers were not used up, there is a problem.  */
-  if (brace_enclosed_p && *initp)
-    error ("too many initializers for %qT", type);
+  /* If there are more initializers than necessary, issue a
+     diagnostic.  */  
+  if (*initp)
+    {
+      if (brace_enclosed_p)
+       error ("too many initializers for %qT", type);
+      else if (warn_missing_braces)
+       warning ("missing braces around initializer");
+    }
 
   return new_init;
 }
@@ -4865,9 +4749,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   if (type == error_mark_node)
     goto finish_end;
 
-  if (TYPE_HAS_MUTABLE_P (type))
-    TREE_READONLY (decl) = 0;
-
   if (processing_template_decl)
     {
       /* Add this declaration to the statement-tree.  */
@@ -4914,16 +4795,13 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
     ttype = target_type (type);
 
 
-  /* Currently, GNU C++ puts constants in text space, making them
-     impossible to initialize.  In the future, one would hope for
-     an operating system which understood the difference between
-     initialization and the running of a program.  */
-  if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
+  /* A reference will be modified here, as it is initialized.  */
+  if (! DECL_EXTERNAL (decl) 
+      && TREE_READONLY (decl)
+      && TREE_CODE (type) == REFERENCE_TYPE)
     {
       was_readonly = 1;
-      if (TYPE_NEEDS_CONSTRUCTING (type)
-         || TREE_CODE (type) == REFERENCE_TYPE)
-       TREE_READONLY (decl) = 0;
+      TREE_READONLY (decl) = 0;
     }
 
   if (TREE_CODE (decl) == VAR_DECL)
@@ -5616,6 +5494,8 @@ bad_specifiers (tree object,
    CHECK is 1 if we must find this method in CTYPE, 0 if we should
    not look, and -1 if we should not call `grokclassfn' at all.
 
+   SFK is the kind of special function (if any) for the new function.
+
    Returns `NULL_TREE' if something goes wrong, after issuing
    applicable error messages.  */
 
@@ -5633,6 +5513,7 @@ grokfndecl (tree ctype,
             int friendp,
             int publicp,
             int inlinep,
+           special_function_kind sfk,
             int funcdef_flag,
             int template_count,
             tree in_namespace,
@@ -5843,14 +5724,13 @@ grokfndecl (tree ctype,
   if (check < 0)
     return decl;
 
-  if (flags == NO_SPECIAL && ctype && constructor_name_p (declarator, ctype))
-    DECL_CONSTRUCTOR_P (decl) = 1;
-
-  /* Function gets the ugly name, field gets the nice one.  This call
-     may change the type of the function (because of default
-     parameters)!  */
   if (ctype != NULL_TREE)
-    grokclassfn (ctype, decl, flags, quals);
+    {
+      if (sfk == sfk_constructor)
+       DECL_CONSTRUCTOR_P (decl) = 1;
+
+      grokclassfn (ctype, decl, flags, quals);
+    }
 
   decl = check_explicit_specialization (orig_declarator, decl,
                                        template_count,
@@ -6673,9 +6553,22 @@ grokdeclarator (const cp_declarator *declarator,
              {
              case BIT_NOT_EXPR:
                {
-                 tree type = TREE_OPERAND (decl, 0);
-                 type = constructor_name (type);
-                 name = IDENTIFIER_POINTER (type);
+                 tree type;
+
+                 if (innermost_code != cdk_function)
+                   {
+                     error ("declaration of %qD as non-function", decl);
+                     return error_mark_node;
+                   }
+                 else if (!qualifying_scope 
+                          && !(current_class_type && at_class_scope_p ()))
+                   {
+                     error ("declaration of %qD as non-member", decl);
+                     return error_mark_node;
+                   }
+                 
+                 type = TREE_OPERAND (decl, 0);
+                 name = IDENTIFIER_POINTER (constructor_name (type));
                }
                break;
 
@@ -7032,6 +6925,20 @@ grokdeclarator (const cp_declarator *declarator,
     error ("qualifiers are not allowed on declaration of %<operator %T%>",
            ctor_return_type);
 
+  if (TREE_CODE (type) == FUNCTION_TYPE 
+      && type_quals != TYPE_UNQUALIFIED)
+    {
+      /* This was an error in C++98 (cv-qualifiers cannot be added to
+         a function type), but DR 295 makes the code well-formed by
+         dropping the extra qualifiers. */
+      if (pedantic)
+        {
+          tree bad_type = build_qualified_type (type, type_quals);
+          pedwarn ("ignoring %qV qualifiers added to function type %qT",
+                   bad_type, type);
+        }
+      type_quals = TYPE_UNQUALIFIED;
+    }
   type_quals |= cp_type_quals (type);
   type = cp_build_qualified_type_real
     (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
@@ -7393,6 +7300,7 @@ grokdeclarator (const cp_declarator *declarator,
              }
 
            type = build_function_type (type, arg_types);
+            type = cp_build_qualified_type (type, quals);
          }
          break;
 
@@ -7425,7 +7333,15 @@ grokdeclarator (const cp_declarator *declarator,
              && (TREE_CODE (type) == FUNCTION_TYPE
                  || (quals && TREE_CODE (type) == METHOD_TYPE)))
            {
-             tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
+             tree dummy;
+             
+              /* If the type is a FUNCTION_TYPE, pick up the
+                 qualifiers from that function type. No other
+                 qualifiers may be supplied. */
+              if (TREE_CODE (type) == FUNCTION_TYPE)
+                quals = cp_type_quals (type);
+
+             dummy = build_decl (TYPE_DECL, NULL_TREE, type);
              grok_method_quals (declarator->u.pointer.class_type,
                                 dummy, quals);
              type = TREE_TYPE (dummy);
@@ -7449,6 +7365,9 @@ grokdeclarator (const cp_declarator *declarator,
                         declarator->u.pointer.class_type);
                  type = build_pointer_type (type);
                }
+             else if (declarator->u.pointer.class_type == error_mark_node)
+               /* We will already have complained.  */
+               type = error_mark_node;
              else
                type = build_ptrmem_type (declarator->u.pointer.class_type,
                                          type);
@@ -7656,18 +7575,14 @@ grokdeclarator (const cp_declarator *declarator,
        TYPE_FOR_JAVA (type) = 1;
 
       if (decl_context == FIELD)
-       {
-         if (constructor_name_p (unqualified_id, current_class_type))
-           pedwarn ("ISO C++ forbids nested type %qD with same name "
-                     "as enclosing class",
-                    unqualified_id);
-         decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
-       }
+       decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
+       decl = build_decl (TYPE_DECL, unqualified_id, type);
+      if (id_declarator && declarator->u.id.qualifying_scope)
+       error ("%Jtypedef name may not be a nested-name-specifier", decl);
+
+      if (decl_context != FIELD)
        {
-         decl = build_decl (TYPE_DECL, unqualified_id, type);
-         if (in_namespace || ctype)
-           error ("%Jtypedef name may not be a nested-name-specifier", decl);
          if (!current_function_decl)
            DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
          else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (current_function_decl)
@@ -7679,6 +7594,10 @@ grokdeclarator (const cp_declarator *declarator,
               clones.  */
            DECL_ABSTRACT (decl) = 1;
        }
+      else if (constructor_name_p (unqualified_id, current_class_type))
+       pedwarn ("ISO C++ forbids nested type %qD with same name "
+                "as enclosing class",
+                unqualified_id);
 
       /* If the user declares "typedef struct {...} foo" then the
         struct will have an anonymous name.  Fill that name in now.
@@ -7719,11 +7638,12 @@ grokdeclarator (const cp_declarator *declarator,
        {
          if (ctype == NULL_TREE)
            {
-             if (TREE_CODE (type) != METHOD_TYPE)
-               error ("%Jinvalid type qualifier for non-member function type",
-                      decl);
-             else
+              if (TREE_CODE (type) == METHOD_TYPE)
                ctype = TYPE_METHOD_BASETYPE (type);
+              /* Any qualifiers on a function type typedef have
+                 already been dealt with. */
+              else if (TREE_CODE (type) == FUNCTION_TYPE)
+                quals = TYPE_UNQUALIFIED;
            }
          if (ctype != NULL_TREE)
            grok_method_quals (ctype, decl, quals);
@@ -7766,6 +7686,23 @@ grokdeclarator (const cp_declarator *declarator,
        }
 
       parms = nreverse (decls);
+
+      if (decl_context != TYPENAME)
+        {
+          /* A cv-qualifier-seq shall only be part of the function type
+             for a non-static member function. [8.3.5/4 dcl.fct] */ 
+          if (cp_type_quals (type) != TYPE_UNQUALIFIED
+              && (current_class_type == NULL_TREE || staticp) )
+            {
+              error ("qualified function types cannot be used to declare %s functions",
+                     (staticp? "static member" : "free"));
+              type = TYPE_MAIN_VARIANT (type);
+            }
+          
+          /* The qualifiers on the function type become the qualifiers on
+             the non-static member function. */
+          quals |= cp_type_quals (type);
+        }
     }
 
   /* If this is a type name (such as, in a cast or sizeof),
@@ -7923,15 +7860,6 @@ grokdeclarator (const cp_declarator *declarator,
            int publicp = 0;
            tree function_context;
 
-           /* We catch the others as conflicts with the builtin
-              typedefs.  */
-           if (friendp && unqualified_id == ridpointers[(int) RID_SIGNED])
-             {
-               error ("function %qD cannot be declared friend",
-                      unqualified_id);
-               friendp = 0;
-             }
-
            if (friendp == 0)
              {
                if (ctype == NULL_TREE)
@@ -7969,6 +7897,18 @@ grokdeclarator (const cp_declarator *declarator,
                                                     TYPE_ARG_TYPES (type));
              }
 
+           /* 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))
+             {
+               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.  */
            function_context = (ctype != NULL_TREE) ?
              decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
@@ -7981,6 +7921,7 @@ grokdeclarator (const cp_declarator *declarator,
                               unqualified_id,
                               virtualp, flags, quals, raises,
                               friendp ? -1 : 0, friendp, publicp, inlinep,
+                              sfk,
                               funcdef_flag, template_count, in_namespace, attrlist);
            if (decl == NULL_TREE)
              return decl;
@@ -8027,8 +7968,9 @@ grokdeclarator (const cp_declarator *declarator,
                               parms,
                               unqualified_id,
                               virtualp, flags, quals, raises,
-                              friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
-                              template_count, in_namespace, attrlist);
+                              friendp ? -1 : 0, friendp, 1, 0, sfk,
+                              funcdef_flag, template_count, in_namespace, 
+                              attrlist); 
            if (decl == NULL_TREE)
              return NULL_TREE;
          }
@@ -8213,7 +8155,7 @@ grokdeclarator (const cp_declarator *declarator,
        decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
                           virtualp, flags, quals, raises,
                           1, friendp,
-                          publicp, inlinep, funcdef_flag,
+                          publicp, inlinep, sfk, funcdef_flag,
                           template_count, in_namespace, attrlist);
        if (decl == NULL_TREE)
          return NULL_TREE;
@@ -8296,7 +8238,7 @@ grokdeclarator (const cp_declarator *declarator,
        when processing a template; we'll do this for the instantiated
        declaration based on the type of DECL.  */
     if (!processing_template_decl)
-      c_apply_type_quals_to_decl (type_quals, decl);
+      cp_apply_type_quals_to_decl (type_quals, decl);
 
     return decl;
   }
@@ -9800,6 +9742,11 @@ build_enumerator (tree name, tree value, tree enumtype)
   tree context;
   tree type;
 
+  /* If the VALUE was erroneous, pretend it wasn't there; that will
+     result in the enum being assigned the next value in sequence.  */
+  if (value == error_mark_node)
+    value = NULL_TREE;
+
   /* Remove no-op casts from the value.  */
   if (value)
     STRIP_TYPE_NOPS (value);
@@ -10075,7 +10022,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       DECL_IGNORED_P (resdecl) = 1;
       DECL_RESULT (decl1) = resdecl;
 
-      c_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
+      cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
     }
 
   /* Initialize RTL machinery.  We cannot do this until
@@ -10998,9 +10945,11 @@ complete_vars (tree type)
       if (same_type_p (type, TREE_PURPOSE (*list)))
        {
          tree var = TREE_VALUE (*list);
+         tree type = TREE_TYPE (var);
          /* Complete the type of the variable.  The VAR_DECL itself
             will be laid out in expand_expr.  */
-         complete_type (TREE_TYPE (var));
+         complete_type (type);
+         cp_apply_type_quals_to_decl (cp_type_quals (type), var);
          /* Remove this entry from the list.  */
          *list = TREE_CHAIN (*list);
        }
@@ -11042,9 +10991,6 @@ cxx_maybe_build_cleanup (tree decl)
       rval = build_delete (TREE_TYPE (rval), rval,
                           sfk_complete_destructor, flags, 0);
 
-      if (has_vbases && !TYPE_HAS_DESTRUCTOR (type))
-       rval = build_compound_expr (rval, build_vbase_delete (type, decl));
-
       return rval;
     }
   return NULL_TREE;