35th Cygnus<->FSF merge

From-SVN: r7217
This commit is contained in:
Mike Stump 1994-05-05 22:19:26 +00:00
parent 87e3e0c1b5
commit 700f8a8792
16 changed files with 618 additions and 410 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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));

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}