From f2d71db6232200171b271499f0eeace035ad82cf Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 11 Sep 2000 14:19:53 +0000 Subject: [PATCH] cp-tree.h (frob_opname): Declare. * cp-tree.h (frob_opname): Declare. * parse.y (saved_scopes): New static variable. (cp_parse_init): Adjust. (do_id): If lastiddecl is NULL, do do_identifier. (operator): Save scope information. (unoperator): new reduction. Restore scope information. (operator_name): Append unoperator. Call frob_opname. * spew.c (frob_opname): Define. From-SVN: r36315 --- gcc/cp/ChangeLog | 11 ++++ gcc/cp/cp-tree.h | 1 + gcc/cp/parse.y | 159 +++++++++++++++++++++++++++++-------------------------- gcc/cp/spew.c | 36 +++++++++++++ 4 files changed, 133 insertions(+), 74 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c1cd621..e7a6acb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2000-09-11 Nathan Sidwell + + * cp-tree.h (frob_opname): Declare. + * parse.y (saved_scopes): New static variable. + (cp_parse_init): Adjust. + (do_id): If lastiddecl is NULL, do do_identifier. + (operator): Save scope information. + (unoperator): new reduction. Restore scope information. + (operator_name): Append unoperator. Call frob_opname. + * spew.c (frob_opname): Define. + 2000-09-10 Zack Weinberg * decl.c, rtti.c: Include defaults.h if not already included. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8dbb82e..97e3298 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4384,6 +4384,7 @@ extern void init_spew PARAMS ((void)); extern int peekyylex PARAMS ((void)); extern int yylex PARAMS ((void)); extern tree arbitrate_lookup PARAMS ((tree, tree, tree)); +extern tree frob_opname PARAMS ((tree)); /* in tree.c */ extern void init_tree PARAMS ((void)); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 5c69e10..bd3c9c5 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -78,6 +78,10 @@ static tree prefix_attributes; /* When defining an enumeration, this is the type of the enumeration. */ static tree current_enum_type; +/* When parsing a conversion operator name, this is the scope of the + operator itself. */ +static tree saved_scopes; + static tree empty_parms PARAMS ((void)); static tree parse_decl0 PARAMS ((tree, tree, tree, tree, int)); static tree parse_decl PARAMS ((tree, tree, int)); @@ -208,6 +212,7 @@ cp_parse_init () ggc_add_tree_root (¤t_declspecs, 1); ggc_add_tree_root (&prefix_attributes, 1); ggc_add_tree_root (¤t_enum_type, 1); + ggc_add_tree_root (&saved_scopes, 1); } %} @@ -1437,7 +1442,7 @@ do_id: means that we're in an expression like S::f, so don't do_identifier; we only do that for unqualified identifiers. */ - if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST) + if (!lastiddecl || TREE_CODE (lastiddecl) != TREE_LIST) $$ = do_identifier ($-1, 1, NULL_TREE); else $$ = $-1; @@ -3746,82 +3751,88 @@ conversion_declarator: ; operator: - OPERATOR - { got_scope = NULL_TREE; } - ; + OPERATOR + { saved_scopes = tree_cons (got_scope, got_object, saved_scopes); + got_scope = NULL_TREE; got_object = NULL_TREE; } + ; +unoperator: + { got_scope = TREE_PURPOSE (saved_scopes); + got_object = TREE_VALUE (saved_scopes); + saved_scopes = TREE_CHAIN (saved_scopes); } + ; operator_name: - operator '*' - { $$ = ansi_opname (MULT_EXPR); } - | operator '/' - { $$ = ansi_opname (TRUNC_DIV_EXPR); } - | operator '%' - { $$ = ansi_opname (TRUNC_MOD_EXPR); } - | operator '+' - { $$ = ansi_opname (PLUS_EXPR); } - | operator '-' - { $$ = ansi_opname (MINUS_EXPR); } - | operator '&' - { $$ = ansi_opname (BIT_AND_EXPR); } - | operator '|' - { $$ = ansi_opname (BIT_IOR_EXPR); } - | operator '^' - { $$ = ansi_opname (BIT_XOR_EXPR); } - | operator '~' - { $$ = ansi_opname (BIT_NOT_EXPR); } - | operator ',' - { $$ = ansi_opname (COMPOUND_EXPR); } - | operator ARITHCOMPARE - { $$ = ansi_opname ($2); } - | operator '<' - { $$ = ansi_opname (LT_EXPR); } - | operator '>' - { $$ = ansi_opname (GT_EXPR); } - | operator EQCOMPARE - { $$ = ansi_opname ($2); } - | operator ASSIGN - { $$ = ansi_assopname ($2); } - | operator '=' - { $$ = ansi_assopname (NOP_EXPR); } - | operator LSHIFT - { $$ = ansi_opname ($2); } - | operator RSHIFT - { $$ = ansi_opname ($2); } - | operator PLUSPLUS - { $$ = ansi_opname (POSTINCREMENT_EXPR); } - | operator MINUSMINUS - { $$ = ansi_opname (PREDECREMENT_EXPR); } - | operator ANDAND - { $$ = ansi_opname (TRUTH_ANDIF_EXPR); } - | operator OROR - { $$ = ansi_opname (TRUTH_ORIF_EXPR); } - | operator '!' - { $$ = ansi_opname (TRUTH_NOT_EXPR); } - | operator '?' ':' - { $$ = ansi_opname (COND_EXPR); } - | operator MIN_MAX - { $$ = ansi_opname ($2); } - | operator POINTSAT %prec EMPTY - { $$ = ansi_opname (COMPONENT_REF); } - | operator POINTSAT_STAR %prec EMPTY - { $$ = ansi_opname (MEMBER_REF); } - | operator LEFT_RIGHT - { $$ = ansi_opname (CALL_EXPR); } - | operator '[' ']' - { $$ = ansi_opname (ARRAY_REF); } - | operator NEW %prec EMPTY - { $$ = ansi_opname (NEW_EXPR); } - | operator DELETE %prec EMPTY - { $$ = ansi_opname (DELETE_EXPR); } - | operator NEW '[' ']' - { $$ = ansi_opname (VEC_NEW_EXPR); } - | operator DELETE '[' ']' - { $$ = ansi_opname (VEC_DELETE_EXPR); } + operator '*' unoperator + { $$ = frob_opname (ansi_opname (MULT_EXPR)); } + | operator '/' unoperator + { $$ = frob_opname (ansi_opname (TRUNC_DIV_EXPR)); } + | operator '%' unoperator + { $$ = frob_opname (ansi_opname (TRUNC_MOD_EXPR)); } + | operator '+' unoperator + { $$ = frob_opname (ansi_opname (PLUS_EXPR)); } + | operator '-' unoperator + { $$ = frob_opname (ansi_opname (MINUS_EXPR)); } + | operator '&' unoperator + { $$ = frob_opname (ansi_opname (BIT_AND_EXPR)); } + | operator '|' unoperator + { $$ = frob_opname (ansi_opname (BIT_IOR_EXPR)); } + | operator '^' unoperator + { $$ = frob_opname (ansi_opname (BIT_XOR_EXPR)); } + | operator '~' unoperator + { $$ = frob_opname (ansi_opname (BIT_NOT_EXPR)); } + | operator ',' unoperator + { $$ = frob_opname (ansi_opname (COMPOUND_EXPR)); } + | operator ARITHCOMPARE unoperator + { $$ = frob_opname (ansi_opname ($2)); } + | operator '<' unoperator + { $$ = frob_opname (ansi_opname (LT_EXPR)); } + | operator '>' unoperator + { $$ = frob_opname (ansi_opname (GT_EXPR)); } + | operator EQCOMPARE unoperator + { $$ = frob_opname (ansi_opname ($2)); } + | operator ASSIGN unoperator + { $$ = frob_opname (ansi_assopname ($2)); } + | operator '=' unoperator + { $$ = frob_opname (ansi_assopname (NOP_EXPR)); } + | operator LSHIFT unoperator + { $$ = frob_opname (ansi_opname ($2)); } + | operator RSHIFT unoperator + { $$ = frob_opname (ansi_opname ($2)); } + | operator PLUSPLUS unoperator + { $$ = frob_opname (ansi_opname (POSTINCREMENT_EXPR)); } + | operator MINUSMINUS unoperator + { $$ = frob_opname (ansi_opname (PREDECREMENT_EXPR)); } + | operator ANDAND unoperator + { $$ = frob_opname (ansi_opname (TRUTH_ANDIF_EXPR)); } + | operator OROR unoperator + { $$ = frob_opname (ansi_opname (TRUTH_ORIF_EXPR)); } + | operator '!' unoperator + { $$ = frob_opname (ansi_opname (TRUTH_NOT_EXPR)); } + | operator '?' ':' unoperator + { $$ = frob_opname (ansi_opname (COND_EXPR)); } + | operator MIN_MAX unoperator + { $$ = frob_opname (ansi_opname ($2)); } + | operator POINTSAT unoperator %prec EMPTY + { $$ = frob_opname (ansi_opname (COMPONENT_REF)); } + | operator POINTSAT_STAR unoperator %prec EMPTY + { $$ = frob_opname (ansi_opname (MEMBER_REF)); } + | operator LEFT_RIGHT unoperator + { $$ = frob_opname (ansi_opname (CALL_EXPR)); } + | operator '[' ']' unoperator + { $$ = frob_opname (ansi_opname (ARRAY_REF)); } + | operator NEW unoperator %prec EMPTY + { $$ = frob_opname (ansi_opname (NEW_EXPR)); } + | operator DELETE unoperator %prec EMPTY + { $$ = frob_opname (ansi_opname (DELETE_EXPR)); } + | operator NEW '[' ']' unoperator + { $$ = frob_opname (ansi_opname (VEC_NEW_EXPR)); } + | operator DELETE '[' ']' unoperator + { $$ = frob_opname (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); } + | operator type_specifier_seq conversion_declarator unoperator + { $$ = frob_opname (grokoptypename ($2.t, $3)); } + | operator error unoperator + { $$ = frob_opname (ansi_opname (ERROR_MARK)); } ; %% diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index 341f772..d6bf7bb 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -938,6 +938,42 @@ yyungetc (ch, rescan) } } +/* ID is an operator name. Duplicate the hackery in yylex to determine what + it really is. */ + +tree frob_opname (id) + tree id; +{ + tree trrr; + + if (yychar == '<') + looking_for_template = 1; + trrr = lookup_name (id, -2); + if (trrr) + { + switch (identifier_type (trrr)) + { + case TYPENAME: + case SELFNAME: + case NSNAME: + case PTYPENAME: + if (got_scope || got_object) + id = trrr; + case PFUNCNAME: + case IDENTIFIER: + lastiddecl = trrr; + break; + default: + my_friendly_abort (20000907); + } + } + else + lastiddecl = NULL_TREE; + got_scope = NULL_TREE; + got_object = NULL_TREE; + looking_for_template = 0; + return id; +} /* Set up the state required to correctly handle the definition of the inline function whose preparsed state has been saved in PI. */ -- 2.7.4