Templates: Fixed scope problem
This commit is contained in:
parent
005bb7c747
commit
a8f73055ad
|
@ -493,7 +493,7 @@ std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateDecla
|
||||||
else if (tok2->str() == "{") {
|
else if (tok2->str() == "{") {
|
||||||
int namepos = getTemplateNamePosition(parmEnd);
|
int namepos = getTemplateNamePosition(parmEnd);
|
||||||
if (namepos > 0)
|
if (namepos > 0)
|
||||||
declarations.push_back(TokenAndName(tok, getFullName(scopeInfo, parmEnd->strAt(namepos))));
|
declarations.push_back(TokenAndName(tok, getScopeName(scopeInfo), getFullName(scopeInfo, parmEnd->strAt(namepos))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,7 +502,7 @@ std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateDecla
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateInstantiations(Token *tokens)
|
std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateInstantiations(Token *tokens, const std::list<TokenAndName> &declarations)
|
||||||
{
|
{
|
||||||
std::list<TokenAndName> instantiations;
|
std::list<TokenAndName> instantiations;
|
||||||
std::list<ScopeInfo2> scopeList;
|
std::list<ScopeInfo2> scopeList;
|
||||||
|
@ -541,13 +541,35 @@ std::list<TemplateSimplifier::TokenAndName> TemplateSimplifier::getTemplateInsta
|
||||||
for (; tok2 && tok2 != tok; tok2 = tok2->previous()) {
|
for (; tok2 && tok2 != tok; tok2 = tok2->previous()) {
|
||||||
if (Token::Match(tok2, ", %name% <") &&
|
if (Token::Match(tok2, ", %name% <") &&
|
||||||
TemplateSimplifier::templateParameters(tok2->tokAt(2))) {
|
TemplateSimplifier::templateParameters(tok2->tokAt(2))) {
|
||||||
instantiations.push_back(TokenAndName(tok2->next(),getFullName(scopeList, tok2->strAt(1))));
|
instantiations.push_back(TokenAndName(tok2->next(), getScopeName(scopeList), getFullName(scopeList, tok2->strAt(1))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add outer template..
|
// Add outer template..
|
||||||
if (TemplateSimplifier::templateParameters(tok->next()))
|
if (TemplateSimplifier::templateParameters(tok->next())) {
|
||||||
instantiations.push_back(TokenAndName(tok, scopeName + (scopeName.empty()?"":" :: ") + tok->str()));
|
bool done = false;
|
||||||
|
const std::string scopeName1(scopeName);
|
||||||
|
while (!done) {
|
||||||
|
const std::string fullName = scopeName + (scopeName.empty()?"":" :: ") + tok->str();
|
||||||
|
|
||||||
|
for (std::list<TokenAndName>::const_iterator it = declarations.begin(); it != declarations.end(); ++it) {
|
||||||
|
if (it->name == fullName) {
|
||||||
|
instantiations.push_back(TokenAndName(tok, getScopeName(scopeList), fullName));
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
if (scopeName.empty()) {
|
||||||
|
instantiations.push_back(TokenAndName(tok, getScopeName(scopeList), scopeName1 + (scopeName1.empty()?"":" :: ") + tok->str()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const std::string::size_type pos = scopeName.rfind(" :: ");
|
||||||
|
scopeName = (pos == std::string::npos) ? std::string() : scopeName.substr(0,pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,7 +1017,7 @@ void TemplateSimplifier::expandTemplate(
|
||||||
std::string name = tok3->str();
|
std::string name = tok3->str();
|
||||||
for (const Token *prev = tok3->tokAt(-2); Token::Match(prev, "%name% ::"); prev = prev->tokAt(-2))
|
for (const Token *prev = tok3->tokAt(-2); Token::Match(prev, "%name% ::"); prev = prev->tokAt(-2))
|
||||||
name = prev->str() + " :: " + name;
|
name = prev->str() + " :: " + name;
|
||||||
templateInstantiations.push_back(TokenAndName(tokenlist.back(), getFullName(scopeInfo, name)));
|
templateInstantiations.push_back(TokenAndName(tokenlist.back(), getScopeName(scopeInfo), getFullName(scopeInfo, name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// link() newly tokens manually
|
// link() newly tokens manually
|
||||||
|
@ -1636,7 +1658,7 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
std::list<TokenAndName> templates(TemplateSimplifier::getTemplateDeclarations(tokenlist.front(), _codeWithTemplates));
|
std::list<TokenAndName> templates(TemplateSimplifier::getTemplateDeclarations(tokenlist.front(), _codeWithTemplates));
|
||||||
|
|
||||||
// Locate possible instantiations of templates..
|
// Locate possible instantiations of templates..
|
||||||
std::list<TokenAndName> templateInstantiations(TemplateSimplifier::getTemplateInstantiations(tokenlist.front()));
|
std::list<TokenAndName> templateInstantiations(TemplateSimplifier::getTemplateInstantiations(tokenlist.front(), templates));
|
||||||
|
|
||||||
// No template instantiations? Then return.
|
// No template instantiations? Then return.
|
||||||
if (templateInstantiations.empty())
|
if (templateInstantiations.empty())
|
||||||
|
|
|
@ -76,8 +76,9 @@ public:
|
||||||
* Token and its full scopename
|
* Token and its full scopename
|
||||||
*/
|
*/
|
||||||
struct TokenAndName {
|
struct TokenAndName {
|
||||||
TokenAndName(Token *tok, const std::string &scopeName) : token(tok), name(scopeName) {}
|
TokenAndName(Token *tok, const std::string &s, const std::string &n) : token(tok), scope(s), name(n) {}
|
||||||
Token *token;
|
Token *token;
|
||||||
|
std::string scope;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,9 +90,11 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get template instantiations
|
* Get template instantiations
|
||||||
|
* @param tokens start of token list
|
||||||
|
* @param declarations template declarations, so names can be matched
|
||||||
* @return list of template instantiations
|
* @return list of template instantiations
|
||||||
*/
|
*/
|
||||||
static std::list<TokenAndName> getTemplateInstantiations(Token *tokens);
|
static std::list<TokenAndName> getTemplateInstantiations(Token *tokens, const std::list<TokenAndName> &declarations);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* simplify template instantiations (use default argument values)
|
* simplify template instantiations (use default argument values)
|
||||||
|
|
|
@ -110,6 +110,7 @@ private:
|
||||||
TEST_CASE(template_namespace_2);
|
TEST_CASE(template_namespace_2);
|
||||||
TEST_CASE(template_namespace_3);
|
TEST_CASE(template_namespace_3);
|
||||||
TEST_CASE(template_namespace_4);
|
TEST_CASE(template_namespace_4);
|
||||||
|
TEST_CASE(template_namespace_5);
|
||||||
|
|
||||||
// Test TemplateSimplifier::templateParameters
|
// Test TemplateSimplifier::templateParameters
|
||||||
TEST_CASE(templateParameters);
|
TEST_CASE(templateParameters);
|
||||||
|
@ -1455,6 +1456,12 @@ private:
|
||||||
"class foo::A<int> { void dostuff ( ) { } } ;", tok(code));
|
"class foo::A<int> { void dostuff ( ) { } } ;", tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template_namespace_5() {
|
||||||
|
const char code[] = "template<class C> struct S {};\n"
|
||||||
|
"namespace X { S<int> s; }";
|
||||||
|
ASSERT_EQUALS("namespace X { S<int> s ; } struct S<int> { } ;", tok(code));
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int templateParameters(const char code[]) {
|
unsigned int templateParameters(const char code[]) {
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue