Skip to content

Commit 911cfe9

Browse files
committed
print static struct member as inline and improve test cases
1 parent cbc23cb commit 911cfe9

File tree

5 files changed

+43
-61
lines changed

5 files changed

+43
-61
lines changed

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,8 @@ class DeclAndTypePrinter::Implementation
517517
auto printStruct = [&](StringRef caseName, EnumElementDecl *elementDecl,
518518
Optional<IRABIDetailsProvider::EnumElementInfo>
519519
elementInfo) {
520-
os << " static struct { // impl struct for case " << caseName << '\n';
520+
os << " inline const static struct { "
521+
<< "// impl struct for case " << caseName << '\n';
521522
os << " inline constexpr operator cases() const {\n";
522523
os << " return cases::";
523524
syntaxPrinter.printIdentifier(caseName);
@@ -670,6 +671,9 @@ class DeclAndTypePrinter::Implementation
670671
}
671672
os << "\n };\n\n"; // enum class cases' closing bracket
672673

674+
os << "#pragma clang diagnostic push\n";
675+
os << "#pragma clang diagnostic ignored \"-Wc++17-extensions\" "
676+
<< "// allow use of inline static data member\n";
673677
for (const auto &pair : elementTagMapping) {
674678
// Printing struct
675679
printStruct(pair.first->getNameStr(), pair.first, pair.second);
@@ -690,7 +694,7 @@ class DeclAndTypePrinter::Implementation
690694
printIsFunction(resilientUnknownDefaultCaseName, ED);
691695
os << '\n';
692696
}
693-
os << '\n';
697+
os << "#pragma clang diagnostic pop\n";
694698

695699
// Printing operator cases()
696700
os << " inline operator cases() const {\n";

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -302,34 +302,6 @@ void ClangValueTypePrinter::printValueTypeDecl(
302302
printCxxImplClassName(os, typeDecl);
303303
os << ";\n";
304304
os << "};\n";
305-
// Print the definition of enum static struct data memebers
306-
if (isa<EnumDecl>(typeDecl)) {
307-
auto tagMapping = interopContext.getIrABIDetails().getEnumTagMapping(
308-
cast<EnumDecl>(typeDecl));
309-
for (const auto &pair : tagMapping) {
310-
os << "decltype(";
311-
printer.printBaseName(typeDecl);
312-
os << "::";
313-
printer.printIdentifier(pair.first->getNameStr());
314-
os << ") ";
315-
printer.printBaseName(typeDecl);
316-
os << "::";
317-
printer.printIdentifier(pair.first->getNameStr());
318-
os << ";\n";
319-
}
320-
if (isOpaqueLayout) {
321-
os << "decltype(";
322-
printer.printBaseName(typeDecl);
323-
// TODO: allow custom name for this special case
324-
os << "::";
325-
printer.printIdentifier("unknownDefault");
326-
os << ") ";
327-
printer.printBaseName(typeDecl);
328-
os << "::";
329-
printer.printIdentifier("unknownDefault");
330-
os << ";\n";
331-
}
332-
}
333305
os << '\n';
334306

335307
const auto *moduleContext = typeDecl->getModuleContext();

test/Interop/SwiftToCxx/enums/resilient-enum-in-cxx.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ public enum Empty {
4646
// CHECK: enum class cases {
4747
// CHECK-NEXT: unknownDefault
4848
// CHECK-NEXT: };
49-
// CHECK-EMPTY:
50-
// CHECK-NEXT: static struct { // impl struct for case unknownDefault
49+
// CHECK: inline const static struct { // impl struct for case unknownDefault
5150
// CHECK-NEXT: inline constexpr operator cases() const {
5251
// CHECK-NEXT: return cases::unknownDefault;
5352
// CHECK-NEXT: }
@@ -71,17 +70,28 @@ public enum Empty {
7170
// NEW_CASE-NEXT: b,
7271
// CHECK-NEXT: unknownDefault
7372
// CHECK-NEXT: }
74-
// CHECK: static struct { // impl struct for case unknownDefault
73+
// CHECK: inline const static struct { // impl struct for case unknownDefault
7574
// CHECK-NEXT: inline constexpr operator cases() const {
7675
// CHECK-NEXT: return cases::unknownDefault;
7776
// CHECK-NEXT: }
7877
// CHECK-NEXT: } unknownDefault;
7978
// CHECK-NEXT: inline bool isUnknownDefault() const;
8079
// CHECK-EMPTY:
81-
// CHECK-EMPTY:
82-
// CHECK-NEXT: inline operator cases() const {
80+
// CHECK: inline operator cases() const {
8381
// CHECK-NEXT: auto tag = _getEnumTag();
8482
// CHECK-NEXT: if (tag == _impl::$s5Enums3FooO1ayACSdcACmFWC) return cases::a;
8583
// NEW_CASE-NEXT: if (tag == _impl::$s5Enums3FooO1byACSicACmFWC) return cases::b;
8684
// CHECK-NEXT: return cases::unknownDefault;
8785
// CHECK-NEXT: }
86+
// CHECK: inline Foo Foo::_impl_a::operator()(double val) const {
87+
// CHECK-NEXT: auto result = Foo::_make();
88+
// CHECK-NEXT: memcpy(result._getOpaquePointer(), &val, sizeof(val));
89+
// CHECK-NEXT: result._destructiveInjectEnumTag(_impl::$s5Enums3FooO1ayACSdcACmFWC);
90+
// CHECK-NEXT: return result;
91+
// CHECK-NEXT: }
92+
// NEW_CASE: inline Foo Foo::_impl_b::operator()(swift::Int val) const {
93+
// NEW_CASE-NEXT: auto result = Foo::_make();
94+
// NEW_CASE-NEXT: memcpy(result._getOpaquePointer(), &val, sizeof(val));
95+
// NEW_CASE-NEXT: result._destructiveInjectEnumTag(_impl::$s5Enums3FooO1byACSicACmFWC);
96+
// NEW_CASE-NEXT: return result;
97+
// NEW_CASE-NEXT: }

test/Interop/SwiftToCxx/enums/swift-enum-implementation-execution.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,63 +15,63 @@
1515

1616
using namespace Enums;
1717

18-
void switchTest(const E &e) {
18+
int switchTest(const E &e) {
1919
switch (e) {
2020
case E::x:
2121
assert(e.isX());
2222
assert(e.getX() == 3.14);
23-
break;
23+
return 0;
2424
case E::y:
2525
assert(e.isY());
2626
assert(e.getY() == nullptr);
27-
break;
27+
return 1;
2828
case E::z:
2929
assert(e.isZ());
3030
assert(e.getZ().getX() == 1234);
31-
break;
31+
return 2;
3232
case E::w:
3333
assert(e.isW());
3434
assert(e.getW() == 5678);
35-
break;
35+
return 3;
3636
case E::auto_:
3737
assert(e.isAuto_());
3838
assert(e.getAuto_() == reinterpret_cast<void *>(1));
39-
break;
39+
return 4;
4040
case E::foobar:
4141
assert(e.isFoobar());
42-
break;
42+
return 5;
4343
}
4444
}
4545

4646
int main() {
4747
{
4848
auto e = E::x(3.14);
49-
switchTest(e);
49+
assert(switchTest(e) == 0);
5050
}
5151

5252
{
5353
auto e = E::y(nullptr);
54-
switchTest(e);
54+
assert(switchTest(e) == 1);
5555
}
5656

5757
{
5858
auto e = E::z(S::init(1234));
59-
switchTest(e);
59+
assert(switchTest(e) == 2);
6060
}
6161

6262
{
6363
auto e = E::w(5678);
64-
switchTest(e);
64+
assert(switchTest(e) == 3);
6565
}
6666

6767
{
6868
auto e = E::auto_(reinterpret_cast<void *>(1));
69-
switchTest(e);
69+
assert(switchTest(e) == 4);
7070
}
7171

7272
{
7373
auto e = E::foobar();
74-
switchTest(e);
74+
assert(switchTest(e) == 5);
7575
}
7676
return 0;
7777
}

test/Interop/SwiftToCxx/enums/swift-enum-implementation.swift

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ public struct S {
3232
// CHECK-NEXT: foobar
3333
// CHECK-NEXT: };
3434
// CHECK-EMPTY:
35-
// CHECK-NEXT: static struct { // impl struct for case x
35+
// CHECK-NEXT: #pragma clang diagnostic push
36+
// CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions" // allow use of inline static data member
37+
// CHECK-NEXT: inline const static struct { // impl struct for case x
3638
// CHECK-NEXT: inline constexpr operator cases() const {
3739
// CHECK-NEXT: return cases::x;
3840
// CHECK-NEXT: }
@@ -41,7 +43,7 @@ public struct S {
4143
// CHECK-NEXT: inline bool isX() const;
4244
// CHECK-NEXT: inline double getX() const;
4345
// CHECK-EMPTY:
44-
// CHECK-NEXT: static struct { // impl struct for case y
46+
// CHECK-NEXT: inline const static struct { // impl struct for case y
4547
// CHECK-NEXT: inline constexpr operator cases() const {
4648
// CHECK-NEXT: return cases::y;
4749
// CHECK-NEXT: }
@@ -50,7 +52,7 @@ public struct S {
5052
// CHECK-NEXT: inline bool isY() const;
5153
// CHECK-NEXT: inline void const * _Nullable getY() const;
5254
// CHECK-EMPTY:
53-
// CHECK-NEXT: static struct { // impl struct for case z
55+
// CHECK-NEXT: inline const static struct { // impl struct for case z
5456
// CHECK-NEXT: inline constexpr operator cases() const {
5557
// CHECK-NEXT: return cases::z;
5658
// CHECK-NEXT: }
@@ -59,7 +61,7 @@ public struct S {
5961
// CHECK-NEXT: inline bool isZ() const;
6062
// CHECK-NEXT: inline S getZ() const;
6163
// CHECK-EMPTY:
62-
// CHECK-NEXT: static struct { // impl struct for case w
64+
// CHECK-NEXT: inline const static struct { // impl struct for case w
6365
// CHECK-NEXT: inline constexpr operator cases() const {
6466
// CHECK-NEXT: return cases::w;
6567
// CHECK-NEXT: }
@@ -68,7 +70,7 @@ public struct S {
6870
// CHECK-NEXT: inline bool isW() const;
6971
// CHECK-NEXT: inline swift::Int getW() const;
7072
// CHECK-EMPTY:
71-
// CHECK-NEXT: static struct { // impl struct for case auto
73+
// CHECK-NEXT: inline const static struct { // impl struct for case auto
7274
// CHECK-NEXT: inline constexpr operator cases() const {
7375
// CHECK-NEXT: return cases::auto_;
7476
// CHECK-NEXT: }
@@ -77,15 +79,15 @@ public struct S {
7779
// CHECK-NEXT: inline bool isAuto_() const;
7880
// CHECK-NEXT: inline void * _Nonnull getAuto_() const;
7981
// CHECK-EMPTY:
80-
// CHECK-NEXT: static struct { // impl struct for case foobar
82+
// CHECK-NEXT: inline const static struct { // impl struct for case foobar
8183
// CHECK-NEXT: inline constexpr operator cases() const {
8284
// CHECK-NEXT: return cases::foobar;
8385
// CHECK-NEXT: }
8486
// CHECK-NEXT: inline E operator()() const;
8587
// CHECK-NEXT: } foobar;
8688
// CHECK-NEXT: inline bool isFoobar() const;
8789
// CHECK-EMPTY:
88-
// CHECK-EMPTY:
90+
// CHECK-NEXT: #pragma clang diagnostic pop
8991
// CHECK-NEXT: inline operator cases() const {
9092
// CHECK-NEXT: switch (_getEnumTag()) {
9193
// CHECK-NEXT: case 0: return cases::x;
@@ -139,12 +141,6 @@ public struct S {
139141
// CHECK-NEXT: using _impl_auto = decltype(auto_);
140142
// CHECK-NEXT: using _impl_foobar = decltype(foobar);
141143
// CHECK: };
142-
// CHECK-NEXT: decltype(E::x) E::x;
143-
// CHECK-NEXT: decltype(E::y) E::y;
144-
// CHECK-NEXT: decltype(E::z) E::z;
145-
// CHECK-NEXT: decltype(E::w) E::w;
146-
// CHECK-NEXT: decltype(E::auto_) E::auto_;
147-
// CHECK-NEXT: decltype(E::foobar) E::foobar;
148144
// CHECK-EMPTY:
149145
// CHECK-NEXT: namespace _impl {
150146
// CHECK-EMPTY:

0 commit comments

Comments
 (0)