diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 9c414fb8a..3e671c98b 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1636,9 +1636,13 @@ void TemplateSimplifier::expandTemplate( (!isVariable || !Token::Match(typeParametersInDeclaration[itype]->previous(), "<|, %type% >|,"))) { typeindentlevel = 0; std::stack brackets1; // holds "(" and "{" tokens + bool pointerType = false; + Token * const dst1 = dst->previous(); for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token(); typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>")); typetok = typetok->next()) { + if (typeindentlevel == 0 && typetok->str() == "*") + pointerType = true; if (Token::simpleMatch(typetok, "...")) continue; if (Token::Match(typetok, "%name% <") && (typetok->strAt(2) == ">" || templateParameters(typetok->next()))) @@ -1674,6 +1678,10 @@ void TemplateSimplifier::expandTemplate( brackets1.pop(); } } + if (pointerType && Token::simpleMatch(dst1, "const")) { + dst->insertToken("const", dst1->originalName(), true); + dst1->deleteThis(); + } } else { if (isSpecialization && !copy && !scope.empty() && Token::Match(start, (scope + templateDeclarationNameToken->str()).c_str())) { // skip scope @@ -1962,9 +1970,13 @@ void TemplateSimplifier::expandTemplate( if (itype < typeParametersInDeclaration.size()) { unsigned int typeindentlevel = 0; std::stack brackets1; // holds "(" and "{" tokens + Token * const beforeTypeToken = mTokenList.back(); + bool pointerType = false; for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token(); typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>")); typetok = typetok->next()) { + if (typeindentlevel == 0 && typetok->str() == "*") + pointerType = true; if (Token::simpleMatch(typetok, "...")) continue; if (Token::Match(typetok, "%name% <") && @@ -2008,6 +2020,10 @@ void TemplateSimplifier::expandTemplate( if (copy) back->isTemplateArg(true); } + if (pointerType && Token::simpleMatch(beforeTypeToken, "const")) { + mTokenList.addtoken(beforeTypeToken); + beforeTypeToken->deleteThis(); + } continue; } } diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index cde08b091..6a402dc28 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -216,6 +216,7 @@ private: TEST_CASE(template_namespace_9); TEST_CASE(template_namespace_10); TEST_CASE(template_namespace_11); // #7145 + TEST_CASE(template_pointer_type); // Test TemplateSimplifier::templateParameters TEST_CASE(templateParameters); @@ -4393,6 +4394,14 @@ private: "} int MyNamespace :: TestClass :: TemplatedMethod ( int t ) { return t ; }", tok(code)); } + void template_pointer_type() { + const char code[] = "template void foo(const T x) {}\n" + "void bar() { foo(0); }"; + ASSERT_EQUALS("void foo ( int * const x ) ; " + "void bar ( ) { foo ( 0 ) ; } " + "void foo ( int * const x ) { }", tok(code)); + } + unsigned int templateParameters(const char code[]) { Tokenizer tokenizer(&settings, this);