optimized non-matchcompiled Token::simpleMatch() a bit (#2640)
This commit is contained in:
parent
dc0b68d505
commit
4f68d85633
|
@ -1428,7 +1428,7 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co
|
|||
continue;
|
||||
|
||||
std::string cast("( " + scope->className + " & )");
|
||||
if (Token::simpleMatch(tok->next(), cast.c_str()))
|
||||
if (Token::simpleMatch(tok->next(), cast.c_str(), cast.size()))
|
||||
tok = tok->tokAt(4);
|
||||
|
||||
// check if a function is called
|
||||
|
@ -1471,7 +1471,8 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co
|
|||
return;
|
||||
}
|
||||
if (startTok->next() == last) {
|
||||
if (Token::simpleMatch(func->argDef, std::string("( const " + scope->className + " &").c_str())) {
|
||||
const std::string tmp("( const " + scope->className + " &");
|
||||
if (Token::simpleMatch(func->argDef, tmp.c_str(), tmp.size())) {
|
||||
// Typical wrong way to suppress default assignment operator by declaring it and leaving empty
|
||||
operatorEqMissingReturnStatementError(func->token, func->access == AccessControl::Public);
|
||||
} else {
|
||||
|
@ -1719,7 +1720,8 @@ void CheckClass::virtualDestructor()
|
|||
if (Token::Match(tok, "[;{}] %var% =") &&
|
||||
baseClassPointers.find(tok->next()->varId()) != baseClassPointers.end()) {
|
||||
// new derived class..
|
||||
if (Token::simpleMatch(tok->tokAt(3), ("new " + derivedClass->str()).c_str())) {
|
||||
const std::string tmp("new " + derivedClass->str());
|
||||
if (Token::simpleMatch(tok->tokAt(3), tmp.c_str(), tmp.size())) {
|
||||
dontDelete.insert(tok->next()->varId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2627,7 +2627,8 @@ void CheckOther::checkUnusedLabel()
|
|||
tok = tok->scope()->bodyEnd;
|
||||
|
||||
if (Token::Match(tok, "{|}|; %name% :") && tok->strAt(1) != "default") {
|
||||
if (!Token::findsimplematch(scope->bodyStart->next(), ("goto " + tok->strAt(1)).c_str(), scope->bodyEnd->previous()))
|
||||
const std::string tmp("goto " + tok->strAt(1));
|
||||
if (!Token::findsimplematch(scope->bodyStart->next(), tmp.c_str(), tmp.size(), scope->bodyEnd->previous()))
|
||||
unusedLabelError(tok->next(), tok->next()->scope()->type == Scope::eSwitch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1405,9 +1405,11 @@ void CheckUnusedVar::checkStructMemberUsage()
|
|||
continue;
|
||||
|
||||
// Check if the struct member variable is used anywhere in the file
|
||||
if (Token::findsimplematch(mTokenizer->tokens(), (". " + var.name()).c_str()))
|
||||
std::string tmp(". " + var.name());
|
||||
if (Token::findsimplematch(mTokenizer->tokens(), tmp.c_str(), tmp.size()))
|
||||
continue;
|
||||
if (Token::findsimplematch(mTokenizer->tokens(), (":: " + var.name()).c_str()))
|
||||
tmp = (":: " + var.name());
|
||||
if (Token::findsimplematch(mTokenizer->tokens(), tmp.c_str(), tmp.size()))
|
||||
continue;
|
||||
|
||||
unusedStructMemberError(var.nameToken(), scope.className, var.name(), scope.type == Scope::eUnion);
|
||||
|
|
|
@ -2356,7 +2356,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
|
|||
else if (arg_path_length && Token::Match(first->next(), "%name%") && first->strAt(1) != "const") {
|
||||
std::string param = path;
|
||||
|
||||
if (Token::simpleMatch(second->next(), param.c_str())) {
|
||||
if (Token::simpleMatch(second->next(), param.c_str(), param.size())) {
|
||||
second = second->tokAt(int(arg_path_length));
|
||||
arg_path_length = 0;
|
||||
}
|
||||
|
@ -2400,7 +2400,7 @@ bool Function::argsMatch(const Scope *scope, const Token *first, const Token *se
|
|||
}
|
||||
|
||||
param = short_path;
|
||||
if (Token::simpleMatch(second->next(), param.c_str())) {
|
||||
if (Token::simpleMatch(second->next(), param.c_str(), param.size())) {
|
||||
second = second->tokAt(int(short_path_length));
|
||||
arg_path_length = 0;
|
||||
}
|
||||
|
|
|
@ -1535,7 +1535,7 @@ bool TemplateSimplifier::alreadyHasNamespace(const TokenAndName &templateDeclara
|
|||
pos += 2;
|
||||
}
|
||||
|
||||
return Token::simpleMatch(tok->tokAt(offset), scope.c_str()) ;
|
||||
return Token::simpleMatch(tok->tokAt(offset), scope.c_str(), scope.size());
|
||||
}
|
||||
|
||||
void TemplateSimplifier::expandTemplate(
|
||||
|
@ -1714,7 +1714,7 @@ void TemplateSimplifier::expandTemplate(
|
|||
}
|
||||
// check if type is instantiated
|
||||
for (const auto & inst : mTemplateInstantiations) {
|
||||
if (Token::simpleMatch(inst.token(), name.c_str())) {
|
||||
if (Token::simpleMatch(inst.token(), name.c_str(), name.size())) {
|
||||
// use the instantiated name
|
||||
dst->insertToken(name, "", true);
|
||||
start = closing;
|
||||
|
|
|
@ -560,14 +560,15 @@ int Token::multiCompare(const Token *tok, const char *haystack, nonneg int varid
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool Token::simpleMatch(const Token *tok, const char pattern[])
|
||||
bool Token::simpleMatch(const Token *tok, const char pattern[], size_t pattern_len)
|
||||
{
|
||||
if (!tok)
|
||||
return false; // shortcut
|
||||
const char *current = pattern;
|
||||
const char *next = std::strchr(pattern, ' ');
|
||||
const char *current = pattern;
|
||||
const char *end = pattern + pattern_len;
|
||||
const char *next = (const char*)std::memchr(pattern, ' ', pattern_len);
|
||||
if (!next)
|
||||
next = pattern + std::strlen(pattern);
|
||||
next = end;
|
||||
|
||||
while (*current) {
|
||||
const std::size_t length = next - current;
|
||||
|
@ -579,7 +580,7 @@ bool Token::simpleMatch(const Token *tok, const char pattern[])
|
|||
if (*next) {
|
||||
next = std::strchr(++current, ' ');
|
||||
if (!next)
|
||||
next = current + std::strlen(current);
|
||||
next = end;
|
||||
}
|
||||
tok = tok->next();
|
||||
}
|
||||
|
@ -938,19 +939,19 @@ Token * Token::findOpeningBracket()
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[])
|
||||
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len)
|
||||
{
|
||||
for (const Token* tok = startTok; tok; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, pattern))
|
||||
if (Token::simpleMatch(tok, pattern, pattern_len))
|
||||
return tok;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], const Token * const end)
|
||||
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
|
||||
{
|
||||
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, pattern))
|
||||
if (Token::simpleMatch(tok, pattern, pattern_len))
|
||||
return tok;
|
||||
}
|
||||
return nullptr;
|
||||
|
|
39
lib/token.h
39
lib/token.h
|
@ -262,7 +262,12 @@ public:
|
|||
* @return true if given token matches with given pattern
|
||||
* false if given token does not match with given pattern
|
||||
*/
|
||||
static bool simpleMatch(const Token *tok, const char pattern[]);
|
||||
template<size_t count>
|
||||
static bool simpleMatch(const Token *tok, const char (&pattern)[count]) {
|
||||
return simpleMatch(tok, pattern, count-1);
|
||||
}
|
||||
|
||||
static bool simpleMatch(const Token *tok, const char pattern[], size_t pattern_len);
|
||||
|
||||
/**
|
||||
* Match given token (or list of tokens) to a pattern list.
|
||||
|
@ -669,16 +674,36 @@ public:
|
|||
setFlag(fIsTemplateArg, value);
|
||||
}
|
||||
|
||||
static const Token *findsimplematch(const Token * const startTok, const char pattern[]);
|
||||
static const Token *findsimplematch(const Token * const startTok, const char pattern[], const Token * const end);
|
||||
template<size_t count>
|
||||
static const Token *findsimplematch(const Token * const startTok, const char (&pattern)[count]) {
|
||||
return findsimplematch(startTok, pattern, count-1);
|
||||
}
|
||||
static const Token *findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len);
|
||||
|
||||
template<size_t count>
|
||||
static const Token *findsimplematch(const Token * const startTok, const char (&pattern)[count], const Token * const end) {
|
||||
return findsimplematch(startTok, pattern, count-1, end);
|
||||
}
|
||||
static const Token *findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end);
|
||||
|
||||
static const Token *findmatch(const Token * const startTok, const char pattern[], const nonneg int varId = 0);
|
||||
static const Token *findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);
|
||||
static Token *findsimplematch(Token * const startTok, const char pattern[]) {
|
||||
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern));
|
||||
|
||||
template<size_t count>
|
||||
static Token *findsimplematch(Token * const startTok, const char (&pattern)[count]) {
|
||||
return findsimplematch(startTok, pattern, count-1);
|
||||
}
|
||||
static Token *findsimplematch(Token * const startTok, const char pattern[], const Token * const end) {
|
||||
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, end));
|
||||
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len) {
|
||||
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len));
|
||||
}
|
||||
template<size_t count>
|
||||
static Token *findsimplematch(Token * const startTok, const char (&pattern)[count], const Token * const end) {
|
||||
return findsimplematch(startTok, pattern, count-1, end);
|
||||
}
|
||||
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end) {
|
||||
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len, end));
|
||||
}
|
||||
|
||||
static Token *findmatch(Token * const startTok, const char pattern[], const nonneg int varId = 0) {
|
||||
return const_cast<Token *>(findmatch(const_cast<const Token *>(startTok), pattern, varId));
|
||||
}
|
||||
|
|
|
@ -1120,7 +1120,7 @@ void Tokenizer::simplifyTypedef()
|
|||
|
||||
// check for typedef that can be substituted
|
||||
else if (tok2->isNameOnly() &&
|
||||
(Token::simpleMatch(tok2, pattern.c_str()) ||
|
||||
(Token::simpleMatch(tok2, pattern.c_str(), pattern.size()) ||
|
||||
(inMemberFunc && tok2->str() == typeName->str()))) {
|
||||
// member function class variables don't need qualification
|
||||
if (!(inMemberFunc && tok2->str() == typeName->str()) && pattern.find("::") != std::string::npos) { // has a "something ::"
|
||||
|
@ -9410,15 +9410,15 @@ void Tokenizer::findGarbageCode() const
|
|||
const bool isCPP11 = isCPP() && mSettings->standards.cpp >= Standards::CPP11;
|
||||
|
||||
const std::set<std::string> nonConsecutiveKeywords{ "break",
|
||||
"continue",
|
||||
"for",
|
||||
"goto",
|
||||
"if",
|
||||
"return",
|
||||
"switch",
|
||||
"throw",
|
||||
"typedef",
|
||||
"while" };
|
||||
"continue",
|
||||
"for",
|
||||
"goto",
|
||||
"if",
|
||||
"return",
|
||||
"switch",
|
||||
"throw",
|
||||
"typedef",
|
||||
"while" };
|
||||
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
// initialization: = {
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
@ -187,9 +188,9 @@ static void setConditionalValues(const Token *tok,
|
|||
const char* lessThan = "<=";
|
||||
if (invert)
|
||||
std::swap(greaterThan, lessThan);
|
||||
if (Token::simpleMatch(tok, greaterThan)) {
|
||||
if (Token::simpleMatch(tok, greaterThan, strlen(greaterThan))) {
|
||||
false_value = ValueFlow::Value{tok, value - 1};
|
||||
} else if (Token::simpleMatch(tok, lessThan)) {
|
||||
} else if (Token::simpleMatch(tok, lessThan, strlen(lessThan))) {
|
||||
false_value = ValueFlow::Value{tok, value + 1};
|
||||
} else {
|
||||
false_value = ValueFlow::Value{tok, value};
|
||||
|
@ -199,10 +200,10 @@ static void setConditionalValues(const Token *tok,
|
|||
const char* lessThan = "<";
|
||||
if (invert)
|
||||
std::swap(greaterThan, lessThan);
|
||||
if (Token::simpleMatch(tok, greaterThan)) {
|
||||
if (Token::simpleMatch(tok, greaterThan, strlen(greaterThan))) {
|
||||
true_value = ValueFlow::Value{tok, value + 1};
|
||||
false_value = ValueFlow::Value{tok, value};
|
||||
} else if (Token::simpleMatch(tok, lessThan)) {
|
||||
} else if (Token::simpleMatch(tok, lessThan, strlen(lessThan))) {
|
||||
true_value = ValueFlow::Value{tok, value - 1};
|
||||
false_value = ValueFlow::Value{tok, value};
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "tokenize.h"
|
||||
#include "tokenlist.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
class TestAstUtils : public TestFixture {
|
||||
public:
|
||||
|
@ -166,8 +167,8 @@ private:
|
|||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
tokenizer.simplifyTokens1("");
|
||||
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1);
|
||||
const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2);
|
||||
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), tokStr1, strlen(tokStr1));
|
||||
const Token * const tok2 = Token::findsimplematch(tok1->next(), tokStr2, strlen(tokStr2));
|
||||
return ::isSameExpression(false, false, tok1, tok2, library, false, true, nullptr);
|
||||
}
|
||||
|
||||
|
@ -203,8 +204,8 @@ private:
|
|||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern);
|
||||
const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern);
|
||||
const Token * const tok1 = Token::findsimplematch(tokenizer.tokens(), startPattern, strlen(startPattern));
|
||||
const Token * const tok2 = Token::findsimplematch(tokenizer.tokens(), endPattern, strlen(endPattern));
|
||||
return ::isVariableChanged(tok1,tok2,1,false,&settings,true);
|
||||
}
|
||||
|
||||
|
@ -247,8 +248,8 @@ private:
|
|||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const Token * tok = Token::findsimplematch(tokenizer.tokens(), parentPattern);
|
||||
return Token::simpleMatch(::nextAfterAstRightmostLeaf(tok), rightPattern);
|
||||
const Token * tok = Token::findsimplematch(tokenizer.tokens(), parentPattern, strlen(parentPattern));
|
||||
return Token::simpleMatch(::nextAfterAstRightmostLeaf(tok), rightPattern, strlen(rightPattern));
|
||||
}
|
||||
|
||||
void nextAfterAstRightmostLeaf() {
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include "token.h"
|
||||
#include "tokenize.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
struct InternalError;
|
||||
|
||||
|
||||
|
@ -4545,7 +4547,7 @@ private:
|
|||
|
||||
const Token *tok1 = TemplateSimplifier::findTemplateDeclarationEnd(_tok);
|
||||
|
||||
return (tok1 == Token::findsimplematch(tokenizer.list.front(), pattern));
|
||||
return (tok1 == Token::findsimplematch(tokenizer.list.front(), pattern, strlen(pattern)));
|
||||
}
|
||||
|
||||
void findTemplateDeclarationEnd() {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
@ -6548,7 +6549,7 @@ private:
|
|||
tokenizer.tokenize(istr, filename);
|
||||
const Token* tok;
|
||||
for (tok = tokenizer.list.back(); tok; tok = tok->previous())
|
||||
if (Token::simpleMatch(tok, pattern))
|
||||
if (Token::simpleMatch(tok, pattern, strlen(pattern)))
|
||||
break;
|
||||
return tok->valueType() ? tok->valueType()->str() : std::string();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
class TestValueFlow : public TestFixture {
|
||||
public:
|
||||
|
@ -231,7 +232,7 @@ private:
|
|||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
for (const ValueFlow::Value &v : tok->values()) {
|
||||
if (v.valueType == type && Token::simpleMatch(v.tokvalue, value))
|
||||
if (v.valueType == type && Token::simpleMatch(v.tokvalue, value, strlen(value)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue