Skip to content

Commit b960c6e

Browse files
committed
Derive a Fingerprint from a Module's BasicSourceFileInfo
1 parent 7c5f8a0 commit b960c6e

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

include/swift/AST/Module.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,20 @@ class ModuleDecl : public DeclContext, public TypeDecl {
734734

735735
/// Calls \p callback for each source file of the module.
736736
void collectBasicSourceFileInfo(
737-
llvm::function_ref<void(const BasicSourceFileInfo &)> callback);
737+
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const;
738+
739+
public:
740+
/// Retrieve a fingerprint value that summarizes the contents of this module.
741+
///
742+
/// This interface hash a of a module is guaranteed to change if the interface
743+
/// hash of any of its (primary) source files changes. For example, when
744+
/// building incrementally, the interface hash of this module will change when
745+
/// the primaries contributing to its content changes. In contrast, when
746+
/// a module is deserialized, the hash of every source file contributes to
747+
/// the module's interface hash. It therefore serves as an effective, if
748+
/// coarse-grained, way of determining when top-level changes to a module's
749+
/// contents have been made.
750+
Fingerprint getFingerprint() const;
738751

739752
SourceRange getSourceRange() const { return SourceRange(); }
740753

include/swift/Basic/Fingerprint.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ class Fingerprint final {
9494
return llvm::hash_value(fp.core);
9595
}
9696

97+
public:
98+
bool operator<(const Fingerprint &other) const {
99+
return core < other.core;
100+
}
101+
97102
public:
98103
/// The fingerprint value consisting of 32 bytes of zeroes.
99104
///

lib/AST/Module.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,25 @@ void ModuleDecl::collectBasicSourceFileInfo(
15491549
}
15501550
}
15511551

1552+
Fingerprint ModuleDecl::getFingerprint() const {
1553+
StableHasher hasher = StableHasher::defaultHasher();
1554+
SmallVector<Fingerprint, 16> FPs;
1555+
collectBasicSourceFileInfo([&](const BasicSourceFileInfo &bsfi) {
1556+
FPs.emplace_back(bsfi.InterfaceHash);
1557+
});
1558+
1559+
// Sort the fingerprints lexicographically so we have a stable hash despite
1560+
// an unstable ordering of files across rebuilds.
1561+
// FIXME: If we used a commutative hash combine (say, if we could take an
1562+
// XOR here) we could avoid this sort.
1563+
std::sort(FPs.begin(), FPs.end(), std::less<Fingerprint>());
1564+
for (const auto &FP : FPs) {
1565+
hasher.combine(FP);
1566+
}
1567+
1568+
return Fingerprint{std::move(hasher)};
1569+
}
1570+
15521571
//===----------------------------------------------------------------------===//
15531572
// Cross-Import Overlays
15541573
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)