@@ -993,27 +993,51 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
993993 invocationArgs.reserve (invocationArgStrs.size ());
994994 for (auto &argStr : invocationArgStrs)
995995 invocationArgs.push_back (argStr.c_str ());
996- // Set up a temporary diagnostic client to report errors from parsing the
997- // command line, which may be important for Swift clients if, for example,
998- // they're using -Xcc options. Unfortunately this diagnostic engine has to
999- // use the default options because the /actual/ options haven't been parsed
1000- // yet.
1001- //
1002- // The long-term client for Clang diagnostics is set up below, after the
1003- // clang::CompilerInstance is created.
1004- llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> tempDiagOpts{
1005- new clang::DiagnosticOptions
1006- };
1007996
1008- ClangDiagnosticConsumer tempDiagClient{importer->Impl , *tempDiagOpts,
1009- importerOpts.DumpClangDiagnostics };
1010- llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> tempClangDiags =
1011- clang::CompilerInstance::createDiagnostics (tempDiagOpts.get (),
1012- &tempDiagClient,
1013- /* owned*/ false );
997+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> clangDiags;
998+ std::unique_ptr<clang::CompilerInvocation> CI;
999+ if (importerOpts.DirectClangCC1ModuleBuild ) {
1000+ // In this mode, we bypass createInvocationFromCommandLine, which goes
1001+ // through the Clang driver, and use strictly cc1 arguments to instantiate a
1002+ // clang Instance directly, assuming that the set of '-Xcc <X>' frontend flags is
1003+ // fully sufficient to do so.
1004+
1005+ // Because we are bypassing the Clang driver, we must populate
1006+ // the diagnostic options here explicitly.
1007+ std::unique_ptr<clang::DiagnosticOptions> clangDiagOpts =
1008+ clang::CreateAndPopulateDiagOpts (invocationArgs);
1009+ ClangDiagnosticConsumer diagClient{importer->Impl , *clangDiagOpts,
1010+ importerOpts.DumpClangDiagnostics };
1011+ clangDiags = clang::CompilerInstance::createDiagnostics (
1012+ clangDiagOpts.release (), &diagClient,
1013+ /* owned*/ false );
1014+
1015+ // Finally, use the CC1 command-line and the diagnostic engine
1016+ // to instantiate our Invocation.
1017+ CI = std::make_unique<clang::CompilerInvocation>();
1018+ if (!clang::CompilerInvocation::CreateFromArgs (
1019+ *CI, invocationArgs, *clangDiags, invocationArgs[0 ]))
1020+ return nullptr ;
1021+ } else {
1022+ // Set up a temporary diagnostic client to report errors from parsing the
1023+ // command line, which may be important for Swift clients if, for example,
1024+ // they're using -Xcc options. Unfortunately this diagnostic engine has to
1025+ // use the default options because the /actual/ options haven't been parsed
1026+ // yet.
1027+ //
1028+ // The long-term client for Clang diagnostics is set up below, after the
1029+ // clang::CompilerInstance is created.
1030+ llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> tempDiagOpts{
1031+ new clang::DiagnosticOptions};
10141032
1015- auto CI = clang::createInvocationFromCommandLine (
1016- invocationArgs, tempClangDiags, VFS, false , CC1Args);
1033+ ClangDiagnosticConsumer tempDiagClient{importer->Impl , *tempDiagOpts,
1034+ importerOpts.DumpClangDiagnostics };
1035+ clangDiags = clang::CompilerInstance::createDiagnostics (tempDiagOpts.get (),
1036+ &tempDiagClient,
1037+ /* owned*/ false );
1038+ CI = clang::createInvocationFromCommandLine (invocationArgs, clangDiags, VFS,
1039+ false , CC1Args);
1040+ }
10171041
10181042 if (!CI) {
10191043 return CI;
@@ -1030,8 +1054,9 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
10301054 // rdar://77516546 is tracking that the clang importer should be more
10311055 // resilient and provide a module even if there were building it.
10321056 auto TempVFS = clang::createVFSFromCompilerInvocation (
1033- *CI, *tempClangDiags ,
1057+ *CI, *clangDiags ,
10341058 VFS ? VFS : importer->Impl .SwiftContext .SourceMgr .getFileSystem ());
1059+
10351060 std::vector<std::string> FilteredModuleMapFiles;
10361061 for (auto ModuleMapFile : CI->getFrontendOpts ().ModuleMapFiles ) {
10371062 if (TempVFS->exists (ModuleMapFile)) {
@@ -1058,13 +1083,11 @@ ClangImporter::create(ASTContext &ctx,
10581083 if (importerOpts.DumpClangDiagnostics ) {
10591084 llvm::errs () << " '" ;
10601085 llvm::interleave (
1061- invocationArgStrs, [](StringRef arg) { llvm::errs () << arg; },
1062- [] { llvm::errs () << " ' '" ; });
1086+ invocationArgStrs, [](StringRef arg) { llvm::errs () << arg; },
1087+ [] { llvm::errs () << " ' '" ; });
10631088 llvm::errs () << " '\n " ;
10641089 }
10651090
1066-
1067-
10681091 if (isPCHFilenameExtension (importerOpts.BridgingHeader )) {
10691092 importer->Impl .setSinglePCHImport (importerOpts.BridgingHeader );
10701093 importer->Impl .IsReadingBridgingPCH = true ;
0 commit comments