template simplifier: fix out of line member function scope and use more full name matching (#1617)
This commit is contained in:
parent
080c9d53af
commit
cb1a1df0fa
|
@ -94,6 +94,36 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *tok, const std::string &s,
|
||||||
if (tok1)
|
if (tok1)
|
||||||
isForwardDeclaration(tok1->str() == ";");
|
isForwardDeclaration(tok1->str() == ";");
|
||||||
}
|
}
|
||||||
|
// check for member function and adjust scope
|
||||||
|
if (isFunction() && nameToken->strAt(-1) == "::") {
|
||||||
|
const Token * start = nameToken;
|
||||||
|
|
||||||
|
while (Token::Match(start->tokAt(-2), "%name% ::") ||
|
||||||
|
(Token::simpleMatch(start->tokAt(-2), "> ::") &&
|
||||||
|
Token::Match(start->tokAt(-2)->findOpeningBracket()->previous(), "%name% <"))) {
|
||||||
|
if (start->strAt(-2) == ">")
|
||||||
|
start = start->tokAt(-2)->findOpeningBracket()->previous();
|
||||||
|
else
|
||||||
|
start = start->tokAt(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start && start != nameToken) {
|
||||||
|
if (!scope.empty())
|
||||||
|
scope += " ::";
|
||||||
|
while (start && start->next() != nameToken) {
|
||||||
|
if (start->str() == "<")
|
||||||
|
start = start->findClosingBracket();
|
||||||
|
else {
|
||||||
|
if (!scope.empty())
|
||||||
|
scope += " ";
|
||||||
|
scope += start->str();
|
||||||
|
}
|
||||||
|
start = start->next();
|
||||||
|
}
|
||||||
|
if (start)
|
||||||
|
fullName = scope.empty() ? name : (scope + " :: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token)
|
if (token)
|
||||||
|
@ -1118,18 +1148,25 @@ void TemplateSimplifier::addNamespace(const TokenAndName &templateDeclaration, c
|
||||||
std::string::size_type end = 0;
|
std::string::size_type end = 0;
|
||||||
while ((end = templateDeclaration.scope.find(" ", start)) != std::string::npos) {
|
while ((end = templateDeclaration.scope.find(" ", start)) != std::string::npos) {
|
||||||
std::string token = templateDeclaration.scope.substr(start, end - start);
|
std::string token = templateDeclaration.scope.substr(start, end - start);
|
||||||
|
// done if scopes overlap
|
||||||
|
if (token == tokStart->str() && tok->strAt(-1) != "::")
|
||||||
|
break;
|
||||||
if (insert)
|
if (insert)
|
||||||
mTokenList.back()->tokAt(offset)->insertToken(token, "");
|
mTokenList.back()->tokAt(offset)->insertToken(token, "");
|
||||||
else
|
else
|
||||||
mTokenList.addtoken(token, tok->linenr(), tok->fileIndex());
|
mTokenList.addtoken(token, tok->linenr(), tok->fileIndex());
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
}
|
}
|
||||||
if (insert) {
|
// don't add if it already exists
|
||||||
mTokenList.back()->tokAt(offset)->insertToken(templateDeclaration.scope.substr(start), "");
|
std::string token = templateDeclaration.scope.substr(start, end - start);
|
||||||
mTokenList.back()->tokAt(offset)->insertToken("::", "");
|
if (token != tokStart->str() || tok->strAt(-1) != "::") {
|
||||||
} else {
|
if (insert) {
|
||||||
mTokenList.addtoken(templateDeclaration.scope.substr(start), tok->linenr(), tok->fileIndex());
|
mTokenList.back()->tokAt(offset)->insertToken(templateDeclaration.scope.substr(start), "");
|
||||||
mTokenList.addtoken("::", tok->linenr(), tok->fileIndex());
|
mTokenList.back()->tokAt(offset)->insertToken("::", "");
|
||||||
|
} else {
|
||||||
|
mTokenList.addtoken(templateDeclaration.scope.substr(start), tok->linenr(), tok->fileIndex());
|
||||||
|
mTokenList.addtoken("::", tok->linenr(), tok->fileIndex());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,7 +1519,7 @@ void TemplateSimplifier::expandTemplate(
|
||||||
continue;
|
continue;
|
||||||
} else if (!templateDeclaration.scope.empty() &&
|
} else if (!templateDeclaration.scope.empty() &&
|
||||||
!alreadyHasNamespace(templateDeclaration, tok3) &&
|
!alreadyHasNamespace(templateDeclaration, tok3) &&
|
||||||
closingBracket->strAt(1) != "(") {
|
!Token::Match(closingBracket->next(), "(|::")) {
|
||||||
if (copy)
|
if (copy)
|
||||||
addNamespace(templateDeclaration, tok3);
|
addNamespace(templateDeclaration, tok3);
|
||||||
}
|
}
|
||||||
|
@ -2024,7 +2061,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (instantiation.fullName != templateDeclaration.fullName) {
|
if (instantiation.fullName != templateDeclaration.fullName) {
|
||||||
// FIXME: fallback to not matching scopes until using namespace and type deduction work
|
// FIXME: fallback to not matching scopes until type deduction work
|
||||||
|
|
||||||
// names must match
|
// names must match
|
||||||
if (instantiation.name != templateDeclaration.name)
|
if (instantiation.name != templateDeclaration.name)
|
||||||
|
@ -2275,41 +2312,18 @@ void TemplateSimplifier::replaceTemplateUsage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getPathName(const TemplateSimplifier::TokenAndName & decl)
|
|
||||||
{
|
|
||||||
std::string name = decl.scope;
|
|
||||||
if (!name.empty())
|
|
||||||
name += " :: ";
|
|
||||||
if (decl.nameToken->strAt(-1) == "::") {
|
|
||||||
const Token * start = decl.nameToken;
|
|
||||||
|
|
||||||
while (Token::Match(start->tokAt(-2), "%name% ::"))
|
|
||||||
start = start->tokAt(-2);
|
|
||||||
|
|
||||||
while (start != decl.nameToken) {
|
|
||||||
name += (start->str() + " ");
|
|
||||||
start = start->next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name += decl.name;
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TemplateSimplifier::getUserDefinedSpecializations()
|
void TemplateSimplifier::getUserDefinedSpecializations()
|
||||||
{
|
{
|
||||||
// try to locate a matching declaration for each user defined specialization
|
// try to locate a matching declaration for each user defined specialization
|
||||||
for (auto & spec : mTemplateDeclarations) {
|
for (auto & spec : mTemplateDeclarations) {
|
||||||
if (spec.isSpecialized()) {
|
if (spec.isSpecialized()) {
|
||||||
std::string specName = getPathName(spec);
|
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto & decl : mTemplateDeclarations) {
|
for (auto & decl : mTemplateDeclarations) {
|
||||||
if (decl.isSpecialized())
|
if (decl.isSpecialized())
|
||||||
continue;
|
continue;
|
||||||
std::string declName = getPathName(decl);
|
|
||||||
|
|
||||||
// make sure the scopes and names match
|
// make sure the scopes and names match
|
||||||
if (specName == declName) {
|
if (spec.fullName == decl.fullName) {
|
||||||
// @todo make sure function parameters also match
|
// @todo make sure function parameters also match
|
||||||
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -2318,10 +2332,8 @@ void TemplateSimplifier::getUserDefinedSpecializations()
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
for (auto & decl : mTemplateForwardDeclarations) {
|
for (auto & decl : mTemplateForwardDeclarations) {
|
||||||
std::string declName = getPathName(decl);
|
|
||||||
|
|
||||||
// make sure the scopes and names match
|
// make sure the scopes and names match
|
||||||
if (specName == declName) {
|
if (spec.fullName == decl.fullName) {
|
||||||
// @todo make sure function parameters also match
|
// @todo make sure function parameters also match
|
||||||
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
mTemplateUserSpecializationMap[spec.token] = decl.token;
|
||||||
}
|
}
|
||||||
|
@ -2346,11 +2358,8 @@ void TemplateSimplifier::fixForwardDeclaredDefaultArgumentValues()
|
||||||
|
|
||||||
// make sure the number of arguments match
|
// make sure the number of arguments match
|
||||||
if (params1.size() == params2.size()) {
|
if (params1.size() == params2.size()) {
|
||||||
std::string declName = getPathName(decl);
|
|
||||||
std::string forwardDeclName = getPathName(forwardDecl);
|
|
||||||
|
|
||||||
// make sure the scopes and names match
|
// make sure the scopes and names match
|
||||||
if (forwardDeclName == declName) {
|
if (forwardDecl.fullName == decl.fullName) {
|
||||||
// save forward declaration for lookup later
|
// save forward declaration for lookup later
|
||||||
if ((decl.nameToken->strAt(1) == "(" && forwardDecl.nameToken->strAt(1) == "(") ||
|
if ((decl.nameToken->strAt(1) == "(" && forwardDecl.nameToken->strAt(1) == "(") ||
|
||||||
(decl.nameToken->strAt(1) == "{" && forwardDecl.nameToken->strAt(1) == ";")) {
|
(decl.nameToken->strAt(1) == "{" && forwardDecl.nameToken->strAt(1) == ";")) {
|
||||||
|
@ -2519,7 +2528,7 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
// get specializations..
|
// get specializations..
|
||||||
std::list<const Token *> specializations;
|
std::list<const Token *> specializations;
|
||||||
for (std::list<TokenAndName>::const_iterator iter2 = mTemplateDeclarations.begin(); iter2 != mTemplateDeclarations.end(); ++iter2) {
|
for (std::list<TokenAndName>::const_iterator iter2 = mTemplateDeclarations.begin(); iter2 != mTemplateDeclarations.end(); ++iter2) {
|
||||||
if (iter1->name == iter2->name)
|
if (iter1->fullName == iter2->fullName)
|
||||||
specializations.push_back(iter2->nameToken);
|
specializations.push_back(iter2->nameToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2636,7 +2636,7 @@ private:
|
||||||
"public:\n"
|
"public:\n"
|
||||||
" TestClass() {\n"
|
" TestClass() {\n"
|
||||||
" SomeFunction();\n"
|
" SomeFunction();\n"
|
||||||
" TemplatedMethod< int >();\n"
|
" TemplatedMethod< int >( 0 );\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" void SomeFunction() { }\n"
|
" void SomeFunction() { }\n"
|
||||||
"private:\n"
|
"private:\n"
|
||||||
|
@ -2649,7 +2649,7 @@ private:
|
||||||
"public: "
|
"public: "
|
||||||
"TestClass ( ) { "
|
"TestClass ( ) { "
|
||||||
"SomeFunction ( ) ; "
|
"SomeFunction ( ) ; "
|
||||||
"TemplatedMethod<int> ( ) ; "
|
"TemplatedMethod<int> ( 0 ) ; "
|
||||||
"} "
|
"} "
|
||||||
"void SomeFunction ( ) { } "
|
"void SomeFunction ( ) { } "
|
||||||
"private: "
|
"private: "
|
||||||
|
|
Loading…
Reference in New Issue