Skip to content

Commit c2f2306

Browse files
committed
handle bridging header decls in ForwardDeclaredConcreteTypeVisitor
1 parent 7cc3843 commit c2f2306

File tree

2 files changed

+88
-13
lines changed

2 files changed

+88
-13
lines changed

lib/ClangImporter/SwiftifyDecl.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ struct CountedByExpressionValidator
228228
case clang::BuiltinType::ULong:
229229
case clang::BuiltinType::LongLong:
230230
case clang::BuiltinType::ULongLong:
231-
DLOG("Ignoring count parameter with non-portable integer literal");
231+
DLOG("Ignoring count parameter with non-portable integer literal\n");
232232
return false;
233233
default:
234234
return true;
@@ -330,7 +330,7 @@ struct UnaliasedInstantiationVisitor
330330
bool
331331
VisitTemplateSpecializationType(const clang::TemplateSpecializationType *) {
332332
hasUnaliasedInstantiation = true;
333-
DLOG("Signature contains raw template, skipping");
333+
DLOG("Signature contains raw template, skipping\n");
334334
return false;
335335
}
336336
};
@@ -340,15 +340,33 @@ struct ForwardDeclaredConcreteTypeVisitor
340340
bool hasForwardDeclaredConcreteType = false;
341341
const clang::Module *Owner;
342342

343-
ForwardDeclaredConcreteTypeVisitor(const clang::Module *Owner) : Owner(Owner) { ASSERT(Owner); };
343+
ForwardDeclaredConcreteTypeVisitor(const clang::Module *Owner) : Owner(Owner) {};
344344

345345
bool VisitRecordType(clang::RecordType *RT) {
346346
const clang::RecordDecl *RD = RT->getDecl()->getDefinition();
347347
ASSERT(RD && "pointer to concrete type without type definition?");
348348
const clang::Module *M = RD->getOwningModule();
349+
350+
if (!Owner && !M) {
351+
DLOG("Both decls are in bridging header");
352+
return true;
353+
}
354+
355+
if (!Owner) {
356+
hasForwardDeclaredConcreteType = true;
357+
DLOG("Imported signature contains concrete type not available in bridging header, skipping\n");
358+
LLVM_DEBUG(DUMP(RD));
359+
return false;
360+
}
361+
if (!M) {
362+
ABORT([RD](auto &out) {
363+
out << "Imported signature contains concrete type without an owning clang module:\n";
364+
RD->dump(out);
365+
});
366+
}
349367
if (!Owner->isModuleVisible(M)) {
350368
hasForwardDeclaredConcreteType = true;
351-
DLOG("Imported signature contains concrete type not available in clang module, skipping");
369+
DLOG("Imported signature contains concrete type not available in clang module, skipping\n");
352370
LLVM_DEBUG(DUMP(RD));
353371
return false;
354372
}
@@ -415,7 +433,7 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
415433
return false;
416434

417435
if (ClangDecl->isImplicit()) {
418-
DLOG("implicit functions lack lifetime and bounds info");
436+
DLOG("implicit functions lack lifetime and bounds info\n");
419437
return false;
420438
}
421439

@@ -427,6 +445,8 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
427445
} else {
428446
OwningModule = ClangDecl->getOwningModule();
429447
}
448+
bool IsInBridgingHeader = MappedDecl->getModuleContext()->getName().str() == CLANG_HEADER_MODULE_NAME;
449+
ASSERT(OwningModule || IsInBridgingHeader);
430450
ForwardDeclaredConcreteTypeVisitor CheckForwardDecls(OwningModule);
431451

432452
// We only attach the macro if it will produce an overload. Any __counted_by
@@ -620,7 +640,7 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
620640

621641
MacroDecl *SwiftifyImportDecl = dyn_cast_or_null<MacroDecl>(getKnownSingleDecl(SwiftContext, "_SwiftifyImport"));
622642
if (!SwiftifyImportDecl) {
623-
DLOG("_SwiftifyImport macro not found");
643+
DLOG("_SwiftifyImport macro not found\n");
624644
return;
625645
}
626646

@@ -672,7 +692,7 @@ void ClangImporter::Implementation::swiftifyProtocol(
672692
MacroDecl *SwiftifyImportDecl = dyn_cast_or_null<MacroDecl>(
673693
getKnownSingleDecl(SwiftContext, "_SwiftifyImportProtocol"));
674694
if (!SwiftifyImportDecl) {
675-
DLOG("_SwiftifyImportProtocol macro not found");
695+
DLOG("_SwiftifyImportProtocol macro not found\n");
676696
return;
677697
}
678698

test/Interop/C/swiftify-import/bridging-header.swift

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ imports for TMP_DIR/test.swift:
1616
_StringProcessing
1717
_SwiftConcurrencyShims
1818
_Concurrency
19+
A
20+
B
21+
C
1922
imports for __ObjC.foo:
2023
imports for @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:
2124
__ObjC
@@ -25,21 +28,73 @@ imports for @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:
2528
@__swiftmacro_So3foo15_SwiftifyImportfMp_.swift
2629
------------------------------
2730
/// This is an auto-generated wrapper for safer interop
28-
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_disfavoredOverload public func foo(_ p: Span<Int32>) {
29-
let len = Int32(exactly: p.count)!
31+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_disfavoredOverload public func foo(_ p: Span<a_t>, _ x: UnsafeMutablePointer<no_module_record_t>!) {
32+
let len = no_module_t(exactly: p.count)!
3033
return unsafe p.withUnsafeBufferPointer { _pPtr in
31-
return unsafe foo(len, _pPtr.baseAddress!)
34+
return unsafe foo(len, _pPtr.baseAddress!, x)
3235
}
3336
}
3437
------------------------------
3538

3639
//--- test.swift
37-
func test(s: Span<CInt>) {
38-
foo(s)
40+
import A
41+
import B
42+
import C
43+
44+
func test(s: Span<a_t>, x: UnsafeMutablePointer<no_module_record_t>) {
45+
unsafe foo(s, x)
46+
}
47+
48+
func test2(p: UnsafeMutablePointer<CInt>, len: CInt, y: UnsafeMutablePointer<b_t>) {
49+
unsafe bar(len, p, y)
50+
}
51+
52+
func test3(p: UnsafeMutablePointer<CInt>, len: CInt, z: UnsafeMutablePointer<c_t>) {
53+
unsafe baz(len, p, z)
3954
}
4055

4156
//--- bridging.h
4257
#include <ptrcheck.h>
4358
#include <lifetimebound.h>
4459

45-
void foo(int len, const int * __counted_by(len) p __noescape);
60+
#include "no-module.h"
61+
#include "a.h"
62+
#include "c.h"
63+
64+
struct no_module_record_t;
65+
void foo(no_module_t len, const a_t * __counted_by(len) p __noescape, struct no_module_record_t *x);
66+
67+
struct b_t;
68+
void bar(int len, const int * __counted_by(len) p __noescape, struct b_t *y);
69+
70+
void baz(int len, const int * __counted_by(len) p __noescape, struct c_t *z);
71+
72+
//--- no-module.h
73+
typedef int no_module_t;
74+
struct no_module_record_t {
75+
int placeholder;
76+
};
77+
78+
//--- a.h
79+
typedef int a_t;
80+
81+
//--- b.h
82+
struct b_t {
83+
int placeholder;
84+
};
85+
86+
//--- c.h
87+
struct c_t {
88+
int placeholder;
89+
};
90+
91+
//--- module.modulemap
92+
module A {
93+
header "a.h"
94+
}
95+
module B {
96+
header "b.h"
97+
}
98+
module C {
99+
header "c.h"
100+
}

0 commit comments

Comments
 (0)