forked from OSchip/llvm-project
[c++2a] P0515R3: Support for overloaded operator<=>.
No CodeGen support for MSABI yet, we don't know how to mangle this there. llvm-svn: 319513
This commit is contained in:
parent
69989bdbf2
commit
d30b23d6a5
|
@ -89,6 +89,7 @@ OVERLOADED_OPERATOR(EqualEqual , "==" , equalequal , false, t
|
||||||
OVERLOADED_OPERATOR(ExclaimEqual , "!=" , exclaimequal , false, true , false)
|
OVERLOADED_OPERATOR(ExclaimEqual , "!=" , exclaimequal , false, true , false)
|
||||||
OVERLOADED_OPERATOR(LessEqual , "<=" , lessequal , false, true , false)
|
OVERLOADED_OPERATOR(LessEqual , "<=" , lessequal , false, true , false)
|
||||||
OVERLOADED_OPERATOR(GreaterEqual , ">=" , greaterequal , 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(AmpAmp , "&&" , ampamp , false, true , false)
|
||||||
OVERLOADED_OPERATOR(PipePipe , "||" , pipepipe , false, true , false)
|
OVERLOADED_OPERATOR(PipePipe , "||" , pipepipe , false, true , false)
|
||||||
OVERLOADED_OPERATOR(PlusPlus , "++" , plusplus , true , true , false)
|
OVERLOADED_OPERATOR(PlusPlus , "++" , plusplus , true , true , false)
|
||||||
|
|
|
@ -2195,6 +2195,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
|
||||||
// Proposal on cxx-abi-dev, 2015-10-21.
|
// Proposal on cxx-abi-dev, 2015-10-21.
|
||||||
// ::= aw # co_await
|
// ::= aw # co_await
|
||||||
case OO_Coawait: Out << "aw"; break;
|
case OO_Coawait: Out << "aw"; break;
|
||||||
|
// Proposed in cxx-abi github issue 43.
|
||||||
|
// ::= ss # <=>
|
||||||
|
case OO_Spaceship: Out << "ss"; break;
|
||||||
|
|
||||||
case OO_None:
|
case OO_None:
|
||||||
case NUM_OVERLOADED_OPERATORS:
|
case NUM_OVERLOADED_OPERATORS:
|
||||||
|
|
|
@ -1192,6 +1192,15 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
|
||||||
// <operator-name> ::= ?__L # co_await
|
// <operator-name> ::= ?__L # co_await
|
||||||
case OO_Coawait: Out << "?__L"; break;
|
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: {
|
case OO_Conditional: {
|
||||||
DiagnosticsEngine &Diags = Context.getDiags();
|
DiagnosticsEngine &Diags = Context.getDiags();
|
||||||
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
|
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
|
||||||
|
|
|
@ -1385,6 +1385,10 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
|
||||||
BinaryOp = BO_GE;
|
BinaryOp = BO_GE;
|
||||||
return Stmt::BinaryOperatorClass;
|
return Stmt::BinaryOperatorClass;
|
||||||
|
|
||||||
|
case OO_Spaceship:
|
||||||
|
// FIXME: Update this once we support <=> expressions.
|
||||||
|
llvm_unreachable("<=> expressions not supported yet");
|
||||||
|
|
||||||
case OO_AmpAmp:
|
case OO_AmpAmp:
|
||||||
BinaryOp = BO_LAnd;
|
BinaryOp = BO_LAnd;
|
||||||
return Stmt::BinaryOperatorClass;
|
return Stmt::BinaryOperatorClass;
|
||||||
|
|
|
@ -2184,7 +2184,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
|
||||||
/// ! = < > += -= *= /= %=
|
/// ! = < > += -= *= /= %=
|
||||||
/// ^= &= |= << >> >>= <<= == !=
|
/// ^= &= |= << >> >>= <<= == !=
|
||||||
/// <= >= && || ++ -- , ->* ->
|
/// <= >= && || ++ -- , ->* ->
|
||||||
/// () []
|
/// () [] <=>
|
||||||
///
|
///
|
||||||
/// conversion-function-id: [C++ 12.3.2]
|
/// conversion-function-id: [C++ 12.3.2]
|
||||||
/// operator conversion-type-id
|
/// operator conversion-type-id
|
||||||
|
|
|
@ -9902,6 +9902,7 @@ static bool ActOnOMPReductionKindClause(
|
||||||
case OO_GreaterGreaterEqual:
|
case OO_GreaterGreaterEqual:
|
||||||
case OO_EqualEqual:
|
case OO_EqualEqual:
|
||||||
case OO_ExclaimEqual:
|
case OO_ExclaimEqual:
|
||||||
|
case OO_Spaceship:
|
||||||
case OO_PlusPlus:
|
case OO_PlusPlus:
|
||||||
case OO_MinusMinus:
|
case OO_MinusMinus:
|
||||||
case OO_Comma:
|
case OO_Comma:
|
||||||
|
|
|
@ -8692,6 +8692,9 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
|
||||||
OpBuilder.addGenericBinaryArithmeticOverloads();
|
OpBuilder.addGenericBinaryArithmeticOverloads();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OO_Spaceship:
|
||||||
|
llvm_unreachable("<=> expressions not supported yet");
|
||||||
|
|
||||||
case OO_Percent:
|
case OO_Percent:
|
||||||
case OO_Caret:
|
case OO_Caret:
|
||||||
case OO_Pipe:
|
case OO_Pipe:
|
||||||
|
|
|
@ -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) {}
|
|
@ -10,7 +10,7 @@ namespace N {
|
||||||
struct A {};
|
struct A {};
|
||||||
void operator<=(A, A);
|
void operator<=(A, A);
|
||||||
#if __cplusplus > 201703L
|
#if __cplusplus > 201703L
|
||||||
void operator<=>(A, A); // expected-error {{}}
|
void operator<=>(A, A);
|
||||||
#ifdef COMPAT
|
#ifdef COMPAT
|
||||||
// expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++2a}}
|
// expected-warning@-2 {{'<=>' operator is incompatible with C++ standards before C++2a}}
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,7 +21,7 @@ X<operator<=>
|
||||||
#if __cplusplus <= 201703L
|
#if __cplusplus <= 201703L
|
||||||
// expected-warning@-2 {{'<=>' is a single token in C++2a; add a space to avoid a change in behavior}}
|
// expected-warning@-2 {{'<=>' is a single token in C++2a; add a space to avoid a change in behavior}}
|
||||||
#else
|
#else
|
||||||
> // expected-error@-4 {{}}
|
>
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPAT
|
#ifdef COMPAT
|
||||||
// expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++2a}}
|
// expected-warning@-7 {{'<=>' operator is incompatible with C++ standards before C++2a}}
|
||||||
|
|
|
@ -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);
|
Loading…
Reference in New Issue