template simplifier: add 2 new template parameter simplifications (#1884)

* template simplifier: add 2 new template parameter simplifications

int{} -> 0
decltype(int{}) -> int

This fixes reduced test cases like #9153.  I'm not sure they will help
real world code that much.

It was necessary to increase the pass count to 4 to get #9153 completly
simplified.

* relax decltype(type{}) simplification to any type
This commit is contained in:
IOBYTE 2019-06-15 03:46:32 -04:00 committed by Daniel Marjamäki
parent e37b92fb3b
commit 75720528b0
2 changed files with 52 additions and 5 deletions

View File

@ -1653,7 +1653,7 @@ void TemplateSimplifier::expandTemplate(
}
dst->insertToken(";", "", true);
if (isVariable)
if (isVariable || isFunction)
simplifyTemplateArgs(dstStart, dst);
}
@ -2344,6 +2344,27 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
tok->str(MathLib::toString(MathLib::toLongNumber(tok->str())));
}
if (validTokenEnd(bounded, tok, backToken, 5) &&
Token::Match(tok, "decltype ( %type% { } )")) {
tok->deleteThis();
tok->deleteThis();
tok->deleteNext();
tok->deleteNext();
tok->deleteNext();
ret = true;
}
if (validTokenEnd(bounded, tok, backToken, 2) &&
Token::Match(tok, "char|short|int|long { }")) {
tok->str("0"); // FIXME add type suffix
tok->isSigned(false);
tok->isUnsigned(false);
tok->isLong(false);
tok->deleteNext();
tok->deleteNext();
ret = true;
}
if (tok && tok->isNumber()) {
if (validTokenEnd(bounded, tok, backToken, 2) &&
simplifyNumericCalculations(tok)) {
@ -3250,7 +3271,7 @@ void TemplateSimplifier::simplifyTemplates(
}
}
// TODO: 3 is not the ideal number of loops.
// TODO: 4 is not the ideal number of loops.
// We should loop until the number of declarations is 0 but we can't
// do that until we instantiate unintstantiated templates with their symbolic types.
// That will allow the uninstantiated template code to be removed from the symbol database.
@ -3258,7 +3279,7 @@ void TemplateSimplifier::simplifyTemplates(
// the uninstantiated template code in the symbol database can't be removed until #8768
// is fixed.
for (int i = 0; i < 3; ++i) {
for (int i = 0; i < 4; ++i) {
if (i) {
// it may take more than one pass to simplify type aliases
while (mTokenizer->simplifyUsing())

View File

@ -152,6 +152,7 @@ private:
TEST_CASE(template112); // #9146 syntax error
TEST_CASE(template113);
TEST_CASE(template114); // #9155
TEST_CASE(template115); // #9153
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -1848,8 +1849,8 @@ private:
"auto d() -> typename a<decltype(b{})>::e {\n"
" d<int, c, int>();\n"
"}";
const char exp[] = "auto d<int,c,int> ( ) . a < decltype ( int { } ) > :: e ; "
"auto d<int,c,int> ( ) . a < decltype ( int { } ) > :: e { "
const char exp[] = "auto d<int,c,int> ( ) . a < int > :: e ; "
"auto d<int,c,int> ( ) . a < int > :: e { "
"d<int,c,int> ( ) ; "
"}";
ASSERT_EQUALS(exp, tok(code));
@ -2696,6 +2697,31 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template115() { // #9153
const char code[] = "namespace {\n"
" namespace b {\n"
" template <int c> struct B { using B<c / 2>::d; };\n"
" }\n"
" template <class, class> using e = typename b::B<int{}>;\n"
" namespace b {\n"
" template <class> struct f {};\n"
" }\n"
" template <class c> using g = b::f<e<int, c>>;\n"
"}\n"
"g<int> g1;";
const char exp[] = "namespace { "
"namespace b { "
"struct B<0> ; "
"} "
"namespace b { "
"struct f<b::B<0>> ; "
"} "
"} "
"b :: f<b::B<0>> g1 ; struct b :: B<0> { using B<0> :: d ; } ; "
"struct b :: f<b::B<0>> { } ;";
ASSERT_EQUALS(exp, tok(code));
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"