+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
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)
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
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;
/* 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;
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 */
#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. */
}
}
- SET_CLASSTYPE_MARKED (ref);
+ TYPE_MARKED_P (ref) = 1;
/* The binfo slot should be empty, unless this is an (ill-formed)
redefinition. */
continue;
}
- if (CLASSTYPE_MARKED (basetype))
+ if (TYPE_MARKED_P (basetype))
{
if (basetype == ref)
error ("recursive type `%T' undefined", basetype);
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;
|= 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,
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;
+ }
}
\f
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;
}
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);
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. */
}
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);