Skip to content

[cxx-interop] [NFC] Stabilize interface order of Clang record members#87026

Merged
j-hui merged 1 commit intoswiftlang:mainfrom
j-hui:sort-members
Feb 8, 2026
Merged

[cxx-interop] [NFC] Stabilize interface order of Clang record members#87026
j-hui merged 1 commit intoswiftlang:mainfrom
j-hui:sort-members

Conversation

@j-hui
Copy link
Contributor

@j-hui j-hui commented Feb 6, 2026

We may visit and thus import these members in an unpredictable order.
To avoid future churn for module interface test cases, sort the printed
module interface output according to some rough heuristics.

@j-hui
Copy link
Contributor Author

j-hui commented Feb 6, 2026

@swift-ci please test

Copy link
Contributor

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

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

Overall looks good to me but I had a question and a small nit inline.

// CHECK-NEXT: init(a: UnsafeMutablePointer<Int{{[0-9]+}}>!, len: Int{{[0-9]+}})
// CHECK-NEXT: var a: UnsafeMutablePointer<Int{{[0-9]+}}>!
// CHECK-NEXT: var len: Int{{[0-9]+}}
// CHECK-DAG: init()
Copy link
Member

Choose a reason for hiding this comment

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

If this patch stabilises the order, I don't think we should use CHECK-DAG. It's significantly worse in terms of output when the checks fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For these, the order differs between C vs C++

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 think it's because the default constructors are generated differently for C vs C++. C++ already has a notion of a default constructor, while in C it's entirely synthetic.

Copy link
Member

Choose a reason for hiding this comment

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

fair enough

Comment on lines +31 to +37
// CHECK-DAG: /// This is an auto-generated wrapper for safer interop
// CHECK-DAG: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
// CHECK-DAG: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func methodWithSafeWrapper(_ s: Span<CInt>)
// CHECK-DAG: /// This is an auto-generated wrapper for safer interop
// CHECK-DAG: @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *)
// CHECK-DAG: @_lifetime(&self)
// CHECK-DAG: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func getMutable(_ s: Span<CInt>) -> MutableSpan<CInt>
Copy link
Member

Choose a reason for hiding this comment

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

Also not a fan of this CHECK-DAG

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These appear to be unstable. I'm not entirely sure why but I think it's because they are being sorted according to the filename of the macro-generated buffer.

Copy link
Member

Choose a reason for hiding this comment

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

urgh... can we sort macro expansion nodes according to the clang node the macro is expanded from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, I think that worked. Fingers crossed for the CI runs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

whelp. using SourceManager::getGeneratedSourceInfo() didn't work.

I hate to ask this, but would you be ok with punting this to follow-up work? I agree that the -DAG checks here is not great, but their "span" (no pun intended) is bounded by the following lines:

// CHECK-DAG:   @_alwaysEmitIntoClient @_disfavoredOverload public mutating func getMutable(_ s: Span<CInt>) -> MutableSpan<CInt>

// CHECK-NEXT:   init()
// CHECK-NEXT:   mutating func methodWithSafeWrapper(_ s: ConstSpanOfInt)
// CHECK-NEXT:   mutating func getMutable(_ s: ConstSpanOfInt) -> SpanOfInt

I'm not familiar with how the -DAG matching algorithm is designed in lit but I would hope that having the CHECK-NEXTs here limit how much it needs to backtrack in the case of a non-match.

Copy link
Member

Choose a reason for hiding this comment

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

Sure!

// CHECK-NEXT: }

// CHECK: struct LongNameAllLower {
// CHECK-NOT: var
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 have no idea what the intention of this original CHECK-NOT was supposed to be. It doesn't catch anything that consecutive CHECK-NEXTs would not catch.

Copy link
Member

@hnrklssn hnrklssn left a comment

Choose a reason for hiding this comment

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

thanks for adding the extra QoL edits

@j-hui
Copy link
Contributor Author

j-hui commented Feb 6, 2026

@swift-ci please test

@j-hui
Copy link
Contributor Author

j-hui commented Feb 7, 2026

@swift-ci please test

@j-hui
Copy link
Contributor Author

j-hui commented Feb 7, 2026

@swift-ci please test

@j-hui j-hui enabled auto-merge February 7, 2026 06:31
We may visit and thus import these members in an unpredictable order.
To avoid future churn for module interface test cases, sort the printed
module interface output according to some rough heuristics.
@j-hui
Copy link
Contributor Author

j-hui commented Feb 7, 2026

@swift-ci please test

@j-hui j-hui merged commit 9f2f857 into swiftlang:main Feb 8, 2026
4 of 5 checks passed
@@ -1,54 +1,54 @@
// RUN: %target-swift-ide-test -print-module -module-to-print=UsingNonPublic -print-access -I %S/Inputs -source-filename=x -cxx-interoperability-mode=default -enable-experimental-feature ImportNonPublicCxxMembers | %FileCheck %s
// RUN: %target-swift-ide-test -print-module -module-to-print=UsingNonPublic -print-access -I %S/Inputs -source-filename=x -cxx-interoperability-mode=default -enable-experimental-feature ImportNonPublicCxxMembers | tee %s.out | %FileCheck %s
Copy link
Contributor

@eeckstein eeckstein Feb 9, 2026

Choose a reason for hiding this comment

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

@j-hui I guess the tee %s.out is just a left over from debugging. It produces the output file in the source directory. Can you please remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I'm very sorry, it is being removed here: #87075

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants