cp-tree.h (ansi_opname): Make it a macro.

2000-05-27  Alex Samuel    <samuel@codesourcery.com>
	    Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (ansi_opname): Make it a macro.
	(ansi_assopname): Likewise.
	(struct lang_decl_flags): Add assignment_operator_p.
	(struct lang_decl): Add operator_code.
	(DECL_VTT_PARM): Adjust.
	(DECL_OVERLOADED_OPERATOR_P): Return the operator_code for an
	overloaded operator.
	(SET_OVERLOADED_OPERATOR_CODE): New macro.
	(DECL_ASSIGNMENT_OPERATOR_P): New macro.
	(DECL_ARRAY_DELETE_OPERATOR_P): Adjust.
	(opname_tab): Remove.
	(assignop_tab): Likewise.
	(operator_name_info_t): New type.
	(operator_name_info): New variable.
	(assignment_operator_name_info): Likewise.
	(build_cp_library_fn): Remove declaration.
	(push_cp_library_fn): Likewise.
	(operator_name_string): Likewise.
	(build_decl_overload): Likewise.
	* call.c (print_z_candidates): Simplify.
	(build_object_call): Adjust usage of ansi_opname.  Use
	DECL_OVERLOADED_OPERATOR_P.
	(op_error): Adjust operator name lookup.
	(build_conditional_expr): Adjust usage of ansi_opname.
	(build_new_op): Likewise.
	(build_op_delete_call): Likewise.
	(build_over_call): Likewise.
	(joust): Use DECL_OVERLOADED_OPERATOR_P.
	* decl.c (duplicate_decls): Copy operator_code.
	(init_decl_processing): Adjust parameters to push_cp_library_fn.
	(builtin_function): Adjust parameters to build_library_fn_1.
	(build_library_fn_1): Accept an overloaded operator code.
	(build_library_fn): Pass ERROR_MARK.
	(build_cp_library_fn): Accept an overloaded operator code.
	(push_cp_library_fn): Likewise.
	(grokfndecl): Tweak.
	(grokdeclarator): Simplify code to compute names of overloaded
	operators.  Adjust use of ansi_opname.
	(ambi_op_p): Work on tree_codes, not identifiers.
	(unary_op_p): Likewise.
	(grok_op_properties): Likewise.
	(start_function): Use DECL_OVERLOADED_OPERATOR_P.
	(lang_mark_tree): Don't try to mark the operator_code.
	* decl2.c (grok_function_init): Use DECL_OVERLOADED_OPERATOR_P.
	* error.c (dump_decl): Remove special handling for operator
	names.
	(dump_function_name): Likewise.
	(dump_expr): Adjust name lookup of operators.
	(op_to_string): Simplify.
	(assop_to_string): Likewise.
	* init.c (build_new_1): Adjust use of ansi_opname.
	* lex.c (opname_tab): Remove.
	(assignop_tab): Likewise.
	(ansi_opname): Likewise.
	(ansi_assopname): Likewise.
	(operator_name_string): Likewise.
	(reinit_lang_specific): Likewise.
	(operator_name_info): New variable.
	(assignment_operator_name_info): Likewise.
	(init_operators): New function.
	(init_parse): Use it.
	(do_identifier): Adjust use of ansi_opname.
	* method.c (mangle_expression): Don't use ansi_opname for
	mangling.
	(build_decl_overload_real): Use DECL_OVERLOADED_OPERATOR_P.
	(build_decl_overload): Remove.
	(build_typename_overload): Use OPERATOR_TYPENAME_FORMAT directly.
	(do_build_assign_ref): Adjust use of ansi_opname.
	(synthesize_method): Likewise.
	(implicitly_declare_fn): Likewise.
	* operators.def: New file.
	* parse.y (operator): Adjust use of ansi_opname.
	* pt.c (tsubst_decl): Use IDENTIFIER_OPNAME_P.
	(set_mangled_name_for_template_decl): Don't play games with
	current_namespace.
	(special_function_p): Adjust use of ansi_opname.
	* typeck.c (check_return_expr): Likewise.
	* Make-lang.in (cc1plus): Depend on operators.def.
	* Makefile.in (lex.o): Likewise.
	(decl.o): Likewise.

Co-Authored-By: Mark Mitchell <mark@codesourcery.com>

From-SVN: r34223
This commit is contained in:
Alex Samuel 2000-05-28 02:58:19 +00:00 committed by Mark Mitchell
parent 4f1c5cce90
commit 596ea4e574
18 changed files with 749 additions and 603 deletions

View File

@ -1,3 +1,87 @@
2000-05-27 Alex Samuel <samuel@codesourcery.com>
Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (ansi_opname): Make it a macro.
(ansi_assopname): Likewise.
(struct lang_decl_flags): Add assignment_operator_p.
(struct lang_decl): Add operator_code.
(DECL_VTT_PARM): Adjust.
(DECL_OVERLOADED_OPERATOR_P): Return the operator_code for an
overloaded operator.
(SET_OVERLOADED_OPERATOR_CODE): New macro.
(DECL_ASSIGNMENT_OPERATOR_P): New macro.
(DECL_ARRAY_DELETE_OPERATOR_P): Adjust.
(opname_tab): Remove.
(assignop_tab): Likewise.
(operator_name_info_t): New type.
(operator_name_info): New variable.
(assignment_operator_name_info): Likewise.
(build_cp_library_fn): Remove declaration.
(push_cp_library_fn): Likewise.
(operator_name_string): Likewise.
(build_decl_overload): Likewise.
* call.c (print_z_candidates): Simplify.
(build_object_call): Adjust usage of ansi_opname. Use
DECL_OVERLOADED_OPERATOR_P.
(op_error): Adjust operator name lookup.
(build_conditional_expr): Adjust usage of ansi_opname.
(build_new_op): Likewise.
(build_op_delete_call): Likewise.
(build_over_call): Likewise.
(joust): Use DECL_OVERLOADED_OPERATOR_P.
* decl.c (duplicate_decls): Copy operator_code.
(init_decl_processing): Adjust parameters to push_cp_library_fn.
(builtin_function): Adjust parameters to build_library_fn_1.
(build_library_fn_1): Accept an overloaded operator code.
(build_library_fn): Pass ERROR_MARK.
(build_cp_library_fn): Accept an overloaded operator code.
(push_cp_library_fn): Likewise.
(grokfndecl): Tweak.
(grokdeclarator): Simplify code to compute names of overloaded
operators. Adjust use of ansi_opname.
(ambi_op_p): Work on tree_codes, not identifiers.
(unary_op_p): Likewise.
(grok_op_properties): Likewise.
(start_function): Use DECL_OVERLOADED_OPERATOR_P.
(lang_mark_tree): Don't try to mark the operator_code.
* decl2.c (grok_function_init): Use DECL_OVERLOADED_OPERATOR_P.
* error.c (dump_decl): Remove special handling for operator
names.
(dump_function_name): Likewise.
(dump_expr): Adjust name lookup of operators.
(op_to_string): Simplify.
(assop_to_string): Likewise.
* init.c (build_new_1): Adjust use of ansi_opname.
* lex.c (opname_tab): Remove.
(assignop_tab): Likewise.
(ansi_opname): Likewise.
(ansi_assopname): Likewise.
(operator_name_string): Likewise.
(reinit_lang_specific): Likewise.
(operator_name_info): New variable.
(assignment_operator_name_info): Likewise.
(init_operators): New function.
(init_parse): Use it.
(do_identifier): Adjust use of ansi_opname.
* method.c (mangle_expression): Don't use ansi_opname for
mangling.
(build_decl_overload_real): Use DECL_OVERLOADED_OPERATOR_P.
(build_decl_overload): Remove.
(build_typename_overload): Use OPERATOR_TYPENAME_FORMAT directly.
(do_build_assign_ref): Adjust use of ansi_opname.
(synthesize_method): Likewise.
(implicitly_declare_fn): Likewise.
* operators.def: New file.
* parse.y (operator): Adjust use of ansi_opname.
* pt.c (tsubst_decl): Use IDENTIFIER_OPNAME_P.
(set_mangled_name_for_template_decl): Don't play games with
current_namespace.
(special_function_p): Adjust use of ansi_opname.
* typeck.c (check_return_expr): Likewise.
* Make-lang.in (cc1plus): Depend on operators.def.
* Makefile.in (lex.o): Likewise.
(decl.o): Likewise.
2000-05-27 Zack Weinberg <zack@wolery.cumb.org>
* Make-lang.in (cplib2.ready): Eradicate.

View File

@ -123,7 +123,8 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/class.c $(srcdir)/cp/cp-tree.def \
cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o \
c-pragma.o $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def \
$(srcdir)/cp/gxx.gperf $(srcdir)/cp/cfns.gperf hash.o
$(srcdir)/cp/gxx.gperf $(srcdir)/cp/cfns.gperf hash.o \
$(srcdir)/cp/operators.def
cd cp; $(MAKE) $(LANG_FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext)
#
# Build hooks:

View File

@ -254,11 +254,11 @@ lex.o : lex.c $(CXX_TREE_H) \
$(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h \
$(srcdir)/../c-pragma.h $(srcdir)/../toplev.h \
$(srcdir)/../output.h $(srcdir)/../mbchar.h $(GGC_H) \
$(srcdir)/../input.h
$(srcdir)/../input.h operators.def
decl.o : decl.c $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \
$(srcdir)/../except.h $(srcdir)/../toplev.h \
$(srcdir)/../hash.h $(GGC_H) $(RTL_H)
$(srcdir)/../hash.h $(GGC_H) $(RTL_H) operators.def
decl2.o : decl2.c $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../output.h $(srcdir)/../except.h \
$(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h \

View File

@ -2257,7 +2257,7 @@ print_z_candidates (candidates)
{
if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
{
if (candidates->fn == ansi_opname [COND_EXPR])
if (TREE_VEC_LENGTH (candidates->convs) == 3)
cp_error ("%s %D(%T, %T, %T) <builtin>", str, candidates->fn,
TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)),
TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)),
@ -2609,7 +2609,7 @@ build_object_call (obj, args)
return error_mark_node;
}
fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 1);
fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname (CALL_EXPR), 1);
if (fns == error_mark_node)
return error_mark_node;
@ -2689,7 +2689,7 @@ build_object_call (obj, args)
function, we must be careful not to unconditionally look at
DECL_NAME here. */
if (TREE_CODE (cand->fn) == FUNCTION_DECL
&& DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
&& DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
return build_over_call (cand, mem_args, LOOKUP_NORMAL);
obj = convert_like_with_context
@ -2705,8 +2705,12 @@ op_error (code, code2, arg1, arg2, arg3, problem)
tree arg1, arg2, arg3;
const char *problem;
{
const char * opname
= (code == MODIFY_EXPR ? assignop_tab [code2] : opname_tab [code]);
const char * opname;
if (code == MODIFY_EXPR)
opname = assignment_operator_name_info[code2].name;
else
opname = operator_name_info[code].name;
switch (code)
{
@ -2987,7 +2991,7 @@ build_conditional_expr (arg1, arg2, arg3)
candidates = add_builtin_candidates (candidates,
COND_EXPR,
NOP_EXPR,
ansi_opname[COND_EXPR],
ansi_opname (COND_EXPR),
args,
LOOKUP_NORMAL);
@ -3166,10 +3170,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
{
code2 = TREE_CODE (arg3);
arg3 = NULL_TREE;
fnname = ansi_assopname[code2];
fnname = ansi_assopname (code2);
}
else
fnname = ansi_opname[code];
fnname = ansi_opname (code);
switch (code)
{
@ -3314,7 +3318,8 @@ build_new_op (code, flags, arg1, arg2, arg3)
one, then we fall back to the old way of doing things. */
if (flags & LOOKUP_COMPLAIN)
cp_pedwarn ("no `%D (int)' declared for postfix `%s', trying prefix operator instead",
fnname, opname_tab [code]);
fnname,
operator_name_info[code].name);
if (code == POSTINCREMENT_EXPR)
code = PREINCREMENT_EXPR;
else
@ -3354,7 +3359,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
{
extern int warn_synth;
if (warn_synth
&& fnname == ansi_opname[MODIFY_EXPR]
&& fnname == ansi_assopname (NOP_EXPR)
&& DECL_ARTIFICIAL (cand->fn)
&& candidates->next
&& ! candidates->next->next)
@ -3516,7 +3521,7 @@ build_op_delete_call (code, addr, size, flags, placement)
return error_mark_node;
type = TREE_TYPE (TREE_TYPE (addr));
fnname = ansi_opname[code];
fnname = ansi_opname (code);
if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL))
/* In [class.free]
@ -4137,7 +4142,7 @@ build_over_call (cand, args, flags)
return address;
}
}
else if (DECL_NAME (fn) == ansi_opname[MODIFY_EXPR]
else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
&& copy_args_p (fn)
&& TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
{
@ -5123,7 +5128,7 @@ joust (cand1, cand2, warn)
/* Kludge around broken overloading rules whereby
Integer a, b; test ? a : b; is ambiguous, since there's a builtin
that takes references and another that takes values. */
if (cand1->fn == ansi_opname[COND_EXPR])
if (DECL_OVERLOADED_OPERATOR_P (cand1->fn) == COND_EXPR)
{
tree c1 = TREE_VEC_ELT (cand1->convs, 1);
tree c2 = TREE_VEC_ELT (cand2->convs, 1);

View File

@ -1012,8 +1012,11 @@ extern tree current_function_return_value;
extern tree global_namespace;
extern tree ridpointers[];
extern tree ansi_opname[];
extern tree ansi_assopname[];
#define ansi_opname(CODE) \
(operator_name_info[(int) (CODE)].identifier)
#define ansi_assopname(CODE) \
(assignment_operator_name_info[(int) (CODE)].identifier)
/* Nonzero means `$' can be in an identifier. */
@ -1864,7 +1867,8 @@ struct lang_decl_flags
unsigned global_ctor_p : 1;
unsigned global_dtor_p : 1;
unsigned tinfo_fn_p : 1;
unsigned dummy : 4;
unsigned assignment_operator_p : 1;
unsigned dummy : 3;
tree context;
@ -1903,15 +1907,21 @@ struct lang_decl
/* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION. */
tree cloned_function;
/* In a FUNCTION_DECL, this is VTT_PARM. */
tree vtt_parm;
union
{
tree sorted_fields;
struct pending_inline *pending_inline_info;
struct language_function *saved_language_function;
} u;
union {
/* In an overloaded operator, this is the value of
DECL_OVERLOADED_OPERATOR_P. */
enum tree_code operator_code;
/* In a maybe-in-charge constructor or destructor, this is
DECL_VTT_PARM. */
tree vtt_parm;
} u2;
};
/* Non-zero if NODE is a _DECL with TREE_READONLY set. */
@ -1997,7 +2007,7 @@ struct lang_decl
/* In a maybe-in-charge constructor or destructor, this is the VTT
parameter. It's not actually on the DECL_ARGUMENTS list. */
#define DECL_VTT_PARM(NODE) \
(DECL_LANG_SPECIFIC (NODE)->vtt_parm)
(DECL_LANG_SPECIFIC (NODE)->u2.vtt_parm)
/* If there's a DECL_VTT_PARM, this is a magic variable that indicates
whether or not the VTT parm should be used. In a subobject
@ -2017,9 +2027,24 @@ struct lang_decl
#define DECL_CONV_FN_P(NODE) \
(IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)))
/* Non-zero if NODE is an overloaded operator. */
#define DECL_OVERLOADED_OPERATOR_P(NODE) \
(IDENTIFIER_OPNAME_P (DECL_NAME ((NODE))))
/* Set the overloaded operator code for NODE to CODE. */
#define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
(DECL_LANG_SPECIFIC (NODE)->u2.operator_code = (CODE))
/* If NODE is an overloaded operator, then this returns the TREE_CODE
associcated with the overloaded operator.
DECL_ASSIGNMENT_OPERATOR_P must also be checked to determine
whether or not NODE is an assignment operator. If NODE is not an
overloaded operator, ERROR_MARK is returned. Since the numerical
value of ERROR_MARK is zero, this macro can be used as a predicate
to test whether or not NODE is an overloaded operator. */
#define DECL_OVERLOADED_OPERATOR_P(NODE) \
(IDENTIFIER_OPNAME_P (DECL_NAME ((NODE))) \
? DECL_LANG_SPECIFIC (NODE)->u2.operator_code : ERROR_MARK)
/* Non-zero if NODE is an assignment operator. */
#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.assignment_operator_p)
/* For FUNCTION_DECLs: nonzero means that this function is a
constructor or a destructor with an extra in-charge parameter to
@ -2040,7 +2065,7 @@ struct lang_decl
/* Nonzero if NODE is an overloaded `operator delete[]' function. */
#define DECL_ARRAY_DELETE_OPERATOR_P(NODE) \
(DECL_NAME (NODE) == ansi_opname[(int) VEC_DELETE_EXPR])
(DECL_OVERLOADED_OPERATOR_P (NODE) == VEC_DELETE_EXPR)
/* Nonzero for _DECL means that this decl appears in (or will appear
in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for
@ -3794,10 +3819,22 @@ enum tree_string_flags
};
/* in lex.c */
/* Indexed by TREE_CODE, these tables give C-looking names to
operators represented by TREE_CODES. For example,
opname_tab[(int) MINUS_EXPR] == "-". */
extern const char **opname_tab, **assignop_tab;
typedef struct operator_name_info_t
{
/* The IDENTIFIER_NODE for the operator. */
tree identifier;
/* The name of the operator. */
const char *name;
/* The mangled name of the operator. */
const char *mangled_name;
} operator_name_info_t;
/* A mapping from tree codes to operator name information. */
extern operator_name_info_t operator_name_info[];
/* Similar, but for assignment operators. */
extern operator_name_info_t assignment_operator_name_info[];
/* in call.c */
extern int check_dtor_name PARAMS ((tree, tree));
@ -3959,11 +3996,9 @@ extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *));
extern int lookup_using_namespace PARAMS ((tree, tree, tree, tree, int, tree *));
extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int));
extern tree build_library_fn PARAMS ((tree, tree));
extern tree build_cp_library_fn PARAMS ((tree, tree));
extern tree build_library_fn_ptr PARAMS ((const char *, tree));
extern tree build_cp_library_fn_ptr PARAMS ((const char *, tree));
extern tree push_library_fn PARAMS ((tree, tree));
extern tree push_cp_library_fn PARAMS ((tree, tree));
extern tree push_void_library_fn PARAMS ((tree, tree));
extern tree push_throw_library_fn PARAMS ((tree, tree));
extern void init_decl_processing PARAMS ((void));
@ -4184,7 +4219,6 @@ extern tree make_pointer_declarator PARAMS ((tree, tree));
extern tree make_reference_declarator PARAMS ((tree, tree));
extern tree make_call_declarator PARAMS ((tree, tree, tree, tree));
extern void set_quals_and_spec PARAMS ((tree, tree, tree));
extern const char *operator_name_string PARAMS ((tree));
extern void lang_init PARAMS ((void));
extern void lang_finish PARAMS ((void));
#if 0
@ -4234,7 +4268,6 @@ extern int cp_type_qual_from_rid PARAMS ((tree));
extern void init_method PARAMS ((void));
extern char *build_overload_name PARAMS ((tree, int, int));
extern tree build_static_name PARAMS ((tree, tree));
extern tree build_decl_overload PARAMS ((tree, tree, int));
extern tree build_decl_overload_real PARAMS ((tree, tree, tree, tree,
tree, int));
extern void set_mangled_name_for_decl PARAMS ((tree));

View File

@ -108,8 +108,8 @@ static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN;
static int decl_jump_unsafe PARAMS ((tree));
static void storedecls PARAMS ((tree));
static void require_complete_types_for_parms PARAMS ((tree));
static int ambi_op_p PARAMS ((tree));
static int unary_op_p PARAMS ((tree));
static int ambi_op_p PARAMS ((enum tree_code));
static int unary_op_p PARAMS ((enum tree_code));
static tree store_bindings PARAMS ((tree, tree));
static tree lookup_tag_reverse PARAMS ((tree, tree));
static tree obscure_complex_init PARAMS ((tree, tree));
@ -126,7 +126,7 @@ static void set_identifier_type_value_with_scope
PARAMS ((tree, tree, struct binding_level *));
static void record_builtin_type PARAMS ((enum rid, const char *, tree));
static void record_unknown_type PARAMS ((tree, const char *));
static tree build_library_fn_1 PARAMS ((tree, tree));
static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
int));
@ -186,6 +186,8 @@ static tree cp_make_fname_decl PARAMS ((tree, const char *, int));
static void initialize_predefined_identifiers PARAMS ((void));
static tree check_special_function_return_type
PARAMS ((special_function_kind, tree, tree, tree));
static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void));
@ -3425,7 +3427,7 @@ duplicate_decls (newdecl, olddecl)
DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
DECL_VTT_PARM (newdecl) = DECL_VTT_PARM (olddecl);
DECL_LANG_SPECIFIC (newdecl)->u2 = DECL_LANG_SPECIFIC (olddecl)->u2;
new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;
/* Optionally warn about more than one declaration for the same
@ -6596,11 +6598,10 @@ init_decl_processing ()
newtype = build_exception_variant
(ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
push_cp_library_fn (ansi_opname[(int) NEW_EXPR], newtype);
push_cp_library_fn (ansi_opname[(int) VEC_NEW_EXPR], newtype);
global_delete_fndecl = push_cp_library_fn (ansi_opname[(int) DELETE_EXPR],
deltype);
push_cp_library_fn (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
push_cp_library_fn (NEW_EXPR, newtype);
push_cp_library_fn (VEC_NEW_EXPR, newtype);
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
push_cp_library_fn (VEC_DELETE_EXPR, deltype);
}
abort_fndecl
@ -6756,7 +6757,7 @@ builtin_function (name, type, code, class, libname)
enum built_in_class class;
const char *libname;
{
tree decl = build_library_fn_1 (get_identifier (name), type);
tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = code;
@ -6776,8 +6777,9 @@ builtin_function (name, type, code, class, libname)
function. Not called directly. */
static tree
build_library_fn_1 (name, type)
build_library_fn_1 (name, operator_code, type)
tree name;
enum tree_code operator_code;
tree type;
{
tree fn = build_lang_decl (FUNCTION_DECL, name, type);
@ -6785,6 +6787,7 @@ build_library_fn_1 (name, type)
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
SET_OVERLOADED_OPERATOR_CODE (fn, operator_code);
return fn;
}
@ -6797,19 +6800,20 @@ build_library_fn (name, type)
tree name;
tree type;
{
tree fn = build_library_fn_1 (name, type);
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
make_function_rtl (fn);
return fn;
}
/* Returns the _DECL for a library function with C++ linkage. */
tree
build_cp_library_fn (name, type)
static tree
build_cp_library_fn (name, operator_code, type)
tree name;
enum tree_code operator_code;
tree type;
{
tree fn = build_library_fn_1 (name, type);
tree fn = build_library_fn_1 (name, operator_code, type);
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
set_mangled_name_for_decl (fn);
make_function_rtl (fn);
@ -6835,7 +6839,7 @@ build_cp_library_fn_ptr (name, type)
const char *name;
tree type;
{
return build_cp_library_fn (get_identifier (name), type);
return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
}
/* Like build_library_fn, but also pushes the function so that we will
@ -6853,12 +6857,14 @@ push_library_fn (name, type)
/* Like build_cp_library_fn, but also pushes the function so that it
will be found by normal lookup. */
tree
push_cp_library_fn (name, type)
tree name;
static tree
push_cp_library_fn (operator_code, type)
enum tree_code operator_code;
tree type;
{
tree fn = build_cp_library_fn (name, type);
tree fn = build_cp_library_fn (ansi_opname (operator_code),
operator_code,
type);
pushdecl (fn);
return fn;
}
@ -8892,7 +8898,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
quals = NULL_TREE;
}
if (DECL_OVERLOADED_OPERATOR_P (decl))
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
grok_op_properties (decl, virtualp, check < 0);
if (ctype && decl_function_context (decl))
@ -9794,18 +9800,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
dname);
name = IDENTIFIER_POINTER (dname);
}
else if (!IDENTIFIER_OPNAME_P (dname))
else if (!IDENTIFIER_TYPENAME_P (dname))
name = IDENTIFIER_POINTER (dname);
else
{
if (IDENTIFIER_TYPENAME_P (dname))
{
my_friendly_assert (flags == NO_SPECIAL, 154);
flags = TYPENAME_FLAG;
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
}
name = operator_name_string (dname);
my_friendly_assert (flags == NO_SPECIAL, 154);
flags = TYPENAME_FLAG;
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
if (IDENTIFIER_GLOBAL_VALUE (dname)
&& (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
== TYPE_DECL))
name = IDENTIFIER_POINTER (dname);
else
name = "<invalid operator>";
}
break;
@ -10369,10 +10377,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else
tmp = TREE_OPERAND (declarator, 0);
op = IDENTIFIER_OPNAME_P (tmp);
if (IDENTIFIER_TYPENAME_P (tmp))
{
if (IDENTIFIER_GLOBAL_VALUE (tmp)
&& (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
== TYPE_DECL))
name = IDENTIFIER_POINTER (tmp);
else
name = "<invalid operator>";
}
}
error ("storage class specified for %s `%s'",
op ? "member operator" : "field",
op ? operator_name_string (tmp) : name);
name);
}
else
{
@ -11356,10 +11373,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
return void_type_node;
}
if (declarator == ansi_opname[(int) NEW_EXPR]
|| declarator == ansi_opname[(int) VEC_NEW_EXPR]
|| declarator == ansi_opname[(int) DELETE_EXPR]
|| declarator == ansi_opname[(int) VEC_DELETE_EXPR])
if (declarator == ansi_opname (NEW_EXPR)
|| declarator == ansi_opname (VEC_NEW_EXPR)
|| declarator == ansi_opname (DELETE_EXPR)
|| declarator == ansi_opname (VEC_DELETE_EXPR))
{
if (virtualp)
{
@ -12225,30 +12242,30 @@ grok_ctor_properties (ctype, decl)
return 1;
}
/* An operator with this name can be either unary or binary. */
/* An operator with this code is unary, but can also be binary. */
static int
ambi_op_p (name)
tree name;
ambi_op_p (code)
enum tree_code code;
{
return (name == ansi_opname [(int) INDIRECT_REF]
|| name == ansi_opname [(int) ADDR_EXPR]
|| name == ansi_opname [(int) NEGATE_EXPR]
|| name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR]
|| name == ansi_opname [(int) CONVERT_EXPR]);
return (code == INDIRECT_REF
|| code == ADDR_EXPR
|| code == CONVERT_EXPR
|| code == NEGATE_EXPR
|| code == PREINCREMENT_EXPR
|| code == PREDECREMENT_EXPR);
}
/* An operator with this name can only be unary. */
static int
unary_op_p (name)
tree name;
unary_op_p (code)
enum tree_code code;
{
return (name == ansi_opname [(int) TRUTH_NOT_EXPR]
|| name == ansi_opname [(int) BIT_NOT_EXPR]
|| name == ansi_opname [(int) COMPONENT_REF]
|| IDENTIFIER_TYPENAME_P (name));
return (code == TRUTH_NOT_EXPR
|| code == BIT_NOT_EXPR
|| code == COMPONENT_REF
|| code == TYPE_EXPR);
}
/* Do a little sanity-checking on how they declared their operator. */
@ -12259,43 +12276,87 @@ grok_op_properties (decl, virtualp, friendp)
int virtualp, friendp;
{
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
tree argtype;
int methodp = (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
tree name = DECL_NAME (decl);
enum tree_code operator_code;
int arity;
/* Count the number of arguments. */
for (argtype = argtypes, arity = 0;
argtype && argtype != void_list_node;
argtype = TREE_CHAIN (argtype))
++arity;
if (current_class_type == NULL_TREE)
friendp = 1;
if (DECL_CONV_FN_P (decl))
operator_code = TYPE_EXPR;
else
do
{
#define DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGING, ARITY, ASSN_P) \
if (ansi_opname (CODE) == name) \
{ \
operator_code = CODE; \
break; \
} \
else if (ansi_assopname (CODE) == name) \
{ \
operator_code = CODE; \
DECL_ASSIGNMENT_OPERATOR_P (decl) = 1; \
break; \
}
#include "operators.def"
#undef DEF_OPERATOR
my_friendly_abort (20000527);
}
while (0);
my_friendly_assert (operator_code != LAST_CPLUS_TREE_CODE, 20000526);
SET_OVERLOADED_OPERATOR_CODE (decl, operator_code);
if (! friendp)
{
/* [class.copy]
switch (operator_code)
{
case CALL_EXPR:
TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
break;
case ARRAY_REF:
TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
break;
A user-declared copy assignment operator X::operator= is a
non-static non-template member function of class X with
exactly one parameter of type X, X&, const X&, volatile X& or
const volatile X&. */
if (name == ansi_opname[(int) MODIFY_EXPR]
&& !(DECL_TEMPLATE_INSTANTIATION (decl)
&& is_member_template (DECL_TI_TEMPLATE (decl))))
;
else if (name == ansi_opname[(int) CALL_EXPR])
TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
else if (name == ansi_opname[(int) ARRAY_REF])
TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
else if (name == ansi_opname[(int) COMPONENT_REF]
|| name == ansi_opname[(int) MEMBER_REF])
TYPE_OVERLOADS_ARROW (current_class_type) = 1;
else if (name == ansi_opname[(int) NEW_EXPR])
TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
else if (name == ansi_opname[(int) DELETE_EXPR])
TYPE_GETS_DELETE (current_class_type) |= 1;
else if (name == ansi_opname[(int) VEC_NEW_EXPR])
TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
else if (name == ansi_opname[(int) VEC_DELETE_EXPR])
TYPE_GETS_DELETE (current_class_type) |= 2;
case COMPONENT_REF:
case MEMBER_REF:
TYPE_OVERLOADS_ARROW (current_class_type) = 1;
break;
case NEW_EXPR:
TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
break;
case DELETE_EXPR:
TYPE_GETS_DELETE (current_class_type) |= 1;
break;
case VEC_NEW_EXPR:
TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
break;
case VEC_DELETE_EXPR:
TYPE_GETS_DELETE (current_class_type) |= 2;
break;
default:
break;
}
}
if (name == ansi_opname[(int) NEW_EXPR]
|| name == ansi_opname[(int) VEC_NEW_EXPR])
if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
{
/* When the compiler encounters the definition of A::operator new, it
doesn't look at the class declaration to find out if it's static. */
@ -12311,8 +12372,7 @@ grok_op_properties (decl, virtualp, friendp)
else
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
}
else if (name == ansi_opname[(int) DELETE_EXPR]
|| name == ansi_opname[(int) VEC_DELETE_EXPR])
else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
{
if (methodp)
revert_static_member_fn (decl);
@ -12332,11 +12392,11 @@ grok_op_properties (decl, virtualp, friendp)
an enumeration, or a reference to an enumeration. 13.4.0.6 */
if (! methodp || DECL_STATIC_FUNCTION_P (decl))
{
if (DECL_CONV_FN_P (decl)
|| name == ansi_opname[(int) CALL_EXPR]
|| name == ansi_opname[(int) MODIFY_EXPR]
|| name == ansi_opname[(int) COMPONENT_REF]
|| name == ansi_opname[(int) ARRAY_REF])
if (operator_code == TYPE_EXPR
|| operator_code == CALL_EXPR
|| operator_code == COMPONENT_REF
|| operator_code == ARRAY_REF
|| operator_code == NOP_EXPR)
cp_error ("`%D' must be a nonstatic member function", decl);
else
{
@ -12367,7 +12427,7 @@ grok_op_properties (decl, virtualp, friendp)
}
}
if (name == ansi_opname[(int) CALL_EXPR])
if (operator_code == CALL_EXPR)
return; /* No restrictions on args. */
if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
@ -12397,18 +12457,27 @@ grok_op_properties (decl, virtualp, friendp)
}
}
if (name == ansi_opname[(int) MODIFY_EXPR])
if (DECL_ASSIGNMENT_OPERATOR_P (decl)
&& operator_code == NOP_EXPR)
{
tree parmtype;
if (list_length (argtypes) != 3 && methodp)
if (arity != 2 && methodp)
{
cp_error ("`%D' must take exactly one argument", decl);
return;
}
parmtype = TREE_VALUE (TREE_CHAIN (argtypes));
/* [class.copy]
A user-declared copy assignment operator X::operator= is
a non-static non-template member function of class X with
exactly one parameter of type X, X&, const X&, volatile
X& or const volatile X&. */
if (copy_assignment_arg_p (parmtype, virtualp)
&& !(DECL_TEMPLATE_INSTANTIATION (decl)
&& is_member_template (DECL_TI_TEMPLATE (decl)))
&& ! friendp)
{
TYPE_HAS_ASSIGN_REF (current_class_type) = 1;
@ -12417,19 +12486,55 @@ grok_op_properties (decl, virtualp, friendp)
TYPE_HAS_CONST_ASSIGN_REF (current_class_type) = 1;
}
}
else if (name == ansi_opname[(int) COND_EXPR])
else if (operator_code == COND_EXPR)
{
/* 13.4.0.3 */
cp_error ("ISO C++ prohibits overloading operator ?:");
}
else if (ambi_op_p (name))
else if (ambi_op_p (operator_code))
{
if (list_length (argtypes) == 2)
/* prefix */;
else if (list_length (argtypes) == 3)
if (arity == 1)
/* We pick the one-argument operator codes by default, so
we don't have to change anything. */
;
else if (arity == 2)
{
if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])
/* If we thought this was a unary operator, we now know
it to be a binary operator. */
switch (operator_code)
{
case INDIRECT_REF:
operator_code = MULT_EXPR;
break;
case ADDR_EXPR:
operator_code = BIT_AND_EXPR;
break;
case CONVERT_EXPR:
operator_code = PLUS_EXPR;
break;
case NEGATE_EXPR:
operator_code = MINUS_EXPR;
break;
case PREINCREMENT_EXPR:
operator_code = POSTINCREMENT_EXPR;
break;
case PREDECREMENT_EXPR:
operator_code = PREDECREMENT_EXPR;
break;
default:
my_friendly_abort (20000527);
}
SET_OVERLOADED_OPERATOR_CODE (decl, operator_code);
if ((operator_code == POSTINCREMENT_EXPR
|| operator_code == POSTDECREMENT_EXPR)
&& ! processing_template_decl
&& ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node))
{
@ -12452,15 +12557,18 @@ grok_op_properties (decl, virtualp, friendp)
/* More Effective C++ rule 6. */
if (warn_ecpp
&& (name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR]))
&& (operator_code == POSTINCREMENT_EXPR
|| operator_code == POSTDECREMENT_EXPR
|| operator_code == PREINCREMENT_EXPR
|| operator_code == PREDECREMENT_EXPR))
{
tree arg = TREE_VALUE (argtypes);
tree ret = TREE_TYPE (TREE_TYPE (decl));
if (methodp || TREE_CODE (arg) == REFERENCE_TYPE)
arg = TREE_TYPE (arg);
arg = TYPE_MAIN_VARIANT (arg);
if (list_length (argtypes) == 2)
if (operator_code == PREINCREMENT_EXPR
|| operator_code == PREDECREMENT_EXPR)
{
if (TREE_CODE (ret) != REFERENCE_TYPE
|| !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
@ -12475,9 +12583,9 @@ grok_op_properties (decl, virtualp, friendp)
}
}
}
else if (unary_op_p (name))
else if (unary_op_p (operator_code))
{
if (list_length (argtypes) != 2)
if (arity != 1)
{
if (methodp)
cp_error ("`%D' must take `void'", decl);
@ -12485,9 +12593,9 @@ grok_op_properties (decl, virtualp, friendp)
cp_error ("`%D' must take exactly one argument", decl);
}
}
else /* if (binary_op_p (name)) */
else /* if (binary_op_p (operator_code)) */
{
if (list_length (argtypes) != 3)
if (arity != 2)
{
if (methodp)
cp_error ("`%D' must take exactly one argument", decl);
@ -12497,20 +12605,20 @@ grok_op_properties (decl, virtualp, friendp)
/* More Effective C++ rule 7. */
if (warn_ecpp
&& (name == ansi_opname [TRUTH_ANDIF_EXPR]
|| name == ansi_opname [TRUTH_ORIF_EXPR]
|| name == ansi_opname [COMPOUND_EXPR]))
&& (operator_code == TRUTH_ANDIF_EXPR
|| operator_code == TRUTH_ORIF_EXPR
|| operator_code == COMPOUND_EXPR))
cp_warning ("user-defined `%D' always evaluates both arguments",
decl);
}
/* Effective C++ rule 23. */
if (warn_ecpp
&& list_length (argtypes) == 3
&& (name == ansi_opname [PLUS_EXPR]
|| name == ansi_opname [MINUS_EXPR]
|| name == ansi_opname [TRUNC_DIV_EXPR]
|| name == ansi_opname [MULT_EXPR])
&& arity == 2
&& (operator_code == PLUS_EXPR
|| operator_code == MINUS_EXPR
|| operator_code == TRUNC_DIV_EXPR
|| operator_code == MULT_EXPR)
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE)
cp_warning ("`%D' should return by value", decl);
@ -12520,8 +12628,8 @@ grok_op_properties (decl, virtualp, friendp)
if (TREE_PURPOSE (argtypes))
{
TREE_PURPOSE (argtypes) = NULL_TREE;
if (name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])
if (operator_code == POSTINCREMENT_EXPR
|| operator_code == POSTDECREMENT_EXPR)
{
if (pedantic)
cp_pedwarn ("`%D' cannot have default arguments", decl);
@ -13464,7 +13572,7 @@ start_function (declspecs, declarator, attrs, flags)
/* Effective C++ rule 15. See also c_expand_return. */
if (warn_ecpp
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
&& DECL_OVERLOADED_OPERATOR_P (decl1) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
cp_warning ("`operator=' should return a reference to `*this'");
@ -14896,7 +15004,8 @@ lang_mark_tree (t)
ggc_mark_tree (ld->befriending_classes);
ggc_mark_tree (ld->saved_tree);
ggc_mark_tree (ld->cloned_function);
ggc_mark_tree (ld->vtt_parm);
if (!DECL_OVERLOADED_OPERATOR_P (t))
ggc_mark_tree (ld->u2.vtt_parm);
if (TREE_CODE (t) == TYPE_DECL)
ggc_mark_tree (ld->u.sorted_fields);
else if (TREE_CODE (t) == FUNCTION_DECL

View File

@ -1960,7 +1960,7 @@ grok_function_init (decl, init)
}
#endif
DECL_PURE_VIRTUAL_P (decl) = 1;
if (DECL_NAME (decl) == ansi_opname [(int) MODIFY_EXPR])
if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
{
tree parmtype
= TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))));

View File

@ -945,14 +945,6 @@ dump_decl (t, flags)
dump_type (TREE_TYPE (t), flags);
break;
}
else if (IDENTIFIER_OPNAME_P (t))
{
const char *name_string = operator_name_string (t);
OB_PUTS ("operator");
if (ISALPHA (name_string[0]))
OB_PUTC (' ');
OB_PUTCP (name_string);
}
else
OB_PUTID (t);
}
@ -1278,13 +1270,7 @@ dump_function_name (t, flags)
dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
}
else if (IDENTIFIER_OPNAME_P (name))
{
const char *name_string = operator_name_string (name);
OB_PUTS ("operator");
if (ISALPHA (name_string[0]))
OB_PUTC (' ');
OB_PUTCP (name_string);
}
OB_PUTID (name);
else
dump_decl (name, flags);
@ -1694,7 +1680,7 @@ dump_expr (t, flags)
case EQ_EXPR:
case NE_EXPR:
case EXACT_DIV_EXPR:
dump_binary_op (opname_tab[(int) TREE_CODE (t)], t, flags);
dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags);
break;
case CEIL_DIV_EXPR:
@ -1782,14 +1768,14 @@ dump_expr (t, flags)
case TRUTH_NOT_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, flags);
dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags);
break;
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
OB_PUTC ('(');
dump_expr (TREE_OPERAND (t, 0), flags | TS_EXPR_PARENS);
OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
OB_PUTCP (operator_name_info[(int)TREE_CODE (t)].name);
OB_PUTC (')');
break;
@ -2307,13 +2293,10 @@ op_to_string (p, v)
enum tree_code p;
int v ATTRIBUTE_UNUSED;
{
static char buf[] = "operator ";
tree id;
if (p == 0)
return "{unknown}";
strcpy (buf + 8, opname_tab [p]);
return buf;
id = operator_name_info[(int) p].identifier;
return id ? IDENTIFIER_POINTER (id) : "{unknown}";
}
static const char *
@ -2342,13 +2325,10 @@ assop_to_string (p, v)
enum tree_code p;
int v ATTRIBUTE_UNUSED;
{
static char buf[] = "operator ";
tree id;
if (p == 0)
return "{unknown}";
strcpy (buf + 9, assignop_tab [p]);
return buf;
id = assignment_operator_name_info[(int) p].identifier;
return id ? IDENTIFIER_POINTER (id) : "{unknown}";
}
static const char *

View File

@ -2331,7 +2331,7 @@ build_new_1 (exp)
tree args;
args = tree_cons (NULL_TREE, size, placement);
fnname = ansi_opname[code];
fnname = ansi_opname (code);
if (use_global_new)
rval = (build_new_function_call

View File

@ -94,6 +94,7 @@ static void mark_impl_file_chain PARAMS ((void *));
static int read_ucs PARAMS ((int));
static int is_extended_char PARAMS ((int));
static int is_extended_char_1 PARAMS ((int));
static void init_operators PARAMS ((void));
/* Given a file name X, return the nondirectory portion.
Keep in mind that X can be computed more than once. */
@ -144,10 +145,6 @@ extern struct obstack token_obstack;
/* ??? Don't really know where this goes yet. */
#include "input.c"
/* Holds translations from TREE_CODEs to operator name strings,
i.e., opname_tab[PLUS_EXPR] == "+". */
const char **opname_tab;
const char **assignop_tab;
extern int yychar; /* the lookahead symbol */
extern YYSTYPE yylval; /* the semantic value of the */
@ -297,52 +294,6 @@ set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
CALL_DECLARATOR_EXCEPTION_SPEC (call_declarator) = exception_specification;
}
/* Build names and nodes for overloaded operators. */
tree ansi_opname[LAST_CPLUS_TREE_CODE];
tree ansi_assopname[LAST_CPLUS_TREE_CODE];
const char *
operator_name_string (name)
tree name;
{
char *opname = IDENTIFIER_POINTER (name) + 2;
tree *opname_table;
int i, assign;
/* Works for builtin and user defined types. */
if (IDENTIFIER_GLOBAL_VALUE (name)
&& TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
return IDENTIFIER_POINTER (name);
if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
{
opname += 1;
assign = 1;
opname_table = ansi_assopname;
}
else
{
assign = 0;
opname_table = ansi_opname;
}
for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
{
if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
&& opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
break;
}
if (i == LAST_CPLUS_TREE_CODE)
return "<invalid operator>";
if (assign)
return assignop_tab[i];
else
return opname_tab[i];
}
int interface_only; /* whether or not current file is only for
interface definitions. */
int interface_unknown; /* whether or not we know this class
@ -487,19 +438,6 @@ init_filename_times ()
}
}
/* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
Stuck this hack in to get the files open correctly; this is called
in place of init_parse if we are an unexec'd binary. */
#if 0
void
reinit_lang_specific ()
{
init_filename_times ();
reinit_search_statistics ();
}
#endif
static int *
init_cpp_parse ()
{
@ -514,6 +452,81 @@ init_cpp_parse ()
return token_count;
}
/* A mapping from tree codes to operator name information. */
operator_name_info_t operator_name_info[(int) LAST_CPLUS_TREE_CODE];
/* Similar, but for assignment operators. */
operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE];
/* Initialize data structures that keep track of operator names. */
static void
init_operators ()
{
tree identifier;
char buffer[256];
struct operator_name_info_t *oni;
#define DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY, ASSN_P) \
my_friendly_assert ((strlen ("operator ") + strlen (NAME) + 1 \
<= 256), \
20000526); \
sprintf (buffer, "operator %s", NAME); \
identifier = get_identifier (buffer); \
IDENTIFIER_OPNAME_P (identifier) = 1; \
\
oni = (ASSN_P \
? &assignment_operator_name_info[(int) CODE] \
: &operator_name_info[(int) CODE]); \
oni->identifier = identifier; \
oni->name = NAME; \
oni->mangled_name = flag_new_abi ? NEW_MANGLING : OLD_MANGLING;
#include "operators.def"
#undef DEF_OPERATOR
operator_name_info[(int) ERROR_MARK].identifier
= get_identifier ("<invalid operator>");
/* Handle some special cases. These operators are not defined in
the language, but can be produced internally. We may need them
for error-reporting. (Eventually, we should ensure that this
does not happen. Error messages involving these operators will
be confusing to users.) */
operator_name_info [(int) INIT_EXPR].name
= operator_name_info [(int) MODIFY_EXPR].name;
operator_name_info [(int) EXACT_DIV_EXPR].name = "(ceiling /)";
operator_name_info [(int) CEIL_DIV_EXPR].name = "(ceiling /)";
operator_name_info [(int) FLOOR_DIV_EXPR].name = "(floor /)";
operator_name_info [(int) ROUND_DIV_EXPR].name = "(round /)";
operator_name_info [(int) CEIL_MOD_EXPR].name = "(ceiling %)";
operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %)";
operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %)";
operator_name_info [(int) ABS_EXPR].name = "abs";
operator_name_info [(int) FFS_EXPR].name = "ffs";
operator_name_info [(int) BIT_ANDTC_EXPR].name = "&~";
operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&";
operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||";
operator_name_info [(int) IN_EXPR].name = "in";
operator_name_info [(int) RANGE_EXPR].name = "...";
operator_name_info [(int) CONVERT_EXPR].name = "+";
assignment_operator_name_info [(int) EXACT_DIV_EXPR].name
= "(exact /=)";
assignment_operator_name_info [(int) CEIL_DIV_EXPR].name
= "(ceiling /=)";
assignment_operator_name_info [(int) FLOOR_DIV_EXPR].name
= "(floor /=)";
assignment_operator_name_info [(int) ROUND_DIV_EXPR].name
= "(round /=)";
assignment_operator_name_info [(int) CEIL_MOD_EXPR].name
= "(ceiling %=)";
assignment_operator_name_info [(int) FLOOR_MOD_EXPR].name
= "(floor %=)";
assignment_operator_name_info [(int) ROUND_MOD_EXPR].name
= "(round %=)";
}
const char *
init_parse (filename)
const char *filename;
@ -521,8 +534,6 @@ init_parse (filename)
extern int flag_no_gnu_keywords;
extern int flag_operator_names;
int i;
#ifdef MULTIBYTE_CHARS
/* Change to the native locale for multibyte conversions. */
setlocale (LC_CTYPE, "");
@ -580,138 +591,7 @@ init_parse (filename)
cplus_tree_code_name,
(LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
opname_tab = (const char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
memset (opname_tab, 0, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
assignop_tab = (const char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
memset (assignop_tab, 0, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
ansi_opname[0] = get_identifier ("<invalid operator>");
for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
{
ansi_opname[i] = ansi_opname[0];
ansi_assopname[i] = ansi_opname[0];
}
ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT);
IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
/* This is not true: these operators are not defined in ANSI,
but we need them anyway. */
ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz");
IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1;
init_operators ();
init_method ();
init_error ();
gcc_obstack_init (&inline_text_obstack);
@ -787,88 +667,6 @@ init_parse (filename)
null_node = build_int_2 (0, 0);
ridpointers[RID_NULL] = null_node;
opname_tab[(int) COMPONENT_REF] = "->";
opname_tab[(int) MEMBER_REF] = "->*";
opname_tab[(int) INDIRECT_REF] = "*";
opname_tab[(int) ARRAY_REF] = "[]";
opname_tab[(int) MODIFY_EXPR] = "=";
opname_tab[(int) INIT_EXPR] = "=";
opname_tab[(int) NEW_EXPR] = "new";
opname_tab[(int) DELETE_EXPR] = "delete";
opname_tab[(int) VEC_NEW_EXPR] = "new []";
opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
opname_tab[(int) COND_EXPR] = "?:";
opname_tab[(int) CALL_EXPR] = "()";
opname_tab[(int) PLUS_EXPR] = "+";
opname_tab[(int) MINUS_EXPR] = "-";
opname_tab[(int) MULT_EXPR] = "*";
opname_tab[(int) TRUNC_DIV_EXPR] = "/";
opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
opname_tab[(int) TRUNC_MOD_EXPR] = "%";
opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
opname_tab[(int) EXACT_DIV_EXPR] = "/";
opname_tab[(int) NEGATE_EXPR] = "-";
opname_tab[(int) MIN_EXPR] = "<?";
opname_tab[(int) MAX_EXPR] = ">?";
opname_tab[(int) ABS_EXPR] = "abs";
opname_tab[(int) FFS_EXPR] = "ffs";
opname_tab[(int) LSHIFT_EXPR] = "<<";
opname_tab[(int) RSHIFT_EXPR] = ">>";
opname_tab[(int) BIT_IOR_EXPR] = "|";
opname_tab[(int) BIT_XOR_EXPR] = "^";
opname_tab[(int) BIT_AND_EXPR] = "&";
opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
opname_tab[(int) BIT_NOT_EXPR] = "~";
opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
opname_tab[(int) TRUTH_NOT_EXPR] = "!";
opname_tab[(int) LT_EXPR] = "<";
opname_tab[(int) LE_EXPR] = "<=";
opname_tab[(int) GT_EXPR] = ">";
opname_tab[(int) GE_EXPR] = ">=";
opname_tab[(int) EQ_EXPR] = "==";
opname_tab[(int) NE_EXPR] = "!=";
opname_tab[(int) IN_EXPR] = "in";
opname_tab[(int) RANGE_EXPR] = "...";
opname_tab[(int) CONVERT_EXPR] = "+";
opname_tab[(int) ADDR_EXPR] = "&";
opname_tab[(int) PREDECREMENT_EXPR] = "--";
opname_tab[(int) PREINCREMENT_EXPR] = "++";
opname_tab[(int) POSTDECREMENT_EXPR] = "--";
opname_tab[(int) POSTINCREMENT_EXPR] = "++";
opname_tab[(int) COMPOUND_EXPR] = ",";
assignop_tab[(int) NOP_EXPR] = "=";
assignop_tab[(int) PLUS_EXPR] = "+=";
assignop_tab[(int) CONVERT_EXPR] = "+=";
assignop_tab[(int) MINUS_EXPR] = "-=";
assignop_tab[(int) NEGATE_EXPR] = "-=";
assignop_tab[(int) MULT_EXPR] = "*=";
assignop_tab[(int) INDIRECT_REF] = "*=";
assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
assignop_tab[(int) MIN_EXPR] = "<?=";
assignop_tab[(int) MAX_EXPR] = ">?=";
assignop_tab[(int) LSHIFT_EXPR] = "<<=";
assignop_tab[(int) RSHIFT_EXPR] = ">>=";
assignop_tab[(int) BIT_IOR_EXPR] = "|=";
assignop_tab[(int) BIT_XOR_EXPR] = "^=";
assignop_tab[(int) BIT_AND_EXPR] = "&=";
assignop_tab[(int) ADDR_EXPR] = "&=";
init_filename_times ();
/* Some options inhibit certain reserved words.
@ -908,8 +706,6 @@ init_parse (filename)
token_count = init_cpp_parse ();
interface_unknown = 1;
ggc_add_tree_root (ansi_opname, LAST_CPLUS_TREE_CODE);
ggc_add_tree_root (ansi_assopname, LAST_CPLUS_TREE_CODE);
ggc_add_string_root (&internal_filename, 1);
ggc_add_tree_root (ridpointers, RID_MAX);
ggc_add_tree_root (&defarg_fns, 1);
@ -3322,7 +3118,7 @@ do_identifier (token, parsing, args)
return build_min_nt (LOOKUP_EXPR, token);
else if (IDENTIFIER_OPNAME_P (token))
{
if (token != ansi_opname[ERROR_MARK])
if (token != ansi_opname (ERROR_MARK))
cp_error ("`%D' not defined", token);
id = error_mark_node;
}

View File

@ -520,12 +520,10 @@ mangle_expression (value)
{
int i;
int operands = TREE_CODE_LENGTH (TREE_CODE (value));
tree id;
const char *name;
id = ansi_opname [(int) TREE_CODE (value)];
my_friendly_assert (id != NULL_TREE, 0);
name = IDENTIFIER_POINTER (id);
name = operator_name_info[TREE_CODE (value)].mangled_name;
my_friendly_assert (name != NULL, 0);
if (name[0] != '_' || name[1] != '_')
/* On some erroneous inputs, we can get here with VALUE a
LOOKUP_EXPR. In that case, the NAME will be the
@ -1576,31 +1574,47 @@ build_static_name (context, name)
of a class (including a static member) and 2 if the declaration is
for a constructor. */
tree
build_decl_overload_real (dname, parms, ret_type, tparms, targs,
build_decl_overload_real (decl, parms, ret_type, tparms, targs,
for_method)
tree dname;
tree decl;
tree parms;
tree ret_type;
tree tparms;
tree targs;
int for_method;
{
const char *name = IDENTIFIER_POINTER (dname);
const char *name;
enum tree_code operator_code;
/* member operators new and delete look like methods at this point. */
if (! for_method && current_namespace == global_namespace
&& parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST
&& TREE_CHAIN (parms) == void_list_node)
operator_code = DECL_OVERLOADED_OPERATOR_P (decl);
if (!DECL_CONV_FN_P (decl) && operator_code)
{
if (dname == ansi_opname[(int) DELETE_EXPR])
return get_identifier ("__builtin_delete");
else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
return get_identifier ("__builtin_vec_delete");
if (dname == ansi_opname[(int) NEW_EXPR])
return get_identifier ("__builtin_new");
else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
return get_identifier ("__builtin_vec_new");
/* member operators new and delete look like methods at this
point. */
if (! for_method && CP_DECL_CONTEXT (decl) == global_namespace
&& parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST
&& TREE_CHAIN (parms) == void_list_node)
switch (operator_code)
{
case DELETE_EXPR:
return get_identifier ("__builtin_delete");
case VEC_DELETE_EXPR:
return get_identifier ("__builtin_vec_delete");
case NEW_EXPR:
return get_identifier ("__builtin_new");
case VEC_NEW_EXPR:
return get_identifier ("__builtin_vec_new");
default:
break;
}
if (DECL_ASSIGNMENT_OPERATOR_P (decl))
name = assignment_operator_name_info[(int) operator_code].mangled_name;
else
name = operator_name_info[(int) operator_code].mangled_name;
}
else
name = IDENTIFIER_POINTER (DECL_NAME (decl));
start_squangling ();
OB_INIT ();
@ -1618,15 +1632,12 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
build_template_parm_names (tparms, targs);
OB_PUTC ('_');
}
else if (!for_method && current_namespace == global_namespace)
/* XXX this works only if we call this in the same namespace
as the declaration. Unfortunately, we don't have the _DECL,
only its name */
else if (!for_method && CP_DECL_CONTEXT (decl) == global_namespace)
OB_PUTC ('F');
if (!for_method && current_namespace != global_namespace)
if (!for_method && CP_DECL_CONTEXT (decl) != global_namespace)
/* qualify with namespace */
build_qualified_name (current_namespace);
build_qualified_name (CP_DECL_CONTEXT (decl));
if (parms == NULL_TREE)
OB_PUTC ('e');
@ -1639,7 +1650,7 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
/* Allocate typevec array. */
size_t typevec_size = list_length (parms);
maxtype = 0;
if (!for_method && current_namespace != global_namespace)
if (!for_method && CP_DECL_CONTEXT (decl) != global_namespace)
/* The namespace of a global function needs one slot. */
typevec_size++;
VARRAY_TREE_INIT (typevec, typevec_size, "typevec");
@ -1668,11 +1679,11 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
{
/* the namespace qualifier for a global function
will count as type */
if (current_namespace != global_namespace
if (CP_DECL_CONTEXT (decl) != global_namespace
&& !flag_do_squangling)
{
my_friendly_assert (maxtype < VARRAY_SIZE (typevec), 387);
VARRAY_TREE (typevec, maxtype) = current_namespace;
VARRAY_TREE (typevec, maxtype) = CP_DECL_CONTEXT (decl);
maxtype++;
}
build_mangled_name (parms, 0, 0);
@ -1694,31 +1705,10 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs,
end_squangling ();
{
tree n = get_identifier (obstack_base (&scratch_obstack));
if (IDENTIFIER_OPNAME_P (dname))
IDENTIFIER_OPNAME_P (n) = 1;
return n;
}
}
/* Change the name of a function definition so that it may be
overloaded. NAME is the name of the function to overload,
PARMS is the parameter list (which determines what name the
final function obtains).
FOR_METHOD is 1 if this overload is being performed
for a method, rather than a function type. It is 2 if
this overload is being performed for a constructor. */
tree
build_decl_overload (dname, parms, for_method)
tree dname;
tree parms;
int for_method;
{
return build_decl_overload_real (dname, parms, NULL_TREE, NULL_TREE,
NULL_TREE, for_method);
}
/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */
void
@ -1746,9 +1736,10 @@ set_mangled_name_for_decl (decl)
0);
DECL_ASSEMBLER_NAME (decl)
= build_decl_overload (DECL_NAME (decl), parm_types,
DECL_FUNCTION_MEMBER_P (decl)
+ DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
= build_decl_overload_real (decl, parm_types, NULL_TREE,
NULL_TREE, NULL_TREE,
DECL_FUNCTION_MEMBER_P (decl)
+ DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
}
/* Build an overload name for the type expression TYPE. */
@ -1760,7 +1751,7 @@ build_typename_overload (type)
tree id;
OB_INIT ();
OB_PUTID (ansi_opname[(int) TYPE_EXPR]);
OB_PUTS (OPERATOR_TYPENAME_FORMAT);
nofold = 1;
start_squangling ();
build_mangled_name (type, 0, 1);
@ -2367,7 +2358,7 @@ do_build_assign_ref (fndecl)
(build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p);
p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
p = build_member_call (basetype, ansi_assopname (NOP_EXPR),
build_tree_list (NULL_TREE, p));
finish_expr_stmt (p);
}
@ -2467,7 +2458,7 @@ synthesize_method (fndecl)
store_parm_decls ();
clear_last_expr ();
if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])
if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
{
do_build_assign_ref (fndecl);
need_body = 0;
@ -2550,7 +2541,7 @@ implicitly_declare_fn (kind, type, const_p)
if (const_p)
type = build_qualified_type (type, TYPE_QUAL_CONST);
name = ansi_opname [(int) MODIFY_EXPR];
name = ansi_assopname (NOP_EXPR);
argtype = build_reference_type (type);
args = tree_cons (NULL_TREE,

153
gcc/cp/operators.def Normal file
View File

@ -0,0 +1,153 @@
/* -*-C-*-
This file contains definitions of the various C++ operators,
including both overloadable operators (like `+') and
non-overloadable operators (like the `?:' ternary operator).
Writtey by Mark Mitchell <mark@codesourcery.com>
Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* The DEF_OPERATOR macro takes the following arguments:
NAME
The name of the operator, as a C string, but without the
preceeding `operator'. This is the name that would be given in
the source program. For `operator +', for example, this would be
`+'.
CODE
The tree_code for this operator. For `operator +', for example,
this would be PLUS_EXPR. Because there are no tree codes for
assignment operators, the same tree-codes are reused; i.e.,
`operator +' will also have PLUS_EXPR as its CODE.
NEW_MANGLING
The mangling prefix for the operator, as a C string, and as
mangled under the new ABI. For `operator +', for example, this
would be "pl".
OLD_MANGLING
Analagous, but for the old ABI.
ARITY
The arity of the operator, or -1 if any arity is allowed. (As
for `operator ()'.) Postincrement and postdecrement operators
are marked as binary.
ASSN_P
A boolean value. If non-zero, this is an assignment operator.
Before including this file, you should define DEFOPERATOR
to take these arguments.
There is code (such as in grok_op_properties) that depends on the
order the operators are presented in this file. In particular,
unary operators must preceed binary operators. */
/* Use DEF_SIMPLE_OPERATOR to define a non-assignment operator. Its
arguments are as for DEF_OPERATOR, but there is no need to provide
an ASSIGNMENT_P argument; it is always zero. */
#define DEF_SIMPLE_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY) \
DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY, 0)
/* Use DEF_ASSN_OPERATOR to define an assignment operator. Its
arguments are as for DEF_OPERATOR, but there is no need to provide
an ASSIGNMENT_P argument; it is always one. */
#define DEF_ASSN_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY) \
DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY, 1)
/* Memory allocation operators. */
DEF_SIMPLE_OPERATOR ("new", NEW_EXPR, "nw", "__nw", -1)
DEF_SIMPLE_OPERATOR ("new []", VEC_NEW_EXPR, "na", "__vn", -1)
DEF_SIMPLE_OPERATOR ("delete", DELETE_EXPR, "dl", "__dl", -1)
DEF_SIMPLE_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", "__vd", -1)
/* Unary operators. */
DEF_SIMPLE_OPERATOR ("+", CONVERT_EXPR, "ps", "__pl", 1)
DEF_SIMPLE_OPERATOR ("-", NEGATE_EXPR, "ng", "__mi", 1)
DEF_SIMPLE_OPERATOR ("&", ADDR_EXPR, "ad", "__ad", 1)
DEF_SIMPLE_OPERATOR ("*", INDIRECT_REF, "de", "__ml", 1)
DEF_SIMPLE_OPERATOR ("~", BIT_NOT_EXPR, "co", "__co", 1)
DEF_SIMPLE_OPERATOR ("!", TRUTH_NOT_EXPR, "nt", "__nt", 1)
DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_EXPR, "pp", "__pp", 1)
DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", "__mm", 1)
DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", "__sz", 1)
/* This is an extension. */
DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "vx7alignof", "__al", 1)
/* The cast operator. */
DEF_SIMPLE_OPERATOR ("", TYPE_EXPR, "cv", OPERATOR_TYPENAME_FORMAT, 1)
/* Binary operators. */
DEF_SIMPLE_OPERATOR ("+", PLUS_EXPR, "pl", "__pl", 2)
DEF_SIMPLE_OPERATOR ("-", MINUS_EXPR, "mi", "__mi", 2)
DEF_SIMPLE_OPERATOR ("*", MULT_EXPR, "ml", "__ml", 2)
DEF_SIMPLE_OPERATOR ("/", TRUNC_DIV_EXPR, "dv", "__dv", 2)
DEF_SIMPLE_OPERATOR ("%", TRUNC_MOD_EXPR, "md", "__md", 2)
DEF_SIMPLE_OPERATOR ("&", BIT_AND_EXPR, "an", "__ad", 2)
DEF_SIMPLE_OPERATOR ("|", BIT_IOR_EXPR, "or", "__or", 2)
DEF_SIMPLE_OPERATOR ("^", BIT_XOR_EXPR, "eo", "__er", 2)
DEF_SIMPLE_OPERATOR ("<<", LSHIFT_EXPR, "ls", "__ls", 2)
DEF_SIMPLE_OPERATOR (">>", RSHIFT_EXPR, "rs", "__rs", 2)
DEF_SIMPLE_OPERATOR ("==", EQ_EXPR, "eq", "__eq", 2)
DEF_SIMPLE_OPERATOR ("!=", NE_EXPR, "ne", "__ne", 2)
DEF_SIMPLE_OPERATOR ("<", LT_EXPR, "lt", "__lt", 2)
DEF_SIMPLE_OPERATOR (">", GT_EXPR, "gt", "__gt", 2)
DEF_SIMPLE_OPERATOR ("<=", LE_EXPR, "le", "__le", 2)
DEF_SIMPLE_OPERATOR (">=", GE_EXPR, "ge", "__ge", 2)
DEF_SIMPLE_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", "__aa", 2)
DEF_SIMPLE_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", "__oo", 2)
DEF_SIMPLE_OPERATOR (",", COMPOUND_EXPR, "cm", "__cm", 2)
DEF_SIMPLE_OPERATOR ("->*", MEMBER_REF, "pm", "__rm", 2)
DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", "__rf", 2)
DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", "__vc", 2)
DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", "__pp", 2)
DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", "__mm", 2)
/* These are extensions. */
DEF_SIMPLE_OPERATOR ("<?", MIN_EXPR, "vx3min", "__mn", 2)
DEF_SIMPLE_OPERATOR ("<?", MAX_EXPR, "vx3max", "__mx", 2)
/* Assignment operators. */
DEF_ASSN_OPERATOR ("=", NOP_EXPR, "aS", "__as", 2)
DEF_ASSN_OPERATOR ("+=", PLUS_EXPR, "pL", "__apl", 2)
DEF_ASSN_OPERATOR ("-=", MINUS_EXPR, "mI", "__ami", 2)
DEF_ASSN_OPERATOR ("*=", MULT_EXPR, "mL", "__aml", 2)
DEF_ASSN_OPERATOR ("/=", TRUNC_DIV_EXPR, "dV", "__adv", 2)
DEF_ASSN_OPERATOR ("%=", TRUNC_MOD_EXPR, "mD", "__amd", 2)
DEF_ASSN_OPERATOR ("&=", BIT_AND_EXPR, "aN", "__aad", 2)
DEF_ASSN_OPERATOR ("|=", BIT_IOR_EXPR, "oR", "__aor", 2)
DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", "__aer", 2)
DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", "__als", 2)
DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", "__ars", 2)
/* Ternary operators. */
DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", "__cn", 3)
/* Miscellaneous. */
DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", "__cl", -1)

View File

@ -8090,135 +8090,135 @@ case 843:
break;}
case 844:
#line 3674 "parse.y"
{ yyval.ttype = ansi_opname[MULT_EXPR]; ;
{ yyval.ttype = ansi_opname (MULT_EXPR); ;
break;}
case 845:
#line 3676 "parse.y"
{ yyval.ttype = ansi_opname[TRUNC_DIV_EXPR]; ;
{ yyval.ttype = ansi_opname (TRUNC_DIV_EXPR); ;
break;}
case 846:
#line 3678 "parse.y"
{ yyval.ttype = ansi_opname[TRUNC_MOD_EXPR]; ;
{ yyval.ttype = ansi_opname (TRUNC_MOD_EXPR); ;
break;}
case 847:
#line 3680 "parse.y"
{ yyval.ttype = ansi_opname[PLUS_EXPR]; ;
{ yyval.ttype = ansi_opname (PLUS_EXPR); ;
break;}
case 848:
#line 3682 "parse.y"
{ yyval.ttype = ansi_opname[MINUS_EXPR]; ;
{ yyval.ttype = ansi_opname (MINUS_EXPR); ;
break;}
case 849:
#line 3684 "parse.y"
{ yyval.ttype = ansi_opname[BIT_AND_EXPR]; ;
{ yyval.ttype = ansi_opname (BIT_AND_EXPR); ;
break;}
case 850:
#line 3686 "parse.y"
{ yyval.ttype = ansi_opname[BIT_IOR_EXPR]; ;
{ yyval.ttype = ansi_opname (BIT_IOR_EXPR); ;
break;}
case 851:
#line 3688 "parse.y"
{ yyval.ttype = ansi_opname[BIT_XOR_EXPR]; ;
{ yyval.ttype = ansi_opname (BIT_XOR_EXPR); ;
break;}
case 852:
#line 3690 "parse.y"
{ yyval.ttype = ansi_opname[BIT_NOT_EXPR]; ;
{ yyval.ttype = ansi_opname (BIT_NOT_EXPR); ;
break;}
case 853:
#line 3692 "parse.y"
{ yyval.ttype = ansi_opname[COMPOUND_EXPR]; ;
{ yyval.ttype = ansi_opname (COMPOUND_EXPR); ;
break;}
case 854:
#line 3694 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
{ yyval.ttype = ansi_opname (yyvsp[0].code); ;
break;}
case 855:
#line 3696 "parse.y"
{ yyval.ttype = ansi_opname[LT_EXPR]; ;
{ yyval.ttype = ansi_opname (LT_EXPR); ;
break;}
case 856:
#line 3698 "parse.y"
{ yyval.ttype = ansi_opname[GT_EXPR]; ;
{ yyval.ttype = ansi_opname (GT_EXPR); ;
break;}
case 857:
#line 3700 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
{ yyval.ttype = ansi_opname (yyvsp[0].code); ;
break;}
case 858:
#line 3702 "parse.y"
{ yyval.ttype = ansi_assopname[yyvsp[0].code]; ;
{ yyval.ttype = ansi_assopname (yyvsp[0].code); ;
break;}
case 859:
#line 3704 "parse.y"
{ yyval.ttype = ansi_opname [MODIFY_EXPR]; ;
{ yyval.ttype = ansi_assopname (NOP_EXPR); ;
break;}
case 860:
#line 3706 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
{ yyval.ttype = ansi_opname (yyvsp[0].code); ;
break;}
case 861:
#line 3708 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
{ yyval.ttype = ansi_opname (yyvsp[0].code); ;
break;}
case 862:
#line 3710 "parse.y"
{ yyval.ttype = ansi_opname[POSTINCREMENT_EXPR]; ;
{ yyval.ttype = ansi_opname (POSTINCREMENT_EXPR); ;
break;}
case 863:
#line 3712 "parse.y"
{ yyval.ttype = ansi_opname[PREDECREMENT_EXPR]; ;
{ yyval.ttype = ansi_opname (PREDECREMENT_EXPR); ;
break;}
case 864:
#line 3714 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_ANDIF_EXPR]; ;
{ yyval.ttype = ansi_opname (TRUTH_ANDIF_EXPR); ;
break;}
case 865:
#line 3716 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_ORIF_EXPR]; ;
{ yyval.ttype = ansi_opname (TRUTH_ORIF_EXPR); ;
break;}
case 866:
#line 3718 "parse.y"
{ yyval.ttype = ansi_opname[TRUTH_NOT_EXPR]; ;
{ yyval.ttype = ansi_opname (TRUTH_NOT_EXPR); ;
break;}
case 867:
#line 3720 "parse.y"
{ yyval.ttype = ansi_opname[COND_EXPR]; ;
{ yyval.ttype = ansi_opname (COND_EXPR); ;
break;}
case 868:
#line 3722 "parse.y"
{ yyval.ttype = ansi_opname[yyvsp[0].code]; ;
{ yyval.ttype = ansi_opname (yyvsp[0].code); ;
break;}
case 869:
#line 3724 "parse.y"
{ yyval.ttype = ansi_opname[COMPONENT_REF]; ;
{ yyval.ttype = ansi_opname (COMPONENT_REF); ;
break;}
case 870:
#line 3726 "parse.y"
{ yyval.ttype = ansi_opname[MEMBER_REF]; ;
{ yyval.ttype = ansi_opname (MEMBER_REF); ;
break;}
case 871:
#line 3728 "parse.y"
{ yyval.ttype = ansi_opname[CALL_EXPR]; ;
{ yyval.ttype = ansi_opname (CALL_EXPR); ;
break;}
case 872:
#line 3730 "parse.y"
{ yyval.ttype = ansi_opname[ARRAY_REF]; ;
{ yyval.ttype = ansi_opname (ARRAY_REF); ;
break;}
case 873:
#line 3732 "parse.y"
{ yyval.ttype = ansi_opname[NEW_EXPR]; ;
{ yyval.ttype = ansi_opname (NEW_EXPR); ;
break;}
case 874:
#line 3734 "parse.y"
{ yyval.ttype = ansi_opname[DELETE_EXPR]; ;
{ yyval.ttype = ansi_opname (DELETE_EXPR); ;
break;}
case 875:
#line 3736 "parse.y"
{ yyval.ttype = ansi_opname[VEC_NEW_EXPR]; ;
{ yyval.ttype = ansi_opname (VEC_NEW_EXPR); ;
break;}
case 876:
#line 3738 "parse.y"
{ yyval.ttype = ansi_opname[VEC_DELETE_EXPR]; ;
{ yyval.ttype = ansi_opname (VEC_DELETE_EXPR); ;
break;}
case 877:
#line 3741 "parse.y"
@ -8226,7 +8226,7 @@ case 877:
break;}
case 878:
#line 3743 "parse.y"
{ yyval.ttype = ansi_opname[ERROR_MARK]; ;
{ yyval.ttype = ansi_opname (ERROR_MARK); ;
break;}
}
/* the action file gets copied in in place of this dollarsign */

View File

@ -3671,76 +3671,76 @@ operator:
operator_name:
operator '*'
{ $$ = ansi_opname[MULT_EXPR]; }
{ $$ = ansi_opname (MULT_EXPR); }
| operator '/'
{ $$ = ansi_opname[TRUNC_DIV_EXPR]; }
{ $$ = ansi_opname (TRUNC_DIV_EXPR); }
| operator '%'
{ $$ = ansi_opname[TRUNC_MOD_EXPR]; }
{ $$ = ansi_opname (TRUNC_MOD_EXPR); }
| operator '+'
{ $$ = ansi_opname[PLUS_EXPR]; }
{ $$ = ansi_opname (PLUS_EXPR); }
| operator '-'
{ $$ = ansi_opname[MINUS_EXPR]; }
{ $$ = ansi_opname (MINUS_EXPR); }
| operator '&'
{ $$ = ansi_opname[BIT_AND_EXPR]; }
{ $$ = ansi_opname (BIT_AND_EXPR); }
| operator '|'
{ $$ = ansi_opname[BIT_IOR_EXPR]; }
{ $$ = ansi_opname (BIT_IOR_EXPR); }
| operator '^'
{ $$ = ansi_opname[BIT_XOR_EXPR]; }
{ $$ = ansi_opname (BIT_XOR_EXPR); }
| operator '~'
{ $$ = ansi_opname[BIT_NOT_EXPR]; }
{ $$ = ansi_opname (BIT_NOT_EXPR); }
| operator ','
{ $$ = ansi_opname[COMPOUND_EXPR]; }
{ $$ = ansi_opname (COMPOUND_EXPR); }
| operator ARITHCOMPARE
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname ($2); }
| operator '<'
{ $$ = ansi_opname[LT_EXPR]; }
{ $$ = ansi_opname (LT_EXPR); }
| operator '>'
{ $$ = ansi_opname[GT_EXPR]; }
{ $$ = ansi_opname (GT_EXPR); }
| operator EQCOMPARE
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname ($2); }
| operator ASSIGN
{ $$ = ansi_assopname[$2]; }
{ $$ = ansi_assopname ($2); }
| operator '='
{ $$ = ansi_opname [MODIFY_EXPR]; }
{ $$ = ansi_assopname (NOP_EXPR); }
| operator LSHIFT
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname ($2); }
| operator RSHIFT
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname ($2); }
| operator PLUSPLUS
{ $$ = ansi_opname[POSTINCREMENT_EXPR]; }
{ $$ = ansi_opname (POSTINCREMENT_EXPR); }
| operator MINUSMINUS
{ $$ = ansi_opname[PREDECREMENT_EXPR]; }
{ $$ = ansi_opname (PREDECREMENT_EXPR); }
| operator ANDAND
{ $$ = ansi_opname[TRUTH_ANDIF_EXPR]; }
{ $$ = ansi_opname (TRUTH_ANDIF_EXPR); }
| operator OROR
{ $$ = ansi_opname[TRUTH_ORIF_EXPR]; }
{ $$ = ansi_opname (TRUTH_ORIF_EXPR); }
| operator '!'
{ $$ = ansi_opname[TRUTH_NOT_EXPR]; }
{ $$ = ansi_opname (TRUTH_NOT_EXPR); }
| operator '?' ':'
{ $$ = ansi_opname[COND_EXPR]; }
{ $$ = ansi_opname (COND_EXPR); }
| operator MIN_MAX
{ $$ = ansi_opname[$2]; }
{ $$ = ansi_opname ($2); }
| operator POINTSAT %prec EMPTY
{ $$ = ansi_opname[COMPONENT_REF]; }
{ $$ = ansi_opname (COMPONENT_REF); }
| operator POINTSAT_STAR %prec EMPTY
{ $$ = ansi_opname[MEMBER_REF]; }
{ $$ = ansi_opname (MEMBER_REF); }
| operator LEFT_RIGHT
{ $$ = ansi_opname[CALL_EXPR]; }
{ $$ = ansi_opname (CALL_EXPR); }
| operator '[' ']'
{ $$ = ansi_opname[ARRAY_REF]; }
{ $$ = ansi_opname (ARRAY_REF); }
| operator NEW %prec EMPTY
{ $$ = ansi_opname[NEW_EXPR]; }
{ $$ = ansi_opname (NEW_EXPR); }
| operator DELETE %prec EMPTY
{ $$ = ansi_opname[DELETE_EXPR]; }
{ $$ = ansi_opname (DELETE_EXPR); }
| operator NEW '[' ']'
{ $$ = ansi_opname[VEC_NEW_EXPR]; }
{ $$ = ansi_opname (VEC_NEW_EXPR); }
| operator DELETE '[' ']'
{ $$ = ansi_opname[VEC_DELETE_EXPR]; }
{ $$ = ansi_opname (VEC_DELETE_EXPR); }
/* Names here should be looked up in class scope ALSO. */
| operator type_specifier_seq conversion_declarator
{ $$ = grokoptypename ($2.t, $3); }
| operator error
{ $$ = ansi_opname[ERROR_MARK]; }
{ $$ = ansi_opname (ERROR_MARK); }
;
%%

View File

@ -5790,7 +5790,7 @@ tsubst_decl (t, args, type, in_decl)
if (DECL_CONSTRUCTOR_P (r))
grok_ctor_properties (ctx, r);
}
else if (DECL_OVERLOADED_OPERATOR_P (r))
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
}
break;
@ -9869,7 +9869,6 @@ static void
set_mangled_name_for_template_decl (decl)
tree decl;
{
tree saved_namespace;
tree context = NULL_TREE;
tree fn_type;
tree ret_type;
@ -9985,21 +9984,10 @@ set_mangled_name_for_template_decl (decl)
my_friendly_assert (TREE_VEC_LENGTH (tparms) == TREE_VEC_LENGTH (targs),
0);
/* If the template is in a namespace, we need to put that into the
mangled name. Unfortunately, build_decl_overload_real does not
get the decl to mangle, so it relies on the current
namespace. Therefore, we set that here temporarily. */
my_friendly_assert (DECL_P (decl), 980702);
saved_namespace = current_namespace;
current_namespace = CP_DECL_CONTEXT (decl);
/* Actually set the DCL_ASSEMBLER_NAME. */
DECL_ASSEMBLER_NAME (decl)
= build_decl_overload_real (DECL_NAME (decl), parm_types, ret_type,
= build_decl_overload_real (decl, parm_types, ret_type,
tparms, targs,
DECL_FUNCTION_MEMBER_P (decl)
+ DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl));
/* Restore the previously active namespace. */
current_namespace = saved_namespace;
}

View File

@ -2429,7 +2429,7 @@ special_function_p (decl)
return sfk_copy_constructor;
if (DECL_CONSTRUCTOR_P (decl))
return sfk_constructor;
if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
if (DECL_OVERLOADED_OPERATOR_P (decl) == NOP_EXPR)
return sfk_assignment_operator;
if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
return sfk_destructor;

View File

@ -6836,15 +6836,15 @@ check_return_expr (retval)
current_function_returns_null = 1;
/* Only operator new(...) throw(), can return NULL [expr.new/13]. */
if ((DECL_NAME (current_function_decl) == ansi_opname[(int) NEW_EXPR]
|| DECL_NAME (current_function_decl) == ansi_opname[(int) VEC_NEW_EXPR])
if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
|| DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
&& !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
&& null_ptr_cst_p (retval))
cp_warning ("`operator new' should throw an exception, not return NULL");
/* Effective C++ rule 15. See also start_function. */
if (warn_ecpp
&& DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR]
&& DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR)
&& retval != current_class_ref)
cp_warning ("`operator=' should return a reference to `*this'");

View File

@ -0,0 +1,6 @@
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
struct S {
bool operator! (int, ...); // ERROR -
};