aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/cplusplus/Lexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/cplusplus/Lexer.cpp')
-rw-r--r--src/libs/3rdparty/cplusplus/Lexer.cpp71
1 files changed, 62 insertions, 9 deletions
diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp
index dc24f5e96c..92cfc5d6ec 100644
--- a/src/libs/3rdparty/cplusplus/Lexer.cpp
+++ b/src/libs/3rdparty/cplusplus/Lexer.cpp
@@ -25,6 +25,8 @@
#include "cppassert.h"
+#include <QScopeGuard>
+
#include <cctype>
using namespace CPlusPlus;
@@ -213,14 +215,19 @@ void Lexer::scan_helper(Token *tok)
return;
} else if (!control() && isRawStringLiteral(s._tokenKind)) {
tok->f.kind = s._tokenKind;
- if (scanUntilRawStringLiteralEndSimple())
+ const bool found = _expectedRawStringSuffix.isEmpty()
+ ? scanUntilRawStringLiteralEndSimple() : scanUntilRawStringLiteralEndPrecise();
+ if (found) {
+ scanOptionalUserDefinedLiteral(tok);
_state = 0;
+ }
return;
} else { // non-raw strings
tok->f.joined = true;
tok->f.kind = s._tokenKind;
_state = 0;
scanUntilQuote(tok, '"');
+ scanOptionalUserDefinedLiteral(tok);
return;
}
@@ -608,7 +615,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();
@@ -744,6 +756,10 @@ void Lexer::scanStringLiteral(Token *tok, unsigned char hint)
void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
{
+ QScopeGuard cleanup([this] { _expectedRawStringSuffix.clear(); });
+ if (control())
+ cleanup.dismiss();
+
const char *yytext = _currentChar;
int delimLength = -1;
@@ -766,6 +782,8 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
tok->f.kind = T_ERROR;
return;
}
+ if (!control())
+ _expectedRawStringSuffix.append(_yychar);
yyinp();
} else {
if (!closingDelimCandidate) {
@@ -808,12 +826,36 @@ void Lexer::scanRawStringLiteral(Token *tok, unsigned char hint)
else
tok->f.kind = T_RAW_STRING_LITERAL;
- if (!control() && !closed)
+ if (!control() && !closed) {
+ cleanup.dismiss();
s._tokenKind = tok->f.kind;
+ _expectedRawStringSuffix.prepend(')');
+ _expectedRawStringSuffix.append('"');
+ }
+ if (closed)
+ scanOptionalUserDefinedLiteral(tok);
+}
+
+bool Lexer::scanUntilRawStringLiteralEndPrecise()
+{
+ QByteArray slidingWindow;
+ slidingWindow.reserve(_expectedRawStringSuffix.size());
+ while (_yychar) {
+ slidingWindow.append(_yychar);
+ if (slidingWindow.size() > _expectedRawStringSuffix.size())
+ slidingWindow.remove(0, 1);
+ if (slidingWindow == _expectedRawStringSuffix) {
+ _expectedRawStringSuffix.clear();
+ yyinp();
+ return true;
+ }
+ yyinp();
+ }
+ return false;
}
-// In the highlighting case we don't have any further information
-// like the delimiter or its length, so just match for: ...)..."
+// In case we don't have any further information
+// like the delimiter or its length, just match for: ...)..."
bool Lexer::scanUntilRawStringLiteralEndSimple()
{
bool closingParenthesisPassed = false;
@@ -926,11 +968,15 @@ bool Lexer::scanOptionalIntegerSuffix(bool allowU)
yyinp();
if (_yychar == 'l')
yyinp();
+ if (_yychar == 'u' || _yychar == 'U')
+ yyinp();
return true;
case 'L':
yyinp();
if (_yychar == 'L')
yyinp();
+ if (_yychar == 'u' || _yychar == 'U')
+ yyinp();
return true;
default:
return false;
@@ -939,7 +985,7 @@ bool Lexer::scanOptionalIntegerSuffix(bool allowU)
void Lexer::scanOptionalUserDefinedLiteral(Token *tok)
{
- if (_languageFeatures.cxx11Enabled && _yychar == '_') {
+ if (_languageFeatures.cxx11Enabled && (_yychar == '_' || std::isalpha(_yychar))) {
tok->f.userDefinedLiteral = true;
while (std::isalnum(_yychar) || _yychar == '_' || isByteOfMultiByteCodePoint(_yychar))
yyinp();
@@ -1030,7 +1076,7 @@ void Lexer::scanPreprocessorNumber(Token *tok, bool dotAlreadySkipped)
yyinp();
if (_yychar == '+' || _yychar == '-')
yyinp();
- } else if (std::isalnum(_yychar) || _yychar == '_' || _yychar == '.') {
+ } else if (std::isalnum(_yychar) || (_yychar == '\'') || _yychar == '_' || _yychar == '.') {
yyinp();
} else {
scanOptionalUserDefinedLiteral(tok);
@@ -1052,10 +1098,17 @@ void Lexer::scanIdentifier(Token *tok, unsigned extraProcessedChars)
yyinp();
}
int yylen = _currentChar - yytext;
- if (f._scanKeywords)
+ if (f._scanKeywords) {
tok->f.kind = classify(yytext, yylen, _languageFeatures);
- else
+
+ if (tok->f.kind == T_FALSE || tok->f.kind == T_TRUE) {
+ if (control()) {
+ tok->number = control()->numericLiteral(yytext, yylen);
+ }
+ }
+ } else {
tok->f.kind = T_IDENTIFIER;
+ }
if (tok->f.kind == T_IDENTIFIER) {
tok->f.kind = classifyOperator(yytext, yylen);