| 4887 | } |
| 4888 | |
| 4889 | const Function * Function::getOverriddenFunctionRecursive(const ::Type* baseType, bool *foundAllBaseClasses) const |
| 4890 | { |
| 4891 | // check each base class |
| 4892 | for (const ::Type::BaseInfo & i : baseType->derivedFrom) { |
| 4893 | const ::Type* derivedFromType = i.type; |
| 4894 | // check if base class exists in database |
| 4895 | if (!derivedFromType || !derivedFromType->classScope) { |
| 4896 | if (foundAllBaseClasses) |
| 4897 | *foundAllBaseClasses = false; |
| 4898 | continue; |
| 4899 | } |
| 4900 | |
| 4901 | const Scope *parent = derivedFromType->classScope; |
| 4902 | |
| 4903 | // check if function defined in base class |
| 4904 | auto range = parent->functionMap.equal_range(tokenDef->str()); |
| 4905 | for (auto it = range.first; it != range.second; ++it) { |
| 4906 | const Function * func = it->second; |
| 4907 | if (func->isImplicitlyVirtual()) { // Base is virtual and of same name |
| 4908 | const Token *temp1 = func->tokenDef->previous(); |
| 4909 | const Token *temp2 = tokenDef->previous(); |
| 4910 | bool match = true; |
| 4911 | |
| 4912 | // check for matching return parameters |
| 4913 | while (!Token::Match(temp1, "virtual|public:|private:|protected:|{|}|;")) { |
| 4914 | if (temp1->str() != temp2->str() && |
| 4915 | !(temp1->type() && temp2->type() && temp2->type()->isDerivedFrom(temp1->type()->name()))) { |
| 4916 | match = false; |
| 4917 | break; |
| 4918 | } |
| 4919 | |
| 4920 | temp1 = temp1->previous(); |
| 4921 | temp2 = temp2->previous(); |
| 4922 | } |
| 4923 | |
| 4924 | // check for matching function parameters |
| 4925 | match = match && argsMatch(baseType->classScope, func->argDef, argDef, "", 0); |
| 4926 | |
| 4927 | // check for matching cv-ref qualifiers |
| 4928 | match = match |
| 4929 | && isConst() == func->isConst() |
| 4930 | && isVolatile() == func->isVolatile() |
| 4931 | && hasRvalRefQualifier() == func->hasRvalRefQualifier() |
| 4932 | && hasLvalRefQualifier() == func->hasLvalRefQualifier(); |
| 4933 | |
| 4934 | // it's a match |
| 4935 | if (match) { |
| 4936 | return func; |
| 4937 | } |
| 4938 | } |
| 4939 | } |
| 4940 | |
| 4941 | if (isDestructor()) { |
| 4942 | auto it = std::find_if(parent->functionList.begin(), parent->functionList.end(), [](const Function& f) { |
| 4943 | return f.isDestructor() && f.isImplicitlyVirtual(); |
| 4944 | }); |
| 4945 | if (it != parent->functionList.end()) |
| 4946 | return &*it; |
nothing calls this directly
no test coverage detected