CPlusPlus: Add parser support for declarations of user-defined literals

... without a space before the identifier.

Change-Id: I977ffae82eb86f5ae6ea594cba17cc486e63bf6c
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2024-08-06 17:06:10 +02:00
parent 5f3a343352
commit 9926de01c1
4 changed files with 22 additions and 14 deletions

View File

@@ -1533,14 +1533,21 @@ bool Parser::parseOperator(OperatorAST *&node) // ### FIXME
} else if (LA() == T_LBRACKET && LA(2) == T_RBRACKET) { } else if (LA() == T_LBRACKET && LA(2) == T_RBRACKET) {
ast->op_token = ast->open_token = consumeToken(); ast->op_token = ast->open_token = consumeToken();
ast->close_token = consumeToken(); ast->close_token = consumeToken();
} else if (_languageFeatures.cxx11Enabled && } else if (_languageFeatures.cxx11Enabled && LA() == T_STRING_LITERAL) {
LA() == T_STRING_LITERAL && LA(2) == T_IDENTIFIER &&
!tok().f.userDefinedLiteral && tok().string->size() == 0 &&
tok(2).identifier->size() > 1 && tok(2).identifier->chars()[0] == '_') {
// C++11 user-defined literal operator, e.g.: // C++11 user-defined literal operator, e.g.:
// int operator"" _abc123(const char *str, size_t size) { ... } // int operator"" _abc123(const char *str, size_t size) { ... }
// There are two variants: With and without a space after the quotes. The former
// is deprecated.
if (LA(2) == T_IDENTIFIER && !tok().f.userDefinedLiteral
&& tok().string->size() == 0 &&
tok(2).identifier->size() > 1 && tok(2).identifier->chars()[0] == '_') {
ast->op_token = consumeToken(); ast->op_token = consumeToken();
consumeToken(); // consume literal operator identifier consumeToken(); // consume literal operator identifier
} else if (tok().f.userDefinedLiteral) {
ast->op_token = consumeToken();
} else {
return false;
}
} else { } else {
return false; return false;
} }

View File

@@ -12,14 +12,7 @@ CPlusPlusAutotest {
name: "Data Files" name: "Data Files"
prefix: "data/" prefix: "data/"
fileTags: ["data"] fileTags: ["data"]
files: [ files: "*"
"inlineNamespace.1.cpp",
"inlineNamespace.1.errors.txt",
"staticAssert.1.cpp",
"staticAssert.1.errors.txt",
"noExcept.1.cpp",
"noExcept.1.errors.txt"
]
} }
cpp.defines: base.concat(['SRCDIR="' + path + '"']) cpp.defines: base.concat(['SRCDIR="' + path + '"'])

View File

@@ -0,0 +1,7 @@
wchar_t operator ""_wc(const wchar_t c) { return c; }
int main()
{
const auto c = L'c'_wc;
return c;
}

View File

@@ -179,6 +179,7 @@ void tst_cxx11::parse_data()
QTest::newRow("trailingtypespec.1") << "trailingtypespec.1.cpp" << ""; QTest::newRow("trailingtypespec.1") << "trailingtypespec.1.cpp" << "";
QTest::newRow("lambda.2") << "lambda.2.cpp" << ""; QTest::newRow("lambda.2") << "lambda.2.cpp" << "";
QTest::newRow("userDefinedLiterals.1") << "userDefinedLiterals.1.cpp" << ""; QTest::newRow("userDefinedLiterals.1") << "userDefinedLiterals.1.cpp" << "";
QTest::newRow("userDefinedLiterals.2") << "userDefinedLiterals.2.cpp" << "";
QTest::newRow("rawstringliterals") << "rawstringliterals.cpp" << ""; QTest::newRow("rawstringliterals") << "rawstringliterals.cpp" << "";
} }