OSDN Git Service

PR c++/19991
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index d8987e2..7ed490e 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 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA.  */
 #include "tree-mudflap.h"
 #include "cgraph.h"
 #include "tree-inline.h"
+#include "c-pragma.h"
 
 extern cpp_reader *parse_in;
 
@@ -63,9 +64,7 @@ typedef struct priority_info_s {
 } *priority_info;
 
 static void mark_vtable_entries (tree);
-static void grok_function_init (tree, tree);
 static bool maybe_emit_vtables (tree);
-static tree build_anon_union_vars (tree);
 static bool acceptable_java_type (tree);
 static tree start_objects (int, int);
 static void finish_objects (int, int, tree);
@@ -157,7 +156,7 @@ cp_build_parm_decl (tree name, tree type)
 /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
    indicated NAME.  */
 
-tree
+static tree
 build_artificial_parm (tree name, tree type)
 {
   tree parm = cp_build_parm_decl (name, type);
@@ -299,7 +298,7 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags,
       this_quals |= TYPE_QUAL_CONST;
       qual_type = cp_build_qualified_type (type, this_quals);
       parm = build_artificial_parm (this_identifier, qual_type);
-      c_apply_type_quals_to_decl (this_quals, parm);
+      cp_apply_type_quals_to_decl (this_quals, parm);
       TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
       DECL_ARGUMENTS (function) = parm;
     }
@@ -418,8 +417,6 @@ delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
       return t;
     }
 
-  exp = convert_from_reference (exp);
-
   /* An array can't have been allocated by new, so complain.  */
   if (TREE_CODE (exp) == VAR_DECL
       && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
@@ -628,10 +625,10 @@ check_classfn (tree ctype, tree function, tree template_parms)
       VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
       tree fndecls, fndecl = 0;
       bool is_conv_op;
-      bool pop_p;
+      tree pushed_scope;
       const char *format = NULL;
       
-      pop_p = push_scope (ctype);
+      pushed_scope = push_scope (ctype);
       for (fndecls = VEC_index (tree, methods, ix);
           fndecls; fndecls = OVL_NEXT (fndecls))
        {
@@ -670,8 +667,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
                      == DECL_TI_TEMPLATE (fndecl))))
            break;
        }
-      if (pop_p)
-       pop_scope (ctype);
+      if (pushed_scope)
+       pop_scope (pushed_scope);
       if (fndecls)
        return OVL_CURRENT (fndecls);
       error ("prototype for %q#D does not match any in class %qT",
@@ -831,11 +828,11 @@ grokfield (const cp_declarator *declarator,
 
   if (!declspecs->any_specifiers_p
       && declarator->kind == cdk_id
-      && TREE_CODE (declarator->u.id.name) == SCOPE_REF
-      && (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1)) 
-         == IDENTIFIER_NODE))
+      && declarator->u.id.qualifying_scope 
+      && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
     /* Access declaration */
-    return do_class_using_decl (declarator->u.id.name);
+    return do_class_using_decl (declarator->u.id.qualifying_scope,
+                               declarator->u.id.unqualified_name);
 
   if (init
       && TREE_CODE (init) == TREE_LIST
@@ -880,7 +877,16 @@ grokfield (const cp_declarator *declarator,
        value = push_template_decl (value);
 
       if (attrlist)
-       cplus_decl_attributes (&value, attrlist, 0);
+       {
+         /* Avoid storing attributes in template parameters:
+            tsubst is not ready to handle them.  */
+         tree type = TREE_TYPE (value);
+         if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+             || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+           sorry ("applying attributes to template parameters is not implemented");
+         else
+           cplus_decl_attributes (&value, attrlist, 0);
+       }
 
       return value;
     }
@@ -898,8 +904,11 @@ grokfield (const cp_declarator *declarator,
     {
       if (TREE_CODE (value) == FUNCTION_DECL)
        {
-         grok_function_init (value, init);
-         init = NULL_TREE;
+         /* Initializers for functions are rejected early in the parser.
+            If we get here, it must be a pure specifier for a method.  */
+         gcc_assert (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE);
+         gcc_assert (error_operand_p (init) || integer_zerop (init));
+         DECL_PURE_VIRTUAL_P (value) = 1;
        }
       else if (pedantic && TREE_CODE (value) != VAR_DECL)
        /* Already complained in grokdeclarator.  */
@@ -918,12 +927,11 @@ grokfield (const cp_declarator *declarator,
 
          if (!processing_template_decl)
            {
-             if (TREE_CODE (init) == CONST_DECL)
-               init = DECL_INITIAL (init);
-             else if (TREE_READONLY_DECL_P (init))
-               init = decl_constant_value (init);
-             else if (TREE_CODE (init) == CONSTRUCTOR)
+             if (TREE_CODE (init) == CONSTRUCTOR)
                init = digest_init (TREE_TYPE (value), init, (tree *)0);
+             else
+               init = integral_constant_value (init);
+             
              if (init != error_mark_node && ! TREE_CONSTANT (init))
                {
                  /* We can allow references to things that are effectively
@@ -1047,55 +1055,6 @@ grokbitfield (const cp_declarator *declarator,
   return value;
 }
 
-/* When a function is declared with an initializer,
-   do the right thing.  Currently, there are two possibilities:
-
-   class B
-   {
-    public:
-     // initialization possibility #1.
-     virtual void f () = 0;
-     int g ();
-   };
-   
-   class D1 : B
-   {
-    public:
-     int d1;
-     // error, no f ();
-   };
-   
-   class D2 : B
-   {
-    public:
-     int d2;
-     void f ();
-   };
-   
-   class D3 : B
-   {
-    public:
-     int d3;
-     // initialization possibility #2
-     void f () = B::f;
-   };
-
-*/
-
-static void
-grok_function_init (tree decl, tree init)
-{
-  /* An initializer for a function tells how this function should
-     be inherited.  */
-  tree type = TREE_TYPE (decl);
-
-  if (TREE_CODE (type) == FUNCTION_TYPE)
-    error ("initializer specified for non-member function %qD", decl);
-  else if (integer_zerop (init))
-    DECL_PURE_VIRTUAL_P (decl) = 1;
-  else
-    error ("invalid initializer for virtual method %qD", decl);
-}
 \f
 void
 cplus_decl_attributes (tree *decl, tree attributes, int flags)
@@ -1112,14 +1071,13 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
     SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
 }
 \f
-/* Walks through the namespace- or function-scope anonymous union OBJECT,
-   building appropriate ALIAS_DECLs.  Returns one of the fields for use in
-   the mangled name.  */
+/* Walks through the namespace- or function-scope anonymous union
+   OBJECT, with the indicated TYPE, building appropriate ALIAS_DECLs.
+   Returns one of the fields for use in the mangled name.  */
 
 static tree
-build_anon_union_vars (tree object)
+build_anon_union_vars (tree type, tree object)
 {
-  tree type = TREE_TYPE (object);
   tree main_decl = NULL_TREE;
   tree field;
 
@@ -1167,7 +1125,7 @@ build_anon_union_vars (tree object)
          decl = pushdecl (decl);
        }
       else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
-       decl = build_anon_union_vars (ref);
+       decl = build_anon_union_vars (TREE_TYPE (field), ref);
       else
        decl = 0;
 
@@ -1207,7 +1165,7 @@ finish_anon_union (tree anon_union_decl)
       return;
     }
 
-  main_decl = build_anon_union_vars (anon_union_decl);
+  main_decl = build_anon_union_vars (type, anon_union_decl);
   if (main_decl == NULL_TREE)
     {
       warning ("anonymous union with no members");
@@ -2000,6 +1958,7 @@ get_guard (tree decl)
         DECL_WEAK (guard) = DECL_WEAK (decl);
       
       DECL_ARTIFICIAL (guard) = 1;
+      DECL_IGNORED_P (guard) = 1;
       TREE_USED (guard) = 1;
       pushdecl_top_level_and_finish (guard, NULL_TREE);
     }
@@ -3062,6 +3021,9 @@ cp_finish_file (void)
   if (priority_info_map)
     splay_tree_delete (priority_info_map);
 
+  /* Generate any missing aliases.  */
+  maybe_apply_pending_pragma_weaks ();
+
   /* We're done with static constructors, so we can go back to "C++"
      linkage now.  */
   pop_lang_context ();
@@ -3206,9 +3168,20 @@ mark_used (tree decl)
       && DECL_ARTIFICIAL (decl) 
       && !DECL_THUNK_P (decl)
       && ! DECL_INITIAL (decl)
-      /* Kludge: don't synthesize for default args.  */
+      /* Kludge: don't synthesize for default args.  Unfortunately this
+        rules out initializers of namespace-scoped objects too, but
+        it's sort-of ok if the implicit ctor or dtor decl keeps
+        pointing to the class location.  */
       && current_function_decl)
     {
+      /* Put the function definition at the position where it is needed,
+        rather than within the body of the class.  That way, an error
+        during the generation of the implicit body points at the place
+        where the attempt to generate the function occurs, giving the
+        user a hint as to why we are attempting to generate the
+        function.  */
+      DECL_SOURCE_LOCATION (decl) = input_location;
+
       synthesize_method (decl);
       /* If we've already synthesized the method we don't need to
         instantiate it, so we can return right away.  */