@@ -434,6 +434,43 @@ namespace {
434
434
}
435
435
}
436
436
};
437
+
438
+ class DeclFingerprintsTableInfo {
439
+ public:
440
+ using key_type = DeclID;
441
+ using key_type_ref = const key_type &;
442
+ using data_type = std::string;
443
+ using data_type_ref = llvm::StringRef;
444
+ using hash_value_type = uint32_t ;
445
+ using offset_type = unsigned ;
446
+
447
+ hash_value_type ComputeHash (key_type_ref key) {
448
+ return llvm::hash_value (static_cast <uint32_t >(key));
449
+ }
450
+
451
+ std::pair<unsigned , unsigned >
452
+ EmitKeyDataLength (raw_ostream &out, key_type_ref key, data_type_ref data) {
453
+ assert ((data.size () == 32 ) && " Fingerprint must be 32-bytes long!" );
454
+ endian::Writer writer (out, little);
455
+ // No need to write the key length; it's constant.
456
+ writer.write <uint16_t >(data.size ());
457
+ return {sizeof (uint32_t ), data.size ()};
458
+ }
459
+
460
+ void EmitKey (raw_ostream &out, key_type_ref key, unsigned len) {
461
+ static_assert (declIDFitsIn32Bits (), " DeclID too large" );
462
+ assert (len == sizeof (uint32_t ));
463
+ endian::Writer writer (out, little);
464
+ writer.write <uint32_t >(key);
465
+ }
466
+
467
+ void EmitData (raw_ostream &out, key_type_ref key, data_type_ref data,
468
+ unsigned len) {
469
+ static_assert (declIDFitsIn32Bits (), " DeclID too large" );
470
+ endian::Writer writer (out, little);
471
+ out << data;
472
+ }
473
+ };
437
474
} // end anonymous namespace
438
475
439
476
static ModuleDecl *getModule (ModuleOrSourceFile DC) {
@@ -799,6 +836,7 @@ void Serializer::writeBlockInfoBlock() {
799
836
BLOCK_RECORD (index_block, PRECEDENCE_GROUPS);
800
837
BLOCK_RECORD (index_block, NESTED_TYPE_DECLS);
801
838
BLOCK_RECORD (index_block, DECL_MEMBER_NAMES);
839
+ BLOCK_RECORD (index_block, DECL_FINGERPRINTS);
802
840
BLOCK_RECORD (index_block, ORDERED_TOP_LEVEL_DECLS);
803
841
804
842
BLOCK (DECL_MEMBER_TABLES_BLOCK);
@@ -4806,6 +4844,27 @@ writeDeclMembersTable(const decl_member_tables_block::DeclMembersLayout &mems,
4806
4844
mems.emit (scratch, tableOffset, hashTableBlob);
4807
4845
}
4808
4846
4847
+ static void
4848
+ writeDeclFingerprintsTable (const index_block::DeclFingerprintsLayout &fpl,
4849
+ const Serializer::DeclFingerprintsTable &table) {
4850
+ SmallVector<uint64_t , 8 > scratch;
4851
+ llvm::SmallString<4096 > hashTableBlob;
4852
+ uint32_t tableOffset;
4853
+ {
4854
+ llvm::OnDiskChainedHashTableGenerator<DeclFingerprintsTableInfo> generator;
4855
+ for (auto &entry : table) {
4856
+ generator.insert (entry.first , entry.second );
4857
+ }
4858
+
4859
+ llvm::raw_svector_ostream blobStream (hashTableBlob);
4860
+ // Make sure that no bucket is at offset 0
4861
+ endian::write <uint32_t >(blobStream, 0 , little);
4862
+ tableOffset = generator.Emit (blobStream);
4863
+ }
4864
+
4865
+ fpl.emit (scratch, tableOffset, hashTableBlob);
4866
+ }
4867
+
4809
4868
namespace {
4810
4869
// / Used to serialize the on-disk Objective-C method hash table.
4811
4870
class ObjCMethodTableInfo {
@@ -5078,6 +5137,7 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
5078
5137
LocalTypeHashTableGenerator localTypeGenerator, opaqueReturnTypeGenerator;
5079
5138
ExtensionTable extensionDecls;
5080
5139
UniquedDerivativeFunctionConfigTable uniquedDerivativeConfigs;
5140
+ DeclFingerprintsTable declFingerprints;
5081
5141
bool hasLocalTypes = false ;
5082
5142
bool hasOpaqueReturnTypes = false ;
5083
5143
@@ -5137,6 +5197,9 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
5137
5197
// derived conformance (for example, ==), force them to be
5138
5198
// serialized.
5139
5199
if (auto IDC = dyn_cast<IterableDeclContext>(D)) {
5200
+ if (auto bodyFP = IDC->getBodyFingerprint ()) {
5201
+ declFingerprints[addDeclRef (D)] = *bodyFP;
5202
+ }
5140
5203
collectInterestingNestedDeclarations (*this , IDC->getMembers (),
5141
5204
operatorMethodDecls, objcMethods,
5142
5205
nestedTypeDecls,
@@ -5167,6 +5230,9 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
5167
5230
localTypeGenerator.insert (MangledName, addDeclRef (TD));
5168
5231
5169
5232
if (auto IDC = dyn_cast<IterableDeclContext>(TD)) {
5233
+ if (auto bodyFP = IDC->getBodyFingerprint ()) {
5234
+ declFingerprints[addDeclRef (TD)] = *bodyFP;
5235
+ }
5170
5236
collectInterestingNestedDeclarations (*this , IDC->getMembers (),
5171
5237
operatorMethodDecls, objcMethods,
5172
5238
nestedTypeDecls,
@@ -5233,6 +5299,12 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
5233
5299
writeNestedTypeDeclsTable (NestedTypeDeclsTable, nestedTypeDecls);
5234
5300
}
5235
5301
5302
+ if (!declFingerprints.empty ()) {
5303
+ // Write decl fingerprints.
5304
+ index_block::DeclFingerprintsLayout DeclsFingerprints (Out);
5305
+ writeDeclFingerprintsTable (DeclsFingerprints, declFingerprints);
5306
+ }
5307
+
5236
5308
// Convert uniqued derivative function config table to serialization-
5237
5309
// ready format: turn `GenericSignature` to `GenericSignatureID`.
5238
5310
DerivativeFunctionConfigTable derivativeConfigs;
0 commit comments