TemplateSimplifier: Broke out code into separate function

This commit is contained in:
Daniel Marjamäki 2017-06-08 00:16:43 +02:00
parent 2740736136
commit d2e7df2c04
2 changed files with 79 additions and 51 deletions

View File

@ -1360,56 +1360,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
}
// Replace all these template usages..
std::list< std::pair<Token *, Token *> > 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<int>
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<Token*,Token*>(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<const Token *> &typesUsedInTemplateInstantiation,
std::list<Token *> &templateInstantiations)
{
std::list< std::pair<Token *, Token *> > 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<int>
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<Token*,Token*>(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<std::string> expandedtemplates(TemplateSimplifier::expandSpecialized(tokenlist.front()));
if (TemplateSimplifier::getTemplateDeclarations(tokenlist.front(), _codeWithTemplates).empty())

View File

@ -153,6 +153,20 @@ public:
std::list<Token *> &templateInstantiations,
std::set<std::string> &expandedtemplates);
/**
* Replace all matching template usages 'Foo < int >' => 'Foo<int>'
* @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<const Token *> &typesUsedInTemplateInstantiation,
std::list<Token *> &templateInstantiations);
/**
* Simplify templates
* @param tokenlist token list