68th Cygnus<->FSF merge

From-SVN: r9555
This commit is contained in:
Mike Stump 1995-05-01 21:36:30 +00:00
parent 896fc32209
commit a58942422c
12 changed files with 351 additions and 177 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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