diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp | 250 |
1 files changed, 167 insertions, 83 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp index fd6708dd5c3f..20ca6d6fd512 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp @@ -159,6 +159,22 @@ namespace clang { Writer.AddStmt(FD->getBody()); } + /// Add to the record the first declaration from each module file that + /// provides a declaration of D. The intent is to provide a sufficient + /// set such that reloading this set will load all current redeclarations. + void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) { + llvm::MapVector<ModuleFile*, const Decl*> Firsts; + // FIXME: We can skip entries that we know are implied by others. + for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) { + if (R->isFromASTFile()) + Firsts[Writer.Chain->getOwningModuleFile(R)] = R; + else if (IncludeLocal) + Firsts[nullptr] = R; + } + for (const auto &F : Firsts) + Writer.AddDeclRef(F.second, Record); + } + /// Get the specialization decl from an entry in the specialization list. template <typename EntryType> typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * @@ -192,22 +208,48 @@ namespace clang { auto &&PartialSpecializations = getPartialSpecializations(Common); ArrayRef<DeclID> LazySpecializations; if (auto *LS = Common->LazySpecializations) - LazySpecializations = ArrayRef<DeclID>(LS + 1, LS + 1 + LS[0]); + LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]); + + // Add a slot to the record for the number of specializations. + unsigned I = Record.size(); + Record.push_back(0); - Record.push_back(Specializations.size() + - PartialSpecializations.size() + - LazySpecializations.size()); for (auto &Entry : Specializations) { auto *D = getSpecializationDecl(Entry); assert(D->isCanonicalDecl() && "non-canonical decl in set"); - Writer.AddDeclRef(D, Record); + AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } for (auto &Entry : PartialSpecializations) { auto *D = getSpecializationDecl(Entry); assert(D->isCanonicalDecl() && "non-canonical decl in set"); - Writer.AddDeclRef(D, Record); + AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } Record.append(LazySpecializations.begin(), LazySpecializations.end()); + + // Update the size entry we added earlier. + Record[I] = Record.size() - I - 1; + } + + /// Ensure that this template specialization is associated with the specified + /// template on reload. + void RegisterTemplateSpecialization(const Decl *Template, + const Decl *Specialization) { + Template = Template->getCanonicalDecl(); + + // If the canonical template is local, we'll write out this specialization + // when we emit it. + // FIXME: We can do the same thing if there is any local declaration of + // the template, to avoid emitting an update record. + if (!Template->isFromASTFile()) + return; + + // We only need to associate the first local declaration of the + // specialization. The other declarations will get pulled in by it. + if (Writer.getFirstLocalDecl(Specialization) != Specialization) + return; + + Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate( + UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization)); } }; } @@ -218,7 +260,7 @@ void ASTDeclWriter::Visit(Decl *D) { // Source locations require array (variable-length) abbreviations. The // abbreviation infrastructure requires that arrays are encoded last, so // we handle it here in the case of those classes derived from DeclaratorDecl - if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)){ + if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { Writer.AddTypeSourceInfo(DD->getTypeSourceInfo(), Record); } @@ -234,7 +276,10 @@ void ASTDeclWriter::Visit(Decl *D) { void ASTDeclWriter::VisitDecl(Decl *D) { Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record); - Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record); + if (D->getDeclContext() != D->getLexicalDeclContext()) + Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record); + else + Record.push_back(0); Record.push_back(D->isInvalidDecl()); Record.push_back(D->hasAttrs()); if (D->hasAttrs()) @@ -298,7 +343,8 @@ void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) { void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { VisitTypedefNameDecl(D); - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->isImplicit() && D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && @@ -336,9 +382,6 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) { Record.push_back(2); Writer.AddDeclRef(TD, Record); Writer.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo(), Record); - } else if (auto *DD = D->getDeclaratorForAnonDecl()) { - Record.push_back(3); - Writer.AddDeclRef(DD, Record); } else { Record.push_back(0); } @@ -363,12 +406,12 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { Writer.AddDeclRef(nullptr, Record); } - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && !D->hasExtInfo() && !D->getTypedefNameForAnonDecl() && - !D->getDeclaratorForAnonDecl() && D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->isReferenced() && @@ -392,12 +435,12 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { Record.push_back(D->hasObjectMember()); Record.push_back(D->hasVolatileMember()); - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && !D->hasExtInfo() && !D->getTypedefNameForAnonDecl() && - !D->getDeclaratorForAnonDecl() && D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->isReferenced() && @@ -479,6 +522,9 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { case FunctionDecl::TK_FunctionTemplateSpecialization: { FunctionTemplateSpecializationInfo * FTSInfo = D->getTemplateSpecializationInfo(); + + RegisterTemplateSpecialization(FTSInfo->getTemplate(), D); + Writer.AddDeclRef(FTSInfo->getTemplate(), Record); Record.push_back(FTSInfo->getTemplateSpecializationKind()); @@ -648,7 +694,8 @@ void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) { Record.push_back(D->getAccessControl()); Record.push_back(D->getSynthesize()); - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && !D->isInvalidDecl() && @@ -780,7 +827,8 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) { if (!D->getDeclName()) Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record); - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && !D->isInvalidDecl() && @@ -854,7 +902,8 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(VarNotTemplate); } - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && !D->isInvalidDecl() && @@ -902,7 +951,8 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here // we dynamically check for the properties that we optimize for, but don't // know are true of all PARM_VAR_DECLs. - if (!D->hasAttrs() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + !D->hasAttrs() && !D->hasExtInfo() && !D->isImplicit() && !D->isUsed(false) && @@ -1122,7 +1172,8 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) { Record.push_back(0); } - if (D->getFirstDecl() == D->getMostRecentDecl() && + if (D->getDeclContext() == D->getLexicalDeclContext() && + D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() && @@ -1249,6 +1300,8 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { void ASTDeclWriter::VisitClassTemplateSpecializationDecl( ClassTemplateSpecializationDecl *D) { + RegisterTemplateSpecialization(D->getSpecializedTemplate(), D); + VisitCXXRecordDecl(D); llvm::PointerUnion<ClassTemplateDecl *, @@ -1308,6 +1361,8 @@ void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) { void ASTDeclWriter::VisitVarTemplateSpecializationDecl( VarTemplateSpecializationDecl *D) { + RegisterTemplateSpecialization(D->getSpecializedTemplate(), D); + VisitVarDecl(D); llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> @@ -1478,48 +1533,77 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, Record.push_back(VisibleOffset); } -/// Determine whether D is the first declaration in its redeclaration chain that -/// is not from an AST file. -template <typename T> -static bool isFirstLocalDecl(Redeclarable<T> *D) { - assert(D && !static_cast<T*>(D)->isFromASTFile()); - do - D = D->getPreviousDecl(); - while (D && static_cast<T*>(D)->isFromASTFile()); - return !D; +const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) { + /// \brief Is this a local declaration (that is, one that will be written to + /// our AST file)? This is the case for declarations that are neither imported + /// from another AST file nor predefined. + auto IsLocalDecl = [&](const Decl *D) -> bool { + if (D->isFromASTFile()) + return false; + auto I = DeclIDs.find(D); + return (I == DeclIDs.end() || I->second >= NUM_PREDEF_DECL_IDS); + }; + + assert(IsLocalDecl(D) && "expected a local declaration"); + + const Decl *Canon = D->getCanonicalDecl(); + if (IsLocalDecl(Canon)) + return Canon; + + const Decl *&CacheEntry = FirstLocalDeclCache[Canon]; + if (CacheEntry) + return CacheEntry; + + for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl()) + if (IsLocalDecl(Redecl)) + D = Redecl; + return CacheEntry = D; } template <typename T> void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { T *First = D->getFirstDecl(); T *MostRecent = First->getMostRecentDecl(); + T *DAsT = static_cast<T *>(D); if (MostRecent != First) { - assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) && + assert(isRedeclarableDeclKind(DAsT->getKind()) && "Not considered redeclarable?"); Writer.AddDeclRef(First, Record); - // In a modules build, emit a list of all imported key declarations - // (excluding First, if it was imported), so that we can be sure that all - // redeclarations visible to this module are before D in the redecl chain. - unsigned I = Record.size(); - Record.push_back(0); - if (Context.getLangOpts().Modules && Writer.Chain) { - if (isFirstLocalDecl(D)) { - Writer.Chain->forEachImportedKeyDecl(First, [&](const Decl *D) { - if (D != First) - Writer.AddDeclRef(D, Record); - }); - Record[I] = Record.size() - I - 1; - - // Write a redeclaration chain, attached to the first key decl. - Writer.Redeclarations.push_back(Writer.Chain->getKeyDeclaration(First)); + // Write out a list of local redeclarations of this declaration if it's the + // first local declaration in the chain. + const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT); + if (DAsT == FirstLocal) { + // Emit a list of all imported first declarations so that we can be sure + // that all redeclarations visible to this module are before D in the + // redecl chain. + unsigned I = Record.size(); + Record.push_back(0); + if (Writer.Chain) + AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false); + // This is the number of imported first declarations + 1. + Record[I] = Record.size() - I; + + // Collect the set of local redeclarations of this declaration, from + // newest to oldest. + RecordData LocalRedecls; + for (const Decl *Prev = FirstLocal->getMostRecentDecl(); + Prev != FirstLocal; Prev = Prev->getPreviousDecl()) + if (!Prev->isFromASTFile()) + Writer.AddDeclRef(Prev, LocalRedecls); + + // If we have any redecls, write them now as a separate record preceding + // the declaration itself. + if (LocalRedecls.empty()) + Record.push_back(0); + else { + Record.push_back(Writer.Stream.GetCurrentBitNo()); + Writer.Stream.EmitRecord(LOCAL_REDECLARATIONS, LocalRedecls); } - } else if (D == First || D->getPreviousDecl()->isFromASTFile()) { - assert(isFirstLocalDecl(D) && "imported decl after local decl"); - - // Write a redeclaration chain attached to the first decl. - Writer.Redeclarations.push_back(First); + } else { + Record.push_back(0); + Writer.AddDeclRef(FirstLocal, Record); } // Make sure that we serialize both the previous and the most-recent @@ -1558,7 +1642,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD)); // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1591,7 +1675,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR)); // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1629,7 +1713,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1677,7 +1761,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1720,7 +1804,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1767,7 +1851,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1796,7 +1880,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(0)); // isImplicit @@ -1842,7 +1926,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext + Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext Abv->Add(BitCodeAbbrevOp(0)); // Invalid Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit @@ -1977,7 +2061,6 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = new BitCodeAbbrev(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE)); - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv); } @@ -1994,14 +2077,19 @@ void ASTWriter::WriteDeclAbbrevs() { /// clients to use a separate API call to "realize" the decl. This should be /// relatively painless since they would presumably only do it for top-level /// decls. -static bool isRequiredDecl(const Decl *D, ASTContext &Context) { +static bool isRequiredDecl(const Decl *D, ASTContext &Context, + bool WritingModule) { // An ObjCMethodDecl is never considered as "required" because its // implementation container always is. - // File scoped assembly or obj-c implementation must be seen. ImportDecl is - // used by codegen to determine the set of imported modules to search for - // inputs for automatic linking. - if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D) || isa<ImportDecl>(D)) + // File scoped assembly or obj-c implementation must be seen. + if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D)) + return true; + + // ImportDecl is used by codegen to determine the set of imported modules to + // search for inputs for automatic linking; include it if it has a semantic + // effect. + if (isa<ImportDecl>(D) && !WritingModule) return true; return Context.DeclMustBeEmitted(D); @@ -2016,16 +2104,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Determine the ID for this declaration. serialization::DeclID ID; - if (D->isFromASTFile()) { - assert(isRewritten(D) && "should not be emitting imported decl"); - ID = getDeclID(D); - } else { - serialization::DeclID &IDR = DeclIDs[D]; - if (IDR == 0) - IDR = NextDeclID++; + assert(!D->isFromASTFile() && "should not be emitting imported decl"); + serialization::DeclID &IDR = DeclIDs[D]; + if (IDR == 0) + IDR = NextDeclID++; - ID= IDR; - } + ID = IDR; bool isReplacingADecl = ID < FirstDeclID; @@ -2050,6 +2134,13 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { VisibleOffset = WriteDeclContextVisibleBlock(Context, DC); } + // Build a record for this declaration + Record.clear(); + W.Code = (serialization::DeclCode)0; + W.AbbrevToUse = 0; + W.Visit(D); + if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); + if (isReplacingADecl) { // We're replacing a decl in a previous file. ReplacedDecls.push_back(ReplacedDeclInfo(ID, Stream.GetCurrentBitNo(), @@ -2066,19 +2157,12 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { DeclOffsets[Index].setLocation(Loc); DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo(); } - + SourceManager &SM = Context.getSourceManager(); if (Loc.isValid() && SM.isLocalSourceLocation(Loc)) associateDeclWithFile(D, ID); } - // Build and emit a record for this declaration - Record.clear(); - W.Code = (serialization::DeclCode)0; - W.AbbrevToUse = 0; - W.Visit(D); - if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); - if (!W.Code) llvm::report_fatal_error(StringRef("unexpected declaration kind '") + D->getDeclKindName() + "'"); @@ -2090,7 +2174,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Note declarations that should be deserialized eagerly so that we can add // them to a record in the AST file later. - if (isRequiredDecl(D, Context)) + if (isRequiredDecl(D, Context, WritingModule)) EagerlyDeserializedDecls.push_back(ID); } |