aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2000-09-11 14:19:53 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2000-09-11 14:19:53 +0000
commitf2d71db6232200171b271499f0eeace035ad82cf (patch)
treed694dbd8f3fee17d98c37d0b5bd6a07b08dafac4
parente695931e414bab5105d78004a68bb5a0c00975cc (diff)
downloadgcc-f2d71db6232200171b271499f0eeace035ad82cf.zip
gcc-f2d71db6232200171b271499f0eeace035ad82cf.tar.gz
gcc-f2d71db6232200171b271499f0eeace035ad82cf.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/parse.y159
-rw-r--r--gcc/cp/spew.c36
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 <nathan@codesourcery.com>
+
+ * 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 <zack@wolery.cumb.org>
* 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 (&current_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
ggc_add_tree_root (&current_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<int>, 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 ($<ttype>-1, 1, NULL_TREE);
else
$$ = $<ttype>-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. */