[c++20] P0515R3: Parsing support and basic AST construction for operator <=>.
Adding the new enumerator forced a bunch more changes into this patch than I
would have liked. The -Wtautological-compare warning was extended to properly
check the new comparison operator, clang-format needed updating because it uses
precedence levels as weights for determining where to break lines (and several
operators increased their precedence levels with this change), thread-safety
analysis needed changes to build its own IL properly for the new operator.
All "real" semantic checking for this operator has been deferred to a future
patch. For now, we use the relational comparison rules and arbitrarily give
the builtin form of the operator a return type of 'void'.
llvm-svn: 320707
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9ed21da..94070bb 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -7279,8 +7279,8 @@
if (!Size)
return false;
- // if E is binop and op is >, <, >=, <=, ==, &&, ||:
- if (!Size->isComparisonOp() && !Size->isEqualityOp() && !Size->isLogicalOp())
+ // if E is binop and op is <=>, >, <, >=, <=, ==, &&, ||:
+ if (!Size->isComparisonOp() && !Size->isLogicalOp())
return false;
SourceRange SizeRange = Size->getSourceRange();
@@ -8433,6 +8433,8 @@
if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
switch (BO->getOpcode()) {
+ case BO_Cmp:
+ llvm_unreachable("builtin <=> should have class type");
// Boolean-valued operations are single-bit and positive.
case BO_LAnd:
@@ -8747,9 +8749,18 @@
llvm_unreachable("impossible compare result");
}
- static llvm::Optional<bool> constantValue(BinaryOperatorKind Op,
- ComparisonResult R,
- bool ConstantOnRHS) {
+ static llvm::Optional<StringRef>
+ constantValue(BinaryOperatorKind Op, ComparisonResult R, bool ConstantOnRHS) {
+ if (Op == BO_Cmp) {
+ ComparisonResult LTFlag = LT, GTFlag = GT;
+ if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
+
+ if (R & EQ) return StringRef("'std::strong_ordering::equal'");
+ if (R & LTFlag) return StringRef("'std::strong_ordering::less'");
+ if (R & GTFlag) return StringRef("'std::strong_ordering::greater'");
+ return llvm::None;
+ }
+
ComparisonResult TrueFlag, FalseFlag;
if (Op == BO_EQ) {
TrueFlag = EQ;
@@ -8769,9 +8780,9 @@
std::swap(TrueFlag, FalseFlag);
}
if (R & TrueFlag)
- return true;
+ return StringRef("true");
if (R & FalseFlag)
- return false;
+ return StringRef("false");
return llvm::None;
}
};