Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -789,6 +806,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.");
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should remove this and just let the code crash.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it affect performance?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically it should because it can raise an exception (hence why noexcept is a thing).

In a short test:
Clang 17 1,194,021,239 -> 1,191,122,393

}
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