Fix ternary operator simplification to accept template parameters. (#2048)
Also simplify decltype of bool and numeric literals in template arguments.
This commit is contained in:
parent
badc573b80
commit
07ac6c5f08
|
@ -2378,7 +2378,9 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
|||
again = true;
|
||||
|
||||
for (Token *tok = first->next(); tok && tok != end; tok = tok->next()) {
|
||||
if (tok->str() == "?" && (tok->previous()->isNumber() || tok->previous()->isBoolean())) {
|
||||
if (tok->str() == "?" &&
|
||||
((tok->previous()->isNumber() || tok->previous()->isBoolean()) ||
|
||||
Token::Match(tok->tokAt(-3), "( %bool%|%num% )"))) {
|
||||
const int offset = (tok->previous()->str() == ")") ? 2 : 1;
|
||||
|
||||
// Find the token ":" then go to the next token
|
||||
|
@ -2415,10 +2417,10 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
|||
|
||||
unsigned int ternaryOplevel = 0;
|
||||
for (const Token *endTok = colon; endTok; endTok = endTok->next()) {
|
||||
if (Token::Match(endTok, "(|[|{")) {
|
||||
if (Token::Match(endTok, "(|[|{"))
|
||||
endTok = endTok->link();
|
||||
}
|
||||
|
||||
else if (endTok->str() == "<" && (endTok->strAt(1) == ">" || templateParameters(endTok)))
|
||||
endTok = endTok->findClosingBracket();
|
||||
else if (endTok->str() == "?")
|
||||
++ternaryOplevel;
|
||||
else if (Token::Match(endTok, ")|}|]|;|,|:|>")) {
|
||||
|
@ -2529,6 +2531,37 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
|||
ret = true;
|
||||
}
|
||||
|
||||
if (validTokenEnd(bounded, tok, backToken, 3) &&
|
||||
Token::Match(tok, "decltype ( %bool%|%num% )")) {
|
||||
tok->deleteThis();
|
||||
tok->deleteThis();
|
||||
if (tok->isBoolean())
|
||||
tok->str("bool");
|
||||
else if (MathLib::isFloat(tok->str())) {
|
||||
// MathLib::getSuffix doesn't work for floating point numbers
|
||||
char suffix = tok->str().back();
|
||||
if (suffix == 'f' || suffix == 'F')
|
||||
tok->str("float");
|
||||
else if (suffix == 'l' || suffix == 'L') {
|
||||
tok->str("double");
|
||||
tok->isLong(true);
|
||||
} else
|
||||
tok->str("double");
|
||||
} else if (MathLib::isInt(tok->str())) {
|
||||
std::string suffix = MathLib::getSuffix(tok->str());
|
||||
if (suffix.find("LL") != std::string::npos) {
|
||||
tok->str("long");
|
||||
tok->isLong(true);
|
||||
} else if (suffix.find('L') != std::string::npos)
|
||||
tok->str("long");
|
||||
else
|
||||
tok->str("int");
|
||||
tok->isUnsigned(suffix.find('U') != std::string::npos);
|
||||
}
|
||||
tok->deleteNext();
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (validTokenEnd(bounded, tok, backToken, 2) &&
|
||||
Token::Match(tok, "char|short|int|long { }")) {
|
||||
tok->str("0"); // FIXME add type suffix
|
||||
|
|
|
@ -5884,10 +5884,10 @@ bool Tokenizer::simplifyConstTernaryOp()
|
|||
|
||||
int ternaryOplevel = 0;
|
||||
for (const Token *endTok = colon; endTok; endTok = endTok->next()) {
|
||||
if (Token::Match(endTok, "(|[|{")) {
|
||||
if (Token::Match(endTok, "(|[|{"))
|
||||
endTok = endTok->link();
|
||||
}
|
||||
|
||||
else if (endTok->str() == "<" && (endTok->strAt(1) == ">" || mTemplateSimplifier->templateParameters(endTok)))
|
||||
endTok = endTok->findClosingBracket();
|
||||
else if (endTok->str() == "?")
|
||||
++ternaryOplevel;
|
||||
else if (Token::Match(endTok, ")|}|]|;|,|:|>")) {
|
||||
|
@ -5904,7 +5904,6 @@ bool Tokenizer::simplifyConstTernaryOp()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,8 @@ private:
|
|||
TEST_CASE(template_variable_2);
|
||||
TEST_CASE(template_variable_3);
|
||||
TEST_CASE(template_variable_4);
|
||||
|
||||
TEST_CASE(simplifyDecltype);
|
||||
}
|
||||
|
||||
std::string tok(const char code[], bool debugwarnings = false, Settings::PlatformType type = Settings::Native) {
|
||||
|
@ -4381,6 +4383,51 @@ private:
|
|||
"void test<int> ( ) { }";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
||||
void simplifyDecltype() {
|
||||
const char code[] = "template<typename T> class type { };\n"
|
||||
"type<decltype(true)> b;\n"
|
||||
"type<decltype(0)> i;\n"
|
||||
"type<decltype(0U)> ui;\n"
|
||||
"type<decltype(0L)> l;\n"
|
||||
"type<decltype(0UL)> ul;\n"
|
||||
"type<decltype(0LL)> ll;\n"
|
||||
"type<decltype(0ULL)> ull;\n"
|
||||
"type<decltype(0.0)> d;\n"
|
||||
"type<decltype(0.0F)> f;\n"
|
||||
"type<decltype(0.0L)> ld;";
|
||||
const char expected[] = "class type<bool> ; "
|
||||
"class type<int> ; "
|
||||
"class type<unsignedint> ; "
|
||||
"class type<long> ; "
|
||||
"class type<unsignedlong> ; "
|
||||
"class type<longlong> ; "
|
||||
"class type<unsignedlonglong> ; "
|
||||
"class type<double> ; "
|
||||
"class type<float> ; "
|
||||
"class type<longdouble> ; "
|
||||
"type<bool> b ; "
|
||||
"type<int> i ; "
|
||||
"type<unsignedint> ui ; "
|
||||
"type<long> l ; "
|
||||
"type<unsignedlong> ul ; "
|
||||
"type<longlong> ll ; "
|
||||
"type<unsignedlonglong> ull ; "
|
||||
"type<double> d ; "
|
||||
"type<float> f ; "
|
||||
"type<longdouble> ld ; "
|
||||
"class type<bool> { } ; "
|
||||
"class type<int> { } ; "
|
||||
"class type<unsignedint> { } ; "
|
||||
"class type<long> { } ; "
|
||||
"class type<unsignedlong> { } ; "
|
||||
"class type<longlong> { } ; "
|
||||
"class type<unsignedlonglong> { } ; "
|
||||
"class type<double> { } ; "
|
||||
"class type<float> { } ; "
|
||||
"class type<longdouble> { } ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestSimplifyTemplate)
|
||||
|
|
|
@ -3407,6 +3407,13 @@ private:
|
|||
ASSERT_EQUALS("; x = * b ;", tok("; x = (false)?*a:*b;"));
|
||||
ASSERT_EQUALS("void f ( ) { return 1 ; }", tok("void f() { char *p=0; return (p==0)?1:2; }"));
|
||||
}
|
||||
|
||||
{
|
||||
ASSERT_EQUALS("; type = decay_t < decltype ( declval < T > ( ) ) > ;",
|
||||
tok("; type = decay_t<decltype(true ? declval<T>() : declval<U>())>;"));
|
||||
ASSERT_EQUALS("; type = decay_t < decltype ( declval < U > ( ) ) > ;",
|
||||
tok("; type = decay_t<decltype(false ? declval<T>() : declval<U>())>;"));
|
||||
}
|
||||
}
|
||||
|
||||
void calculations() {
|
||||
|
|
Loading…
Reference in New Issue