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:
parent
e37b92fb3b
commit
75720528b0
|
@ -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())
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue