@@ -1307,6 +1307,114 @@ 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
+ // If the type is Unmanaged, that is it is not CF ARC audited,
1338
+ // we will store the underlying type and leave it up to the use site
1339
+ // to determine whether to use this new_type, or an Unmanaged<CF...> type.
1340
+ if (auto genericType = storedUnderlyingType->getAs <BoundGenericType>()) {
1341
+ if (genericType->getDecl () == Impl.SwiftContext .getUnmanagedDecl ()) {
1342
+ assert (genericType->getGenericArgs ().size () == 1 && " other args?" );
1343
+ storedUnderlyingType = genericType->getGenericArgs ()[0 ];
1344
+ }
1345
+ }
1346
+
1347
+ // Find a bridged type, which may be different
1348
+ auto computedPropertyUnderlyingType = Impl.importType (
1349
+ decl->getUnderlyingType (), ImportTypeKind::Property,
1350
+ isInSystemModule (dc), decl->getUnderlyingType ()->isBlockPointerType (),
1351
+ OTK_None);
1352
+
1353
+ bool isBridged =
1354
+ !storedUnderlyingType->isEqual (computedPropertyUnderlyingType);
1355
+
1356
+ // Determine the set of protocols to which the synthesized
1357
+ // type will conform.
1358
+ SmallVector<ProtocolDecl *, 4 > protocols;
1359
+ SmallVector<KnownProtocolKind, 4 > synthesizedProtocols;
1360
+
1361
+ // Local function to add a known protocol.
1362
+ auto addKnown = [&](KnownProtocolKind kind) {
1363
+ if (auto proto = cxt.getProtocol (kind)) {
1364
+ protocols.push_back (proto);
1365
+ synthesizedProtocols.push_back (kind);
1366
+ }
1367
+ };
1368
+
1369
+ // Add conformances that are always available.
1370
+ addKnown (KnownProtocolKind::RawRepresentable);
1371
+ addKnown (KnownProtocolKind::SwiftNewtypeWrapper);
1372
+
1373
+ // Local function to add a known protocol only when the
1374
+ // underlying type conforms to it.
1375
+ auto computedNominal = computedPropertyUnderlyingType->getAnyNominal ();
1376
+ auto transferKnown = [&](KnownProtocolKind kind) {
1377
+ if (!computedNominal)
1378
+ return ;
1379
+
1380
+ auto proto = cxt.getProtocol (kind);
1381
+ if (!proto)
1382
+ return ;
1383
+
1384
+ SmallVector<ProtocolConformance *, 1 > conformances;
1385
+ if (computedNominal->lookupConformance (
1386
+ computedNominal->getParentModule (), proto, conformances)) {
1387
+ protocols.push_back (proto);
1388
+ synthesizedProtocols.push_back (kind);
1389
+ }
1390
+ };
1391
+
1392
+ // Transfer conformances. Each of these needs a forwarding
1393
+ // implementation in the standard library.
1394
+ transferKnown (KnownProtocolKind::Equatable);
1395
+ transferKnown (KnownProtocolKind::Hashable);
1396
+ transferKnown (KnownProtocolKind::Comparable);
1397
+ transferKnown (KnownProtocolKind::ObjectiveCBridgeable);
1398
+
1399
+ if (!isBridged) {
1400
+ // Simple, our stored type is equivalent to our computed
1401
+ // type.
1402
+ makeStructRawValued (structDecl, storedUnderlyingType,
1403
+ synthesizedProtocols, protocols);
1404
+ } else {
1405
+ // We need to make a stored rawValue or storage type, and a
1406
+ // computed one of bridged type.
1407
+ makeStructRawValuedWithBridge (structDecl, storedUnderlyingType,
1408
+ computedPropertyUnderlyingType,
1409
+ synthesizedProtocols, protocols);
1410
+ }
1411
+
1412
+ Impl.ImportedDecls [{decl->getCanonicalDecl (), useSwift2Name}] =
1413
+ structDecl;
1414
+ Impl.registerExternalDecl (structDecl);
1415
+ return structDecl;
1416
+ }
1417
+
1310
1418
Decl *VisitTypedefNameDecl (const clang::TypedefNameDecl *Decl) {
1311
1419
Optional<ImportedName> swift3Name;
1312
1420
auto importedName = importFullName (Decl, swift3Name);
@@ -1390,6 +1498,13 @@ namespace {
1390
1498
if (!underlying)
1391
1499
return nullptr ;
1392
1500
1501
+ // Check for a newtype
1502
+ if (auto newtypeAttr =
1503
+ Impl.getSwiftNewtypeAttr (Decl, useSwift2Name))
1504
+ if (auto newtype =
1505
+ importSwiftNewtype (Decl, newtypeAttr, DC, Name))
1506
+ return newtype;
1507
+
1393
1508
// Create a typealias for this CF typedef.
1394
1509
TypeAliasDecl *typealias = nullptr ;
1395
1510
typealias = Impl.createDeclWithClangNode <TypeAliasDecl>(
@@ -1467,104 +1582,10 @@ namespace {
1467
1582
return nullptr ;
1468
1583
1469
1584
// 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
- }
1585
+ if (!SwiftType)
1586
+ if (auto newtypeAttr = Impl.getSwiftNewtypeAttr (Decl, useSwift2Name))
1587
+ if (auto newtype = importSwiftNewtype (Decl, newtypeAttr, DC, Name))
1588
+ return newtype;
1568
1589
1569
1590
if (!SwiftType) {
1570
1591
// Import typedefs of blocks as their fully-bridged equivalent Swift
0 commit comments