Hello all, I've been getting to know my way around the c++ compiler front-end while implementing the spaceship operator. To ensure this feature is part of the next release I'm including my work so far as a patch. Testing and development are still very much ongoing.
This patch adds only the new token from the pre-pocessor and its recognition / use in the C++ front-end. Tim. diff --git gcc/cp/ChangeLog gcc/cp/ChangeLog index b0dc668d9df..cb5ab8feb05 100644 --- gcc/cp/ChangeLog +++ gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2018-11-05 Tim van Deurzen <t...@kompiler.org> + + Add new tree code for the spaceship operator. + * cp-tree.def: Add new tree code. + Add new operator. + * operators.def: New binary operator. + Implement parsing of the spaceship operator. + * parser.c: Add new token and tree code. + 2018-11-04 Jason Merrill <ja...@redhat.com> Implement UDL changes from P0732R2. diff --git gcc/cp/cp-tree.def gcc/cp/cp-tree.def index c64225ded6f..6da2d6b9b38 100644 --- gcc/cp/cp-tree.def +++ gcc/cp/cp-tree.def @@ -594,6 +594,7 @@ DEFTREECODE (PARM_CONSTR, "parm_constr", tcc_expression, 2) DEFTREECODE (CONJ_CONSTR, "conj_constr", tcc_expression, 2) DEFTREECODE (DISJ_CONSTR, "disj_constr", tcc_expression, 2) +DEFTREECODE (SPACESHIP_EXPR, "spaceship_expr", tcc_expression, 2) /* Local variables: diff --git gcc/cp/operators.def gcc/cp/operators.def index 07f586b1c28..ac96e27c124 100644 --- gcc/cp/operators.def +++ gcc/cp/operators.def @@ -110,6 +110,7 @@ DEF_OPERATOR ("<", LT_EXPR, "lt", OVL_OP_FLAG_BINARY) DEF_OPERATOR (">", GT_EXPR, "gt", OVL_OP_FLAG_BINARY) DEF_OPERATOR ("<=", LE_EXPR, "le", OVL_OP_FLAG_BINARY) DEF_OPERATOR (">=", GE_EXPR, "ge", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("<=>", SPACESHIP_EXPR, "le", OVL_OP_FLAG_BINARY) DEF_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", OVL_OP_FLAG_BINARY) DEF_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", OVL_OP_FLAG_BINARY) DEF_OPERATOR (",", COMPOUND_EXPR, "cm", OVL_OP_FLAG_BINARY) diff --git gcc/cp/parser.c gcc/cp/parser.c index 30a47662f55..c0de47a7550 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -1893,6 +1893,8 @@ static const cp_parser_binary_operations_map_node binops[] = { { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, + /* FIXME check precedence of spaceship operator. */ + { CPP_SPACESHIP, SPACESHIP_EXPR, PREC_RELATIONAL_EXPRESSION }, { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION }, { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION }, { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION }, @@ -15052,6 +15054,10 @@ cp_parser_operator (cp_parser* parser) op = GE_EXPR; break; + case CPP_SPACESHIP: + op = SPACESHIP_EXPR; + break; + case CPP_AND_AND: op = TRUTH_ANDIF_EXPR; break; diff --git libcpp/ChangeLog libcpp/ChangeLog index 4f280471ba4..5a73b66b3e8 100644 --- libcpp/ChangeLog +++ libcpp/ChangeLog @@ -1,3 +1,7 @@ +2018-11-05 Tim van Deurzen <t...@kompiler.org> + * cpplib.h: Add spaceship operator for C++. + * lex.c: Implement conditional lexing of spaceship operator for C++20. + 2018-11-05 Martin Liska <mli...@suse.cz> * symtab.c (ht_dump_statistics): Replace %zu with %lu format. diff --git libcpp/include/cpplib.h libcpp/include/cpplib.h index aad836d2192..55869278f5f 100644 --- libcpp/include/cpplib.h +++ libcpp/include/cpplib.h @@ -78,6 +78,7 @@ struct _cpp_file; OP(NOT_EQ, "!=") \ OP(GREATER_EQ, ">=") \ OP(LESS_EQ, "<=") \ + OP(SPACESHIP, "<=>") \ \ /* These two are unary + / - in preprocessor expressions. */ \ OP(PLUS_EQ, "+=") /* math */ \ diff --git libcpp/lex.c libcpp/lex.c index c6e34b33343..b6423d15cc6 100644 --- libcpp/lex.c +++ libcpp/lex.c @@ -2963,7 +2963,14 @@ _cpp_lex_direct (cpp_reader *pfile) result->type = CPP_LESS; if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_LESS_EQ; + if (CPP_OPTION(pfile, cplusplus) + && (CPP_OPTION(pfile, lang) == CLK_CXX2A || CPP_OPTION(pfile, lang) == CLK_GNUCXX2A) + && buffer->cur[1] == '>') + { + buffer->cur += 2, result->type = CPP_SPACESHIP; + } else { + buffer->cur++, result->type = CPP_LESS_EQ; + } else if (*buffer->cur == '<') { buffer->cur++;
diff --git gcc/cp/ChangeLog gcc/cp/ChangeLog index b0dc668d9df..cb5ab8feb05 100644 --- gcc/cp/ChangeLog +++ gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2018-11-05 Tim van Deurzen <t...@kompiler.org> + + Add new tree code for the spaceship operator. + * cp-tree.def: Add new tree code. + Add new operator. + * operators.def: New binary operator. + Implement parsing of the spaceship operator. + * parser.c: Add new token and tree code. + 2018-11-04 Jason Merrill <ja...@redhat.com> Implement UDL changes from P0732R2. diff --git gcc/cp/cp-tree.def gcc/cp/cp-tree.def index c64225ded6f..6da2d6b9b38 100644 --- gcc/cp/cp-tree.def +++ gcc/cp/cp-tree.def @@ -594,6 +594,7 @@ DEFTREECODE (PARM_CONSTR, "parm_constr", tcc_expression, 2) DEFTREECODE (CONJ_CONSTR, "conj_constr", tcc_expression, 2) DEFTREECODE (DISJ_CONSTR, "disj_constr", tcc_expression, 2) +DEFTREECODE (SPACESHIP_EXPR, "spaceship_expr", tcc_expression, 2) /* Local variables: diff --git gcc/cp/operators.def gcc/cp/operators.def index 07f586b1c28..ac96e27c124 100644 --- gcc/cp/operators.def +++ gcc/cp/operators.def @@ -110,6 +110,7 @@ DEF_OPERATOR ("<", LT_EXPR, "lt", OVL_OP_FLAG_BINARY) DEF_OPERATOR (">", GT_EXPR, "gt", OVL_OP_FLAG_BINARY) DEF_OPERATOR ("<=", LE_EXPR, "le", OVL_OP_FLAG_BINARY) DEF_OPERATOR (">=", GE_EXPR, "ge", OVL_OP_FLAG_BINARY) +DEF_OPERATOR ("<=>", SPACESHIP_EXPR, "le", OVL_OP_FLAG_BINARY) DEF_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", OVL_OP_FLAG_BINARY) DEF_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", OVL_OP_FLAG_BINARY) DEF_OPERATOR (",", COMPOUND_EXPR, "cm", OVL_OP_FLAG_BINARY) diff --git gcc/cp/parser.c gcc/cp/parser.c index 30a47662f55..c0de47a7550 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -1893,6 +1893,8 @@ static const cp_parser_binary_operations_map_node binops[] = { { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, + /* FIXME check precedence of spaceship operator. */ + { CPP_SPACESHIP, SPACESHIP_EXPR, PREC_RELATIONAL_EXPRESSION }, { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION }, { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION }, { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION }, @@ -15052,6 +15054,10 @@ cp_parser_operator (cp_parser* parser) op = GE_EXPR; break; + case CPP_SPACESHIP: + op = SPACESHIP_EXPR; + break; + case CPP_AND_AND: op = TRUTH_ANDIF_EXPR; break; diff --git libcpp/ChangeLog libcpp/ChangeLog index 4f280471ba4..5a73b66b3e8 100644 --- libcpp/ChangeLog +++ libcpp/ChangeLog @@ -1,3 +1,7 @@ +2018-11-05 Tim van Deurzen <t...@kompiler.org> + * cpplib.h: Add spaceship operator for C++. + * lex.c: Implement conditional lexing of spaceship operator for C++20. + 2018-11-05 Martin Liska <mli...@suse.cz> * symtab.c (ht_dump_statistics): Replace %zu with %lu format. diff --git libcpp/include/cpplib.h libcpp/include/cpplib.h index aad836d2192..55869278f5f 100644 --- libcpp/include/cpplib.h +++ libcpp/include/cpplib.h @@ -78,6 +78,7 @@ struct _cpp_file; OP(NOT_EQ, "!=") \ OP(GREATER_EQ, ">=") \ OP(LESS_EQ, "<=") \ + OP(SPACESHIP, "<=>") \ \ /* These two are unary + / - in preprocessor expressions. */ \ OP(PLUS_EQ, "+=") /* math */ \ diff --git libcpp/lex.c libcpp/lex.c index c6e34b33343..b6423d15cc6 100644 --- libcpp/lex.c +++ libcpp/lex.c @@ -2963,7 +2963,14 @@ _cpp_lex_direct (cpp_reader *pfile) result->type = CPP_LESS; if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_LESS_EQ; + if (CPP_OPTION(pfile, cplusplus) + && (CPP_OPTION(pfile, lang) == CLK_CXX2A || CPP_OPTION(pfile, lang) == CLK_GNUCXX2A) + && buffer->cur[1] == '>') + { + buffer->cur += 2, result->type = CPP_SPACESHIP; + } else { + buffer->cur++, result->type = CPP_LESS_EQ; + } else if (*buffer->cur == '<') { buffer->cur++;