diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 055890d9e..46717e796 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1572,8 +1572,38 @@ void TemplateSimplifier::expandTemplate( tok5->str(newName); eraseTokens(tok5, tok5->next()->findClosingBracket()->next()); } - } else if (copy) - mTokenList.addtoken(tok5, tok5->linenr(), tok5->fileIndex()); + } else if (copy) { + bool added = false; + if (tok5->isName()) { + // search for this token in the type vector + unsigned int itype = 0; + while (itype < typeParametersInDeclaration.size() && typeParametersInDeclaration[itype]->str() != tok5->str()) + ++itype; + + // replace type with given type.. + if (itype < typeParametersInDeclaration.size()) { + unsigned int typeindentlevel = 0; + for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token; + typetok && (typeindentlevel>0 || !Token::Match(typetok, ",|>")); + typetok = typetok->next()) { + if (Token::simpleMatch(typetok, ". . .")) { + typetok = typetok->tokAt(2); + } else { + if (Token::Match(typetok, "%name% <") && templateParameters(typetok->next()) > 0) + ++typeindentlevel; + else if (typeindentlevel > 0 && typetok->str() == ">") + --typeindentlevel; + mTokenList.addtoken(typetok, tok5->linenr(), tok5->fileIndex()); + mTokenList.back()->isTemplateArg(true); + added = true; + break; + } + } + } + } + if (!added) + mTokenList.addtoken(tok5, tok5->linenr(), tok5->fileIndex()); + } tok5 = tok5->next(); } diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index de305f66b..b86a53602 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -140,6 +140,7 @@ private: TEST_CASE(template100); // #8967 TEST_CASE(template101); // #8968 TEST_CASE(template102); // #9005 + TEST_CASE(template103); TEST_CASE(template_specialization_1); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) @@ -2326,6 +2327,33 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template103() { + const char code[] = "namespace sample {\n" + " template \n" + " class Sample {\n" + " public:\n" + " T function(T t);\n" + " };\n" + " template \n" + " T Sample::function(T t) {\n" + " return t;\n" + " }\n" + "}\n" + "sample::Sample s1;"; + const char exp[] = "namespace sample { " + "class Sample ; " + "} " + "sample :: Sample s1 ; " + "class sample :: Sample { " + "public: " + "int function ( int t ) ; " + "} ; " + "int sample :: Sample :: function ( int t ) { " + "return t ; " + "}"; + ASSERT_EQUALS(exp, tok(code)); + } + void template_specialization_1() { // #7868 - template specialization template struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n"