| 1260 | } |
| 1261 | |
| 1262 | static SmallVector<ReferenceToken> followAllReferencesInternal(const Token* tok, |
| 1263 | bool temporary = true, |
| 1264 | bool inconclusive = true, |
| 1265 | ErrorPath errors = ErrorPath{}, |
| 1266 | int depth = 20) |
| 1267 | { |
| 1268 | struct ReferenceTokenLess { |
| 1269 | bool operator()(const ReferenceToken& x, const ReferenceToken& y) const { |
| 1270 | return x.token < y.token; |
| 1271 | } |
| 1272 | }; |
| 1273 | if (!tok) |
| 1274 | return {}; |
| 1275 | if (depth < 0) { |
| 1276 | SmallVector<ReferenceToken> refs_result; |
| 1277 | refs_result.emplace_back(tok, std::move(errors)); |
| 1278 | return refs_result; |
| 1279 | } |
| 1280 | const Variable *var = tok->variable(); |
| 1281 | if (var && var->declarationId() == tok->varId()) { |
| 1282 | if (var->nameToken() == tok || isStructuredBindingVariable(var)) { |
| 1283 | SmallVector<ReferenceToken> refs_result; |
| 1284 | refs_result.emplace_back(tok, std::move(errors)); |
| 1285 | return refs_result; |
| 1286 | } |
| 1287 | if (var->isReference() || var->isRValueReference()) { |
| 1288 | const Token * const varDeclEndToken = var->declEndToken(); |
| 1289 | if (!varDeclEndToken) { |
| 1290 | SmallVector<ReferenceToken> refs_result; |
| 1291 | refs_result.emplace_back(tok, std::move(errors)); |
| 1292 | return refs_result; |
| 1293 | } |
| 1294 | if (var->isArgument()) { |
| 1295 | errors.emplace_back(varDeclEndToken, "Passed to reference."); |
| 1296 | SmallVector<ReferenceToken> refs_result; |
| 1297 | refs_result.emplace_back(tok, std::move(errors)); |
| 1298 | return refs_result; |
| 1299 | } |
| 1300 | if (Token::simpleMatch(varDeclEndToken, "=")) { |
| 1301 | if (astHasToken(varDeclEndToken, tok)) |
| 1302 | return {}; |
| 1303 | errors.emplace_back(varDeclEndToken, "Assigned to reference."); |
| 1304 | const Token *vartok = varDeclEndToken->astOperand2(); |
| 1305 | if (vartok == tok || (!temporary && isTemporary(vartok, nullptr, true) && |
| 1306 | (var->isConst() || var->isRValueReference()))) { |
| 1307 | SmallVector<ReferenceToken> refs_result; |
| 1308 | refs_result.emplace_back(tok, std::move(errors)); |
| 1309 | return refs_result; |
| 1310 | } |
| 1311 | if (vartok) |
| 1312 | return followAllReferencesInternal(vartok, temporary, inconclusive, std::move(errors), depth - 1); |
| 1313 | } |
| 1314 | } |
| 1315 | } else if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) { |
| 1316 | std::set<ReferenceToken, ReferenceTokenLess> result; |
| 1317 | const Token* tok2 = tok->astOperand2(); |
| 1318 | |
| 1319 | auto refs = followAllReferencesInternal(tok2->astOperand1(), temporary, inconclusive, errors, depth - 1); |
no test coverage detected