diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 8e39b3e8f84d1..f9d3378206205 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -200,7 +200,9 @@ class ClangImporter final : public ClangModuleLoader { /// \returns a new Clang module importer, or null (with a diagnostic) if /// an error occurred. static std::unique_ptr - create(ASTContext &ctx, std::string swiftPCHHash = "", + create(ASTContext &ctx, + const IRGenOptions *IRGenOpts = nullptr, + std::string swiftPCHHash = "", DependencyTracker *tracker = nullptr, DWARFImporterDelegate *dwarfImporterDelegate = nullptr, bool ignoreFileMapping = false); diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index ab6eedc32fa62..97607593af81f 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -1312,7 +1312,8 @@ std::unique_ptr ClangImporter::createClangInvocation( } std::unique_ptr ClangImporter::create( - ASTContext &ctx, std::string swiftPCHHash, DependencyTracker *tracker, + ASTContext &ctx, const IRGenOptions *IRGenOpts, std::string swiftPCHHash, + DependencyTracker *tracker, DWARFImporterDelegate *dwarfImporterDelegate, bool ignoreFileMapping) { std::unique_ptr importer{ new ClangImporter(ctx, tracker, dwarfImporterDelegate)}; @@ -1446,6 +1447,48 @@ std::unique_ptr ClangImporter::create( importer->Impl.configureOptionsForCodeGen(clangDiags); } + if (IRGenOpts) { + // We need to set the AST-affecting CodeGenOpts here early so that + // the clang module cache hash will be consistent throughout. Also + // prefer to set the AST-benign ones here unless they are computed + // after this point or may var per inputs. + auto &CGO = importer->getCodeGenOpts(); + CGO.OptimizationLevel = IRGenOpts->shouldOptimize() ? 3 : 0; + CGO.DebugTypeExtRefs = !IRGenOpts->DisableClangModuleSkeletonCUs; + switch (IRGenOpts->DebugInfoLevel) { + case IRGenDebugInfoLevel::None: + CGO.setDebugInfo(llvm::codegenoptions::DebugInfoKind::NoDebugInfo); + break; + case IRGenDebugInfoLevel::LineTables: + CGO.setDebugInfo(llvm::codegenoptions::DebugInfoKind::DebugLineTablesOnly); + break; + case IRGenDebugInfoLevel::ASTTypes: + case IRGenDebugInfoLevel::DwarfTypes: + CGO.setDebugInfo(llvm::codegenoptions::DebugInfoKind::FullDebugInfo); + break; + } + switch (IRGenOpts->DebugInfoFormat) { + case IRGenDebugInfoFormat::None: + break; + case IRGenDebugInfoFormat::DWARF: + CGO.DebugCompilationDir = IRGenOpts->DebugCompilationDir; + CGO.DwarfVersion = IRGenOpts->DWARFVersion; + break; + case IRGenDebugInfoFormat::CodeView: + CGO.EmitCodeView = true; + CGO.DebugCompilationDir = IRGenOpts->DebugCompilationDir; + break; + } + if (!IRGenOpts->TrapFuncName.empty()) { + CGO.TrapFuncName = IRGenOpts->TrapFuncName; + } + // We don't need to perform coverage mapping for any Clang decls we've + // synthesized, as they have no user-written code. This is also needed to + // avoid a Clang crash when attempting to emit coverage for decls without + // source locations (rdar://100172217). + CGO.CoverageMapping = false; + } + // Create the associated action. importer->Impl.Action.reset(new ParsingAction(*importer, importer->Impl, diff --git a/lib/DriverTool/modulewrap_main.cpp b/lib/DriverTool/modulewrap_main.cpp index cea5130e58555..95a0ed61c984f 100644 --- a/lib/DriverTool/modulewrap_main.cpp +++ b/lib/DriverTool/modulewrap_main.cpp @@ -198,8 +198,9 @@ int modulewrap_main(ArrayRef Args, const char *Argv0, registerParseRequestFunctions(ASTCtx.evaluator); registerTypeCheckerRequestFunctions(ASTCtx.evaluator); - ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, "", - nullptr, nullptr, + IRGenOptions IRGenOpts; + ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, &IRGenOpts, + "", nullptr, nullptr, true), true); ModuleDecl *M = diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index a7d7acdaa10af..a6b5aacf63323 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -872,7 +872,8 @@ bool CompilerInstance::setUpModuleLoaders() { // Otherwise, we just keep it around as our interface to Clang's ABI // knowledge. std::unique_ptr clangImporter = - ClangImporter::create(*Context, Invocation.getPCHHash(), + ClangImporter::create(*Context, &Invocation.getIRGenOptions(), + Invocation.getPCHHash(), getDependencyTracker()); if (!clangImporter) { Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail); diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 0d259aae6b912..72f9c5a69dc0c 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -108,50 +108,20 @@ static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context, auto &CGTI = Importer->getTargetInfo(); auto &CGO = Importer->getCodeGenOpts(); - CGO.OptimizationLevel = Opts.shouldOptimize() ? 3 : 0; - CGO.DebugTypeExtRefs = !Opts.DisableClangModuleSkeletonCUs; + // Here we set the AST-benign CodeGenOpts options only. Set the + // AST-affecting ones early in ClangImporter::create. CGO.DiscardValueNames = !Opts.shouldProvideValueNames(); - switch (Opts.DebugInfoLevel) { - case IRGenDebugInfoLevel::None: - CGO.setDebugInfo(llvm::codegenoptions::DebugInfoKind::NoDebugInfo); - break; - case IRGenDebugInfoLevel::LineTables: - CGO.setDebugInfo(llvm::codegenoptions::DebugInfoKind::DebugLineTablesOnly); - break; - case IRGenDebugInfoLevel::ASTTypes: - case IRGenDebugInfoLevel::DwarfTypes: - CGO.setDebugInfo(llvm::codegenoptions::DebugInfoKind::FullDebugInfo); - break; - } switch (Opts.DebugInfoFormat) { case IRGenDebugInfoFormat::None: break; case IRGenDebugInfoFormat::DWARF: - CGO.DebugCompilationDir = Opts.DebugCompilationDir; - CGO.DwarfVersion = Opts.DWARFVersion; - CGO.DwarfDebugFlags = - Opts.getDebugFlags(PD, Context.LangOpts.EnableCXXInterop, - Context.LangOpts.hasFeature(Feature::Embedded)); - break; case IRGenDebugInfoFormat::CodeView: - CGO.EmitCodeView = true; - CGO.DebugCompilationDir = Opts.DebugCompilationDir; - // This actually contains the debug flags for codeview. CGO.DwarfDebugFlags = Opts.getDebugFlags(PD, Context.LangOpts.EnableCXXInterop, Context.LangOpts.hasFeature(Feature::Embedded)); break; } - if (!Opts.TrapFuncName.empty()) { - CGO.TrapFuncName = Opts.TrapFuncName; - } - - // We don't need to perform coverage mapping for any Clang decls we've - // synthesized, as they have no user-written code. This is also needed to - // avoid a Clang crash when attempting to emit coverage for decls without - // source locations (rdar://100172217). - CGO.CoverageMapping = false; auto &VFS = Importer->getClangInstance().getVirtualFileSystem(); auto &HSI = Importer->getClangPreprocessor() diff --git a/test/DebugInfo/BridgingHeaderPCH-Type.swift b/test/DebugInfo/BridgingHeaderPCH-Type.swift index cd6d725081c4b..7cd790c5a3452 100644 --- a/test/DebugInfo/BridgingHeaderPCH-Type.swift +++ b/test/DebugInfo/BridgingHeaderPCH-Type.swift @@ -1,5 +1,5 @@ // RUN: %target-swift-frontend \ -// RUN: -emit-pch %S/Inputs/BridgingHeader.h -o %t.pch +// RUN: -emit-pch %S/Inputs/BridgingHeader.h -o %t.pch -g // RUN: %target-swift-frontend \ // RUN: -import-objc-header %t.pch -emit-ir -g %s -o - | %FileCheck %s diff --git a/test/DebugInfo/BridgingHeaderPCH.swift b/test/DebugInfo/BridgingHeaderPCH.swift index b7a6996658eba..532b76fe4931f 100644 --- a/test/DebugInfo/BridgingHeaderPCH.swift +++ b/test/DebugInfo/BridgingHeaderPCH.swift @@ -1,5 +1,5 @@ // RUN: %target-swift-frontend \ -// RUN: -emit-pch %S/Inputs/InlineBridgingHeader.h -o %t.pch +// RUN: -emit-pch %S/Inputs/InlineBridgingHeader.h -o %t.pch -g // RUN: %target-swift-frontend \ // RUN: -import-objc-header %t.pch -emit-ir -g %s -o - | %FileCheck %s diff --git a/test/Interop/Cxx/modules/module-cache-hash.swift b/test/Interop/Cxx/modules/module-cache-hash.swift new file mode 100644 index 0000000000000..4904a5d60c87f --- /dev/null +++ b/test/Interop/Cxx/modules/module-cache-hash.swift @@ -0,0 +1,6 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t +// RUN: %target-swift-frontend -c -emit-module-path %t/Foo.swiftmodule -g -cxx-interoperability-mode=default %t/Test.swift -module-cache-path %t/clang-module-cache + +//--- Test.swift +// Empty