parent
0d33d22e9f
commit
2c73f9f57a
240
gcc/cp/ChangeLog
240
gcc/cp/ChangeLog
|
@ -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
|
||||
|
|
106
gcc/cp/call.c
106
gcc/cp/call.c
|
@ -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. */
|
||||
|
|
435
gcc/cp/class.c
435
gcc/cp/class.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
102
gcc/cp/cp-tree.h
102
gcc/cp/cp-tree.h
|
@ -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));
|
||||
|
|
859
gcc/cp/decl.c
859
gcc/cp/decl.c
File diff suppressed because it is too large
Load Diff
702
gcc/cp/decl2.c
702
gcc/cp/decl2.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <new>
|
||||
|
||||
#if 0
|
||||
#ifdef __HONOR_STD
|
||||
using std::new_handler;
|
||||
using std::set_new_handler;
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
32
gcc/cp/lex.c
32
gcc/cp/lex.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
1650
gcc/cp/parse.c
1650
gcc/cp/parse.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
117
gcc/cp/pt.c
117
gcc/cp/pt.c
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
15
gcc/cp/sig.c
15
gcc/cp/sig.c
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
131
gcc/cp/tree.c
131
gcc/cp/tree.c
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue