]> granicus.if.org Git - clang/commitdiff
[c++2a] P0515R3: Support for overloaded operator<=>.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 1 Dec 2017 02:13:10 +0000 (02:13 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 1 Dec 2017 02:13:10 +0000 (02:13 +0000)
No CodeGen support for MSABI yet, we don't know how to mangle this there.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@319513 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/OperatorKinds.def
lib/AST/ItaniumMangle.cpp
lib/AST/MicrosoftMangle.cpp
lib/AST/StmtProfile.cpp
lib/Parse/ParseExprCXX.cpp
lib/Sema/SemaOpenMP.cpp
lib/Sema/SemaOverload.cpp
test/CodeGenCXX/cxx2a-three-way-comparison.cpp [new file with mode: 0644]
test/Lexer/cxx2a-spaceship.cpp
test/SemaCXX/cxx2a-three-way-comparison.cpp [new file with mode: 0644]

index 34ad7644cd2bafa480d9253cd81e368e582c2118..d86294bac90201e02d87fc05bf106db3c888a9a7 100644 (file)
@@ -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)
index 58e2bc8a39ba5dc9d3229011bfefbb85906c5dc5..f95dc8458e8a884b785abd2995e030a440b3404d 100644 (file)
@@ -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:
index c8048544ab8ffb874e2e770e0b656d34aab0708d..0c55c1a922873c473d5a2c2408524526b979cf80 100644 (file)
@@ -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,
index 6cc77f682ee7b7c04e965d0916f68fbb0153a23e..00ef0da18bbbf90cd0a8fb0ccd947cb9668b3c59 100644 (file)
@@ -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;
index ad4801971aa559a0bd4da5907dd3288397140f83..c3199f28cfc71a866aab61e42cf15c6c948e6bdc 100644 (file)
@@ -2184,7 +2184,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
 ///            !     =    <  >    += -=   *=  /=  %=
 ///            ^=    &=   |= <<   >> >>= <<=  ==  !=
 ///            <=    >=   && ||   ++ --   ,   ->* ->
-///            ()    []
+///            ()    []   <=>
 ///
 ///       conversion-function-id: [C++ 12.3.2]
 ///         operator conversion-type-id
index fb60ebf23ac9463eb92e3da45c2571b9c292695c..f0b43f068533e9a54677ba3b1286a3007cb9a2be 100644 (file)
@@ -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:
index fa6279800dc8adab5b1ab42330c0c8c3f95d5397..8680d3d0d2704f6ba98f8a79a71b29ff7af78319 100644 (file)
@@ -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/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
new file mode 100644 (file)
index 0000000..08ab41b
--- /dev/null
@@ -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) {}
index f407937c4e317c185b49ce98ac5ff72ff5b5c20f..604575ee976b75f72de57798dc2b766991d90154 100644 (file)
@@ -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/test/SemaCXX/cxx2a-three-way-comparison.cpp b/test/SemaCXX/cxx2a-three-way-comparison.cpp
new file mode 100644 (file)
index 0000000..eb1480c
--- /dev/null
@@ -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);