1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Add basic support for c++20 three-way comparison operator

This commit is contained in:
Igor V. Kovalenko 2022-12-07 21:56:12 +03:00 committed by Jonah Graham
parent ccf8053680
commit ff8ac10f6e
21 changed files with 96 additions and 10 deletions

View file

@ -29,14 +29,18 @@ public class LexerTests extends BaseTestCase {
private static final LexerOptions DEFAULT_OPTIONS = new LexerOptions(); private static final LexerOptions DEFAULT_OPTIONS = new LexerOptions();
private static final LexerOptions NO_DOLLAR = new LexerOptions(); private static final LexerOptions NO_DOLLAR = new LexerOptions();
private static final LexerOptions NO_MINMAX = 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 SLASH_PERCENT = new LexerOptions();
private static final LexerOptions CPP_OPTIONS = new LexerOptions(); private static final LexerOptions CPP_OPTIONS = new LexerOptions();
static { static {
NO_DOLLAR.fSupportDollarInIdentifiers = false; NO_DOLLAR.fSupportDollarInIdentifiers = false;
NO_MINMAX.fSupportMinAndMax = false; NO_MINMAX.fSupportMinAndMax = false;
NO_MINMAX_CPP.fSupportMinAndMax = false;
NO_MINMAX_CPP.fSupportThreeWayComparisonOperator = true;
SLASH_PERCENT.fSupportSlashPercentComments = true; SLASH_PERCENT.fSupportSlashPercentComments = true;
CPP_OPTIONS.fSupportRawStringLiterals = true; CPP_OPTIONS.fSupportRawStringLiterals = true;
CPP_OPTIONS.fSupportDigitSeparators = true; CPP_OPTIONS.fSupportDigitSeparators = true;
CPP_OPTIONS.fSupportThreeWayComparisonOperator = true;
} }
static String TRIGRAPH_REPLACES_CHARS = "#^[]|{}~\\"; 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.tGTEQUAL, IToken.tAND, IToken.tOR, IToken.tINCR, IToken.tDECR, IToken.tCOMMA, IToken.tARROWSTAR,
IToken.tARROW, IGCCToken.tMIN, IGCCToken.tMAX, Lexer.tOTHER_CHARACTER, }; 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 splices = 0; splices < 9; splices++) {
for (int trigraphs = 0; trigraphs < 6; trigraphs++) { for (int trigraphs = 0; trigraphs < 6; trigraphs++) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
String input = useTrigraphs(ops.toCharArray(), trigraphs); String input = useTrigraphs(ops.toCharArray(), trigraphs);
init(instertLineSplices(input, splices)); init(instertLineSplices(input, splices), options);
for (int token2 : tokens) { for (int token2 : tokens) {
Token token = fLexer.currentToken(); Token token = fLexer.currentToken();
buf.append(token.getCharImage()); buf.append(token.getCharImage());
@ -729,7 +748,7 @@ public class LexerTests extends BaseTestCase {
eof(); eof();
assertEquals(ops, buf.toString()); // check token image assertEquals(ops, buf.toString()); // check token image
init(input, NO_MINMAX); init(input, optionsNoMinMax);
for (int token : tokens) { for (int token : tokens) {
switch (token) { switch (token) {
case IGCCToken.tMIN: case IGCCToken.tMIN:

View file

@ -1167,6 +1167,8 @@ public class ASTStringUtil {
return Keywords.cpEQUAL; return Keywords.cpEQUAL;
case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_notequals:
return Keywords.cpNOTEQUAL; return Keywords.cpNOTEQUAL;
case IASTBinaryExpression.op_threewaycomparison:
return Keywords.cpTHREEWAYCOMPARISON;
case IASTBinaryExpression.op_max: case IASTBinaryExpression.op_max:
return Keywords.cpMAX; return Keywords.cpMAX;
case IASTBinaryExpression.op_min: case IASTBinaryExpression.op_min:

View file

@ -1311,6 +1311,9 @@ public class ASTSignatureUtil {
case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_notequals:
opString = String.valueOf(Keywords.cpNOTEQUAL); opString = String.valueOf(Keywords.cpNOTEQUAL);
break; break;
case IASTBinaryExpression.op_threewaycomparison:
opString = String.valueOf(Keywords.cpTHREEWAYCOMPARISON);
break;
case IASTBinaryExpression.op_max: case IASTBinaryExpression.op_max:
opString = String.valueOf(Keywords.cpMAX); opString = String.valueOf(Keywords.cpMAX);
break; break;

View file

@ -226,6 +226,13 @@ public interface IASTBinaryExpression extends IASTExpression {
*/ */
public static final int op_ellipses = 34; public static final int op_ellipses = 34;
/**
* For c++, only.
* <code>op_threewaycompare</code> represents <code><=></code> three-way comparison operator.
* @since 8.0
*/
public static final int op_threewaycomparison = 35;
/** /**
* Get the first operand. * Get the first operand.
* *

View file

@ -85,6 +85,8 @@ public interface IToken {
int tNOTEQUAL = 35; int tNOTEQUAL = 35;
int tNOT = 36; int tNOT = 36;
int tEQUAL = 37; int tEQUAL = 37;
/** @since 8.0 */
int tTHREEWAYCOMPARISON = 8001;
int tASSIGN = 38; int tASSIGN = 38;
int tUNKNOWN_CHAR = 39; int tUNKNOWN_CHAR = 39;
int tSHIFTL = 40; int tSHIFTL = 40;

View file

@ -279,6 +279,7 @@ public class Keywords {
public static final char[] cpNOTEQUAL = "!=".toCharArray(); public static final char[] cpNOTEQUAL = "!=".toCharArray();
public static final char[] cpNOT = "!".toCharArray(); public static final char[] cpNOT = "!".toCharArray();
public static final char[] cpEQUAL = "==".toCharArray(); public static final char[] cpEQUAL = "==".toCharArray();
public static final char[] cpTHREEWAYCOMPARISON = "<=>".toCharArray();
public static final char[] cpASSIGN = "=".toCharArray(); public static final char[] cpASSIGN = "=".toCharArray();
public static final char[] cpSHIFTL = "<<".toCharArray(); public static final char[] cpSHIFTL = "<<".toCharArray();
public static final char[] cpLTEQUAL = "<=".toCharArray(); public static final char[] cpLTEQUAL = "<=".toCharArray();

View file

@ -224,19 +224,21 @@ public abstract class ASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousNod
case IASTBinaryExpression.op_max: case IASTBinaryExpression.op_max:
case IASTBinaryExpression.op_min: case IASTBinaryExpression.op_min:
return 7; return 7;
case IASTBinaryExpression.op_threewaycomparison:
return 8;
case IASTBinaryExpression.op_shiftLeft: case IASTBinaryExpression.op_shiftLeft:
case IASTBinaryExpression.op_shiftRight: case IASTBinaryExpression.op_shiftRight:
return 8; return 9;
case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_plus:
case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_minus:
return 9; return 10;
case IASTBinaryExpression.op_multiply: case IASTBinaryExpression.op_multiply:
case IASTBinaryExpression.op_divide: case IASTBinaryExpression.op_divide:
case IASTBinaryExpression.op_modulo: case IASTBinaryExpression.op_modulo:
return 10; return 11;
case IASTBinaryExpression.op_pmarrow: case IASTBinaryExpression.op_pmarrow:
case IASTBinaryExpression.op_pmdot: case IASTBinaryExpression.op_pmdot:
return 11; return 12;
} }
assert false; assert false;
return 0; return 0;

View file

@ -1123,6 +1123,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
case IToken.tNOTEQUAL: case IToken.tNOTEQUAL:
op = IASTBinaryExpression.op_notequals; op = IASTBinaryExpression.op_notequals;
break; break;
case IToken.tTHREEWAYCOMPARISON:
op = IASTBinaryExpression.op_threewaycomparison;
break;
case IToken.tGT: case IToken.tGT:
op = IASTBinaryExpression.op_greaterThan; op = IASTBinaryExpression.op_greaterThan;
break; break;
@ -2731,6 +2734,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
case IToken.tDOT: case IToken.tDOT:
case IToken.tDOTSTAR: case IToken.tDOTSTAR:
case IToken.tEQUAL: case IToken.tEQUAL:
case IToken.tTHREEWAYCOMPARISON:
case IToken.tGT: case IToken.tGT:
case IToken.tGT_in_SHIFTR: case IToken.tGT_in_SHIFTR:
case IToken.tGTEQUAL: case IToken.tGTEQUAL:

View file

@ -224,6 +224,9 @@ public class ValueFactory {
case IASTBinaryExpression.op_greaterEqual: case IASTBinaryExpression.op_greaterEqual:
value = v1 >= v2 ? 1l : 0l; value = v1 >= v2 ? 1l : 0l;
break; break;
case IASTBinaryExpression.op_threewaycomparison:
// TODO: implement for <=>
break;
case IASTBinaryExpression.op_binaryAnd: case IASTBinaryExpression.op_binaryAnd:
value = v1 & v2; value = v1 & v2;
break; break;

View file

@ -439,6 +439,7 @@ public abstract class VariableReadWriteFlags {
case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_notequals:
case IASTBinaryExpression.op_shiftLeft: case IASTBinaryExpression.op_shiftLeft:
case IASTBinaryExpression.op_shiftRight: case IASTBinaryExpression.op_shiftRight:
case IASTBinaryExpression.op_threewaycomparison:
return Optional.of(READ); return Optional.of(READ);
case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_minus:

View file

@ -234,6 +234,10 @@ public class CASTBinaryExpression extends ASTNode implements IASTBinaryExpressio
case op_notequals: case op_notequals:
return new CBasicType(Kind.eInt, 0, this); return new CBasicType(Kind.eInt, 0, this);
case op_threewaycomparison:
// TODO: implement for <=>
break;
case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_plus:
if (type1 instanceof IArrayType) { if (type1 instanceof IArrayType) {
return Conversions.arrayTypeToPointerType((ICArrayType) type1); return Conversions.arrayTypeToPointerType((ICArrayType) type1);

View file

@ -548,6 +548,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
break; break;
case IToken.tEQUAL: case IToken.tEQUAL:
case IToken.tNOTEQUAL: case IToken.tNOTEQUAL:
case IToken.tTHREEWAYCOMPARISON:
lastOperator = new BinaryOperator(lastOperator, lastExpression, lt1, 80, 81); lastOperator = new BinaryOperator(lastOperator, lastExpression, lt1, 80, 81);
break; break;
case IToken.tGT: case IToken.tGT:

View file

@ -1106,6 +1106,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
break; break;
case IToken.tEQUAL: case IToken.tEQUAL:
case IToken.tNOTEQUAL: case IToken.tNOTEQUAL:
case IToken.tTHREEWAYCOMPARISON:
lastOperator = new BinaryOperator(lastOperator, expr, lt1, 80, 81); lastOperator = new BinaryOperator(lastOperator, expr, lt1, 80, 81);
break; break;
case IToken.tGT: case IToken.tGT:

View file

@ -34,9 +34,9 @@ public enum OverloadableOperator {
GT(">"), LT("<"), NOT("!"), BITCOMPLEMENT("~"), BITOR("|"), AMPER("&"), XOR("^"), MOD("%"), DIV("/"), STAR("*"), GT(">"), LT("<"), NOT("!"), BITCOMPLEMENT("~"), BITOR("|"), AMPER("&"), XOR("^"), MOD("%"), DIV("/"), STAR("*"),
PLUS("+"), BRACKET("[]"), PAREN("()"), ARROW("->"), ARROWSTAR("->*"), COMMA(","), MINUS("-"), DECR("--"), PLUS("+"), BRACKET("[]"), PAREN("()"), ARROW("->"), ARROWSTAR("->*"), COMMA(","), MINUS("-"), DECR("--"),
INCR("++"), OR("||"), AND("&&"), ASSIGN("="), GTEQUAL(">="), LTEQUAL("<="), NOTEQUAL("!="), EQUAL("=="), INCR("++"), OR("||"), AND("&&"), ASSIGN("="), GTEQUAL(">="), LTEQUAL("<="), NOTEQUAL("!="), EQUAL("=="),
SHIFTR(">>"), SHIFTL("<<"), SHIFTLASSIGN("<<="), SHIFTRASSIGN(">>="), BITORASSIGN("|="), AMPERASSIGN("&="), SHIFTR(">>"), SHIFTL("<<"), SHIFTLASSIGN("<<="), SHIFTRASSIGN(">>="), THREEWAYCOMPARISON("<=>"), BITORASSIGN("|="),
XORASSIGN("^="), MODASSIGN("%="), DIVASSIGN("/="), STARASSIGN("*="), MINUSASSIGN("-="), PLUSASSIGN("+="), AMPERASSIGN("&="), XORASSIGN("^="), MODASSIGN("%="), DIVASSIGN("/="), STARASSIGN("*="), MINUSASSIGN("-="),
NEW("new"), DELETE_ARRAY("delete[]"), DELETE("delete"), NEW_ARRAY("new[]"), PLUSASSIGN("+="), NEW("new"), DELETE_ARRAY("delete[]"), DELETE("delete"), NEW_ARRAY("new[]"),
/** /**
* Cannot be overloaded by the user, however overload resolution needs to be performed. * Cannot be overloaded by the user, however overload resolution needs to be performed.
@ -155,6 +155,8 @@ public enum OverloadableOperator {
return LT; return LT;
case IToken.tLTEQUAL: case IToken.tLTEQUAL:
return LTEQUAL; return LTEQUAL;
case IToken.tTHREEWAYCOMPARISON:
return THREEWAYCOMPARISON;
// other // other
case IToken.tASSIGN: case IToken.tASSIGN:
@ -247,6 +249,8 @@ public enum OverloadableOperator {
return LT; return LT;
case IASTBinaryExpression.op_lessEqual: case IASTBinaryExpression.op_lessEqual:
return LTEQUAL; return LTEQUAL;
case IASTBinaryExpression.op_threewaycomparison:
return THREEWAYCOMPARISON;
// other // other
case IASTBinaryExpression.op_assign: case IASTBinaryExpression.op_assign:

View file

@ -167,6 +167,10 @@ class BuiltinOperators {
comparison(true); comparison(true);
break; break;
case THREEWAYCOMPARISON:
// TODO: implement for <=>
break;
case GT: case GT:
case GTEQUAL: case GTEQUAL:
case LT: case LT:

View file

@ -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_shiftLeftAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRight; 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_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.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; 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: case op_notequals:
return CPPBasicType.BOOLEAN; return CPPBasicType.BOOLEAN;
case op_threewaycomparison:
// TODO: implement for <=>
return ProblemType.UNKNOWN_FOR_EXPRESSION;
case op_plus: case op_plus:
if (type1 instanceof IPointerType) { if (type1 instanceof IPointerType) {
return ExpressionTypes.restoreTypedefs(type1, originalType1); return ExpressionTypes.restoreTypedefs(type1, originalType1);

View file

@ -91,6 +91,7 @@ public class ExpressionWriter extends NodeWriter {
private static final String ELLIPSES = " ... "; //$NON-NLS-1$ private static final String ELLIPSES = " ... "; //$NON-NLS-1$
private static final String NOT_EQUALS_OP = " != "; //$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 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_OR_ASSIGN = " |= "; //$NON-NLS-1$
private static final String BINARY_XOR_ASSIGN_OP = " ^= "; //$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$ private static final String BINARY_AND_ASSIGN_OP = " &= "; //$NON-NLS-1$
@ -226,6 +227,8 @@ public class ExpressionWriter extends NodeWriter {
return EQUALS_OP; return EQUALS_OP;
case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_notequals:
return NOT_EQUALS_OP; return NOT_EQUALS_OP;
case IASTBinaryExpression.op_threewaycomparison:
return THREEWAYCOMPARISON_OP;
case ICPPASTBinaryExpression.op_pmdot: case ICPPASTBinaryExpression.op_pmdot:
return PMDOT_OP; return PMDOT_OP;
case ICPPASTBinaryExpression.op_pmarrow: case ICPPASTBinaryExpression.op_pmarrow:

View file

@ -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 int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE;
private static final char[] ONE = "1".toCharArray(); //$NON-NLS-1$ 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 // Standard built-ins
private static final ObjectStyleMacro __CDT_PARSER__ = new ObjectStyleMacro("__CDT_PARSER__".toCharArray(), //$NON-NLS-1$ 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); fIncludeSearchPath = configureIncludeSearchPath(new File(contextPath).getParentFile(), info);
setupMacroDictionary(configuration, info, language); setupMacroDictionary(configuration, info, language);
if (fMacroDictionary.containsKey(CPP_IMPL_THREE_WAY_COMPARISON)) {
fLexOptions.fSupportThreeWayComparisonOperator = true;
}
ILocationCtx ctx = fLocationMap.pushTranslationUnit(fRootContent.getFileLocation(), fRootContent.getSource()); ILocationCtx ctx = fLocationMap.pushTranslationUnit(fRootContent.getFileLocation(), fRootContent.getSource());
Lexer lexer = new Lexer(fRootContent.getSource(), fLexOptions, this, this); Lexer lexer = new Lexer(fRootContent.getSource(), fLexOptions, this, this);
fRootContext = fCurrentContext = new ScannerContext(ctx, null, lexer); fRootContext = fCurrentContext = new ScannerContext(ctx, null, lexer);

View file

@ -63,6 +63,7 @@ final public class Lexer implements ITokenSequence {
public boolean fSupportRawStringLiterals = false; public boolean fSupportRawStringLiterals = false;
public boolean fSupportUserDefinedLiterals = false; public boolean fSupportUserDefinedLiterals = false;
public boolean fSupportDigitSeparators = false; public boolean fSupportDigitSeparators = false;
public boolean fSupportThreeWayComparisonOperator = false;
public IncludeExportPatterns fIncludeExportPatterns; public IncludeExportPatterns fIncludeExportPatterns;
@Override @Override
@ -641,7 +642,13 @@ final public class Lexer implements ITokenSequence {
switch (d) { switch (d) {
case '=': case '=':
nextCharPhase3(); final int se = nextCharPhase3();
if (fOptions.fSupportThreeWayComparisonOperator) {
if (se == '>') {
nextCharPhase3();
return newToken(IToken.tTHREEWAYCOMPARISON, start);
}
}
return newToken(IToken.tLTEQUAL, start); return newToken(IToken.tLTEQUAL, start);
case '<': case '<':
final int e = nextCharPhase3(); final int e = nextCharPhase3();

View file

@ -78,6 +78,7 @@ public class TokenUtil {
case IToken.tGTEQUAL: case IToken.tGTEQUAL:
case IToken.tLT: case IToken.tLT:
case IToken.tLTEQUAL: case IToken.tLTEQUAL:
case IToken.tTHREEWAYCOMPARISON:
// other // other
case IToken.tASSIGN: case IToken.tASSIGN:
@ -164,6 +165,8 @@ public class TokenUtil {
return Keywords.cpNOT; return Keywords.cpNOT;
case IToken.tEQUAL: case IToken.tEQUAL:
return Keywords.cpEQUAL; return Keywords.cpEQUAL;
case IToken.tTHREEWAYCOMPARISON:
return Keywords.cpTHREEWAYCOMPARISON;
case IToken.tASSIGN: case IToken.tASSIGN:
return Keywords.cpASSIGN; return Keywords.cpASSIGN;
case IToken.tSHIFTL: case IToken.tSHIFTL:

View file

@ -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(); IType operand1Type = binaryExpression.getOperand1().getExpressionType();
IASTInitializerClause operand2 = binaryExpression.getInitOperand2(); IASTInitializerClause operand2 = binaryExpression.getInitOperand2();
IType operand2Type; IType operand2Type;