@@ -1275,6 +1275,45 @@ namespace {
1275
1275
if (!DC)
1276
1276
return nullptr ;
1277
1277
1278
+ // Check for swift_newtype
1279
+ if (!SwiftType) {
1280
+ if (auto newtypeAttr =
1281
+ Decl->template getAttr <clang::SwiftNewtypeAttr>()) {
1282
+ switch (newtypeAttr->getNewtypeKind ()) {
1283
+ case clang::SwiftNewtypeAttr::NK_Enum:
1284
+ // TODO: import as closed enum instead
1285
+
1286
+ // For now, fall through and treat as a struct
1287
+ case clang::SwiftNewtypeAttr::NK_Struct: {
1288
+
1289
+ auto underlyingType = Impl.importType (
1290
+ Decl->getUnderlyingType (), ImportTypeKind::Typedef,
1291
+ isInSystemModule (DC),
1292
+ Decl->getUnderlyingType ()->isBlockPointerType ());
1293
+
1294
+ auto &cxt = Impl.SwiftContext ;
1295
+ auto Loc = Impl.importSourceLoc (Decl->getLocation ());
1296
+
1297
+ auto structDecl = Impl.createDeclWithClangNode <StructDecl>(
1298
+ Decl, Loc, Name, Loc, None, nullptr , DC);
1299
+ structDecl->computeType ();
1300
+
1301
+ ProtocolDecl *protocols[] = {
1302
+ cxt.getProtocol (KnownProtocolKind::RawRepresentable),
1303
+ };
1304
+ makeStructRawValued (structDecl, underlyingType,
1305
+ {KnownProtocolKind::RawRepresentable},
1306
+ protocols);
1307
+
1308
+ Impl.ImportedDecls [Decl->getCanonicalDecl ()] = structDecl;
1309
+ Impl.registerExternalDecl (structDecl);
1310
+ return structDecl;
1311
+ }
1312
+ }
1313
+
1314
+ }
1315
+ }
1316
+
1278
1317
if (!SwiftType) {
1279
1318
// Import typedefs of blocks as their fully-bridged equivalent Swift
1280
1319
// type. That matches how we want to use them in most cases. All other
@@ -1379,6 +1418,73 @@ namespace {
1379
1418
return constructor;
1380
1419
}
1381
1420
1421
+ // / Make a struct declaration into a raw-value-backed struct
1422
+ // /
1423
+ // / \param structDecl the struct to make a raw value for
1424
+ // / \param underlyingType the type of the raw value
1425
+ // / \param synthesizedProtocolAttrs synthesized protocol attributes to add
1426
+ // / \param protocols the protocols to make this struct conform to
1427
+ // / \param setterAccessibility the accessiblity of the raw value's setter
1428
+ // / \param isLet whether the raw value should be a let
1429
+ // / \param makeUnlabeledValueInit whether to also create an unlabeled init
1430
+ // / \param isImplicit whether to mark the rawValue as implicit
1431
+ // /
1432
+ // / This will perform most of the work involved in making a new Swift struct
1433
+ // / be backed by a raw value. This will populated derived protocols and
1434
+ // / synthesized protocols, add the new variable and pattern bindings, and
1435
+ // / create the inits parameterized over a raw value
1436
+ // /
1437
+ template <unsigned N>
1438
+ void makeStructRawValued (
1439
+ StructDecl *structDecl,
1440
+ Type underlyingType,
1441
+ ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs,
1442
+ ProtocolDecl *const (&protocols)[N],
1443
+ Accessibility setterAccessibility = Accessibility::Private,
1444
+ bool isLet = true,
1445
+ bool makeUnlabeledValueInit = false,
1446
+ bool isImplicit = true) {
1447
+ auto &cxt = Impl.SwiftContext ;
1448
+ populateInheritedTypes (structDecl, protocols);
1449
+
1450
+ // Note synthesized protocols
1451
+ for (auto kind : synthesizedProtocolAttrs)
1452
+ structDecl->getAttrs ().add (new (cxt) SynthesizedProtocolAttr (kind));
1453
+
1454
+ // Create a variable to store the underlying value.
1455
+ auto varName = cxt.Id_rawValue ;
1456
+ auto var = new (cxt) VarDecl (
1457
+ /* static*/ false ,
1458
+ /* IsLet*/ isLet, SourceLoc (), varName, underlyingType, structDecl);
1459
+ if (isImplicit)
1460
+ var->setImplicit ();
1461
+ var->setAccessibility (Accessibility::Public);
1462
+ var->setSetterAccessibility (setterAccessibility);
1463
+
1464
+ // Create a pattern binding to describe the variable.
1465
+ Pattern *varPattern = createTypedNamedPattern (var);
1466
+
1467
+ auto patternBinding = PatternBindingDecl::create (
1468
+ cxt, SourceLoc (), StaticSpellingKind::None, SourceLoc (), varPattern,
1469
+ nullptr , structDecl);
1470
+ structDecl->setHasDelayedMembers ();
1471
+
1472
+ // Create constructors to initialize that value from a value of the
1473
+ // underlying type.
1474
+ if (makeUnlabeledValueInit)
1475
+ structDecl->addMember (createValueConstructor (
1476
+ structDecl, var,
1477
+ /* wantCtorParamNames=*/ false ,
1478
+ /* wantBody=*/ !Impl.hasFinishedTypeChecking ()));
1479
+ structDecl->addMember (
1480
+ createValueConstructor (structDecl, var,
1481
+ /* wantCtorParamNames=*/ true ,
1482
+ /* wantBody=*/ !Impl.hasFinishedTypeChecking ()));
1483
+
1484
+ structDecl->addMember (patternBinding);
1485
+ structDecl->addMember (var);
1486
+ }
1487
+
1382
1488
// / \brief Create a constructor that initializes a struct from its members.
1383
1489
ConstructorDecl *createValueConstructor (StructDecl *structDecl,
1384
1490
ArrayRef<VarDecl *> members,
@@ -1625,45 +1731,10 @@ namespace {
1625
1731
Loc, name, Loc, None, nullptr , dc);
1626
1732
structDecl->computeType ();
1627
1733
1628
- // Note that this is a raw option set type.
1629
- structDecl->getAttrs ().add (
1630
- new (Impl.SwiftContext ) SynthesizedProtocolAttr (
1631
- KnownProtocolKind::OptionSet));
1632
-
1633
-
1634
- // Create a field to store the underlying value.
1635
- auto varName = Impl.SwiftContext .Id_rawValue ;
1636
- auto var = new (Impl.SwiftContext ) VarDecl (/* static*/ false ,
1637
- /* IsLet*/ true ,
1638
- SourceLoc (), varName,
1639
- underlyingType,
1640
- structDecl);
1641
- var->setImplicit ();
1642
- var->setAccessibility (Accessibility::Public);
1643
- var->setSetterAccessibility (Accessibility::Private);
1644
-
1645
- // Create a pattern binding to describe the variable.
1646
- Pattern *varPattern = createTypedNamedPattern (var);
1647
-
1648
- auto patternBinding =
1649
- PatternBindingDecl::create (Impl.SwiftContext , SourceLoc (),
1650
- StaticSpellingKind::None, SourceLoc (),
1651
- varPattern, nullptr , structDecl);
1652
-
1653
- // Create the init(rawValue:) constructor.
1654
- auto labeledValueConstructor = createValueConstructor (
1655
- structDecl, var,
1656
- /* wantCtorParamNames=*/ true ,
1657
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1658
-
1659
- // Build an OptionSet conformance for the type.
1660
1734
ProtocolDecl *protocols[]
1661
1735
= {cxt.getProtocol (KnownProtocolKind::OptionSet)};
1662
- populateInheritedTypes (structDecl, protocols);
1663
-
1664
- structDecl->addMember (labeledValueConstructor);
1665
- structDecl->addMember (patternBinding);
1666
- structDecl->addMember (var);
1736
+ makeStructRawValued (structDecl, underlyingType,
1737
+ {KnownProtocolKind::OptionSet}, protocols);
1667
1738
return structDecl;
1668
1739
}
1669
1740
@@ -1714,49 +1785,12 @@ namespace {
1714
1785
ProtocolDecl *protocols[]
1715
1786
= {cxt.getProtocol (KnownProtocolKind::RawRepresentable),
1716
1787
cxt.getProtocol (KnownProtocolKind::Equatable)};
1717
- populateInheritedTypes (structDecl, protocols);
1718
-
1719
- // Note that this is a raw representable type.
1720
- structDecl->getAttrs ().add (
1721
- new (Impl.SwiftContext ) SynthesizedProtocolAttr (
1722
- KnownProtocolKind::RawRepresentable));
1723
-
1724
- // Create a variable to store the underlying value.
1725
- auto varName = Impl.SwiftContext .Id_rawValue ;
1726
- auto var = new (Impl.SwiftContext ) VarDecl (/* static*/ false ,
1727
- /* IsLet*/ false ,
1728
- SourceLoc (), varName,
1729
- underlyingType,
1730
- structDecl);
1731
- var->setAccessibility (Accessibility::Public);
1732
- var->setSetterAccessibility (Accessibility::Public);
1733
-
1734
- // Create a pattern binding to describe the variable.
1735
- Pattern *varPattern = createTypedNamedPattern (var);
1736
-
1737
- auto patternBinding =
1738
- PatternBindingDecl::create (Impl.SwiftContext , SourceLoc (),
1739
- StaticSpellingKind::None, SourceLoc (),
1740
- varPattern, nullptr , structDecl);
1741
-
1742
- // Create a constructor to initialize that value from a value of the
1743
- // underlying type.
1744
- auto valueConstructor =
1745
- createValueConstructor (structDecl, var,
1746
- /* wantCtorParamNames=*/ false ,
1747
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1748
- auto labeledValueConstructor =
1749
- createValueConstructor (structDecl, var,
1750
- /* wantCtorParamNames=*/ true ,
1751
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1752
-
1753
- structDecl->setHasDelayedMembers ();
1754
-
1755
- // Set the members of the struct.
1756
- structDecl->addMember (valueConstructor);
1757
- structDecl->addMember (labeledValueConstructor);
1758
- structDecl->addMember (patternBinding);
1759
- structDecl->addMember (var);
1788
+ makeStructRawValued (structDecl, underlyingType,
1789
+ {KnownProtocolKind::RawRepresentable}, protocols,
1790
+ /* setterAccessibility=*/ Accessibility::Public,
1791
+ /* isLet=*/ false ,
1792
+ /* makeUnlabeledValueInit=*/ true ,
1793
+ /* isImplicit=*/ false );
1760
1794
1761
1795
result = structDecl;
1762
1796
break ;
0 commit comments