@@ -1328,11 +1328,20 @@ namespace {
1328
1328
Decl *importSwiftNewtype (const clang::TypedefNameDecl *decl,
1329
1329
clang::SwiftNewtypeAttr *newtypeAttr,
1330
1330
DeclContext *dc, Identifier name) {
1331
+ // The only (current) difference between swift_newtype(struct) and
1332
+ // swift_newtype(enum), until we can get real enum support, is that enums
1333
+ // have no un-labeld inits(). This is because enums are to be considered
1334
+ // closed, and if constructed from a rawValue, should be very explicit.
1335
+ bool unlabeledCtor = false ;
1336
+
1331
1337
switch (newtypeAttr->getNewtypeKind ()) {
1332
1338
case clang::SwiftNewtypeAttr::NK_Enum:
1333
- // TODO: import as closed enum instead
1334
- // For now, fall through and treat as a struct
1339
+ unlabeledCtor = false ;
1340
+ // TODO: import as closed enum instead
1341
+ break ;
1342
+
1335
1343
case clang::SwiftNewtypeAttr::NK_Struct:
1344
+ unlabeledCtor = true ;
1336
1345
break ;
1337
1346
// No other cases yet
1338
1347
}
@@ -1421,13 +1430,15 @@ namespace {
1421
1430
// Simple, our stored type is equivalent to our computed
1422
1431
// type.
1423
1432
makeStructRawValued (structDecl, storedUnderlyingType,
1424
- synthesizedProtocols, protocols);
1433
+ synthesizedProtocols, protocols,
1434
+ /* makeUnlabeledValueInit=*/ unlabeledCtor);
1425
1435
} else {
1426
1436
// We need to make a stored rawValue or storage type, and a
1427
1437
// computed one of bridged type.
1428
1438
makeStructRawValuedWithBridge (structDecl, storedUnderlyingType,
1429
1439
computedPropertyUnderlyingType,
1430
- synthesizedProtocols, protocols);
1440
+ synthesizedProtocols, protocols,
1441
+ /* makeUnlabeledValueInit=*/ unlabeledCtor);
1431
1442
}
1432
1443
1433
1444
Impl.ImportedDecls [{decl->getCanonicalDecl (), useSwift2Name}] =
@@ -1706,9 +1717,9 @@ namespace {
1706
1717
Type underlyingType,
1707
1718
ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs,
1708
1719
ArrayRef<ProtocolDecl *> protocols,
1720
+ bool makeUnlabeledValueInit = false ,
1709
1721
Accessibility setterAccessibility = Accessibility::Private,
1710
1722
bool isLet = true ,
1711
- bool makeUnlabeledValueInit = false ,
1712
1723
bool isImplicit = true ) {
1713
1724
auto &cxt = Impl.SwiftContext ;
1714
1725
addProtocolsToStruct (structDecl, synthesizedProtocolAttrs, protocols);
@@ -1753,14 +1764,12 @@ namespace {
1753
1764
// / over a bridged type that will cast to the stored type, as appropriate.
1754
1765
// /
1755
1766
void makeStructRawValuedWithBridge (
1756
- StructDecl *structDecl,
1757
- Type storedUnderlyingType,
1758
- Type bridgedType,
1767
+ StructDecl *structDecl, Type storedUnderlyingType, Type bridgedType,
1759
1768
ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs,
1760
- ArrayRef<ProtocolDecl *> protocols) {
1769
+ ArrayRef<ProtocolDecl *> protocols,
1770
+ bool makeUnlabeledValueInit = false ) {
1761
1771
auto &cxt = Impl.SwiftContext ;
1762
- addProtocolsToStruct (structDecl, synthesizedProtocolAttrs,
1763
- protocols);
1772
+ addProtocolsToStruct (structDecl, synthesizedProtocolAttrs, protocols);
1764
1773
1765
1774
auto storedVarName = cxt.getIdentifier (" _rawValue" );
1766
1775
auto computedVarName = cxt.Id_rawValue ;
@@ -1774,46 +1783,70 @@ namespace {
1774
1783
1775
1784
//
1776
1785
// Create a computed value variable
1777
- auto computedVar = new (cxt) VarDecl ( /* static */ false ,
1778
- /* IsLet */ false ,
1779
- SourceLoc (), computedVarName,
1780
- bridgedType, structDecl);
1786
+ auto computedVar =
1787
+ new (cxt) VarDecl ( /* static */ false ,
1788
+ /* IsLet */ false , SourceLoc (), computedVarName,
1789
+ bridgedType, structDecl);
1781
1790
computedVar->setImplicit ();
1782
1791
computedVar->setAccessibility (Accessibility::Public);
1783
1792
computedVar->setSetterAccessibility (Accessibility::Private);
1784
1793
1785
1794
// Create the getter for the computed value variable.
1786
- auto computedVarGetter = makeNewtypeBridgedRawValueGetter (Impl,
1787
- structDecl,
1788
- computedVar,
1789
- storedVar);
1795
+ auto computedVarGetter = makeNewtypeBridgedRawValueGetter (
1796
+ Impl, structDecl, computedVar, storedVar);
1790
1797
1791
1798
// Create a pattern binding to describe the variable.
1792
1799
Pattern *computedVarPattern = createTypedNamedPattern (computedVar);
1793
1800
auto computedPatternBinding = PatternBindingDecl::create (
1794
1801
cxt, SourceLoc (), StaticSpellingKind::None, SourceLoc (),
1795
1802
computedVarPattern, nullptr , structDecl);
1796
1803
1797
- auto init = createValueConstructor (structDecl, computedVar,
1798
- /* wantCtorParamNames=*/ true ,
1804
+ auto init = createRawValueBridgingConstructor (
1805
+ structDecl, computedVar, storedVar,
1806
+ /* wantLabel*/ true , !Impl.hasFinishedTypeChecking ());
1807
+
1808
+ ConstructorDecl *unlabeledCtor = nullptr ;
1809
+ if (makeUnlabeledValueInit)
1810
+ unlabeledCtor = createRawValueBridgingConstructor (
1811
+ structDecl, computedVar, storedVar,
1812
+ /* wantLabel*/ false , !Impl.hasFinishedTypeChecking ());
1813
+
1814
+ structDecl->setHasDelayedMembers ();
1815
+ if (unlabeledCtor)
1816
+ structDecl->addMember (unlabeledCtor);
1817
+ structDecl->addMember (init);
1818
+ structDecl->addMember (storedPatternBinding);
1819
+ structDecl->addMember (storedVar);
1820
+ structDecl->addMember (computedPatternBinding);
1821
+ structDecl->addMember (computedVar);
1822
+ structDecl->addMember (computedVarGetter);
1823
+ }
1824
+
1825
+ // / Create a rawValue-ed constructor that bridges to its underlying storage.
1826
+ ConstructorDecl *createRawValueBridgingConstructor (
1827
+ StructDecl *structDecl, VarDecl *computedRawValue,
1828
+ VarDecl *storedRawValue, bool wantLabel, bool wantBody) {
1829
+ auto &cxt = Impl.SwiftContext ;
1830
+ auto init = createValueConstructor (structDecl, computedRawValue,
1831
+ /* wantCtorParamNames=*/ wantLabel,
1799
1832
/* wantBody=*/ false );
1800
1833
// Insert our custom init body
1801
- if (!Impl. hasFinishedTypeChecking () ) {
1834
+ if (wantBody ) {
1802
1835
auto selfDecl = init->getParameterList (0 )->get (0 );
1803
1836
1804
1837
// Construct left-hand side.
1805
1838
Expr *lhs = new (cxt) DeclRefExpr (selfDecl, DeclNameLoc (),
1806
1839
/* Implicit=*/ true );
1807
- lhs = new (cxt) MemberRefExpr (lhs, SourceLoc (), storedVar ,
1840
+ lhs = new (cxt) MemberRefExpr (lhs, SourceLoc (), storedRawValue ,
1808
1841
DeclNameLoc (), /* Implicit=*/ true );
1809
1842
1810
1843
// Construct right-hand side.
1811
1844
// FIXME: get the parameter from the init, and plug it in here.
1812
1845
auto rhs = new (cxt)
1813
- CoerceExpr (new (cxt) DeclRefExpr (
1814
- init-> getParameterList ( 1 )-> get ( 0 ),
1815
- DeclNameLoc ( ),
1816
- /* Implicit= */ true ), {}, {nullptr , storedUnderlyingType });
1846
+ CoerceExpr (new (cxt) DeclRefExpr (init-> getParameterList ( 1 )-> get ( 0 ),
1847
+ DeclNameLoc (),
1848
+ /* Implicit= */ true ),
1849
+ {}, {nullptr , storedRawValue-> getType () });
1817
1850
1818
1851
// Add assignment.
1819
1852
auto assign = new (cxt) AssignExpr (lhs, SourceLoc (), rhs,
@@ -1822,13 +1855,7 @@ namespace {
1822
1855
init->setBody (body);
1823
1856
}
1824
1857
1825
- structDecl->setHasDelayedMembers ();
1826
- structDecl->addMember (init);
1827
- structDecl->addMember (storedPatternBinding);
1828
- structDecl->addMember (storedVar);
1829
- structDecl->addMember (computedPatternBinding);
1830
- structDecl->addMember (computedVar);
1831
- structDecl->addMember (computedVarGetter);
1858
+ return init;
1832
1859
}
1833
1860
1834
1861
// / \brief Create a constructor that initializes a struct from its members.
@@ -2178,9 +2205,9 @@ namespace {
2178
2205
cxt.getProtocol (KnownProtocolKind::Equatable)};
2179
2206
makeStructRawValued (structDecl, underlyingType,
2180
2207
{KnownProtocolKind::RawRepresentable}, protocols,
2208
+ /* makeUnlabeledValueInit=*/ true ,
2181
2209
/* setterAccessibility=*/ Accessibility::Public,
2182
2210
/* isLet=*/ false ,
2183
- /* makeUnlabeledValueInit=*/ true ,
2184
2211
/* isImplicit=*/ false );
2185
2212
2186
2213
result = structDecl;
0 commit comments