summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/OperatorKinds.def1
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp3
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp9
-rw-r--r--clang/lib/AST/StmtProfile.cpp4
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp2
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp1
-rw-r--r--clang/lib/Sema/SemaOverload.cpp3
-rw-r--r--clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp13
-rw-r--r--clang/test/Lexer/cxx2a-spaceship.cpp4
-rw-r--r--clang/test/SemaCXX/cxx2a-three-way-comparison.cpp24
10 files changed, 61 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/OperatorKinds.def b/clang/include/clang/Basic/OperatorKinds.def
index 34ad7644cd2..d86294bac90 100644
--- a/clang/include/clang/Basic/OperatorKinds.def
+++ b/clang/include/clang/Basic/OperatorKinds.def
@@ -89,6 +89,7 @@ OVERLOADED_OPERATOR(EqualEqual , "==" , equalequal , false, t
OVERLOADED_OPERATOR(ExclaimEqual , "!=" , exclaimequal , false, true , false)
OVERLOADED_OPERATOR(LessEqual , "<=" , lessequal , false, true , false)
OVERLOADED_OPERATOR(GreaterEqual , ">=" , greaterequal , false, true , false)
+OVERLOADED_OPERATOR(Spaceship , "<=>" , spaceship , false, true , false)
OVERLOADED_OPERATOR(AmpAmp , "&&" , ampamp , false, true , false)
OVERLOADED_OPERATOR(PipePipe , "||" , pipepipe , false, true , false)
OVERLOADED_OPERATOR(PlusPlus , "++" , plusplus , true , true , false)
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 58e2bc8a39b..f95dc8458e8 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2195,6 +2195,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
// Proposal on cxx-abi-dev, 2015-10-21.
// ::= aw # co_await
case OO_Coawait: Out << "aw"; break;
+ // Proposed in cxx-abi github issue 43.
+ // ::= ss # <=>
+ case OO_Spaceship: Out << "ss"; break;
case OO_None:
case NUM_OVERLOADED_OPERATORS:
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index c8048544ab8..0c55c1a9228 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1192,6 +1192,15 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
// <operator-name> ::= ?__L # co_await
case OO_Coawait: Out << "?__L"; break;
+ case OO_Spaceship: {
+ // FIXME: Once MS picks a mangling, use it.
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle this three-way comparison operator yet");
+ Diags.Report(Loc, DiagID);
+ break;
+ }
+
case OO_Conditional: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 6cc77f682ee..00ef0da18bb 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1384,6 +1384,10 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
case OO_GreaterEqual:
BinaryOp = BO_GE;
return Stmt::BinaryOperatorClass;
+
+ case OO_Spaceship:
+ // FIXME: Update this once we support <=> expressions.
+ llvm_unreachable("<=> expressions not supported yet");
case OO_AmpAmp:
BinaryOp = BO_LAnd;
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index ad4801971aa..c3199f28cfc 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2184,7 +2184,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
/// ! = < > += -= *= /= %=
/// ^= &= |= << >> >>= <<= == !=
/// <= >= && || ++ -- , ->* ->
-/// () []
+/// () [] <=>
///
/// conversion-function-id: [C++ 12.3.2]
/// operator conversion-type-id
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index fb60ebf23ac..f0b43f06853 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -9902,6 +9902,7 @@ static bool ActOnOMPReductionKindClause(
case OO_GreaterGreaterEqual:
case OO_EqualEqual:
case OO_ExclaimEqual:
+ case OO_Spaceship:
case OO_PlusPlus:
case OO_MinusMinus:
case OO_Comma:
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index fa6279800dc..8680d3d0d27 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -8692,6 +8692,9 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
OpBuilder.addGenericBinaryArithmeticOverloads();
break;
+ case OO_Spaceship:
+ llvm_unreachable("<=> expressions not supported yet");
+
case OO_Percent:
case OO_Caret:
case OO_Pipe:
diff --git a/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
new file mode 100644
index 00000000000..08ab41b1eaa
--- /dev/null
+++ b/clang/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
+// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %ms_abi_triple 2>&1 | FileCheck %s --check-prefix=MSABI
+// MSABI: cannot mangle this three-way comparison operator yet
+
+struct A {
+ void operator<=>(int);
+};
+
+// ITANIUM: define {{.*}}@_ZN1AssEi(
+void A::operator<=>(int) {}
+
+// ITANIUM: define {{.*}}@_Zssi1A(
+void operator<=>(int, A) {}
diff --git a/clang/test/Lexer/cxx2a-spaceship.cpp b/clang/test/Lexer/cxx2a-spaceship.cpp
index f407937c4e3..604575ee976 100644
--- a/clang/test/Lexer/cxx2a-spaceship.cpp
+++ b/clang/test/Lexer/cxx2a-spaceship.cpp
@@ -10,7 +10,7 @@ namespace N {
struct A {};
void operator<=(A, A);
#if __cplusplus > 201703L
-void operator<=>(A, A); // expected-error {{}}
+void operator<=>(A, A);
#ifdef COMPAT
// expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++2a}}
#endif
@@ -21,7 +21,7 @@ X<operator<=>
#if __cplusplus <= 201703L
// expected-warning@-2 {{'<=>' is a single token in C++2a; add a space to avoid a change in behavior}}
#else
- > // expected-error@-4 {{}}
+ >
#endif
#ifdef COMPAT
// expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++2a}}
diff --git a/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp b/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp
new file mode 100644
index 00000000000..eb1480ce610
--- /dev/null
+++ b/clang/test/SemaCXX/cxx2a-three-way-comparison.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+struct A {};
+constexpr int operator<=>(A a, A b) { return 42; }
+static_assert(operator<=>(A(), A()) == 42);
+
+int operator<=>(); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}}
+int operator<=>(A); // expected-error {{overloaded 'operator<=>' must be a binary operator}}
+int operator<=>(int, int); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}}
+int operator<=>(A, A, A); // expected-error {{overloaded 'operator<=>' must be a binary operator}}
+int operator<=>(A, A, ...); // expected-error {{overloaded 'operator<=>' cannot be variadic}}
+int operator<=>(int, A = {}); // expected-error {{parameter of overloaded 'operator<=>' cannot have a default argument}}
+
+struct B {
+ int &operator<=>(int);
+ friend int operator<=>(A, B);
+
+ friend int operator<=>(int, int); // expected-error {{overloaded 'operator<=>' must have at least one parameter of class or enumeration type}}
+ void operator<=>(); // expected-error {{overloaded 'operator<=>' must be a binary operator}};
+ void operator<=>(A, ...); // expected-error {{overloaded 'operator<=>' cannot be variadic}}
+ void operator<=>(A, A); // expected-error {{overloaded 'operator<=>' must be a binary operator}};
+};
+
+int &r = B().operator<=>(0);
OpenPOWER on IntegriCloud