Skip to content

Commit c0c28c4

Browse files
authored
Merge pull request #74384 from apple/gaborh/print-decl-order
[cxx-interop] Fix generated declaration order
2 parents b99b6af + dbdd983 commit c0c28c4

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

lib/PrintAsClang/ModuleContentsWriter.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "PrintSwiftToClangCoreScaffold.h"
2121
#include "SwiftToClangInteropContext.h"
2222

23+
#include "swift/AST/Decl.h"
2324
#include "swift/AST/DiagnosticsSema.h"
2425
#include "swift/AST/ExistentialLayout.h"
2526
#include "swift/AST/Module.h"
@@ -671,6 +672,15 @@ class ModuleWriter {
671672
llvm_unreachable("unknown top-level ObjC decl");
672673
};
673674

675+
// When we visit a function, we might also generate a thunk that calls into the
676+
// implementation of structs/enums to get the opaque pointers. To avoid
677+
// referencing these methods before we see the definition for the generated
678+
// classes, we want to visit function definitions last.
679+
if (isa<AbstractFunctionDecl>(*rhs) && isa<NominalTypeDecl>(*lhs))
680+
return Descending;
681+
if (isa<AbstractFunctionDecl>(*lhs) && isa<NominalTypeDecl>(*rhs))
682+
return Ascending;
683+
674684
// Sort by names.
675685
int result = getSortName(*rhs).compare(getSortName(*lhs));
676686
if (result != 0)
@@ -700,9 +710,9 @@ class ModuleWriter {
700710
// even when the variable might not actually be emitted by the emitter.
701711
// In that case, order the function before the variable.
702712
if (isa<AbstractFunctionDecl>(*rhs) && isa<VarDecl>(*lhs))
703-
return 1;
713+
return Descending;
704714
if (isa<AbstractFunctionDecl>(*lhs) && isa<VarDecl>(*rhs))
705-
return -1;
715+
return Ascending;
706716

707717
// Prefer value decls to extensions.
708718
assert(!(isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs)));

test/Interop/SwiftToCxx/class/swift-class-in-cxx.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ public final class ClassWithIntField {
102102
// CHECK-EMPTY:
103103
// CHECK-NEXT: namespace Class SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("Class") {
104104

105-
// CHECK: SWIFT_INLINE_THUNK ClassWithIntField passThroughClassWithIntField(const ClassWithIntField& x) noexcept SWIFT_SYMBOL("s:5Class011passThroughA12WithIntFieldyAA0adeF0CADF") SWIFT_WARN_UNUSED_RESULT {
106-
// CHECK-NEXT: return _impl::_impl_ClassWithIntField::makeRetained(_impl::$s5Class011passThroughA12WithIntFieldyAA0adeF0CADF(::swift::_impl::_impl_RefCountedClass::getOpaquePointer(x)));
107-
// CHECK-NEXT: }
108-
109105
public final class register { }
110106

111107
// CHECK: class SWIFT_SYMBOL("s:5Class8registerC") register_ final : public swift::_impl::RefCountedClass {
112108

109+
// CHECK: SWIFT_INLINE_THUNK ClassWithIntField passThroughClassWithIntField(const ClassWithIntField& x) noexcept SWIFT_SYMBOL("s:5Class011passThroughA12WithIntFieldyAA0adeF0CADF") SWIFT_WARN_UNUSED_RESULT {
110+
// CHECK-NEXT: return _impl::_impl_ClassWithIntField::makeRetained(_impl::$s5Class011passThroughA12WithIntFieldyAA0adeF0CADF(::swift::_impl::_impl_RefCountedClass::getOpaquePointer(x)));
111+
// CHECK-NEXT: }
112+
113113
public func returnClassWithIntField() -> ClassWithIntField {
114114
return ClassWithIntField()
115115
}

test/Interop/SwiftToCxx/functions/swift-operators.swift

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// RUN: %target-swift-frontend %s -typecheck -module-name Operators -clang-header-expose-decls=all-public -emit-clang-header-path %t/operators.h
33
// RUN: %FileCheck %s < %t/operators.h
44

5-
// TODO: %check-interop-cxx-header-in-clang(%t/operators.h)
6-
// unfortunately the header still triggers an error:
7-
// error: no member named '_impl_IntBox' in namespace 'Operators::_impl'
5+
// RUN: %check-interop-cxx-header-in-clang(%t/operators.h)
86

97
// CHECK-LABEL: namespace Operators SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("Operators") {
108

0 commit comments

Comments
 (0)