diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2efd79f6c..459f3e14f 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -18,6 +18,7 @@ #include "templatesimplifier.h" #include "token.h" +#include #include #include @@ -272,3 +273,69 @@ void TemplateSimplifier::removeTemplates(Token *tok) } } } + + +std::set TemplateSimplifier::simplifyTemplatesExpandSpecialized(Token *tokens) +{ + std::set expandedtemplates; + + // Locate specialized templates.. + for (Token *tok = tokens; tok; tok = tok->next()) { + if (tok->str() != "template") + continue; + if (!Token::simpleMatch(tok->next(), "< >")) + continue; + + // what kind of template is this? + Token *tok2 = tok->tokAt(3); + while (tok2 && (tok2->isName() || tok2->str() == "*")) + tok2 = tok2->next(); + + if (!TemplateSimplifier::templateParameters(tok2)) + continue; + + // unknown template.. bail out + if (!tok2->previous()->isName()) + continue; + + tok2 = tok2->previous(); + std::string s; + { + std::ostringstream ostr; + const Token *tok3 = tok2; + for (tok3 = tok2; tok3 && tok3->str() != ">"; tok3 = tok3->next()) { + if (tok3 != tok2) + ostr << " "; + ostr << tok3->str(); + } + if (!Token::simpleMatch(tok3, "> (")) + continue; + s = ostr.str(); + } + + // save search pattern.. + const std::string pattern(s + " > ("); + + // remove spaces to create new name + while (s.find(" ") != std::string::npos) + s.erase(s.find(" "), 1); + const std::string name(s + ">"); + expandedtemplates.insert(name); + + // Rename template.. + Token::eraseTokens(tok2, Token::findsimplematch(tok2, "(")); + tok2->str(name); + + // delete the "template < >" + tok->deleteNext(2); + tok->deleteThis(); + + // Use this special template in the code.. + while (NULL != (tok2 = const_cast(Token::findmatch(tok2, pattern.c_str())))) { + Token::eraseTokens(tok2, Token::findsimplematch(tok2, "(")); + tok2->str(name); + } + } + + return expandedtemplates; +} diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index 3f83721de..237e19135 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -22,7 +22,8 @@ #define templatesimplifierH //--------------------------------------------------------------------------- - +#include +#include class Token; @@ -61,6 +62,12 @@ public: * Remove "template < ..." they can cause false positives because they are not expanded */ static void removeTemplates(Token *tok); + + /** + * Expand specialized templates : "template<>.." + * @return names of expanded templates + */ + static std::set simplifyTemplatesExpandSpecialized(Token *tokens); }; /// @} diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 87480e694..60ead520d 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2681,71 +2681,6 @@ void Tokenizer::simplifyLabelsCaseDefault() } } -std::set Tokenizer::simplifyTemplatesExpandSpecialized() -{ - std::set expandedtemplates; - - // Locate specialized templates.. - for (Token *tok = _tokens; tok; tok = tok->next()) { - if (tok->str() != "template") - continue; - if (!Token::simpleMatch(tok->next(), "< >")) - continue; - - // what kind of template is this? - Token *tok2 = tok->tokAt(3); - while (tok2 && (tok2->isName() || tok2->str() == "*")) - tok2 = tok2->next(); - - if (!TemplateSimplifier::templateParameters(tok2)) - continue; - - // unknown template.. bail out - if (!tok2->previous()->isName()) - continue; - - tok2 = tok2->previous(); - std::string s; - { - std::ostringstream ostr; - const Token *tok3 = tok2; - for (tok3 = tok2; tok3 && tok3->str() != ">"; tok3 = tok3->next()) { - if (tok3 != tok2) - ostr << " "; - ostr << tok3->str(); - } - if (!Token::simpleMatch(tok3, "> (")) - continue; - s = ostr.str(); - } - - // save search pattern.. - const std::string pattern(s + " > ("); - - // remove spaces to create new name - while (s.find(" ") != std::string::npos) - s.erase(s.find(" "), 1); - const std::string name(s + ">"); - expandedtemplates.insert(name); - - // Rename template.. - Token::eraseTokens(tok2, Token::findsimplematch(tok2, "(")); - tok2->str(name); - - // delete the "template < >" - tok->deleteNext(2); - tok->deleteThis(); - - // Use this special template in the code.. - while (NULL != (tok2 = const_cast(Token::findmatch(tok2, pattern.c_str())))) { - Token::eraseTokens(tok2, Token::findsimplematch(tok2, "(")); - tok2->str(name); - } - } - - return expandedtemplates; -} - std::list Tokenizer::simplifyTemplatesGetTemplateDeclarations() { std::list templates; @@ -3280,7 +3215,7 @@ void Tokenizer::simplifyTemplateInstantions(const Token *tok, void Tokenizer::simplifyTemplates() { - std::set expandedtemplates(simplifyTemplatesExpandSpecialized()); + std::set expandedtemplates(TemplateSimplifier::simplifyTemplatesExpandSpecialized(_tokens)); // Locate templates.. std::list templates(simplifyTemplatesGetTemplateDeclarations()); diff --git a/lib/tokenize.h b/lib/tokenize.h index cbb819d9f..4828ec40a 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -473,12 +473,6 @@ public: */ void simplifyTemplates(); - /** - * Expand specialized templates : "template<>.." - * @return names of expanded templates - */ - std::set simplifyTemplatesExpandSpecialized(); - void simplifyDoublePlusAndDoubleMinus(); void simplifyRedundantConsecutiveBraces();