mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-08 14:27:40 +08:00
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:
parent
4f1c5cce90
commit
596ea4e574
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
333
gcc/cp/decl.c
333
gcc/cp/decl.c
@ -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
|
||||
|
@ -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))));
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
360
gcc/cp/lex.c
360
gcc/cp/lex.c
@ -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;
|
||||
}
|
||||
|
103
gcc/cp/method.c
103
gcc/cp/method.c
@ -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
153
gcc/cp/operators.def
Normal 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)
|
||||
|
@ -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 */
|
||||
|
@ -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); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
16
gcc/cp/pt.c
16
gcc/cp/pt.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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'");
|
||||
|
||||
|
6
gcc/testsuite/g++.old-deja/g++.other/op1.C
Normal file
6
gcc/testsuite/g++.old-deja/g++.other/op1.C
Normal file
@ -0,0 +1,6 @@
|
||||
// Build don't link:
|
||||
// Origin: Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
struct S {
|
||||
bool operator! (int, ...); // ERROR -
|
||||
};
|
Loading…
Reference in New Issue
Block a user