diff options
author | Alex Samuel <samuel@codesourcery.com> | 2000-05-28 02:58:19 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2000-05-28 02:58:19 +0000 |
commit | 596ea4e574aa9177437b95dcb2412e0673df8c0a (patch) | |
tree | e69d1900e45d7c20303ea928d731e1f70c7ec263 /gcc | |
parent | 4f1c5cce901c4d53fb9130183ca275ef1d04fe8a (diff) | |
download | gcc-596ea4e574aa9177437b95dcb2412e0673df8c0a.zip gcc-596ea4e574aa9177437b95dcb2412e0673df8c0a.tar.gz gcc-596ea4e574aa9177437b95dcb2412e0673df8c0a.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 84 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 3 | ||||
-rw-r--r-- | gcc/cp/Makefile.in | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 31 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 71 | ||||
-rw-r--r-- | gcc/cp/decl.c | 337 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/error.c | 40 | ||||
-rw-r--r-- | gcc/cp/init.c | 2 | ||||
-rw-r--r-- | gcc/cp/lex.c | 360 | ||||
-rw-r--r-- | gcc/cp/method.c | 105 | ||||
-rw-r--r-- | gcc/cp/operators.def | 153 | ||||
-rw-r--r-- | gcc/cp/parse.c | 68 | ||||
-rw-r--r-- | gcc/cp/parse.y | 68 | ||||
-rw-r--r-- | gcc/cp/pt.c | 16 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/op1.C | 6 |
18 files changed, 752 insertions, 606 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d843b3e..08a9bce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index e36dc5e..0d6fae8 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -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: diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index e8a43fa..5284e7d 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -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 \ diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a034f52..2bd5c81 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 810d174..347cde8 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index eecf36d..25270d4 100644 --- a/gcc/cp/decl.c +++ b/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; - } - - if (name == ansi_opname[(int) NEW_EXPR] - || name == ansi_opname[(int) VEC_NEW_EXPR]) + 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 (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 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 11250e7..6a90a0a 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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)))); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index bfd921f..f4c116b 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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 * diff --git a/gcc/cp/init.c b/gcc/cp/init.c index cc5be91..073aa68 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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 diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 279b42d..e9cd519 100644 --- a/gcc/cp/lex.c +++ b/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; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 1f595e0..13d627a 100644 --- a/gcc/cp/method.c +++ b/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; + + operator_code = DECL_OVERLOADED_OPERATOR_P (decl); + if (!DECL_CONV_FN_P (decl) && operator_code) + { + /* 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; + } - /* 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) - { - 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"); + 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, diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def new file mode 100644 index 0000000..1ad8d04 --- /dev/null +++ b/gcc/cp/operators.def @@ -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) + diff --git a/gcc/cp/parse.c b/gcc/cp/parse.c index 407025e..9cb24dd 100644 --- a/gcc/cp/parse.c +++ b/gcc/cp/parse.c @@ -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 */ diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 65b90bb..6f26be4 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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); } ; %% diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5e2ff5e..b64fc72 100644 --- a/gcc/cp/pt.c +++ b/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; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index b62fc61..382e254 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c0927ef..28ac0f3 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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'"); diff --git a/gcc/testsuite/g++.old-deja/g++.other/op1.C b/gcc/testsuite/g++.old-deja/g++.other/op1.C new file mode 100644 index 0000000..cf36886 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/op1.C @@ -0,0 +1,6 @@ +// Build don't link: +// Origin: Mark Mitchell <mark@codesourcery.com> + +struct S { + bool operator! (int, ...); // ERROR - +}; |