+2004-07-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1, build_new_op,
+ check_constructor_callable, build_temp,
+ perform_direct_initialization_of_possible): Pass type directly to
+ lookup_fnfields & build_special_member_call.
+ (build_special_member_call): Accept a type, and complete it.
+ * class.c (finish_stuct_bits): Copy the BINFOs here.
+ * cvt.c (ocp_convert): Pass type directly to
+ build_special_member_call.
+ * decl.c (build_ptrmemfunc_type): Call xref_bastypes here.
+ (xref_basetypes): Allocate the binfo here. Adjust.
+ * init.c (build_init, build_new_1): Pass type directly to
+ build_special_member_call.
+ * lex.c (cxx_make_type): Do not allocate binfo here.
+ * name-lookup.c (arg_assoc_class): Incomplete types have no binfo.
+ * parser.c (cp_parser_class_head): Always call xref_basetypes.
+ * pt.c (instantiate_class_template): Likewise. Inhibit access
+ checking for template friends.
+ * ptree.c (cxx_print_type): Adjust record printing.
+ * search.c (lookup_base): When taking a type, complete it before
+ looking for a binfo.
+ (lookup_member): Delay completing a type.
+ (push_class_decls): Don't walk an incomplete type.
+ (lookup_conversions): Likewise.
+ * semantics.c (finish_stmt_expr_expr): Pass type directly to
+ build_special_member_call.
+ * tree.c (copy_base_binfos): Adjust.
+ (make_binfo): Likewise.
+ * typeck.c (build_modify_expr): Pass type directly to
+ build_special_member_call.
+ * typeck2.c (process_init_constructor): Check a binfo exists.
+ (build_m_component_ref): Allow accessing an incomplete type.
+ (build_functional_cast): Pass type directly to
+ build_special_member_call.
+
2004-07-12 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/2204
|| !DERIVED_FROM_P (totype, fromtype), 20011226);
if (IS_AGGR_TYPE (totype))
- ctors = lookup_fnfields (TYPE_BINFO (totype),
- complete_ctor_identifier,
- 0);
+ ctors = lookup_fnfields (totype, complete_ctor_identifier, 0);
if (IS_AGGR_TYPE (fromtype))
conv_fns = lookup_conversions (fromtype);
{
tree fns;
- fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
+ fns = lookup_fnfields (TREE_TYPE (arg1), fnname, 1);
if (fns == error_mark_node)
{
result = error_mark_node;
build_special_member_call (NULL_TREE,
complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type),
+ type,
LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
| LOOKUP_CONSTRUCTOR_CALLABLE);
}
expr = build_special_member_call (NULL_TREE,
complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type),
- flags);
+ type, flags);
if (warningcount > savew)
*diagnostic_fn = warning;
else if (errorcount > savee)
|| name == deleting_dtor_identifier
|| name == ansi_assopname (NOP_EXPR),
20020712);
+ if (TYPE_P (binfo))
+ {
+ /* Resolve the name. */
+ if (!complete_type_or_else (binfo, NULL_TREE))
+ return error_mark_node;
+
+ binfo = TYPE_BINFO (binfo);
+ }
+
my_friendly_assert (binfo != NULL_TREE, 20020712);
class_type = BINFO_TYPE (binfo);
my_friendly_assert (instance != NULL_TREE, 20020712);
- /* Resolve the name. */
- if (!complete_type_or_else (BINFO_TYPE (binfo), NULL_TREE))
- return error_mark_node;
-
fns = lookup_fnfields (binfo, name, 1);
/* When making a call to a constructor or destructor for a subobject
{
expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type),
- LOOKUP_NORMAL);
+ type, LOOKUP_NORMAL);
return build_cplus_new (type, expr);
}
= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (t);
TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);
+
+ TYPE_BINFO (variants) = TYPE_BINFO (t);
+
/* Copy whatever these are holding today. */
TYPE_VFIELD (variants) = TYPE_VFIELD (t);
TYPE_METHODS (variants) = TYPE_METHODS (t);
TYPE_FIELDS (variants) = TYPE_FIELDS (t);
TYPE_SIZE (variants) = TYPE_SIZE (t);
TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
+
variants = TYPE_NEXT_VARIANT (variants);
}
ctor = build_special_member_call (NULL_TREE,
complete_ctor_identifier,
build_tree_list (NULL_TREE, ctor),
- TYPE_BINFO (type), flags);
+ type, flags);
if (ctor)
return build_cplus_new (type, ctor);
}
= build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
t = make_aggr_type (RECORD_TYPE);
+ xref_basetypes (t, NULL_TREE);
+
/* Let the front-end know this is a pointer to member function... */
TYPE_PTRMEMFUNC_FLAG (t) = 1;
/* ... and not really an aggregate. */
if (ref == error_mark_node)
return;
- if (TREE_CODE (ref) == UNION_TYPE)
- {
- error ("derived union `%T' invalid", ref);
- return;
- }
-
- tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
+ tag_code = TREE_CODE (ref) == UNION_TYPE ? union_type
+ : (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
/* First, make sure that any templates in base-classes are
instantiated. This ensures that if we call ourselves recursively
while (*basep)
{
tree basetype = TREE_VALUE (*basep);
+
if (!(processing_template_decl && uses_template_parms (basetype))
&& !complete_type_or_else (basetype, NULL))
/* An incomplete type. Remove it from the list. */
SET_CLASSTYPE_MARKED (ref);
i = list_length (base_list);
+ /* The binfo slot should be empty, unless this is an (ill-formed)
+ redefinition. */
+ my_friendly_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref), 20040706);
+ TYPE_BINFO (ref) = make_binfo (size_zero_node, ref, NULL_TREE, NULL_TREE);
+
if (i)
{
tree binfo = TYPE_BINFO (ref);
if (CLASS_TYPE_P (basetype))
{
base_binfo = TYPE_BINFO (basetype);
- /* This flag will be in the binfo of the base type, we must
- clear it after copying the base binfos. */
- BINFO_DEPENDENT_BASE_P (base_binfo)
- = dependent_type_p (basetype);
+
+ if (dependent_type_p (basetype))
+ {
+ base_binfo = make_binfo (size_zero_node, basetype,
+ NULL_TREE, NULL_TREE);
+ BINFO_DEPENDENT_BASE_P (base_binfo) = 1;
+ }
+ else
+ my_friendly_assert (base_binfo, 20040706);
}
else
- base_binfo = make_binfo (size_zero_node, basetype,
- NULL_TREE, NULL_TREE);
+ {
+ base_binfo = make_binfo (size_zero_node, basetype,
+ NULL_TREE, NULL_TREE);
+ BINFO_DEPENDENT_BASE_P (base_binfo) = 1;
+ }
TREE_VEC_ELT (binfos, i) = base_binfo;
TREE_VEC_ELT (accesses, i) = access;
inheritance order chain. */
copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
+ if (TREE_CODE (ref) == UNION_TYPE)
+ {
+ if (i)
+ error ("derived union `%T' invalid", ref);
+ }
+
if (TYPE_FOR_JAVA (ref))
{
if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
/* Unmark all the types. */
while (i--)
{
- tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (ref), i));
+ tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (ref), i);
+ tree basetype = BINFO_TYPE (binfo);
CLEAR_CLASSTYPE_MARKED (basetype);
- if (CLASS_TYPE_P (basetype))
- {
- BINFO_VIRTUAL_P (TYPE_BINFO (basetype)) = 0;
- BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0;
- }
+ if (!BINFO_DEPENDENT_BASE_P (binfo))
+ BINFO_VIRTUAL_P (TYPE_BINFO (basetype)) = 0;
}
CLEAR_CLASSTYPE_MARKED (ref);
}
else if (CLASS_TYPE_P (TREE_TYPE (decl)))
expr = build_special_member_call (decl, complete_ctor_identifier,
build_tree_list (NULL_TREE, init),
- TYPE_BINFO (TREE_TYPE (decl)),
+ TREE_TYPE (decl),
LOOKUP_NORMAL|flags);
else
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
{
init_expr = build_special_member_call (init_expr,
complete_ctor_identifier,
- init, TYPE_BINFO (true_type),
+ init, true_type,
LOOKUP_NORMAL);
stable = stabilize_init (init_expr, &init_preeval_expr);
}
presence of parse errors, the normal was of assuring this
might not ever get executed, so we lay it out *immediately*. */
build_pointer_type (t);
-
- TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);
}
else
/* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But,
bool invalid_explicit_specialization_p = false;
bool pop_p = false;
unsigned num_templates;
+ tree bases;
/* Assume no nested-name-specifier will be present. */
*nested_name_specifier_p = false;
is valid. */
if (nested_name_specifier)
pop_p = push_scope (nested_name_specifier);
- /* Now, look for the base-clause. */
- token = cp_lexer_peek_token (parser->lexer);
- if (token->type == CPP_COLON)
- {
- tree bases;
+
+ bases = NULL_TREE;
+
+ /* Get the list of base-classes, if there is one. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ bases = cp_parser_base_clause (parser);
+
+ /* Process the base classes. */
+ xref_basetypes (type, bases);
- /* Get the list of base-classes. */
- bases = cp_parser_base_clause (parser);
- /* Process them. */
- xref_basetypes (type, bases);
- }
/* Leave the scope given by the nested-name-specifier. We will
enter the class scope itself while processing the members. */
if (pop_p)
tree template, args, pattern, t, member;
tree typedecl;
tree pbinfo;
+ tree base_list;
if (type == error_mark_node)
return error_mark_node;
abort ();
#endif
+ base_list = NULL_TREE;
if (BINFO_BASE_BINFOS (pbinfo))
{
- tree base_list = NULL_TREE;
tree pbases = BINFO_BASE_BINFOS (pbinfo);
tree paccesses = BINFO_BASE_ACCESSES (pbinfo);
tree context = TYPE_CONTEXT (type);
/* The list is now in reverse order; correct that. */
base_list = nreverse (base_list);
- /* Now call xref_basetypes to set up all the base-class
- information. */
- xref_basetypes (type, base_list);
-
if (pop_p)
pop_scope (context ? context : global_namespace);
}
+ /* Now call xref_basetypes to set up all the base-class
+ information. */
+ xref_basetypes (type, base_list);
+
/* Now that our base classes are set up, enter the scope of the
class, so that name lookups into base classes, etc. will work
tree r;
if (TREE_CODE (t) == TEMPLATE_DECL)
- ++processing_template_decl;
+ {
+ ++processing_template_decl;
+ push_deferring_access_checks (dk_no_check);
+ }
+
r = tsubst_friend_function (t, args);
- if (TREE_CODE (t) == TEMPLATE_DECL)
- --processing_template_decl;
add_friend (type, r, /*complain=*/false);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ {
+ pop_deferring_access_checks ();
+ --processing_template_decl;
+ }
}
}
}
if (TREE_CODE (node) == RECORD_TYPE)
{
- fprintf (file, " n_parents %d", BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
+ if (TYPE_BINFO (node))
+ fprintf (file, " n_parents=%d",
+ BINFO_N_BASE_BINFOS (TYPE_BINFO (node)));
+ else
+ fprintf (file, " no-binfo");
+
fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node));
if (CLASSTYPE_INTERFACE_ONLY (node))
fprintf (file, " interface-only");
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
#include "config.h"
#include "system.h"
#include "coretypes.h"
tree
lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
{
- tree binfo = NULL; /* The binfo we've found so far. */
- tree t_binfo = NULL;
+ tree binfo = NULL_TREE; /* The binfo we've found so far. */
+ tree t_binfo = NULL_TREE;
base_kind bk;
if (t == error_mark_node || base == error_mark_node)
t_binfo = t;
t = BINFO_TYPE (t);
}
- else
- t_binfo = TYPE_BINFO (t);
-
- /* Ensure that the types are instantiated. */
- t = complete_type (TYPE_MAIN_VARIANT (t));
- base = complete_type (TYPE_MAIN_VARIANT (base));
+ else
+ {
+ t = complete_type (TYPE_MAIN_VARIANT (t));
+ t_binfo = TYPE_BINFO (t);
+ }
- bk = lookup_base_r (t_binfo, base, access, 0, &binfo);
+ base = complete_type (TYPE_MAIN_VARIANT (base));
+
+ if (t_binfo)
+ bk = lookup_base_r (t_binfo, base, access, 0, &binfo);
+ else
+ bk = bk_not_base;
/* Check that the base is unambiguous and accessible. */
if (access != ba_any)
{
my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)), 20030624);
type = xbasetype;
- basetype_path = TYPE_BINFO (type);
- my_friendly_assert (!BINFO_INHERITANCE_CHAIN (basetype_path), 980827);
+ xbasetype = NULL_TREE;
}
if (type == current_class_type && TYPE_BEING_DEFINED (type)
return field;
}
- complete_type (type);
+ type = complete_type (type);
+ if (!basetype_path)
+ basetype_path = TYPE_BINFO (type);
+
+ if (!basetype_path)
+ return NULL_TREE;
#ifdef GATHER_STATISTICS
n_calls_lookup_field++;
{
search_stack = push_search_level (search_stack, &search_obstack);
+ if (!TYPE_BINFO (type))
+ /* This occurs when parsing an invalid declarator id where the
+ scope is incomplete. */
+ return;
+
/* Enter type declarations and mark. */
dfs_walk (TYPE_BINFO (type), dfs_push_type_decls, unmarked_pushdecls_p, 0);
tree conversions = NULL_TREE;
complete_type (type);
- bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
+ if (TYPE_BINFO (type))
+ bfs_walk (TYPE_BINFO (type), add_conversions, 0, &conversions);
for (t = conversions; t; t = TREE_CHAIN (t))
IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0;
expr = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (type), LOOKUP_NORMAL);
+ type, LOOKUP_NORMAL);
expr = build_cplus_new (type, expr);
my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729);
}
tree base_binfo = TREE_VEC_ELT (binfos, ix);
tree new_binfo = NULL_TREE;
- if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo)))
+ if (BINFO_DEPENDENT_BASE_P (base_binfo))
{
my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);
if (TREE_CODE (binfo) == TREE_BINFO)
{
type = BINFO_TYPE (binfo);
- BINFO_DEPENDENT_BASE_P (new_binfo) = BINFO_DEPENDENT_BASE_P (binfo);
+ my_friendly_assert (!BINFO_DEPENDENT_BASE_P (binfo), 20040706);
}
else
{
type = binfo;
binfo = NULL_TREE;
- BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
}
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
BINFO_VTABLE (new_binfo) = vtable;
BINFO_VIRTUALS (new_binfo) = virtuals;
- if (binfo && !BINFO_DEPENDENT_BASE_P (binfo)
- && BINFO_BASE_BINFOS (binfo) != NULL_TREE)
+ if (binfo && BINFO_BASE_BINFOS (binfo))
{
BINFO_BASE_BINFOS (new_binfo) = copy_node (BINFO_BASE_BINFOS (binfo));
/* We do not need to copy the accesses, as they are read only. */
{
result = build_special_member_call (lhs, complete_ctor_identifier,
build_tree_list (NULL_TREE, rhs),
- TYPE_BINFO (lhstype),
- LOOKUP_NORMAL);
+ lhstype, LOOKUP_NORMAL);
if (result == NULL_TREE)
return error_mark_node;
return result;
return error_mark_node;
}
- if (BINFO_BASE_BINFOS (TYPE_BINFO (type)))
+ if (TYPE_BINFO (type) && BINFO_BASE_BINFOS (TYPE_BINFO (type)))
{
sorry ("initializer list for object of class with base classes");
return error_mark_node;
tree objtype;
tree type;
tree binfo;
+ tree ctype;
datum = decay_conversion (datum);
}
type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
- binfo = lookup_base (objtype, TYPE_PTRMEM_CLASS_TYPE (ptrmem_type),
- ba_check, NULL);
- if (!binfo)
+ ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));
+
+ if (!COMPLETE_TYPE_P (ctype))
{
- error ("member type `%T::' incompatible with object type `%T'",
- type, objtype);
- return error_mark_node;
+ if (!same_type_p (ctype, objtype))
+ goto mismatch;
+ binfo = NULL;
+ }
+ else
+ {
+ binfo = lookup_base (objtype, ctype, ba_check, NULL);
+
+ if (!binfo)
+ {
+ mismatch:
+ error ("pointer to member type `%T' incompatible with object type `%T'",
+ type, objtype);
+ return error_mark_node;
+ }
+ else if (binfo == error_mark_node)
+ return error_mark_node;
}
- else if (binfo == error_mark_node)
- return error_mark_node;
if (TYPE_PTRMEM_P (ptrmem_type))
{
type = cp_build_qualified_type (type,
(cp_type_quals (type)
| cp_type_quals (TREE_TYPE (datum))));
+
+ datum = build_address (datum);
+
+ /* Convert object to the correct base. */
+ if (binfo)
+ datum = build_base_path (PLUS_EXPR, datum, binfo, 1);
+
/* Build an expression for "object + offset" where offset is the
value stored in the pointer-to-data-member. */
datum = build (PLUS_EXPR, build_pointer_type (type),
- build_base_path (PLUS_EXPR, build_address (datum),
- binfo, 1),
- build_nop (ptrdiff_type_node, component));
+ datum, build_nop (ptrdiff_type_node, component));
return build_indirect_ref (datum, 0);
}
else
}
exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
- TYPE_BINFO (type), LOOKUP_NORMAL);
+ type, LOOKUP_NORMAL);
if (exp == error_mark_node)
return error_mark_node;