diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 05cb728c60d8896838650e0a149617a1f736955a..f88f663fedf1a1ff03b313c3594f25c296ec4889 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,21 @@
+2004-09-22  Nathan Sidwell  <nathan@codesourcery.com>
+
+	* cp-tree.h (struct lang_type_class): Remove marked flags, add
+	diamond_shaped and repeated_base flags.  Reorder to keep 8-bit blocks.
+	(TYPE_MARKED_P): New.
+	(CLASSTYPE_DIAMOND_SHAPED_P, CLASSTYPE_REPEATED_BASE_P): New.
+	(CLASSTYPE_MARKED_N, SET_CLASSTYPE_MARKED_N,
+	CLEAR_CLASSTYPE_MARKED_N): Remove.
+	(CLASSTYPE_MARKED_*, SET_CLASSTYPE_MARKED_*,
+	CLEAR_CLASSTYPE_MARKED_*): Remove.
+	* decl.c (xref_basetypes): Use TYPE_MARKED_P. Determine diamond
+	shaped and repeated base properties.
+	* lex.c (cxx_make_type): Don't clear TYPE_ALIAS_SET.
+	* rtti.c (dfs_class_hint_mark, dfs_class_hint_unmark,
+	class_hint_flags): Remove.
+	(get_pseudo_ti_init): Use CLASSTYPE_REPEATED_BASE_P and
+	CLASSTYPE_DIAMOND_SHAPED_P.
+	
 2004-09-21  Ziemowit Laski  <zlaski@apple.com>
 
 	* cp-lang.c (LANG_HOOKS_FOLD_OBJ_TYPE_REF): Moved here from
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 19158e9975046b3e75a4708c3467e6b80b0ac52a..417d179ff0dd34f444b9dd1bc376efd5fd23e239 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -56,7 +56,6 @@ struct diagnostic_context;
       ICS_ELLIPSIS_FLAG (in _CONV)
       DECL_INITIALIZED_P (in VAR_DECL)
    2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE)
-      TYPE_POLYMORPHIC_P (in _TYPE)
       ICS_THIS_FLAG (in _CONV)
       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
       STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST)
@@ -73,6 +72,7 @@ struct diagnostic_context;
       DECL_VTABLE_OR_VTT_P (in VAR_DECL)
    6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE)
       DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL)
+      TYPE_MARKED_P (in _TYPE)
 
    Usage of TYPE_LANG_FLAG_?:
    0: TYPE_DEPENDENT_P
@@ -1001,22 +1001,23 @@ struct lang_type_class GTY(())
   unsigned non_zero_init : 1;
   unsigned empty_p : 1;
 
-  unsigned marks: 6;
   unsigned vec_new_uses_cookie : 1;
   unsigned declared_class : 1;
-
+  unsigned diamond_shaped : 1;
+  unsigned repeated_base : 1;
   unsigned being_defined : 1;
   unsigned redefined : 1;
   unsigned debug_requested : 1;
-  unsigned use_template : 2;
   unsigned fields_readonly : 1;
+  
+  unsigned use_template : 2;
   unsigned ptrmemfunc_flag : 1;
   unsigned was_anonymous : 1;
-
   unsigned lazy_default_ctor : 1;
   unsigned lazy_copy_ctor : 1;
   unsigned lazy_assignment_op : 1;
   unsigned has_const_init_ref : 1;
+  
   unsigned has_complex_init_ref : 1;
   unsigned has_complex_assign_ref : 1;
   unsigned non_aggregate : 1;
@@ -1029,7 +1030,7 @@ struct lang_type_class GTY(())
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 8;
+  unsigned dummy : 12;
 
   tree primary_base;
   VEC (tree_pair_s) *vcall_indices;
@@ -1158,6 +1159,19 @@ struct lang_type GTY(())
    convenient, don't reprocess any methods that appear in its redefinition.  */
 #define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined)
 
+/* Mark bits for repeated base checks.  */
+#define TYPE_MARKED_P(NODE) TREE_LANG_FLAG_6 (TYPE_CHECK (NODE))
+
+/* Non-zero if the class NODE has multiple paths to the same (virtual)
+   base object.  */
+#define CLASSTYPE_DIAMOND_SHAPED_P(NODE) \
+  (LANG_TYPE_CLASS_CHECK(NODE)->diamond_shaped)
+
+/* Non-zero if the class NODE has multiple instances of the same base
+   type.  */
+#define CLASSTYPE_REPEATED_BASE_P(NODE) \
+  (LANG_TYPE_CLASS_CHECK(NODE)->repeated_base)
+
 /* The member function with which the vtable will be emitted:
    the first noninline non-pure-virtual member function.  NULL_TREE
    if there is no key function or if this is a class template */
@@ -1203,47 +1217,6 @@ struct lang_type GTY(())
 #define CLASSTYPE_DESTRUCTORS(NODE) \
   (VEC_index (tree, CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_DESTRUCTOR_SLOT))
 
-/* Mark bits for depth-first and breath-first searches.  */
-
-/* Get the value of the Nth mark bit.  */
-#define CLASSTYPE_MARKED_N(NODE, N)				\
-  (((CLASS_TYPE_P (NODE) ? LANG_TYPE_CLASS_CHECK (NODE)->marks	\
-     : ((unsigned) TYPE_ALIAS_SET (NODE))) & (1 << (N))) != 0)
-
-/* Set the Nth mark bit.  */
-#define SET_CLASSTYPE_MARKED_N(NODE, N)				\
-  (CLASS_TYPE_P (NODE)						\
-   ? (void) (LANG_TYPE_CLASS_CHECK (NODE)->marks |= (1 << (N)))	\
-   : (void) (TYPE_ALIAS_SET (NODE) |= (1 << (N))))
-
-/* Clear the Nth mark bit.  */
-#define CLEAR_CLASSTYPE_MARKED_N(NODE, N)			\
-  (CLASS_TYPE_P (NODE)						\
-   ? (void) (LANG_TYPE_CLASS_CHECK (NODE)->marks &= ~(1 << (N)))	\
-   : (void) (TYPE_ALIAS_SET (NODE) &= ~(1 << (N))))
-
-/* Get the value of the mark bits.  */
-#define CLASSTYPE_MARKED(NODE) CLASSTYPE_MARKED_N (NODE, 0)
-#define CLASSTYPE_MARKED2(NODE) CLASSTYPE_MARKED_N (NODE, 1)
-#define CLASSTYPE_MARKED3(NODE) CLASSTYPE_MARKED_N (NODE, 2)
-#define CLASSTYPE_MARKED4(NODE) CLASSTYPE_MARKED_N (NODE, 3)
-#define CLASSTYPE_MARKED5(NODE) CLASSTYPE_MARKED_N (NODE, 4)
-#define CLASSTYPE_MARKED6(NODE) CLASSTYPE_MARKED_N (NODE, 5)
-
-/* Macros to modify the above flags */
-#define SET_CLASSTYPE_MARKED(NODE)    SET_CLASSTYPE_MARKED_N (NODE, 0)
-#define CLEAR_CLASSTYPE_MARKED(NODE)  CLEAR_CLASSTYPE_MARKED_N (NODE, 0)
-#define SET_CLASSTYPE_MARKED2(NODE)   SET_CLASSTYPE_MARKED_N (NODE, 1)
-#define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 1)
-#define SET_CLASSTYPE_MARKED3(NODE)   SET_CLASSTYPE_MARKED_N (NODE, 2)
-#define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 2)
-#define SET_CLASSTYPE_MARKED4(NODE)   SET_CLASSTYPE_MARKED_N (NODE, 3)
-#define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 3)
-#define SET_CLASSTYPE_MARKED5(NODE)   SET_CLASSTYPE_MARKED_N (NODE, 4)
-#define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 4)
-#define SET_CLASSTYPE_MARKED6(NODE)   SET_CLASSTYPE_MARKED_N (NODE, 5)
-#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 5)
-
 /* A dictionary of the nested user-defined-types (class-types, or enums)
    found within this class.  This table includes nested member class
    templates.  */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 463fa60ab1268d187e396f93c340be28ae78e400..73f54d92809067ae43baa04bb9b4525a4e128668 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9228,7 +9228,7 @@ xref_basetypes (tree ref, tree base_list)
 	}
     }
 
-  SET_CLASSTYPE_MARKED (ref);
+  TYPE_MARKED_P (ref) = 1;
 
   /* The binfo slot should be empty, unless this is an (ill-formed)
      redefinition.  */
@@ -9286,7 +9286,7 @@ xref_basetypes (tree ref, tree base_list)
 	  continue;
 	}
 
-      if (CLASSTYPE_MARKED (basetype))
+      if (TYPE_MARKED_P (basetype))
 	{
 	  if (basetype == ref)
 	    error ("recursive type `%T' undefined", basetype);
@@ -9294,7 +9294,7 @@ xref_basetypes (tree ref, tree base_list)
 	    error ("duplicate base type `%T' invalid", basetype);
 	  continue;
 	}
-      SET_CLASSTYPE_MARKED (basetype);
+      TYPE_MARKED_P (basetype) = 1;
 
       if (TYPE_FOR_JAVA (basetype) && (current_lang_depth () == 0))
 	TYPE_FOR_JAVA (ref) = 1;
@@ -9313,6 +9313,10 @@ xref_basetypes (tree ref, tree base_list)
 	    |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
 	  TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
 	  TYPE_HAS_CONVERSION (ref) |= TYPE_HAS_CONVERSION (basetype);
+	  CLASSTYPE_DIAMOND_SHAPED_P (ref)
+	    |= CLASSTYPE_DIAMOND_SHAPED_P (basetype);
+	  CLASSTYPE_REPEATED_BASE_P (ref)
+	    |= CLASSTYPE_REPEATED_BASE_P (basetype);
 	}
 
       base_binfo = copy_binfo (base_binfo, basetype, ref,
@@ -9324,10 +9328,36 @@ xref_basetypes (tree ref, tree base_list)
       BINFO_BASE_ACCESS_APPEND (binfo, access);
     }
 
+  if (VEC_space (tree, CLASSTYPE_VBASECLASSES (ref), 1))
+    /* If we have space in the vbase vector, we must have shared at
+       least one of them, and are therefore diamond shaped.  */
+    CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1;
+
   /* Unmark all the types.  */
   for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-    CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (base_binfo));
-  CLEAR_CLASSTYPE_MARKED (ref);
+    TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
+  TYPE_MARKED_P (ref) = 0;
+
+  /* Now see if we have a repeated base type.  */
+  if (!CLASSTYPE_REPEATED_BASE_P (ref))
+    {
+      for (base_binfo = binfo; base_binfo;
+	   base_binfo = TREE_CHAIN (base_binfo))
+	{
+	  if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
+	    {
+	      CLASSTYPE_REPEATED_BASE_P (ref) = 1;
+	      break;
+	    }
+	  TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 1;
+	}
+      for (base_binfo = binfo; base_binfo;
+	   base_binfo = TREE_CHAIN (base_binfo))
+	if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
+	  TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
+	else
+	  break;
+    }
 }
 
 
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 82dc35ec999796dee84ad36654c6089ffc99cc33..5addca4988b3bbb7625bbeb5cdeaf34ad2ae4f81 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -782,11 +782,6 @@ cxx_make_type (enum tree_code code)
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
       CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
     }
-  else
-    /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
-       TYPE_ALIAS_SET is initialized to -1 by default, so we must
-       clear it here.  */
-    TYPE_ALIAS_SET (t) = 0;
 
   return t;
 }
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 4219d301260bb624664f9b3a089d9e4db02577e3..2dc05ad3cab8d87dc87127ed730073454e3fa36d 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -89,9 +89,6 @@ static int qualifier_flags (tree);
 static bool target_incomplete_p (tree);
 static tree tinfo_base_init (tree, tree);
 static tree generic_initializer (tree, tree);
-static tree dfs_class_hint_mark (tree, void *);
-static tree dfs_class_hint_unmark (tree, void *);
-static int class_hint_flags (tree);
 static tree class_initializer (tree, tree, tree);
 static tree create_pseudo_type_info (const char *, int, ...);
 static tree get_pseudo_ti_init (tree, tree);
@@ -924,59 +921,6 @@ ptm_initializer (tree desc, tree target)
   return init;  
 }
 
-/* Check base BINFO to set hint flags in *DATA, which is really an int.
-   We use CLASSTYPE_MARKED to tag types we've found as non-virtual bases and
-   CLASSTYPE_MARKED2 to tag those which are virtual bases. Remember it is
-   possible for a type to be both a virtual and non-virtual base.  */
-
-static tree
-dfs_class_hint_mark (tree binfo, void *data)
-{
-  tree basetype = BINFO_TYPE (binfo);
-  int *hint = (int *) data;
-  
-  if (BINFO_VIRTUAL_P (binfo))
-    {
-      if (CLASSTYPE_MARKED (basetype))
-        *hint |= 1;
-      if (CLASSTYPE_MARKED2 (basetype))
-        *hint |= 2;
-      SET_CLASSTYPE_MARKED2 (basetype);
-    }
-  else
-    {
-      if (CLASSTYPE_MARKED (basetype) || CLASSTYPE_MARKED2 (basetype))
-        *hint |= 1;
-      SET_CLASSTYPE_MARKED (basetype);
-    }
-  return NULL_TREE;
-}
-
-/* Clear the base's dfs marks, after searching for duplicate bases.  */
-
-static tree
-dfs_class_hint_unmark (tree binfo, void *data ATTRIBUTE_UNUSED)
-{
-  tree basetype = BINFO_TYPE (binfo);
-  
-  CLEAR_CLASSTYPE_MARKED (basetype);
-  CLEAR_CLASSTYPE_MARKED2 (basetype);
-  return NULL_TREE;
-}
-
-/* Determine the hint flags describing the features of a class's hierarchy.  */
-
-static int
-class_hint_flags (tree type)
-{
-  int hint_flags = 0;
-  
-  dfs_walk (TYPE_BINFO (type), dfs_class_hint_mark, NULL, &hint_flags);
-  dfs_walk (TYPE_BINFO (type), dfs_class_hint_unmark, NULL, NULL);
-  
-  return hint_flags;
-}
-        
 /* Return the CONSTRUCTOR expr for a type_info of class TYPE.
    DESC provides information about the particular __class_type_info derivation,
    which adds hint flags and TRAIL initializers to the type_info base.  */
@@ -1058,7 +1002,8 @@ get_pseudo_ti_init (tree type, tree var_desc)
 	}
       else
         {
-	  int hint = class_hint_flags (type);
+	  int hint = ((CLASSTYPE_REPEATED_BASE_P (type) << 0)
+		      | (CLASSTYPE_DIAMOND_SHAPED_P (type) << 1));
 	  tree binfo = TYPE_BINFO (type);
           int nbases = BINFO_N_BASE_BINFOS (binfo);
 	  VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo);