Commit e3417fcd by Mike Stump

57 Cygnus<->FSF merge

From-SVN: r8971
parent 71a81095
...@@ -10,6 +10,59 @@ Wed Jan 25 15:02:09 1995 David S. Miller (davem@nadzieja.rutgers.edu) ...@@ -10,6 +10,59 @@ Wed Jan 25 15:02:09 1995 David S. Miller (davem@nadzieja.rutgers.edu)
* class.c (instantiate_type): Change error message text. * class.c (instantiate_type): Change error message text.
* typeck2.c (store_init_value): Likewise. * typeck2.c (store_init_value): Likewise.
Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* decl2.c (reparse_decl_as_expr): Support being called without a
type argument.
* parse.y (primary): Add '(' expr_or_declarator ')'. Adds 4 r/r
conflicts. Sigh.
Fri Feb 17 12:02:06 1995 Mike Stump <mrs@cygnus.com>
* parse.y (template_def, fndef, fn.def1, return_init, condition,
initdcl0, initdcl, notype_initdcl0, nomods_initdcl0,
component_decl_1, after_type_component_declarator0,
notype_component_declarator0, after_type_component_declarator,
notype_component_declarator, after_type_component_declarator,
full_parm, maybe_raises, exception_specification_opt): Fix up,
include exception_specification_opt maybeasm maybe_attribute and
maybe_init if missing. Rename maybe_raises to
exception_specification_opt to match draft wording. Use maybe_init
to simplify rules.
Fri Feb 17 01:54:46 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* init.c (build_new): Set TREE_NO_UNUSED_WARNING on COMPOUND_EXPRs
built for news of scalar types.
Thu Feb 16 17:48:28 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* typeck.c (build_binary_op_nodefault): Update code for warning
about signed/unsigned comparisons from C frontend. Realize that the
code in the C frontend is, if anything, even more bogus. Fix it.
(build_binary_op): Undo default_conversion if it wasn't useful.
* typeck.c (build_unary_op, ADDR_EXPR): Lose bogus special case for
PRE*CREMENT_EXPR.
* decl2.c (import_export_vtable): Don't try the vtable hack
if the class doesn't have any real non-inline virtual functions.
(finish_vtable_vardecl): Don't bother trying to find a non-inline
virtual function in a non-polymorphic class.
(finish_prevtable_vardecl): Ditto.
* decl2.c (import_export_vtable): Use and set DECL_INTERFACE_KNOWN.
* cp-tree.h (DECL_INTERFACE_KNOWN): Use DECL_LANG_FLAG_5.
* init.c (expand_virtual_init): Always call assemble_external.
* class.c (build_vfn_ref): Always call assemble_external.
(build_vtable): Always call import_export_vtable.
(prepare_fresh_vtable): Ditto.
(add_virtual_function): Don't bother setting TREE_ADDRESSABLE.
Thu Feb 16 03:28:49 1995 Jason Merrill <jason@phydeaux.cygnus.com> Thu Feb 16 03:28:49 1995 Jason Merrill <jason@phydeaux.cygnus.com>
* class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine * class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine
......
...@@ -196,12 +196,12 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h ...@@ -196,12 +196,12 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
$(PARSE_H) : $(PARSE_C) $(PARSE_H) : $(PARSE_C)
$(PARSE_C) : $(srcdir)/parse.y $(PARSE_C) : $(srcdir)/parse.y
@echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts. @echo expect 1 shift/reduce confict and 39 reduce/reduce conflicts.
cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
#$(PARSE_C) $(PARSE_H) : stamp-parse ; @true #$(PARSE_C) $(PARSE_H) : stamp-parse ; @true
#stamp-parse: $(srcdir)/parse.y #stamp-parse: $(srcdir)/parse.y
# @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts. # @echo expect 1 shift/reduce confict and 39 reduce/reduce conflicts.
# $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y # $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y
# grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h # grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h
# $(srcdir)/../move-if-change y.tab.c $(PARSE_C) # $(srcdir)/../move-if-change y.tab.c $(PARSE_C)
......
...@@ -478,8 +478,7 @@ build_vfn_ref (ptr_to_instptr, instance, idx) ...@@ -478,8 +478,7 @@ build_vfn_ref (ptr_to_instptr, instance, idx)
vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
NULL_PTR); NULL_PTR);
} }
if (!flag_vtable_thunks) assemble_external (vtbl);
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx); aref = build_array_ref (vtbl, idx);
/* Save the intermediate result in a SAVE_EXPR so we don't have to /* Save the intermediate result in a SAVE_EXPR so we don't have to
...@@ -552,8 +551,7 @@ build_vtable (binfo, type) ...@@ -552,8 +551,7 @@ build_vtable (binfo, type)
#endif #endif
/* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */
if (! flag_vtable_thunks) import_export_vtable (decl, type, 0);
import_export_vtable (decl, type);
IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl); IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl);
/* Initialize the association list for this type, based /* Initialize the association list for this type, based
...@@ -699,8 +697,7 @@ prepare_fresh_vtable (binfo, for_type) ...@@ -699,8 +697,7 @@ prepare_fresh_vtable (binfo, for_type)
#endif #endif
/* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */
if (! flag_vtable_thunks) import_export_vtable (new_decl, for_type, 0);
import_export_vtable (new_decl, for_type);
if (TREE_VIA_VIRTUAL (binfo)) if (TREE_VIA_VIRTUAL (binfo))
my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo), my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo),
...@@ -803,9 +800,6 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t) ...@@ -803,9 +800,6 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
fndecl); fndecl);
#endif #endif
if (!flag_vtable_thunks)
TREE_ADDRESSABLE (fndecl) = CLASSTYPE_VTABLE_NEEDS_WRITING (t);
/* If the virtual function is a redefinition of a prior one, /* If the virtual function is a redefinition of a prior one,
figure out in which base class the new definition goes, figure out in which base class the new definition goes,
and if necessary, make a fresh virtual function table and if necessary, make a fresh virtual function table
......
...@@ -954,10 +954,9 @@ struct lang_decl_flags ...@@ -954,10 +954,9 @@ struct lang_decl_flags
unsigned saved_inline : 1; unsigned saved_inline : 1;
unsigned use_template : 2; unsigned use_template : 2;
unsigned interface_known : 1;
unsigned declared_static : 1; unsigned declared_static : 1;
unsigned nonconverting : 1; unsigned nonconverting : 1;
unsigned dummy : 5; unsigned dummy : 6;
tree access; tree access;
tree context; tree context;
...@@ -1131,7 +1130,7 @@ struct lang_decl ...@@ -1131,7 +1130,7 @@ struct lang_decl
#if 0 #if 0
/* Same, but tells if this field is private in current context. */ /* Same, but tells if this field is private in current context. */
#define DECL_PRIVATE(NODE) (DECL_LANG_FLAG_5 (NODE)) #define DECL_PRIVATE(NODE) (FOO)
/* Same, but tells if this field is private in current context. */ /* Same, but tells if this field is private in current context. */
#define DECL_PROTECTED(NODE) (DECL_LANG_FLAG_6 (NODE)) #define DECL_PROTECTED(NODE) (DECL_LANG_FLAG_6 (NODE))
...@@ -1337,8 +1336,7 @@ struct lang_decl ...@@ -1337,8 +1336,7 @@ struct lang_decl
(CLASSTYPE_USE_TEMPLATE(NODE) = 3) (CLASSTYPE_USE_TEMPLATE(NODE) = 3)
/* We know what we're doing with this decl now. */ /* We know what we're doing with this decl now. */
#define DECL_INTERFACE_KNOWN(NODE) \ #define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
(DECL_LANG_SPECIFIC (NODE)->decl_flags.interface_known)
/* This decl was declared to have internal linkage. */ /* This decl was declared to have internal linkage. */
#define DECL_DECLARED_STATIC(NODE) \ #define DECL_DECLARED_STATIC(NODE) \
......
...@@ -144,10 +144,8 @@ int warn_implicit = 1; ...@@ -144,10 +144,8 @@ int warn_implicit = 1;
int warn_ctor_dtor_privacy = 1; int warn_ctor_dtor_privacy = 1;
/* True if we want to implement vtbvales using "thunks". /* True if we want to implement vtbvales using "thunks".
The default is off now, but will be on later. The default is off now, but will be on later. */
Also causes output of vtables to be controlled by whether
we seen the class's first non-inline virtual function. */
int flag_vtable_thunks; int flag_vtable_thunks;
/* Nonzero means give string constants the type `const char *' /* Nonzero means give string constants the type `const char *'
...@@ -2466,23 +2464,61 @@ mark_vtable_entries (decl) ...@@ -2466,23 +2464,61 @@ mark_vtable_entries (decl)
it's public in this file or in another one. */ it's public in this file or in another one. */
void void
import_export_vtable (decl, type) import_export_vtable (decl, type, final)
tree decl, type; tree decl, type;
int final;
{ {
if (write_virtuals >= 2 if (DECL_INTERFACE_KNOWN (decl))
|| CLASSTYPE_TEMPLATE_INSTANTIATION (type)) return;
{
if (CLASSTYPE_INTERFACE_KNOWN (type)) /* +e0 or +e1 */
{ if (write_virtuals < 2 && write_virtuals != 0)
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
}
}
else if (write_virtuals != 0)
{ {
TREE_PUBLIC (decl) = 1; TREE_PUBLIC (decl) = 1;
if (write_virtuals < 0) if (write_virtuals < 0)
DECL_EXTERNAL (decl) = 1; DECL_EXTERNAL (decl) = 1;
DECL_INTERFACE_KNOWN (decl) = 1;
}
else if (CLASSTYPE_INTERFACE_KNOWN (type))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type);
DECL_INTERFACE_KNOWN (decl) = 1;
}
else
{
/* We can only do this optimization if we have real non-inline
virtual functions in our class, or if we come from a template. */
int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type);
if (! found && ! final)
{
/* This check only works before the method definitions are seen,
since DECL_INLINE may get bashed. */
tree method;
for (method = CLASSTYPE_METHODS (type); method != NULL_TREE;
method = DECL_NEXT_METHOD (method))
if (DECL_VINDEX (method) != NULL_TREE && ! DECL_INLINE (method)
&& ! DECL_ABSTRACT_VIRTUAL_P (method))
{
found = 1;
break;
}
}
if (final || ! found)
{
TREE_PUBLIC (decl) = 0;
DECL_EXTERNAL (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1;
}
else
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
DECL_INTERFACE_KNOWN (decl) = 0;
}
} }
} }
...@@ -2506,9 +2542,8 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2506,9 +2542,8 @@ finish_prevtable_vardecl (prev, vars)
{ {
tree ctype = DECL_CONTEXT (vars); tree ctype = DECL_CONTEXT (vars);
import_export_template (ctype); import_export_template (ctype);
import_export_vtable (vars, ctype);
if (CLASSTYPE_INTERFACE_UNKNOWN (ctype)) if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype))
{ {
tree method; tree method;
for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE; for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
...@@ -2520,13 +2555,13 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2520,13 +2555,13 @@ finish_prevtable_vardecl (prev, vars)
SET_CLASSTYPE_INTERFACE_KNOWN (ctype); SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method); CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method); CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
TREE_PUBLIC (vars) = 1;
DECL_EXTERNAL (vars) = DECL_EXTERNAL (method);
break; break;
} }
} }
} }
import_export_vtable (vars, ctype, 1);
if (write_virtuals >= 0 if (write_virtuals >= 0
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
{ {
...@@ -2549,9 +2584,8 @@ finish_vtable_vardecl (prev, vars) ...@@ -2549,9 +2584,8 @@ finish_vtable_vardecl (prev, vars)
{ {
tree ctype = DECL_CONTEXT (vars); tree ctype = DECL_CONTEXT (vars);
import_export_template (ctype); import_export_template (ctype);
import_export_vtable (vars, ctype);
if (CLASSTYPE_INTERFACE_UNKNOWN (ctype)) if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype))
{ {
tree method; tree method;
for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE; for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
...@@ -2563,8 +2597,6 @@ finish_vtable_vardecl (prev, vars) ...@@ -2563,8 +2597,6 @@ finish_vtable_vardecl (prev, vars)
SET_CLASSTYPE_INTERFACE_KNOWN (ctype); SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method); CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method); CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
TREE_PUBLIC (vars) = 1;
DECL_EXTERNAL (vars) = DECL_EXTERNAL (method);
if (flag_rtti) if (flag_rtti)
cp_warning ("compiler error: rtti entry for `%T' decided too late", ctype); cp_warning ("compiler error: rtti entry for `%T' decided too late", ctype);
break; break;
...@@ -2572,6 +2604,8 @@ finish_vtable_vardecl (prev, vars) ...@@ -2572,6 +2604,8 @@ finish_vtable_vardecl (prev, vars)
} }
} }
import_export_vtable (vars, ctype, 1);
if (write_virtuals >= 0 if (write_virtuals >= 0
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
{ {
...@@ -2612,7 +2646,7 @@ finish_vtable_vardecl (prev, vars) ...@@ -2612,7 +2646,7 @@ finish_vtable_vardecl (prev, vars)
rest_of_decl_compilation (vars, NULL_PTR, 1, 1); rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
} }
else if (TREE_USED (vars) && flag_vtable_thunks) else if (TREE_USED (vars))
assemble_external (vars); assemble_external (vars);
/* We know that PREV must be non-zero here. */ /* We know that PREV must be non-zero here. */
TREE_CHAIN (prev) = TREE_CHAIN (vars); TREE_CHAIN (prev) = TREE_CHAIN (vars);
...@@ -3230,8 +3264,11 @@ tree ...@@ -3230,8 +3264,11 @@ tree
reparse_decl_as_expr (type, decl) reparse_decl_as_expr (type, decl)
tree type, decl; tree type, decl;
{ {
decl = build_tree_list (NULL_TREE, reparse_decl_as_expr1 (decl)); decl = reparse_decl_as_expr1 (decl);
return build_functional_cast (type, decl); if (type)
return build_functional_cast (type, build_tree_list (NULL_TREE, decl));
else
return decl;
} }
/* This is something of the form `int (*a)' that has turned out to be a /* This is something of the form `int (*a)' that has turned out to be a
......
...@@ -730,8 +730,7 @@ expand_virtual_init (binfo, decl) ...@@ -730,8 +730,7 @@ expand_virtual_init (binfo, decl)
vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type)); vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type));
vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0); vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0);
vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo)); vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo));
if (!flag_vtable_thunks) assemble_external (vtbl);
assemble_external (vtbl);
TREE_USED (vtbl) = 1; TREE_USED (vtbl) = 1;
vtbl = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl); vtbl = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl);
decl = convert_pointer_to_real (vtype_binfo, decl); decl = convert_pointer_to_real (vtype_binfo, decl);
...@@ -3093,6 +3092,7 @@ build_new (placement, decl, init, use_global_new) ...@@ -3093,6 +3092,7 @@ build_new (placement, decl, init, use_global_new)
rval = build (COMPOUND_EXPR, TREE_TYPE (rval), rval = build (COMPOUND_EXPR, TREE_TYPE (rval),
build_modify_expr (deref, NOP_EXPR, init), build_modify_expr (deref, NOP_EXPR, init),
rval); rval);
TREE_NO_UNUSED_WARNING (rval) = 1;
TREE_SIDE_EFFECTS (rval) = 1; TREE_SIDE_EFFECTS (rval) = 1;
TREE_CALLS_NEW (rval) = 1; TREE_CALLS_NEW (rval) = 1;
} }
......
...@@ -205,7 +205,7 @@ empty_parms () ...@@ -205,7 +205,7 @@ empty_parms ()
%type <ttype> declmods typespec typespecqual_reserved %type <ttype> declmods typespec typespecqual_reserved
%type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
%type <itype> initdecls notype_initdecls initdcl /* C++ modification */ %type <itype> initdecls notype_initdecls initdcl /* C++ modification */
%type <ttype> init initlist maybeasm %type <ttype> init initlist maybeasm maybe_init
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib %type <ttype> maybe_attribute attributes attribute attribute_list attrib
%type <ttype> any_word %type <ttype> any_word
...@@ -244,7 +244,7 @@ empty_parms () ...@@ -244,7 +244,7 @@ empty_parms ()
%type <ttype> class_head base_class_list %type <ttype> class_head base_class_list
%type <itype> base_class_access_list %type <itype> base_class_access_list
%type <ttype> base_class maybe_base_class_list base_class.1 %type <ttype> base_class maybe_base_class_list base_class.1
%type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers %type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
%type <ttype> component_declarator0 %type <ttype> component_declarator0
%type <ttype> forhead.1 operator_name %type <ttype> forhead.1 operator_name
%type <ttype> object aggr %type <ttype> object aggr
...@@ -495,7 +495,7 @@ template_def: ...@@ -495,7 +495,7 @@ template_def:
/* declare $2 as template name with $1 parm list */ /* declare $2 as template name with $1 parm list */
} }
| template_header /* notype_initdcl0 ';' */ | template_header /* notype_initdcl0 ';' */
notype_declarator maybe_raises maybeasm maybe_attribute notype_declarator exception_specification_opt maybeasm maybe_attribute
fn_tmpl_end fn_tmpl_end
{ {
tree d; tree d;
...@@ -512,7 +512,7 @@ template_def: ...@@ -512,7 +512,7 @@ template_def:
resume_momentary (momentary); resume_momentary (momentary);
} }
| template_header typed_declspecs /*initdcl0*/ | template_header typed_declspecs /*initdcl0*/
declarator maybe_raises maybeasm maybe_attribute declarator exception_specification_opt maybeasm maybe_attribute
fn_tmpl_end fn_tmpl_end
{ {
tree d; tree d;
...@@ -649,17 +649,17 @@ fndef: ...@@ -649,17 +649,17 @@ fndef:
; ;
fn.def1: fn.def1:
typed_declspecs declarator maybe_raises typed_declspecs declarator exception_specification_opt
{ if (! start_function ($$, $2, $3, 0)) { if (! start_function ($$, $2, $3, 0))
YYERROR1; YYERROR1;
reinit_parse_for_function (); reinit_parse_for_function ();
$$ = NULL_TREE; } $$ = NULL_TREE; }
| declmods notype_declarator maybe_raises | declmods notype_declarator exception_specification_opt
{ if (! start_function ($$, $2, $3, 0)) { if (! start_function ($$, $2, $3, 0))
YYERROR1; YYERROR1;
reinit_parse_for_function (); reinit_parse_for_function ();
$$ = NULL_TREE; } $$ = NULL_TREE; }
| notype_declarator maybe_raises | notype_declarator exception_specification_opt
{ if (! start_function (NULL_TREE, $$, $2, 0)) { if (! start_function (NULL_TREE, $$, $2, 0))
YYERROR1; YYERROR1;
reinit_parse_for_function (); reinit_parse_for_function ();
...@@ -672,7 +672,7 @@ fn.def1: ...@@ -672,7 +672,7 @@ fn.def1:
/* more C++ complexity. See component_decl for a comment on the /* more C++ complexity. See component_decl for a comment on the
reduce/reduce conflict introduced by these rules. */ reduce/reduce conflict introduced by these rules. */
fn.def2: fn.def2:
typed_declspecs '(' parmlist ')' type_quals maybe_raises typed_declspecs '(' parmlist ')' type_quals exception_specification_opt
{ {
$$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5); $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
$$ = start_method (TREE_CHAIN ($1), $$, $6); $$ = start_method (TREE_CHAIN ($1), $$, $6);
...@@ -682,18 +682,18 @@ fn.def2: ...@@ -682,18 +682,18 @@ fn.def2:
if (yychar == YYEMPTY) if (yychar == YYEMPTY)
yychar = YYLEX; yychar = YYLEX;
reinit_parse_for_method (yychar, $$); } reinit_parse_for_method (yychar, $$); }
| typed_declspecs LEFT_RIGHT type_quals maybe_raises | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt
{ {
$$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
empty_parms (), $3); empty_parms (), $3);
$$ = start_method (TREE_CHAIN ($1), $$, $4); $$ = start_method (TREE_CHAIN ($1), $$, $4);
goto rest_of_mdef; goto rest_of_mdef;
} }
| typed_declspecs declarator maybe_raises | typed_declspecs declarator exception_specification_opt
{ $$ = start_method ($$, $2, $3); goto rest_of_mdef; } { $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
| declmods notype_declarator maybe_raises | declmods notype_declarator exception_specification_opt
{ $$ = start_method ($$, $2, $3); goto rest_of_mdef; } { $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
| notype_declarator maybe_raises | notype_declarator exception_specification_opt
{ $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; } { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
; ;
...@@ -705,10 +705,8 @@ return_id: RETURN IDENTIFIER ...@@ -705,10 +705,8 @@ return_id: RETURN IDENTIFIER
} }
; ;
return_init: return_id return_init: return_id maybe_init
{ store_return_init ($<ttype>$, NULL_TREE); } { store_return_init ($<ttype>$, $2); }
| return_id '=' init
{ store_return_init ($<ttype>$, $3); }
| return_id '(' nonnull_exprlist ')' | return_id '(' nonnull_exprlist ')'
{ store_return_init ($<ttype>$, $3); } { store_return_init ($<ttype>$, $3); }
| return_id LEFT_RIGHT | return_id LEFT_RIGHT
...@@ -962,7 +960,7 @@ xcond: ...@@ -962,7 +960,7 @@ xcond:
; ;
condition: condition:
type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '=' type_specifier_seq declarator exception_specification_opt maybeasm maybe_attribute '='
{ { { {
tree d; tree d;
for (d = getdecls (); d; d = TREE_CHAIN (d)) for (d = getdecls (); d; d = TREE_CHAIN (d))
...@@ -1334,12 +1332,21 @@ primary: ...@@ -1334,12 +1332,21 @@ primary:
| string | string
{ $$ = combine_strings ($$); } { $$ = combine_strings ($$); }
| '(' expr ')' | '(' expr ')'
{ char class = TREE_CODE_CLASS (TREE_CODE ($2)); { char class;
$$ = $2;
class = TREE_CODE_CLASS (TREE_CODE ($$));
if (class == 'e' || class == '1'
|| class == '2' || class == '<')
/* This inhibits warnings in truthvalue_conversion. */
C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
| '(' expr_or_declarator ')'
{ char class;
$$ = reparse_decl_as_expr (NULL_TREE, $2);
class = TREE_CODE_CLASS (TREE_CODE ($$));
if (class == 'e' || class == '1' if (class == 'e' || class == '1'
|| class == '2' || class == '<') || class == '2' || class == '<')
/* This inhibits warnings in truthvalue_conversion. */ /* This inhibits warnings in truthvalue_conversion. */
C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK); C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
$$ = $2; }
| '(' error ')' | '(' error ')'
{ $$ = error_mark_node; } { $$ = error_mark_node; }
| '(' | '('
...@@ -1948,7 +1955,7 @@ maybeasm: ...@@ -1948,7 +1955,7 @@ maybeasm:
; ;
initdcl0: initdcl0:
declarator maybe_raises maybeasm maybe_attribute '=' declarator exception_specification_opt maybeasm maybe_attribute '='
{ current_declspecs = $<ttype>0; { current_declspecs = $<ttype>0;
if (TREE_CODE (current_declspecs) != TREE_LIST) if (TREE_CODE (current_declspecs) != TREE_LIST)
current_declspecs = get_decl_list (current_declspecs); current_declspecs = get_decl_list (current_declspecs);
...@@ -1966,7 +1973,7 @@ initdcl0: ...@@ -1966,7 +1973,7 @@ initdcl0:
/* Note how the declaration of the variable is in effect while its init is parsed! */ /* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING);
$$ = $<itype>5; } $$ = $<itype>5; }
| declarator maybe_raises maybeasm maybe_attribute | declarator exception_specification_opt maybeasm maybe_attribute
{ tree d; { tree d;
current_declspecs = $<ttype>0; current_declspecs = $<ttype>0;
if (TREE_CODE (current_declspecs) != TREE_LIST) if (TREE_CODE (current_declspecs) != TREE_LIST)
...@@ -1985,20 +1992,20 @@ initdcl0: ...@@ -1985,20 +1992,20 @@ initdcl0:
; ;
initdcl: initdcl:
declarator maybe_raises maybeasm maybe_attribute '=' declarator exception_specification_opt maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
cplus_decl_attributes ($<ttype>$, $4); } cplus_decl_attributes ($<ttype>$, $4); }
init init
/* Note how the declaration of the variable is in effect while its init is parsed! */ /* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); } { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); }
| declarator maybe_raises maybeasm maybe_attribute | declarator exception_specification_opt maybeasm maybe_attribute
{ $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2); { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2);
cplus_decl_attributes ($<ttype>$, $4); cplus_decl_attributes ($<ttype>$, $4);
finish_decl ($<ttype>$, NULL_TREE, $3, 0, 0); } finish_decl ($<ttype>$, NULL_TREE, $3, 0, 0); }
; ;
notype_initdcl0: notype_initdcl0:
notype_declarator maybe_raises maybeasm maybe_attribute '=' notype_declarator exception_specification_opt maybeasm maybe_attribute '='
{ current_declspecs = $<ttype>0; { current_declspecs = $<ttype>0;
$<itype>5 = suspend_momentary (); $<itype>5 = suspend_momentary ();
$<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
...@@ -2007,7 +2014,7 @@ notype_initdcl0: ...@@ -2007,7 +2014,7 @@ notype_initdcl0:
/* Note how the declaration of the variable is in effect while its init is parsed! */ /* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING);
$$ = $<itype>5; } $$ = $<itype>5; }
| notype_declarator maybe_raises maybeasm maybe_attribute | notype_declarator exception_specification_opt maybeasm maybe_attribute
{ tree d; { tree d;
current_declspecs = $<ttype>0; current_declspecs = $<ttype>0;
$$ = suspend_momentary (); $$ = suspend_momentary ();
...@@ -2017,7 +2024,7 @@ notype_initdcl0: ...@@ -2017,7 +2024,7 @@ notype_initdcl0:
; ;
nomods_initdcl0: nomods_initdcl0:
notype_declarator maybe_raises maybeasm maybe_attribute '=' notype_declarator exception_specification_opt maybeasm maybe_attribute '='
{ current_declspecs = NULL_TREE; { current_declspecs = NULL_TREE;
$<itype>5 = suspend_momentary (); $<itype>5 = suspend_momentary ();
$<ttype>$ = start_decl ($1, current_declspecs, 1, $2); $<ttype>$ = start_decl ($1, current_declspecs, 1, $2);
...@@ -2026,7 +2033,7 @@ nomods_initdcl0: ...@@ -2026,7 +2033,7 @@ nomods_initdcl0:
/* Note how the declaration of the variable is in effect while its init is parsed! */ /* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING);
$$ = $<itype>5; } $$ = $<itype>5; }
| notype_declarator maybe_raises maybeasm maybe_attribute | notype_declarator exception_specification_opt maybeasm maybe_attribute
{ tree d; { tree d;
current_declspecs = NULL_TREE; current_declspecs = NULL_TREE;
$$ = suspend_momentary (); $$ = suspend_momentary ();
...@@ -2094,6 +2101,12 @@ identifiers_or_typenames: ...@@ -2094,6 +2101,12 @@ identifiers_or_typenames:
{ $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
; ;
maybe_init:
%prec EMPTY /* empty */
{ $$ = NULL_TREE; }
| '=' init
{ $$ = $2; }
init: init:
expr_no_commas %prec '=' expr_no_commas %prec '='
| '{' '}' | '{' '}'
...@@ -2593,8 +2606,8 @@ component_decl_1: ...@@ -2593,8 +2606,8 @@ component_decl_1:
{ {
$$ = grok_x_components ($$, $2); $$ = grok_x_components ($$, $2);
} }
| notype_declarator maybe_raises maybeasm maybe_attribute | notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3); { $$ = grokfield ($$, NULL_TREE, $2, $5, $3);
cplus_decl_attributes ($$, $4); } cplus_decl_attributes ($$, $4); }
| ':' expr_no_commas | ':' expr_no_commas
{ $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
...@@ -2609,16 +2622,16 @@ component_decl_1: ...@@ -2609,16 +2622,16 @@ component_decl_1:
should "A::foo" be declared as a function or "A::bar" as a data should "A::foo" be declared as a function or "A::bar" as a data
member? In other words, is "bar" an after_type_declarator or a member? In other words, is "bar" an after_type_declarator or a
parmlist? */ parmlist? */
| typed_declspecs '(' parmlist ')' type_quals | typed_declspecs '(' parmlist ')' type_quals exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
$3, $5); $3, $5);
$$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, $$ = grokfield ($$, TREE_CHAIN ($1), $6, $9, $7);
NULL_TREE); } cplus_decl_attributes ($$, $8); }
| typed_declspecs LEFT_RIGHT type_quals | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
empty_parms (), $3); empty_parms (), $3);
$$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, $$ = grokfield ($$, TREE_CHAIN ($1), $4, $7, $5);
NULL_TREE); } cplus_decl_attributes ($$, $6); }
| using_decl | using_decl
; ;
...@@ -2664,13 +2677,9 @@ component_declarator: ...@@ -2664,13 +2677,9 @@ component_declarator:
; ;
after_type_component_declarator0: after_type_component_declarator0:
after_type_declarator maybe_raises maybeasm maybe_attribute after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ current_declspecs = $<ttype>0;
$$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
cplus_decl_attributes ($$, $4); }
| after_type_declarator maybe_raises maybeasm maybe_attribute '=' init
{ current_declspecs = $<ttype>0; { current_declspecs = $<ttype>0;
$$ = grokfield ($$, current_declspecs, $2, $6, $3); $$ = grokfield ($$, current_declspecs, $2, $5, $3);
cplus_decl_attributes ($$, $4); } cplus_decl_attributes ($$, $4); }
| TYPENAME ':' expr_no_commas maybe_attribute | TYPENAME ':' expr_no_commas maybe_attribute
{ current_declspecs = $<ttype>0; { current_declspecs = $<ttype>0;
...@@ -2679,13 +2688,9 @@ after_type_component_declarator0: ...@@ -2679,13 +2688,9 @@ after_type_component_declarator0:
; ;
notype_component_declarator0: notype_component_declarator0:
notype_declarator maybe_raises maybeasm maybe_attribute notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ current_declspecs = $<ttype>0;
$$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
cplus_decl_attributes ($$, $4); }
| notype_declarator maybe_raises maybeasm maybe_attribute '=' init
{ current_declspecs = $<ttype>0; { current_declspecs = $<ttype>0;
$$ = grokfield ($$, current_declspecs, $2, $6, $3); $$ = grokfield ($$, current_declspecs, $2, $5, $3);
cplus_decl_attributes ($$, $4); } cplus_decl_attributes ($$, $4); }
| IDENTIFIER ':' expr_no_commas maybe_attribute | IDENTIFIER ':' expr_no_commas maybe_attribute
{ current_declspecs = $<ttype>0; { current_declspecs = $<ttype>0;
...@@ -2698,11 +2703,8 @@ notype_component_declarator0: ...@@ -2698,11 +2703,8 @@ notype_component_declarator0:
; ;
after_type_component_declarator: after_type_component_declarator:
after_type_declarator maybe_raises maybeasm maybe_attribute after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); { $$ = grokfield ($$, current_declspecs, $2, $5, $3);
cplus_decl_attributes ($$, $4); }
| after_type_declarator maybe_raises maybeasm maybe_attribute '=' init
{ $$ = grokfield ($$, current_declspecs, $2, $6, $3);
cplus_decl_attributes ($$, $4); } cplus_decl_attributes ($$, $4); }
| TYPENAME ':' expr_no_commas maybe_attribute | TYPENAME ':' expr_no_commas maybe_attribute
{ $$ = grokbitfield ($$, current_declspecs, $3); { $$ = grokbitfield ($$, current_declspecs, $3);
...@@ -2710,11 +2712,8 @@ after_type_component_declarator: ...@@ -2710,11 +2712,8 @@ after_type_component_declarator:
; ;
notype_component_declarator: notype_component_declarator:
notype_declarator maybe_raises maybeasm maybe_attribute notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); { $$ = grokfield ($$, current_declspecs, $2, $5, $3);
cplus_decl_attributes ($$, $4); }
| notype_declarator maybe_raises maybeasm maybe_attribute '=' init
{ $$ = grokfield ($$, current_declspecs, $2, $6, $3);
cplus_decl_attributes ($$, $4); } cplus_decl_attributes ($$, $4); }
| IDENTIFIER ':' expr_no_commas maybe_attribute | IDENTIFIER ':' expr_no_commas maybe_attribute
{ $$ = grokbitfield ($$, current_declspecs, $3); { $$ = grokbitfield ($$, current_declspecs, $3);
...@@ -3702,10 +3701,8 @@ named_parm: ...@@ -3702,10 +3701,8 @@ named_parm:
; ;
full_parm: full_parm:
parm parm maybe_init
{ $$ = build_tree_list (NULL_TREE, $$); } { $$ = build_tree_list ($2, $$); }
| parm '=' init
{ $$ = build_tree_list ($3, $$); }
; ;
parm: parm:
...@@ -3748,7 +3745,7 @@ bad_parm: ...@@ -3748,7 +3745,7 @@ bad_parm:
} }
; ;
maybe_raises: exception_specification_opt:
%prec EMPTY /* empty */ %prec EMPTY /* empty */
{ $$ = NULL_TREE; } { $$ = NULL_TREE; }
| THROW '(' ansi_raise_identifiers ')' %prec EMPTY | THROW '(' ansi_raise_identifiers ')' %prec EMPTY
......
...@@ -2723,8 +2723,9 @@ build_binary_op (code, arg1, arg2, convert_p) ...@@ -2723,8 +2723,9 @@ build_binary_op (code, arg1, arg2, convert_p)
if (convert_p) if (convert_p)
{ {
args[0] = default_conversion (args[0]); tree args_save [2];
args[1] = default_conversion (args[1]); args[0] = args_save [0] = default_conversion (args[0]);
args[1] = args_save [1] = default_conversion (args[1]);
if (type_unknown_p (args[0])) if (type_unknown_p (args[0]))
{ {
...@@ -2780,6 +2781,11 @@ build_binary_op (code, arg1, arg2, convert_p) ...@@ -2780,6 +2781,11 @@ build_binary_op (code, arg1, arg2, convert_p)
error ("ambiguous pointer conversion"); error ("ambiguous pointer conversion");
args[convert_index] = try; args[convert_index] = try;
} }
if (args[0] == args_save[0])
args[0] = arg1;
if (args[1] == args_save[1])
args[1] = arg2;
} }
return build_binary_op_nodefault (code, args[0], args[1], code); return build_binary_op_nodefault (code, args[0], args[1], code);
} }
...@@ -3457,19 +3463,34 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3457,19 +3463,34 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
if (short_compare && extra_warnings) if (short_compare && extra_warnings)
{ {
int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
tree comp_type = TREE_TYPE (op0);
int unsignedp0, unsignedp1; int unsignedp0, unsignedp1;
tree primop0 = get_narrower (op0, &unsignedp0); tree primop0 = get_narrower (op0, &unsignedp0);
tree primop1 = get_narrower (op1, &unsignedp1); tree primop1 = get_narrower (op1, &unsignedp1);
/* Warn if signed and unsigned are being compared in a size larger /* Give warnings for comparisons between signed and unsigned
than their original size, as this will always fail. */ quantities that may fail. Do not warn if the signed quantity
is an unsuffixed integer literal (or some static constant
if (unsignedp0 != unsignedp1 expression involving such literals) and it is positive.
&& (TYPE_PRECISION (TREE_TYPE (primop0)) Do not warn if the comparison is being done in a signed type,
< TYPE_PRECISION (result_type)) since the signed type will only be chosen if it can represent
&& (TYPE_PRECISION (TREE_TYPE (primop1)) all the values of the unsigned type. */
< TYPE_PRECISION (result_type))) /* Do the checking based on the original operand trees, so that
warning ("comparison between promoted unsigned and signed"); casts will be considered, but default promotions won't be. */
if (TREE_UNSIGNED (comp_type)
&& ((op0_signed
&& (TREE_CODE (op0) != INTEGER_CST
|| (TREE_CODE (op0) == INTEGER_CST
&& INT_CST_LT (op0, integer_zero_node))))
|| (op1_signed
&& (TREE_CODE (op1) != INTEGER_CST
|| (TREE_CODE (op1) == INTEGER_CST
&& INT_CST_LT (op1, integer_zero_node))))))
warning ("comparison between signed and unsigned");
/* Warn if two unsigned values are being compared in a size /* Warn if two unsigned values are being compared in a size
larger than their original size, and one (and only one) is the larger than their original size, and one (and only one) is the
...@@ -3509,7 +3530,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3509,7 +3530,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
} }
bits = TYPE_PRECISION (TREE_TYPE (primop)); bits = TYPE_PRECISION (TREE_TYPE (primop));
if (bits < TYPE_PRECISION (result_type) if (bits < TYPE_PRECISION (comp_type)
&& bits < HOST_BITS_PER_LONG && unsignedp) && bits < HOST_BITS_PER_LONG && unsignedp)
{ {
mask = (~ (HOST_WIDE_INT) 0) << bits; mask = (~ (HOST_WIDE_INT) 0) << bits;
...@@ -3519,9 +3540,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) ...@@ -3519,9 +3540,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
} }
else if (unsignedp0 && unsignedp1 else if (unsignedp0 && unsignedp1
&& (TYPE_PRECISION (TREE_TYPE (primop0)) && (TYPE_PRECISION (TREE_TYPE (primop0))
< TYPE_PRECISION (result_type)) < TYPE_PRECISION (comp_type))
&& (TYPE_PRECISION (TREE_TYPE (primop1)) && (TYPE_PRECISION (TREE_TYPE (primop1))
< TYPE_PRECISION (result_type))) < TYPE_PRECISION (comp_type)))
warning ("comparison of promoted ~unsigned with unsigned"); warning ("comparison of promoted ~unsigned with unsigned");
} }
} }
...@@ -4120,15 +4141,6 @@ build_unary_op (code, xarg, noconvert) ...@@ -4120,15 +4141,6 @@ build_unary_op (code, xarg, noconvert)
TREE_OPERAND (arg, 1), 1); TREE_OPERAND (arg, 1), 1);
} }
/* For &(++foo), we are really taking the address of the variable
being acted upon by the increment/decrement operator. ARM $5.3.1
However, according to ARM $5.2.5, we don't allow postfix ++ and
--, since the prefix operators return lvalues, but the postfix
operators do not. */
if (TREE_CODE (arg) == PREINCREMENT_EXPR
|| TREE_CODE (arg) == PREDECREMENT_EXPR)
arg = TREE_OPERAND (arg, 0);
/* Uninstantiated types are all functions. Taking the /* Uninstantiated types are all functions. Taking the
address of a function is a no-op, so just return the address of a function is a no-op, so just return the
argument. */ argument. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment