[clang] [Serialization] Load Specializations Lazily (PR #76774)
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 21 18:03:07 PST 2024
================
@@ -3924,6 +3925,154 @@ class ASTDeclContextNameLookupTrait {
} // namespace
+namespace {
+class SpecializationsLookupTrait {
+ ASTWriter &Writer;
+ llvm::SmallVector<DeclID, 64> DeclIDs;
+
+public:
+ using key_type = unsigned;
+ using key_type_ref = key_type;
+
+ /// A start and end index into DeclIDs, representing a sequence of decls.
+ using data_type = std::pair<unsigned, unsigned>;
+ using data_type_ref = const data_type &;
+
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
+
+ explicit SpecializationsLookupTrait(ASTWriter &Writer) : Writer(Writer) {}
+
+ template <typename Col> data_type getData(Col &&C) {
+ unsigned Start = DeclIDs.size();
+ for (auto *D : C)
+ DeclIDs.push_back(Writer.GetDeclRef(getDeclForLocalLookup(
+ Writer.getLangOpts(), const_cast<NamedDecl *>(D))));
+ return std::make_pair(Start, DeclIDs.size());
+ }
+
+ data_type
+ ImportData(const reader::SpecializationsLookupTrait::data_type &FromReader) {
+ unsigned Start = DeclIDs.size();
+ for (auto ID : FromReader)
+ DeclIDs.push_back(ID);
+ return std::make_pair(Start, DeclIDs.size());
+ }
+
+ static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
+
+ hash_value_type ComputeHash(key_type Name) { return Name; }
+
+ void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
+ assert(Writer.hasChain() &&
+ "have reference to loaded module file but no chain?");
+
+ using namespace llvm::support;
+ endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F),
+ llvm::endianness::little);
+ }
+
+ std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
+ key_type HashValue,
+ data_type_ref Lookup) {
+ // 4 bytes for each slot.
+ unsigned KeyLen = 4;
+ unsigned DataLen = 4 * (Lookup.second - Lookup.first);
+
+ return emitULEBKeyDataLength(KeyLen, DataLen, Out);
+ }
+
+ void EmitKey(raw_ostream &Out, key_type HashValue, unsigned) {
+ using namespace llvm::support;
+
+ endian::Writer LE(Out, llvm::endianness::little);
+ LE.write<uint32_t>(HashValue);
+ }
+
+ void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
+ unsigned DataLen) {
+ using namespace llvm::support;
+
+ endian::Writer LE(Out, llvm::endianness::little);
+ uint64_t Start = Out.tell();
+ (void)Start;
+ for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
+ LE.write<uint32_t>(DeclIDs[I]);
+ assert(Out.tell() - Start == DataLen && "Data length is wrong");
+ }
+};
+
+unsigned CalculateODRHashForSpecs(const Decl *Spec) {
----------------
ChuanqiXu9 wrote:
It looks like the implementation is basically the same with https://reviews.llvm.org/D41416# except this patch added the size of templated args, which shouldn't matter.
https://github.com/llvm/llvm-project/pull/76774
More information about the cfe-commits
mailing list