diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 2c6dcceb6662a..2a52def34eea7 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -20,6 +20,7 @@ #include "swift/AST/AttrKind.h" #include "swift/AST/ClangModuleLoader.h" #include "clang/AST/Attr.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/Specifiers.h" #include "llvm/Support/VirtualFileSystem.h" @@ -213,7 +214,8 @@ class ClangImporter final : public ClangModuleLoader { std::vector getClangDepScanningInvocationArguments(ASTContext &ctx); - static std::unique_ptr + static std::pair, + std::unique_ptr> createClangInvocation(ClangImporter *importer, const ClangImporterOptions &importerOpts, llvm::IntrusiveRefCntPtr VFS, @@ -223,8 +225,9 @@ class ClangImporter final : public ClangModuleLoader { /// /// \return a pair of the Clang Driver and the diagnostic engine, which needs /// to be alive during the use of the Driver. - static std::pair> + static std::tuple, + std::unique_ptr> createClangDriver( const LangOptions &LangOpts, const ClangImporterOptions &ClangImporterOpts, diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index c3b747062d53e..5cbea00fca77c 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -1283,7 +1283,9 @@ std::optional> ClangImporter::getClangCC1Arguments( return CI->getCC1CommandLine(); } -std::unique_ptr ClangImporter::createClangInvocation( +std::pair, + std::unique_ptr> +ClangImporter::createClangInvocation( ClangImporter *importer, const ClangImporterOptions &importerOpts, llvm::IntrusiveRefCntPtr VFS, const std::vector &CC1Args) { @@ -1297,19 +1299,19 @@ std::unique_ptr ClangImporter::createClangInvocation( // 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; + auto diagOpts = std::make_unique(); clang::DiagnosticsEngine clangDiags( - new clang::DiagnosticIDs(), diagOpts, - new clang::TextDiagnosticPrinter(llvm::errs(), diagOpts)); + 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(); if (!clang::CompilerInvocation::CreateFromArgs( *CI, invocationArgs, clangDiags, importerOpts.clangPath.c_str())) - return nullptr; + return {nullptr, nullptr}; - return CI; + return {std::move(CI), std::move(diagOpts)}; } std::unique_ptr ClangImporter::create( @@ -1357,8 +1359,9 @@ std::unique_ptr ClangImporter::create( [] { llvm::errs() << "' '"; }); llvm::errs() << "'\n"; } - importer->Impl.Invocation = createClangInvocation( - importer.get(), importerOpts, VFS, importer->Impl.ClangArgs); + std::tie(importer->Impl.Invocation, importer->Impl.DiagnosticOptions) = + createClangInvocation(importer.get(), importerOpts, VFS, + importer->Impl.ClangArgs); if (!importer->Impl.Invocation) return nullptr; } @@ -1434,7 +1437,7 @@ std::unique_ptr ClangImporter::create( ctx, instance.getVirtualFileSystemPtr(), true); if (!swiftTargetClangArgs) return nullptr; - auto swiftTargetClangInvocation = createClangInvocation( + auto [swiftTargetClangInvocation, clangDiagOpts] = createClangInvocation( importer.get(), importerOpts, instance.getVirtualFileSystemPtr(), *swiftTargetClangArgs); if (!swiftTargetClangInvocation) diff --git a/lib/ClangImporter/ClangIncludePaths.cpp b/lib/ClangImporter/ClangIncludePaths.cpp index f8289e1e8e17e..479d712f8a253 100644 --- a/lib/ClangImporter/ClangIncludePaths.cpp +++ b/lib/ClangImporter/ClangIncludePaths.cpp @@ -122,22 +122,23 @@ parseClangDriverArgs(const clang::driver::Driver &clangDriver, return clangDriver.getOpts().ParseArgs(args, unused1, unused2); } -std::pair> +std::tuple, + std::unique_ptr> ClangImporter::createClangDriver( const LangOptions &LangOpts, const ClangImporterOptions &ClangImporterOpts, llvm::IntrusiveRefCntPtr vfs) { auto diagVFS = vfs ? vfs : llvm::vfs::getRealFileSystem(); - clang::DiagnosticOptions diagOpts; + auto diagOpts = std::make_unique(); auto *silentDiagConsumer = new clang::DiagnosticConsumer(); auto clangDiags = clang::CompilerInstance::createDiagnostics( - *diagVFS, diagOpts, silentDiagConsumer); + *diagVFS, *diagOpts, silentDiagConsumer); clang::driver::Driver clangDriver(ClangImporterOpts.clangPath, LangOpts.Target.str(), *clangDiags, "clang LLVM compiler", vfs); - return {std::move(clangDriver), clangDiags}; + return {std::move(clangDriver), clangDiags, std::move(diagOpts)}; } /// Given a list of include paths and a list of file names, finds the first @@ -208,8 +209,9 @@ getLibcFileMapping(const ASTContext &ctx, StringRef modulemapFileName, const llvm::Triple &triple = ctx.LangOpts.Target; // Extract the libc path from Clang driver. - auto [clangDriver, clangDiagEngine] = ClangImporter::createClangDriver( - ctx.LangOpts, ctx.ClangImporterOpts, vfs); + auto [clangDriver, clangDiagEngine, clangDiagOpts] = + ClangImporter::createClangDriver(ctx.LangOpts, ctx.ClangImporterOpts, + vfs); auto clangDriverArgs = ClangImporter::createClangArgs( ctx.ClangImporterOpts, ctx.SearchPathOpts, clangDriver); @@ -287,8 +289,9 @@ static void getLibStdCxxFileMapping( return; // Extract the libstdc++ installation path from Clang driver. - auto [clangDriver, clangDiagEngine] = ClangImporter::createClangDriver( - ctx.LangOpts, ctx.ClangImporterOpts, vfs); + auto [clangDriver, clangDiagEngine, clangDiagOpts] = + ClangImporter::createClangDriver(ctx.LangOpts, ctx.ClangImporterOpts, + vfs); auto clangDriverArgs = ClangImporter::createClangArgs( ctx.ClangImporterOpts, ctx.SearchPathOpts, clangDriver); @@ -482,8 +485,9 @@ void GetWindowsFileMappings( if (!Triple.isWindowsMSVCEnvironment()) return; - auto [Driver, clangDiagEngine] = ClangImporter::createClangDriver( - Context.LangOpts, Context.ClangImporterOpts, driverVFS); + auto [Driver, clangDiagEngine, clangDiagOpts] = + ClangImporter::createClangDriver(Context.LangOpts, + Context.ClangImporterOpts, driverVFS); const llvm::opt::InputArgList Args = ClangImporter::createClangArgs( Context.ClangImporterOpts, Context.SearchPathOpts, Driver); const clang::driver::ToolChain &ToolChain = Driver.getToolChain(Args, Triple); diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index cfdc97e0bef06..a241abaf0375b 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -551,6 +551,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// Clang arguments used to create the Clang invocation. std::vector ClangArgs; + /// Clang diagnostic options used to create the Clang invocation. + std::unique_ptr DiagnosticOptions; + /// Mapping from Clang swift_attr attribute text to the Swift source file(s) /// that contain that attribute text. /// diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index a937d4bea9b7b..105bed5f869e0 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -392,7 +392,7 @@ void CompilerInvocation::computeCXXStdlibOptions() { LangOpts.PlatformDefaultCXXStdlib = CXXStdlibKind::Msvcprt; } else if (LangOpts.Target.isOSLinux() || LangOpts.Target.isOSDarwin() || LangOpts.Target.isOSFreeBSD()) { - auto [clangDriver, clangDiagEngine] = + auto [clangDriver, clangDiagEngine, clangDiagOpts] = ClangImporter::createClangDriver(LangOpts, ClangImporterOpts); auto clangDriverArgs = ClangImporter::createClangArgs( ClangImporterOpts, SearchPathOpts, clangDriver);