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>
|
||||
|
||||
* typeck.c (common_type): Call lookup_attribute instead of
|
||||
|
|
|
@ -585,6 +585,47 @@ convert_harshness (type, parmtype, parm)
|
|||
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
|
||||
can_convert (to, from)
|
||||
tree to, from;
|
||||
|
@ -884,30 +925,14 @@ compute_conversion_costs (function, tta_in, cp, arglen)
|
|||
if (TYPE_LANG_SPECIFIC (actual_type)
|
||||
&& TYPE_HAS_CONVERSION (actual_type))
|
||||
{
|
||||
tree conv;
|
||||
/* 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;
|
||||
int extra = user_harshness (formal_type, actual_type);
|
||||
|
||||
inhibit_warnings = 1;
|
||||
conv = build_type_conversion
|
||||
(CALL_EXPR, formal_type, TREE_VALUE (tta), 0);
|
||||
inhibit_warnings = old_inhibit_warnings;
|
||||
|
||||
if (conv)
|
||||
if (extra == EVIL_CODE)
|
||||
win += 2;
|
||||
else if (extra >= 0)
|
||||
{
|
||||
if (conv == error_mark_node
|
||||
|| (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE
|
||||
&& ! TYPE_READONLY (TREE_VALUE (TREE_VALUE (ttf)))
|
||||
&& ! lvalue_p (conv)))
|
||||
win += 2;
|
||||
else
|
||||
{
|
||||
win++;
|
||||
if (TREE_CODE (conv) != CALL_EXPR)
|
||||
extra_conversions = 1;
|
||||
}
|
||||
win++;
|
||||
extra_conversions = extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1789,11 +1814,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (instance) != CALL_EXPR
|
||||
#ifdef PCC_STATIC_STRUCT_RETURN
|
||||
&& TREE_CODE (instance) != RTL_EXPR
|
||||
#endif
|
||||
)
|
||||
if (TREE_CODE (instance) != CALL_EXPR)
|
||||
my_friendly_abort (125);
|
||||
if (TYPE_NEEDS_CONSTRUCTING (basetype))
|
||||
instance = build_cplus_new (basetype, instance, 0);
|
||||
|
@ -2397,13 +2418,16 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
#if 1
|
||||
/* Is it a synthesized method that needs to be synthesized? */
|
||||
if (DECL_ARTIFICIAL (function) && ! flag_no_inline
|
||||
&& DECL_SAVED_INSNS (function) == 0
|
||||
&& ! TREE_ASM_WRITTEN (function)
|
||||
&& ! DECL_INITIAL (function)
|
||||
/* Kludge: don't synthesize for default args. */
|
||||
&& current_function_decl)
|
||||
synthesize_method (function);
|
||||
#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);
|
||||
if (TREE_CODE (fntype) == POINTER_TYPE)
|
||||
fntype = TREE_TYPE (fntype);
|
||||
|
|
|
@ -2315,6 +2315,11 @@ duplicate_decls (newdecl, 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. */
|
||||
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. */
|
||||
/* XXX Note decl is never actually used. (bpk) */
|
||||
void
|
||||
|
@ -3667,19 +3696,46 @@ define_case_label (decl)
|
|||
tree decl;
|
||||
{
|
||||
tree cleanup = last_cleanup_this_contour ();
|
||||
struct binding_level *b = current_binding_level;
|
||||
int identified = 0;
|
||||
|
||||
if (cleanup)
|
||||
{
|
||||
static int explained = 0;
|
||||
cp_error_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
|
||||
error ("where case label appears here");
|
||||
cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup));
|
||||
warning ("where case label appears here");
|
||||
if (!explained)
|
||||
{
|
||||
error ("(enclose actions of previous case statements requiring");
|
||||
error ("destructors in their own binding contours.)");
|
||||
warning ("(enclose actions of previous case statements requiring");
|
||||
warning ("destructors in their own binding contours.)");
|
||||
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
|
||||
own new (temporary) binding contour. */
|
||||
|
||||
|
@ -8428,6 +8484,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
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
|
||||
for the pointer. */
|
||||
|
||||
|
|
|
@ -2078,6 +2078,7 @@ mark_inline_for_output (decl)
|
|||
return;
|
||||
my_friendly_assert (TREE_PERMANENT (decl), 363);
|
||||
DECL_SAVED_INLINE (decl) = 1;
|
||||
#if 0
|
||||
if (DECL_PENDING_INLINE_INFO (decl) != 0
|
||||
&& ! DECL_PENDING_INLINE_INFO (decl)->deja_vu)
|
||||
{
|
||||
|
@ -2097,6 +2098,7 @@ mark_inline_for_output (decl)
|
|||
}
|
||||
DECL_PENDING_INLINE_INFO (decl) = 0;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
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;
|
||||
DECL_RTL (init) = return_target;
|
||||
|
||||
flag_access_control = 0;
|
||||
expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
|
||||
|
@ -160,8 +161,10 @@ cplus_expand_expr (exp, target, tmode, modifier)
|
|||
|
||||
if (TYPE_NEEDS_DESTRUCTOR (type))
|
||||
{
|
||||
init = build (RTL_EXPR, build_reference_type (type), 0,
|
||||
XEXP (return_target, 0));
|
||||
init = build_decl (VAR_DECL, 0,
|
||||
build_reference_type (type));
|
||||
DECL_RTL (init) = XEXP (return_target, 0);
|
||||
|
||||
init = maybe_build_cleanup (convert_from_reference (init));
|
||||
if (init != NULL_TREE)
|
||||
expand_expr (init, 0, 0, 0);
|
||||
|
|
|
@ -1321,6 +1321,17 @@ main()
|
|||
@}
|
||||
@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
|
||||
@section Concept Index
|
||||
|
||||
|
|
|
@ -1797,13 +1797,13 @@ cons_up_default_function (type, full_name, kind)
|
|||
if (CLASSTYPE_INTERFACE_KNOWN (type))
|
||||
{
|
||||
DECL_INTERFACE_KNOWN (fn) = 1;
|
||||
DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type)
|
||||
|| ! flag_implement_inlines);
|
||||
TREE_STATIC (fn) = ! DECL_EXTERNAL (fn);
|
||||
DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
|
||||
&& flag_implement_inlines);
|
||||
}
|
||||
else
|
||||
DECL_NOT_REALLY_EXTERN (fn) = 1;
|
||||
|
||||
#if 0
|
||||
/* When on-the-fly synthesis works properly, remove the second and third
|
||||
conditions here. */
|
||||
if (flag_keep_inline_functions
|
||||
|
@ -1822,6 +1822,7 @@ cons_up_default_function (type, full_name, kind)
|
|||
store_pending_inline (fn, t);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
mark_inline_for_output (fn);
|
||||
|
||||
#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:
|
||||
|
||||
if (! nofold)
|
||||
if (! nofold && ! just_one)
|
||||
{
|
||||
if (! just_one)
|
||||
/* Every argument gets counted. */
|
||||
typevec[maxtype++] = parmtype;
|
||||
/* Every argument gets counted. */
|
||||
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 (! just_one && parmtype == typevec[maxtype-2])
|
||||
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 ('_');
|
||||
}
|
||||
}
|
||||
flush_repeats (parmtype);
|
||||
goto next;
|
||||
}
|
||||
if (nrepeats)
|
||||
flush_repeats (typevec[maxtype-2]);
|
||||
if (! just_one
|
||||
/* Only cache types which take more than one character. */
|
||||
&& (parmtype != TYPE_MAIN_VARIANT (parmtype)
|
||||
|| (TREE_CODE (parmtype) != INTEGER_TYPE
|
||||
&& TREE_CODE (parmtype) != REAL_TYPE)))
|
||||
|
||||
/* Only cache types which take more than one character. */
|
||||
if (parmtype != TYPE_MAIN_VARIANT (parmtype)
|
||||
|| (TREE_CODE (parmtype) != INTEGER_TYPE
|
||||
&& TREE_CODE (parmtype) != REAL_TYPE))
|
||||
TREE_USED (parmtype) = 1;
|
||||
}
|
||||
|
||||
|
@ -1496,23 +1482,7 @@ hack_identifier (value, name, yychar)
|
|||
return error_mark_node;
|
||||
}
|
||||
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
|
||||
this field was initialized by a base initializer,
|
||||
we can emit an error message. */
|
||||
|
@ -2094,32 +2064,34 @@ do_build_copy_constructor (fndecl)
|
|||
for (; fields; fields = TREE_CHAIN (fields))
|
||||
{
|
||||
tree name, init, t;
|
||||
if (TREE_CODE (fields) != FIELD_DECL)
|
||||
tree field = fields;
|
||||
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
continue;
|
||||
if (DECL_NAME (fields))
|
||||
if (DECL_NAME (field))
|
||||
{
|
||||
if (VFIELD_NAME_P (DECL_NAME (fields)))
|
||||
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||
continue;
|
||||
if (VBASE_NAME_P (DECL_NAME (fields)))
|
||||
if (VBASE_NAME_P (DECL_NAME (field)))
|
||||
continue;
|
||||
|
||||
/* True for duplicate members. */
|
||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
|
||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
|
||||
continue;
|
||||
}
|
||||
else if ((t = TREE_TYPE (fields)) != NULL_TREE
|
||||
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& TREE_CODE (t) == UNION_TYPE
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
|
||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||
fields = largest_union_member (t);
|
||||
field = largest_union_member (t);
|
||||
else
|
||||
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);
|
||||
|
||||
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_base_init_list = nreverse (current_base_init_list);
|
||||
|
@ -2171,29 +2143,31 @@ do_build_assign_ref (fndecl)
|
|||
for (; fields; fields = TREE_CHAIN (fields))
|
||||
{
|
||||
tree comp, init, t;
|
||||
if (TREE_CODE (fields) != FIELD_DECL)
|
||||
tree field = fields;
|
||||
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
continue;
|
||||
if (DECL_NAME (fields))
|
||||
if (DECL_NAME (field))
|
||||
{
|
||||
if (VFIELD_NAME_P (DECL_NAME (fields)))
|
||||
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||
continue;
|
||||
if (VBASE_NAME_P (DECL_NAME (fields)))
|
||||
if (VBASE_NAME_P (DECL_NAME (field)))
|
||||
continue;
|
||||
|
||||
/* True for duplicate members. */
|
||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
|
||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
|
||||
continue;
|
||||
}
|
||||
else if ((t = TREE_TYPE (fields)) != NULL_TREE
|
||||
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& TREE_CODE (t) == UNION_TYPE
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
|
||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||
fields = largest_union_member (t);
|
||||
field = largest_union_member (t);
|
||||
else
|
||||
continue;
|
||||
|
||||
comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields);
|
||||
init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
|
||||
comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);
|
||||
init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
|
||||
|
||||
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
|
||||
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. */
|
||||
#define YYDEBUG 1
|
||||
|
@ -251,7 +237,7 @@ empty_parms ()
|
|||
%type <ttype> object aggr
|
||||
%type <itype> new delete
|
||||
/* %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 <ttype> template_header template_parm_list template_parm
|
||||
%type <ttype> template_type_parm
|
||||
|
@ -346,7 +332,8 @@ lang_extdef:
|
|||
{ if (pending_lang_change) do_pending_lang_change(); }
|
||||
extdef
|
||||
{ if (! global_bindings_p () && ! pseudo_global_level_p())
|
||||
pop_everything (); }
|
||||
pop_everything ();
|
||||
prefix_attributes = NULL_TREE; }
|
||||
;
|
||||
|
||||
extdef:
|
||||
|
@ -2600,7 +2587,6 @@ component_decl_list:
|
|||
$$ = $2;
|
||||
}
|
||||
}
|
||||
| component_decl_list ';'
|
||||
;
|
||||
|
||||
component_decl:
|
||||
|
@ -2614,6 +2600,8 @@ component_decl:
|
|||
{ $$ = finish_method ($$); }
|
||||
| fn.def2 '{' /* nodecls compstmt */
|
||||
{ $$ = finish_method ($$); }
|
||||
| ';'
|
||||
{ $$ = NULL_TREE; }
|
||||
;
|
||||
|
||||
component_decl_1:
|
||||
|
@ -2796,12 +2784,27 @@ nonempty_type_quals:
|
|||
/* These rules must follow the rules for function declarations
|
||||
and component declarations. That way, longer rules are preferred. */
|
||||
|
||||
suspend_mom:
|
||||
{ $<itype>$ = suspend_momentary (); }
|
||||
|
||||
/* An expression which will not live on the momentary obstack. */
|
||||
nonmomentary_expr:
|
||||
{ $<itype>$ = suspend_momentary (); } expr
|
||||
suspend_mom expr
|
||||
{ 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. */
|
||||
/* may all be followed by prec '.' */
|
||||
after_type_declarator:
|
||||
|
@ -2843,14 +2846,8 @@ nested_type:
|
|||
;
|
||||
|
||||
direct_after_type_declarator:
|
||||
direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
|
||||
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
|
||||
| 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 maybe_parmlist type_quals %prec '.'
|
||||
{ $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
|
||||
| direct_after_type_declarator '[' nonmomentary_expr ']'
|
||||
{ $$ = build_parse_node (ARRAY_REF, $$, $3); }
|
||||
| direct_after_type_declarator '[' ']'
|
||||
|
@ -2900,14 +2897,8 @@ complex_notype_declarator:
|
|||
;
|
||||
|
||||
complex_direct_notype_declarator:
|
||||
direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
|
||||
{ $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
|
||||
| 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); }
|
||||
direct_notype_declarator maybe_parmlist type_quals %prec '.'
|
||||
{ $$ = build_parse_node (CALL_EXPR, $$, $2, $3); }
|
||||
| '(' complex_notype_declarator ')'
|
||||
{ $$ = $2; }
|
||||
| direct_notype_declarator '[' nonmomentary_expr ']'
|
||||
|
@ -3192,7 +3183,8 @@ stmt:
|
|||
|
||||
simple_stmt:
|
||||
decl
|
||||
{ finish_stmt (); }
|
||||
{ finish_stmt ();
|
||||
prefix_attributes = NULL_TREE; }
|
||||
| expr ';'
|
||||
{
|
||||
tree expr = $1;
|
||||
|
@ -3294,12 +3286,14 @@ simple_stmt:
|
|||
| SWITCH .pushlevel '(' condition ')'
|
||||
{ emit_line_note (input_filename, lineno);
|
||||
c_expand_start_case ($4);
|
||||
push_switch ();
|
||||
/* Don't let the tree nodes for $4 be discarded by
|
||||
clear_momentary during the parsing of the next stmt. */
|
||||
push_momentary (); }
|
||||
implicitly_scoped_stmt
|
||||
{ expand_end_case ($4);
|
||||
pop_momentary ();
|
||||
pop_switch ();
|
||||
expand_end_bindings (getdecls (), kept_level_p (), 1);
|
||||
poplevel (kept_level_p (), 1, 0);
|
||||
pop_momentary ();
|
||||
|
|
|
@ -1452,6 +1452,8 @@ tsubst (t, args, nargs, in_decl)
|
|||
DECL_INTERFACE_KNOWN (r) = 0;
|
||||
DECL_INLINE (r) = DECL_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 */
|
||||
struct tinst_level *til = tinst_for_decl();
|
||||
|
@ -2412,7 +2414,7 @@ do_pending_expansions ()
|
|||
If `interface', ext ref. */
|
||||
if (CLASSTYPE_INTERFACE_KNOWN (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));
|
||||
#else /* This compiles too much stuff, but that's probably better in
|
||||
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));
|
||||
|
||||
extern rtx original_result_rtx;
|
||||
extern int warn_synth;
|
||||
|
||||
/* Return the target type of TYPE, which meas return T for:
|
||||
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");
|
||||
}
|
||||
|
||||
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
|
||||
(because calling an inline function does not mean the function
|
||||
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)
|
||||
|| is_method))
|
||||
{
|
||||
error ("called object is not a function");
|
||||
cp_error ("`%E' cannot be used as a function", function);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -4617,9 +4624,21 @@ build_conditional_expr (ifexp, op1, op2)
|
|||
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
|
||||
after promotion. */
|
||||
if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
|
||||
else if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
|
||||
{
|
||||
if (type1 == type2)
|
||||
result_type = type1;
|
||||
|
@ -4814,7 +4833,8 @@ build_conditional_expr (ifexp, op1, op2)
|
|||
if (TREE_CONSTANT (ifexp))
|
||||
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,
|
||||
|
@ -5630,7 +5650,14 @@ build_modify_expr (lhs, modifycode, rhs)
|
|||
cp_error ("`%T' does not define operator=", lhstype);
|
||||
else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype)
|
||||
&& 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
|
||||
{
|
||||
result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
|
||||
|
|
|
@ -975,6 +975,13 @@ process_init_constructor (type, init, elts)
|
|||
tree tail1 = tail;
|
||||
next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
|
||||
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
|
||||
|| TREE_CODE (tail1) == TREE_LIST, 319);
|
||||
if (tail == tail1 && len < 0)
|
||||
|
@ -1529,37 +1536,7 @@ build_functional_cast (exp, parms)
|
|||
if (expr_as_ctor == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (current_function_decl)
|
||||
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 build_cplus_new (type, expr_as_ctor, 1);
|
||||
}
|
||||
|
||||
/* Return the character string for the name that encodes the
|
||||
|
|
Loading…
Reference in New Issue