From d2e7df2c04144cecdab40c74fac732343f204637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 8 Jun 2017 00:16:43 +0200 Subject: [PATCH] TemplateSimplifier: Broke out code into separate function --- lib/templatesimplifier.cpp | 116 +++++++++++++++++++++---------------- lib/templatesimplifier.h | 14 +++++ 2 files changed, 79 insertions(+), 51 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 45d4666ab..e6f4720e3 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -1360,56 +1360,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( } // Replace all these template usages.. - std::list< std::pair > removeTokens; - for (Token *tok4 = tok2; tok4; tok4 = tok4->next()) { - if (Token::simpleMatch(tok4, templateMatchPattern.c_str())) { - Token * tok5 = tok4->tokAt(2); - unsigned int typeCountInInstantiation = 1U; // There is always at least one type - const Token *typetok = (!typesUsedInTemplateInstantiation.empty()) ? typesUsedInTemplateInstantiation[0] : 0; - unsigned int indentlevel5 = 0; // indentlevel for tok5 - while (tok5 && (indentlevel5 > 0 || tok5->str() != ">")) { - if (tok5->str() == "<" && templateParameters(tok5) > 0) - ++indentlevel5; - else if (indentlevel5 > 0 && Token::Match(tok5, "> [,>]")) - --indentlevel5; - else if (indentlevel5 == 0) { - if (tok5->str() != ",") { - if (!typetok || - tok5->isUnsigned() != typetok->isUnsigned() || - tok5->isSigned() != typetok->isSigned() || - tok5->isLong() != typetok->isLong()) { - break; - } - - typetok = typetok ? typetok->next() : 0; - } else { - typetok = (typeCountInInstantiation < typesUsedInTemplateInstantiation.size()) ? typesUsedInTemplateInstantiation[typeCountInInstantiation] : 0; - ++typeCountInInstantiation; - } - } - tok5 = tok5->next(); - } - - // matching template usage => replace tokens.. - // Foo < int > => Foo - if (tok5 && tok5->str() == ">" && typeCountInInstantiation == typesUsedInTemplateInstantiation.size()) { - tok4->str(newName); - for (Token *tok6 = tok4->next(); tok6 != tok5; tok6 = tok6->next()) { - if (tok6->isName()) - templateInstantiations.remove(tok6); - } - removeTokens.push_back(std::pair(tok4, tok5->next())); - } - - tok4 = tok5; - if (!tok4) - break; - } - } - while (!removeTokens.empty()) { - Token::eraseTokens(removeTokens.back().first, removeTokens.back().second); - removeTokens.pop_back(); - } + replaceTemplateUsage(tok2, templateMatchPattern, newName, typesUsedInTemplateInstantiation, templateInstantiations); } // Template has been instantiated .. then remove the template declaration @@ -1417,6 +1368,70 @@ bool TemplateSimplifier::simplifyTemplateInstantiations( } +void TemplateSimplifier::replaceTemplateUsage(Token * const instantiationToken, + const std::string &templateMatchPattern, + const std::string &newName, + const std::vector &typesUsedInTemplateInstantiation, + std::list &templateInstantiations) +{ + std::list< std::pair > removeTokens; + for (Token *nameTok = instantiationToken; nameTok; nameTok = nameTok->next()) { + if (!Token::simpleMatch(nameTok, templateMatchPattern.c_str())) + continue; + + // match parameters + Token * tok2 = nameTok->tokAt(2); + unsigned int typeCountInInstantiation = 1U; // There is always at least one type + const Token *typetok = (!typesUsedInTemplateInstantiation.empty()) ? typesUsedInTemplateInstantiation[0] : 0; + unsigned int indentlevel2 = 0; // indentlevel for tokgt + while (tok2 && (indentlevel2 > 0 || tok2->str() != ">")) { + if (tok2->str() == "<" && templateParameters(tok2) > 0) + ++indentlevel2; + else if (indentlevel2 > 0 && Token::Match(tok2, "> [,>]")) + --indentlevel2; + else if (indentlevel2 == 0) { + if (tok2->str() != ",") { + if (!typetok || + tok2->isUnsigned() != typetok->isUnsigned() || + tok2->isSigned() != typetok->isSigned() || + tok2->isLong() != typetok->isLong()) { + break; + } + + typetok = typetok ? typetok->next() : 0; + } else { + if (typeCountInInstantiation < typesUsedInTemplateInstantiation.size()) + typetok = typesUsedInTemplateInstantiation[typeCountInInstantiation++]; + else + typetok = nullptr; + } + } + tok2 = tok2->next(); + } + + if (!tok2) + break; + + // matching template usage => replace tokens.. + // Foo < int > => Foo + if (tok2->str() == ">" && typeCountInInstantiation == typesUsedInTemplateInstantiation.size()) { + nameTok->str(newName); + for (Token *tok = nameTok->next(); tok != tok2; tok = tok->next()) { + if (tok->isName()) + templateInstantiations.remove(tok); + } + removeTokens.push_back(std::pair(nameTok, tok2->next())); + } + + nameTok = tok2; + } + while (!removeTokens.empty()) { + Token::eraseTokens(removeTokens.back().first, removeTokens.back().second); + removeTokens.pop_back(); + } +} + + void TemplateSimplifier::simplifyTemplates( TokenList& tokenlist, ErrorLogger* errorlogger, @@ -1425,7 +1440,6 @@ void TemplateSimplifier::simplifyTemplates( bool &_codeWithTemplates ) { - std::set expandedtemplates(TemplateSimplifier::expandSpecialized(tokenlist.front())); if (TemplateSimplifier::getTemplateDeclarations(tokenlist.front(), _codeWithTemplates).empty()) diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index 442bf103d..bf2be3f97 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -153,6 +153,20 @@ public: std::list &templateInstantiations, std::set &expandedtemplates); + /** + * Replace all matching template usages 'Foo < int >' => 'Foo' + * @param instantiationToken Template instantiation token + * @param templateMatchPattern Pattern compatible with Token::simpleMatch + * @param newName The new type name + * @param typesUsedInTemplateInstantiation template instantiation parameters + * @param templateInstantiations All seen instantiations + */ + static void replaceTemplateUsage(Token *const instantiationToken, + const std::string &templateMatchPattern, + const std::string &newName, + const std::vector &typesUsedInTemplateInstantiation, + std::list &templateInstantiations); + /** * Simplify templates * @param tokenlist token list