Repository: apple/swift
File: lib/AST/DeclContext.cpp (C++)

Code before:
}

ArrayRef<Decl *> IterableDeclContext::getABIMembers() const {
  ASTContext &ctx = getASTContext();
  return evaluateOrDefault(
      ctx.evaluator,
      ABIMembersRequest{const_cast<IterableDeclContext *>(this)},
      ArrayRef<Decl *>());
}

ArrayRef<Decl *> IterableDeclContext::getAllMembers() const {
  ASTContext &ctx = getASTContext();
  return evaluateOrDefault(
      ctx.evaluator,
      AllMembersRequest{const_cast<IterableDeclContext *>(this)},
      ArrayRef<Decl *>());
}

void IterableDeclContext::addMemberPreservingSourceOrder(Decl *member) {
  auto &SM = getASTContext().SourceMgr;

  SourceLoc start = member->getStartLoc();
  Decl *hint = nullptr;

  addParsedMembers();
  for (auto *existingMember : getCurrentMembersWithoutLoading()) {
    if (existingMember->isImplicit())
      continue;

    // An EnumCaseDecl contains one or more EnumElementDecls,
    // but the EnumElementDecls are also added as members of
    // the parent enum. We ignore the EnumCaseDecl since its
    // source range overlaps with that of the EnumElementDecls.
    if (isa<EnumCaseDecl>(existingMember))
      continue;

    if (!SM.isBeforeInBuffer(existingMember->getEndLoc(), start))
      break;

    hint = existingMember;
  }

  addMember(member, hint, /*insertAtHead=*/hint == nullptr);
}

/// Add a member to this context.
void IterableDeclContext::addMember(Decl *member, Decl *hint, bool insertAtHead) {
  // Add the member to the list of declarations without notification.
  addMemberSilently(member, hint, insertAtHead);

  // Notify our parent declaration that we have added the member, which can

Review comment (bug):
It looks like addMemberPreservingSourceOrder() is only called in one place in the parser, can we assert here that getParentSourceFile() != nullptr? Or is it necessary to change this function at all? getMembers() should be the same as getParsedMembers() in this case.

Code after:
}

ArrayRef<Decl *> IterableDeclContext::getABIMembers() const {
  ASTContext &ctx = getASTContext();
  return evaluateOrDefault(
      ctx.evaluator,
      ABIMembersRequest{const_cast<IterableDeclContext *>(this)},
      ArrayRef<Decl *>());
}

ArrayRef<Decl *> IterableDeclContext::getAllMembers() const {
  ASTContext &ctx = getASTContext();
  return evaluateOrDefault(
      ctx.evaluator,
      AllMembersRequest{const_cast<IterableDeclContext *>(this)},
      ArrayRef<Decl *>());
}

void IterableDeclContext::addMemberPreservingSourceOrder(Decl *member) {
  auto &SM = getASTContext().SourceMgr;

  SourceLoc start = member->getStartLoc();
  Decl *hint = nullptr;

  for (auto *existingMember : getMembers()) {
    if (existingMember->isImplicit())
      continue;

    // An EnumCaseDecl contains one or more EnumElementDecls,
    // but the EnumElementDecls are also added as members of
    // the parent enum. We ignore the EnumCaseDecl since its
    // source range overlaps with that of the EnumElementDecls.
    if (isa<EnumCaseDecl>(existingMember))
      continue;

    if (!SM.isBeforeInBuffer(existingMember->getEndLoc(), start))
      break;

    hint = existingMember;
  }

  addMember(member, hint, /*insertAtHead=*/hint == nullptr);
}

/// Add a member to this context.
void IterableDeclContext::addMember(Decl *member, Decl *hint, bool insertAtHead) {
  // Add the member to the list of declarations without notification.
  addMemberSilently(member, hint, insertAtHead);

  // Notify our parent declaration that we have added the member, which can
  // be used to update the lookup tables.