Skip to content

Commit fcf25a4

Browse files
committed
improve test cases for resilient enum cxx interop
1 parent 48c9a02 commit fcf25a4

File tree

4 files changed

+99
-77
lines changed

4 files changed

+99
-77
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,13 @@ class DeclAndTypePrinter::Implementation
477477
auto name = pair.first->getNameStr().str();
478478
name[0] = std::toupper(name[0]);
479479
os << name << "() const {\n";
480-
os << " return *this == cases::";
481-
syntaxPrinter.printIdentifier(pair.first->getNameStr());
480+
os << " return _getEnumTag() == ";
481+
if (ED->isResilient()) {
482+
os << cxx_synthesis::getCxxImplNamespaceName()
483+
<< "::" << pair.second.globalVariableName;
484+
} else {
485+
os << pair.second.tag;
486+
}
482487
os << ";\n }\n";
483488

484489
if (!pair.first->hasAssociatedValues()) {

test/Interop/SwiftToCxx/enums/resilient-enum-in-cxx-execution.cpp

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,43 @@
33
// RUN: %target-swift-frontend %S/resilient-enum-in-cxx.swift -enable-library-evolution -typecheck -module-name Enums -clang-header-expose-public-decls -emit-clang-header-path %t/enums.h
44

55
// RUN: %target-interop-build-clangxx -c %s -I %t -o %t/swift-enums-execution.o
6-
// RUN: %target-interop-build-swift %S/resilient-enum-in-cxx.swift -enable-library-evolution -o %t/swift-enums-execution -Xlinker %t/swift-enums-execution.o -module-name Enums -Xfrontend -entry-point-function-name -Xfrontend swiftMain
76

7+
// RUN: %target-interop-build-swift %S/resilient-enum-in-cxx.swift -enable-library-evolution -o %t/swift-enums-execution -Xlinker %t/swift-enums-execution.o -module-name Enums -Xfrontend -entry-point-function-name -Xfrontend swiftMain
88
// RUN: %target-codesign %t/swift-enums-execution
9-
// RUN: %target-run %t/swift-enums-execution
9+
// RUN: %target-run %t/swift-enums-execution | %FileCheck --check-prefixes=CHECK,OLD_CASE %s
10+
11+
// RUN: %target-interop-build-swift %S/resilient-enum-in-cxx.swift -enable-library-evolution -o %t//swift-enums-execution-new -Xlinker %t/swift-enums-execution.o -module-name Enums -Xfrontend -entry-point-function-name -Xfrontend swiftMain -D NEW_CASE
12+
// RUN: %target-codesign %t/swift-enums-execution-new
13+
// RUN: %target-run %t/swift-enums-execution-new | %FileCheck --check-prefixes=CHECK,NEW_CASE %s
1014

1115
// REQUIRES: executable_test
1216

1317
#include <cassert>
18+
#include <iostream>
1419
#include "enums.h"
1520

1621
int main() {
1722
using namespace Enums;
18-
19-
{
20-
auto f = makeFoo(0);
21-
assert(f == Foo::cases::a);
22-
}
23-
{
24-
auto f = makeFoo(1);
25-
assert(f == Foo::cases::b);
26-
assert(f.getB() == 123);
27-
}
28-
{
29-
auto f = makeFoo(2);
30-
assert(f == Foo::cases::c);
31-
}
32-
{
33-
auto f = makeFoo(3);
34-
assert(f == Foo::cases::d);
35-
assert(f.getD() == 2.34);
23+
auto f1 = makeFoo(10);
24+
auto f2 = makeFoo(-10);
25+
26+
printFoo(f1);
27+
printFoo(f2);
28+
29+
assert(!f2.inResilientUnknownCase());
30+
if (f1.inResilientUnknownCase()) {
31+
std::cout << "f1.inResilientUnknownCase()\n";
32+
assert(!f1.isA());
33+
} else {
34+
assert(f1.isA());
35+
assert(f1.getA() == 10.0);
3636
}
3737

3838
return 0;
3939
}
40+
41+
// OLD_CASE: a(10.0)
42+
// NEW_CASE: b(10)
43+
// CHECK-NEXT: a(-10.0)
44+
45+
// NEW_CASE: f1.inResilientUnknownCase()
Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,63 @@
11
// RUN: %empty-directory(%t)
2+
23
// RUN: %target-swift-frontend %s -enable-library-evolution -typecheck -module-name Enums -clang-header-expose-public-decls -emit-clang-header-path %t/enums.h
3-
// RUN: %FileCheck %s < %t/enums.h
4+
// RUN: %FileCheck --check-prefixes=CHECK,OLD_CASE %s < %t/enums.h
5+
6+
// RUN: %target-swift-frontend %s -enable-library-evolution -D NEW_CASE -typecheck -module-name Enums -clang-header-expose-public-decls -emit-clang-header-path %t/enums_new_case.h
7+
// RUN: %FileCheck --check-prefixes=CHECK,NEW_CASE %s < %t/enums_new_case.h
48

59
// RUN: %check-interop-cxx-header-in-clang(%t/enums.h -Wno-unused-private-field -Wno-unused-function)
10+
// RUN: %check-interop-cxx-header-in-clang(%t/enums_new_case.h -Wno-unused-private-field -Wno-unused-function)
611

712
public enum Foo {
8-
case a, b(Int), c
9-
case d(Double)
13+
case a(Double)
14+
#if NEW_CASE
15+
case b(Int)
16+
#endif
1017
}
1118

1219
public func makeFoo(_ x: Int) -> Foo {
13-
switch x {
14-
case 0:
15-
return .a
16-
case 1:
17-
return .b(123)
18-
case 2:
19-
return .c
20-
default:
21-
return .d(2.34)
20+
#if NEW_CASE
21+
if x >= 0 {
22+
return .b(x)
23+
} else {
24+
return .a(Double(x))
2225
}
26+
#else
27+
return .a(Double(x))
28+
#endif
29+
}
30+
31+
public func printFoo(_ x: Foo) {
32+
print(x)
2333
}
2434

25-
// CHECK: // Tags for resilient enum Foo
26-
// CHECK-NEXT: extern "C" {
27-
// CHECK-NEXT: extern int $s5Enums3FooO1ayA2CmFWC;
28-
// CHECK-NEXT: extern int $s5Enums3FooO1byACSicACmFWC;
29-
// CHECK-NEXT: extern int $s5Enums3FooO1cyA2CmFWC;
30-
// CHECK-NEXT: extern int $s5Enums3FooO1dyACSdcACmFWC;
31-
// CHECK-NEXT: }
35+
// CHECK: // Tags for resilient enum Foo
36+
// CHECK-NEXT: extern "C" {
37+
// CHECK-NEXT: extern int $s5Enums3FooO1ayACSdcACmFWC;
38+
// NEW_CASE-NEXT: extern int $s5Enums3FooO1byACSicACmFWC;
39+
// CHECK-NEXT: }
3240
// CHECK-EMPTY:
33-
// CHECK-NEXT: } // namespace _impl
41+
// CHECK-NEXT: } // namespace _impl
3442
// CHECK-EMPTY:
35-
// CHECK-NEXT: class Foo final {
36-
// CHECK-NEXT: public:
37-
// CHECK: inline operator cases() const {
38-
// CHECK-NEXT: auto tag = _getEnumTag();
39-
// CHECK-NEXT: if (tag == _impl::$s5Enums3FooO1byACSicACmFWC) return cases::b;
40-
// CHECK-NEXT: if (tag == _impl::$s5Enums3FooO1dyACSdcACmFWC) return cases::d;
41-
// CHECK-NEXT: if (tag == _impl::$s5Enums3FooO1ayA2CmFWC) return cases::a;
42-
// CHECK-NEXT: if (tag == _impl::$s5Enums3FooO1cyA2CmFWC) return cases::c;
43-
// CHECK-NEXT: abort();
44-
// CHECK-NEXT: }
45-
// CHECK-NEXT: inline bool inResilientUnknownCase() const {
46-
// CHECK-NEXT: auto tag = _getEnumTag();
47-
// CHECK-NEXT: return
48-
// CHECK-NEXT: tag != _impl::$s5Enums3FooO1byACSicACmFWC &&
49-
// CHECK-NEXT: tag != _impl::$s5Enums3FooO1dyACSdcACmFWC &&
50-
// CHECK-NEXT: tag != _impl::$s5Enums3FooO1ayA2CmFWC &&
51-
// CHECK-NEXT: tag != _impl::$s5Enums3FooO1cyA2CmFWC;
52-
// CHECK-NEXT: }
43+
// CHECK-NEXT: class Foo final {
44+
// CHECK-NEXT: public:
45+
// CHECK: inline operator cases() const {
46+
// CHECK-NEXT: auto tag = _getEnumTag();
47+
// CHECK-NEXT: if (tag == _impl::$s5Enums3FooO1ayACSdcACmFWC) return cases::a;
48+
// NEW_CASE-NEXT: if (tag == _impl::$s5Enums3FooO1byACSicACmFWC) return cases::b;
49+
// CHECK-NEXT: abort();
50+
// CHECK-NEXT: }
51+
// CHECK-NEXT: inline bool inResilientUnknownCase() const {
52+
// CHECK-NEXT: auto tag = _getEnumTag();
53+
// CHECK-NEXT: return
54+
// OLD_CASE-NEXT: tag != _impl::$s5Enums3FooO1ayACSdcACmFWC;
55+
// NEW_CASE-NEXT: tag != _impl::$s5Enums3FooO1ayACSdcACmFWC &&
56+
// NEW_CASE-NEXT: tag != _impl::$s5Enums3FooO1byACSicACmFWC;
57+
// CHECK-NEXT: }
58+
// CHECK-NEXT: inline bool isA() const {
59+
// CHECK-NEXT: return _getEnumTag() == _impl::$s5Enums3FooO1ayACSdcACmFWC;
60+
// CHECK-NEXT: }
61+
// NEW_CASE: inline bool isB() const {
62+
// NEW_CASE-NEXT: return _getEnumTag() == _impl::$s5Enums3FooO1byACSicACmFWC;
63+
// NEW_CASE-NEXT: }

test/Interop/SwiftToCxx/enums/swift-enum-case-functions.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,13 @@ public func checkIntDoubleOrBignum(_ x: IntDoubleOrBignum, tag: Int) -> Bool {
162162
// CHECK-NEXT: }
163163
// CHECK-NEXT: }
164164
// CHECK-NEXT: inline bool isSecond() const {
165-
// CHECK-NEXT: return *this == cases::second;
165+
// CHECK-NEXT: return _getEnumTag() == 0;
166166
// CHECK-NEXT: }
167167
// CHECK: inline bool isFirst() const {
168-
// CHECK-NEXT: return *this == cases::first;
168+
// CHECK-NEXT: return _getEnumTag() == 1;
169169
// CHECK-NEXT: }
170170
// CHECK-NEXT: inline bool isThird() const {
171-
// CHECK-NEXT: return *this == cases::third;
171+
// CHECK-NEXT: return _getEnumTag() == 2;
172172
// CHECK-NEXT: }
173173
// CHECK: inline int _getEnumTag() const {
174174
// CHECK-NEXT: auto metadata = _impl::$s5Enums12BoolWithCaseOMa(0);
@@ -193,13 +193,13 @@ public func checkIntDoubleOrBignum(_ x: IntDoubleOrBignum, tag: Int) -> Bool {
193193
// CHECK-NEXT: }
194194
// CHECK-NEXT: }
195195
// CHECK-NEXT: inline bool isOne() const {
196-
// CHECK-NEXT: return *this == cases::one;
196+
// CHECK-NEXT: return _getEnumTag() == 0;
197197
// CHECK-NEXT: }
198198
// CHECK: inline bool isTwo() const {
199-
// CHECK-NEXT: return *this == cases::two;
199+
// CHECK-NEXT: return _getEnumTag() == 1;
200200
// CHECK-NEXT: }
201201
// CHECK: inline bool isThree() const {
202-
// CHECK-NEXT: return *this == cases::three;
202+
// CHECK-NEXT: return _getEnumTag() == 2;
203203
// CHECK-NEXT: }
204204
// CHECK: inline int _getEnumTag() const {
205205
// CHECK-NEXT: auto metadata = _impl::$s5Enums9CLikeEnumOMa(0);
@@ -222,7 +222,7 @@ public func checkIntDoubleOrBignum(_ x: IntDoubleOrBignum, tag: Int) -> Bool {
222222
// CHECK-NEXT: }
223223
// CHECK-NEXT: }
224224
// CHECK-NEXT: inline bool isOne() const {
225-
// CHECK-NEXT: return *this == cases::one;
225+
// CHECK-NEXT: return _getEnumTag() == 0;
226226
// CHECK-NEXT: }
227227
// CHECK: inline int _getEnumTag() const {
228228
// CHECK-NEXT: auto metadata = _impl::$s5Enums8DataCaseOMa(0);
@@ -247,13 +247,13 @@ public func checkIntDoubleOrBignum(_ x: IntDoubleOrBignum, tag: Int) -> Bool {
247247
// CHECK-NEXT: }
248248
// CHECK-NEXT: }
249249
// CHECK-NEXT: inline bool isInt() const {
250-
// CHECK-NEXT: return *this == cases::Int;
250+
// CHECK-NEXT: return _getEnumTag() == 0;
251251
// CHECK-NEXT: }
252252
// CHECK: inline bool isDouble() const {
253-
// CHECK-NEXT: return *this == cases::Double;
253+
// CHECK-NEXT: return _getEnumTag() == 1;
254254
// CHECK-NEXT: }
255255
// CHECK: inline bool isBignum() const {
256-
// CHECK-NEXT: return *this == cases::Bignum;
256+
// CHECK-NEXT: return _getEnumTag() == 2;
257257
// CHECK-NEXT: }
258258
// CHECK: inline int _getEnumTag() const {
259259
// CHECK-NEXT: auto metadata = _impl::$s5Enums17IntDoubleOrBignumOMa(0);
@@ -278,13 +278,13 @@ public func checkIntDoubleOrBignum(_ x: IntDoubleOrBignum, tag: Int) -> Bool {
278278
// CHECK-NEXT: }
279279
// CHECK-NEXT: }
280280
// CHECK-NEXT: inline bool isInt() const {
281-
// CHECK-NEXT: return *this == cases::Int;
281+
// CHECK-NEXT: return _getEnumTag() == 0;
282282
// CHECK-NEXT: }
283283
// CHECK: inline bool isNegInfinity() const {
284-
// CHECK-NEXT: return *this == cases::NegInfinity;
284+
// CHECK-NEXT: return _getEnumTag() == 1;
285285
// CHECK-NEXT: }
286286
// CHECK: inline bool isPosInfinity() const {
287-
// CHECK-NEXT: return *this == cases::PosInfinity;
287+
// CHECK-NEXT: return _getEnumTag() == 2;
288288
// CHECK-NEXT: }
289289
// CHECK: inline int _getEnumTag() const {
290290
// CHECK-NEXT: auto metadata = _impl::$s5Enums13IntOrInfinityOMa(0);
@@ -310,16 +310,16 @@ public func checkIntDoubleOrBignum(_ x: IntDoubleOrBignum, tag: Int) -> Bool {
310310
// CHECK-NEXT: }
311311
// CHECK-NEXT: }
312312
// CHECK-NEXT: inline bool isSecond() const {
313-
// CHECK-NEXT: return *this == cases::second;
313+
// CHECK-NEXT: return _getEnumTag() == 0;
314314
// CHECK-NEXT: }
315315
// CHECK: inline bool isThird() const {
316-
// CHECK-NEXT: return *this == cases::third;
316+
// CHECK-NEXT: return _getEnumTag() == 1;
317317
// CHECK-NEXT: }
318318
// CHECK: inline bool isFirst() const {
319-
// CHECK-NEXT: return *this == cases::first;
319+
// CHECK-NEXT: return _getEnumTag() == 2;
320320
// CHECK-NEXT: }
321321
// CHECK-NEXT: inline bool isFourth() const {
322-
// CHECK-NEXT: return *this == cases::fourth;
322+
// CHECK-NEXT: return _getEnumTag() == 3;
323323
// CHECK-NEXT: }
324324
// CHECK: inline int _getEnumTag() const {
325325
// CHECK-NEXT: auto metadata = _impl::$s5Enums20MultipleBoolWithCaseOMa(0);

0 commit comments

Comments
 (0)