summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2019-11-05 18:56:18 -0500
committerJason Merrill <jason@gcc.gnu.org>2019-11-05 18:56:18 -0500
commitb7689b962dd6536bbb2567bfdec52e35109af7ab (patch)
tree6a00e1710db7a55cbcfec28cfbaf837950a9c70b /libcpp
parentb63566a4045e9cc27f739c89f863dbfb9dbe7860 (diff)
Implement C++20 operator<=>.
There are three major pieces to this support: scalar operator<=>, synthesis of comparison operators, and rewritten/reversed overload resolution (e.g. a < b becomes 0 > b <=> a). Unlike other defaulted functions, where we use synthesized_method_walk to semi-simulate what the definition of the function will be like, this patch determines the characteristics of a comparison operator by trying to define it. My handling of non-dependent rewritten operators in templates can still use some work: build_min_non_dep_op_overload can't understand the rewrites and crashes, so I'm avoiding it for now by clearing *overload. This means we'll do name lookup again at instantiation time, which can incorrectly mean a different result. I'll poke at this more in stage 3. I'm leaving out a fourth section ("strong structural equality") even though I've implemented it, because it seems likely to change radically tomorrow. Thanks to Tim van Deurzen and Jakub for implementing lexing of the <=> operator, and Jonathan for the initial <compare> header. gcc/cp/ * cp-tree.h (struct lang_decl_fn): Add maybe_deleted bitfield. (DECL_MAYBE_DELETED): New. (enum special_function_kind): Add sfk_comparison. (LOOKUP_REWRITTEN, LOOKUP_REVERSED): New. * call.c (struct z_candidate): Add rewritten and reversed methods. (add_builtin_candidate): Handle SPACESHIP_EXPR. (add_builtin_candidates): Likewise. (add_candidates): Don't add a reversed candidate if the parms are the same. (add_operator_candidates): Split out from build_new_op_1. Handle rewritten and reversed candidates. (add_candidate): Swap conversions of reversed candidate. (build_new_op_1): Swap them back. Build a second operation for rewritten candidates. (extract_call_expr): Handle rewritten calls. (same_fn_or_template): New. (joust): Handle rewritten and reversed candidates. * class.c (add_implicitly_declared_members): Add implicit op==. (classtype_has_op, classtype_has_defaulted_op): New. * constexpr.c (cxx_eval_binary_expression): Handle SPACESHIP_EXPR. (cxx_eval_constant_expression, potential_constant_expression_1): Likewise. * cp-gimplify.c (genericize_spaceship): New. (cp_genericize_r): Use it. * cp-objcp-common.c (cp_common_init_ts): Handle SPACESHIP_EXPR. * decl.c (finish_function): Handle deleted function. * decl2.c (grokfield): SET_DECL_FRIEND_CONTEXT on defaulted friend. (mark_used): Check DECL_MAYBE_DELETED. Remove assumption that defaulted functions are non-static members. * error.c (dump_expr): Handle SPACESHIP_EXPR. * method.c (type_has_trivial_fn): False for sfk_comparison. (enum comp_cat_tag, struct comp_cat_info_t): New types. (comp_cat_cache): New array variable. (lookup_comparison_result, lookup_comparison_category) (is_cat, cat_tag_for, spaceship_comp_cat) (spaceship_type, genericize_spaceship) (common_comparison_type, early_check_defaulted_comparison) (comp_info, build_comparison_op): New. (synthesize_method): Handle sfk_comparison. Handle deleted. (get_defaulted_eh_spec, maybe_explain_implicit_delete) (explain_implicit_non_constexpr, implicitly_declare_fn) (defaulted_late_check, defaultable_fn_check): Handle sfk_comparison. * name-lookup.c (get_std_name_hint): Add comparison categories. * tree.c (special_function_p): Add sfk_comparison. * typeck.c (cp_build_binary_op): Handle SPACESHIP_EXPR. 2019-11-05 Tim van Deurzen <tim@kompiler.org> Add new tree code for the spaceship operator. gcc/cp/ * cp-tree.def: Add new tree code. * operators.def: New binary operator. * parser.c: Add new token and tree code. libcpp/ * cpplib.h: Add spaceship operator for C++. * lex.c: Implement conditional lexing of spaceship operator for C++20. 2019-11-05 Jonathan Wakely <jwakely@redhat.com> libstdc++-v3/ * libsupc++/compare: New header. * libsupc++/Makefile.am (std_HEADERS): Add compare. * include/std/version: Define __cpp_lib_three_way_comparison. * include/std/functional: #include <compare>. From-SVN: r277865
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog5
-rw-r--r--libcpp/include/cpplib.h1
-rw-r--r--libcpp/lex.c9
3 files changed, 14 insertions, 1 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index a13f7508599..8be84386d6c 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-05 Tim van Deurzen <tim@kompiler.org>
+
+ * cpplib.h: Add spaceship operator for C++.
+ * lex.c: Implement conditional lexing of spaceship operator for C++20.
+
2019-10-31 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/92296
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index c655d3ffc90..ed108f17bfa 100644
--- a/libcpp/include/cpplib.h
+++ b/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 a/libcpp/lex.c b/libcpp/lex.c
index 3e7d1c37ff5..e95eda3f44e 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -2980,7 +2980,13 @@ _cpp_lex_direct (cpp_reader *pfile)
result->type = CPP_LESS;
if (*buffer->cur == '=')
- buffer->cur++, result->type = CPP_LESS_EQ;
+ {
+ buffer->cur++, result->type = CPP_LESS_EQ;
+ if (*buffer->cur == '>'
+ && CPP_OPTION (pfile, cplusplus)
+ && CPP_OPTION (pfile, lang) >= CLK_GNUCXX2A)
+ buffer->cur++, result->type = CPP_SPACESHIP;
+ }
else if (*buffer->cur == '<')
{
buffer->cur++;
@@ -3491,6 +3497,7 @@ cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1,
|| (CPP_OPTION (pfile, objc)
&& token1->val.str.text[0] == '@'
&& (b == CPP_NAME || b == CPP_STRING)));
+ case CPP_LESS_EQ: return c == '>';
case CPP_STRING:
case CPP_WSTRING:
case CPP_UTF8STRING: