Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/swift/AST/DiagnosticsFrontend.def
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,11 @@ ERROR(package_cmo_requires_library_evolution, none,
WARNING(internal_bridging_header_without_library_evolution,none,
"using internal bridging headers without library evolution can cause instability", ())

ERROR(error_invalid_clang_header_access_level, none,
"invalid minimum clang header access level '%0'; chose from "
"'public'|'package'|'internal'",
(StringRef))

ERROR(experimental_not_supported_in_production,none,
"experimental feature '%0' cannot be enabled in production compiler",
(StringRef))
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef SWIFT_FRONTEND_FRONTENDOPTIONS_H
#define SWIFT_FRONTEND_FRONTENDOPTIONS_H

#include "swift/AST/AttrKind.h"
#include "swift/Basic/FileTypes.h"
#include "swift/Basic/PathRemapper.h"
#include "swift/Basic/Version.h"
Expand Down Expand Up @@ -501,6 +502,10 @@ class FrontendOptions {
/// header.
std::optional<ClangHeaderExposeBehavior> ClangHeaderExposedDecls;

// Include declarations that are at least as visible as the acces specified
// by -emit-clang-header-min-access
std::optional<AccessLevel> ClangHeaderMinAccess;

struct ClangHeaderExposedImportedModule {
std::string moduleName;
std::string headerName;
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,11 @@ def emit_clang_header_path : Separate<["-"], "emit-clang-header-path">,
HelpText<"Emit an Objective-C and C++ header file to <path>">,
Alias<emit_objc_header_path>;

def emit_clang_header_min_access : Separate<["-"], "emit-clang-header-min-access">,
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath, CacheInvariant]>,
MetaVarName<"<access-level>">,
HelpText<"The minimum access level of declarations to include in the emitted header.>">;

def static : Flag<["-"], "static">,
Flags<[FrontendOption, ModuleInterfaceOption, NoInteractiveOption]>,
HelpText<"Make this module statically linkable and make the output of -emit-library a static library.">;
Expand Down
20 changes: 16 additions & 4 deletions lib/Frontend/ArgsToFrontendOptionsConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include "ArgsToFrontendInputsConverter.h"
#include "ArgsToFrontendOutputsConverter.h"
#include "clang/Driver/Driver.h"
#include "swift/AST/AttrKind.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Platform.h"
Expand All @@ -24,18 +24,19 @@
#include "swift/Parse/Lexer.h"
#include "swift/Parse/ParseVersion.h"
#include "swift/Strings.h"
#include "clang/Driver/Driver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/CAS/ObjectStore.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/PrefixMapper.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrefixMapper.h"
#include "llvm/Support/Process.h"
#include "llvm/TargetParser/Triple.h"

using namespace swift;
using namespace llvm::opt;
Expand Down Expand Up @@ -400,6 +401,17 @@ bool ArgsToFrontendOptionsConverter::convert(
HasExposeAttrOrImplicitDeps)
.Default(std::nullopt);
}
if (const Arg *A = Args.getLastArg(OPT_emit_clang_header_min_access)) {
Opts.ClangHeaderMinAccess =
llvm::StringSwitch<std::optional<AccessLevel>>(A->getValue())
.Case("public", AccessLevel::Public)
.Case("package", AccessLevel::Package)
.Case("internal", AccessLevel::Internal)
.Default(std::nullopt);
if (!Opts.ClangHeaderMinAccess)
Diags.diagnose(SourceLoc(), diag::error_invalid_clang_header_access_level,
A->getValue());
}
for (const auto &arg :
Args.getAllArgValues(options::OPT_clang_header_expose_module)) {
auto splitArg = StringRef(arg).split('=');
Expand Down
25 changes: 17 additions & 8 deletions lib/PrintAsClang/ModuleContentsWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "PrintSwiftToClangCoreScaffold.h"
#include "SwiftToClangInteropContext.h"

#include "swift/AST/AttrKind.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/ExistentialLayout.h"
Expand Down Expand Up @@ -1151,35 +1152,43 @@ class ModuleWriter {
};
} // end anonymous namespace

static AccessLevel getRequiredAccess(const ModuleDecl &M) {
static AccessLevel getRequiredAccess(const ModuleDecl &M,
std::optional<AccessLevel> minAccess) {
if (minAccess)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have brought this up last time, but since you're writing this in a way that affects ObjC generated headers, would you be willing to add test cases for that?

I took a look and I think you'd get adequate coverage by just adding another set of RUN lines to test/PrintAsObjC/accessibility.swift:

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -application-extension-library -emit-clang-header-min-access internal -typecheck -verify -emit-objc-header-path %t/accessibility-explicit-internal.h -disable-objc-attr-requires-foundation-module
// RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-INTERNAL %s < %t/accessibility-explicit-internal.h
// RUN: %check-in-clang %t/accessibility-explicit-internal.h

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -application-extension -emit-clang-header-min-access public -typecheck -verify -emit-objc-header-path %t/accessibility-explicit-public.h -disable-objc-attr-requires-foundation-module
// RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PUBLIC %s < %t/accessibility-explicit-public.h
// RUN: %check-in-clang %t/accessibility-explicit-public.h

This test is already set up to exercise all the heuristics; we're just adding another pair of cases that override the heuristics with your new flag.

Assuming that passes, that's the only issue I see at this point—feel free to merge once it's resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added these tests and they pass. Thanks a lot! Will merge this PR, but I am also happy to address if anything comes up post-merge.

return *minAccess;
return M.isExternallyConsumed() ? AccessLevel::Public : AccessLevel::Internal;
}

void swift::printModuleContentsAsObjC(
raw_ostream &os, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
ModuleDecl &M, SwiftToClangInteropContext &interopContext) {
ModuleDecl &M, SwiftToClangInteropContext &interopContext,
std::optional<AccessLevel> minAccess) {
llvm::raw_null_ostream prologueOS;
llvm::StringSet<> exposedModules;
ModuleWriter(os, prologueOS, imports, M, interopContext, getRequiredAccess(M),
ModuleWriter(os, prologueOS, imports, M, interopContext,
getRequiredAccess(M, minAccess),
/*requiresExposedAttribute=*/false, exposedModules,
OutputLanguageMode::ObjC)
.write();
}

void swift::printModuleContentsAsC(
raw_ostream &os, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
ModuleDecl &M, SwiftToClangInteropContext &interopContext) {
ModuleDecl &M, SwiftToClangInteropContext &interopContext,
std::optional<AccessLevel> minAccess) {
llvm::raw_null_ostream prologueOS;
llvm::StringSet<> exposedModules;
ModuleWriter(os, prologueOS, imports, M, interopContext, getRequiredAccess(M),
ModuleWriter(os, prologueOS, imports, M, interopContext,
getRequiredAccess(M, minAccess),
/*requiresExposedAttribute=*/false, exposedModules,
OutputLanguageMode::C)
.write();
}

EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(
raw_ostream &os, ModuleDecl &M, SwiftToClangInteropContext &interopContext,
bool requiresExposedAttribute, llvm::StringSet<> &exposedModules) {
AccessLevel minAccess, bool requiresExposedAttribute,
llvm::StringSet<> &exposedModules) {
std::string moduleContentsBuf;
llvm::raw_string_ostream moduleOS{moduleContentsBuf};
std::string modulePrologueBuf;
Expand All @@ -1197,8 +1206,8 @@ EmittedClangHeaderDependencyInfo swift::printModuleContentsAsCxx(

// FIXME: Use getRequiredAccess once @expose is supported.
ModuleWriter writer(moduleOS, prologueOS, info.imports, M, interopContext,
AccessLevel::Public, requiresExposedAttribute,
exposedModules, OutputLanguageMode::Cxx);
minAccess, requiresExposedAttribute, exposedModules,
OutputLanguageMode::Cxx);
writer.write();
info.dependsOnStandardLibrary = writer.isStdlibRequired();
if (M.isStdlibModule()) {
Expand Down
14 changes: 9 additions & 5 deletions lib/PrintAsClang/ModuleContentsWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ using ImportModuleTy = PointerUnion<ModuleDecl*, const clang::Module*>;
void printModuleContentsAsObjC(raw_ostream &os,
llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
ModuleDecl &M,
SwiftToClangInteropContext &interopContext);
SwiftToClangInteropContext &interopContext,
std::optional<AccessLevel> minAccess);

void printModuleContentsAsC(raw_ostream &os,
llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
ModuleDecl &M,
SwiftToClangInteropContext &interopContext);
SwiftToClangInteropContext &interopContext,
std::optional<AccessLevel> minAccess);

struct EmittedClangHeaderDependencyInfo {
/// The set of imported modules used by this module.
Expand All @@ -52,9 +54,11 @@ struct EmittedClangHeaderDependencyInfo {
/// Prints the declarations of \p M to \p os in C++ language mode.
///
/// \returns Dependencies required by this module.
EmittedClangHeaderDependencyInfo printModuleContentsAsCxx(
raw_ostream &os, ModuleDecl &M, SwiftToClangInteropContext &interopContext,
bool requiresExposedAttribute, llvm::StringSet<> &exposedModules);
EmittedClangHeaderDependencyInfo
printModuleContentsAsCxx(raw_ostream &os, ModuleDecl &M,
SwiftToClangInteropContext &interopContext,
AccessLevel minAccess, bool requiresExposedAttribute,
llvm::StringSet<> &exposedModules);

} // end namespace swift

Expand Down
15 changes: 10 additions & 5 deletions lib/PrintAsClang/PrintAsClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "SwiftToClangInteropContext.h"

#include "swift/AST/ASTContext.h"
#include "swift/AST/AttrKind.h"
#include "swift/AST/Module.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/Basic/Assertions.h"
Expand Down Expand Up @@ -620,7 +621,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
if (M->getASTContext().LangOpts.hasFeature(Feature::CDecl)) {
SmallPtrSet<ImportModuleTy, 8> imports;
llvm::raw_string_ostream cModuleContents{moduleContentsScratch};
printModuleContentsAsC(cModuleContents, imports, *M, interopContext);
printModuleContentsAsC(cModuleContents, imports, *M, interopContext,
frontendOpts.ClangHeaderMinAccess);

llvm::StringMap<StringRef> exposedModuleHeaderNames;
writeImports(os, imports, *M, bridgingHeader, frontendOpts,
Expand All @@ -634,7 +636,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
// Objective-C content
SmallPtrSet<ImportModuleTy, 8> imports;
llvm::raw_string_ostream objcModuleContents{moduleContentsScratch};
printModuleContentsAsObjC(objcModuleContents, imports, *M, interopContext);
printModuleContentsAsObjC(objcModuleContents, imports, *M, interopContext,
frontendOpts.ClangHeaderMinAccess);
emitObjCConditional(os, [&] {
llvm::StringMap<StringRef> exposedModuleHeaderNames;
writeImports(os, imports, *M, bridgingHeader, frontendOpts,
Expand Down Expand Up @@ -685,6 +688,7 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
llvm::raw_string_ostream moduleContents{moduleContentsBuf};
auto deps = printModuleContentsAsCxx(
moduleContents, *M, interopContext,
frontendOpts.ClangHeaderMinAccess.value_or(AccessLevel::Public),
/*requiresExposedAttribute=*/requiresExplicitExpose, exposedModules);
// FIXME: In ObjC++ mode, we do not need to reimport duplicate modules.
llvm::StringMap<StringRef> exposedModuleHeaderNames;
Expand All @@ -701,9 +705,10 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
auto macroGuard = computeMacroGuard(M->getASTContext().getStdlibModule());
os << "#ifndef " << macroGuard << "\n";
os << "#define " << macroGuard << "\n";
printModuleContentsAsCxx(
os, *M->getASTContext().getStdlibModule(), interopContext,
/*requiresExposedAttribute=*/true, exposedModules);
printModuleContentsAsCxx(os, *M->getASTContext().getStdlibModule(),
interopContext, AccessLevel::Public,
/*requiresExposedAttribute=*/true,
exposedModules);
os << "#endif // " << macroGuard << "\n";
}

Expand Down
2 changes: 1 addition & 1 deletion lib/PrintAsClang/SwiftToClangInteropContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ SwiftToClangInteropContext::SwiftToClangInteropContext(
ModuleDecl &mod, const IRGenOptions &irGenOpts)
: mod(mod), irGenOpts(irGenOpts) {}

SwiftToClangInteropContext::~SwiftToClangInteropContext() {}
SwiftToClangInteropContext::~SwiftToClangInteropContext() = default;

IRABIDetailsProvider &SwiftToClangInteropContext::getIrABIDetails() {
if (!irABIDetails)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -module-name Core -typecheck -verify -emit-clang-header-path %t/core.h -clang-header-expose-decls=has-expose-attr -emit-clang-header-min-access public -package-name Core
// RUN: %FileCheck %s --check-prefix CHECK-PUBLIC < %t/core.h

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -module-name Core -typecheck -verify -emit-clang-header-path %t/core.h -clang-header-expose-decls=has-expose-attr -emit-clang-header-min-access package -package-name Core
// RUN: %FileCheck %s --check-prefix CHECK-PACKAGE < %t/core.h

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -module-name Core -typecheck -verify -emit-clang-header-path %t/core.h -clang-header-expose-decls=has-expose-attr -emit-clang-header-min-access internal -package-name Core
// RUN: %FileCheck %s --check-prefix CHECK-INTERNAL < %t/core.h

@_expose(Cxx)
public func publicFunc(_ x: Int) -> Int {
return x
}

@_expose(Cxx)
package func packageFunc(_ x: Int) -> Int {
return x
}

@_expose(Cxx)
internal func internalFunc(_ x: Int) -> Int {
return x
}

@_expose(Cxx)
private func privateFunc(_ x: Int) -> Int {
return x
}

// CHECK-PUBLIC-NOT: internalFunc
// CHECK-PUBLIC-NOT: packageFunc
// CHECK-PUBLIC-NOT: privateFunc
// CHECK-PUBLIC: SWIFT_INLINE_THUNK swift::Int publicFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core10publicFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {

// CHECK-PACKAGE-NOT: internalFunc
// CHECK-PACKAGE: SWIFT_INLINE_THUNK swift::Int packageFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core11packageFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-PACKAGE-NOT: privateFunc
// CHECK-PACKAGE: SWIFT_INLINE_THUNK swift::Int publicFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core10publicFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {

// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int internalFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core12internalFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int packageFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core11packageFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-INTERNAL-NOT: privateFunc
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int publicFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core10publicFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
79 changes: 79 additions & 0 deletions test/Interop/SwiftToCxx/core/set-min-access-level.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -module-name Core -typecheck -verify -emit-clang-header-path %t/core.h -clang-header-expose-decls=all-public -emit-clang-header-min-access public -package-name Core
// RUN: %FileCheck %s --check-prefix CHECK-PUBLIC < %t/core.h

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -module-name Core -typecheck -verify -emit-clang-header-path %t/core.h -clang-header-expose-decls=all-public -emit-clang-header-min-access package -package-name Core
// RUN: %FileCheck %s --check-prefix CHECK-PACKAGE < %t/core.h

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend %s -module-name Core -typecheck -verify -emit-clang-header-path %t/core.h -clang-header-expose-decls=all-public -emit-clang-header-min-access internal -package-name Core
// RUN: %FileCheck %s --check-prefix CHECK-INTERNAL < %t/core.h

// RUN: %empty-directory(%t)
// RUN: not %target-swift-frontend %s -module-name Core -typecheck -emit-clang-header-path %t/core.h -clang-header-expose-decls=all-public -emit-clang-header-min-access inernal -package-name Core 2>&1 | %FileCheck %s --check-prefix CHECK-DIAGNOSTIC

public func publicFunc(_ x: Int) -> Int {
return x
}

package func packageFunc(_ x: Int) -> Int {
return x
}

internal func internalFunc(_ x: Int) -> Int {
return x
}

private func privateFunc(_ x: Int) -> Int {
return x
}

public struct S {
public func publicMethod(_ x: Int) -> Int {
return x
}

package func packageMethod(_ x: Int) -> Int {
return x
}

internal func internalMethod(_ x: Int) -> Int {
return x
}

private func privateMethod(_ x: Int) -> Int {
return x
}

private var x: Int
}

// CHECK-PUBLIC-NOT: internalFunc
// CHECK-PUBLIC-NOT: packageFunc
// CHECK-PUBLIC-NOT: privateFunc
// CHECK-PUBLIC: SWIFT_INLINE_THUNK swift::Int publicFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core10publicFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-PUBLIC: SWIFT_INLINE_THUNK swift::Int S::publicMethod(swift::Int x) const {
// CHECK-PUBLIC-NOT: packageMethod
// CHECK-PUBLIC-NOT: internalMethod
// CHECK-PUBLIC-NOT: privateMethod

// CHECK-PACKAGE-NOT: internalFunc
// CHECK-PACKAGE: SWIFT_INLINE_THUNK swift::Int packageFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core11packageFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-PACKAGE-NOT: privateFunc
// CHECK-PACKAGE: SWIFT_INLINE_THUNK swift::Int publicFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core10publicFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-PACKAGE: SWIFT_INLINE_THUNK swift::Int S::publicMethod(swift::Int x) const {
// CHECK-PACKAGE: SWIFT_INLINE_THUNK swift::Int S::packageMethod(swift::Int x) const {
// CHECK-PACKAGE-NOT: internalMethod
// CHECK-PACKAGE-NOT: privateMethod

// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int internalFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core12internalFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int packageFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core11packageFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-INTERNAL-NOT: privateFunc
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int publicFunc(swift::Int x) noexcept SWIFT_SYMBOL("s:4Core10publicFuncyS2iF") SWIFT_WARN_UNUSED_RESULT {
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int S::publicMethod(swift::Int x) const {
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int S::packageMethod(swift::Int x) const {
// CHECK-INTERNAL: SWIFT_INLINE_THUNK swift::Int S::internalMethod(swift::Int x) const {
// CHECK-INTERNAL-NOT: privateMethod

// CHECK-DIAGNOSTIC: error: invalid minimum clang header access level 'inernal'; chose from 'public'|'package'|'internal'
8 changes: 8 additions & 0 deletions test/PrintAsObjC/accessibility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
// RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PUBLIC %s < %t/accessibility-appextlib.h
// RUN: %check-in-clang %t/accessibility-appextlib.h

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -application-extension-library -emit-clang-header-min-access internal -typecheck -verify -emit-objc-header-path %t/accessibility-explicit-internal.h -disable-objc-attr-requires-foundation-module
// RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-INTERNAL %s < %t/accessibility-explicit-internal.h
// RUN: %check-in-clang %t/accessibility-explicit-internal.h

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse-as-library %s -application-extension -emit-clang-header-min-access public -typecheck -verify -emit-objc-header-path %t/accessibility-explicit-public.h -disable-objc-attr-requires-foundation-module
// RUN: %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PUBLIC %s < %t/accessibility-explicit-public.h
// RUN: %check-in-clang %t/accessibility-explicit-public.h

// REQUIRES: objc_interop

// CHECK: #ifndef ACCESSIBILITY_SWIFT_H
Expand Down