LCppC backport: Various optimizations (#4182)
* Optimization: Use Token::eIncDecOp instead of expensive Token::Match calls Merged from LCppC. * Small Optimizations: - Moved a std::set that is only need during initialization of SymbolDatabase to function scope - Use std::vector instead of std::list Merged from LCppC. * Optimization: Refactorized various Token::Match calls and surrounding conditions Merged from LCppC. * Refactorization: Cleanup usage of std::multimap Merged from LCppC.
This commit is contained in:
parent
4bd189c3c8
commit
1275b5275e
|
@ -885,7 +885,7 @@ bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth)
|
||||||
if (classScope && classScope->isClassOrStruct())
|
if (classScope && classScope->isClassOrStruct())
|
||||||
return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn);
|
return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn);
|
||||||
return false;
|
return false;
|
||||||
} else if (onVar && Token::Match(expr, "%var%") && expr->variable()) {
|
} else if (onVar && expr->variable()) {
|
||||||
const Variable* var = expr->variable();
|
const Variable* var = expr->variable();
|
||||||
return (var->isPrivate() || var->isPublic() || var->isProtected());
|
return (var->isPrivate() || var->isPublic() || var->isProtected());
|
||||||
}
|
}
|
||||||
|
@ -1287,7 +1287,7 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Follow variable
|
// Follow variable
|
||||||
if (followVar && !tok_str_eq && (Token::Match(tok1, "%var%") || Token::Match(tok2, "%var%"))) {
|
if (followVar && !tok_str_eq && (tok1->varId() || tok2->varId())) {
|
||||||
const Token * varTok1 = followVariableExpression(tok1, cpp, tok2);
|
const Token * varTok1 = followVariableExpression(tok1, cpp, tok2);
|
||||||
if ((varTok1->str() == tok2->str()) || isSameConstantValue(macro, varTok1, tok2)) {
|
if ((varTok1->str() == tok2->str()) || isSameConstantValue(macro, varTok1, tok2)) {
|
||||||
followVariableExpressionError(tok1, varTok1, errors);
|
followVariableExpressionError(tok1, varTok1, errors);
|
||||||
|
@ -2156,7 +2156,7 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
|
||||||
parenTok = parenTok->link()->next();
|
parenTok = parenTok->link()->next();
|
||||||
const bool possiblyPassedByReference = (parenTok->next() == tok1 || Token::Match(tok1->previous(), ", %name% [,)}]"));
|
const bool possiblyPassedByReference = (parenTok->next() == tok1 || Token::Match(tok1->previous(), ", %name% [,)}]"));
|
||||||
|
|
||||||
if (!tok->function() && !tok->variable() && Token::Match(tok, "%name%")) {
|
if (!tok->function() && !tok->variable() && tok->isName()) {
|
||||||
if (settings) {
|
if (settings) {
|
||||||
const bool requireInit = settings->library.isuninitargbad(tok, 1 + argnr);
|
const bool requireInit = settings->library.isuninitargbad(tok, 1 + argnr);
|
||||||
const bool requireNonNull = settings->library.isnullargbad(tok, 1 + argnr);
|
const bool requireNonNull = settings->library.isnullargbad(tok, 1 + argnr);
|
||||||
|
@ -2238,7 +2238,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
|
||||||
while (Token::simpleMatch(tok2->astParent(), "?") || (Token::simpleMatch(tok2->astParent(), ":") && Token::simpleMatch(tok2->astParent()->astParent(), "?")))
|
while (Token::simpleMatch(tok2->astParent(), "?") || (Token::simpleMatch(tok2->astParent(), ":") && Token::simpleMatch(tok2->astParent()->astParent(), "?")))
|
||||||
tok2 = tok2->astParent();
|
tok2 = tok2->astParent();
|
||||||
|
|
||||||
if (Token::Match(tok2->astParent(), "++|--"))
|
if (tok2->astParent() && tok2->astParent()->tokType() == Token::eIncDecOp)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto skipRedundantPtrOp = [](const Token* tok, const Token* parent) {
|
auto skipRedundantPtrOp = [](const Token* tok, const Token* parent) {
|
||||||
|
@ -2816,7 +2816,7 @@ static const Token* getLHSVariableRecursive(const Token* tok)
|
||||||
|
|
||||||
const Variable *getLHSVariable(const Token *tok)
|
const Variable *getLHSVariable(const Token *tok)
|
||||||
{
|
{
|
||||||
if (!Token::Match(tok, "%assign%"))
|
if (!tok || !tok->isAssignmentOp())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!tok->astOperand1())
|
if (!tok->astOperand1())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -214,7 +214,7 @@ void CheckAutoVariables::assignFunctionArg()
|
||||||
// TODO: What happens if this is removed?
|
// TODO: What happens if this is removed?
|
||||||
if (tok->astParent())
|
if (tok->astParent())
|
||||||
continue;
|
continue;
|
||||||
if (!(tok->isAssignmentOp() || Token::Match(tok, "++|--")) || !Token::Match(tok->astOperand1(), "%var%"))
|
if (!(tok->isAssignmentOp() || tok->tokType() == Token::eIncDecOp) || !Token::Match(tok->astOperand1(), "%var%"))
|
||||||
continue;
|
continue;
|
||||||
const Token* const vartok = tok->astOperand1();
|
const Token* const vartok = tok->astOperand1();
|
||||||
if (isNonReferenceArg(vartok) &&
|
if (isNonReferenceArg(vartok) &&
|
||||||
|
|
|
@ -1439,7 +1439,7 @@ void CheckCondition::alwaysTrueFalse()
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "%oror%|&&|:"))
|
if (Token::Match(tok, "%oror%|&&|:"))
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "%comp%") && isSameExpression(mTokenizer->isCPP(), true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true))
|
if (tok->isComparisonOp() && isSameExpression(mTokenizer->isCPP(), true, tok->astOperand1(), tok->astOperand2(), mSettings->library, true, true))
|
||||||
continue;
|
continue;
|
||||||
if (isConstVarExpression(tok, "[|(|&|+|-|*|/|%|^|>>|<<"))
|
if (isConstVarExpression(tok, "[|(|&|+|-|*|/|%|^|>>|<<"))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1340,7 +1340,7 @@ CheckIO::ArgumentInfo::ArgumentInfo(const Token * arg, const Settings *settings,
|
||||||
|
|
||||||
// Use AST type info
|
// Use AST type info
|
||||||
// TODO: This is a bailout so that old code is used in simple cases. Remove the old code and always use the AST type.
|
// TODO: This is a bailout so that old code is used in simple cases. Remove the old code and always use the AST type.
|
||||||
if (!Token::Match(arg, "%str% ,|)") && !(Token::Match(arg,"%var%") && arg->variable() && arg->variable()->isArray())) {
|
if (!Token::Match(arg, "%str% ,|)") && !(arg->variable() && arg->variable()->isArray())) {
|
||||||
const Token *top = arg;
|
const Token *top = arg;
|
||||||
while (top->str() == "(" && !top->isCast())
|
while (top->str() == "(" && !top->isCast())
|
||||||
top = top->next();
|
top = top->next();
|
||||||
|
|
|
@ -501,7 +501,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
}
|
}
|
||||||
if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) {
|
if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) {
|
||||||
return ChildrenToVisit::op2;
|
return ChildrenToVisit::op2;
|
||||||
} else if (tok3->str() == "(" && Token::Match(tok3->previous(), "%name%")) {
|
} else if (tok3->str() == "(" && tok3->previous()->isName()) {
|
||||||
const std::vector<const Token *> params = getArguments(tok3->previous());
|
const std::vector<const Token *> params = getArguments(tok3->previous());
|
||||||
for (const Token *par : params) {
|
for (const Token *par : params) {
|
||||||
if (!par->isComparisonOp())
|
if (!par->isComparisonOp())
|
||||||
|
@ -1020,7 +1020,7 @@ void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndO
|
||||||
(tok3->valueType()->typeSize(*mSettings) == 0) ||
|
(tok3->valueType()->typeSize(*mSettings) == 0) ||
|
||||||
(tok3->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
(tok3->valueType()->typeSize(*mSettings) >= mSettings->sizeof_pointer)))
|
||||||
tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1();
|
tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1();
|
||||||
if (Token::Match(tok3, "%varid%", varid))
|
if (tok3 && tok3->varId() == varid)
|
||||||
tok2 = tok3->next();
|
tok2 = tok3->next();
|
||||||
else if (Token::Match(tok3, "& %varid% . %name%", varid))
|
else if (Token::Match(tok3, "& %varid% . %name%", varid))
|
||||||
tok2 = tok3->tokAt(4);
|
tok2 = tok3->tokAt(4);
|
||||||
|
|
|
@ -228,7 +228,7 @@ void CheckOther::clarifyStatement()
|
||||||
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
|
||||||
for (const Scope * scope : symbolDatabase->functionScopes) {
|
for (const Scope * scope : symbolDatabase->functionScopes) {
|
||||||
for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
|
for (const Token* tok = scope->bodyStart; tok && tok != scope->bodyEnd; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "* %name%") && tok->astOperand1()) {
|
if (tok->astOperand1() && Token::Match(tok, "* %name%")) {
|
||||||
const Token *tok2 = tok->previous();
|
const Token *tok2 = tok->previous();
|
||||||
|
|
||||||
while (tok2 && tok2->str() == "*")
|
while (tok2 && tok2->str() == "*")
|
||||||
|
@ -445,7 +445,7 @@ void CheckOther::checkRedundantAssignment()
|
||||||
if (Token::simpleMatch(tok, "try {"))
|
if (Token::simpleMatch(tok, "try {"))
|
||||||
// todo: check try blocks
|
// todo: check try blocks
|
||||||
tok = tok->linkAt(1);
|
tok = tok->linkAt(1);
|
||||||
if ((tok->isAssignmentOp() || Token::Match(tok, "++|--")) && tok->astOperand1()) {
|
if ((tok->isAssignmentOp() || tok->tokType() == Token::eIncDecOp) && tok->astOperand1()) {
|
||||||
if (tok->astParent())
|
if (tok->astParent())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1777,7 +1777,7 @@ static bool isVarDeclOp(const Token* tok)
|
||||||
if (vartok && vartok->variable() && vartok->variable()->nameToken() == vartok)
|
if (vartok && vartok->variable() && vartok->variable()->nameToken() == vartok)
|
||||||
return true;
|
return true;
|
||||||
const Token * typetok = tok->astOperand1();
|
const Token * typetok = tok->astOperand1();
|
||||||
return isType(typetok, Token::Match(vartok, "%var%"));
|
return isType(typetok, vartok && vartok->varId() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isBracketAccess(const Token* tok)
|
static bool isBracketAccess(const Token* tok)
|
||||||
|
@ -1800,9 +1800,9 @@ static bool isConstStatement(const Token *tok, bool cpp)
|
||||||
return false;
|
return false;
|
||||||
if (tok->isExpandedMacro())
|
if (tok->isExpandedMacro())
|
||||||
return false;
|
return false;
|
||||||
if (Token::Match(tok, "%bool%|%num%|%str%|%char%|nullptr|NULL"))
|
if (tok->varId() != 0)
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(tok, "%var%"))
|
if (Token::Match(tok, "%bool%|%num%|%str%|%char%|nullptr|NULL"))
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(tok, "*|&|&&") &&
|
if (Token::Match(tok, "*|&|&&") &&
|
||||||
(Token::Match(tok->previous(), "::|.|const|volatile|restrict") || isVarDeclOp(tok)))
|
(Token::Match(tok->previous(), "::|.|const|volatile|restrict") || isVarDeclOp(tok)))
|
||||||
|
@ -1939,7 +1939,7 @@ void CheckOther::checkIncompleteStatement()
|
||||||
if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral()))
|
if (mTokenizer->isCPP() && tok->str() == "&" && !(tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isIntegral()))
|
||||||
// Possible archive
|
// Possible archive
|
||||||
continue;
|
continue;
|
||||||
bool inconclusive = Token::Match(tok, "%cop%");
|
bool inconclusive = tok->isConstOp();
|
||||||
if (mSettings->certainty.isEnabled(Certainty::inconclusive) || !inconclusive)
|
if (mSettings->certainty.isEnabled(Certainty::inconclusive) || !inconclusive)
|
||||||
constStatementError(tok, tok->isNumber() ? "numeric" : "string", inconclusive);
|
constStatementError(tok, tok->isNumber() ? "numeric" : "string", inconclusive);
|
||||||
}
|
}
|
||||||
|
@ -3117,7 +3117,7 @@ void CheckOther::checkEvaluationOrder()
|
||||||
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
|
||||||
for (const Scope * functionScope : symbolDatabase->functionScopes) {
|
for (const Scope * functionScope : symbolDatabase->functionScopes) {
|
||||||
for (const Token* tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) {
|
for (const Token* tok = functionScope->bodyStart; tok != functionScope->bodyEnd; tok = tok->next()) {
|
||||||
if (!Token::Match(tok, "++|--") && !tok->isAssignmentOp())
|
if (tok->tokType() != Token::eIncDecOp && !tok->isAssignmentOp())
|
||||||
continue;
|
continue;
|
||||||
if (!tok->astOperand1())
|
if (!tok->astOperand1())
|
||||||
continue;
|
continue;
|
||||||
|
@ -3470,7 +3470,7 @@ void CheckOther::shadowError(const Token *var, const Token *shadowed, std::strin
|
||||||
|
|
||||||
static bool isVariableExpression(const Token* tok)
|
static bool isVariableExpression(const Token* tok)
|
||||||
{
|
{
|
||||||
if (Token::Match(tok, "%var%"))
|
if (tok->varId() != 0)
|
||||||
return true;
|
return true;
|
||||||
if (Token::simpleMatch(tok, "."))
|
if (Token::simpleMatch(tok, "."))
|
||||||
return isVariableExpression(tok->astOperand1()) &&
|
return isVariableExpression(tok->astOperand1()) &&
|
||||||
|
@ -3498,7 +3498,7 @@ void CheckOther::checkKnownArgument()
|
||||||
continue;
|
continue;
|
||||||
if (!tok->hasKnownIntValue())
|
if (!tok->hasKnownIntValue())
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "++|--"))
|
if (tok->tokType() == Token::eIncDecOp)
|
||||||
continue;
|
continue;
|
||||||
if (isConstVarExpression(tok))
|
if (isConstVarExpression(tok))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1583,10 +1583,8 @@ static const Token *skipLocalVars(const Token *tok)
|
||||||
return tok;
|
return tok;
|
||||||
return skipLocalVars(semi->next());
|
return skipLocalVars(semi->next());
|
||||||
}
|
}
|
||||||
if (Token::Match(top, "%assign%")) {
|
if (tok->isAssignmentOp()) {
|
||||||
const Token *varTok = top->astOperand1();
|
const Token *varTok = top->astOperand1();
|
||||||
if (!Token::Match(varTok, "%var%"))
|
|
||||||
return tok;
|
|
||||||
const Variable *var = varTok->variable();
|
const Variable *var = varTok->variable();
|
||||||
if (!var)
|
if (!var)
|
||||||
return tok;
|
return tok;
|
||||||
|
@ -1956,8 +1954,7 @@ void CheckStl::string_c_str()
|
||||||
if (var->isPointer())
|
if (var->isPointer())
|
||||||
string_c_strError(tok);
|
string_c_strError(tok);
|
||||||
}
|
}
|
||||||
} else if (printPerformance && tok->function() && Token::Match(tok, "%name% ( !!)") && c_strFuncParam.find(tok->function()) != c_strFuncParam.end() &&
|
} else if (printPerformance && tok->function() && Token::Match(tok, "%name% ( !!)") && tok->str() != scope.className) {
|
||||||
tok->str() != scope.className) {
|
|
||||||
const std::pair<std::multimap<const Function*, int>::const_iterator, std::multimap<const Function*, int>::const_iterator> range = c_strFuncParam.equal_range(tok->function());
|
const std::pair<std::multimap<const Function*, int>::const_iterator, std::multimap<const Function*, int>::const_iterator> range = c_strFuncParam.equal_range(tok->function());
|
||||||
for (std::multimap<const Function*, int>::const_iterator i = range.first; i != range.second; ++i) {
|
for (std::multimap<const Function*, int>::const_iterator i = range.first; i != range.second; ++i) {
|
||||||
if (i->second == 0)
|
if (i->second == 0)
|
||||||
|
@ -2613,7 +2610,7 @@ void CheckStl::useStlAlgorithm()
|
||||||
if (!Token::simpleMatch(splitTok, ":"))
|
if (!Token::simpleMatch(splitTok, ":"))
|
||||||
continue;
|
continue;
|
||||||
const Token *loopVar = splitTok->previous();
|
const Token *loopVar = splitTok->previous();
|
||||||
if (!Token::Match(loopVar, "%var%"))
|
if (loopVar->varId() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check for single assignment
|
// Check for single assignment
|
||||||
|
|
|
@ -663,7 +663,7 @@ static ValueFlow::Value executeImpl(const Token* expr, ProgramMemory& pm, const
|
||||||
} else if (expr->str() == "," && expr->astOperand1() && expr->astOperand2()) {
|
} else if (expr->str() == "," && expr->astOperand1() && expr->astOperand2()) {
|
||||||
execute(expr->astOperand1(), pm);
|
execute(expr->astOperand1(), pm);
|
||||||
return execute(expr->astOperand2(), pm);
|
return execute(expr->astOperand2(), pm);
|
||||||
} else if (Token::Match(expr, "++|--") && expr->astOperand1() && expr->astOperand1()->exprId() != 0) {
|
} else if (expr->tokType() == Token::eIncDecOp && expr->astOperand1() && expr->astOperand1()->exprId() != 0) {
|
||||||
if (!pm.hasValue(expr->astOperand1()->exprId()))
|
if (!pm.hasValue(expr->astOperand1()->exprId()))
|
||||||
return unknown;
|
return unknown;
|
||||||
ValueFlow::Value& lhs = pm.at(expr->astOperand1()->exprId());
|
ValueFlow::Value& lhs = pm.at(expr->astOperand1()->exprId());
|
||||||
|
|
|
@ -646,8 +646,9 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool newFunc = true; // Is this function already in the database?
|
bool newFunc = true; // Is this function already in the database?
|
||||||
for (std::multimap<std::string, const Function *>::const_iterator i = scope->functionMap.find(tok->str()); i != scope->functionMap.end() && i->first == tok->str(); ++i) {
|
auto range = scope->functionMap.equal_range(tok->str());
|
||||||
if (i->second->argsMatch(scope, i->second->argDef, argStart, emptyString, 0)) {
|
for (std::multimap<std::string, const Function*>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
|
if (it->second->argsMatch(scope, it->second->argDef, argStart, emptyString, 0)) {
|
||||||
newFunc = false;
|
newFunc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1319,6 +1320,8 @@ void SymbolDatabase::createSymbolDatabaseEnums()
|
||||||
const_cast<Token *>(i.name)->enumerator(&i);
|
const_cast<Token *>(i.name)->enumerator(&i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<std::string> tokensThatAreNotEnumeratorValues;
|
||||||
|
|
||||||
for (Scope &scope : scopeList) {
|
for (Scope &scope : scopeList) {
|
||||||
if (scope.type != Scope::eEnum)
|
if (scope.type != Scope::eEnum)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1330,7 +1333,7 @@ void SymbolDatabase::createSymbolDatabaseEnums()
|
||||||
mTokenizer->syntaxError(enumerator.start);
|
mTokenizer->syntaxError(enumerator.start);
|
||||||
for (const Token * tok3 = enumerator.start; tok3 && tok3 != enumerator.end->next(); tok3 = tok3->next()) {
|
for (const Token * tok3 = enumerator.start; tok3 && tok3 != enumerator.end->next(); tok3 = tok3->next()) {
|
||||||
if (tok3->tokType() == Token::eName) {
|
if (tok3->tokType() == Token::eName) {
|
||||||
const Enumerator * e = findEnumerator(tok3);
|
const Enumerator * e = findEnumerator(tok3, tokensThatAreNotEnumeratorValues);
|
||||||
if (e)
|
if (e)
|
||||||
const_cast<Token *>(tok3)->enumerator(e);
|
const_cast<Token *>(tok3)->enumerator(e);
|
||||||
}
|
}
|
||||||
|
@ -1343,7 +1346,7 @@ void SymbolDatabase::createSymbolDatabaseEnums()
|
||||||
for (const Token* tok = mTokenizer->list.front(); tok != mTokenizer->list.back(); tok = tok->next()) {
|
for (const Token* tok = mTokenizer->list.front(); tok != mTokenizer->list.back(); tok = tok->next()) {
|
||||||
if (tok->tokType() != Token::eName)
|
if (tok->tokType() != Token::eName)
|
||||||
continue;
|
continue;
|
||||||
const Enumerator * enumerator = findEnumerator(tok);
|
const Enumerator * enumerator = findEnumerator(tok, tokensThatAreNotEnumeratorValues);
|
||||||
if (enumerator)
|
if (enumerator)
|
||||||
const_cast<Token *>(tok)->enumerator(enumerator);
|
const_cast<Token *>(tok)->enumerator(enumerator);
|
||||||
}
|
}
|
||||||
|
@ -1417,12 +1420,10 @@ void SymbolDatabase::createSymbolDatabaseIncompleteVars()
|
||||||
continue;
|
continue;
|
||||||
if (!scope->isExecutable())
|
if (!scope->isExecutable())
|
||||||
continue;
|
continue;
|
||||||
if (!Token::Match(tok, "%name%"))
|
if (tok->varId() != 0)
|
||||||
continue;
|
continue;
|
||||||
if (!tok->isNameOnly())
|
if (!tok->isNameOnly())
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "%var%"))
|
|
||||||
continue;
|
|
||||||
if (tok->type())
|
if (tok->type())
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok->next(), "::|.|(|:|%var%"))
|
if (Token::Match(tok->next(), "::|.|(|:|%var%"))
|
||||||
|
@ -1763,7 +1764,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
||||||
// skip over qualification
|
// skip over qualification
|
||||||
while (Token::simpleMatch(tok1, "::")) {
|
while (Token::simpleMatch(tok1, "::")) {
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
if (Token::Match(tok1, "%name%"))
|
if (tok1 && tok1->isName())
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
||||||
tok1 = tok1->link()->tokAt(-2);
|
tok1 = tok1->link()->tokAt(-2);
|
||||||
|
@ -1810,7 +1811,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// skip over return type
|
// skip over return type
|
||||||
if (Token::Match(tok1, "%name%")) {
|
if (tok1 && tok1->isName()) {
|
||||||
if (tok1->str() == "return")
|
if (tok1->str() == "return")
|
||||||
return false;
|
return false;
|
||||||
if (tok1->str() != "friend")
|
if (tok1->str() != "friend")
|
||||||
|
@ -1820,7 +1821,7 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
||||||
// skip over qualification
|
// skip over qualification
|
||||||
while (Token::simpleMatch(tok1, "::")) {
|
while (Token::simpleMatch(tok1, "::")) {
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
if (Token::Match(tok1, "%name%"))
|
if (tok1 && tok1->isName())
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
else if (tok1 && tok1->str() == ">" && tok1->link() && Token::Match(tok1->link()->previous(), "%name%"))
|
||||||
tok1 = tok1->link()->tokAt(-2);
|
tok1 = tok1->link()->tokAt(-2);
|
||||||
|
@ -2931,12 +2932,13 @@ Function* SymbolDatabase::addGlobalFunction(Scope*& scope, const Token*& tok, co
|
||||||
Function* function = nullptr;
|
Function* function = nullptr;
|
||||||
// Lambda functions are always unique
|
// Lambda functions are always unique
|
||||||
if (tok->str() != "[") {
|
if (tok->str() != "[") {
|
||||||
for (std::multimap<std::string, const Function *>::iterator i = scope->functionMap.find(tok->str()); i != scope->functionMap.end() && i->first == tok->str(); ++i) {
|
auto range = scope->functionMap.equal_range(tok->str());
|
||||||
const Function *f = i->second;
|
for (std::multimap<std::string, const Function*>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
|
const Function *f = it->second;
|
||||||
if (f->hasBody())
|
if (f->hasBody())
|
||||||
continue;
|
continue;
|
||||||
if (f->argsMatch(scope, f->argDef, argStart, emptyString, 0)) {
|
if (f->argsMatch(scope, f->argDef, argStart, emptyString, 0)) {
|
||||||
function = const_cast<Function *>(i->second);
|
function = const_cast<Function *>(it->second);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3019,7 +3021,7 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
|
||||||
|
|
||||||
// check in namespace if using found
|
// check in namespace if using found
|
||||||
if (*scope == scope1 && !scope1->usingList.empty()) {
|
if (*scope == scope1 && !scope1->usingList.empty()) {
|
||||||
std::list<Scope::UsingInfo>::const_iterator it2;
|
std::vector<Scope::UsingInfo>::const_iterator it2;
|
||||||
for (it2 = scope1->usingList.begin(); it2 != scope1->usingList.end(); ++it2) {
|
for (it2 = scope1->usingList.begin(); it2 != scope1->usingList.end(); ++it2) {
|
||||||
if (it2->scope) {
|
if (it2->scope) {
|
||||||
Function * func = findFunctionInScope(tok1, it2->scope, path, path_length);
|
Function * func = findFunctionInScope(tok1, it2->scope, path, path_length);
|
||||||
|
@ -3090,7 +3092,8 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
for (std::multimap<std::string, const Function *>::iterator it = scope1->functionMap.find((*tok)->str()); it != scope1->functionMap.end() && it->first == (*tok)->str(); ++it) {
|
auto range = scope1->functionMap.equal_range((*tok)->str());
|
||||||
|
for (std::multimap<std::string, const Function*>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
Function * func = const_cast<Function *>(it->second);
|
Function * func = const_cast<Function *>(it->second);
|
||||||
if (!func->hasBody()) {
|
if (!func->hasBody()) {
|
||||||
if (func->argsMatch(scope1, func->argDef, (*tok)->next(), path, path_length)) {
|
if (func->argsMatch(scope1, func->argDef, (*tok)->next(), path, path_length)) {
|
||||||
|
@ -3597,17 +3600,15 @@ void SymbolDatabase::printOut(const char *title) const
|
||||||
if (title)
|
if (title)
|
||||||
std::cout << "\n### " << title << " ###\n";
|
std::cout << "\n### " << title << " ###\n";
|
||||||
|
|
||||||
for (std::list<Scope>::const_iterator scope = scopeList.begin(); scope != scopeList.end(); ++scope) {
|
for (std::list<Scope>::const_iterator scope = scopeList.cbegin(); scope != scopeList.cend(); ++scope) {
|
||||||
std::cout << "Scope: " << &*scope << " " << scope->type << std::endl;
|
std::cout << "Scope: " << &*scope << " " << scope->type << std::endl;
|
||||||
std::cout << " className: " << scope->className << std::endl;
|
std::cout << " className: " << scope->className << std::endl;
|
||||||
std::cout << " classDef: " << tokenToString(scope->classDef, mTokenizer) << std::endl;
|
std::cout << " classDef: " << tokenToString(scope->classDef, mTokenizer) << std::endl;
|
||||||
std::cout << " bodyStart: " << tokenToString(scope->bodyStart, mTokenizer) << std::endl;
|
std::cout << " bodyStart: " << tokenToString(scope->bodyStart, mTokenizer) << std::endl;
|
||||||
std::cout << " bodyEnd: " << tokenToString(scope->bodyEnd, mTokenizer) << std::endl;
|
std::cout << " bodyEnd: " << tokenToString(scope->bodyEnd, mTokenizer) << std::endl;
|
||||||
|
|
||||||
std::list<Function>::const_iterator func;
|
|
||||||
|
|
||||||
// find the function body if not implemented inline
|
// find the function body if not implemented inline
|
||||||
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
for (auto func = scope->functionList.cbegin(); func != scope->functionList.cend(); ++func) {
|
||||||
std::cout << " Function: " << &*func << std::endl;
|
std::cout << " Function: " << &*func << std::endl;
|
||||||
std::cout << " name: " << tokenToString(func->tokenDef, mTokenizer) << std::endl;
|
std::cout << " name: " << tokenToString(func->tokenDef, mTokenizer) << std::endl;
|
||||||
std::cout << " type: " << (func->type == Function::eConstructor? "Constructor" :
|
std::cout << " type: " << (func->type == Function::eConstructor? "Constructor" :
|
||||||
|
@ -3686,17 +3687,13 @@ void SymbolDatabase::printOut(const char *title) const
|
||||||
std::cout << " nestedIn: " << scopeToString(func->nestedIn, mTokenizer) << std::endl;
|
std::cout << " nestedIn: " << scopeToString(func->nestedIn, mTokenizer) << std::endl;
|
||||||
std::cout << " functionScope: " << scopeToString(func->functionScope, mTokenizer) << std::endl;
|
std::cout << " functionScope: " << scopeToString(func->functionScope, mTokenizer) << std::endl;
|
||||||
|
|
||||||
std::list<Variable>::const_iterator var;
|
for (auto var = func->argumentList.cbegin(); var != func->argumentList.cend(); ++var) {
|
||||||
|
|
||||||
for (var = func->argumentList.begin(); var != func->argumentList.end(); ++var) {
|
|
||||||
std::cout << " Variable: " << &*var << std::endl;
|
std::cout << " Variable: " << &*var << std::endl;
|
||||||
printVariable(&*var, " ");
|
printVariable(&*var, " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<Variable>::const_iterator var;
|
for (auto var = scope->varlist.cbegin(); var != scope->varlist.cend(); ++var) {
|
||||||
|
|
||||||
for (var = scope->varlist.begin(); var != scope->varlist.end(); ++var) {
|
|
||||||
std::cout << " Variable: " << &*var << std::endl;
|
std::cout << " Variable: " << &*var << std::endl;
|
||||||
printVariable(&*var, " ");
|
printVariable(&*var, " ");
|
||||||
}
|
}
|
||||||
|
@ -3741,10 +3738,8 @@ void SymbolDatabase::printOut(const char *title) const
|
||||||
|
|
||||||
std::cout << " nestedList[" << scope->nestedList.size() << "] = (";
|
std::cout << " nestedList[" << scope->nestedList.size() << "] = (";
|
||||||
|
|
||||||
std::list<Scope *>::const_iterator nsi;
|
|
||||||
|
|
||||||
std::size_t count = scope->nestedList.size();
|
std::size_t count = scope->nestedList.size();
|
||||||
for (nsi = scope->nestedList.begin(); nsi != scope->nestedList.end(); ++nsi) {
|
for (std::vector<Scope*>::const_iterator nsi = scope->nestedList.cbegin(); nsi != scope->nestedList.cend(); ++nsi) {
|
||||||
std::cout << " " << (*nsi) << " " << (*nsi)->type << " " << (*nsi)->className;
|
std::cout << " " << (*nsi) << " " << (*nsi)->type << " " << (*nsi)->className;
|
||||||
if (count-- > 1)
|
if (count-- > 1)
|
||||||
std::cout << ",";
|
std::cout << ",";
|
||||||
|
@ -3752,9 +3747,7 @@ void SymbolDatabase::printOut(const char *title) const
|
||||||
|
|
||||||
std::cout << " )" << std::endl;
|
std::cout << " )" << std::endl;
|
||||||
|
|
||||||
std::list<Scope::UsingInfo>::const_iterator use;
|
for (auto use = scope->usingList.cbegin(); use != scope->usingList.cend(); ++use) {
|
||||||
|
|
||||||
for (use = scope->usingList.begin(); use != scope->usingList.end(); ++use) {
|
|
||||||
std::cout << " using: " << use->scope << " " << use->start->strAt(2);
|
std::cout << " using: " << use->scope << " " << use->start->strAt(2);
|
||||||
const Token *tok1 = use->start->tokAt(3);
|
const Token *tok1 = use->start->tokAt(3);
|
||||||
while (tok1 && tok1->str() == "::") {
|
while (tok1 && tok1->str() == "::") {
|
||||||
|
@ -4160,7 +4153,8 @@ const Function * Function::getOverriddenFunctionRecursive(const ::Type* baseType
|
||||||
const Scope *parent = derivedFromType->classScope;
|
const Scope *parent = derivedFromType->classScope;
|
||||||
|
|
||||||
// check if function defined in base class
|
// check if function defined in base class
|
||||||
for (std::multimap<std::string, const Function *>::const_iterator it = parent->functionMap.find(tokenDef->str()); it != parent->functionMap.end() && it->first == tokenDef->str(); ++it) {
|
auto range = parent->functionMap.equal_range(tokenDef->str());
|
||||||
|
for (std::multimap<std::string, const Function*>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
const Function * func = it->second;
|
const Function * func = it->second;
|
||||||
if (func->hasVirtualSpecifier()) { // Base is virtual and of same name
|
if (func->hasVirtualSpecifier()) { // Base is virtual and of same name
|
||||||
const Token *temp1 = func->tokenDef->previous();
|
const Token *temp1 = func->tokenDef->previous();
|
||||||
|
@ -4714,13 +4708,13 @@ const Token * Scope::addEnum(const Token * tok, bool isCpp)
|
||||||
return tok2;
|
return tok2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
|
const Enumerator * SymbolDatabase::findEnumerator(const Token * tok, std::set<std::string>& tokensThatAreNotEnumeratorValues) const
|
||||||
{
|
{
|
||||||
const Scope * scope = tok->scope();
|
const Scope * scope = tok->scope();
|
||||||
|
|
||||||
const std::string &tokStr = tok->str();
|
const std::string &tokStr = tok->str();
|
||||||
|
|
||||||
if (mTokensThatAreNotEnumeratorValues.find(tokStr) != mTokensThatAreNotEnumeratorValues.end()) {
|
if (tokensThatAreNotEnumeratorValues.find(tokStr) != tokensThatAreNotEnumeratorValues.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4761,7 +4755,7 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
|
||||||
return enumerator;
|
return enumerator;
|
||||||
// enum
|
// enum
|
||||||
else {
|
else {
|
||||||
for (std::list<Scope *>::const_iterator it = scope->nestedList.begin(), end = scope->nestedList.end(); it != end; ++it) {
|
for (std::vector<Scope *>::const_iterator it = scope->nestedList.begin(), end = scope->nestedList.end(); it != end; ++it) {
|
||||||
enumerator = (*it)->findEnumerator(tokStr);
|
enumerator = (*it)->findEnumerator(tokStr);
|
||||||
|
|
||||||
if (enumerator)
|
if (enumerator)
|
||||||
|
@ -4776,7 +4770,7 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
|
||||||
if (enumerator)
|
if (enumerator)
|
||||||
return enumerator;
|
return enumerator;
|
||||||
|
|
||||||
for (std::list<Scope *>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) {
|
for (std::vector<Scope *>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) {
|
||||||
enumerator = (*s)->findEnumerator(tokStr);
|
enumerator = (*s)->findEnumerator(tokStr);
|
||||||
|
|
||||||
if (enumerator)
|
if (enumerator)
|
||||||
|
@ -4807,7 +4801,7 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
|
||||||
if (enumerator)
|
if (enumerator)
|
||||||
return enumerator;
|
return enumerator;
|
||||||
|
|
||||||
for (std::list<Scope*>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) {
|
for (std::vector<Scope*>::const_iterator s = scope->nestedList.begin(); s != scope->nestedList.end(); ++s) {
|
||||||
enumerator = (*s)->findEnumerator(tokStr);
|
enumerator = (*s)->findEnumerator(tokStr);
|
||||||
|
|
||||||
if (enumerator)
|
if (enumerator)
|
||||||
|
@ -4816,7 +4810,7 @@ const Enumerator * SymbolDatabase::findEnumerator(const Token * tok) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mTokensThatAreNotEnumeratorValues.insert(tokStr);
|
tokensThatAreNotEnumeratorValues.insert(tokStr);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -4986,7 +4980,8 @@ void Scope::findFunctionInBase(const std::string & name, nonneg int args, std::v
|
||||||
if (base->classScope == this) // Ticket #5120, #5125: Recursive class; tok should have been found already
|
if (base->classScope == this) // Ticket #5120, #5125: Recursive class; tok should have been found already
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (std::multimap<std::string, const Function *>::const_iterator it = base->classScope->functionMap.find(name); it != base->classScope->functionMap.end() && it->first == name; ++it) {
|
auto range = base->classScope->functionMap.equal_range(name);
|
||||||
|
for (std::multimap<std::string, const Function*>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
const Function *func = it->second;
|
const Function *func = it->second;
|
||||||
if ((func->isVariadic() && args >= (func->argCount() - 1)) ||
|
if ((func->isVariadic() && args >= (func->argCount() - 1)) ||
|
||||||
(args == func->argCount() || (args < func->argCount() && args >= func->minArgCount()))) {
|
(args == func->argCount() || (args < func->argCount() && args >= func->minArgCount()))) {
|
||||||
|
@ -5127,7 +5122,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
|
||||||
const std::size_t args = arguments.size();
|
const std::size_t args = arguments.size();
|
||||||
|
|
||||||
auto addMatchingFunctions = [&](const Scope *scope) {
|
auto addMatchingFunctions = [&](const Scope *scope) {
|
||||||
for (std::multimap<std::string, const Function *>::const_iterator it = scope->functionMap.find(tok->str()); it != scope->functionMap.cend() && it->first == tok->str(); ++it) {
|
auto range = scope->functionMap.equal_range(tok->str());
|
||||||
|
for (std::multimap<std::string, const Function *>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
const Function *func = it->second;
|
const Function *func = it->second;
|
||||||
if (!isCall || args == func->argCount() ||
|
if (!isCall || args == func->argCount() ||
|
||||||
(func->isVariadic() && args >= (func->minArgCount() - 1)) ||
|
(func->isVariadic() && args >= (func->minArgCount() - 1)) ||
|
||||||
|
@ -5677,7 +5673,7 @@ const Type* SymbolDatabase::findType(const Token *startTok, const Scope *startSc
|
||||||
|
|
||||||
// check using namespaces
|
// check using namespaces
|
||||||
while (startScope) {
|
while (startScope) {
|
||||||
for (std::list<Scope::UsingInfo>::const_iterator it = startScope->usingList.begin();
|
for (std::vector<Scope::UsingInfo>::const_iterator it = startScope->usingList.begin();
|
||||||
it != startScope->usingList.end(); ++it) {
|
it != startScope->usingList.end(); ++it) {
|
||||||
tok = startTok;
|
tok = startTok;
|
||||||
scope = it->scope;
|
scope = it->scope;
|
||||||
|
@ -5796,9 +5792,8 @@ Function * SymbolDatabase::findFunctionInScope(const Token *func, const Scope *n
|
||||||
const Function * function = nullptr;
|
const Function * function = nullptr;
|
||||||
const bool destructor = func->strAt(-1) == "~";
|
const bool destructor = func->strAt(-1) == "~";
|
||||||
|
|
||||||
for (std::multimap<std::string, const Function *>::const_iterator it = ns->functionMap.find(func->str());
|
auto range = ns->functionMap.equal_range(func->str());
|
||||||
it != ns->functionMap.end() && it->first == func->str(); ++it) {
|
for (std::multimap<std::string, const Function*>::const_iterator it = range.first; it != range.second; ++it) {
|
||||||
|
|
||||||
if (it->second->argsMatch(ns, it->second->argDef, func->next(), path, path_length) &&
|
if (it->second->argsMatch(ns, it->second->argDef, func->next(), path, path_length) &&
|
||||||
it->second->isDestructor() == destructor) {
|
it->second->isDestructor() == destructor) {
|
||||||
function = it->second;
|
function = it->second;
|
||||||
|
|
|
@ -1033,10 +1033,10 @@ public:
|
||||||
std::multimap<std::string, const Function *> functionMap;
|
std::multimap<std::string, const Function *> functionMap;
|
||||||
std::list<Variable> varlist;
|
std::list<Variable> varlist;
|
||||||
const Scope *nestedIn;
|
const Scope *nestedIn;
|
||||||
std::list<Scope *> nestedList;
|
std::vector<Scope *> nestedList;
|
||||||
nonneg int numConstructors;
|
nonneg int numConstructors;
|
||||||
nonneg int numCopyOrMoveConstructors;
|
nonneg int numCopyOrMoveConstructors;
|
||||||
std::list<UsingInfo> usingList;
|
std::vector<UsingInfo> usingList;
|
||||||
ScopeType type;
|
ScopeType type;
|
||||||
Type* definedType;
|
Type* definedType;
|
||||||
std::map<std::string, Type*> definedTypesMap;
|
std::map<std::string, Type*> definedTypesMap;
|
||||||
|
@ -1481,7 +1481,7 @@ private:
|
||||||
/** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/
|
/** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/
|
||||||
bool isReservedName(const std::string& iName) const;
|
bool isReservedName(const std::string& iName) const;
|
||||||
|
|
||||||
const Enumerator * findEnumerator(const Token * tok) const;
|
const Enumerator * findEnumerator(const Token * tok, std::set<std::string>& tokensThatAreNotEnumeratorValues) const;
|
||||||
|
|
||||||
void setValueType(Token *tok, const ValueType &valuetype);
|
void setValueType(Token *tok, const ValueType &valuetype);
|
||||||
void setValueType(Token *tok, const Variable &var);
|
void setValueType(Token *tok, const Variable &var);
|
||||||
|
@ -1499,9 +1499,6 @@ private:
|
||||||
|
|
||||||
bool mIsCpp;
|
bool mIsCpp;
|
||||||
ValueType::Sign mDefaultSignedness;
|
ValueType::Sign mDefaultSignedness;
|
||||||
|
|
||||||
/** "negative cache" list of tokens that we find are not enumeration values */
|
|
||||||
mutable std::set<std::string> mTokensThatAreNotEnumeratorValues;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -822,8 +822,8 @@ void TemplateSimplifier::getTemplateInstantiations()
|
||||||
fullName = tok->str();
|
fullName = tok->str();
|
||||||
|
|
||||||
// get all declarations with this name
|
// get all declarations with this name
|
||||||
for (auto pos = functionNameMap.lower_bound(tok->str());
|
auto range = functionNameMap.equal_range(tok->str());
|
||||||
pos != functionNameMap.upper_bound(tok->str()); ++pos) {
|
for (auto pos = range.first; pos != range.second; ++pos) {
|
||||||
// look for declaration with same qualification or constructor with same qualification
|
// look for declaration with same qualification or constructor with same qualification
|
||||||
if (pos->second->fullName() == fullName ||
|
if (pos->second->fullName() == fullName ||
|
||||||
(pos->second->scope() == fullName && tok->str() == pos->second->name())) {
|
(pos->second->scope() == fullName && tok->str() == pos->second->name())) {
|
||||||
|
@ -2550,7 +2550,7 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
||||||
|
|
||||||
for (Token *tok = first->next(); tok && tok != end; tok = tok->next()) {
|
for (Token *tok = first->next(); tok && tok != end; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "( %num%|%bool% )") &&
|
if (Token::Match(tok, "( %num%|%bool% )") &&
|
||||||
(tok->previous() && !Token::Match(tok->previous(), "%name%"))) {
|
(tok->previous() && !tok->previous()->isName())) {
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
tok->deleteNext();
|
tok->deleteNext();
|
||||||
again = true;
|
again = true;
|
||||||
|
|
|
@ -1508,7 +1508,7 @@ bool Token::isUnaryPreOp() const
|
||||||
{
|
{
|
||||||
if (!astOperand1() || astOperand2())
|
if (!astOperand1() || astOperand2())
|
||||||
return false;
|
return false;
|
||||||
if (!Token::Match(this, "++|--"))
|
if (this->tokType() != Token::eIncDecOp)
|
||||||
return true;
|
return true;
|
||||||
const Token *tokbefore = mPrevious;
|
const Token *tokbefore = mPrevious;
|
||||||
const Token *tokafter = mNext;
|
const Token *tokafter = mNext;
|
||||||
|
@ -2197,7 +2197,13 @@ const ::Type* Token::typeOf(const Token* tok, const Token** typeTok)
|
||||||
if (typeTok != nullptr)
|
if (typeTok != nullptr)
|
||||||
*typeTok = tok;
|
*typeTok = tok;
|
||||||
const Token* lhsVarTok{};
|
const Token* lhsVarTok{};
|
||||||
if (Token::simpleMatch(tok, "return")) {
|
if (tok->type()) {
|
||||||
|
return tok->type();
|
||||||
|
} else if (tok->variable()) {
|
||||||
|
return tok->variable()->type();
|
||||||
|
} else if (tok->function()) {
|
||||||
|
return tok->function()->retType;
|
||||||
|
} else if (Token::simpleMatch(tok, "return")) {
|
||||||
const Scope *scope = tok->scope();
|
const Scope *scope = tok->scope();
|
||||||
if (!scope)
|
if (!scope)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -2205,18 +2211,6 @@ const ::Type* Token::typeOf(const Token* tok, const Token** typeTok)
|
||||||
if (!function)
|
if (!function)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return function->retType;
|
return function->retType;
|
||||||
} else if (Token::Match(tok, "%type%")) {
|
|
||||||
return tok->type();
|
|
||||||
} else if (Token::Match(tok, "%var%")) {
|
|
||||||
const Variable *var = tok->variable();
|
|
||||||
if (!var)
|
|
||||||
return nullptr;
|
|
||||||
return var->type();
|
|
||||||
} else if (Token::Match(tok, "%name%")) {
|
|
||||||
const Function *function = tok->function();
|
|
||||||
if (!function)
|
|
||||||
return nullptr;
|
|
||||||
return function->retType;
|
|
||||||
} else if (Token::Match(tok->previous(), "%type%|= (|{")) {
|
} else if (Token::Match(tok->previous(), "%type%|= (|{")) {
|
||||||
return typeOf(tok->previous(), typeTok);
|
return typeOf(tok->previous(), typeTok);
|
||||||
} else if (Token::simpleMatch(tok, "=") && (lhsVarTok = getLHSVariableToken(tok)) != tok->next()) {
|
} else if (Token::simpleMatch(tok, "=") && (lhsVarTok = getLHSVariableToken(tok)) != tok->next()) {
|
||||||
|
@ -2251,20 +2245,10 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token * tok)
|
||||||
{
|
{
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return {};
|
return {};
|
||||||
if (Token::simpleMatch(tok, "return")) {
|
else if (tok->type()) {
|
||||||
const Scope *scope = tok->scope();
|
|
||||||
if (!scope)
|
|
||||||
return {};
|
|
||||||
const Function *function = scope->function;
|
|
||||||
if (!function)
|
|
||||||
return {};
|
|
||||||
return {function->retDef, function->returnDefEnd()};
|
|
||||||
} else if (Token::Match(tok, "%type%")) {
|
|
||||||
return {tok, tok->next()};
|
return {tok, tok->next()};
|
||||||
} else if (Token::Match(tok, "%var%")) {
|
} else if (tok->variable()) {
|
||||||
const Variable *var = tok->variable();
|
const Variable *var = tok->variable();
|
||||||
if (!var)
|
|
||||||
return {};
|
|
||||||
if (!var->typeStartToken() || !var->typeEndToken())
|
if (!var->typeStartToken() || !var->typeEndToken())
|
||||||
return {};
|
return {};
|
||||||
if (Token::simpleMatch(var->typeStartToken(), "auto")) {
|
if (Token::simpleMatch(var->typeStartToken(), "auto")) {
|
||||||
|
@ -2278,10 +2262,16 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token * tok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {var->typeStartToken(), var->typeEndToken()->next()};
|
return {var->typeStartToken(), var->typeEndToken()->next()};
|
||||||
} else if (Token::Match(tok->previous(), "%name% (")) {
|
} else if (Token::simpleMatch(tok, "return")) {
|
||||||
const Function *function = tok->previous()->function();
|
const Scope* scope = tok->scope();
|
||||||
|
if (!scope)
|
||||||
|
return {};
|
||||||
|
const Function* function = scope->function;
|
||||||
if (!function)
|
if (!function)
|
||||||
return {};
|
return {};
|
||||||
|
return { function->retDef, function->returnDefEnd() };
|
||||||
|
} else if (tok->previous()->function()) {
|
||||||
|
const Function *function = tok->previous()->function();
|
||||||
return {function->retDef, function->returnDefEnd()};
|
return {function->retDef, function->returnDefEnd()};
|
||||||
} else if (Token::simpleMatch(tok, "=")) {
|
} else if (Token::simpleMatch(tok, "=")) {
|
||||||
return Token::typeDecl(tok->astOperand1());
|
return Token::typeDecl(tok->astOperand1());
|
||||||
|
|
|
@ -12203,7 +12203,7 @@ void Tokenizer::printUnknownTypes() const
|
||||||
if (!mSymbolDatabase)
|
if (!mSymbolDatabase)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::multimap<std::string, const Token *> unknowns;
|
std::vector<std::pair<std::string, const Token *>> unknowns;
|
||||||
|
|
||||||
for (int i = 1; i <= mVarId; ++i) {
|
for (int i = 1; i <= mVarId; ++i) {
|
||||||
const Variable *var = mSymbolDatabase->getVariableFromVarId(i);
|
const Variable *var = mSymbolDatabase->getVariableFromVarId(i);
|
||||||
|
@ -12252,14 +12252,14 @@ void Tokenizer::printUnknownTypes() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unknowns.insert(std::pair<std::string, const Token *>(name, nameTok));
|
unknowns.emplace_back(std::make_pair(name, nameTok));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unknowns.empty()) {
|
if (!unknowns.empty()) {
|
||||||
std::string last;
|
std::string last;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (std::multimap<std::string, const Token *>::const_iterator it = unknowns.begin(); it != unknowns.end(); ++it) {
|
for (auto it = unknowns.begin(); it != unknowns.end(); ++it) {
|
||||||
// skip types is std namespace because they are not interesting
|
// skip types is std namespace because they are not interesting
|
||||||
if (it->first.find("std::") != 0) {
|
if (it->first.find("std::") != 0) {
|
||||||
if (it->first != last) {
|
if (it->first != last) {
|
||||||
|
|
|
@ -2181,9 +2181,9 @@ static bool bifurcate(const Token* tok, const std::set<nonneg int>& varids, cons
|
||||||
return true;
|
return true;
|
||||||
if (tok->hasKnownIntValue())
|
if (tok->hasKnownIntValue())
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(tok, "%cop%"))
|
if (tok->isConstOp())
|
||||||
return bifurcate(tok->astOperand1(), varids, settings, depth) && bifurcate(tok->astOperand2(), varids, settings, depth);
|
return bifurcate(tok->astOperand1(), varids, settings, depth) && bifurcate(tok->astOperand2(), varids, settings, depth);
|
||||||
if (Token::Match(tok, "%var%")) {
|
if (tok->varId() != 0) {
|
||||||
if (varids.count(tok->varId()) > 0)
|
if (varids.count(tok->varId()) > 0)
|
||||||
return true;
|
return true;
|
||||||
const Variable* var = tok->variable();
|
const Variable* var = tok->variable();
|
||||||
|
|
Loading…
Reference in New Issue