@@ -1040,27 +1040,51 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
10401040 invocationArgs.reserve (invocationArgStrs.size ());
10411041 for (auto &argStr : invocationArgStrs)
10421042 invocationArgs.push_back (argStr.c_str ());
1043- // Set up a temporary diagnostic client to report errors from parsing the
1044- // command line, which may be important for Swift clients if, for example,
1045- // they're using -Xcc options. Unfortunately this diagnostic engine has to
1046- // use the default options because the /actual/ options haven't been parsed
1047- // yet.
1048- //
1049- // The long-term client for Clang diagnostics is set up below, after the
1050- // clang::CompilerInstance is created.
1051- llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> tempDiagOpts{
1052- new clang::DiagnosticOptions
1053- };
10541043
1055- ClangDiagnosticConsumer tempDiagClient{importer->Impl , *tempDiagOpts,
1056- importerOpts.DumpClangDiagnostics };
1057- llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> tempClangDiags =
1058- clang::CompilerInstance::createDiagnostics (tempDiagOpts.get (),
1059- &tempDiagClient,
1060- /* owned*/ false );
1044+ llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> clangDiags;
1045+ std::unique_ptr<clang::CompilerInvocation> CI;
1046+ if (importerOpts.DirectClangCC1ModuleBuild ) {
1047+ // In this mode, we bypass createInvocationFromCommandLine, which goes
1048+ // through the Clang driver, and use strictly cc1 arguments to instantiate a
1049+ // clang Instance directly, assuming that the set of '-Xcc <X>' frontend flags is
1050+ // fully sufficient to do so.
1051+
1052+ // Because we are bypassing the Clang driver, we must populate
1053+ // the diagnostic options here explicitly.
1054+ std::unique_ptr<clang::DiagnosticOptions> clangDiagOpts =
1055+ clang::CreateAndPopulateDiagOpts (invocationArgs);
1056+ ClangDiagnosticConsumer diagClient{importer->Impl , *clangDiagOpts,
1057+ importerOpts.DumpClangDiagnostics };
1058+ clangDiags = clang::CompilerInstance::createDiagnostics (
1059+ clangDiagOpts.release (), &diagClient,
1060+ /* owned*/ false );
1061+
1062+ // Finally, use the CC1 command-line and the diagnostic engine
1063+ // to instantiate our Invocation.
1064+ CI = std::make_unique<clang::CompilerInvocation>();
1065+ if (!clang::CompilerInvocation::CreateFromArgs (
1066+ *CI, invocationArgs, *clangDiags, invocationArgs[0 ]))
1067+ return nullptr ;
1068+ } else {
1069+ // Set up a temporary diagnostic client to report errors from parsing the
1070+ // command line, which may be important for Swift clients if, for example,
1071+ // they're using -Xcc options. Unfortunately this diagnostic engine has to
1072+ // use the default options because the /actual/ options haven't been parsed
1073+ // yet.
1074+ //
1075+ // The long-term client for Clang diagnostics is set up below, after the
1076+ // clang::CompilerInstance is created.
1077+ llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> tempDiagOpts{
1078+ new clang::DiagnosticOptions};
10611079
1062- auto CI = clang::createInvocationFromCommandLine (
1063- invocationArgs, tempClangDiags, VFS, false , CC1Args);
1080+ ClangDiagnosticConsumer tempDiagClient{importer->Impl , *tempDiagOpts,
1081+ importerOpts.DumpClangDiagnostics };
1082+ clangDiags = clang::CompilerInstance::createDiagnostics (tempDiagOpts.get (),
1083+ &tempDiagClient,
1084+ /* owned*/ false );
1085+ CI = clang::createInvocationFromCommandLine (invocationArgs, clangDiags, VFS,
1086+ false , CC1Args);
1087+ }
10641088
10651089 if (!CI) {
10661090 return CI;
@@ -1077,8 +1101,9 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
10771101 // rdar://77516546 is tracking that the clang importer should be more
10781102 // resilient and provide a module even if there were building it.
10791103 auto TempVFS = clang::createVFSFromCompilerInvocation (
1080- *CI, *tempClangDiags ,
1104+ *CI, *clangDiags ,
10811105 VFS ? VFS : importer->Impl .SwiftContext .SourceMgr .getFileSystem ());
1106+
10821107 std::vector<std::string> FilteredModuleMapFiles;
10831108 for (auto ModuleMapFile : CI->getFrontendOpts ().ModuleMapFiles ) {
10841109 if (TempVFS->exists (ModuleMapFile)) {
@@ -1105,13 +1130,11 @@ ClangImporter::create(ASTContext &ctx,
11051130 if (importerOpts.DumpClangDiagnostics ) {
11061131 llvm::errs () << " '" ;
11071132 llvm::interleave (
1108- invocationArgStrs, [](StringRef arg) { llvm::errs () << arg; },
1109- [] { llvm::errs () << " ' '" ; });
1133+ invocationArgStrs, [](StringRef arg) { llvm::errs () << arg; },
1134+ [] { llvm::errs () << " ' '" ; });
11101135 llvm::errs () << " '\n " ;
11111136 }
11121137
1113-
1114-
11151138 if (isPCHFilenameExtension (importerOpts.BridgingHeader )) {
11161139 importer->Impl .setSinglePCHImport (importerOpts.BridgingHeader );
11171140 importer->Impl .IsReadingBridgingPCH = true ;
0 commit comments