forked from qt-creator/qt-creator
Cpp: support space ship operator in lexer
Fixes: QTCREATORBUG-27503 Change-Id: Idbff5a9b5b2e6e841e298ca6f706ef3c6aa1622b Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
4
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
4
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -915,6 +915,10 @@ OperatorNameId::Kind Bind::cppOperator(OperatorAST *ast)
|
||||
kind = OperatorNameId::ArrayAccessOp;
|
||||
break;
|
||||
|
||||
case T_LESS_EQUAL_GREATER:
|
||||
kind = OperatorNameId::SpaceShipOp;
|
||||
break;
|
||||
|
||||
default:
|
||||
kind = OperatorNameId::InvalidOp;
|
||||
} // switch
|
||||
|
||||
7
src/libs/3rdparty/cplusplus/Lexer.cpp
vendored
7
src/libs/3rdparty/cplusplus/Lexer.cpp
vendored
@@ -612,7 +612,12 @@ void Lexer::scan_helper(Token *tok)
|
||||
tok->f.kind = T_LESS_LESS;
|
||||
} else if (_yychar == '=') {
|
||||
yyinp();
|
||||
tok->f.kind = T_LESS_EQUAL;
|
||||
if (_languageFeatures.cxx20Enabled && _yychar == '>') {
|
||||
yyinp();
|
||||
tok->f.kind = T_LESS_EQUAL_GREATER;
|
||||
} else {
|
||||
tok->f.kind = T_LESS_EQUAL;
|
||||
}
|
||||
} else if (_yychar == ':') {
|
||||
if (*(_currentChar+1) != ':' || *(_currentChar+2) == ':' || *(_currentChar+2) == '>') {
|
||||
yyinp();
|
||||
|
||||
5
src/libs/3rdparty/cplusplus/Names.h
vendored
5
src/libs/3rdparty/cplusplus/Names.h
vendored
@@ -180,7 +180,7 @@ public:
|
||||
! = < > += -= *= /= %=
|
||||
^= &= |= << >> >>= <<= == !=
|
||||
<= >= && || ++ -- , ->* ->
|
||||
() []
|
||||
() [] <=>
|
||||
*/
|
||||
enum Kind {
|
||||
InvalidOp,
|
||||
@@ -225,7 +225,8 @@ public:
|
||||
ArrowStarOp,
|
||||
ArrowOp,
|
||||
FunctionCallOp,
|
||||
ArrayAccessOp
|
||||
ArrayAccessOp,
|
||||
SpaceShipOp
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
39
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
39
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -98,10 +98,11 @@ enum {
|
||||
And = 8,
|
||||
Equality = 9,
|
||||
Relational = 10,
|
||||
Shift = 11,
|
||||
Additive = 12,
|
||||
Multiplicative = 13,
|
||||
PointerToMember = 14
|
||||
ThreeWayComp = 11,
|
||||
Shift = 12,
|
||||
Additive = 13,
|
||||
Multiplicative = 14,
|
||||
PointerToMember = 15
|
||||
};
|
||||
} // namespace Precedece
|
||||
|
||||
@@ -116,29 +117,30 @@ inline int precedence(int tokenKind, bool templateArguments)
|
||||
return Prec::Assignment;
|
||||
|
||||
switch (tokenKind) {
|
||||
case T_COMMA: return Prec::Comma;
|
||||
case T_QUESTION: return Prec::Conditional;
|
||||
case T_PIPE_PIPE: return Prec::LogicalOr;
|
||||
case T_AMPER_AMPER: return Prec::LogicalAnd;
|
||||
case T_PIPE: return Prec::InclusiveOr;
|
||||
case T_CARET: return Prec::ExclusiveOr;
|
||||
case T_AMPER: return Prec::And;
|
||||
case T_COMMA: return Prec::Comma;
|
||||
case T_QUESTION: return Prec::Conditional;
|
||||
case T_PIPE_PIPE: return Prec::LogicalOr;
|
||||
case T_AMPER_AMPER: return Prec::LogicalAnd;
|
||||
case T_PIPE: return Prec::InclusiveOr;
|
||||
case T_CARET: return Prec::ExclusiveOr;
|
||||
case T_AMPER: return Prec::And;
|
||||
case T_EQUAL_EQUAL:
|
||||
case T_EXCLAIM_EQUAL: return Prec::Equality;
|
||||
case T_EXCLAIM_EQUAL: return Prec::Equality;
|
||||
case T_GREATER:
|
||||
case T_LESS:
|
||||
case T_LESS_EQUAL:
|
||||
case T_GREATER_EQUAL: return Prec::Relational;
|
||||
case T_GREATER_EQUAL: return Prec::Relational;
|
||||
case T_LESS_EQUAL_GREATER: return Prec::ThreeWayComp;
|
||||
case T_LESS_LESS:
|
||||
case T_GREATER_GREATER: return Prec::ExclusiveOr;
|
||||
case T_GREATER_GREATER: return Prec::ExclusiveOr;
|
||||
case T_PLUS:
|
||||
case T_MINUS: return Prec::Additive;
|
||||
case T_MINUS: return Prec::Additive;
|
||||
case T_STAR:
|
||||
case T_SLASH:
|
||||
case T_PERCENT: return Prec::Multiplicative;
|
||||
case T_PERCENT: return Prec::Multiplicative;
|
||||
case T_ARROW_STAR:
|
||||
case T_DOT_STAR: return Prec::PointerToMember;
|
||||
default: return Prec::Unknown;
|
||||
case T_DOT_STAR: return Prec::PointerToMember;
|
||||
default: return Prec::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1300,6 +1302,7 @@ bool Parser::parseOperator(OperatorAST *&node) // ### FIXME
|
||||
case T_GREATER_EQUAL:
|
||||
case T_GREATER_GREATER_EQUAL:
|
||||
case T_LESS_EQUAL:
|
||||
case T_LESS_EQUAL_GREATER:
|
||||
case T_LESS_LESS_EQUAL:
|
||||
case T_MINUS_EQUAL:
|
||||
case T_PERCENT_EQUAL:
|
||||
|
||||
1
src/libs/3rdparty/cplusplus/Token.cpp
vendored
1
src/libs/3rdparty/cplusplus/Token.cpp
vendored
@@ -91,6 +91,7 @@ const char *token_names[] = {
|
||||
("<="),
|
||||
("<<"),
|
||||
("<<="),
|
||||
("<=>"),
|
||||
("-"),
|
||||
("-="),
|
||||
("--"),
|
||||
|
||||
2
src/libs/3rdparty/cplusplus/Token.h
vendored
2
src/libs/3rdparty/cplusplus/Token.h
vendored
@@ -99,6 +99,7 @@ enum Kind {
|
||||
T_LESS_EQUAL,
|
||||
T_LESS_LESS,
|
||||
T_LESS_LESS_EQUAL,
|
||||
T_LESS_EQUAL_GREATER,
|
||||
T_MINUS,
|
||||
T_MINUS_EQUAL,
|
||||
T_MINUS_MINUS,
|
||||
@@ -446,6 +447,7 @@ struct LanguageFeatures
|
||||
unsigned int cxxEnabled : 1;
|
||||
unsigned int cxx11Enabled : 1;
|
||||
unsigned int cxx14Enabled : 1;
|
||||
unsigned int cxx20Enabled : 1;
|
||||
unsigned int objCEnabled : 1;
|
||||
unsigned int c99Enabled : 1;
|
||||
};
|
||||
|
||||
@@ -222,6 +222,9 @@ void NamePrettyPrinter::visit(const OperatorNameId *name)
|
||||
case OperatorNameId::ArrayAccessOp:
|
||||
_name += QLatin1String("[]");
|
||||
break;
|
||||
case OperatorNameId::SpaceShipOp:
|
||||
_name += QLatin1String("<=>");
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
|
||||
|
||||
@@ -202,6 +202,24 @@ struct Value
|
||||
inline bool is_zero () const
|
||||
{ return l == 0; }
|
||||
|
||||
template<typename T> static bool cmpImpl(T v1, T v2)
|
||||
{
|
||||
if (v1 < v2)
|
||||
return -1;
|
||||
if (v1 > v2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
Value cmp(const Value &other) const
|
||||
{
|
||||
Value v = *this;
|
||||
if (v.is_ulong() || other.is_ulong())
|
||||
v.set_long(cmpImpl(v.ul, other.ul));
|
||||
else
|
||||
v.set_long(cmpImpl(v.l, other.l));
|
||||
return v;
|
||||
}
|
||||
|
||||
#define PP_DEFINE_BIN_OP(name, op) \
|
||||
inline Value operator op(const Value &other) const \
|
||||
{ \
|
||||
@@ -488,24 +506,25 @@ private:
|
||||
inline int precedence(int tokenKind) const
|
||||
{
|
||||
switch (tokenKind) {
|
||||
case T_PIPE_PIPE: return 0;
|
||||
case T_AMPER_AMPER: return 1;
|
||||
case T_PIPE: return 2;
|
||||
case T_CARET: return 3;
|
||||
case T_AMPER: return 4;
|
||||
case T_PIPE_PIPE: return 0;
|
||||
case T_AMPER_AMPER: return 1;
|
||||
case T_PIPE: return 2;
|
||||
case T_CARET: return 3;
|
||||
case T_AMPER: return 4;
|
||||
case T_EQUAL_EQUAL:
|
||||
case T_EXCLAIM_EQUAL: return 5;
|
||||
case T_EXCLAIM_EQUAL: return 5;
|
||||
case T_GREATER:
|
||||
case T_LESS:
|
||||
case T_LESS_EQUAL:
|
||||
case T_GREATER_EQUAL: return 6;
|
||||
case T_GREATER_EQUAL: return 6;
|
||||
case T_LESS_EQUAL_GREATER: return 7;
|
||||
case T_LESS_LESS:
|
||||
case T_GREATER_GREATER: return 7;
|
||||
case T_GREATER_GREATER: return 8;
|
||||
case T_PLUS:
|
||||
case T_MINUS: return 8;
|
||||
case T_MINUS: return 9;
|
||||
case T_STAR:
|
||||
case T_SLASH:
|
||||
case T_PERCENT: return 9;
|
||||
case T_PERCENT: return 10;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
@@ -525,6 +544,7 @@ private:
|
||||
case T_GREATER:
|
||||
case T_LESS:
|
||||
case T_LESS_EQUAL:
|
||||
case T_LESS_EQUAL_GREATER:
|
||||
case T_GREATER_EQUAL:
|
||||
case T_LESS_LESS:
|
||||
case T_GREATER_GREATER:
|
||||
@@ -543,24 +563,25 @@ private:
|
||||
static inline Value evaluate_expression(int tokenKind, const Value &lhs, const Value &rhs)
|
||||
{
|
||||
switch (tokenKind) {
|
||||
case T_PIPE_PIPE: return lhs || rhs;
|
||||
case T_AMPER_AMPER: return lhs && rhs;
|
||||
case T_PIPE: return lhs | rhs;
|
||||
case T_CARET: return lhs ^ rhs;
|
||||
case T_AMPER: return lhs & rhs;
|
||||
case T_EQUAL_EQUAL: return lhs == rhs;
|
||||
case T_EXCLAIM_EQUAL: return lhs != rhs;
|
||||
case T_GREATER: return lhs > rhs;
|
||||
case T_LESS: return lhs < rhs;
|
||||
case T_LESS_EQUAL: return lhs <= rhs;
|
||||
case T_GREATER_EQUAL: return lhs >= rhs;
|
||||
case T_LESS_LESS: return lhs << rhs;
|
||||
case T_GREATER_GREATER: return lhs >> rhs;
|
||||
case T_PLUS: return lhs + rhs;
|
||||
case T_MINUS: return lhs - rhs;
|
||||
case T_STAR: return lhs * rhs;
|
||||
case T_SLASH: return rhs.is_zero() ? Value() : lhs / rhs;
|
||||
case T_PERCENT: return rhs.is_zero() ? Value() : lhs % rhs;
|
||||
case T_PIPE_PIPE: return lhs || rhs;
|
||||
case T_AMPER_AMPER: return lhs && rhs;
|
||||
case T_PIPE: return lhs | rhs;
|
||||
case T_CARET: return lhs ^ rhs;
|
||||
case T_AMPER: return lhs & rhs;
|
||||
case T_EQUAL_EQUAL: return lhs == rhs;
|
||||
case T_EXCLAIM_EQUAL: return lhs != rhs;
|
||||
case T_GREATER: return lhs > rhs;
|
||||
case T_LESS: return lhs < rhs;
|
||||
case T_LESS_EQUAL: return lhs <= rhs;
|
||||
case T_LESS_EQUAL_GREATER: return lhs.cmp(rhs);
|
||||
case T_GREATER_EQUAL: return lhs >= rhs;
|
||||
case T_LESS_LESS: return lhs << rhs;
|
||||
case T_GREATER_GREATER: return lhs >> rhs;
|
||||
case T_PLUS: return lhs + rhs;
|
||||
case T_MINUS: return lhs - rhs;
|
||||
case T_STAR: return lhs * rhs;
|
||||
case T_SLASH: return rhs.is_zero() ? Value() : lhs / rhs;
|
||||
case T_PERCENT: return rhs.is_zero() ? Value() : lhs % rhs;
|
||||
|
||||
default:
|
||||
return Value();
|
||||
|
||||
@@ -219,6 +219,7 @@ QString Utils::toString(CPlusPlus::Kind kind)
|
||||
TOKEN(T_LBRACKET);
|
||||
TOKEN(T_LESS);
|
||||
TOKEN(T_LESS_EQUAL);
|
||||
TOKEN(T_LESS_EQUAL_GREATER);
|
||||
TOKEN(T_LESS_LESS);
|
||||
TOKEN(T_LESS_LESS_EQUAL);
|
||||
TOKEN(T_LPAREN);
|
||||
|
||||
@@ -163,6 +163,7 @@ CPlusPlus::LanguageFeatures ProjectPart::deriveLanguageFeatures() const
|
||||
CPlusPlus::LanguageFeatures features;
|
||||
features.cxx11Enabled = languageVersion >= Utils::LanguageVersion::CXX11;
|
||||
features.cxx14Enabled = languageVersion >= Utils::LanguageVersion::CXX14;
|
||||
features.cxx20Enabled = languageVersion >= Utils::LanguageVersion::CXX20;
|
||||
features.cxxEnabled = hasCxx;
|
||||
features.c99Enabled = languageVersion >= Utils::LanguageVersion::C99;
|
||||
features.objCEnabled = languageExtensions.testFlag(Utils::LanguageExtension::ObjectiveC);
|
||||
|
||||
@@ -442,6 +442,7 @@ void tst_SimpleLexer::ppOpOrPunc()
|
||||
const QByteArray source = QTest::currentDataTag();
|
||||
LanguageFeatures languageFeatures;
|
||||
languageFeatures.cxxEnabled = true;
|
||||
languageFeatures.cxx20Enabled = true;
|
||||
run(source, toTokens({unsigned(expectedTokenKind)}), false, CompareKind, true, languageFeatures);
|
||||
}
|
||||
|
||||
@@ -492,6 +493,7 @@ void tst_SimpleLexer::ppOpOrPunc_data()
|
||||
QTest::newRow("==") << T_EQUAL_EQUAL;
|
||||
QTest::newRow("!=") << T_EXCLAIM_EQUAL;
|
||||
QTest::newRow("<=") << T_LESS_EQUAL;
|
||||
QTest::newRow("<=>") << T_LESS_EQUAL_GREATER;
|
||||
QTest::newRow(">=") << T_GREATER_EQUAL;
|
||||
QTest::newRow("&&") << T_AMPER_AMPER;
|
||||
QTest::newRow("||") << T_PIPE_PIPE;
|
||||
|
||||
Reference in New Issue
Block a user