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

Code before:
  // resilient and provide a module even if there were building it.
  auto TempVFS = clang::createVFSFromCompilerInvocation(*CI, *clangDiags, VFS);

  std::vector<std::string> FilteredModuleMapFiles;
  for (auto ModuleMapFile : CI->getFrontendOpts().ModuleMapFiles) {
    if (ctx.CASOpts.HasImmutableFileSystem) {
      // There is no need to add any module map file here. Issue a warning and
      // drop the option.
      Impl.diagnose(SourceLoc(), diag::module_map_ignored, ModuleMapFile);
    } else if (TempVFS->exists(ModuleMapFile)) {
      FilteredModuleMapFiles.push_back(ModuleMapFile);
    } else {
      Impl.diagnose(SourceLoc(), diag::module_map_not_found, ModuleMapFile);
    }
  }
  CI->getFrontendOpts().ModuleMapFiles = FilteredModuleMapFiles;

  // Clear clang debug flags.
  CI->getCodeGenOpts().DwarfDebugFlags.clear();

  return CI->getCC1CommandLine();
}

std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
    ClangImporter *importer, const ClangImporterOptions &importerOpts,
    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
    const std::vector<std::string> &CC1Args) {
  std::vector<const char *> invocationArgs;
  invocationArgs.reserve(CC1Args.size());
  llvm::for_each(CC1Args, [&](const std::string &Arg) {
    invocationArgs.push_back(Arg.c_str());
  });

  // Create a diagnostics engine for creating clang compiler invocation. The
  // option here is either generated by dependency scanner or just round tripped
  // from `getClangCC1Arguments` so we don't expect it to fail. Use a simple
  // printing diagnostics consumer for debugging any unexpected error.
  clang::DiagnosticOptions diagOpts;
  clang::DiagnosticsEngine clangDiags(
      new clang::DiagnosticIDs(), diagOpts,
      new clang::TextDiagnosticPrinter(llvm::errs(), diagOpts));

  // Finally, use the CC1 command-line and the diagnostic engine
  // to instantiate our Invocation.
  auto CI = std::make_unique<clang::CompilerInvocation>();
  if (!clang::CompilerInvocation::CreateFromArgs(
          *CI, invocationArgs, clangDiags, importerOpts.clangPath.c_str()))
    return nullptr;

  return CI;
}

Review comment (suggestion):
I don't think this is necessary. `clangDiags` is a local, so `diagOpts` being local should be fine. The returned `CI` doesn't hold on to either of these.

Code after:
  // resilient and provide a module even if there were building it.
  auto TempVFS = clang::createVFSFromCompilerInvocation(*CI, *clangDiags, VFS);

  std::vector<std::string> FilteredModuleMapFiles;
  for (auto ModuleMapFile : CI->getFrontendOpts().ModuleMapFiles) {
    if (ctx.CASOpts.HasImmutableFileSystem) {
      // There is no need to add any module map file here. Issue a warning and
      // drop the option.
      Impl.diagnose(SourceLoc(), diag::module_map_ignored, ModuleMapFile);
    } else if (TempVFS->exists(ModuleMapFile)) {
      FilteredModuleMapFiles.push_back(ModuleMapFile);
    } else {
      Impl.diagnose(SourceLoc(), diag::module_map_not_found, ModuleMapFile);
    }
  }
  CI->getFrontendOpts().ModuleMapFiles = FilteredModuleMapFiles;

  // Clear clang debug flags.
  CI->getCodeGenOpts().DwarfDebugFlags.clear();

  return CI->getCC1CommandLine();
}

std::pair<std::unique_ptr<clang::CompilerInvocation>,
          std::unique_ptr<clang::DiagnosticOptions>>
ClangImporter::createClangInvocation(
    ClangImporter *importer, const ClangImporterOptions &importerOpts,
    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
    const std::vector<std::string> &CC1Args) {
  std::vector<const char *> invocationArgs;
  invocationArgs.reserve(CC1Args.size());
  llvm::for_each(CC1Args, [&](const std::string &Arg) {
    invocationArgs.push_back(Arg.c_str());
  });

  // Create a diagnostics engine for creating clang compiler invocation. The
  // option here is either generated by dependency scanner or just round tripped
  // from `getClangCC1Arguments` so we don't expect it to fail. Use a simple
  // printing diagnostics consumer for debugging any unexpected error.
  auto diagOpts = std::make_unique<clang::DiagnosticOptions>();
  clang::DiagnosticsEngine clangDiags(
      new clang::DiagnosticIDs(), *diagOpts,
      new clang::TextDiagnosticPrinter(llvm::errs(), *diagOpts));

  // Finally, use the CC1 command-line and the diagnostic engine
  // to instantiate our Invocation.
  auto CI = std::make_unique<clang::CompilerInvocation>();
  if (!clang::CompilerInvocation::CreateFromArgs(
          *CI, invocationArgs, clangDiags, importerOpts.clangPath.c_str()))
    return {nullptr, nullptr};