@@ -993,27 +993,51 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
993
993
invocationArgs.reserve (invocationArgStrs.size ());
994
994
for (auto &argStr : invocationArgStrs)
995
995
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
- };
1007
996
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};
1014
1032
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
+ }
1017
1041
1018
1042
if (!CI) {
1019
1043
return CI;
@@ -1030,8 +1054,9 @@ std::unique_ptr<clang::CompilerInvocation> ClangImporter::createClangInvocation(
1030
1054
// rdar://77516546 is tracking that the clang importer should be more
1031
1055
// resilient and provide a module even if there were building it.
1032
1056
auto TempVFS = clang::createVFSFromCompilerInvocation (
1033
- *CI, *tempClangDiags ,
1057
+ *CI, *clangDiags ,
1034
1058
VFS ? VFS : importer->Impl .SwiftContext .SourceMgr .getFileSystem ());
1059
+
1035
1060
std::vector<std::string> FilteredModuleMapFiles;
1036
1061
for (auto ModuleMapFile : CI->getFrontendOpts ().ModuleMapFiles ) {
1037
1062
if (TempVFS->exists (ModuleMapFile)) {
@@ -1058,13 +1083,11 @@ ClangImporter::create(ASTContext &ctx,
1058
1083
if (importerOpts.DumpClangDiagnostics ) {
1059
1084
llvm::errs () << " '" ;
1060
1085
llvm::interleave (
1061
- invocationArgStrs, [](StringRef arg) { llvm::errs () << arg; },
1062
- [] { llvm::errs () << " ' '" ; });
1086
+ invocationArgStrs, [](StringRef arg) { llvm::errs () << arg; },
1087
+ [] { llvm::errs () << " ' '" ; });
1063
1088
llvm::errs () << " '\n " ;
1064
1089
}
1065
1090
1066
-
1067
-
1068
1091
if (isPCHFilenameExtension (importerOpts.BridgingHeader )) {
1069
1092
importer->Impl .setSinglePCHImport (importerOpts.BridgingHeader );
1070
1093
importer->Impl .IsReadingBridgingPCH = true ;
0 commit comments