TemplateSimplifier: Simplification of const types

This commit is contained in:
Daniel Marjamäki 2020-04-05 13:51:58 +02:00
parent 189cf29597
commit 8dd0a9241c
2 changed files with 25 additions and 0 deletions

View File

@ -1636,9 +1636,13 @@ void TemplateSimplifier::expandTemplate(
(!isVariable || !Token::Match(typeParametersInDeclaration[itype]->previous(), "<|, %type% >|,"))) {
typeindentlevel = 0;
std::stack<Token *> 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<Token *> 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;
}
}

View File

@ -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> ( int t ) { return t ; }", tok(code));
}
void template_pointer_type() {
const char code[] = "template<class T> void foo(const T x) {}\n"
"void bar() { foo<int*>(0); }";
ASSERT_EQUALS("void foo<int*> ( int * const x ) ; "
"void bar ( ) { foo<int*> ( 0 ) ; } "
"void foo<int*> ( int * const x ) { }", tok(code));
}
unsigned int templateParameters(const char code[]) {
Tokenizer tokenizer(&settings, this);