Repository: apple/swift
File: lib/IDE/SourceEntityWalker.cpp (C++)

Code before:

      return Action::SkipNode(E);
    }
  }

  if (!SEWalker.walkToExprPre(E)) {
    return Action::SkipNode(E);
  }

  if (auto *CtorRefE = dyn_cast<ConstructorRefCallExpr>(E))
    CtorRefs.push_back(CtorRefE);

  if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
    auto *FD = dyn_cast<FuncDecl>(DRE->getDecl());
    // Handle implicit callAsFunction reference. An explicit reference will be
    // handled by the usual DeclRefExpr case below.
    if (DRE->isImplicit() && FD && FD->isCallAsFunctionMethod()) {
      ReferenceMetaData data(SemaReferenceKind::DeclMemberRef, OpAccess);
      if (!passCallAsFunctionReference(FD, DRE->getLoc(), data))
        return Action::Stop();

      return Action::Continue(E);
    }

    // Skip implicit constructor references - they're handled via CtorRefs.
    if (DRE->isImplicit() && isa<ConstructorDecl>(DRE->getDecl()))
      return Action::Continue(E);
  }

  if (!isa<InOutExpr>(E) && !isa<LoadExpr>(E) && !isa<OpenExistentialExpr>(E) &&
      !isa<MakeTemporarilyEscapableExpr>(E) &&
      !isa<CollectionUpcastConversionExpr>(E) && !isa<OpaqueValueExpr>(E) &&
      !isa<SubscriptExpr>(E) && !isa<KeyPathExpr>(E) && !isa<LiteralExpr>(E) &&
      !isa<CollectionExpr>(E) && !isa<DeclRefExpr>(E) && !isa<MemberRefExpr>(E) &&
      E->isImplicit())
    return Action::Continue(E);

  if (auto LE = dyn_cast<LiteralExpr>(E)) {
    if (LE->getInitializer() &&
        !passReference(LE->getInitializer().getDecl(), LE->getType(), {},
                       LE->getSourceRange(),
                       ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,
                                         /*isImplicit=*/true))) {
      return Action::Stop();
    }
    return Action::Continue(E);
  } else if (auto CE = dyn_cast<CollectionExpr>(E)) {
    if (CE->getInitializer() &&
        !passReference(CE->getInitializer().getDecl(), CE->getType(), {},
                       CE->getSourceRange(),
                       ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,

Review comment (suggestion):
I think a more accurate way to check this would be to query `CtorRefs` and if the last element's `getFn()->getLoc()` is the same loc as the DeclRefExpr then we know it will be handled in `passReference` (since that matches the check there).

Code after:

      return Action::SkipNode(E);
    }
  }

  if (!SEWalker.walkToExprPre(E)) {
    return Action::SkipNode(E);
  }

  if (auto *CtorRefE = dyn_cast<ConstructorRefCallExpr>(E))
    CtorRefs.push_back(CtorRefE);

  if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
    auto *FD = dyn_cast<FuncDecl>(DRE->getDecl());
    // Handle implicit callAsFunction reference. An explicit reference will be
    // handled by the usual DeclRefExpr case below.
    if (DRE->isImplicit() && FD && FD->isCallAsFunctionMethod()) {
      ReferenceMetaData data(SemaReferenceKind::DeclMemberRef, OpAccess);
      if (!passCallAsFunctionReference(FD, DRE->getLoc(), data))
        return Action::Stop();

      return Action::Continue(E);
    }

    // Skip implicit DeclRefExprs that will be handled via CtorRefs in
    // passReference. This matches the location check in passReference.
    if (DRE->isImplicit() && !CtorRefs.empty() &&
        CtorRefs.back()->getFn()->getLoc() == DRE->getLoc())
      return Action::Continue(E);
  }

  if (!isa<InOutExpr>(E) && !isa<LoadExpr>(E) && !isa<OpenExistentialExpr>(E) &&
      !isa<MakeTemporarilyEscapableExpr>(E) &&
      !isa<CollectionUpcastConversionExpr>(E) && !isa<OpaqueValueExpr>(E) &&
      !isa<SubscriptExpr>(E) && !isa<KeyPathExpr>(E) && !isa<LiteralExpr>(E) &&
      !isa<CollectionExpr>(E) && !isa<DeclRefExpr>(E) && !isa<MemberRefExpr>(E) &&
      E->isImplicit())
    return Action::Continue(E);

  if (auto LE = dyn_cast<LiteralExpr>(E)) {
    if (LE->getInitializer() &&
        !passReference(LE->getInitializer().getDecl(), LE->getType(), {},
                       LE->getSourceRange(),
                       ReferenceMetaData(SemaReferenceKind::DeclRef, OpAccess,
                                         /*isImplicit=*/true))) {
      return Action::Stop();
    }
    return Action::Continue(E);
  } else if (auto CE = dyn_cast<CollectionExpr>(E)) {
    if (CE->getInitializer() &&
        !passReference(CE->getInitializer().getDecl(), CE->getType(), {},