Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 37 additions & 15 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5943,47 +5943,59 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const

//---------------------------------------------------------------------------

const Scope *Scope::findRecordInNestedList(const std::string & name, bool isC) const
template<class S, class T, REQUIRES("S must be a Scope class", std::is_convertible<S*, const Scope*> ), REQUIRES("T must be a Type class", std::is_convertible<T*, const Type*> )>
S* findRecordInNestedListImpl(S& thisScope, const std::string & name, bool isC)
{
for (const Scope* scope: nestedList) {
if (scope->className == name && scope->type != eFunction)
for (S* scope: thisScope.nestedList) {
if (scope->className == name && scope->type != Scope::eFunction)
return scope;
if (isC) {
const Scope* nestedScope = scope->findRecordInNestedList(name, isC);
S* nestedScope = scope->findRecordInNestedList(name, isC);
if (nestedScope)
return nestedScope;
}
}

const Type * nested_type = findType(name);
T * nested_type = thisScope.findType(name);

if (nested_type) {
if (nested_type->isTypeAlias()) {
if (nested_type->typeStart == nested_type->typeEnd)
return findRecordInNestedList(nested_type->typeStart->str());
return thisScope.findRecordInNestedList(nested_type->typeStart->str()); // TODO: pass isC?
} else
return nested_type->classScope;
return const_cast<S*>(nested_type->classScope);
}

return nullptr;
}

const Scope* Scope::findRecordInNestedList(const std::string & name, bool isC) const
{
return findRecordInNestedListImpl<const Scope, const Type>(*this, name, isC);
}

Scope* Scope::findRecordInNestedList(const std::string & name, bool isC)
{
return findRecordInNestedListImpl<Scope, Type>(*this, name, isC);
}

//---------------------------------------------------------------------------

const Type* Scope::findType(const std::string & name) const
template<class S, class T, REQUIRES("S must be a Scope class", std::is_convertible<S*, const Scope*> ), REQUIRES("T must be a Type class", std::is_convertible<T*, const Type*> )>
T* findTypeImpl(S& thisScope, const std::string & name)
{
auto it = definedTypesMap.find(name);
auto it = thisScope.definedTypesMap.find(name);

// Type was found
if (definedTypesMap.end() != it)
if (thisScope.definedTypesMap.end() != it)
return it->second;

// is type defined in anonymous namespace..
it = definedTypesMap.find(emptyString);
if (it != definedTypesMap.end()) {
for (const Scope *scope : nestedList) {
if (scope->className.empty() && (scope->type == eNamespace || scope->isClassOrStructOrUnion())) {
const Type *t = scope->findType(name);
it = thisScope.definedTypesMap.find(emptyString);
if (it != thisScope.definedTypesMap.end()) {
for (S *scope : thisScope.nestedList) {
if (scope->className.empty() && (scope->type == thisScope.eNamespace || scope->isClassOrStructOrUnion())) {
T *t = scope->findType(name);
if (t)
return t;
}
Expand All @@ -5994,6 +6006,16 @@ const Type* Scope::findType(const std::string & name) const
return nullptr;
}

const Type* Scope::findType(const std::string& name) const
{
return findTypeImpl<const Scope, const Type>(*this, name);
}

Type* Scope::findType(const std::string& name)
{
return findTypeImpl<Scope, Type>(*this, name);
}

//---------------------------------------------------------------------------

Scope *Scope::findInNestedListRecursive(const std::string & name)
Expand Down
8 changes: 2 additions & 6 deletions lib/symboldatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1130,14 +1130,10 @@ class CPPCHECKLIB Scope {
const Function *findFunction(const Token *tok, bool requireConst=false) const;

const Scope *findRecordInNestedList(const std::string & name, bool isC = false) const;
Scope *findRecordInNestedList(const std::string & name) {
return const_cast<Scope *>(const_cast<const Scope *>(this)->findRecordInNestedList(name));
}
Scope *findRecordInNestedList(const std::string & name, bool isC = false);

const Type* findType(const std::string& name) const;
Type* findType(const std::string& name) {
return const_cast<Type*>(const_cast<const Scope *>(this)->findType(name));
}
Type* findType(const std::string& name);

/**
* @brief find if name is in nested list
Expand Down
20 changes: 13 additions & 7 deletions lib/templatesimplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,8 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
return 0;
}

const Token *TemplateSimplifier::findTemplateDeclarationEnd(const Token *tok)
{
return const_cast<const Token *>(findTemplateDeclarationEnd(const_cast<Token *>(tok)));
}

Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *findTemplateDeclarationEndImpl(T *tok)
{
if (Token::simpleMatch(tok, "template <")) {
tok = tok->next()->findClosingBracket();
Expand All @@ -570,7 +566,7 @@ Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
if (!tok)
return nullptr;

Token * tok2 = tok;
T * tok2 = tok;
bool in_init = false;
while (tok2 && !Token::Match(tok2, ";|{")) {
if (tok2->str() == "<")
Expand Down Expand Up @@ -599,6 +595,16 @@ Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
return tok;
}

Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
{
return findTemplateDeclarationEndImpl(tok);
}

const Token *TemplateSimplifier::findTemplateDeclarationEnd(const Token *tok)
{
return findTemplateDeclarationEndImpl(tok);
}

void TemplateSimplifier::eraseTokens(Token *begin, const Token *end)
{
if (!begin || begin == end)
Expand Down
103 changes: 88 additions & 15 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,9 @@ void Token::replace(Token *replaceThis, Token *start, Token *end)
delete replaceThis;
}

const Token *Token::tokAt(int index) const
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *tokAtImpl(T *tok, int index)
{
const Token *tok = this;
while (index > 0 && tok) {
tok = tok->next();
--index;
Expand All @@ -416,15 +416,36 @@ const Token *Token::tokAt(int index) const
return tok;
}

const Token *Token::linkAt(int index) const
const Token *Token::tokAt(int index) const
{
const Token *tok = this->tokAt(index);
return tokAtImpl(this, index);
}

Token *Token::tokAt(int index)
{
return tokAtImpl(this, index);
}

template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *linkAtImpl(T *thisTok, int index)
{
T *tok = thisTok->tokAt(index);
if (!tok) {
throw InternalError(this, "Internal error. Token::linkAt called with index outside the tokens range.");
throw InternalError(thisTok, "Internal error. Token::linkAt called with index outside the tokens range.");
}
return tok->link();
}

const Token *Token::linkAt(int index) const
{
return linkAtImpl(this, index);
}

Token *Token::linkAt(int index)
{
return linkAtImpl(this, index);
}

const std::string &Token::strAt(int index) const
{
const Token *tok = this->tokAt(index);
Expand Down Expand Up @@ -857,9 +878,10 @@ void Token::move(Token *srcStart, Token *srcEnd, Token *newLocation)
tok->mImpl->mProgressValue = newLocation->mImpl->mProgressValue;
}

const Token* Token::nextArgument() const
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T* nextArgumentImpl(T *thisTok)
{
for (const Token* tok = this; tok; tok = tok->next()) {
for (T* tok = thisTok; tok; tok = tok->next()) {
if (tok->str() == ",")
return tok->next();
if (tok->link() && Token::Match(tok, "(|{|[|<"))
Expand All @@ -870,6 +892,16 @@ const Token* Token::nextArgument() const
return nullptr;
}

const Token* Token::nextArgument() const
{
return nextArgumentImpl(this);
}

Token *Token::nextArgument()
{
return nextArgumentImpl(this);
}

const Token* Token::nextArgumentBeforeCreateLinks2() const
{
for (const Token* tok = this; tok; tok = tok->next()) {
Expand Down Expand Up @@ -1007,42 +1039,83 @@ Token * Token::findOpeningBracket()

//---------------------------------------------------------------------------

const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len)
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *findsimplematchImpl(T * const startTok, const char pattern[], size_t pattern_len)
{
for (const Token* tok = startTok; tok; tok = tok->next()) {
for (T* tok = startTok; tok; tok = tok->next()) {
if (Token::simpleMatch(tok, pattern, pattern_len))
return tok;
}
return nullptr;
}

const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len)
{
return findsimplematchImpl(startTok, pattern, pattern_len);
}

Token *Token::findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len)
{
return findsimplematchImpl(startTok, pattern, pattern_len);
}

template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *findsimplematchImpl(T * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
{
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
for (T* tok = startTok; tok && tok != end; tok = tok->next()) {
if (Token::simpleMatch(tok, pattern, pattern_len))
return tok;
}
return nullptr;
}

const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varId)
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
{
return findsimplematchImpl(startTok, pattern, pattern_len, end);
}

Token *Token::findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end) {
return findsimplematchImpl(startTok, pattern, pattern_len, end);
}

template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *findmatchImpl(T * const startTok, const char pattern[], const nonneg int varId)
{
for (const Token* tok = startTok; tok; tok = tok->next()) {
for (T* tok = startTok; tok; tok = tok->next()) {
if (Token::Match(tok, pattern, varId))
return tok;
}
return nullptr;
}

const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varId)
{
return findmatchImpl(startTok, pattern, varId);
}

Token *Token::findmatch(Token * const startTok, const char pattern[], const nonneg int varId) {
return findmatchImpl(startTok, pattern, varId);
}

template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *findmatchImpl(T * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
{
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
for (T* tok = startTok; tok && tok != end; tok = tok->next()) {
if (Token::Match(tok, pattern, varId))
return tok;
}
return nullptr;
}

const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
{
return findmatchImpl(startTok, pattern, end, varId);
}

Token *Token::findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId) {
return findmatchImpl(startTok, pattern, end, varId);
}

void Token::function(const Function *f)
{
mImpl->mFunction = f;
Expand Down
28 changes: 7 additions & 21 deletions lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,14 @@ class CPPCHECKLIB Token {
* would return next from that one.
*/
const Token *tokAt(int index) const;
Token *tokAt(int index) {
return const_cast<Token *>(const_cast<const Token *>(this)->tokAt(index));
}
Token *tokAt(int index);

/**
* @return the link to the token in given index, related to this token.
* For example index 1 would return the link to next token.
*/
const Token *linkAt(int index) const;
Token *linkAt(int index) {
return const_cast<Token *>(const_cast<const Token *>(this)->linkAt(index));
}
Token *linkAt(int index);

/**
* @return String of the token in given index, related to this token.
Expand Down Expand Up @@ -780,23 +776,15 @@ class CPPCHECKLIB Token {
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[], size_t pattern_len) {
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len));
}
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t 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 *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const 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));
}
static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0) {
return const_cast<Token *>(findmatch(const_cast<const Token *>(startTok), pattern, end, varId));
}
static Token *findmatch(Token * const startTok, const char pattern[], const nonneg int varId = 0);
static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);

private:
/**
Expand Down Expand Up @@ -1173,9 +1161,7 @@ class CPPCHECKLIB Token {
* Returns 0, if there is no next argument.
*/
const Token* nextArgument() const;
Token *nextArgument() {
return const_cast<Token *>(const_cast<const Token *>(this)->nextArgument());
}
Token *nextArgument();

/**
* @return the first token of the next argument. Does only work on argument
Expand Down