aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c202
1 files changed, 125 insertions, 77 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 6b8f880..4bceaa1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -81,7 +81,6 @@ tree previous_class_type; /* _TYPE: the previous type that was a class */
tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list
when leaving an outermost class scope. */
static tree get_vfield_name PROTO((tree));
-tree the_null_vtable_entry;
/* Way of stacking language names. */
tree *current_lang_base, *current_lang_stack;
@@ -109,6 +108,7 @@ tree access_private_virtual_node; /* 6 */
/* Variables shared between class.c and call.c. */
+#ifdef GATHER_STATISTICS
int n_vtables = 0;
int n_vtable_entries = 0;
int n_vtable_searches = 0;
@@ -117,6 +117,7 @@ int n_convert_harshness = 0;
int n_compute_conversion_costs = 0;
int n_build_method_call = 0;
int n_inner_fields_searched = 0;
+#endif
/* Virtual baseclass things. */
tree
@@ -362,7 +363,6 @@ build_vbase_path (code, type, expr, path, alias_this)
classes. We do all overrides after we layout virtual base classes.
*/
static tree pending_hard_virtuals;
-static int doing_hard_virtuals;
/* Build an entry in the virtual function table.
DELTA is the offset for the `this' pointer.
@@ -698,8 +698,7 @@ prepare_fresh_vtable (binfo, for_type)
for_type, and we really want different names. (mrs) */
tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
- tree path, offset;
- int result;
+ tree offset;
/* Remember which class this vtable is really for. */
DECL_CONTEXT (new_decl) = for_type;
@@ -741,6 +740,7 @@ prepare_fresh_vtable (binfo, for_type)
SET_BINFO_NEW_VTABLE_MARKED (binfo);
}
+#if 0
/* Access the virtual function table entry that logically
contains BASE_FNDECL. VIRTUALS is the virtual function table's
initializer. We can run off the end, when dealing with virtual
@@ -765,6 +765,7 @@ get_vtable_entry (virtuals, base_fndecl)
}
return virtuals;
}
+#endif
/* Put new entry ENTRY into virtual function table initializer
VIRTUALS.
@@ -913,7 +914,7 @@ add_method (type, fields, method)
decl = copy_node (method);
if (DECL_RTL (decl) == 0
&& (!processing_template_decl
- || !uses_template_parms (decl)))
+ || !uses_template_parms (decl)))
{
make_function_rtl (decl);
DECL_RTL (method) = DECL_RTL (decl);
@@ -1087,8 +1088,16 @@ delete_duplicate_fields_1 (field, fields)
cp_error_at ("duplicate nested type `%D'", x);
else if (TREE_CODE (field) == TYPE_DECL
|| TREE_CODE (x) == TYPE_DECL)
- cp_error_at ("duplicate field `%D' (as type and non-type)",
- x);
+ {
+ /* Hide tag decls. */
+ if ((TREE_CODE (field) == TYPE_DECL
+ && DECL_ARTIFICIAL (field))
+ || (TREE_CODE (x) == TYPE_DECL
+ && DECL_ARTIFICIAL (x)))
+ continue;
+ cp_error_at ("duplicate field `%D' (as type and non-type)",
+ x);
+ }
else
cp_error_at ("duplicate member `%D'", x);
if (prev == 0)
@@ -1658,7 +1667,6 @@ finish_struct_bits (t, max_has_virtual)
int max_has_virtual;
{
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
- tree method_vec = CLASSTYPE_METHOD_VEC (t);
/* Fix up variants (if any). */
tree variants = TYPE_NEXT_VARIANT (t);
@@ -1677,6 +1685,7 @@ finish_struct_bits (t, max_has_virtual)
/* Copy whatever these are holding today. */
TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);
TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);
+ TYPE_FIELDS (variants) = TYPE_FIELDS (t);
variants = TYPE_NEXT_VARIANT (variants);
}
@@ -2167,7 +2176,7 @@ overrides (fndecl, base_fndecl)
return 0;
if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
{
- tree rettype, base_rettype, types, base_types;
+ tree types, base_types;
#if 0
retypes = TREE_TYPE (TREE_TYPE (fndecl));
base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl));
@@ -2291,7 +2300,6 @@ modify_one_vtable (binfo, t, fndecl, pfn)
tree binfo, t, fndecl, pfn;
{
tree virtuals = BINFO_VIRTUALS (binfo);
- tree old_rtti;
unsigned HOST_WIDE_INT n;
/* update rtti entry */
@@ -2711,8 +2719,6 @@ get_basefndecls (fndecl, t)
while (methods)
{
- tree purpose = NULL_TREE;
-
if (TREE_CODE (methods) == FUNCTION_DECL
&& DECL_VINDEX (methods) != NULL_TREE
&& DECL_NAME (fndecl) == DECL_NAME (methods))
@@ -2728,7 +2734,6 @@ get_basefndecls (fndecl, t)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
tree basetype = BINFO_TYPE (base_binfo);
- tree methods = TYPE_METHODS (basetype);
base_fndecls = chainon (get_basefndecls (fndecl, basetype),
base_fndecls);
@@ -2913,8 +2918,6 @@ finish_struct_anon (t)
tree* uelt = &TYPE_FIELDS (TREE_TYPE (field));
for (; *uelt; uelt = &TREE_CHAIN (*uelt))
{
- tree offset, x;
-
if (TREE_CODE (*uelt) != FIELD_DECL)
continue;
@@ -3190,8 +3193,11 @@ finish_struct_1 (t, attributes, warn_anon)
&has_virtual, x, t);
if (DECL_ABSTRACT_VIRTUAL_P (x))
abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals);
+#if 0
+ /* XXX Why did I comment this out? (jason) */
else
TREE_USED (x) = 1;
+#endif
}
}
@@ -3377,9 +3383,26 @@ finish_struct_1 (t, attributes, warn_anon)
/* Detect and ignore out of range field width. */
if (DECL_INITIAL (x))
{
- register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
+ tree w = DECL_INITIAL (x);
+ register int width;
- if (width < 0)
+ /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
+ STRIP_NOPS (w);
+
+ /* detect invalid field size. */
+ if (TREE_CODE (w) == CONST_DECL)
+ w = DECL_INITIAL (w);
+ else if (TREE_READONLY_DECL_P (w))
+ w = decl_constant_value (w);
+
+ if (TREE_CODE (w) != INTEGER_CST)
+ {
+ cp_error_at ("bit-field `%D' width not an integer constant",
+ x);
+ DECL_INITIAL (x) = NULL_TREE;
+ }
+ else if (width = TREE_INT_CST_LOW (w),
+ width < 0)
{
DECL_INITIAL (x) = NULL;
cp_error_at ("negative width in bit-field `%D'", x);
@@ -3789,6 +3812,8 @@ finish_struct_1 (t, attributes, warn_anon)
{
tree name = DECL_NAME (x);
int i = /*TREE_VEC_ELT (method_vec, 0) ? 0 : */ 1;
+ if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))
+ continue;
for (; i < n_methods; ++i)
if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
{
@@ -3842,7 +3867,6 @@ finish_struct_1 (t, attributes, warn_anon)
/* Now fix up any virtual base class types that we left lying
around. We must get these done before we try to lay out the
virtual function table. */
- doing_hard_virtuals = 1;
pending_hard_virtuals = nreverse (pending_hard_virtuals);
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
@@ -3949,8 +3973,6 @@ finish_struct_1 (t, attributes, warn_anon)
}
}
- doing_hard_virtuals = 0;
-
/* Under our model of GC, every C++ class gets its own virtual
function table, at least virtually. */
if (pending_virtuals || (flag_rtti && TYPE_VIRTUAL_P (t)))
@@ -4090,42 +4112,6 @@ finish_struct_1 (t, attributes, warn_anon)
}
}
- /* Now add the tags, if any, to the list of TYPE_DECLs
- defined for this type. */
- if (CLASSTYPE_TAGS (t))
- {
- x = CLASSTYPE_TAGS (t);
- last_x = tree_last (TYPE_FIELDS (t));
- while (x)
- {
- tree tag = TYPE_NAME (TREE_VALUE (x));
-
- /* Check to see if it is already there. This will be the case if
- was do enum { red; } color; */
- if (chain_member (tag, TYPE_FIELDS (t)))
- {
- x = TREE_CHAIN (x);
- continue;
- }
-
-#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG)
- {
- /* Notify dwarfout.c that this TYPE_DECL node represent a
- gratuitous typedef. */
- DECL_IGNORED_P (tag) = 1;
- }
-#endif /* DWARF_DEBUGGING_INFO */
-
- TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
- x = TREE_CHAIN (x);
- last_x = chainon (last_x, tag);
- }
- if (TYPE_FIELDS (t) == NULL_TREE)
- TYPE_FIELDS (t) = last_x;
- CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
- }
-
if (TYPE_HAS_CONSTRUCTOR (t))
{
tree vfields = CLASSTYPE_VFIELDS (t);
@@ -4185,17 +4171,12 @@ finish_struct_1 (t, attributes, warn_anon)
/* Make the rtl for any new vtables we have created, and unmark
the base types we marked. */
finish_vtbls (TYPE_BINFO (t), 1, t);
- TYPE_BEING_DEFINED (t) = 0;
hack_incomplete_structures (t);
#if 0
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
#endif
- if (current_class_type)
- popclass (0);
- else
- error ("trying to finish struct, but kicked out due to previous parse errors.");
resume_momentary (old);
@@ -4235,9 +4216,12 @@ finish_struct_1 (t, attributes, warn_anon)
= (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0);
else if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
+#if 0
+ /* XXX do something about this. */
else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
/* Only a first approximation! */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
+#endif
}
else if (CLASSTYPE_INTERFACE_ONLY (t))
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
@@ -4336,6 +4320,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
if (TREE_CODE (x) == FUNCTION_DECL)
{
+ DECL_CLASS_CONTEXT (x) = t;
if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x);
/* Link x onto end of TYPE_METHODS. */
@@ -4354,6 +4339,8 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
DECL_RESULT (x) = n;
}
#endif
+ if (TREE_CODE (x) != TYPE_DECL)
+ DECL_FIELD_CONTEXT (x) = t;
if (! fields)
fields = x;
@@ -4372,17 +4359,79 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
}
}
+ /* Now add the tags, if any, to the list of TYPE_DECLs
+ defined for this type. */
+ if (CLASSTYPE_TAGS (t))
+ {
+ x = CLASSTYPE_TAGS (t);
+ while (x)
+ {
+ tree tag = TYPE_NAME (TREE_VALUE (x));
+
+ /* Check to see if it is already there. This will be the case if
+ was do enum { red; } color; */
+ if (chain_member (tag, fields))
+ {
+ x = TREE_CHAIN (x);
+ continue;
+ }
+
+#ifdef DWARF_DEBUGGING_INFO
+ if (write_symbols == DWARF_DEBUG)
+ {
+ /* Notify dwarfout.c that this TYPE_DECL node represent a
+ gratuitous typedef. */
+ DECL_IGNORED_P (tag) = 1;
+ }
+#endif /* DWARF_DEBUGGING_INFO */
+
+ TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
+ x = TREE_CHAIN (x);
+ last_x = chainon (last_x, tag);
+ }
+ if (fields == NULL_TREE)
+ fields = last_x;
+ CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
+ }
+
*tail = NULL_TREE;
TYPE_FIELDS (t) = fields;
- if (0 && processing_template_defn)
+ if (processing_template_decl)
{
+ tree d = getdecls ();
+ for (; d; d = TREE_CHAIN (d))
+ {
+ /* If this is the decl for the class or one of the template
+ parms, we've seen all the injected decls. */
+ if ((TREE_CODE (d) == TYPE_DECL
+ && (TREE_TYPE (d) == t
+ || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM))
+ || TREE_CODE (d) == CONST_DECL)
+ break;
+ /* Don't inject TYPE_NESTED_NAMEs. */
+ else if (TREE_MANGLED (DECL_NAME (d))
+ || IDENTIFIER_TEMPLATE (DECL_NAME (d)))
+ continue;
+ DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))
+ = tree_cons (NULL_TREE, d,
+ DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
+ }
CLASSTYPE_METHOD_VEC (t)
= finish_struct_methods (t, TYPE_METHODS (t), 1);
- return t;
- }
+ TYPE_SIZE (t) = integer_zero_node;
+ }
else
- return finish_struct_1 (t, attributes, warn_anon);
+ t = finish_struct_1 (t, attributes, warn_anon);
+
+ TYPE_BEING_DEFINED (t) = 0;
+
+ if (current_class_type)
+ popclass (0);
+ else
+ error ("trying to finish struct, but kicked out due to previous parse errors.");
+
+ return t;
}
/* Return non-zero if the effective type of INSTANCE is static.
@@ -4516,7 +4565,6 @@ init_class_processing ()
access_private_virtual_node = build_int_2 (6, 0);
/* Keep these values lying around. */
- the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node);
base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE);
@@ -4592,6 +4640,9 @@ pushclass (type, modify)
pushlevel_class ();
+ if (CLASSTYPE_TEMPLATE_INFO (type))
+ overload_template_name (type);
+
if (modify)
{
tree tags;
@@ -4604,9 +4655,7 @@ pushclass (type, modify)
else
current_function_decl = NULL_TREE;
- if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
- declare_uninstantiated_type_level ();
- else if (type != previous_class_type || current_class_depth > 1)
+ if (type != previous_class_type || current_class_depth > 1)
{
build_mi_matrix (type);
push_class_decls (type);
@@ -4633,9 +4682,6 @@ pushclass (type, modify)
unuse_fields (type);
}
- if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (type)))
- overload_template_name (current_class_name, 0);
-
for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
{
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
@@ -4686,8 +4732,6 @@ popclass (modify)
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
tags = TREE_CHAIN (tags);
}
- if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)))
- undo_template_name_overload (current_class_name, 0);
}
/* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
@@ -4698,7 +4742,7 @@ popclass (modify)
this really only frees the obstack used for these decls.
That's why it had to be moved down here. */
if (modify)
- pop_class_decls (current_class_type);
+ pop_class_decls ();
current_class_depth--;
current_class_type = *--current_class_stack;
@@ -4724,7 +4768,8 @@ push_nested_class (type, modify)
{
tree context;
- if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type))
+ if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
+ || TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return;
context = DECL_CONTEXT (TYPE_NAME (type));
@@ -4992,7 +5037,10 @@ instantiate_type (lhstype, rhs, complain)
}
}
if (save_elem)
- return save_elem;
+ {
+ mark_used (save_elem);
+ return save_elem;
+ }
}
/* No match found, look for a compatible function. */