Fixed more false positives of #6056:

- Implemented nextArgument() for usages before < and > are linked
- slightly optimized nextArgument()
This commit is contained in:
PKEuS 2014-08-20 14:57:00 +02:00
parent 8188578cf2
commit c678937538
4 changed files with 34 additions and 7 deletions

View File

@ -719,9 +719,7 @@ Token* Token::nextArgument() const
for (const Token* tok = this; tok; tok = tok->next()) {
if (tok->str() == ",")
return tok->next();
else if (tok->str() == "(" || tok->str() == "{" || tok->str() == "[")
tok = tok->link();
else if (tok->str() == "<" && tok->link())
else if (tok->link() && (tok->str() == "(" || tok->str() == "{" || tok->str() == "[" || tok->str() == "<"))
tok = tok->link();
else if (tok->str() == ")" || tok->str() == ";")
return 0;
@ -729,6 +727,23 @@ Token* Token::nextArgument() const
return 0;
}
Token* Token::nextArgumentBeforeCreateLinks2() const
{
for (const Token* tok = this; tok; tok = tok->next()) {
if (tok->str() == ",")
return tok->next();
else if (tok->link() && (tok->str() == "(" || tok->str() == "{" || tok->str() == "["))
tok = tok->link();
else if (tok->str() == "<") {
const Token* temp = tok->findClosingBracket();
if (temp)
tok = temp;
} else if (tok->str() == ")" || tok->str() == ";")
return 0;
}
return 0;
}
const Token * Token::findClosingBracket() const
{
const Token *closing = nullptr;

View File

@ -618,10 +618,18 @@ public:
/**
* @return the first token of the next argument. Does only work on argument
* lists. Returns 0, if there is no next argument
* lists. Requires that Tokenizer::createLinks2() has been called before.
* Returns 0, if there is no next argument.
*/
Token* nextArgument() const;
/**
* @return the first token of the next argument. Does only work on argument
* lists. Should be used only before Tokenizer::createLinks2() was called.
* Returns 0, if there is no next argument.
*/
Token* nextArgumentBeforeCreateLinks2() const;
/**
* Returns the closing bracket of opening '<'. Should only be used if link()
* is unavailable.

View File

@ -2590,8 +2590,8 @@ void Tokenizer::setVarId()
if (!executableScope.top()) {
// Detecting initializations with () in non-executable scope is hard and often impossible to be done safely. Thus, only treat code as a variable that definitly is one.
decl = false;
for (; tok3; tok3 = tok3->nextArgument()) {
if (tok3->isLiteral() || (tok3->isName() && (variableId.find(tok3->str()) != variableId.end())) || tok3->isOp() || (tok3->next()->isOp() && !Token::Match(tok3->next(), "*|&")) || notstart.find(tok3->str()) != notstart.end()) {
for (; tok3; tok3 = tok3->nextArgumentBeforeCreateLinks2()) {
if (tok3->isLiteral() || (tok3->isName() && (variableId.find(tok3->str()) != variableId.end())) || tok3->isOp() || (tok3->next()->isOp() && !Token::Match(tok3->next(), "*|&|<")) || notstart.find(tok3->str()) != notstart.end()) {
decl = true;
break;
}

View File

@ -4642,6 +4642,8 @@ private:
" int method_with_internal(const B &, int);\n"
" void Set(BAR);\n"
" FOO Set(BAR);\n"
" int method_with_class(B<B> b);\n"
" bool function(std::map<int, int, MYless> & m);\n"
"};";
ASSERT_EQUALS("\n\n##file 0\n"
"1: class Fred {\n"
@ -4653,7 +4655,9 @@ private:
"7: int method_with_internal ( const B & , int ) ;\n"
"8: void Set ( BAR ) ;\n"
"9: FOO Set ( BAR ) ;\n"
"10: } ;\n", tokenizeDebugListing(code1, false, "test.cpp"));
"10: int method_with_class ( B < B > b@3 ) ;\n"
"11: bool function ( std :: map < int , int , MYless > & m@4 ) ;\n"
"12: } ;\n", tokenizeDebugListing(code1, false, "test.cpp"));
const char code2[] = "int i;\n"
"SomeType someVar1(i, i);\n"