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:
parent
ccf8053680
commit
ff8ac10f6e
21 changed files with 96 additions and 10 deletions
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -226,6 +226,13 @@ public interface IASTBinaryExpression extends IASTExpression {
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -167,6 +167,10 @@ class BuiltinOperators {
|
|||
comparison(true);
|
||||
break;
|
||||
|
||||
case THREEWAYCOMPARISON:
|
||||
// TODO: implement for <=>
|
||||
break;
|
||||
|
||||
case GT:
|
||||
case GTEQUAL:
|
||||
case LT:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue