avoid `const_cast` usage in headers (#5720)

This commit is contained in:
Oliver Stöneberg 2023-12-06 14:15:35 +01:00 committed by GitHub
parent 007b5cf8b8
commit 5761e55a67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 65 deletions

View File

@ -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;
}
@ -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)

View File

@ -1130,14 +1130,10 @@ public:
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

View File

@ -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();
@ -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)

View File

@ -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;
@ -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);
@ -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, "(|{|[|<"))
@ -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,9 +1039,30 @@ Token * Token::findOpeningBracket()
//---------------------------------------------------------------------------
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 (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)
{
for (const Token* tok = startTok; tok; tok = tok->next()) {
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 (T* tok = startTok; tok && tok != end; tok = tok->next()) {
if (Token::simpleMatch(tok, pattern, pattern_len))
return tok;
}
@ -1018,8 +1071,18 @@ const Token *Token::findsimplematch(const Token * const startTok, const char pat
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, pattern_len))
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 (T* tok = startTok; tok; tok = tok->next()) {
if (Token::Match(tok, pattern, varId))
return tok;
}
return nullptr;
@ -1027,7 +1090,17 @@ const Token *Token::findsimplematch(const Token * const startTok, const char pat
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varId)
{
for (const Token* tok = startTok; tok; tok = tok->next()) {
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 (T* tok = startTok; tok && tok != end; tok = tok->next()) {
if (Token::Match(tok, pattern, varId))
return tok;
}
@ -1036,11 +1109,11 @@ const Token *Token::findmatch(const Token * const startTok, const char pattern[]
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
{
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
if (Token::Match(tok, pattern, varId))
return tok;
}
return nullptr;
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)

View File

@ -212,18 +212,14 @@ public:
* 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.
@ -780,23 +776,15 @@ public:
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:
/**
@ -1170,9 +1158,7 @@ public:
* 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