From ff8ac10f6efa51760b07c5c20f27d1186796bdb2 Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Wed, 7 Dec 2022 21:56:12 +0300 Subject: [PATCH] Add basic support for c++20 three-way comparison operator --- .../core/parser/tests/scanner/LexerTests.java | 23 +++++++++++++++++-- .../internal/core/model/ASTStringUtil.java | 2 ++ .../cdt/core/dom/ast/ASTSignatureUtil.java | 3 +++ .../core/dom/ast/IASTBinaryExpression.java | 7 ++++++ .../org/eclipse/cdt/core/parser/IToken.java | 2 ++ .../org/eclipse/cdt/core/parser/Keywords.java | 1 + .../ASTAmbiguousBinaryVsCastExpression.java | 10 ++++---- .../parser/AbstractGNUSourceCodeParser.java | 4 ++++ .../core/dom/parser/ValueFactory.java | 3 +++ .../dom/parser/VariableReadWriteFlags.java | 1 + .../dom/parser/c/CASTBinaryExpression.java | 4 ++++ .../core/dom/parser/c/GNUCSourceParser.java | 1 + .../dom/parser/cpp/GNUCPPSourceParser.java | 1 + .../dom/parser/cpp/OverloadableOperator.java | 10 +++++--- .../cpp/semantics/BuiltinOperators.java | 4 ++++ .../dom/parser/cpp/semantics/EvalBinary.java | 5 ++++ .../rewrite/astwriter/ExpressionWriter.java | 3 +++ .../core/parser/scanner/CPreprocessor.java | 5 ++++ .../internal/core/parser/scanner/Lexer.java | 9 +++++++- .../core/parser/scanner/TokenUtil.java | 3 +++ .../includes/BindingClassifier.java | 5 ++++ 21 files changed, 96 insertions(+), 10 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java index 6fef3fe2675..6edc6b13712 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LexerTests.java @@ -29,14 +29,18 @@ public class LexerTests extends BaseTestCase { private static final LexerOptions DEFAULT_OPTIONS = new LexerOptions(); private static final LexerOptions NO_DOLLAR = new LexerOptions(); private static final LexerOptions NO_MINMAX = new LexerOptions(); + private static final LexerOptions NO_MINMAX_CPP = new LexerOptions(); private static final LexerOptions SLASH_PERCENT = new LexerOptions(); private static final LexerOptions CPP_OPTIONS = new LexerOptions(); static { NO_DOLLAR.fSupportDollarInIdentifiers = false; NO_MINMAX.fSupportMinAndMax = false; + NO_MINMAX_CPP.fSupportMinAndMax = false; + NO_MINMAX_CPP.fSupportThreeWayComparisonOperator = true; SLASH_PERCENT.fSupportSlashPercentComments = true; CPP_OPTIONS.fSupportRawStringLiterals = true; CPP_OPTIONS.fSupportDigitSeparators = true; + CPP_OPTIONS.fSupportThreeWayComparisonOperator = true; } static String TRIGRAPH_REPLACES_CHARS = "#^[]|{}~\\"; @@ -716,11 +720,26 @@ public class LexerTests extends BaseTestCase { IToken.tGTEQUAL, IToken.tAND, IToken.tOR, IToken.tINCR, IToken.tDECR, IToken.tCOMMA, IToken.tARROWSTAR, IToken.tARROW, IGCCToken.tMIN, IGCCToken.tMAX, Lexer.tOTHER_CHARACTER, }; + verifyOperatorAndPunctuators(ops, tokens, DEFAULT_OPTIONS, NO_MINMAX); + } + + public void testOperatorAndPunctuatorsCpp20() throws Exception { + final String ops = "<<>><<=>>===!=<=>>=<=&&"; + + final int[] tokens = new int[] { IToken.tSHIFTL, IToken.tSHIFTR, IToken.tSHIFTLASSIGN, IToken.tSHIFTRASSIGN, + IToken.tEQUAL, IToken.tNOTEQUAL, IToken.tTHREEWAYCOMPARISON, IToken.tGTEQUAL, IToken.tLTEQUAL, + IToken.tAND, }; + + verifyOperatorAndPunctuators(ops, tokens, CPP_OPTIONS, NO_MINMAX_CPP); + } + + private void verifyOperatorAndPunctuators(String ops, int[] tokens, LexerOptions options, + LexerOptions optionsNoMinMax) throws Exception { for (int splices = 0; splices < 9; splices++) { for (int trigraphs = 0; trigraphs < 6; trigraphs++) { StringBuilder buf = new StringBuilder(); String input = useTrigraphs(ops.toCharArray(), trigraphs); - init(instertLineSplices(input, splices)); + init(instertLineSplices(input, splices), options); for (int token2 : tokens) { Token token = fLexer.currentToken(); buf.append(token.getCharImage()); @@ -729,7 +748,7 @@ public class LexerTests extends BaseTestCase { eof(); assertEquals(ops, buf.toString()); // check token image - init(input, NO_MINMAX); + init(input, optionsNoMinMax); for (int token : tokens) { switch (token) { case IGCCToken.tMIN: diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java index a8bb67cfdd5..63f376c1188 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java @@ -1167,6 +1167,8 @@ public class ASTStringUtil { return Keywords.cpEQUAL; case IASTBinaryExpression.op_notequals: return Keywords.cpNOTEQUAL; + case IASTBinaryExpression.op_threewaycomparison: + return Keywords.cpTHREEWAYCOMPARISON; case IASTBinaryExpression.op_max: return Keywords.cpMAX; case IASTBinaryExpression.op_min: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java index d3ac4a8b088..cae8555cda0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java @@ -1311,6 +1311,9 @@ public class ASTSignatureUtil { case IASTBinaryExpression.op_notequals: opString = String.valueOf(Keywords.cpNOTEQUAL); break; + case IASTBinaryExpression.op_threewaycomparison: + opString = String.valueOf(Keywords.cpTHREEWAYCOMPARISON); + break; case IASTBinaryExpression.op_max: opString = String.valueOf(Keywords.cpMAX); break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryExpression.java index af70cd64de0..4900e09081a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryExpression.java @@ -226,6 +226,13 @@ public interface IASTBinaryExpression extends IASTExpression { */ public static final int op_ellipses = 34; + /** + * For c++, only. + * op_threewaycompare represents <=> three-way comparison operator. + * @since 8.0 + */ + public static final int op_threewaycomparison = 35; + /** * Get the first operand. * diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java index 7fbc0234437..bd9d6f05f1c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java @@ -85,6 +85,8 @@ public interface IToken { int tNOTEQUAL = 35; int tNOT = 36; int tEQUAL = 37; + /** @since 8.0 */ + int tTHREEWAYCOMPARISON = 8001; int tASSIGN = 38; int tUNKNOWN_CHAR = 39; int tSHIFTL = 40; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java index 88b56e076db..f4112f35e01 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java @@ -279,6 +279,7 @@ public class Keywords { public static final char[] cpNOTEQUAL = "!=".toCharArray(); public static final char[] cpNOT = "!".toCharArray(); public static final char[] cpEQUAL = "==".toCharArray(); + public static final char[] cpTHREEWAYCOMPARISON = "<=>".toCharArray(); public static final char[] cpASSIGN = "=".toCharArray(); public static final char[] cpSHIFTL = "<<".toCharArray(); public static final char[] cpLTEQUAL = "<=".toCharArray(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousBinaryVsCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousBinaryVsCastExpression.java index 562956b5ca6..65dc11bd7e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousBinaryVsCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousBinaryVsCastExpression.java @@ -224,19 +224,21 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousNod case IASTBinaryExpression.op_max: case IASTBinaryExpression.op_min: return 7; + case IASTBinaryExpression.op_threewaycomparison: + return 8; case IASTBinaryExpression.op_shiftLeft: case IASTBinaryExpression.op_shiftRight: - return 8; + return 9; case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_minus: - return 9; + return 10; case IASTBinaryExpression.op_multiply: case IASTBinaryExpression.op_divide: case IASTBinaryExpression.op_modulo: - return 10; + return 11; case IASTBinaryExpression.op_pmarrow: case IASTBinaryExpression.op_pmdot: - return 11; + return 12; } assert false; return 0; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index 9b7b8232643..440e8bc6ebe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -1123,6 +1123,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { case IToken.tNOTEQUAL: op = IASTBinaryExpression.op_notequals; break; + case IToken.tTHREEWAYCOMPARISON: + op = IASTBinaryExpression.op_threewaycomparison; + break; case IToken.tGT: op = IASTBinaryExpression.op_greaterThan; break; @@ -2731,6 +2734,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { case IToken.tDOT: case IToken.tDOTSTAR: case IToken.tEQUAL: + case IToken.tTHREEWAYCOMPARISON: case IToken.tGT: case IToken.tGT_in_SHIFTR: case IToken.tGTEQUAL: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java index 68651b83224..fbb7eb713fb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java @@ -224,6 +224,9 @@ public class ValueFactory { case IASTBinaryExpression.op_greaterEqual: value = v1 >= v2 ? 1l : 0l; break; + case IASTBinaryExpression.op_threewaycomparison: + // TODO: implement for <=> + break; case IASTBinaryExpression.op_binaryAnd: value = v1 & v2; break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java index 594a4240d0d..ef5e55a71d0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java @@ -439,6 +439,7 @@ public abstract class VariableReadWriteFlags { case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_shiftLeft: case IASTBinaryExpression.op_shiftRight: + case IASTBinaryExpression.op_threewaycomparison: return Optional.of(READ); case IASTBinaryExpression.op_minus: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java index b93f604f461..420f943ff31 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java @@ -234,6 +234,10 @@ public class CASTBinaryExpression extends ASTNode implements IASTBinaryExpressio case op_notequals: return new CBasicType(Kind.eInt, 0, this); + case op_threewaycomparison: + // TODO: implement for <=> + break; + case IASTBinaryExpression.op_plus: if (type1 instanceof IArrayType) { return Conversions.arrayTypeToPointerType((ICArrayType) type1); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index bd63a89dfab..0194855751f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -548,6 +548,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { break; case IToken.tEQUAL: case IToken.tNOTEQUAL: + case IToken.tTHREEWAYCOMPARISON: lastOperator = new BinaryOperator(lastOperator, lastExpression, lt1, 80, 81); break; case IToken.tGT: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 4709d51a4e7..82a767c2273 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -1106,6 +1106,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; case IToken.tEQUAL: case IToken.tNOTEQUAL: + case IToken.tTHREEWAYCOMPARISON: lastOperator = new BinaryOperator(lastOperator, expr, lt1, 80, 81); break; case IToken.tGT: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java index 5303b2c5367..5df33da292a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java @@ -34,9 +34,9 @@ public enum OverloadableOperator { GT(">"), LT("<"), NOT("!"), BITCOMPLEMENT("~"), BITOR("|"), AMPER("&"), XOR("^"), MOD("%"), DIV("/"), STAR("*"), PLUS("+"), BRACKET("[]"), PAREN("()"), ARROW("->"), ARROWSTAR("->*"), COMMA(","), MINUS("-"), DECR("--"), INCR("++"), OR("||"), AND("&&"), ASSIGN("="), GTEQUAL(">="), LTEQUAL("<="), NOTEQUAL("!="), EQUAL("=="), - SHIFTR(">>"), SHIFTL("<<"), SHIFTLASSIGN("<<="), SHIFTRASSIGN(">>="), BITORASSIGN("|="), AMPERASSIGN("&="), - XORASSIGN("^="), MODASSIGN("%="), DIVASSIGN("/="), STARASSIGN("*="), MINUSASSIGN("-="), PLUSASSIGN("+="), - NEW("new"), DELETE_ARRAY("delete[]"), DELETE("delete"), NEW_ARRAY("new[]"), + SHIFTR(">>"), SHIFTL("<<"), SHIFTLASSIGN("<<="), SHIFTRASSIGN(">>="), THREEWAYCOMPARISON("<=>"), BITORASSIGN("|="), + AMPERASSIGN("&="), XORASSIGN("^="), MODASSIGN("%="), DIVASSIGN("/="), STARASSIGN("*="), MINUSASSIGN("-="), + PLUSASSIGN("+="), NEW("new"), DELETE_ARRAY("delete[]"), DELETE("delete"), NEW_ARRAY("new[]"), /** * Cannot be overloaded by the user, however overload resolution needs to be performed. @@ -155,6 +155,8 @@ public enum OverloadableOperator { return LT; case IToken.tLTEQUAL: return LTEQUAL; + case IToken.tTHREEWAYCOMPARISON: + return THREEWAYCOMPARISON; // other case IToken.tASSIGN: @@ -247,6 +249,8 @@ public enum OverloadableOperator { return LT; case IASTBinaryExpression.op_lessEqual: return LTEQUAL; + case IASTBinaryExpression.op_threewaycomparison: + return THREEWAYCOMPARISON; // other case IASTBinaryExpression.op_assign: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java index 26276e39bfe..ab6e4ce51f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java @@ -167,6 +167,10 @@ class BuiltinOperators { comparison(true); break; + case THREEWAYCOMPARISON: + // TODO: implement for <=> + break; + case GT: case GTEQUAL: case LT: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index 8cfda662951..e9408f89e1a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -45,6 +45,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftLeft; import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftLeftAssign; import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRight; import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRightAssign; +import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_threewaycomparison; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; @@ -388,6 +389,10 @@ public class EvalBinary extends CPPDependentEvaluation { case op_notequals: return CPPBasicType.BOOLEAN; + case op_threewaycomparison: + // TODO: implement for <=> + return ProblemType.UNKNOWN_FOR_EXPRESSION; + case op_plus: if (type1 instanceof IPointerType) { return ExpressionTypes.restoreTypedefs(type1, originalType1); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java index f335097b89a..cd5cc76cf33 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ExpressionWriter.java @@ -91,6 +91,7 @@ public class ExpressionWriter extends NodeWriter { private static final String ELLIPSES = " ... "; //$NON-NLS-1$ private static final String NOT_EQUALS_OP = " != "; //$NON-NLS-1$ private static final String EQUALS_OP = " == "; //$NON-NLS-1$ + private static final String THREEWAYCOMPARISON_OP = " <=> "; //$NON-NLS-1$ private static final String BINARY_OR_ASSIGN = " |= "; //$NON-NLS-1$ private static final String BINARY_XOR_ASSIGN_OP = " ^= "; //$NON-NLS-1$ private static final String BINARY_AND_ASSIGN_OP = " &= "; //$NON-NLS-1$ @@ -226,6 +227,8 @@ public class ExpressionWriter extends NodeWriter { return EQUALS_OP; case IASTBinaryExpression.op_notequals: return NOT_EQUALS_OP; + case IASTBinaryExpression.op_threewaycomparison: + return THREEWAYCOMPARISON_OP; case ICPPASTBinaryExpression.op_pmdot: return PMDOT_OP; case ICPPASTBinaryExpression.op_pmarrow: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 4a8762f0af7..efd581d5661 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -99,6 +99,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { private static final int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE; private static final char[] ONE = "1".toCharArray(); //$NON-NLS-1$ + private static final char[] CPP_IMPL_THREE_WAY_COMPARISON = "__cpp_impl_three_way_comparison".toCharArray(); //$NON-NLS-1$ // Standard built-ins private static final ObjectStyleMacro __CDT_PARSER__ = new ObjectStyleMacro("__CDT_PARSER__".toCharArray(), //$NON-NLS-1$ @@ -352,6 +353,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { fIncludeSearchPath = configureIncludeSearchPath(new File(contextPath).getParentFile(), info); setupMacroDictionary(configuration, info, language); + if (fMacroDictionary.containsKey(CPP_IMPL_THREE_WAY_COMPARISON)) { + fLexOptions.fSupportThreeWayComparisonOperator = true; + } + ILocationCtx ctx = fLocationMap.pushTranslationUnit(fRootContent.getFileLocation(), fRootContent.getSource()); Lexer lexer = new Lexer(fRootContent.getSource(), fLexOptions, this, this); fRootContext = fCurrentContext = new ScannerContext(ctx, null, lexer); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Lexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Lexer.java index 98b8f29e007..0f509b022c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Lexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/Lexer.java @@ -63,6 +63,7 @@ final public class Lexer implements ITokenSequence { public boolean fSupportRawStringLiterals = false; public boolean fSupportUserDefinedLiterals = false; public boolean fSupportDigitSeparators = false; + public boolean fSupportThreeWayComparisonOperator = false; public IncludeExportPatterns fIncludeExportPatterns; @Override @@ -641,7 +642,13 @@ final public class Lexer implements ITokenSequence { switch (d) { case '=': - nextCharPhase3(); + final int se = nextCharPhase3(); + if (fOptions.fSupportThreeWayComparisonOperator) { + if (se == '>') { + nextCharPhase3(); + return newToken(IToken.tTHREEWAYCOMPARISON, start); + } + } return newToken(IToken.tLTEQUAL, start); case '<': final int e = nextCharPhase3(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenUtil.java index 910451816f5..a56716ec4a1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenUtil.java @@ -78,6 +78,7 @@ public class TokenUtil { case IToken.tGTEQUAL: case IToken.tLT: case IToken.tLTEQUAL: + case IToken.tTHREEWAYCOMPARISON: // other case IToken.tASSIGN: @@ -164,6 +165,8 @@ public class TokenUtil { return Keywords.cpNOT; case IToken.tEQUAL: return Keywords.cpEQUAL; + case IToken.tTHREEWAYCOMPARISON: + return Keywords.cpTHREEWAYCOMPARISON; case IToken.tASSIGN: return Keywords.cpASSIGN; case IToken.tSHIFTL: diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java index b8287e83117..0d24c71443b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java @@ -650,6 +650,11 @@ public class BindingClassifier { } } + if (binaryExpression.getOperator() == IASTBinaryExpression.op_threewaycomparison) { + // TODO: implement for three-way comparison operator x <=> y + return PROCESS_CONTINUE; + } + IType operand1Type = binaryExpression.getOperand1().getExpressionType(); IASTInitializerClause operand2 = binaryExpression.getInitOperand2(); IType operand2Type;