diff --git a/gui/projectfiledialog.ui b/gui/projectfiledialog.ui index 343dab7d9..e7d40d3e9 100644 --- a/gui/projectfiledialog.ui +++ b/gui/projectfiledialog.ui @@ -17,7 +17,7 @@ - 2 + 0 diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 6a8d48241..174cd43d6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2102,7 +2102,11 @@ Function::Function(const Tokenizer *mTokenizer, } // class constructor/destructor - else if (tokenDef->str() == scope->className && scope->type != Scope::ScopeType::eNamespace) { + else if (((tokenDef->str() == scope->className) || + (tokenDef->str().substr(0, scope->className.size()) == scope->className && + tokenDef->str().size() > scope->className.size() + 1 && + tokenDef->str()[scope->className.size() + 1] == '<')) && + scope->type != Scope::ScopeType::eNamespace) { // destructor if (tokenDef->previous()->str() == "~") type = Function::eDestructor; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 1a19a7ef1..05fe300e6 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -673,15 +673,6 @@ bool TemplateSimplifier::removeTemplate(Token *tok) if (tok2->str() == ">") countgt++; - // don't remove constructor - if (tok2->str() == "explicit" || - (countgt == 1 && Token::Match(tok2->previous(), "> %type% (") && - Tokenizer::startOfExecutableScope(tok2->linkAt(1)))) { - eraseTokens(tok, tok2); - deleteToken(tok); - return true; - } - if (tok2->str() == ";") { tok2 = tok2->next(); eraseTokens(tok, tok2); @@ -895,8 +886,9 @@ void TemplateSimplifier::getTemplateInstantiations() // get all declarations with this name for (auto pos = functionNameMap.lower_bound(tok->str()); pos != functionNameMap.upper_bound(tok->str()); ++pos) { - // look for declaration with same qualification - if (pos->second->fullName() == fullName) { + // look for declaration with same qualification or constructor with same qualification + if (pos->second->fullName() == fullName || + (pos->second->scope() == fullName && tok->str() == pos->second->name())) { std::vector templateParams; getTemplateParametersInDeclaration(pos->second->token()->tokAt(2), templateParams); @@ -3038,7 +3030,9 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( if (!Token::Match(instantiation.token(), "%name% <")) continue; - if (instantiation.fullName() != templateDeclaration.fullName()) { + if (!((instantiation.fullName() == templateDeclaration.fullName()) || + (instantiation.name() == templateDeclaration.name() && + instantiation.fullName() == templateDeclaration.scope()))) { // FIXME: fallback to not matching scopes until type deduction works // names must match diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index c79a040f0..d84dd6275 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -252,6 +252,7 @@ private: TEST_CASE(templateTypeDeduction2); TEST_CASE(templateTypeDeduction3); TEST_CASE(templateTypeDeduction4); // #9983 + TEST_CASE(templateTypeDeduction5); TEST_CASE(simplifyTemplateArgs1); TEST_CASE(simplifyTemplateArgs2); @@ -5374,6 +5375,73 @@ private: } } + void templateTypeDeduction5() { + { + const char code[] = "class Fred {\n" + "public:\n" + " template Fred(T t) { }\n" + "};\n" + "Fred fred1 = Fred(0);\n" + "Fred fred2 = Fred(0.0);\n" + "Fred fred3 = Fred(\"zero\");\n" + "Fred fred4 = Fred(false);"; + const char exp[] = "class Fred { " + "public: " + "Fred ( int t ) ; " + "Fred ( double t ) ; " + "Fred ( const char * t ) ; " + "Fred ( bool t ) ; " + "} ; " + "Fred fred1 ; fred1 = Fred ( 0 ) ; " + "Fred fred2 ; fred2 = Fred ( 0.0 ) ; " + "Fred fred3 ; fred3 = Fred ( \"zero\" ) ; " + "Fred fred4 ; fred4 = Fred ( false ) ; " + "Fred :: Fred ( int t ) { } " + "Fred :: Fred ( double t ) { } " + "Fred :: Fred ( const char * t ) { } " + "Fred :: Fred ( bool t ) { }"; + ASSERT_EQUALS(exp, tok(code)); + } + { + const char code[] = "namespace NS {\n" + "class Fred {\n" + "public:\n" + " template Fred(T t) { }\n" + "};\n" + "Fred fred1 = Fred(0);\n" + "Fred fred2 = Fred(0.0);\n" + "Fred fred3 = Fred(\"zero\");\n" + "Fred fred4 = Fred(false);\n" + "}\n" + "NS::Fred fred1 = NS::Fred(0);\n" + "NS::Fred fred2 = NS::Fred(0.0);\n" + "NS::Fred fred3 = NS::Fred(\"zero\");\n" + "NS::Fred fred4 = NS::Fred(false);\n"; + const char exp[] = "namespace NS { " + "class Fred { " + "public: " + "Fred ( int t ) ; " + "Fred ( double t ) ; " + "Fred ( const char * t ) ; " + "Fred ( bool t ) ; " + "} ; " + "Fred fred1 ; fred1 = Fred ( 0 ) ; " + "Fred fred2 ; fred2 = Fred ( 0.0 ) ; " + "Fred fred3 ; fred3 = Fred ( \"zero\" ) ; " + "Fred fred4 ; fred4 = Fred ( false ) ; " + "} " + "NS :: Fred fred1 ; fred1 = NS :: Fred ( 0 ) ; " + "NS :: Fred fred2 ; fred2 = NS :: Fred ( 0.0 ) ; " + "NS :: Fred fred3 ; fred3 = NS :: Fred ( \"zero\" ) ; " + "NS :: Fred fred4 ; fred4 = NS :: Fred ( false ) ; " + "NS :: Fred :: Fred ( int t ) { } " + "NS :: Fred :: Fred ( double t ) { } " + "NS :: Fred :: Fred ( const char * t ) { } " + "NS :: Fred :: Fred ( bool t ) { }"; + ASSERT_EQUALS(exp, tok(code)); + } + } + void simplifyTemplateArgs1() { ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template foo = N; foo < ( 2 ) >;")); ASSERT_EQUALS("foo<2> = 2 ; foo<2> ;", tok("template foo = N; foo < 1 + 1 >;"));