* @throws Token* thrown when closing brackets are missing */
| 4340 | * @throws Token* thrown when closing brackets are missing |
| 4341 | */ |
| 4342 | static bool setVarIdParseDeclaration(Token*& tok, const VariableMap& variableMap, bool executableScope, Standards::cstd_t cStandard) |
| 4343 | { |
| 4344 | const Token* const tok1 = tok; |
| 4345 | Token* tok2 = tok; |
| 4346 | if (!tok2->isName() || (tok2->tokType() != Token::eType && tok2->tokType() != Token::eName && tok2->tokType() != Token::eKeyword)) |
| 4347 | return false; |
| 4348 | |
| 4349 | nonneg int typeCount = 0; |
| 4350 | nonneg int singleNameCount = 0; |
| 4351 | bool hasstruct = false; // Is there a "struct" or "class"? |
| 4352 | bool bracket = false; |
| 4353 | bool ref = false; |
| 4354 | while (tok2) { |
| 4355 | if (tok2->isName()) { |
| 4356 | if (Token::simpleMatch(tok2, "alignas (")) { |
| 4357 | tok2 = tok2->linkAt(1)->next(); |
| 4358 | continue; |
| 4359 | } |
| 4360 | if (tok2->isCpp() && Token::Match(tok2, "namespace|public|private|protected")) |
| 4361 | return false; |
| 4362 | bool isC23 = tok2->isC() && cStandard >= Standards::C23; |
| 4363 | if (((tok2->isCpp() || isC23) && Token::Match(tok2, "decltype|typeof (")) || |
| 4364 | (tok2->isC() && Token::simpleMatch(tok2, "__typeof ("))) { |
| 4365 | typeCount = 1; |
| 4366 | tok2 = tok2->linkAt(1)->next(); |
| 4367 | continue; |
| 4368 | } |
| 4369 | if (Token::Match(tok2, "struct|union|enum") || (tok2->isCpp() && Token::Match(tok2, "class|typename"))) { |
| 4370 | hasstruct = true; |
| 4371 | typeCount = 0; |
| 4372 | singleNameCount = 0; |
| 4373 | } else if (Token::Match(tok2, "const|extern")) { |
| 4374 | // just skip "const", "extern" |
| 4375 | } else if (!hasstruct && variableMap.map(false).count(tok2->str()) && tok2->strAt(-1) != "::") { |
| 4376 | ++typeCount; |
| 4377 | tok2 = tok2->next(); |
| 4378 | if (!tok2 || tok2->str() != "::") |
| 4379 | break; |
| 4380 | } else { |
| 4381 | if (tok2->str() != "void" || Token::Match(tok2, "void const| *|(")) // just "void" cannot be a variable type |
| 4382 | ++typeCount; |
| 4383 | ++singleNameCount; |
| 4384 | } |
| 4385 | } else if (tok2->isCpp() && ((TemplateSimplifier::templateParameters(tok2) > 0) || |
| 4386 | Token::simpleMatch(tok2, "< >") /* Ticket #4764 */)) { |
| 4387 | const Token *start = tok; |
| 4388 | if (Token::Match(start->previous(), "%or%|%oror%|&&|&|^|+|-|*|/")) |
| 4389 | return false; |
| 4390 | Token* const closingBracket = tok2->findClosingBracket(); |
| 4391 | if (closingBracket == nullptr) { /* Ticket #8151 */ |
| 4392 | throw tok2; |
| 4393 | } |
| 4394 | tok2 = closingBracket; |
| 4395 | if (tok2->str() != ">") |
| 4396 | break; |
| 4397 | singleNameCount = 1; |
| 4398 | if (Token::Match(tok2, "> %name% %or%|%oror%|&&|&|^|+|-|*|/") && !Token::Match(tok2, "> const [*&]")) |
| 4399 | return false; |
no test coverage detected