| 3169 | } |
| 3170 | |
| 3171 | static std::vector<DuplMemberFuncInfo> getDuplInheritedMemberFunctionsRecursive(const Type* typeCurrent, const Type* typeBase, bool skipPrivate = true) |
| 3172 | { |
| 3173 | std::vector<DuplMemberFuncInfo> results; |
| 3174 | for (const Type::BaseInfo &parentClassIt : typeBase->derivedFrom) { |
| 3175 | // Check if there is info about the 'Base' class |
| 3176 | if (!parentClassIt.type || !parentClassIt.type->classScope) |
| 3177 | continue; |
| 3178 | // Don't crash on recursive templates |
| 3179 | if (parentClassIt.type == typeBase) |
| 3180 | continue; |
| 3181 | for (const Function& classFuncIt : typeCurrent->classScope->functionList) { |
| 3182 | if (classFuncIt.isImplicitlyVirtual()) |
| 3183 | continue; |
| 3184 | if (classFuncIt.tokenDef->isExpandedMacro()) |
| 3185 | continue; |
| 3186 | if (classFuncIt.templateDef) |
| 3187 | continue; |
| 3188 | for (const Function& parentClassFuncIt : parentClassIt.type->classScope->functionList) { |
| 3189 | if (classFuncIt.name() == parentClassFuncIt.name() && |
| 3190 | (parentClassFuncIt.access != AccessControl::Private || !skipPrivate) && |
| 3191 | !classFuncIt.isConstructor() && !classFuncIt.isDestructor() && |
| 3192 | classFuncIt.argsMatch(parentClassIt.type->classScope, parentClassFuncIt.argDef, classFuncIt.argDef, "", 0) && |
| 3193 | (classFuncIt.isConst() == parentClassFuncIt.isConst() || Function::returnsConst(&classFuncIt) == Function::returnsConst(&parentClassFuncIt)) && |
| 3194 | !(classFuncIt.isDelete() || parentClassFuncIt.isDelete())) |
| 3195 | results.emplace_back(&classFuncIt, &parentClassFuncIt, &parentClassIt); |
| 3196 | } |
| 3197 | } |
| 3198 | if (typeCurrent != parentClassIt.type) { |
| 3199 | const auto recursive = getDuplInheritedMemberFunctionsRecursive(typeCurrent, parentClassIt.type); |
| 3200 | results.insert(results.end(), recursive.begin(), recursive.end()); |
| 3201 | } |
| 3202 | } |
| 3203 | return results; |
| 3204 | } |
| 3205 | |
| 3206 | void CheckClassImpl::checkDuplInheritedMembersRecursive(const Type* typeCurrent, const Type* typeBase) |
| 3207 | { |