OSDN Git Service

* cp-tree.h (struct lang_decl): Overhaul.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 4 Jul 2009 00:43:26 +0000 (00:43 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 4 Jul 2009 00:43:26 +0000 (00:43 +0000)
(struct lang_decl_flags): Remove.
(struct lang_decl_base): New.
(struct lang_decl_min): New.
(struct lang_decl_fn): New.
(struct lang_decl_ns): New.
(CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN.
(LANG_DECL_MIN_CHECK): New.
(LANG_DECL_FN_CHECK): New.
(LANG_DECL_NS_CHECK): New.
(STRIP_TEMPLATE): New.
(NON_THUNK_FUNCTION_CHECK): Remove.
(DECL_DECLARES_FUNCTION_P): New.
(lots): Adjust.
* lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust.
* decl.c (push_local_name, duplicate_decls): Adjust.
* decl2.c (start_objects): Don't set u2sel.
* semantics.c (finish_omp_threadprivate): Adjust.
* class.c (build_clone): Don't do much on TEMPLATE_DECLs.
(decl_cloned_function_p): Out-of-line implementation of macros.
(clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P.
* mangle.c (write_unqualified_name): Don't check function flags
on non-functions.
* method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION.
* pt.c (build_template_decl): Don't set function flags.
(check_default_tmpl_args): Check that it's a function.
(instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the
cloned template.

* pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst
DECL_CLONED_FUNCTION.

* cp-tree.h (struct lang_type_class): Move sorted_fields here.
* class.c (finish_struct_1): Adjust.
* ptree.c (cxx_print_decl, cxx_print_type): Adjust.
* search.c (lookup_field_1): Adjust.

* cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove.
* decl.c (finish_method): Don't add to it.
* class.c (fixup_pending_inline): Remove.
(fixup_inline_methods): Remove.
(finish_struct_1): Don't call it.

* error.c (dump_function_name): Handle null name.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149217 138bc75d-0d04-0410-961f-82ee72b054a4

15 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/lex.c
gcc/cp/mangle.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/ptree.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/pure1.C

index 17ac919..257dca4 100644 (file)
@@ -1,3 +1,50 @@
+2009-07-03  Jason Merrill  <jason@redhat.com>
+
+       * cp-tree.h (struct lang_decl): Overhaul.
+       (struct lang_decl_flags): Remove.
+       (struct lang_decl_base): New.
+       (struct lang_decl_min): New.
+       (struct lang_decl_fn): New.
+       (struct lang_decl_ns): New.
+       (CAN_HAVE_FULL_LANG_DECL_P): Replace with LANG_DECL_HAS_MIN.
+       (LANG_DECL_MIN_CHECK): New.
+       (LANG_DECL_FN_CHECK): New.
+       (LANG_DECL_NS_CHECK): New.
+       (STRIP_TEMPLATE): New.
+       (NON_THUNK_FUNCTION_CHECK): Remove.
+       (DECL_DECLARES_FUNCTION_P): New.
+       (lots): Adjust.
+       * lex.c (retrofit_lang_decl, cxx_dup_lang_specific_decl): Adjust.
+       * decl.c (push_local_name, duplicate_decls): Adjust.
+       * decl2.c (start_objects): Don't set u2sel.
+       * semantics.c (finish_omp_threadprivate): Adjust.
+       * class.c (build_clone): Don't do much on TEMPLATE_DECLs.
+       (decl_cloned_function_p): Out-of-line implementation of macros.
+       (clone_function_decl, adjust_clone_args): Use DECL_CLONED_FUNCTION_P.
+       * mangle.c (write_unqualified_name): Don't check function flags
+       on non-functions.
+       * method.c (make_alias_for): Don't set DECL_CLONED_FUNCTION.
+       * pt.c (build_template_decl): Don't set function flags.
+       (check_default_tmpl_args): Check that it's a function.
+       (instantiate_template): Use DECL_ABSTRACT_ORIGIN to find the
+       cloned template.
+
+       * pt.c (tsubst_decl) [FUNCTION_DECL]: Don't tsubst
+       DECL_CLONED_FUNCTION.
+
+       * cp-tree.h (struct lang_type_class): Move sorted_fields here.
+       * class.c (finish_struct_1): Adjust.
+       * ptree.c (cxx_print_decl, cxx_print_type): Adjust.
+       * search.c (lookup_field_1): Adjust.
+
+       * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Remove.
+       * decl.c (finish_method): Don't add to it.
+       * class.c (fixup_pending_inline): Remove.
+       (fixup_inline_methods): Remove.
+       (finish_struct_1): Don't call it.
+
+       * error.c (dump_function_name): Handle null name.
+
 2009-07-02  Mark Mitchell  <mark@codesourcery.com>
 
        * typeck.c (cp_build_binary_op): Move warnings about use of NULL
index 12192e6..4668c68 100644 (file)
@@ -151,8 +151,6 @@ static void check_bases_and_members (tree);
 static tree create_vtable_ptr (tree, tree *);
 static void include_empty_classes (record_layout_info);
 static void layout_class_type (tree, tree *);
-static void fixup_pending_inline (tree);
-static void fixup_inline_methods (tree);
 static void propagate_binfo_offsets (tree, tree);
 static void layout_virtual_bases (record_layout_info, splay_tree);
 static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
@@ -3799,12 +3797,27 @@ build_clone (tree fn, tree name)
 
   /* Copy the function.  */
   clone = copy_decl (fn);
-  /* Remember where this function came from.  */
-  DECL_CLONED_FUNCTION (clone) = fn;
-  DECL_ABSTRACT_ORIGIN (clone) = fn;
   /* Reset the function name.  */
   DECL_NAME (clone) = name;
   SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
+  /* Remember where this function came from.  */
+  DECL_ABSTRACT_ORIGIN (clone) = fn;
+  /* Make it easy to find the CLONE given the FN.  */
+  TREE_CHAIN (clone) = TREE_CHAIN (fn);
+  TREE_CHAIN (fn) = clone;
+
+  /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT.  */
+  if (TREE_CODE (clone) == TEMPLATE_DECL)
+    {
+      tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name);
+      DECL_TEMPLATE_RESULT (clone) = result;
+      DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
+      DECL_TI_TEMPLATE (result) = clone;
+      TREE_TYPE (clone) = TREE_TYPE (result);
+      return clone;
+    }
+
+  DECL_CLONED_FUNCTION (clone) = fn;
   /* There's no pending inline data for this function.  */
   DECL_PENDING_INLINE_INFO (clone) = NULL;
   DECL_PENDING_INLINE_P (clone) = 0;
@@ -3852,61 +3865,79 @@ build_clone (tree fn, tree name)
                                           TYPE_ATTRIBUTES (TREE_TYPE (fn)));
     }
 
-  /* Copy the function parameters.  But, DECL_ARGUMENTS on a TEMPLATE_DECL
-     aren't function parameters; those are the template parameters.  */
-  if (TREE_CODE (clone) != TEMPLATE_DECL)
+  /* Copy the function parameters.  */
+  DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
+  /* Remove the in-charge parameter.  */
+  if (DECL_HAS_IN_CHARGE_PARM_P (clone))
+    {
+      TREE_CHAIN (DECL_ARGUMENTS (clone))
+       = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
+      DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
+    }
+  /* And the VTT parm, in a complete [cd]tor.  */
+  if (DECL_HAS_VTT_PARM_P (fn))
     {
-      DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
-      /* Remove the in-charge parameter.  */
-      if (DECL_HAS_IN_CHARGE_PARM_P (clone))
+      if (DECL_NEEDS_VTT_PARM_P (clone))
+       DECL_HAS_VTT_PARM_P (clone) = 1;
+      else
        {
          TREE_CHAIN (DECL_ARGUMENTS (clone))
            = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
-         DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
-       }
-      /* And the VTT parm, in a complete [cd]tor.  */
-      if (DECL_HAS_VTT_PARM_P (fn))
-       {
-         if (DECL_NEEDS_VTT_PARM_P (clone))
-           DECL_HAS_VTT_PARM_P (clone) = 1;
-         else
-           {
-             TREE_CHAIN (DECL_ARGUMENTS (clone))
-               = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
-             DECL_HAS_VTT_PARM_P (clone) = 0;
-           }
+         DECL_HAS_VTT_PARM_P (clone) = 0;
        }
+    }
 
-      for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
-       {
-         DECL_CONTEXT (parms) = clone;
-         cxx_dup_lang_specific_decl (parms);
-       }
+  for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
+    {
+      DECL_CONTEXT (parms) = clone;
+      cxx_dup_lang_specific_decl (parms);
     }
 
   /* Create the RTL for this function.  */
   SET_DECL_RTL (clone, NULL_RTX);
   rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
 
-  /* Make it easy to find the CLONE given the FN.  */
-  TREE_CHAIN (clone) = TREE_CHAIN (fn);
-  TREE_CHAIN (fn) = clone;
+  if (pch_file)
+    note_decl_for_pch (clone);
 
-  /* If this is a template, handle the DECL_TEMPLATE_RESULT as well.  */
-  if (TREE_CODE (clone) == TEMPLATE_DECL)
-    {
-      tree result;
+  return clone;
+}
 
-      DECL_TEMPLATE_RESULT (clone)
-       = build_clone (DECL_TEMPLATE_RESULT (clone), name);
-      result = DECL_TEMPLATE_RESULT (clone);
-      DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
-      DECL_TI_TEMPLATE (result) = clone;
+/* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
+   not invoke this function directly.
+
+   For a non-thunk function, returns the address of the slot for storing
+   the function it is a clone of.  Otherwise returns NULL_TREE.
+
+   If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
+   cloned_function is unset.  This is to support the separate
+   DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
+   on a template makes sense, but not the former.  */
+
+tree *
+decl_cloned_function_p (const_tree decl, bool just_testing)
+{
+  tree *ptr;
+  if (just_testing)
+    decl = STRIP_TEMPLATE (decl);
+
+  if (TREE_CODE (decl) != FUNCTION_DECL
+      || !DECL_LANG_SPECIFIC (decl)
+      || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
+    {
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+      if (!just_testing)
+       lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
+      else
+#endif
+       return NULL;
     }
-  else if (pch_file)
-    note_decl_for_pch (clone);
 
-  return clone;
+  ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
+  if (just_testing && *ptr == NULL_TREE)
+    return NULL;
+  else
+    return ptr;
 }
 
 /* Produce declarations for all appropriate clones of FN.  If
@@ -3920,7 +3951,7 @@ clone_function_decl (tree fn, int update_method_vec_p)
 
   /* Avoid inappropriate cloning.  */
   if (TREE_CHAIN (fn)
-      && DECL_CLONED_FUNCTION (TREE_CHAIN (fn)))
+      && DECL_CLONED_FUNCTION_P (TREE_CHAIN (fn)))
     return;
 
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
@@ -3977,7 +4008,7 @@ adjust_clone_args (tree decl)
 {
   tree clone;
 
-  for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone);
+  for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
        clone = TREE_CHAIN (clone))
     {
       tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
@@ -4447,54 +4478,6 @@ create_vtable_ptr (tree t, tree* virtuals_p)
   return NULL_TREE;
 }
 
-/* Fixup the inline function given by INFO now that the class is
-   complete.  */
-
-static void
-fixup_pending_inline (tree fn)
-{
-  if (DECL_PENDING_INLINE_INFO (fn))
-    {
-      tree args = DECL_ARGUMENTS (fn);
-      while (args)
-       {
-         DECL_CONTEXT (args) = fn;
-         args = TREE_CHAIN (args);
-       }
-    }
-}
-
-/* Fixup the inline methods and friends in TYPE now that TYPE is
-   complete.  */
-
-static void
-fixup_inline_methods (tree type)
-{
-  tree method = TYPE_METHODS (type);
-  VEC(tree,gc) *friends;
-  unsigned ix;
-
-  if (method && TREE_CODE (method) == TREE_VEC)
-    {
-      if (TREE_VEC_ELT (method, 1))
-       method = TREE_VEC_ELT (method, 1);
-      else if (TREE_VEC_ELT (method, 0))
-       method = TREE_VEC_ELT (method, 0);
-      else
-       method = TREE_VEC_ELT (method, 2);
-    }
-
-  /* Do inline member functions.  */
-  for (; method; method = TREE_CHAIN (method))
-    fixup_pending_inline (method);
-
-  /* Do friends.  */
-  for (friends = CLASSTYPE_INLINE_FRIENDS (type), ix = 0;
-       VEC_iterate (tree, friends, ix, method); ix++)
-    fixup_pending_inline (method);
-  CLASSTYPE_INLINE_FRIENDS (type) = NULL;
-}
-
 /* Add OFFSET to all base types of BINFO which is a base in the
    hierarchy dominated by T.
 
@@ -5219,8 +5202,6 @@ finish_struct_1 (tree t)
   TYPE_SIZE (t) = NULL_TREE;
   CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
 
-  fixup_inline_methods (t);
-
   /* Make assumptions about the class; we'll reset the flags if
      necessary.  */
   CLASSTYPE_EMPTY_P (t) = 1;
@@ -5332,9 +5313,7 @@ finish_struct_1 (tree t)
       add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
       qsort (field_vec->elts, n_fields, sizeof (tree),
             field_decl_cmp);
-      if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
-       retrofit_lang_decl (TYPE_MAIN_DECL (t));
-      DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
+      CLASSTYPE_SORTED_FIELDS (t) = field_vec;
     }
 
   /* Complain if one of the field types requires lower visibility.  */
index 03dad66..50ed2ea 100644 (file)
@@ -199,21 +199,13 @@ framework extensions, you must include this file before toplev.h, not after.
   TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
 
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-#define NON_THUNK_FUNCTION_CHECK(NODE) __extension__                   \
-({  __typeof(NODE) const __t = (NODE);                                 \
-    if (TREE_CODE (__t) != FUNCTION_DECL &&                            \
-       TREE_CODE (__t) != TEMPLATE_DECL && __t->decl_common.lang_specific      \
-       && __t->decl_common.lang_specific->decl_flags.thunk_p)                  \
-      tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0);    \
-    __t; })
 #define THUNK_FUNCTION_CHECK(NODE) __extension__                       \
 ({  __typeof (NODE) const __t = (NODE);                                        \
-    if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl_common.lang_specific    \
-       || !__t->decl_common.lang_specific->decl_flags.thunk_p)         \
+    if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl_common.lang_specific \
+       || !__t->decl_common.lang_specific->u.fn.thunk_p)               \
       tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0);    \
      __t; })
 #else
-#define NON_THUNK_FUNCTION_CHECK(NODE) (NODE)
 #define THUNK_FUNCTION_CHECK(NODE) (NODE)
 #endif
 \f
@@ -1160,6 +1152,10 @@ struct GTY(()) lang_type_class {
      as a list of adopted protocols or a pointer to a corresponding
      @interface.  See objc/objc-act.h for details.  */
   tree objc_info;
+  /* sorted_fields is sorted based on a pointer, so we need to be able
+     to resort it if pointers get rearranged.  */
+  struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields")))
+    sorted_fields;
 };
 
 struct GTY(()) lang_type_ptrmem {
@@ -1197,13 +1193,6 @@ struct GTY(()) lang_type {
 
 #endif /* ENABLE_TREE_CHECKING */
 
-/* Fields used for storing information before the class is defined.
-   After the class is defined, these fields hold other information.  */
-
-/* VEC(tree) of friends which were defined inline in this class
-   definition.  */
-#define CLASSTYPE_INLINE_FRIENDS(NODE) CLASSTYPE_PURE_VIRTUALS (NODE)
-
 /* Nonzero for _CLASSTYPE means that operator delete is defined.  */
 #define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete)
 #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
@@ -1563,142 +1552,188 @@ struct GTY(()) lang_type {
 
 /* The binding level associated with the namespace.  */
 #define NAMESPACE_LEVEL(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.u.level)
+  (LANG_DECL_NS_CHECK (NODE)->level)
 \f
+/* Flags shared by all forms of DECL_LANG_SPECIFIC.
 
-/* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or
-   a lang_decl (which has lang_decl_flags as its initial prefix).
-   This macro is nonzero for tree nodes whose DECL_LANG_SPECIFIC is
-   the full lang_decl, and not just lang_decl_flags.  Keep these
-   checks in ascending code order.  */
-#define CAN_HAVE_FULL_LANG_DECL_P(NODE)                        \
-  (!(TREE_CODE (NODE) == FIELD_DECL                    \
-     || TREE_CODE (NODE) == VAR_DECL                   \
-     || TREE_CODE (NODE) == CONST_DECL                 \
-     || TREE_CODE (NODE) == USING_DECL))
+   Some of the flags live here only to make lang_decl_min/fn smaller.  Do
+   not make this struct larger than 32 bits; instead, make sel smaller.  */
 
-struct GTY(()) lang_decl_flags {
+struct GTY(()) lang_decl_base {
+  unsigned selector : 16;   /* Larger than necessary for faster access.  */
   ENUM_BITFIELD(languages) language : 4;
+  unsigned use_template : 2;
+  unsigned not_really_extern : 1;         /* var or fn */
+  unsigned initialized_in_class : 1;      /* var or fn */
+  unsigned repo_available_p : 1;          /* var or fn */
+  unsigned threadprivate_or_deleted_p : 1; /* var or fn */
+  unsigned anticipated_p : 1;             /* fn or type */
+  unsigned friend_attr : 1;               /* fn or type */
+  unsigned template_conv_p : 1;                   /* template only? */
+  unsigned u2sel : 1;
+  /* 2 spare bits */
+};
+
+/* True for DECL codes which have template info and access.  */
+#define LANG_DECL_HAS_MIN(NODE)                        \
+  (TREE_CODE (NODE) == FUNCTION_DECL           \
+   || TREE_CODE (NODE) == FIELD_DECL           \
+   || TREE_CODE (NODE) == VAR_DECL             \
+   || TREE_CODE (NODE) == CONST_DECL           \
+   || TREE_CODE (NODE) == TYPE_DECL            \
+   || TREE_CODE (NODE) == TEMPLATE_DECL                \
+   || TREE_CODE (NODE) == USING_DECL)
+
+/* DECL_LANG_SPECIFIC for the above codes.  */
+
+struct GTY(()) lang_decl_min {
+  struct lang_decl_base base;
+
+  /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+     THUNK_ALIAS.
+     In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
+     VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
+     DECL_TEMPLATE_INFO.  */
+  tree template_info;
+
+  union lang_decl_u2 {
+    /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+       THUNK_VIRTUAL_OFFSET.
+       Otherwise this is DECL_ACCESS.  */
+    tree GTY ((tag ("0"))) access;
+
+    /* For VAR_DECL in function, this is DECL_DISCRIMINATOR.  */
+    int GTY ((tag ("1"))) discriminator;
+  } GTY ((desc ("%0.u.base.u2sel"))) u2;
+};
+
+/* Additional DECL_LANG_SPECIFIC information for functions.  */
+
+struct GTY(()) lang_decl_fn {
+  struct lang_decl_min min;
+
+  /* In an overloaded operator, this is the value of
+     DECL_OVERLOADED_OPERATOR_P.  */
+  ENUM_BITFIELD (tree_code) operator_code : 16;
+
   unsigned global_ctor_p : 1;
   unsigned global_dtor_p : 1;
-  unsigned anticipated_p : 1;
-  unsigned template_conv_p : 1;
-
-  unsigned operator_attr : 1;
   unsigned constructor_attr : 1;
   unsigned destructor_attr : 1;
-  unsigned friend_attr : 1;
+  unsigned assignment_operator_p : 1;
   unsigned static_function : 1;
   unsigned pure_virtual : 1;
+  unsigned defaulted_p : 1;
+
   unsigned has_in_charge_parm_p : 1;
   unsigned has_vtt_parm_p : 1;
-
-  unsigned deferred : 1;
-  unsigned use_template : 2;
+  unsigned pending_inline_p : 1;
   unsigned nonconverting : 1;
-  unsigned not_really_extern : 1;
-  unsigned initialized_in_class : 1;
-  unsigned assignment_operator_p : 1;
-  unsigned u1sel : 1;
-
-  unsigned u2sel : 1;
-  unsigned can_be_full : 1;
   unsigned thunk_p : 1;
   unsigned this_thunk_p : 1;
-  unsigned repo_available_p : 1;
   unsigned hidden_friend_p : 1;
-  unsigned threadprivate_or_deleted_p : 1;
-  unsigned defaulted_p : 1;
+  unsigned deferred : 1;
+  /* No spare bits; consider adding to lang_decl_base instead.  */
 
-  union lang_decl_u {
-    /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
-       THUNK_ALIAS.
-       In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
-       VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
-       DECL_TEMPLATE_INFO.  */
-    tree GTY ((tag ("0"))) template_info;
+  /* For a non-thunk function decl, this is a tree list of
+     friendly classes. For a thunk function decl, it is the
+     thunked to function decl.  */
+  tree befriending_classes;
 
-    /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL.  */
-    struct cp_binding_level * GTY ((tag ("1"))) level;
-  } GTY ((desc ("%1.u1sel"))) u;
+  /* For a non-virtual FUNCTION_DECL, this is
+     DECL_FRIEND_CONTEXT.  For a virtual FUNCTION_DECL for which
+     DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
+     this pointer and result pointer adjusting thunks are
+     chained here.  This pointer thunks to return pointer thunks
+     will be chained on the return pointer thunk.  */
+  tree context;
 
-  union lang_decl_u2 {
-    /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
-       THUNK_VIRTUAL_OFFSET.
-       Otherwise this is DECL_ACCESS.  */
-    tree GTY ((tag ("0"))) access;
+  union lang_decl_u5
+  {
+    /* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is
+       DECL_CLONED_FUNCTION.  */
+    tree GTY ((tag ("0"))) cloned_function;
 
-    /* For VAR_DECL in function, this is DECL_DISCRIMINATOR.  */
-    int GTY ((tag ("1"))) discriminator;
-  } GTY ((desc ("%1.u2sel"))) u2;
+    /* In a FUNCTION_DECL for which THUNK_P holds this is the
+       THUNK_FIXED_OFFSET.  */
+    HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
+  } GTY ((desc ("%1.thunk_p"))) u5;
+
+  union lang_decl_u3
+  {
+    struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info;
+    struct language_function * GTY ((tag ("0")))
+      saved_language_function;
+  } GTY ((desc ("%1.pending_inline_p"))) u;
+
+};
+
+/* DECL_LANG_SPECIFIC for namespaces.  */
+
+struct GTY(()) lang_decl_ns {
+  struct lang_decl_base base;
+  struct cp_binding_level *level;
 };
 
-/* sorted_fields is sorted based on a pointer, so we need to be able
-   to resort it if pointers get rearranged.  */
+/* DECL_LANG_SPECIFIC for all types.  It would be nice to just make this a
+   union rather than a struct containing a union as its only field, but
+   tree.h declares it as a struct.  */
 
 struct GTY(()) lang_decl {
-  struct lang_decl_flags decl_flags;
-
-  union lang_decl_u4
-    {
-      struct full_lang_decl
-      {
-       /* In an overloaded operator, this is the value of
-          DECL_OVERLOADED_OPERATOR_P.  */
-       ENUM_BITFIELD (tree_code) operator_code : 16;
-
-       unsigned u3sel : 1;
-       unsigned pending_inline_p : 1;
-       unsigned spare : 14;
-
-       /* For a non-thunk function decl, this is a tree list of
-          friendly classes. For a thunk function decl, it is the
-          thunked to function decl.  */
-       tree befriending_classes;
-
-       /* For a non-virtual FUNCTION_DECL, this is
-          DECL_FRIEND_CONTEXT.  For a virtual FUNCTION_DECL for which
-          DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
-          this pointer and result pointer adjusting thunks are
-          chained here.  This pointer thunks to return pointer thunks
-          will be chained on the return pointer thunk.  */
-       tree context;
-
-       union lang_decl_u5
-       {
-         /* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is
-            DECL_CLONED_FUNCTION.  */
-         tree GTY ((tag ("0"))) cloned_function;
-
-         /* In a FUNCTION_DECL for which THUNK_P holds this is the
-            THUNK_FIXED_OFFSET.  */
-         HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset;
-       } GTY ((desc ("%0.decl_flags.thunk_p"))) u5;
-
-       union lang_decl_u3
-       {
-         struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields")))
-              sorted_fields;
-         struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info;
-         struct language_function * GTY ((tag ("1")))
-              saved_language_function;
-       } GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u;
-      } GTY ((tag ("1"))) f;
-  } GTY ((desc ("%1.decl_flags.can_be_full"))) u;
+  union GTY((desc ("%h.base.selector"))) lang_decl_u {
+    struct lang_decl_base GTY ((default)) base;
+    struct lang_decl_min GTY((tag ("0"))) min;
+    struct lang_decl_fn GTY ((tag ("1"))) fn;
+    struct lang_decl_ns GTY((tag ("2"))) ns;
+  } u;
 };
 
+/* Looks through a template (if present) to find what it declares.  */
+#define STRIP_TEMPLATE(NODE) \
+  (TREE_CODE (NODE) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (NODE) : NODE)
+
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 
+#define LANG_DECL_MIN_CHECK(NODE) __extension__                        \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);           \
+   if (!LANG_DECL_HAS_MIN (NODE))                              \
+     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);     \
+   &lt->u.min; })
+
+/* We want to be able to check DECL_CONSTRUCTOR_P and such on a function
+   template, not just on a FUNCTION_DECL.  So when looking for things in
+   lang_decl_fn, look down through a TEMPLATE_DECL into its result.  */
+#define LANG_DECL_FN_CHECK(NODE) __extension__                         \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE));  \
+   if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != 1)   \
+     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);             \
+   &lt->u.fn; })
+
+#define LANG_DECL_NS_CHECK(NODE) __extension__                         \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);                   \
+   if (TREE_CODE (NODE) != NAMESPACE_DECL || lt->u.base.selector != 2) \
+     lang_check_failed (__FILE__, __LINE__, __FUNCTION__);             \
+   &lt->u.ns; })
+
 #define LANG_DECL_U2_CHECK(NODE, TF) __extension__             \
 ({  struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);          \
-    if (lt->decl_flags.u2sel != TF)                            \
+    if (lt->u.base.u2sel != TF)                                        \
       lang_check_failed (__FILE__, __LINE__, __FUNCTION__);    \
-    &lt->decl_flags.u2; })
+    &lt->u.min.u2; })
 
 #else
 
+#define LANG_DECL_MIN_CHECK(NODE) \
+  (&DECL_LANG_SPECIFIC (NODE)->u.min)
+
+#define LANG_DECL_FN_CHECK(NODE) \
+  (&DECL_LANG_SPECIFIC (NODE)->u.fn)
+
+#define LANG_DECL_NS_CHECK(NODE) \
+  (&DECL_LANG_SPECIFIC (NODE)->u.ns)
+
 #define LANG_DECL_U2_CHECK(NODE, TF) \
-  (&DECL_LANG_SPECIFIC (NODE)->decl_flags.u2)
+  (&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
 
 #endif /* ENABLE_TREE_CHECKING */
 
@@ -1713,17 +1748,17 @@ struct GTY(()) lang_decl {
    we do create DECL_LANG_SPECIFIC for variables with non-C++ linkage.  */
 #define DECL_LANGUAGE(NODE)                            \
   (DECL_LANG_SPECIFIC (NODE)                           \
-   ? DECL_LANG_SPECIFIC (NODE)->decl_flags.language    \
+   ? DECL_LANG_SPECIFIC (NODE)->u.base.language                \
    : (TREE_CODE (NODE) == FUNCTION_DECL                        \
       ? lang_c : lang_cplusplus))
 
 /* Set the language linkage for NODE to LANGUAGE.  */
 #define SET_DECL_LANGUAGE(NODE, LANGUAGE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.language = (LANGUAGE))
+  (DECL_LANG_SPECIFIC (NODE)->u.base.language = (LANGUAGE))
 
 /* For FUNCTION_DECLs: nonzero means that this function is a constructor.  */
 #define DECL_CONSTRUCTOR_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.constructor_attr)
+  (LANG_DECL_FN_CHECK (NODE)->constructor_attr)
 
 /* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete
    object.  */
@@ -1741,7 +1776,8 @@ struct GTY(()) lang_decl {
    specialized in-charge constructor or the specialized not-in-charge
    constructor.  */
 #define DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(NODE)               \
-  (DECL_CONSTRUCTOR_P (NODE) && !DECL_CLONED_FUNCTION_P (NODE))
+  (DECL_DECLARES_FUNCTION_P (NODE) && DECL_CONSTRUCTOR_P (NODE) \
+   && !DECL_CLONED_FUNCTION_P (NODE))
 
 /* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor.  */
 #define DECL_COPY_CONSTRUCTOR_P(NODE) \
@@ -1753,13 +1789,14 @@ struct GTY(()) lang_decl {
 
 /* Nonzero if NODE is a destructor.  */
 #define DECL_DESTRUCTOR_P(NODE)                                \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.destructor_attr)
+  (LANG_DECL_FN_CHECK (NODE)->destructor_attr)
 
 /* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
    specialized in-charge constructor, in-charge deleting constructor,
    or the base destructor.  */
 #define DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(NODE)                        \
-  (DECL_DESTRUCTOR_P (NODE) && !DECL_CLONED_FUNCTION_P (NODE))
+  (DECL_DECLARES_FUNCTION_P (NODE) && DECL_DESTRUCTOR_P (NODE) \
+   && !DECL_CLONED_FUNCTION_P (NODE))
 
 /* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete
    object.  */
@@ -1781,17 +1818,11 @@ struct GTY(()) lang_decl {
 
 /* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or
    destructor.  */
-#define DECL_CLONED_FUNCTION_P(NODE)                   \
-  ((TREE_CODE (NODE) == FUNCTION_DECL                  \
-    || TREE_CODE (NODE) == TEMPLATE_DECL)              \
-   && DECL_LANG_SPECIFIC (NODE)                                \
-   && !DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p   \
-   && DECL_CLONED_FUNCTION (NODE) != NULL_TREE)
+#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true))
 
 /* If DECL_CLONED_FUNCTION_P holds, this is the function that was
    cloned.  */
-#define DECL_CLONED_FUNCTION(NODE) \
-  (DECL_LANG_SPECIFIC (NON_THUNK_FUNCTION_CHECK(NODE))->u.f.u5.cloned_function)
+#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false))
 
 /* Perform an action for each clone of FN, if FN is a function with
    clones.  This macro should be used like:
@@ -1818,7 +1849,7 @@ struct GTY(()) lang_decl {
 
 /* Nonzero if the VTT parm has been added to NODE.  */
 #define DECL_HAS_VTT_PARM_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_vtt_parm_p)
+  (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
 
 /* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is
    required.  */
@@ -1840,11 +1871,11 @@ struct GTY(()) lang_decl {
    conversion operator to a type dependent on the innermost template
    args.  */
 #define DECL_TEMPLATE_CONV_FN_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.template_conv_p)
+  (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p)
 
 /* Set the overloaded operator code for NODE to CODE.  */
 #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.operator_code = (CODE))
+  (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE))
 
 /* If NODE is an overloaded operator, then this returns the TREE_CODE
    associated with the overloaded operator.
@@ -1855,17 +1886,17 @@ struct GTY(()) lang_decl {
    to test whether or not NODE is an overloaded operator.  */
 #define DECL_OVERLOADED_OPERATOR_P(NODE)               \
   (IDENTIFIER_OPNAME_P (DECL_NAME (NODE))              \
-   ? DECL_LANG_SPECIFIC (NODE)->u.f.operator_code : ERROR_MARK)
+   ? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK)
 
 /* Nonzero if NODE is an assignment operator (including += and such).  */
 #define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.assignment_operator_p)
+  (LANG_DECL_FN_CHECK (NODE)->assignment_operator_p)
 
 /* For FUNCTION_DECLs: nonzero means that this function is a
    constructor or a destructor with an extra in-charge parameter to
    control whether or not virtual bases are constructed.  */
 #define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p)
+  (LANG_DECL_FN_CHECK (NODE)->has_in_charge_parm_p)
 
 /* Nonzero if DECL is a declaration of __builtin_constant_p.  */
 #define DECL_IS_BUILTIN_CONSTANT_P(NODE)               \
@@ -1917,20 +1948,21 @@ struct GTY(()) lang_decl {
    rather than outside the class.  This is used for both static member
    VAR_DECLS, and FUNCTION_DECLS that are defined in the class.  */
 #define DECL_INITIALIZED_IN_CLASS_P(DECL) \
- (DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class)
+  (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \
+   ->u.base.initialized_in_class)
 
 /* Nonzero for DECL means that this decl is just a friend declaration,
    and should not be added to the list of members for this class.  */
-#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.friend_attr)
+#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.friend_attr)
 
 /* A TREE_LIST of the types which have befriended this FUNCTION_DECL.  */
 #define DECL_BEFRIENDING_CLASSES(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
+  (LANG_DECL_FN_CHECK (NODE)->befriending_classes)
 
 /* Nonzero for FUNCTION_DECL means that this decl is a static
    member function.  */
 #define DECL_STATIC_FUNCTION_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.static_function)
+  (LANG_DECL_FN_CHECK (NODE)->static_function)
 
 /* Nonzero for FUNCTION_DECL means that this decl is a non-static
    member function.  */
@@ -1940,7 +1972,7 @@ struct GTY(()) lang_decl {
 /* Nonzero for FUNCTION_DECL means that this decl is a member function
    (static or non-static).  */
 #define DECL_FUNCTION_MEMBER_P(NODE) \
- (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
 (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE))
 
 /* Nonzero for FUNCTION_DECL means that this member function
    has `this' as const X *const.  */
@@ -1968,12 +2000,12 @@ struct GTY(()) lang_decl {
 /* Nonzero for _DECL means that this constructor or conversion function is
    non-converting.  */
 #define DECL_NONCONVERTING_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.nonconverting)
+  (LANG_DECL_FN_CHECK (NODE)->nonconverting)
 
 /* Nonzero for FUNCTION_DECL means that this member function is a pure
    virtual function.  */
 #define DECL_PURE_VIRTUAL_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.pure_virtual)
+  (LANG_DECL_FN_CHECK (NODE)->pure_virtual)
 
 /* True (in a FUNCTION_DECL) if NODE is a virtual function that is an
    invalid overrider for a function from a base class.  Once we have
@@ -1984,27 +2016,26 @@ struct GTY(()) lang_decl {
 
 /* The thunks associated with NODE, a FUNCTION_DECL.  */
 #define DECL_THUNKS(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.context)
+  (LANG_DECL_FN_CHECK (NODE)->context)
 
 /* Nonzero if NODE is a thunk, rather than an ordinary function.  */
 #define DECL_THUNK_P(NODE)                     \
   (TREE_CODE (NODE) == FUNCTION_DECL           \
    && DECL_LANG_SPECIFIC (NODE)                        \
-   && DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p)
+   && LANG_DECL_FN_CHECK (NODE)->thunk_p)
 
 /* Set DECL_THUNK_P for node.  */
 #define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING)                 \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.thunk_p = 1,          \
-   DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1,                   \
-   DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING))
+  (LANG_DECL_FN_CHECK (NODE)->thunk_p = 1,                     \
+   LANG_DECL_FN_CHECK (NODE)->this_thunk_p = (THIS_ADJUSTING))
 
 /* Nonzero if NODE is a this pointer adjusting thunk.  */
 #define DECL_THIS_THUNK_P(NODE)                        \
-  (DECL_THUNK_P (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p)
+  (DECL_THUNK_P (NODE) && LANG_DECL_FN_CHECK (NODE)->this_thunk_p)
 
 /* Nonzero if NODE is a result pointer adjusting thunk.  */
 #define DECL_RESULT_THUNK_P(NODE)                      \
-  (DECL_THUNK_P (NODE) && !DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p)
+  (DECL_THUNK_P (NODE) && !LANG_DECL_FN_CHECK (NODE)->this_thunk_p)
 
 /* Nonzero if NODE is a FUNCTION_DECL, but not a thunk.  */
 #define DECL_NON_THUNK_FUNCTION_P(NODE)                                \
@@ -2021,7 +2052,7 @@ struct GTY(()) lang_decl {
 /* True iff DECL is an entity with vague linkage whose definition is
    available in this translation unit.  */
 #define DECL_REPO_AVAILABLE_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.repo_available_p)
+  (DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p)
 
 /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
    template function.  */
@@ -2040,13 +2071,14 @@ struct GTY(()) lang_decl {
 
    the DECL_FRIEND_CONTEXT for `f' will be `S'.  */
 #define DECL_FRIEND_CONTEXT(NODE)                              \
-  ((DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE))    \
-   ? DECL_LANG_SPECIFIC (NODE)->u.f.context                    \
+  ((DECL_DECLARES_FUNCTION_P (NODE)                            \
+    && DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \
+   ? LANG_DECL_FN_CHECK (NODE)->context                                \
    : NULL_TREE)
 
 /* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT.  */
 #define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.context = (CONTEXT))
+  (LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT))
 
 /* NULL_TREE in DECL_CONTEXT represents the global namespace.  */
 #define CP_DECL_CONTEXT(NODE) \
@@ -2153,21 +2185,21 @@ extern void decl_shadowed_for_var_insert (tree, tree);
    the class definition.  We have saved away the text of the function,
    but have not yet processed it.  */
 #define DECL_PENDING_INLINE_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.pending_inline_p)
+  (LANG_DECL_FN_CHECK (NODE)->pending_inline_p)
 
 /* If DECL_PENDING_INLINE_P holds, this is the saved text of the
    function.  */
 #define DECL_PENDING_INLINE_INFO(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.u.pending_inline_info)
+  (LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info)
 
-/* For a TYPE_DECL: if this structure has many fields, we'll sort them
+/* For a class type: if this structure has many fields, we'll sort them
    and put them into a TREE_VEC.  */
-#define DECL_SORTED_FIELDS(NODE) \
-  (DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.f.u.sorted_fields)
+#define CLASSTYPE_SORTED_FIELDS(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields)
 
 /* True if on the deferred_fns (see decl2.c) list.  */
 #define DECL_DEFERRED_FN(DECL) \
-  (DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
+  (LANG_DECL_FN_CHECK (DECL)->deferred)
 
 /* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
    TEMPLATE_DECL, the entity is either a template specialization (if
@@ -2190,7 +2222,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
    will be non-NULL, but DECL_USE_TEMPLATE will be zero.  */
 #define DECL_TEMPLATE_INFO(NODE) \
   (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
-   ->decl_flags.u.template_info)
+   ->u.min.template_info)
 
 /* For a VAR_DECL, indicates that the variable is actually a
    non-static data member of anonymous union that has been promoted to
@@ -2440,8 +2472,8 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 
 /* In a FUNCTION_DECL, the saved language-specific per-function data.  */
 #define DECL_SAVED_FUNCTION_DATA(NODE)                 \
-  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))     \
-   ->u.f.u.saved_language_function)
+  (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE))     \
+   ->u.saved_language_function)
 
 /* Indicates an indirect_expr is for converting a reference.  */
 #define REFERENCE_REF_P(NODE) \
@@ -2617,26 +2649,26 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
    declared inside a class.  In the latter case DECL_HIDDEN_FRIEND_P
    will be set.  */
 #define DECL_ANTICIPATED(NODE) \
-  (DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->decl_flags.anticipated_p)
+  (DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->u.base.anticipated_p)
 
 /* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
    within a class but has not been declared in the surrounding scope.
    The function is invisible except via argument dependent lookup.  */
 #define DECL_HIDDEN_FRIEND_P(NODE) \
-  (DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->decl_flags.hidden_friend_p)
+  (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
 
 /* Nonzero if DECL has been declared threadprivate by
    #pragma omp threadprivate.  */
 #define CP_DECL_THREADPRIVATE_P(DECL) \
-  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->decl_flags.threadprivate_or_deleted_p)
+  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p)
 
 /* Nonzero if DECL was declared with '= delete'.  */
 #define DECL_DELETED_FN(DECL) \
-  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.threadprivate_or_deleted_p)
+  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p)
 
 /* Nonzero if DECL was declared with '= default'.  */
 #define DECL_DEFAULTED_FN(DECL) \
-  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.defaulted_p)
+  (LANG_DECL_FN_CHECK (DECL)->defaulted_p)
 
 /* Record whether a typedef for type `int' was actually `signed int'.  */
 #define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
@@ -3046,11 +3078,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
 /* Nonzero if the FUNCTION_DECL is a global constructor.  */
 #define DECL_GLOBAL_CTOR_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.global_ctor_p)
+  (LANG_DECL_FN_CHECK (NODE)->global_ctor_p)
 
 /* Nonzero if the FUNCTION_DECL is a global destructor.  */
 #define DECL_GLOBAL_DTOR_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.global_dtor_p)
+  (LANG_DECL_FN_CHECK (NODE)->global_dtor_p)
 
 /* Accessor macros for C++ template decl nodes.  */
 
@@ -3151,6 +3183,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define DECL_DECLARES_TYPE_P(NODE) \
   (TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE))
 
+/* Nonzero if NODE declares a function.  */
+#define DECL_DECLARES_FUNCTION_P(NODE) \
+  (TREE_CODE (NODE) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (NODE))
+
 /* Nonzero if NODE is the typedef implicitly generated for a type when
    the type is declared.  In C++, `struct S {};' is roughly
    equivalent to `struct S {}; typedef struct S S;' in C.
@@ -3204,7 +3240,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
    If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also
    be non-NULL.  */
-#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.use_template)
+#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.use_template)
 
 /* Like DECL_USE_TEMPLATE, but for class types.  */
 #define CLASSTYPE_USE_TEMPLATE(NODE) \
@@ -3277,7 +3313,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
    current translation unit; it indicates whether or not we should emit the
    decl at the end of compilation if it is defined and needed.  */
 #define DECL_NOT_REALLY_EXTERN(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern)
+  (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)
 
 #define DECL_REALLY_EXTERN(NODE) \
   (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
@@ -3324,7 +3360,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 /* An integer indicating how many bytes should be subtracted from the
    this or result pointer when this function is called.  */
 #define THUNK_FIXED_OFFSET(DECL) \
-  (DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.f.u5.fixed_offset)
+  (DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.fn.u5.fixed_offset)
 
 /* A tree indicating how to perform the virtual adjustment. For a this
    adjusting thunk it is the number of bytes to be added to the vtable
@@ -3341,12 +3377,12 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
 /* A thunk which is equivalent to another thunk.  */
 #define THUNK_ALIAS(DECL) \
-  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.template_info)
+  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.min.template_info)
 
 /* For thunk NODE, this is the FUNCTION_DECL thunked to.  It is
    possible for the target to be a thunk too.  */
 #define THUNK_TARGET(NODE)                             \
-  (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
+  (LANG_DECL_FN_CHECK (NODE)->befriending_classes)
 
 /* True for a SCOPE_REF iff the "template" keyword was used to
    indicate that the qualified name denotes a template.  */
@@ -4258,6 +4294,7 @@ extern bool type_has_user_provided_constructor  (tree);
 extern bool type_has_user_provided_default_constructor (tree);
 extern bool defaultable_fn_p                   (tree);
 extern void fixup_type_variants                        (tree);
+extern tree* decl_cloned_function_p            (const_tree, bool);
 extern void clone_function_decl                        (tree, int);
 extern void adjust_clone_args                  (tree);
 
index 73c756f..dc2ef1e 100644 (file)
@@ -873,7 +873,7 @@ push_local_name (tree decl)
        {
          if (!DECL_LANG_SPECIFIC (decl))
            retrofit_lang_decl (decl);
-         DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1;
+         DECL_LANG_SPECIFIC (decl)->u.base.u2sel = 1;
          if (DECL_LANG_SPECIFIC (t))
            DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
          else
@@ -1786,9 +1786,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
        {
          DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
          DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
-         if (CAN_HAVE_FULL_LANG_DECL_P (newdecl)
-             && DECL_LANG_SPECIFIC (newdecl)
-             && DECL_LANG_SPECIFIC (olddecl))
+         if (TREE_CODE (newdecl) == FUNCTION_DECL)
            {
              DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
              DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
@@ -1894,24 +1892,27 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* 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);
-      DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 =
-       DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
-      DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
       DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
-      if (DECL_TEMPLATE_INFO (newdecl))
-       new_template_info = DECL_TEMPLATE_INFO (newdecl);
-      DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
       DECL_INITIALIZED_IN_CLASS_P (newdecl)
        |= DECL_INITIALIZED_IN_CLASS_P (olddecl);
-      olddecl_friend = DECL_FRIEND_P (olddecl);
-      hidden_friend = (DECL_ANTICIPATED (olddecl)
-                      && DECL_HIDDEN_FRIEND_P (olddecl)
-                      && newdecl_is_friend);
 
-      /* Only functions have DECL_BEFRIENDING_CLASSES.  */
+      if (LANG_DECL_HAS_MIN (newdecl))
+       {
+         DECL_LANG_SPECIFIC (newdecl)->u.min.u2 =
+           DECL_LANG_SPECIFIC (olddecl)->u.min.u2;
+         if (DECL_TEMPLATE_INFO (newdecl))
+           new_template_info = DECL_TEMPLATE_INFO (newdecl);
+         DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+       }
+      /* Only functions have these fields.  */
       if (TREE_CODE (newdecl) == FUNCTION_DECL
          || DECL_FUNCTION_TEMPLATE_P (newdecl))
        {
+         DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
+         olddecl_friend = DECL_FRIEND_P (olddecl);
+         hidden_friend = (DECL_ANTICIPATED (olddecl)
+                          && DECL_HIDDEN_FRIEND_P (olddecl)
+                          && newdecl_is_friend);
          DECL_BEFRIENDING_CLASSES (newdecl)
            = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
                       DECL_BEFRIENDING_CLASSES (olddecl));
@@ -12582,16 +12583,6 @@ finish_method (tree decl)
 
   DECL_INITIAL (fndecl) = old_initial;
 
-  /* We used to check if the context of FNDECL was different from
-     current_class_type as another way to get inside here.  This didn't work
-     for String.cc in libg++.  */
-  if (DECL_FRIEND_P (fndecl))
-    {
-      VEC_safe_push (tree, gc, CLASSTYPE_INLINE_FRIENDS (current_class_type),
-                    fndecl);
-      decl = void_type_node;
-    }
-
   return decl;
 }
 \f
index 1191964..6be57a6 100644 (file)
@@ -2634,7 +2634,6 @@ start_objects (int method_type, int initp)
     DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
   else
     DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
-  DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1;
 
   body = begin_compound_stmt (BCS_FN_BODY);
 
index fa97a3b..850f406 100644 (file)
@@ -1406,7 +1406,7 @@ dump_function_name (tree t, int flags)
       pp_cxx_ws_string (cxx_pp, "operator");
       dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
     }
-  else if (IDENTIFIER_OPNAME_P (name))
+  else if (name && IDENTIFIER_OPNAME_P (name))
     pp_cxx_tree_identifier (cxx_pp, name);
   else
     dump_decl (name, flags);
index bf50741..5effd7a 100644 (file)
@@ -532,19 +532,20 @@ retrofit_lang_decl (tree t)
 {
   struct lang_decl *ld;
   size_t size;
-
-  if (CAN_HAVE_FULL_LANG_DECL_P (t))
-    size = sizeof (struct lang_decl);
+  int sel;
+
+  if (TREE_CODE (t) == FUNCTION_DECL)
+    sel = 1, size = sizeof (struct lang_decl_fn);
+  else if (TREE_CODE (t) == NAMESPACE_DECL)
+    sel = 2, size = sizeof (struct lang_decl_ns);
+  else if (LANG_DECL_HAS_MIN (t))
+    sel = 0, size = sizeof (struct lang_decl_min);
   else
-    size = sizeof (struct lang_decl_flags);
+    gcc_unreachable ();
 
   ld = GGC_CNEWVAR (struct lang_decl, size);
 
-  ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
-  ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
-  ld->decl_flags.u2sel = 0;
-  if (ld->decl_flags.can_be_full)
-    ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
+  ld->u.base.selector = sel;
 
   DECL_LANG_SPECIFIC (t) = ld;
   if (current_lang_name == lang_name_cplusplus
@@ -572,10 +573,15 @@ cxx_dup_lang_specific_decl (tree node)
   if (! DECL_LANG_SPECIFIC (node))
     return;
 
-  if (!CAN_HAVE_FULL_LANG_DECL_P (node))
-    size = sizeof (struct lang_decl_flags);
+  if (TREE_CODE (node) == FUNCTION_DECL)
+    size = sizeof (struct lang_decl_fn);
+  else if (TREE_CODE (node) == NAMESPACE_DECL)
+    size = sizeof (struct lang_decl_ns);
+  else if (LANG_DECL_HAS_MIN (node))
+    size = sizeof (struct lang_decl_min);
   else
-    size = sizeof (struct lang_decl);
+    gcc_unreachable ();
+
   ld = GGC_NEWVAR (struct lang_decl, size);
   memcpy (ld, DECL_LANG_SPECIFIC (node), size);
   DECL_LANG_SPECIFIC (node) = ld;
index f7d9d41..fe2f6fd 100644 (file)
@@ -1088,43 +1088,54 @@ write_unqualified_name (const tree decl)
 {
   MANGLE_TRACE_TREE ("unqualified-name", decl);
 
-  if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_CONSTRUCTOR_P (decl))
-    write_special_name_constructor (decl);
-  else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
-    write_special_name_destructor (decl);
-  else if (DECL_NAME (decl) == NULL_TREE)
+  if (DECL_NAME (decl) == NULL_TREE)
     {
       gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
       write_source_name (DECL_ASSEMBLER_NAME (decl));
+      return;
     }
-  else if (DECL_CONV_FN_P (decl))
+  else if (DECL_DECLARES_FUNCTION_P (decl))
     {
-      /* Conversion operator. Handle it right here.
-          <operator> ::= cv <type>  */
-      tree type;
-      if (decl_is_template_id (decl, NULL))
+      bool found = true;
+      if (DECL_CONSTRUCTOR_P (decl))
+       write_special_name_constructor (decl);
+      else if (DECL_DESTRUCTOR_P (decl))
+       write_special_name_destructor (decl);
+      else if (DECL_CONV_FN_P (decl))
        {
-         tree fn_type;
-         fn_type = get_mostly_instantiated_function_type (decl);
-         type = TREE_TYPE (fn_type);
+         /* Conversion operator. Handle it right here.
+            <operator> ::= cv <type>  */
+         tree type;
+         if (decl_is_template_id (decl, NULL))
+           {
+             tree fn_type;
+             fn_type = get_mostly_instantiated_function_type (decl);
+             type = TREE_TYPE (fn_type);
+           }
+         else
+           type = DECL_CONV_FN_TYPE (decl);
+         write_conversion_operator_name (type);
+       }
+      else if (DECL_OVERLOADED_OPERATOR_P (decl))
+       {
+         operator_name_info_t *oni;
+         if (DECL_ASSIGNMENT_OPERATOR_P (decl))
+           oni = assignment_operator_name_info;
+         else
+           oni = operator_name_info;
+
+         write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
        }
       else
-       type = DECL_CONV_FN_TYPE (decl);
-      write_conversion_operator_name (type);
-    }
-  else if (DECL_OVERLOADED_OPERATOR_P (decl))
-    {
-      operator_name_info_t *oni;
-      if (DECL_ASSIGNMENT_OPERATOR_P (decl))
-       oni = assignment_operator_name_info;
-      else
-       oni = operator_name_info;
+       found = false;
 
-      write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name);
+      if (found)
+       return;
     }
-  else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
-          && DECL_NAMESPACE_SCOPE_P (decl)
-          && decl_linkage (decl) == lk_internal)
+
+  if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
+      && DECL_NAMESPACE_SCOPE_P (decl)
+      && decl_linkage (decl) == lk_internal)
     {
       MANGLE_TRACE_TREE ("local-source-name", decl);
       write_char ('L');
index af58afe..4e22a20 100644 (file)
@@ -277,7 +277,6 @@ make_alias_for (tree function, tree newid)
   DECL_SAVED_FUNCTION_DATA (alias) = NULL;
   DECL_DESTRUCTOR_P (alias) = 0;
   DECL_CONSTRUCTOR_P (alias) = 0;
-  DECL_CLONED_FUNCTION (alias) = NULL_TREE;
   DECL_EXTERNAL (alias) = 0;
   DECL_ARTIFICIAL (alias) = 1;
   DECL_NO_STATIC_CHAIN (alias) = 1;
index c65ffcd..b93c811 100644 (file)
@@ -3458,17 +3458,6 @@ build_template_decl (tree decl, tree parms, bool member_template_p)
   DECL_TEMPLATE_PARMS (tmpl) = parms;
   DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
   DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p;
-  if (DECL_LANG_SPECIFIC (decl))
-    {
-      DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl);
-      DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl);
-      DECL_DESTRUCTOR_P (tmpl) = DECL_DESTRUCTOR_P (decl);
-      DECL_NONCONVERTING_P (tmpl) = DECL_NONCONVERTING_P (decl);
-      DECL_ASSIGNMENT_OPERATOR_P (tmpl) = DECL_ASSIGNMENT_OPERATOR_P (decl);
-      if (DECL_OVERLOADED_OPERATOR_P (decl))
-       SET_OVERLOADED_OPERATOR_CODE (tmpl,
-                                     DECL_OVERLOADED_OPERATOR_P (decl));
-    }
 
   return tmpl;
 }
@@ -3792,6 +3781,7 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
   if (current_class_type
       && !TYPE_BEING_DEFINED (current_class_type)
       && DECL_LANG_SPECIFIC (decl)
+      && DECL_DECLARES_FUNCTION_P (decl)
       /* If this is either a friend defined in the scope of the class
         or a member function.  */
       && (DECL_FUNCTION_MEMBER_P (decl)
@@ -8594,13 +8584,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
        DECL_SAVED_TREE (r) = NULL_TREE;
        DECL_STRUCT_FUNCTION (r) = NULL;
        TREE_USED (r) = 0;
-       if (DECL_CLONED_FUNCTION (r))
-         {
-           DECL_CLONED_FUNCTION (r) = tsubst (DECL_CLONED_FUNCTION (t),
-                                              args, complain, t);
-           TREE_CHAIN (r) = TREE_CHAIN (DECL_CLONED_FUNCTION (r));
-           TREE_CHAIN (DECL_CLONED_FUNCTION (r)) = r;
-         }
+       /* We'll re-clone as appropriate in instantiate_template.  */
+       DECL_CLONED_FUNCTION (r) = NULL_TREE;
 
        /* Set up the DECL_TEMPLATE_INFO for R.  There's no need to do
           this in the special friend case mentioned above where
@@ -12330,8 +12315,10 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
       tree spec;
       tree clone;
 
-      spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr,
-                                  complain);
+      /* Use DECL_ABSTRACT_ORIGIN because only FUNCTION_DECLs have
+        DECL_CLONED_FUNCTION.  */
+      spec = instantiate_template (DECL_ABSTRACT_ORIGIN (tmpl),
+                                  targ_ptr, complain);
       if (spec == error_mark_node)
        return error_mark_node;
 
index 2452abc..ec7a471 100644 (file)
@@ -65,10 +65,6 @@ cxx_print_decl (FILE *file, tree node, int indent)
       && DECL_PENDING_INLINE_INFO (node))
     fprintf (file, " pending-inline-info %p",
             (void *) DECL_PENDING_INLINE_INFO (node));
-  if (TREE_CODE (node) == TYPE_DECL
-      && DECL_SORTED_FIELDS (node))
-    fprintf (file, " sorted-fields %p",
-            (void *) DECL_SORTED_FIELDS (node));
   if ((TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL)
       && DECL_TEMPLATE_INFO (node))
     fprintf (file, " template-info %p",
@@ -95,13 +91,6 @@ cxx_print_type (FILE *file, tree node, int indent)
        print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4);
       return;
 
-    case RECORD_TYPE:
-    case UNION_TYPE:
-      indent_to (file, indent + 4);
-      fprintf (file, "full-name \"%s\"",
-              type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
-      break;
-
     default:
       return;
     }
@@ -113,6 +102,10 @@ cxx_print_type (FILE *file, tree node, int indent)
   if (! CLASS_TYPE_P (node))
     return;
 
+  indent_to (file, indent + 4);
+  fprintf (file, "full-name \"%s\"",
+          type_as_string (node, TFF_CLASS_KEY_OR_ENUM));
+
   indent_to (file, indent + 3);
 
   if (TYPE_NEEDS_CONSTRUCTING (node))
@@ -140,6 +133,9 @@ cxx_print_type (FILE *file, tree node, int indent)
     fputs (" delete[]", file);
   if (TYPE_HAS_ASSIGN_REF (node))
     fputs (" this=(X&)", file);
+  if (CLASSTYPE_SORTED_FIELDS (node))
+    fprintf (file, " sorted-fields %p",
+            (void *) CLASSTYPE_SORTED_FIELDS (node));
 
   if (TREE_CODE (node) == RECORD_TYPE)
     {
index 4f36e64..c50cc4a 100644 (file)
@@ -395,12 +395,10 @@ lookup_field_1 (tree type, tree name, bool want_type)
        The TYPE_FIELDS of TYPENAME_TYPE is its TYPENAME_TYPE_FULLNAME.  */
     return NULL_TREE;
 
-  if (TYPE_NAME (type)
-      && DECL_LANG_SPECIFIC (TYPE_NAME (type))
-      && DECL_SORTED_FIELDS (TYPE_NAME (type)))
+  if (CLASSTYPE_SORTED_FIELDS (type))
     {
-      tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0];
-      int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len;
+      tree *fields = &CLASSTYPE_SORTED_FIELDS (type)->elts[0];
+      int lo = 0, hi = CLASSTYPE_SORTED_FIELDS (type)->len;
       int i;
 
       while (lo < hi)
index 9a43863..59a5312 100644 (file)
@@ -3861,7 +3861,7 @@ finish_omp_threadprivate (tree vars)
              /* Make sure that DECL_DISCRIMINATOR_P continues to be true
                 after the allocation of the lang_decl structure.  */
              if (DECL_DISCRIMINATOR_P (v))
-               DECL_LANG_SPECIFIC (v)->decl_flags.u2sel = 1;
+               DECL_LANG_SPECIFIC (v)->u.base.u2sel = 1;
            }
 
          if (! DECL_THREAD_LOCAL_P (v))
index d7d4d7e..23ea945 100644 (file)
@@ -1,3 +1,7 @@
+2009-07-03  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/template/pure1.C: Expect another error.
+
 2009-07-03  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/40640
index ca9b94e..68dbe6b 100644 (file)
@@ -2,5 +2,5 @@
 
 struct A
 {
-  template<int> void foo() = 1; // { dg-error "pure" }
+  template<int> void foo() = 1; // { dg-error "pure|non-virtual" }
 };