Skip to content

Commit

Permalink
avoid const_cast usage in headers (#5720)
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave committed Dec 6, 2023
1 parent 007b5cf commit 5761e55
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 64 deletions.
52 changes: 37 additions & 15 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<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 @@ -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<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 @@ -1170,9 +1158,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

0 comments on commit 5761e55

Please sign in to comment.