parent
87e3e0c1b5
commit
700f8a8792
213
gcc/cp/ChangeLog
213
gcc/cp/ChangeLog
|
@ -1,17 +1,210 @@
|
|||
Tue May 3 19:11:24 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
Thu May 5 09:35:35 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
|
||||
|
||||
* typeck.c (build_modify_expr): Warn about assignment to `this'.
|
||||
|
||||
Wed May 4 15:55:49 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* init.c (build_delete): Use the global operator delete when
|
||||
requested.
|
||||
|
||||
* decl.c (lookup_name_real): If we find the type we're looking in a
|
||||
base class while defining a class, set IDENTIFIER_CLASS_VALUE for
|
||||
the type.
|
||||
|
||||
* class.c (finish_struct): Remove a couple of dependencies on
|
||||
language linkage.
|
||||
|
||||
* decl.c (pushtag): Classes do nest in extern "C" blocks.
|
||||
(pushdecl): Only set DECL_NESTED_TYPENAME on the canonical one for
|
||||
the type.
|
||||
(pushtag): Remove another dependency on the language linkage.
|
||||
|
||||
* lex.c (cons_up_default_function): Don't set DECL_CLASS_CONTEXT to
|
||||
a const-qualified type.
|
||||
|
||||
* decl.c (push_overloaded_decl): Throw away built-in decls here.
|
||||
(duplicate_decls): Instead of here.
|
||||
|
||||
Wed May 4 15:27:40 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||
|
||||
* typeck.c (get_member_function_from_ptrfunc): Do The Right
|
||||
Thing (I hope) if we're using thunks.
|
||||
|
||||
Wed May 4 13:52:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* parse.y (specialization): aggr template_type_name ';'.
|
||||
(named_class_head_sans_basetype): Use it.
|
||||
(explicit_instantiation): Ditto.
|
||||
(tmpl.2): Revert.
|
||||
|
||||
* cvt.c (build_type_conversion_1): Use convert_for_initialization,
|
||||
rather than convert, to do conversions after the UDC.
|
||||
|
||||
* cp-tree.h (SHARED_MEMBER_P): This member is shared between all
|
||||
instances of the class.
|
||||
|
||||
* search.c (lookup_field): If the entity found by two routes is the
|
||||
same, it's not ambiguous.
|
||||
|
||||
Wed May 4 12:10:00 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||
|
||||
* decl.c (lookup_name_real): Check for a NULL TREE_VALUE,
|
||||
to prevent the compiler from crashing ...
|
||||
|
||||
Wed May 4 11:19:45 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* call.c (build_method_call): If we don't have an object, check
|
||||
basetype_path to figure out where to look up the function.
|
||||
|
||||
* typeck.c (convert_for_initialization): Pass TYPE_BINFO (type) to
|
||||
build_method_call in case exp is NULL_TREE.
|
||||
|
||||
Tue May 3 16:02:53 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||
|
||||
Give a vtable entries a unique named type, for the sake of gdb.
|
||||
* class.c (build_vtable_entry): The addres of a thunk now has
|
||||
type vtable_entry_type, not ptr_type_node.
|
||||
* method.c (make_thunk): Fix type of THUNK_DECL.
|
||||
* class.c (add_virtual_function, override_one_vtable): Use
|
||||
vfunc_ptr_type_node, instead of ptr_type_node.
|
||||
* cp-tree.h (vfunc_ptr_type_node): New macro.
|
||||
* decl.c (init_decl_processing): Make vtable_entry_type
|
||||
be a unique type of pointer to a unique function type.
|
||||
|
||||
Tue May 3 09:20:44 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* parse.y (do_explicit): Sets doing_explicit to 1.
|
||||
(explicit_instantiation): Use do_explicit rather than TEMPLATE
|
||||
directly, add "do_explicit error" rule.
|
||||
(datadef): Set doing_explicit to 0 after an explicit instantiation.
|
||||
(tmpl.2): Don't instantiate if we see a ';' unless we're doing an
|
||||
explicit instantiation.
|
||||
(named_class_head_sans_basetype): Remove aggr template_type_name
|
||||
';' again.
|
||||
|
||||
Mon May 2 23:17:21 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* search.c (lookup_nested_tag): Lose.
|
||||
|
||||
* decl2.c (grokfield): Set DECL_CONTEXT on TYPE_DECLs.
|
||||
(lookup_name_nonclass): Lose.
|
||||
|
||||
* decl.c (poplevel_class): Add force parameter.
|
||||
(lookup_name_real): Fix handling of explicit scoping which specifies
|
||||
a class currently being defined. Add 'nonclass' argument.
|
||||
(lookup_name, lookup_name_nonclass): Shells for lookup_name_real.
|
||||
|
||||
* class.c (finish_struct): Don't unset IDENTIFIER_CLASS_VALUEs here.
|
||||
(popclass): Force clearing of IDENTIFIER_CLASS_VALUEs if we're being
|
||||
called from finish_struct.
|
||||
|
||||
Mon May 2 19:06:21 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||
|
||||
* decl.c (init_decl_processing), cp-tree.h: Removed memptr_type.
|
||||
(It seeems redundant, given build_ptrmemfunc_type.)
|
||||
* typeck.c (get_member_function_from_ptrfunc), gc.c (build_headof,
|
||||
build_classof): Use vtable_entry_type instead of memptr_type.
|
||||
* method.c (emit_thunk): Call poplevel with functionbody==0
|
||||
to prevent DECL_INITIAL being set to a BLOCK.
|
||||
|
||||
Mon May 2 15:02:11 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* parse.y (named_class_head_sans_basetype): Add "aggr
|
||||
template_type_name ';'" rule for forward declaration of
|
||||
specializations.
|
||||
|
||||
Mon May 2 15:02:11 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* class.c (instantiate_type): Deal with pmf's.
|
||||
|
||||
* Make-lang.in (cc1plus): Don't depend on OBJS or BC_OBJS, since
|
||||
stamp-objlist does.
|
||||
|
||||
* Makefile.in (../cc1plus): Depend on OBJDEPS.
|
||||
(OBJDEPS): Dependency version of OBJS.
|
||||
|
||||
Mon May 2 12:51:31 1994 Kung Hsu (kung@mexican.cygnus.com)
|
||||
|
||||
* search.c (dfs_debug_mark): unmark TYPE_DECL_SUPPRESS_DEBUG, not
|
||||
DECL_IGNORED_P.
|
||||
|
||||
Fri Apr 29 12:29:56 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* class.c (finish_struct): Clear out memory of local tags. And
|
||||
typedefs.
|
||||
|
||||
* decl2.c (grokclassfn): Don't set DECL_CONTEXT to a cv-qualified
|
||||
type.
|
||||
* search.c (get_matching_virtual): Be more helpful in error message.
|
||||
|
||||
* *: Use DECL_ARTIFICIAL (renamed from DECL_SYNTHESIZED).
|
||||
|
||||
* lex.c (default_assign_ref_body): Expect TYPE_NESTED_NAME to work.
|
||||
(default_copy_constructor_body): Ditto.
|
||||
|
||||
* class.c (finish_struct): Don't gratuitously create multiple decls
|
||||
for nested classes.
|
||||
|
||||
Thu Apr 28 23:39:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
Avoid clobbering the arg types of other functions when reverting
|
||||
static member functions.
|
||||
* decl.c (revert_static_member_fn): Rearrange arguments, don't
|
||||
require values for 'fn' and 'argtypes', add warning to comment
|
||||
above.
|
||||
(decls_match): Rearrange arguments in call to rsmf.
|
||||
(grok_op_properties): Don't pass values for fn and argtypes.
|
||||
* pt.c (instantiate_template): Don't pass values for fn and argtypes.
|
||||
|
||||
Thu Apr 28 16:29:11 1994 Doug Evans (dje@canuck.cygnus.com)
|
||||
|
||||
* Make-lang.in (cc1plus): Depend on stamp-objlist.
|
||||
* Makefile.in (BC_OBJS): Delete.
|
||||
(OBJS): Cat ../stamp-objlist to get everything, except ../c-common.o.
|
||||
(OBJS): Cat ../stamp-objlist to get language independent files.
|
||||
Include ../c-common.o.
|
||||
(../cc1plus): Delete reference to BC_OBJS.
|
||||
|
||||
Thu Apr 28 02:12:08 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* search.c (compute_access): No really, deal with static members
|
||||
properly. Would I lie to you?
|
||||
|
||||
Implement lexical hiding of function declarations.
|
||||
* pt.c (tsubst): Use lookup_name to look for function decls to guide
|
||||
instantiation.
|
||||
* method.c (build_opfncall): Use lookup_name_nonclass to look for
|
||||
non-member functions.
|
||||
* init.c (do_friend): Use lookup_name_nonclass to look for
|
||||
functions.
|
||||
* error.c (ident_fndecl): Use lookup_name to look for functions.
|
||||
* decl2.c (lookup_name_nonclass): New function, skips over
|
||||
CLASS_VALUE.
|
||||
* decl.c (struct binding_level): Lose overloads_shadowed field.
|
||||
(poplevel): Don't deal with overloads_shadowed.
|
||||
(push_overloaded_decl): Do lexical hiding for functions.
|
||||
* class.c (instantiate_type): Don't check non-members if we have
|
||||
members with the same name.
|
||||
* call.c (build_method_call): Use lookup_name_nonclass instead of
|
||||
IDENTIFIER_GLOBAL_VALUE to check for non-member functions.
|
||||
(build_overload_call_real): Ditto.
|
||||
|
||||
* decl.c (duplicate_decls): Check for ambiguous overloads here.
|
||||
(push_overloaded_decl): Instead of here.
|
||||
|
||||
* decl.c (pushdecl): Back out Chip's last change.
|
||||
|
||||
* decl.c (grok_op_properties): operators cannot be static members.
|
||||
|
||||
* cp-tree.h (DECL_SYNTHESIZED): DECL_SOURCE_LINE == 0
|
||||
(SET_DECL_SYNTHESIZED): DECL_SOURCE_LINE = 0
|
||||
* lex.c (cons_up_default_function): Use SET_DECL_SYNTHESIZED.
|
||||
|
||||
* method.c (do_inline_function_hair): Don't put friends of local
|
||||
classes into global scope, either.
|
||||
|
||||
* typeck2.c (build_functional_cast): Don't look for a function call
|
||||
interpretation.
|
||||
|
||||
Thu Apr 28 15:19:46 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* cp-tree.h: disable use of backend EH.
|
||||
|
@ -170,6 +363,17 @@ Sun Apr 24 16:52:51 1994 Doug Evans (dje@canuck.cygnus.com)
|
|||
(*.o): Use complete pathname to headers in parent dir.
|
||||
(doc, info, dvi): Delete.
|
||||
|
||||
Sun Apr 24 16:52:51 1994 Doug Evans (dje@canuck.cygnus.com)
|
||||
|
||||
* Make-lang.in (c++.install-common): Check for g++-cross.
|
||||
* Makefile.in: Remove Cygnus cruft.
|
||||
(config.status): Delete.
|
||||
(RTL_H): Define.
|
||||
(TREE_H): Use complete pathname, some native makes have minimal
|
||||
VPATH support.
|
||||
(*.o): Use complete pathname to headers in parent dir.
|
||||
(doc, info, dvi): Delete.
|
||||
|
||||
Sun Apr 24 00:47:49 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (pushdecl): Avoid redundant warning on redeclaring function
|
||||
|
@ -290,6 +494,11 @@ Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com)
|
|||
* Language directory reorganization.
|
||||
See parent makefile.
|
||||
|
||||
Fri Apr 22 03:27:26 1994 Doug Evans (dje@cygnus.com)
|
||||
|
||||
* Language directory reorganization.
|
||||
See parent makefile.
|
||||
|
||||
Thu Apr 21 18:27:57 1994 Per Bothner (bothner@kalessin.cygnus.com)
|
||||
|
||||
* cp-tree.h (THUNK_DELTA): It is normally negative, so
|
||||
|
|
|
@ -2859,6 +2859,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
if (basetype != NULL_TREE)
|
||||
;
|
||||
/* call to a constructor... */
|
||||
else if (basetype_path)
|
||||
basetype = BINFO_TYPE (basetype_path);
|
||||
else if (IDENTIFIER_HAS_TYPE_VALUE (name))
|
||||
{
|
||||
basetype = IDENTIFIER_TYPE_VALUE (name);
|
||||
|
@ -3429,7 +3431,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
}
|
||||
if (pass == 0)
|
||||
{
|
||||
tree igv = IDENTIFIER_GLOBAL_VALUE (name);
|
||||
tree igv = lookup_name_nonclass (name);
|
||||
|
||||
/* No exact match could be found. Now try to find match
|
||||
using default conversions. */
|
||||
|
@ -3516,7 +3518,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
goto found_and_maybe_warn;
|
||||
}
|
||||
|
||||
if ((flags & ~LOOKUP_GLOBAL) & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY))
|
||||
if (flags & (LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY))
|
||||
{
|
||||
if ((flags & (LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN))
|
||||
== LOOKUP_SPECULATIVELY)
|
||||
|
@ -3925,23 +3927,25 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
|
|||
|
||||
if (! flag_ansi_overloading)
|
||||
{
|
||||
tree fn;
|
||||
|
||||
/* This is a speed improvement that ends up not working properly in
|
||||
the situation of fns with and without default parameters. I turned
|
||||
this off in the new method so it'll go through the argument matching
|
||||
code to properly diagnose a match/failure. (bpk) */
|
||||
overload_name = build_decl_overload (fnname, parmtypes, 0);
|
||||
fn = lookup_name_nonclass (overload_name);
|
||||
|
||||
/* Now check to see whether or not we can win.
|
||||
Note that if we are called from `build_method_call',
|
||||
then we cannot have a mis-match, because we would have
|
||||
already found such a winning case. */
|
||||
|
||||
if (IDENTIFIER_GLOBAL_VALUE (overload_name))
|
||||
if (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (overload_name)) != TREE_LIST)
|
||||
return build_function_call (DECL_MAIN_VARIANT (IDENTIFIER_GLOBAL_VALUE (overload_name)), parms);
|
||||
if (fn && TREE_CODE (fn) == FUNCTION_DECL)
|
||||
return build_function_call (DECL_MAIN_VARIANT (fn), parms);
|
||||
}
|
||||
|
||||
functions = IDENTIFIER_GLOBAL_VALUE (fnname);
|
||||
functions = lookup_name_nonclass (fnname);
|
||||
|
||||
if (functions == NULL_TREE)
|
||||
{
|
||||
|
|
|
@ -361,7 +361,7 @@ build_vtable_entry (delta, pfn)
|
|||
extern tree make_thunk ();
|
||||
if (idelta)
|
||||
{
|
||||
pfn = build1 (ADDR_EXPR, ptr_type_node,
|
||||
pfn = build1 (ADDR_EXPR, vtable_entry_type,
|
||||
make_thunk (pfn, idelta));
|
||||
TREE_READONLY (pfn) = 1;
|
||||
TREE_CONSTANT (pfn) = 1;
|
||||
|
@ -782,7 +782,7 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
|
|||
{
|
||||
/* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely
|
||||
convert to void *. Make such a conversion here. */
|
||||
tree vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl);
|
||||
tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
|
||||
TREE_CONSTANT (vfn) = 1;
|
||||
|
||||
#ifndef DUMB_USER
|
||||
|
@ -2389,7 +2389,7 @@ override_one_vtable (binfo, old, t)
|
|||
if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
|
||||
CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
|
||||
|
||||
vfn = build1 (ADDR_EXPR, ptr_type_node, fndecl);
|
||||
vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
|
||||
TREE_CONSTANT (vfn) = 1;
|
||||
|
||||
/* We can use integer_zero_node, as we will will core dump
|
||||
|
@ -2668,7 +2668,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
}
|
||||
|
||||
if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t)
|
||||
&& current_lang_name == lang_name_cplusplus && ! IS_SIGNATURE (t))
|
||||
&& ! IS_SIGNATURE (t))
|
||||
{
|
||||
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
|
||||
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only;
|
||||
|
@ -3653,7 +3653,14 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
last_x = tree_last (TYPE_FIELDS (t));
|
||||
while (x)
|
||||
{
|
||||
#if 0 /* What's wrong with using the decl the type already has? */
|
||||
tree tag = build_lang_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x));
|
||||
DECL_CONTEXT (tag) = t;
|
||||
#else
|
||||
tree tag = TYPE_NAME (TREE_VALUE (x));
|
||||
#endif
|
||||
DECL_CLASS_CONTEXT (tag) = t;
|
||||
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
{
|
||||
|
@ -3662,8 +3669,8 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
DECL_IGNORED_P (tag) = 1;
|
||||
}
|
||||
#endif /* DWARF_DEBUGGING_INFO */
|
||||
DECL_CONTEXT (tag) = t;
|
||||
DECL_CLASS_CONTEXT (tag) = t;
|
||||
|
||||
TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
|
||||
x = TREE_CHAIN (x);
|
||||
last_x = chainon (last_x, tag);
|
||||
}
|
||||
|
@ -3691,16 +3698,12 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
else if (TYPE_NEEDS_CONSTRUCTING (t))
|
||||
build_class_init_list (t);
|
||||
|
||||
if (current_lang_name == lang_name_cplusplus)
|
||||
{
|
||||
if (! CLASSTYPE_DECLARED_EXCEPTION (t)
|
||||
&& ! IS_SIGNATURE (t))
|
||||
embrace_waiting_friends (t);
|
||||
if (! CLASSTYPE_DECLARED_EXCEPTION (t) && ! IS_SIGNATURE (t))
|
||||
embrace_waiting_friends (t);
|
||||
|
||||
/* Write out inline function definitions. */
|
||||
do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
|
||||
CLASSTYPE_INLINE_FRIENDS (t) = 0;
|
||||
}
|
||||
/* Write out inline function definitions. */
|
||||
do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
|
||||
CLASSTYPE_INLINE_FRIENDS (t) = 0;
|
||||
|
||||
if (CLASSTYPE_VSIZE (t) != 0)
|
||||
{
|
||||
|
@ -4097,9 +4100,9 @@ pushclass (type, modify)
|
|||
}
|
||||
|
||||
/* Get out of the current class scope. If we were in a class scope
|
||||
previously, that is the one popped to. The flag MODIFY tells
|
||||
whether the current scope declarations needs to be modified
|
||||
as a result of popping to the previous scope. */
|
||||
previously, that is the one popped to. The flag MODIFY tells whether
|
||||
the current scope declarations needs to be modified as a result of
|
||||
popping to the previous scope. 0 is used for class definitions. */
|
||||
void
|
||||
popclass (modify)
|
||||
int modify;
|
||||
|
@ -4116,7 +4119,7 @@ popclass (modify)
|
|||
/* This code can be seen as a cache miss. When we've cached a
|
||||
class' scope's bindings and we can't use them, we need to reset
|
||||
them. This is it! */
|
||||
for (t = previous_class_values; t; t = TREE_CHAIN(t))
|
||||
for (t = previous_class_values; t; t = TREE_CHAIN (t))
|
||||
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
|
||||
while (tags)
|
||||
{
|
||||
|
@ -4141,7 +4144,9 @@ popclass (modify)
|
|||
undo_template_name_overload (current_class_name, 0);
|
||||
}
|
||||
|
||||
poplevel_class ();
|
||||
/* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
|
||||
since not all class decls make it there currently. */
|
||||
poplevel_class (! modify);
|
||||
|
||||
/* Since poplevel_class does the popping of class decls nowadays,
|
||||
this really only frees the obstack used for these decls.
|
||||
|
@ -4540,10 +4545,11 @@ instantiate_type (lhstype, rhs, complain)
|
|||
return save_elem;
|
||||
}
|
||||
name = DECL_NAME (TREE_VALUE (rhs));
|
||||
#if 0
|
||||
if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
|
||||
{
|
||||
/* Try to instantiate from non-member functions. */
|
||||
rhs = IDENTIFIER_GLOBAL_VALUE (name);
|
||||
rhs = lookup_name_nonclass (name);
|
||||
if (rhs && TREE_CODE (rhs) == TREE_LIST)
|
||||
{
|
||||
/* This code seems to be missing a `return'. */
|
||||
|
@ -4551,6 +4557,7 @@ instantiate_type (lhstype, rhs, complain)
|
|||
instantiate_type (lhstype, rhs, complain);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (complain)
|
||||
error ("no static member functions named `%s'",
|
||||
|
@ -4655,7 +4662,9 @@ instantiate_type (lhstype, rhs, complain)
|
|||
return rhs;
|
||||
|
||||
case ADDR_EXPR:
|
||||
if (TREE_CODE (lhstype) != POINTER_TYPE)
|
||||
if (TYPE_PTRMEMFUNC_P (lhstype))
|
||||
lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
|
||||
else if (TREE_CODE (lhstype) != POINTER_TYPE)
|
||||
{
|
||||
if (complain)
|
||||
error ("type for resolving address of overloaded function must be pointer type");
|
||||
|
@ -4663,7 +4672,8 @@ instantiate_type (lhstype, rhs, complain)
|
|||
}
|
||||
TREE_TYPE (rhs) = lhstype;
|
||||
lhstype = TREE_TYPE (lhstype);
|
||||
TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
|
||||
TREE_OPERAND (rhs, 0) = instantiate_type (lhstype, TREE_OPERAND (rhs, 0),
|
||||
complain);
|
||||
if (TREE_OPERAND (rhs, 0) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
|
|
@ -936,9 +936,8 @@ struct lang_decl_flags
|
|||
unsigned constructor_for_vbase_attr : 1;
|
||||
unsigned mutable_flag : 1;
|
||||
unsigned is_default_implementation : 1;
|
||||
unsigned synthesized : 1;
|
||||
unsigned saved_inline : 1;
|
||||
unsigned dummy : 9;
|
||||
unsigned dummy : 10;
|
||||
|
||||
tree access;
|
||||
tree context;
|
||||
|
@ -1000,6 +999,12 @@ struct lang_decl
|
|||
member function. */
|
||||
#define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function)
|
||||
|
||||
/* Nonzero for a class member means that it is shared between all objects
|
||||
of that class. */
|
||||
#define SHARED_MEMBER_P(NODE) \
|
||||
(TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \
|
||||
|| TREE_CODE (NODE) == CONST_DECL)
|
||||
|
||||
/* Nonzero for FUNCTION_DECL means that this decl is a member function
|
||||
(static or non-static). */
|
||||
#define DECL_FUNCTION_MEMBER_P(NODE) \
|
||||
|
@ -1106,8 +1111,9 @@ struct lang_decl
|
|||
#define DECL_PUBLIC(NODE) (DECL_LANG_FLAG_7 (NODE))
|
||||
#endif
|
||||
|
||||
/* This method was synthesized by cons_up_default_function. */
|
||||
#define DECL_SYNTHESIZED(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.synthesized)
|
||||
/* This _DECL represents a compiler-generated entity. */
|
||||
#define DECL_ARTIFICIAL(NODE) (DECL_SOURCE_LINE (NODE) == 0)
|
||||
#define SET_DECL_ARTIFICIAL(NODE) (DECL_SOURCE_LINE (NODE) = 0)
|
||||
|
||||
/* Record whether a typedef for type `int' was actually `signed int'. */
|
||||
#define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp))
|
||||
|
@ -1327,7 +1333,6 @@ extern tree void_list_node;
|
|||
extern tree void_zero_node;
|
||||
extern tree default_function_type;
|
||||
extern tree vtable_entry_type;
|
||||
extern tree memptr_type;
|
||||
extern tree sigtable_entry_type;
|
||||
extern tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
|
||||
extern tree Type_info_type_node;
|
||||
|
@ -1347,6 +1352,11 @@ extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
|
|||
extern tree exception_type_node, unknown_type_node;
|
||||
extern tree opaque_type_node, signature_type_node;
|
||||
|
||||
/* Node for "pointer to (virtual) function".
|
||||
This may be distinct from ptr_type_node so gdb can distinuish them. */
|
||||
#define vfunc_ptr_type_node \
|
||||
(flag_vtable_thunks ? vtable_entry_type : ptr_type_node)
|
||||
|
||||
/* Array type `(void *)[]' */
|
||||
extern tree vtbl_type_node;
|
||||
extern tree delta_type_node;
|
||||
|
@ -1812,7 +1822,7 @@ extern void insert_block PROTO((tree));
|
|||
extern void add_block_current_level PROTO((tree));
|
||||
extern void set_block PROTO((tree));
|
||||
extern void pushlevel_class PROTO((void));
|
||||
extern tree poplevel_class PROTO((void));
|
||||
extern tree poplevel_class PROTO((int));
|
||||
/* skip print_other_binding_stack and print_binding_level */
|
||||
extern void print_binding_stack PROTO((void));
|
||||
extern void push_to_top_level PROTO((void));
|
||||
|
@ -1906,6 +1916,7 @@ extern tree reparse_absdcl_as_expr PROTO((tree, tree));
|
|||
extern tree reparse_absdcl_as_casts PROTO((tree, tree));
|
||||
extern tree reparse_decl_as_expr PROTO((tree, tree));
|
||||
extern tree finish_decl_parsing PROTO((tree));
|
||||
extern tree lookup_name_nonclass PROTO((tree));
|
||||
|
||||
/* in edsel.c */
|
||||
|
||||
|
|
|
@ -1539,7 +1539,11 @@ build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
|
|||
&& (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
|
||||
> TREE_READONLY (TREE_TYPE (xtype))))
|
||||
warning ("user-defined conversion casting away `const'");
|
||||
return convert (xtype, rval);
|
||||
rval = convert_for_initialization (NULL_TREE, xtype, rval, flags,
|
||||
"conversion", NULL_TREE, 0);
|
||||
if (rval == error_mark_node)
|
||||
return NULL_TREE;
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Convert an aggregate EXPR to type XTYPE. If a conversion
|
||||
|
|
363
gcc/cp/decl.c
363
gcc/cp/decl.c
|
@ -224,7 +224,7 @@ tree sizet_ftype_string;
|
|||
tree int_ftype_cptr_cptr_sizet;
|
||||
|
||||
/* C++ extensions */
|
||||
tree memptr_type, vtable_entry_type;
|
||||
tree vtable_entry_type;
|
||||
tree delta_type_node;
|
||||
tree __t_desc_type_node, __i_desc_type_node, __m_desc_type_node;
|
||||
tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
|
||||
|
@ -531,9 +531,6 @@ struct binding_level
|
|||
/* Same, for IDENTIFIER_TYPE_VALUE. */
|
||||
tree type_shadowed;
|
||||
|
||||
/* Same, for IDENTIFIER_GLOBAL_VALUE for overloaded functions. */
|
||||
tree overloads_shadowed;
|
||||
|
||||
/* For each level (except not the global one),
|
||||
a chain of BLOCK nodes for all the levels
|
||||
that were entered and exited one level down. */
|
||||
|
@ -1025,9 +1022,6 @@ poplevel (keep, reverse, functionbody)
|
|||
for (link = current_binding_level->type_shadowed;
|
||||
link; link = TREE_CHAIN (link))
|
||||
IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
|
||||
for (link = current_binding_level->overloads_shadowed;
|
||||
link; link = TREE_CHAIN (link))
|
||||
IDENTIFIER_GLOBAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
|
||||
|
||||
/* If the level being exited is the top level of a function,
|
||||
check over all the labels. */
|
||||
|
@ -1232,9 +1226,11 @@ pushlevel_class ()
|
|||
while (current_binding_level->parm_flag == 2);
|
||||
}
|
||||
|
||||
/* ...and a poplevel for class declarations. */
|
||||
/* ...and a poplevel for class declarations. FORCE is used to force
|
||||
clearing out of CLASS_VALUEs after a class definition. */
|
||||
tree
|
||||
poplevel_class ()
|
||||
poplevel_class (force)
|
||||
int force;
|
||||
{
|
||||
register struct binding_level *level = class_binding_level;
|
||||
tree block = NULL_TREE;
|
||||
|
@ -1250,7 +1246,7 @@ poplevel_class ()
|
|||
shouldn't even be used when current_class_type isn't set, and second,
|
||||
if we don't touch it here, we're able to use the caching effect if the
|
||||
next time we're entering a class scope, it is the same class. */
|
||||
if (current_class_depth != 1)
|
||||
if (current_class_depth != 1 || force)
|
||||
for (shadowed = level->class_shadowed;
|
||||
shadowed;
|
||||
shadowed = TREE_CHAIN (shadowed))
|
||||
|
@ -1779,10 +1775,7 @@ pushtag (name, type, globalize)
|
|||
if (b->parm_flag != 2
|
||||
|| TYPE_SIZE (current_class_type) != NULL_TREE)
|
||||
{
|
||||
if (current_lang_name == lang_name_cplusplus)
|
||||
d = lookup_nested_type (type, cdecl);
|
||||
else
|
||||
d = NULL_TREE;
|
||||
d = lookup_nested_type (type, cdecl);
|
||||
|
||||
if (d == NULL_TREE)
|
||||
{
|
||||
|
@ -1854,7 +1847,7 @@ pushtag (name, type, globalize)
|
|||
}
|
||||
TYPE_NAME (type) = d;
|
||||
|
||||
if (context == NULL_TREE || current_lang_name != lang_name_cplusplus)
|
||||
if (context == NULL_TREE)
|
||||
/* Non-nested class. */
|
||||
DECL_NESTED_TYPENAME (d) = name;
|
||||
else if (context && TREE_CODE (context) == FUNCTION_DECL)
|
||||
|
@ -1980,10 +1973,10 @@ decls_match (newdecl, olddecl)
|
|||
is METHOD_TYPE. Change that to FUNCTION_TYPE, and
|
||||
proceed. */
|
||||
if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl))
|
||||
revert_static_member_fn (&f1, &newdecl, &p1);
|
||||
revert_static_member_fn (&newdecl, &f1, &p1);
|
||||
else if (TREE_CODE (f2) == METHOD_TYPE
|
||||
&& DECL_STATIC_FUNCTION_P (newdecl))
|
||||
revert_static_member_fn (&f2, &olddecl, &p2);
|
||||
revert_static_member_fn (&olddecl, &f2, &p2);
|
||||
|
||||
/* Here we must take care of the case where new default
|
||||
parameters are specified. Also, warn if an old
|
||||
|
@ -2154,29 +2147,29 @@ duplicate_decls (newdecl, olddecl)
|
|||
else if (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
&& (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))
|
||||
&& DECL_ASSEMBLER_NAME (newdecl) == DECL_ASSEMBLER_NAME (olddecl))
|
||||
/* Redeclaring a builtin as another function is handled in
|
||||
push_overloaded_decl. */
|
||||
{
|
||||
/* If you declare a built-in or predefined function name as static,
|
||||
the old definition is overridden,
|
||||
but optionally warn this was a bad choice of name. */
|
||||
if (! TREE_PUBLIC (newdecl))
|
||||
{
|
||||
if (warn_shadow)
|
||||
cp_warning ("shadowing %s function `%#D'",
|
||||
DECL_BUILT_IN (olddecl) ? "built-in" : "library",
|
||||
newdecl);
|
||||
/* Discard the old built-in function. */
|
||||
}
|
||||
else if (! types_match)
|
||||
if (warn_shadow)
|
||||
cp_warning ("shadowing %s function `%#D'",
|
||||
DECL_BUILT_IN (olddecl) ? "built-in" : "library",
|
||||
newdecl);
|
||||
/* Likewise, if the built-in is not ansi, then programs can override
|
||||
it even globally without an error. */
|
||||
else if (! DECL_BUILT_IN (olddecl))
|
||||
cp_warning ("library function `%#D' redeclared as non-function `%#D'",
|
||||
olddecl, newdecl);
|
||||
else
|
||||
{
|
||||
cp_warning ("declaration of `%#D'", newdecl);
|
||||
cp_warning ("conflicts with built-in declaration `%#D'",
|
||||
olddecl);
|
||||
}
|
||||
if (TREE_CODE (newdecl) != FUNCTION_DECL)
|
||||
return 0;
|
||||
|
||||
if (! types_match)
|
||||
TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
|
||||
return 0;
|
||||
}
|
||||
else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
|
||||
{
|
||||
|
@ -2211,8 +2204,15 @@ duplicate_decls (newdecl, olddecl)
|
|||
newdecl);
|
||||
cp_error_at ("previous declaration `%#D' here", olddecl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
|
||||
TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2))
|
||||
{
|
||||
cp_error ("new declaration `%#D'", newdecl);
|
||||
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Already complained about this, so don't do so again. */
|
||||
|
@ -2333,7 +2333,7 @@ duplicate_decls (newdecl, olddecl)
|
|||
/* Optionally warn about more than one declaration for the same name,
|
||||
but don't warn about a function declaration followed by a definition. */
|
||||
if (warn_redundant_decls
|
||||
&& DECL_SOURCE_LINE (olddecl) != 0
|
||||
&& ! DECL_ARTIFICIAL (olddecl)
|
||||
&& !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
|
||||
/* Don't warn about extern decl followed by (tentative) definition. */
|
||||
&& !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
|
||||
|
@ -2490,6 +2490,14 @@ duplicate_decls (newdecl, olddecl)
|
|||
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
if (! types_match)
|
||||
{
|
||||
DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl);
|
||||
DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl);
|
||||
DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
|
||||
DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
|
||||
DECL_RTL (olddecl) = DECL_RTL (newdecl);
|
||||
}
|
||||
if (new_defines_function)
|
||||
/* If defining a function declared with other language
|
||||
linkage, use the previously declared language linkage. */
|
||||
|
@ -2630,10 +2638,9 @@ pushdecl (x)
|
|||
nglobals = len;
|
||||
#endif
|
||||
|
||||
/* Don't change DECL_CONTEXT of virtual methods. */
|
||||
if (x != current_function_decl
|
||||
&& (TREE_CODE (x) != FUNCTION_DECL
|
||||
|| !DECL_VIRTUAL_P (x))
|
||||
/* Don't change DECL_CONTEXT of virtual methods. */
|
||||
&& (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x))
|
||||
&& ! DECL_CONTEXT (x))
|
||||
DECL_CONTEXT (x) = current_function_decl;
|
||||
/* A local declaration for a function doesn't constitute nesting. */
|
||||
|
@ -2660,10 +2667,7 @@ pushdecl (x)
|
|||
char *file;
|
||||
int line;
|
||||
|
||||
if (DECL_EXTERNAL (x))
|
||||
t = lookup_name (name, 0);
|
||||
else
|
||||
t = lookup_name_current_level (name);
|
||||
t = lookup_name_current_level (name);
|
||||
if (t == error_mark_node)
|
||||
{
|
||||
/* error_mark_node is 0 for a while during initialization! */
|
||||
|
@ -2956,7 +2960,7 @@ pushdecl (x)
|
|||
/* Maybe warn if shadowing something else. */
|
||||
else if (warn_shadow && !DECL_EXTERNAL (x)
|
||||
/* No shadow warnings for internally generated vars. */
|
||||
&& DECL_SOURCE_LINE (x) != 0
|
||||
&& ! DECL_ARTIFICIAL (x)
|
||||
/* No shadow warnings for vars made for inlining. */
|
||||
&& ! DECL_FROM_INLINE (x))
|
||||
{
|
||||
|
@ -2997,7 +3001,7 @@ pushdecl (x)
|
|||
{
|
||||
if (current_class_name)
|
||||
{
|
||||
if (!DECL_NESTED_TYPENAME (x))
|
||||
if (!DECL_NESTED_TYPENAME (TYPE_NAME (TREE_TYPE (x))))
|
||||
set_nested_typename (x, current_class_name, DECL_NAME (x),
|
||||
TREE_TYPE (x));
|
||||
}
|
||||
|
@ -3173,10 +3177,10 @@ overloaded_globals_p (list)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* DECL is a FUNCTION_DECL which may have other definitions already in place.
|
||||
We get around this by making IDENTIFIER_GLOBAL_VALUE (DECL_NAME (DECL))
|
||||
point to a list of all the things that want to be referenced by that name.
|
||||
It is then up to the users of that name to decide what to do with that
|
||||
/* DECL is a FUNCTION_DECL which may have other definitions already in
|
||||
place. We get around this by making the value of the identifier point
|
||||
to a list of all the things that want to be referenced by that name. It
|
||||
is then up to the users of that name to decide what to do with that
|
||||
list.
|
||||
|
||||
DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT
|
||||
|
@ -3191,80 +3195,89 @@ push_overloaded_decl (decl, forgettable)
|
|||
int forgettable;
|
||||
{
|
||||
tree orig_name = DECL_NAME (decl);
|
||||
tree glob = IDENTIFIER_GLOBAL_VALUE (orig_name);
|
||||
tree old;
|
||||
int doing_global = (global_bindings_p () || ! forgettable
|
||||
|| flag_traditional || pseudo_global_level_p ());
|
||||
|
||||
if (glob)
|
||||
if (doing_global)
|
||||
{
|
||||
old = IDENTIFIER_GLOBAL_VALUE (orig_name);
|
||||
if (old && TREE_CODE (old) == FUNCTION_DECL
|
||||
&& (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old)))
|
||||
{
|
||||
if (! decls_match (decl, old)
|
||||
&& (DECL_LANGUAGE (decl) == lang_c
|
||||
|| compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
|
||||
TYPE_ARG_TYPES (TREE_TYPE (old)), 2)))
|
||||
{
|
||||
cp_warning ("declaration of `%#D'", decl);
|
||||
cp_warning ("conflicts with built-in declaration `%#D'", old);
|
||||
}
|
||||
old = NULL_TREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
old = IDENTIFIER_LOCAL_VALUE (orig_name);
|
||||
|
||||
if (! purpose_member (orig_name, current_binding_level->shadowed))
|
||||
{
|
||||
current_binding_level->shadowed
|
||||
= tree_cons (orig_name, old, current_binding_level->shadowed);
|
||||
old = NULL_TREE;
|
||||
}
|
||||
}
|
||||
|
||||
if (old)
|
||||
{
|
||||
#if 0
|
||||
/* We cache the value of builtin functions as ADDR_EXPRs
|
||||
in the name space. Convert it to some kind of _DECL after
|
||||
remembering what to forget. */
|
||||
if (TREE_CODE (glob) == ADDR_EXPR)
|
||||
glob = TREE_OPERAND (glob, 0);
|
||||
|
||||
else if (TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
if (TREE_CODE (old) == ADDR_EXPR)
|
||||
old = TREE_OPERAND (old, 0);
|
||||
else
|
||||
#endif
|
||||
if (TREE_CODE (old) == VAR_DECL)
|
||||
{
|
||||
tree tmp;
|
||||
|
||||
for (tmp = get_first_fn (glob); tmp; tmp = DECL_CHAIN (tmp))
|
||||
if (decl == tmp || duplicate_decls (decl, tmp))
|
||||
return decl;
|
||||
}
|
||||
else if (TREE_CODE (glob) == VAR_DECL)
|
||||
{
|
||||
cp_error_at ("previous non-function declaration `%#D'", glob);
|
||||
cp_error_at ("previous non-function declaration `%#D'", old);
|
||||
cp_error ("conflicts with function declaration `%#D'", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (glob) == TYPE_DECL)
|
||||
else if (TREE_CODE (old) == TYPE_DECL)
|
||||
{
|
||||
tree t = TREE_TYPE (glob);
|
||||
tree t = TREE_TYPE (old);
|
||||
if (IS_AGGR_TYPE (t) && warn_shadow)
|
||||
cp_warning ("`%#D' hides constructor for `%#T'", decl, t);
|
||||
}
|
||||
else if (is_overloaded_fn (glob))
|
||||
else if (is_overloaded_fn (old))
|
||||
{
|
||||
tree tmp;
|
||||
|
||||
for (tmp = get_first_fn (glob); tmp; tmp = DECL_CHAIN (tmp))
|
||||
{
|
||||
if (decl == tmp || duplicate_decls (decl, tmp))
|
||||
return tmp;
|
||||
/* Avoid doing things about built-ins, since duplicate_decls
|
||||
will have given warnings/errors for them. */
|
||||
if (!DECL_BUILT_IN (tmp) && !DECL_BUILT_IN_NONANSI (tmp)
|
||||
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (decl)),
|
||||
TYPE_ARG_TYPES (TREE_TYPE (tmp)), 2))
|
||||
{
|
||||
cp_error ("new declaration `%#D'", decl);
|
||||
cp_error_at ("ambiguates old declaration `%#D'", tmp);
|
||||
}
|
||||
}
|
||||
for (tmp = get_first_fn (old); tmp; tmp = DECL_CHAIN (tmp))
|
||||
if (decl == tmp || duplicate_decls (decl, tmp))
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (forgettable
|
||||
&& ! flag_traditional
|
||||
&& (glob == NULL_TREE || TREE_PERMANENT (glob) == 1)
|
||||
&& !global_bindings_p ()
|
||||
&& !pseudo_global_level_p ())
|
||||
current_binding_level->overloads_shadowed
|
||||
= tree_cons (orig_name, glob,
|
||||
current_binding_level->overloads_shadowed);
|
||||
|
||||
if (glob || TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
if (old || TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
{
|
||||
if (glob && is_overloaded_fn (glob))
|
||||
DECL_CHAIN (decl) = get_first_fn (glob);
|
||||
if (old && is_overloaded_fn (old))
|
||||
DECL_CHAIN (decl) = get_first_fn (old);
|
||||
else
|
||||
DECL_CHAIN (decl) = NULL_TREE;
|
||||
glob = tree_cons (orig_name, decl, NULL_TREE);
|
||||
TREE_TYPE (glob) = unknown_type_node;
|
||||
old = tree_cons (orig_name, decl, NULL_TREE);
|
||||
TREE_TYPE (old) = unknown_type_node;
|
||||
}
|
||||
else
|
||||
/* orig_name is not ambiguous. */
|
||||
glob = decl;
|
||||
|
||||
IDENTIFIER_GLOBAL_VALUE (orig_name) = glob;
|
||||
old = decl;
|
||||
|
||||
if (doing_global)
|
||||
IDENTIFIER_GLOBAL_VALUE (orig_name) = old;
|
||||
else
|
||||
IDENTIFIER_LOCAL_VALUE (orig_name) = old;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
@ -3530,7 +3543,7 @@ define_label (filename, line, name)
|
|||
of internal entities. They can't be accessed,
|
||||
and they should be cleaned up
|
||||
by the time we get to the label. */
|
||||
&& DECL_SOURCE_LINE (new_decls) != 0
|
||||
&& ! DECL_ARTIFICIAL (new_decls)
|
||||
&& ((DECL_INITIAL (new_decls) != NULL_TREE
|
||||
&& DECL_INITIAL (new_decls) != error_mark_node)
|
||||
|| TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
|
||||
|
@ -3849,9 +3862,9 @@ lookup_nested_type (type, context)
|
|||
Otherwise we prefer non-TYPE_DECLs. */
|
||||
|
||||
tree
|
||||
lookup_name (name, prefer_type)
|
||||
lookup_name_real (name, prefer_type, nonclass)
|
||||
tree name;
|
||||
int prefer_type;
|
||||
int prefer_type, nonclass;
|
||||
{
|
||||
register tree val;
|
||||
int yylex = 0;
|
||||
|
@ -3879,10 +3892,29 @@ lookup_name (name, prefer_type)
|
|||
else if (! IS_AGGR_TYPE (got_scope))
|
||||
/* Someone else will give an error about this if needed. */
|
||||
val = NULL_TREE;
|
||||
else if (TYPE_BEING_DEFINED (got_scope))
|
||||
{
|
||||
val = IDENTIFIER_CLASS_VALUE (name);
|
||||
if (val && DECL_CONTEXT (val) != got_scope)
|
||||
{
|
||||
struct binding_level *b = class_binding_level;
|
||||
for (val = NULL_TREE; b; b = b->level_chain)
|
||||
{
|
||||
tree t = purpose_member (name, b->class_shadowed);
|
||||
if (t && TREE_VALUE (t)
|
||||
&& DECL_CONTEXT (TREE_VALUE (t)) == got_scope)
|
||||
{
|
||||
val = TREE_VALUE (t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (val == NULL_TREE
|
||||
&& CLASSTYPE_LOCAL_TYPEDECLS (got_scope))
|
||||
val = lookup_field (got_scope, name, 0, 1);
|
||||
}
|
||||
else if (got_scope == current_class_type)
|
||||
val = IDENTIFIER_CLASS_VALUE (name);
|
||||
else if (TYPE_BEING_DEFINED (got_scope))
|
||||
val = lookup_nested_tag (got_scope, name);
|
||||
else
|
||||
val = lookup_field (got_scope, name, 0, 0);
|
||||
|
||||
|
@ -3895,21 +3927,19 @@ lookup_name (name, prefer_type)
|
|||
val = IDENTIFIER_LOCAL_VALUE (name);
|
||||
/* In C++ class fields are between local and global scope,
|
||||
just before the global scope. */
|
||||
else if (current_class_type)
|
||||
else if (current_class_type && ! nonclass)
|
||||
{
|
||||
val = IDENTIFIER_CLASS_VALUE (name);
|
||||
if (val == NULL_TREE
|
||||
&& TYPE_SIZE (current_class_type) == NULL_TREE
|
||||
&& TYPE_BEING_DEFINED (current_class_type)
|
||||
&& CLASSTYPE_LOCAL_TYPEDECLS (current_class_type))
|
||||
/* Try to find values from base classes if we are presently
|
||||
defining a type. We are presently only interested in
|
||||
TYPE_DECLs. */
|
||||
{
|
||||
/* Try to find values from base classes
|
||||
if we are presently defining a type.
|
||||
We are presently only interested in TYPE_DECLs. */
|
||||
val = lookup_field (current_class_type, name, 0, 1);
|
||||
if (val == error_mark_node)
|
||||
return val;
|
||||
if (val && TREE_CODE (val) != TYPE_DECL)
|
||||
val = NULL_TREE;
|
||||
if (val)
|
||||
pushdecl_class_level (val);
|
||||
}
|
||||
|
||||
/* yylex() calls this with -2, since we should never start digging for
|
||||
|
@ -3948,6 +3978,21 @@ lookup_name (name, prefer_type)
|
|||
return val;
|
||||
}
|
||||
|
||||
tree
|
||||
lookup_name_nonclass (name)
|
||||
tree name;
|
||||
{
|
||||
return lookup_name_real (name, 0, 1);
|
||||
}
|
||||
|
||||
tree
|
||||
lookup_name (name, prefer_type)
|
||||
tree name;
|
||||
int prefer_type;
|
||||
{
|
||||
return lookup_name_real (name, prefer_type, 0);
|
||||
}
|
||||
|
||||
/* Similar to `lookup_name' but look only at current binding level. */
|
||||
|
||||
tree
|
||||
|
@ -4654,34 +4699,40 @@ init_decl_processing ()
|
|||
pushdecl (lookup_name (get_identifier ("__gc_main"), 0));
|
||||
}
|
||||
|
||||
/* Simplify life by making a "memptr_type". Give its
|
||||
fields names so that the debugger can use them. */
|
||||
|
||||
memptr_type = make_lang_type (RECORD_TYPE);
|
||||
fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
|
||||
delta_type_node);
|
||||
fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
|
||||
delta_type_node);
|
||||
fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier,
|
||||
ptr_type_node);
|
||||
finish_builtin_type (memptr_type, VTBL_PTR_TYPE, fields, 2,
|
||||
double_type_node);
|
||||
|
||||
/* Make this part of an invisible union. */
|
||||
fields[3] = copy_node (fields[2]);
|
||||
TREE_TYPE (fields[3]) = delta_type_node;
|
||||
DECL_NAME (fields[3]) = delta2_identifier;
|
||||
DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
|
||||
DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
|
||||
TREE_UNSIGNED (fields[3]) = 0;
|
||||
TREE_CHAIN (fields[2]) = fields[3];
|
||||
memptr_type = build_type_variant (memptr_type, 1, 0);
|
||||
record_builtin_type (RID_MAX, VTBL_PTR_TYPE, memptr_type);
|
||||
|
||||
if (flag_vtable_thunks)
|
||||
vtable_entry_type = ptr_type_node;
|
||||
{
|
||||
/* Make sure we get a unique function type, so we can give
|
||||
its pointer type a name. (This wins for gdb.) */
|
||||
tree vfunc_type = make_node (FUNCTION_TYPE);
|
||||
TREE_TYPE (vfunc_type) = integer_type_node;
|
||||
TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
|
||||
layout_type (vfunc_type);
|
||||
|
||||
vtable_entry_type = build_pointer_type (vfunc_type);
|
||||
}
|
||||
else
|
||||
vtable_entry_type = memptr_type;
|
||||
{
|
||||
vtable_entry_type = make_lang_type (RECORD_TYPE);
|
||||
fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
|
||||
delta_type_node);
|
||||
fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
|
||||
delta_type_node);
|
||||
fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier,
|
||||
ptr_type_node);
|
||||
finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2,
|
||||
double_type_node);
|
||||
|
||||
/* Make this part of an invisible union. */
|
||||
fields[3] = copy_node (fields[2]);
|
||||
TREE_TYPE (fields[3]) = delta_type_node;
|
||||
DECL_NAME (fields[3]) = delta2_identifier;
|
||||
DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
|
||||
DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
|
||||
TREE_UNSIGNED (fields[3]) = 0;
|
||||
TREE_CHAIN (fields[2]) = fields[3];
|
||||
vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0);
|
||||
}
|
||||
record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
|
||||
|
||||
vtbl_type_node
|
||||
= build_array_type (vtable_entry_type, NULL_TREE);
|
||||
|
@ -6625,7 +6676,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
grok_ctor_properties (ctype, decl);
|
||||
if (check == 0 && ! current_function_decl)
|
||||
{
|
||||
/* FIXME: this should only need to look at IDENTIFIER_GLOBAL_VALUE. */
|
||||
/* FIXME: this should only need to look at
|
||||
IDENTIFIER_GLOBAL_VALUE. */
|
||||
tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0);
|
||||
if (tmp == NULL_TREE)
|
||||
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)) = decl;
|
||||
|
@ -9515,8 +9567,7 @@ grok_op_properties (decl, virtualp, friendp)
|
|||
/* When the compiler encounters the definition of A::operator new, it
|
||||
doesn't look at the class declaration to find out if it's static. */
|
||||
if (methodp)
|
||||
revert_static_member_fn (&TREE_TYPE (decl), &decl,
|
||||
&TYPE_ARG_TYPES (TREE_TYPE (decl)));
|
||||
revert_static_member_fn (&decl, NULL, NULL);
|
||||
|
||||
/* Take care of function decl if we had syntax errors. */
|
||||
if (argtypes == NULL_TREE)
|
||||
|
@ -9531,8 +9582,7 @@ grok_op_properties (decl, virtualp, friendp)
|
|||
|| name == ansi_opname[(int) VEC_DELETE_EXPR])
|
||||
{
|
||||
if (methodp)
|
||||
revert_static_member_fn (&TREE_TYPE (decl), &decl,
|
||||
&TYPE_ARG_TYPES (TREE_TYPE (decl)));
|
||||
revert_static_member_fn (&decl, NULL, NULL);
|
||||
|
||||
if (argtypes == NULL_TREE)
|
||||
TREE_TYPE (decl) =
|
||||
|
@ -9554,7 +9604,7 @@ grok_op_properties (decl, virtualp, friendp)
|
|||
/* An operator function must either be a non-static member function
|
||||
or have at least one parameter of a class, a reference to a class,
|
||||
an enumeration, or a reference to an enumeration. 13.4.0.6 */
|
||||
if (! methodp)
|
||||
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
|
||||
{
|
||||
if (OPERATOR_TYPENAME_P (name)
|
||||
|| name == ansi_opname[(int) CALL_EXPR]
|
||||
|
@ -9566,6 +9616,9 @@ grok_op_properties (decl, virtualp, friendp)
|
|||
{
|
||||
tree p = argtypes;
|
||||
|
||||
if (DECL_STATIC_FUNCTION_P (decl))
|
||||
cp_error ("`%D' must be either a non-static member function or a non-member function", decl);
|
||||
|
||||
if (p)
|
||||
for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p))
|
||||
{
|
||||
|
@ -12119,20 +12172,30 @@ deactivate_exception_cleanups ()
|
|||
}
|
||||
|
||||
/* Change a static member function definition into a FUNCTION_TYPE, instead
|
||||
of the METHOD_TYPE that we create when it's originally parsed. */
|
||||
void
|
||||
revert_static_member_fn (fn, decl, argtypes)
|
||||
tree *fn, *decl, *argtypes;
|
||||
{
|
||||
tree tmp, function = *fn;
|
||||
of the METHOD_TYPE that we create when it's originally parsed.
|
||||
|
||||
*argtypes = TREE_CHAIN (*argtypes);
|
||||
tmp = build_function_type (TREE_TYPE (function), *argtypes);
|
||||
WARNING: DO NOT pass &TREE_TYPE (decl) to FN or &TYPE_ARG_TYPES
|
||||
(TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of
|
||||
other decls. Either pass the addresses of local variables or NULL. */
|
||||
|
||||
void
|
||||
revert_static_member_fn (decl, fn, argtypes)
|
||||
tree *decl, *fn, *argtypes;
|
||||
{
|
||||
tree tmp;
|
||||
tree function = fn ? *fn : TREE_TYPE (*decl);
|
||||
tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function);
|
||||
|
||||
args = TREE_CHAIN (args);
|
||||
tmp = build_function_type (TREE_TYPE (function), args);
|
||||
tmp = build_type_variant (tmp, TYPE_READONLY (function),
|
||||
TYPE_VOLATILE (function));
|
||||
tmp = build_exception_variant (TYPE_METHOD_BASETYPE (function), tmp,
|
||||
TYPE_RAISES_EXCEPTIONS (function));
|
||||
TREE_TYPE (*decl) = tmp;
|
||||
*fn = tmp;
|
||||
DECL_STATIC_FUNCTION_P (*decl) = 1;
|
||||
if (fn)
|
||||
*fn = tmp;
|
||||
if (argtypes)
|
||||
*argtypes = args;
|
||||
}
|
||||
|
|
|
@ -781,6 +781,7 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
tree fn_name = DECL_NAME (function);
|
||||
tree arg_types;
|
||||
tree parm;
|
||||
tree qualtype;
|
||||
|
||||
if (fn_name == NULL_TREE)
|
||||
{
|
||||
|
@ -790,7 +791,9 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
}
|
||||
|
||||
if (quals)
|
||||
ctype = grok_method_quals (ctype, function, quals);
|
||||
qualtype = grok_method_quals (ctype, function, quals);
|
||||
else
|
||||
qualtype = ctype;
|
||||
|
||||
arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
|
||||
if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
|
||||
|
@ -812,7 +815,7 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
of virtual baseclasses or not. */
|
||||
parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);
|
||||
/* Mark the artificial `__in_chrg' parameter as "artificial". */
|
||||
DECL_SOURCE_LINE (parm) = 0;
|
||||
SET_DECL_ARTIFICIAL (parm);
|
||||
DECL_ARG_TYPE (parm) = integer_type_node;
|
||||
DECL_REGISTER (parm) = 1;
|
||||
TREE_CHAIN (parm) = last_function_parms;
|
||||
|
@ -822,7 +825,7 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
|
||||
parm = build_decl (PARM_DECL, this_identifier, type);
|
||||
/* Mark the artificial `this' parameter as "artificial". */
|
||||
DECL_SOURCE_LINE (parm) = 0;
|
||||
SET_DECL_ARTIFICIAL (parm);
|
||||
DECL_ARG_TYPE (parm) = type;
|
||||
/* We can make this a register, so long as we don't
|
||||
accidentally complain if someone tries to take its address. */
|
||||
|
@ -865,7 +868,7 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
DECL_ASSEMBLER_NAME (function) = get_identifier (buf);
|
||||
parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type);
|
||||
/* Mark the artificial `__in_chrg' parameter as "artificial". */
|
||||
DECL_SOURCE_LINE (parm) = 0;
|
||||
SET_DECL_ARTIFICIAL (parm);
|
||||
TREE_USED (parm) = 1;
|
||||
#if 0
|
||||
/* We don't need to mark the __in_chrg parameter itself as `const'
|
||||
|
@ -878,7 +881,7 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
/* This is the same chain as DECL_ARGUMENTS (...). */
|
||||
TREE_CHAIN (last_function_parms) = parm;
|
||||
|
||||
TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node,
|
||||
TREE_TYPE (function) = build_cplus_method_type (qualtype, void_type_node,
|
||||
arg_types);
|
||||
TYPE_HAS_DESTRUCTOR (ctype) = 1;
|
||||
}
|
||||
|
@ -891,7 +894,7 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
arg_types = hash_tree_chain (integer_type_node,
|
||||
TREE_CHAIN (arg_types));
|
||||
TREE_TYPE (function)
|
||||
= build_cplus_method_type (ctype,
|
||||
= build_cplus_method_type (qualtype,
|
||||
TREE_TYPE (TREE_TYPE (function)),
|
||||
arg_types);
|
||||
arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));
|
||||
|
@ -901,7 +904,8 @@ grokclassfn (ctype, cname, function, flags, quals)
|
|||
|
||||
if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
|
||||
/* Only true for static member functions. */
|
||||
these_arg_types = hash_tree_chain (TYPE_POINTER_TO (ctype), arg_types);
|
||||
these_arg_types = hash_tree_chain (TYPE_POINTER_TO (qualtype),
|
||||
arg_types);
|
||||
|
||||
DECL_ASSEMBLER_NAME (function)
|
||||
= build_decl_overload (fn_name, these_arg_types,
|
||||
|
@ -1211,6 +1215,8 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
|
|||
if (TREE_CODE (value) == TYPE_DECL)
|
||||
{
|
||||
DECL_NONLOCAL (value) = 1;
|
||||
DECL_CONTEXT (value) = current_class_type;
|
||||
DECL_CLASS_CONTEXT (value) = current_class_type;
|
||||
CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
|
||||
pushdecl_class_level (value);
|
||||
return value;
|
||||
|
@ -2739,7 +2745,7 @@ finish_file ()
|
|||
vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node);
|
||||
#endif
|
||||
DECL_IGNORED_P (vars) = 1;
|
||||
DECL_SOURCE_LINE (vars) = 0;
|
||||
SET_DECL_ARTIFICIAL (vars);
|
||||
pushdecl (vars);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -500,7 +500,7 @@ tree
|
|||
ident_fndecl (t)
|
||||
tree t;
|
||||
{
|
||||
tree n = IDENTIFIER_GLOBAL_VALUE (t);
|
||||
tree n = lookup_name (t, 0);
|
||||
|
||||
if (TREE_CODE (n) == FUNCTION_DECL)
|
||||
return n;
|
||||
|
|
|
@ -2791,7 +2791,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
|
|||
{
|
||||
/* @@ Should be able to ingest later definitions of this function
|
||||
before use. */
|
||||
tree decl = IDENTIFIER_GLOBAL_VALUE (declarator);
|
||||
tree decl = lookup_name_nonclass (declarator);
|
||||
if (decl == NULL_TREE)
|
||||
{
|
||||
warning ("implicitly declaring `%s' as struct",
|
||||
|
@ -3676,6 +3676,26 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|
|||
{
|
||||
tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0));
|
||||
tree basetypes = TYPE_BINFO (type);
|
||||
tree passed_auto_delete;
|
||||
tree do_delete = NULL_TREE;
|
||||
|
||||
if (use_global_delete)
|
||||
{
|
||||
tree cond = fold (build (BIT_AND_EXPR, integer_type_node,
|
||||
auto_delete, integer_one_node));
|
||||
tree call = build_builtin_call
|
||||
(void_type_node, BID, build_tree_list (NULL_TREE, addr));
|
||||
|
||||
cond = fold (build (COND_EXPR, void_type_node, cond,
|
||||
call, void_zero_node));
|
||||
if (cond != void_zero_node)
|
||||
do_delete = cond;
|
||||
|
||||
passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node,
|
||||
auto_delete, integer_two_node));
|
||||
}
|
||||
else
|
||||
passed_auto_delete = auto_delete;
|
||||
|
||||
if (flags & LOOKUP_PROTECT)
|
||||
{
|
||||
|
@ -3723,8 +3743,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|
|||
if (function == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor));
|
||||
TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete);
|
||||
TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
|
||||
expr = build_function_call (function, parms);
|
||||
if (do_delete)
|
||||
expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
|
||||
if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0)
|
||||
{
|
||||
/* Handle the case where a virtual destructor is
|
||||
|
@ -3761,8 +3783,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|
|||
but that's now obsolete. */
|
||||
my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221);
|
||||
|
||||
TREE_CHAIN (parms) = build_tree_list (NULL_TREE, auto_delete);
|
||||
TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
|
||||
expr = build_function_call (dtor, parms);
|
||||
if (do_delete)
|
||||
expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
|
||||
|
||||
if (ifexp != integer_one_node)
|
||||
expr = build (COND_EXPR, void_type_node,
|
||||
|
|
10
gcc/cp/lex.c
10
gcc/cp/lex.c
|
@ -1836,14 +1836,10 @@ cons_up_default_function (type, name, fields, kind)
|
|||
}
|
||||
#endif /* DEBUG_DEFAULT_FUNCTIONS */
|
||||
|
||||
DECL_CLASS_CONTEXT (fn) = type;
|
||||
DECL_CLASS_CONTEXT (fn) = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
/* Show that this function was generated by the compiler. */
|
||||
#if 0
|
||||
DECL_SOURCE_LINE (fn) = 0;
|
||||
#else
|
||||
DECL_SYNTHESIZED (fn) = 1;
|
||||
#endif
|
||||
SET_DECL_ARTIFICIAL (fn);
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
@ -1956,7 +1952,6 @@ default_assign_ref_body (bufp, lenp, type, fields)
|
|||
|
||||
btype = BINFO_TYPE (binfo);
|
||||
name = TYPE_NESTED_NAME (btype);
|
||||
if (!name) name = DECL_NAME(TYPE_NAME(btype));
|
||||
s = IDENTIFIER_POINTER (name);
|
||||
|
||||
tneed = (2 * strlen (s)) + 33;
|
||||
|
@ -2122,7 +2117,6 @@ default_copy_constructor_body (bufp, lenp, type, fields)
|
|||
|
||||
btype = BINFO_TYPE (binfo);
|
||||
name = TYPE_NESTED_NAME (btype);
|
||||
if (!name) name = DECL_NAME(TYPE_NAME(btype));
|
||||
s = IDENTIFIER_POINTER (name);
|
||||
|
||||
tneed = (2 * strlen (s)) + 30;
|
||||
|
|
|
@ -135,7 +135,8 @@ do_inline_function_hair (type, friend_list)
|
|||
}
|
||||
|
||||
/* Allow this decl to be seen in global scope */
|
||||
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
|
||||
if (! current_function_decl)
|
||||
IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
|
||||
}
|
||||
|
||||
friend_list = TREE_CHAIN (friend_list);
|
||||
|
@ -1242,7 +1243,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
|
|||
else
|
||||
fnname = ansi_opname[(int) code];
|
||||
|
||||
global_fn = IDENTIFIER_GLOBAL_VALUE (fnname);
|
||||
global_fn = lookup_name_nonclass (fnname);
|
||||
|
||||
/* This is the last point where we will accept failure. This
|
||||
may be too eager if we wish an overloaded operator not to match,
|
||||
|
@ -1682,7 +1683,7 @@ make_thunk (function, delta)
|
|||
thunk = build_decl (THUNK_DECL, get_identifier (buffer),
|
||||
TREE_TYPE (func_decl));
|
||||
DECL_RESULT (thunk)
|
||||
= build_decl (RESULT_DECL, NULL_TREE, void_type_node);
|
||||
= build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type));
|
||||
make_function_rtl (thunk);
|
||||
DECL_INITIAL (thunk) = function;
|
||||
THUNK_DELTA (thunk) = delta;
|
||||
|
@ -1824,7 +1825,7 @@ emit_thunk (thunk_fndecl)
|
|||
emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count]));
|
||||
|
||||
expand_end_bindings (NULL, 1, 0);
|
||||
poplevel (0, 0, 1);
|
||||
poplevel (0, 0, 0);
|
||||
|
||||
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
|
||||
|
||||
|
|
|
@ -80,6 +80,8 @@ void yyerror ();
|
|||
error message if the user supplies an empty conditional expression. */
|
||||
static char *cond_stmt_keyword;
|
||||
|
||||
static int doing_explicit;
|
||||
|
||||
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */
|
||||
int have_extern_spec;
|
||||
int used_extern_spec;
|
||||
|
@ -262,7 +264,7 @@ empty_parms ()
|
|||
%type <ttype> qualified_type_name complete_type_name notype_identifier
|
||||
%type <ttype> complex_type_name nested_name_specifier_1
|
||||
%type <itype> nomods_initdecls nomods_initdcl0
|
||||
%type <ttype> new_initializer new_placement
|
||||
%type <ttype> new_initializer new_placement specialization
|
||||
|
||||
/* in order to recognize aggr tags as defining and thus shadowing. */
|
||||
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
|
||||
|
@ -542,6 +544,7 @@ datadef:
|
|||
| declmods ';'
|
||||
{ pedwarn ("empty declaration"); }
|
||||
| explicit_instantiation ';'
|
||||
{ doing_explicit = 0; }
|
||||
| typed_declspecs ';'
|
||||
{
|
||||
tree t = $<ttype>$;
|
||||
|
@ -778,11 +781,16 @@ identifier_defn:
|
|||
| PTYPENAME_DEFN
|
||||
;
|
||||
|
||||
do_explicit: TEMPLATE %prec EMPTY
|
||||
{ doing_explicit = 1; }
|
||||
;
|
||||
|
||||
explicit_instantiation:
|
||||
TEMPLATE aggr template_type
|
||||
{ do_type_instantiation ($3); }
|
||||
| TEMPLATE typed_declspecs declarator
|
||||
do_explicit specialization template_instantiation
|
||||
{ do_type_instantiation ($3 ? $3 : $2); }
|
||||
| do_explicit typed_declspecs declarator
|
||||
{ do_function_instantiation ($2, $3); }
|
||||
| do_explicit error
|
||||
;
|
||||
|
||||
template_type:
|
||||
|
@ -797,8 +805,8 @@ template_type_name:
|
|||
{ $$ = lookup_template_class ($$, $3, NULL_TREE); }
|
||||
;
|
||||
|
||||
tmpl.2: %prec EMPTY
|
||||
/* Always do expansion if it hasn't been done already. */
|
||||
tmpl.2:
|
||||
/* empty */ %prec EMPTY
|
||||
{ $$ = instantiate_class_template ($<ttype>0, 1); }
|
||||
;
|
||||
|
||||
|
@ -2212,6 +2220,15 @@ aggr: AGGR
|
|||
{ error ("no body nor ';' separates two class, struct or union declarations"); }
|
||||
;
|
||||
|
||||
specialization:
|
||||
aggr template_type_name ';'
|
||||
{
|
||||
yyungetc (';', 1); current_aggr = $$; $$ = $2;
|
||||
if (doing_explicit)
|
||||
instantiate_class_template ($$, 1);
|
||||
}
|
||||
;
|
||||
|
||||
named_class_head_sans_basetype:
|
||||
aggr identifier
|
||||
{ current_aggr = $$; $$ = $2; }
|
||||
|
@ -2227,6 +2244,7 @@ named_class_head_sans_basetype:
|
|||
overload_template_name ($$, 0); }
|
||||
| aggr template_type_name ':'
|
||||
{ yyungetc (':', 1); goto aggr2; }
|
||||
| specialization
|
||||
;
|
||||
|
||||
named_class_head_sans_basetype_defn:
|
||||
|
@ -4137,7 +4155,7 @@ operator_name:
|
|||
{ $$ = ansi_opname[VEC_NEW_EXPR]; }
|
||||
| operator DELETE '[' ']'
|
||||
{ $$ = ansi_opname[VEC_DELETE_EXPR]; }
|
||||
/* Should we be pushing into class scope to parse this? */
|
||||
/* Names here should be looked up in class scope ALSO. */
|
||||
| operator typed_typespecs conversion_declarator
|
||||
{ $$ = grokoptypename ($2, $3); }
|
||||
| operator error
|
||||
|
|
|
@ -1314,7 +1314,7 @@ tsubst (t, args, nargs, in_decl)
|
|||
tree decls;
|
||||
int got_it = 0;
|
||||
|
||||
decls = IDENTIFIER_GLOBAL_VALUE (r);
|
||||
decls = lookup_name (r, 0);
|
||||
if (decls == NULL_TREE)
|
||||
/* no match */;
|
||||
else if (TREE_CODE (decls) == TREE_LIST)
|
||||
|
@ -1624,8 +1624,7 @@ instantiate_template (tmpl, targ_ptr)
|
|||
&& DECL_STATIC_FUNCTION_P (fndecl))
|
||||
{
|
||||
tree olddecl = DECL_RESULT (tmpl);
|
||||
revert_static_member_fn (&TREE_TYPE (olddecl), &DECL_RESULT (tmpl),
|
||||
&TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
|
||||
revert_static_member_fn (&DECL_RESULT (tmpl), NULL, NULL);
|
||||
/* Chop off the this pointer that grokclassfn so kindly added
|
||||
for us (it didn't know yet if the fn was static or not). */
|
||||
DECL_ARGUMENTS (olddecl) = TREE_CHAIN (DECL_ARGUMENTS (olddecl));
|
||||
|
|
|
@ -813,7 +813,7 @@ compute_access (basetype_path, field)
|
|||
PUBLIC_RETURN;
|
||||
|
||||
/* Member found immediately within object. */
|
||||
if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE || static_mem)
|
||||
if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
|
||||
{
|
||||
/* Are we (or an enclosing scope) friends with the class that has
|
||||
FIELD? */
|
||||
|
@ -847,7 +847,8 @@ compute_access (basetype_path, field)
|
|||
types = basetype_path;
|
||||
via_protected = 0;
|
||||
access = access_default;
|
||||
protected_ok = 0;
|
||||
protected_ok = static_mem && current_class_type
|
||||
&& ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -1024,7 +1025,6 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
we know that binfo of a virtual base class will always == itself when
|
||||
found along any line. (mrs) */
|
||||
|
||||
/* Things for memoization. */
|
||||
char *errstr = 0;
|
||||
|
||||
/* Set this to nonzero if we don't know how to compute
|
||||
|
@ -1209,7 +1209,11 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
|
||||
if (nval || lookup_fnfields_here (type, name)>=0)
|
||||
{
|
||||
if (rval_binfo && hides (rval_binfo_h, binfo_h))
|
||||
if (nval && nval == rval && SHARED_MEMBER_P (nval))
|
||||
{
|
||||
/* This is ok, the member found is the same [class.ambig] */
|
||||
}
|
||||
else if (rval_binfo && hides (rval_binfo_h, binfo_h))
|
||||
{
|
||||
/* This is ok, the member found is in rval_binfo, not
|
||||
here (binfo). */
|
||||
|
@ -1476,7 +1480,6 @@ lookup_fnfields (basetype_path, name, complain)
|
|||
/* For now, don't try this. */
|
||||
int protect = complain;
|
||||
|
||||
/* Things for memoization. */
|
||||
char *errstr = 0;
|
||||
|
||||
/* Set this to nonzero if we don't know how to compute
|
||||
|
@ -1578,11 +1581,6 @@ lookup_fnfields (basetype_path, name, complain)
|
|||
TREE_TYPE (entry) = NULL_TREE;
|
||||
}
|
||||
|
||||
if (errstr && protect)
|
||||
{
|
||||
error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
|
||||
return error_mark_node;
|
||||
}
|
||||
return rvals;
|
||||
}
|
||||
rval = NULL_TREE;
|
||||
|
@ -1697,7 +1695,7 @@ lookup_fnfields (basetype_path, name, complain)
|
|||
else
|
||||
{
|
||||
/* This is ambiguous. */
|
||||
errstr = "request for member `%s' is ambiguous";
|
||||
errstr = "request for method `%D' is ambiguous";
|
||||
rvals = error_mark_node;
|
||||
break;
|
||||
}
|
||||
|
@ -1733,7 +1731,7 @@ lookup_fnfields (basetype_path, name, complain)
|
|||
|
||||
if (errstr && protect)
|
||||
{
|
||||
error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
|
||||
cp_error (errstr, name);
|
||||
rvals = error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -1946,7 +1944,8 @@ get_matching_virtual (binfo, fndecl, dtorp)
|
|||
if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
|
||||
&& ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
|
||||
{
|
||||
cp_error ("conflicting return type specified for virtual function `%D'", fndecl);
|
||||
cp_error ("conflicting return type specified for virtual function `%#D'", fndecl);
|
||||
cp_error ("overriding definition as `%#D'", tmp);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
|
||||
}
|
||||
break;
|
||||
|
@ -2368,7 +2367,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. */
|
||||
if (write_symbols != DWARF_DEBUG)
|
||||
DECL_IGNORED_P (TYPE_NAME (t)) = 0;
|
||||
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
|
||||
if (! TREE_ASM_WRITTEN (TYPE_NAME (t)))
|
||||
rest_of_type_compilation (t, global_bindings_p ());
|
||||
}
|
||||
|
@ -3175,27 +3174,3 @@ reinit_search_statistics ()
|
|||
n_outer_fields_searched = 0;
|
||||
n_contexts_saved = 0;
|
||||
}
|
||||
|
||||
tree
|
||||
lookup_nested_tag (type, name)
|
||||
tree type, name;
|
||||
{
|
||||
tree tags = CLASSTYPE_TAGS (type);
|
||||
|
||||
for (; tags; tags = TREE_CHAIN (tags))
|
||||
{
|
||||
/* The TREE_PURPOSE of an enum tag (which becomes a member of the
|
||||
enclosing class) is set to the name for the enum type. So, if
|
||||
name is `bar', and we strike `baz' for `enum bar { baz }', then
|
||||
this test will be true. */
|
||||
if (TREE_PURPOSE (tags) == name)
|
||||
break;
|
||||
}
|
||||
if (tags)
|
||||
return TYPE_NAME (TREE_VALUE (tags));
|
||||
|
||||
if (TYPE_CONTEXT (type))
|
||||
return lookup_nested_tag (TYPE_CONTEXT (type), name);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
|
|
@ -2114,28 +2114,35 @@ get_member_function_from_ptrfunc (instance_ptrptr, instance, function)
|
|||
return instance;
|
||||
|
||||
vtbl = convert_pointer_to (ptr_type_node, instance);
|
||||
vtbl = build (PLUS_EXPR,
|
||||
build_pointer_type (build_pointer_type (memptr_type)),
|
||||
vtbl, convert (sizetype, delta2));
|
||||
vtbl
|
||||
= build (PLUS_EXPR,
|
||||
build_pointer_type (build_pointer_type (vtable_entry_type)),
|
||||
vtbl, convert (sizetype, delta2));
|
||||
vtbl = build_indirect_ref (vtbl, NULL_PTR);
|
||||
aref = build_array_ref (vtbl, size_binop (MINUS_EXPR,
|
||||
index,
|
||||
integer_one_node));
|
||||
aref = save_expr (aref);
|
||||
if (! flag_vtable_thunks)
|
||||
{
|
||||
aref = save_expr (aref);
|
||||
|
||||
/* Save the intermediate result in a SAVE_EXPR so we don't have to
|
||||
compute each component of the virtual function pointer twice. */
|
||||
if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF)
|
||||
TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
|
||||
/* Save the intermediate result in a SAVE_EXPR so we don't have to
|
||||
compute each component of the virtual function pointer twice. */
|
||||
if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF)
|
||||
TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
|
||||
|
||||
delta = build (PLUS_EXPR, integer_type_node,
|
||||
build_conditional_expr (e1, build_component_ref (aref, delta_identifier, 0, 0), integer_zero_node),
|
||||
delta);
|
||||
delta = build (PLUS_EXPR, integer_type_node,
|
||||
build_conditional_expr (e1, build_component_ref (aref, delta_identifier, 0, 0), integer_zero_node),
|
||||
delta);
|
||||
}
|
||||
|
||||
*instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (*instance_ptrptr),
|
||||
*instance_ptrptr,
|
||||
convert (integer_type_node, delta));
|
||||
e2 = build_component_ref (aref, pfn_identifier, 0, 0);
|
||||
if (flag_vtable_thunks)
|
||||
e2 = aref;
|
||||
else
|
||||
e2 = build_component_ref (aref, pfn_identifier, 0, 0);
|
||||
|
||||
e3 = PFN_FROM_PTRMEMFUNC (function);
|
||||
TREE_TYPE (e2) = TREE_TYPE (e3);
|
||||
|
@ -5502,10 +5509,16 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
/* check to see if there is an assignment to `this' */
|
||||
if (lhs == current_class_decl)
|
||||
{
|
||||
if (flag_this_is_variable > 0
|
||||
&& DECL_NAME (current_function_decl) != NULL_TREE
|
||||
&& current_class_name != DECL_NAME (current_function_decl))
|
||||
warning ("assignment to `this' not in constructor or destructor");
|
||||
if (DECL_NAME (current_function_decl) != NULL_TREE)
|
||||
{
|
||||
/* ARM 18.3.3 and draft standard section C.11 say that assigning
|
||||
something to this is an anachronism. */
|
||||
if (pedantic)
|
||||
warning ("anachronistic assignment to `this' pointer");
|
||||
else if (flag_this_is_variable > 0
|
||||
&& current_class_name != DECL_NAME (current_function_decl))
|
||||
warning ("assignment to `this' not in constructor or destructor");
|
||||
}
|
||||
current_function_just_assigned_this = 1;
|
||||
}
|
||||
|
||||
|
@ -5670,7 +5683,7 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
{
|
||||
/* Allow array assignment in compiler-generated code. */
|
||||
if ((pedantic || flag_ansi)
|
||||
&& ! DECL_SYNTHESIZED (current_function_decl))
|
||||
&& ! DECL_ARTIFICIAL (current_function_decl))
|
||||
pedwarn ("ANSI C++ forbids assignment between arrays");
|
||||
|
||||
/* Have to wrap this in RTL_EXPR for two cases:
|
||||
|
@ -6600,7 +6613,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
|
|||
{
|
||||
tree init = build_method_call (exp, constructor_name_full (type),
|
||||
build_tree_list (NULL_TREE, rhs),
|
||||
NULL_TREE, LOOKUP_NORMAL);
|
||||
TYPE_BINFO (type), LOOKUP_NORMAL);
|
||||
|
||||
if (init == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
|
141
gcc/cp/typeck2.c
141
gcc/cp/typeck2.c
|
@ -1362,10 +1362,9 @@ build_m_component_ref (datum, component)
|
|||
|
||||
/* Return a tree node for the expression TYPENAME '(' PARMS ')'.
|
||||
|
||||
Because we cannot tell whether this construct is really
|
||||
a function call or a call to a constructor or a request for
|
||||
a type conversion, we try all three, and report any ambiguities
|
||||
we find. */
|
||||
Because we cannot tell whether this construct is really a call to a
|
||||
constructor or a request for a type conversion, we try both, and
|
||||
report any ambiguities we find. */
|
||||
tree
|
||||
build_functional_cast (exp, parms)
|
||||
tree exp;
|
||||
|
@ -1375,8 +1374,6 @@ build_functional_cast (exp, parms)
|
|||
or a C cast in C++'s `functional' notation. */
|
||||
tree type, name = NULL_TREE;
|
||||
tree expr_as_ctor = NULL_TREE;
|
||||
tree expr_as_method = NULL_TREE;
|
||||
tree expr_as_fncall = NULL_TREE;
|
||||
tree expr_as_conversion = NULL_TREE;
|
||||
|
||||
if (exp == error_mark_node || parms == error_mark_node)
|
||||
|
@ -1423,50 +1420,16 @@ build_functional_cast (exp, parms)
|
|||
name = DECL_NAME (name);
|
||||
}
|
||||
|
||||
/* Try evaluating as a call to a function. */
|
||||
if (IDENTIFIER_CLASS_VALUE (name)
|
||||
&& (TREE_CODE (IDENTIFIER_CLASS_VALUE (name)) == TREE_LIST
|
||||
|| TREE_CODE (IDENTIFIER_CLASS_VALUE (name)) == FUNCTION_DECL))
|
||||
{
|
||||
expr_as_method = build_method_call (current_class_decl, name, parms,
|
||||
NULL_TREE, LOOKUP_SPECULATIVELY);
|
||||
if (expr_as_method == error_mark_node)
|
||||
expr_as_method = NULL_TREE;
|
||||
}
|
||||
|
||||
if (IDENTIFIER_GLOBAL_VALUE (name)
|
||||
&& (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TREE_LIST
|
||||
|| TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == FUNCTION_DECL))
|
||||
{
|
||||
expr_as_fncall = build_overload_call (name, parms, 0,
|
||||
(struct candidate *)0);
|
||||
if (expr_as_fncall == NULL_TREE)
|
||||
expr_as_fncall = error_mark_node;
|
||||
}
|
||||
|
||||
if (! IS_AGGR_TYPE (type))
|
||||
{
|
||||
/* this must build a C cast */
|
||||
if (parms == NULL_TREE)
|
||||
{
|
||||
if (expr_as_method || expr_as_fncall)
|
||||
goto return_function;
|
||||
|
||||
return build1 (NOP_EXPR, type, integer_zero_node);
|
||||
}
|
||||
if (expr_as_method
|
||||
|| (expr_as_fncall && expr_as_fncall != error_mark_node))
|
||||
{
|
||||
cp_error ("ambiguity between cast to `%#T' and function call", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
return build1 (NOP_EXPR, type, integer_zero_node);
|
||||
return build_c_cast (type, build_compound_expr (parms));
|
||||
}
|
||||
|
||||
if (TYPE_SIZE (type) == NULL_TREE)
|
||||
{
|
||||
if (expr_as_method || expr_as_fncall)
|
||||
goto return_function;
|
||||
cp_error ("type `%T' is not yet defined", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -1475,7 +1438,7 @@ build_functional_cast (exp, parms)
|
|||
expr_as_conversion
|
||||
= build_type_conversion (CONVERT_EXPR, type, TREE_VALUE (parms), 0);
|
||||
|
||||
if (! TYPE_NEEDS_CONSTRUCTING (type) && parms != NULL_TREE)
|
||||
if (! TYPE_HAS_CONSTRUCTOR (type) && parms != NULL_TREE)
|
||||
{
|
||||
char *msg = 0;
|
||||
|
||||
|
@ -1488,71 +1451,13 @@ build_functional_cast (exp, parms)
|
|||
}
|
||||
else msg = "type `%T' does not have a constructor";
|
||||
|
||||
if ((expr_as_method || expr_as_fncall) && expr_as_conversion)
|
||||
msg = "ambiguity between conversion to `%T' and function call";
|
||||
else if (expr_as_method || expr_as_fncall)
|
||||
goto return_function;
|
||||
else if (expr_as_conversion)
|
||||
if (expr_as_conversion)
|
||||
return expr_as_conversion;
|
||||
|
||||
cp_error (msg, type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Constructors are not inherited... --jason */
|
||||
if (! TYPE_HAS_CONSTRUCTOR (type))
|
||||
{
|
||||
if (expr_as_method || expr_as_fncall)
|
||||
goto return_function;
|
||||
if (expr_as_conversion)
|
||||
return expr_as_conversion;
|
||||
|
||||
/* Look through this type until we find the
|
||||
base type which has a constructor. */
|
||||
do
|
||||
{
|
||||
tree binfos = TYPE_BINFO_BASETYPES (type);
|
||||
int i, index = 0;
|
||||
|
||||
while (binfos && TREE_VEC_LENGTH (binfos) == 1
|
||||
&& ! TYPE_HAS_CONSTRUCTOR (type))
|
||||
{
|
||||
type = BINFO_TYPE (TREE_VEC_ELT (binfos, 0));
|
||||
binfos = TYPE_BINFO_BASETYPES (type);
|
||||
}
|
||||
if (TYPE_HAS_CONSTRUCTOR (type))
|
||||
break;
|
||||
/* Hack for MI. */
|
||||
i = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
if (i == 0) break;
|
||||
while (--i > 0)
|
||||
{
|
||||
if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (TREE_VEC_ELT (binfos, i))))
|
||||
{
|
||||
if (index == 0)
|
||||
index = i;
|
||||
else
|
||||
{
|
||||
error ("multiple base classes with constructor, ambiguous");
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == 0)
|
||||
break;
|
||||
} while (! TYPE_HAS_CONSTRUCTOR (type));
|
||||
if (type == 0)
|
||||
return error_mark_node;
|
||||
}
|
||||
name = TYPE_NAME (type);
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
name = DECL_NAME (name);
|
||||
|
||||
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 321);
|
||||
#endif
|
||||
|
||||
{
|
||||
int flags = LOOKUP_SPECULATIVELY|LOOKUP_COMPLAIN;
|
||||
|
||||
|
@ -1565,20 +1470,7 @@ build_functional_cast (exp, parms)
|
|||
|
||||
if (expr_as_ctor && expr_as_ctor != error_mark_node)
|
||||
{
|
||||
#if 0
|
||||
/* mrs Mar 12, 1992 I claim that if it is a constructor, it is
|
||||
impossible to be an expr_as_method, without being a
|
||||
constructor call. */
|
||||
if (expr_as_method
|
||||
|| (expr_as_fncall && expr_as_fncall != error_mark_node))
|
||||
#else
|
||||
if (expr_as_fncall && expr_as_fncall != error_mark_node)
|
||||
#endif
|
||||
{
|
||||
cp_warning ("function hides constructor for class `%T'", type);
|
||||
return expr_as_fncall;
|
||||
}
|
||||
else if (expr_as_conversion && expr_as_conversion != error_mark_node)
|
||||
if (expr_as_conversion && expr_as_conversion != error_mark_node)
|
||||
{
|
||||
/* ANSI C++ June 5 1992 WP 12.3.2.6.1 */
|
||||
cp_error ("ambiguity between conversion to `%T' and constructor",
|
||||
|
@ -1632,23 +1524,8 @@ build_functional_cast (exp, parms)
|
|||
}
|
||||
|
||||
if (expr_as_conversion)
|
||||
{
|
||||
if (expr_as_method || expr_as_fncall)
|
||||
{
|
||||
cp_error ("ambiguity between conversion to `%T' and function call",
|
||||
type);
|
||||
return error_mark_node;
|
||||
}
|
||||
return expr_as_conversion;
|
||||
}
|
||||
return_function:
|
||||
if (expr_as_method)
|
||||
return build_method_call (current_class_decl, name, parms,
|
||||
NULL_TREE, LOOKUP_NORMAL);
|
||||
if (expr_as_fncall)
|
||||
return expr_as_fncall == error_mark_node
|
||||
? build_overload_call (name, parms, LOOKUP_COMPLAIN, (struct candidate *)0)
|
||||
: expr_as_fncall;
|
||||
return expr_as_conversion;
|
||||
|
||||
cp_error ("no suitable conversion to `%T' exists", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue