Repository: llvm/llvm-project
File: clang/lib/Interpreter/IncrementalParser.cpp (C++)

Code before:
void IncrementalParser::CleanUpPTU(TranslationUnitDecl *MostRecentTU) {
  if (auto *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) {
    for (auto &&[Key, List] : *Map) {
      DeclContextLookupResult R = List.getLookupResult();
      std::vector<NamedDecl *> NamedDeclsToRemove;
      bool RemoveAll = true;
      for (NamedDecl *D : R) {
        if (D->getTranslationUnitDecl() == MostRecentTU)
          NamedDeclsToRemove.push_back(D);
        else
          RemoveAll = false;
      }
      if (LLVM_LIKELY(RemoveAll)) {
        Map->erase(Key);
      } else {
        for (NamedDecl *D : NamedDeclsToRemove)
          List.remove(D);
      }
    }
  }

  auto *ECCD = S.getASTContext().getExternCContextDecl();
  if (auto *Map = ECCD->getPrimaryContext()->getLookupPtr()) {
    for (auto &&[Key, List] : *Map) {
      DeclContextLookupResult R = List.getLookupResult();
      std::vector<NamedDecl *> NamedDeclsToRemove;
      for (NamedDecl *D : R) {
        // Implicitly generated C decl is not attached to the current TU but
        // lexically attached to the recent TU, so we need to check the lexical
        // context.
        DeclContext *LDC = D->getLexicalDeclContext();
        while (LDC && !isa<TranslationUnitDecl>(LDC)) {
          LDC = LDC->getLexicalParent();
        }
        TranslationUnitDecl *TopTU = cast_or_null<TranslationUnitDecl>(LDC);
        if (TopTU == MostRecentTU)
          NamedDeclsToRemove.push_back(D);
      }
      for (NamedDecl *D : NamedDeclsToRemove) {
        List.remove(D);
        S.IdResolver.RemoveDecl(D);
      }
    }
  }

  // FIXME: We should de-allocate MostRecentTU
  for (Decl *D : MostRecentTU->decls()) {
    auto *ND = dyn_cast<NamedDecl>(D);
    if (!ND || ND->getDeclName().isEmpty())
      continue;
    // Check if we need to clean up the IdResolver chain.

Review comment (suggestion):
Use `SmallVector`.

https://llvm.org/docs/CodingStandards.html#c-standard-library

Code after:

void IncrementalParser::CleanUpPTU(TranslationUnitDecl *MostRecentTU) {
  if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) {
    for (auto &&[Key, List] : *Map) {
      DeclContextLookupResult R = List.getLookupResult();
      std::vector<NamedDecl *> NamedDeclsToRemove;
      bool RemoveAll = true;
      for (NamedDecl *D : R) {
        if (D->getTranslationUnitDecl() == MostRecentTU)
          NamedDeclsToRemove.push_back(D);
        else
          RemoveAll = false;
      }
      if (LLVM_LIKELY(RemoveAll)) {
        Map->erase(Key);
      } else {
        for (NamedDecl *D : NamedDeclsToRemove)
          List.remove(D);
      }
    }
  }

  ExternCContextDecl *ECCD = S.getASTContext().getExternCContextDecl();
  if (StoredDeclsMap *Map = ECCD->getPrimaryContext()->getLookupPtr()) {
    for (auto &&[Key, List] : *Map) {
      DeclContextLookupResult R = List.getLookupResult();
      llvm::SmallVector<NamedDecl *, 4> NamedDeclsToRemove;
      for (NamedDecl *D : R) {
        // Implicitly generated C decl is not attached to the current TU but
        // lexically attached to the recent TU, so we need to check the lexical
        // context.
        DeclContext *LDC = D->getLexicalDeclContext();
        while (LDC && !isa<TranslationUnitDecl>(LDC))
          LDC = LDC->getLexicalParent();
        TranslationUnitDecl *TopTU = cast_or_null<TranslationUnitDecl>(LDC);
        if (TopTU == MostRecentTU)
          NamedDeclsToRemove.push_back(D);
      }
      for (NamedDecl *D : NamedDeclsToRemove) {
        List.remove(D);
        S.IdResolver.RemoveDecl(D);
      }
    }
  }

  // FIXME: We should de-allocate MostRecentTU
  for (Decl *D : MostRecentTU->decls()) {
    auto *ND = dyn_cast<NamedDecl>(D);
    if (!ND || ND->getDeclName().isEmpty())
      continue;
    // Check if we need to clean up the IdResolver chain.