Skip to content

Commit

Permalink
Token: allow the compiler to inline *At() calls (#6479)
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave authored Jun 2, 2024
1 parent dfa928f commit edf0104
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 55 deletions.
50 changes: 0 additions & 50 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,56 +376,6 @@ void Token::replace(Token *replaceThis, Token *start, Token *end)
delete replaceThis;
}

template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *tokAtImpl(T *tok, int index)
{
while (index > 0 && tok) {
tok = tok->next();
--index;
}
while (index < 0 && tok) {
tok = tok->previous();
++index;
}
return tok;
}

const Token *Token::tokAt(int index) const
{
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(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);
return tok ? tok->mStr : emptyString;
}

static
#if defined(__GNUC__)
// GCC does not inline this by itself
Expand Down
51 changes: 46 additions & 5 deletions lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
//---------------------------------------------------------------------------

#include "config.h"
#include "errortypes.h"
#include "mathlib.h"
#include "templatesimplifier.h"
#include "utils.h"
Expand Down Expand Up @@ -213,21 +214,37 @@ class CPPCHECKLIB Token {
* For example index 1 would return next token, and 2
* would return next from that one.
*/
const Token *tokAt(int index) const;
Token *tokAt(int index);
const Token *tokAt(int index) const
{
return tokAtImpl(this, index);
}
Token *tokAt(int index)
{
return tokAtImpl(this, 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);
const Token *linkAt(int index) const
{
return linkAtImpl(this, index);
}
Token *linkAt(int index)
{
return linkAtImpl(this, index);
}

/**
* @return String of the token in given index, related to this token.
* If that token does not exist, an empty string is being returned.
*/
const std::string &strAt(int index) const;
const std::string &strAt(int index) const
{
const Token *tok = this->tokAt(index);
return tok ? tok->mStr : emptyString;
}

/**
* Match given token (or list of tokens) to a pattern list.
Expand Down Expand Up @@ -784,6 +801,30 @@ class CPPCHECKLIB Token {
static Token *findmatch(Token * const startTok, const char pattern[], const Token * const end, const nonneg int varId = 0);

private:
template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )>
static T *tokAtImpl(T *tok, int index)
{
while (index > 0 && tok) {
tok = tok->next();
--index;
}
while (index < 0 && tok) {
tok = tok->previous();
++index;
}
return tok;
}

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(thisTok, "Internal error. Token::linkAt called with index outside the tokens range.");
}
return tok->link();
}

/**
* Needle is build from multiple alternatives. If one of
* them is equal to haystack, return value is 1. If there
Expand Down

0 comments on commit edf0104

Please sign in to comment.