| 1122 | } |
| 1123 | |
| 1124 | bool exprDependsOnThis(const Token* expr, bool onVar, nonneg int depth) |
| 1125 | { |
| 1126 | if (!expr) |
| 1127 | return false; |
| 1128 | if (expr->str() == "this") |
| 1129 | return true; |
| 1130 | if (depth >= 1000) |
| 1131 | // Abort recursion to avoid stack overflow |
| 1132 | return true; |
| 1133 | ++depth; |
| 1134 | |
| 1135 | // calling nonstatic method? |
| 1136 | if (Token::Match(expr, "%name% (")) { |
| 1137 | if (expr->function() && expr->function()->nestedIn && expr->function()->nestedIn->isClassOrStruct() && !expr->function()->isStatic()) { |
| 1138 | // is it a method of this? |
| 1139 | const Scope* fScope = expr->scope(); |
| 1140 | while (!fScope->functionOf && fScope->nestedIn) |
| 1141 | fScope = fScope->nestedIn; |
| 1142 | |
| 1143 | const Scope* classScope = fScope->functionOf; |
| 1144 | if (classScope && classScope->function) |
| 1145 | classScope = classScope->function->token->scope(); |
| 1146 | |
| 1147 | if (classScope && classScope->isClassOrStruct()) |
| 1148 | return contains(classScope->findAssociatedScopes(), expr->function()->nestedIn); |
| 1149 | return false; |
| 1150 | } |
| 1151 | if (expr->isOperatorKeyword() && !Token::simpleMatch(expr->next()->astParent(), ".")) |
| 1152 | return true; |
| 1153 | } |
| 1154 | if (onVar && expr->variable()) { |
| 1155 | const Variable* var = expr->variable(); |
| 1156 | return ((var->isPrivate() || var->isPublic() || var->isProtected()) && !var->isStatic()); |
| 1157 | } |
| 1158 | if (Token::simpleMatch(expr, ".")) |
| 1159 | return exprDependsOnThis(expr->astOperand1(), onVar, depth); |
| 1160 | return exprDependsOnThis(expr->astOperand1(), onVar, depth) || exprDependsOnThis(expr->astOperand2(), onVar, depth); |
| 1161 | } |
| 1162 | |
| 1163 | static bool hasUnknownVars(const Token* startTok) |
| 1164 | { |
no test coverage detected