Handle c++20 spaceship operator

This commit is contained in:
Daniel Marjamäki 2021-04-22 19:15:22 +02:00
parent bccc0607d1
commit 26c0945309
5 changed files with 49 additions and 2 deletions

View File

@ -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 == "--"))

View File

@ -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<std::string> keywords = {
"inline"
, "_inline"

View File

@ -695,6 +695,9 @@ private:
/** Remove alignas */
void removeAlignas();
/** Simplify c++20 spaceship operator */
void simplifySpaceshipOperator();
/**
* Remove keywords "volatile", "inline", "register", and "restrict"
*/

View File

@ -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);

View File

@ -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)