xref: /freebsd-src/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp (revision d686ce931cab72612a9e1ada9fe99d65e11a32a3)
10b57cec5SDimitry Andric //===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements serialization for Declarations.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "ASTCommon.h"
14480093f4SDimitry Andric #include "clang/AST/Attr.h"
150b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclVisitor.h"
180b57cec5SDimitry Andric #include "clang/AST/Expr.h"
190b57cec5SDimitry Andric #include "clang/AST/OpenMPClause.h"
200b57cec5SDimitry Andric #include "clang/AST/PrettyDeclStackTrace.h"
210b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
220b57cec5SDimitry Andric #include "clang/Serialization/ASTReader.h"
23480093f4SDimitry Andric #include "clang/Serialization/ASTRecordWriter.h"
240b57cec5SDimitry Andric #include "llvm/Bitstream/BitstreamWriter.h"
250b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
26bdd1243dSDimitry Andric #include <optional>
270b57cec5SDimitry Andric using namespace clang;
280b57cec5SDimitry Andric using namespace serialization;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
310b57cec5SDimitry Andric // Declaration serialization
320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric namespace clang {
350b57cec5SDimitry Andric   class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
360b57cec5SDimitry Andric     ASTWriter &Writer;
370b57cec5SDimitry Andric     ASTContext &Context;
380b57cec5SDimitry Andric     ASTRecordWriter Record;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric     serialization::DeclCode Code;
410b57cec5SDimitry Andric     unsigned AbbrevToUse;
420b57cec5SDimitry Andric 
430fca6ea1SDimitry Andric     bool GeneratingReducedBMI = false;
440fca6ea1SDimitry Andric 
450b57cec5SDimitry Andric   public:
460b57cec5SDimitry Andric     ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
470fca6ea1SDimitry Andric                   ASTWriter::RecordDataImpl &Record, bool GeneratingReducedBMI)
480b57cec5SDimitry Andric         : Writer(Writer), Context(Context), Record(Writer, Record),
490fca6ea1SDimitry Andric           Code((serialization::DeclCode)0), AbbrevToUse(0),
500fca6ea1SDimitry Andric           GeneratingReducedBMI(GeneratingReducedBMI) {}
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric     uint64_t Emit(Decl *D) {
530b57cec5SDimitry Andric       if (!Code)
540b57cec5SDimitry Andric         llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
550b57cec5SDimitry Andric             D->getDeclKindName() + "'");
560b57cec5SDimitry Andric       return Record.Emit(Code, AbbrevToUse);
570b57cec5SDimitry Andric     }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric     void Visit(Decl *D);
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric     void VisitDecl(Decl *D);
620b57cec5SDimitry Andric     void VisitPragmaCommentDecl(PragmaCommentDecl *D);
630b57cec5SDimitry Andric     void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D);
640b57cec5SDimitry Andric     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
650b57cec5SDimitry Andric     void VisitNamedDecl(NamedDecl *D);
660b57cec5SDimitry Andric     void VisitLabelDecl(LabelDecl *LD);
670b57cec5SDimitry Andric     void VisitNamespaceDecl(NamespaceDecl *D);
680b57cec5SDimitry Andric     void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
690b57cec5SDimitry Andric     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
700b57cec5SDimitry Andric     void VisitTypeDecl(TypeDecl *D);
710b57cec5SDimitry Andric     void VisitTypedefNameDecl(TypedefNameDecl *D);
720b57cec5SDimitry Andric     void VisitTypedefDecl(TypedefDecl *D);
730b57cec5SDimitry Andric     void VisitTypeAliasDecl(TypeAliasDecl *D);
740b57cec5SDimitry Andric     void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
75fe6060f1SDimitry Andric     void VisitUnresolvedUsingIfExistsDecl(UnresolvedUsingIfExistsDecl *D);
760b57cec5SDimitry Andric     void VisitTagDecl(TagDecl *D);
770b57cec5SDimitry Andric     void VisitEnumDecl(EnumDecl *D);
780b57cec5SDimitry Andric     void VisitRecordDecl(RecordDecl *D);
790b57cec5SDimitry Andric     void VisitCXXRecordDecl(CXXRecordDecl *D);
800b57cec5SDimitry Andric     void VisitClassTemplateSpecializationDecl(
810b57cec5SDimitry Andric                                             ClassTemplateSpecializationDecl *D);
820b57cec5SDimitry Andric     void VisitClassTemplatePartialSpecializationDecl(
830b57cec5SDimitry Andric                                      ClassTemplatePartialSpecializationDecl *D);
840b57cec5SDimitry Andric     void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
850b57cec5SDimitry Andric     void VisitVarTemplatePartialSpecializationDecl(
860b57cec5SDimitry Andric         VarTemplatePartialSpecializationDecl *D);
870b57cec5SDimitry Andric     void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
880b57cec5SDimitry Andric     void VisitValueDecl(ValueDecl *D);
890b57cec5SDimitry Andric     void VisitEnumConstantDecl(EnumConstantDecl *D);
900b57cec5SDimitry Andric     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
910b57cec5SDimitry Andric     void VisitDeclaratorDecl(DeclaratorDecl *D);
920b57cec5SDimitry Andric     void VisitFunctionDecl(FunctionDecl *D);
930b57cec5SDimitry Andric     void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D);
940b57cec5SDimitry Andric     void VisitCXXMethodDecl(CXXMethodDecl *D);
950b57cec5SDimitry Andric     void VisitCXXConstructorDecl(CXXConstructorDecl *D);
960b57cec5SDimitry Andric     void VisitCXXDestructorDecl(CXXDestructorDecl *D);
970b57cec5SDimitry Andric     void VisitCXXConversionDecl(CXXConversionDecl *D);
980b57cec5SDimitry Andric     void VisitFieldDecl(FieldDecl *D);
990b57cec5SDimitry Andric     void VisitMSPropertyDecl(MSPropertyDecl *D);
1005ffd83dbSDimitry Andric     void VisitMSGuidDecl(MSGuidDecl *D);
10181ad6265SDimitry Andric     void VisitUnnamedGlobalConstantDecl(UnnamedGlobalConstantDecl *D);
102e8d8bef9SDimitry Andric     void VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D);
1030b57cec5SDimitry Andric     void VisitIndirectFieldDecl(IndirectFieldDecl *D);
1040b57cec5SDimitry Andric     void VisitVarDecl(VarDecl *D);
1050b57cec5SDimitry Andric     void VisitImplicitParamDecl(ImplicitParamDecl *D);
1060b57cec5SDimitry Andric     void VisitParmVarDecl(ParmVarDecl *D);
1070b57cec5SDimitry Andric     void VisitDecompositionDecl(DecompositionDecl *D);
1080b57cec5SDimitry Andric     void VisitBindingDecl(BindingDecl *D);
1090b57cec5SDimitry Andric     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
1100b57cec5SDimitry Andric     void VisitTemplateDecl(TemplateDecl *D);
1110b57cec5SDimitry Andric     void VisitConceptDecl(ConceptDecl *D);
112bdd1243dSDimitry Andric     void VisitImplicitConceptSpecializationDecl(
113bdd1243dSDimitry Andric         ImplicitConceptSpecializationDecl *D);
11455e4f9d5SDimitry Andric     void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
1150b57cec5SDimitry Andric     void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
1160b57cec5SDimitry Andric     void VisitClassTemplateDecl(ClassTemplateDecl *D);
1170b57cec5SDimitry Andric     void VisitVarTemplateDecl(VarTemplateDecl *D);
1180b57cec5SDimitry Andric     void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
1190b57cec5SDimitry Andric     void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
1200b57cec5SDimitry Andric     void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
1210b57cec5SDimitry Andric     void VisitUsingDecl(UsingDecl *D);
122fe6060f1SDimitry Andric     void VisitUsingEnumDecl(UsingEnumDecl *D);
1230b57cec5SDimitry Andric     void VisitUsingPackDecl(UsingPackDecl *D);
1240b57cec5SDimitry Andric     void VisitUsingShadowDecl(UsingShadowDecl *D);
1250b57cec5SDimitry Andric     void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
1260b57cec5SDimitry Andric     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
1270b57cec5SDimitry Andric     void VisitExportDecl(ExportDecl *D);
1280b57cec5SDimitry Andric     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
129bdd1243dSDimitry Andric     void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
1300b57cec5SDimitry Andric     void VisitImportDecl(ImportDecl *D);
1310b57cec5SDimitry Andric     void VisitAccessSpecDecl(AccessSpecDecl *D);
1320b57cec5SDimitry Andric     void VisitFriendDecl(FriendDecl *D);
1330b57cec5SDimitry Andric     void VisitFriendTemplateDecl(FriendTemplateDecl *D);
1340b57cec5SDimitry Andric     void VisitStaticAssertDecl(StaticAssertDecl *D);
1350b57cec5SDimitry Andric     void VisitBlockDecl(BlockDecl *D);
1360b57cec5SDimitry Andric     void VisitCapturedDecl(CapturedDecl *D);
1370b57cec5SDimitry Andric     void VisitEmptyDecl(EmptyDecl *D);
138480093f4SDimitry Andric     void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
1390b57cec5SDimitry Andric     void VisitDeclContext(DeclContext *DC);
1400b57cec5SDimitry Andric     template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
141bdd1243dSDimitry Andric     void VisitHLSLBufferDecl(HLSLBufferDecl *D);
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric     // FIXME: Put in the same order is DeclNodes.td?
1440b57cec5SDimitry Andric     void VisitObjCMethodDecl(ObjCMethodDecl *D);
1450b57cec5SDimitry Andric     void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
1460b57cec5SDimitry Andric     void VisitObjCContainerDecl(ObjCContainerDecl *D);
1470b57cec5SDimitry Andric     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
1480b57cec5SDimitry Andric     void VisitObjCIvarDecl(ObjCIvarDecl *D);
1490b57cec5SDimitry Andric     void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
1500b57cec5SDimitry Andric     void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
1510b57cec5SDimitry Andric     void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
1520b57cec5SDimitry Andric     void VisitObjCImplDecl(ObjCImplDecl *D);
1530b57cec5SDimitry Andric     void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
1540b57cec5SDimitry Andric     void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
1550b57cec5SDimitry Andric     void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
1560b57cec5SDimitry Andric     void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
1570b57cec5SDimitry Andric     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
1580b57cec5SDimitry Andric     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
1590b57cec5SDimitry Andric     void VisitOMPAllocateDecl(OMPAllocateDecl *D);
1600b57cec5SDimitry Andric     void VisitOMPRequiresDecl(OMPRequiresDecl *D);
1610b57cec5SDimitry Andric     void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
1620b57cec5SDimitry Andric     void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
1630b57cec5SDimitry Andric     void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric     /// Add an Objective-C type parameter list to the given record.
1660b57cec5SDimitry Andric     void AddObjCTypeParamList(ObjCTypeParamList *typeParams) {
1670b57cec5SDimitry Andric       // Empty type parameter list.
1680b57cec5SDimitry Andric       if (!typeParams) {
1690b57cec5SDimitry Andric         Record.push_back(0);
1700b57cec5SDimitry Andric         return;
1710b57cec5SDimitry Andric       }
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric       Record.push_back(typeParams->size());
174bdd1243dSDimitry Andric       for (auto *typeParam : *typeParams) {
1750b57cec5SDimitry Andric         Record.AddDeclRef(typeParam);
1760b57cec5SDimitry Andric       }
1770b57cec5SDimitry Andric       Record.AddSourceLocation(typeParams->getLAngleLoc());
1780b57cec5SDimitry Andric       Record.AddSourceLocation(typeParams->getRAngleLoc());
1790b57cec5SDimitry Andric     }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric     /// Add to the record the first declaration from each module file that
1820b57cec5SDimitry Andric     /// provides a declaration of D. The intent is to provide a sufficient
1830b57cec5SDimitry Andric     /// set such that reloading this set will load all current redeclarations.
1840b57cec5SDimitry Andric     void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
1850b57cec5SDimitry Andric       llvm::MapVector<ModuleFile*, const Decl*> Firsts;
1860b57cec5SDimitry Andric       // FIXME: We can skip entries that we know are implied by others.
1870b57cec5SDimitry Andric       for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
1880b57cec5SDimitry Andric         if (R->isFromASTFile())
1890b57cec5SDimitry Andric           Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
1900b57cec5SDimitry Andric         else if (IncludeLocal)
1910b57cec5SDimitry Andric           Firsts[nullptr] = R;
1920b57cec5SDimitry Andric       }
1930b57cec5SDimitry Andric       for (const auto &F : Firsts)
1940b57cec5SDimitry Andric         Record.AddDeclRef(F.second);
1950b57cec5SDimitry Andric     }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric     /// Get the specialization decl from an entry in the specialization list.
1980b57cec5SDimitry Andric     template <typename EntryType>
1990b57cec5SDimitry Andric     typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
2000b57cec5SDimitry Andric     getSpecializationDecl(EntryType &T) {
2010b57cec5SDimitry Andric       return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T);
2020b57cec5SDimitry Andric     }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric     /// Get the list of partial specializations from a template's common ptr.
2050b57cec5SDimitry Andric     template<typename T>
2060b57cec5SDimitry Andric     decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
2070b57cec5SDimitry Andric       return Common->PartialSpecializations;
2080b57cec5SDimitry Andric     }
2090b57cec5SDimitry Andric     ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) {
210bdd1243dSDimitry Andric       return std::nullopt;
2110b57cec5SDimitry Andric     }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric     template<typename DeclTy>
2140b57cec5SDimitry Andric     void AddTemplateSpecializations(DeclTy *D) {
2150b57cec5SDimitry Andric       auto *Common = D->getCommonPtr();
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric       // If we have any lazy specializations, and the external AST source is
2180b57cec5SDimitry Andric       // our chained AST reader, we can just write out the DeclIDs. Otherwise,
2190b57cec5SDimitry Andric       // we need to resolve them to actual declarations.
2200b57cec5SDimitry Andric       if (Writer.Chain != Writer.Context->getExternalSource() &&
2210b57cec5SDimitry Andric           Common->LazySpecializations) {
2220b57cec5SDimitry Andric         D->LoadLazySpecializations();
2230b57cec5SDimitry Andric         assert(!Common->LazySpecializations);
2240b57cec5SDimitry Andric       }
2250b57cec5SDimitry Andric 
2260fca6ea1SDimitry Andric       ArrayRef<GlobalDeclID> LazySpecializations;
2270b57cec5SDimitry Andric       if (auto *LS = Common->LazySpecializations)
2280fca6ea1SDimitry Andric         LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].getRawValue());
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric       // Add a slot to the record for the number of specializations.
2310b57cec5SDimitry Andric       unsigned I = Record.size();
2320b57cec5SDimitry Andric       Record.push_back(0);
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric       // AddFirstDeclFromEachModule might trigger deserialization, invalidating
2350b57cec5SDimitry Andric       // *Specializations iterators.
2360b57cec5SDimitry Andric       llvm::SmallVector<const Decl*, 16> Specs;
2370b57cec5SDimitry Andric       for (auto &Entry : Common->Specializations)
2380b57cec5SDimitry Andric         Specs.push_back(getSpecializationDecl(Entry));
2390b57cec5SDimitry Andric       for (auto &Entry : getPartialSpecializations(Common))
2400b57cec5SDimitry Andric         Specs.push_back(getSpecializationDecl(Entry));
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric       for (auto *D : Specs) {
2430b57cec5SDimitry Andric         assert(D->isCanonicalDecl() && "non-canonical decl in set");
2440b57cec5SDimitry Andric         AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
2450b57cec5SDimitry Andric       }
2460fca6ea1SDimitry Andric       Record.append(
2470fca6ea1SDimitry Andric           DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.begin()),
2480fca6ea1SDimitry Andric           DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.end()));
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric       // Update the size entry we added earlier.
2510b57cec5SDimitry Andric       Record[I] = Record.size() - I - 1;
2520b57cec5SDimitry Andric     }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric     /// Ensure that this template specialization is associated with the specified
2550b57cec5SDimitry Andric     /// template on reload.
2560b57cec5SDimitry Andric     void RegisterTemplateSpecialization(const Decl *Template,
2570b57cec5SDimitry Andric                                         const Decl *Specialization) {
2580b57cec5SDimitry Andric       Template = Template->getCanonicalDecl();
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric       // If the canonical template is local, we'll write out this specialization
2610b57cec5SDimitry Andric       // when we emit it.
2620b57cec5SDimitry Andric       // FIXME: We can do the same thing if there is any local declaration of
2630b57cec5SDimitry Andric       // the template, to avoid emitting an update record.
2640b57cec5SDimitry Andric       if (!Template->isFromASTFile())
2650b57cec5SDimitry Andric         return;
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric       // We only need to associate the first local declaration of the
2680b57cec5SDimitry Andric       // specialization. The other declarations will get pulled in by it.
2690b57cec5SDimitry Andric       if (Writer.getFirstLocalDecl(Specialization) != Specialization)
2700b57cec5SDimitry Andric         return;
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric       Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate(
2730b57cec5SDimitry Andric           UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization));
2740b57cec5SDimitry Andric     }
2750b57cec5SDimitry Andric   };
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric 
2780fca6ea1SDimitry Andric bool clang::CanElideDeclDef(const Decl *D) {
2790fca6ea1SDimitry Andric   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
2800fca6ea1SDimitry Andric     if (FD->isInlined() || FD->isConstexpr())
2810fca6ea1SDimitry Andric       return false;
2820fca6ea1SDimitry Andric 
2830fca6ea1SDimitry Andric     if (FD->isDependentContext())
2840fca6ea1SDimitry Andric       return false;
2850fca6ea1SDimitry Andric 
2860fca6ea1SDimitry Andric     if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
2870fca6ea1SDimitry Andric       return false;
2880fca6ea1SDimitry Andric   }
2890fca6ea1SDimitry Andric 
2900fca6ea1SDimitry Andric   if (auto *VD = dyn_cast<VarDecl>(D)) {
2910fca6ea1SDimitry Andric     if (!VD->getDeclContext()->getRedeclContext()->isFileContext() ||
2920fca6ea1SDimitry Andric         VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(VD) ||
2930fca6ea1SDimitry Andric         // Constant initialized variable may not affect the ABI, but they
2940fca6ea1SDimitry Andric         // may be used in constant evaluation in the frontend, so we have
2950fca6ea1SDimitry Andric         // to remain them.
2960fca6ea1SDimitry Andric         VD->hasConstantInitialization())
2970fca6ea1SDimitry Andric       return false;
2980fca6ea1SDimitry Andric 
2990fca6ea1SDimitry Andric     if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
3000fca6ea1SDimitry Andric       return false;
3010fca6ea1SDimitry Andric   }
3020fca6ea1SDimitry Andric 
3030fca6ea1SDimitry Andric   return true;
3040fca6ea1SDimitry Andric }
3050fca6ea1SDimitry Andric 
3060b57cec5SDimitry Andric void ASTDeclWriter::Visit(Decl *D) {
3070b57cec5SDimitry Andric   DeclVisitor<ASTDeclWriter>::Visit(D);
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   // Source locations require array (variable-length) abbreviations.  The
3100b57cec5SDimitry Andric   // abbreviation infrastructure requires that arrays are encoded last, so
3110b57cec5SDimitry Andric   // we handle it here in the case of those classes derived from DeclaratorDecl
31206c3fb27SDimitry Andric   if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
3130b57cec5SDimitry Andric     if (auto *TInfo = DD->getTypeSourceInfo())
3140b57cec5SDimitry Andric       Record.AddTypeLoc(TInfo->getTypeLoc());
3150b57cec5SDimitry Andric   }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric   // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
3180b57cec5SDimitry Andric   // have been written. We want it last because we will not read it back when
3190b57cec5SDimitry Andric   // retrieving it from the AST, we'll just lazily set the offset.
32006c3fb27SDimitry Andric   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
3210fca6ea1SDimitry Andric     if (!GeneratingReducedBMI || !CanElideDeclDef(FD)) {
3220b57cec5SDimitry Andric       Record.push_back(FD->doesThisDeclarationHaveABody());
3230b57cec5SDimitry Andric       if (FD->doesThisDeclarationHaveABody())
3240b57cec5SDimitry Andric         Record.AddFunctionDefinition(FD);
3250fca6ea1SDimitry Andric     } else
3260fca6ea1SDimitry Andric       Record.push_back(0);
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric 
32906c3fb27SDimitry Andric   // Similar to FunctionDecls, handle VarDecl's initializer here and write it
33006c3fb27SDimitry Andric   // after all other Stmts/Exprs. We will not read the initializer until after
33106c3fb27SDimitry Andric   // we have finished recursive deserialization, because it can recursively
33206c3fb27SDimitry Andric   // refer back to the variable.
33306c3fb27SDimitry Andric   if (auto *VD = dyn_cast<VarDecl>(D)) {
3340fca6ea1SDimitry Andric     if (!GeneratingReducedBMI || !CanElideDeclDef(VD))
33506c3fb27SDimitry Andric       Record.AddVarDeclInit(VD);
3360fca6ea1SDimitry Andric     else
3370fca6ea1SDimitry Andric       Record.push_back(0);
33806c3fb27SDimitry Andric   }
33906c3fb27SDimitry Andric 
34006c3fb27SDimitry Andric   // And similarly for FieldDecls. We already serialized whether there is a
34106c3fb27SDimitry Andric   // default member initializer.
34206c3fb27SDimitry Andric   if (auto *FD = dyn_cast<FieldDecl>(D)) {
34306c3fb27SDimitry Andric     if (FD->hasInClassInitializer()) {
34406c3fb27SDimitry Andric       if (Expr *Init = FD->getInClassInitializer()) {
34506c3fb27SDimitry Andric         Record.push_back(1);
34606c3fb27SDimitry Andric         Record.AddStmt(Init);
34706c3fb27SDimitry Andric       } else {
34806c3fb27SDimitry Andric         Record.push_back(0);
34906c3fb27SDimitry Andric         // Initializer has not been instantiated yet.
35006c3fb27SDimitry Andric       }
35106c3fb27SDimitry Andric     }
35206c3fb27SDimitry Andric   }
35306c3fb27SDimitry Andric 
3540b57cec5SDimitry Andric   // If this declaration is also a DeclContext, write blocks for the
3550b57cec5SDimitry Andric   // declarations that lexically stored inside its context and those
3560b57cec5SDimitry Andric   // declarations that are visible from its context.
35706c3fb27SDimitry Andric   if (auto *DC = dyn_cast<DeclContext>(D))
3580b57cec5SDimitry Andric     VisitDeclContext(DC);
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric void ASTDeclWriter::VisitDecl(Decl *D) {
3625f757f3fSDimitry Andric   BitsPacker DeclBits;
363cb14a3feSDimitry Andric 
364cb14a3feSDimitry Andric   // The order matters here. It will be better to put the bit with higher
365cb14a3feSDimitry Andric   // probability to be 0 in the end of the bits.
366cb14a3feSDimitry Andric   //
367cb14a3feSDimitry Andric   // Since we're using VBR6 format to store it.
368cb14a3feSDimitry Andric   // It will be pretty effient if all the higher bits are 0.
369cb14a3feSDimitry Andric   // For example, if we need to pack 8 bits into a value and the stored value
370cb14a3feSDimitry Andric   // is 0xf0, the actual stored value will be 0b000111'110000, which takes 12
371cb14a3feSDimitry Andric   // bits actually. However, if we changed the order to be 0x0f, then we can
372cb14a3feSDimitry Andric   // store it as 0b001111, which takes 6 bits only now.
3735f757f3fSDimitry Andric   DeclBits.addBits((uint64_t)D->getModuleOwnershipKind(), /*BitWidth=*/3);
374cb14a3feSDimitry Andric   DeclBits.addBit(D->isReferenced());
375cb14a3feSDimitry Andric   DeclBits.addBit(D->isUsed(false));
376cb14a3feSDimitry Andric   DeclBits.addBits(D->getAccess(), /*BitWidth=*/2);
377cb14a3feSDimitry Andric   DeclBits.addBit(D->isImplicit());
378cb14a3feSDimitry Andric   DeclBits.addBit(D->getDeclContext() != D->getLexicalDeclContext());
379cb14a3feSDimitry Andric   DeclBits.addBit(D->hasAttrs());
380cb14a3feSDimitry Andric   DeclBits.addBit(D->isTopLevelDeclInObjCContainer());
381cb14a3feSDimitry Andric   DeclBits.addBit(D->isInvalidDecl());
3825f757f3fSDimitry Andric   Record.push_back(DeclBits);
3835f757f3fSDimitry Andric 
3840b57cec5SDimitry Andric   Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
3850b57cec5SDimitry Andric   if (D->getDeclContext() != D->getLexicalDeclContext())
3860b57cec5SDimitry Andric     Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
3875f757f3fSDimitry Andric 
3880b57cec5SDimitry Andric   if (D->hasAttrs())
3890b57cec5SDimitry Andric     Record.AddAttributes(D->getAttrs());
3905f757f3fSDimitry Andric 
3910b57cec5SDimitry Andric   Record.push_back(Writer.getSubmoduleID(D->getOwningModule()));
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   // If this declaration injected a name into a context different from its
3940b57cec5SDimitry Andric   // lexical context, and that context is an imported namespace, we need to
3950b57cec5SDimitry Andric   // update its visible declarations to include this name.
3960b57cec5SDimitry Andric   //
3970b57cec5SDimitry Andric   // This happens when we instantiate a class with a friend declaration or a
3980b57cec5SDimitry Andric   // function with a local extern declaration, for instance.
3990b57cec5SDimitry Andric   //
4000b57cec5SDimitry Andric   // FIXME: Can we handle this in AddedVisibleDecl instead?
4010b57cec5SDimitry Andric   if (D->isOutOfLine()) {
4020b57cec5SDimitry Andric     auto *DC = D->getDeclContext();
4030b57cec5SDimitry Andric     while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
4040b57cec5SDimitry Andric       if (!NS->isFromASTFile())
4050b57cec5SDimitry Andric         break;
4060b57cec5SDimitry Andric       Writer.UpdatedDeclContexts.insert(NS->getPrimaryContext());
4070b57cec5SDimitry Andric       if (!NS->isInlineNamespace())
4080b57cec5SDimitry Andric         break;
4090b57cec5SDimitry Andric       DC = NS->getParent();
4100b57cec5SDimitry Andric     }
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric void ASTDeclWriter::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
4150b57cec5SDimitry Andric   StringRef Arg = D->getArg();
4160b57cec5SDimitry Andric   Record.push_back(Arg.size());
4170b57cec5SDimitry Andric   VisitDecl(D);
4180b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
4190b57cec5SDimitry Andric   Record.push_back(D->getCommentKind());
4200b57cec5SDimitry Andric   Record.AddString(Arg);
4210b57cec5SDimitry Andric   Code = serialization::DECL_PRAGMA_COMMENT;
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric void ASTDeclWriter::VisitPragmaDetectMismatchDecl(
4250b57cec5SDimitry Andric     PragmaDetectMismatchDecl *D) {
4260b57cec5SDimitry Andric   StringRef Name = D->getName();
4270b57cec5SDimitry Andric   StringRef Value = D->getValue();
4280b57cec5SDimitry Andric   Record.push_back(Name.size() + 1 + Value.size());
4290b57cec5SDimitry Andric   VisitDecl(D);
4300b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
4310b57cec5SDimitry Andric   Record.AddString(Name);
4320b57cec5SDimitry Andric   Record.AddString(Value);
4330b57cec5SDimitry Andric   Code = serialization::DECL_PRAGMA_DETECT_MISMATCH;
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
4370b57cec5SDimitry Andric   llvm_unreachable("Translation units aren't directly serialized");
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
4410b57cec5SDimitry Andric   VisitDecl(D);
4420b57cec5SDimitry Andric   Record.AddDeclarationName(D->getDeclName());
4430b57cec5SDimitry Andric   Record.push_back(needsAnonymousDeclarationNumber(D)
4440b57cec5SDimitry Andric                        ? Writer.getAnonymousDeclarationNumber(D)
4450b57cec5SDimitry Andric                        : 0);
4460b57cec5SDimitry Andric }
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
4490b57cec5SDimitry Andric   VisitNamedDecl(D);
4500b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
4510b57cec5SDimitry Andric   Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
4550b57cec5SDimitry Andric   VisitRedeclarable(D);
4560b57cec5SDimitry Andric   VisitTypeDecl(D);
4570b57cec5SDimitry Andric   Record.AddTypeSourceInfo(D->getTypeSourceInfo());
4580b57cec5SDimitry Andric   Record.push_back(D->isModed());
4590b57cec5SDimitry Andric   if (D->isModed())
4600b57cec5SDimitry Andric     Record.AddTypeRef(D->getUnderlyingType());
4610b57cec5SDimitry Andric   Record.AddDeclRef(D->getAnonDeclWithTypedefName(false));
4620b57cec5SDimitry Andric }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
4650b57cec5SDimitry Andric   VisitTypedefNameDecl(D);
4660b57cec5SDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() &&
4670b57cec5SDimitry Andric       !D->hasAttrs() &&
4680b57cec5SDimitry Andric       !D->isImplicit() &&
4690b57cec5SDimitry Andric       D->getFirstDecl() == D->getMostRecentDecl() &&
4700b57cec5SDimitry Andric       !D->isInvalidDecl() &&
4710b57cec5SDimitry Andric       !D->isTopLevelDeclInObjCContainer() &&
4720b57cec5SDimitry Andric       !D->isModulePrivate() &&
4730b57cec5SDimitry Andric       !needsAnonymousDeclarationNumber(D) &&
4740b57cec5SDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier)
4750b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclTypedefAbbrev();
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   Code = serialization::DECL_TYPEDEF;
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
4810b57cec5SDimitry Andric   VisitTypedefNameDecl(D);
4820b57cec5SDimitry Andric   Record.AddDeclRef(D->getDescribedAliasTemplate());
4830b57cec5SDimitry Andric   Code = serialization::DECL_TYPEALIAS;
4840b57cec5SDimitry Andric }
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
4875f757f3fSDimitry Andric   static_assert(DeclContext::NumTagDeclBits == 23,
48806c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
48906c3fb27SDimitry Andric                 "TagDeclBits");
49006c3fb27SDimitry Andric 
4910b57cec5SDimitry Andric   VisitRedeclarable(D);
4920b57cec5SDimitry Andric   VisitTypeDecl(D);
4930b57cec5SDimitry Andric   Record.push_back(D->getIdentifierNamespace());
4945f757f3fSDimitry Andric 
4955f757f3fSDimitry Andric   BitsPacker TagDeclBits;
4965f757f3fSDimitry Andric   TagDeclBits.addBits(llvm::to_underlying(D->getTagKind()), /*BitWidth=*/3);
4975f757f3fSDimitry Andric   TagDeclBits.addBit(!isa<CXXRecordDecl>(D) ? D->isCompleteDefinition() : 0);
4985f757f3fSDimitry Andric   TagDeclBits.addBit(D->isEmbeddedInDeclarator());
4995f757f3fSDimitry Andric   TagDeclBits.addBit(D->isFreeStanding());
5005f757f3fSDimitry Andric   TagDeclBits.addBit(D->isCompleteDefinitionRequired());
5015f757f3fSDimitry Andric   TagDeclBits.addBits(
5025f757f3fSDimitry Andric       D->hasExtInfo() ? 1 : (D->getTypedefNameForAnonDecl() ? 2 : 0),
5035f757f3fSDimitry Andric       /*BitWidth=*/2);
5045f757f3fSDimitry Andric   Record.push_back(TagDeclBits);
5055f757f3fSDimitry Andric 
5060b57cec5SDimitry Andric   Record.AddSourceRange(D->getBraceRange());
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   if (D->hasExtInfo()) {
5090b57cec5SDimitry Andric     Record.AddQualifierInfo(*D->getExtInfo());
5100b57cec5SDimitry Andric   } else if (auto *TD = D->getTypedefNameForAnonDecl()) {
5110b57cec5SDimitry Andric     Record.AddDeclRef(TD);
5120b57cec5SDimitry Andric     Record.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo());
5130b57cec5SDimitry Andric   }
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
5175f757f3fSDimitry Andric   static_assert(DeclContext::NumEnumDeclBits == 43,
51806c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
51906c3fb27SDimitry Andric                 "EnumDeclBits");
52006c3fb27SDimitry Andric 
5210b57cec5SDimitry Andric   VisitTagDecl(D);
5220b57cec5SDimitry Andric   Record.AddTypeSourceInfo(D->getIntegerTypeSourceInfo());
5230b57cec5SDimitry Andric   if (!D->getIntegerTypeSourceInfo())
5240b57cec5SDimitry Andric     Record.AddTypeRef(D->getIntegerType());
5250b57cec5SDimitry Andric   Record.AddTypeRef(D->getPromotionType());
5265f757f3fSDimitry Andric 
5275f757f3fSDimitry Andric   BitsPacker EnumDeclBits;
5285f757f3fSDimitry Andric   EnumDeclBits.addBits(D->getNumPositiveBits(), /*BitWidth=*/8);
5295f757f3fSDimitry Andric   EnumDeclBits.addBits(D->getNumNegativeBits(), /*BitWidth=*/8);
5305f757f3fSDimitry Andric   EnumDeclBits.addBit(D->isScoped());
5315f757f3fSDimitry Andric   EnumDeclBits.addBit(D->isScopedUsingClassTag());
5325f757f3fSDimitry Andric   EnumDeclBits.addBit(D->isFixed());
5335f757f3fSDimitry Andric   Record.push_back(EnumDeclBits);
5345f757f3fSDimitry Andric 
5350b57cec5SDimitry Andric   Record.push_back(D->getODRHash());
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
5380b57cec5SDimitry Andric     Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
5390b57cec5SDimitry Andric     Record.push_back(MemberInfo->getTemplateSpecializationKind());
5400b57cec5SDimitry Andric     Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
5410b57cec5SDimitry Andric   } else {
5420b57cec5SDimitry Andric     Record.AddDeclRef(nullptr);
5430b57cec5SDimitry Andric   }
5440b57cec5SDimitry Andric 
545cb14a3feSDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
546cb14a3feSDimitry Andric       !D->isInvalidDecl() && !D->isImplicit() && !D->hasExtInfo() &&
5470b57cec5SDimitry Andric       !D->getTypedefNameForAnonDecl() &&
5480b57cec5SDimitry Andric       D->getFirstDecl() == D->getMostRecentDecl() &&
5490b57cec5SDimitry Andric       !D->isTopLevelDeclInObjCContainer() &&
5500b57cec5SDimitry Andric       !CXXRecordDecl::classofKind(D->getKind()) &&
551cb14a3feSDimitry Andric       !D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() &&
5520fca6ea1SDimitry Andric       !needsAnonymousDeclarationNumber(D) &&
5530b57cec5SDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier)
5540b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclEnumAbbrev();
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric   Code = serialization::DECL_ENUM;
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
5605f757f3fSDimitry Andric   static_assert(DeclContext::NumRecordDeclBits == 64,
56106c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
56206c3fb27SDimitry Andric                 "RecordDeclBits");
56306c3fb27SDimitry Andric 
5640b57cec5SDimitry Andric   VisitTagDecl(D);
5655f757f3fSDimitry Andric 
5665f757f3fSDimitry Andric   BitsPacker RecordDeclBits;
5675f757f3fSDimitry Andric   RecordDeclBits.addBit(D->hasFlexibleArrayMember());
5685f757f3fSDimitry Andric   RecordDeclBits.addBit(D->isAnonymousStructOrUnion());
5695f757f3fSDimitry Andric   RecordDeclBits.addBit(D->hasObjectMember());
5705f757f3fSDimitry Andric   RecordDeclBits.addBit(D->hasVolatileMember());
5715f757f3fSDimitry Andric   RecordDeclBits.addBit(D->isNonTrivialToPrimitiveDefaultInitialize());
5725f757f3fSDimitry Andric   RecordDeclBits.addBit(D->isNonTrivialToPrimitiveCopy());
5735f757f3fSDimitry Andric   RecordDeclBits.addBit(D->isNonTrivialToPrimitiveDestroy());
5745f757f3fSDimitry Andric   RecordDeclBits.addBit(D->hasNonTrivialToPrimitiveDefaultInitializeCUnion());
5755f757f3fSDimitry Andric   RecordDeclBits.addBit(D->hasNonTrivialToPrimitiveDestructCUnion());
5765f757f3fSDimitry Andric   RecordDeclBits.addBit(D->hasNonTrivialToPrimitiveCopyCUnion());
5775f757f3fSDimitry Andric   RecordDeclBits.addBit(D->isParamDestroyedInCallee());
5785f757f3fSDimitry Andric   RecordDeclBits.addBits(llvm::to_underlying(D->getArgPassingRestrictions()), 2);
5795f757f3fSDimitry Andric   Record.push_back(RecordDeclBits);
5805f757f3fSDimitry Andric 
581bdd1243dSDimitry Andric   // Only compute this for C/Objective-C, in C++ this is computed as part
582bdd1243dSDimitry Andric   // of CXXRecordDecl.
583bdd1243dSDimitry Andric   if (!isa<CXXRecordDecl>(D))
584bdd1243dSDimitry Andric     Record.push_back(D->getODRHash());
5850b57cec5SDimitry Andric 
586cb14a3feSDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
587cb14a3feSDimitry Andric       !D->isImplicit() && !D->isInvalidDecl() && !D->hasExtInfo() &&
5880b57cec5SDimitry Andric       !D->getTypedefNameForAnonDecl() &&
5890b57cec5SDimitry Andric       D->getFirstDecl() == D->getMostRecentDecl() &&
5900b57cec5SDimitry Andric       !D->isTopLevelDeclInObjCContainer() &&
5910b57cec5SDimitry Andric       !CXXRecordDecl::classofKind(D->getKind()) &&
5920b57cec5SDimitry Andric       !needsAnonymousDeclarationNumber(D) &&
5930b57cec5SDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier)
5940b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclRecordAbbrev();
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric   Code = serialization::DECL_RECORD;
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
6000b57cec5SDimitry Andric   VisitNamedDecl(D);
6010b57cec5SDimitry Andric   Record.AddTypeRef(D->getType());
6020b57cec5SDimitry Andric }
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
6050b57cec5SDimitry Andric   VisitValueDecl(D);
6060b57cec5SDimitry Andric   Record.push_back(D->getInitExpr()? 1 : 0);
6070b57cec5SDimitry Andric   if (D->getInitExpr())
6080b57cec5SDimitry Andric     Record.AddStmt(D->getInitExpr());
6090b57cec5SDimitry Andric   Record.AddAPSInt(D->getInitVal());
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric   Code = serialization::DECL_ENUM_CONSTANT;
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
6150b57cec5SDimitry Andric   VisitValueDecl(D);
6160b57cec5SDimitry Andric   Record.AddSourceLocation(D->getInnerLocStart());
6170b57cec5SDimitry Andric   Record.push_back(D->hasExtInfo());
618480093f4SDimitry Andric   if (D->hasExtInfo()) {
619480093f4SDimitry Andric     DeclaratorDecl::ExtInfo *Info = D->getExtInfo();
620480093f4SDimitry Andric     Record.AddQualifierInfo(*Info);
621480093f4SDimitry Andric     Record.AddStmt(Info->TrailingRequiresClause);
622480093f4SDimitry Andric   }
6230b57cec5SDimitry Andric   // The location information is deferred until the end of the record.
6240b57cec5SDimitry Andric   Record.AddTypeRef(D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType()
6250b57cec5SDimitry Andric                                            : QualType());
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
6295f757f3fSDimitry Andric   static_assert(DeclContext::NumFunctionDeclBits == 44,
63006c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
63106c3fb27SDimitry Andric                 "FunctionDeclBits");
63206c3fb27SDimitry Andric 
6330b57cec5SDimitry Andric   VisitRedeclarable(D);
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   Record.push_back(D->getTemplatedKind());
6360b57cec5SDimitry Andric   switch (D->getTemplatedKind()) {
6370b57cec5SDimitry Andric   case FunctionDecl::TK_NonTemplate:
6380b57cec5SDimitry Andric     break;
639fcaf7f86SDimitry Andric   case FunctionDecl::TK_DependentNonTemplate:
640fcaf7f86SDimitry Andric     Record.AddDeclRef(D->getInstantiatedFromDecl());
641fcaf7f86SDimitry Andric     break;
6420b57cec5SDimitry Andric   case FunctionDecl::TK_FunctionTemplate:
6430b57cec5SDimitry Andric     Record.AddDeclRef(D->getDescribedFunctionTemplate());
6440b57cec5SDimitry Andric     break;
6450b57cec5SDimitry Andric   case FunctionDecl::TK_MemberSpecialization: {
6460b57cec5SDimitry Andric     MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
6470b57cec5SDimitry Andric     Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
6480b57cec5SDimitry Andric     Record.push_back(MemberInfo->getTemplateSpecializationKind());
6490b57cec5SDimitry Andric     Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
6500b57cec5SDimitry Andric     break;
6510b57cec5SDimitry Andric   }
6520b57cec5SDimitry Andric   case FunctionDecl::TK_FunctionTemplateSpecialization: {
6530b57cec5SDimitry Andric     FunctionTemplateSpecializationInfo *
6540b57cec5SDimitry Andric       FTSInfo = D->getTemplateSpecializationInfo();
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric     RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric     Record.AddDeclRef(FTSInfo->getTemplate());
6590b57cec5SDimitry Andric     Record.push_back(FTSInfo->getTemplateSpecializationKind());
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric     // Template arguments.
6620b57cec5SDimitry Andric     Record.AddTemplateArgumentList(FTSInfo->TemplateArguments);
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric     // Template args as written.
6650b57cec5SDimitry Andric     Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
6665f757f3fSDimitry Andric     if (FTSInfo->TemplateArgumentsAsWritten)
6675f757f3fSDimitry Andric       Record.AddASTTemplateArgumentListInfo(
6685f757f3fSDimitry Andric           FTSInfo->TemplateArgumentsAsWritten);
6690b57cec5SDimitry Andric 
6700b57cec5SDimitry Andric     Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric     if (MemberSpecializationInfo *MemberInfo =
6730b57cec5SDimitry Andric         FTSInfo->getMemberSpecializationInfo()) {
6740b57cec5SDimitry Andric       Record.push_back(1);
6750b57cec5SDimitry Andric       Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
6760b57cec5SDimitry Andric       Record.push_back(MemberInfo->getTemplateSpecializationKind());
6770b57cec5SDimitry Andric       Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
6780b57cec5SDimitry Andric     } else {
6790b57cec5SDimitry Andric       Record.push_back(0);
6800b57cec5SDimitry Andric     }
6810b57cec5SDimitry Andric 
6820b57cec5SDimitry Andric     if (D->isCanonicalDecl()) {
6830b57cec5SDimitry Andric       // Write the template that contains the specializations set. We will
6840b57cec5SDimitry Andric       // add a FunctionTemplateSpecializationInfo to it when reading.
6850b57cec5SDimitry Andric       Record.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl());
6860b57cec5SDimitry Andric     }
6870b57cec5SDimitry Andric     break;
6880b57cec5SDimitry Andric   }
6890b57cec5SDimitry Andric   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
6900b57cec5SDimitry Andric     DependentFunctionTemplateSpecializationInfo *
6910b57cec5SDimitry Andric       DFTSInfo = D->getDependentSpecializationInfo();
6920b57cec5SDimitry Andric 
6935f757f3fSDimitry Andric     // Candidates.
6945f757f3fSDimitry Andric     Record.push_back(DFTSInfo->getCandidates().size());
6955f757f3fSDimitry Andric     for (FunctionTemplateDecl *FTD : DFTSInfo->getCandidates())
6965f757f3fSDimitry Andric       Record.AddDeclRef(FTD);
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric     // Templates args.
6995f757f3fSDimitry Andric     Record.push_back(DFTSInfo->TemplateArgumentsAsWritten != nullptr);
7005f757f3fSDimitry Andric     if (DFTSInfo->TemplateArgumentsAsWritten)
7015f757f3fSDimitry Andric       Record.AddASTTemplateArgumentListInfo(
7025f757f3fSDimitry Andric           DFTSInfo->TemplateArgumentsAsWritten);
7030b57cec5SDimitry Andric     break;
7040b57cec5SDimitry Andric   }
7050b57cec5SDimitry Andric   }
7060b57cec5SDimitry Andric 
707bdd1243dSDimitry Andric   VisitDeclaratorDecl(D);
708bdd1243dSDimitry Andric   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
709bdd1243dSDimitry Andric   Record.push_back(D->getIdentifierNamespace());
710bdd1243dSDimitry Andric 
711cb14a3feSDimitry Andric   // The order matters here. It will be better to put the bit with higher
712cb14a3feSDimitry Andric   // probability to be 0 in the end of the bits. See the comments in VisitDecl
713cb14a3feSDimitry Andric   // for details.
7145f757f3fSDimitry Andric   BitsPacker FunctionDeclBits;
7155f757f3fSDimitry Andric   // FIXME: stable encoding
716cb14a3feSDimitry Andric   FunctionDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()), 3);
7175f757f3fSDimitry Andric   FunctionDeclBits.addBits((uint32_t)D->getStorageClass(), /*BitWidth=*/3);
7185f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isInlineSpecified());
7195f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isInlined());
720cb14a3feSDimitry Andric   FunctionDeclBits.addBit(D->hasSkippedBody());
7215f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isVirtualAsWritten());
7227a6dacacSDimitry Andric   FunctionDeclBits.addBit(D->isPureVirtual());
7235f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->hasInheritedPrototype());
7245f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->hasWrittenPrototype());
7255f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isDeletedBit());
7265f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isTrivial());
7275f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isTrivialForCall());
7285f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isDefaulted());
7295f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isExplicitlyDefaulted());
7305f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isIneligibleOrNotSelected());
7315f757f3fSDimitry Andric   FunctionDeclBits.addBits((uint64_t)(D->getConstexprKind()), /*BitWidth=*/2);
732cb14a3feSDimitry Andric   FunctionDeclBits.addBit(D->hasImplicitReturnZero());
7335f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isMultiVersion());
7345f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->isLateTemplateParsed());
7355f757f3fSDimitry Andric   FunctionDeclBits.addBit(D->FriendConstraintRefersToEnclosingTemplate());
736cb14a3feSDimitry Andric   FunctionDeclBits.addBit(D->usesSEHTry());
7375f757f3fSDimitry Andric   Record.push_back(FunctionDeclBits);
7385f757f3fSDimitry Andric 
739bdd1243dSDimitry Andric   Record.AddSourceLocation(D->getEndLoc());
7405f757f3fSDimitry Andric   if (D->isExplicitlyDefaulted())
741bdd1243dSDimitry Andric     Record.AddSourceLocation(D->getDefaultLoc());
742bdd1243dSDimitry Andric 
743bdd1243dSDimitry Andric   Record.push_back(D->getODRHash());
744bdd1243dSDimitry Andric 
7450fca6ea1SDimitry Andric   if (D->isDefaulted() || D->isDeletedAsWritten()) {
7460fca6ea1SDimitry Andric     if (auto *FDI = D->getDefalutedOrDeletedInfo()) {
7470fca6ea1SDimitry Andric       // Store both that there is an DefaultedOrDeletedInfo and whether it
7480fca6ea1SDimitry Andric       // contains a DeletedMessage.
7490fca6ea1SDimitry Andric       StringLiteral *DeletedMessage = FDI->getDeletedMessage();
7500fca6ea1SDimitry Andric       Record.push_back(1 | (DeletedMessage ? 2 : 0));
7510fca6ea1SDimitry Andric       if (DeletedMessage)
7520fca6ea1SDimitry Andric         Record.AddStmt(DeletedMessage);
7530fca6ea1SDimitry Andric 
754bdd1243dSDimitry Andric       Record.push_back(FDI->getUnqualifiedLookups().size());
755bdd1243dSDimitry Andric       for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
756bdd1243dSDimitry Andric         Record.AddDeclRef(P.getDecl());
757bdd1243dSDimitry Andric         Record.push_back(P.getAccess());
758bdd1243dSDimitry Andric       }
759bdd1243dSDimitry Andric     } else {
760bdd1243dSDimitry Andric       Record.push_back(0);
761bdd1243dSDimitry Andric     }
762bdd1243dSDimitry Andric   }
763bdd1243dSDimitry Andric 
7640b57cec5SDimitry Andric   Record.push_back(D->param_size());
765bdd1243dSDimitry Andric   for (auto *P : D->parameters())
7660b57cec5SDimitry Andric     Record.AddDeclRef(P);
7670b57cec5SDimitry Andric   Code = serialization::DECL_FUNCTION;
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric static void addExplicitSpecifier(ExplicitSpecifier ES,
7710b57cec5SDimitry Andric                                  ASTRecordWriter &Record) {
7720b57cec5SDimitry Andric   uint64_t Kind = static_cast<uint64_t>(ES.getKind());
7730b57cec5SDimitry Andric   Kind = Kind << 1 | static_cast<bool>(ES.getExpr());
7740b57cec5SDimitry Andric   Record.push_back(Kind);
7750b57cec5SDimitry Andric   if (ES.getExpr()) {
7760b57cec5SDimitry Andric     Record.AddStmt(ES.getExpr());
7770b57cec5SDimitry Andric   }
7780b57cec5SDimitry Andric }
7790b57cec5SDimitry Andric 
7800b57cec5SDimitry Andric void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
7810b57cec5SDimitry Andric   addExplicitSpecifier(D->getExplicitSpecifier(), Record);
782fe6060f1SDimitry Andric   Record.AddDeclRef(D->Ctor);
7830b57cec5SDimitry Andric   VisitFunctionDecl(D);
78406c3fb27SDimitry Andric   Record.push_back(static_cast<unsigned char>(D->getDeductionCandidateKind()));
7850b57cec5SDimitry Andric   Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
7860b57cec5SDimitry Andric }
7870b57cec5SDimitry Andric 
7880b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
7895f757f3fSDimitry Andric   static_assert(DeclContext::NumObjCMethodDeclBits == 37,
79006c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
79106c3fb27SDimitry Andric                 "ObjCMethodDeclBits");
79206c3fb27SDimitry Andric 
7930b57cec5SDimitry Andric   VisitNamedDecl(D);
7940b57cec5SDimitry Andric   // FIXME: convert to LazyStmtPtr?
7950b57cec5SDimitry Andric   // Unlike C/C++, method bodies will never be in header files.
796480093f4SDimitry Andric   bool HasBodyStuff = D->getBody() != nullptr;
7970b57cec5SDimitry Andric   Record.push_back(HasBodyStuff);
7980b57cec5SDimitry Andric   if (HasBodyStuff) {
7990b57cec5SDimitry Andric     Record.AddStmt(D->getBody());
800480093f4SDimitry Andric   }
8010b57cec5SDimitry Andric   Record.AddDeclRef(D->getSelfDecl());
8020b57cec5SDimitry Andric   Record.AddDeclRef(D->getCmdDecl());
8030b57cec5SDimitry Andric   Record.push_back(D->isInstanceMethod());
8040b57cec5SDimitry Andric   Record.push_back(D->isVariadic());
8050b57cec5SDimitry Andric   Record.push_back(D->isPropertyAccessor());
806480093f4SDimitry Andric   Record.push_back(D->isSynthesizedAccessorStub());
8070b57cec5SDimitry Andric   Record.push_back(D->isDefined());
8080b57cec5SDimitry Andric   Record.push_back(D->isOverriding());
8090b57cec5SDimitry Andric   Record.push_back(D->hasSkippedBody());
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric   Record.push_back(D->isRedeclaration());
8120b57cec5SDimitry Andric   Record.push_back(D->hasRedeclaration());
8130b57cec5SDimitry Andric   if (D->hasRedeclaration()) {
8140b57cec5SDimitry Andric     assert(Context.getObjCMethodRedeclaration(D));
8150b57cec5SDimitry Andric     Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
8160b57cec5SDimitry Andric   }
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   // FIXME: stable encoding for @required/@optional
8195f757f3fSDimitry Andric   Record.push_back(llvm::to_underlying(D->getImplementationControl()));
8200b57cec5SDimitry Andric   // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
8210b57cec5SDimitry Andric   Record.push_back(D->getObjCDeclQualifier());
8220b57cec5SDimitry Andric   Record.push_back(D->hasRelatedResultType());
8230b57cec5SDimitry Andric   Record.AddTypeRef(D->getReturnType());
8240b57cec5SDimitry Andric   Record.AddTypeSourceInfo(D->getReturnTypeSourceInfo());
8250b57cec5SDimitry Andric   Record.AddSourceLocation(D->getEndLoc());
8260b57cec5SDimitry Andric   Record.push_back(D->param_size());
8270b57cec5SDimitry Andric   for (const auto *P : D->parameters())
8280b57cec5SDimitry Andric     Record.AddDeclRef(P);
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric   Record.push_back(D->getSelLocsKind());
8310b57cec5SDimitry Andric   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
8320b57cec5SDimitry Andric   SourceLocation *SelLocs = D->getStoredSelLocs();
8330b57cec5SDimitry Andric   Record.push_back(NumStoredSelLocs);
8340b57cec5SDimitry Andric   for (unsigned i = 0; i != NumStoredSelLocs; ++i)
8350b57cec5SDimitry Andric     Record.AddSourceLocation(SelLocs[i]);
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_METHOD;
8380b57cec5SDimitry Andric }
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
8410b57cec5SDimitry Andric   VisitTypedefNameDecl(D);
8420b57cec5SDimitry Andric   Record.push_back(D->Variance);
8430b57cec5SDimitry Andric   Record.push_back(D->Index);
8440b57cec5SDimitry Andric   Record.AddSourceLocation(D->VarianceLoc);
8450b57cec5SDimitry Andric   Record.AddSourceLocation(D->ColonLoc);
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_TYPE_PARAM;
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
8515f757f3fSDimitry Andric   static_assert(DeclContext::NumObjCContainerDeclBits == 64,
85206c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
85306c3fb27SDimitry Andric                 "ObjCContainerDeclBits");
85406c3fb27SDimitry Andric 
8550b57cec5SDimitry Andric   VisitNamedDecl(D);
8560b57cec5SDimitry Andric   Record.AddSourceLocation(D->getAtStartLoc());
8570b57cec5SDimitry Andric   Record.AddSourceRange(D->getAtEndRange());
8580b57cec5SDimitry Andric   // Abstract class (no need to define a stable serialization::DECL code).
8590b57cec5SDimitry Andric }
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
8620b57cec5SDimitry Andric   VisitRedeclarable(D);
8630b57cec5SDimitry Andric   VisitObjCContainerDecl(D);
8640b57cec5SDimitry Andric   Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
8650b57cec5SDimitry Andric   AddObjCTypeParamList(D->TypeParamList);
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   Record.push_back(D->isThisDeclarationADefinition());
8680b57cec5SDimitry Andric   if (D->isThisDeclarationADefinition()) {
8690b57cec5SDimitry Andric     // Write the DefinitionData
8700b57cec5SDimitry Andric     ObjCInterfaceDecl::DefinitionData &Data = D->data();
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric     Record.AddTypeSourceInfo(D->getSuperClassTInfo());
8730b57cec5SDimitry Andric     Record.AddSourceLocation(D->getEndOfDefinitionLoc());
8740b57cec5SDimitry Andric     Record.push_back(Data.HasDesignatedInitializers);
875bdd1243dSDimitry Andric     Record.push_back(D->getODRHash());
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric     // Write out the protocols that are directly referenced by the @interface.
8780b57cec5SDimitry Andric     Record.push_back(Data.ReferencedProtocols.size());
8790b57cec5SDimitry Andric     for (const auto *P : D->protocols())
8800b57cec5SDimitry Andric       Record.AddDeclRef(P);
8810b57cec5SDimitry Andric     for (const auto &PL : D->protocol_locs())
8820b57cec5SDimitry Andric       Record.AddSourceLocation(PL);
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric     // Write out the protocols that are transitively referenced.
8850b57cec5SDimitry Andric     Record.push_back(Data.AllReferencedProtocols.size());
8860b57cec5SDimitry Andric     for (ObjCList<ObjCProtocolDecl>::iterator
8870b57cec5SDimitry Andric               P = Data.AllReferencedProtocols.begin(),
8880b57cec5SDimitry Andric            PEnd = Data.AllReferencedProtocols.end();
8890b57cec5SDimitry Andric          P != PEnd; ++P)
8900b57cec5SDimitry Andric       Record.AddDeclRef(*P);
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric     if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
8940b57cec5SDimitry Andric       // Ensure that we write out the set of categories for this class.
8950b57cec5SDimitry Andric       Writer.ObjCClassesWithCategories.insert(D);
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric       // Make sure that the categories get serialized.
8980b57cec5SDimitry Andric       for (; Cat; Cat = Cat->getNextClassCategoryRaw())
8990b57cec5SDimitry Andric         (void)Writer.GetDeclRef(Cat);
9000b57cec5SDimitry Andric     }
9010b57cec5SDimitry Andric   }
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_INTERFACE;
9040b57cec5SDimitry Andric }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
9070b57cec5SDimitry Andric   VisitFieldDecl(D);
9080b57cec5SDimitry Andric   // FIXME: stable encoding for @public/@private/@protected/@package
9090b57cec5SDimitry Andric   Record.push_back(D->getAccessControl());
9100b57cec5SDimitry Andric   Record.push_back(D->getSynthesize());
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() &&
9130b57cec5SDimitry Andric       !D->hasAttrs() &&
9140b57cec5SDimitry Andric       !D->isImplicit() &&
9150b57cec5SDimitry Andric       !D->isUsed(false) &&
9160b57cec5SDimitry Andric       !D->isInvalidDecl() &&
9170b57cec5SDimitry Andric       !D->isReferenced() &&
9180b57cec5SDimitry Andric       !D->isModulePrivate() &&
9190b57cec5SDimitry Andric       !D->getBitWidth() &&
9200b57cec5SDimitry Andric       !D->hasExtInfo() &&
9210b57cec5SDimitry Andric       D->getDeclName())
9220b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclObjCIvarAbbrev();
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_IVAR;
9250b57cec5SDimitry Andric }
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
9280b57cec5SDimitry Andric   VisitRedeclarable(D);
9290b57cec5SDimitry Andric   VisitObjCContainerDecl(D);
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   Record.push_back(D->isThisDeclarationADefinition());
9320b57cec5SDimitry Andric   if (D->isThisDeclarationADefinition()) {
9330b57cec5SDimitry Andric     Record.push_back(D->protocol_size());
9340b57cec5SDimitry Andric     for (const auto *I : D->protocols())
9350b57cec5SDimitry Andric       Record.AddDeclRef(I);
9360b57cec5SDimitry Andric     for (const auto &PL : D->protocol_locs())
9370b57cec5SDimitry Andric       Record.AddSourceLocation(PL);
938bdd1243dSDimitry Andric     Record.push_back(D->getODRHash());
9390b57cec5SDimitry Andric   }
9400b57cec5SDimitry Andric 
9410b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_PROTOCOL;
9420b57cec5SDimitry Andric }
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
9450b57cec5SDimitry Andric   VisitFieldDecl(D);
9460b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
9500b57cec5SDimitry Andric   VisitObjCContainerDecl(D);
9510b57cec5SDimitry Andric   Record.AddSourceLocation(D->getCategoryNameLoc());
9520b57cec5SDimitry Andric   Record.AddSourceLocation(D->getIvarLBraceLoc());
9530b57cec5SDimitry Andric   Record.AddSourceLocation(D->getIvarRBraceLoc());
9540b57cec5SDimitry Andric   Record.AddDeclRef(D->getClassInterface());
9550b57cec5SDimitry Andric   AddObjCTypeParamList(D->TypeParamList);
9560b57cec5SDimitry Andric   Record.push_back(D->protocol_size());
9570b57cec5SDimitry Andric   for (const auto *I : D->protocols())
9580b57cec5SDimitry Andric     Record.AddDeclRef(I);
9590b57cec5SDimitry Andric   for (const auto &PL : D->protocol_locs())
9600b57cec5SDimitry Andric     Record.AddSourceLocation(PL);
9610b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_CATEGORY;
9620b57cec5SDimitry Andric }
9630b57cec5SDimitry Andric 
9640b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
9650b57cec5SDimitry Andric   VisitNamedDecl(D);
9660b57cec5SDimitry Andric   Record.AddDeclRef(D->getClassInterface());
9670b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
9710b57cec5SDimitry Andric   VisitNamedDecl(D);
9720b57cec5SDimitry Andric   Record.AddSourceLocation(D->getAtLoc());
9730b57cec5SDimitry Andric   Record.AddSourceLocation(D->getLParenLoc());
9740b57cec5SDimitry Andric   Record.AddTypeRef(D->getType());
9750b57cec5SDimitry Andric   Record.AddTypeSourceInfo(D->getTypeSourceInfo());
9760b57cec5SDimitry Andric   // FIXME: stable encoding
9770b57cec5SDimitry Andric   Record.push_back((unsigned)D->getPropertyAttributes());
9780b57cec5SDimitry Andric   Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
9790b57cec5SDimitry Andric   // FIXME: stable encoding
9800b57cec5SDimitry Andric   Record.push_back((unsigned)D->getPropertyImplementation());
9810b57cec5SDimitry Andric   Record.AddDeclarationName(D->getGetterName());
9820b57cec5SDimitry Andric   Record.AddSourceLocation(D->getGetterNameLoc());
9830b57cec5SDimitry Andric   Record.AddDeclarationName(D->getSetterName());
9840b57cec5SDimitry Andric   Record.AddSourceLocation(D->getSetterNameLoc());
9850b57cec5SDimitry Andric   Record.AddDeclRef(D->getGetterMethodDecl());
9860b57cec5SDimitry Andric   Record.AddDeclRef(D->getSetterMethodDecl());
9870b57cec5SDimitry Andric   Record.AddDeclRef(D->getPropertyIvarDecl());
9880b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_PROPERTY;
9890b57cec5SDimitry Andric }
9900b57cec5SDimitry Andric 
9910b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
9920b57cec5SDimitry Andric   VisitObjCContainerDecl(D);
9930b57cec5SDimitry Andric   Record.AddDeclRef(D->getClassInterface());
9940b57cec5SDimitry Andric   // Abstract class (no need to define a stable serialization::DECL code).
9950b57cec5SDimitry Andric }
9960b57cec5SDimitry Andric 
9970b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
9980b57cec5SDimitry Andric   VisitObjCImplDecl(D);
9990b57cec5SDimitry Andric   Record.AddSourceLocation(D->getCategoryNameLoc());
10000b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_CATEGORY_IMPL;
10010b57cec5SDimitry Andric }
10020b57cec5SDimitry Andric 
10030b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
10040b57cec5SDimitry Andric   VisitObjCImplDecl(D);
10050b57cec5SDimitry Andric   Record.AddDeclRef(D->getSuperClass());
10060b57cec5SDimitry Andric   Record.AddSourceLocation(D->getSuperClassLoc());
10070b57cec5SDimitry Andric   Record.AddSourceLocation(D->getIvarLBraceLoc());
10080b57cec5SDimitry Andric   Record.AddSourceLocation(D->getIvarRBraceLoc());
10090b57cec5SDimitry Andric   Record.push_back(D->hasNonZeroConstructors());
10100b57cec5SDimitry Andric   Record.push_back(D->hasDestructors());
10110b57cec5SDimitry Andric   Record.push_back(D->NumIvarInitializers);
10120b57cec5SDimitry Andric   if (D->NumIvarInitializers)
10130b57cec5SDimitry Andric     Record.AddCXXCtorInitializers(
1014bdd1243dSDimitry Andric         llvm::ArrayRef(D->init_begin(), D->init_end()));
10150b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_IMPLEMENTATION;
10160b57cec5SDimitry Andric }
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
10190b57cec5SDimitry Andric   VisitDecl(D);
10200b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
10210b57cec5SDimitry Andric   Record.AddDeclRef(D->getPropertyDecl());
10220b57cec5SDimitry Andric   Record.AddDeclRef(D->getPropertyIvarDecl());
10230b57cec5SDimitry Andric   Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
1024480093f4SDimitry Andric   Record.AddDeclRef(D->getGetterMethodDecl());
1025480093f4SDimitry Andric   Record.AddDeclRef(D->getSetterMethodDecl());
10260b57cec5SDimitry Andric   Record.AddStmt(D->getGetterCXXConstructor());
10270b57cec5SDimitry Andric   Record.AddStmt(D->getSetterCXXAssignment());
10280b57cec5SDimitry Andric   Code = serialization::DECL_OBJC_PROPERTY_IMPL;
10290b57cec5SDimitry Andric }
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
10320b57cec5SDimitry Andric   VisitDeclaratorDecl(D);
10330b57cec5SDimitry Andric   Record.push_back(D->isMutable());
10340b57cec5SDimitry Andric 
103506c3fb27SDimitry Andric   Record.push_back((D->StorageKind << 1) | D->BitField);
103606c3fb27SDimitry Andric   if (D->StorageKind == FieldDecl::ISK_CapturedVLAType)
10370b57cec5SDimitry Andric     Record.AddTypeRef(QualType(D->getCapturedVLAType(), 0));
103806c3fb27SDimitry Andric   else if (D->BitField)
10390b57cec5SDimitry Andric     Record.AddStmt(D->getBitWidth());
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   if (!D->getDeclName())
10420b57cec5SDimitry Andric     Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() &&
10450b57cec5SDimitry Andric       !D->hasAttrs() &&
10460b57cec5SDimitry Andric       !D->isImplicit() &&
10470b57cec5SDimitry Andric       !D->isUsed(false) &&
10480b57cec5SDimitry Andric       !D->isInvalidDecl() &&
10490b57cec5SDimitry Andric       !D->isReferenced() &&
10500b57cec5SDimitry Andric       !D->isTopLevelDeclInObjCContainer() &&
10510b57cec5SDimitry Andric       !D->isModulePrivate() &&
10520b57cec5SDimitry Andric       !D->getBitWidth() &&
10530b57cec5SDimitry Andric       !D->hasInClassInitializer() &&
10540b57cec5SDimitry Andric       !D->hasCapturedVLAType() &&
10550b57cec5SDimitry Andric       !D->hasExtInfo() &&
10560b57cec5SDimitry Andric       !ObjCIvarDecl::classofKind(D->getKind()) &&
10570b57cec5SDimitry Andric       !ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
10580b57cec5SDimitry Andric       D->getDeclName())
10590b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclFieldAbbrev();
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric   Code = serialization::DECL_FIELD;
10620b57cec5SDimitry Andric }
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
10650b57cec5SDimitry Andric   VisitDeclaratorDecl(D);
10660b57cec5SDimitry Andric   Record.AddIdentifierRef(D->getGetterId());
10670b57cec5SDimitry Andric   Record.AddIdentifierRef(D->getSetterId());
10680b57cec5SDimitry Andric   Code = serialization::DECL_MS_PROPERTY;
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric 
10715ffd83dbSDimitry Andric void ASTDeclWriter::VisitMSGuidDecl(MSGuidDecl *D) {
10725ffd83dbSDimitry Andric   VisitValueDecl(D);
10735ffd83dbSDimitry Andric   MSGuidDecl::Parts Parts = D->getParts();
10745ffd83dbSDimitry Andric   Record.push_back(Parts.Part1);
10755ffd83dbSDimitry Andric   Record.push_back(Parts.Part2);
10765ffd83dbSDimitry Andric   Record.push_back(Parts.Part3);
107781ad6265SDimitry Andric   Record.append(std::begin(Parts.Part4And5), std::end(Parts.Part4And5));
10785ffd83dbSDimitry Andric   Code = serialization::DECL_MS_GUID;
10795ffd83dbSDimitry Andric }
10805ffd83dbSDimitry Andric 
108181ad6265SDimitry Andric void ASTDeclWriter::VisitUnnamedGlobalConstantDecl(
108281ad6265SDimitry Andric     UnnamedGlobalConstantDecl *D) {
108381ad6265SDimitry Andric   VisitValueDecl(D);
108481ad6265SDimitry Andric   Record.AddAPValue(D->getValue());
108581ad6265SDimitry Andric   Code = serialization::DECL_UNNAMED_GLOBAL_CONSTANT;
108681ad6265SDimitry Andric }
108781ad6265SDimitry Andric 
1088e8d8bef9SDimitry Andric void ASTDeclWriter::VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D) {
1089e8d8bef9SDimitry Andric   VisitValueDecl(D);
1090e8d8bef9SDimitry Andric   Record.AddAPValue(D->getValue());
1091e8d8bef9SDimitry Andric   Code = serialization::DECL_TEMPLATE_PARAM_OBJECT;
1092e8d8bef9SDimitry Andric }
1093e8d8bef9SDimitry Andric 
10940b57cec5SDimitry Andric void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
10950b57cec5SDimitry Andric   VisitValueDecl(D);
10960b57cec5SDimitry Andric   Record.push_back(D->getChainingSize());
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric   for (const auto *P : D->chain())
10990b57cec5SDimitry Andric     Record.AddDeclRef(P);
11000b57cec5SDimitry Andric   Code = serialization::DECL_INDIRECTFIELD;
11010b57cec5SDimitry Andric }
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
11040b57cec5SDimitry Andric   VisitRedeclarable(D);
11050b57cec5SDimitry Andric   VisitDeclaratorDecl(D);
11065f757f3fSDimitry Andric 
1107cb14a3feSDimitry Andric   // The order matters here. It will be better to put the bit with higher
1108cb14a3feSDimitry Andric   // probability to be 0 in the end of the bits. See the comments in VisitDecl
1109cb14a3feSDimitry Andric   // for details.
11105f757f3fSDimitry Andric   BitsPacker VarDeclBits;
1111cb14a3feSDimitry Andric   VarDeclBits.addBits(llvm::to_underlying(D->getLinkageInternal()),
1112cb14a3feSDimitry Andric                       /*BitWidth=*/3);
11135f757f3fSDimitry Andric 
11140b57cec5SDimitry Andric   bool ModulesCodegen = false;
111506c3fb27SDimitry Andric   if (Writer.WritingModule && D->getStorageDuration() == SD_Static &&
111606c3fb27SDimitry Andric       !D->getDescribedVarTemplate()) {
111781ad6265SDimitry Andric     // When building a C++20 module interface unit or a partition unit, a
111881ad6265SDimitry Andric     // strong definition in the module interface is provided by the
111981ad6265SDimitry Andric     // compilation of that unit, not by its users. (Inline variables are still
112081ad6265SDimitry Andric     // emitted in module users.)
11210b57cec5SDimitry Andric     ModulesCodegen =
112281ad6265SDimitry Andric         (Writer.WritingModule->isInterfaceOrPartition() ||
1123e8d8bef9SDimitry Andric          (D->hasAttr<DLLExportAttr>() &&
1124e8d8bef9SDimitry Andric           Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
112506c3fb27SDimitry Andric         Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal;
11260b57cec5SDimitry Andric   }
11275f757f3fSDimitry Andric   VarDeclBits.addBit(ModulesCodegen);
1128cb14a3feSDimitry Andric 
1129cb14a3feSDimitry Andric   VarDeclBits.addBits(D->getStorageClass(), /*BitWidth=*/3);
1130cb14a3feSDimitry Andric   VarDeclBits.addBits(D->getTSCSpec(), /*BitWidth=*/2);
1131cb14a3feSDimitry Andric   VarDeclBits.addBits(D->getInitStyle(), /*BitWidth=*/2);
1132cb14a3feSDimitry Andric   VarDeclBits.addBit(D->isARCPseudoStrong());
1133cb14a3feSDimitry Andric 
1134cb14a3feSDimitry Andric   bool HasDeducedType = false;
1135cb14a3feSDimitry Andric   if (!isa<ParmVarDecl>(D)) {
1136cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isThisDeclarationADemotedDefinition());
1137cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isExceptionVariable());
1138cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isNRVOVariable());
1139cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isCXXForRangeDecl());
1140cb14a3feSDimitry Andric 
1141cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isInline());
1142cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isInlineSpecified());
1143cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isConstexpr());
1144cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isInitCapture());
1145cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isPreviousDeclInSameBlockScope());
1146cb14a3feSDimitry Andric 
1147cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isEscapingByref());
1148cb14a3feSDimitry Andric     HasDeducedType = D->getType()->getContainedDeducedType();
1149cb14a3feSDimitry Andric     VarDeclBits.addBit(HasDeducedType);
1150cb14a3feSDimitry Andric 
1151cb14a3feSDimitry Andric     if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D))
1152cb14a3feSDimitry Andric       VarDeclBits.addBits(llvm::to_underlying(IPD->getParameterKind()),
1153cb14a3feSDimitry Andric                           /*Width=*/3);
1154cb14a3feSDimitry Andric     else
1155cb14a3feSDimitry Andric       VarDeclBits.addBits(0, /*Width=*/3);
1156cb14a3feSDimitry Andric 
1157cb14a3feSDimitry Andric     VarDeclBits.addBit(D->isObjCForDecl());
1158cb14a3feSDimitry Andric   }
1159cb14a3feSDimitry Andric 
11605f757f3fSDimitry Andric   Record.push_back(VarDeclBits);
11615f757f3fSDimitry Andric 
11620b57cec5SDimitry Andric   if (ModulesCodegen)
11630fca6ea1SDimitry Andric     Writer.AddDeclRef(D, Writer.ModularCodegenDecls);
11640b57cec5SDimitry Andric 
11655f757f3fSDimitry Andric   if (D->hasAttr<BlocksAttr>()) {
11665f757f3fSDimitry Andric     BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
11675f757f3fSDimitry Andric     Record.AddStmt(Init.getCopyExpr());
11685f757f3fSDimitry Andric     if (Init.getCopyExpr())
11695f757f3fSDimitry Andric       Record.push_back(Init.canThrow());
11705f757f3fSDimitry Andric   }
11715f757f3fSDimitry Andric 
11720b57cec5SDimitry Andric   enum {
11730b57cec5SDimitry Andric     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
11740b57cec5SDimitry Andric   };
11750b57cec5SDimitry Andric   if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
11760b57cec5SDimitry Andric     Record.push_back(VarTemplate);
11770b57cec5SDimitry Andric     Record.AddDeclRef(TemplD);
11780b57cec5SDimitry Andric   } else if (MemberSpecializationInfo *SpecInfo
11790b57cec5SDimitry Andric                = D->getMemberSpecializationInfo()) {
11800b57cec5SDimitry Andric     Record.push_back(StaticDataMemberSpecialization);
11810b57cec5SDimitry Andric     Record.AddDeclRef(SpecInfo->getInstantiatedFrom());
11820b57cec5SDimitry Andric     Record.push_back(SpecInfo->getTemplateSpecializationKind());
11830b57cec5SDimitry Andric     Record.AddSourceLocation(SpecInfo->getPointOfInstantiation());
11840b57cec5SDimitry Andric   } else {
11850b57cec5SDimitry Andric     Record.push_back(VarNotTemplate);
11860b57cec5SDimitry Andric   }
11870b57cec5SDimitry Andric 
1188cb14a3feSDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
11890b57cec5SDimitry Andric       !D->isTopLevelDeclInObjCContainer() &&
11900b57cec5SDimitry Andric       !needsAnonymousDeclarationNumber(D) &&
11910b57cec5SDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
1192cb14a3feSDimitry Andric       !D->hasExtInfo() && D->getFirstDecl() == D->getMostRecentDecl() &&
1193cb14a3feSDimitry Andric       D->getKind() == Decl::Var && !D->isInline() && !D->isConstexpr() &&
1194cb14a3feSDimitry Andric       !D->isInitCapture() && !D->isPreviousDeclInSameBlockScope() &&
1195cb14a3feSDimitry Andric       !D->isEscapingByref() && !HasDeducedType &&
1196cb14a3feSDimitry Andric       D->getStorageDuration() != SD_Static && !D->getDescribedVarTemplate() &&
1197cb14a3feSDimitry Andric       !D->getMemberSpecializationInfo() && !D->isObjCForDecl() &&
1198cb14a3feSDimitry Andric       !isa<ImplicitParamDecl>(D) && !D->isEscapingByref())
11990b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclVarAbbrev();
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric   Code = serialization::DECL_VAR;
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
12050b57cec5SDimitry Andric   VisitVarDecl(D);
12060b57cec5SDimitry Andric   Code = serialization::DECL_IMPLICIT_PARAM;
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
12100b57cec5SDimitry Andric   VisitVarDecl(D);
12115f757f3fSDimitry Andric 
1212647cbc5dSDimitry Andric   // See the implementation of `ParmVarDecl::getParameterIndex()`, which may
1213647cbc5dSDimitry Andric   // exceed the size of the normal bitfield. So it may be better to not pack
1214647cbc5dSDimitry Andric   // these bits.
1215647cbc5dSDimitry Andric   Record.push_back(D->getFunctionScopeIndex());
1216647cbc5dSDimitry Andric 
12175f757f3fSDimitry Andric   BitsPacker ParmVarDeclBits;
12185f757f3fSDimitry Andric   ParmVarDeclBits.addBit(D->isObjCMethodParameter());
12195f757f3fSDimitry Andric   ParmVarDeclBits.addBits(D->getFunctionScopeDepth(), /*BitsWidth=*/7);
12205f757f3fSDimitry Andric   // FIXME: stable encoding
12215f757f3fSDimitry Andric   ParmVarDeclBits.addBits(D->getObjCDeclQualifier(), /*BitsWidth=*/7);
12225f757f3fSDimitry Andric   ParmVarDeclBits.addBit(D->isKNRPromoted());
12235f757f3fSDimitry Andric   ParmVarDeclBits.addBit(D->hasInheritedDefaultArg());
12245f757f3fSDimitry Andric   ParmVarDeclBits.addBit(D->hasUninstantiatedDefaultArg());
12255f757f3fSDimitry Andric   ParmVarDeclBits.addBit(D->getExplicitObjectParamThisLoc().isValid());
12265f757f3fSDimitry Andric   Record.push_back(ParmVarDeclBits);
12275f757f3fSDimitry Andric 
12280b57cec5SDimitry Andric   if (D->hasUninstantiatedDefaultArg())
12290b57cec5SDimitry Andric     Record.AddStmt(D->getUninstantiatedDefaultArg());
12305f757f3fSDimitry Andric   if (D->getExplicitObjectParamThisLoc().isValid())
12315f757f3fSDimitry Andric     Record.AddSourceLocation(D->getExplicitObjectParamThisLoc());
12320b57cec5SDimitry Andric   Code = serialization::DECL_PARM_VAR;
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric   // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
12350b57cec5SDimitry Andric   // we dynamically check for the properties that we optimize for, but don't
12360b57cec5SDimitry Andric   // know are true of all PARM_VAR_DECLs.
12375f757f3fSDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() &&
1238cb14a3feSDimitry Andric       !D->hasExtInfo() && D->getStorageClass() == 0 && !D->isInvalidDecl() &&
1239cb14a3feSDimitry Andric       !D->isTopLevelDeclInObjCContainer() &&
12400b57cec5SDimitry Andric       D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
1241cb14a3feSDimitry Andric       D->getInit() == nullptr)               // No default expr.
12420b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclParmVarAbbrev();
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric   // Check things we know are true of *every* PARM_VAR_DECL, which is more than
12450b57cec5SDimitry Andric   // just us assuming it.
12460b57cec5SDimitry Andric   assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
12470b57cec5SDimitry Andric   assert(!D->isThisDeclarationADemotedDefinition()
12480b57cec5SDimitry Andric          && "PARM_VAR_DECL can't be demoted definition.");
12490b57cec5SDimitry Andric   assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
12500b57cec5SDimitry Andric   assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
12510b57cec5SDimitry Andric   assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
12520b57cec5SDimitry Andric   assert(!D->isStaticDataMember() &&
12530b57cec5SDimitry Andric          "PARM_VAR_DECL can't be static data member");
12540b57cec5SDimitry Andric }
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric void ASTDeclWriter::VisitDecompositionDecl(DecompositionDecl *D) {
12570b57cec5SDimitry Andric   // Record the number of bindings first to simplify deserialization.
12580b57cec5SDimitry Andric   Record.push_back(D->bindings().size());
12590b57cec5SDimitry Andric 
12600b57cec5SDimitry Andric   VisitVarDecl(D);
12610b57cec5SDimitry Andric   for (auto *B : D->bindings())
12620b57cec5SDimitry Andric     Record.AddDeclRef(B);
12630b57cec5SDimitry Andric   Code = serialization::DECL_DECOMPOSITION;
12640b57cec5SDimitry Andric }
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric void ASTDeclWriter::VisitBindingDecl(BindingDecl *D) {
12670b57cec5SDimitry Andric   VisitValueDecl(D);
12680b57cec5SDimitry Andric   Record.AddStmt(D->getBinding());
12690b57cec5SDimitry Andric   Code = serialization::DECL_BINDING;
12700b57cec5SDimitry Andric }
12710b57cec5SDimitry Andric 
12720b57cec5SDimitry Andric void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
12730b57cec5SDimitry Andric   VisitDecl(D);
12740b57cec5SDimitry Andric   Record.AddStmt(D->getAsmString());
12750b57cec5SDimitry Andric   Record.AddSourceLocation(D->getRParenLoc());
12760b57cec5SDimitry Andric   Code = serialization::DECL_FILE_SCOPE_ASM;
12770b57cec5SDimitry Andric }
12780b57cec5SDimitry Andric 
1279bdd1243dSDimitry Andric void ASTDeclWriter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
1280bdd1243dSDimitry Andric   VisitDecl(D);
1281bdd1243dSDimitry Andric   Record.AddStmt(D->getStmt());
1282bdd1243dSDimitry Andric   Code = serialization::DECL_TOP_LEVEL_STMT_DECL;
1283bdd1243dSDimitry Andric }
1284bdd1243dSDimitry Andric 
12850b57cec5SDimitry Andric void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
12860b57cec5SDimitry Andric   VisitDecl(D);
12870b57cec5SDimitry Andric   Code = serialization::DECL_EMPTY;
12880b57cec5SDimitry Andric }
12890b57cec5SDimitry Andric 
1290480093f4SDimitry Andric void ASTDeclWriter::VisitLifetimeExtendedTemporaryDecl(
1291480093f4SDimitry Andric     LifetimeExtendedTemporaryDecl *D) {
1292480093f4SDimitry Andric   VisitDecl(D);
1293480093f4SDimitry Andric   Record.AddDeclRef(D->getExtendingDecl());
1294480093f4SDimitry Andric   Record.AddStmt(D->getTemporaryExpr());
1295480093f4SDimitry Andric   Record.push_back(static_cast<bool>(D->getValue()));
1296480093f4SDimitry Andric   if (D->getValue())
1297480093f4SDimitry Andric     Record.AddAPValue(*D->getValue());
1298480093f4SDimitry Andric   Record.push_back(D->getManglingNumber());
1299480093f4SDimitry Andric   Code = serialization::DECL_LIFETIME_EXTENDED_TEMPORARY;
1300480093f4SDimitry Andric }
13010b57cec5SDimitry Andric void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
13020b57cec5SDimitry Andric   VisitDecl(D);
13030b57cec5SDimitry Andric   Record.AddStmt(D->getBody());
13040b57cec5SDimitry Andric   Record.AddTypeSourceInfo(D->getSignatureAsWritten());
13050b57cec5SDimitry Andric   Record.push_back(D->param_size());
13060b57cec5SDimitry Andric   for (ParmVarDecl *P : D->parameters())
13070b57cec5SDimitry Andric     Record.AddDeclRef(P);
13080b57cec5SDimitry Andric   Record.push_back(D->isVariadic());
13090b57cec5SDimitry Andric   Record.push_back(D->blockMissingReturnType());
13100b57cec5SDimitry Andric   Record.push_back(D->isConversionFromLambda());
13110b57cec5SDimitry Andric   Record.push_back(D->doesNotEscape());
13120b57cec5SDimitry Andric   Record.push_back(D->canAvoidCopyToHeap());
13130b57cec5SDimitry Andric   Record.push_back(D->capturesCXXThis());
13140b57cec5SDimitry Andric   Record.push_back(D->getNumCaptures());
13150b57cec5SDimitry Andric   for (const auto &capture : D->captures()) {
13160b57cec5SDimitry Andric     Record.AddDeclRef(capture.getVariable());
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric     unsigned flags = 0;
13190b57cec5SDimitry Andric     if (capture.isByRef()) flags |= 1;
13200b57cec5SDimitry Andric     if (capture.isNested()) flags |= 2;
13210b57cec5SDimitry Andric     if (capture.hasCopyExpr()) flags |= 4;
13220b57cec5SDimitry Andric     Record.push_back(flags);
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric     if (capture.hasCopyExpr()) Record.AddStmt(capture.getCopyExpr());
13250b57cec5SDimitry Andric   }
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric   Code = serialization::DECL_BLOCK;
13280b57cec5SDimitry Andric }
13290b57cec5SDimitry Andric 
13300b57cec5SDimitry Andric void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
13310b57cec5SDimitry Andric   Record.push_back(CD->getNumParams());
13320b57cec5SDimitry Andric   VisitDecl(CD);
13330b57cec5SDimitry Andric   Record.push_back(CD->getContextParamPosition());
13340b57cec5SDimitry Andric   Record.push_back(CD->isNothrow() ? 1 : 0);
13350b57cec5SDimitry Andric   // Body is stored by VisitCapturedStmt.
13360b57cec5SDimitry Andric   for (unsigned I = 0; I < CD->getNumParams(); ++I)
13370b57cec5SDimitry Andric     Record.AddDeclRef(CD->getParam(I));
13380b57cec5SDimitry Andric   Code = serialization::DECL_CAPTURED;
13390b57cec5SDimitry Andric }
13400b57cec5SDimitry Andric 
13410b57cec5SDimitry Andric void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
13425f757f3fSDimitry Andric   static_assert(DeclContext::NumLinkageSpecDeclBits == 17,
134306c3fb27SDimitry Andric                 "You need to update the serializer after you change the"
134406c3fb27SDimitry Andric                 "LinkageSpecDeclBits");
134506c3fb27SDimitry Andric 
13460b57cec5SDimitry Andric   VisitDecl(D);
13475f757f3fSDimitry Andric   Record.push_back(llvm::to_underlying(D->getLanguage()));
13480b57cec5SDimitry Andric   Record.AddSourceLocation(D->getExternLoc());
13490b57cec5SDimitry Andric   Record.AddSourceLocation(D->getRBraceLoc());
13500b57cec5SDimitry Andric   Code = serialization::DECL_LINKAGE_SPEC;
13510b57cec5SDimitry Andric }
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric void ASTDeclWriter::VisitExportDecl(ExportDecl *D) {
13540b57cec5SDimitry Andric   VisitDecl(D);
13550b57cec5SDimitry Andric   Record.AddSourceLocation(D->getRBraceLoc());
13560b57cec5SDimitry Andric   Code = serialization::DECL_EXPORT;
13570b57cec5SDimitry Andric }
13580b57cec5SDimitry Andric 
13590b57cec5SDimitry Andric void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
13600b57cec5SDimitry Andric   VisitNamedDecl(D);
13610b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
13620b57cec5SDimitry Andric   Code = serialization::DECL_LABEL;
13630b57cec5SDimitry Andric }
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric 
13660b57cec5SDimitry Andric void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
13670b57cec5SDimitry Andric   VisitRedeclarable(D);
13680b57cec5SDimitry Andric   VisitNamedDecl(D);
13695f757f3fSDimitry Andric 
13705f757f3fSDimitry Andric   BitsPacker NamespaceDeclBits;
13715f757f3fSDimitry Andric   NamespaceDeclBits.addBit(D->isInline());
13725f757f3fSDimitry Andric   NamespaceDeclBits.addBit(D->isNested());
13735f757f3fSDimitry Andric   Record.push_back(NamespaceDeclBits);
13745f757f3fSDimitry Andric 
13750b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
13760b57cec5SDimitry Andric   Record.AddSourceLocation(D->getRBraceLoc());
13770b57cec5SDimitry Andric 
13780fca6ea1SDimitry Andric   if (D->isFirstDecl())
13790b57cec5SDimitry Andric     Record.AddDeclRef(D->getAnonymousNamespace());
13800b57cec5SDimitry Andric   Code = serialization::DECL_NAMESPACE;
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric   if (Writer.hasChain() && D->isAnonymousNamespace() &&
13830b57cec5SDimitry Andric       D == D->getMostRecentDecl()) {
13840b57cec5SDimitry Andric     // This is a most recent reopening of the anonymous namespace. If its parent
13850b57cec5SDimitry Andric     // is in a previous PCH (or is the TU), mark that parent for update, because
13860b57cec5SDimitry Andric     // the original namespace always points to the latest re-opening of its
13870b57cec5SDimitry Andric     // anonymous namespace.
13880b57cec5SDimitry Andric     Decl *Parent = cast<Decl>(
13890b57cec5SDimitry Andric         D->getParent()->getRedeclContext()->getPrimaryContext());
13900b57cec5SDimitry Andric     if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
13910b57cec5SDimitry Andric       Writer.DeclUpdates[Parent].push_back(
13920b57cec5SDimitry Andric           ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
13930b57cec5SDimitry Andric     }
13940b57cec5SDimitry Andric   }
13950b57cec5SDimitry Andric }
13960b57cec5SDimitry Andric 
13970b57cec5SDimitry Andric void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
13980b57cec5SDimitry Andric   VisitRedeclarable(D);
13990b57cec5SDimitry Andric   VisitNamedDecl(D);
14000b57cec5SDimitry Andric   Record.AddSourceLocation(D->getNamespaceLoc());
14010b57cec5SDimitry Andric   Record.AddSourceLocation(D->getTargetNameLoc());
14020b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
14030b57cec5SDimitry Andric   Record.AddDeclRef(D->getNamespace());
14040b57cec5SDimitry Andric   Code = serialization::DECL_NAMESPACE_ALIAS;
14050b57cec5SDimitry Andric }
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
14080b57cec5SDimitry Andric   VisitNamedDecl(D);
14090b57cec5SDimitry Andric   Record.AddSourceLocation(D->getUsingLoc());
14100b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
14110b57cec5SDimitry Andric   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
14120b57cec5SDimitry Andric   Record.AddDeclRef(D->FirstUsingShadow.getPointer());
14130b57cec5SDimitry Andric   Record.push_back(D->hasTypename());
14140b57cec5SDimitry Andric   Record.AddDeclRef(Context.getInstantiatedFromUsingDecl(D));
14150b57cec5SDimitry Andric   Code = serialization::DECL_USING;
14160b57cec5SDimitry Andric }
14170b57cec5SDimitry Andric 
1418fe6060f1SDimitry Andric void ASTDeclWriter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1419fe6060f1SDimitry Andric   VisitNamedDecl(D);
1420fe6060f1SDimitry Andric   Record.AddSourceLocation(D->getUsingLoc());
1421fe6060f1SDimitry Andric   Record.AddSourceLocation(D->getEnumLoc());
1422bdd1243dSDimitry Andric   Record.AddTypeSourceInfo(D->getEnumType());
1423fe6060f1SDimitry Andric   Record.AddDeclRef(D->FirstUsingShadow.getPointer());
1424fe6060f1SDimitry Andric   Record.AddDeclRef(Context.getInstantiatedFromUsingEnumDecl(D));
1425fe6060f1SDimitry Andric   Code = serialization::DECL_USING_ENUM;
1426fe6060f1SDimitry Andric }
1427fe6060f1SDimitry Andric 
14280b57cec5SDimitry Andric void ASTDeclWriter::VisitUsingPackDecl(UsingPackDecl *D) {
14290b57cec5SDimitry Andric   Record.push_back(D->NumExpansions);
14300b57cec5SDimitry Andric   VisitNamedDecl(D);
14310b57cec5SDimitry Andric   Record.AddDeclRef(D->getInstantiatedFromUsingDecl());
14320b57cec5SDimitry Andric   for (auto *E : D->expansions())
14330b57cec5SDimitry Andric     Record.AddDeclRef(E);
14340b57cec5SDimitry Andric   Code = serialization::DECL_USING_PACK;
14350b57cec5SDimitry Andric }
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
14380b57cec5SDimitry Andric   VisitRedeclarable(D);
14390b57cec5SDimitry Andric   VisitNamedDecl(D);
14400b57cec5SDimitry Andric   Record.AddDeclRef(D->getTargetDecl());
14410b57cec5SDimitry Andric   Record.push_back(D->getIdentifierNamespace());
14420b57cec5SDimitry Andric   Record.AddDeclRef(D->UsingOrNextShadow);
14430b57cec5SDimitry Andric   Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
1444cb14a3feSDimitry Andric 
1445cb14a3feSDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() &&
1446cb14a3feSDimitry Andric       D->getFirstDecl() == D->getMostRecentDecl() && !D->hasAttrs() &&
1447cb14a3feSDimitry Andric       !needsAnonymousDeclarationNumber(D) &&
1448cb14a3feSDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier)
1449cb14a3feSDimitry Andric     AbbrevToUse = Writer.getDeclUsingShadowAbbrev();
1450cb14a3feSDimitry Andric 
14510b57cec5SDimitry Andric   Code = serialization::DECL_USING_SHADOW;
14520b57cec5SDimitry Andric }
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric void ASTDeclWriter::VisitConstructorUsingShadowDecl(
14550b57cec5SDimitry Andric     ConstructorUsingShadowDecl *D) {
14560b57cec5SDimitry Andric   VisitUsingShadowDecl(D);
14570b57cec5SDimitry Andric   Record.AddDeclRef(D->NominatedBaseClassShadowDecl);
14580b57cec5SDimitry Andric   Record.AddDeclRef(D->ConstructedBaseClassShadowDecl);
14590b57cec5SDimitry Andric   Record.push_back(D->IsVirtual);
14600b57cec5SDimitry Andric   Code = serialization::DECL_CONSTRUCTOR_USING_SHADOW;
14610b57cec5SDimitry Andric }
14620b57cec5SDimitry Andric 
14630b57cec5SDimitry Andric void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
14640b57cec5SDimitry Andric   VisitNamedDecl(D);
14650b57cec5SDimitry Andric   Record.AddSourceLocation(D->getUsingLoc());
14660b57cec5SDimitry Andric   Record.AddSourceLocation(D->getNamespaceKeyLocation());
14670b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
14680b57cec5SDimitry Andric   Record.AddDeclRef(D->getNominatedNamespace());
14690b57cec5SDimitry Andric   Record.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()));
14700b57cec5SDimitry Andric   Code = serialization::DECL_USING_DIRECTIVE;
14710b57cec5SDimitry Andric }
14720b57cec5SDimitry Andric 
14730b57cec5SDimitry Andric void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
14740b57cec5SDimitry Andric   VisitValueDecl(D);
14750b57cec5SDimitry Andric   Record.AddSourceLocation(D->getUsingLoc());
14760b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
14770b57cec5SDimitry Andric   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
14780b57cec5SDimitry Andric   Record.AddSourceLocation(D->getEllipsisLoc());
14790b57cec5SDimitry Andric   Code = serialization::DECL_UNRESOLVED_USING_VALUE;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
14830b57cec5SDimitry Andric                                                UnresolvedUsingTypenameDecl *D) {
14840b57cec5SDimitry Andric   VisitTypeDecl(D);
14850b57cec5SDimitry Andric   Record.AddSourceLocation(D->getTypenameLoc());
14860b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
14870b57cec5SDimitry Andric   Record.AddSourceLocation(D->getEllipsisLoc());
14880b57cec5SDimitry Andric   Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
14890b57cec5SDimitry Andric }
14900b57cec5SDimitry Andric 
1491fe6060f1SDimitry Andric void ASTDeclWriter::VisitUnresolvedUsingIfExistsDecl(
1492fe6060f1SDimitry Andric     UnresolvedUsingIfExistsDecl *D) {
1493fe6060f1SDimitry Andric   VisitNamedDecl(D);
1494fe6060f1SDimitry Andric   Code = serialization::DECL_UNRESOLVED_USING_IF_EXISTS;
1495fe6060f1SDimitry Andric }
1496fe6060f1SDimitry Andric 
14970b57cec5SDimitry Andric void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
14980b57cec5SDimitry Andric   VisitRecordDecl(D);
14990b57cec5SDimitry Andric 
15000b57cec5SDimitry Andric   enum {
150106c3fb27SDimitry Andric     CXXRecNotTemplate = 0,
150206c3fb27SDimitry Andric     CXXRecTemplate,
150306c3fb27SDimitry Andric     CXXRecMemberSpecialization,
150406c3fb27SDimitry Andric     CXXLambda
15050b57cec5SDimitry Andric   };
15060b57cec5SDimitry Andric   if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
15070b57cec5SDimitry Andric     Record.push_back(CXXRecTemplate);
15080b57cec5SDimitry Andric     Record.AddDeclRef(TemplD);
15090b57cec5SDimitry Andric   } else if (MemberSpecializationInfo *MSInfo
15100b57cec5SDimitry Andric                = D->getMemberSpecializationInfo()) {
15110b57cec5SDimitry Andric     Record.push_back(CXXRecMemberSpecialization);
15120b57cec5SDimitry Andric     Record.AddDeclRef(MSInfo->getInstantiatedFrom());
15130b57cec5SDimitry Andric     Record.push_back(MSInfo->getTemplateSpecializationKind());
15140b57cec5SDimitry Andric     Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
151506c3fb27SDimitry Andric   } else if (D->isLambda()) {
151606c3fb27SDimitry Andric     // For a lambda, we need some information early for merging.
151706c3fb27SDimitry Andric     Record.push_back(CXXLambda);
151806c3fb27SDimitry Andric     if (auto *Context = D->getLambdaContextDecl()) {
151906c3fb27SDimitry Andric       Record.AddDeclRef(Context);
152006c3fb27SDimitry Andric       Record.push_back(D->getLambdaIndexInContext());
152106c3fb27SDimitry Andric     } else {
152206c3fb27SDimitry Andric       Record.push_back(0);
152306c3fb27SDimitry Andric     }
15240b57cec5SDimitry Andric   } else {
15250b57cec5SDimitry Andric     Record.push_back(CXXRecNotTemplate);
15260b57cec5SDimitry Andric   }
15270b57cec5SDimitry Andric 
15280b57cec5SDimitry Andric   Record.push_back(D->isThisDeclarationADefinition());
15290b57cec5SDimitry Andric   if (D->isThisDeclarationADefinition())
15300b57cec5SDimitry Andric     Record.AddCXXDefinitionData(D);
15310b57cec5SDimitry Andric 
153262987288SDimitry Andric   if (D->isCompleteDefinition() && D->isInNamedModule())
153362987288SDimitry Andric     Writer.AddDeclRef(D, Writer.ModularCodegenDecls);
153462987288SDimitry Andric 
15350b57cec5SDimitry Andric   // Store (what we currently believe to be) the key function to avoid
15360b57cec5SDimitry Andric   // deserializing every method so we can compute it.
153762987288SDimitry Andric   //
153862987288SDimitry Andric   // FIXME: Avoid adding the key function if the class is defined in
153962987288SDimitry Andric   // module purview since in that case the key function is meaningless.
15400b57cec5SDimitry Andric   if (D->isCompleteDefinition())
15410b57cec5SDimitry Andric     Record.AddDeclRef(Context.getCurrentKeyFunction(D));
15420b57cec5SDimitry Andric 
15430b57cec5SDimitry Andric   Code = serialization::DECL_CXX_RECORD;
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
15470b57cec5SDimitry Andric   VisitFunctionDecl(D);
15480b57cec5SDimitry Andric   if (D->isCanonicalDecl()) {
15490b57cec5SDimitry Andric     Record.push_back(D->size_overridden_methods());
15500b57cec5SDimitry Andric     for (const CXXMethodDecl *MD : D->overridden_methods())
15510b57cec5SDimitry Andric       Record.AddDeclRef(MD);
15520b57cec5SDimitry Andric   } else {
15530b57cec5SDimitry Andric     // We only need to record overridden methods once for the canonical decl.
15540b57cec5SDimitry Andric     Record.push_back(0);
15550b57cec5SDimitry Andric   }
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric   if (D->getDeclContext() == D->getLexicalDeclContext() &&
1558bdd1243dSDimitry Andric       D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
1559bdd1243dSDimitry Andric       !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
15600b57cec5SDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
15610fca6ea1SDimitry Andric       !D->hasExtInfo() && !D->isExplicitlyDefaulted()) {
1562cb14a3feSDimitry Andric     if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate ||
1563cb14a3feSDimitry Andric         D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate ||
1564cb14a3feSDimitry Andric         D->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
1565cb14a3feSDimitry Andric         D->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate)
1566cb14a3feSDimitry Andric       AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind());
1567cb14a3feSDimitry Andric     else if (D->getTemplatedKind() ==
1568cb14a3feSDimitry Andric              FunctionDecl::TK_FunctionTemplateSpecialization) {
1569cb14a3feSDimitry Andric       FunctionTemplateSpecializationInfo *FTSInfo =
1570cb14a3feSDimitry Andric           D->getTemplateSpecializationInfo();
1571cb14a3feSDimitry Andric 
1572cb14a3feSDimitry Andric       if (FTSInfo->TemplateArguments->size() == 1) {
1573cb14a3feSDimitry Andric         const TemplateArgument &TA = FTSInfo->TemplateArguments->get(0);
1574cb14a3feSDimitry Andric         if (TA.getKind() == TemplateArgument::Type &&
1575cb14a3feSDimitry Andric             !FTSInfo->TemplateArgumentsAsWritten &&
1576cb14a3feSDimitry Andric             !FTSInfo->getMemberSpecializationInfo())
1577cb14a3feSDimitry Andric           AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind());
1578cb14a3feSDimitry Andric       }
1579cb14a3feSDimitry Andric     } else if (D->getTemplatedKind() ==
1580cb14a3feSDimitry Andric                FunctionDecl::TK_DependentFunctionTemplateSpecialization) {
1581cb14a3feSDimitry Andric       DependentFunctionTemplateSpecializationInfo *DFTSInfo =
1582cb14a3feSDimitry Andric           D->getDependentSpecializationInfo();
1583cb14a3feSDimitry Andric       if (!DFTSInfo->TemplateArgumentsAsWritten)
1584cb14a3feSDimitry Andric         AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind());
1585cb14a3feSDimitry Andric     }
1586cb14a3feSDimitry Andric   }
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric   Code = serialization::DECL_CXX_METHOD;
15890b57cec5SDimitry Andric }
15900b57cec5SDimitry Andric 
15910b57cec5SDimitry Andric void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
15925f757f3fSDimitry Andric   static_assert(DeclContext::NumCXXConstructorDeclBits == 64,
159306c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
159406c3fb27SDimitry Andric                 "CXXConstructorDeclBits");
159506c3fb27SDimitry Andric 
1596fe6060f1SDimitry Andric   Record.push_back(D->getTrailingAllocKind());
15970b57cec5SDimitry Andric   addExplicitSpecifier(D->getExplicitSpecifier(), Record);
15980b57cec5SDimitry Andric   if (auto Inherited = D->getInheritedConstructor()) {
15990b57cec5SDimitry Andric     Record.AddDeclRef(Inherited.getShadowDecl());
16000b57cec5SDimitry Andric     Record.AddDeclRef(Inherited.getConstructor());
16010b57cec5SDimitry Andric   }
16020b57cec5SDimitry Andric 
16030b57cec5SDimitry Andric   VisitCXXMethodDecl(D);
16040b57cec5SDimitry Andric   Code = serialization::DECL_CXX_CONSTRUCTOR;
16050b57cec5SDimitry Andric }
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
16080b57cec5SDimitry Andric   VisitCXXMethodDecl(D);
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric   Record.AddDeclRef(D->getOperatorDelete());
16110b57cec5SDimitry Andric   if (D->getOperatorDelete())
16120b57cec5SDimitry Andric     Record.AddStmt(D->getOperatorDeleteThisArg());
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric   Code = serialization::DECL_CXX_DESTRUCTOR;
16150b57cec5SDimitry Andric }
16160b57cec5SDimitry Andric 
16170b57cec5SDimitry Andric void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
16180b57cec5SDimitry Andric   addExplicitSpecifier(D->getExplicitSpecifier(), Record);
16190b57cec5SDimitry Andric   VisitCXXMethodDecl(D);
16200b57cec5SDimitry Andric   Code = serialization::DECL_CXX_CONVERSION;
16210b57cec5SDimitry Andric }
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric void ASTDeclWriter::VisitImportDecl(ImportDecl *D) {
16240b57cec5SDimitry Andric   VisitDecl(D);
16250b57cec5SDimitry Andric   Record.push_back(Writer.getSubmoduleID(D->getImportedModule()));
16260b57cec5SDimitry Andric   ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
16270b57cec5SDimitry Andric   Record.push_back(!IdentifierLocs.empty());
16280b57cec5SDimitry Andric   if (IdentifierLocs.empty()) {
16290b57cec5SDimitry Andric     Record.AddSourceLocation(D->getEndLoc());
16300b57cec5SDimitry Andric     Record.push_back(1);
16310b57cec5SDimitry Andric   } else {
16320b57cec5SDimitry Andric     for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
16330b57cec5SDimitry Andric       Record.AddSourceLocation(IdentifierLocs[I]);
16340b57cec5SDimitry Andric     Record.push_back(IdentifierLocs.size());
16350b57cec5SDimitry Andric   }
16360b57cec5SDimitry Andric   // Note: the number of source locations must always be the last element in
16370b57cec5SDimitry Andric   // the record.
16380b57cec5SDimitry Andric   Code = serialization::DECL_IMPORT;
16390b57cec5SDimitry Andric }
16400b57cec5SDimitry Andric 
16410b57cec5SDimitry Andric void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
16420b57cec5SDimitry Andric   VisitDecl(D);
16430b57cec5SDimitry Andric   Record.AddSourceLocation(D->getColonLoc());
16440b57cec5SDimitry Andric   Code = serialization::DECL_ACCESS_SPEC;
16450b57cec5SDimitry Andric }
16460b57cec5SDimitry Andric 
16470b57cec5SDimitry Andric void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
16480b57cec5SDimitry Andric   // Record the number of friend type template parameter lists here
16490b57cec5SDimitry Andric   // so as to simplify memory allocation during deserialization.
16500b57cec5SDimitry Andric   Record.push_back(D->NumTPLists);
16510b57cec5SDimitry Andric   VisitDecl(D);
16520b57cec5SDimitry Andric   bool hasFriendDecl = D->Friend.is<NamedDecl*>();
16530b57cec5SDimitry Andric   Record.push_back(hasFriendDecl);
16540b57cec5SDimitry Andric   if (hasFriendDecl)
16550b57cec5SDimitry Andric     Record.AddDeclRef(D->getFriendDecl());
16560b57cec5SDimitry Andric   else
16570b57cec5SDimitry Andric     Record.AddTypeSourceInfo(D->getFriendType());
16580b57cec5SDimitry Andric   for (unsigned i = 0; i < D->NumTPLists; ++i)
16590b57cec5SDimitry Andric     Record.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i));
16600b57cec5SDimitry Andric   Record.AddDeclRef(D->getNextFriend());
16610b57cec5SDimitry Andric   Record.push_back(D->UnsupportedFriend);
16620b57cec5SDimitry Andric   Record.AddSourceLocation(D->FriendLoc);
16630b57cec5SDimitry Andric   Code = serialization::DECL_FRIEND;
16640b57cec5SDimitry Andric }
16650b57cec5SDimitry Andric 
16660b57cec5SDimitry Andric void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
16670b57cec5SDimitry Andric   VisitDecl(D);
16680b57cec5SDimitry Andric   Record.push_back(D->getNumTemplateParameters());
16690b57cec5SDimitry Andric   for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
16700b57cec5SDimitry Andric     Record.AddTemplateParameterList(D->getTemplateParameterList(i));
16710b57cec5SDimitry Andric   Record.push_back(D->getFriendDecl() != nullptr);
16720b57cec5SDimitry Andric   if (D->getFriendDecl())
16730b57cec5SDimitry Andric     Record.AddDeclRef(D->getFriendDecl());
16740b57cec5SDimitry Andric   else
16750b57cec5SDimitry Andric     Record.AddTypeSourceInfo(D->getFriendType());
16760b57cec5SDimitry Andric   Record.AddSourceLocation(D->getFriendLoc());
16770b57cec5SDimitry Andric   Code = serialization::DECL_FRIEND_TEMPLATE;
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
16810b57cec5SDimitry Andric   VisitNamedDecl(D);
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric   Record.AddTemplateParameterList(D->getTemplateParameters());
1684bdd1243dSDimitry Andric   Record.AddDeclRef(D->getTemplatedDecl());
16850b57cec5SDimitry Andric }
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
16880b57cec5SDimitry Andric   VisitTemplateDecl(D);
16890b57cec5SDimitry Andric   Record.AddStmt(D->getConstraintExpr());
16900b57cec5SDimitry Andric   Code = serialization::DECL_CONCEPT;
16910b57cec5SDimitry Andric }
16920b57cec5SDimitry Andric 
1693bdd1243dSDimitry Andric void ASTDeclWriter::VisitImplicitConceptSpecializationDecl(
1694bdd1243dSDimitry Andric     ImplicitConceptSpecializationDecl *D) {
1695bdd1243dSDimitry Andric   Record.push_back(D->getTemplateArguments().size());
1696bdd1243dSDimitry Andric   VisitDecl(D);
1697bdd1243dSDimitry Andric   for (const TemplateArgument &Arg : D->getTemplateArguments())
1698bdd1243dSDimitry Andric     Record.AddTemplateArgument(Arg);
1699bdd1243dSDimitry Andric   Code = serialization::DECL_IMPLICIT_CONCEPT_SPECIALIZATION;
1700bdd1243dSDimitry Andric }
1701bdd1243dSDimitry Andric 
170255e4f9d5SDimitry Andric void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
170355e4f9d5SDimitry Andric   Code = serialization::DECL_REQUIRES_EXPR_BODY;
170455e4f9d5SDimitry Andric }
170555e4f9d5SDimitry Andric 
17060b57cec5SDimitry Andric void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
17070b57cec5SDimitry Andric   VisitRedeclarable(D);
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric   // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
17100b57cec5SDimitry Andric   // getCommonPtr() can be used while this is still initializing.
17110b57cec5SDimitry Andric   if (D->isFirstDecl()) {
17120b57cec5SDimitry Andric     // This declaration owns the 'common' pointer, so serialize that data now.
17130b57cec5SDimitry Andric     Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
17140b57cec5SDimitry Andric     if (D->getInstantiatedFromMemberTemplate())
17150b57cec5SDimitry Andric       Record.push_back(D->isMemberSpecialization());
17160b57cec5SDimitry Andric   }
17170b57cec5SDimitry Andric 
17180b57cec5SDimitry Andric   VisitTemplateDecl(D);
17190b57cec5SDimitry Andric   Record.push_back(D->getIdentifierNamespace());
17200b57cec5SDimitry Andric }
17210b57cec5SDimitry Andric 
17220b57cec5SDimitry Andric void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
17230b57cec5SDimitry Andric   VisitRedeclarableTemplateDecl(D);
17240b57cec5SDimitry Andric 
17250b57cec5SDimitry Andric   if (D->isFirstDecl())
17260b57cec5SDimitry Andric     AddTemplateSpecializations(D);
17270fca6ea1SDimitry Andric 
17280fca6ea1SDimitry Andric   // Force emitting the corresponding deduction guide in reduced BMI mode.
17290fca6ea1SDimitry Andric   // Otherwise, the deduction guide may be optimized out incorrectly.
17300fca6ea1SDimitry Andric   if (Writer.isGeneratingReducedBMI()) {
17310fca6ea1SDimitry Andric     auto Name = Context.DeclarationNames.getCXXDeductionGuideName(D);
17320fca6ea1SDimitry Andric     for (auto *DG : D->getDeclContext()->noload_lookup(Name))
17330fca6ea1SDimitry Andric       Writer.GetDeclRef(DG->getCanonicalDecl());
17340fca6ea1SDimitry Andric   }
17350fca6ea1SDimitry Andric 
17360b57cec5SDimitry Andric   Code = serialization::DECL_CLASS_TEMPLATE;
17370b57cec5SDimitry Andric }
17380b57cec5SDimitry Andric 
17390b57cec5SDimitry Andric void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
17400b57cec5SDimitry Andric                                            ClassTemplateSpecializationDecl *D) {
17410b57cec5SDimitry Andric   RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric   VisitCXXRecordDecl(D);
17440b57cec5SDimitry Andric 
17450b57cec5SDimitry Andric   llvm::PointerUnion<ClassTemplateDecl *,
17460b57cec5SDimitry Andric                      ClassTemplatePartialSpecializationDecl *> InstFrom
17470b57cec5SDimitry Andric     = D->getSpecializedTemplateOrPartial();
17480b57cec5SDimitry Andric   if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
17490b57cec5SDimitry Andric     Record.AddDeclRef(InstFromD);
17500b57cec5SDimitry Andric   } else {
17510b57cec5SDimitry Andric     Record.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>());
17520b57cec5SDimitry Andric     Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
17530b57cec5SDimitry Andric   }
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric   Record.AddTemplateArgumentList(&D->getTemplateArgs());
17560b57cec5SDimitry Andric   Record.AddSourceLocation(D->getPointOfInstantiation());
17570b57cec5SDimitry Andric   Record.push_back(D->getSpecializationKind());
17580b57cec5SDimitry Andric   Record.push_back(D->isCanonicalDecl());
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric   if (D->isCanonicalDecl()) {
17610b57cec5SDimitry Andric     // When reading, we'll add it to the folding set of the following template.
17620b57cec5SDimitry Andric     Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
17630b57cec5SDimitry Andric   }
17640b57cec5SDimitry Andric 
17650fca6ea1SDimitry Andric   bool ExplicitInstantiation =
17660fca6ea1SDimitry Andric       D->getTemplateSpecializationKind() ==
17670fca6ea1SDimitry Andric           TSK_ExplicitInstantiationDeclaration ||
17680fca6ea1SDimitry Andric       D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
17690fca6ea1SDimitry Andric   Record.push_back(ExplicitInstantiation);
17700fca6ea1SDimitry Andric   if (ExplicitInstantiation) {
17710fca6ea1SDimitry Andric     Record.AddSourceLocation(D->getExternKeywordLoc());
17720b57cec5SDimitry Andric     Record.AddSourceLocation(D->getTemplateKeywordLoc());
17730b57cec5SDimitry Andric   }
17740b57cec5SDimitry Andric 
17750fca6ea1SDimitry Andric   const ASTTemplateArgumentListInfo *ArgsWritten =
17760fca6ea1SDimitry Andric       D->getTemplateArgsAsWritten();
17770fca6ea1SDimitry Andric   Record.push_back(!!ArgsWritten);
17780fca6ea1SDimitry Andric   if (ArgsWritten)
17790fca6ea1SDimitry Andric     Record.AddASTTemplateArgumentListInfo(ArgsWritten);
17800fca6ea1SDimitry Andric 
17810b57cec5SDimitry Andric   Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
17820b57cec5SDimitry Andric }
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
17850b57cec5SDimitry Andric                                     ClassTemplatePartialSpecializationDecl *D) {
17860b57cec5SDimitry Andric   Record.AddTemplateParameterList(D->getTemplateParameters());
17870b57cec5SDimitry Andric 
1788480093f4SDimitry Andric   VisitClassTemplateSpecializationDecl(D);
1789480093f4SDimitry Andric 
17900b57cec5SDimitry Andric   // These are read/set from/to the first declaration.
17910b57cec5SDimitry Andric   if (D->getPreviousDecl() == nullptr) {
17920b57cec5SDimitry Andric     Record.AddDeclRef(D->getInstantiatedFromMember());
17930b57cec5SDimitry Andric     Record.push_back(D->isMemberSpecialization());
17940b57cec5SDimitry Andric   }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
17970b57cec5SDimitry Andric }
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
18000b57cec5SDimitry Andric   VisitRedeclarableTemplateDecl(D);
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric   if (D->isFirstDecl())
18030b57cec5SDimitry Andric     AddTemplateSpecializations(D);
18040b57cec5SDimitry Andric   Code = serialization::DECL_VAR_TEMPLATE;
18050b57cec5SDimitry Andric }
18060b57cec5SDimitry Andric 
18070b57cec5SDimitry Andric void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
18080b57cec5SDimitry Andric     VarTemplateSpecializationDecl *D) {
18090b57cec5SDimitry Andric   RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
18100b57cec5SDimitry Andric 
18110b57cec5SDimitry Andric   llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
18120b57cec5SDimitry Andric   InstFrom = D->getSpecializedTemplateOrPartial();
18130b57cec5SDimitry Andric   if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
18140b57cec5SDimitry Andric     Record.AddDeclRef(InstFromD);
18150b57cec5SDimitry Andric   } else {
18160b57cec5SDimitry Andric     Record.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>());
18170b57cec5SDimitry Andric     Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
18180b57cec5SDimitry Andric   }
18190b57cec5SDimitry Andric 
18200fca6ea1SDimitry Andric   bool ExplicitInstantiation =
18210fca6ea1SDimitry Andric       D->getTemplateSpecializationKind() ==
18220fca6ea1SDimitry Andric           TSK_ExplicitInstantiationDeclaration ||
18230fca6ea1SDimitry Andric       D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
18240fca6ea1SDimitry Andric   Record.push_back(ExplicitInstantiation);
18250fca6ea1SDimitry Andric   if (ExplicitInstantiation) {
18260fca6ea1SDimitry Andric     Record.AddSourceLocation(D->getExternKeywordLoc());
18270b57cec5SDimitry Andric     Record.AddSourceLocation(D->getTemplateKeywordLoc());
18280b57cec5SDimitry Andric   }
18290b57cec5SDimitry Andric 
18300fca6ea1SDimitry Andric   const ASTTemplateArgumentListInfo *ArgsWritten =
18310fca6ea1SDimitry Andric       D->getTemplateArgsAsWritten();
18320fca6ea1SDimitry Andric   Record.push_back(!!ArgsWritten);
18330fca6ea1SDimitry Andric   if (ArgsWritten)
18340fca6ea1SDimitry Andric     Record.AddASTTemplateArgumentListInfo(ArgsWritten);
18350fca6ea1SDimitry Andric 
18360b57cec5SDimitry Andric   Record.AddTemplateArgumentList(&D->getTemplateArgs());
18370b57cec5SDimitry Andric   Record.AddSourceLocation(D->getPointOfInstantiation());
18380b57cec5SDimitry Andric   Record.push_back(D->getSpecializationKind());
18390b57cec5SDimitry Andric   Record.push_back(D->IsCompleteDefinition);
1840bdd1243dSDimitry Andric 
1841bdd1243dSDimitry Andric   VisitVarDecl(D);
1842bdd1243dSDimitry Andric 
18430b57cec5SDimitry Andric   Record.push_back(D->isCanonicalDecl());
18440b57cec5SDimitry Andric 
18450b57cec5SDimitry Andric   if (D->isCanonicalDecl()) {
18460b57cec5SDimitry Andric     // When reading, we'll add it to the folding set of the following template.
18470b57cec5SDimitry Andric     Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
18480b57cec5SDimitry Andric   }
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric   Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
18510b57cec5SDimitry Andric }
18520b57cec5SDimitry Andric 
18530b57cec5SDimitry Andric void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
18540b57cec5SDimitry Andric     VarTemplatePartialSpecializationDecl *D) {
18550b57cec5SDimitry Andric   Record.AddTemplateParameterList(D->getTemplateParameters());
18560b57cec5SDimitry Andric 
1857480093f4SDimitry Andric   VisitVarTemplateSpecializationDecl(D);
1858480093f4SDimitry Andric 
18590b57cec5SDimitry Andric   // These are read/set from/to the first declaration.
18600b57cec5SDimitry Andric   if (D->getPreviousDecl() == nullptr) {
18610b57cec5SDimitry Andric     Record.AddDeclRef(D->getInstantiatedFromMember());
18620b57cec5SDimitry Andric     Record.push_back(D->isMemberSpecialization());
18630b57cec5SDimitry Andric   }
18640b57cec5SDimitry Andric 
18650b57cec5SDimitry Andric   Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
18690b57cec5SDimitry Andric   VisitRedeclarableTemplateDecl(D);
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric   if (D->isFirstDecl())
18720b57cec5SDimitry Andric     AddTemplateSpecializations(D);
18730b57cec5SDimitry Andric   Code = serialization::DECL_FUNCTION_TEMPLATE;
18740b57cec5SDimitry Andric }
18750b57cec5SDimitry Andric 
18760b57cec5SDimitry Andric void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
1877480093f4SDimitry Andric   Record.push_back(D->hasTypeConstraint());
18780b57cec5SDimitry Andric   VisitTypeDecl(D);
18790b57cec5SDimitry Andric 
18800b57cec5SDimitry Andric   Record.push_back(D->wasDeclaredWithTypename());
1881480093f4SDimitry Andric 
1882480093f4SDimitry Andric   const TypeConstraint *TC = D->getTypeConstraint();
1883*d686ce93SDimitry Andric   Record.push_back(/*TypeConstraintInitialized=*/TC != nullptr);
1884480093f4SDimitry Andric   if (TC) {
18855f757f3fSDimitry Andric     auto *CR = TC->getConceptReference();
18865f757f3fSDimitry Andric     Record.push_back(CR != nullptr);
18875f757f3fSDimitry Andric     if (CR)
18885f757f3fSDimitry Andric       Record.AddConceptReference(CR);
1889480093f4SDimitry Andric     Record.AddStmt(TC->getImmediatelyDeclaredConstraint());
1890480093f4SDimitry Andric     Record.push_back(D->isExpandedParameterPack());
1891480093f4SDimitry Andric     if (D->isExpandedParameterPack())
1892480093f4SDimitry Andric       Record.push_back(D->getNumExpansionParameters());
1893480093f4SDimitry Andric   }
1894480093f4SDimitry Andric 
18950b57cec5SDimitry Andric   bool OwnsDefaultArg = D->hasDefaultArgument() &&
18960b57cec5SDimitry Andric                         !D->defaultArgumentWasInherited();
18970b57cec5SDimitry Andric   Record.push_back(OwnsDefaultArg);
18980b57cec5SDimitry Andric   if (OwnsDefaultArg)
18990fca6ea1SDimitry Andric     Record.AddTemplateArgumentLoc(D->getDefaultArgument());
19000b57cec5SDimitry Andric 
1901*d686ce93SDimitry Andric   if (!D->hasTypeConstraint() && !OwnsDefaultArg &&
1902cb14a3feSDimitry Andric       D->getDeclContext() == D->getLexicalDeclContext() &&
1903cb14a3feSDimitry Andric       !D->isInvalidDecl() && !D->hasAttrs() &&
1904cb14a3feSDimitry Andric       !D->isTopLevelDeclInObjCContainer() && !D->isImplicit() &&
1905cb14a3feSDimitry Andric       D->getDeclName().getNameKind() == DeclarationName::Identifier)
1906cb14a3feSDimitry Andric     AbbrevToUse = Writer.getDeclTemplateTypeParmAbbrev();
1907cb14a3feSDimitry Andric 
19080b57cec5SDimitry Andric   Code = serialization::DECL_TEMPLATE_TYPE_PARM;
19090b57cec5SDimitry Andric }
19100b57cec5SDimitry Andric 
19110b57cec5SDimitry Andric void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
19120b57cec5SDimitry Andric   // For an expanded parameter pack, record the number of expansion types here
19130b57cec5SDimitry Andric   // so that it's easier for deserialization to allocate the right amount of
19140b57cec5SDimitry Andric   // memory.
191555e4f9d5SDimitry Andric   Expr *TypeConstraint = D->getPlaceholderTypeConstraint();
191655e4f9d5SDimitry Andric   Record.push_back(!!TypeConstraint);
19170b57cec5SDimitry Andric   if (D->isExpandedParameterPack())
19180b57cec5SDimitry Andric     Record.push_back(D->getNumExpansionTypes());
19190b57cec5SDimitry Andric 
19200b57cec5SDimitry Andric   VisitDeclaratorDecl(D);
19210b57cec5SDimitry Andric   // TemplateParmPosition.
19220b57cec5SDimitry Andric   Record.push_back(D->getDepth());
19230b57cec5SDimitry Andric   Record.push_back(D->getPosition());
192455e4f9d5SDimitry Andric   if (TypeConstraint)
192555e4f9d5SDimitry Andric     Record.AddStmt(TypeConstraint);
19260b57cec5SDimitry Andric 
19270b57cec5SDimitry Andric   if (D->isExpandedParameterPack()) {
19280b57cec5SDimitry Andric     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
19290b57cec5SDimitry Andric       Record.AddTypeRef(D->getExpansionType(I));
19300b57cec5SDimitry Andric       Record.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I));
19310b57cec5SDimitry Andric     }
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric     Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
19340b57cec5SDimitry Andric   } else {
19350b57cec5SDimitry Andric     // Rest of NonTypeTemplateParmDecl.
19360b57cec5SDimitry Andric     Record.push_back(D->isParameterPack());
19370b57cec5SDimitry Andric     bool OwnsDefaultArg = D->hasDefaultArgument() &&
19380b57cec5SDimitry Andric                           !D->defaultArgumentWasInherited();
19390b57cec5SDimitry Andric     Record.push_back(OwnsDefaultArg);
19400b57cec5SDimitry Andric     if (OwnsDefaultArg)
19410fca6ea1SDimitry Andric       Record.AddTemplateArgumentLoc(D->getDefaultArgument());
19420b57cec5SDimitry Andric     Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
19430b57cec5SDimitry Andric   }
19440b57cec5SDimitry Andric }
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
19470b57cec5SDimitry Andric   // For an expanded parameter pack, record the number of expansion types here
19480b57cec5SDimitry Andric   // so that it's easier for deserialization to allocate the right amount of
19490b57cec5SDimitry Andric   // memory.
19500b57cec5SDimitry Andric   if (D->isExpandedParameterPack())
19510b57cec5SDimitry Andric     Record.push_back(D->getNumExpansionTemplateParameters());
19520b57cec5SDimitry Andric 
19530b57cec5SDimitry Andric   VisitTemplateDecl(D);
19540fca6ea1SDimitry Andric   Record.push_back(D->wasDeclaredWithTypename());
19550b57cec5SDimitry Andric   // TemplateParmPosition.
19560b57cec5SDimitry Andric   Record.push_back(D->getDepth());
19570b57cec5SDimitry Andric   Record.push_back(D->getPosition());
19580b57cec5SDimitry Andric 
19590b57cec5SDimitry Andric   if (D->isExpandedParameterPack()) {
19600b57cec5SDimitry Andric     for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
19610b57cec5SDimitry Andric          I != N; ++I)
19620b57cec5SDimitry Andric       Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I));
19630b57cec5SDimitry Andric     Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
19640b57cec5SDimitry Andric   } else {
19650b57cec5SDimitry Andric     // Rest of TemplateTemplateParmDecl.
19660b57cec5SDimitry Andric     Record.push_back(D->isParameterPack());
19670b57cec5SDimitry Andric     bool OwnsDefaultArg = D->hasDefaultArgument() &&
19680b57cec5SDimitry Andric                           !D->defaultArgumentWasInherited();
19690b57cec5SDimitry Andric     Record.push_back(OwnsDefaultArg);
19700b57cec5SDimitry Andric     if (OwnsDefaultArg)
19710b57cec5SDimitry Andric       Record.AddTemplateArgumentLoc(D->getDefaultArgument());
19720b57cec5SDimitry Andric     Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
19730b57cec5SDimitry Andric   }
19740b57cec5SDimitry Andric }
19750b57cec5SDimitry Andric 
19760b57cec5SDimitry Andric void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
19770b57cec5SDimitry Andric   VisitRedeclarableTemplateDecl(D);
19780b57cec5SDimitry Andric   Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
19790b57cec5SDimitry Andric }
19800b57cec5SDimitry Andric 
19810b57cec5SDimitry Andric void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
19820b57cec5SDimitry Andric   VisitDecl(D);
19830b57cec5SDimitry Andric   Record.AddStmt(D->getAssertExpr());
19840b57cec5SDimitry Andric   Record.push_back(D->isFailed());
19850b57cec5SDimitry Andric   Record.AddStmt(D->getMessage());
19860b57cec5SDimitry Andric   Record.AddSourceLocation(D->getRParenLoc());
19870b57cec5SDimitry Andric   Code = serialization::DECL_STATIC_ASSERT;
19880b57cec5SDimitry Andric }
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric /// Emit the DeclContext part of a declaration context decl.
19910b57cec5SDimitry Andric void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
199206c3fb27SDimitry Andric   static_assert(DeclContext::NumDeclContextBits == 13,
199306c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
199406c3fb27SDimitry Andric                 "DeclContextBits");
199506c3fb27SDimitry Andric 
19960fca6ea1SDimitry Andric   uint64_t LexicalOffset = 0;
19970fca6ea1SDimitry Andric   uint64_t VisibleOffset = 0;
19980fca6ea1SDimitry Andric 
19990fca6ea1SDimitry Andric   if (Writer.isGeneratingReducedBMI() && isa<NamespaceDecl>(DC) &&
20000fca6ea1SDimitry Andric       cast<NamespaceDecl>(DC)->isFromExplicitGlobalModule()) {
20010fca6ea1SDimitry Andric     // In reduced BMI, delay writing lexical and visible block for namespace
20020fca6ea1SDimitry Andric     // in the global module fragment. See the comments of DelayedNamespace for
20030fca6ea1SDimitry Andric     // details.
20040fca6ea1SDimitry Andric     Writer.DelayedNamespace.push_back(cast<NamespaceDecl>(DC));
20050fca6ea1SDimitry Andric   } else {
20060fca6ea1SDimitry Andric     LexicalOffset = Writer.WriteDeclContextLexicalBlock(Context, DC);
20070fca6ea1SDimitry Andric     VisibleOffset = Writer.WriteDeclContextVisibleBlock(Context, DC);
20080fca6ea1SDimitry Andric   }
20090fca6ea1SDimitry Andric 
20100fca6ea1SDimitry Andric   Record.AddOffset(LexicalOffset);
20110fca6ea1SDimitry Andric   Record.AddOffset(VisibleOffset);
20120b57cec5SDimitry Andric }
20130b57cec5SDimitry Andric 
20140b57cec5SDimitry Andric const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
20150b57cec5SDimitry Andric   assert(IsLocalDecl(D) && "expected a local declaration");
20160b57cec5SDimitry Andric 
20170b57cec5SDimitry Andric   const Decl *Canon = D->getCanonicalDecl();
20180b57cec5SDimitry Andric   if (IsLocalDecl(Canon))
20190b57cec5SDimitry Andric     return Canon;
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric   const Decl *&CacheEntry = FirstLocalDeclCache[Canon];
20220b57cec5SDimitry Andric   if (CacheEntry)
20230b57cec5SDimitry Andric     return CacheEntry;
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl())
20260b57cec5SDimitry Andric     if (IsLocalDecl(Redecl))
20270b57cec5SDimitry Andric       D = Redecl;
20280b57cec5SDimitry Andric   return CacheEntry = D;
20290b57cec5SDimitry Andric }
20300b57cec5SDimitry Andric 
20310b57cec5SDimitry Andric template <typename T>
20320b57cec5SDimitry Andric void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
20330b57cec5SDimitry Andric   T *First = D->getFirstDecl();
20340b57cec5SDimitry Andric   T *MostRecent = First->getMostRecentDecl();
20350b57cec5SDimitry Andric   T *DAsT = static_cast<T *>(D);
20360b57cec5SDimitry Andric   if (MostRecent != First) {
20370b57cec5SDimitry Andric     assert(isRedeclarableDeclKind(DAsT->getKind()) &&
20380b57cec5SDimitry Andric            "Not considered redeclarable?");
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric     Record.AddDeclRef(First);
20410b57cec5SDimitry Andric 
20420b57cec5SDimitry Andric     // Write out a list of local redeclarations of this declaration if it's the
20430b57cec5SDimitry Andric     // first local declaration in the chain.
20440b57cec5SDimitry Andric     const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT);
20450b57cec5SDimitry Andric     if (DAsT == FirstLocal) {
20460b57cec5SDimitry Andric       // Emit a list of all imported first declarations so that we can be sure
20470b57cec5SDimitry Andric       // that all redeclarations visible to this module are before D in the
20480b57cec5SDimitry Andric       // redecl chain.
20490b57cec5SDimitry Andric       unsigned I = Record.size();
20500b57cec5SDimitry Andric       Record.push_back(0);
20510b57cec5SDimitry Andric       if (Writer.Chain)
20520b57cec5SDimitry Andric         AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
20530b57cec5SDimitry Andric       // This is the number of imported first declarations + 1.
20540b57cec5SDimitry Andric       Record[I] = Record.size() - I;
20550b57cec5SDimitry Andric 
20560b57cec5SDimitry Andric       // Collect the set of local redeclarations of this declaration, from
20570b57cec5SDimitry Andric       // newest to oldest.
20580b57cec5SDimitry Andric       ASTWriter::RecordData LocalRedecls;
20590b57cec5SDimitry Andric       ASTRecordWriter LocalRedeclWriter(Record, LocalRedecls);
20600b57cec5SDimitry Andric       for (const Decl *Prev = FirstLocal->getMostRecentDecl();
20610b57cec5SDimitry Andric            Prev != FirstLocal; Prev = Prev->getPreviousDecl())
20620b57cec5SDimitry Andric         if (!Prev->isFromASTFile())
20630b57cec5SDimitry Andric           LocalRedeclWriter.AddDeclRef(Prev);
20640b57cec5SDimitry Andric 
20650b57cec5SDimitry Andric       // If we have any redecls, write them now as a separate record preceding
20660b57cec5SDimitry Andric       // the declaration itself.
20670b57cec5SDimitry Andric       if (LocalRedecls.empty())
20680b57cec5SDimitry Andric         Record.push_back(0);
20690b57cec5SDimitry Andric       else
20700b57cec5SDimitry Andric         Record.AddOffset(LocalRedeclWriter.Emit(LOCAL_REDECLARATIONS));
20710b57cec5SDimitry Andric     } else {
20720b57cec5SDimitry Andric       Record.push_back(0);
20730b57cec5SDimitry Andric       Record.AddDeclRef(FirstLocal);
20740b57cec5SDimitry Andric     }
20750b57cec5SDimitry Andric 
20760b57cec5SDimitry Andric     // Make sure that we serialize both the previous and the most-recent
20770b57cec5SDimitry Andric     // declarations, which (transitively) ensures that all declarations in the
20780b57cec5SDimitry Andric     // chain get serialized.
20790b57cec5SDimitry Andric     //
20800b57cec5SDimitry Andric     // FIXME: This is not correct; when we reach an imported declaration we
20810b57cec5SDimitry Andric     // won't emit its previous declaration.
20820b57cec5SDimitry Andric     (void)Writer.GetDeclRef(D->getPreviousDecl());
20830b57cec5SDimitry Andric     (void)Writer.GetDeclRef(MostRecent);
20840b57cec5SDimitry Andric   } else {
20850b57cec5SDimitry Andric     // We use the sentinel value 0 to indicate an only declaration.
20860b57cec5SDimitry Andric     Record.push_back(0);
20870b57cec5SDimitry Andric   }
20880b57cec5SDimitry Andric }
20890b57cec5SDimitry Andric 
2090bdd1243dSDimitry Andric void ASTDeclWriter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
2091bdd1243dSDimitry Andric   VisitNamedDecl(D);
2092bdd1243dSDimitry Andric   VisitDeclContext(D);
2093bdd1243dSDimitry Andric   Record.push_back(D->isCBuffer());
2094bdd1243dSDimitry Andric   Record.AddSourceLocation(D->getLocStart());
2095bdd1243dSDimitry Andric   Record.AddSourceLocation(D->getLBraceLoc());
2096bdd1243dSDimitry Andric   Record.AddSourceLocation(D->getRBraceLoc());
2097bdd1243dSDimitry Andric 
2098bdd1243dSDimitry Andric   Code = serialization::DECL_HLSL_BUFFER;
2099bdd1243dSDimitry Andric }
2100bdd1243dSDimitry Andric 
21010b57cec5SDimitry Andric void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
2102e8d8bef9SDimitry Andric   Record.writeOMPChildren(D->Data);
21030b57cec5SDimitry Andric   VisitDecl(D);
21040b57cec5SDimitry Andric   Code = serialization::DECL_OMP_THREADPRIVATE;
21050b57cec5SDimitry Andric }
21060b57cec5SDimitry Andric 
21070b57cec5SDimitry Andric void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
2108e8d8bef9SDimitry Andric   Record.writeOMPChildren(D->Data);
21090b57cec5SDimitry Andric   VisitDecl(D);
21100b57cec5SDimitry Andric   Code = serialization::DECL_OMP_ALLOCATE;
21110b57cec5SDimitry Andric }
21120b57cec5SDimitry Andric 
21130b57cec5SDimitry Andric void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
2114e8d8bef9SDimitry Andric   Record.writeOMPChildren(D->Data);
21150b57cec5SDimitry Andric   VisitDecl(D);
21160b57cec5SDimitry Andric   Code = serialization::DECL_OMP_REQUIRES;
21170b57cec5SDimitry Andric }
21180b57cec5SDimitry Andric 
21190b57cec5SDimitry Andric void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
21205f757f3fSDimitry Andric   static_assert(DeclContext::NumOMPDeclareReductionDeclBits == 15,
212106c3fb27SDimitry Andric                 "You need to update the serializer after you change the "
212206c3fb27SDimitry Andric                 "NumOMPDeclareReductionDeclBits");
212306c3fb27SDimitry Andric 
21240b57cec5SDimitry Andric   VisitValueDecl(D);
21250b57cec5SDimitry Andric   Record.AddSourceLocation(D->getBeginLoc());
21260b57cec5SDimitry Andric   Record.AddStmt(D->getCombinerIn());
21270b57cec5SDimitry Andric   Record.AddStmt(D->getCombinerOut());
21280b57cec5SDimitry Andric   Record.AddStmt(D->getCombiner());
21290b57cec5SDimitry Andric   Record.AddStmt(D->getInitOrig());
21300b57cec5SDimitry Andric   Record.AddStmt(D->getInitPriv());
21310b57cec5SDimitry Andric   Record.AddStmt(D->getInitializer());
21325f757f3fSDimitry Andric   Record.push_back(llvm::to_underlying(D->getInitializerKind()));
21330b57cec5SDimitry Andric   Record.AddDeclRef(D->getPrevDeclInScope());
21340b57cec5SDimitry Andric   Code = serialization::DECL_OMP_DECLARE_REDUCTION;
21350b57cec5SDimitry Andric }
21360b57cec5SDimitry Andric 
21370b57cec5SDimitry Andric void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
2138e8d8bef9SDimitry Andric   Record.writeOMPChildren(D->Data);
21390b57cec5SDimitry Andric   VisitValueDecl(D);
21400b57cec5SDimitry Andric   Record.AddDeclarationName(D->getVarName());
21410b57cec5SDimitry Andric   Record.AddDeclRef(D->getPrevDeclInScope());
21420b57cec5SDimitry Andric   Code = serialization::DECL_OMP_DECLARE_MAPPER;
21430b57cec5SDimitry Andric }
21440b57cec5SDimitry Andric 
21450b57cec5SDimitry Andric void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
21460b57cec5SDimitry Andric   VisitVarDecl(D);
21470b57cec5SDimitry Andric   Code = serialization::DECL_OMP_CAPTUREDEXPR;
21480b57cec5SDimitry Andric }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21510b57cec5SDimitry Andric // ASTWriter Implementation
21520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
21530b57cec5SDimitry Andric 
2154cb14a3feSDimitry Andric namespace {
2155cb14a3feSDimitry Andric template <FunctionDecl::TemplatedKind Kind>
2156cb14a3feSDimitry Andric std::shared_ptr<llvm::BitCodeAbbrev>
2157cb14a3feSDimitry Andric getFunctionDeclAbbrev(serialization::DeclCode Code) {
2158cb14a3feSDimitry Andric   using namespace llvm;
2159cb14a3feSDimitry Andric 
2160cb14a3feSDimitry Andric   auto Abv = std::make_shared<BitCodeAbbrev>();
2161cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(Code));
2162cb14a3feSDimitry Andric   // RedeclarableDecl
2163cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
2164cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(Kind));
2165cb14a3feSDimitry Andric   if constexpr (Kind == FunctionDecl::TK_NonTemplate) {
2166cb14a3feSDimitry Andric 
2167cb14a3feSDimitry Andric   } else if constexpr (Kind == FunctionDecl::TK_FunctionTemplate) {
2168cb14a3feSDimitry Andric     // DescribedFunctionTemplate
2169cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2170cb14a3feSDimitry Andric   } else if constexpr (Kind == FunctionDecl::TK_DependentNonTemplate) {
2171cb14a3feSDimitry Andric     // Instantiated From Decl
2172cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2173cb14a3feSDimitry Andric   } else if constexpr (Kind == FunctionDecl::TK_MemberSpecialization) {
2174cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedFrom
2175cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2176cb14a3feSDimitry Andric                              3)); // TemplateSpecializationKind
2177cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Specialized Location
2178cb14a3feSDimitry Andric   } else if constexpr (Kind ==
2179cb14a3feSDimitry Andric                        FunctionDecl::TK_FunctionTemplateSpecialization) {
2180cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template
2181cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2182cb14a3feSDimitry Andric                              3)); // TemplateSpecializationKind
2183cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(1)); // Template Argument Size
2184cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(TemplateArgument::Type)); // Template Argument Kind
2185cb14a3feSDimitry Andric     Abv->Add(
2186cb14a3feSDimitry Andric         BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template Argument Type
2187cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is Defaulted
2188cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten
2189cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
2190cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(0));
2191cb14a3feSDimitry Andric     Abv->Add(
2192cb14a3feSDimitry Andric         BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Canonical Decl of template
2193cb14a3feSDimitry Andric   } else if constexpr (Kind == FunctionDecl::
2194cb14a3feSDimitry Andric                                    TK_DependentFunctionTemplateSpecialization) {
2195cb14a3feSDimitry Andric     // Candidates of specialization
2196cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2197cb14a3feSDimitry Andric     Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten
2198cb14a3feSDimitry Andric   } else {
2199cb14a3feSDimitry Andric     llvm_unreachable("Unknown templated kind?");
2200cb14a3feSDimitry Andric   }
2201cb14a3feSDimitry Andric   // Decl
2202cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2203cb14a3feSDimitry Andric                            8)); // Packed DeclBits: ModuleOwnershipKind,
2204cb14a3feSDimitry Andric                                 // isUsed, isReferenced,  AccessSpecifier,
2205cb14a3feSDimitry Andric                                 // isImplicit
2206cb14a3feSDimitry Andric                                 //
2207cb14a3feSDimitry Andric                                 // The following bits should be 0:
2208cb14a3feSDimitry Andric                                 // HasStandaloneLexicalDC, HasAttrs,
2209cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer,
2210cb14a3feSDimitry Andric                                 // isInvalidDecl
2211cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2212cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2213cb14a3feSDimitry Andric   // NamedDecl
2214cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
2215cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));     // Identifier
2216cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                           // AnonDeclNumber
2217cb14a3feSDimitry Andric   // ValueDecl
2218cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2219cb14a3feSDimitry Andric   // DeclaratorDecl
2220cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
2221cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // HasExtInfo
2222cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
2223cb14a3feSDimitry Andric   // FunctionDecl
2224cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
2225cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(
2226cb14a3feSDimitry Andric       BitCodeAbbrevOp::Fixed,
222756727255SDimitry Andric       28)); // Packed Function Bits: StorageClass, Inline, InlineSpecified,
2228cb14a3feSDimitry Andric             // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto,
2229cb14a3feSDimitry Andric             // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted,
2230cb14a3feSDimitry Andric             // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr,
2231cb14a3feSDimitry Andric             // UsesSEHTry, SkippedBody, MultiVersion, LateParsed,
223256727255SDimitry Andric             // FriendConstraintRefersToEnclosingTemplate, Linkage,
223356727255SDimitry Andric             // ShouldSkipCheckingODR
2234cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // LocEnd
2235cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
2236cb14a3feSDimitry Andric   // This Array slurps the rest of the record. Fortunately we want to encode
2237cb14a3feSDimitry Andric   // (nearly) all the remaining (variable number of) fields in the same way.
2238cb14a3feSDimitry Andric   //
2239cb14a3feSDimitry Andric   // This is:
2240cb14a3feSDimitry Andric   //         NumParams and Params[] from FunctionDecl, and
2241cb14a3feSDimitry Andric   //         NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
2242cb14a3feSDimitry Andric   //
2243cb14a3feSDimitry Andric   //  Add an AbbrevOp for 'size then elements' and use it here.
2244cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2245cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2246cb14a3feSDimitry Andric   return Abv;
2247cb14a3feSDimitry Andric }
2248cb14a3feSDimitry Andric 
2249cb14a3feSDimitry Andric template <FunctionDecl::TemplatedKind Kind>
2250cb14a3feSDimitry Andric std::shared_ptr<llvm::BitCodeAbbrev> getCXXMethodAbbrev() {
2251cb14a3feSDimitry Andric   return getFunctionDeclAbbrev<Kind>(serialization::DECL_CXX_METHOD);
2252cb14a3feSDimitry Andric }
2253cb14a3feSDimitry Andric } // namespace
2254cb14a3feSDimitry Andric 
22550b57cec5SDimitry Andric void ASTWriter::WriteDeclAbbrevs() {
22560b57cec5SDimitry Andric   using namespace llvm;
22570b57cec5SDimitry Andric 
22580b57cec5SDimitry Andric   std::shared_ptr<BitCodeAbbrev> Abv;
22590b57cec5SDimitry Andric 
22600b57cec5SDimitry Andric   // Abbreviation for DECL_FIELD
22610b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
22620b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
22630b57cec5SDimitry Andric   // Decl
22645f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2265cb14a3feSDimitry Andric                            7)); // Packed DeclBits: ModuleOwnershipKind,
2266cb14a3feSDimitry Andric                                 // isUsed, isReferenced,  AccessSpecifier,
2267cb14a3feSDimitry Andric                                 //
2268cb14a3feSDimitry Andric                                 // The following bits should be 0:
2269cb14a3feSDimitry Andric                                 // isImplicit, HasStandaloneLexicalDC, HasAttrs,
2270cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer,
2271cb14a3feSDimitry Andric                                 // isInvalidDecl
22720b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
22730b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
22740b57cec5SDimitry Andric   // NamedDecl
22750b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
22760b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
22770b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
22780b57cec5SDimitry Andric   // ValueDecl
22790b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
22800b57cec5SDimitry Andric   // DeclaratorDecl
22810b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
22820b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
22830b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
22840b57cec5SDimitry Andric   // FieldDecl
22850b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
228606c3fb27SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // StorageKind
22870b57cec5SDimitry Andric   // Type Source Info
22880b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
22890b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
22900b57cec5SDimitry Andric   DeclFieldAbbrev = Stream.EmitAbbrev(std::move(Abv));
22910b57cec5SDimitry Andric 
22920b57cec5SDimitry Andric   // Abbreviation for DECL_OBJC_IVAR
22930b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
22940b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
22950b57cec5SDimitry Andric   // Decl
22965f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
22975f757f3fSDimitry Andric                            12)); // Packed DeclBits: HasStandaloneLexicalDC,
22985f757f3fSDimitry Andric                                  // isInvalidDecl, HasAttrs, isImplicit, isUsed,
22995f757f3fSDimitry Andric                                  // isReferenced, TopLevelDeclInObjCContainer,
23005f757f3fSDimitry Andric                                  // AccessSpecifier, ModuleOwnershipKind
23010b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
23020b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
23030b57cec5SDimitry Andric   // NamedDecl
23040b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
23050b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
23060b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
23070b57cec5SDimitry Andric   // ValueDecl
23080b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
23090b57cec5SDimitry Andric   // DeclaratorDecl
23100b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
23110b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
23120b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
23130b57cec5SDimitry Andric   // FieldDecl
23140b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
23150b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
23160b57cec5SDimitry Andric   // ObjC Ivar
23170b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
23180b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
23190b57cec5SDimitry Andric   // Type Source Info
23200b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
23210b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
23220b57cec5SDimitry Andric   DeclObjCIvarAbbrev = Stream.EmitAbbrev(std::move(Abv));
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric   // Abbreviation for DECL_ENUM
23250b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
23260b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
23270b57cec5SDimitry Andric   // Redeclarable
23280b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
23290b57cec5SDimitry Andric   // Decl
23305f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2331cb14a3feSDimitry Andric                            7)); // Packed DeclBits: ModuleOwnershipKind,
2332cb14a3feSDimitry Andric                                 // isUsed, isReferenced,  AccessSpecifier,
2333cb14a3feSDimitry Andric                                 //
2334cb14a3feSDimitry Andric                                 // The following bits should be 0:
2335cb14a3feSDimitry Andric                                 // isImplicit, HasStandaloneLexicalDC, HasAttrs,
2336cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer,
2337cb14a3feSDimitry Andric                                 // isInvalidDecl
23380b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
23390b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
23400b57cec5SDimitry Andric   // NamedDecl
23410b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
23420b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
23430b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
23440b57cec5SDimitry Andric   // TypeDecl
23450b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
23460b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
23470b57cec5SDimitry Andric   // TagDecl
23480b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
23495f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(
23505f757f3fSDimitry Andric       BitCodeAbbrevOp::Fixed,
23515f757f3fSDimitry Andric       9)); // Packed Tag Decl Bits: getTagKind, isCompleteDefinition,
23525f757f3fSDimitry Andric            // EmbeddedInDeclarator, IsFreeStanding,
23535f757f3fSDimitry Andric            // isCompleteDefinitionRequired, ExtInfoKind
23540b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
23550b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
23560b57cec5SDimitry Andric   // EnumDecl
23570b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // AddTypeRef
23580b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IntegerType
23590b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getPromotionType
236056727255SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 20)); // Enum Decl Bits
23610b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
23620b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum
23630b57cec5SDimitry Andric   // DC
23640b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
23650b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
23660b57cec5SDimitry Andric   DeclEnumAbbrev = Stream.EmitAbbrev(std::move(Abv));
23670b57cec5SDimitry Andric 
23680b57cec5SDimitry Andric   // Abbreviation for DECL_RECORD
23690b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
23700b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
23710b57cec5SDimitry Andric   // Redeclarable
23720b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
23730b57cec5SDimitry Andric   // Decl
23745f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2375cb14a3feSDimitry Andric                            7)); // Packed DeclBits: ModuleOwnershipKind,
2376cb14a3feSDimitry Andric                                 // isUsed, isReferenced,  AccessSpecifier,
2377cb14a3feSDimitry Andric                                 //
2378cb14a3feSDimitry Andric                                 // The following bits should be 0:
2379cb14a3feSDimitry Andric                                 // isImplicit, HasStandaloneLexicalDC, HasAttrs,
2380cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer,
2381cb14a3feSDimitry Andric                                 // isInvalidDecl
23820b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
23830b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
23840b57cec5SDimitry Andric   // NamedDecl
23850b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
23860b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
23870b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
23880b57cec5SDimitry Andric   // TypeDecl
23890b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
23900b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
23910b57cec5SDimitry Andric   // TagDecl
23920b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
23935f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(
23945f757f3fSDimitry Andric       BitCodeAbbrevOp::Fixed,
23955f757f3fSDimitry Andric       9)); // Packed Tag Decl Bits: getTagKind, isCompleteDefinition,
23965f757f3fSDimitry Andric            // EmbeddedInDeclarator, IsFreeStanding,
23975f757f3fSDimitry Andric            // isCompleteDefinitionRequired, ExtInfoKind
23980b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
23990b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
24000b57cec5SDimitry Andric   // RecordDecl
24015f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(
24025f757f3fSDimitry Andric       BitCodeAbbrevOp::Fixed,
24035f757f3fSDimitry Andric       13)); // Packed Record Decl Bits: FlexibleArrayMember,
24045f757f3fSDimitry Andric             // AnonymousStructUnion, hasObjectMember, hasVolatileMember,
24055f757f3fSDimitry Andric             // isNonTrivialToPrimitiveDefaultInitialize,
24065f757f3fSDimitry Andric             // isNonTrivialToPrimitiveCopy, isNonTrivialToPrimitiveDestroy,
24075f757f3fSDimitry Andric             // hasNonTrivialToPrimitiveDefaultInitializeCUnion,
24085f757f3fSDimitry Andric             // hasNonTrivialToPrimitiveDestructCUnion,
24095f757f3fSDimitry Andric             // hasNonTrivialToPrimitiveCopyCUnion, isParamDestroyedInCallee,
24100b57cec5SDimitry Andric             // getArgPassingRestrictions
2411bdd1243dSDimitry Andric   // ODRHash
2412bdd1243dSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 26));
24130b57cec5SDimitry Andric 
24140b57cec5SDimitry Andric   // DC
24150b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
24160b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
24170b57cec5SDimitry Andric   DeclRecordAbbrev = Stream.EmitAbbrev(std::move(Abv));
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric   // Abbreviation for DECL_PARM_VAR
24200b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
24210b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
24220b57cec5SDimitry Andric   // Redeclarable
24230b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
24240b57cec5SDimitry Andric   // Decl
24255f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2426cb14a3feSDimitry Andric                            8)); // Packed DeclBits: ModuleOwnershipKind, isUsed,
2427cb14a3feSDimitry Andric                                 // isReferenced, AccessSpecifier,
2428cb14a3feSDimitry Andric                                 // HasStandaloneLexicalDC, HasAttrs, isImplicit,
2429cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer,
2430cb14a3feSDimitry Andric                                 // isInvalidDecl,
24310b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
24320b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
24330b57cec5SDimitry Andric   // NamedDecl
24340b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
24350b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
24360b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
24370b57cec5SDimitry Andric   // ValueDecl
24380b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
24390b57cec5SDimitry Andric   // DeclaratorDecl
24400b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
24410b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
24420b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
24430b57cec5SDimitry Andric   // VarDecl
24445f757f3fSDimitry Andric   Abv->Add(
24455f757f3fSDimitry Andric       BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
24465f757f3fSDimitry Andric                       12)); // Packed Var Decl bits: SClass, TSCSpec, InitStyle,
24475f757f3fSDimitry Andric                             // isARCPseudoStrong, Linkage, ModulesCodegen
244806c3fb27SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                          // VarKind (local enum)
24490b57cec5SDimitry Andric   // ParmVarDecl
2450647cbc5dSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
24515f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(
24525f757f3fSDimitry Andric       BitCodeAbbrevOp::Fixed,
2453647cbc5dSDimitry Andric       19)); // Packed Parm Var Decl bits: IsObjCMethodParameter, ScopeDepth,
2454647cbc5dSDimitry Andric             // ObjCDeclQualifier, KNRPromoted,
24555f757f3fSDimitry Andric             // HasInheritedDefaultArg, HasUninstantiatedDefaultArg
24560b57cec5SDimitry Andric   // Type Source Info
24570b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
24580b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
24590b57cec5SDimitry Andric   DeclParmVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric   // Abbreviation for DECL_TYPEDEF
24620b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
24630b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
24640b57cec5SDimitry Andric   // Redeclarable
24650b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
24660b57cec5SDimitry Andric   // Decl
24675f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2468cb14a3feSDimitry Andric                            7)); // Packed DeclBits: ModuleOwnershipKind,
2469cb14a3feSDimitry Andric                                 // isReferenced, isUsed, AccessSpecifier. Other
2470cb14a3feSDimitry Andric                                 // higher bits should be 0: isImplicit,
2471cb14a3feSDimitry Andric                                 // HasStandaloneLexicalDC, HasAttrs,
2472cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer, isInvalidDecl
24730b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
24740b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
24750b57cec5SDimitry Andric   // NamedDecl
24760b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
24770b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
24780b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
24790b57cec5SDimitry Andric   // TypeDecl
24800b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
24810b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
24820b57cec5SDimitry Andric   // TypedefDecl
24830b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
24840b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
24850b57cec5SDimitry Andric   DeclTypedefAbbrev = Stream.EmitAbbrev(std::move(Abv));
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric   // Abbreviation for DECL_VAR
24880b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
24890b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
24900b57cec5SDimitry Andric   // Redeclarable
24910b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
24920b57cec5SDimitry Andric   // Decl
24935f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
24945f757f3fSDimitry Andric                            12)); // Packed DeclBits: HasStandaloneLexicalDC,
24955f757f3fSDimitry Andric                                  // isInvalidDecl, HasAttrs, isImplicit, isUsed,
24965f757f3fSDimitry Andric                                  // isReferenced, TopLevelDeclInObjCContainer,
24975f757f3fSDimitry Andric                                  // AccessSpecifier, ModuleOwnershipKind
24980b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
24990b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
25000b57cec5SDimitry Andric   // NamedDecl
25010b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
25020b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
25030b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
25040b57cec5SDimitry Andric   // ValueDecl
25050b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
25060b57cec5SDimitry Andric   // DeclaratorDecl
25070b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
25080b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
25090b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
25100b57cec5SDimitry Andric   // VarDecl
25115f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(
25125f757f3fSDimitry Andric       BitCodeAbbrevOp::Fixed,
2513cb14a3feSDimitry Andric       21)); // Packed Var Decl bits:  Linkage, ModulesCodegen,
2514cb14a3feSDimitry Andric             // SClass, TSCSpec, InitStyle,
25155f757f3fSDimitry Andric             // isARCPseudoStrong, IsThisDeclarationADemotedDefinition,
25165f757f3fSDimitry Andric             // isExceptionVariable, isNRVOVariable, isCXXForRangeDecl,
2517cb14a3feSDimitry Andric             // isInline, isInlineSpecified, isConstexpr,
2518cb14a3feSDimitry Andric             // isInitCapture, isPrevDeclInSameScope,
2519cb14a3feSDimitry Andric             // EscapingByref, HasDeducedType, ImplicitParamKind, isObjCForDecl
252006c3fb27SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                         // VarKind (local enum)
25210b57cec5SDimitry Andric   // Type Source Info
25220b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
25230b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
25240b57cec5SDimitry Andric   DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
25250b57cec5SDimitry Andric 
25260b57cec5SDimitry Andric   // Abbreviation for DECL_CXX_METHOD
2527cb14a3feSDimitry Andric   DeclCXXMethodAbbrev =
2528cb14a3feSDimitry Andric       Stream.EmitAbbrev(getCXXMethodAbbrev<FunctionDecl::TK_NonTemplate>());
2529cb14a3feSDimitry Andric   DeclTemplateCXXMethodAbbrev = Stream.EmitAbbrev(
2530cb14a3feSDimitry Andric       getCXXMethodAbbrev<FunctionDecl::TK_FunctionTemplate>());
2531cb14a3feSDimitry Andric   DeclDependentNonTemplateCXXMethodAbbrev = Stream.EmitAbbrev(
2532cb14a3feSDimitry Andric       getCXXMethodAbbrev<FunctionDecl::TK_DependentNonTemplate>());
2533cb14a3feSDimitry Andric   DeclMemberSpecializedCXXMethodAbbrev = Stream.EmitAbbrev(
2534cb14a3feSDimitry Andric       getCXXMethodAbbrev<FunctionDecl::TK_MemberSpecialization>());
2535cb14a3feSDimitry Andric   DeclTemplateSpecializedCXXMethodAbbrev = Stream.EmitAbbrev(
2536cb14a3feSDimitry Andric       getCXXMethodAbbrev<FunctionDecl::TK_FunctionTemplateSpecialization>());
2537cb14a3feSDimitry Andric   DeclDependentSpecializationCXXMethodAbbrev = Stream.EmitAbbrev(
2538cb14a3feSDimitry Andric       getCXXMethodAbbrev<
2539cb14a3feSDimitry Andric           FunctionDecl::TK_DependentFunctionTemplateSpecialization>());
2540cb14a3feSDimitry Andric 
2541cb14a3feSDimitry Andric   // Abbreviation for DECL_TEMPLATE_TYPE_PARM
25420b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2543cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_TEMPLATE_TYPE_PARM));
2544cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0)); // hasTypeConstraint
2545cb14a3feSDimitry Andric   // Decl
2546cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
2547cb14a3feSDimitry Andric                            7)); // Packed DeclBits: ModuleOwnershipKind,
2548cb14a3feSDimitry Andric                                 // isReferenced, isUsed, AccessSpecifier. Other
2549cb14a3feSDimitry Andric                                 // higher bits should be 0: isImplicit,
2550cb14a3feSDimitry Andric                                 // HasStandaloneLexicalDC, HasAttrs,
2551cb14a3feSDimitry Andric                                 // TopLevelDeclInObjCContainer, isInvalidDecl
2552cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2553cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2554cb14a3feSDimitry Andric   // NamedDecl
2555cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
2556cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2557cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));
2558cb14a3feSDimitry Andric   // TypeDecl
2559cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2560cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
2561cb14a3feSDimitry Andric   // TemplateTypeParmDecl
2562cb14a3feSDimitry Andric   Abv->Add(
2563cb14a3feSDimitry Andric       BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename
2564*d686ce93SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                    // TypeConstraintInitialized
2565cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                    // OwnsDefaultArg
2566cb14a3feSDimitry Andric   DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv));
2567cb14a3feSDimitry Andric 
2568cb14a3feSDimitry Andric   // Abbreviation for DECL_USING_SHADOW
2569cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2570cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_USING_SHADOW));
2571cb14a3feSDimitry Andric   // Redeclarable
2572cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
25730b57cec5SDimitry Andric   // Decl
25745f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
25755f757f3fSDimitry Andric                            12)); // Packed DeclBits: HasStandaloneLexicalDC,
25765f757f3fSDimitry Andric                                  // isInvalidDecl, HasAttrs, isImplicit, isUsed,
25775f757f3fSDimitry Andric                                  // isReferenced, TopLevelDeclInObjCContainer,
25785f757f3fSDimitry Andric                                  // AccessSpecifier, ModuleOwnershipKind
25790b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
25800b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
25810b57cec5SDimitry Andric   // NamedDecl
2582cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
2583cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2584cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));
2585cb14a3feSDimitry Andric   // UsingShadowDecl
2586cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // TargetDecl
25870b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
2588cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // UsingOrNextShadow
2589cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR,
2590cb14a3feSDimitry Andric                            6)); // InstantiatedFromUsingShadowDecl
2591cb14a3feSDimitry Andric   DeclUsingShadowAbbrev = Stream.EmitAbbrev(std::move(Abv));
25920b57cec5SDimitry Andric 
25930b57cec5SDimitry Andric   // Abbreviation for EXPR_DECL_REF
25940b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
25950b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
25960b57cec5SDimitry Andric   // Stmt
25970b57cec5SDimitry Andric   //  Expr
2598cb14a3feSDimitry Andric   //  PackingBits: DependenceKind, ValueKind. ObjectKind should be 0.
2599cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7));
26000b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
26010b57cec5SDimitry Andric   // DeclRefExpr
2602cb14a3feSDimitry Andric   // Packing Bits: , HadMultipleCandidates, RefersToEnclosingVariableOrCapture,
2603cb14a3feSDimitry Andric   // IsImmediateEscalating, NonOdrUseReason.
2604cb14a3feSDimitry Andric   // GetDeclFound, HasQualifier and ExplicitTemplateArgs should be 0.
2605cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
26060b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
26070b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
26080b57cec5SDimitry Andric   DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
26090b57cec5SDimitry Andric 
26100b57cec5SDimitry Andric   // Abbreviation for EXPR_INTEGER_LITERAL
26110b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
26120b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
26130b57cec5SDimitry Andric   //Stmt
26140b57cec5SDimitry Andric   // Expr
26155f757f3fSDimitry Andric   // DependenceKind, ValueKind, ObjectKind
26165f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
2617cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
26180b57cec5SDimitry Andric   // Integer Literal
26190b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
26200b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(32));                      // Bit Width
26210b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
26220b57cec5SDimitry Andric   IntegerLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
26230b57cec5SDimitry Andric 
26240b57cec5SDimitry Andric   // Abbreviation for EXPR_CHARACTER_LITERAL
26250b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
26260b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
26270b57cec5SDimitry Andric   //Stmt
26280b57cec5SDimitry Andric   // Expr
26295f757f3fSDimitry Andric   // DependenceKind, ValueKind, ObjectKind
26305f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
2631cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
26320b57cec5SDimitry Andric   // Character Literal
26330b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
26340b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
26350b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
26360b57cec5SDimitry Andric   CharacterLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
26370b57cec5SDimitry Andric 
26380b57cec5SDimitry Andric   // Abbreviation for EXPR_IMPLICIT_CAST
26390b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
26400b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
26410b57cec5SDimitry Andric   // Stmt
26420b57cec5SDimitry Andric   // Expr
2643cb14a3feSDimitry Andric   // Packing Bits: DependenceKind, ValueKind, ObjectKind,
26445f757f3fSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
2645cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
26460b57cec5SDimitry Andric   // CastExpr
26470b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(0)); // PathSize
2648cb14a3feSDimitry Andric   // Packing Bits: CastKind, StoredFPFeatures, isPartOfExplicitCast
2649cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 9));
26500b57cec5SDimitry Andric   // ImplicitCastExpr
26510b57cec5SDimitry Andric   ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
26520b57cec5SDimitry Andric 
2653cb14a3feSDimitry Andric   // Abbreviation for EXPR_BINARY_OPERATOR
2654cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2655cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_BINARY_OPERATOR));
2656cb14a3feSDimitry Andric   // Stmt
2657cb14a3feSDimitry Andric   // Expr
2658cb14a3feSDimitry Andric   // Packing Bits: DependenceKind. ValueKind and ObjectKind should
2659cb14a3feSDimitry Andric   // be 0 in this case.
2660cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
2661cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2662cb14a3feSDimitry Andric   // BinaryOperator
2663cb14a3feSDimitry Andric   Abv->Add(
2664cb14a3feSDimitry Andric       BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpCode and HasFPFeatures
2665cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2666cb14a3feSDimitry Andric   BinaryOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv));
2667cb14a3feSDimitry Andric 
2668cb14a3feSDimitry Andric   // Abbreviation for EXPR_COMPOUND_ASSIGN_OPERATOR
2669cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2670cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_COMPOUND_ASSIGN_OPERATOR));
2671cb14a3feSDimitry Andric   // Stmt
2672cb14a3feSDimitry Andric   // Expr
2673cb14a3feSDimitry Andric   // Packing Bits: DependenceKind. ValueKind and ObjectKind should
2674cb14a3feSDimitry Andric   // be 0 in this case.
2675cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
2676cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2677cb14a3feSDimitry Andric   // BinaryOperator
2678cb14a3feSDimitry Andric   // Packing Bits: OpCode. The HasFPFeatures bit should be 0
2679cb14a3feSDimitry Andric   Abv->Add(
2680cb14a3feSDimitry Andric       BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpCode and HasFPFeatures
2681cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2682cb14a3feSDimitry Andric   // CompoundAssignOperator
2683cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHSType
2684cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Result Type
2685cb14a3feSDimitry Andric   CompoundAssignOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv));
2686cb14a3feSDimitry Andric 
2687cb14a3feSDimitry Andric   // Abbreviation for EXPR_CALL
2688cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2689cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CALL));
2690cb14a3feSDimitry Andric   // Stmt
2691cb14a3feSDimitry Andric   // Expr
2692cb14a3feSDimitry Andric   // Packing Bits: DependenceKind, ValueKind, ObjectKind,
2693cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
2694cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2695cb14a3feSDimitry Andric   // CallExpr
2696cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs
2697cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // ADLCallKind
2698cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2699cb14a3feSDimitry Andric   CallExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
2700cb14a3feSDimitry Andric 
2701cb14a3feSDimitry Andric   // Abbreviation for EXPR_CXX_OPERATOR_CALL
2702cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2703cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_OPERATOR_CALL));
2704cb14a3feSDimitry Andric   // Stmt
2705cb14a3feSDimitry Andric   // Expr
2706cb14a3feSDimitry Andric   // Packing Bits: DependenceKind, ValueKind, ObjectKind,
2707cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
2708cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2709cb14a3feSDimitry Andric   // CallExpr
2710cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs
2711cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // ADLCallKind
2712cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2713cb14a3feSDimitry Andric   // CXXOperatorCallExpr
2714cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Operator Kind
2715cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2716cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2717cb14a3feSDimitry Andric   CXXOperatorCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
2718cb14a3feSDimitry Andric 
2719cb14a3feSDimitry Andric   // Abbreviation for EXPR_CXX_MEMBER_CALL
2720cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2721cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_MEMBER_CALL));
2722cb14a3feSDimitry Andric   // Stmt
2723cb14a3feSDimitry Andric   // Expr
2724cb14a3feSDimitry Andric   // Packing Bits: DependenceKind, ValueKind, ObjectKind,
2725cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10));
2726cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2727cb14a3feSDimitry Andric   // CallExpr
2728cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // NumArgs
2729cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // ADLCallKind
2730cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2731cb14a3feSDimitry Andric   // CXXMemberCallExpr
2732cb14a3feSDimitry Andric   CXXMemberCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
2733cb14a3feSDimitry Andric 
2734cb14a3feSDimitry Andric   // Abbreviation for STMT_COMPOUND
2735cb14a3feSDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
2736cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::STMT_COMPOUND));
2737cb14a3feSDimitry Andric   // Stmt
2738cb14a3feSDimitry Andric   // CompoundStmt
2739cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Num Stmts
2740cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(0));                       // hasStoredFPFeatures
2741cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2742cb14a3feSDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2743cb14a3feSDimitry Andric   CompoundStmtAbbrev = Stream.EmitAbbrev(std::move(Abv));
2744cb14a3feSDimitry Andric 
27450b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
27460b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
27470b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
27480b57cec5SDimitry Andric   DeclContextLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
27490b57cec5SDimitry Andric 
27500b57cec5SDimitry Andric   Abv = std::make_shared<BitCodeAbbrev>();
27510b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
27520b57cec5SDimitry Andric   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
27530b57cec5SDimitry Andric   DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
27540b57cec5SDimitry Andric }
27550b57cec5SDimitry Andric 
27560b57cec5SDimitry Andric /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
27570b57cec5SDimitry Andric /// consumers of the AST.
27580b57cec5SDimitry Andric ///
27590b57cec5SDimitry Andric /// Such decls will always be deserialized from the AST file, so we would like
27600b57cec5SDimitry Andric /// this to be as restrictive as possible. Currently the predicate is driven by
27610b57cec5SDimitry Andric /// code generation requirements, if other clients have a different notion of
27620b57cec5SDimitry Andric /// what is "required" then we may have to consider an alternate scheme where
27630b57cec5SDimitry Andric /// clients can iterate over the top-level decls and get information on them,
27640b57cec5SDimitry Andric /// without necessary deserializing them. We could explicitly require such
27650b57cec5SDimitry Andric /// clients to use a separate API call to "realize" the decl. This should be
27660b57cec5SDimitry Andric /// relatively painless since they would presumably only do it for top-level
27670b57cec5SDimitry Andric /// decls.
27680b57cec5SDimitry Andric static bool isRequiredDecl(const Decl *D, ASTContext &Context,
276906c3fb27SDimitry Andric                            Module *WritingModule) {
277006c3fb27SDimitry Andric   // Named modules have different semantics than header modules. Every named
277106c3fb27SDimitry Andric   // module units owns a translation unit. So the importer of named modules
277206c3fb27SDimitry Andric   // doesn't need to deserilize everything ahead of time.
27735f757f3fSDimitry Andric   if (WritingModule && WritingModule->isNamedModule()) {
277406c3fb27SDimitry Andric     // The PragmaCommentDecl and PragmaDetectMismatchDecl are MSVC's extension.
277506c3fb27SDimitry Andric     // And the behavior of MSVC for such cases will leak this to the module
277606c3fb27SDimitry Andric     // users. Given pragma is not a standard thing, the compiler has the space
277706c3fb27SDimitry Andric     // to do their own decision. Let's follow MSVC here.
277806c3fb27SDimitry Andric     if (isa<PragmaCommentDecl, PragmaDetectMismatchDecl>(D))
277906c3fb27SDimitry Andric       return true;
278006c3fb27SDimitry Andric     return false;
278106c3fb27SDimitry Andric   }
278206c3fb27SDimitry Andric 
27830b57cec5SDimitry Andric   // An ObjCMethodDecl is never considered as "required" because its
27840b57cec5SDimitry Andric   // implementation container always is.
27850b57cec5SDimitry Andric 
27860b57cec5SDimitry Andric   // File scoped assembly or obj-c or OMP declare target implementation must be
27870b57cec5SDimitry Andric   // seen.
2788bdd1243dSDimitry Andric   if (isa<FileScopeAsmDecl, TopLevelStmtDecl, ObjCImplDecl>(D))
27890b57cec5SDimitry Andric     return true;
27900b57cec5SDimitry Andric 
27910b57cec5SDimitry Andric   if (WritingModule && isPartOfPerModuleInitializer(D)) {
27920b57cec5SDimitry Andric     // These declarations are part of the module initializer, and are emitted
27930b57cec5SDimitry Andric     // if and when the module is imported, rather than being emitted eagerly.
27940b57cec5SDimitry Andric     return false;
27950b57cec5SDimitry Andric   }
27960b57cec5SDimitry Andric 
27970b57cec5SDimitry Andric   return Context.DeclMustBeEmitted(D);
27980b57cec5SDimitry Andric }
27990b57cec5SDimitry Andric 
28000b57cec5SDimitry Andric void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
28010b57cec5SDimitry Andric   PrettyDeclStackTraceEntry CrashInfo(Context, D, SourceLocation(),
28020b57cec5SDimitry Andric                                       "serializing");
28030b57cec5SDimitry Andric 
28040b57cec5SDimitry Andric   // Determine the ID for this declaration.
28050fca6ea1SDimitry Andric   LocalDeclID ID;
28060b57cec5SDimitry Andric   assert(!D->isFromASTFile() && "should not be emitting imported decl");
28070fca6ea1SDimitry Andric   LocalDeclID &IDR = DeclIDs[D];
28080fca6ea1SDimitry Andric   if (IDR.isInvalid())
28090b57cec5SDimitry Andric     IDR = NextDeclID++;
28100b57cec5SDimitry Andric 
28110b57cec5SDimitry Andric   ID = IDR;
28120b57cec5SDimitry Andric 
28130b57cec5SDimitry Andric   assert(ID >= FirstDeclID && "invalid decl ID");
28140b57cec5SDimitry Andric 
28150b57cec5SDimitry Andric   RecordData Record;
28160fca6ea1SDimitry Andric   ASTDeclWriter W(*this, Context, Record, GeneratingReducedBMI);
28170b57cec5SDimitry Andric 
28180b57cec5SDimitry Andric   // Build a record for this declaration
28190b57cec5SDimitry Andric   W.Visit(D);
28200b57cec5SDimitry Andric 
28210b57cec5SDimitry Andric   // Emit this declaration to the bitstream.
28220b57cec5SDimitry Andric   uint64_t Offset = W.Emit(D);
28230b57cec5SDimitry Andric 
28240b57cec5SDimitry Andric   // Record the offset for this declaration
28250b57cec5SDimitry Andric   SourceLocation Loc = D->getLocation();
28260fca6ea1SDimitry Andric   SourceLocationEncoding::RawLocEncoding RawLoc =
28270fca6ea1SDimitry Andric       getRawSourceLocationEncoding(getAdjustedLocation(Loc));
28280fca6ea1SDimitry Andric 
28290fca6ea1SDimitry Andric   unsigned Index = ID.getRawValue() - FirstDeclID.getRawValue();
28300b57cec5SDimitry Andric   if (DeclOffsets.size() == Index)
28310fca6ea1SDimitry Andric     DeclOffsets.emplace_back(RawLoc, Offset, DeclTypesBlockStartOffset);
28320b57cec5SDimitry Andric   else if (DeclOffsets.size() < Index) {
28330b57cec5SDimitry Andric     // FIXME: Can/should this happen?
28340b57cec5SDimitry Andric     DeclOffsets.resize(Index+1);
28350fca6ea1SDimitry Andric     DeclOffsets[Index].setRawLoc(RawLoc);
28365ffd83dbSDimitry Andric     DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset);
28370b57cec5SDimitry Andric   } else {
28380b57cec5SDimitry Andric     llvm_unreachable("declarations should be emitted in ID order");
28390b57cec5SDimitry Andric   }
28400b57cec5SDimitry Andric 
28410b57cec5SDimitry Andric   SourceManager &SM = Context.getSourceManager();
28420b57cec5SDimitry Andric   if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
28430b57cec5SDimitry Andric     associateDeclWithFile(D, ID);
28440b57cec5SDimitry Andric 
28450b57cec5SDimitry Andric   // Note declarations that should be deserialized eagerly so that we can add
28460b57cec5SDimitry Andric   // them to a record in the AST file later.
28470b57cec5SDimitry Andric   if (isRequiredDecl(D, Context, WritingModule))
28480fca6ea1SDimitry Andric     AddDeclRef(D, EagerlyDeserializedDecls);
28490b57cec5SDimitry Andric }
28500b57cec5SDimitry Andric 
28510b57cec5SDimitry Andric void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
28520b57cec5SDimitry Andric   // Switch case IDs are per function body.
28530b57cec5SDimitry Andric   Writer->ClearSwitchCaseIDs();
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric   assert(FD->doesThisDeclarationHaveABody());
28560b57cec5SDimitry Andric   bool ModulesCodegen = false;
28575ffd83dbSDimitry Andric   if (!FD->isDependentContext()) {
2858bdd1243dSDimitry Andric     std::optional<GVALinkage> Linkage;
28595ffd83dbSDimitry Andric     if (Writer->WritingModule &&
286081ad6265SDimitry Andric         Writer->WritingModule->isInterfaceOrPartition()) {
286181ad6265SDimitry Andric       // When building a C++20 module interface unit or a partition unit, a
286281ad6265SDimitry Andric       // strong definition in the module interface is provided by the
286381ad6265SDimitry Andric       // compilation of that unit, not by its users. (Inline functions are still
286481ad6265SDimitry Andric       // emitted in module users.)
28650b57cec5SDimitry Andric       Linkage = Writer->Context->GetGVALinkageForFunction(FD);
286606c3fb27SDimitry Andric       ModulesCodegen = *Linkage >= GVA_StrongExternal;
28670b57cec5SDimitry Andric     }
2868e8d8bef9SDimitry Andric     if (Writer->Context->getLangOpts().ModulesCodegen ||
2869e8d8bef9SDimitry Andric         (FD->hasAttr<DLLExportAttr>() &&
2870e8d8bef9SDimitry Andric          Writer->Context->getLangOpts().BuildingPCHWithObjectFile)) {
2871e8d8bef9SDimitry Andric 
28720b57cec5SDimitry Andric       // Under -fmodules-codegen, codegen is performed for all non-internal,
2873480093f4SDimitry Andric       // non-always_inline functions, unless they are available elsewhere.
28740b57cec5SDimitry Andric       if (!FD->hasAttr<AlwaysInlineAttr>()) {
28750b57cec5SDimitry Andric         if (!Linkage)
28760b57cec5SDimitry Andric           Linkage = Writer->Context->GetGVALinkageForFunction(FD);
2877480093f4SDimitry Andric         ModulesCodegen =
2878480093f4SDimitry Andric             *Linkage != GVA_Internal && *Linkage != GVA_AvailableExternally;
28790b57cec5SDimitry Andric       }
28800b57cec5SDimitry Andric     }
28810b57cec5SDimitry Andric   }
28820b57cec5SDimitry Andric   Record->push_back(ModulesCodegen);
28830b57cec5SDimitry Andric   if (ModulesCodegen)
28840fca6ea1SDimitry Andric     Writer->AddDeclRef(FD, Writer->ModularCodegenDecls);
28850b57cec5SDimitry Andric   if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
28860b57cec5SDimitry Andric     Record->push_back(CD->getNumCtorInitializers());
28870b57cec5SDimitry Andric     if (CD->getNumCtorInitializers())
2888bdd1243dSDimitry Andric       AddCXXCtorInitializers(llvm::ArrayRef(CD->init_begin(), CD->init_end()));
28890b57cec5SDimitry Andric   }
28900b57cec5SDimitry Andric   AddStmt(FD->getBody());
28910b57cec5SDimitry Andric }
2892