@@ -351,6 +351,14 @@ namespace {
351
351
= endian::readNext<uint16_t , little, unaligned>(data);
352
352
info.ResultType = std::string (data, data + resultTypeLen);
353
353
data += resultTypeLen;
354
+
355
+ unsigned importAsLength =
356
+ endian::readNext<uint16_t , little, unaligned>(data);
357
+ if (importAsLength > 0 ) {
358
+ info.SwiftImportAs =
359
+ std::string (reinterpret_cast <const char *>(data), importAsLength-1 );
360
+ data += importAsLength-1 ;
361
+ }
354
362
}
355
363
356
364
// / Used to deserialize the on-disk Objective-C method table.
@@ -465,6 +473,24 @@ namespace {
465
473
}
466
474
};
467
475
476
+ // / Used to deserialize the on-disk global function table.
477
+ class MemberFunctionTableInfo
478
+ : public VersionedTableInfo<MemberFunctionTableInfo, unsigned ,
479
+ GlobalFunctionInfo> {
480
+ public:
481
+ static internal_key_type ReadKey (const uint8_t *data, unsigned length) {
482
+ auto nameID = endian::readNext<uint32_t , little, unaligned>(data);
483
+ return nameID;
484
+ }
485
+
486
+ static GlobalFunctionInfo readUnversioned (internal_key_type key,
487
+ const uint8_t *&data) {
488
+ GlobalFunctionInfo info;
489
+ readFunctionInfo (data, info);
490
+ return info;
491
+ }
492
+ };
493
+
468
494
// / Used to deserialize the on-disk enumerator table.
469
495
class EnumConstantTableInfo
470
496
: public VersionedTableInfo<EnumConstantTableInfo, unsigned ,
@@ -506,6 +532,26 @@ namespace {
506
532
static_cast <EnumExtensibilityKind>((payload & 0x3 ) - 1 );
507
533
}
508
534
535
+ auto readStringIfPresent = [&]() -> llvm::Optional<std::string> {
536
+ unsigned len =
537
+ endian::readNext<uint16_t , little, unaligned>(data);
538
+ if (len > 0 ) {
539
+ auto out = std::string (reinterpret_cast <const char *>(data), len-1 );
540
+ data += len-1 ;
541
+ return out;
542
+ }
543
+ return None;
544
+ };
545
+
546
+ if (auto importAs = readStringIfPresent ())
547
+ info.SwiftImportAs = importAs;
548
+
549
+ if (auto importAs = readStringIfPresent ())
550
+ info.SwiftRetainOp = importAs;
551
+
552
+ if (auto importAs = readStringIfPresent ())
553
+ info.SwiftReleaseOp = importAs;
554
+
509
555
readCommonTypeInfo (data, info);
510
556
return info;
511
557
}
@@ -604,6 +650,11 @@ class APINotesReader::Implementation {
604
650
// / The global function table.
605
651
std::unique_ptr<SerializedGlobalFunctionTable> GlobalFunctionTable;
606
652
653
+ using SerializedMemberFunctionTable =
654
+ llvm::OnDiskIterableChainedHashTable<MemberFunctionTableInfo>;
655
+
656
+ std::unique_ptr<SerializedMemberFunctionTable> MemberFunctionTable;
657
+
607
658
using SerializedEnumConstantTable =
608
659
llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
609
660
@@ -646,6 +697,8 @@ class APINotesReader::Implementation {
646
697
SmallVectorImpl<uint64_t > &scratch);
647
698
bool readGlobalFunctionBlock (llvm::BitstreamCursor &cursor,
648
699
SmallVectorImpl<uint64_t > &scratch);
700
+ bool readMemberFunctionBlock (llvm::BitstreamCursor &cursor,
701
+ SmallVectorImpl<uint64_t > &scratch);
649
702
bool readEnumConstantBlock (llvm::BitstreamCursor &cursor,
650
703
SmallVectorImpl<uint64_t > &scratch);
651
704
bool readTagBlock (llvm::BitstreamCursor &cursor,
@@ -1344,6 +1397,84 @@ bool APINotesReader::Implementation::readGlobalFunctionBlock(
1344
1397
return false ;
1345
1398
}
1346
1399
1400
+ bool APINotesReader::Implementation::readMemberFunctionBlock (
1401
+ llvm::BitstreamCursor &cursor,
1402
+ SmallVectorImpl<uint64_t > &scratch) {
1403
+ if (cursor.EnterSubBlock (MEMBER_FUNCTION_BLOCK_ID))
1404
+ return true ;
1405
+
1406
+ llvm::Expected<llvm::BitstreamEntry> maybeNext = cursor.advance ();
1407
+ if (!maybeNext) {
1408
+ // FIXME this drops the error on the floor.
1409
+ consumeError (maybeNext.takeError ());
1410
+ return false ;
1411
+ }
1412
+ llvm::BitstreamEntry next = maybeNext.get ();
1413
+ while (next.Kind != llvm::BitstreamEntry::EndBlock) {
1414
+ if (next.Kind == llvm::BitstreamEntry::Error)
1415
+ return true ;
1416
+
1417
+ if (next.Kind == llvm::BitstreamEntry::SubBlock) {
1418
+ // Unknown sub-block, possibly for use by a future version of the
1419
+ // API notes format.
1420
+ if (cursor.SkipBlock ())
1421
+ return true ;
1422
+
1423
+ maybeNext = cursor.advance ();
1424
+ if (!maybeNext) {
1425
+ // FIXME this drops the error on the floor.
1426
+ consumeError (maybeNext.takeError ());
1427
+ return false ;
1428
+ }
1429
+ next = maybeNext.get ();
1430
+ continue ;
1431
+ }
1432
+
1433
+ scratch.clear ();
1434
+ StringRef blobData;
1435
+ llvm::Expected<unsigned > maybeKind = cursor.readRecord (next.ID , scratch, &blobData);
1436
+ if (!maybeKind) {
1437
+ // FIXME this drops the error on the floor.
1438
+ consumeError (maybeKind.takeError ());
1439
+ return false ;
1440
+ }
1441
+ unsigned kind = maybeKind.get ();
1442
+ switch (kind) {
1443
+ case member_function_block::MEMBER_FUNCTION_DATA: {
1444
+ // Already saw global function table.
1445
+ if (MemberFunctionTable)
1446
+ return true ;
1447
+
1448
+ uint32_t tableOffset;
1449
+ member_function_block::MemberFunctionDataLayout::readRecord (scratch,
1450
+ tableOffset);
1451
+ auto base = reinterpret_cast <const uint8_t *>(blobData.data ());
1452
+
1453
+ MemberFunctionTable.reset (
1454
+ SerializedMemberFunctionTable::Create (base + tableOffset,
1455
+ base + sizeof (uint32_t ),
1456
+ base));
1457
+ break ;
1458
+ }
1459
+
1460
+ default :
1461
+ // Unknown record, possibly for use by a future version of the
1462
+ // module format.
1463
+ break ;
1464
+ }
1465
+
1466
+ maybeNext = cursor.advance ();
1467
+ if (!maybeNext) {
1468
+ // FIXME this drops the error on the floor.
1469
+ consumeError (maybeNext.takeError ());
1470
+ return false ;
1471
+ }
1472
+ next = maybeNext.get ();
1473
+ }
1474
+
1475
+ return false ;
1476
+ }
1477
+
1347
1478
bool APINotesReader::Implementation::readEnumConstantBlock (
1348
1479
llvm::BitstreamCursor &cursor,
1349
1480
SmallVectorImpl<uint64_t > &scratch) {
@@ -1697,6 +1828,14 @@ APINotesReader::APINotesReader(llvm::MemoryBuffer *inputBuffer,
1697
1828
}
1698
1829
break ;
1699
1830
1831
+ case MEMBER_FUNCTION_BLOCK_ID:
1832
+ if (!hasValidControlBlock ||
1833
+ Impl.readMemberFunctionBlock (cursor, scratch)) {
1834
+ failed = true ;
1835
+ return ;
1836
+ }
1837
+ break ;
1838
+
1700
1839
case ENUM_CONSTANT_BLOCK_ID:
1701
1840
if (!hasValidControlBlock ||
1702
1841
Impl.readEnumConstantBlock (cursor, scratch)) {
@@ -1952,6 +2091,19 @@ auto APINotesReader::lookupGlobalFunction(StringRef name)
1952
2091
return { Impl.SwiftVersion , *known };
1953
2092
}
1954
2093
2094
+ auto APINotesReader::lookupMemberFunction (llvm::StringRef name)
2095
+ -> VersionedInfo<GlobalFunctionInfo> {
2096
+ Optional<IdentifierID> nameID = Impl.getIdentifier (name);
2097
+ if (!nameID)
2098
+ return None;
2099
+
2100
+ auto known = Impl.MemberFunctionTable ->find (*nameID);
2101
+ if (known == Impl.MemberFunctionTable ->end ())
2102
+ return None;
2103
+
2104
+ return { Impl.SwiftVersion , *known };
2105
+ }
2106
+
1955
2107
auto APINotesReader::lookupEnumConstant (StringRef name)
1956
2108
-> VersionedInfo<EnumConstantInfo> {
1957
2109
if (!Impl.EnumConstantTable )
0 commit comments