void ParentVirtualCallCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *Member = Result.Nodes.getNodeAs<MemberExpr>("member");
  assert(Member);

  if (!Member->getQualifier())
    return;

  const auto *MemberDecl = cast<CXXMethodDecl>(Member->getMemberDecl());

  const auto *ThisTypePtr = Result.Nodes.getNodeAs<PointerType>("thisType");
  assert(ThisTypePtr);

  const auto *ThisType = ThisTypePtr->getPointeeCXXRecordDecl();
  assert(ThisType);

  const auto *CastToTypePtr = Result.Nodes.getNodeAs<Type>("castToType");
  assert(CastToTypePtr);

  const auto *CastToType = CastToTypePtr->getAsCXXRecordDecl();
  assert(CastToType);

  if (isParentOf(*CastToType, *ThisType))
    return;

  const BasesVector Parents =
      getParentsByGrandParent(*CastToType, *ThisType, *MemberDecl);

  if (Parents.empty())
    return;

  std::string ParentsStr;
  ParentsStr.reserve(30 * Parents.size());
  for (const CXXRecordDecl *Parent : Parents) {
    if (!ParentsStr.empty())
      ParentsStr.append(" or ");
    ParentsStr.append("'").append(getNameAsString(Parent)).append("'");
  }

  assert(Member->getQualifierLoc().getSourceRange().getBegin().isValid());
  auto Diag = diag(Member->getQualifierLoc().getSourceRange().getBegin(),
                   "qualified name '%0' refers to a member overridden "
                   "in subclass%1; did you mean %2?")
              << getExprAsString(*Member, *Result.Context)
              << (Parents.size() > 1 ? "es" : "") << ParentsStr;

  // Propose a fix if there's only one parent class...
  if (Parents.size() == 1 &&
      // ...unless parent class is templated
      !isa<ClassTemplateSpecializationDecl>(Parents.front()))
    Diag << FixItHint::CreateReplacement(
        Member->getQualifierLoc().getSourceRange(),
        getNameAsString(Parents.front()) + "::");
}
示例#2
0
文件: ASTUtil.cpp 项目: Jhana1/CAPA
bool isObjCInterfaceClassOrSubclass(
    const clang::ObjCInterfaceDecl* decl, const std::string& className) {
    for(auto current = decl; current != nullptr; current = current->getSuperClass()) {
        if(current->getNameAsString() == className) {
            return true;
        }
    }
    return false;
}
    void collectUnifiedSymbolResoltions(clang::ASTContext &astContext,
                                        const clang::SourceLocation &cursorSourceLocation)
    {
        const auto foundDeclarations = namedDeclarationsAt(astContext, cursorSourceLocation);

        if (!foundDeclarations.empty()) {
            const auto firstFoundDeclaration = foundDeclarations.front();

            if (const auto *constructorDecl = clang::dyn_cast<clang::CXXConstructorDecl>(firstFoundDeclaration)) {
                const clang::CXXRecordDecl *foundDeclarationParent = constructorDecl->getParent();
                unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
            } else if (const auto *destructorDecl = clang::dyn_cast<clang::CXXDestructorDecl>(firstFoundDeclaration)) {
                const clang::CXXRecordDecl *foundDeclarationParent = destructorDecl->getParent();
                unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(foundDeclarationParent);
            } else if (const auto *recordDeclaration = clang::dyn_cast<clang::CXXRecordDecl>(firstFoundDeclaration)) {
                unifiedSymbolResolutions = collectConstructorUnifiedSymbolResolutions(recordDeclaration);
            }

            addUnifiedSymbolResolutionsForDeclaration(foundDeclarations, unifiedSymbolResolutions);
            symbolName = firstFoundDeclaration->getNameAsString();
        }
    }
示例#4
0
std::string FunctionState::getNameAsString() const {
  auto const FunctionDecl = getFunctionDecl();
  
  return FunctionDecl ? FunctionDecl->getNameAsString()
                      : UnmappedState.getFunction()->getName().str();
}