Skip to content

Commit 5761e55

Browse files
authored
avoid const_cast usage in headers (#5720)
1 parent 007b5cf commit 5761e55

5 files changed

Lines changed: 147 additions & 64 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6030,47 +6030,59 @@ const Scope *SymbolDatabase::findScopeByName(const std::string& name) const
60306030

60316031
//---------------------------------------------------------------------------
60326032

6033-
const Scope *Scope::findRecordInNestedList(const std::string & name, bool isC) const
6033+
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*> )>
6034+
S* findRecordInNestedListImpl(S& thisScope, const std::string & name, bool isC)
60346035
{
6035-
for (const Scope* scope: nestedList) {
6036-
if (scope->className == name && scope->type != eFunction)
6036+
for (S* scope: thisScope.nestedList) {
6037+
if (scope->className == name && scope->type != Scope::eFunction)
60376038
return scope;
60386039
if (isC) {
6039-
const Scope* nestedScope = scope->findRecordInNestedList(name, isC);
6040+
S* nestedScope = scope->findRecordInNestedList(name, isC);
60406041
if (nestedScope)
60416042
return nestedScope;
60426043
}
60436044
}
60446045

6045-
const Type * nested_type = findType(name);
6046+
T * nested_type = thisScope.findType(name);
60466047

60476048
if (nested_type) {
60486049
if (nested_type->isTypeAlias()) {
60496050
if (nested_type->typeStart == nested_type->typeEnd)
6050-
return findRecordInNestedList(nested_type->typeStart->str());
6051+
return thisScope.findRecordInNestedList(nested_type->typeStart->str()); // TODO: pass isC?
60516052
} else
6052-
return nested_type->classScope;
6053+
return const_cast<S*>(nested_type->classScope);
60536054
}
60546055

60556056
return nullptr;
60566057
}
60576058

6059+
const Scope* Scope::findRecordInNestedList(const std::string & name, bool isC) const
6060+
{
6061+
return findRecordInNestedListImpl<const Scope, const Type>(*this, name, isC);
6062+
}
6063+
6064+
Scope* Scope::findRecordInNestedList(const std::string & name, bool isC)
6065+
{
6066+
return findRecordInNestedListImpl<Scope, Type>(*this, name, isC);
6067+
}
6068+
60586069
//---------------------------------------------------------------------------
60596070

6060-
const Type* Scope::findType(const std::string & name) const
6071+
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*> )>
6072+
T* findTypeImpl(S& thisScope, const std::string & name)
60616073
{
6062-
auto it = definedTypesMap.find(name);
6074+
auto it = thisScope.definedTypesMap.find(name);
60636075

60646076
// Type was found
6065-
if (definedTypesMap.end() != it)
6077+
if (thisScope.definedTypesMap.end() != it)
60666078
return it->second;
60676079

60686080
// is type defined in anonymous namespace..
6069-
it = definedTypesMap.find(emptyString);
6070-
if (it != definedTypesMap.end()) {
6071-
for (const Scope *scope : nestedList) {
6072-
if (scope->className.empty() && (scope->type == eNamespace || scope->isClassOrStructOrUnion())) {
6073-
const Type *t = scope->findType(name);
6081+
it = thisScope.definedTypesMap.find(emptyString);
6082+
if (it != thisScope.definedTypesMap.end()) {
6083+
for (S *scope : thisScope.nestedList) {
6084+
if (scope->className.empty() && (scope->type == thisScope.eNamespace || scope->isClassOrStructOrUnion())) {
6085+
T *t = scope->findType(name);
60746086
if (t)
60756087
return t;
60766088
}
@@ -6081,6 +6093,16 @@ const Type* Scope::findType(const std::string & name) const
60816093
return nullptr;
60826094
}
60836095

6096+
const Type* Scope::findType(const std::string& name) const
6097+
{
6098+
return findTypeImpl<const Scope, const Type>(*this, name);
6099+
}
6100+
6101+
Type* Scope::findType(const std::string& name)
6102+
{
6103+
return findTypeImpl<Scope, Type>(*this, name);
6104+
}
6105+
60846106
//---------------------------------------------------------------------------
60856107

60866108
Scope *Scope::findInNestedListRecursive(const std::string & name)

lib/symboldatabase.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,14 +1130,10 @@ class CPPCHECKLIB Scope {
11301130
const Function *findFunction(const Token *tok, bool requireConst=false) const;
11311131

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

11371135
const Type* findType(const std::string& name) const;
1138-
Type* findType(const std::string& name) {
1139-
return const_cast<Type*>(const_cast<const Scope *>(this)->findType(name));
1140-
}
1136+
Type* findType(const std::string& name);
11411137

11421138
/**
11431139
* @brief find if name is in nested list

lib/templatesimplifier.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,8 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
554554
return 0;
555555
}
556556

557-
const Token *TemplateSimplifier::findTemplateDeclarationEnd(const Token *tok)
558-
{
559-
return const_cast<const Token *>(findTemplateDeclarationEnd(const_cast<Token *>(tok)));
560-
}
561-
562-
Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
557+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
558+
static T *findTemplateDeclarationEndImpl(T *tok)
563559
{
564560
if (Token::simpleMatch(tok, "template <")) {
565561
tok = tok->next()->findClosingBracket();
@@ -570,7 +566,7 @@ Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
570566
if (!tok)
571567
return nullptr;
572568

573-
Token * tok2 = tok;
569+
T * tok2 = tok;
574570
bool in_init = false;
575571
while (tok2 && !Token::Match(tok2, ";|{")) {
576572
if (tok2->str() == "<")
@@ -599,6 +595,16 @@ Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
599595
return tok;
600596
}
601597

598+
Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
599+
{
600+
return findTemplateDeclarationEndImpl(tok);
601+
}
602+
603+
const Token *TemplateSimplifier::findTemplateDeclarationEnd(const Token *tok)
604+
{
605+
return findTemplateDeclarationEndImpl(tok);
606+
}
607+
602608
void TemplateSimplifier::eraseTokens(Token *begin, const Token *end)
603609
{
604610
if (!begin || begin == end)

lib/token.cpp

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,9 @@ void Token::replace(Token *replaceThis, Token *start, Token *end)
402402
delete replaceThis;
403403
}
404404

405-
const Token *Token::tokAt(int index) const
405+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
406+
static T *tokAtImpl(T *tok, int index)
406407
{
407-
const Token *tok = this;
408408
while (index > 0 && tok) {
409409
tok = tok->next();
410410
--index;
@@ -416,15 +416,36 @@ const Token *Token::tokAt(int index) const
416416
return tok;
417417
}
418418

419-
const Token *Token::linkAt(int index) const
419+
const Token *Token::tokAt(int index) const
420420
{
421-
const Token *tok = this->tokAt(index);
421+
return tokAtImpl(this, index);
422+
}
423+
424+
Token *Token::tokAt(int index)
425+
{
426+
return tokAtImpl(this, index);
427+
}
428+
429+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
430+
static T *linkAtImpl(T *thisTok, int index)
431+
{
432+
T *tok = thisTok->tokAt(index);
422433
if (!tok) {
423-
throw InternalError(this, "Internal error. Token::linkAt called with index outside the tokens range.");
434+
throw InternalError(thisTok, "Internal error. Token::linkAt called with index outside the tokens range.");
424435
}
425436
return tok->link();
426437
}
427438

439+
const Token *Token::linkAt(int index) const
440+
{
441+
return linkAtImpl(this, index);
442+
}
443+
444+
Token *Token::linkAt(int index)
445+
{
446+
return linkAtImpl(this, index);
447+
}
448+
428449
const std::string &Token::strAt(int index) const
429450
{
430451
const Token *tok = this->tokAt(index);
@@ -857,9 +878,10 @@ void Token::move(Token *srcStart, Token *srcEnd, Token *newLocation)
857878
tok->mImpl->mProgressValue = newLocation->mImpl->mProgressValue;
858879
}
859880

860-
const Token* Token::nextArgument() const
881+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
882+
static T* nextArgumentImpl(T *thisTok)
861883
{
862-
for (const Token* tok = this; tok; tok = tok->next()) {
884+
for (T* tok = thisTok; tok; tok = tok->next()) {
863885
if (tok->str() == ",")
864886
return tok->next();
865887
if (tok->link() && Token::Match(tok, "(|{|[|<"))
@@ -870,6 +892,16 @@ const Token* Token::nextArgument() const
870892
return nullptr;
871893
}
872894

895+
const Token* Token::nextArgument() const
896+
{
897+
return nextArgumentImpl(this);
898+
}
899+
900+
Token *Token::nextArgument()
901+
{
902+
return nextArgumentImpl(this);
903+
}
904+
873905
const Token* Token::nextArgumentBeforeCreateLinks2() const
874906
{
875907
for (const Token* tok = this; tok; tok = tok->next()) {
@@ -1007,42 +1039,83 @@ Token * Token::findOpeningBracket()
10071039

10081040
//---------------------------------------------------------------------------
10091041

1010-
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len)
1042+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
1043+
static T *findsimplematchImpl(T * const startTok, const char pattern[], size_t pattern_len)
10111044
{
1012-
for (const Token* tok = startTok; tok; tok = tok->next()) {
1045+
for (T* tok = startTok; tok; tok = tok->next()) {
10131046
if (Token::simpleMatch(tok, pattern, pattern_len))
10141047
return tok;
10151048
}
10161049
return nullptr;
10171050
}
10181051

1019-
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
1052+
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len)
1053+
{
1054+
return findsimplematchImpl(startTok, pattern, pattern_len);
1055+
}
1056+
1057+
Token *Token::findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len)
1058+
{
1059+
return findsimplematchImpl(startTok, pattern, pattern_len);
1060+
}
1061+
1062+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
1063+
static T *findsimplematchImpl(T * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
10201064
{
1021-
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
1065+
for (T* tok = startTok; tok && tok != end; tok = tok->next()) {
10221066
if (Token::simpleMatch(tok, pattern, pattern_len))
10231067
return tok;
10241068
}
10251069
return nullptr;
10261070
}
10271071

1028-
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varId)
1072+
const Token *Token::findsimplematch(const Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end)
1073+
{
1074+
return findsimplematchImpl(startTok, pattern, pattern_len, end);
1075+
}
1076+
1077+
Token *Token::findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end) {
1078+
return findsimplematchImpl(startTok, pattern, pattern_len, end);
1079+
}
1080+
1081+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
1082+
static T *findmatchImpl(T * const startTok, const char pattern[], const nonneg int varId)
10291083
{
1030-
for (const Token* tok = startTok; tok; tok = tok->next()) {
1084+
for (T* tok = startTok; tok; tok = tok->next()) {
10311085
if (Token::Match(tok, pattern, varId))
10321086
return tok;
10331087
}
10341088
return nullptr;
10351089
}
10361090

1037-
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
1091+
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const nonneg int varId)
1092+
{
1093+
return findmatchImpl(startTok, pattern, varId);
1094+
}
1095+
1096+
Token *Token::findmatch(Token * const startTok, const char pattern[], const nonneg int varId) {
1097+
return findmatchImpl(startTok, pattern, varId);
1098+
}
1099+
1100+
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
1101+
static T *findmatchImpl(T * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
10381102
{
1039-
for (const Token* tok = startTok; tok && tok != end; tok = tok->next()) {
1103+
for (T* tok = startTok; tok && tok != end; tok = tok->next()) {
10401104
if (Token::Match(tok, pattern, varId))
10411105
return tok;
10421106
}
10431107
return nullptr;
10441108
}
10451109

1110+
const Token *Token::findmatch(const Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId)
1111+
{
1112+
return findmatchImpl(startTok, pattern, end, varId);
1113+
}
1114+
1115+
Token *Token::findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId) {
1116+
return findmatchImpl(startTok, pattern, end, varId);
1117+
}
1118+
10461119
void Token::function(const Function *f)
10471120
{
10481121
mImpl->mFunction = f;

lib/token.h

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,14 @@ class CPPCHECKLIB Token {
212212
* would return next from that one.
213213
*/
214214
const Token *tokAt(int index) const;
215-
Token *tokAt(int index) {
216-
return const_cast<Token *>(const_cast<const Token *>(this)->tokAt(index));
217-
}
215+
Token *tokAt(int index);
218216

219217
/**
220218
* @return the link to the token in given index, related to this token.
221219
* For example index 1 would return the link to next token.
222220
*/
223221
const Token *linkAt(int index) const;
224-
Token *linkAt(int index) {
225-
return const_cast<Token *>(const_cast<const Token *>(this)->linkAt(index));
226-
}
222+
Token *linkAt(int index);
227223

228224
/**
229225
* @return String of the token in given index, related to this token.
@@ -780,23 +776,15 @@ class CPPCHECKLIB Token {
780776
static Token *findsimplematch(Token * const startTok, const char (&pattern)[count]) {
781777
return findsimplematch(startTok, pattern, count-1);
782778
}
783-
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len) {
784-
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len));
785-
}
779+
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len);
786780
template<size_t count>
787781
static Token *findsimplematch(Token * const startTok, const char (&pattern)[count], const Token * const end) {
788782
return findsimplematch(startTok, pattern, count-1, end);
789783
}
790-
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end) {
791-
return const_cast<Token *>(findsimplematch(const_cast<const Token *>(startTok), pattern, pattern_len, end));
792-
}
784+
static Token *findsimplematch(Token * const startTok, const char pattern[], size_t pattern_len, const Token * const end);
793785

794-
static Token *findmatch(Token * const startTok, const char pattern[], const nonneg int varId = 0) {
795-
return const_cast<Token *>(findmatch(const_cast<const Token *>(startTok), pattern, varId));
796-
}
797-
static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0) {
798-
return const_cast<Token *>(findmatch(const_cast<const Token *>(startTok), pattern, end, varId));
799-
}
786+
static Token *findmatch(Token * const startTok, const char pattern[], const nonneg int varId = 0);
787+
static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);
800788

801789
private:
802790
/**
@@ -1170,9 +1158,7 @@ class CPPCHECKLIB Token {
11701158
* Returns 0, if there is no next argument.
11711159
*/
11721160
const Token* nextArgument() const;
1173-
Token *nextArgument() {
1174-
return const_cast<Token *>(const_cast<const Token *>(this)->nextArgument());
1175-
}
1161+
Token *nextArgument();
11761162

11771163
/**
11781164
* @return the first token of the next argument. Does only work on argument

0 commit comments

Comments
 (0)