parent
896fc32209
commit
a58942422c
|
@ -1,3 +1,97 @@
|
||||||
|
Fri Apr 28 07:58:41 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* lex.c (cons_up_default_function): Fix linkage of #pragma
|
||||||
|
implemented functions.
|
||||||
|
|
||||||
|
Thu Apr 27 16:56:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* method.c (build_overload_name): Simplify and fix repeated type
|
||||||
|
folding.
|
||||||
|
|
||||||
|
* decl.c (grokdeclarator): Prohibit pointers to void or reference
|
||||||
|
members.
|
||||||
|
|
||||||
|
Thu Apr 27 09:49:07 1995 Mike Stump <mrs@cygnus.com>
|
||||||
|
|
||||||
|
* typeck2.c (process_init_constructor): Make sure initializers are
|
||||||
|
fully digested.
|
||||||
|
|
||||||
|
Thu Apr 27 01:11:55 1995 Jason Merrill <jason@python.cygnus.com>
|
||||||
|
|
||||||
|
* lex.c (cons_up_default_function): Always defer synthesis.
|
||||||
|
|
||||||
|
Thu Apr 27 00:20:37 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* decl2.c (mark_inline_for_output): Don't play with pending_inline
|
||||||
|
stuff.
|
||||||
|
|
||||||
|
Wed Apr 26 17:48:24 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* call.c (user_harshness): New function; like build_type_conversion,
|
||||||
|
but doesn't actually build anything.
|
||||||
|
(compute_conversion_costs): Use it instead of build_type_conversion.
|
||||||
|
|
||||||
|
Wed Apr 26 17:11:25 1995 Jason Merrill <jason@deneb.cygnus.com>
|
||||||
|
|
||||||
|
* typeck.c (build_function_call_real): Improve error message for
|
||||||
|
calling a non-function.
|
||||||
|
|
||||||
|
* method.c (hack_identifier): Lose check for calling a data member.
|
||||||
|
|
||||||
|
Wed Apr 26 16:59:13 1995 Mike Stump <mrs@cygnus.com>
|
||||||
|
|
||||||
|
* typeck2.c (build_functional_cast): Remove very old cruft.
|
||||||
|
Seems like good code is generated without it.
|
||||||
|
|
||||||
|
Wed Apr 26 00:47:16 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* method.c (do_build_assign_ref): Fix handling of anonymous unions.
|
||||||
|
(do_build_copy_constructor): Ditto.
|
||||||
|
|
||||||
|
* parse.y (simple_stmt, SWITCH): Call {push,pop}_switch.
|
||||||
|
|
||||||
|
* decl.c (push_switch): New function.
|
||||||
|
(pop_switch): Ditto.
|
||||||
|
(define_case_label): Check for jumping over initialization.
|
||||||
|
|
||||||
|
* call.c (build_method_call): Check for an inline function being
|
||||||
|
called before its definition has been seen.
|
||||||
|
* typeck.c (build_function_call_real): Ditto.
|
||||||
|
|
||||||
|
* decl.c (duplicate_decls): Check for a function being redeclared
|
||||||
|
inline after its address has been taken.
|
||||||
|
|
||||||
|
* typeck.c (build_conditional_expr): Handle related class lvalues.
|
||||||
|
|
||||||
|
Tue Apr 25 13:20:45 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* pt.c (do_pending_expansions): Don't expand unused templates.
|
||||||
|
|
||||||
|
* parse.y (component_decl): Accept a lone semicolon.
|
||||||
|
|
||||||
|
Tue Apr 25 00:25:56 1995 Jason Merrill <jason@rtl.cygnus.com>
|
||||||
|
|
||||||
|
* call.c (build_method_call): Don't allow an RTL_EXPR to serve as the
|
||||||
|
object parameter anymore.
|
||||||
|
|
||||||
|
* expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns.
|
||||||
|
|
||||||
|
Mon Apr 24 12:35:48 1995 Jason Merrill <jason@phydeaux.cygnus.com>
|
||||||
|
|
||||||
|
* parse.y (simple_stmt, decl case): Clear prefix_attributes.
|
||||||
|
(lang_extdef): Ditto.
|
||||||
|
|
||||||
|
* parse.y (maybe_parmlist): New rule for use in declarators where
|
||||||
|
this could either be a list of expressions or parameters. Calls
|
||||||
|
suspend_momentary before deciding which.
|
||||||
|
(direct_after_type_declarator): Use it.
|
||||||
|
(complex_direct_notype_declarator): Use it.
|
||||||
|
|
||||||
|
* pt.c (tsubst): Propagate attributes const and noreturn.
|
||||||
|
|
||||||
|
* typeck.c (build_modify_expr): If warn_synth, call build_opfncall
|
||||||
|
before doing the default thing.
|
||||||
|
|
||||||
Thu Apr 27 21:49:36 1995 Doug Evans <dje@cygnus.com>
|
Thu Apr 27 21:49:36 1995 Doug Evans <dje@cygnus.com>
|
||||||
|
|
||||||
* typeck.c (common_type): Call lookup_attribute instead of
|
* typeck.c (common_type): Call lookup_attribute instead of
|
||||||
|
|
|
@ -585,6 +585,47 @@ convert_harshness (type, parmtype, parm)
|
||||||
return EVIL_RETURN (h);
|
return EVIL_RETURN (h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
user_harshness (type, parmtype, parm)
|
||||||
|
register tree type, parmtype;
|
||||||
|
tree parm;
|
||||||
|
{
|
||||||
|
tree conv;
|
||||||
|
tree winner = NULL_TREE;
|
||||||
|
int code;
|
||||||
|
|
||||||
|
{
|
||||||
|
tree typename = build_typename_overload (type);
|
||||||
|
if (lookup_fnfields (TYPE_BINFO (parmtype), typename, 0))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv))
|
||||||
|
{
|
||||||
|
struct harshness_code tmp;
|
||||||
|
|
||||||
|
if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
|
||||||
|
tmp.code < USER_CODE)
|
||||||
|
{
|
||||||
|
if (winner)
|
||||||
|
return EVIL_CODE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
winner = conv;
|
||||||
|
code = tmp.code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (winner)
|
||||||
|
return code;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
can_convert (to, from)
|
can_convert (to, from)
|
||||||
tree to, from;
|
tree to, from;
|
||||||
|
@ -884,30 +925,14 @@ compute_conversion_costs (function, tta_in, cp, arglen)
|
||||||
if (TYPE_LANG_SPECIFIC (actual_type)
|
if (TYPE_LANG_SPECIFIC (actual_type)
|
||||||
&& TYPE_HAS_CONVERSION (actual_type))
|
&& TYPE_HAS_CONVERSION (actual_type))
|
||||||
{
|
{
|
||||||
tree conv;
|
int extra = user_harshness (formal_type, actual_type);
|
||||||
/* Don't issue warnings since we're only groping
|
|
||||||
around for the right answer, we haven't yet
|
|
||||||
committed to going with this solution. */
|
|
||||||
int old_inhibit_warnings = inhibit_warnings;
|
|
||||||
|
|
||||||
inhibit_warnings = 1;
|
if (extra == EVIL_CODE)
|
||||||
conv = build_type_conversion
|
win += 2;
|
||||||
(CALL_EXPR, formal_type, TREE_VALUE (tta), 0);
|
else if (extra >= 0)
|
||||||
inhibit_warnings = old_inhibit_warnings;
|
|
||||||
|
|
||||||
if (conv)
|
|
||||||
{
|
{
|
||||||
if (conv == error_mark_node
|
win++;
|
||||||
|| (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE
|
extra_conversions = extra;
|
||||||
&& ! TYPE_READONLY (TREE_VALUE (TREE_VALUE (ttf)))
|
|
||||||
&& ! lvalue_p (conv)))
|
|
||||||
win += 2;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
win++;
|
|
||||||
if (TREE_CODE (conv) != CALL_EXPR)
|
|
||||||
extra_conversions = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1789,11 +1814,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (TREE_CODE (instance) != CALL_EXPR
|
if (TREE_CODE (instance) != CALL_EXPR)
|
||||||
#ifdef PCC_STATIC_STRUCT_RETURN
|
|
||||||
&& TREE_CODE (instance) != RTL_EXPR
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
my_friendly_abort (125);
|
my_friendly_abort (125);
|
||||||
if (TYPE_NEEDS_CONSTRUCTING (basetype))
|
if (TYPE_NEEDS_CONSTRUCTING (basetype))
|
||||||
instance = build_cplus_new (basetype, instance, 0);
|
instance = build_cplus_new (basetype, instance, 0);
|
||||||
|
@ -2397,13 +2418,16 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
||||||
#if 1
|
#if 1
|
||||||
/* Is it a synthesized method that needs to be synthesized? */
|
/* Is it a synthesized method that needs to be synthesized? */
|
||||||
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
|
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
|
||||||
&& DECL_SAVED_INSNS (function) == 0
|
&& ! DECL_INITIAL (function)
|
||||||
&& ! TREE_ASM_WRITTEN (function)
|
|
||||||
/* Kludge: don't synthesize for default args. */
|
/* Kludge: don't synthesize for default args. */
|
||||||
&& current_function_decl)
|
&& current_function_decl)
|
||||||
synthesize_method (function);
|
synthesize_method (function);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function)
|
||||||
|
&& ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function))
|
||||||
|
cp_pedwarn ("inline function `%#D' called before definition", function);
|
||||||
|
|
||||||
fntype = TREE_TYPE (function);
|
fntype = TREE_TYPE (function);
|
||||||
if (TREE_CODE (fntype) == POINTER_TYPE)
|
if (TREE_CODE (fntype) == POINTER_TYPE)
|
||||||
fntype = TREE_TYPE (fntype);
|
fntype = TREE_TYPE (fntype);
|
||||||
|
|
|
@ -2315,6 +2315,11 @@ duplicate_decls (newdecl, olddecl)
|
||||||
olddecl);
|
olddecl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl)
|
||||||
|
&& TREE_ADDRESSABLE (olddecl))
|
||||||
|
cp_pedwarn ("`%#D' was used before it was declared inline",
|
||||||
|
newdecl);
|
||||||
}
|
}
|
||||||
/* These bits are logically part of the type for non-functions. */
|
/* These bits are logically part of the type for non-functions. */
|
||||||
else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
|
else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
|
||||||
|
@ -3660,6 +3665,30 @@ define_label (filename, line, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cp_switch
|
||||||
|
{
|
||||||
|
struct binding_level *level;
|
||||||
|
struct cp_switch *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct cp_switch *switch_stack;
|
||||||
|
|
||||||
|
void
|
||||||
|
push_switch ()
|
||||||
|
{
|
||||||
|
struct cp_switch *p
|
||||||
|
= (struct cp_switch *) oballoc (sizeof (struct cp_switch));
|
||||||
|
p->level = current_binding_level;
|
||||||
|
p->next = switch_stack;
|
||||||
|
switch_stack = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pop_switch ()
|
||||||
|
{
|
||||||
|
switch_stack = switch_stack->next;
|
||||||
|
}
|
||||||
|
|
||||||
/* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */
|
/* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */
|
||||||
/* XXX Note decl is never actually used. (bpk) */
|
/* XXX Note decl is never actually used. (bpk) */
|
||||||
void
|
void
|
||||||
|
@ -3667,19 +3696,46 @@ define_case_label (decl)
|
||||||
tree decl;
|
tree decl;
|
||||||
{
|
{
|
||||||
tree cleanup = last_cleanup_this_contour ();
|
tree cleanup = last_cleanup_this_contour ();
|
||||||
|
struct binding_level *b = current_binding_level;
|
||||||
|
int identified = 0;
|
||||||
|
|
||||||
if (cleanup)
|
if (cleanup)
|
||||||
{
|
{
|
||||||
static int explained = 0;
|
static int explained = 0;
|
||||||
cp_error_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
|
cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
|
||||||
error ("where case label appears here");
|
warning ("where case label appears here");
|
||||||
if (!explained)
|
if (!explained)
|
||||||
{
|
{
|
||||||
error ("(enclose actions of previous case statements requiring");
|
warning ("(enclose actions of previous case statements requiring");
|
||||||
error ("destructors in their own binding contours.)");
|
warning ("destructors in their own binding contours.)");
|
||||||
explained = 1;
|
explained = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (; b && b != switch_stack->level; b = b->level_chain)
|
||||||
|
{
|
||||||
|
tree new_decls = b->names;
|
||||||
|
for (; new_decls; new_decls = TREE_CHAIN (new_decls))
|
||||||
|
{
|
||||||
|
if (TREE_CODE (new_decls) == VAR_DECL
|
||||||
|
/* Don't complain about crossing initialization
|
||||||
|
of internal entities. They can't be accessed,
|
||||||
|
and they should be cleaned up
|
||||||
|
by the time we get to the label. */
|
||||||
|
&& ! DECL_ARTIFICIAL (new_decls)
|
||||||
|
&& ((DECL_INITIAL (new_decls) != NULL_TREE
|
||||||
|
&& DECL_INITIAL (new_decls) != error_mark_node)
|
||||||
|
|| TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
|
||||||
|
{
|
||||||
|
if (! identified)
|
||||||
|
error ("jump to case label");
|
||||||
|
identified = 1;
|
||||||
|
cp_error_at (" crosses initialization of `%#D'",
|
||||||
|
new_decls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* After labels, make any new cleanups go into their
|
/* After labels, make any new cleanups go into their
|
||||||
own new (temporary) binding contour. */
|
own new (temporary) binding contour. */
|
||||||
|
|
||||||
|
@ -8428,6 +8484,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE (type) == OFFSET_TYPE
|
||||||
|
&& (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE
|
||||||
|
|| TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE))
|
||||||
|
{
|
||||||
|
cp_error ("cannot declare pointer to `%#T' member",
|
||||||
|
TREE_TYPE (type));
|
||||||
|
type = TREE_TYPE (type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Merge any constancy or volatility into the target type
|
/* Merge any constancy or volatility into the target type
|
||||||
for the pointer. */
|
for the pointer. */
|
||||||
|
|
||||||
|
|
|
@ -2078,6 +2078,7 @@ mark_inline_for_output (decl)
|
||||||
return;
|
return;
|
||||||
my_friendly_assert (TREE_PERMANENT (decl), 363);
|
my_friendly_assert (TREE_PERMANENT (decl), 363);
|
||||||
DECL_SAVED_INLINE (decl) = 1;
|
DECL_SAVED_INLINE (decl) = 1;
|
||||||
|
#if 0
|
||||||
if (DECL_PENDING_INLINE_INFO (decl) != 0
|
if (DECL_PENDING_INLINE_INFO (decl) != 0
|
||||||
&& ! DECL_PENDING_INLINE_INFO (decl)->deja_vu)
|
&& ! DECL_PENDING_INLINE_INFO (decl)->deja_vu)
|
||||||
{
|
{
|
||||||
|
@ -2097,6 +2098,7 @@ mark_inline_for_output (decl)
|
||||||
}
|
}
|
||||||
DECL_PENDING_INLINE_INFO (decl) = 0;
|
DECL_PENDING_INLINE_INFO (decl) = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines);
|
saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,8 +151,9 @@ cplus_expand_expr (exp, target, tmode, modifier)
|
||||||
extern int flag_access_control;
|
extern int flag_access_control;
|
||||||
int old_ac = flag_access_control;
|
int old_ac = flag_access_control;
|
||||||
|
|
||||||
tree init = build (RTL_EXPR, type, 0, return_target);
|
tree init = build_decl (VAR_DECL, 0, type);
|
||||||
TREE_ADDRESSABLE (init) = 1;
|
TREE_ADDRESSABLE (init) = 1;
|
||||||
|
DECL_RTL (init) = return_target;
|
||||||
|
|
||||||
flag_access_control = 0;
|
flag_access_control = 0;
|
||||||
expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
|
expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
|
||||||
|
@ -160,8 +161,10 @@ cplus_expand_expr (exp, target, tmode, modifier)
|
||||||
|
|
||||||
if (TYPE_NEEDS_DESTRUCTOR (type))
|
if (TYPE_NEEDS_DESTRUCTOR (type))
|
||||||
{
|
{
|
||||||
init = build (RTL_EXPR, build_reference_type (type), 0,
|
init = build_decl (VAR_DECL, 0,
|
||||||
XEXP (return_target, 0));
|
build_reference_type (type));
|
||||||
|
DECL_RTL (init) = XEXP (return_target, 0);
|
||||||
|
|
||||||
init = maybe_build_cleanup (convert_from_reference (init));
|
init = maybe_build_cleanup (convert_from_reference (init));
|
||||||
if (init != NULL_TREE)
|
if (init != NULL_TREE)
|
||||||
expand_expr (init, 0, 0, 0);
|
expand_expr (init, 0, 0, 0);
|
||||||
|
|
|
@ -1321,6 +1321,17 @@ main()
|
||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@section Linkage
|
||||||
|
The linkage code in g++ is horribly twisted in order to meet two design goals:
|
||||||
|
|
||||||
|
1) Avoid unnecessary emission of inlines and vtables.
|
||||||
|
|
||||||
|
2) Support pedantic assemblers like the one in AIX.
|
||||||
|
|
||||||
|
To meet the first goal, we defer emission of inlines and vtables until
|
||||||
|
the end of the translation unit, where we can decide whether or not they
|
||||||
|
are needed, and how to emit them if they are.
|
||||||
|
|
||||||
@node Concept Index, , Free Store, Top
|
@node Concept Index, , Free Store, Top
|
||||||
@section Concept Index
|
@section Concept Index
|
||||||
|
|
||||||
|
|
|
@ -1797,13 +1797,13 @@ cons_up_default_function (type, full_name, kind)
|
||||||
if (CLASSTYPE_INTERFACE_KNOWN (type))
|
if (CLASSTYPE_INTERFACE_KNOWN (type))
|
||||||
{
|
{
|
||||||
DECL_INTERFACE_KNOWN (fn) = 1;
|
DECL_INTERFACE_KNOWN (fn) = 1;
|
||||||
DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type)
|
DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
|
||||||
|| ! flag_implement_inlines);
|
&& flag_implement_inlines);
|
||||||
TREE_STATIC (fn) = ! DECL_EXTERNAL (fn);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DECL_NOT_REALLY_EXTERN (fn) = 1;
|
DECL_NOT_REALLY_EXTERN (fn) = 1;
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* When on-the-fly synthesis works properly, remove the second and third
|
/* When on-the-fly synthesis works properly, remove the second and third
|
||||||
conditions here. */
|
conditions here. */
|
||||||
if (flag_keep_inline_functions
|
if (flag_keep_inline_functions
|
||||||
|
@ -1822,6 +1822,7 @@ cons_up_default_function (type, full_name, kind)
|
||||||
store_pending_inline (fn, t);
|
store_pending_inline (fn, t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
mark_inline_for_output (fn);
|
mark_inline_for_output (fn);
|
||||||
|
|
||||||
#ifdef DEBUG_DEFAULT_FUNCTIONS
|
#ifdef DEBUG_DEFAULT_FUNCTIONS
|
||||||
|
|
108
gcc/cp/method.c
108
gcc/cp/method.c
|
@ -562,44 +562,30 @@ build_overload_name (parmtypes, begin, end)
|
||||||
|
|
||||||
only_one:
|
only_one:
|
||||||
|
|
||||||
if (! nofold)
|
if (! nofold && ! just_one)
|
||||||
{
|
{
|
||||||
if (! just_one)
|
/* Every argument gets counted. */
|
||||||
/* Every argument gets counted. */
|
typevec[maxtype++] = parmtype;
|
||||||
typevec[maxtype++] = parmtype;
|
|
||||||
|
if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
|
||||||
|
{
|
||||||
|
nrepeats++;
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nrepeats)
|
||||||
|
flush_repeats (typevec[maxtype-2]);
|
||||||
|
|
||||||
if (TREE_USED (parmtype))
|
if (TREE_USED (parmtype))
|
||||||
{
|
{
|
||||||
if (! just_one && parmtype == typevec[maxtype-2])
|
flush_repeats (parmtype);
|
||||||
nrepeats++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (nrepeats)
|
|
||||||
flush_repeats (parmtype);
|
|
||||||
if (! just_one && TREE_CHAIN (parmtypes)
|
|
||||||
&& parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
|
|
||||||
nrepeats++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int tindex = 0;
|
|
||||||
|
|
||||||
while (typevec[tindex] != parmtype)
|
|
||||||
tindex++;
|
|
||||||
OB_PUTC ('T');
|
|
||||||
icat (tindex);
|
|
||||||
if (tindex > 9)
|
|
||||||
OB_PUTC ('_');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
if (nrepeats)
|
|
||||||
flush_repeats (typevec[maxtype-2]);
|
/* Only cache types which take more than one character. */
|
||||||
if (! just_one
|
if (parmtype != TYPE_MAIN_VARIANT (parmtype)
|
||||||
/* Only cache types which take more than one character. */
|
|| (TREE_CODE (parmtype) != INTEGER_TYPE
|
||||||
&& (parmtype != TYPE_MAIN_VARIANT (parmtype)
|
&& TREE_CODE (parmtype) != REAL_TYPE))
|
||||||
|| (TREE_CODE (parmtype) != INTEGER_TYPE
|
|
||||||
&& TREE_CODE (parmtype) != REAL_TYPE)))
|
|
||||||
TREE_USED (parmtype) = 1;
|
TREE_USED (parmtype) = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1496,23 +1482,7 @@ hack_identifier (value, name, yychar)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
TREE_USED (current_class_decl) = 1;
|
TREE_USED (current_class_decl) = 1;
|
||||||
if (yychar == '(')
|
|
||||||
if (! ((TYPE_LANG_SPECIFIC (type)
|
|
||||||
&& TYPE_OVERLOADS_CALL_EXPR (type))
|
|
||||||
|| (TREE_CODE (type) == REFERENCE_TYPE
|
|
||||||
&& TYPE_LANG_SPECIFIC (TREE_TYPE (type))
|
|
||||||
&& TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
|
|
||||||
&& TREE_CODE (type) != FUNCTION_TYPE
|
|
||||||
&& TREE_CODE (type) != METHOD_TYPE
|
|
||||||
&& !TYPE_PTRMEMFUNC_P (type)
|
|
||||||
&& (TREE_CODE (type) != POINTER_TYPE
|
|
||||||
|| (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
|
|
||||||
&& TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
|
|
||||||
{
|
|
||||||
error ("component `%s' is not a method",
|
|
||||||
IDENTIFIER_POINTER (name));
|
|
||||||
return error_mark_node;
|
|
||||||
}
|
|
||||||
/* Mark so that if we are in a constructor, and then find that
|
/* Mark so that if we are in a constructor, and then find that
|
||||||
this field was initialized by a base initializer,
|
this field was initialized by a base initializer,
|
||||||
we can emit an error message. */
|
we can emit an error message. */
|
||||||
|
@ -2094,32 +2064,34 @@ do_build_copy_constructor (fndecl)
|
||||||
for (; fields; fields = TREE_CHAIN (fields))
|
for (; fields; fields = TREE_CHAIN (fields))
|
||||||
{
|
{
|
||||||
tree name, init, t;
|
tree name, init, t;
|
||||||
if (TREE_CODE (fields) != FIELD_DECL)
|
tree field = fields;
|
||||||
|
|
||||||
|
if (TREE_CODE (field) != FIELD_DECL)
|
||||||
continue;
|
continue;
|
||||||
if (DECL_NAME (fields))
|
if (DECL_NAME (field))
|
||||||
{
|
{
|
||||||
if (VFIELD_NAME_P (DECL_NAME (fields)))
|
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||||
continue;
|
continue;
|
||||||
if (VBASE_NAME_P (DECL_NAME (fields)))
|
if (VBASE_NAME_P (DECL_NAME (field)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* True for duplicate members. */
|
/* True for duplicate members. */
|
||||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
|
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((t = TREE_TYPE (fields)) != NULL_TREE
|
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||||
&& TREE_CODE (t) == UNION_TYPE
|
&& TREE_CODE (t) == UNION_TYPE
|
||||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
|
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
|
||||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||||
fields = largest_union_member (t);
|
field = largest_union_member (t);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
|
init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
|
||||||
init = build_tree_list (NULL_TREE, init);
|
init = build_tree_list (NULL_TREE, init);
|
||||||
|
|
||||||
current_member_init_list
|
current_member_init_list
|
||||||
= tree_cons (DECL_NAME (fields), init, current_member_init_list);
|
= tree_cons (DECL_NAME (field), init, current_member_init_list);
|
||||||
}
|
}
|
||||||
current_member_init_list = nreverse (current_member_init_list);
|
current_member_init_list = nreverse (current_member_init_list);
|
||||||
current_base_init_list = nreverse (current_base_init_list);
|
current_base_init_list = nreverse (current_base_init_list);
|
||||||
|
@ -2171,29 +2143,31 @@ do_build_assign_ref (fndecl)
|
||||||
for (; fields; fields = TREE_CHAIN (fields))
|
for (; fields; fields = TREE_CHAIN (fields))
|
||||||
{
|
{
|
||||||
tree comp, init, t;
|
tree comp, init, t;
|
||||||
if (TREE_CODE (fields) != FIELD_DECL)
|
tree field = fields;
|
||||||
|
|
||||||
|
if (TREE_CODE (field) != FIELD_DECL)
|
||||||
continue;
|
continue;
|
||||||
if (DECL_NAME (fields))
|
if (DECL_NAME (field))
|
||||||
{
|
{
|
||||||
if (VFIELD_NAME_P (DECL_NAME (fields)))
|
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||||
continue;
|
continue;
|
||||||
if (VBASE_NAME_P (DECL_NAME (fields)))
|
if (VBASE_NAME_P (DECL_NAME (field)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* True for duplicate members. */
|
/* True for duplicate members. */
|
||||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
|
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((t = TREE_TYPE (fields)) != NULL_TREE
|
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||||
&& TREE_CODE (t) == UNION_TYPE
|
&& TREE_CODE (t) == UNION_TYPE
|
||||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
|
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
|
||||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||||
fields = largest_union_member (t);
|
field = largest_union_member (t);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields);
|
comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);
|
||||||
init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
|
init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
|
||||||
|
|
||||||
expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
|
expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
all derivations; this is applied before the explicit action, if one
|
all derivations; this is applied before the explicit action, if one
|
||||||
is given. Keep this in mind when reading the actions. */
|
is given. Keep this in mind when reading the actions. */
|
||||||
|
|
||||||
/* Also note: this version contains experimental exception
|
|
||||||
handling features. They could break, change, disappear,
|
|
||||||
or otherwise exhibit volatile behavior. Don't depend on
|
|
||||||
me (Michael Tiemann) to protect you from any negative impact
|
|
||||||
this may have on your professional, personal, or spiritual life.
|
|
||||||
|
|
||||||
NEWS FLASH: This version now supports the exception handling
|
|
||||||
syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given.
|
|
||||||
THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the
|
|
||||||
'catch' much match EXACTLY (no inheritance support or coercions).
|
|
||||||
Also, throw-specifications of functions don't work.
|
|
||||||
Destructors aren't called correctly. Etc, etc. --Per Bothner.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
/* Cause the `yydebug' variable to be defined. */
|
/* Cause the `yydebug' variable to be defined. */
|
||||||
#define YYDEBUG 1
|
#define YYDEBUG 1
|
||||||
|
@ -251,7 +237,7 @@ empty_parms ()
|
||||||
%type <ttype> object aggr
|
%type <ttype> object aggr
|
||||||
%type <itype> new delete
|
%type <itype> new delete
|
||||||
/* %type <ttype> primary_no_id */
|
/* %type <ttype> primary_no_id */
|
||||||
%type <ttype> nonmomentary_expr
|
%type <ttype> nonmomentary_expr maybe_parmlist
|
||||||
%type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
|
%type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
|
||||||
%type <ttype> template_header template_parm_list template_parm
|
%type <ttype> template_header template_parm_list template_parm
|
||||||
%type <ttype> template_type_parm
|
%type <ttype> template_type_parm
|
||||||
|
@ -346,7 +332,8 @@ lang_extdef:
|
||||||
{ if (pending_lang_change) do_pending_lang_change(); }
|
{ if (pending_lang_change) do_pending_lang_change(); }
|
||||||
extdef
|
extdef
|
||||||
{ if (! global_bindings_p () && ! pseudo_global_level_p())
|
{ if (! global_bindings_p () && ! pseudo_global_level_p())
|
||||||
pop_everything (); }
|
pop_everything ();
|
||||||
|
prefix_attributes = NULL_TREE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
extdef:
|
extdef:
|
||||||
|
@ -2600,7 +2587,6 @@ component_decl_list:
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| component_decl_list ';'
|
|
||||||
;
|
;
|
||||||
|
|
||||||
component_decl:
|
component_decl:
|
||||||
|
@ -2614,6 +2600,8 @@ component_decl:
|
||||||
{ $$ = finish_method ($$); }
|
{ $$ = finish_method ($$); }
|
||||||
| fn.def2 '{' /* nodecls compstmt */
|
| fn.def2 '{' /* nodecls compstmt */
|
||||||
{ $$ = finish_method ($$); }
|
{ $$ = finish_method ($$); }
|
||||||
|
| ';'
|
||||||
|
{ $$ = NULL_TREE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
component_decl_1:
|
component_decl_1:
|
||||||
|
@ -2796,12 +2784,27 @@ nonempty_type_quals:
|
||||||
/* These rules must follow the rules for function declarations
|
/* These rules must follow the rules for function declarations
|
||||||
and component declarations. That way, longer rules are preferred. */
|
and component declarations. That way, longer rules are preferred. */
|
||||||
|
|
||||||
|
suspend_mom:
|
||||||
|
{ $<itype>$ = suspend_momentary (); }
|
||||||
|
|
||||||
/* An expression which will not live on the momentary obstack. */
|
/* An expression which will not live on the momentary obstack. */
|
||||||
nonmomentary_expr:
|
nonmomentary_expr:
|
||||||
{ $<itype>$ = suspend_momentary (); } expr
|
suspend_mom expr
|
||||||
{ resume_momentary ((int) $<itype>1); $$ = $2; }
|
{ resume_momentary ((int) $<itype>1); $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/* An expression which will not live on the momentary obstack. */
|
||||||
|
maybe_parmlist:
|
||||||
|
suspend_mom '(' nonnull_exprlist ')'
|
||||||
|
{ resume_momentary ((int) $<itype>1); $$ = $3; }
|
||||||
|
| suspend_mom '(' parmlist ')'
|
||||||
|
{ resume_momentary ((int) $<itype>1); $$ = $3; }
|
||||||
|
| suspend_mom LEFT_RIGHT
|
||||||
|
{ resume_momentary ((int) $<itype>1); $$ = empty_parms (); }
|
||||||
|
| suspend_mom '(' error ')'
|
||||||
|
{ resume_momentary ((int) $<itype>1); $$ = NULL_TREE; }
|
||||||
|
;
|
||||||
|
|
||||||
/* A declarator that is allowed only after an explicit typespec. */
|
/* A declarator that is allowed only after an explicit typespec. */
|
||||||
/* may all be followed by prec '.' */
|
/* may all be followed by prec '.' */
|
||||||
after_type_declarator:
|
after_type_declarator:
|
||||||
|
@ -2843,14 +2846,8 @@ nested_type:
|
||||||
;
|
;
|
||||||
|
|
||||||
direct_after_type_declarator:
|
direct_after_type_declarator:
|
||||||
direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
|
direct_after_type_declarator maybe_parmlist type_quals %prec '.'
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
|
{ $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
|
||||||
| direct_after_type_declarator '(' parmlist ')' type_quals %prec '.'
|
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
|
|
||||||
| direct_after_type_declarator LEFT_RIGHT type_quals %prec '.'
|
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
|
|
||||||
| direct_after_type_declarator '(' error ')' type_quals %prec '.'
|
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
|
|
||||||
| direct_after_type_declarator '[' nonmomentary_expr ']'
|
| direct_after_type_declarator '[' nonmomentary_expr ']'
|
||||||
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
|
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
|
||||||
| direct_after_type_declarator '[' ']'
|
| direct_after_type_declarator '[' ']'
|
||||||
|
@ -2900,14 +2897,8 @@ complex_notype_declarator:
|
||||||
;
|
;
|
||||||
|
|
||||||
complex_direct_notype_declarator:
|
complex_direct_notype_declarator:
|
||||||
direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
|
direct_notype_declarator maybe_parmlist type_quals %prec '.'
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
|
{ $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
|
||||||
| direct_notype_declarator '(' parmlist ')' type_quals %prec '.'
|
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
|
|
||||||
| direct_notype_declarator LEFT_RIGHT type_quals %prec '.'
|
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
|
|
||||||
| direct_notype_declarator '(' error ')' type_quals %prec '.'
|
|
||||||
{ $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
|
|
||||||
| '(' complex_notype_declarator ')'
|
| '(' complex_notype_declarator ')'
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
| direct_notype_declarator '[' nonmomentary_expr ']'
|
| direct_notype_declarator '[' nonmomentary_expr ']'
|
||||||
|
@ -3192,7 +3183,8 @@ stmt:
|
||||||
|
|
||||||
simple_stmt:
|
simple_stmt:
|
||||||
decl
|
decl
|
||||||
{ finish_stmt (); }
|
{ finish_stmt ();
|
||||||
|
prefix_attributes = NULL_TREE; }
|
||||||
| expr ';'
|
| expr ';'
|
||||||
{
|
{
|
||||||
tree expr = $1;
|
tree expr = $1;
|
||||||
|
@ -3294,12 +3286,14 @@ simple_stmt:
|
||||||
| SWITCH .pushlevel '(' condition ')'
|
| SWITCH .pushlevel '(' condition ')'
|
||||||
{ emit_line_note (input_filename, lineno);
|
{ emit_line_note (input_filename, lineno);
|
||||||
c_expand_start_case ($4);
|
c_expand_start_case ($4);
|
||||||
|
push_switch ();
|
||||||
/* Don't let the tree nodes for $4 be discarded by
|
/* Don't let the tree nodes for $4 be discarded by
|
||||||
clear_momentary during the parsing of the next stmt. */
|
clear_momentary during the parsing of the next stmt. */
|
||||||
push_momentary (); }
|
push_momentary (); }
|
||||||
implicitly_scoped_stmt
|
implicitly_scoped_stmt
|
||||||
{ expand_end_case ($4);
|
{ expand_end_case ($4);
|
||||||
pop_momentary ();
|
pop_momentary ();
|
||||||
|
pop_switch ();
|
||||||
expand_end_bindings (getdecls (), kept_level_p (), 1);
|
expand_end_bindings (getdecls (), kept_level_p (), 1);
|
||||||
poplevel (kept_level_p (), 1, 0);
|
poplevel (kept_level_p (), 1, 0);
|
||||||
pop_momentary ();
|
pop_momentary ();
|
||||||
|
|
|
@ -1452,6 +1452,8 @@ tsubst (t, args, nargs, in_decl)
|
||||||
DECL_INTERFACE_KNOWN (r) = 0;
|
DECL_INTERFACE_KNOWN (r) = 0;
|
||||||
DECL_INLINE (r) = DECL_INLINE (t);
|
DECL_INLINE (r) = DECL_INLINE (t);
|
||||||
DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t);
|
DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t);
|
||||||
|
TREE_READONLY (r) = TREE_READONLY (t);
|
||||||
|
TREE_THIS_VOLATILE (r) = TREE_THIS_VOLATILE (t);
|
||||||
{
|
{
|
||||||
#if 0 /* Maybe later. -jason */
|
#if 0 /* Maybe later. -jason */
|
||||||
struct tinst_level *til = tinst_for_decl();
|
struct tinst_level *til = tinst_for_decl();
|
||||||
|
@ -2412,7 +2414,7 @@ do_pending_expansions ()
|
||||||
If `interface', ext ref. */
|
If `interface', ext ref. */
|
||||||
if (CLASSTYPE_INTERFACE_KNOWN (context))
|
if (CLASSTYPE_INTERFACE_KNOWN (context))
|
||||||
DECIDE (!CLASSTYPE_INTERFACE_ONLY (context));
|
DECIDE (!CLASSTYPE_INTERFACE_ONLY (context));
|
||||||
#if 0 /* This doesn't get us stuff needed only by the file initializer. */
|
#if 1 /* This doesn't get us stuff needed only by the file initializer. */
|
||||||
DECIDE (TREE_USED (t));
|
DECIDE (TREE_USED (t));
|
||||||
#else /* This compiles too much stuff, but that's probably better in
|
#else /* This compiles too much stuff, but that's probably better in
|
||||||
most cases than never compiling the stuff we need. */
|
most cases than never compiling the stuff we need. */
|
||||||
|
|
|
@ -51,6 +51,7 @@ static tree convert_sequence ();
|
||||||
static tree get_delta_difference PROTO((tree, tree, int));
|
static tree get_delta_difference PROTO((tree, tree, int));
|
||||||
|
|
||||||
extern rtx original_result_rtx;
|
extern rtx original_result_rtx;
|
||||||
|
extern int warn_synth;
|
||||||
|
|
||||||
/* Return the target type of TYPE, which meas return T for:
|
/* Return the target type of TYPE, which meas return T for:
|
||||||
T*, T&, T[], T (...), and otherwise, just T. */
|
T*, T&, T[], T (...), and otherwise, just T. */
|
||||||
|
@ -2359,6 +2360,12 @@ build_function_call_real (function, params, require_complete, flags)
|
||||||
pedwarn ("ANSI C++ forbids calling `main' from within program");
|
pedwarn ("ANSI C++ forbids calling `main' from within program");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pedantic && DECL_THIS_INLINE (function) && ! DECL_INITIAL (function)
|
||||||
|
&& ! DECL_ARTIFICIAL (function)
|
||||||
|
&& ! DECL_PENDING_INLINE_INFO (function))
|
||||||
|
cp_pedwarn ("inline function `%#D' called before definition",
|
||||||
|
function);
|
||||||
|
|
||||||
/* Differs from default_conversion by not setting TREE_ADDRESSABLE
|
/* Differs from default_conversion by not setting TREE_ADDRESSABLE
|
||||||
(because calling an inline function does not mean the function
|
(because calling an inline function does not mean the function
|
||||||
needs to be separately compiled). */
|
needs to be separately compiled). */
|
||||||
|
@ -2403,7 +2410,7 @@ build_function_call_real (function, params, require_complete, flags)
|
||||||
&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)
|
&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)
|
||||||
|| is_method))
|
|| is_method))
|
||||||
{
|
{
|
||||||
error ("called object is not a function");
|
cp_error ("`%E' cannot be used as a function", function);
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4617,9 +4624,21 @@ build_conditional_expr (ifexp, op1, op2)
|
||||||
code2 = TREE_CODE (type2);
|
code2 = TREE_CODE (type2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (code1 == RECORD_TYPE && code2 == RECORD_TYPE
|
||||||
|
&& real_lvalue_p (op1) && real_lvalue_p (op2)
|
||||||
|
&& comptypes (type1, type2, -1))
|
||||||
|
{
|
||||||
|
type1 = build_reference_type (type1);
|
||||||
|
type2 = build_reference_type (type2);
|
||||||
|
result_type = common_type (type1, type2);
|
||||||
|
op1 = convert_to_reference (result_type, op1, CONV_IMPLICIT,
|
||||||
|
LOOKUP_NORMAL, NULL_TREE);
|
||||||
|
op2 = convert_to_reference (result_type, op2, CONV_IMPLICIT,
|
||||||
|
LOOKUP_NORMAL, NULL_TREE);
|
||||||
|
}
|
||||||
/* Quickly detect the usual case where op1 and op2 have the same type
|
/* Quickly detect the usual case where op1 and op2 have the same type
|
||||||
after promotion. */
|
after promotion. */
|
||||||
if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
|
else if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
|
||||||
{
|
{
|
||||||
if (type1 == type2)
|
if (type1 == type2)
|
||||||
result_type = type1;
|
result_type = type1;
|
||||||
|
@ -4814,7 +4833,8 @@ build_conditional_expr (ifexp, op1, op2)
|
||||||
if (TREE_CONSTANT (ifexp))
|
if (TREE_CONSTANT (ifexp))
|
||||||
return integer_zerop (ifexp) ? op2 : op1;
|
return integer_zerop (ifexp) ? op2 : op1;
|
||||||
|
|
||||||
return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
|
return convert_from_reference
|
||||||
|
(fold (build (COND_EXPR, result_type, ifexp, op1, op2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle overloading of the ',' operator when needed. Otherwise,
|
/* Handle overloading of the ',' operator when needed. Otherwise,
|
||||||
|
@ -5630,7 +5650,14 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||||
cp_error ("`%T' does not define operator=", lhstype);
|
cp_error ("`%T' does not define operator=", lhstype);
|
||||||
else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype)
|
else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype)
|
||||||
&& TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
|
&& TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
|
||||||
/* Do the default thing */;
|
{
|
||||||
|
if (warn_synth)
|
||||||
|
/* If we care about this, do overload resolution. */
|
||||||
|
build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
|
||||||
|
lhs, rhs, make_node (NOP_EXPR));
|
||||||
|
|
||||||
|
/* Do the default thing */;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
|
result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
|
||||||
|
|
|
@ -975,6 +975,13 @@ process_init_constructor (type, init, elts)
|
||||||
tree tail1 = tail;
|
tree tail1 = tail;
|
||||||
next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
|
next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
|
||||||
TREE_VALUE (tail), &tail1);
|
TREE_VALUE (tail), &tail1);
|
||||||
|
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))
|
||||||
|
&& TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1)))
|
||||||
|
{
|
||||||
|
/* The fact this needs to be done suggests this code needs
|
||||||
|
to be totally rewritten. */
|
||||||
|
next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0);
|
||||||
|
}
|
||||||
my_friendly_assert (tail1 == 0
|
my_friendly_assert (tail1 == 0
|
||||||
|| TREE_CODE (tail1) == TREE_LIST, 319);
|
|| TREE_CODE (tail1) == TREE_LIST, 319);
|
||||||
if (tail == tail1 && len < 0)
|
if (tail == tail1 && len < 0)
|
||||||
|
@ -1529,37 +1536,7 @@ build_functional_cast (exp, parms)
|
||||||
if (expr_as_ctor == error_mark_node)
|
if (expr_as_ctor == error_mark_node)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
if (current_function_decl)
|
return build_cplus_new (type, expr_as_ctor, 1);
|
||||||
return build_cplus_new (type, expr_as_ctor, 1);
|
|
||||||
|
|
||||||
{
|
|
||||||
register tree parm = TREE_OPERAND (expr_as_ctor, 1);
|
|
||||||
|
|
||||||
/* Initializers for static variables and parameters have
|
|
||||||
to handle doing the initialization and cleanup themselves. */
|
|
||||||
my_friendly_assert (TREE_CODE (expr_as_ctor) == CALL_EXPR, 322);
|
|
||||||
#if 0
|
|
||||||
/* The following assertion fails in cases where we are initializing
|
|
||||||
a static member variable of a particular instance of a template
|
|
||||||
class with a call to a constructor of the given instance, as in:
|
|
||||||
|
|
||||||
TMPL<int> object = TMPL<int>();
|
|
||||||
|
|
||||||
Curiously, the assertion does not fail if we do the same thing
|
|
||||||
for a static member of a non-template class, as in:
|
|
||||||
|
|
||||||
T object = T();
|
|
||||||
|
|
||||||
I can't see why we should care here whether or not the initializer
|
|
||||||
expression involves a call to `new', so for the time being, it
|
|
||||||
seems best to just avoid doing this assertion. */
|
|
||||||
my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)), 323);
|
|
||||||
#endif
|
|
||||||
TREE_VALUE (parm) = NULL_TREE;
|
|
||||||
expr_as_ctor = build_indirect_ref (expr_as_ctor, NULL_PTR);
|
|
||||||
TREE_HAS_CONSTRUCTOR (expr_as_ctor) = 1;
|
|
||||||
}
|
|
||||||
return expr_as_ctor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the character string for the name that encodes the
|
/* Return the character string for the name that encodes the
|
||||||
|
|
Loading…
Reference in New Issue