cp-tree.h (struct lang_decl_inlined_fns): New.
[gcc.git] / gcc / cp / decl.c
index 3e3f37be89de6b737e8f79cce1b65ea1db7ddd58..39008956f4af09d8b6d3e3db84b0511c97430be6 100644 (file)
@@ -3399,7 +3399,9 @@ duplicate_decls (newdecl, olddecl)
       DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
       DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
       DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
-      DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
+      if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK)
+       SET_OVERLOADED_OPERATOR_CODE
+         (newdecl, DECL_OVERLOADED_OPERATOR_P (olddecl));
       new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
 
       /* Optionally warn about more than one declaration for the same
@@ -3624,6 +3626,9 @@ duplicate_decls (newdecl, olddecl)
        DECL_INLINE (olddecl) = 1;
       DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
 
+      /* Preserve abstractness on cloned [cd]tors.  */
+      DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
+
       if (! types_match)
        {
          DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
@@ -6846,6 +6851,7 @@ check_tag_decl (declspecs)
 {
   int found_type = 0;
   int saw_friend = 0;
+  int saw_typedef = 0;
   tree ob_modifier = NULL_TREE;
   register tree link;
   register tree t = NULL_TREE;
@@ -6877,6 +6883,8 @@ check_tag_decl (declspecs)
              t = value;
            }
        }
+      else if (value == ridpointers[(int) RID_TYPEDEF])
+        saw_typedef = 1;
       else if (value == ridpointers[(int) RID_FRIEND])
        {
          if (current_class_type == NULL_TREE
@@ -6910,6 +6918,27 @@ check_tag_decl (declspecs)
           && TYPE_NAME (t)
           && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
     {
+      /* 7/3 In a simple-declaration, the optional init-declarator-list
+         can be omitted only when declaring a class (clause 9) or
+         enumeration (7.2), that is, when the decl-specifier-seq contains
+         either a class-specifier, an elaborated-type-specifier with
+         a class-key (9.1), or an enum-specifier.  In these cases and
+         whenever a class-specifier or enum-specifier is present in the
+         decl-specifier-seq, the identifiers in these specifiers are among
+         the names being declared by the declaration (as class-name,
+         enum-names, or enumerators, depending on the syntax).  In such
+         cases, and except for the declaration of an unnamed bit-field (9.6),
+         the decl-specifier-seq shall introduce one or more names into the
+         program, or shall redeclare a name introduced by a previous
+         declaration.  [Example:
+             enum { };            // ill-formed
+             typedef class { };   // ill-formed
+         --end example]  */
+      if (saw_typedef)
+        {
+          error ("Missing type-name in typedef-declaration.");
+          return NULL_TREE;
+        }
       /* Anonymous unions are objects, so they can have specifiers.  */;
       SET_ANON_AGGR_TYPE_P (t);
 
@@ -8614,7 +8643,8 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
              object, type);
   if (friendp)
     cp_error_at ("`%D' declared as a friend", object);
-  if (raises)
+  if (raises && !TYPE_PTRFN_P (TREE_TYPE (object))
+      && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))
     cp_error_at ("`%D' declared with an exception specification", object);
 }
 
@@ -8835,7 +8865,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
   /* Plain overloading: will not be grok'd by grokclassfn.  */
   if (! ctype && ! processing_template_decl
       && (! DECL_EXTERN_C_P (decl) || DECL_OVERLOADED_OPERATOR_P (decl))
-      && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1))
+      && ! DECL_USE_TEMPLATE (decl))
     set_mangled_name_for_decl (decl);
 
   if (funcdef_flag)
@@ -11275,15 +11305,8 @@ friend declaration requires class-key, i.e. `friend %#T'",
                /* The constructor can be called with exactly one
                   parameter if there is at least one parameter, and
                   any subsequent parameters have default arguments.
-                  We don't look at the first parameter, which is
-                  really just the `this' parameter for the new
-                  object.  */
-               tree arg_types =
-                 TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)));
-
-               /* Skip the `in_chrg' argument too, if present.  */
-               if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-                 arg_types = TREE_CHAIN (arg_types);
+                  Ignore any compiler-added parms.  */
+               tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (decl);
 
                if (arg_types == void_list_node
                    || (arg_types
@@ -11898,9 +11921,7 @@ copy_args_p (d)
   if (!DECL_FUNCTION_MEMBER_P (d))
     return 0;
 
-  t = FUNCTION_ARG_CHAIN (d);
-  if (DECL_CONSTRUCTOR_P (d) && DECL_HAS_IN_CHARGE_PARM_P (d))
-    t = TREE_CHAIN (t);
+  t = FUNCTION_FIRST_USER_PARMTYPE (d);
   if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
       && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t)))
          == DECL_CONTEXT (d))
@@ -11923,22 +11944,9 @@ int
 grok_ctor_properties (ctype, decl)
      tree ctype, decl;
 {
-  tree parmtypes = FUNCTION_ARG_CHAIN (decl);
+  tree parmtypes = FUNCTION_FIRST_USER_PARMTYPE (decl);
   tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
 
-  /* When a type has virtual baseclasses, a magical first int argument is
-     added to any ctor so we can tell if the class has been initialized
-     yet.  This could screw things up in this function, so we deliberately
-     ignore the leading int if we're in that situation.  */
-  if (DECL_HAS_IN_CHARGE_PARM_P (decl))
-    {
-      my_friendly_assert (parmtypes
-                         && TREE_VALUE (parmtypes) == integer_type_node,
-                         980529);
-      parmtypes = TREE_CHAIN (parmtypes);
-      parmtype = TREE_VALUE (parmtypes);
-    }
-
   /* [class.copy]
 
      A non-template constructor for class X is a copy constructor if
@@ -13448,8 +13456,18 @@ start_function (declspecs, declarator, attrs, flags)
 
       /* Constructors and destructors need to know whether they're "in
         charge" of initializing virtual base classes.  */
+      t = TREE_CHAIN (t);
       if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
-       current_in_charge_parm = TREE_CHAIN (t);
+       {
+         current_in_charge_parm = t;
+         t = TREE_CHAIN (t);
+       }
+      if (DECL_HAS_VTT_PARM_P (decl1))
+       {
+         if (DECL_NAME (t) != vtt_parm_identifier)
+           abort ();
+         current_vtt_parm = t;
+       }
     }
 
   if (DECL_INTERFACE_KNOWN (decl1))
@@ -14314,6 +14332,19 @@ pop_cp_function_context (f)
   f->language = 0;
 }
 
+/* Mark I for GC.  */
+
+static void
+mark_inlined_fns (i)
+     struct lang_decl_inlined_fns *i;
+{
+  int n;
+
+  for (n = i->num_fns - 1; n >= 0; n--)
+    ggc_mark_tree (i->fns [n]);
+  ggc_set_mark (i);
+}
+
 /* Mark P for GC.  */
 
 static void
@@ -14400,8 +14431,8 @@ lang_mark_tree (t)
              ggc_mark_tree (ld->befriending_classes);
              ggc_mark_tree (ld->context);
              ggc_mark_tree (ld->cloned_function);
-             if (!DECL_OVERLOADED_OPERATOR_P (t))
-               ggc_mark_tree (ld->u2.vtt_parm);
+             if (ld->inlined_fns)
+               mark_inlined_fns (ld->inlined_fns);
              if (TREE_CODE (t) == TYPE_DECL)
                ggc_mark_tree (ld->u.sorted_fields);
              else if (TREE_CODE (t) == FUNCTION_DECL