| 7208 | } |
| 7209 | |
| 7210 | void Tokenizer::simplifyFunctionPointers() |
| 7211 | { |
| 7212 | for (Token *tok = list.front(); tok; tok = tok->next()) { |
| 7213 | // #2873 - do not simplify function pointer usage here: |
| 7214 | // (void)(xy(*p)(0)); |
| 7215 | if (Token::simpleMatch(tok, ") (")) { |
| 7216 | tok = tok->linkAt(1); |
| 7217 | continue; |
| 7218 | } |
| 7219 | |
| 7220 | // check for function pointer cast |
| 7221 | if (Token::Match(tok, "( %type% %type%| *| *| ( * ) (") || |
| 7222 | Token::Match(tok, "static_cast < %type% %type%| *| *| ( * ) (")) { |
| 7223 | Token *tok1 = tok; |
| 7224 | |
| 7225 | if (tok1->isCpp() && tok1->str() == "static_cast") |
| 7226 | tok1 = tok1->next(); |
| 7227 | |
| 7228 | tok1 = tok1->next(); |
| 7229 | |
| 7230 | if (Token::Match(tok1->next(), "%type%")) |
| 7231 | tok1 = tok1->next(); |
| 7232 | |
| 7233 | while (tok1->strAt(1) == "*") |
| 7234 | tok1 = tok1->next(); |
| 7235 | |
| 7236 | // check that the cast ends |
| 7237 | if (!Token::Match(tok1->linkAt(4), ") )|>")) |
| 7238 | continue; |
| 7239 | |
| 7240 | // ok simplify this function pointer cast to an ordinary pointer cast |
| 7241 | tok1->deleteNext(); |
| 7242 | tok1->next()->deleteNext(); |
| 7243 | Token::eraseTokens(tok1->next(), tok1->linkAt(2)->next()); |
| 7244 | continue; |
| 7245 | } |
| 7246 | |
| 7247 | // check for start of statement |
| 7248 | if (tok->previous() && !Token::Match(tok->previous(), "{|}|;|,|(|public:|protected:|private:")) |
| 7249 | continue; |
| 7250 | |
| 7251 | if (Token::Match(tok, "delete|else|return|throw|typedef")) |
| 7252 | continue; |
| 7253 | |
| 7254 | while (Token::Match(tok, "%type%|:: %type%|::")) |
| 7255 | tok = tok->next(); |
| 7256 | |
| 7257 | Token *tok2 = (tok && tok->isName()) ? tok->next() : nullptr; |
| 7258 | while (Token::Match(tok2, "*|&")) |
| 7259 | tok2 = tok2->next(); |
| 7260 | if (!tok2 || tok2->str() != "(") |
| 7261 | continue; |
| 7262 | while (Token::Match(tok2, "(|:: %type%")) |
| 7263 | tok2 = tok2->tokAt(2); |
| 7264 | if (!Token::Match(tok2, "(|:: * *| %name%")) |
| 7265 | continue; |
| 7266 | tok2 = tok2->tokAt(2); |
| 7267 | if (tok2->str() == "*") |
nothing calls this directly
no test coverage detected