Skip to content

Commit abc99be

Browse files
committed
avoid some redundant code in followAllReferences()
1 parent bc1ed42 commit abc99be

1 file changed

Lines changed: 83 additions & 103 deletions

File tree

lib/astutils.cpp

Lines changed: 83 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,121 +1212,101 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
12121212
};
12131213
if (!tok)
12141214
return {};
1215-
if (depth < 0) {
1216-
SmallVector<ReferenceToken> refs_result;
1217-
refs_result.emplace_back(ReferenceToken{tok, std::move(errors)});
1218-
return refs_result;
1219-
}
1220-
const Variable *var = tok->variable();
1221-
if (var && var->declarationId() == tok->varId()) {
1222-
if (var->nameToken() == tok || isStructuredBindingVariable(var)) {
1223-
SmallVector<ReferenceToken> refs_result;
1224-
refs_result.push_back({tok, std::move(errors)});
1225-
return refs_result;
1226-
}
1227-
if (var->isReference() || var->isRValueReference()) {
1228-
const Token * const varDeclEndToken = var->declEndToken();
1229-
if (!varDeclEndToken) {
1230-
SmallVector<ReferenceToken> refs_result;
1231-
refs_result.push_back({tok, std::move(errors)});
1232-
return refs_result;
1233-
}
1234-
if (var->isArgument()) {
1235-
errors.emplace_back(varDeclEndToken, "Passed to reference.");
1236-
SmallVector<ReferenceToken> refs_result;
1237-
refs_result.push_back({tok, std::move(errors)});
1238-
return refs_result;
1215+
do {
1216+
if (depth < 0) {
1217+
break;
1218+
}
1219+
const Variable *var = tok->variable();
1220+
if (var && var->declarationId() == tok->varId()) {
1221+
if (var->nameToken() == tok || isStructuredBindingVariable(var)) {
1222+
break;
12391223
}
1240-
if (Token::simpleMatch(varDeclEndToken, "=")) {
1241-
if (astHasToken(varDeclEndToken, tok))
1242-
return {};
1243-
errors.emplace_back(varDeclEndToken, "Assigned to reference.");
1244-
const Token *vartok = varDeclEndToken->astOperand2();
1245-
if (vartok == tok || (!temporary && isTemporary(true, vartok, nullptr, true) &&
1246-
(var->isConst() || var->isRValueReference()))) {
1247-
SmallVector<ReferenceToken> refs_result;
1248-
refs_result.push_back({tok, std::move(errors)});
1249-
return refs_result;
1224+
if (var->isReference() || var->isRValueReference()) {
1225+
const Token * const varDeclEndToken = var->declEndToken();
1226+
if (!varDeclEndToken) {
1227+
break;
1228+
}
1229+
if (var->isArgument()) {
1230+
errors.emplace_back(varDeclEndToken, "Passed to reference.");
1231+
break;
1232+
}
1233+
if (Token::simpleMatch(varDeclEndToken, "=")) {
1234+
if (astHasToken(varDeclEndToken, tok))
1235+
return {};
1236+
errors.emplace_back(varDeclEndToken, "Assigned to reference.");
1237+
const Token *vartok = varDeclEndToken->astOperand2();
1238+
if (vartok == tok || (!temporary && isTemporary(true, vartok, nullptr, true) &&
1239+
(var->isConst() || var->isRValueReference()))) {
1240+
break;
1241+
}
1242+
if (vartok)
1243+
return followAllReferences(vartok, temporary, inconclusive, std::move(errors), depth - 1);
12501244
}
1251-
if (vartok)
1252-
return followAllReferences(vartok, temporary, inconclusive, std::move(errors), depth - 1);
12531245
}
1254-
}
1255-
} else if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) {
1256-
std::set<ReferenceToken, ReferenceTokenLess> result;
1257-
const Token* tok2 = tok->astOperand2();
1246+
} else if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) {
1247+
std::set<ReferenceToken, ReferenceTokenLess> result;
1248+
const Token* tok2 = tok->astOperand2();
12581249

1259-
auto refs = followAllReferences(tok2->astOperand1(), temporary, inconclusive, errors, depth - 1);
1260-
result.insert(refs.cbegin(), refs.cend());
1261-
refs = followAllReferences(tok2->astOperand2(), temporary, inconclusive, errors, depth - 1);
1262-
result.insert(refs.cbegin(), refs.cend());
1250+
auto refs = followAllReferences(tok2->astOperand1(), temporary, inconclusive, errors, depth - 1);
1251+
result.insert(refs.cbegin(), refs.cend());
1252+
refs = followAllReferences(tok2->astOperand2(), temporary, inconclusive, errors, depth - 1);
1253+
result.insert(refs.cbegin(), refs.cend());
12631254

1264-
if (!inconclusive && result.size() != 1) {
1265-
SmallVector<ReferenceToken> refs_result;
1266-
refs_result.push_back({tok, std::move(errors)});
1267-
return refs_result;
1268-
}
1255+
if (!inconclusive && result.size() != 1) {
1256+
break;
1257+
}
12691258

1270-
if (!result.empty()) {
1271-
SmallVector<ReferenceToken> refs_result;
1272-
refs_result.insert(refs_result.end(), result.cbegin(), result.cend());
1273-
return refs_result;
1274-
}
1259+
if (!result.empty()) {
1260+
SmallVector<ReferenceToken> refs_result;
1261+
refs_result.insert(refs_result.end(), result.cbegin(), result.cend());
1262+
return refs_result;
1263+
}
12751264

1276-
} else if (tok->previous() && tok->previous()->function() && Token::Match(tok->previous(), "%name% (")) {
1277-
const Function *f = tok->previous()->function();
1278-
if (!Function::returnsReference(f)) {
1279-
SmallVector<ReferenceToken> refs_result;
1280-
refs_result.push_back({tok, std::move(errors)});
1281-
return refs_result;
1282-
}
1283-
std::set<ReferenceToken, ReferenceTokenLess> result;
1284-
std::vector<const Token*> returns = Function::findReturns(f);
1285-
for (const Token* returnTok : returns) {
1286-
if (returnTok == tok)
1287-
continue;
1288-
for (const ReferenceToken& rt :
1289-
followAllReferences(returnTok, temporary, inconclusive, errors, depth - returns.size())) {
1290-
const Variable* argvar = rt.token->variable();
1291-
if (!argvar) {
1292-
SmallVector<ReferenceToken> refs_result;
1293-
refs_result.push_back({tok, std::move(errors)});
1294-
return refs_result;
1295-
}
1296-
if (argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) {
1297-
const int n = getArgumentPos(argvar, f);
1298-
if (n < 0) {
1299-
SmallVector<ReferenceToken> refs_result;
1300-
refs_result.push_back({tok, std::move(errors)});
1301-
return refs_result;
1302-
}
1303-
std::vector<const Token*> args = getArguments(tok->previous());
1304-
if (n >= args.size()) {
1305-
SmallVector<ReferenceToken> refs_result;
1306-
refs_result.push_back({tok, std::move(errors)});
1307-
return refs_result;
1265+
} else if (tok->previous() && tok->previous()->function() && Token::Match(tok->previous(), "%name% (")) {
1266+
const Function *f = tok->previous()->function();
1267+
if (!Function::returnsReference(f)) {
1268+
break;
1269+
}
1270+
std::set<ReferenceToken, ReferenceTokenLess> result;
1271+
std::vector<const Token*> returns = Function::findReturns(f);
1272+
for (const Token* returnTok : returns) {
1273+
if (returnTok == tok)
1274+
continue;
1275+
for (const ReferenceToken& rt :
1276+
followAllReferences(returnTok, temporary, inconclusive, errors, depth - returns.size())) {
1277+
const Variable* argvar = rt.token->variable();
1278+
if (!argvar) {
1279+
break;
13081280
}
1309-
const Token* argTok = args[n];
1310-
ErrorPath er = errors;
1311-
er.emplace_back(returnTok, "Return reference.");
1312-
er.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
1313-
auto refs =
1314-
followAllReferences(argTok, temporary, inconclusive, std::move(er), depth - returns.size());
1315-
result.insert(refs.cbegin(), refs.cend());
1316-
if (!inconclusive && result.size() > 1) {
1317-
SmallVector<ReferenceToken> refs_result;
1318-
refs_result.push_back({tok, std::move(errors)});
1319-
return refs_result;
1281+
if (argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) {
1282+
const int n = getArgumentPos(argvar, f);
1283+
if (n < 0) {
1284+
break;
1285+
}
1286+
std::vector<const Token*> args = getArguments(tok->previous());
1287+
if (n >= args.size()) {
1288+
break;
1289+
}
1290+
const Token* argTok = args[n];
1291+
ErrorPath er = errors;
1292+
er.emplace_back(returnTok, "Return reference.");
1293+
er.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
1294+
auto refs =
1295+
followAllReferences(argTok, temporary, inconclusive, std::move(er), depth - returns.size());
1296+
if (!inconclusive && refs.size() > 1) {
1297+
break;
1298+
}
1299+
result.insert(refs.cbegin(), refs.cend());
13201300
}
13211301
}
13221302
}
1303+
if (!result.empty()) {
1304+
SmallVector<ReferenceToken> refs_result;
1305+
refs_result.insert(refs_result.end(), result.cbegin(), result.cend());
1306+
return refs_result;
1307+
}
13231308
}
1324-
if (!result.empty()) {
1325-
SmallVector<ReferenceToken> refs_result;
1326-
refs_result.insert(refs_result.end(), result.cbegin(), result.cend());
1327-
return refs_result;
1328-
}
1329-
}
1309+
} while(false);
13301310
SmallVector<ReferenceToken> refs_result;
13311311
refs_result.push_back({tok, std::move(errors)});
13321312
return refs_result;

0 commit comments

Comments
 (0)