From 5761e55a673e70ceaf1b0eb02c28c4137e7eaa1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 6 Dec 2023 14:15:35 +0100 Subject: [PATCH] avoid `const_cast` usage in headers (#5720) --- lib/symboldatabase.cpp | 52 +++++++++++++------ lib/symboldatabase.h | 8 +-- lib/templatesimplifier.cpp | 20 ++++--- lib/token.cpp | 103 +++++++++++++++++++++++++++++++------ lib/token.h | 28 +++------- 5 files changed, 147 insertions(+), 64 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index a3278f3f191..e7523d75995 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6030,47 +6030,59 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const //--------------------------------------------------------------------------- -const Scope *Scope::findRecordInNestedList(const std::string & name, bool isC) const +template ), REQUIRES("T must be a Type class", std::is_convertible )> +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(nested_type->classScope); } return nullptr; } +const Scope* Scope::findRecordInNestedList(const std::string & name, bool isC) const +{ + return findRecordInNestedListImpl(*this, name, isC); +} + +Scope* Scope::findRecordInNestedList(const std::string & name, bool isC) +{ + return findRecordInNestedListImpl(*this, name, isC); +} + //--------------------------------------------------------------------------- -const Type* Scope::findType(const std::string & name) const +template ), REQUIRES("T must be a Type class", std::is_convertible )> +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; } @@ -6081,6 +6093,16 @@ const Type* Scope::findType(const std::string & name) const return nullptr; } +const Type* Scope::findType(const std::string& name) const +{ + return findTypeImpl(*this, name); +} + +Type* Scope::findType(const std::string& name) +{ + return findTypeImpl(*this, name); +} + //--------------------------------------------------------------------------- Scope *Scope::findInNestedListRecursive(const std::string & name) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 83b0fb33119..6f59ebc8a27 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -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(const_cast(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(const_cast(this)->findType(name)); - } + Type* findType(const std::string& name); /** * @brief find if name is in nested list diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index e156e4be792..86a10d5a7ee 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -554,12 +554,8 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) return 0; } -const Token *TemplateSimplifier::findTemplateDeclarationEnd(const Token *tok) -{ - return const_cast(findTemplateDeclarationEnd(const_cast(tok))); -} - -Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok) +template )> +static T *findTemplateDeclarationEndImpl(T *tok) { if (Token::simpleMatch(tok, "template <")) { tok = tok->next()->findClosingBracket(); @@ -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() == "<") @@ -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) diff --git a/lib/token.cpp b/lib/token.cpp index 6565b01e1d6..686b5a0e23c 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -402,9 +402,9 @@ void Token::replace(Token *replaceThis, Token *start, Token *end) delete replaceThis; } -const Token *Token::tokAt(int index) const +template )> +static T *tokAtImpl(T *tok, int index) { - const Token *tok = this; while (index > 0 && tok) { tok = tok->next(); --index; @@ -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 )> +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); @@ -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 )> +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, "(|{|[|<")) @@ -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()) { @@ -1007,42 +1039,83 @@ Token * Token::findOpeningBracket() //--------------------------------------------------------------------------- -const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len) +template )> +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 )> +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 )> +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 )> +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; diff --git a/lib/token.h b/lib/token.h index cf7b30cd5ad..91d8281be76 100644 --- a/lib/token.h +++ b/lib/token.h @@ -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(const_cast(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(const_cast(this)->linkAt(index)); - } + Token *linkAt(int index); /** * @return String of the token in given index, related to this token. @@ -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(findsimplematch(const_cast(startTok), pattern, pattern_len)); - } + static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len); template 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(findsimplematch(const_cast(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(findmatch(const_cast(startTok), pattern, varId)); - } - static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0) { - return const_cast(findmatch(const_cast(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: /** @@ -1170,9 +1158,7 @@ class CPPCHECKLIB Token { * Returns 0, if there is no next argument. */ const Token* nextArgument() const; - Token *nextArgument() { - return const_cast(const_cast(this)->nextArgument()); - } + Token *nextArgument(); /** * @return the first token of the next argument. Does only work on argument