106f32e7eSjoerg //===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg //  This file implements serialization for Declarations.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #include "ASTCommon.h"
14*13fbcb42Sjoerg #include "clang/AST/Attr.h"
1506f32e7eSjoerg #include "clang/AST/DeclCXX.h"
1606f32e7eSjoerg #include "clang/AST/DeclTemplate.h"
1706f32e7eSjoerg #include "clang/AST/DeclVisitor.h"
1806f32e7eSjoerg #include "clang/AST/Expr.h"
1906f32e7eSjoerg #include "clang/AST/OpenMPClause.h"
2006f32e7eSjoerg #include "clang/AST/PrettyDeclStackTrace.h"
2106f32e7eSjoerg #include "clang/Basic/SourceManager.h"
2206f32e7eSjoerg #include "clang/Serialization/ASTReader.h"
23*13fbcb42Sjoerg #include "clang/Serialization/ASTRecordWriter.h"
2406f32e7eSjoerg #include "llvm/Bitstream/BitstreamWriter.h"
2506f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
2606f32e7eSjoerg using namespace clang;
2706f32e7eSjoerg using namespace serialization;
2806f32e7eSjoerg 
2906f32e7eSjoerg //===----------------------------------------------------------------------===//
3006f32e7eSjoerg // Declaration serialization
3106f32e7eSjoerg //===----------------------------------------------------------------------===//
3206f32e7eSjoerg 
3306f32e7eSjoerg namespace clang {
3406f32e7eSjoerg   class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
3506f32e7eSjoerg     ASTWriter &Writer;
3606f32e7eSjoerg     ASTContext &Context;
3706f32e7eSjoerg     ASTRecordWriter Record;
3806f32e7eSjoerg 
3906f32e7eSjoerg     serialization::DeclCode Code;
4006f32e7eSjoerg     unsigned AbbrevToUse;
4106f32e7eSjoerg 
4206f32e7eSjoerg   public:
ASTDeclWriter(ASTWriter & Writer,ASTContext & Context,ASTWriter::RecordDataImpl & Record)4306f32e7eSjoerg     ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
4406f32e7eSjoerg                   ASTWriter::RecordDataImpl &Record)
4506f32e7eSjoerg         : Writer(Writer), Context(Context), Record(Writer, Record),
4606f32e7eSjoerg           Code((serialization::DeclCode)0), AbbrevToUse(0) {}
4706f32e7eSjoerg 
Emit(Decl * D)4806f32e7eSjoerg     uint64_t Emit(Decl *D) {
4906f32e7eSjoerg       if (!Code)
5006f32e7eSjoerg         llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
5106f32e7eSjoerg             D->getDeclKindName() + "'");
5206f32e7eSjoerg       return Record.Emit(Code, AbbrevToUse);
5306f32e7eSjoerg     }
5406f32e7eSjoerg 
5506f32e7eSjoerg     void Visit(Decl *D);
5606f32e7eSjoerg 
5706f32e7eSjoerg     void VisitDecl(Decl *D);
5806f32e7eSjoerg     void VisitPragmaCommentDecl(PragmaCommentDecl *D);
5906f32e7eSjoerg     void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D);
6006f32e7eSjoerg     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
6106f32e7eSjoerg     void VisitNamedDecl(NamedDecl *D);
6206f32e7eSjoerg     void VisitLabelDecl(LabelDecl *LD);
6306f32e7eSjoerg     void VisitNamespaceDecl(NamespaceDecl *D);
6406f32e7eSjoerg     void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
6506f32e7eSjoerg     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
6606f32e7eSjoerg     void VisitTypeDecl(TypeDecl *D);
6706f32e7eSjoerg     void VisitTypedefNameDecl(TypedefNameDecl *D);
6806f32e7eSjoerg     void VisitTypedefDecl(TypedefDecl *D);
6906f32e7eSjoerg     void VisitTypeAliasDecl(TypeAliasDecl *D);
7006f32e7eSjoerg     void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
7106f32e7eSjoerg     void VisitTagDecl(TagDecl *D);
7206f32e7eSjoerg     void VisitEnumDecl(EnumDecl *D);
7306f32e7eSjoerg     void VisitRecordDecl(RecordDecl *D);
7406f32e7eSjoerg     void VisitCXXRecordDecl(CXXRecordDecl *D);
7506f32e7eSjoerg     void VisitClassTemplateSpecializationDecl(
7606f32e7eSjoerg                                             ClassTemplateSpecializationDecl *D);
7706f32e7eSjoerg     void VisitClassTemplatePartialSpecializationDecl(
7806f32e7eSjoerg                                      ClassTemplatePartialSpecializationDecl *D);
7906f32e7eSjoerg     void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
8006f32e7eSjoerg     void VisitVarTemplatePartialSpecializationDecl(
8106f32e7eSjoerg         VarTemplatePartialSpecializationDecl *D);
8206f32e7eSjoerg     void VisitClassScopeFunctionSpecializationDecl(
8306f32e7eSjoerg                                        ClassScopeFunctionSpecializationDecl *D);
8406f32e7eSjoerg     void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
8506f32e7eSjoerg     void VisitValueDecl(ValueDecl *D);
8606f32e7eSjoerg     void VisitEnumConstantDecl(EnumConstantDecl *D);
8706f32e7eSjoerg     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
8806f32e7eSjoerg     void VisitDeclaratorDecl(DeclaratorDecl *D);
8906f32e7eSjoerg     void VisitFunctionDecl(FunctionDecl *D);
9006f32e7eSjoerg     void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D);
9106f32e7eSjoerg     void VisitCXXMethodDecl(CXXMethodDecl *D);
9206f32e7eSjoerg     void VisitCXXConstructorDecl(CXXConstructorDecl *D);
9306f32e7eSjoerg     void VisitCXXDestructorDecl(CXXDestructorDecl *D);
9406f32e7eSjoerg     void VisitCXXConversionDecl(CXXConversionDecl *D);
9506f32e7eSjoerg     void VisitFieldDecl(FieldDecl *D);
9606f32e7eSjoerg     void VisitMSPropertyDecl(MSPropertyDecl *D);
97*13fbcb42Sjoerg     void VisitMSGuidDecl(MSGuidDecl *D);
98*13fbcb42Sjoerg     void VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D);
9906f32e7eSjoerg     void VisitIndirectFieldDecl(IndirectFieldDecl *D);
10006f32e7eSjoerg     void VisitVarDecl(VarDecl *D);
10106f32e7eSjoerg     void VisitImplicitParamDecl(ImplicitParamDecl *D);
10206f32e7eSjoerg     void VisitParmVarDecl(ParmVarDecl *D);
10306f32e7eSjoerg     void VisitDecompositionDecl(DecompositionDecl *D);
10406f32e7eSjoerg     void VisitBindingDecl(BindingDecl *D);
10506f32e7eSjoerg     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
10606f32e7eSjoerg     void VisitTemplateDecl(TemplateDecl *D);
10706f32e7eSjoerg     void VisitConceptDecl(ConceptDecl *D);
108*13fbcb42Sjoerg     void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
10906f32e7eSjoerg     void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
11006f32e7eSjoerg     void VisitClassTemplateDecl(ClassTemplateDecl *D);
11106f32e7eSjoerg     void VisitVarTemplateDecl(VarTemplateDecl *D);
11206f32e7eSjoerg     void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
11306f32e7eSjoerg     void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
11406f32e7eSjoerg     void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
11506f32e7eSjoerg     void VisitUsingDecl(UsingDecl *D);
11606f32e7eSjoerg     void VisitUsingPackDecl(UsingPackDecl *D);
11706f32e7eSjoerg     void VisitUsingShadowDecl(UsingShadowDecl *D);
11806f32e7eSjoerg     void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
11906f32e7eSjoerg     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
12006f32e7eSjoerg     void VisitExportDecl(ExportDecl *D);
12106f32e7eSjoerg     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
12206f32e7eSjoerg     void VisitImportDecl(ImportDecl *D);
12306f32e7eSjoerg     void VisitAccessSpecDecl(AccessSpecDecl *D);
12406f32e7eSjoerg     void VisitFriendDecl(FriendDecl *D);
12506f32e7eSjoerg     void VisitFriendTemplateDecl(FriendTemplateDecl *D);
12606f32e7eSjoerg     void VisitStaticAssertDecl(StaticAssertDecl *D);
12706f32e7eSjoerg     void VisitBlockDecl(BlockDecl *D);
12806f32e7eSjoerg     void VisitCapturedDecl(CapturedDecl *D);
12906f32e7eSjoerg     void VisitEmptyDecl(EmptyDecl *D);
130*13fbcb42Sjoerg     void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
13106f32e7eSjoerg 
13206f32e7eSjoerg     void VisitDeclContext(DeclContext *DC);
13306f32e7eSjoerg     template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
13406f32e7eSjoerg 
13506f32e7eSjoerg 
13606f32e7eSjoerg     // FIXME: Put in the same order is DeclNodes.td?
13706f32e7eSjoerg     void VisitObjCMethodDecl(ObjCMethodDecl *D);
13806f32e7eSjoerg     void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
13906f32e7eSjoerg     void VisitObjCContainerDecl(ObjCContainerDecl *D);
14006f32e7eSjoerg     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
14106f32e7eSjoerg     void VisitObjCIvarDecl(ObjCIvarDecl *D);
14206f32e7eSjoerg     void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
14306f32e7eSjoerg     void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
14406f32e7eSjoerg     void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
14506f32e7eSjoerg     void VisitObjCImplDecl(ObjCImplDecl *D);
14606f32e7eSjoerg     void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
14706f32e7eSjoerg     void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
14806f32e7eSjoerg     void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
14906f32e7eSjoerg     void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
15006f32e7eSjoerg     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
15106f32e7eSjoerg     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
15206f32e7eSjoerg     void VisitOMPAllocateDecl(OMPAllocateDecl *D);
15306f32e7eSjoerg     void VisitOMPRequiresDecl(OMPRequiresDecl *D);
15406f32e7eSjoerg     void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
15506f32e7eSjoerg     void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
15606f32e7eSjoerg     void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
15706f32e7eSjoerg 
15806f32e7eSjoerg     /// Add an Objective-C type parameter list to the given record.
AddObjCTypeParamList(ObjCTypeParamList * typeParams)15906f32e7eSjoerg     void AddObjCTypeParamList(ObjCTypeParamList *typeParams) {
16006f32e7eSjoerg       // Empty type parameter list.
16106f32e7eSjoerg       if (!typeParams) {
16206f32e7eSjoerg         Record.push_back(0);
16306f32e7eSjoerg         return;
16406f32e7eSjoerg       }
16506f32e7eSjoerg 
16606f32e7eSjoerg       Record.push_back(typeParams->size());
16706f32e7eSjoerg       for (auto typeParam : *typeParams) {
16806f32e7eSjoerg         Record.AddDeclRef(typeParam);
16906f32e7eSjoerg       }
17006f32e7eSjoerg       Record.AddSourceLocation(typeParams->getLAngleLoc());
17106f32e7eSjoerg       Record.AddSourceLocation(typeParams->getRAngleLoc());
17206f32e7eSjoerg     }
17306f32e7eSjoerg 
17406f32e7eSjoerg     /// Add to the record the first declaration from each module file that
17506f32e7eSjoerg     /// provides a declaration of D. The intent is to provide a sufficient
17606f32e7eSjoerg     /// set such that reloading this set will load all current redeclarations.
AddFirstDeclFromEachModule(const Decl * D,bool IncludeLocal)17706f32e7eSjoerg     void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
17806f32e7eSjoerg       llvm::MapVector<ModuleFile*, const Decl*> Firsts;
17906f32e7eSjoerg       // FIXME: We can skip entries that we know are implied by others.
18006f32e7eSjoerg       for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
18106f32e7eSjoerg         if (R->isFromASTFile())
18206f32e7eSjoerg           Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
18306f32e7eSjoerg         else if (IncludeLocal)
18406f32e7eSjoerg           Firsts[nullptr] = R;
18506f32e7eSjoerg       }
18606f32e7eSjoerg       for (const auto &F : Firsts)
18706f32e7eSjoerg         Record.AddDeclRef(F.second);
18806f32e7eSjoerg     }
18906f32e7eSjoerg 
19006f32e7eSjoerg     /// Get the specialization decl from an entry in the specialization list.
19106f32e7eSjoerg     template <typename EntryType>
19206f32e7eSjoerg     typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
getSpecializationDecl(EntryType & T)19306f32e7eSjoerg     getSpecializationDecl(EntryType &T) {
19406f32e7eSjoerg       return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T);
19506f32e7eSjoerg     }
19606f32e7eSjoerg 
19706f32e7eSjoerg     /// Get the list of partial specializations from a template's common ptr.
19806f32e7eSjoerg     template<typename T>
getPartialSpecializations(T * Common)19906f32e7eSjoerg     decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
20006f32e7eSjoerg       return Common->PartialSpecializations;
20106f32e7eSjoerg     }
getPartialSpecializations(FunctionTemplateDecl::Common *)20206f32e7eSjoerg     ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) {
20306f32e7eSjoerg       return None;
20406f32e7eSjoerg     }
20506f32e7eSjoerg 
20606f32e7eSjoerg     template<typename DeclTy>
AddTemplateSpecializations(DeclTy * D)20706f32e7eSjoerg     void AddTemplateSpecializations(DeclTy *D) {
20806f32e7eSjoerg       auto *Common = D->getCommonPtr();
20906f32e7eSjoerg 
21006f32e7eSjoerg       // If we have any lazy specializations, and the external AST source is
21106f32e7eSjoerg       // our chained AST reader, we can just write out the DeclIDs. Otherwise,
21206f32e7eSjoerg       // we need to resolve them to actual declarations.
21306f32e7eSjoerg       if (Writer.Chain != Writer.Context->getExternalSource() &&
21406f32e7eSjoerg           Common->LazySpecializations) {
21506f32e7eSjoerg         D->LoadLazySpecializations();
21606f32e7eSjoerg         assert(!Common->LazySpecializations);
21706f32e7eSjoerg       }
21806f32e7eSjoerg 
21906f32e7eSjoerg       ArrayRef<DeclID> LazySpecializations;
22006f32e7eSjoerg       if (auto *LS = Common->LazySpecializations)
22106f32e7eSjoerg         LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]);
22206f32e7eSjoerg 
22306f32e7eSjoerg       // Add a slot to the record for the number of specializations.
22406f32e7eSjoerg       unsigned I = Record.size();
22506f32e7eSjoerg       Record.push_back(0);
22606f32e7eSjoerg 
22706f32e7eSjoerg       // AddFirstDeclFromEachModule might trigger deserialization, invalidating
22806f32e7eSjoerg       // *Specializations iterators.
22906f32e7eSjoerg       llvm::SmallVector<const Decl*, 16> Specs;
23006f32e7eSjoerg       for (auto &Entry : Common->Specializations)
23106f32e7eSjoerg         Specs.push_back(getSpecializationDecl(Entry));
23206f32e7eSjoerg       for (auto &Entry : getPartialSpecializations(Common))
23306f32e7eSjoerg         Specs.push_back(getSpecializationDecl(Entry));
23406f32e7eSjoerg 
23506f32e7eSjoerg       for (auto *D : Specs) {
23606f32e7eSjoerg         assert(D->isCanonicalDecl() && "non-canonical decl in set");
23706f32e7eSjoerg         AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
23806f32e7eSjoerg       }
23906f32e7eSjoerg       Record.append(LazySpecializations.begin(), LazySpecializations.end());
24006f32e7eSjoerg 
24106f32e7eSjoerg       // Update the size entry we added earlier.
24206f32e7eSjoerg       Record[I] = Record.size() - I - 1;
24306f32e7eSjoerg     }
24406f32e7eSjoerg 
24506f32e7eSjoerg     /// Ensure that this template specialization is associated with the specified
24606f32e7eSjoerg     /// template on reload.
RegisterTemplateSpecialization(const Decl * Template,const Decl * Specialization)24706f32e7eSjoerg     void RegisterTemplateSpecialization(const Decl *Template,
24806f32e7eSjoerg                                         const Decl *Specialization) {
24906f32e7eSjoerg       Template = Template->getCanonicalDecl();
25006f32e7eSjoerg 
25106f32e7eSjoerg       // If the canonical template is local, we'll write out this specialization
25206f32e7eSjoerg       // when we emit it.
25306f32e7eSjoerg       // FIXME: We can do the same thing if there is any local declaration of
25406f32e7eSjoerg       // the template, to avoid emitting an update record.
25506f32e7eSjoerg       if (!Template->isFromASTFile())
25606f32e7eSjoerg         return;
25706f32e7eSjoerg 
25806f32e7eSjoerg       // We only need to associate the first local declaration of the
25906f32e7eSjoerg       // specialization. The other declarations will get pulled in by it.
26006f32e7eSjoerg       if (Writer.getFirstLocalDecl(Specialization) != Specialization)
26106f32e7eSjoerg         return;
26206f32e7eSjoerg 
26306f32e7eSjoerg       Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate(
26406f32e7eSjoerg           UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization));
26506f32e7eSjoerg     }
26606f32e7eSjoerg   };
26706f32e7eSjoerg }
26806f32e7eSjoerg 
Visit(Decl * D)26906f32e7eSjoerg void ASTDeclWriter::Visit(Decl *D) {
27006f32e7eSjoerg   DeclVisitor<ASTDeclWriter>::Visit(D);
27106f32e7eSjoerg 
27206f32e7eSjoerg   // Source locations require array (variable-length) abbreviations.  The
27306f32e7eSjoerg   // abbreviation infrastructure requires that arrays are encoded last, so
27406f32e7eSjoerg   // we handle it here in the case of those classes derived from DeclaratorDecl
27506f32e7eSjoerg   if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
27606f32e7eSjoerg     if (auto *TInfo = DD->getTypeSourceInfo())
27706f32e7eSjoerg       Record.AddTypeLoc(TInfo->getTypeLoc());
27806f32e7eSjoerg   }
27906f32e7eSjoerg 
28006f32e7eSjoerg   // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
28106f32e7eSjoerg   // have been written. We want it last because we will not read it back when
28206f32e7eSjoerg   // retrieving it from the AST, we'll just lazily set the offset.
28306f32e7eSjoerg   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
28406f32e7eSjoerg     Record.push_back(FD->doesThisDeclarationHaveABody());
28506f32e7eSjoerg     if (FD->doesThisDeclarationHaveABody())
28606f32e7eSjoerg       Record.AddFunctionDefinition(FD);
28706f32e7eSjoerg   }
28806f32e7eSjoerg 
28906f32e7eSjoerg   // If this declaration is also a DeclContext, write blocks for the
29006f32e7eSjoerg   // declarations that lexically stored inside its context and those
29106f32e7eSjoerg   // declarations that are visible from its context.
29206f32e7eSjoerg   if (DeclContext *DC = dyn_cast<DeclContext>(D))
29306f32e7eSjoerg     VisitDeclContext(DC);
29406f32e7eSjoerg }
29506f32e7eSjoerg 
VisitDecl(Decl * D)29606f32e7eSjoerg void ASTDeclWriter::VisitDecl(Decl *D) {
29706f32e7eSjoerg   Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
29806f32e7eSjoerg   if (D->getDeclContext() != D->getLexicalDeclContext())
29906f32e7eSjoerg     Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
30006f32e7eSjoerg   else
30106f32e7eSjoerg     Record.push_back(0);
30206f32e7eSjoerg   Record.push_back(D->isInvalidDecl());
30306f32e7eSjoerg   Record.push_back(D->hasAttrs());
30406f32e7eSjoerg   if (D->hasAttrs())
30506f32e7eSjoerg     Record.AddAttributes(D->getAttrs());
30606f32e7eSjoerg   Record.push_back(D->isImplicit());
30706f32e7eSjoerg   Record.push_back(D->isUsed(false));
30806f32e7eSjoerg   Record.push_back(D->isReferenced());
30906f32e7eSjoerg   Record.push_back(D->isTopLevelDeclInObjCContainer());
31006f32e7eSjoerg   Record.push_back(D->getAccess());
31106f32e7eSjoerg   Record.push_back(D->isModulePrivate());
31206f32e7eSjoerg   Record.push_back(Writer.getSubmoduleID(D->getOwningModule()));
31306f32e7eSjoerg 
31406f32e7eSjoerg   // If this declaration injected a name into a context different from its
31506f32e7eSjoerg   // lexical context, and that context is an imported namespace, we need to
31606f32e7eSjoerg   // update its visible declarations to include this name.
31706f32e7eSjoerg   //
31806f32e7eSjoerg   // This happens when we instantiate a class with a friend declaration or a
31906f32e7eSjoerg   // function with a local extern declaration, for instance.
32006f32e7eSjoerg   //
32106f32e7eSjoerg   // FIXME: Can we handle this in AddedVisibleDecl instead?
32206f32e7eSjoerg   if (D->isOutOfLine()) {
32306f32e7eSjoerg     auto *DC = D->getDeclContext();
32406f32e7eSjoerg     while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
32506f32e7eSjoerg       if (!NS->isFromASTFile())
32606f32e7eSjoerg         break;
32706f32e7eSjoerg       Writer.UpdatedDeclContexts.insert(NS->getPrimaryContext());
32806f32e7eSjoerg       if (!NS->isInlineNamespace())
32906f32e7eSjoerg         break;
33006f32e7eSjoerg       DC = NS->getParent();
33106f32e7eSjoerg     }
33206f32e7eSjoerg   }
33306f32e7eSjoerg }
33406f32e7eSjoerg 
VisitPragmaCommentDecl(PragmaCommentDecl * D)33506f32e7eSjoerg void ASTDeclWriter::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
33606f32e7eSjoerg   StringRef Arg = D->getArg();
33706f32e7eSjoerg   Record.push_back(Arg.size());
33806f32e7eSjoerg   VisitDecl(D);
33906f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
34006f32e7eSjoerg   Record.push_back(D->getCommentKind());
34106f32e7eSjoerg   Record.AddString(Arg);
34206f32e7eSjoerg   Code = serialization::DECL_PRAGMA_COMMENT;
34306f32e7eSjoerg }
34406f32e7eSjoerg 
VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl * D)34506f32e7eSjoerg void ASTDeclWriter::VisitPragmaDetectMismatchDecl(
34606f32e7eSjoerg     PragmaDetectMismatchDecl *D) {
34706f32e7eSjoerg   StringRef Name = D->getName();
34806f32e7eSjoerg   StringRef Value = D->getValue();
34906f32e7eSjoerg   Record.push_back(Name.size() + 1 + Value.size());
35006f32e7eSjoerg   VisitDecl(D);
35106f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
35206f32e7eSjoerg   Record.AddString(Name);
35306f32e7eSjoerg   Record.AddString(Value);
35406f32e7eSjoerg   Code = serialization::DECL_PRAGMA_DETECT_MISMATCH;
35506f32e7eSjoerg }
35606f32e7eSjoerg 
VisitTranslationUnitDecl(TranslationUnitDecl * D)35706f32e7eSjoerg void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
35806f32e7eSjoerg   llvm_unreachable("Translation units aren't directly serialized");
35906f32e7eSjoerg }
36006f32e7eSjoerg 
VisitNamedDecl(NamedDecl * D)36106f32e7eSjoerg void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
36206f32e7eSjoerg   VisitDecl(D);
36306f32e7eSjoerg   Record.AddDeclarationName(D->getDeclName());
36406f32e7eSjoerg   Record.push_back(needsAnonymousDeclarationNumber(D)
36506f32e7eSjoerg                        ? Writer.getAnonymousDeclarationNumber(D)
36606f32e7eSjoerg                        : 0);
36706f32e7eSjoerg }
36806f32e7eSjoerg 
VisitTypeDecl(TypeDecl * D)36906f32e7eSjoerg void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
37006f32e7eSjoerg   VisitNamedDecl(D);
37106f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
37206f32e7eSjoerg   Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
37306f32e7eSjoerg }
37406f32e7eSjoerg 
VisitTypedefNameDecl(TypedefNameDecl * D)37506f32e7eSjoerg void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
37606f32e7eSjoerg   VisitRedeclarable(D);
37706f32e7eSjoerg   VisitTypeDecl(D);
37806f32e7eSjoerg   Record.AddTypeSourceInfo(D->getTypeSourceInfo());
37906f32e7eSjoerg   Record.push_back(D->isModed());
38006f32e7eSjoerg   if (D->isModed())
38106f32e7eSjoerg     Record.AddTypeRef(D->getUnderlyingType());
38206f32e7eSjoerg   Record.AddDeclRef(D->getAnonDeclWithTypedefName(false));
38306f32e7eSjoerg }
38406f32e7eSjoerg 
VisitTypedefDecl(TypedefDecl * D)38506f32e7eSjoerg void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
38606f32e7eSjoerg   VisitTypedefNameDecl(D);
38706f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
38806f32e7eSjoerg       !D->hasAttrs() &&
38906f32e7eSjoerg       !D->isImplicit() &&
39006f32e7eSjoerg       D->getFirstDecl() == D->getMostRecentDecl() &&
39106f32e7eSjoerg       !D->isInvalidDecl() &&
39206f32e7eSjoerg       !D->isTopLevelDeclInObjCContainer() &&
39306f32e7eSjoerg       !D->isModulePrivate() &&
39406f32e7eSjoerg       !needsAnonymousDeclarationNumber(D) &&
39506f32e7eSjoerg       D->getDeclName().getNameKind() == DeclarationName::Identifier)
39606f32e7eSjoerg     AbbrevToUse = Writer.getDeclTypedefAbbrev();
39706f32e7eSjoerg 
39806f32e7eSjoerg   Code = serialization::DECL_TYPEDEF;
39906f32e7eSjoerg }
40006f32e7eSjoerg 
VisitTypeAliasDecl(TypeAliasDecl * D)40106f32e7eSjoerg void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
40206f32e7eSjoerg   VisitTypedefNameDecl(D);
40306f32e7eSjoerg   Record.AddDeclRef(D->getDescribedAliasTemplate());
40406f32e7eSjoerg   Code = serialization::DECL_TYPEALIAS;
40506f32e7eSjoerg }
40606f32e7eSjoerg 
VisitTagDecl(TagDecl * D)40706f32e7eSjoerg void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
40806f32e7eSjoerg   VisitRedeclarable(D);
40906f32e7eSjoerg   VisitTypeDecl(D);
41006f32e7eSjoerg   Record.push_back(D->getIdentifierNamespace());
41106f32e7eSjoerg   Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
41206f32e7eSjoerg   if (!isa<CXXRecordDecl>(D))
41306f32e7eSjoerg     Record.push_back(D->isCompleteDefinition());
41406f32e7eSjoerg   Record.push_back(D->isEmbeddedInDeclarator());
41506f32e7eSjoerg   Record.push_back(D->isFreeStanding());
41606f32e7eSjoerg   Record.push_back(D->isCompleteDefinitionRequired());
41706f32e7eSjoerg   Record.AddSourceRange(D->getBraceRange());
41806f32e7eSjoerg 
41906f32e7eSjoerg   if (D->hasExtInfo()) {
42006f32e7eSjoerg     Record.push_back(1);
42106f32e7eSjoerg     Record.AddQualifierInfo(*D->getExtInfo());
42206f32e7eSjoerg   } else if (auto *TD = D->getTypedefNameForAnonDecl()) {
42306f32e7eSjoerg     Record.push_back(2);
42406f32e7eSjoerg     Record.AddDeclRef(TD);
42506f32e7eSjoerg     Record.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo());
42606f32e7eSjoerg   } else {
42706f32e7eSjoerg     Record.push_back(0);
42806f32e7eSjoerg   }
42906f32e7eSjoerg }
43006f32e7eSjoerg 
VisitEnumDecl(EnumDecl * D)43106f32e7eSjoerg void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
43206f32e7eSjoerg   VisitTagDecl(D);
43306f32e7eSjoerg   Record.AddTypeSourceInfo(D->getIntegerTypeSourceInfo());
43406f32e7eSjoerg   if (!D->getIntegerTypeSourceInfo())
43506f32e7eSjoerg     Record.AddTypeRef(D->getIntegerType());
43606f32e7eSjoerg   Record.AddTypeRef(D->getPromotionType());
43706f32e7eSjoerg   Record.push_back(D->getNumPositiveBits());
43806f32e7eSjoerg   Record.push_back(D->getNumNegativeBits());
43906f32e7eSjoerg   Record.push_back(D->isScoped());
44006f32e7eSjoerg   Record.push_back(D->isScopedUsingClassTag());
44106f32e7eSjoerg   Record.push_back(D->isFixed());
44206f32e7eSjoerg   Record.push_back(D->getODRHash());
44306f32e7eSjoerg 
44406f32e7eSjoerg   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
44506f32e7eSjoerg     Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
44606f32e7eSjoerg     Record.push_back(MemberInfo->getTemplateSpecializationKind());
44706f32e7eSjoerg     Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
44806f32e7eSjoerg   } else {
44906f32e7eSjoerg     Record.AddDeclRef(nullptr);
45006f32e7eSjoerg   }
45106f32e7eSjoerg 
45206f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
45306f32e7eSjoerg       !D->hasAttrs() &&
45406f32e7eSjoerg       !D->isImplicit() &&
45506f32e7eSjoerg       !D->isUsed(false) &&
45606f32e7eSjoerg       !D->hasExtInfo() &&
45706f32e7eSjoerg       !D->getTypedefNameForAnonDecl() &&
45806f32e7eSjoerg       D->getFirstDecl() == D->getMostRecentDecl() &&
45906f32e7eSjoerg       !D->isInvalidDecl() &&
46006f32e7eSjoerg       !D->isReferenced() &&
46106f32e7eSjoerg       !D->isTopLevelDeclInObjCContainer() &&
46206f32e7eSjoerg       D->getAccess() == AS_none &&
46306f32e7eSjoerg       !D->isModulePrivate() &&
46406f32e7eSjoerg       !CXXRecordDecl::classofKind(D->getKind()) &&
46506f32e7eSjoerg       !D->getIntegerTypeSourceInfo() &&
46606f32e7eSjoerg       !D->getMemberSpecializationInfo() &&
46706f32e7eSjoerg       !needsAnonymousDeclarationNumber(D) &&
46806f32e7eSjoerg       D->getDeclName().getNameKind() == DeclarationName::Identifier)
46906f32e7eSjoerg     AbbrevToUse = Writer.getDeclEnumAbbrev();
47006f32e7eSjoerg 
47106f32e7eSjoerg   Code = serialization::DECL_ENUM;
47206f32e7eSjoerg }
47306f32e7eSjoerg 
VisitRecordDecl(RecordDecl * D)47406f32e7eSjoerg void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
47506f32e7eSjoerg   VisitTagDecl(D);
47606f32e7eSjoerg   Record.push_back(D->hasFlexibleArrayMember());
47706f32e7eSjoerg   Record.push_back(D->isAnonymousStructOrUnion());
47806f32e7eSjoerg   Record.push_back(D->hasObjectMember());
47906f32e7eSjoerg   Record.push_back(D->hasVolatileMember());
48006f32e7eSjoerg   Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize());
48106f32e7eSjoerg   Record.push_back(D->isNonTrivialToPrimitiveCopy());
48206f32e7eSjoerg   Record.push_back(D->isNonTrivialToPrimitiveDestroy());
48306f32e7eSjoerg   Record.push_back(D->hasNonTrivialToPrimitiveDefaultInitializeCUnion());
48406f32e7eSjoerg   Record.push_back(D->hasNonTrivialToPrimitiveDestructCUnion());
48506f32e7eSjoerg   Record.push_back(D->hasNonTrivialToPrimitiveCopyCUnion());
48606f32e7eSjoerg   Record.push_back(D->isParamDestroyedInCallee());
48706f32e7eSjoerg   Record.push_back(D->getArgPassingRestrictions());
48806f32e7eSjoerg 
48906f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
49006f32e7eSjoerg       !D->hasAttrs() &&
49106f32e7eSjoerg       !D->isImplicit() &&
49206f32e7eSjoerg       !D->isUsed(false) &&
49306f32e7eSjoerg       !D->hasExtInfo() &&
49406f32e7eSjoerg       !D->getTypedefNameForAnonDecl() &&
49506f32e7eSjoerg       D->getFirstDecl() == D->getMostRecentDecl() &&
49606f32e7eSjoerg       !D->isInvalidDecl() &&
49706f32e7eSjoerg       !D->isReferenced() &&
49806f32e7eSjoerg       !D->isTopLevelDeclInObjCContainer() &&
49906f32e7eSjoerg       D->getAccess() == AS_none &&
50006f32e7eSjoerg       !D->isModulePrivate() &&
50106f32e7eSjoerg       !CXXRecordDecl::classofKind(D->getKind()) &&
50206f32e7eSjoerg       !needsAnonymousDeclarationNumber(D) &&
50306f32e7eSjoerg       D->getDeclName().getNameKind() == DeclarationName::Identifier)
50406f32e7eSjoerg     AbbrevToUse = Writer.getDeclRecordAbbrev();
50506f32e7eSjoerg 
50606f32e7eSjoerg   Code = serialization::DECL_RECORD;
50706f32e7eSjoerg }
50806f32e7eSjoerg 
VisitValueDecl(ValueDecl * D)50906f32e7eSjoerg void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
51006f32e7eSjoerg   VisitNamedDecl(D);
51106f32e7eSjoerg   Record.AddTypeRef(D->getType());
51206f32e7eSjoerg }
51306f32e7eSjoerg 
VisitEnumConstantDecl(EnumConstantDecl * D)51406f32e7eSjoerg void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
51506f32e7eSjoerg   VisitValueDecl(D);
51606f32e7eSjoerg   Record.push_back(D->getInitExpr()? 1 : 0);
51706f32e7eSjoerg   if (D->getInitExpr())
51806f32e7eSjoerg     Record.AddStmt(D->getInitExpr());
51906f32e7eSjoerg   Record.AddAPSInt(D->getInitVal());
52006f32e7eSjoerg 
52106f32e7eSjoerg   Code = serialization::DECL_ENUM_CONSTANT;
52206f32e7eSjoerg }
52306f32e7eSjoerg 
VisitDeclaratorDecl(DeclaratorDecl * D)52406f32e7eSjoerg void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
52506f32e7eSjoerg   VisitValueDecl(D);
52606f32e7eSjoerg   Record.AddSourceLocation(D->getInnerLocStart());
52706f32e7eSjoerg   Record.push_back(D->hasExtInfo());
528*13fbcb42Sjoerg   if (D->hasExtInfo()) {
529*13fbcb42Sjoerg     DeclaratorDecl::ExtInfo *Info = D->getExtInfo();
530*13fbcb42Sjoerg     Record.AddQualifierInfo(*Info);
531*13fbcb42Sjoerg     Record.AddStmt(Info->TrailingRequiresClause);
532*13fbcb42Sjoerg   }
53306f32e7eSjoerg   // The location information is deferred until the end of the record.
53406f32e7eSjoerg   Record.AddTypeRef(D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType()
53506f32e7eSjoerg                                            : QualType());
53606f32e7eSjoerg }
53706f32e7eSjoerg 
VisitFunctionDecl(FunctionDecl * D)53806f32e7eSjoerg void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
53906f32e7eSjoerg   VisitRedeclarable(D);
54006f32e7eSjoerg   VisitDeclaratorDecl(D);
54106f32e7eSjoerg   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
54206f32e7eSjoerg   Record.push_back(D->getIdentifierNamespace());
54306f32e7eSjoerg 
54406f32e7eSjoerg   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
54506f32e7eSjoerg   // after everything else is written.
54606f32e7eSjoerg   Record.push_back(static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
54706f32e7eSjoerg   Record.push_back(D->isInlineSpecified());
54806f32e7eSjoerg   Record.push_back(D->isInlined());
54906f32e7eSjoerg   Record.push_back(D->isVirtualAsWritten());
55006f32e7eSjoerg   Record.push_back(D->isPure());
55106f32e7eSjoerg   Record.push_back(D->hasInheritedPrototype());
55206f32e7eSjoerg   Record.push_back(D->hasWrittenPrototype());
55306f32e7eSjoerg   Record.push_back(D->isDeletedBit());
55406f32e7eSjoerg   Record.push_back(D->isTrivial());
55506f32e7eSjoerg   Record.push_back(D->isTrivialForCall());
55606f32e7eSjoerg   Record.push_back(D->isDefaulted());
55706f32e7eSjoerg   Record.push_back(D->isExplicitlyDefaulted());
55806f32e7eSjoerg   Record.push_back(D->hasImplicitReturnZero());
559*13fbcb42Sjoerg   Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
56006f32e7eSjoerg   Record.push_back(D->usesSEHTry());
56106f32e7eSjoerg   Record.push_back(D->hasSkippedBody());
56206f32e7eSjoerg   Record.push_back(D->isMultiVersion());
56306f32e7eSjoerg   Record.push_back(D->isLateTemplateParsed());
56406f32e7eSjoerg   Record.push_back(D->getLinkageInternal());
56506f32e7eSjoerg   Record.AddSourceLocation(D->getEndLoc());
56606f32e7eSjoerg 
56706f32e7eSjoerg   Record.push_back(D->getODRHash());
56806f32e7eSjoerg 
569*13fbcb42Sjoerg   if (D->isDefaulted()) {
570*13fbcb42Sjoerg     if (auto *FDI = D->getDefaultedFunctionInfo()) {
571*13fbcb42Sjoerg       Record.push_back(FDI->getUnqualifiedLookups().size());
572*13fbcb42Sjoerg       for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
573*13fbcb42Sjoerg         Record.AddDeclRef(P.getDecl());
574*13fbcb42Sjoerg         Record.push_back(P.getAccess());
575*13fbcb42Sjoerg       }
576*13fbcb42Sjoerg     } else {
577*13fbcb42Sjoerg       Record.push_back(0);
578*13fbcb42Sjoerg     }
579*13fbcb42Sjoerg   }
580*13fbcb42Sjoerg 
58106f32e7eSjoerg   Record.push_back(D->getTemplatedKind());
58206f32e7eSjoerg   switch (D->getTemplatedKind()) {
58306f32e7eSjoerg   case FunctionDecl::TK_NonTemplate:
58406f32e7eSjoerg     break;
58506f32e7eSjoerg   case FunctionDecl::TK_FunctionTemplate:
58606f32e7eSjoerg     Record.AddDeclRef(D->getDescribedFunctionTemplate());
58706f32e7eSjoerg     break;
58806f32e7eSjoerg   case FunctionDecl::TK_MemberSpecialization: {
58906f32e7eSjoerg     MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
59006f32e7eSjoerg     Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
59106f32e7eSjoerg     Record.push_back(MemberInfo->getTemplateSpecializationKind());
59206f32e7eSjoerg     Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
59306f32e7eSjoerg     break;
59406f32e7eSjoerg   }
59506f32e7eSjoerg   case FunctionDecl::TK_FunctionTemplateSpecialization: {
59606f32e7eSjoerg     FunctionTemplateSpecializationInfo *
59706f32e7eSjoerg       FTSInfo = D->getTemplateSpecializationInfo();
59806f32e7eSjoerg 
59906f32e7eSjoerg     RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
60006f32e7eSjoerg 
60106f32e7eSjoerg     Record.AddDeclRef(FTSInfo->getTemplate());
60206f32e7eSjoerg     Record.push_back(FTSInfo->getTemplateSpecializationKind());
60306f32e7eSjoerg 
60406f32e7eSjoerg     // Template arguments.
60506f32e7eSjoerg     Record.AddTemplateArgumentList(FTSInfo->TemplateArguments);
60606f32e7eSjoerg 
60706f32e7eSjoerg     // Template args as written.
60806f32e7eSjoerg     Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
60906f32e7eSjoerg     if (FTSInfo->TemplateArgumentsAsWritten) {
61006f32e7eSjoerg       Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
61106f32e7eSjoerg       for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
61206f32e7eSjoerg              i!=e; ++i)
61306f32e7eSjoerg         Record.AddTemplateArgumentLoc(
61406f32e7eSjoerg             (*FTSInfo->TemplateArgumentsAsWritten)[i]);
61506f32e7eSjoerg       Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc);
61606f32e7eSjoerg       Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc);
61706f32e7eSjoerg     }
61806f32e7eSjoerg 
61906f32e7eSjoerg     Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
62006f32e7eSjoerg 
62106f32e7eSjoerg     if (MemberSpecializationInfo *MemberInfo =
62206f32e7eSjoerg         FTSInfo->getMemberSpecializationInfo()) {
62306f32e7eSjoerg       Record.push_back(1);
62406f32e7eSjoerg       Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
62506f32e7eSjoerg       Record.push_back(MemberInfo->getTemplateSpecializationKind());
62606f32e7eSjoerg       Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
62706f32e7eSjoerg     } else {
62806f32e7eSjoerg       Record.push_back(0);
62906f32e7eSjoerg     }
63006f32e7eSjoerg 
63106f32e7eSjoerg     if (D->isCanonicalDecl()) {
63206f32e7eSjoerg       // Write the template that contains the specializations set. We will
63306f32e7eSjoerg       // add a FunctionTemplateSpecializationInfo to it when reading.
63406f32e7eSjoerg       Record.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl());
63506f32e7eSjoerg     }
63606f32e7eSjoerg     break;
63706f32e7eSjoerg   }
63806f32e7eSjoerg   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
63906f32e7eSjoerg     DependentFunctionTemplateSpecializationInfo *
64006f32e7eSjoerg       DFTSInfo = D->getDependentSpecializationInfo();
64106f32e7eSjoerg 
64206f32e7eSjoerg     // Templates.
64306f32e7eSjoerg     Record.push_back(DFTSInfo->getNumTemplates());
64406f32e7eSjoerg     for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
64506f32e7eSjoerg       Record.AddDeclRef(DFTSInfo->getTemplate(i));
64606f32e7eSjoerg 
64706f32e7eSjoerg     // Templates args.
64806f32e7eSjoerg     Record.push_back(DFTSInfo->getNumTemplateArgs());
64906f32e7eSjoerg     for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
65006f32e7eSjoerg       Record.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i));
65106f32e7eSjoerg     Record.AddSourceLocation(DFTSInfo->getLAngleLoc());
65206f32e7eSjoerg     Record.AddSourceLocation(DFTSInfo->getRAngleLoc());
65306f32e7eSjoerg     break;
65406f32e7eSjoerg   }
65506f32e7eSjoerg   }
65606f32e7eSjoerg 
65706f32e7eSjoerg   Record.push_back(D->param_size());
65806f32e7eSjoerg   for (auto P : D->parameters())
65906f32e7eSjoerg     Record.AddDeclRef(P);
66006f32e7eSjoerg   Code = serialization::DECL_FUNCTION;
66106f32e7eSjoerg }
66206f32e7eSjoerg 
addExplicitSpecifier(ExplicitSpecifier ES,ASTRecordWriter & Record)66306f32e7eSjoerg static void addExplicitSpecifier(ExplicitSpecifier ES,
66406f32e7eSjoerg                                  ASTRecordWriter &Record) {
66506f32e7eSjoerg   uint64_t Kind = static_cast<uint64_t>(ES.getKind());
66606f32e7eSjoerg   Kind = Kind << 1 | static_cast<bool>(ES.getExpr());
66706f32e7eSjoerg   Record.push_back(Kind);
66806f32e7eSjoerg   if (ES.getExpr()) {
66906f32e7eSjoerg     Record.AddStmt(ES.getExpr());
67006f32e7eSjoerg   }
67106f32e7eSjoerg }
67206f32e7eSjoerg 
VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl * D)67306f32e7eSjoerg void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
67406f32e7eSjoerg   addExplicitSpecifier(D->getExplicitSpecifier(), Record);
675*13fbcb42Sjoerg   Record.AddDeclRef(D->Ctor);
67606f32e7eSjoerg   VisitFunctionDecl(D);
67706f32e7eSjoerg   Record.push_back(D->isCopyDeductionCandidate());
67806f32e7eSjoerg   Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
67906f32e7eSjoerg }
68006f32e7eSjoerg 
VisitObjCMethodDecl(ObjCMethodDecl * D)68106f32e7eSjoerg void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
68206f32e7eSjoerg   VisitNamedDecl(D);
68306f32e7eSjoerg   // FIXME: convert to LazyStmtPtr?
68406f32e7eSjoerg   // Unlike C/C++, method bodies will never be in header files.
685*13fbcb42Sjoerg   bool HasBodyStuff = D->getBody() != nullptr;
68606f32e7eSjoerg   Record.push_back(HasBodyStuff);
68706f32e7eSjoerg   if (HasBodyStuff) {
68806f32e7eSjoerg     Record.AddStmt(D->getBody());
689*13fbcb42Sjoerg   }
69006f32e7eSjoerg   Record.AddDeclRef(D->getSelfDecl());
69106f32e7eSjoerg   Record.AddDeclRef(D->getCmdDecl());
69206f32e7eSjoerg   Record.push_back(D->isInstanceMethod());
69306f32e7eSjoerg   Record.push_back(D->isVariadic());
69406f32e7eSjoerg   Record.push_back(D->isPropertyAccessor());
695*13fbcb42Sjoerg   Record.push_back(D->isSynthesizedAccessorStub());
69606f32e7eSjoerg   Record.push_back(D->isDefined());
69706f32e7eSjoerg   Record.push_back(D->isOverriding());
69806f32e7eSjoerg   Record.push_back(D->hasSkippedBody());
69906f32e7eSjoerg 
70006f32e7eSjoerg   Record.push_back(D->isRedeclaration());
70106f32e7eSjoerg   Record.push_back(D->hasRedeclaration());
70206f32e7eSjoerg   if (D->hasRedeclaration()) {
70306f32e7eSjoerg     assert(Context.getObjCMethodRedeclaration(D));
70406f32e7eSjoerg     Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
70506f32e7eSjoerg   }
70606f32e7eSjoerg 
70706f32e7eSjoerg   // FIXME: stable encoding for @required/@optional
70806f32e7eSjoerg   Record.push_back(D->getImplementationControl());
70906f32e7eSjoerg   // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
71006f32e7eSjoerg   Record.push_back(D->getObjCDeclQualifier());
71106f32e7eSjoerg   Record.push_back(D->hasRelatedResultType());
71206f32e7eSjoerg   Record.AddTypeRef(D->getReturnType());
71306f32e7eSjoerg   Record.AddTypeSourceInfo(D->getReturnTypeSourceInfo());
71406f32e7eSjoerg   Record.AddSourceLocation(D->getEndLoc());
71506f32e7eSjoerg   Record.push_back(D->param_size());
71606f32e7eSjoerg   for (const auto *P : D->parameters())
71706f32e7eSjoerg     Record.AddDeclRef(P);
71806f32e7eSjoerg 
71906f32e7eSjoerg   Record.push_back(D->getSelLocsKind());
72006f32e7eSjoerg   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
72106f32e7eSjoerg   SourceLocation *SelLocs = D->getStoredSelLocs();
72206f32e7eSjoerg   Record.push_back(NumStoredSelLocs);
72306f32e7eSjoerg   for (unsigned i = 0; i != NumStoredSelLocs; ++i)
72406f32e7eSjoerg     Record.AddSourceLocation(SelLocs[i]);
72506f32e7eSjoerg 
72606f32e7eSjoerg   Code = serialization::DECL_OBJC_METHOD;
72706f32e7eSjoerg }
72806f32e7eSjoerg 
VisitObjCTypeParamDecl(ObjCTypeParamDecl * D)72906f32e7eSjoerg void ASTDeclWriter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
73006f32e7eSjoerg   VisitTypedefNameDecl(D);
73106f32e7eSjoerg   Record.push_back(D->Variance);
73206f32e7eSjoerg   Record.push_back(D->Index);
73306f32e7eSjoerg   Record.AddSourceLocation(D->VarianceLoc);
73406f32e7eSjoerg   Record.AddSourceLocation(D->ColonLoc);
73506f32e7eSjoerg 
73606f32e7eSjoerg   Code = serialization::DECL_OBJC_TYPE_PARAM;
73706f32e7eSjoerg }
73806f32e7eSjoerg 
VisitObjCContainerDecl(ObjCContainerDecl * D)73906f32e7eSjoerg void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
74006f32e7eSjoerg   VisitNamedDecl(D);
74106f32e7eSjoerg   Record.AddSourceLocation(D->getAtStartLoc());
74206f32e7eSjoerg   Record.AddSourceRange(D->getAtEndRange());
74306f32e7eSjoerg   // Abstract class (no need to define a stable serialization::DECL code).
74406f32e7eSjoerg }
74506f32e7eSjoerg 
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)74606f32e7eSjoerg void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
74706f32e7eSjoerg   VisitRedeclarable(D);
74806f32e7eSjoerg   VisitObjCContainerDecl(D);
74906f32e7eSjoerg   Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
75006f32e7eSjoerg   AddObjCTypeParamList(D->TypeParamList);
75106f32e7eSjoerg 
75206f32e7eSjoerg   Record.push_back(D->isThisDeclarationADefinition());
75306f32e7eSjoerg   if (D->isThisDeclarationADefinition()) {
75406f32e7eSjoerg     // Write the DefinitionData
75506f32e7eSjoerg     ObjCInterfaceDecl::DefinitionData &Data = D->data();
75606f32e7eSjoerg 
75706f32e7eSjoerg     Record.AddTypeSourceInfo(D->getSuperClassTInfo());
75806f32e7eSjoerg     Record.AddSourceLocation(D->getEndOfDefinitionLoc());
75906f32e7eSjoerg     Record.push_back(Data.HasDesignatedInitializers);
76006f32e7eSjoerg 
76106f32e7eSjoerg     // Write out the protocols that are directly referenced by the @interface.
76206f32e7eSjoerg     Record.push_back(Data.ReferencedProtocols.size());
76306f32e7eSjoerg     for (const auto *P : D->protocols())
76406f32e7eSjoerg       Record.AddDeclRef(P);
76506f32e7eSjoerg     for (const auto &PL : D->protocol_locs())
76606f32e7eSjoerg       Record.AddSourceLocation(PL);
76706f32e7eSjoerg 
76806f32e7eSjoerg     // Write out the protocols that are transitively referenced.
76906f32e7eSjoerg     Record.push_back(Data.AllReferencedProtocols.size());
77006f32e7eSjoerg     for (ObjCList<ObjCProtocolDecl>::iterator
77106f32e7eSjoerg               P = Data.AllReferencedProtocols.begin(),
77206f32e7eSjoerg            PEnd = Data.AllReferencedProtocols.end();
77306f32e7eSjoerg          P != PEnd; ++P)
77406f32e7eSjoerg       Record.AddDeclRef(*P);
77506f32e7eSjoerg 
77606f32e7eSjoerg 
77706f32e7eSjoerg     if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
77806f32e7eSjoerg       // Ensure that we write out the set of categories for this class.
77906f32e7eSjoerg       Writer.ObjCClassesWithCategories.insert(D);
78006f32e7eSjoerg 
78106f32e7eSjoerg       // Make sure that the categories get serialized.
78206f32e7eSjoerg       for (; Cat; Cat = Cat->getNextClassCategoryRaw())
78306f32e7eSjoerg         (void)Writer.GetDeclRef(Cat);
78406f32e7eSjoerg     }
78506f32e7eSjoerg   }
78606f32e7eSjoerg 
78706f32e7eSjoerg   Code = serialization::DECL_OBJC_INTERFACE;
78806f32e7eSjoerg }
78906f32e7eSjoerg 
VisitObjCIvarDecl(ObjCIvarDecl * D)79006f32e7eSjoerg void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
79106f32e7eSjoerg   VisitFieldDecl(D);
79206f32e7eSjoerg   // FIXME: stable encoding for @public/@private/@protected/@package
79306f32e7eSjoerg   Record.push_back(D->getAccessControl());
79406f32e7eSjoerg   Record.push_back(D->getSynthesize());
79506f32e7eSjoerg 
79606f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
79706f32e7eSjoerg       !D->hasAttrs() &&
79806f32e7eSjoerg       !D->isImplicit() &&
79906f32e7eSjoerg       !D->isUsed(false) &&
80006f32e7eSjoerg       !D->isInvalidDecl() &&
80106f32e7eSjoerg       !D->isReferenced() &&
80206f32e7eSjoerg       !D->isModulePrivate() &&
80306f32e7eSjoerg       !D->getBitWidth() &&
80406f32e7eSjoerg       !D->hasExtInfo() &&
80506f32e7eSjoerg       D->getDeclName())
80606f32e7eSjoerg     AbbrevToUse = Writer.getDeclObjCIvarAbbrev();
80706f32e7eSjoerg 
80806f32e7eSjoerg   Code = serialization::DECL_OBJC_IVAR;
80906f32e7eSjoerg }
81006f32e7eSjoerg 
VisitObjCProtocolDecl(ObjCProtocolDecl * D)81106f32e7eSjoerg void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
81206f32e7eSjoerg   VisitRedeclarable(D);
81306f32e7eSjoerg   VisitObjCContainerDecl(D);
81406f32e7eSjoerg 
81506f32e7eSjoerg   Record.push_back(D->isThisDeclarationADefinition());
81606f32e7eSjoerg   if (D->isThisDeclarationADefinition()) {
81706f32e7eSjoerg     Record.push_back(D->protocol_size());
81806f32e7eSjoerg     for (const auto *I : D->protocols())
81906f32e7eSjoerg       Record.AddDeclRef(I);
82006f32e7eSjoerg     for (const auto &PL : D->protocol_locs())
82106f32e7eSjoerg       Record.AddSourceLocation(PL);
82206f32e7eSjoerg   }
82306f32e7eSjoerg 
82406f32e7eSjoerg   Code = serialization::DECL_OBJC_PROTOCOL;
82506f32e7eSjoerg }
82606f32e7eSjoerg 
VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl * D)82706f32e7eSjoerg void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
82806f32e7eSjoerg   VisitFieldDecl(D);
82906f32e7eSjoerg   Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
83006f32e7eSjoerg }
83106f32e7eSjoerg 
VisitObjCCategoryDecl(ObjCCategoryDecl * D)83206f32e7eSjoerg void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
83306f32e7eSjoerg   VisitObjCContainerDecl(D);
83406f32e7eSjoerg   Record.AddSourceLocation(D->getCategoryNameLoc());
83506f32e7eSjoerg   Record.AddSourceLocation(D->getIvarLBraceLoc());
83606f32e7eSjoerg   Record.AddSourceLocation(D->getIvarRBraceLoc());
83706f32e7eSjoerg   Record.AddDeclRef(D->getClassInterface());
83806f32e7eSjoerg   AddObjCTypeParamList(D->TypeParamList);
83906f32e7eSjoerg   Record.push_back(D->protocol_size());
84006f32e7eSjoerg   for (const auto *I : D->protocols())
84106f32e7eSjoerg     Record.AddDeclRef(I);
84206f32e7eSjoerg   for (const auto &PL : D->protocol_locs())
84306f32e7eSjoerg     Record.AddSourceLocation(PL);
84406f32e7eSjoerg   Code = serialization::DECL_OBJC_CATEGORY;
84506f32e7eSjoerg }
84606f32e7eSjoerg 
VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl * D)84706f32e7eSjoerg void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
84806f32e7eSjoerg   VisitNamedDecl(D);
84906f32e7eSjoerg   Record.AddDeclRef(D->getClassInterface());
85006f32e7eSjoerg   Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
85106f32e7eSjoerg }
85206f32e7eSjoerg 
VisitObjCPropertyDecl(ObjCPropertyDecl * D)85306f32e7eSjoerg void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
85406f32e7eSjoerg   VisitNamedDecl(D);
85506f32e7eSjoerg   Record.AddSourceLocation(D->getAtLoc());
85606f32e7eSjoerg   Record.AddSourceLocation(D->getLParenLoc());
85706f32e7eSjoerg   Record.AddTypeRef(D->getType());
85806f32e7eSjoerg   Record.AddTypeSourceInfo(D->getTypeSourceInfo());
85906f32e7eSjoerg   // FIXME: stable encoding
86006f32e7eSjoerg   Record.push_back((unsigned)D->getPropertyAttributes());
86106f32e7eSjoerg   Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
86206f32e7eSjoerg   // FIXME: stable encoding
86306f32e7eSjoerg   Record.push_back((unsigned)D->getPropertyImplementation());
86406f32e7eSjoerg   Record.AddDeclarationName(D->getGetterName());
86506f32e7eSjoerg   Record.AddSourceLocation(D->getGetterNameLoc());
86606f32e7eSjoerg   Record.AddDeclarationName(D->getSetterName());
86706f32e7eSjoerg   Record.AddSourceLocation(D->getSetterNameLoc());
86806f32e7eSjoerg   Record.AddDeclRef(D->getGetterMethodDecl());
86906f32e7eSjoerg   Record.AddDeclRef(D->getSetterMethodDecl());
87006f32e7eSjoerg   Record.AddDeclRef(D->getPropertyIvarDecl());
87106f32e7eSjoerg   Code = serialization::DECL_OBJC_PROPERTY;
87206f32e7eSjoerg }
87306f32e7eSjoerg 
VisitObjCImplDecl(ObjCImplDecl * D)87406f32e7eSjoerg void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
87506f32e7eSjoerg   VisitObjCContainerDecl(D);
87606f32e7eSjoerg   Record.AddDeclRef(D->getClassInterface());
87706f32e7eSjoerg   // Abstract class (no need to define a stable serialization::DECL code).
87806f32e7eSjoerg }
87906f32e7eSjoerg 
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)88006f32e7eSjoerg void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
88106f32e7eSjoerg   VisitObjCImplDecl(D);
88206f32e7eSjoerg   Record.AddSourceLocation(D->getCategoryNameLoc());
88306f32e7eSjoerg   Code = serialization::DECL_OBJC_CATEGORY_IMPL;
88406f32e7eSjoerg }
88506f32e7eSjoerg 
VisitObjCImplementationDecl(ObjCImplementationDecl * D)88606f32e7eSjoerg void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
88706f32e7eSjoerg   VisitObjCImplDecl(D);
88806f32e7eSjoerg   Record.AddDeclRef(D->getSuperClass());
88906f32e7eSjoerg   Record.AddSourceLocation(D->getSuperClassLoc());
89006f32e7eSjoerg   Record.AddSourceLocation(D->getIvarLBraceLoc());
89106f32e7eSjoerg   Record.AddSourceLocation(D->getIvarRBraceLoc());
89206f32e7eSjoerg   Record.push_back(D->hasNonZeroConstructors());
89306f32e7eSjoerg   Record.push_back(D->hasDestructors());
89406f32e7eSjoerg   Record.push_back(D->NumIvarInitializers);
89506f32e7eSjoerg   if (D->NumIvarInitializers)
89606f32e7eSjoerg     Record.AddCXXCtorInitializers(
89706f32e7eSjoerg         llvm::makeArrayRef(D->init_begin(), D->init_end()));
89806f32e7eSjoerg   Code = serialization::DECL_OBJC_IMPLEMENTATION;
89906f32e7eSjoerg }
90006f32e7eSjoerg 
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * D)90106f32e7eSjoerg void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
90206f32e7eSjoerg   VisitDecl(D);
90306f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
90406f32e7eSjoerg   Record.AddDeclRef(D->getPropertyDecl());
90506f32e7eSjoerg   Record.AddDeclRef(D->getPropertyIvarDecl());
90606f32e7eSjoerg   Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
907*13fbcb42Sjoerg   Record.AddDeclRef(D->getGetterMethodDecl());
908*13fbcb42Sjoerg   Record.AddDeclRef(D->getSetterMethodDecl());
90906f32e7eSjoerg   Record.AddStmt(D->getGetterCXXConstructor());
91006f32e7eSjoerg   Record.AddStmt(D->getSetterCXXAssignment());
91106f32e7eSjoerg   Code = serialization::DECL_OBJC_PROPERTY_IMPL;
91206f32e7eSjoerg }
91306f32e7eSjoerg 
VisitFieldDecl(FieldDecl * D)91406f32e7eSjoerg void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
91506f32e7eSjoerg   VisitDeclaratorDecl(D);
91606f32e7eSjoerg   Record.push_back(D->isMutable());
91706f32e7eSjoerg 
91806f32e7eSjoerg   FieldDecl::InitStorageKind ISK = D->InitStorage.getInt();
91906f32e7eSjoerg   Record.push_back(ISK);
92006f32e7eSjoerg   if (ISK == FieldDecl::ISK_CapturedVLAType)
92106f32e7eSjoerg     Record.AddTypeRef(QualType(D->getCapturedVLAType(), 0));
92206f32e7eSjoerg   else if (ISK)
92306f32e7eSjoerg     Record.AddStmt(D->getInClassInitializer());
92406f32e7eSjoerg 
92506f32e7eSjoerg   Record.AddStmt(D->getBitWidth());
92606f32e7eSjoerg 
92706f32e7eSjoerg   if (!D->getDeclName())
92806f32e7eSjoerg     Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
92906f32e7eSjoerg 
93006f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
93106f32e7eSjoerg       !D->hasAttrs() &&
93206f32e7eSjoerg       !D->isImplicit() &&
93306f32e7eSjoerg       !D->isUsed(false) &&
93406f32e7eSjoerg       !D->isInvalidDecl() &&
93506f32e7eSjoerg       !D->isReferenced() &&
93606f32e7eSjoerg       !D->isTopLevelDeclInObjCContainer() &&
93706f32e7eSjoerg       !D->isModulePrivate() &&
93806f32e7eSjoerg       !D->getBitWidth() &&
93906f32e7eSjoerg       !D->hasInClassInitializer() &&
94006f32e7eSjoerg       !D->hasCapturedVLAType() &&
94106f32e7eSjoerg       !D->hasExtInfo() &&
94206f32e7eSjoerg       !ObjCIvarDecl::classofKind(D->getKind()) &&
94306f32e7eSjoerg       !ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
94406f32e7eSjoerg       D->getDeclName())
94506f32e7eSjoerg     AbbrevToUse = Writer.getDeclFieldAbbrev();
94606f32e7eSjoerg 
94706f32e7eSjoerg   Code = serialization::DECL_FIELD;
94806f32e7eSjoerg }
94906f32e7eSjoerg 
VisitMSPropertyDecl(MSPropertyDecl * D)95006f32e7eSjoerg void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
95106f32e7eSjoerg   VisitDeclaratorDecl(D);
95206f32e7eSjoerg   Record.AddIdentifierRef(D->getGetterId());
95306f32e7eSjoerg   Record.AddIdentifierRef(D->getSetterId());
95406f32e7eSjoerg   Code = serialization::DECL_MS_PROPERTY;
95506f32e7eSjoerg }
95606f32e7eSjoerg 
VisitMSGuidDecl(MSGuidDecl * D)957*13fbcb42Sjoerg void ASTDeclWriter::VisitMSGuidDecl(MSGuidDecl *D) {
958*13fbcb42Sjoerg   VisitValueDecl(D);
959*13fbcb42Sjoerg   MSGuidDecl::Parts Parts = D->getParts();
960*13fbcb42Sjoerg   Record.push_back(Parts.Part1);
961*13fbcb42Sjoerg   Record.push_back(Parts.Part2);
962*13fbcb42Sjoerg   Record.push_back(Parts.Part3);
963*13fbcb42Sjoerg   for (auto C : Parts.Part4And5)
964*13fbcb42Sjoerg     Record.push_back(C);
965*13fbcb42Sjoerg   Code = serialization::DECL_MS_GUID;
966*13fbcb42Sjoerg }
967*13fbcb42Sjoerg 
VisitTemplateParamObjectDecl(TemplateParamObjectDecl * D)968*13fbcb42Sjoerg void ASTDeclWriter::VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D) {
969*13fbcb42Sjoerg   VisitValueDecl(D);
970*13fbcb42Sjoerg   Record.AddAPValue(D->getValue());
971*13fbcb42Sjoerg   Code = serialization::DECL_TEMPLATE_PARAM_OBJECT;
972*13fbcb42Sjoerg }
973*13fbcb42Sjoerg 
VisitIndirectFieldDecl(IndirectFieldDecl * D)97406f32e7eSjoerg void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
97506f32e7eSjoerg   VisitValueDecl(D);
97606f32e7eSjoerg   Record.push_back(D->getChainingSize());
97706f32e7eSjoerg 
97806f32e7eSjoerg   for (const auto *P : D->chain())
97906f32e7eSjoerg     Record.AddDeclRef(P);
98006f32e7eSjoerg   Code = serialization::DECL_INDIRECTFIELD;
98106f32e7eSjoerg }
98206f32e7eSjoerg 
VisitVarDecl(VarDecl * D)98306f32e7eSjoerg void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
98406f32e7eSjoerg   VisitRedeclarable(D);
98506f32e7eSjoerg   VisitDeclaratorDecl(D);
98606f32e7eSjoerg   Record.push_back(D->getStorageClass());
98706f32e7eSjoerg   Record.push_back(D->getTSCSpec());
98806f32e7eSjoerg   Record.push_back(D->getInitStyle());
98906f32e7eSjoerg   Record.push_back(D->isARCPseudoStrong());
99006f32e7eSjoerg   if (!isa<ParmVarDecl>(D)) {
99106f32e7eSjoerg     Record.push_back(D->isThisDeclarationADemotedDefinition());
99206f32e7eSjoerg     Record.push_back(D->isExceptionVariable());
99306f32e7eSjoerg     Record.push_back(D->isNRVOVariable());
99406f32e7eSjoerg     Record.push_back(D->isCXXForRangeDecl());
99506f32e7eSjoerg     Record.push_back(D->isObjCForDecl());
99606f32e7eSjoerg     Record.push_back(D->isInline());
99706f32e7eSjoerg     Record.push_back(D->isInlineSpecified());
99806f32e7eSjoerg     Record.push_back(D->isConstexpr());
99906f32e7eSjoerg     Record.push_back(D->isInitCapture());
100006f32e7eSjoerg     Record.push_back(D->isPreviousDeclInSameBlockScope());
100106f32e7eSjoerg     if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D))
100206f32e7eSjoerg       Record.push_back(static_cast<unsigned>(IPD->getParameterKind()));
100306f32e7eSjoerg     else
100406f32e7eSjoerg       Record.push_back(0);
100506f32e7eSjoerg     Record.push_back(D->isEscapingByref());
100606f32e7eSjoerg   }
100706f32e7eSjoerg   Record.push_back(D->getLinkageInternal());
100806f32e7eSjoerg 
1009*13fbcb42Sjoerg   Record.AddVarDeclInit(D);
101006f32e7eSjoerg 
101106f32e7eSjoerg   if (D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) {
1012*13fbcb42Sjoerg     BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
101306f32e7eSjoerg     Record.AddStmt(Init.getCopyExpr());
101406f32e7eSjoerg     if (Init.getCopyExpr())
101506f32e7eSjoerg       Record.push_back(Init.canThrow());
101606f32e7eSjoerg   }
101706f32e7eSjoerg 
101806f32e7eSjoerg   if (D->getStorageDuration() == SD_Static) {
101906f32e7eSjoerg     bool ModulesCodegen = false;
102006f32e7eSjoerg     if (Writer.WritingModule &&
102106f32e7eSjoerg         !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
102206f32e7eSjoerg         !isa<VarTemplateSpecializationDecl>(D)) {
102306f32e7eSjoerg       // When building a C++ Modules TS module interface unit, a strong
102406f32e7eSjoerg       // definition in the module interface is provided by the compilation of
102506f32e7eSjoerg       // that module interface unit, not by its users. (Inline variables are
102606f32e7eSjoerg       // still emitted in module users.)
102706f32e7eSjoerg       ModulesCodegen =
1028*13fbcb42Sjoerg           (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit ||
1029*13fbcb42Sjoerg            (D->hasAttr<DLLExportAttr>() &&
1030*13fbcb42Sjoerg             Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
1031*13fbcb42Sjoerg           Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
103206f32e7eSjoerg     }
103306f32e7eSjoerg     Record.push_back(ModulesCodegen);
103406f32e7eSjoerg     if (ModulesCodegen)
103506f32e7eSjoerg       Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
103606f32e7eSjoerg   }
103706f32e7eSjoerg 
103806f32e7eSjoerg   enum {
103906f32e7eSjoerg     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
104006f32e7eSjoerg   };
104106f32e7eSjoerg   if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
104206f32e7eSjoerg     Record.push_back(VarTemplate);
104306f32e7eSjoerg     Record.AddDeclRef(TemplD);
104406f32e7eSjoerg   } else if (MemberSpecializationInfo *SpecInfo
104506f32e7eSjoerg                = D->getMemberSpecializationInfo()) {
104606f32e7eSjoerg     Record.push_back(StaticDataMemberSpecialization);
104706f32e7eSjoerg     Record.AddDeclRef(SpecInfo->getInstantiatedFrom());
104806f32e7eSjoerg     Record.push_back(SpecInfo->getTemplateSpecializationKind());
104906f32e7eSjoerg     Record.AddSourceLocation(SpecInfo->getPointOfInstantiation());
105006f32e7eSjoerg   } else {
105106f32e7eSjoerg     Record.push_back(VarNotTemplate);
105206f32e7eSjoerg   }
105306f32e7eSjoerg 
105406f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
105506f32e7eSjoerg       !D->hasAttrs() &&
105606f32e7eSjoerg       !D->isImplicit() &&
105706f32e7eSjoerg       !D->isUsed(false) &&
105806f32e7eSjoerg       !D->isInvalidDecl() &&
105906f32e7eSjoerg       !D->isReferenced() &&
106006f32e7eSjoerg       !D->isTopLevelDeclInObjCContainer() &&
106106f32e7eSjoerg       D->getAccess() == AS_none &&
106206f32e7eSjoerg       !D->isModulePrivate() &&
106306f32e7eSjoerg       !needsAnonymousDeclarationNumber(D) &&
106406f32e7eSjoerg       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
106506f32e7eSjoerg       !D->hasExtInfo() &&
106606f32e7eSjoerg       D->getFirstDecl() == D->getMostRecentDecl() &&
106706f32e7eSjoerg       D->getKind() == Decl::Var &&
106806f32e7eSjoerg       !D->isInline() &&
106906f32e7eSjoerg       !D->isConstexpr() &&
107006f32e7eSjoerg       !D->isInitCapture() &&
107106f32e7eSjoerg       !D->isPreviousDeclInSameBlockScope() &&
107206f32e7eSjoerg       !(D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) &&
107306f32e7eSjoerg       !D->isEscapingByref() &&
107406f32e7eSjoerg       D->getStorageDuration() != SD_Static &&
107506f32e7eSjoerg       !D->getMemberSpecializationInfo())
107606f32e7eSjoerg     AbbrevToUse = Writer.getDeclVarAbbrev();
107706f32e7eSjoerg 
107806f32e7eSjoerg   Code = serialization::DECL_VAR;
107906f32e7eSjoerg }
108006f32e7eSjoerg 
VisitImplicitParamDecl(ImplicitParamDecl * D)108106f32e7eSjoerg void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
108206f32e7eSjoerg   VisitVarDecl(D);
108306f32e7eSjoerg   Code = serialization::DECL_IMPLICIT_PARAM;
108406f32e7eSjoerg }
108506f32e7eSjoerg 
VisitParmVarDecl(ParmVarDecl * D)108606f32e7eSjoerg void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
108706f32e7eSjoerg   VisitVarDecl(D);
108806f32e7eSjoerg   Record.push_back(D->isObjCMethodParameter());
108906f32e7eSjoerg   Record.push_back(D->getFunctionScopeDepth());
109006f32e7eSjoerg   Record.push_back(D->getFunctionScopeIndex());
109106f32e7eSjoerg   Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
109206f32e7eSjoerg   Record.push_back(D->isKNRPromoted());
109306f32e7eSjoerg   Record.push_back(D->hasInheritedDefaultArg());
109406f32e7eSjoerg   Record.push_back(D->hasUninstantiatedDefaultArg());
109506f32e7eSjoerg   if (D->hasUninstantiatedDefaultArg())
109606f32e7eSjoerg     Record.AddStmt(D->getUninstantiatedDefaultArg());
109706f32e7eSjoerg   Code = serialization::DECL_PARM_VAR;
109806f32e7eSjoerg 
109906f32e7eSjoerg   // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
110006f32e7eSjoerg   // we dynamically check for the properties that we optimize for, but don't
110106f32e7eSjoerg   // know are true of all PARM_VAR_DECLs.
110206f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
110306f32e7eSjoerg       !D->hasAttrs() &&
110406f32e7eSjoerg       !D->hasExtInfo() &&
110506f32e7eSjoerg       !D->isImplicit() &&
110606f32e7eSjoerg       !D->isUsed(false) &&
110706f32e7eSjoerg       !D->isInvalidDecl() &&
110806f32e7eSjoerg       !D->isReferenced() &&
110906f32e7eSjoerg       D->getAccess() == AS_none &&
111006f32e7eSjoerg       !D->isModulePrivate() &&
111106f32e7eSjoerg       D->getStorageClass() == 0 &&
111206f32e7eSjoerg       D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
111306f32e7eSjoerg       D->getFunctionScopeDepth() == 0 &&
111406f32e7eSjoerg       D->getObjCDeclQualifier() == 0 &&
111506f32e7eSjoerg       !D->isKNRPromoted() &&
111606f32e7eSjoerg       !D->hasInheritedDefaultArg() &&
111706f32e7eSjoerg       D->getInit() == nullptr &&
111806f32e7eSjoerg       !D->hasUninstantiatedDefaultArg())  // No default expr.
111906f32e7eSjoerg     AbbrevToUse = Writer.getDeclParmVarAbbrev();
112006f32e7eSjoerg 
112106f32e7eSjoerg   // Check things we know are true of *every* PARM_VAR_DECL, which is more than
112206f32e7eSjoerg   // just us assuming it.
112306f32e7eSjoerg   assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
112406f32e7eSjoerg   assert(!D->isThisDeclarationADemotedDefinition()
112506f32e7eSjoerg          && "PARM_VAR_DECL can't be demoted definition.");
112606f32e7eSjoerg   assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
112706f32e7eSjoerg   assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
112806f32e7eSjoerg   assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
112906f32e7eSjoerg   assert(!D->isStaticDataMember() &&
113006f32e7eSjoerg          "PARM_VAR_DECL can't be static data member");
113106f32e7eSjoerg }
113206f32e7eSjoerg 
VisitDecompositionDecl(DecompositionDecl * D)113306f32e7eSjoerg void ASTDeclWriter::VisitDecompositionDecl(DecompositionDecl *D) {
113406f32e7eSjoerg   // Record the number of bindings first to simplify deserialization.
113506f32e7eSjoerg   Record.push_back(D->bindings().size());
113606f32e7eSjoerg 
113706f32e7eSjoerg   VisitVarDecl(D);
113806f32e7eSjoerg   for (auto *B : D->bindings())
113906f32e7eSjoerg     Record.AddDeclRef(B);
114006f32e7eSjoerg   Code = serialization::DECL_DECOMPOSITION;
114106f32e7eSjoerg }
114206f32e7eSjoerg 
VisitBindingDecl(BindingDecl * D)114306f32e7eSjoerg void ASTDeclWriter::VisitBindingDecl(BindingDecl *D) {
114406f32e7eSjoerg   VisitValueDecl(D);
114506f32e7eSjoerg   Record.AddStmt(D->getBinding());
114606f32e7eSjoerg   Code = serialization::DECL_BINDING;
114706f32e7eSjoerg }
114806f32e7eSjoerg 
VisitFileScopeAsmDecl(FileScopeAsmDecl * D)114906f32e7eSjoerg void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
115006f32e7eSjoerg   VisitDecl(D);
115106f32e7eSjoerg   Record.AddStmt(D->getAsmString());
115206f32e7eSjoerg   Record.AddSourceLocation(D->getRParenLoc());
115306f32e7eSjoerg   Code = serialization::DECL_FILE_SCOPE_ASM;
115406f32e7eSjoerg }
115506f32e7eSjoerg 
VisitEmptyDecl(EmptyDecl * D)115606f32e7eSjoerg void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
115706f32e7eSjoerg   VisitDecl(D);
115806f32e7eSjoerg   Code = serialization::DECL_EMPTY;
115906f32e7eSjoerg }
116006f32e7eSjoerg 
VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl * D)1161*13fbcb42Sjoerg void ASTDeclWriter::VisitLifetimeExtendedTemporaryDecl(
1162*13fbcb42Sjoerg     LifetimeExtendedTemporaryDecl *D) {
1163*13fbcb42Sjoerg   VisitDecl(D);
1164*13fbcb42Sjoerg   Record.AddDeclRef(D->getExtendingDecl());
1165*13fbcb42Sjoerg   Record.AddStmt(D->getTemporaryExpr());
1166*13fbcb42Sjoerg   Record.push_back(static_cast<bool>(D->getValue()));
1167*13fbcb42Sjoerg   if (D->getValue())
1168*13fbcb42Sjoerg     Record.AddAPValue(*D->getValue());
1169*13fbcb42Sjoerg   Record.push_back(D->getManglingNumber());
1170*13fbcb42Sjoerg   Code = serialization::DECL_LIFETIME_EXTENDED_TEMPORARY;
1171*13fbcb42Sjoerg }
VisitBlockDecl(BlockDecl * D)117206f32e7eSjoerg void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
117306f32e7eSjoerg   VisitDecl(D);
117406f32e7eSjoerg   Record.AddStmt(D->getBody());
117506f32e7eSjoerg   Record.AddTypeSourceInfo(D->getSignatureAsWritten());
117606f32e7eSjoerg   Record.push_back(D->param_size());
117706f32e7eSjoerg   for (ParmVarDecl *P : D->parameters())
117806f32e7eSjoerg     Record.AddDeclRef(P);
117906f32e7eSjoerg   Record.push_back(D->isVariadic());
118006f32e7eSjoerg   Record.push_back(D->blockMissingReturnType());
118106f32e7eSjoerg   Record.push_back(D->isConversionFromLambda());
118206f32e7eSjoerg   Record.push_back(D->doesNotEscape());
118306f32e7eSjoerg   Record.push_back(D->canAvoidCopyToHeap());
118406f32e7eSjoerg   Record.push_back(D->capturesCXXThis());
118506f32e7eSjoerg   Record.push_back(D->getNumCaptures());
118606f32e7eSjoerg   for (const auto &capture : D->captures()) {
118706f32e7eSjoerg     Record.AddDeclRef(capture.getVariable());
118806f32e7eSjoerg 
118906f32e7eSjoerg     unsigned flags = 0;
119006f32e7eSjoerg     if (capture.isByRef()) flags |= 1;
119106f32e7eSjoerg     if (capture.isNested()) flags |= 2;
119206f32e7eSjoerg     if (capture.hasCopyExpr()) flags |= 4;
119306f32e7eSjoerg     Record.push_back(flags);
119406f32e7eSjoerg 
119506f32e7eSjoerg     if (capture.hasCopyExpr()) Record.AddStmt(capture.getCopyExpr());
119606f32e7eSjoerg   }
119706f32e7eSjoerg 
119806f32e7eSjoerg   Code = serialization::DECL_BLOCK;
119906f32e7eSjoerg }
120006f32e7eSjoerg 
VisitCapturedDecl(CapturedDecl * CD)120106f32e7eSjoerg void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
120206f32e7eSjoerg   Record.push_back(CD->getNumParams());
120306f32e7eSjoerg   VisitDecl(CD);
120406f32e7eSjoerg   Record.push_back(CD->getContextParamPosition());
120506f32e7eSjoerg   Record.push_back(CD->isNothrow() ? 1 : 0);
120606f32e7eSjoerg   // Body is stored by VisitCapturedStmt.
120706f32e7eSjoerg   for (unsigned I = 0; I < CD->getNumParams(); ++I)
120806f32e7eSjoerg     Record.AddDeclRef(CD->getParam(I));
120906f32e7eSjoerg   Code = serialization::DECL_CAPTURED;
121006f32e7eSjoerg }
121106f32e7eSjoerg 
VisitLinkageSpecDecl(LinkageSpecDecl * D)121206f32e7eSjoerg void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
121306f32e7eSjoerg   VisitDecl(D);
121406f32e7eSjoerg   Record.push_back(D->getLanguage());
121506f32e7eSjoerg   Record.AddSourceLocation(D->getExternLoc());
121606f32e7eSjoerg   Record.AddSourceLocation(D->getRBraceLoc());
121706f32e7eSjoerg   Code = serialization::DECL_LINKAGE_SPEC;
121806f32e7eSjoerg }
121906f32e7eSjoerg 
VisitExportDecl(ExportDecl * D)122006f32e7eSjoerg void ASTDeclWriter::VisitExportDecl(ExportDecl *D) {
122106f32e7eSjoerg   VisitDecl(D);
122206f32e7eSjoerg   Record.AddSourceLocation(D->getRBraceLoc());
122306f32e7eSjoerg   Code = serialization::DECL_EXPORT;
122406f32e7eSjoerg }
122506f32e7eSjoerg 
VisitLabelDecl(LabelDecl * D)122606f32e7eSjoerg void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
122706f32e7eSjoerg   VisitNamedDecl(D);
122806f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
122906f32e7eSjoerg   Code = serialization::DECL_LABEL;
123006f32e7eSjoerg }
123106f32e7eSjoerg 
123206f32e7eSjoerg 
VisitNamespaceDecl(NamespaceDecl * D)123306f32e7eSjoerg void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
123406f32e7eSjoerg   VisitRedeclarable(D);
123506f32e7eSjoerg   VisitNamedDecl(D);
123606f32e7eSjoerg   Record.push_back(D->isInline());
123706f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
123806f32e7eSjoerg   Record.AddSourceLocation(D->getRBraceLoc());
123906f32e7eSjoerg 
124006f32e7eSjoerg   if (D->isOriginalNamespace())
124106f32e7eSjoerg     Record.AddDeclRef(D->getAnonymousNamespace());
124206f32e7eSjoerg   Code = serialization::DECL_NAMESPACE;
124306f32e7eSjoerg 
124406f32e7eSjoerg   if (Writer.hasChain() && D->isAnonymousNamespace() &&
124506f32e7eSjoerg       D == D->getMostRecentDecl()) {
124606f32e7eSjoerg     // This is a most recent reopening of the anonymous namespace. If its parent
124706f32e7eSjoerg     // is in a previous PCH (or is the TU), mark that parent for update, because
124806f32e7eSjoerg     // the original namespace always points to the latest re-opening of its
124906f32e7eSjoerg     // anonymous namespace.
125006f32e7eSjoerg     Decl *Parent = cast<Decl>(
125106f32e7eSjoerg         D->getParent()->getRedeclContext()->getPrimaryContext());
125206f32e7eSjoerg     if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
125306f32e7eSjoerg       Writer.DeclUpdates[Parent].push_back(
125406f32e7eSjoerg           ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
125506f32e7eSjoerg     }
125606f32e7eSjoerg   }
125706f32e7eSjoerg }
125806f32e7eSjoerg 
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)125906f32e7eSjoerg void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
126006f32e7eSjoerg   VisitRedeclarable(D);
126106f32e7eSjoerg   VisitNamedDecl(D);
126206f32e7eSjoerg   Record.AddSourceLocation(D->getNamespaceLoc());
126306f32e7eSjoerg   Record.AddSourceLocation(D->getTargetNameLoc());
126406f32e7eSjoerg   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
126506f32e7eSjoerg   Record.AddDeclRef(D->getNamespace());
126606f32e7eSjoerg   Code = serialization::DECL_NAMESPACE_ALIAS;
126706f32e7eSjoerg }
126806f32e7eSjoerg 
VisitUsingDecl(UsingDecl * D)126906f32e7eSjoerg void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
127006f32e7eSjoerg   VisitNamedDecl(D);
127106f32e7eSjoerg   Record.AddSourceLocation(D->getUsingLoc());
127206f32e7eSjoerg   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
127306f32e7eSjoerg   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
127406f32e7eSjoerg   Record.AddDeclRef(D->FirstUsingShadow.getPointer());
127506f32e7eSjoerg   Record.push_back(D->hasTypename());
127606f32e7eSjoerg   Record.AddDeclRef(Context.getInstantiatedFromUsingDecl(D));
127706f32e7eSjoerg   Code = serialization::DECL_USING;
127806f32e7eSjoerg }
127906f32e7eSjoerg 
VisitUsingPackDecl(UsingPackDecl * D)128006f32e7eSjoerg void ASTDeclWriter::VisitUsingPackDecl(UsingPackDecl *D) {
128106f32e7eSjoerg   Record.push_back(D->NumExpansions);
128206f32e7eSjoerg   VisitNamedDecl(D);
128306f32e7eSjoerg   Record.AddDeclRef(D->getInstantiatedFromUsingDecl());
128406f32e7eSjoerg   for (auto *E : D->expansions())
128506f32e7eSjoerg     Record.AddDeclRef(E);
128606f32e7eSjoerg   Code = serialization::DECL_USING_PACK;
128706f32e7eSjoerg }
128806f32e7eSjoerg 
VisitUsingShadowDecl(UsingShadowDecl * D)128906f32e7eSjoerg void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
129006f32e7eSjoerg   VisitRedeclarable(D);
129106f32e7eSjoerg   VisitNamedDecl(D);
129206f32e7eSjoerg   Record.AddDeclRef(D->getTargetDecl());
129306f32e7eSjoerg   Record.push_back(D->getIdentifierNamespace());
129406f32e7eSjoerg   Record.AddDeclRef(D->UsingOrNextShadow);
129506f32e7eSjoerg   Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
129606f32e7eSjoerg   Code = serialization::DECL_USING_SHADOW;
129706f32e7eSjoerg }
129806f32e7eSjoerg 
VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl * D)129906f32e7eSjoerg void ASTDeclWriter::VisitConstructorUsingShadowDecl(
130006f32e7eSjoerg     ConstructorUsingShadowDecl *D) {
130106f32e7eSjoerg   VisitUsingShadowDecl(D);
130206f32e7eSjoerg   Record.AddDeclRef(D->NominatedBaseClassShadowDecl);
130306f32e7eSjoerg   Record.AddDeclRef(D->ConstructedBaseClassShadowDecl);
130406f32e7eSjoerg   Record.push_back(D->IsVirtual);
130506f32e7eSjoerg   Code = serialization::DECL_CONSTRUCTOR_USING_SHADOW;
130606f32e7eSjoerg }
130706f32e7eSjoerg 
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)130806f32e7eSjoerg void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
130906f32e7eSjoerg   VisitNamedDecl(D);
131006f32e7eSjoerg   Record.AddSourceLocation(D->getUsingLoc());
131106f32e7eSjoerg   Record.AddSourceLocation(D->getNamespaceKeyLocation());
131206f32e7eSjoerg   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
131306f32e7eSjoerg   Record.AddDeclRef(D->getNominatedNamespace());
131406f32e7eSjoerg   Record.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()));
131506f32e7eSjoerg   Code = serialization::DECL_USING_DIRECTIVE;
131606f32e7eSjoerg }
131706f32e7eSjoerg 
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)131806f32e7eSjoerg void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
131906f32e7eSjoerg   VisitValueDecl(D);
132006f32e7eSjoerg   Record.AddSourceLocation(D->getUsingLoc());
132106f32e7eSjoerg   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
132206f32e7eSjoerg   Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
132306f32e7eSjoerg   Record.AddSourceLocation(D->getEllipsisLoc());
132406f32e7eSjoerg   Code = serialization::DECL_UNRESOLVED_USING_VALUE;
132506f32e7eSjoerg }
132606f32e7eSjoerg 
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)132706f32e7eSjoerg void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
132806f32e7eSjoerg                                                UnresolvedUsingTypenameDecl *D) {
132906f32e7eSjoerg   VisitTypeDecl(D);
133006f32e7eSjoerg   Record.AddSourceLocation(D->getTypenameLoc());
133106f32e7eSjoerg   Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
133206f32e7eSjoerg   Record.AddSourceLocation(D->getEllipsisLoc());
133306f32e7eSjoerg   Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
133406f32e7eSjoerg }
133506f32e7eSjoerg 
VisitCXXRecordDecl(CXXRecordDecl * D)133606f32e7eSjoerg void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
133706f32e7eSjoerg   VisitRecordDecl(D);
133806f32e7eSjoerg 
133906f32e7eSjoerg   enum {
134006f32e7eSjoerg     CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
134106f32e7eSjoerg   };
134206f32e7eSjoerg   if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
134306f32e7eSjoerg     Record.push_back(CXXRecTemplate);
134406f32e7eSjoerg     Record.AddDeclRef(TemplD);
134506f32e7eSjoerg   } else if (MemberSpecializationInfo *MSInfo
134606f32e7eSjoerg                = D->getMemberSpecializationInfo()) {
134706f32e7eSjoerg     Record.push_back(CXXRecMemberSpecialization);
134806f32e7eSjoerg     Record.AddDeclRef(MSInfo->getInstantiatedFrom());
134906f32e7eSjoerg     Record.push_back(MSInfo->getTemplateSpecializationKind());
135006f32e7eSjoerg     Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
135106f32e7eSjoerg   } else {
135206f32e7eSjoerg     Record.push_back(CXXRecNotTemplate);
135306f32e7eSjoerg   }
135406f32e7eSjoerg 
135506f32e7eSjoerg   Record.push_back(D->isThisDeclarationADefinition());
135606f32e7eSjoerg   if (D->isThisDeclarationADefinition())
135706f32e7eSjoerg     Record.AddCXXDefinitionData(D);
135806f32e7eSjoerg 
135906f32e7eSjoerg   // Store (what we currently believe to be) the key function to avoid
136006f32e7eSjoerg   // deserializing every method so we can compute it.
136106f32e7eSjoerg   if (D->isCompleteDefinition())
136206f32e7eSjoerg     Record.AddDeclRef(Context.getCurrentKeyFunction(D));
136306f32e7eSjoerg 
136406f32e7eSjoerg   Code = serialization::DECL_CXX_RECORD;
136506f32e7eSjoerg }
136606f32e7eSjoerg 
VisitCXXMethodDecl(CXXMethodDecl * D)136706f32e7eSjoerg void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
136806f32e7eSjoerg   VisitFunctionDecl(D);
136906f32e7eSjoerg   if (D->isCanonicalDecl()) {
137006f32e7eSjoerg     Record.push_back(D->size_overridden_methods());
137106f32e7eSjoerg     for (const CXXMethodDecl *MD : D->overridden_methods())
137206f32e7eSjoerg       Record.AddDeclRef(MD);
137306f32e7eSjoerg   } else {
137406f32e7eSjoerg     // We only need to record overridden methods once for the canonical decl.
137506f32e7eSjoerg     Record.push_back(0);
137606f32e7eSjoerg   }
137706f32e7eSjoerg 
137806f32e7eSjoerg   if (D->getDeclContext() == D->getLexicalDeclContext() &&
137906f32e7eSjoerg       D->getFirstDecl() == D->getMostRecentDecl() &&
138006f32e7eSjoerg       !D->isInvalidDecl() &&
138106f32e7eSjoerg       !D->hasAttrs() &&
138206f32e7eSjoerg       !D->isTopLevelDeclInObjCContainer() &&
138306f32e7eSjoerg       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
138406f32e7eSjoerg       !D->hasExtInfo() &&
138506f32e7eSjoerg       !D->hasInheritedPrototype() &&
138606f32e7eSjoerg       D->hasWrittenPrototype())
138706f32e7eSjoerg     AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
138806f32e7eSjoerg 
138906f32e7eSjoerg   Code = serialization::DECL_CXX_METHOD;
139006f32e7eSjoerg }
139106f32e7eSjoerg 
VisitCXXConstructorDecl(CXXConstructorDecl * D)139206f32e7eSjoerg void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1393*13fbcb42Sjoerg   Record.push_back(D->getTrailingAllocKind());
139406f32e7eSjoerg   addExplicitSpecifier(D->getExplicitSpecifier(), Record);
139506f32e7eSjoerg   if (auto Inherited = D->getInheritedConstructor()) {
139606f32e7eSjoerg     Record.AddDeclRef(Inherited.getShadowDecl());
139706f32e7eSjoerg     Record.AddDeclRef(Inherited.getConstructor());
139806f32e7eSjoerg   }
139906f32e7eSjoerg 
140006f32e7eSjoerg   VisitCXXMethodDecl(D);
140106f32e7eSjoerg   Code = serialization::DECL_CXX_CONSTRUCTOR;
140206f32e7eSjoerg }
140306f32e7eSjoerg 
VisitCXXDestructorDecl(CXXDestructorDecl * D)140406f32e7eSjoerg void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
140506f32e7eSjoerg   VisitCXXMethodDecl(D);
140606f32e7eSjoerg 
140706f32e7eSjoerg   Record.AddDeclRef(D->getOperatorDelete());
140806f32e7eSjoerg   if (D->getOperatorDelete())
140906f32e7eSjoerg     Record.AddStmt(D->getOperatorDeleteThisArg());
141006f32e7eSjoerg 
141106f32e7eSjoerg   Code = serialization::DECL_CXX_DESTRUCTOR;
141206f32e7eSjoerg }
141306f32e7eSjoerg 
VisitCXXConversionDecl(CXXConversionDecl * D)141406f32e7eSjoerg void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
141506f32e7eSjoerg   addExplicitSpecifier(D->getExplicitSpecifier(), Record);
141606f32e7eSjoerg   VisitCXXMethodDecl(D);
141706f32e7eSjoerg   Code = serialization::DECL_CXX_CONVERSION;
141806f32e7eSjoerg }
141906f32e7eSjoerg 
VisitImportDecl(ImportDecl * D)142006f32e7eSjoerg void ASTDeclWriter::VisitImportDecl(ImportDecl *D) {
142106f32e7eSjoerg   VisitDecl(D);
142206f32e7eSjoerg   Record.push_back(Writer.getSubmoduleID(D->getImportedModule()));
142306f32e7eSjoerg   ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
142406f32e7eSjoerg   Record.push_back(!IdentifierLocs.empty());
142506f32e7eSjoerg   if (IdentifierLocs.empty()) {
142606f32e7eSjoerg     Record.AddSourceLocation(D->getEndLoc());
142706f32e7eSjoerg     Record.push_back(1);
142806f32e7eSjoerg   } else {
142906f32e7eSjoerg     for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
143006f32e7eSjoerg       Record.AddSourceLocation(IdentifierLocs[I]);
143106f32e7eSjoerg     Record.push_back(IdentifierLocs.size());
143206f32e7eSjoerg   }
143306f32e7eSjoerg   // Note: the number of source locations must always be the last element in
143406f32e7eSjoerg   // the record.
143506f32e7eSjoerg   Code = serialization::DECL_IMPORT;
143606f32e7eSjoerg }
143706f32e7eSjoerg 
VisitAccessSpecDecl(AccessSpecDecl * D)143806f32e7eSjoerg void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
143906f32e7eSjoerg   VisitDecl(D);
144006f32e7eSjoerg   Record.AddSourceLocation(D->getColonLoc());
144106f32e7eSjoerg   Code = serialization::DECL_ACCESS_SPEC;
144206f32e7eSjoerg }
144306f32e7eSjoerg 
VisitFriendDecl(FriendDecl * D)144406f32e7eSjoerg void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
144506f32e7eSjoerg   // Record the number of friend type template parameter lists here
144606f32e7eSjoerg   // so as to simplify memory allocation during deserialization.
144706f32e7eSjoerg   Record.push_back(D->NumTPLists);
144806f32e7eSjoerg   VisitDecl(D);
144906f32e7eSjoerg   bool hasFriendDecl = D->Friend.is<NamedDecl*>();
145006f32e7eSjoerg   Record.push_back(hasFriendDecl);
145106f32e7eSjoerg   if (hasFriendDecl)
145206f32e7eSjoerg     Record.AddDeclRef(D->getFriendDecl());
145306f32e7eSjoerg   else
145406f32e7eSjoerg     Record.AddTypeSourceInfo(D->getFriendType());
145506f32e7eSjoerg   for (unsigned i = 0; i < D->NumTPLists; ++i)
145606f32e7eSjoerg     Record.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i));
145706f32e7eSjoerg   Record.AddDeclRef(D->getNextFriend());
145806f32e7eSjoerg   Record.push_back(D->UnsupportedFriend);
145906f32e7eSjoerg   Record.AddSourceLocation(D->FriendLoc);
146006f32e7eSjoerg   Code = serialization::DECL_FRIEND;
146106f32e7eSjoerg }
146206f32e7eSjoerg 
VisitFriendTemplateDecl(FriendTemplateDecl * D)146306f32e7eSjoerg void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
146406f32e7eSjoerg   VisitDecl(D);
146506f32e7eSjoerg   Record.push_back(D->getNumTemplateParameters());
146606f32e7eSjoerg   for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
146706f32e7eSjoerg     Record.AddTemplateParameterList(D->getTemplateParameterList(i));
146806f32e7eSjoerg   Record.push_back(D->getFriendDecl() != nullptr);
146906f32e7eSjoerg   if (D->getFriendDecl())
147006f32e7eSjoerg     Record.AddDeclRef(D->getFriendDecl());
147106f32e7eSjoerg   else
147206f32e7eSjoerg     Record.AddTypeSourceInfo(D->getFriendType());
147306f32e7eSjoerg   Record.AddSourceLocation(D->getFriendLoc());
147406f32e7eSjoerg   Code = serialization::DECL_FRIEND_TEMPLATE;
147506f32e7eSjoerg }
147606f32e7eSjoerg 
VisitTemplateDecl(TemplateDecl * D)147706f32e7eSjoerg void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
147806f32e7eSjoerg   VisitNamedDecl(D);
147906f32e7eSjoerg 
148006f32e7eSjoerg   Record.AddDeclRef(D->getTemplatedDecl());
148106f32e7eSjoerg   Record.AddTemplateParameterList(D->getTemplateParameters());
148206f32e7eSjoerg }
148306f32e7eSjoerg 
VisitConceptDecl(ConceptDecl * D)148406f32e7eSjoerg void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
148506f32e7eSjoerg   VisitTemplateDecl(D);
148606f32e7eSjoerg   Record.AddStmt(D->getConstraintExpr());
148706f32e7eSjoerg   Code = serialization::DECL_CONCEPT;
148806f32e7eSjoerg }
148906f32e7eSjoerg 
VisitRequiresExprBodyDecl(RequiresExprBodyDecl * D)1490*13fbcb42Sjoerg void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
1491*13fbcb42Sjoerg   Code = serialization::DECL_REQUIRES_EXPR_BODY;
1492*13fbcb42Sjoerg }
1493*13fbcb42Sjoerg 
VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl * D)149406f32e7eSjoerg void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
149506f32e7eSjoerg   VisitRedeclarable(D);
149606f32e7eSjoerg 
149706f32e7eSjoerg   // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
149806f32e7eSjoerg   // getCommonPtr() can be used while this is still initializing.
149906f32e7eSjoerg   if (D->isFirstDecl()) {
150006f32e7eSjoerg     // This declaration owns the 'common' pointer, so serialize that data now.
150106f32e7eSjoerg     Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
150206f32e7eSjoerg     if (D->getInstantiatedFromMemberTemplate())
150306f32e7eSjoerg       Record.push_back(D->isMemberSpecialization());
150406f32e7eSjoerg   }
150506f32e7eSjoerg 
150606f32e7eSjoerg   VisitTemplateDecl(D);
150706f32e7eSjoerg   Record.push_back(D->getIdentifierNamespace());
150806f32e7eSjoerg }
150906f32e7eSjoerg 
VisitClassTemplateDecl(ClassTemplateDecl * D)151006f32e7eSjoerg void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
151106f32e7eSjoerg   VisitRedeclarableTemplateDecl(D);
151206f32e7eSjoerg 
151306f32e7eSjoerg   if (D->isFirstDecl())
151406f32e7eSjoerg     AddTemplateSpecializations(D);
151506f32e7eSjoerg   Code = serialization::DECL_CLASS_TEMPLATE;
151606f32e7eSjoerg }
151706f32e7eSjoerg 
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)151806f32e7eSjoerg void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
151906f32e7eSjoerg                                            ClassTemplateSpecializationDecl *D) {
152006f32e7eSjoerg   RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
152106f32e7eSjoerg 
152206f32e7eSjoerg   VisitCXXRecordDecl(D);
152306f32e7eSjoerg 
152406f32e7eSjoerg   llvm::PointerUnion<ClassTemplateDecl *,
152506f32e7eSjoerg                      ClassTemplatePartialSpecializationDecl *> InstFrom
152606f32e7eSjoerg     = D->getSpecializedTemplateOrPartial();
152706f32e7eSjoerg   if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
152806f32e7eSjoerg     Record.AddDeclRef(InstFromD);
152906f32e7eSjoerg   } else {
153006f32e7eSjoerg     Record.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>());
153106f32e7eSjoerg     Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
153206f32e7eSjoerg   }
153306f32e7eSjoerg 
153406f32e7eSjoerg   Record.AddTemplateArgumentList(&D->getTemplateArgs());
153506f32e7eSjoerg   Record.AddSourceLocation(D->getPointOfInstantiation());
153606f32e7eSjoerg   Record.push_back(D->getSpecializationKind());
153706f32e7eSjoerg   Record.push_back(D->isCanonicalDecl());
153806f32e7eSjoerg 
153906f32e7eSjoerg   if (D->isCanonicalDecl()) {
154006f32e7eSjoerg     // When reading, we'll add it to the folding set of the following template.
154106f32e7eSjoerg     Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
154206f32e7eSjoerg   }
154306f32e7eSjoerg 
154406f32e7eSjoerg   // Explicit info.
154506f32e7eSjoerg   Record.AddTypeSourceInfo(D->getTypeAsWritten());
154606f32e7eSjoerg   if (D->getTypeAsWritten()) {
154706f32e7eSjoerg     Record.AddSourceLocation(D->getExternLoc());
154806f32e7eSjoerg     Record.AddSourceLocation(D->getTemplateKeywordLoc());
154906f32e7eSjoerg   }
155006f32e7eSjoerg 
155106f32e7eSjoerg   Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
155206f32e7eSjoerg }
155306f32e7eSjoerg 
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)155406f32e7eSjoerg void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
155506f32e7eSjoerg                                     ClassTemplatePartialSpecializationDecl *D) {
155606f32e7eSjoerg   Record.AddTemplateParameterList(D->getTemplateParameters());
155706f32e7eSjoerg   Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
155806f32e7eSjoerg 
1559*13fbcb42Sjoerg   VisitClassTemplateSpecializationDecl(D);
1560*13fbcb42Sjoerg 
156106f32e7eSjoerg   // These are read/set from/to the first declaration.
156206f32e7eSjoerg   if (D->getPreviousDecl() == nullptr) {
156306f32e7eSjoerg     Record.AddDeclRef(D->getInstantiatedFromMember());
156406f32e7eSjoerg     Record.push_back(D->isMemberSpecialization());
156506f32e7eSjoerg   }
156606f32e7eSjoerg 
156706f32e7eSjoerg   Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
156806f32e7eSjoerg }
156906f32e7eSjoerg 
VisitVarTemplateDecl(VarTemplateDecl * D)157006f32e7eSjoerg void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
157106f32e7eSjoerg   VisitRedeclarableTemplateDecl(D);
157206f32e7eSjoerg 
157306f32e7eSjoerg   if (D->isFirstDecl())
157406f32e7eSjoerg     AddTemplateSpecializations(D);
157506f32e7eSjoerg   Code = serialization::DECL_VAR_TEMPLATE;
157606f32e7eSjoerg }
157706f32e7eSjoerg 
VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * D)157806f32e7eSjoerg void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
157906f32e7eSjoerg     VarTemplateSpecializationDecl *D) {
158006f32e7eSjoerg   RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
158106f32e7eSjoerg 
158206f32e7eSjoerg   VisitVarDecl(D);
158306f32e7eSjoerg 
158406f32e7eSjoerg   llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
158506f32e7eSjoerg   InstFrom = D->getSpecializedTemplateOrPartial();
158606f32e7eSjoerg   if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
158706f32e7eSjoerg     Record.AddDeclRef(InstFromD);
158806f32e7eSjoerg   } else {
158906f32e7eSjoerg     Record.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>());
159006f32e7eSjoerg     Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
159106f32e7eSjoerg   }
159206f32e7eSjoerg 
159306f32e7eSjoerg   // Explicit info.
159406f32e7eSjoerg   Record.AddTypeSourceInfo(D->getTypeAsWritten());
159506f32e7eSjoerg   if (D->getTypeAsWritten()) {
159606f32e7eSjoerg     Record.AddSourceLocation(D->getExternLoc());
159706f32e7eSjoerg     Record.AddSourceLocation(D->getTemplateKeywordLoc());
159806f32e7eSjoerg   }
159906f32e7eSjoerg 
160006f32e7eSjoerg   Record.AddTemplateArgumentList(&D->getTemplateArgs());
160106f32e7eSjoerg   Record.AddSourceLocation(D->getPointOfInstantiation());
160206f32e7eSjoerg   Record.push_back(D->getSpecializationKind());
160306f32e7eSjoerg   Record.push_back(D->IsCompleteDefinition);
160406f32e7eSjoerg   Record.push_back(D->isCanonicalDecl());
160506f32e7eSjoerg 
160606f32e7eSjoerg   if (D->isCanonicalDecl()) {
160706f32e7eSjoerg     // When reading, we'll add it to the folding set of the following template.
160806f32e7eSjoerg     Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
160906f32e7eSjoerg   }
161006f32e7eSjoerg 
161106f32e7eSjoerg   Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
161206f32e7eSjoerg }
161306f32e7eSjoerg 
VisitVarTemplatePartialSpecializationDecl(VarTemplatePartialSpecializationDecl * D)161406f32e7eSjoerg void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
161506f32e7eSjoerg     VarTemplatePartialSpecializationDecl *D) {
161606f32e7eSjoerg   Record.AddTemplateParameterList(D->getTemplateParameters());
161706f32e7eSjoerg   Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
161806f32e7eSjoerg 
1619*13fbcb42Sjoerg   VisitVarTemplateSpecializationDecl(D);
1620*13fbcb42Sjoerg 
162106f32e7eSjoerg   // These are read/set from/to the first declaration.
162206f32e7eSjoerg   if (D->getPreviousDecl() == nullptr) {
162306f32e7eSjoerg     Record.AddDeclRef(D->getInstantiatedFromMember());
162406f32e7eSjoerg     Record.push_back(D->isMemberSpecialization());
162506f32e7eSjoerg   }
162606f32e7eSjoerg 
162706f32e7eSjoerg   Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
162806f32e7eSjoerg }
162906f32e7eSjoerg 
VisitClassScopeFunctionSpecializationDecl(ClassScopeFunctionSpecializationDecl * D)163006f32e7eSjoerg void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
163106f32e7eSjoerg                                     ClassScopeFunctionSpecializationDecl *D) {
163206f32e7eSjoerg   VisitDecl(D);
163306f32e7eSjoerg   Record.AddDeclRef(D->getSpecialization());
163406f32e7eSjoerg   Record.push_back(D->hasExplicitTemplateArgs());
163506f32e7eSjoerg   if (D->hasExplicitTemplateArgs())
163606f32e7eSjoerg     Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
163706f32e7eSjoerg   Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
163806f32e7eSjoerg }
163906f32e7eSjoerg 
164006f32e7eSjoerg 
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)164106f32e7eSjoerg void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
164206f32e7eSjoerg   VisitRedeclarableTemplateDecl(D);
164306f32e7eSjoerg 
164406f32e7eSjoerg   if (D->isFirstDecl())
164506f32e7eSjoerg     AddTemplateSpecializations(D);
164606f32e7eSjoerg   Code = serialization::DECL_FUNCTION_TEMPLATE;
164706f32e7eSjoerg }
164806f32e7eSjoerg 
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)164906f32e7eSjoerg void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
1650*13fbcb42Sjoerg   Record.push_back(D->hasTypeConstraint());
165106f32e7eSjoerg   VisitTypeDecl(D);
165206f32e7eSjoerg 
165306f32e7eSjoerg   Record.push_back(D->wasDeclaredWithTypename());
1654*13fbcb42Sjoerg 
1655*13fbcb42Sjoerg   const TypeConstraint *TC = D->getTypeConstraint();
1656*13fbcb42Sjoerg   Record.push_back(TC != nullptr);
1657*13fbcb42Sjoerg   if (TC) {
1658*13fbcb42Sjoerg     Record.AddNestedNameSpecifierLoc(TC->getNestedNameSpecifierLoc());
1659*13fbcb42Sjoerg     Record.AddDeclarationNameInfo(TC->getConceptNameInfo());
1660*13fbcb42Sjoerg     Record.AddDeclRef(TC->getNamedConcept());
1661*13fbcb42Sjoerg     Record.push_back(TC->getTemplateArgsAsWritten() != nullptr);
1662*13fbcb42Sjoerg     if (TC->getTemplateArgsAsWritten())
1663*13fbcb42Sjoerg       Record.AddASTTemplateArgumentListInfo(TC->getTemplateArgsAsWritten());
1664*13fbcb42Sjoerg     Record.AddStmt(TC->getImmediatelyDeclaredConstraint());
1665*13fbcb42Sjoerg     Record.push_back(D->isExpandedParameterPack());
1666*13fbcb42Sjoerg     if (D->isExpandedParameterPack())
1667*13fbcb42Sjoerg       Record.push_back(D->getNumExpansionParameters());
1668*13fbcb42Sjoerg   }
1669*13fbcb42Sjoerg 
167006f32e7eSjoerg   bool OwnsDefaultArg = D->hasDefaultArgument() &&
167106f32e7eSjoerg                         !D->defaultArgumentWasInherited();
167206f32e7eSjoerg   Record.push_back(OwnsDefaultArg);
167306f32e7eSjoerg   if (OwnsDefaultArg)
167406f32e7eSjoerg     Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
167506f32e7eSjoerg 
167606f32e7eSjoerg   Code = serialization::DECL_TEMPLATE_TYPE_PARM;
167706f32e7eSjoerg }
167806f32e7eSjoerg 
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)167906f32e7eSjoerg void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
168006f32e7eSjoerg   // For an expanded parameter pack, record the number of expansion types here
168106f32e7eSjoerg   // so that it's easier for deserialization to allocate the right amount of
168206f32e7eSjoerg   // memory.
1683*13fbcb42Sjoerg   Expr *TypeConstraint = D->getPlaceholderTypeConstraint();
1684*13fbcb42Sjoerg   Record.push_back(!!TypeConstraint);
168506f32e7eSjoerg   if (D->isExpandedParameterPack())
168606f32e7eSjoerg     Record.push_back(D->getNumExpansionTypes());
168706f32e7eSjoerg 
168806f32e7eSjoerg   VisitDeclaratorDecl(D);
168906f32e7eSjoerg   // TemplateParmPosition.
169006f32e7eSjoerg   Record.push_back(D->getDepth());
169106f32e7eSjoerg   Record.push_back(D->getPosition());
1692*13fbcb42Sjoerg   if (TypeConstraint)
1693*13fbcb42Sjoerg     Record.AddStmt(TypeConstraint);
169406f32e7eSjoerg 
169506f32e7eSjoerg   if (D->isExpandedParameterPack()) {
169606f32e7eSjoerg     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
169706f32e7eSjoerg       Record.AddTypeRef(D->getExpansionType(I));
169806f32e7eSjoerg       Record.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I));
169906f32e7eSjoerg     }
170006f32e7eSjoerg 
170106f32e7eSjoerg     Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
170206f32e7eSjoerg   } else {
170306f32e7eSjoerg     // Rest of NonTypeTemplateParmDecl.
170406f32e7eSjoerg     Record.push_back(D->isParameterPack());
170506f32e7eSjoerg     bool OwnsDefaultArg = D->hasDefaultArgument() &&
170606f32e7eSjoerg                           !D->defaultArgumentWasInherited();
170706f32e7eSjoerg     Record.push_back(OwnsDefaultArg);
170806f32e7eSjoerg     if (OwnsDefaultArg)
170906f32e7eSjoerg       Record.AddStmt(D->getDefaultArgument());
171006f32e7eSjoerg     Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
171106f32e7eSjoerg   }
171206f32e7eSjoerg }
171306f32e7eSjoerg 
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)171406f32e7eSjoerg void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
171506f32e7eSjoerg   // For an expanded parameter pack, record the number of expansion types here
171606f32e7eSjoerg   // so that it's easier for deserialization to allocate the right amount of
171706f32e7eSjoerg   // memory.
171806f32e7eSjoerg   if (D->isExpandedParameterPack())
171906f32e7eSjoerg     Record.push_back(D->getNumExpansionTemplateParameters());
172006f32e7eSjoerg 
172106f32e7eSjoerg   VisitTemplateDecl(D);
172206f32e7eSjoerg   // TemplateParmPosition.
172306f32e7eSjoerg   Record.push_back(D->getDepth());
172406f32e7eSjoerg   Record.push_back(D->getPosition());
172506f32e7eSjoerg 
172606f32e7eSjoerg   if (D->isExpandedParameterPack()) {
172706f32e7eSjoerg     for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
172806f32e7eSjoerg          I != N; ++I)
172906f32e7eSjoerg       Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I));
173006f32e7eSjoerg     Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
173106f32e7eSjoerg   } else {
173206f32e7eSjoerg     // Rest of TemplateTemplateParmDecl.
173306f32e7eSjoerg     Record.push_back(D->isParameterPack());
173406f32e7eSjoerg     bool OwnsDefaultArg = D->hasDefaultArgument() &&
173506f32e7eSjoerg                           !D->defaultArgumentWasInherited();
173606f32e7eSjoerg     Record.push_back(OwnsDefaultArg);
173706f32e7eSjoerg     if (OwnsDefaultArg)
173806f32e7eSjoerg       Record.AddTemplateArgumentLoc(D->getDefaultArgument());
173906f32e7eSjoerg     Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
174006f32e7eSjoerg   }
174106f32e7eSjoerg }
174206f32e7eSjoerg 
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)174306f32e7eSjoerg void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
174406f32e7eSjoerg   VisitRedeclarableTemplateDecl(D);
174506f32e7eSjoerg   Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
174606f32e7eSjoerg }
174706f32e7eSjoerg 
VisitStaticAssertDecl(StaticAssertDecl * D)174806f32e7eSjoerg void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
174906f32e7eSjoerg   VisitDecl(D);
175006f32e7eSjoerg   Record.AddStmt(D->getAssertExpr());
175106f32e7eSjoerg   Record.push_back(D->isFailed());
175206f32e7eSjoerg   Record.AddStmt(D->getMessage());
175306f32e7eSjoerg   Record.AddSourceLocation(D->getRParenLoc());
175406f32e7eSjoerg   Code = serialization::DECL_STATIC_ASSERT;
175506f32e7eSjoerg }
175606f32e7eSjoerg 
175706f32e7eSjoerg /// Emit the DeclContext part of a declaration context decl.
VisitDeclContext(DeclContext * DC)175806f32e7eSjoerg void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
175906f32e7eSjoerg   Record.AddOffset(Writer.WriteDeclContextLexicalBlock(Context, DC));
176006f32e7eSjoerg   Record.AddOffset(Writer.WriteDeclContextVisibleBlock(Context, DC));
176106f32e7eSjoerg }
176206f32e7eSjoerg 
getFirstLocalDecl(const Decl * D)176306f32e7eSjoerg const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
176406f32e7eSjoerg   assert(IsLocalDecl(D) && "expected a local declaration");
176506f32e7eSjoerg 
176606f32e7eSjoerg   const Decl *Canon = D->getCanonicalDecl();
176706f32e7eSjoerg   if (IsLocalDecl(Canon))
176806f32e7eSjoerg     return Canon;
176906f32e7eSjoerg 
177006f32e7eSjoerg   const Decl *&CacheEntry = FirstLocalDeclCache[Canon];
177106f32e7eSjoerg   if (CacheEntry)
177206f32e7eSjoerg     return CacheEntry;
177306f32e7eSjoerg 
177406f32e7eSjoerg   for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl())
177506f32e7eSjoerg     if (IsLocalDecl(Redecl))
177606f32e7eSjoerg       D = Redecl;
177706f32e7eSjoerg   return CacheEntry = D;
177806f32e7eSjoerg }
177906f32e7eSjoerg 
178006f32e7eSjoerg template <typename T>
VisitRedeclarable(Redeclarable<T> * D)178106f32e7eSjoerg void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
178206f32e7eSjoerg   T *First = D->getFirstDecl();
178306f32e7eSjoerg   T *MostRecent = First->getMostRecentDecl();
178406f32e7eSjoerg   T *DAsT = static_cast<T *>(D);
178506f32e7eSjoerg   if (MostRecent != First) {
178606f32e7eSjoerg     assert(isRedeclarableDeclKind(DAsT->getKind()) &&
178706f32e7eSjoerg            "Not considered redeclarable?");
178806f32e7eSjoerg 
178906f32e7eSjoerg     Record.AddDeclRef(First);
179006f32e7eSjoerg 
179106f32e7eSjoerg     // Write out a list of local redeclarations of this declaration if it's the
179206f32e7eSjoerg     // first local declaration in the chain.
179306f32e7eSjoerg     const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT);
179406f32e7eSjoerg     if (DAsT == FirstLocal) {
179506f32e7eSjoerg       // Emit a list of all imported first declarations so that we can be sure
179606f32e7eSjoerg       // that all redeclarations visible to this module are before D in the
179706f32e7eSjoerg       // redecl chain.
179806f32e7eSjoerg       unsigned I = Record.size();
179906f32e7eSjoerg       Record.push_back(0);
180006f32e7eSjoerg       if (Writer.Chain)
180106f32e7eSjoerg         AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
180206f32e7eSjoerg       // This is the number of imported first declarations + 1.
180306f32e7eSjoerg       Record[I] = Record.size() - I;
180406f32e7eSjoerg 
180506f32e7eSjoerg       // Collect the set of local redeclarations of this declaration, from
180606f32e7eSjoerg       // newest to oldest.
180706f32e7eSjoerg       ASTWriter::RecordData LocalRedecls;
180806f32e7eSjoerg       ASTRecordWriter LocalRedeclWriter(Record, LocalRedecls);
180906f32e7eSjoerg       for (const Decl *Prev = FirstLocal->getMostRecentDecl();
181006f32e7eSjoerg            Prev != FirstLocal; Prev = Prev->getPreviousDecl())
181106f32e7eSjoerg         if (!Prev->isFromASTFile())
181206f32e7eSjoerg           LocalRedeclWriter.AddDeclRef(Prev);
181306f32e7eSjoerg 
181406f32e7eSjoerg       // If we have any redecls, write them now as a separate record preceding
181506f32e7eSjoerg       // the declaration itself.
181606f32e7eSjoerg       if (LocalRedecls.empty())
181706f32e7eSjoerg         Record.push_back(0);
181806f32e7eSjoerg       else
181906f32e7eSjoerg         Record.AddOffset(LocalRedeclWriter.Emit(LOCAL_REDECLARATIONS));
182006f32e7eSjoerg     } else {
182106f32e7eSjoerg       Record.push_back(0);
182206f32e7eSjoerg       Record.AddDeclRef(FirstLocal);
182306f32e7eSjoerg     }
182406f32e7eSjoerg 
182506f32e7eSjoerg     // Make sure that we serialize both the previous and the most-recent
182606f32e7eSjoerg     // declarations, which (transitively) ensures that all declarations in the
182706f32e7eSjoerg     // chain get serialized.
182806f32e7eSjoerg     //
182906f32e7eSjoerg     // FIXME: This is not correct; when we reach an imported declaration we
183006f32e7eSjoerg     // won't emit its previous declaration.
183106f32e7eSjoerg     (void)Writer.GetDeclRef(D->getPreviousDecl());
183206f32e7eSjoerg     (void)Writer.GetDeclRef(MostRecent);
183306f32e7eSjoerg   } else {
183406f32e7eSjoerg     // We use the sentinel value 0 to indicate an only declaration.
183506f32e7eSjoerg     Record.push_back(0);
183606f32e7eSjoerg   }
183706f32e7eSjoerg }
183806f32e7eSjoerg 
VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl * D)183906f32e7eSjoerg void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1840*13fbcb42Sjoerg   Record.writeOMPChildren(D->Data);
184106f32e7eSjoerg   VisitDecl(D);
184206f32e7eSjoerg   Code = serialization::DECL_OMP_THREADPRIVATE;
184306f32e7eSjoerg }
184406f32e7eSjoerg 
VisitOMPAllocateDecl(OMPAllocateDecl * D)184506f32e7eSjoerg void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1846*13fbcb42Sjoerg   Record.writeOMPChildren(D->Data);
184706f32e7eSjoerg   VisitDecl(D);
184806f32e7eSjoerg   Code = serialization::DECL_OMP_ALLOCATE;
184906f32e7eSjoerg }
185006f32e7eSjoerg 
VisitOMPRequiresDecl(OMPRequiresDecl * D)185106f32e7eSjoerg void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1852*13fbcb42Sjoerg   Record.writeOMPChildren(D->Data);
185306f32e7eSjoerg   VisitDecl(D);
185406f32e7eSjoerg   Code = serialization::DECL_OMP_REQUIRES;
185506f32e7eSjoerg }
185606f32e7eSjoerg 
VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl * D)185706f32e7eSjoerg void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
185806f32e7eSjoerg   VisitValueDecl(D);
185906f32e7eSjoerg   Record.AddSourceLocation(D->getBeginLoc());
186006f32e7eSjoerg   Record.AddStmt(D->getCombinerIn());
186106f32e7eSjoerg   Record.AddStmt(D->getCombinerOut());
186206f32e7eSjoerg   Record.AddStmt(D->getCombiner());
186306f32e7eSjoerg   Record.AddStmt(D->getInitOrig());
186406f32e7eSjoerg   Record.AddStmt(D->getInitPriv());
186506f32e7eSjoerg   Record.AddStmt(D->getInitializer());
186606f32e7eSjoerg   Record.push_back(D->getInitializerKind());
186706f32e7eSjoerg   Record.AddDeclRef(D->getPrevDeclInScope());
186806f32e7eSjoerg   Code = serialization::DECL_OMP_DECLARE_REDUCTION;
186906f32e7eSjoerg }
187006f32e7eSjoerg 
VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl * D)187106f32e7eSjoerg void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1872*13fbcb42Sjoerg   Record.writeOMPChildren(D->Data);
187306f32e7eSjoerg   VisitValueDecl(D);
187406f32e7eSjoerg   Record.AddDeclarationName(D->getVarName());
187506f32e7eSjoerg   Record.AddDeclRef(D->getPrevDeclInScope());
187606f32e7eSjoerg   Code = serialization::DECL_OMP_DECLARE_MAPPER;
187706f32e7eSjoerg }
187806f32e7eSjoerg 
VisitOMPCapturedExprDecl(OMPCapturedExprDecl * D)187906f32e7eSjoerg void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
188006f32e7eSjoerg   VisitVarDecl(D);
188106f32e7eSjoerg   Code = serialization::DECL_OMP_CAPTUREDEXPR;
188206f32e7eSjoerg }
188306f32e7eSjoerg 
188406f32e7eSjoerg //===----------------------------------------------------------------------===//
188506f32e7eSjoerg // ASTWriter Implementation
188606f32e7eSjoerg //===----------------------------------------------------------------------===//
188706f32e7eSjoerg 
WriteDeclAbbrevs()188806f32e7eSjoerg void ASTWriter::WriteDeclAbbrevs() {
188906f32e7eSjoerg   using namespace llvm;
189006f32e7eSjoerg 
189106f32e7eSjoerg   std::shared_ptr<BitCodeAbbrev> Abv;
189206f32e7eSjoerg 
189306f32e7eSjoerg   // Abbreviation for DECL_FIELD
189406f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
189506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
189606f32e7eSjoerg   // Decl
189706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
189806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
189906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
190006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
190106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
190206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
190306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
190406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
190506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // AccessSpecifier
190606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
190706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
190806f32e7eSjoerg   // NamedDecl
190906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
191006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
191106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
191206f32e7eSjoerg   // ValueDecl
191306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
191406f32e7eSjoerg   // DeclaratorDecl
191506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
191606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
191706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
191806f32e7eSjoerg   // FieldDecl
191906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
192006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
192106f32e7eSjoerg   // Type Source Info
192206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
192306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
192406f32e7eSjoerg   DeclFieldAbbrev = Stream.EmitAbbrev(std::move(Abv));
192506f32e7eSjoerg 
192606f32e7eSjoerg   // Abbreviation for DECL_OBJC_IVAR
192706f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
192806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
192906f32e7eSjoerg   // Decl
193006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
193106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
193206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
193306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
193406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
193506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
193606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
193706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
193806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // AccessSpecifier
193906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
194006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
194106f32e7eSjoerg   // NamedDecl
194206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
194306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
194406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
194506f32e7eSjoerg   // ValueDecl
194606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
194706f32e7eSjoerg   // DeclaratorDecl
194806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
194906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
195006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
195106f32e7eSjoerg   // FieldDecl
195206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
195306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
195406f32e7eSjoerg   // ObjC Ivar
195506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
195606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
195706f32e7eSjoerg   // Type Source Info
195806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
195906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
196006f32e7eSjoerg   DeclObjCIvarAbbrev = Stream.EmitAbbrev(std::move(Abv));
196106f32e7eSjoerg 
196206f32e7eSjoerg   // Abbreviation for DECL_ENUM
196306f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
196406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
196506f32e7eSjoerg   // Redeclarable
196606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
196706f32e7eSjoerg   // Decl
196806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
196906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
197006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
197106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
197206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
197306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
197406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
197506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
197606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
197706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
197806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
197906f32e7eSjoerg   // NamedDecl
198006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
198106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
198206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
198306f32e7eSjoerg   // TypeDecl
198406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
198506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
198606f32e7eSjoerg   // TagDecl
198706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
198806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getTagKind
198906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
199006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
199106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
199206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
199306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
199406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
199506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind
199606f32e7eSjoerg   // EnumDecl
199706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // AddTypeRef
199806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IntegerType
199906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getPromotionType
200006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getNumPositiveBits
200106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getNumNegativeBits
200206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScoped
200306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScopedUsingClassTag
200406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isFixed
200506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
200606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum
200706f32e7eSjoerg   // DC
200806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
200906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
201006f32e7eSjoerg   DeclEnumAbbrev = Stream.EmitAbbrev(std::move(Abv));
201106f32e7eSjoerg 
201206f32e7eSjoerg   // Abbreviation for DECL_RECORD
201306f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
201406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
201506f32e7eSjoerg   // Redeclarable
201606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
201706f32e7eSjoerg   // Decl
201806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
201906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
202006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
202106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
202206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
202306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
202406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
202506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
202606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
202706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
202806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
202906f32e7eSjoerg   // NamedDecl
203006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
203106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
203206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
203306f32e7eSjoerg   // TypeDecl
203406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
203506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
203606f32e7eSjoerg   // TagDecl
203706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
203806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getTagKind
203906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
204006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
204106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
204206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
204306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
204406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
204506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind
204606f32e7eSjoerg   // RecordDecl
204706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
204806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
204906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
205006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember
205106f32e7eSjoerg 
205206f32e7eSjoerg   // isNonTrivialToPrimitiveDefaultInitialize
205306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
205406f32e7eSjoerg   // isNonTrivialToPrimitiveCopy
205506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
205606f32e7eSjoerg   // isNonTrivialToPrimitiveDestroy
205706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
205806f32e7eSjoerg   // hasNonTrivialToPrimitiveDefaultInitializeCUnion
205906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
206006f32e7eSjoerg   // hasNonTrivialToPrimitiveDestructCUnion
206106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
206206f32e7eSjoerg   // hasNonTrivialToPrimitiveCopyCUnion
206306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
206406f32e7eSjoerg   // isParamDestroyedInCallee
206506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
206606f32e7eSjoerg   // getArgPassingRestrictions
206706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
206806f32e7eSjoerg 
206906f32e7eSjoerg   // DC
207006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
207106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
207206f32e7eSjoerg   DeclRecordAbbrev = Stream.EmitAbbrev(std::move(Abv));
207306f32e7eSjoerg 
207406f32e7eSjoerg   // Abbreviation for DECL_PARM_VAR
207506f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
207606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
207706f32e7eSjoerg   // Redeclarable
207806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
207906f32e7eSjoerg   // Decl
208006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
208106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
208206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
208306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
208406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
208506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
208606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
208706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
208806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
208906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
209006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
209106f32e7eSjoerg   // NamedDecl
209206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
209306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
209406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
209506f32e7eSjoerg   // ValueDecl
209606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
209706f32e7eSjoerg   // DeclaratorDecl
209806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
209906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
210006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
210106f32e7eSjoerg   // VarDecl
210206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // SClass
210306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // TSCSpec
210406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // InitStyle
2105*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
210606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // Linkage
210706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
210806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // HasMemberSpecializationInfo
210906f32e7eSjoerg   // ParmVarDecl
211006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
211106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ScopeDepth
211206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
211306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
211406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // KNRPromoted
211506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
211606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // HasUninstantiatedDefaultArg
211706f32e7eSjoerg   // Type Source Info
211806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
211906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
212006f32e7eSjoerg   DeclParmVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
212106f32e7eSjoerg 
212206f32e7eSjoerg   // Abbreviation for DECL_TYPEDEF
212306f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
212406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
212506f32e7eSjoerg   // Redeclarable
212606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
212706f32e7eSjoerg   // Decl
212806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
212906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
213006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
213106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
213206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
213306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
213406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
213506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
213606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
213706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
213806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
213906f32e7eSjoerg   // NamedDecl
214006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
214106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
214206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
214306f32e7eSjoerg   // TypeDecl
214406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
214506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
214606f32e7eSjoerg   // TypedefDecl
214706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
214806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
214906f32e7eSjoerg   DeclTypedefAbbrev = Stream.EmitAbbrev(std::move(Abv));
215006f32e7eSjoerg 
215106f32e7eSjoerg   // Abbreviation for DECL_VAR
215206f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
215306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
215406f32e7eSjoerg   // Redeclarable
215506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
215606f32e7eSjoerg   // Decl
215706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
215806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // LexicalDeclContext
215906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
216006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
216106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
216206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
216306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
216406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
216506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
216606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
216706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
216806f32e7eSjoerg   // NamedDecl
216906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
217006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
217106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // AnonDeclNumber
217206f32e7eSjoerg   // ValueDecl
217306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
217406f32e7eSjoerg   // DeclaratorDecl
217506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
217606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
217706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
217806f32e7eSjoerg   // VarDecl
217906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass
218006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec
218106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle
218206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
218306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition
218406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
218506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
218606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
218706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl
218806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // isInline
218906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // isInlineSpecified
219006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // isConstexpr
219106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // isInitCapture
219206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // isPrevDeclInSameScope
219306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // ImplicitParamKind
219406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // EscapingByref
219506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
2196*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // HasConstant*
219706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // VarKind (local enum)
219806f32e7eSjoerg   // Type Source Info
219906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
220006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
220106f32e7eSjoerg   DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
220206f32e7eSjoerg 
220306f32e7eSjoerg   // Abbreviation for DECL_CXX_METHOD
220406f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
220506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
220606f32e7eSjoerg   // RedeclarableDecl
220706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // CanonicalDecl
220806f32e7eSjoerg   // Decl
220906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // DeclContext
221006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // LexicalDeclContext
221106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // Invalid
221206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // HasAttrs
221306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
221406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
221506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
221606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // InObjCContainer
221706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
221806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModulePrivate
221906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SubmoduleID
222006f32e7eSjoerg   // NamedDecl
222106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
222206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Identifier
222306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // AnonDeclNumber
222406f32e7eSjoerg   // ValueDecl
222506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Type
222606f32e7eSjoerg   // DeclaratorDecl
222706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InnerLocStart
222806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // HasExtInfo
222906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // TSIType
223006f32e7eSjoerg   // FunctionDecl
223106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
223206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
223306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
223406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
223506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
223606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
223706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0));                         // HasInheritedProto
223806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(1));                         // HasWrittenProto
223906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Deleted
224006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
224106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // TrivialForCall
224206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
224306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
224406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
224506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
224606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
224706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
224806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // MultiVersion
224906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
225006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
225106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LocEnd
225206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
225306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
225406f32e7eSjoerg   // This Array slurps the rest of the record. Fortunately we want to encode
225506f32e7eSjoerg   // (nearly) all the remaining (variable number of) fields in the same way.
225606f32e7eSjoerg   //
225706f32e7eSjoerg   // This is the function template information if any, then
225806f32e7eSjoerg   //         NumParams and Params[] from FunctionDecl, and
225906f32e7eSjoerg   //         NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
226006f32e7eSjoerg   //
226106f32e7eSjoerg   //  Add an AbbrevOp for 'size then elements' and use it here.
226206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
226306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
226406f32e7eSjoerg   DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv));
226506f32e7eSjoerg 
226606f32e7eSjoerg   // Abbreviation for EXPR_DECL_REF
226706f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
226806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
226906f32e7eSjoerg   //Stmt
227006f32e7eSjoerg   // Expr
227106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
227206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
227306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
227406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
227506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
2276*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors
227706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
227806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
227906f32e7eSjoerg   //DeclRefExpr
228006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
228106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
228206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
228306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
228406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture
228506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason
228606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
228706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
228806f32e7eSjoerg   DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
228906f32e7eSjoerg 
229006f32e7eSjoerg   // Abbreviation for EXPR_INTEGER_LITERAL
229106f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
229206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
229306f32e7eSjoerg   //Stmt
229406f32e7eSjoerg   // Expr
229506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
229606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
229706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
229806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
229906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
2300*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors
230106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
230206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
230306f32e7eSjoerg   //Integer Literal
230406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
230506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(32));                      // Bit Width
230606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
230706f32e7eSjoerg   IntegerLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
230806f32e7eSjoerg 
230906f32e7eSjoerg   // Abbreviation for EXPR_CHARACTER_LITERAL
231006f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
231106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
231206f32e7eSjoerg   //Stmt
231306f32e7eSjoerg   // Expr
231406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
231506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
231606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
231706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
231806f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
2319*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors
232006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
232106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
232206f32e7eSjoerg   //Character Literal
232306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
232406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
232506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
232606f32e7eSjoerg   CharacterLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
232706f32e7eSjoerg 
232806f32e7eSjoerg   // Abbreviation for EXPR_IMPLICIT_CAST
232906f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
233006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
233106f32e7eSjoerg   // Stmt
233206f32e7eSjoerg   // Expr
233306f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
233406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
233506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
233606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
233706f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
2338*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ContainsErrors
233906f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
234006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
234106f32e7eSjoerg   // CastExpr
234206f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(0)); // PathSize
2343*13fbcb42Sjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasFPFeatures
234406f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
234506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast
234606f32e7eSjoerg   // ImplicitCastExpr
234706f32e7eSjoerg   ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
234806f32e7eSjoerg 
234906f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
235006f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
235106f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
235206f32e7eSjoerg   DeclContextLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
235306f32e7eSjoerg 
235406f32e7eSjoerg   Abv = std::make_shared<BitCodeAbbrev>();
235506f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
235606f32e7eSjoerg   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
235706f32e7eSjoerg   DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
235806f32e7eSjoerg }
235906f32e7eSjoerg 
236006f32e7eSjoerg /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
236106f32e7eSjoerg /// consumers of the AST.
236206f32e7eSjoerg ///
236306f32e7eSjoerg /// Such decls will always be deserialized from the AST file, so we would like
236406f32e7eSjoerg /// this to be as restrictive as possible. Currently the predicate is driven by
236506f32e7eSjoerg /// code generation requirements, if other clients have a different notion of
236606f32e7eSjoerg /// what is "required" then we may have to consider an alternate scheme where
236706f32e7eSjoerg /// clients can iterate over the top-level decls and get information on them,
236806f32e7eSjoerg /// without necessary deserializing them. We could explicitly require such
236906f32e7eSjoerg /// clients to use a separate API call to "realize" the decl. This should be
237006f32e7eSjoerg /// relatively painless since they would presumably only do it for top-level
237106f32e7eSjoerg /// decls.
isRequiredDecl(const Decl * D,ASTContext & Context,bool WritingModule)237206f32e7eSjoerg static bool isRequiredDecl(const Decl *D, ASTContext &Context,
237306f32e7eSjoerg                            bool WritingModule) {
237406f32e7eSjoerg   // An ObjCMethodDecl is never considered as "required" because its
237506f32e7eSjoerg   // implementation container always is.
237606f32e7eSjoerg 
237706f32e7eSjoerg   // File scoped assembly or obj-c or OMP declare target implementation must be
237806f32e7eSjoerg   // seen.
237906f32e7eSjoerg   if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
238006f32e7eSjoerg     return true;
238106f32e7eSjoerg 
238206f32e7eSjoerg   if (WritingModule && isPartOfPerModuleInitializer(D)) {
238306f32e7eSjoerg     // These declarations are part of the module initializer, and are emitted
238406f32e7eSjoerg     // if and when the module is imported, rather than being emitted eagerly.
238506f32e7eSjoerg     return false;
238606f32e7eSjoerg   }
238706f32e7eSjoerg 
238806f32e7eSjoerg   return Context.DeclMustBeEmitted(D);
238906f32e7eSjoerg }
239006f32e7eSjoerg 
WriteDecl(ASTContext & Context,Decl * D)239106f32e7eSjoerg void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
239206f32e7eSjoerg   PrettyDeclStackTraceEntry CrashInfo(Context, D, SourceLocation(),
239306f32e7eSjoerg                                       "serializing");
239406f32e7eSjoerg 
239506f32e7eSjoerg   // Determine the ID for this declaration.
239606f32e7eSjoerg   serialization::DeclID ID;
239706f32e7eSjoerg   assert(!D->isFromASTFile() && "should not be emitting imported decl");
239806f32e7eSjoerg   serialization::DeclID &IDR = DeclIDs[D];
239906f32e7eSjoerg   if (IDR == 0)
240006f32e7eSjoerg     IDR = NextDeclID++;
240106f32e7eSjoerg 
240206f32e7eSjoerg   ID = IDR;
240306f32e7eSjoerg 
240406f32e7eSjoerg   assert(ID >= FirstDeclID && "invalid decl ID");
240506f32e7eSjoerg 
240606f32e7eSjoerg   RecordData Record;
240706f32e7eSjoerg   ASTDeclWriter W(*this, Context, Record);
240806f32e7eSjoerg 
240906f32e7eSjoerg   // Build a record for this declaration
241006f32e7eSjoerg   W.Visit(D);
241106f32e7eSjoerg 
241206f32e7eSjoerg   // Emit this declaration to the bitstream.
241306f32e7eSjoerg   uint64_t Offset = W.Emit(D);
241406f32e7eSjoerg 
241506f32e7eSjoerg   // Record the offset for this declaration
241606f32e7eSjoerg   SourceLocation Loc = D->getLocation();
241706f32e7eSjoerg   unsigned Index = ID - FirstDeclID;
241806f32e7eSjoerg   if (DeclOffsets.size() == Index)
2419*13fbcb42Sjoerg     DeclOffsets.emplace_back(Loc, Offset, DeclTypesBlockStartOffset);
242006f32e7eSjoerg   else if (DeclOffsets.size() < Index) {
242106f32e7eSjoerg     // FIXME: Can/should this happen?
242206f32e7eSjoerg     DeclOffsets.resize(Index+1);
242306f32e7eSjoerg     DeclOffsets[Index].setLocation(Loc);
2424*13fbcb42Sjoerg     DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset);
242506f32e7eSjoerg   } else {
242606f32e7eSjoerg     llvm_unreachable("declarations should be emitted in ID order");
242706f32e7eSjoerg   }
242806f32e7eSjoerg 
242906f32e7eSjoerg   SourceManager &SM = Context.getSourceManager();
243006f32e7eSjoerg   if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
243106f32e7eSjoerg     associateDeclWithFile(D, ID);
243206f32e7eSjoerg 
243306f32e7eSjoerg   // Note declarations that should be deserialized eagerly so that we can add
243406f32e7eSjoerg   // them to a record in the AST file later.
243506f32e7eSjoerg   if (isRequiredDecl(D, Context, WritingModule))
243606f32e7eSjoerg     EagerlyDeserializedDecls.push_back(ID);
243706f32e7eSjoerg }
243806f32e7eSjoerg 
AddFunctionDefinition(const FunctionDecl * FD)243906f32e7eSjoerg void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
244006f32e7eSjoerg   // Switch case IDs are per function body.
244106f32e7eSjoerg   Writer->ClearSwitchCaseIDs();
244206f32e7eSjoerg 
244306f32e7eSjoerg   assert(FD->doesThisDeclarationHaveABody());
244406f32e7eSjoerg   bool ModulesCodegen = false;
2445*13fbcb42Sjoerg   if (!FD->isDependentContext()) {
244606f32e7eSjoerg     Optional<GVALinkage> Linkage;
2447*13fbcb42Sjoerg     if (Writer->WritingModule &&
2448*13fbcb42Sjoerg         Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) {
244906f32e7eSjoerg       // When building a C++ Modules TS module interface unit, a strong
245006f32e7eSjoerg       // definition in the module interface is provided by the compilation of
245106f32e7eSjoerg       // that module interface unit, not by its users. (Inline functions are
245206f32e7eSjoerg       // still emitted in module users.)
245306f32e7eSjoerg       Linkage = Writer->Context->GetGVALinkageForFunction(FD);
245406f32e7eSjoerg       ModulesCodegen = *Linkage == GVA_StrongExternal;
245506f32e7eSjoerg     }
2456*13fbcb42Sjoerg     if (Writer->Context->getLangOpts().ModulesCodegen ||
2457*13fbcb42Sjoerg         (FD->hasAttr<DLLExportAttr>() &&
2458*13fbcb42Sjoerg          Writer->Context->getLangOpts().BuildingPCHWithObjectFile)) {
2459*13fbcb42Sjoerg 
246006f32e7eSjoerg       // Under -fmodules-codegen, codegen is performed for all non-internal,
2461*13fbcb42Sjoerg       // non-always_inline functions, unless they are available elsewhere.
246206f32e7eSjoerg       if (!FD->hasAttr<AlwaysInlineAttr>()) {
246306f32e7eSjoerg         if (!Linkage)
246406f32e7eSjoerg           Linkage = Writer->Context->GetGVALinkageForFunction(FD);
2465*13fbcb42Sjoerg         ModulesCodegen =
2466*13fbcb42Sjoerg             *Linkage != GVA_Internal && *Linkage != GVA_AvailableExternally;
246706f32e7eSjoerg       }
246806f32e7eSjoerg     }
246906f32e7eSjoerg   }
247006f32e7eSjoerg   Record->push_back(ModulesCodegen);
247106f32e7eSjoerg   if (ModulesCodegen)
247206f32e7eSjoerg     Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD));
247306f32e7eSjoerg   if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
247406f32e7eSjoerg     Record->push_back(CD->getNumCtorInitializers());
247506f32e7eSjoerg     if (CD->getNumCtorInitializers())
247606f32e7eSjoerg       AddCXXCtorInitializers(
247706f32e7eSjoerg           llvm::makeArrayRef(CD->init_begin(), CD->init_end()));
247806f32e7eSjoerg   }
247906f32e7eSjoerg   AddStmt(FD->getBody());
248006f32e7eSjoerg }
2481