diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 065291fe82fb4..c2ebf1b73e9bb 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -609,6 +609,9 @@ ERROR(no_swift_sources_with_embedded,none, ERROR(package_cmo_requires_library_evolution, none, "Library evolution must be enabled for Package CMO", ()) +WARNING(internal_bridging_header_without_library_evolution,none, + "using internal bridging headers without library evolution can cause instability", ()) + ERROR(experimental_not_supported_in_production,none, "experimental feature '%0' cannot be enabled in production compiler", (StringRef)) @@ -636,6 +639,8 @@ NOTE(dependency_scan_unexpected_variant_module_map_note, none, NOTE(dependency_scan_unexpected_variant_extra_arg_note, none, "%select{first|second}0 module command-line has extra argument: '%1'", (bool, StringRef)) +ERROR(bridging_header_and_pch_internal_mismatch,none, + "bridging header and precompiled header options mismatch on internal vs. public import", ()) #define UNDEFINE_DIAGNOSTIC_MACROS #include "DefineDiagnosticMacros.h" diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 97bc1f14a4183..92dfb54da7e8f 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -2702,13 +2702,13 @@ NOTE(module_imported_here,none, NOTE(decl_import_via_here,none, "%kind0 imported as " "'%select{private|fileprivate|internal|package|%ERROR|%ERROR}1' " - "from %2 here", - (const Decl *, AccessLevel, const ModuleDecl*)) + "from %select{%2 here|bridging header}3", + (const Decl *, AccessLevel, const ModuleDecl*, bool)) NOTE(decl_import_via_local,none, "%kind0 is imported by this file as " "'%select{private|fileprivate|internal|package|%ERROR|%ERROR}1' " - "from %2", - (const Decl *, AccessLevel, const ModuleDecl*)) + "from %select{%2|bridging header}3", + (const Decl *, AccessLevel, const ModuleDecl*, bool)) // Opaque return types ERROR(opaque_type_invalid_constraint,none, @@ -3834,6 +3834,7 @@ ERROR(decl_from_hidden_module,none, "%2 was imported for SPI only|" "%2 was not imported by this file|" "C++ types from imported module %2 do not support library evolution|" + "it was imported via the internal bridging header|" "%2 was not imported publicly}3", (const Decl *, unsigned, Identifier, unsigned)) ERROR(typealias_desugars_to_type_from_hidden_module,none, @@ -3850,6 +3851,7 @@ ERROR(typealias_desugars_to_type_from_hidden_module,none, "%4 was imported for SPI only|" "%4 was not imported by this file|" "C++ types from imported module %4 do not support library evolution|" + "it was imported via the internal bridging header|" "%4 was not imported publicly}5", (const TypeAliasDecl *, StringRef, StringRef, unsigned, Identifier, unsigned)) ERROR(conformance_from_implementation_only_module,none, @@ -3864,6 +3866,7 @@ ERROR(conformance_from_implementation_only_module,none, "%3 was imported for SPI only|" "%3 was not imported by this file|" "C++ types from imported module %3 do not support library evolution|" + "it was imported via the internal bridging header|" "%3 was not imported publicly}4", (Type, Identifier, unsigned, Identifier, unsigned)) NOTE(assoc_conformance_from_implementation_only_module,none, @@ -7317,6 +7320,7 @@ ERROR(inlinable_decl_ref_from_hidden_module, "%2 was imported for SPI only|" "%2 was not imported by this file|" "C++ APIs from imported module %2 do not support library evolution|" + "it was imported via the internal bridging header|" "%2 was not imported publicly}3", (const ValueDecl *, unsigned, Identifier, unsigned)) @@ -7328,6 +7332,7 @@ ERROR(inlinable_typealias_desugars_to_type_from_hidden_module, "%4 was imported for SPI only|" "%4 was not imported by this file|" "C++ types from imported module %4 do not support library evolution|" + "it was imported via the internal bridging header|" "%4 was not imported publicly}5", (const TypeAliasDecl *, StringRef, StringRef, unsigned, Identifier, unsigned)) diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index cfd593e18112f..e3991483dde0e 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -1046,6 +1046,10 @@ namespace swift { /// The bridging header PCH file. std::string BridgingHeaderPCH; + /// Whether the bridging header and PCH file are considered to be + /// internal imports. + bool BridgingHeaderIsInternal = false; + /// When automatically generating a precompiled header from the bridging /// header, place it in this directory. std::string PrecompiledHeaderOutputDir; diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index eee71255c1392..38b91a728e8bb 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -66,12 +66,16 @@ class FrontendOptions { bool isOutputFileDirectory() const; - /// An Objective-C header to import and make implicitly visible. + /// A C header to import and make implicitly visible. std::string ImplicitObjCHeaderPath; - /// An Objective-C pch to import and make implicitly visible. + /// A C pch to import and make implicitly visible. std::string ImplicitObjCPCHPath; + /// Whether the imported C header or precompiled header is considered + /// an internal import (vs. the default, a public import). + bool ImportHeaderAsInternal = false; + /// The map of aliases and real names of imported or referenced modules. llvm::StringMap ModuleAliasMap; diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index c3d87e4941df9..e99cdc850671f 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -347,16 +347,25 @@ def import_underlying_module : Flag<["-"], "import-underlying-module">, Flags<[FrontendOption, NoInteractiveOption]>, HelpText<"Implicitly imports the Objective-C half of a module">; -def import_objc_header : Separate<["-"], "import-objc-header">, - Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>, - HelpText<"Implicitly imports an Objective-C header file">; def import_bridging_header : Separate<["-"], "import-bridging-header">, + Flags<[FrontendOption, ArgumentIsPath]>, + HelpText<"Implicitly imports a C header file">; +def import_objc_header : Separate<["-"], "import-objc-header">, Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>, - Alias; + Alias; + +def internal_import_bridging_header : Separate<["-"], "internal-import-bridging-header">, + Flags<[FrontendOption, ArgumentIsPath]>, + HelpText<"Implicitly imports a C header file as an internal import">; + def import_pch : Separate<["-"], "import-pch">, Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>, HelpText<"Import bridging header PCH file">; +def internal_import_pch : Separate<["-"], "internal-import-pch">, + Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>, + HelpText<"Import bridging header PCH file as internal">; + def pch_output_dir: Separate<["-"], "pch-output-dir">, Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>, HelpText<"Directory to persist automatically created precompiled bridging headers">; diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 93409fb5eed9b..c3ed11ff240cd 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -2991,7 +2991,9 @@ SourceFile::getImportAccessLevel(const ModuleDecl *targetModule) const { // they are recommended over indirect imports. if ((!restrictiveImport.has_value() || restrictiveImport->accessLevel < AccessLevel::Public) && - imports.isImportedBy(targetModule, getParentModule())) + !(restrictiveImport && + restrictiveImport->module.importedModule->isClangHeaderImportModule()) && + imports.isImportedBy(targetModule, getParentModule())) return std::nullopt; return restrictiveImport; diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 6182b43e83a50..19449f9365094 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -2714,6 +2714,7 @@ ClangImporter::Implementation::Implementation( DisableSwiftBridgeAttr(ctx.ClangImporterOpts.DisableSwiftBridgeAttr), BridgingHeaderExplicitlyRequested( !ctx.ClangImporterOpts.BridgingHeader.empty()), + BridgingHeaderIsInternal(ctx.ClangImporterOpts.BridgingHeaderIsInternal), DisableOverlayModules(ctx.ClangImporterOpts.DisableOverlayModules), EnableClangSPI(ctx.ClangImporterOpts.EnableClangSPI), IsReadingBridgingPCH(false), @@ -3762,8 +3763,13 @@ ImportDecl *swift::createImportDecl(ASTContext &Ctx, auto *ID = ImportDecl::create(Ctx, DC, SourceLoc(), ImportKind::Module, SourceLoc(), importPath.get(), ClangN); - if (IsExported) + if (Ctx.ClangImporterOpts.BridgingHeaderIsInternal) { + ID->getAttrs().add( + new (Ctx) AccessControlAttr(SourceLoc(), SourceRange(), + AccessLevel::Internal, /*implicit=*/true)); + } else if (IsExported) { ID->getAttrs().add(new (Ctx) ExportedAttr(/*IsImplicit=*/false)); + } return ID; } diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 3138cca331a52..4b7126a7b2d0d 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -481,6 +481,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation const bool ImportForwardDeclarations; const bool DisableSwiftBridgeAttr; const bool BridgingHeaderExplicitlyRequested; + const bool BridgingHeaderIsInternal; const bool DisableOverlayModules; const bool EnableClangSPI; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 6c42ca0c8a64c..60903dd63226d 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -144,7 +144,8 @@ static void validateLegacyUnsupportedArgs(DiagnosticEngine &diags, static void validateBridgingHeaderArgs(DiagnosticEngine &diags, const ArgList &args) { - if (!args.hasArgNoClaim(options::OPT_import_objc_header)) + if (!args.hasArgNoClaim(options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header)) return; if (args.hasArgNoClaim(options::OPT_import_underlying_module)) @@ -1521,7 +1522,9 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, if (Args.hasFlag(options::OPT_enable_bridging_pch, options::OPT_disable_bridging_pch, true)) { - if (Arg *A = Args.getLastArg(options::OPT_import_objc_header)) { + if (Arg *A = Args.getLastArg( + options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header)) { StringRef Value = A->getValue(); auto Ty = TC.lookupTypeForExtension(llvm::sys::path::extension(Value)); if (Ty == file_types::TY_ClangHeader) { diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 8011dd7d02b62..2d2deec00e082 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -522,19 +522,28 @@ ToolChain::constructInvocation(const CompileJobAction &job, addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments); addRuntimeLibraryFlags(context.OI, Arguments); - // Pass along an -import-objc-header arg, replacing the argument with the name - // of any input PCH to the current action if one is present. - if (context.Args.hasArgNoClaim(options::OPT_import_objc_header)) { + // Pass along an -(internal-)?import-bridging-header arg, replacing the + // argument with the name of any input PCH to the current action if one is + // present. + if (context.Args.hasArgNoClaim(options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header)) { bool ForwardAsIs = true; bool bridgingPCHIsEnabled = context.Args.hasFlag(options::OPT_enable_bridging_pch, options::OPT_disable_bridging_pch, true); bool usePersistentPCH = bridgingPCHIsEnabled && context.Args.hasArg(options::OPT_pch_output_dir); + bool isInternalImport = context.Args.getLastArgNoClaim( + options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header) + ->getOption().getID() == options::OPT_internal_import_bridging_header; if (!usePersistentPCH) { for (auto *IJ : context.Inputs) { if (!IJ->getOutput().getAnyOutputForType(file_types::TY_PCH).empty()) { - Arguments.push_back("-import-objc-header"); + if (isInternalImport) + Arguments.push_back("-internal-import-bridging-header"); + else + Arguments.push_back("-import-bridging-header"); addInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_PCH); ForwardAsIs = false; @@ -543,7 +552,8 @@ ToolChain::constructInvocation(const CompileJobAction &job, } } if (ForwardAsIs) { - context.Args.AddLastArg(Arguments, options::OPT_import_objc_header); + context.Args.AddLastArg(Arguments, options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header); } if (usePersistentPCH) { context.Args.AddLastArg(Arguments, options::OPT_pch_output_dir); @@ -972,7 +982,8 @@ ToolChain::constructInvocation(const InterpretJobAction &job, addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments); addRuntimeLibraryFlags(context.OI, Arguments); - context.Args.AddLastArg(Arguments, options::OPT_import_objc_header); + context.Args.AddLastArg(Arguments, options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header); context.Args.AddLastArg(Arguments, options::OPT_parse_sil); @@ -1233,7 +1244,8 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job, options::OPT_omit_extension_block_symbols); context.Args.AddLastArg(Arguments, options::OPT_symbol_graph_minimum_access_level); - context.Args.AddLastArg(Arguments, options::OPT_import_objc_header); + context.Args.AddLastArg(Arguments, options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header); Arguments.push_back("-module-name"); Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); @@ -1276,7 +1288,8 @@ ToolChain::constructInvocation(const VerifyModuleInterfaceJobAction &job, file_types::TY_SerializedDiagnostics, "-serialize-diagnostics-path"); - context.Args.AddLastArg(Arguments, options::OPT_import_objc_header); + context.Args.AddLastArg(Arguments, options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header); Arguments.push_back("-module-name"); Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); @@ -1342,7 +1355,8 @@ ToolChain::constructInvocation(const REPLJobAction &job, addCommonFrontendArgs(context.OI, context.Output, context.Args, FrontendArgs); addRuntimeLibraryFlags(context.OI, FrontendArgs); - context.Args.AddLastArg(FrontendArgs, options::OPT_import_objc_header); + context.Args.AddLastArg(FrontendArgs, options::OPT_import_bridging_header, + options::OPT_internal_import_bridging_header); context.Args.addAllArgs(FrontendArgs, {options::OPT_framework, options::OPT_L}); ToolChain::addLinkedLibArgs(context.Args, FrontendArgs); diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index ecbcfbd3d44d1..b40573686b280 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -913,18 +913,40 @@ static inline bool isPCHFilenameExtension(StringRef path) { void ArgsToFrontendOptionsConverter::computeImportObjCHeaderOptions() { using namespace options; - if (const Arg *A = Args.getLastArgNoClaim(OPT_import_objc_header)) { - // Legacy support for passing PCH file through `-import-objc-header`. + bool hadNormalBridgingHeader = false; + if (const Arg *A = Args.getLastArgNoClaim( + OPT_import_bridging_header, + OPT_internal_import_bridging_header)) { + // Legacy support for passing PCH file through `-import-bridging-header`. if (isPCHFilenameExtension(A->getValue())) Opts.ImplicitObjCPCHPath = A->getValue(); else Opts.ImplicitObjCHeaderPath = A->getValue(); - // If `-import-object-header` is used, it means the module has a direct + // If `-import-bridging-header` is used, it means the module has a direct // bridging header dependency and it can be serialized into binary module. Opts.ModuleHasBridgingHeader |= true; + + Opts.ImportHeaderAsInternal = + A->getOption().getID() == OPT_internal_import_bridging_header; + + hadNormalBridgingHeader = true; } - if (const Arg *A = Args.getLastArgNoClaim(OPT_import_pch)) + if (const Arg *A = Args.getLastArgNoClaim(OPT_import_pch, + OPT_internal_import_pch)) { Opts.ImplicitObjCPCHPath = A->getValue(); + + bool importAsInternal = A->getOption().getID() == OPT_internal_import_pch; + + /// Don't let the bridging-header and precompiled-header options differ in + /// whether they are treated as internal or public imports. + if (hadNormalBridgingHeader && + importAsInternal != Opts.ImportHeaderAsInternal) { + Diags.diagnose(SourceLoc(), + diag::bridging_header_and_pch_internal_mismatch); + } + + Opts.ImportHeaderAsInternal = importAsInternal; + } } void ArgsToFrontendOptionsConverter:: computeImplicitImportModuleNames(OptSpecifier id, bool isTestable) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d31373ff4b4d7..0f7e155b9c2da 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -363,6 +363,8 @@ setBridgingHeaderFromFrontendOptions(ClangImporterOptions &ImporterOpts, if (!FrontendOpts.InputsAndOutputs.hasInputs()) return; + ImporterOpts.BridgingHeaderIsInternal = FrontendOpts.ImportHeaderAsInternal; + // If we aren't asked to output a bridging header, we don't need to set this. if (ImporterOpts.PrecompiledHeaderOutputDir.empty()) return; @@ -2109,10 +2111,31 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, ArgList &Args, else if (Args.hasArg(OPT_emit_pcm) || Args.hasArg(OPT_dump_pcm)) Opts.Mode = ClangImporterOptions::Modes::PrecompiledModule; - if (auto *A = Args.getLastArg(OPT_import_objc_header)) + bool hadNormalBridgingHeader = false; + if (auto *A = Args.getLastArg(OPT_import_bridging_header, + OPT_internal_import_bridging_header)) { Opts.BridgingHeader = A->getValue(); - if (auto *A = Args.getLastArg(OPT_import_pch)) + Opts.BridgingHeaderIsInternal = + A->getOption().getID() == OPT_internal_import_bridging_header; + } + if (auto *A = Args.getLastArg(OPT_import_pch, OPT_internal_import_pch)) { Opts.BridgingHeaderPCH = A->getValue(); + bool importAsInternal = A->getOption().getID() == OPT_internal_import_pch; + if (hadNormalBridgingHeader && + importAsInternal != Opts.BridgingHeaderIsInternal) { + Diags.diagnose(SourceLoc(), + diag::bridging_header_and_pch_internal_mismatch); + } + Opts.BridgingHeaderIsInternal = importAsInternal; + } + + // Until we have some checking in place, internal bridging headers are a + // bit unsafe without library evolution. + if (Opts.BridgingHeaderIsInternal && !FrontendOpts.EnableLibraryEvolution) { + Diags.diagnose(SourceLoc(), + diag::internal_bridging_header_without_library_evolution); + } + Opts.DisableSwiftBridgeAttr |= Args.hasArg(OPT_disable_swift_bridge_attr); Opts.DisableOverlayModules |= Args.hasArg(OPT_emit_imported_modules); diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 5ce141e45a407..ff0ba284205fd 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -197,7 +197,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( serializationOpts.DocOutputPath = outs.ModuleDocOutputPath; serializationOpts.SourceInfoOutputPath = outs.ModuleSourceInfoOutputPath; serializationOpts.GroupInfoPath = opts.GroupInfoPath.c_str(); - if (opts.ModuleHasBridgingHeader && !outs.ModuleOutputPath.empty()) + if (opts.ModuleHasBridgingHeader && !outs.ModuleOutputPath.empty() && + !opts.ImportHeaderAsInternal) serializationOpts.SerializeBridgingHeader = true; // For batch mode, emit empty header path as placeholder. if (serializationOpts.SerializeBridgingHeader && diff --git a/lib/Option/features.json b/lib/Option/features.json index f9c87c00022b9..7d521787a4dd8 100644 --- a/lib/Option/features.json +++ b/lib/Option/features.json @@ -50,6 +50,9 @@ }, { "name": "Isystem" + }, + { + "name": "internal-import-bridging-header" } ] } diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp index e14ef37dfb046..9811296b1611d 100644 --- a/lib/Sema/ImportResolution.cpp +++ b/lib/Sema/ImportResolution.cpp @@ -574,8 +574,13 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator, !clangImporter->importBridgingHeader(bridgingHeaderPath, module)) { auto *headerModule = clangImporter->getImportedHeaderModule(); assert(headerModule && "Didn't load bridging header?"); - imports.emplace_back( + AttributedImport import( ImportedModule(headerModule), SourceLoc(), ImportFlags::Exported); + if (ctx.ClangImporterOpts.BridgingHeaderIsInternal) { + import.accessLevel = AccessLevel::Internal; + } + + imports.emplace_back(import); } // Implicitly import the underlying Clang half of this module if needed. diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp index 5fb3249585144..3a4dbd1112107 100644 --- a/lib/Sema/ResilienceDiagnostics.cpp +++ b/lib/Sema/ResilienceDiagnostics.cpp @@ -133,7 +133,9 @@ bool TypeChecker::diagnoseInlinableDeclRefAccess(SourceLoc loc, Context.Diags.diagnose(problematicImport->importLoc, diag::decl_import_via_here, D, problematicImport->accessLevel, - problematicImport->module.importedModule); + problematicImport->module.importedModule, + problematicImport->module.importedModule + ->isClangHeaderImportModule()); } return (downgradeToWarning == DowngradeToWarning::No); @@ -213,7 +215,9 @@ static bool diagnoseTypeAliasDeclRefExportability(SourceLoc loc, ctx.Diags.diagnose(limitImport->importLoc, diag::decl_import_via_here, D, limitImport->accessLevel, - limitImport->module.importedModule); + limitImport->module.importedModule, + limitImport->module.importedModule + ->isClangHeaderImportModule()); } return true; @@ -273,7 +277,8 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D, D, DC, AccessLevel::Public, [&](AttributedImport attributedImport) { if (where.isExported() && reason != ExportabilityReason::General && - originKind != DisallowedOriginKind::NonPublicImport) { + originKind != DisallowedOriginKind::NonPublicImport && + originKind != DisallowedOriginKind::InternalBridgingHeaderImport) { // These may be reported twice, for the Type and for the TypeRepr. ModuleDecl *importedVia = attributedImport.module.importedModule, *sourceModule = D->getModuleContext(); @@ -290,6 +295,7 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D, return false; case DisallowedOriginKind::NonPublicImport: + case DisallowedOriginKind::InternalBridgingHeaderImport: // With a few exceptions, access levels from imports are diagnosed during // access checking and should be skipped here. if (!shouldDiagnoseDeclAccess(D, where)) @@ -368,7 +374,9 @@ static bool diagnoseValueDeclRefExportability(SourceLoc loc, const ValueDecl *D, ctx.Diags.diagnose(import->importLoc, diag::decl_import_via_here, D, import->accessLevel, - import->module.importedModule); + import->module.importedModule, + import->module.importedModule + ->isClangHeaderImportModule()); } return true; @@ -454,7 +462,9 @@ TypeChecker::diagnoseConformanceExportability(SourceLoc loc, ctx.Diags.diagnose(limitImport->importLoc, diag::decl_import_via_here, ext, limitImport->accessLevel, - limitImport->module.importedModule); + limitImport->module.importedModule, + limitImport->module.importedModule + ->isClangHeaderImportModule()); } return true; diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp index 4a844cf7b2e0f..f7c12060e4ac5 100644 --- a/lib/Sema/TypeCheckAccess.cpp +++ b/lib/Sema/TypeCheckAccess.cpp @@ -454,12 +454,16 @@ static void noteLimitingImport(const Decl *userDecl, ASTContext &ctx, if (userDecl) userDecl->diagnose(diag::decl_import_via_local, complainDecl, limitImport->accessLevel, - limitImport->module.importedModule); + limitImport->module.importedModule, + limitImport->module.importedModule + ->isClangHeaderImportModule()); if (limitImport->importLoc.isValid()) ctx.Diags.diagnose(limitImport->importLoc, diag::decl_import_via_here, complainDecl, limitImport->accessLevel, - limitImport->module.importedModule); + limitImport->module.importedModule, + limitImport->module.importedModule + ->isClangHeaderImportModule()); } else if (limitImport->importLoc.isValid()) { ctx.Diags.diagnose(limitImport->importLoc, diag::module_imported_here, limitImport->module.importedModule, @@ -2163,8 +2167,11 @@ swift::getDisallowedOriginKind(const Decl *decl, // See \c diagnoseValueDeclRefExportability. auto importSource = decl->getImportAccessFrom(where.getDeclContext()); if (importSource.has_value() && - importSource->accessLevel < AccessLevel::Public) - return DisallowedOriginKind::NonPublicImport; + importSource->accessLevel < AccessLevel::Public) { + return importSource->module.importedModule->isClangHeaderImportModule() + ? DisallowedOriginKind::InternalBridgingHeaderImport + : DisallowedOriginKind::NonPublicImport; + } return DisallowedOriginKind::None; } @@ -2692,6 +2699,11 @@ void swift::recordRequiredImportAccessLevelForDecl( if (definingModule == dc->getParentModule()) return; + // Egregious hack: if the declaration is for a C++ namespace, assume it's + // accessible. + if (isa_and_nonnull(decl->getClangDecl())) + return; + sf->registerRequiredAccessLevelForModule(definingModule, accessLevel); if (auto attributedImport = sf->getImportAccessLevel(definingModule)) { diff --git a/lib/Sema/TypeCheckAccess.h b/lib/Sema/TypeCheckAccess.h index 6291c1de9d419..c97312b962370 100644 --- a/lib/Sema/TypeCheckAccess.h +++ b/lib/Sema/TypeCheckAccess.h @@ -47,6 +47,10 @@ enum class DisallowedOriginKind : uint8_t { SPIOnly, MissingImport, FragileCxxAPI, + + /// An import that is internal via the internally-imported bridging header. + InternalBridgingHeaderImport, + NonPublicImport, None }; diff --git a/test/ClangImporter/Inputs/c-bridging-header.h b/test/ClangImporter/Inputs/c-bridging-header.h new file mode 100644 index 0000000000000..5dc00a6d1a586 --- /dev/null +++ b/test/ClangImporter/Inputs/c-bridging-header.h @@ -0,0 +1,12 @@ +#ifndef C_BRIDGING_HEADER_H +#define C_BRIDGING_HEADER_H + +#include "ctypes.h" +#include "macros.h" + +typedef struct { + double x, y; +} MyPoint; + +typedef double MyDouble; +#endif diff --git a/test/ClangImporter/Inputs/cxx-bridging-header.h b/test/ClangImporter/Inputs/cxx-bridging-header.h new file mode 100644 index 0000000000000..d792ba4ecc409 --- /dev/null +++ b/test/ClangImporter/Inputs/cxx-bridging-header.h @@ -0,0 +1,9 @@ + +namespace OuterNS { + class MyPoint { + public: + double x, y; + }; +} + +#include "cxx-outer-ns.h" diff --git a/test/ClangImporter/Inputs/cxx-outer-ns.h b/test/ClangImporter/Inputs/cxx-outer-ns.h new file mode 100644 index 0000000000000..d9d78404852f4 --- /dev/null +++ b/test/ClangImporter/Inputs/cxx-outer-ns.h @@ -0,0 +1,7 @@ +namespace OuterNS { + enum Color { + red, + green, + blue + }; +} diff --git a/test/ClangImporter/Inputs/module.modulemap b/test/ClangImporter/Inputs/module.modulemap new file mode 100644 index 0000000000000..296486613ab8c --- /dev/null +++ b/test/ClangImporter/Inputs/module.modulemap @@ -0,0 +1,3 @@ +module CXXOuterNS { + header "cxx-outer-ns.h" +} diff --git a/test/ClangImporter/InternalBridgingHeader/access_checking.swift b/test/ClangImporter/InternalBridgingHeader/access_checking.swift new file mode 100644 index 0000000000000..237536cec4ef7 --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/access_checking.swift @@ -0,0 +1,39 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/tmp + +// Test with the normal bridging header. +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk + +// Test with a precompiled bridging header. +// RUN: %target-swift-frontend -emit-pch -o %t/c-bridging-header.pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %t/c-bridging-header.pch -sdk %clang-importer-sdk + + +// Overrides the internal import that comes through the bridging header. +public import macros + +public func getRed() -> Color { red } // expected-error{{function cannot be declared public because its result uses an internal type}} +// expected-note@-1{{struct 'Color' is imported by this file as 'internal' from bridging header}} + +public func getX(point: MyPoint) -> Double { point.x } // expected-error{{function cannot be declared public because its parameter uses an internal type}} +// expected-note@-1{{struct 'MyPoint' is imported by this file as 'internal' from bridging header}} + +// Comes from the macros module. +public func returnsFromMacrosModule() -> okay_t { 0 } + +public protocol P { + associatedtype A +} + +public struct MyType: P { + public typealias A = MyDouble + // expected-error@-1{{type alias cannot be declared public because its underlying type uses an internal type}} + // expected-note@-2{{type alias 'MyDouble' is imported by this file as 'internal' from bridging header}} +} + +// expected-error@+1{{cannot use struct 'MyPoint' in an extension with public or '@usableFromInline' members; it was imported via the internal bridging header}} +extension MyPoint: P { + public typealias A = MyDouble + // expected-error@-1{{type alias cannot be declared public because its underlying type uses an internal type}} + // expected-note@-2{{type alias 'MyDouble' is imported by this file as 'internal' from bridging header}} +} diff --git a/test/ClangImporter/InternalBridgingHeader/access_checking_cxx.swift b/test/ClangImporter/InternalBridgingHeader/access_checking_cxx.swift new file mode 100644 index 0000000000000..fb355fd625db5 --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/access_checking_cxx.swift @@ -0,0 +1,9 @@ +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/cxx-bridging-header.h -sdk %clang-importer-sdk -cxx-interoperability-mode=default -I %S/../Inputs + +public func getRed() -> OuterNS.Color { OuterNS.red } +// expected-error@-1{{function cannot be declared public because its result uses an internal type}} +// expected-note@-2{{enum 'OuterNS' is imported by this file as 'internal' from bridging header}} + +public func getX(point: OuterNS.MyPoint) -> Double { point.x } +// expected-error@-1{{function cannot be declared public because its parameter uses an internal type}} +// expected-note@-2{{enum 'OuterNS' is imported by this file as 'internal' from bridging header}} diff --git a/test/ClangImporter/InternalBridgingHeader/implementation_only_checking.swift b/test/ClangImporter/InternalBridgingHeader/implementation_only_checking.swift new file mode 100644 index 0000000000000..ba10fe9969c62 --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/implementation_only_checking.swift @@ -0,0 +1,21 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/tmp + +// Test with the normal bridging header. +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk -verify-ignore-unknown + +// RUN: not %target-swift-frontend -typecheck -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk %s 2>&1 | %FileCheck %s + +// Test with a precompiled bridging header. +// RUN: %target-swift-frontend -emit-pch -o %t/c-bridging-header.pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %t/c-bridging-header.pch -sdk %clang-importer-sdk -verify-ignore-unknown + + +@inlinable +public func f() -> Any { + return red + // expected-error@-1{{var 'red' is internal and cannot be referenced from an '@inlinable' function}} + // expected-warning@-2{{getter for var 'red' is internal and should not be referenced from an '@inlinable' function}} +} + +// CHECK: var 'red' imported as 'internal' from bridging header diff --git a/test/ClangImporter/InternalBridgingHeader/interface.swift b/test/ClangImporter/InternalBridgingHeader/interface.swift new file mode 100644 index 0000000000000..f6ea1825348fe --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/interface.swift @@ -0,0 +1,14 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-swift-emit-module-interface(%t/MyModule.swiftinterface) %s -module-name MyModule -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk -enable-library-evolution + +// RUN: %FileCheck %s < %t/MyModule.swiftinterface + +// CHECK-NOT: internal-import-bridging-header + +// CHECK: public func g() + +func getX(point: MyPoint) -> Double { point.x } + +public func g() { +} diff --git a/test/ClangImporter/InternalBridgingHeader/library_evolution.swift b/test/ClangImporter/InternalBridgingHeader/library_evolution.swift new file mode 100644 index 0000000000000..df3b9de4bf58e --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/library_evolution.swift @@ -0,0 +1,14 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk %s 2>&1 | %FileCheck -check-prefix NONRESILIENT %s + +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk %s -enable-library-evolution 2>&1 | %FileCheck -check-prefix EVOLUTION %s + +// NONRESILIENT: warning: using internal bridging headers without library evolution can cause instability + +// EVOLUTION-NOT: internal bridging head + +@available(*, deprecated) +func f() { } + +func g(){ + f() // make sure we emit something +} diff --git a/test/ClangImporter/InternalBridgingHeader/pch.swift b/test/ClangImporter/InternalBridgingHeader/pch.swift new file mode 100644 index 0000000000000..d0b65ffe8a993 --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/pch.swift @@ -0,0 +1,52 @@ +// RUN: %empty-directory(%t) +// RUN: mkdir -p %t/tmp + +// First test the explicit frontend-based bridging PCH generation and use works +// RUN: %target-swift-frontend -emit-pch -o %t/c-bridging-header.pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %t/c-bridging-header.pch -sdk %clang-importer-sdk + +// Now test the driver-automated version is inert when disabled +// Output path of the PCH differs in the new driver, so force SWIFT_USE_OLD_DRIVER for now. +// RUN: env TMPDIR=%t/tmp/ SWIFT_USE_OLD_DRIVER=1 %target-swiftc_driver -typecheck -disable-bridging-pch -save-temps %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: not ls %t/tmp/*.pch >/dev/null 2>&1 + +// Test the driver-automated version works by default +// Output path of the PCH differs in the new driver, so force SWIFT_USE_OLD_DRIVER for now. +// RUN: env TMPDIR=%t/tmp/ SWIFT_USE_OLD_DRIVER=1 %target-swiftc_driver -typecheck -save-temps %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: ls %t/tmp/*.pch >/dev/null 2>&1 +// RUN: llvm-objdump --raw-clang-ast %t/tmp/*.pch | llvm-bcanalyzer -dump | %FileCheck %s +// CHECK: ORIGINAL_FILE{{.*}}Inputs/c-bridging-header.h + +// Test the driver-automated version deletes its PCH file when done +// RUN: rm %t/tmp/*.pch +// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -typecheck %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: not ls %t/tmp/*.pch >/dev/null 2>&1 + +// Test -emit-pch invocation but with a persistent PCH +// RUN: %target-swift-frontend -emit-pch -pch-output-dir %t/pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch -pch-disable-validation -sdk %clang-importer-sdk +// RUN: ls %t/pch/*.pch >/dev/null 2>&1 + +// Test implicit use of persistent PCH +// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch2 -sdk %clang-importer-sdk +// RUN: ls %t/pch2/*.pch >/dev/null 2>&1 + +// RUN: touch %t/header.with.dot.h +// RUN: touch %t/test.swift +// RUN: %target-swift-frontend -typecheck %t/test.swift -internal-import-bridging-header %t/header.with.dot.h -pch-output-dir %t/pch_with_dot -module-cache-path %t/mcp1 -sdk %clang-importer-sdk +// RUN: %target-swift-frontend -typecheck %t/test.swift -internal-import-bridging-header %t/header.with.dot.h -pch-output-dir %t/pch_with_dot -module-cache-path %t/mcp2 -sdk %clang-importer-sdk +// RUN: ls %t/pch_with_dot/*swift*clang*.pch | count 2 + +// Test the driver-automated version using persistent PCH +// RUN: %target-swiftc_driver -typecheck -save-temps %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch3 -sdk %clang-importer-sdk +// RUN: ls %t/pch3/*.pch >/dev/null 2>&1 +// RUN: llvm-objdump --raw-clang-ast %t/pch3/*.pch | llvm-bcanalyzer -dump | %FileCheck %s -check-prefix=PERSISTENT +// PERSISTENT: ORIGINAL_FILE{{.*}}Inputs/c-bridging-header.h + +// Test that -pch-disable-validation works in that it won't implicitly create a PCH +// RUN: not %target-swift-frontend -typecheck %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/no-pch -pch-disable-validation -sdk %clang-importer-sdk 2>&1 | %FileCheck %s -check-prefix=NO-VALIDATION +// NO-VALIDATION: PCH file {{.*}} not found + +// UNSUPPORTED: OS=windows-msvc + +func getX(point: MyPoint) -> Double { point.x } diff --git a/test/ClangImporter/InternalBridgingHeader/serialization.swift b/test/ClangImporter/InternalBridgingHeader/serialization.swift new file mode 100644 index 0000000000000..499d2b883a4ce --- /dev/null +++ b/test/ClangImporter/InternalBridgingHeader/serialization.swift @@ -0,0 +1,48 @@ +// RUN: %empty-directory(%t) + +// Stage in the headers we need +// RUN: mkdir %t/headers +// RUN: cp %S/../Inputs/c-bridging-header.h %t/headers + +// RUN: mkdir %t/src +// RUN: split-file %s %t/src + +// Build a module +// RUN: mkdir %t/modules +// RUN: %target-swift-frontend -internal-import-bridging-header %t/headers/c-bridging-header.h -sdk %clang-importer-sdk -emit-module -o %t/modules/MyModule.swiftmodule %t/src/MyModule.swift + +// Check that there's no serialized bridging header in the module file. +// RUN: llvm-bcanalyzer -dump %t/modules/MyModule.swiftmodule | %FileCheck -check-prefix MODULE-FILE %s + +// Use the module. +// RUN: %target-swift-frontend -typecheck -sdk %clang-importer-sdk -I %t/modules %t/src/MyClient.swift + +// Delete the bridging header, and again use the module. +// RUN: rm %t/headers/c-bridging-header.h +// RUN: %target-swift-frontend -typecheck -sdk %clang-importer-sdk -I %t/modules %t/src/MyClient.swift + +//--- MyModule.swift +func getRed() -> Color { red } + +func getX(point: MyPoint) -> Double { point.x } + +public func f() { + _ = getRed() +} + +//--- MyClient.swift + +import MyModule + +func g() { + f() +} + + +// MODULE-FILE-NOT: IMPORTED_HEADER +// MODULE-FILE-NOT: IMPORTED_HEADER_CONTENTS + +// MODULE-FILE: SEARCH_PATH + +// MODULE-FILE-NOT: IMPORTED_HEADER +// MODULE-FILE-NOT: IMPORTED_HEADER_CONTENTS diff --git a/test/Driver/bridging-pch.swift b/test/Driver/bridging-pch.swift index 522303fe7c82d..2f50b15d3a36d 100644 --- a/test/Driver/bridging-pch.swift +++ b/test/Driver/bridging-pch.swift @@ -6,63 +6,63 @@ // YESPCHACT: 2: input, "{{.*}}bridging-pch.swift", swift // YESPCHACT: 3: compile, {2, 1}, none -// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-actions -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=NOPCHACT +// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-actions -import-bridging-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=NOPCHACT // NOPCHACT: 0: input, "{{.*}}bridging-pch.swift", swift // NOPCHACT: 1: compile, {0}, none -// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=YESPCHJOB +// RUN: %target-build-swift -typecheck -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=YESPCHJOB // YESPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -emit-pch -o {{.*}}bridging-header-{{.*}}.pch -// YESPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -import-objc-header {{.*}}bridging-header-{{.*}}.pch +// YESPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -import-bridging-header {{.*}}bridging-header-{{.*}}.pch -// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB -// NOPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -import-objc-header {{.*}}Inputs/bridging-header.h +// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB +// NOPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -import-bridging-header {{.*}}Inputs/bridging-header.h -// RUN: %target-build-swift -typecheck -driver-print-jobs -index-store-path %t/idx -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=INDEXSTORE +// RUN: %target-build-swift -typecheck -driver-print-jobs -index-store-path %t/idx -import-bridging-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=INDEXSTORE // INDEXSTORE: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -index-store-path {{.*}}/idx{{"?}} -emit-pch -o {{.*}}bridging-header-{{.*}}.pch // RUN: echo "{\"\": {\"swift-dependencies\": \"%/t/master.swiftdeps\"}, \"%/s\": {\"swift-dependencies\": \"%/t/bridging-header.swiftdeps\"}}" > %t.json -// RUN: %target-build-swift -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-objc-header %S/Inputs/bridging-header.h %s +// RUN: %target-build-swift -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-bridging-header %S/Inputs/bridging-header.h %s // RUN: mkdir %t/tmp -// RUN: env TMP="%t/tmp/" TMPDIR="%t/tmp/" not %target-build-swift -typecheck -import-objc-header %S/../Inputs/empty.h -driver-use-frontend-path "%{python.unquoted};%S/Inputs/crash-after-generating-pch.py" -v %s +// RUN: env TMP="%t/tmp/" TMPDIR="%t/tmp/" not %target-build-swift -typecheck -import-bridging-header %S/../Inputs/empty.h -driver-use-frontend-path "%{python.unquoted};%S/Inputs/crash-after-generating-pch.py" -v %s // RUN: ls %/t/tmp/ | grep .*pch // Test persistent PCH -// RUN: %target-build-swift -typecheck -driver-print-actions -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHACT +// RUN: %target-build-swift -typecheck -driver-print-actions -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHACT // PERSISTENT-YESPCHACT: 0: input, "{{.*}}Inputs/bridging-header.h", clang-header // PERSISTENT-YESPCHACT: 1: generate-pch, {0}, none // PERSISTENT-YESPCHACT: 2: input, "{{.*}}bridging-pch.swift", swift // PERSISTENT-YESPCHACT: 3: compile, {2, 1}, none -// RUN: %target-build-swift -c -driver-print-actions -embed-bitcode -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHACTBC +// RUN: %target-build-swift -c -driver-print-actions -embed-bitcode -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHACTBC // PERSISTENT-YESPCHACTBC: 0: input, "{{.*}}Inputs/bridging-header.h", clang-header // PERSISTENT-YESPCHACTBC: 1: generate-pch, {0}, none // PERSISTENT-YESPCHACTBC: 2: input, "{{.*}}bridging-pch.swift", swift // PERSISTENT-YESPCHACTBC: 3: compile, {2, 1}, llvm-bc -// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-actions -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=NOPCHACT +// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-actions -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=NOPCHACT -// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -disable-bridging-pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-DISABLED-YESPCHJOB -// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -whole-module-optimization -disable-bridging-pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-DISABLED-YESPCHJOB +// RUN: %target-build-swift -typecheck -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -disable-bridging-pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-DISABLED-YESPCHJOB +// RUN: %target-build-swift -typecheck -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -whole-module-optimization -disable-bridging-pch %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-DISABLED-YESPCHJOB // PERSISTENT-DISABLED-YESPCHJOB-NOT: -pch-output-dir -// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -serialize-diagnostics %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG1 +// RUN: %target-build-swift -typecheck -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -serialize-diagnostics %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG1 // PERSISTENT-YESPCHJOB-DIAG1: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -serialize-diagnostics-path {{.*}}bridging-header-{{.*}}.dia{{"?}} {{.*}} -emit-pch -pch-output-dir {{.*}}/pch -// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch-out-dir -serialize-diagnostics %s -emit-module -emit-module-path /module-path-dir 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG2 +// RUN: %target-build-swift -typecheck -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch-out-dir -serialize-diagnostics %s -emit-module -emit-module-path /module-path-dir 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-YESPCHJOB-DIAG2 // PERSISTENT-YESPCHJOB-DIAG2: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -serialize-diagnostics-path {{.*}}/pch-out-dir{{/|\\\\}}bridging-header-{{.*}}.dia{{"?}} {{.*}} -emit-pch -pch-output-dir {{.*}}/pch-out-dir -// RUN: %target-build-swift -typecheck -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -parseable-output -driver-skip-execution %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-OUTPUT +// RUN: %target-build-swift -typecheck -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -parseable-output -driver-skip-execution %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-OUTPUT // PERSISTENT-OUTPUT-NOT: "outputs": [ -// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -whole-module-optimization %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-WMO-YESPCHJOB --implicit-check-not pch-disable-validation -// PERSISTENT-WMO-YESPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -import-objc-header {{.*}}bridging-header.h{{"?}} -pch-output-dir {{.*}}/pch +// RUN: %target-build-swift -typecheck -driver-print-jobs -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -whole-module-optimization %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-WMO-YESPCHJOB --implicit-check-not pch-disable-validation +// PERSISTENT-WMO-YESPCHJOB: {{.*}}swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend {{.*}} -import-bridging-header {{.*}}bridging-header.h{{"?}} -pch-output-dir {{.*}}/pch -// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-jobs -import-objc-header %/S/Inputs/bridging-header.h -pch-output-dir %t/pch %/s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB -// RUN: %target-build-swift -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s +// RUN: %target-build-swift -typecheck -disable-bridging-pch -driver-print-jobs -import-bridging-header %/S/Inputs/bridging-header.h -pch-output-dir %t/pch %/s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB +// RUN: %target-build-swift -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-bridging-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s -// RUN: %target-build-swift -### -typecheck -O -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=OPTPCH +// RUN: %target-build-swift -### -typecheck -O -import-bridging-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=OPTPCH // OPTPCH: swift{{(c|c-legacy-driver|-frontend)?(\.exe)?"?}} -frontend // OPTPCH-SAME: -O{{ }} // OPTPCH-SAME: -emit-pch diff --git a/test/Driver/working-directory.swift b/test/Driver/working-directory.swift index 26919e89d6472..b5ab72fab7f65 100644 --- a/test/Driver/working-directory.swift +++ b/test/Driver/working-directory.swift @@ -32,10 +32,10 @@ // RUN: cd %t && %swiftc_driver -driver-print-jobs -working-directory %/S/Inputs -emit-executable %/s -L=. | %FileCheck %s -check-prefix=L_PATH // L_PATH: -L {{"?}}SOURCE_DIR/test/Driver/Inputs -// RUN: cd %t && %swiftc_driver -driver-print-jobs -working-directory %/S/Inputs -c %/s -disable-bridging-pch -import-objc-header bridging-header.h | %FileCheck %s -check-prefix=OBJC_HEADER1 -// OBJC_HEADER1: -import-objc-header {{"?}}SOURCE_DIR/test/Driver/Inputs{{/|\\\\}}bridging-header.h +// RUN: cd %t && %swiftc_driver -driver-print-jobs -working-directory %/S/Inputs -c %/s -disable-bridging-pch -import-bridging-header bridging-header.h | %FileCheck %s -check-prefix=OBJC_HEADER1 +// OBJC_HEADER1: -import-bridging-header {{"?}}SOURCE_DIR/test/Driver/Inputs{{/|\\\\}}bridging-header.h -// RUN: cd %t && %swiftc_driver -driver-print-jobs -working-directory %/S/Inputs -c %/s -enable-bridging-pch -import-objc-header bridging-header.h | %FileCheck %s -check-prefix=OBJC_HEADER2 +// RUN: cd %t && %swiftc_driver -driver-print-jobs -working-directory %/S/Inputs -c %/s -enable-bridging-pch -import-bridging-header bridging-header.h | %FileCheck %s -check-prefix=OBJC_HEADER2 // OBJC_HEADER2: SOURCE_DIR/test/Driver/Inputs{{/|\\\\}}bridging-header.h{{"? .*}}-emit-pch // RUN: cd %t && %swiftc_driver -driver-print-jobs -working-directory %/S/Inputs -c %/s -o main.o | %FileCheck %s -check-prefix=OUTPUT_OBJ