massive namespace patch

From-SVN: r19631
This commit is contained in:
Martin v. Löwis 1998-05-07 22:06:26 -04:00 committed by Jason Merrill
parent 0d33d22e9f
commit 2c73f9f57a
36 changed files with 2912 additions and 1779 deletions

View File

@ -1,3 +1,243 @@
Mon Apr 27 07:17:38 1998 Martin von Loewis <loewis@informatik.hu-berlin.de>
* cp-tree.def (OVERLOAD): New node.
* cp-tree.h (BINDING_TYPE, SET_IDENTIFIER_GLOBAL_VALUE,
SET_IDENTIFIER_NAMESPACE_VALUE): Define.
(NAMESPACE_BINDING): Remove.
(IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_NAMESPACE_VALUE): Use
namespace_binding.
(OVL_FUNCTION, OVL_CHAIN, OVL_CURRENT, OVL_NEXT, OVL_USED):
Define.
(tree_overload): New struct.
(IDENTIFIER_TYPE_VALUE): Use identifier_type_value.
(REAL_IDENTIFIER_TYPE_VALUE): Define.
(IDENTIFIER_HAS_TYPE_VALUE): Use IDENTIFIER_TYPE_VALUE.
(lang_decl_flags): Remove in_namespace.
(lang_decl): Remove chain.
(DECL_CHAIN, DECL_NAMESPACE): Remove.
(flag_honor_std): Declare extern.
(identifier_type_value, pushdecl_namespace_level, push_using_decl,
namespace_binding, set_namespace_binding,
lookup_function_nonclass, cat_namespace_levels,
set_decl_namespace, lookup_arg_dependent, binding_init, ovl_cons,
scratch_ovl_cons, ovl_member, build_overload): Declare.
(decl_list_length, get_namespace_id, current_namespace_id,
overloaded_globals_p): Remove.
(lookup_using_namespace, qualified_lookup_using_namespace): Change
return type.
(push_scratch_obstack): New macro.
* call.c (add_function_candidate): Special-case type of OVERLOAD node.
(build_user_conversions_1): Iterate using OVL_NEXT for ctors,
convs, fns.
(build_new_function_call): Iterate using OVL_CHAIN.
Print DECL_NAME in when reporting ambiguities.
(build_object_call): Iterate using OVL_NEXT for fns, convs.
(build_new_op): Call lookup_function_nonclass.
Iterate using OVL_NEXT.
(build_op_delete_call): Change detection of members.
Do not wrap TREE_LIST around fields and single global functions.
(build_over_call): Don't push a class level if the context is a
namespace.
(build_new_method_call): Iterate using OVL_NEXT.
* class.c (add_method): Chain overloaded members using
build_overload. Remove copying of method.
(grow_method): When iterating through the obstack, expect OVERLOAD
nodes. Chain overload members.
(finish_struct_methods): Chain overload members. Unpack OVERLOAD
nodes in call to get_baselinks.
(duplicate_tag_error): Expect OVERLOAD nodes when unchaining.
(finish_struct_1): Iterate over ctor using OVL_NEXT. Handle
fdecls that are OVERLOAD nodes.
(validate_lhs): New function.
(instantiate_type): Do not copy OVERLOAD nodes. Remove dead
code. Use DECL_NAME in error messages. Split code between global
and member function processing.
* decl.c (global_type_node): New static variable.
(in_std): New global.
(struct binding_level): New field usings.
(resume_binding_level): Assert that we are not in a class.
(toplevel_bindings_p): Just check for namespace_p or
pseudo_global.
(resume_level): Remove.
(find_binding): New function.
(binding_for_name): Call it.
(namespace_binding, set_namespace_binding): New functions.
(push_namespace): Associate binding level with new namespace,
resume_binding_level for existing namespace. Remove old code.
Fake std by counting.
(store_bindings): Use REAL_IDENTIFIER_TYPE_VALUE.
(maybe_push_to_top_level): Save current namespace.
(pop_from_top_level): Restore saved namespace.
(pop_namespace): Call suspend_binding_level. Remove old code.
(cat_namespace_levels): New function.
(set_identifier_type_value_with_scope): For namespace bindings,
set BINDING_TYPE, and use global_type_node.
Use REAL_IDENTIFIER_TYPE_VALUE otherwise.
(identifier_type_value): New function.
(pushtag): If no context, use current_namespace.
(duplicate_decls): Don't process DECL_CHAIN.
(pushdecl): Set DECL_CONTEXT to current_namespace, if it is not
already set. Never reset it to NULL_TREE. Lookup global variables
in their namespace. Push overloaded templates if they are on
namespace level.
(pushdecl_namespace_level): New function.
(pushdecl_top_level): Implement using pushdecl_namespace_level.
(pushdecl_using_decl): New function.
(overloaded_globals_p): Remove.
(push_overloaded_decl): Create OVERLOAD nodes, and iterate through
them. Use namespace_binding and set_namespace_value.
(redeclaration_error_message): Complain if the declarations come
from different namespaces.
(lookup_tag): On namespace level, look in the BINDING_TYPE.
(lookup_namespace_name): Pass tree_bindings from stack. Remove
old code.
(select_decl): New function.
(lookup_name_real): Call it for qualified and unqualified lookup.
Pass tree_bindings from the stack.
If prefer_type is 1, also accept namespaces.
(lookup_function_nonclass): New function.
(init_decl_processing): Set the binding level of the global
namespace to global_binding_level.
Build a proper type list for __builtin_apply.
Initialize std_node to "fake std" if flag_honor_std is set.
Initialize global_type_node.
Allocated bad_alloc in namespace std if flag_honor_std.
(define_function): Set the DECL_CONTEXT to the current_namespace.
(start_decl): A namespace is not considered as a context here. If
the DECL_CONTEXT is a namespace, push the decl.
(cp_finish_decl): Check for namespaces used as initializers.
(grokfndecl): Add namespace parameter. Remove processing of
DECL_CHAIN.
(grokvardecl): Add namespace parameter.
(grokdeclarator): Process SCOPEs that are namespaces. For
mangling, temporarily set the DECL_CONTEXT on anonymous structs.
(start_function): Check for contexts that are namespaces.
Set context for declarations that have not been pushed.
(store_parm_decls): Check for ::main only.
(finish_function): Likewise.
(start_method): Check for contexts that are namespaces.
(start_method): Remove DECL_CHAIN processing.
* decl2.c (flag_honor_std): Declare.
(lang_decode_option): Set it if -fhonor-std or -fnew-abi is given.
(decl_namespace_list): New static global.
(grok_x_components): Ignore namespaces as type contexts.
(check_classfn): Expect OVERLOAD nodes.
(grokfield): Remove DECL_CHAIN processing.
(finish_file): Call cat_namespace_levels.
(merge_functions): New function.
(ambiguous_decl): Rewrite.
(lookup_using_namespace): Produce tree_bindings.
(qualified_lookup_using_namespace): Likewise.
(set_decl_namespace, decl_namespace, current_decl_namespace,
push_decl_namespace, pop_decl_namespace): New functions.
(arg_lookup): New struct.
(add_function, arg_assoc_namespace, arg_assoc_class,
arg_assoc_type, arg_assoc_args, arg_assoc, lookup_arg_dependent):
New functions.
(get_namespace_id, current_namespace_id): Remove.
(do_toplevel_using_decl): Rewrite.
(do_class_using_decl): Complain about namespace qualifiers.
(do_using_directive): Sorry if not on namespace level. Complain
about unknown namespaces.
* error.c (dump_aggr_type): Check for namespace contexts.
* except.c (init_exception_processing): Push terminate into std.
* friend.c (is_friend): A namespace is not a context, here.
* init.c (expand_member_init): Remove DECL_CHAIN processing.
(build_offset_ref): Process OVERLOAD nodes.
* lang-specs.h (__HONOR_STD): Define if -fnew-abi or -fhonor-std.
* lex.c (identifier_type): Loop using OVL_CHAIN.
(see_typename): Set looking_for_typename to 2.
(real_yylex): Likewise.
(do_identifier): Expect OVERLOAD nodes instead of TREE_LISTs.
(do_scoped_id): Expect OVERLOAD nodes.
Change calling convention for qualified_lookup_using_namespace.
(build_lang_decl): Don't set in_namespace anymore.
* method.c (typevec_size): New global.
(build_overload_nested_name): Return if global_namespace.
Otherwise, always expect a declaration context.
(build_qualified_name): Likewise.
Make sure we don't write beyond typevec_size.
(build_decl_overload_real): Likewise.
Allocate one extra slot for the namespace.
(hack_identifier): Mark code dead.
Process OVERLOAD and NAMESPACE_DECL nodes.
* parse.y (program): Pop namespaces until in global namespace.
(extdef): In a using-declaration, don't discard the identifier if
there is no declaration.
(left_curly): Ignore type contexts which are namespaces.
(typename_sub2): Use IDENTIFIER_TYPE_VALUE to retrieve the type
used as scope.
* pt.c (template_class_depth): Expect types to be namespaces.
(determine_specialization): Simplify by expecting OVERLOAD nodes.
(push_template_decl): Push into namespace level.
Reset ctx if it is a namespace.
Set DECL_CONTEXT to current_namespace if not set already.
Ignore real contexts that are namespaces.
(mangle_class_name_for_template): Skip global_namespace.
Mangle other namepaces as declarations.
(lookup_template_function): Set type of OVERLOAD nodes to unknown.
(lookup_template_class): Push into namespace of context.
If the context is a namespace, set it to global_namespace.
Use id_context for mangling.
(for_each_template_parm): Handle OVERLOAD and NAMESPACE_DECL nodes.
(tsubst_friend_function): Ignore namespace contexts.
Push into namespace level.
(tsubst): Handle NAMESPACE_DECL nodes.
Remove DECL_CHAIN processing.
(type_unification_real): Recognize OVERLOAD instead of TREE_LIST nodes.
* ptree.c (print_lang_identifier): Print bindings.
(lang_print_xnode): Print OVERLOAD nodes.
* rtti.c (init_rtti_processing): Push type_info into std.
* search.c (lookup_fnfields_here): Expect OVERLOAD nodes.
(lookup_fnfields_1, get_virtuals_named_this, get_matching_virtual,
dfs_debug_mark, dfs_pushdecls, dfs_compress_decls, add_conversions,
lookup_fnfields_here): Likewise.
Process all nodes, instead of going through TREE_CHAIN.
* sig.c (build_signature_pointer_or_reference_type): Set context
to global_namespace.
(build_signature_table_constructor): Expect OVERLOAD nodes.
* spew.c (yylex): Save old setting of looking_for_typename.
* tree.c (decl_list_length): Remove.
(binding_init): New function.
(count_functions): Rewrite.
(is_overloaded_fn): Expect OVERLOAD nodes.
(really_overloaded_fn, get_first_fn, lvalue_type): Likewise.
(ovl_cons, scratch_ovl_cons, build_overload, build_overload_after,
ovl_member): New functions.
* typeck.c (require_complete_type): Expect OVERLOAD nodes.
(type_unknown_p): Likewise.
(require_instantiated_type): Likewise.
(build_component_ref): Declare code dead.
(build_x_function_call): Create and expect OVERLOAD nodes.
(build_function_call_real): Check for ::main only.
(build_unary_op): Likewise. Expect OVERLOAD nodes.
(convert_for_assignment): Check for TREE_LIST before accessing
TREE_VALUE.
* decl.c (duplicate_decls): Check for namespace bindings instead
of global bindings.
(pushdecl, push_overloaded_decl, lookup_tag, lookup_name_real,
lookup_name_current_level, start_decl, xref_tag,
finish_enum): Likewise.
* init.c (build_offset_ref): Likewise.
* search.c (lookup_field): Likewise.
(lookup_fnfields): Likewise.
(dfs_debug_mark): Likewise.
* decl.c (poplevel): Use SET_IDENTIFIER_TYPE_VALUE.
(poplevel_class, pop_from_top_level): Likewise.
* decl2.c (finish_method): Likewise.
* class.c (build_vtable): Use SET_IDENTIFIER_GLOBAL_VALUE.
* decl.c (record_builtin_type): Likewise.
(init_decl_processing, grokfndecl): Likewise.
* lex.c (get_time_identifier, do_identifier, do_scoped_id): Likewise.
(make_lang_type): Likewise.
* parse.y (make_thunk): Likewise.
* pt.c (tsubst): Likewise.
* tree.c (debug_binfo): Likewise.
* exception.cc, new.cc, new1.cc, new2.cc, tinfo.cc, tinfo.h,
tinfo2.cc, inc/new.h: Add std qualifications.
* inc/new: Wrap with namespace std if __HONOR_STD.
* inc/typeinfo: Likewise.
Fri May 8 00:43:50 1998 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_user_type_conversion_1): Handle second_conv

View File

@ -1117,6 +1117,9 @@ add_function_candidate (candidates, fn, arglist, flags)
tree argtype = TREE_TYPE (arg);
tree t;
/* An overloaded function does not have an argument type */
if (TREE_CODE (arg) == OVERLOAD)
argtype = unknown_type_node;
argtype = cp_build_type_variant
(argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
@ -2044,20 +2047,21 @@ build_user_type_conversion_1 (totype, expr, flags)
ctors = TREE_VALUE (ctors);
}
for (; ctors; ctors = DECL_CHAIN (ctors))
for (; ctors; ctors = OVL_NEXT (ctors))
{
if (DECL_NONCONVERTING_P (ctors))
tree ctor = OVL_CURRENT (ctors);
if (DECL_NONCONVERTING_P (ctor))
continue;
if (TREE_CODE (ctors) == TEMPLATE_DECL)
if (TREE_CODE (ctor) == TEMPLATE_DECL)
{
templates = scratch_tree_cons (NULL_TREE, ctors, templates);
templates = scratch_tree_cons (NULL_TREE, ctor, templates);
candidates =
add_template_candidate (candidates, ctors,
add_template_candidate (candidates, ctor,
NULL_TREE, args, NULL_TREE, flags);
}
else
candidates = add_function_candidate (candidates, ctors,
candidates = add_function_candidate (candidates, ctor,
args, flags);
if (candidates)
@ -2072,7 +2076,7 @@ build_user_type_conversion_1 (totype, expr, flags)
for (; convs; convs = TREE_CHAIN (convs))
{
tree fn = TREE_VALUE (convs);
tree fns = TREE_VALUE (convs);
int convflags = LOOKUP_NO_CONVERSION;
tree ics;
@ -2083,9 +2087,9 @@ build_user_type_conversion_1 (totype, expr, flags)
if (TREE_CODE (totype) == REFERENCE_TYPE)
convflags |= LOOKUP_NO_TEMP_BIND;
if (TREE_CODE (fn) != TEMPLATE_DECL)
if (TREE_CODE (fns) != TEMPLATE_DECL)
ics = implicit_conversion
(totype, TREE_TYPE (TREE_TYPE (fn)), 0, convflags);
(totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags);
else
/* We can't compute this yet. */
ics = error_mark_node;
@ -2093,8 +2097,9 @@ build_user_type_conversion_1 (totype, expr, flags)
if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics))
/* ignore the near match. */;
else if (ics)
for (; fn; fn = DECL_CHAIN (fn))
for (; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
struct z_candidate *old_candidates = candidates;
if (TREE_CODE (fn) == TEMPLATE_DECL)
@ -2240,7 +2245,7 @@ build_new_function_call (fn, args)
if (really_overloaded_fn (fn))
{
tree t;
tree t1;
tree templates = NULL_TREE;
args = resolve_args (args);
@ -2248,8 +2253,9 @@ build_new_function_call (fn, args)
if (args == error_mark_node)
return error_mark_node;
for (t = TREE_VALUE (fn); t; t = DECL_CHAIN (t))
for (t1 = fn; t1; t1 = OVL_CHAIN (t1))
{
tree t = OVL_FUNCTION (t1);
if (TREE_CODE (t) == TEMPLATE_DECL)
{
templates = scratch_tree_cons (NULL_TREE, t, templates);
@ -2267,7 +2273,7 @@ build_new_function_call (fn, args)
if (candidates && ! candidates->next)
return build_function_call (candidates->fn, args);
cp_error ("no matching function for call to `%D (%A)'",
TREE_PURPOSE (fn), args);
DECL_NAME (OVL_FUNCTION (fn)), args);
if (candidates)
print_z_candidates (candidates);
return error_mark_node;
@ -2278,7 +2284,7 @@ build_new_function_call (fn, args)
if (cand == 0)
{
cp_error ("call of overloaded `%D (%A)' is ambiguous",
TREE_PURPOSE (fn), args);
DECL_NAME (OVL_FUNCTION (fn)), args);
print_z_candidates (candidates);
return error_mark_node;
}
@ -2293,6 +2299,9 @@ build_new_function_call (fn, args)
return build_over_call (cand, args, LOOKUP_NORMAL);
}
/* This is not really overloaded. */
fn = OVL_CURRENT (fn);
return build_function_call (fn, args);
}
@ -2325,11 +2334,12 @@ build_object_call (obj, args)
if (fns)
{
tree fn = TREE_VALUE (fns);
tree base = TREE_PURPOSE (fns);
mem_args = scratch_tree_cons (NULL_TREE, build_this (obj), args);
for (; fn; fn = DECL_CHAIN (fn))
for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
templates = scratch_tree_cons (NULL_TREE, fn, templates);
@ -2343,7 +2353,7 @@ build_object_call (obj, args)
(candidates, fn, mem_args, LOOKUP_NORMAL);
if (candidates)
candidates->basetype_path = TREE_PURPOSE (fns);
candidates->basetype_path = base;
}
}
@ -2351,13 +2361,15 @@ build_object_call (obj, args)
for (; convs; convs = TREE_CHAIN (convs))
{
tree fn = TREE_VALUE (convs);
tree totype = TREE_TYPE (TREE_TYPE (fn));
tree fns = TREE_VALUE (convs);
tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns)));
tree fn;
if (TREE_CODE (totype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
for (; fn; fn = DECL_CHAIN (fn))
for (; fns; fns = OVL_NEXT (fn))
{
fn = OVL_CURRENT (fn);
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
templates = scratch_tree_cons (NULL_TREE, fn, templates);
@ -2477,7 +2489,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
arglist = scratch_tree_cons (NULL_TREE, arg2, arg3);
if (flags & LOOKUP_GLOBAL)
return build_new_function_call
(lookup_name_nonclass (fnname), arglist);
(lookup_function_nonclass (fnname, arglist), arglist);
/* FIXME */
rval = build_method_call
@ -2499,9 +2511,11 @@ build_new_op (code, flags, arg1, arg2, arg3)
tree rval;
if (flags & LOOKUP_GLOBAL)
return build_new_function_call
(lookup_name_nonclass (fnname),
build_scratch_list (NULL_TREE, arg1));
{
arglist = build_scratch_list (NULL_TREE, arg1);
return build_new_function_call
(lookup_function_nonclass (fnname, arglist), arglist);
}
arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2));
@ -2576,23 +2590,23 @@ build_new_op (code, flags, arg1, arg2, arg3)
else
arglist = build_scratch_list (NULL_TREE, arg1);
fns = lookup_name_nonclass (fnname);
/* + Koenig lookup */
fns = lookup_function_nonclass (fnname, arglist);
if (fns && TREE_CODE (fns) == TREE_LIST)
fns = TREE_VALUE (fns);
for (; fns; fns = DECL_CHAIN (fns))
for (; fns; fns = OVL_NEXT (fns))
{
if (TREE_CODE (fns) == TEMPLATE_DECL)
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
templates = scratch_tree_cons (NULL_TREE, fns, templates);
templates = scratch_tree_cons (NULL_TREE, fn, templates);
candidates
= add_template_candidate (candidates, fns, NULL_TREE,
= add_template_candidate (candidates, fn, NULL_TREE,
arglist, TREE_TYPE (fnname),
flags);
}
else
candidates = add_function_candidate (candidates, fns, arglist, flags);
candidates = add_function_candidate (candidates, fn, arglist, flags);
}
if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
@ -2606,10 +2620,11 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (fns)
{
tree fn = TREE_VALUE (fns);
tree basetype = TREE_PURPOSE (fns);
mem_arglist = scratch_tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
for (; fn; fn = DECL_CHAIN (fn))
for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
tree this_arglist;
if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
@ -2631,7 +2646,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
(candidates, fn, this_arglist, flags);
if (candidates)
candidates->basetype_path = TREE_PURPOSE (fns);
candidates->basetype_path = basetype;
}
}
@ -2860,7 +2875,8 @@ build_op_new_call (code, type, args, flags)
return build_method_call (dummy, fnname, args, NULL_TREE, flags);
}
else
return build_new_function_call (lookup_name_nonclass (fnname), args);
return build_new_function_call
(lookup_function_nonclass (fnname, args), args);
}
/* Build a call to operator delete. This has to be handled very specially,
@ -2908,9 +2924,12 @@ build_op_delete_call (code, addr, size, flags)
if (fns)
{
#if 0
/* It is unnecessary to wrap another TREE_LIST around it. (MvL) */
/* Build this up like build_offset_ref does. */
fns = build_tree_list (error_mark_node, fns);
TREE_TYPE (fns) = build_offset_type (type, unknown_type_node);
#endif
}
else
fns = lookup_name_nonclass (fnname);
@ -2957,15 +2976,15 @@ build_op_delete_call (code, addr, size, flags)
/* instantiate_type will always return a plain function; pretend it's
overloaded. */
if (TREE_CODE (fns) == FUNCTION_DECL)
fns = scratch_tree_cons (NULL_TREE, fns, NULL_TREE);
fns = scratch_ovl_cons (fns, NULL_TREE);
fn = instantiate_type (fntype, fns, 0);
if (fn != error_mark_node)
{
if (TREE_CODE (TREE_VALUE (fns)) == TREE_LIST)
if (TREE_CODE (fns) == TREE_LIST)
/* Member functions. */
enforce_access (TREE_PURPOSE (TREE_VALUE (fns)), fn);
enforce_access (TREE_PURPOSE (fns), fn);
return build_function_call (fn, expr_tree_cons (NULL_TREE, addr, args));
}
@ -3268,12 +3287,14 @@ build_over_call (cand, args, flags)
we must be careful to do name lookup in the scope of
S<T>, rather than in the current class. */
if (DECL_REAL_CONTEXT (fn))
if (DECL_REAL_CONTEXT (fn)
&& TREE_CODE (DECL_REAL_CONTEXT (fn)) != NAMESPACE_DECL)
pushclass (DECL_REAL_CONTEXT (fn), 2);
arg = tsubst_expr (arg, DECL_TI_ARGS (fn), NULL_TREE);
if (DECL_REAL_CONTEXT (fn))
if (DECL_REAL_CONTEXT (fn)
&& TREE_CODE (DECL_CONTEXT (fn)) != NAMESPACE_DECL)
popclass (0);
}
converted_args = expr_tree_cons
@ -3540,7 +3561,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
return error_mark_node;
if (fns)
{
tree t = TREE_VALUE (fns);
tree fn = TREE_VALUE (fns);
if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype)
&& ! (flags & LOOKUP_HAS_IN_CHARGE))
{
@ -3548,8 +3569,9 @@ build_new_method_call (instance, name, args, basetype_path, flags)
args = scratch_tree_cons (NULL_TREE, integer_one_node, args);
}
mem_args = scratch_tree_cons (NULL_TREE, instance_ptr, args);
for (; t; t = DECL_CHAIN (t))
for (; fn; fn = OVL_NEXT (fn))
{
tree t = OVL_CURRENT (fn);
tree this_arglist;
/* We can end up here for copy-init of same or base class. */

View File

@ -710,7 +710,8 @@ build_vtable (binfo, type)
/* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */
import_export_vtable (decl, type, 0);
IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl);
decl = pushdecl_top_level (decl);
SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
/* Initialize the association list for this type, based
on our first approximation. */
TYPE_BINFO_VTABLE (type) = decl;
@ -1072,42 +1073,24 @@ void
add_method (type, fields, method)
tree type, *fields, method;
{
/* We must make a copy of METHOD here, since we must be sure that
we have exclusive title to this method's DECL_CHAIN. */
tree decl;
push_obstacks (&permanent_obstack, &permanent_obstack);
{
decl = copy_node (method);
if (DECL_RTL (decl) == 0
&& (!processing_template_decl
|| !uses_template_parms (decl)))
{
make_function_rtl (decl);
DECL_RTL (method) = DECL_RTL (decl);
}
}
if (fields && *fields)
{
/* Take care not to hide destructor. */
DECL_CHAIN (decl) = DECL_CHAIN (*fields);
DECL_CHAIN (*fields) = decl;
}
*fields = build_overload (method, *fields);
else if (CLASSTYPE_METHOD_VEC (type) == 0)
{
tree method_vec = make_node (TREE_VEC);
if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
if (TYPE_IDENTIFIER (type) == DECL_NAME (method))
{
/* ??? Is it possible for there to have been enough room in the
current chunk for the tree_vec structure but not a tree_vec
plus a tree*? Will this work in that case? */
obstack_free (current_obstack, method_vec);
obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))
TREE_VEC_ELT (method_vec, 1) = decl;
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)))
TREE_VEC_ELT (method_vec, 1) = method;
else
TREE_VEC_ELT (method_vec, 0) = decl;
TREE_VEC_ELT (method_vec, 0) = method;
TREE_VEC_LENGTH (method_vec) = 2;
}
else
@ -1117,7 +1100,7 @@ add_method (type, fields, method)
plus a tree*? Will this work in that case? */
obstack_free (current_obstack, method_vec);
obstack_blank (current_obstack, sizeof (struct tree_vec) + 2*sizeof (tree *));
TREE_VEC_ELT (method_vec, 2) = decl;
TREE_VEC_ELT (method_vec, 2) = method;
TREE_VEC_LENGTH (method_vec) = 3;
obstack_finish (current_obstack);
}
@ -1130,15 +1113,13 @@ add_method (type, fields, method)
/* Adding a new ctor or dtor. This is easy because our
METHOD_VEC always has a slot for such entries. */
if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
if (TYPE_IDENTIFIER (type) == DECL_NAME (method))
{
int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl));
/* TREE_VEC_ELT (method_vec, idx) = decl; */
if (decl != TREE_VEC_ELT (method_vec, idx))
{
DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, idx);
TREE_VEC_ELT (method_vec, idx) = decl;
}
int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method));
/* TREE_VEC_ELT (method_vec, idx) = method; */
if (method != TREE_VEC_ELT (method_vec, idx))
TREE_VEC_ELT (method_vec, idx) =
build_overload (method, TREE_VEC_ELT (method_vec, idx));
}
else
{
@ -1177,7 +1158,7 @@ add_method (type, fields, method)
}
obstack_finish (ob);
TREE_VEC_ELT (method_vec, len) = decl;
TREE_VEC_ELT (method_vec, len) = method;
TREE_VEC_LENGTH (method_vec) = len + 1;
CLASSTYPE_METHOD_VEC (type) = method_vec;
@ -1194,8 +1175,8 @@ add_method (type, fields, method)
}
}
}
DECL_CONTEXT (decl) = type;
DECL_CLASS_CONTEXT (decl) = type;
DECL_CONTEXT (method) = type;
DECL_CLASS_CONTEXT (method) = type;
pop_obstacks ();
}
@ -1866,16 +1847,11 @@ grow_method (fndecl, method_vec_ptr)
tree *testp = &TREE_VEC_ELT (method_vec, 2);
while (testp < (tree *) obstack_next_free (&class_obstack)
&& (*testp == NULL_TREE || DECL_NAME (*testp) != DECL_NAME (fndecl)))
&& (*testp == NULL_TREE || DECL_NAME (OVL_CURRENT (*testp)) != DECL_NAME (fndecl)))
testp++;
if (testp < (tree *) obstack_next_free (&class_obstack))
{
tree *p;
for (p = testp; *p; )
p = &DECL_CHAIN (*p);
*p = fndecl;
}
*testp = build_overload (fndecl, *testp);
else
{
obstack_ptr_grow (&class_obstack, fndecl);
@ -1966,14 +1942,14 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields)))
{
/* Destructors go in slot 1. */
DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 1);
TREE_VEC_ELT (method_vec, 1) = fn_fields;
TREE_VEC_ELT (method_vec, 1) =
build_overload (fn_fields, TREE_VEC_ELT (method_vec, 1));
}
else
{
/* Constructors go in slot 0. */
DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);
TREE_VEC_ELT (method_vec, 0) = fn_fields;
TREE_VEC_ELT (method_vec, 0) =
build_overload (fn_fields, TREE_VEC_ELT (method_vec, 0));
}
}
else if (IDENTIFIER_TYPENAME_P (fn_name))
@ -2057,7 +2033,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
for (i = 2; i < len; i++)
{
TREE_VEC_ELT (baselink_vec, i)
= get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i)));
= get_baselinks (baselink_binfo, t,
DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))));
if (TREE_VEC_ELT (baselink_vec, i) != 0)
any_links = 1;
}
@ -2098,8 +2075,8 @@ duplicate_tag_error (t)
tree unchain = TREE_VEC_ELT (method_vec, i);
while (unchain != NULL_TREE)
{
TREE_CHAIN (unchain) = NULL_TREE;
unchain = DECL_CHAIN (unchain);
TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
unchain = OVL_NEXT (unchain);
}
}
}
@ -3675,8 +3652,8 @@ finish_struct_1 (t, warn_anon)
for (ctor = TREE_VEC_ELT (method_vec, 0);
ctor;
ctor = DECL_CHAIN (ctor))
if (! TREE_PRIVATE (ctor))
ctor = OVL_NEXT (ctor))
if (! TREE_PRIVATE (OVL_CURRENT (ctor)))
{
nonprivate_ctor = 1;
break;
@ -3710,10 +3687,19 @@ finish_struct_1 (t, warn_anon)
int i = 2;
tree tmp;
/* Functions are represented as TREE_LIST, with the purpose
being the type and the value the functions. Other members
come as themselves. */
if (TREE_CODE (fdecl) == TREE_LIST)
{
/* Ignore base type this came from. */
fdecl = TREE_VALUE (fdecl);
}
if (TREE_CODE (fdecl) == OVERLOAD)
{
/* We later iterate over all functions. */
flist = fdecl;
fdecl = TREE_VALUE (flist);
fdecl = OVL_FUNCTION (flist);
}
name = DECL_NAME (fdecl);
@ -3746,12 +3732,11 @@ finish_struct_1 (t, warn_anon)
/* Make type T see field decl FDECL with access ACCESS.*/
if (flist)
{
fdecl = TREE_VALUE (flist);
while (fdecl)
while (flist)
{
if (alter_access (t, fdecl, access) == 0)
if (alter_access (t, OVL_FUNCTION (flist), access) == 0)
break;
fdecl = DECL_CHAIN (fdecl);
flist = OVL_CHAIN (flist);
}
}
else
@ -4921,6 +4906,29 @@ pop_lang_context ()
/* Type instantiation routines. */
static tree
validate_lhs (lhstype, complain)
tree lhstype;
int complain;
{
if (TYPE_PTRMEMFUNC_P (lhstype))
lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
if (TREE_CODE (lhstype) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
lhstype = TREE_TYPE (lhstype);
else
{
if (complain)
error ("invalid type combination for overload");
return error_mark_node;
}
}
return lhstype;
}
/* This function will instantiate the type of the expression given in
RHS to match the type of LHSTYPE. If errors exist, then return
error_mark_node. If only complain is COMPLAIN is set. If we are
@ -4955,7 +4963,10 @@ instantiate_type (lhstype, rhs, complain)
return error_mark_node;
}
rhs = copy_node (rhs);
/* We don't overwrite rhs if it is an overloaded function.
Copying it would destroy the tree link. */
if (TREE_CODE (rhs) != OVERLOAD)
rhs = copy_node (rhs);
/* This should really only be used when attempting to distinguish
what sort of a pointer to function we have. For now, any
@ -5016,6 +5027,9 @@ instantiate_type (lhstype, rhs, complain)
return function;
}
/* I could not trigger this code. MvL */
my_friendly_abort (980326);
#if 0
my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178);
my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE),
@ -5056,6 +5070,7 @@ instantiate_type (lhstype, rhs, complain)
error ("no appropriate overload exists for COMPONENT_REF");
return error_mark_node;
}
#endif
return rhs;
}
@ -5064,149 +5079,167 @@ instantiate_type (lhstype, rhs, complain)
explicit_targs = TREE_OPERAND (rhs, 1);
rhs = TREE_OPERAND (rhs, 0);
}
/* fall through */
/* fall through */
my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
case OVERLOAD:
{
tree elem, elems;
/* First look for an exact match. Search overloaded
functions. May have to undo what `default_conversion'
might do to lhstype. */
lhstype = validate_lhs (lhstype, complain);
if (lhstype == error_mark_node)
return lhstype;
if (TREE_CODE (lhstype) != FUNCTION_TYPE)
{
rhs = DECL_NAME (OVL_FUNCTION (rhs));
if (complain)
cp_error("cannot resolve overloaded function `%D' "
"based on non-function type", rhs);
return error_mark_node;
}
elems = rhs;
/* If there are explicit_targs, only a template function
can match. */
if (explicit_targs == NULL_TREE)
while (elems)
{
elem = OVL_FUNCTION (elems);
if (! comptypes (lhstype, TREE_TYPE (elem), 1))
elems = OVL_CHAIN (elems);
else
{
mark_used (elem);
return elem;
}
}
/* No exact match found, look for a compatible template. */
{
tree save_elem = 0;
elems = rhs;
if (TREE_CODE (elems) == TREE_LIST)
elems = TREE_VALUE (rhs);
for (; elems; elems = OVL_NEXT (elems))
if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL)
{
int n = DECL_NTPARMS (elem);
tree t = make_scratch_vec (n);
int i;
i = type_unification
(DECL_INNERMOST_TEMPLATE_PARMS (elem), t,
TYPE_ARG_TYPES (TREE_TYPE (elem)),
TYPE_ARG_TYPES (lhstype), explicit_targs, 1, 1);
if (i == 0)
{
if (save_elem)
{
cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
return error_mark_node;
}
save_elem = instantiate_template (elem, t);
/* Check the return type. */
if (! comptypes (TREE_TYPE (lhstype),
TREE_TYPE (TREE_TYPE (save_elem)), 1))
save_elem = 0;
}
}
if (save_elem)
{
mark_used (save_elem);
return save_elem;
}
}
/* If there are explicit_targs, only a template function
can match. */
if (explicit_targs == NULL_TREE)
{
/* No match found, look for a compatible function. */
tree elems = rhs;
elems = rhs;
for (; elems; elems = OVL_NEXT (elems))
{
elem = OVL_CURRENT (elems);
if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0)
break;
}
if (elems)
{
tree save_elem = elem;
for (elems = OVL_CHAIN (elems); elems;
elems = OVL_CHAIN (elems))
{
elem = OVL_FUNCTION (elems);
if (comp_target_types (lhstype, TREE_TYPE (elem), 0) > 0)
break;
}
if (elems)
{
if (complain)
{
cp_error
("cannot resolve overload to target type `%#T'",
lhstype);
cp_error_at (" ambiguity between `%#D'", save_elem);
cp_error_at (" and `%#D', at least", elem);
}
return error_mark_node;
}
mark_used (save_elem);
return save_elem;
}
}
if (complain)
{
cp_error ("cannot resolve overload to target type `%#T'", lhstype);
cp_error
(" because no suitable overload of function `%D' exists",
DECL_NAME (OVL_FUNCTION (rhs)));
}
return error_mark_node;
}
case TREE_LIST:
{
tree elem, baselink, name = NULL_TREE;
int globals = overloaded_globals_p (rhs);
/* First look for an exact match. Search either overloaded
functions or member functions. May have to undo what
`default_conversion' might do to lhstype. */
if (TREE_PURPOSE (rhs) == error_mark_node)
{
/* Make sure we don't drop the non-local flag, as the old code
would rely on it. */
int nl = TREE_NONLOCAL_FLAG (rhs);
/* We don't need the type of this node. */
rhs = TREE_VALUE (rhs);
my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331);
}
/* Now we should have a baselink. */
my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC, 980331);
/* First look for an exact match. Search member functions.
May have to undo what `default_conversion' might do to
lhstype. */
if (TYPE_PTRMEMFUNC_P (lhstype))
lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
if (TREE_CODE (lhstype) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
lhstype = TREE_TYPE (lhstype);
else
{
if (complain)
error ("invalid type combination for overload");
return error_mark_node;
}
}
if (TREE_CODE (lhstype) != FUNCTION_TYPE && globals > 0)
{
if (complain)
cp_error ("cannot resolve overloaded function `%D' based on non-function type",
TREE_PURPOSE (rhs));
return error_mark_node;
}
if (globals > 0)
{
elem = get_first_fn (rhs);
/* If there are explicit_targs, only a template function
can match. */
if (explicit_targs == NULL_TREE)
while (elem)
{
if (! comptypes (lhstype, TREE_TYPE (elem), 1))
elem = DECL_CHAIN (elem);
else
{
mark_used (elem);
return elem;
}
}
/* No exact match found, look for a compatible template. */
{
tree save_elem = 0;
for (elem = get_first_fn (rhs); elem; elem = DECL_CHAIN (elem))
if (TREE_CODE (elem) == TEMPLATE_DECL)
{
int n = DECL_NTPARMS (elem);
tree t = make_scratch_vec (n);
int i;
i = type_unification
(DECL_INNERMOST_TEMPLATE_PARMS (elem), t,
TYPE_ARG_TYPES (TREE_TYPE (elem)),
TYPE_ARG_TYPES (lhstype), explicit_targs, 1, 1);
if (i == 0)
{
if (save_elem)
{
cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
return error_mark_node;
}
save_elem = instantiate_template (elem, t);
/* Check the return type. */
if (! comptypes (TREE_TYPE (lhstype),
TREE_TYPE (TREE_TYPE (save_elem)), 1))
save_elem = 0;
}
}
if (save_elem)
{
mark_used (save_elem);
return save_elem;
}
}
/* If there are explicit_targs, only a template function
can match. */
if (explicit_targs == NULL_TREE)
{
/* No match found, look for a compatible function. */
elem = get_first_fn (rhs);
while (elem && comp_target_types (lhstype,
TREE_TYPE (elem), 1) <= 0)
elem = DECL_CHAIN (elem);
if (elem)
{
tree save_elem = elem;
elem = DECL_CHAIN (elem);
while (elem
&& comp_target_types (lhstype,
TREE_TYPE (elem), 0) <= 0)
elem = DECL_CHAIN (elem);
if (elem)
{
if (complain)
{
cp_error
("cannot resolve overload to target type `%#T'",
lhstype);
cp_error_at (" ambiguity between `%#D'",
save_elem);
cp_error_at (" and `%#D', at least", elem);
}
return error_mark_node;
}
mark_used (save_elem);
return save_elem;
}
}
if (complain)
{
cp_error ("cannot resolve overload to target type `%#T'",
lhstype);
cp_error
(" because no suitable overload of function `%D' exists",
TREE_PURPOSE (rhs));
}
return error_mark_node;
}
lhstype = validate_lhs (lhstype, complain);
if (lhstype == error_mark_node)
return lhstype;
if (TREE_NONLOCAL_FLAG (rhs))
{
my_friendly_abort (980401);
/* Got to get it as a baselink. */
rhs = lookup_fnfields (TYPE_BINFO (current_class_type),
TREE_PURPOSE (rhs), 0);
DECL_NAME (OVL_FUNCTION (rhs)), 0);
}
else
{
my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
if (TREE_CODE (TREE_VALUE (rhs)) == TREE_LIST)
rhs = TREE_VALUE (rhs);
my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL,
my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL
|| TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD,
182);
}
@ -5215,13 +5248,13 @@ instantiate_type (lhstype, rhs, complain)
{
elem = TREE_VALUE (baselink);
while (elem)
if (comptypes (lhstype, TREE_TYPE (elem), 1))
if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1))
{
mark_used (elem);
return elem;
mark_used (OVL_CURRENT (elem));
return OVL_CURRENT (elem);
}
else
elem = DECL_CHAIN (elem);
elem = OVL_NEXT (elem);
}
/* No exact match found, look for a compatible method. */
@ -5229,16 +5262,17 @@ instantiate_type (lhstype, rhs, complain)
baselink = next_baselink (baselink))
{
elem = TREE_VALUE (baselink);
while (elem && comp_target_types (lhstype,
TREE_TYPE (elem), 1) <= 0)
elem = DECL_CHAIN (elem);
for (; elem; elem = OVL_NEXT (elem))
if (comp_target_types (lhstype,
TREE_TYPE (OVL_CURRENT (elem)), 1) > 0)
break;
if (elem)
{
tree save_elem = elem;
elem = DECL_CHAIN (elem);
while (elem && comp_target_types (lhstype,
TREE_TYPE (elem), 0) <= 0)
elem = DECL_CHAIN (elem);
tree save_elem = OVL_CURRENT (elem);
for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem))
if (comp_target_types (lhstype,
TREE_TYPE (OVL_CURRENT (elem)), 0) > 0)
break;
if (elem)
{
if (complain)
@ -5248,7 +5282,10 @@ instantiate_type (lhstype, rhs, complain)
mark_used (save_elem);
return save_elem;
}
name = DECL_NAME (TREE_VALUE (rhs));
name = rhs;
while (TREE_CODE (name) == TREE_LIST)
name = TREE_VALUE (name);
name = DECL_NAME (OVL_CURRENT (name));
#if 0
if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
{

View File

@ -166,10 +166,15 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2)
the template will be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* has two fields: scope and value */
/* XXX: could recycle some of the common fields */
/* An association between namespace and entity. Parameters are the
scope and the (non-type) value.
TREE_TYPE indicates the type bound to the name. */
DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
/* A list-like node for chaining overloading candidates. TREE_TYPE is
the original name, and the parameter is the FUNCTION_DECL. */
DEFTREECODE (OVERLOAD, "overload", 'x', 1)
/* A generic wrapper for something not tree that we want to include in
tree structure. */
DEFTREECODE (WRAPPER, "wrapper", 'x', 1)

View File

@ -58,13 +58,23 @@ typedef struct
tree decl;
} template_parm_index;
#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope)
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
#define NAMESPACE_BINDING(ID,NS) BINDING_VALUE (binding_for_name (ID, NS))
/* For a binding between a name and an entity, defines the scope
where the binding is declared. Currently always points to a
namespace declaration. */
#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope)
/* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */
#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value)
/* If name is bound to a type, this is the type (struct, union, enum). */
#define BINDING_TYPE(NODE) TREE_TYPE(NODE)
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
NAMESPACE_BINDING (NODE, global_namespace)
namespace_binding (NODE, global_namespace)
#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
set_namespace_binding (NODE, global_namespace, VAL)
#define IDENTIFIER_NAMESPACE_VALUE(NODE) \
NAMESPACE_BINDING (NODE, current_namespace)
namespace_binding (NODE, current_namespace)
#define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) \
set_namespace_binding (NODE, current_namespace, VAL)
struct tree_binding
{
@ -73,6 +83,25 @@ struct tree_binding
tree value;
};
/* The overloaded FUNCTION_DECL. */
#define OVL_FUNCTION(NODE) (((struct tree_overload*)NODE)->function)
#define OVL_CHAIN(NODE) TREE_CHAIN(NODE)
/* Polymorphic access to FUNCTION and CHAIN. */
#define OVL_CURRENT(NODE) \
((TREE_CODE(NODE)==OVERLOAD) ? OVL_FUNCTION(NODE) : NODE)
#define OVL_NEXT(NODE) \
((TREE_CODE(NODE)==OVERLOAD) ? TREE_CHAIN(NODE) : NULL_TREE)
/* If set, this was imported in a using declaration.
This is not to confuse with being used somewhere, which
is not important for this node. */
#define OVL_USED(NODE) TREE_USED(NODE)
struct tree_overload
{
char common[sizeof (struct tree_common)];
tree function;
};
#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr)
#define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i)
@ -100,9 +129,14 @@ struct tree_wrapper
#define IDENTIFIER_TEMPLATE(NODE) \
(((struct lang_identifier *)(NODE))->class_template_info)
#define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
/* TREE_TYPE only indicates on local and class scope the current
type. For namespace scope, the presence of a type in any namespace
is indicated with global_type_node, and the real type behind must
be found through lookup. */
#define IDENTIFIER_TYPE_VALUE(NODE) (identifier_type_value(NODE))
#define REAL_IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE)
#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (TREE_TYPE (NODE) ? 1 : 0)
#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0)
#define LANG_ID_FIELD(NAME,NODE) \
(((struct lang_identifier *)(NODE))->x \
@ -950,7 +984,6 @@ struct lang_decl_flags
tree memfunc_pointer_to;
tree template_info;
struct binding_level *level;
tree in_namespace;
};
struct lang_decl
@ -959,7 +992,6 @@ struct lang_decl
tree main_decl_variant;
struct pending_inline *pending_inline_info;
tree chain;
};
/* Non-zero if NODE is a _DECL with TREE_READONLY set. */
@ -1065,21 +1097,13 @@ struct lang_decl
((TREE_CODE (NODE) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (NODE)) \
? DECL_CLASS_CONTEXT (NODE) : DECL_CONTEXT (NODE))
/* For a FUNCTION_DECL: the chain through which the next method
with the same name is found. We now use TREE_CHAIN to
walk through the methods in order of declaration.
For a NAMESPACE_DECL: the list of using namespace directives
/* For a NAMESPACE_DECL: the list of using namespace directives
The PURPOSE is the used namespace, the value is the namespace
that is the common ancestor */
#if 1
#define DECL_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->chain)
#else
#define DECL_CHAIN(NODE) (TREE_CHAIN (NODE))
#endif
#define DECL_NAMESPACE_USING(NODE) (DECL_LANG_SPECIFIC(NODE)->chain)
that is the common ancestor. */
#define DECL_NAMESPACE_USING(NODE) DECL_VINDEX(NODE)
/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users
of a namespace, to record the transitive closure of using namespace */
of a namespace, to record the transitive closure of using namespace. */
#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NODE)
/* In a TREE_LIST concatenating using directives, indicate indirekt
@ -1494,12 +1518,6 @@ extern int flag_new_for_scope;
#define DECL_REALLY_EXTERN(NODE) \
(DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
/* Records the namespace we are in */
#define DECL_NAMESPACE(NODE) \
(DECL_LANG_SPECIFIC (NODE) ? DECL_LANG_SPECIFIC (NODE)->decl_flags.in_namespace : 0)
#define SET_DECL_NAMESPACE(NODE, val) \
DECL_LANG_SPECIFIC (NODE)->decl_flags.in_namespace = val
/* Used to tell cp_finish_decl that it should approximate comdat linkage
as best it can for this decl. */
#define DECL_COMDAT(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.comdat)
@ -1952,6 +1970,10 @@ extern int flag_weak;
extern int flag_new_abi;
/* Nonzero to not ignore namespace std. */
extern int flag_honor_std;
/* Nonzero if we're done parsing and into end-of-file activities. */
extern int at_eof;
@ -2153,6 +2175,7 @@ extern void pop_namespace PROTO((void));
extern void maybe_push_to_top_level PROTO((int));
extern void push_to_top_level PROTO((void));
extern void pop_from_top_level PROTO((void));
extern tree identifier_type_value PROTO((tree));
extern void set_identifier_type_value PROTO((tree, tree));
extern void pop_everything PROTO((void));
extern void pushtag PROTO((tree, tree, int));
@ -2166,8 +2189,9 @@ extern tree pushdecl_class_level PROTO((tree));
#if 0
extern void pushdecl_nonclass_level PROTO((tree));
#endif
extern tree pushdecl_namespace_level PROTO((tree));
extern tree push_using_decl PROTO((tree, tree));
extern void push_class_level_binding PROTO((tree, tree));
extern int overloaded_globals_p PROTO((tree));
extern tree implicitly_declare PROTO((tree));
extern tree lookup_label PROTO((tree));
extern tree shadow_label PROTO((tree));
@ -2181,13 +2205,16 @@ extern tree gettags PROTO((void));
extern void set_current_level_tags_transparency PROTO((int));
#endif
extern tree binding_for_name PROTO((tree, tree));
extern tree namespace_binding PROTO((tree, tree));
extern void set_namespace_binding PROTO((tree, tree, tree));
extern tree lookup_namespace_name PROTO((tree, tree));
extern tree make_typename_type PROTO((tree, tree));
extern tree lookup_name_nonclass PROTO((tree));
extern tree lookup_function_nonclass PROTO((tree, tree));
extern tree lookup_name PROTO((tree, int));
extern tree lookup_name_current_level PROTO((tree));
extern tree lookup_using_namespace PROTO((tree,tree,tree,tree));
extern tree qualified_lookup_using_namespace PROTO((tree,tree));
extern int lookup_using_namespace PROTO((tree,tree,tree,tree));
extern int qualified_lookup_using_namespace PROTO((tree,tree,tree));
extern tree auto_function PROTO((tree, tree, enum built_in_function));
extern void init_decl_processing PROTO((void));
extern int init_type_desc PROTO((void));
@ -2234,6 +2261,7 @@ extern int in_function_p PROTO((void));
extern void replace_defarg PROTO((tree, tree));
extern void print_other_binding_stack PROTO((struct binding_level *));
extern void revert_static_member_fn PROTO((tree*, tree*, tree*));
extern void cat_namespace_levels PROTO((void));
/* in decl2.c */
extern int flag_assume_nonnull_objects;
@ -2281,8 +2309,10 @@ extern tree build_expr_from_tree PROTO((tree));
extern tree reparse_decl_as_expr PROTO((tree, tree));
extern tree finish_decl_parsing PROTO((tree));
extern tree check_cp_case_value PROTO((tree));
extern tree get_namespace_id PROTO((void));
extern tree current_namespace_id PROTO((tree));
extern void set_decl_namespace PROTO((tree, tree));
extern tree current_decl_namespace PROTO((void));
extern void push_decl_namespace PROTO((tree));
extern void pop_decl_namespace PROTO((void));
extern void do_namespace_alias PROTO((tree, tree));
extern void do_toplevel_using_decl PROTO((tree));
extern tree do_class_using_decl PROTO((tree));
@ -2290,6 +2320,7 @@ extern void do_using_directive PROTO((tree));
extern void check_default_args PROTO((tree));
extern void mark_used PROTO((tree));
extern tree handle_class_head PROTO((tree, tree, tree));
extern tree lookup_arg_dependent PROTO((tree, tree, tree));
/* in errfn.c */
extern void cp_error ();
@ -2636,10 +2667,14 @@ extern tree get_decl_list PROTO((tree));
extern tree make_binfo PROTO((tree, tree, tree, tree, tree));
extern tree binfo_value PROTO((tree, tree));
extern tree reverse_path PROTO((tree));
extern int decl_list_length PROTO((tree));
extern int count_functions PROTO((tree));
extern int is_overloaded_fn PROTO((tree));
extern tree get_first_fn PROTO((tree));
extern tree binding_init PROTO((struct tree_binding*));
extern tree ovl_cons PROTO((tree, tree));
extern tree scratch_ovl_cons PROTO((tree, tree));
extern int ovl_member PROTO((tree, tree));
extern tree build_overload PROTO((tree, tree));
extern tree fnaddr_from_vtable_entry PROTO((tree));
extern tree function_arg_chain PROTO((tree));
extern int promotes_to_aggr_type PROTO((tree, enum tree_code));
@ -2674,6 +2709,7 @@ extern void push_expression_obstack PROTO((void));
#define scratch_tree_cons expr_tree_cons
#define build_scratch_list build_expr_list
#define make_scratch_vec make_temp_vec
#define push_scratch_obstack push_expression_obstack
/* in typeck.c */
extern tree condition_conversion PROTO((tree));

File diff suppressed because it is too large Load Diff

View File

@ -88,11 +88,15 @@ int at_eof;
tree static_ctors, static_dtors;
/* The current open namespace, and :: */
/* The current open namespace, and ::. */
tree current_namespace;
tree global_namespace;
/* The stack for namespaces of current declarations. */
static tree decl_namespace_list;
/* C (and C++) language-specific option variables. */
@ -410,6 +414,10 @@ int flag_weak = 1;
int flag_new_abi;
/* Nonzero to not ignore namespace std. */
int flag_honor_std;
/* Maximum template instantiation depth. Must be at least 17 for ANSI
compliance. */
@ -460,6 +468,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"default-inline", &flag_default_inline, 1},
{"dollars-in-identifiers", &dollars_in_ident, 1},
{"enum-int-equiv", &flag_int_enum_equivalence, 1},
{"honor-std", &flag_honor_std, 1},
{"rtti", &flag_rtti, 1},
{"xref", &flag_gnu_xref, 1},
{"nonnull-objects", &flag_assume_nonnull_objects, 1},
@ -572,12 +581,14 @@ lang_decode_option (p)
{
flag_new_abi = 1;
flag_do_squangling = 1;
flag_honor_std = 1;
flag_vtable_thunks = 1;
}
else if (!strcmp (p, "no-new-abi"))
{
flag_new_abi = 0;
flag_do_squangling = 0;
flag_honor_std = 0;
}
else if (!strncmp (p, "template-depth-", 15))
{
@ -1391,7 +1402,7 @@ check_classfn (ctype, function)
tree ctype, function;
{
tree fn_name = DECL_NAME (function);
tree fndecl;
tree fndecl, fndecls;
tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
tree *methods = 0;
tree *end = 0;
@ -1403,22 +1414,23 @@ check_classfn (ctype, function)
end = TREE_VEC_END (method_vec);
/* First suss out ctors and dtors. */
if (*methods && fn_name == DECL_NAME (*methods)
if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
&& DECL_CONSTRUCTOR_P (function))
goto got_it;
if (*++methods && fn_name == DECL_NAME (*methods)
if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
&& DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))
goto got_it;
while (++methods != end)
{
fndecl = *methods;
if (fn_name == DECL_NAME (*methods))
if (fn_name == DECL_NAME (OVL_CURRENT (*methods)))
{
got_it:
for (fndecl = *methods; fndecl != NULL_TREE;
fndecl = DECL_CHAIN (fndecl))
for (fndecls = *methods; fndecls != NULL_TREE;
fndecls = OVL_NEXT (fndecls))
{
fndecl = OVL_CURRENT (fndecls);
/* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is
not mangled, so the check below does not work
correctly in that case. */
@ -1489,10 +1501,10 @@ check_classfn (ctype, function)
tree fndecl = *methods;
cp_error ("prototype for `%#D' does not match any in class `%T'",
function, ctype);
cp_error_at ("candidate%s: %+#D", DECL_CHAIN (fndecl) ? "s are" : " is",
fndecl);
while (fndecl = DECL_CHAIN (fndecl), fndecl)
cp_error_at (" %#D", fndecl);
cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is",
OVL_CURRENT (fndecl));
while (fndecl = OVL_NEXT (fndecl), fndecl)
cp_error_at (" %#D", OVL_CURRENT(fndecl));
}
else
{
@ -1745,14 +1757,6 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
if (TREE_CODE (value) == FUNCTION_DECL)
{
check_default_args (value);
if (DECL_CHAIN (value) != NULL_TREE)
{
/* Need a fresh node here so that we don't get circularity
when we link these together. */
value = copy_node (value);
/* When does this happen? */
my_friendly_assert (init == NULL_TREE, 193);
}
if (asmspec)
{
/* This must override the asm specifier which was placed
@ -2777,7 +2781,7 @@ get_sentry (base)
tree base;
{
tree sname = get_id_2 ("__sn", base);
/* for struct X foo __attribute__((weak)), there is a counter
/* For struct X foo __attribute__((weak)), there is a counter
__snfoo. Since base is already an assembler name, sname should
be globally unique */
tree sentry = IDENTIFIER_GLOBAL_VALUE (sname);
@ -2855,6 +2859,8 @@ finish_file ()
instantiate_decl (fn);
}
cat_namespace_levels();
/* Push into C language context, because that's all
we'll need here. */
push_lang_context (lang_name_c);
@ -2973,7 +2979,7 @@ finish_file ()
assemble_destructor (IDENTIFIER_POINTER (fnname));
/* if it needed cleaning, then it will need messing up: drop through */
/* If it needed cleaning, then it will need messing up: drop through. */
mess_up:
/* Must do this while we think we are at the top level. */
@ -3666,7 +3672,8 @@ check_cp_case_value (value)
return value;
}
/* return 1 if root encloses child */
/* Return 1 if root encloses child. */
static int
is_namespace_ancestor (root, child)
tree root, child;
@ -3677,19 +3684,20 @@ is_namespace_ancestor (root, child)
return 1;
if (child == global_namespace)
return 0;
return is_namespace_ancestor (root, DECL_NAMESPACE (child));
return is_namespace_ancestor (root, DECL_CONTEXT (child));
}
/* return the namespace that is the common ancestor
of two given namespaces */
/* Return the namespace that is the common ancestor
of two given namespaces. */
static tree
namespace_ancestor (ns1, ns2)
tree ns1, ns2;
{
if (is_namespace_ancestor (ns1, ns2))
return ns1;
return namespace_ancestor (DECL_NAMESPACE (ns1), ns2);
return namespace_ancestor (DECL_CONTEXT (ns1), ns2);
}
/* Insert used into the using list of user. Set indirect_flag if this
@ -3702,23 +3710,23 @@ add_using_namespace (user, used, indirect)
int indirect;
{
tree iter;
/* using oneself is a no-op */
/* Using oneself is a no-op. */
if (user == used)
return;
my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
/* check if we already have this */
/* Check if we already have this. */
if (purpose_member (used, DECL_NAMESPACE_USING (user)) != NULL_TREE)
return;
/* add used to the user's using list */
/* Add used to the user's using list. */
DECL_NAMESPACE_USING (user)
= perm_tree_cons (used, namespace_ancestor (user, used),
DECL_NAMESPACE_USING (user));
TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
/* add user to the used's users list */
/* Add user to the used's users list. */
DECL_NAMESPACE_USERS (used)
= perm_tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
@ -3727,102 +3735,130 @@ add_using_namespace (user, used, indirect)
add_using_namespace (TREE_PURPOSE (iter), used, 1);
}
/* Combines two sets of overloaded functions into an OVERLOAD chain.
The first list becomes the tail of the result. */
static tree
merge_functions (s1, s2)
tree s1;
tree s2;
{
tree tmp, tempn;
if (TREE_CODE (s2) == OVERLOAD)
while (s2)
{
s1 = build_overload (OVL_FUNCTION (s2), s1);
s2 = OVL_CHAIN (s2);
}
else
s1 = build_overload (s2, s1);
return s1;
}
/* This should return an error not all definitions define functions.
It is not an error if we find two functions with exactly the
same signature, only if these are selected in overload resolution.
old is the current set of bindings, new the freshly-found binding.
XXX Do we want to give *all* candidates in case of ambiguity?
XXX In what way should I treat extern declarations?
XXX I don't want to repeat the entire duplicate_decls here */
static tree
ambiguous_decl (name, val1, val2)
tree name, val1, val2;
ambiguous_decl (name, old, new)
tree name;
tree old;
tree new;
{
my_friendly_assert (val1 != val2, 376);
if (is_overloaded_fn (val1) && is_overloaded_fn (val1))
my_friendly_assert (old != NULL_TREE, 393);
/* Copy the value. */
if (!BINDING_VALUE (old))
BINDING_VALUE (old) = BINDING_VALUE (new);
else if (BINDING_VALUE (new)
&& BINDING_VALUE (new) != BINDING_VALUE (old))
{
/* now built a joint list of all overloaded declarations */
/* XXX if I chain'em together, they will be always considered
as overloaded */
sorry ("overloaded functions used from different namespaces");
if (is_overloaded_fn (BINDING_VALUE (old))
&& is_overloaded_fn (BINDING_VALUE (new)))
{
BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old),
BINDING_VALUE (new));
}
else
{
/* Some declarations are functions, some are not. */
cp_error ("ambiguous definition `%D' used", name);
cp_error_at ("first definition here", BINDING_VALUE (old));
cp_error_at ("other definition here", BINDING_VALUE (new));
return error_mark_node;
}
}
cp_error ("ambiguous definition `%D' used", name);
cp_error_at ("first definition here", val1);
cp_error_at ("other definition here", val2);
return error_mark_node;
/* ... and copy the type. */
if (!BINDING_TYPE (old))
BINDING_TYPE (old) = BINDING_TYPE (new);
else if(BINDING_TYPE (new)
&& BINDING_TYPE (old) != BINDING_TYPE (new))
{
cp_error ("`%D' denotes an ambiguous type",name);
cp_error_at ("first type here", BINDING_TYPE (old));
cp_error_at ("other type here", BINDING_TYPE (new));
}
return old;
}
/* add the bindings of name in used namespaces to val
the using list is defined by current, and the lookup goes to scope */
tree
/* Add the bindings of name in used namespaces to val.
The using list is defined by current, and the lookup goes to scope.
Returns zero on errors. */
int
lookup_using_namespace (name, val, current, scope)
tree name, val, current, scope;
{
tree iter;
tree val1;
/* iterate over all namespaces from current to scope */
while (1)
/* Iterate over all namespaces from current to scope. */
while (val != error_mark_node)
{
/* iterate over all used namespaces in current, searching for
using directives of scope */
/* Iterate over all used namespaces in current, searching for
using directives of scope. */
for (iter = DECL_NAMESPACE_USING (current);
iter; iter = TREE_CHAIN (iter))
if (TREE_VALUE (iter) == scope)
{
val1 = NAMESPACE_BINDING (name, TREE_PURPOSE (iter));
/* name not found in this space */
if (!val1)
continue;
/* first definition ever */
if (!val)
{
val = val1;
continue;
}
/* Hmmm. Ambiguity. As long as both are overloaded functions,
this is fine */
val1 = binding_for_name (name, TREE_PURPOSE (iter));
/* Resolve ambiguities. */
val = ambiguous_decl (name, val, val1);
if (val == error_mark_node)
break;
}
if (current == scope)
break;
current = DECL_NAMESPACE (current);
current = DECL_CONTEXT (current);
}
return val;
return val != error_mark_node;
}
/* [namespace.qual] */
tree
qualified_lookup_using_namespace (name, scope)
/* [namespace.qual]
Excepts the name to lookup and its qualifying scope.
Returns the name/type pair found into the CPLUS_BINDING result,
or 0 on error. */
int
qualified_lookup_using_namespace (name, scope, result)
tree name;
tree scope;
tree result;
{
tree val = NULL_TREE;
tree val1;
/* maintain a list of namespaces visited */
/* Maintain a list of namespaces visited... */
tree seen = NULL_TREE;
/* and a list of namespace yet to see */
/* ... and a list of namespace yet to see. */
tree todo = NULL_TREE;
tree usings;
while (scope)
while (scope && (result != error_mark_node))
{
seen = temp_tree_cons (scope, NULL_TREE, seen);
val1 = NAMESPACE_BINDING (name, scope);
if (val1)
{
if (val)
{
val = ambiguous_decl (name, val, val1);
break;
}
else
val = val1;
}
else
/* consider using directives */
result = ambiguous_decl (name, result, binding_for_name (name, scope));
if (!BINDING_VALUE (result) && !BINDING_TYPE (result))
/* Consider using directives. */
for (usings = DECL_NAMESPACE_USING (scope); usings;
usings = TREE_CHAIN (usings))
/* if this was a real directive, and we have not seen it */
/* If this was a real directive, and we have not seen it. */
if (!TREE_INDIRECT_USING (usings)
&& !purpose_member (seen, TREE_PURPOSE (usings)))
todo = temp_tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
@ -3832,45 +3868,360 @@ qualified_lookup_using_namespace (name, scope)
todo = TREE_CHAIN (todo);
}
else
scope = NULL_TREE; /* if there never was a todo list */
scope = NULL_TREE; /* If there never was a todo list. */
}
return val;
return result != error_mark_node;
}
#if 0
/* this is broken and should not be called anymore */
/* Get the inner part of a namespace id. It doesn't have any prefix, nor
postfix. Returns 0 if in global namespace. */
/* [namespace.memdef]/2 */
tree
get_namespace_id ()
/* Set the context of a declaration to scope. Complain if we are not
outside scope. */
void
set_decl_namespace (decl, scope)
tree decl;
tree scope;
{
tree x = current_namespace;
if (x)
x = TREE_PURPOSE (x);
return x;
}
tree old;
if (scope == std_node)
scope = global_namespace;
if (!is_namespace_ancestor (current_namespace, scope))
cp_error ("declaration of `%D' not in a namespace surrounding `%D'",
decl, scope);
DECL_CONTEXT (decl) = scope;
if (scope != current_namespace)
{
/* See whether this has been declared in the namespace. */
old = namespace_binding (DECL_NAME (decl), scope);
if (!old)
/* No old declaration at all. */
goto complain;
if (!is_overloaded_fn (decl))
/* Don't compare non-function decls with decls_match here,
since it can't check for the correct constness at this
point. pushdecl will find those errors later. */
return;
/* Since decl is a function, old should contain a function decl. */
if (!is_overloaded_fn (old))
goto complain;
for (; old; old = OVL_NEXT (old))
if (decls_match (decl, OVL_CURRENT (old)))
return;
}
else
return;
complain:
cp_error ("`%D' should have been declared inside `%D'",
decl, scope);
}
/* Build up a DECL_ASSEMBLER_NAME for NAME in the current namespace. */
/* Compute the namespace where a declaration is defined. */
tree
current_namespace_id (name)
decl_namespace (decl)
tree decl;
{
while (DECL_CONTEXT (decl))
{
decl = DECL_CONTEXT (decl);
if (TREE_CODE (decl) == NAMESPACE_DECL)
return decl;
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')
decl = TYPE_STUB_DECL (decl);
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 390);
}
/* We should always find the namespace. */
my_friendly_abort (390);
return NULL_TREE;
}
/* Return the namespace where the current declaration is declared. */
tree
current_decl_namespace ()
{
tree result;
/* If we have been pushed into a different namespace, use it. */
if (decl_namespace_list)
return TREE_PURPOSE (decl_namespace_list);
if (current_class_type)
if (CLASSTYPE_USE_TEMPLATE (current_class_type))
result = decl_namespace (CLASSTYPE_TI_TEMPLATE (current_class_type));
else
result = decl_namespace (TYPE_STUB_DECL (current_class_type));
else if (current_function_decl)
if (DECL_USE_TEMPLATE (current_function_decl))
result = decl_namespace (DECL_TI_TEMPLATE (current_function_decl));
else
result = decl_namespace (current_function_decl);
else
result = current_namespace;
return result;
}
/* Temporarily set the namespace for the current declaration. */
void
push_decl_namespace (decl)
tree decl;
{
if (TREE_CODE (decl) != NAMESPACE_DECL)
decl = decl_namespace (decl);
decl_namespace_list = tree_cons (decl, NULL_TREE, decl_namespace_list);
}
void
pop_decl_namespace ()
{
decl_namespace_list = TREE_CHAIN (decl_namespace_list);
}
/* [basic.lookup.koenig] */
/* A non-zero return value in the functions below indicates an error.
All nodes allocated in the procedure are on the scratch obstack. */
struct arg_lookup
{
tree name;
tree namespaces;
tree classes;
tree functions;
};
static int arg_assoc PROTO((struct arg_lookup*, tree));
static int arg_assoc_args PROTO((struct arg_lookup*, tree));
/* Add a function to the lookup structure. */
static int
add_function (k, fn)
struct arg_lookup *k;
tree fn;
{
if (ovl_member (fn, k->functions))
return 0;
k->functions = build_overload (fn, k->functions);
return 0;
}
/* Add functions of a namespace to the lookup structure. */
static int
arg_assoc_namespace (k, scope)
struct arg_lookup *k;
tree scope;
{
tree value;
if (purpose_member (scope, k->namespaces))
return 0;
k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
value = namespace_binding (k->name, scope);
if (!value)
return 0;
if (!is_overloaded_fn (value))
{
cp_error_at ("`%D' is not a function", value);
cp_error ("in call to `%D'", k->name);
return 1;
}
for (; value; value = OVL_NEXT (value))
if (add_function (k, OVL_CURRENT (value)))
return 1;
return 0;
}
/* Adds everything associated with class to the lookup structure. */
static int
arg_assoc_class (k, type)
struct arg_lookup* k;
tree type;
{
tree list, friends, context;
int i;
if (purpose_member (type, k->classes))
return 0;
k->classes = tree_cons (type, NULL_TREE, k->classes);
context = decl_namespace (TYPE_MAIN_DECL (type));
if (arg_assoc_namespace (k, context))
return 1;
/* Process baseclasses. */
for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++)
if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i)))
return 1;
/* Process friends. */
for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
list = TREE_CHAIN (list))
if (k->name == TREE_PURPOSE (list))
for (friends = TREE_VALUE (list); friends;
friends = TREE_CHAIN (friends))
/* Only interested in global functions with potentially hidden
(i.e. unqualified) declarations. */
if (TREE_PURPOSE (list) == error_mark_node && TREE_VALUE (list)
&& decl_namespace (TREE_VALUE (list)) == context)
if (add_function (k, TREE_VALUE (list)))
return 1;
return 0;
}
/* Adds everything associated with a given type. */
static int
arg_assoc_type (k, type)
struct arg_lookup *k;
tree type;
{
switch (TREE_CODE (type))
{
case VOID_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
case COMPLEX_TYPE:
case CHAR_TYPE:
case BOOLEAN_TYPE:
return 0;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type))
return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
return arg_assoc_class (k, type);
case POINTER_TYPE:
case REFERENCE_TYPE:
case ARRAY_TYPE:
return arg_assoc_type (k, TREE_TYPE (type));
case UNION_TYPE:
case ENUMERAL_TYPE:
return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
case METHOD_TYPE:
/* Associate the class of the method. */
if (arg_assoc_type (k, TYPE_METHOD_BASETYPE (type)))
return 1;
/* Fall through. */
case FUNCTION_TYPE:
/* Associate the parameter types. */
if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
return 1;
/* Associate the return type. */
return arg_assoc_type (k, TREE_TYPE (type));
default:
my_friendly_abort (390);
}
return 0;
}
/* Adds everything associated with arguments. */
static int
arg_assoc_args (k, args)
struct arg_lookup* k;
tree args;
{
for (; args; args = TREE_CHAIN (args))
if (arg_assoc (k, TREE_VALUE (args)))
return 1;
return 0;
}
/* Adds everything associated with a given tree_node. */
static int
arg_assoc (k, n)
struct arg_lookup* k;
tree n;
{
switch (TREE_CODE_CLASS (TREE_CODE (n)))
{
case 't':
return arg_assoc_type (k, n);
case 'c':
case '1':
case '2':
case '<':
case 'r':
return arg_assoc_type (k, TREE_TYPE (n));
case 'e':
switch (TREE_CODE (n))
{
case ADDR_EXPR:
/* special processing */
break;
default:
return arg_assoc_type (k, TREE_TYPE (n));
}
default:
break;
}
while (n)
switch (TREE_CODE (n))
{
case CONST_DECL: /* 'd' */
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
return arg_assoc_type (k, TREE_TYPE (n));
case ADDR_EXPR: /* 'e' */
/* We can't use the TREE_TYPE, as the type of an overloaded function
will be useless here. */
n = TREE_OPERAND (n, 0);
continue;
case OVERLOAD: /* 'x' */
if (arg_assoc (k, OVL_CURRENT (n)))
return 1;
n = OVL_NEXT (n);
continue;
case TREE_LIST: /* 'x' */
/* XXX Overloaded member, should get an OVERLOAD directly, here. */
n = TREE_VALUE (n);
continue;
case FUNCTION_DECL: /* 'd' */
if (arg_assoc_args (k, FUNCTION_ARG_CHAIN (n)))
return 1;
if (DECL_FUNCTION_MEMBER_P (n))
if (arg_assoc_type (k, DECL_CLASS_CONTEXT (n)))
return 1;
return 0;
default:
cp_error ("sorry, Koenig lookup for `%s' of type `%T' failed",
tree_code_name [(int)TREE_CODE (n)], TREE_TYPE (n));
my_friendly_abort (391);
}
return 0;
}
/* Performs Koenig lookup depending on arguments, where fns
are the functions found in normal lookup. */
tree
lookup_arg_dependent (name, fns, args)
tree name;
tree fns;
tree args;
{
tree old_id = get_namespace_id ();
char *buf;
/* Global names retain old encoding. */
if (! old_id)
return name;
buf = (char *) alloca (8 + IDENTIFIER_LENGTH (old_id)
+ IDENTIFIER_LENGTH (name));
sprintf (buf, "__ns_%s_%s", IDENTIFIER_POINTER (old_id),
IDENTIFIER_POINTER (name));
return get_identifier (buf);
struct arg_lookup k;
k.name = name;
k.functions = fns;
k.namespaces = NULL_TREE;
k.classes = NULL_TREE;
push_scratch_obstack ();
arg_assoc_args (&k, args);
pop_obstacks ();
return k.functions;
}
#endif
/* Process a namespace-alias declaration. */
void
do_namespace_alias (alias, namespace)
@ -3901,34 +4252,100 @@ do_namespace_alias (alias, namespace)
}
}
/* Process a using-declaration not appearing in class or local scope. */
void
do_toplevel_using_decl (decl)
tree decl;
{
#if 1
tree scope, name, binding, decls, newval, newtype;
struct tree_binding _decls;
if (TREE_CODE (decl) == SCOPE_REF
&& TREE_OPERAND (decl, 0) == std_node)
return;
sorry ("using-declaration");
#else
if (decl == NULL_TREE || decl == error_mark_node)
return;
if (TREE_CODE (decl) == SCOPE_REF)
decl = resolve_scope_to_name (NULL_TREE, decl);
/* Is this the right way to do an id list? */
if (TREE_CODE (decl) != TREE_LIST)
{
pushdecl (decl);
scope = TREE_OPERAND (decl, 0);
name = TREE_OPERAND (decl, 1);
}
else if (TREE_CODE (decl) == IDENTIFIER_NODE)
{
scope = global_namespace;
name = decl;
}
else
while (decl)
{
pushdecl (TREE_VALUE (decl));
decl = TREE_CHAIN (decl);
}
#endif
my_friendly_abort (382);
if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd')
name = DECL_NAME (name);
/* Make a USING_DECL. */
decl = push_using_decl (scope, name);
if (!decl)
return;
binding = binding_for_name (name, current_namespace);
decls = binding_init (&_decls);
if (!qualified_lookup_using_namespace (name, scope, decls))
/* Lookup error */
return;
if (!BINDING_VALUE (decls) && !BINDING_TYPE (decls))
{
cp_error ("`%D' not declared", name);
return;
}
newval = newtype = NULL_TREE;
/* Check for using functions. */
if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls)))
{
tree oldval = BINDING_VALUE (binding);
tree tmp, tmp1;
newval = oldval;
for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
{
/* Compare each new function with each old one.
If the old function was also used, there is no conflict. */
for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
if (OVL_CURRENT (tmp) == OVL_CURRENT (tmp1))
break;
else if (OVL_USED (tmp1))
continue;
else if (duplicate_decls (OVL_CURRENT (tmp), OVL_CURRENT (tmp1)))
return;
/* Duplicate use, ignore */
if (tmp1)
continue;
newval = build_overload (OVL_CURRENT (tmp), newval);
if (TREE_CODE (newval) != OVERLOAD)
newval = ovl_cons (newval, NULL_TREE);
OVL_USED (newval) = 1;
}
}
else
{
tree oldval = BINDING_VALUE (binding);
newval = BINDING_VALUE (decls);
if (oldval && oldval != newval && !duplicate_decls (newval, oldval))
newval = oldval;
}
newtype = BINDING_TYPE (decls);
if (BINDING_TYPE (binding) && newtype && BINDING_TYPE (binding) != newtype)
{
cp_error ("using directive `%D' introduced ambiguous type `%T'",
name, BINDING_TYPE (decls));
return;
}
/* Copy declarations found. */
if (newval)
BINDING_VALUE (binding) = newval;
if (newtype)
BINDING_TYPE (binding) = newtype;
return;
}
tree
@ -3937,7 +4354,8 @@ do_class_using_decl (decl)
{
tree name, value;
if (TREE_CODE (decl) != SCOPE_REF)
if (TREE_CODE (decl) != SCOPE_REF
|| TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (decl, 0))) != 't')
{
cp_error ("using-declaration for non-member at class scope");
return NULL_TREE;
@ -3954,15 +4372,33 @@ do_class_using_decl (decl)
return value;
}
/* Process a using-directive. */
void
do_using_directive (namespace)
tree namespace;
{
if (namespace == std_node)
return;
if (!toplevel_bindings_p ())
{
sorry ("using directives inside functions");
return;
}
/* using A::B::C; */
if (TREE_CODE (namespace) == SCOPE_REF)
namespace = TREE_OPERAND (namespace, 1);
if (TREE_CODE (namespace) == IDENTIFIER_NODE)
{
/* Lookup in lexer did not find a namespace. */
cp_error ("namespace `%T' undeclared", namespace);
return;
}
if (TREE_CODE (namespace) != NAMESPACE_DECL)
{
cp_error ("`%T' is not a namespace", namespace);
return;
}
/* direct usage */
add_using_namespace (current_namespace, namespace, 0);
}

View File

@ -341,7 +341,7 @@ dump_aggr_type (t, v, canonical_name)
name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t);
if (name && DECL_CONTEXT (name))
if (name && DECL_CONTEXT (name) && DECL_CONTEXT (name) != global_namespace)
{
/* FUNCTION_DECL or RECORD_TYPE */
dump_decl (DECL_CONTEXT (name), 0);
@ -710,9 +710,9 @@ dump_decl (t, v)
break;
case NAMESPACE_DECL:
if (DECL_NAMESPACE (t) != global_namespace)
if (DECL_CONTEXT (t) != global_namespace)
{
dump_decl (DECL_NAMESPACE (t), v);
dump_decl (DECL_CONTEXT (t), v);
OB_PUTC2 (':',':');
}
OB_PUTID (DECL_NAME (t));

View File

@ -217,9 +217,13 @@ init_exception_processing ()
/* void vtype () */
tree vtype = build_function_type (void_type_node, void_list_node);
if (flag_honor_std)
push_namespace (get_identifier ("std"));
Terminate = auto_function (get_identifier ("terminate"),
vtype, NOT_BUILT_IN);
TREE_THIS_VOLATILE (Terminate) = 1;
if (flag_honor_std)
pop_namespace ();
push_lang_context (lang_name_c);

View File

@ -34,10 +34,11 @@
/* Define terminate, unexpected, set_terminate, set_unexpected as
well as the default terminate func and default unexpected func. */
extern terminate_handler __terminate_func __attribute__((__noreturn__));
extern std::terminate_handler __terminate_func __attribute__((__noreturn__));
using std::terminate;
void
terminate ()
std::terminate ()
{
__terminate_func ();
}
@ -48,29 +49,29 @@ __default_unexpected ()
terminate ();
}
static unexpected_handler __unexpected_func __attribute__((__noreturn__))
static std::unexpected_handler __unexpected_func __attribute__((__noreturn__))
= __default_unexpected;
terminate_handler
set_terminate (terminate_handler func)
std::terminate_handler
std::set_terminate (std::terminate_handler func)
{
terminate_handler old = __terminate_func;
std::terminate_handler old = __terminate_func;
__terminate_func = func;
return old;
}
unexpected_handler
set_unexpected (unexpected_handler func)
std::unexpected_handler
std::set_unexpected (std::unexpected_handler func)
{
unexpected_handler old = __unexpected_func;
std::unexpected_handler old = __unexpected_func;
__unexpected_func = func;
return old;
}
void
unexpected ()
std::unexpected ()
{
__unexpected_func ();
}
@ -223,7 +224,7 @@ __check_eh_spec (int n, const void **spec)
try
{
unexpected ();
std::unexpected ();
}
catch (...)
{
@ -238,11 +239,11 @@ __check_eh_spec (int n, const void **spec)
}
}
const type_info &bad_exc = typeid (bad_exception);
const std::type_info &bad_exc = typeid (std::bad_exception);
for (int i = 0; i < n; ++i)
{
if (__throw_type_match_rtti (spec[i], &bad_exc, p->value))
throw bad_exception ();
throw std::bad_exception ();
}
terminate ();
@ -252,25 +253,25 @@ __check_eh_spec (int n, const void **spec)
extern "C" void
__throw_bad_cast (void)
{
throw bad_cast ();
throw std::bad_cast ();
}
extern "C" void
__throw_bad_typeid (void)
{
throw bad_typeid ();
throw std::bad_typeid ();
}
/* Has the current exception been caught? */
bool
uncaught_exception ()
std::uncaught_exception ()
{
cp_eh_info *p = __cp_exception_info ();
return p && ! p->caught;
}
const char * exception::
const char * std::exception::
what () const
{
return typeid (*this).name ();

View File

@ -118,6 +118,10 @@ is_friend (type, supplicant)
else
context = NULL_TREE;
/* A namespace is not friend to anybody. */
if (context && TREE_CODE (context) == NAMESPACE_DECL)
context = NULL_TREE;
if (context)
return is_friend (type, context);

View File

@ -8,7 +8,7 @@
extern "C++" {
#if 0
#ifdef __HONOR_STD
namespace std {
#endif
@ -34,7 +34,7 @@ unexpected_handler set_unexpected (unexpected_handler);
void unexpected (void) __attribute__ ((__noreturn__));
bool uncaught_exception ();
#if 0
#ifdef __HONOR_STD
} // namespace std
#endif

View File

@ -10,7 +10,7 @@
extern "C++" {
#if 0
#ifdef __HONOR_STD
namespace std {
#endif
@ -24,7 +24,7 @@ namespace std {
typedef void (*new_handler)();
new_handler set_new_handler (new_handler);
#if 0
#ifdef __HONOR_STD
} // namespace std
#endif
@ -33,10 +33,10 @@ void *operator new (size_t) throw (std::bad_alloc);
void *operator new[] (size_t) throw (std::bad_alloc);
void operator delete (void *) throw();
void operator delete[] (void *) throw();
void *operator new (size_t, const nothrow_t&) throw();
void *operator new[] (size_t, const nothrow_t&) throw();
void operator delete (void *, const nothrow_t&) throw();
void operator delete[] (void *, const nothrow_t&) throw();
void *operator new (size_t, const std::nothrow_t&) throw();
void *operator new[] (size_t, const std::nothrow_t&) throw();
void operator delete (void *, const std::nothrow_t&) throw();
void operator delete[] (void *, const std::nothrow_t&) throw();
// default placement versions of operator new
inline void *operator new(size_t, void *place) throw() { return place; }

View File

@ -5,7 +5,7 @@
#include <new>
#if 0
#ifdef __HONOR_STD
using std::new_handler;
using std::set_new_handler;
#endif

View File

@ -8,7 +8,7 @@
extern "C++" {
#if 0
#ifdef __HONOR_STD
namespace std {
#endif
@ -63,7 +63,7 @@ class bad_typeid : public exception {
virtual ~bad_typeid () { }
};
#if 0
#ifdef __HONOR_STD
} // namespace std
#endif

View File

@ -1069,22 +1069,8 @@ expand_member_init (exp, name, init)
if (fndecl)
my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 209);
/* If the field is unique, we can use the parameter
types to guide possible type instantiation. */
if (DECL_CHAIN (fndecl) == NULL_TREE)
{
/* There was a confusion here between
FIELD and FNDECL. The following code
should be correct, but abort is here
to make sure. */
my_friendly_abort (48);
parmtypes = FUNCTION_ARG_CHAIN (fndecl);
}
else
{
parmtypes = NULL_TREE;
fndecl = NULL_TREE;
}
parmtypes = NULL_TREE;
fndecl = NULL_TREE;
init = convert_arguments (parm, parmtypes, NULL_TREE, fndecl, LOOKUP_NORMAL);
if (init == NULL_TREE || TREE_TYPE (init) != error_mark_node)
@ -1711,10 +1697,13 @@ build_offset_ref (type, name)
/* Go from the TREE_BASELINK to the member function info. */
t = TREE_VALUE (fnfields);
if (DECL_CHAIN (t) == NULL_TREE)
if (!really_overloaded_fn (t))
{
tree access;
/* Get rid of a potential OVERLOAD around it */
t = OVL_CURRENT (t);
/* unique functions are handled easily. */
access = compute_access (basebinfo, t);
if (access == access_protected_node)
@ -1742,7 +1731,7 @@ build_offset_ref (type, name)
??? The smart thing to do for the case of saving initializers
is to resolve them before we're done with this scope. */
if (!TREE_PERMANENT (fnfields)
&& ((flag_save_memoized_contexts && global_bindings_p ())
&& ((flag_save_memoized_contexts && toplevel_bindings_p ())
|| ! allocation_temporary_p ()))
fnfields = copy_list (fnfields);

View File

@ -56,6 +56,8 @@ Boston, MA 02111-1307, USA. */
"-fno-handle-exceptions",
"-fhandle-signatures",
"-fno-handle-signatures",
"-fhonor-std",
"-fno-honor-std",
"-fhuge-objects",
"-fno-huge-objects",
"-fimplement-inlines",

View File

@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */
-undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\
%{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\
%{!fno-exceptions:-D__EXCEPTIONS}\
%{fhonor-std:-D__HONOR_STD} %{fnew-abi:-D__HONOR_STD}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.ii}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",

View File

@ -332,7 +332,7 @@ get_time_identifier (name)
end_temporary_allocation ();
IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times;
SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
filename_times = time_identifier;
pop_obstacks ();
}
@ -2740,8 +2740,8 @@ identifier_type (decl)
if (looking_for_template && really_overloaded_fn (decl))
{
tree t;
for (t = TREE_VALUE (decl); t != NULL_TREE; t = DECL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (t))
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
return PFUNCNAME;
}
if (TREE_CODE (decl) == NAMESPACE_DECL)
@ -2758,7 +2758,8 @@ identifier_type (decl)
void
see_typename ()
{
looking_for_typename = 1;
/* Only types expected, not even namespaces. */
looking_for_typename = 2;
if (yychar < 0)
if ((yychar = yylex ()) < 0) yychar = 0;
looking_for_typename = 0;
@ -2827,7 +2828,7 @@ do_identifier (token, parsing)
refers to an overloaded method. Eventually this will not be
necessary, since default arguments shouldn't be parsed until
after the class is complete. (jason 3/12/97) */
&& TREE_CODE (id) != TREE_LIST)
&& TREE_CODE (id) != OVERLOAD)
pushdecl_class_level (id);
if (!id || id == error_mark_node)
@ -2876,7 +2877,7 @@ do_identifier (token, parsing)
}
id = error_mark_node;
/* Prevent repeated error messages. */
IDENTIFIER_NAMESPACE_VALUE (token) = error_mark_node;
SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
}
}
@ -2966,7 +2967,14 @@ do_scoped_id (token, parsing)
tree id;
/* during parsing, this is ::name. Otherwise, it is black magic. */
if (parsing)
id = qualified_lookup_using_namespace (token, global_namespace);
{
struct tree_binding _b;
id = binding_init (&_b);
if (!qualified_lookup_using_namespace (token, global_namespace, id))
id = NULL_TREE;
else
id = BINDING_VALUE (id);
}
else
id = IDENTIFIER_GLOBAL_VALUE (token);
if (parsing && yychar == YYEMPTY)
@ -2988,14 +2996,14 @@ do_scoped_id (token, parsing)
IDENTIFIER_POINTER (token));
id = error_mark_node;
/* Prevent repeated error messages. */
IDENTIFIER_NAMESPACE_VALUE (token) = error_mark_node;
SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
}
}
else
{
if (TREE_CODE (id) == ADDR_EXPR)
mark_used (TREE_OPERAND (id, 0));
else if (TREE_CODE (id) != TREE_LIST)
else if (TREE_CODE (id) != OVERLOAD)
mark_used (id);
}
if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
@ -3232,7 +3240,7 @@ real_yylex ()
&& TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
looking_for_typename = 0;
else if (ptr->token == AGGR || ptr->token == ENUM)
looking_for_typename = 1;
looking_for_typename = 2;
/* Check if this is a language-type declaration.
Just glimpse the next non-white character. */
@ -4375,8 +4383,6 @@ build_lang_decl (code, name, type)
DECL_LANGUAGE (t) = lang_java;
else my_friendly_abort (64);
SET_DECL_NAMESPACE (t, current_namespace);
#if 0 /* not yet, should get fixed properly later */
if (code == TYPE_DECL)
{
@ -4508,7 +4514,7 @@ dump_time_statistics ()
for (decl = filename_times; decl; decl = next)
{
next = IDENTIFIER_GLOBAL_VALUE (decl);
IDENTIFIER_GLOBAL_VALUE (decl) = prev;
SET_IDENTIFIER_GLOBAL_VALUE (decl, prev);
prev = decl;
}

View File

@ -187,6 +187,7 @@ static int nrepeats = 0;
/* Array of types seen so far in top-level call to `build_mangled_name'.
Allocated and deallocated by caller. */
static tree *typevec = NULL;
static int typevec_size;
/* Number of types interned by `build_mangled_name' so far. */
static int maxtype = 0;
@ -418,6 +419,9 @@ build_overload_nested_name (decl)
if (ktypelist && issue_ktype (decl))
return;
if (decl == global_namespace)
return;
if (DECL_CONTEXT (decl))
{
tree context = DECL_CONTEXT (decl);
@ -438,14 +442,8 @@ build_overload_nested_name (decl)
}
}
}
else if (decl == global_namespace)
return;
else if (DECL_NAMESPACE (decl))
build_overload_nested_name (DECL_NAMESPACE (decl));
else
/* XXX the above does not work for non-namespaces */
if (current_namespace && TREE_CODE (decl) != NAMESPACE_DECL)
build_overload_nested_name (current_namespace);
else
my_friendly_abort (392);
if (TREE_CODE (decl) == FUNCTION_DECL)
{
@ -946,8 +944,8 @@ build_qualified_name (decl)
/* if we can't find a Ktype, do it the hard way */
if (check_ktype (context, FALSE) == -1)
{
/* count type scopes */
while (DECL_CONTEXT (context))
/* count type and namespace scopes */
while (DECL_CONTEXT (context) && DECL_CONTEXT (context) != global_namespace)
{
i += 1;
context = DECL_CONTEXT (context);
@ -956,25 +954,6 @@ build_qualified_name (decl)
if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
context = TYPE_NAME (context);
}
/* now count namespace scopes */
if (TREE_CODE (decl) == NAMESPACE_DECL)
{
i = 0; /* we have nothing done, yet: reset */
context = decl;
}
else
/* decl must be a type, which we have to scope with the
namespace */
{
/* XXX MvL somehow, types have no lang_decl, so no namespace */
context = current_namespace;
}
}
while (context != global_namespace)
{
i += 1;
context = DECL_NAMESPACE (context);
}
if (i > 1)
@ -1052,6 +1031,7 @@ build_mangled_name (parmtypes, begin, end)
if (!nofold && typevec)
{
/* Every argument gets counted. */
my_friendly_assert (maxtype < typevec_size, 387);
typevec[maxtype++] = parmtype;
if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]
@ -1588,7 +1568,11 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
{
maxtype = 0;
Nrepeats = 0;
typevec = (tree *)alloca (list_length (parms) * sizeof (tree));
typevec_size = list_length (parms);
if (!for_method && current_namespace != global_namespace)
/* the namespace of a global function needs one slot */
typevec_size++;
typevec = (tree *)alloca (typevec_size * sizeof (tree));
}
nofold = 0;
if (for_method)
@ -1596,6 +1580,7 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
build_mangled_name (TREE_VALUE (parms), 0, 0);
if (!flag_do_squangling) {
my_friendly_assert (maxtype < typevec_size, 387);
typevec[maxtype++] = TREE_VALUE (parms);
TREE_USED (TREE_VALUE (parms)) = 1;
}
@ -1611,7 +1596,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
will count as type */
if (current_namespace != global_namespace
&& !flag_do_squangling)
typevec[maxtype++] = current_namespace;
{
my_friendly_assert (maxtype < typevec_size, 387);
typevec[maxtype++] = current_namespace;
}
build_mangled_name (parms, 0, 0);
}
@ -1805,6 +1793,9 @@ hack_identifier (value, name)
fndecl = TREE_VALUE (fields);
my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251);
/* I could not trigger this code. MvL */
my_friendly_abort (980325);
#ifdef DEAD
if (DECL_CHAIN (fndecl) == NULL_TREE)
{
warning ("methods cannot be converted to function pointers");
@ -1816,6 +1807,7 @@ hack_identifier (value, name)
IDENTIFIER_POINTER (name));
return error_mark_node;
}
#endif
}
}
if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
@ -1856,6 +1848,9 @@ hack_identifier (value, name)
}
#endif
}
else if (TREE_CODE (value) == OVERLOAD)
/* not really overloaded function */
mark_used (OVL_FUNCTION (value));
else if (TREE_CODE (value) == TREE_LIST)
{
/* Ambiguous reference to base members, possibly other cases?. */
@ -1866,6 +1861,9 @@ hack_identifier (value, name)
t = TREE_CHAIN (t);
}
}
else if (TREE_CODE (value) == NAMESPACE_DECL)
/* A namespace is not really expected here; this is likely illegal code. */
return value;
else
mark_used (value);
@ -1957,7 +1955,8 @@ make_thunk (function, delta)
if (thunk && TREE_CODE (thunk) != THUNK_DECL)
{
cp_error ("implementation-reserved name `%D' used", thunk_id);
IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
thunk = NULL_TREE;
SET_IDENTIFIER_GLOBAL_VALUE (thunk_id, thunk);
}
if (thunk == NULL_TREE)
{

View File

@ -28,8 +28,9 @@
#pragma implementation "new"
#include "new"
const nothrow_t nothrow = { };
const std::nothrow_t std::nothrow = { };
using std::new_handler;
new_handler __new_handler;
new_handler

View File

@ -26,6 +26,8 @@
// the executable file might be covered by the GNU General Public License.
#include "new"
using std::new_handler;
using std::bad_alloc;
extern "C" void *malloc (size_t);
extern new_handler __new_handler;
@ -35,7 +37,7 @@ extern new_handler __new_handler;
x
#ifdef L_op_newnt
WEAK (void * operator new (size_t sz, const nothrow_t&) throw())
WEAK (void * operator new (size_t sz, const std::nothrow_t&) throw())
{
void *p;

View File

@ -41,7 +41,7 @@ WEAK(void * operator new[] (size_t sz) throw (std::bad_alloc))
#endif
#ifdef L_op_vnewnt
WEAK(void *operator new[] (size_t sz, const nothrow_t& nothrow) throw())
WEAK(void *operator new[] (size_t sz, const std::nothrow_t& nothrow) throw())
{
return ::operator new(sz, nothrow);
}

File diff suppressed because it is too large Load Diff

View File

@ -331,8 +331,10 @@ program:
{
/* In case there were missing closebraces,
get us back to the global binding level. */
while (! global_bindings_p ())
while (! toplevel_bindings_p ())
poplevel (0, 0, 0);
while (current_namespace != global_namespace)
pop_namespace ();
finish_file ();
}
;
@ -413,7 +415,10 @@ extdef:
{ do_toplevel_using_decl ($1); }
| USING NAMESPACE any_id ';'
{
if (TREE_CODE ($3) == IDENTIFIER_NODE)
/* If no declaration was found, the using-directive is
invalid. Since that was not reported, we need the
identifier for the error message. */
if (TREE_CODE ($3) == IDENTIFIER_NODE && lastiddecl)
$3 = lastiddecl;
do_using_directive ($3);
}
@ -2348,6 +2353,7 @@ left_curly:
$<ttype>0 = t;
}
if (processing_template_decl && TYPE_CONTEXT (t)
&& TREE_CODE (TYPE_CONTEXT (t)) != NAMESPACE_DECL
&& ! current_class_type)
push_template_decl (TYPE_STUB_DECL (t));
pushclass (t, 0);
@ -3014,7 +3020,9 @@ typename_sub2:
if (TREE_CODE ($1) != IDENTIFIER_NODE)
$1 = lastiddecl;
got_scope = $$ = complete_type (TREE_TYPE ($1));
/* Retrieve the type for the identifier, which might involve
some computation. */
got_scope = $$ = complete_type (IDENTIFIER_TYPE_VALUE ($1));
if ($$ == error_mark_node)
cp_error ("`%T' is not a class or namespace", $1);

View File

@ -171,7 +171,9 @@ template_class_depth (type)
{
int depth;
for (depth = 0; type && TREE_CODE (type) != FUNCTION_DECL;
for (depth = 0;
type && TREE_CODE (type) != FUNCTION_DECL
&& TREE_CODE (type) != NAMESPACE_DECL;
type = TYPE_CONTEXT (type))
if (CLASSTYPE_TEMPLATE_INFO (type)
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
@ -730,22 +732,19 @@ determine_specialization (template_id, decl, targs_out,
tree targs_in = TREE_OPERAND (template_id, 1);
tree templates = NULL_TREE;
tree fn;
int overloaded;
int i;
*targs_out = NULL_TREE;
if (is_overloaded_fn (fns))
fn = get_first_fn (fns);
else
fn = NULL_TREE;
/* Check for baselinks. */
if (TREE_CODE (fns) == TREE_LIST)
fns = TREE_VALUE (fns);
overloaded = really_overloaded_fn (fns);
for (; fn != NULL_TREE;
fn = overloaded ? DECL_CHAIN (fn) : NULL_TREE)
for (; fns; fns = OVL_NEXT (fns))
{
tree tmpl;
fn = OVL_CURRENT (fns);
if (!need_member_template
&& TREE_CODE (fn) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (fn)
@ -1576,7 +1575,8 @@ push_template_decl_real (decl, is_friend)
/* For a friend, we want the context of the friend function, not
the type of which it is a friend. */
ctx = DECL_CONTEXT (decl);
else if (DECL_REAL_CONTEXT (decl))
else if (DECL_REAL_CONTEXT (decl)
&& TREE_CODE (DECL_REAL_CONTEXT (decl)) != NAMESPACE_DECL)
/* In the case of a virtual function, we want the class in which
it is defined. */
ctx = DECL_REAL_CONTEXT (decl);
@ -1585,6 +1585,12 @@ push_template_decl_real (decl, is_friend)
is assumed to be a member of the class. */
ctx = current_class_type;
if (ctx && TREE_CODE (ctx) == NAMESPACE_DECL)
ctx = NULL_TREE;
if (!DECL_CONTEXT (decl))
DECL_CONTEXT (decl) = current_namespace;
/* For determining whether this is a primary template or not, we're really
interested in the lexical context, not the true context. */
if (is_friend)
@ -1818,7 +1824,7 @@ push_template_decl_real (decl, is_friend)
/* Note that we do not try to push a global template friend
declared in a template class; such a thing may well depend on
the template parameters of the class. */
tmpl = pushdecl_top_level (tmpl);
tmpl = pushdecl_namespace_level (tmpl);
if (primary)
DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
@ -2602,7 +2608,7 @@ mangle_class_name_for_template (name, parms, arglist, ctx)
#define cat(s) obstack_grow (&scratch_obstack, (s), strlen (s))
#endif
if (ctx)
if (ctx && ctx != global_namespace)
{
char* s;
@ -2610,6 +2616,8 @@ mangle_class_name_for_template (name, parms, arglist, ctx)
s = fndecl_as_string (ctx, 0);
else if (TREE_CODE_CLASS (TREE_CODE (ctx)) == 't')
s = type_as_string_real (ctx, 0, 1);
else if (TREE_CODE (ctx) == NAMESPACE_DECL)
s = decl_as_string (ctx, 0);
else
my_friendly_abort (0);
cat (s);
@ -2635,9 +2643,18 @@ mangle_class_name_for_template (name, parms, arglist, ctx)
else if (TREE_CODE (parm) == TEMPLATE_DECL)
{
if (TREE_CODE (arg) == TEMPLATE_DECL)
/* Already substituted with real template. Just output
the template name here */
cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
{
/* Already substituted with real template. Just output
the template name here */
my_friendly_assert (TREE_CODE (DECL_CONTEXT (arg))
== NAMESPACE_DECL, 980422);
if (DECL_CONTEXT (arg) != global_namespace)
{
cat(decl_as_string (DECL_CONTEXT (arg), 0));
cat("::");
}
cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
}
else
/* Output the parameter declaration */
cat (type_as_string_real (arg, 0, 1));
@ -2729,7 +2746,7 @@ tree
lookup_template_function (fns, arglist)
tree fns, arglist;
{
tree t;
tree type;
if (fns == NULL_TREE)
{
@ -2740,10 +2757,11 @@ lookup_template_function (fns, arglist)
if (arglist != NULL_TREE && !TREE_PERMANENT (arglist))
copy_to_permanent (arglist);
return build_min (TEMPLATE_ID_EXPR,
TREE_TYPE (fns)
? TREE_TYPE (fns) : unknown_type_node,
fns, arglist);
type = TREE_TYPE (fns);
if (TREE_CODE (fns) == OVERLOAD || !type)
type = unknown_type_node;
return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);
}
/* Within the scope of a template class S<T>, the name S gets bound
@ -2786,7 +2804,7 @@ lookup_template_class (d1, arglist, in_decl, context)
{
tree template = NULL_TREE, parmlist;
char *mangled_name;
tree id, t;
tree id, t, id_context;
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
@ -2795,11 +2813,15 @@ lookup_template_class (d1, arglist, in_decl, context)
template = IDENTIFIER_LOCAL_VALUE (d1);
else
{
if (context)
push_decl_namespace (context);
template =
maybe_get_template_decl_from_type_decl
(IDENTIFIER_CLASS_VALUE (d1));
if (template == NULL_TREE)
template = IDENTIFIER_NAMESPACE_VALUE (d1);
template = lookup_name_nonclass (d1);
if (context)
pop_decl_namespace ();
}
if (template)
context = DECL_CONTEXT (template);
@ -2826,12 +2848,28 @@ lookup_template_class (d1, arglist, in_decl, context)
else
my_friendly_abort (272);
/* A namespace is used as context only for mangling.
Template IDs with namespace context are found
in the global binding level. */
if (context != NULL_TREE && TREE_CODE (context) == NAMESPACE_DECL)
context = global_namespace;
/* With something like `template <class T> class X class X { ... };'
we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.
We don't want to do that, but we have to deal with the situation, so
let's give them some syntax errors to chew on instead of a crash. */
if (! template)
return error_mark_node;
/* We need an id_context to get the mangling right. If this is a
nested template, use the context. If it is global, retrieve the
context from the template. */
if (context && TREE_CODE (context) != NAMESPACE_DECL)
id_context = context;
else
id_context = DECL_CONTEXT (template);
my_friendly_assert (id_context != NULL_TREE, 980410);
if (TREE_CODE (template) != TEMPLATE_DECL)
{
cp_error ("non-template type `%T' used as a template", d1);
@ -2903,7 +2941,7 @@ lookup_template_class (d1, arglist, in_decl, context)
mangled_name = mangle_class_name_for_template (IDENTIFIER_POINTER (d1),
parmlist,
arglist,
context);
id_context);
id = get_identifier (mangled_name);
IDENTIFIER_TEMPLATE (id) = d1;
@ -3027,6 +3065,11 @@ for_each_template_parm (t, fn, data)
return 1;
return for_each_template_parm (TREE_CHAIN (t), fn, data);
case OVERLOAD:
if (for_each_template_parm (OVL_FUNCTION (t), fn, data))
return 1;
return for_each_template_parm (OVL_CHAIN (t), fn, data);
/* constructed type nodes */
case POINTER_TYPE:
case REFERENCE_TYPE:
@ -3118,6 +3161,7 @@ for_each_template_parm (t, fn, data)
case COMPLEX_TYPE:
case VOID_TYPE:
case BOOLEAN_TYPE:
case NAMESPACE_DECL:
return 0;
case ENUMERAL_TYPE:
@ -3366,14 +3410,15 @@ tsubst_friend_function (decl, args)
if (TREE_CODE (decl) == TEMPLATE_DECL)
DECL_USE_TEMPLATE (DECL_TEMPLATE_RESULT (new_friend)) = 0;
if (DECL_CONTEXT (new_friend) == NULL_TREE)
if (!DECL_CONTEXT (new_friend)
|| TREE_CODE (DECL_CONTEXT (new_friend)) == NAMESPACE_DECL)
{
if (TREE_CODE (new_friend) == TEMPLATE_DECL)
/* This declaration is a `primary' template. */
TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (new_friend))
= new_friend;
new_friend = pushdecl_top_level (new_friend);
new_friend = pushdecl_namespace_level (new_friend);
}
else if (TYPE_SIZE (DECL_CONTEXT (new_friend)))
{
@ -3852,10 +3897,14 @@ tsubst (t, args, in_decl)
if (t == NULL_TREE || t == error_mark_node
|| t == integer_type_node
|| t == void_type_node
|| t == char_type_node)
|| t == char_type_node
|| TREE_CODE (t) == NAMESPACE_DECL)
return t;
type = TREE_TYPE (t);
if (TREE_CODE (t) == IDENTIFIER_NODE)
type = IDENTIFIER_TYPE_VALUE (t);
else
type = TREE_TYPE (t);
if (type == unknown_type_node)
my_friendly_abort (42);
if (type && TREE_CODE (t) != FUNCTION_DECL
@ -3904,12 +3953,13 @@ tsubst (t, args, in_decl)
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
case NAMESPACE_DECL:
return t;
case ENUMERAL_TYPE:
{
tree ctx = tsubst (TYPE_CONTEXT (t), args, in_decl);
if (ctx == NULL_TREE)
if (ctx == NULL_TREE || TREE_CODE (ctx) == NAMESPACE_DECL)
return t;
else if (ctx == current_function_decl)
return lookup_name (TYPE_IDENTIFIER (t), 1);
@ -4089,7 +4139,6 @@ tsubst (t, args, in_decl)
tmpl = copy_node (t);
copy_lang_decl (tmpl);
my_friendly_assert (DECL_LANG_SPECIFIC (tmpl) != 0, 0);
DECL_CHAIN (tmpl) = NULL_TREE;
TREE_CHAIN (tmpl) = NULL_TREE;
if (is_template_template_parm)
@ -4407,7 +4456,6 @@ tsubst (t, args, in_decl)
DECL_INTERFACE_KNOWN (r) = 0;
DECL_DEFER_OUTPUT (r) = 0;
TREE_CHAIN (r) = NULL_TREE;
DECL_CHAIN (r) = NULL_TREE;
DECL_PENDING_INLINE_INFO (r) = 0;
TREE_USED (r) = 0;
@ -4436,7 +4484,7 @@ tsubst (t, args, in_decl)
TREE_CHAIN because it doesn't find a previous decl. Sigh. */
if (member
&& IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r)) == NULL_TREE)
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r)) = r;
SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r);
return r;
}
@ -5632,15 +5680,14 @@ type_unification_real (tparms, targs, parms, args, subr,
if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't')
{
my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
if (TREE_CODE (arg) == TREE_LIST
&& TREE_TYPE (arg) == unknown_type_node
&& TREE_CODE (TREE_VALUE (arg)) == TEMPLATE_DECL)
if (TREE_CODE (arg) == OVERLOAD
&& TREE_CODE (OVL_FUNCTION (arg)) == TEMPLATE_DECL)
{
int ntparms;
tree targs;
/* Have to back unify here */
arg = TREE_VALUE (arg);
arg = OVL_FUNCTION (arg);
ntparms = DECL_NTPARMS (arg);
targs = make_scratch_vec (ntparms);
parm = expr_tree_cons (NULL_TREE, parm, NULL_TREE);

View File

@ -147,7 +147,7 @@ print_lang_identifier (file, node, indent)
tree node;
int indent;
{
print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + 4);
print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4);
print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
@ -169,6 +169,9 @@ lang_print_xnode (file, node, indent)
print_node (file, "value", BINDING_VALUE (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4);
break;
case OVERLOAD:
print_node (file, "function", OVL_FUNCTION (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4);
case TEMPLATE_PARM_INDEX:
indent_to (file, indent + 3);
fprintf (file, "index %d level %d orig_level %d",

View File

@ -57,8 +57,12 @@ tree tinfo_fn_type;
void
init_rtti_processing ()
{
if (flag_honor_std)
push_namespace (get_identifier ("std"));
type_info_type_node = xref_tag
(class_type_node, get_identifier ("type_info"), NULL_TREE, 1);
if (flag_honor_std)
pop_namespace ();
tinfo_fn_id = get_identifier ("__tf");
tinfo_fn_type = build_function_type
(build_reference_type (build_type_variant (type_info_type_node, 1, 0)),

View File

@ -1152,10 +1152,10 @@ lookup_fnfields_here (type, name)
fndecls = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
while (fndecls)
{
if (TYPE_MAIN_VARIANT (DECL_CLASS_CONTEXT (fndecls))
if (TYPE_MAIN_VARIANT (DECL_CLASS_CONTEXT (OVL_CURRENT (fndecls)))
== TYPE_MAIN_VARIANT (type))
return idx;
fndecls = TREE_CHAIN (fndecls);
fndecls = OVL_CHAIN (fndecls);
}
return -1;
}
@ -1266,7 +1266,7 @@ lookup_field (xbasetype, name, protect, want_type)
#ifdef GATHER_STATISTICS
n_calls_lookup_field++;
#endif /* GATHER_STATISTICS */
if (protect && flag_memoize_lookups && ! global_bindings_p ())
if (protect && flag_memoize_lookups && ! toplevel_bindings_p ())
entry = make_memoized_table_entry (type, name, 0);
else
entry = 0;
@ -1662,7 +1662,7 @@ lookup_fnfields_1 (type, name)
#ifdef GATHER_STATISTICS
n_outer_fields_searched++;
#endif /* GATHER_STATISTICS */
if (DECL_NAME (*methods) == name)
if (DECL_NAME (OVL_CURRENT (*methods)) == name)
break;
}
@ -1676,8 +1676,8 @@ lookup_fnfields_1 (type, name)
while (++methods != end)
{
if (TREE_CODE (*methods) == TEMPLATE_DECL
&& IDENTIFIER_TYPENAME_P (DECL_NAME (*methods)))
if (TREE_CODE (OVL_CURRENT (*methods)) == TEMPLATE_DECL
&& IDENTIFIER_TYPENAME_P (DECL_NAME (OVL_CURRENT (*methods))))
break;
}
}
@ -1815,7 +1815,7 @@ lookup_fnfields (basetype_path, name, complain)
#ifdef GATHER_STATISTICS
n_calls_lookup_fnfields++;
#endif /* GATHER_STATISTICS */
if (protect && flag_memoize_lookups && ! global_bindings_p ())
if (protect && flag_memoize_lookups && ! toplevel_bindings_p ())
entry = make_memoized_table_entry (type, name, 1);
else
entry = 0;
@ -2101,8 +2101,8 @@ get_virtuals_named_this (binfo)
{
tree fndecl;
for (fndecl = TREE_VALUE (fields); fndecl; fndecl = DECL_CHAIN (fndecl))
if (DECL_VINDEX (fndecl))
for (fndecl = TREE_VALUE (fields); fndecl; fndecl = OVL_NEXT (fndecl))
if (DECL_VINDEX (OVL_CURRENT (fndecl)))
return fields;
fields = next_baselink (fields);
}
@ -2187,8 +2187,10 @@ get_matching_virtual (binfo, fndecl, dtorp)
for (; baselink; baselink = next_baselink (baselink))
{
for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
tree tmps;
for (tmps = TREE_VALUE (baselink); tmps; tmps = OVL_NEXT (tmps))
{
tmp = OVL_CURRENT (tmps);
if (! DECL_VINDEX (tmp))
continue;
@ -2256,7 +2258,8 @@ get_matching_virtual (binfo, fndecl, dtorp)
break;
}
}
if (tmp)
/* If not at the end */
if (tmps)
{
best = tmp;
break;
@ -2680,6 +2683,7 @@ dfs_debug_mark (binfo)
methods = TREE_VEC_ELT (methods, 0);
else
methods = TREE_VEC_ELT (methods, 2);
methods = OVL_CURRENT (methods);
while (methods)
{
if (DECL_VINDEX (methods)
@ -2697,7 +2701,7 @@ dfs_debug_mark (binfo)
/* We cannot rely on some alien method to solve our problems,
so we must write out the debug info ourselves. */
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
rest_of_type_compilation (t, global_bindings_p ());
rest_of_type_compilation (t, toplevel_bindings_p ());
}
/* Attach to the type of the virtual base class, the pointer to the
@ -3471,7 +3475,7 @@ dfs_pushdecls (binfo)
{
/* This will cause lookup_name to return a pointer
to the tree_list of possible methods of this name. */
tree name = DECL_NAME (*methods);
tree name = DECL_NAME (OVL_CURRENT (*methods));
tree class_value = IDENTIFIER_CLASS_VALUE (name);
/* If the class value is not an envelope of the kind described in
@ -3491,7 +3495,7 @@ dfs_pushdecls (binfo)
If we can't do that, keep a TREE_LIST with possibly ambiguous
decls in there. */
maybe_push_cache_obstack ();
envelope_add_decl (type, *methods, &TREE_PURPOSE (class_value));
envelope_add_decl (type, OVL_CURRENT (*methods), &TREE_PURPOSE (class_value));
pop_obstacks ();
methods++;
@ -3519,7 +3523,8 @@ dfs_compress_decls (binfo)
{
/* This is known to be an envelope of the kind described before
dfs_pushdecls. */
tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
tree class_value =
IDENTIFIER_CLASS_VALUE (DECL_NAME (OVL_CURRENT (*methods)));
tree tmp = TREE_PURPOSE (class_value);
/* This was replaced in scope by somebody else. Just leave it
@ -3529,7 +3534,7 @@ dfs_compress_decls (binfo)
if (TREE_CHAIN (tmp) == NULL_TREE
&& TREE_VALUE (tmp)
&& DECL_CHAIN (TREE_VALUE (tmp)) == NULL_TREE)
&& OVL_NEXT (TREE_VALUE (tmp)) == NULL_TREE)
{
TREE_PURPOSE (class_value) = TREE_VALUE (tmp);
}
@ -3738,7 +3743,7 @@ add_conversions (binfo)
for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
{
tree tmp = TREE_VEC_ELT (method_vec, i);
if (! IDENTIFIER_TYPENAME_P (DECL_NAME (tmp)))
if (! IDENTIFIER_TYPENAME_P (DECL_NAME (OVL_CURRENT (tmp))))
break;
conversions = scratch_tree_cons (binfo, tmp, conversions);
}

View File

@ -96,6 +96,8 @@ build_signature_pointer_or_reference_decl (type, name)
decl = build_decl (TYPE_DECL, name, type);
TYPE_NAME (type) = decl;
TREE_CHAIN (type) = decl;
/* But we mangle it, so it needs a scope. */
DECL_CONTEXT (decl) = global_namespace;
}
/* Construct, lay out and return the type of pointers or references
@ -532,19 +534,20 @@ build_signature_table_constructor (sig_ty, rhs)
else
{
/* Find the class method of the correct type. */
tree rhs_methods;
basetypes = TREE_PURPOSE (baselink);
if (TREE_CODE (basetypes) == TREE_LIST)
basetypes = TREE_VALUE (basetypes);
rhs_method = TREE_VALUE (baselink);
for (; rhs_method; rhs_method = TREE_CHAIN (rhs_method))
if (sig_mname == DECL_NAME (rhs_method)
rhs_methods = TREE_VALUE (baselink);
for (; rhs_methods; rhs_methods = OVL_NEXT (rhs_methods))
if ((rhs_method = OVL_CURRENT (rhs_methods))
&& sig_mname == DECL_NAME (rhs_method)
&& ! DECL_STATIC_FUNCTION_P (rhs_method)
&& match_method_types (sig_mtype, TREE_TYPE (rhs_method)))
break;
if (rhs_method == NULL_TREE
if (rhs_methods == NULL_TREE
|| (compute_access (basetypes, rhs_method)
!= access_public_node))
{
@ -754,7 +757,7 @@ build_sigtable (sig_type, rhs_type, init_from)
decl = pushdecl_top_level (build_decl (VAR_DECL, name, sig_type));
current_function_decl = context;
}
IDENTIFIER_GLOBAL_VALUE (name) = decl;
SET_IDENTIFIER_GLOBAL_VALUE (name, decl);
store_init_value (decl, init_expr);
if (IS_SIGNATURE (rhs_type))
{

View File

@ -245,6 +245,7 @@ yylex ()
{
struct token tmp_token;
tree trrr;
int old_looking_for_typename = 0;
retry:
#ifdef SPEW_DEBUG
@ -306,8 +307,11 @@ yylex ()
case IDENTIFIER:
scan_tokens (1);
if (nth_token (1)->yychar == SCOPE)
/* Don't interfere with the setting from an 'aggr' prefix. */
looking_for_typename++;
{
/* Don't interfere with the setting from an 'aggr' prefix. */
old_looking_for_typename = looking_for_typename;
looking_for_typename = 1;
}
else if (nth_token (1)->yychar == '<')
looking_for_template = 1;
@ -346,8 +350,9 @@ yylex ()
case PTYPENAME:
case PTYPENAME_DEFN:
consume_token ();
if (looking_for_typename > 0)
looking_for_typename--;
/* If we see a SCOPE next, restore the old value.
Otherwise, we got what we want. */
looking_for_typename = old_looking_for_typename;
looking_for_template = 0;
break;
@ -368,7 +373,7 @@ yylex ()
/* fall through to output... */
case ENUM:
/* Set this again, in case we are rescanning. */
looking_for_typename = 1;
looking_for_typename = 2;
/* fall through... */
default:
consume_token ();

View File

@ -33,7 +33,7 @@
// that uses virtual functions and -frtti but does not actually use RTTI
// functionality.
type_info::
std::type_info::
~type_info ()
{ }
@ -43,7 +43,7 @@ __rtti_class (void *addr, const char *name,
{ new (addr) __class_type_info (name, bl, bn); }
extern "C" void
__rtti_si (void *addr, const char *n, const type_info *ti)
__rtti_si (void *addr, const char *n, const std::type_info *ti)
{
new (addr) __si_type_info
(n, static_cast <const __user_type_info &> (*ti));

View File

@ -7,7 +7,7 @@
// type_info for a class with no base classes (or an enum).
struct __user_type_info : public type_info {
struct __user_type_info : public std::type_info {
__user_type_info (const char *n) : type_info (n) {}
// If our type can be converted to the desired type,

View File

@ -29,6 +29,7 @@
#include "tinfo.h"
#include "new" // for placement new
using std::type_info;
// service function for comparing types by name.
static inline int

View File

@ -1271,33 +1271,38 @@ debug_binfo (elem)
}
}
/* Return the length of a chain of nodes chained through DECL_CHAIN.
We expect a null pointer to mark the end of the chain.
This is the Lisp primitive `length'. */
/* Initialize an CPLUS_BINDING node that does not live on an obstack. */
int
decl_list_length (t)
tree t;
tree
binding_init (node)
struct tree_binding* node;
{
register tree tail;
register int len = 0;
my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
|| TREE_CODE (t) == TEMPLATE_DECL, 300);
for (tail = t; tail; tail = DECL_CHAIN (tail))
len++;
return len;
static struct tree_binding* source;
if (!source)
{
extern struct obstack permanent_obstack;
push_obstacks (&permanent_obstack, &permanent_obstack);
source = (struct tree_binding*)make_node (CPLUS_BINDING);
pop_obstacks ();
}
*node = *source;
TREE_PERMANENT ((tree)node) = 0;
return (tree)node;
}
int
count_functions (t)
tree t;
{
int i;
if (TREE_CODE (t) == FUNCTION_DECL)
return 1;
else if (TREE_CODE (t) == TREE_LIST)
return decl_list_length (TREE_VALUE (t));
else if (TREE_CODE (t) == OVERLOAD)
{
for (i=0; t; t = OVL_CHAIN (t))
i++;
return i;
}
my_friendly_abort (359);
return 0;
@ -1307,19 +1312,29 @@ int
is_overloaded_fn (x)
tree x;
{
/* XXX A baselink is also considered an overloaded function. */
if (TREE_CODE (x) == TREE_LIST)
{
my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC, 388);
x = TREE_VALUE (x);
}
return (TREE_CODE (x) == FUNCTION_DECL
|| TREE_CODE (x) == TEMPLATE_ID_EXPR
|| DECL_FUNCTION_TEMPLATE_P (x)
|| really_overloaded_fn (x));
|| TREE_CODE (x) == OVERLOAD);
}
int
really_overloaded_fn (x)
tree x;
{
return (TREE_CODE (x) == TREE_LIST
&& (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
|| DECL_FUNCTION_TEMPLATE_P (TREE_VALUE (x))));
/* A baselink is also considered an overloaded function.
This might also be an ambiguous class member. */
while (TREE_CODE (x) == TREE_LIST)
x = TREE_VALUE (x);
return (TREE_CODE (x) == OVERLOAD
&& (TREE_CHAIN (x) != NULL_TREE
|| DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (x))));
}
tree
@ -1327,11 +1342,72 @@ get_first_fn (from)
tree from;
{
my_friendly_assert (is_overloaded_fn (from), 9);
/* A baselink is also considered an overloaded function. */
if (TREE_CODE (from) == TREE_LIST)
from = TREE_VALUE (from);
return OVL_CURRENT (from);
}
if (really_overloaded_fn (from))
return TREE_VALUE (from);
else
return from;
/* Return a new OVL node, concatenating it with the old one. */
tree
ovl_cons (decl, chain)
tree decl;
tree chain;
{
tree result = make_node (OVERLOAD);
TREE_TYPE (result) = unknown_type_node;
OVL_FUNCTION (result) = decl;
TREE_CHAIN (result) = chain;
return result;
}
/* Same as ovl_cons, but on the scratch_obstack. */
tree
scratch_ovl_cons (value, chain)
tree value, chain;
{
register tree node;
register struct obstack *ambient_obstack = current_obstack;
extern struct obstack *expression_obstack;
current_obstack = expression_obstack;
node = ovl_cons (value, chain);
current_obstack = ambient_obstack;
return node;
}
/* Build a new overloaded function. If this is the first one,
just return it; otherwise, ovl_cons the _DECLs */
tree
build_overload (decl, chain)
tree decl;
tree chain;
{
if (!chain)
return decl;
if (TREE_CODE (chain) != OVERLOAD)
chain = ovl_cons (chain, NULL_TREE);
return ovl_cons (decl, chain);
}
/* True if fn is in ovl. */
int
ovl_member (fn, ovl)
tree fn;
tree ovl;
{
if (fn == ovl)
return 1;
if (!ovl || TREE_CODE (ovl) != OVERLOAD)
return 0;
for (; ovl; ovl = OVL_CHAIN (ovl))
if (OVL_FUNCTION (ovl) == fn)
return 1;
return 0;
}
int
@ -2193,8 +2269,11 @@ tree
lvalue_type (arg)
tree arg;
{
tree type = TREE_TYPE (arg);
if (TREE_CODE (arg) == OVERLOAD)
type = unknown_type_node;
return cp_build_type_variant
(TREE_TYPE (arg), TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
(type, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg));
}
/* The type of ARG for printing error messages; denote lvalues with

View File

@ -91,7 +91,10 @@ require_complete_type (value)
if (processing_template_decl)
return value;
type = TREE_TYPE (value);
if (TREE_CODE (value) == OVERLOAD)
type = unknown_type_node;
else
type = TREE_TYPE (value);
/* First, detect a valid value with a complete type. */
if (TYPE_SIZE (type) != 0
@ -161,7 +164,7 @@ int
type_unknown_p (exp)
tree exp;
{
return (TREE_CODE (exp) == TREE_LIST
return (TREE_CODE (exp) == OVERLOAD
|| TREE_TYPE (exp) == unknown_type_node
|| (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE
&& TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node));
@ -193,7 +196,8 @@ require_instantiated_type (type, exp, errval)
return errval;
}
if (TREE_TYPE (exp) == unknown_type_node
if (TREE_CODE (exp) == OVERLOAD
|| TREE_TYPE (exp) == unknown_type_node
|| (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE
&& TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node))
{
@ -1837,8 +1841,12 @@ build_component_ref (datum, component, basetype_path, protect)
/* First, see if there is a field or component with name COMPONENT. */
if (TREE_CODE (component) == TREE_LIST)
{
/* I could not trigger this code. MvL */
my_friendly_abort (980326);
#ifdef DEAD
my_friendly_assert (!(TREE_CHAIN (component) == NULL_TREE
&& DECL_CHAIN (TREE_VALUE (component)) == NULL_TREE), 309);
#endif
return build (COMPONENT_REF, TREE_TYPE (component), datum, component);
}
@ -1907,7 +1915,7 @@ build_component_ref (datum, component, basetype_path, protect)
if (fndecls)
{
if (TREE_CHAIN (fndecls) == NULL_TREE
&& DECL_CHAIN (TREE_VALUE (fndecls)) == NULL_TREE)
&& TREE_CODE (TREE_VALUE (fndecls)) != OVERLOAD)
{
tree access, fndecl;
@ -2365,7 +2373,7 @@ build_x_function_call (function, params, decl)
/* A friend template. Make it look like a toplevel declaration. */
if (! is_method && TREE_CODE (function) == TEMPLATE_DECL)
function = build_scratch_list (NULL_TREE, function);
function = scratch_ovl_cons (function, NULL_TREE);
/* Handle methods, friends, and overloaded functions, respectively. */
if (is_method)
@ -2453,7 +2461,7 @@ build_x_function_call (function, params, decl)
}
else if (really_overloaded_fn (function))
{
if (TREE_VALUE (function) == NULL_TREE)
if (OVL_FUNCTION (function) == NULL_TREE)
{
cp_error ("function `%D' declared overloaded, but no definitions appear with which to resolve it?!?",
TREE_PURPOSE (function));
@ -2467,6 +2475,9 @@ build_x_function_call (function, params, decl)
return build_new_function_call (function, params);
}
}
else
/* Remove a potential OVERLOAD around it */
function = OVL_CURRENT (function);
do_x_function:
if (TREE_CODE (function) == OFFSET_REF)
@ -2673,7 +2684,7 @@ build_function_call_real (function, params, require_complete, flags)
&& name
&& IDENTIFIER_LENGTH (name) == 4
&& ! strcmp (IDENTIFIER_POINTER (name), "main")
&& DECL_CONTEXT (function) == NULL_TREE)
&& DECL_CONTEXT (function) == global_namespace)
{
pedwarn ("ANSI C++ forbids calling `main' from within program");
}
@ -4437,7 +4448,7 @@ build_unary_op (code, xarg, noconvert)
else if (pedantic
&& TREE_CODE (arg) == FUNCTION_DECL
&& DECL_NAME (arg)
&& DECL_CONTEXT (arg) == NULL_TREE
&& DECL_CONTEXT (arg) == global_namespace
&& IDENTIFIER_LENGTH (DECL_NAME (arg)) == 4
&& IDENTIFIER_POINTER (DECL_NAME (arg))[0] == 'm'
&& ! strcmp (IDENTIFIER_POINTER (DECL_NAME (arg)), "main"))
@ -4488,15 +4499,16 @@ build_unary_op (code, xarg, noconvert)
return build1 (ADDR_EXPR, unknown_type_node, arg);
}
if (TREE_CODE (arg) == TREE_LIST)
if (TREE_CODE (arg) == OVERLOAD)
return build1 (ADDR_EXPR, unknown_type_node, arg);
else if (TREE_CODE (arg) == TREE_LIST)
{
if (TREE_CODE (TREE_VALUE (arg)) == FUNCTION_DECL
&& DECL_CHAIN (TREE_VALUE (arg)) == NULL_TREE)
if (TREE_CODE (TREE_VALUE (arg)) == FUNCTION_DECL)
/* Unique overloaded non-member function. */
return build_unary_op (ADDR_EXPR, TREE_VALUE (arg), 0);
if (TREE_CHAIN (arg) == NULL_TREE
&& TREE_CODE (TREE_VALUE (arg)) == TREE_LIST
&& DECL_CHAIN (TREE_VALUE (TREE_VALUE (arg))) == NULL_TREE)
&& TREE_CODE (TREE_VALUE (TREE_VALUE (arg))) != OVERLOAD)
/* Unique overloaded member function. */
return build_unary_op (ADDR_EXPR, TREE_VALUE (TREE_VALUE (arg)),
0);
@ -6500,7 +6512,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (rhs == error_mark_node)
return error_mark_node;
if (TREE_VALUE (rhs) == error_mark_node)
if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
return error_mark_node;
if (TREE_CODE (TREE_TYPE (rhs)) == OFFSET_TYPE)