@@ -1307,6 +1307,104 @@ namespace {
1307
1307
return alias;
1308
1308
}
1309
1309
1310
+ // / Create a swift_newtype struct corresponding to a typedef. Returns
1311
+ // / nullptr if unable.
1312
+ Decl *importSwiftNewtype (const clang::TypedefNameDecl *decl,
1313
+ clang::SwiftNewtypeAttr *newtypeAttr,
1314
+ DeclContext *dc, Identifier name) {
1315
+ switch (newtypeAttr->getNewtypeKind ()) {
1316
+ case clang::SwiftNewtypeAttr::NK_Enum:
1317
+ // TODO: import as closed enum instead
1318
+ // For now, fall through and treat as a struct
1319
+ case clang::SwiftNewtypeAttr::NK_Struct:
1320
+ break ;
1321
+ // No other cases yet
1322
+ }
1323
+
1324
+ auto &cxt = Impl.SwiftContext ;
1325
+ auto Loc = Impl.importSourceLoc (decl->getLocation ());
1326
+
1327
+ auto structDecl = Impl.createDeclWithClangNode <StructDecl>(
1328
+ decl, Loc, name, Loc, None, nullptr , dc);
1329
+ structDecl->computeType ();
1330
+
1331
+ // Import the type of the underlying storage
1332
+ auto storedUnderlyingType = Impl.importType (
1333
+ decl->getUnderlyingType (), ImportTypeKind::Value,
1334
+ isInSystemModule (dc), decl->getUnderlyingType ()->isBlockPointerType (),
1335
+ OTK_None);
1336
+
1337
+ // Find a bridged type, which may be different
1338
+ auto computedPropertyUnderlyingType = Impl.importType (
1339
+ decl->getUnderlyingType (), ImportTypeKind::Property,
1340
+ isInSystemModule (dc), decl->getUnderlyingType ()->isBlockPointerType (),
1341
+ OTK_None);
1342
+
1343
+ bool isBridged =
1344
+ !storedUnderlyingType->isEqual (computedPropertyUnderlyingType);
1345
+
1346
+ // Determine the set of protocols to which the synthesized
1347
+ // type will conform.
1348
+ SmallVector<ProtocolDecl *, 4 > protocols;
1349
+ SmallVector<KnownProtocolKind, 4 > synthesizedProtocols;
1350
+
1351
+ // Local function to add a known protocol.
1352
+ auto addKnown = [&](KnownProtocolKind kind) {
1353
+ if (auto proto = cxt.getProtocol (kind)) {
1354
+ protocols.push_back (proto);
1355
+ synthesizedProtocols.push_back (kind);
1356
+ }
1357
+ };
1358
+
1359
+ // Add conformances that are always available.
1360
+ addKnown (KnownProtocolKind::RawRepresentable);
1361
+ addKnown (KnownProtocolKind::SwiftNewtypeWrapper);
1362
+
1363
+ // Local function to add a known protocol only when the
1364
+ // underlying type conforms to it.
1365
+ auto computedNominal = computedPropertyUnderlyingType->getAnyNominal ();
1366
+ auto transferKnown = [&](KnownProtocolKind kind) {
1367
+ if (!computedNominal)
1368
+ return ;
1369
+
1370
+ auto proto = cxt.getProtocol (kind);
1371
+ if (!proto)
1372
+ return ;
1373
+
1374
+ SmallVector<ProtocolConformance *, 1 > conformances;
1375
+ if (computedNominal->lookupConformance (
1376
+ computedNominal->getParentModule (), proto, conformances)) {
1377
+ protocols.push_back (proto);
1378
+ synthesizedProtocols.push_back (kind);
1379
+ }
1380
+ };
1381
+
1382
+ // Transfer conformances. Each of these needs a forwarding
1383
+ // implementation in the standard library.
1384
+ transferKnown (KnownProtocolKind::Equatable);
1385
+ transferKnown (KnownProtocolKind::Hashable);
1386
+ transferKnown (KnownProtocolKind::Comparable);
1387
+ transferKnown (KnownProtocolKind::ObjectiveCBridgeable);
1388
+
1389
+ if (!isBridged) {
1390
+ // Simple, our stored type is equivalent to our computed
1391
+ // type.
1392
+ makeStructRawValued (structDecl, storedUnderlyingType,
1393
+ synthesizedProtocols, protocols);
1394
+ } else {
1395
+ // We need to make a stored rawValue or storage type, and a
1396
+ // computed one of bridged type.
1397
+ makeStructRawValuedWithBridge (structDecl, storedUnderlyingType,
1398
+ computedPropertyUnderlyingType,
1399
+ synthesizedProtocols, protocols);
1400
+ }
1401
+
1402
+ Impl.ImportedDecls [{decl->getCanonicalDecl (), useSwift2Name}] =
1403
+ structDecl;
1404
+ Impl.registerExternalDecl (structDecl);
1405
+ return structDecl;
1406
+ }
1407
+
1310
1408
Decl *VisitTypedefNameDecl (const clang::TypedefNameDecl *Decl) {
1311
1409
Optional<ImportedName> swift3Name;
1312
1410
auto importedName = importFullName (Decl, swift3Name);
@@ -1390,6 +1488,13 @@ namespace {
1390
1488
if (!underlying)
1391
1489
return nullptr ;
1392
1490
1491
+ // Check for a newtype
1492
+ if (auto newtypeAttr =
1493
+ Impl.getSwiftNewtypeAttr (Decl, useSwift2Name))
1494
+ if (auto newtype =
1495
+ importSwiftNewtype (Decl, newtypeAttr, DC, Name))
1496
+ return newtype;
1497
+
1393
1498
// Create a typealias for this CF typedef.
1394
1499
TypeAliasDecl *typealias = nullptr ;
1395
1500
typealias = Impl.createDeclWithClangNode <TypeAliasDecl>(
@@ -1467,104 +1572,10 @@ namespace {
1467
1572
return nullptr ;
1468
1573
1469
1574
// Check for swift_newtype
1470
- if (!SwiftType) {
1471
- if (auto newtypeAttr = Impl.getSwiftNewtypeAttr (Decl, useSwift2Name)) {
1472
- switch (newtypeAttr->getNewtypeKind ()) {
1473
- case clang::SwiftNewtypeAttr::NK_Enum:
1474
- // TODO: import as closed enum instead
1475
-
1476
- // For now, fall through and treat as a struct
1477
- case clang::SwiftNewtypeAttr::NK_Struct: {
1478
-
1479
- auto &cxt = Impl.SwiftContext ;
1480
- auto Loc = Impl.importSourceLoc (Decl->getLocation ());
1481
-
1482
- auto structDecl = Impl.createDeclWithClangNode <StructDecl>(
1483
- Decl, Loc, Name, Loc, None, nullptr , DC);
1484
- structDecl->computeType ();
1485
-
1486
- // Import the type of the underlying storage
1487
- auto storedUnderlyingType = Impl.importType (
1488
- Decl->getUnderlyingType (), ImportTypeKind::Value,
1489
- isInSystemModule (DC),
1490
- Decl->getUnderlyingType ()->isBlockPointerType (),
1491
- OTK_None);
1492
-
1493
- // Find a bridged type, which may be different
1494
- auto computedPropertyUnderlyingType = Impl.importType (
1495
- Decl->getUnderlyingType (), ImportTypeKind::Property,
1496
- isInSystemModule (DC),
1497
- Decl->getUnderlyingType ()->isBlockPointerType (),
1498
- OTK_None);
1499
-
1500
- bool isBridged =
1501
- !storedUnderlyingType->isEqual (computedPropertyUnderlyingType);
1502
-
1503
- // Determine the set of protocols to which the synthesized
1504
- // type will conform.
1505
- SmallVector<ProtocolDecl *, 4 > protocols;
1506
- SmallVector<KnownProtocolKind, 4 > synthesizedProtocols;
1507
-
1508
- // Local function to add a known protocol.
1509
- auto addKnown = [&](KnownProtocolKind kind) {
1510
- if (auto proto = cxt.getProtocol (kind)) {
1511
- protocols.push_back (proto);
1512
- synthesizedProtocols.push_back (kind);
1513
- }
1514
- };
1515
-
1516
- // Add conformances that are always available.
1517
- addKnown (KnownProtocolKind::RawRepresentable);
1518
- addKnown (KnownProtocolKind::SwiftNewtypeWrapper);
1519
-
1520
- // Local function to add a known protocol only when the
1521
- // underlying type conforms to it.
1522
- auto computedNominal =
1523
- computedPropertyUnderlyingType->getAnyNominal ();
1524
- auto transferKnown = [&](KnownProtocolKind kind) {
1525
- if (!computedNominal) return ;
1526
-
1527
- auto proto = cxt.getProtocol (kind);
1528
- if (!proto) return ;
1529
-
1530
- SmallVector<ProtocolConformance *, 1 > conformances;
1531
- if (computedNominal->lookupConformance (
1532
- computedNominal->getParentModule (), proto, conformances)) {
1533
- protocols.push_back (proto);
1534
- synthesizedProtocols.push_back (kind);
1535
- }
1536
- };
1537
-
1538
- // Transfer conformances. Each of these needs a forwarding
1539
- // implementation in the standard library.
1540
- transferKnown (KnownProtocolKind::Equatable);
1541
- transferKnown (KnownProtocolKind::Hashable);
1542
- transferKnown (KnownProtocolKind::Comparable);
1543
- transferKnown (KnownProtocolKind::ObjectiveCBridgeable);
1544
-
1545
- if (!isBridged) {
1546
- // Simple, our stored type is equivalent to our computed
1547
- // type.
1548
- makeStructRawValued (structDecl, storedUnderlyingType,
1549
- synthesizedProtocols, protocols);
1550
- } else {
1551
- // We need to make a stored rawValue or storage type, and a
1552
- // computed one of bridged type.
1553
- makeStructRawValuedWithBridge (
1554
- structDecl, storedUnderlyingType,
1555
- computedPropertyUnderlyingType,
1556
- synthesizedProtocols, protocols);
1557
- }
1558
-
1559
- Impl.ImportedDecls [{Decl->getCanonicalDecl (), useSwift2Name}]
1560
- = structDecl;
1561
- Impl.registerExternalDecl (structDecl);
1562
- return structDecl;
1563
- }
1564
- }
1565
-
1566
- }
1567
- }
1575
+ if (!SwiftType)
1576
+ if (auto newtypeAttr = Impl.getSwiftNewtypeAttr (Decl, useSwift2Name))
1577
+ if (auto newtype = importSwiftNewtype (Decl, newtypeAttr, DC, Name))
1578
+ return newtype;
1568
1579
1569
1580
if (!SwiftType) {
1570
1581
// Import typedefs of blocks as their fully-bridged equivalent Swift
0 commit comments