| 2362 | } |
| 2363 | |
| 2364 | template<class T, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )> |
| 2365 | static T* getTokenArgumentFunctionImpl(T* tok, int& argn) |
| 2366 | { |
| 2367 | argn = -1; |
| 2368 | { |
| 2369 | T* parent = tok->astParent(); |
| 2370 | if (parent && (parent->isUnaryOp("&") || parent->isIncDecOp())) |
| 2371 | parent = parent->astParent(); |
| 2372 | while (parent && parent->isCast()) |
| 2373 | parent = parent->astParent(); |
| 2374 | if (Token::Match(parent, "[+-]") && parent->valueType() && parent->valueType()->pointer) |
| 2375 | parent = parent->astParent(); |
| 2376 | |
| 2377 | // passing variable to subfunction? |
| 2378 | if (Token::Match(parent, "[[(,{.]") || Token::Match(parent, "%oror%|&&") || (parent && parent->isUnaryOp("*"))) |
| 2379 | ; |
| 2380 | else if (Token::simpleMatch(parent, ":")) { |
| 2381 | while (Token::Match(parent, "[?:]")) |
| 2382 | parent = parent->astParent(); |
| 2383 | while (Token::simpleMatch(parent, ",")) |
| 2384 | parent = parent->astParent(); |
| 2385 | if (!parent || parent->str() != "(") |
| 2386 | return nullptr; |
| 2387 | } else |
| 2388 | return nullptr; |
| 2389 | } |
| 2390 | |
| 2391 | T* argtok = tok; |
| 2392 | while (argtok && argtok->astParent() && (!Token::Match(argtok->astParent(), ",|(|{") || argtok->astParent()->isCast())) { |
| 2393 | argtok = argtok->astParent(); |
| 2394 | } |
| 2395 | if (!argtok) |
| 2396 | return nullptr; |
| 2397 | if (Token::simpleMatch(argtok, ",")) |
| 2398 | argtok = argtok->astOperand1(); |
| 2399 | tok = argtok; |
| 2400 | while (Token::Match(tok->astParent(), ",|(|{")) { |
| 2401 | tok = tok->astParent(); |
| 2402 | if (Token::Match(tok, "(|{")) |
| 2403 | break; |
| 2404 | } |
| 2405 | argn = getArgumentPos(tok, argtok); |
| 2406 | if (argn == -1) |
| 2407 | return nullptr; |
| 2408 | if (!Token::Match(tok, "{|(")) |
| 2409 | return nullptr; |
| 2410 | if (tok->astOperand2()) |
| 2411 | tok = tok->astOperand1(); |
| 2412 | while (tok && (tok->isUnaryOp("*") || tok->str() == "[")) |
| 2413 | tok = tok->astOperand1(); |
| 2414 | if (Token::Match(tok, ". * %name%")) // bailout for pointer to member |
| 2415 | return tok->tokAt(2); |
| 2416 | while (Token::simpleMatch(tok, ".")) |
| 2417 | tok = tok->astOperand2(); |
| 2418 | while (Token::simpleMatch(tok, "::")) { |
| 2419 | // If there is only a op1 and not op2, then this is a global scope |
| 2420 | if (!tok->astOperand2() && tok->astOperand1()) { |
| 2421 | tok = tok->astOperand1(); |
no test coverage detected