From 26c0945309f5e3fa62cfc38713dbadcb0d6e25de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 22 Apr 2021 19:15:22 +0200 Subject: [PATCH] Handle c++20 spaceship operator --- lib/token.cpp | 2 ++ lib/tokenize.cpp | 14 ++++++++++++++ lib/tokenize.h | 3 +++ lib/tokenlist.cpp | 14 ++++++++++++-- test/testtokenize.cpp | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 205bfaf53..16879c204 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -111,6 +111,8 @@ void Token::update_property_info() mStr == ">" || mStr == ">=")) tokType(eComparisonOp); + else if (mStr == "<=>") + tokType(eComparisonOp); else if (mStr.size() == 2 && (mStr == "++" || mStr == "--")) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 7a4947361..91934ee16 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4783,6 +4783,8 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) removeAlignas(); + simplifySpaceshipOperator(); + // Bail out if code is garbage if (mTimerResults) { Timer t("Tokenizer::tokenize::findGarbageCode", mSettings->showtime, mTimerResults); @@ -10923,6 +10925,18 @@ void Tokenizer::removeAlignas() } } +void Tokenizer::simplifySpaceshipOperator() +{ + if (isCPP() && mSettings->standards.cpp >= Standards::CPP20) { + for (Token *tok = list.front(); tok && tok->next(); tok = tok->next()) { + if (Token::simpleMatch(tok, "<= >")) { + tok->str("<=>"); + tok->deleteNext(); + } + } + } +} + static const std::unordered_set keywords = { "inline" , "_inline" diff --git a/lib/tokenize.h b/lib/tokenize.h index af92bfc82..27754efbf 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -695,6 +695,9 @@ private: /** Remove alignas */ void removeAlignas(); + /** Simplify c++20 spaceship operator */ + void simplifySpaceshipOperator(); + /** * Remove keywords "volatile", "inline", "register", and "restrict" */ diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index e6a55903a..00033f0c1 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -1152,16 +1152,26 @@ static void compileShift(Token *&tok, AST_state& state) } } -static void compileRelComp(Token *&tok, AST_state& state) +static void compileThreewayComp(Token *&tok, AST_state& state) { compileShift(tok, state); while (tok) { - if (Token::Match(tok, "<|<=|>=|>") && !tok->link()) { + if (tok->str() == "<=>") { compileBinOp(tok, state, compileShift); } else break; } } +static void compileRelComp(Token *&tok, AST_state& state) +{ + compileThreewayComp(tok, state); + while (tok) { + if (Token::Match(tok, "<|<=|>=|>") && !tok->link()) { + compileBinOp(tok, state, compileThreewayComp); + } else break; + } +} + static void compileEqComp(Token *&tok, AST_state& state) { compileRelComp(tok, state); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index ee8612a26..50fea13e9 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -327,6 +327,7 @@ private: TEST_CASE(simplifyOperatorName26); TEST_CASE(simplifyOperatorName27); TEST_CASE(simplifyOperatorName28); + TEST_CASE(simplifyOperatorName29); // spaceship operator TEST_CASE(simplifyOverloadedOperators1); TEST_CASE(simplifyOverloadedOperators2); // (*this)(123) @@ -418,6 +419,8 @@ private: TEST_CASE(removeAlignas); TEST_CASE(simplifyCoroutines); + + TEST_CASE(simplifySpaceshipOperator); } std::string tokenizeAndStringify(const char code[], bool expand = true, Settings::PlatformType platform = Settings::Native, const char* filename = "test.cpp", bool cpp11 = true) { @@ -4707,6 +4710,12 @@ private: tokenizeAndStringify(code)); } + void simplifyOperatorName29() { + Settings settings; + settings.standards.cpp = Standards::CPP20; + ASSERT_EQUALS("auto operator<=> ( ) ;", tokenizeAndStringify("auto operator<=>();", settings)); + } + void simplifyOverloadedOperators1() { const char code[] = "struct S { void operator()(int); };\n" "\n" @@ -5309,6 +5318,7 @@ private: tokenList.combineStringAndCharLiterals(); tokenList.combineOperators(); + tokenList.simplifySpaceshipOperator(); tokenList.createLinks(); tokenList.createLinks2(); tokenList.list.front()->assignIndexes(); @@ -5363,6 +5373,7 @@ private: ASSERT_EQUALS("abc=,", testAst("a,b=c")); ASSERT_EQUALS("a-1+", testAst("-a+1")); ASSERT_EQUALS("ab++-c-", testAst("a-b++-c")); + ASSERT_EQUALS("ab<=>", testAst("a<=>b")); // sizeof ASSERT_EQUALS("ab.sizeof", testAst("sizeof a.b")); @@ -6526,6 +6537,13 @@ private: const char expected3[] = "generator < int > f ( ) { co_return ( 7 ) ; }"; ASSERT_EQUALS(expected3, tokenizeAndStringify(code3, settings)); } + + void simplifySpaceshipOperator() { + Settings settings; + settings.standards.cpp = Standards::CPP20; + + ASSERT_EQUALS("; x <=> y ;", tokenizeAndStringify(";x<=>y;", settings)); + } }; REGISTER_TEST(TestTokenizer)