Skip to content

Commit b13c2ae

Browse files
committed
Treat internally-imported bridging headers as internally-imported
When using an internal import for a bridging header, semantically treat the contents of the bridging header, and anything that it imports, as if they were imported internally. This is the actual semantic behavior we wanted from internally-imported bridging headers. This is the main semantic checking bit for rdar://74011750.
1 parent 2383d7a commit b13c2ae

File tree

8 files changed

+59
-18
lines changed

8 files changed

+59
-18
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,8 +2707,8 @@ NOTE(decl_import_via_here,none,
27072707
NOTE(decl_import_via_local,none,
27082708
"%kind0 is imported by this file as "
27092709
"'%select{private|fileprivate|internal|package|%ERROR|%ERROR}1' "
2710-
"from %2",
2711-
(const Decl *, AccessLevel, const ModuleDecl*))
2710+
"from %select{%2|bridging header}3",
2711+
(const Decl *, AccessLevel, const ModuleDecl*, bool))
27122712

27132713
// Opaque return types
27142714
ERROR(opaque_type_invalid_constraint,none,

lib/AST/Module.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2991,7 +2991,9 @@ SourceFile::getImportAccessLevel(const ModuleDecl *targetModule) const {
29912991
// they are recommended over indirect imports.
29922992
if ((!restrictiveImport.has_value() ||
29932993
restrictiveImport->accessLevel < AccessLevel::Public) &&
2994-
imports.isImportedBy(targetModule, getParentModule()))
2994+
!(restrictiveImport &&
2995+
restrictiveImport->module.importedModule->isClangHeaderImportModule()) &&
2996+
imports.isImportedBy(targetModule, getParentModule()))
29952997
return std::nullopt;
29962998

29972999
return restrictiveImport;

lib/ClangImporter/ClangImporter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3763,8 +3763,14 @@ ImportDecl *swift::createImportDecl(ASTContext &Ctx,
37633763
auto *ID = ImportDecl::create(Ctx, DC, SourceLoc(),
37643764
ImportKind::Module, SourceLoc(),
37653765
importPath.get(), ClangN);
3766-
if (IsExported)
3766+
if (Ctx.ClangImporterOpts.BridgingHeaderIsInternal) {
3767+
ID->getAttrs().add(
3768+
new (Ctx) AccessControlAttr(SourceLoc(), SourceRange(),
3769+
AccessLevel::Internal, /*implicit=*/true));
3770+
ID->getAttrs().add(new (Ctx) ImplementationOnlyAttr(/*IsImplicit=*/true));
3771+
} else if (IsExported) {
37673772
ID->getAttrs().add(new (Ctx) ExportedAttr(/*IsImplicit=*/false));
3773+
}
37683774
return ID;
37693775
}
37703776

lib/Sema/ImportResolution.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,14 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator,
574574
!clangImporter->importBridgingHeader(bridgingHeaderPath, module)) {
575575
auto *headerModule = clangImporter->getImportedHeaderModule();
576576
assert(headerModule && "Didn't load bridging header?");
577-
imports.emplace_back(
577+
AttributedImport<ImportedModule> import(
578578
ImportedModule(headerModule), SourceLoc(), ImportFlags::Exported);
579+
if (ctx.ClangImporterOpts.BridgingHeaderIsInternal) {
580+
import.accessLevel = AccessLevel::Internal;
581+
import.options |= ImportFlags::ImplementationOnly;
582+
}
583+
584+
imports.emplace_back(import);
579585
}
580586

581587
// Implicitly import the underlying Clang half of this module if needed.

lib/Sema/TypeCheckAccess.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,9 @@ static void noteLimitingImport(const Decl *userDecl, ASTContext &ctx,
454454
if (userDecl)
455455
userDecl->diagnose(diag::decl_import_via_local, complainDecl,
456456
limitImport->accessLevel,
457-
limitImport->module.importedModule);
457+
limitImport->module.importedModule,
458+
limitImport->module.importedModule
459+
->isClangHeaderImportModule());
458460

459461
if (limitImport->importLoc.isValid())
460462
ctx.Diags.diagnose(limitImport->importLoc, diag::decl_import_via_here,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include "ctypes.h"
2+
#include "macros.h"
3+
14
typedef struct {
25
double x, y;
36
} MyPoint;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: mkdir -p %t/tmp
3+
4+
// Test with the normal bridging header.
5+
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk
6+
7+
// Test with a precompiled bridging header.
8+
// RUN: %target-swift-frontend -emit-pch -o %t/c-bridging-header.pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk
9+
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %t/c-bridging-header.pch -sdk %clang-importer-sdk
10+
11+
12+
// Overrides the internal import that comes through the bridging header.
13+
public import macros
14+
15+
public func getRed() -> Color { red } // expected-error{{function cannot be declared public because its result uses an internal type}}
16+
// expected-note@-1{{struct 'Color' is imported by this file as 'internal' from bridging header}}
17+
18+
public func getX(point: MyPoint) -> Double { point.x } // expected-error{{function cannot be declared public because its parameter uses an internal type}}
19+
// expected-note@-1{{struct 'MyPoint' is imported by this file as 'internal' from bridging header}}
20+
21+
// Comes from the macros module.
22+
public func returnsFromMacrosModule() -> okay_t { 0 }

test/ClangImporter/InternalBridgingHeader/pch.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,49 @@
22
// RUN: mkdir -p %t/tmp
33

44
// First test the explicit frontend-based bridging PCH generation and use works
5-
// RUN: %target-swift-frontend -emit-pch -o %t/c-bridging-header.pch %S/../Inputs/c-bridging-header.h
6-
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %t/c-bridging-header.pch
5+
// RUN: %target-swift-frontend -emit-pch -o %t/c-bridging-header.pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk
6+
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %t/c-bridging-header.pch -sdk %clang-importer-sdk
77

88
// Now test the driver-automated version is inert when disabled
99
// Output path of the PCH differs in the new driver, so force SWIFT_USE_OLD_DRIVER for now.
10-
// 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
10+
// 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
1111
// RUN: not ls %t/tmp/*.pch >/dev/null 2>&1
1212

1313
// Test the driver-automated version works by default
1414
// Output path of the PCH differs in the new driver, so force SWIFT_USE_OLD_DRIVER for now.
15-
// 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
15+
// 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
1616
// RUN: ls %t/tmp/*.pch >/dev/null 2>&1
1717
// RUN: llvm-objdump --raw-clang-ast %t/tmp/*.pch | llvm-bcanalyzer -dump | %FileCheck %s
1818
// CHECK: ORIGINAL_FILE{{.*}}Inputs/c-bridging-header.h
1919

2020
// Test the driver-automated version deletes its PCH file when done
2121
// RUN: rm %t/tmp/*.pch
22-
// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -typecheck %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h
22+
// RUN: env TMPDIR=%t/tmp/ %target-swiftc_driver -typecheck %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk
2323
// RUN: not ls %t/tmp/*.pch >/dev/null 2>&1
2424

2525
// Test -emit-pch invocation but with a persistent PCH
26-
// RUN: %target-swift-frontend -emit-pch -pch-output-dir %t/pch %S/../Inputs/c-bridging-header.h
27-
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch -pch-disable-validation
26+
// RUN: %target-swift-frontend -emit-pch -pch-output-dir %t/pch %S/../Inputs/c-bridging-header.h -sdk %clang-importer-sdk
27+
// 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
2828
// RUN: ls %t/pch/*.pch >/dev/null 2>&1
2929

3030
// Test implicit use of persistent PCH
31-
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch2
31+
// RUN: %target-typecheck-verify-swift -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch2 -sdk %clang-importer-sdk
3232
// RUN: ls %t/pch2/*.pch >/dev/null 2>&1
3333

3434
// RUN: touch %t/header.with.dot.h
3535
// RUN: touch %t/test.swift
36-
// 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
37-
// 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
36+
// 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
37+
// 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
3838
// RUN: ls %t/pch_with_dot/*swift*clang*.pch | count 2
3939

4040
// Test the driver-automated version using persistent PCH
41-
// RUN: %target-swiftc_driver -typecheck -save-temps %s -internal-import-bridging-header %S/../Inputs/c-bridging-header.h -pch-output-dir %t/pch3
41+
// 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
4242
// RUN: ls %t/pch3/*.pch >/dev/null 2>&1
4343
// RUN: llvm-objdump --raw-clang-ast %t/pch3/*.pch | llvm-bcanalyzer -dump | %FileCheck %s -check-prefix=PERSISTENT
4444
// PERSISTENT: ORIGINAL_FILE{{.*}}Inputs/c-bridging-header.h
4545

4646
// Test that -pch-disable-validation works in that it won't implicitly create a PCH
47-
// 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 2>&1 | %FileCheck %s -check-prefix=NO-VALIDATION
47+
// 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
4848
// NO-VALIDATION: PCH file {{.*}} not found
4949

5050
func getX(point: MyPoint) -> Double { point.x }

0 commit comments

Comments
 (0)