From 247b2d8c8382622bf3a4c34b00ffa43373418a8f Mon Sep 17 00:00:00 2001 From: dummyunit Date: Sun, 23 May 2021 11:40:09 +0300 Subject: [PATCH] Support array types in template simplifier (#3267) --- lib/templatesimplifier.cpp | 8 ++++---- test/testsimplifytemplate.cpp | 36 +++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 28ddb2602..8abeece3e 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -528,7 +528,7 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) } tok = tok->next(); - if (Token::simpleMatch(tok,"(")) + if (Token::Match(tok, "(|[")) tok = tok->link()->next(); if (!tok) @@ -2939,7 +2939,7 @@ std::string TemplateSimplifier::getNewName( const Token * endToken = tok2->next()->findClosingBracket(); for (Token *tok3 = tok2->tokAt(2); tok3 != endToken && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) { // #2721 - unhandled [ => bail out - if (tok3->str() == "[") { + if (tok3->str() == "[" && !Token::Match(tok3->next(), "%num%| ]")) { typeForNewName.clear(); break; } @@ -2954,9 +2954,9 @@ std::string TemplateSimplifier::getNewName( if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]")) { mTypesUsedInTemplateInstantiation.emplace_back(tok3, ""); } - if (tok3->str() == "(") + if (Token::Match(tok3, "(|[")) ++indentlevel; - else if (tok3->str() == ")") + else if (Token::Match(tok3, ")|]")) --indentlevel; const bool constconst = tok3->str() == "const" && tok3->strAt(1) == "const"; if (!constconst) { diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 4a348e8a9..ff8009a5f 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -237,6 +237,7 @@ private: TEST_CASE(template_namespace_10); TEST_CASE(template_namespace_11); // #7145 TEST_CASE(template_pointer_type); + TEST_CASE(template_array_type); // Test TemplateSimplifier::templateParameters TEST_CASE(templateParameters); @@ -875,8 +876,7 @@ private: "class C: public A {};\n" "\n" "C<2> a;\n"; - // TODO: expand A also - ASSERT_EQUALS("template < class T > class A { public: T x ; } ; class C<2> ; C<2> a ; class C<2> : public A < char [ 2 ] > { } ;", tok(code)); + ASSERT_EQUALS("class A ; class C<2> ; C<2> a ; class C<2> : public A { } ; class A { public: char [ 2 ] x ; } ;", tok(code)); } void template27() { @@ -5104,6 +5104,36 @@ private: "void foo ( int * const x ) { }", tok(code)); } + void template_array_type() { + ASSERT_EQUALS("void foo ( int [ ] x ) ; " + "void bar ( ) { int [ 3 ] y ; foo ( y ) ; } " + "void foo ( int [ ] x ) { } ;", + tok("template void foo(T x) {};\n" + "void bar() {\n" + " int[3] y;\n" + " foo(y);\n" + "}")); + ASSERT_EQUALS("struct A ; " + "A y ; " + "struct A { int [ 2 ] x ; } ;", + tok("template struct A { T x; };\n" + "A y;")); + + // Previously resulted in: + // test.cpp:2:33: error: Syntax Error: AST broken, binary operator '>' doesn't have two operands. [internalAstError] + ASSERT_EQUALS("struct A[]> ; " + "struct B> ; " + "struct C> ; " + "C> y ; " + "struct C> : B> { } ; " + "struct B> { A[]> x ; } ; " + "struct A[]> { } ;", + tok("template struct A {};\n" + "template struct B { A x; };\n" + "template struct C : B {};\n" + "C> y;")); + } + unsigned int templateParameters(const char code[]) { Tokenizer tokenizer(&settings, this); @@ -5139,6 +5169,8 @@ private: ASSERT_EQUALS(1U, templateParameters("X x;")); ASSERT_EQUALS(2U, templateParameters("X x;")); ASSERT_EQUALS(2U, templateParameters("X<1, T> x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); + ASSERT_EQUALS(1U, templateParameters("X x;")); ASSERT_EQUALS(1U, templateParameters("X x;")); ASSERT_EQUALS(2U, templateParameters("X=0> x;")); ASSERT_EQUALS(3U, templateParameters("X=0, i - 2> x;"));