template simplifier: fix return type of out of line member function when it is a template parameter (#1723)

This commit is contained in:
IOBYTE 2019-03-03 13:42:46 -05:00 committed by Daniel Marjamäki
parent 9c7eff5b69
commit 40d7d5a3d0
2 changed files with 60 additions and 2 deletions

View File

@ -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();
}

View File

@ -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 <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)
@ -2326,6 +2327,33 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template103() {
const char code[] = "namespace sample {\n"
" template <typename T>\n"
" class Sample {\n"
" public:\n"
" T function(T t);\n"
" };\n"
" template <typename T>\n"
" T Sample<T>::function(T t) {\n"
" return t;\n"
" }\n"
"}\n"
"sample::Sample<int> s1;";
const char exp[] = "namespace sample { "
"class Sample<int> ; "
"} "
"sample :: Sample<int> s1 ; "
"class sample :: Sample<int> { "
"public: "
"int function ( int t ) ; "
"} ; "
"int sample :: Sample<int> :: function ( int t ) { "
"return t ; "
"}";
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"