OSDN Git Service

PR c++/19991
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index 0df5b25..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.
@@ -64,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);
@@ -300,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;
     }
@@ -627,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))
        {
@@ -669,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",
@@ -879,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;
     }
@@ -897,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.  */
@@ -1045,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)
@@ -1110,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;
 
@@ -1165,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;
 
@@ -1205,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");
@@ -1998,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);
     }
@@ -3207,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.  */