xref: /minix3/external/bsd/llvm/dist/clang/lib/Serialization/ASTWriterDecl.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file implements serialization for Declarations.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "clang/Serialization/ASTWriter.h"
15f4a2713aSLionel Sambuc #include "ASTCommon.h"
16f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
17f4a2713aSLionel Sambuc #include "clang/AST/DeclContextInternals.h"
18f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclVisitor.h"
20f4a2713aSLionel Sambuc #include "clang/AST/Expr.h"
21f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
22f4a2713aSLionel Sambuc #include "clang/Serialization/ASTReader.h"
23f4a2713aSLionel Sambuc #include "llvm/ADT/Twine.h"
24f4a2713aSLionel Sambuc #include "llvm/Bitcode/BitstreamWriter.h"
25f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
26f4a2713aSLionel Sambuc using namespace clang;
27f4a2713aSLionel Sambuc using namespace serialization;
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
30f4a2713aSLionel Sambuc // Declaration serialization
31f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc namespace clang {
34f4a2713aSLionel Sambuc   class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
35f4a2713aSLionel Sambuc 
36f4a2713aSLionel Sambuc     ASTWriter &Writer;
37f4a2713aSLionel Sambuc     ASTContext &Context;
38f4a2713aSLionel Sambuc     typedef ASTWriter::RecordData RecordData;
39f4a2713aSLionel Sambuc     RecordData &Record;
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc   public:
42f4a2713aSLionel Sambuc     serialization::DeclCode Code;
43f4a2713aSLionel Sambuc     unsigned AbbrevToUse;
44f4a2713aSLionel Sambuc 
ASTDeclWriter(ASTWriter & Writer,ASTContext & Context,RecordData & Record)45f4a2713aSLionel Sambuc     ASTDeclWriter(ASTWriter &Writer, ASTContext &Context, RecordData &Record)
46f4a2713aSLionel Sambuc       : Writer(Writer), Context(Context), Record(Record) {
47f4a2713aSLionel Sambuc     }
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc     void Visit(Decl *D);
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc     void VisitDecl(Decl *D);
52f4a2713aSLionel Sambuc     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
53f4a2713aSLionel Sambuc     void VisitNamedDecl(NamedDecl *D);
54f4a2713aSLionel Sambuc     void VisitLabelDecl(LabelDecl *LD);
55f4a2713aSLionel Sambuc     void VisitNamespaceDecl(NamespaceDecl *D);
56f4a2713aSLionel Sambuc     void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
57f4a2713aSLionel Sambuc     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
58f4a2713aSLionel Sambuc     void VisitTypeDecl(TypeDecl *D);
59f4a2713aSLionel Sambuc     void VisitTypedefNameDecl(TypedefNameDecl *D);
60f4a2713aSLionel Sambuc     void VisitTypedefDecl(TypedefDecl *D);
61f4a2713aSLionel Sambuc     void VisitTypeAliasDecl(TypeAliasDecl *D);
62f4a2713aSLionel Sambuc     void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
63f4a2713aSLionel Sambuc     void VisitTagDecl(TagDecl *D);
64f4a2713aSLionel Sambuc     void VisitEnumDecl(EnumDecl *D);
65f4a2713aSLionel Sambuc     void VisitRecordDecl(RecordDecl *D);
66f4a2713aSLionel Sambuc     void VisitCXXRecordDecl(CXXRecordDecl *D);
67f4a2713aSLionel Sambuc     void VisitClassTemplateSpecializationDecl(
68f4a2713aSLionel Sambuc                                             ClassTemplateSpecializationDecl *D);
69f4a2713aSLionel Sambuc     void VisitClassTemplatePartialSpecializationDecl(
70f4a2713aSLionel Sambuc                                      ClassTemplatePartialSpecializationDecl *D);
71f4a2713aSLionel Sambuc     void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
72f4a2713aSLionel Sambuc     void VisitVarTemplatePartialSpecializationDecl(
73f4a2713aSLionel Sambuc         VarTemplatePartialSpecializationDecl *D);
74f4a2713aSLionel Sambuc     void VisitClassScopeFunctionSpecializationDecl(
75f4a2713aSLionel Sambuc                                        ClassScopeFunctionSpecializationDecl *D);
76f4a2713aSLionel Sambuc     void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
77f4a2713aSLionel Sambuc     void VisitValueDecl(ValueDecl *D);
78f4a2713aSLionel Sambuc     void VisitEnumConstantDecl(EnumConstantDecl *D);
79f4a2713aSLionel Sambuc     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
80f4a2713aSLionel Sambuc     void VisitDeclaratorDecl(DeclaratorDecl *D);
81f4a2713aSLionel Sambuc     void VisitFunctionDecl(FunctionDecl *D);
82f4a2713aSLionel Sambuc     void VisitCXXMethodDecl(CXXMethodDecl *D);
83f4a2713aSLionel Sambuc     void VisitCXXConstructorDecl(CXXConstructorDecl *D);
84f4a2713aSLionel Sambuc     void VisitCXXDestructorDecl(CXXDestructorDecl *D);
85f4a2713aSLionel Sambuc     void VisitCXXConversionDecl(CXXConversionDecl *D);
86f4a2713aSLionel Sambuc     void VisitFieldDecl(FieldDecl *D);
87f4a2713aSLionel Sambuc     void VisitMSPropertyDecl(MSPropertyDecl *D);
88f4a2713aSLionel Sambuc     void VisitIndirectFieldDecl(IndirectFieldDecl *D);
89f4a2713aSLionel Sambuc     void VisitVarDecl(VarDecl *D);
90f4a2713aSLionel Sambuc     void VisitImplicitParamDecl(ImplicitParamDecl *D);
91f4a2713aSLionel Sambuc     void VisitParmVarDecl(ParmVarDecl *D);
92f4a2713aSLionel Sambuc     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
93f4a2713aSLionel Sambuc     void VisitTemplateDecl(TemplateDecl *D);
94f4a2713aSLionel Sambuc     void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
95f4a2713aSLionel Sambuc     void VisitClassTemplateDecl(ClassTemplateDecl *D);
96f4a2713aSLionel Sambuc     void VisitVarTemplateDecl(VarTemplateDecl *D);
97f4a2713aSLionel Sambuc     void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
98f4a2713aSLionel Sambuc     void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
99f4a2713aSLionel Sambuc     void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
100f4a2713aSLionel Sambuc     void VisitUsingDecl(UsingDecl *D);
101f4a2713aSLionel Sambuc     void VisitUsingShadowDecl(UsingShadowDecl *D);
102f4a2713aSLionel Sambuc     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
103f4a2713aSLionel Sambuc     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
104f4a2713aSLionel Sambuc     void VisitImportDecl(ImportDecl *D);
105f4a2713aSLionel Sambuc     void VisitAccessSpecDecl(AccessSpecDecl *D);
106f4a2713aSLionel Sambuc     void VisitFriendDecl(FriendDecl *D);
107f4a2713aSLionel Sambuc     void VisitFriendTemplateDecl(FriendTemplateDecl *D);
108f4a2713aSLionel Sambuc     void VisitStaticAssertDecl(StaticAssertDecl *D);
109f4a2713aSLionel Sambuc     void VisitBlockDecl(BlockDecl *D);
110f4a2713aSLionel Sambuc     void VisitCapturedDecl(CapturedDecl *D);
111f4a2713aSLionel Sambuc     void VisitEmptyDecl(EmptyDecl *D);
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc     void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
114f4a2713aSLionel Sambuc                           uint64_t VisibleOffset);
115f4a2713aSLionel Sambuc     template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc     // FIXME: Put in the same order is DeclNodes.td?
119f4a2713aSLionel Sambuc     void VisitObjCMethodDecl(ObjCMethodDecl *D);
120f4a2713aSLionel Sambuc     void VisitObjCContainerDecl(ObjCContainerDecl *D);
121f4a2713aSLionel Sambuc     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
122f4a2713aSLionel Sambuc     void VisitObjCIvarDecl(ObjCIvarDecl *D);
123f4a2713aSLionel Sambuc     void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
124f4a2713aSLionel Sambuc     void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
125f4a2713aSLionel Sambuc     void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
126f4a2713aSLionel Sambuc     void VisitObjCImplDecl(ObjCImplDecl *D);
127f4a2713aSLionel Sambuc     void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
128f4a2713aSLionel Sambuc     void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
129f4a2713aSLionel Sambuc     void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
130f4a2713aSLionel Sambuc     void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
131f4a2713aSLionel Sambuc     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
132f4a2713aSLionel Sambuc     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
133*0a6a1f1dSLionel Sambuc 
AddFunctionDefinition(const FunctionDecl * FD)134*0a6a1f1dSLionel Sambuc     void AddFunctionDefinition(const FunctionDecl *FD) {
135*0a6a1f1dSLionel Sambuc       assert(FD->doesThisDeclarationHaveABody());
136*0a6a1f1dSLionel Sambuc       if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
137*0a6a1f1dSLionel Sambuc         Writer.AddCXXCtorInitializers(CD->CtorInitializers,
138*0a6a1f1dSLionel Sambuc                                       CD->NumCtorInitializers, Record);
139*0a6a1f1dSLionel Sambuc       Writer.AddStmt(FD->getBody());
140*0a6a1f1dSLionel Sambuc     }
141f4a2713aSLionel Sambuc   };
142f4a2713aSLionel Sambuc }
143f4a2713aSLionel Sambuc 
Visit(Decl * D)144f4a2713aSLionel Sambuc void ASTDeclWriter::Visit(Decl *D) {
145f4a2713aSLionel Sambuc   DeclVisitor<ASTDeclWriter>::Visit(D);
146f4a2713aSLionel Sambuc 
147f4a2713aSLionel Sambuc   // Source locations require array (variable-length) abbreviations.  The
148f4a2713aSLionel Sambuc   // abbreviation infrastructure requires that arrays are encoded last, so
149f4a2713aSLionel Sambuc   // we handle it here in the case of those classes derived from DeclaratorDecl
150f4a2713aSLionel Sambuc   if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)){
151f4a2713aSLionel Sambuc     Writer.AddTypeSourceInfo(DD->getTypeSourceInfo(), Record);
152f4a2713aSLionel Sambuc   }
153f4a2713aSLionel Sambuc 
154f4a2713aSLionel Sambuc   // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
155f4a2713aSLionel Sambuc   // have been written. We want it last because we will not read it back when
156f4a2713aSLionel Sambuc   // retrieving it from the AST, we'll just lazily set the offset.
157f4a2713aSLionel Sambuc   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
158f4a2713aSLionel Sambuc     Record.push_back(FD->doesThisDeclarationHaveABody());
159f4a2713aSLionel Sambuc     if (FD->doesThisDeclarationHaveABody())
160f4a2713aSLionel Sambuc       Writer.AddStmt(FD->getBody());
161f4a2713aSLionel Sambuc   }
162f4a2713aSLionel Sambuc }
163f4a2713aSLionel Sambuc 
VisitDecl(Decl * D)164f4a2713aSLionel Sambuc void ASTDeclWriter::VisitDecl(Decl *D) {
165f4a2713aSLionel Sambuc   Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
166f4a2713aSLionel Sambuc   Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
167f4a2713aSLionel Sambuc   Record.push_back(D->isInvalidDecl());
168f4a2713aSLionel Sambuc   Record.push_back(D->hasAttrs());
169f4a2713aSLionel Sambuc   if (D->hasAttrs())
170*0a6a1f1dSLionel Sambuc     Writer.WriteAttributes(llvm::makeArrayRef(D->getAttrs().begin(),
171f4a2713aSLionel Sambuc                                               D->getAttrs().size()), Record);
172f4a2713aSLionel Sambuc   Record.push_back(D->isImplicit());
173f4a2713aSLionel Sambuc   Record.push_back(D->isUsed(false));
174f4a2713aSLionel Sambuc   Record.push_back(D->isReferenced());
175f4a2713aSLionel Sambuc   Record.push_back(D->isTopLevelDeclInObjCContainer());
176f4a2713aSLionel Sambuc   Record.push_back(D->getAccess());
177f4a2713aSLionel Sambuc   Record.push_back(D->isModulePrivate());
178f4a2713aSLionel Sambuc   Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
179*0a6a1f1dSLionel Sambuc 
180*0a6a1f1dSLionel Sambuc   // If this declaration injected a name into a context different from its
181*0a6a1f1dSLionel Sambuc   // lexical context, and that context is an imported namespace, we need to
182*0a6a1f1dSLionel Sambuc   // update its visible declarations to include this name.
183*0a6a1f1dSLionel Sambuc   //
184*0a6a1f1dSLionel Sambuc   // This happens when we instantiate a class with a friend declaration or a
185*0a6a1f1dSLionel Sambuc   // function with a local extern declaration, for instance.
186*0a6a1f1dSLionel Sambuc   if (D->isOutOfLine()) {
187*0a6a1f1dSLionel Sambuc     auto *DC = D->getDeclContext();
188*0a6a1f1dSLionel Sambuc     while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
189*0a6a1f1dSLionel Sambuc       if (!NS->isFromASTFile())
190*0a6a1f1dSLionel Sambuc         break;
191*0a6a1f1dSLionel Sambuc       Writer.AddUpdatedDeclContext(NS->getPrimaryContext());
192*0a6a1f1dSLionel Sambuc       if (!NS->isInlineNamespace())
193*0a6a1f1dSLionel Sambuc         break;
194*0a6a1f1dSLionel Sambuc       DC = NS->getParent();
195*0a6a1f1dSLionel Sambuc     }
196*0a6a1f1dSLionel Sambuc   }
197f4a2713aSLionel Sambuc }
198f4a2713aSLionel Sambuc 
VisitTranslationUnitDecl(TranslationUnitDecl * D)199f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
200f4a2713aSLionel Sambuc   llvm_unreachable("Translation units aren't directly serialized");
201f4a2713aSLionel Sambuc }
202f4a2713aSLionel Sambuc 
VisitNamedDecl(NamedDecl * D)203f4a2713aSLionel Sambuc void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
204f4a2713aSLionel Sambuc   VisitDecl(D);
205f4a2713aSLionel Sambuc   Writer.AddDeclarationName(D->getDeclName(), Record);
206*0a6a1f1dSLionel Sambuc   if (needsAnonymousDeclarationNumber(D))
207*0a6a1f1dSLionel Sambuc     Record.push_back(Writer.getAnonymousDeclarationNumber(D));
208f4a2713aSLionel Sambuc }
209f4a2713aSLionel Sambuc 
VisitTypeDecl(TypeDecl * D)210f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
211f4a2713aSLionel Sambuc   VisitNamedDecl(D);
212f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLocStart(), Record);
213f4a2713aSLionel Sambuc   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
214f4a2713aSLionel Sambuc }
215f4a2713aSLionel Sambuc 
VisitTypedefNameDecl(TypedefNameDecl * D)216f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
217f4a2713aSLionel Sambuc   VisitRedeclarable(D);
218f4a2713aSLionel Sambuc   VisitTypeDecl(D);
219f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
220f4a2713aSLionel Sambuc   Record.push_back(D->isModed());
221f4a2713aSLionel Sambuc   if (D->isModed())
222f4a2713aSLionel Sambuc     Writer.AddTypeRef(D->getUnderlyingType(), Record);
223f4a2713aSLionel Sambuc }
224f4a2713aSLionel Sambuc 
VisitTypedefDecl(TypedefDecl * D)225f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
226f4a2713aSLionel Sambuc   VisitTypedefNameDecl(D);
227f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
228f4a2713aSLionel Sambuc       !D->isImplicit() &&
229f4a2713aSLionel Sambuc       D->getFirstDecl() == D->getMostRecentDecl() &&
230f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
231f4a2713aSLionel Sambuc       !D->isTopLevelDeclInObjCContainer() &&
232f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
233*0a6a1f1dSLionel Sambuc       !needsAnonymousDeclarationNumber(D) &&
234f4a2713aSLionel Sambuc       D->getDeclName().getNameKind() == DeclarationName::Identifier)
235f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclTypedefAbbrev();
236f4a2713aSLionel Sambuc 
237f4a2713aSLionel Sambuc   Code = serialization::DECL_TYPEDEF;
238f4a2713aSLionel Sambuc }
239f4a2713aSLionel Sambuc 
VisitTypeAliasDecl(TypeAliasDecl * D)240f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
241f4a2713aSLionel Sambuc   VisitTypedefNameDecl(D);
242*0a6a1f1dSLionel Sambuc   Writer.AddDeclRef(D->getDescribedAliasTemplate(), Record);
243f4a2713aSLionel Sambuc   Code = serialization::DECL_TYPEALIAS;
244f4a2713aSLionel Sambuc }
245f4a2713aSLionel Sambuc 
VisitTagDecl(TagDecl * D)246f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
247f4a2713aSLionel Sambuc   VisitRedeclarable(D);
248f4a2713aSLionel Sambuc   VisitTypeDecl(D);
249f4a2713aSLionel Sambuc   Record.push_back(D->getIdentifierNamespace());
250f4a2713aSLionel Sambuc   Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
251*0a6a1f1dSLionel Sambuc   if (!isa<CXXRecordDecl>(D))
252f4a2713aSLionel Sambuc     Record.push_back(D->isCompleteDefinition());
253f4a2713aSLionel Sambuc   Record.push_back(D->isEmbeddedInDeclarator());
254f4a2713aSLionel Sambuc   Record.push_back(D->isFreeStanding());
255f4a2713aSLionel Sambuc   Record.push_back(D->isCompleteDefinitionRequired());
256f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getRBraceLoc(), Record);
257*0a6a1f1dSLionel Sambuc 
258*0a6a1f1dSLionel Sambuc   if (D->hasExtInfo()) {
259*0a6a1f1dSLionel Sambuc     Record.push_back(1);
260f4a2713aSLionel Sambuc     Writer.AddQualifierInfo(*D->getExtInfo(), Record);
261*0a6a1f1dSLionel Sambuc   } else if (auto *TD = D->getTypedefNameForAnonDecl()) {
262*0a6a1f1dSLionel Sambuc     Record.push_back(2);
263*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(TD, Record);
264*0a6a1f1dSLionel Sambuc     Writer.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo(), Record);
265*0a6a1f1dSLionel Sambuc   } else if (auto *DD = D->getDeclaratorForAnonDecl()) {
266*0a6a1f1dSLionel Sambuc     Record.push_back(3);
267*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(DD, Record);
268*0a6a1f1dSLionel Sambuc   } else {
269*0a6a1f1dSLionel Sambuc     Record.push_back(0);
270*0a6a1f1dSLionel Sambuc   }
271f4a2713aSLionel Sambuc }
272f4a2713aSLionel Sambuc 
VisitEnumDecl(EnumDecl * D)273f4a2713aSLionel Sambuc void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
274f4a2713aSLionel Sambuc   VisitTagDecl(D);
275f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getIntegerTypeSourceInfo(), Record);
276f4a2713aSLionel Sambuc   if (!D->getIntegerTypeSourceInfo())
277f4a2713aSLionel Sambuc     Writer.AddTypeRef(D->getIntegerType(), Record);
278f4a2713aSLionel Sambuc   Writer.AddTypeRef(D->getPromotionType(), Record);
279f4a2713aSLionel Sambuc   Record.push_back(D->getNumPositiveBits());
280f4a2713aSLionel Sambuc   Record.push_back(D->getNumNegativeBits());
281f4a2713aSLionel Sambuc   Record.push_back(D->isScoped());
282f4a2713aSLionel Sambuc   Record.push_back(D->isScopedUsingClassTag());
283f4a2713aSLionel Sambuc   Record.push_back(D->isFixed());
284f4a2713aSLionel Sambuc   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
285f4a2713aSLionel Sambuc     Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
286f4a2713aSLionel Sambuc     Record.push_back(MemberInfo->getTemplateSpecializationKind());
287f4a2713aSLionel Sambuc     Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
288f4a2713aSLionel Sambuc   } else {
289*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(nullptr, Record);
290f4a2713aSLionel Sambuc   }
291f4a2713aSLionel Sambuc 
292f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
293f4a2713aSLionel Sambuc       !D->isImplicit() &&
294f4a2713aSLionel Sambuc       !D->isUsed(false) &&
295f4a2713aSLionel Sambuc       !D->hasExtInfo() &&
296*0a6a1f1dSLionel Sambuc       !D->getTypedefNameForAnonDecl() &&
297*0a6a1f1dSLionel Sambuc       !D->getDeclaratorForAnonDecl() &&
298f4a2713aSLionel Sambuc       D->getFirstDecl() == D->getMostRecentDecl() &&
299f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
300f4a2713aSLionel Sambuc       !D->isReferenced() &&
301f4a2713aSLionel Sambuc       !D->isTopLevelDeclInObjCContainer() &&
302f4a2713aSLionel Sambuc       D->getAccess() == AS_none &&
303f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
304f4a2713aSLionel Sambuc       !CXXRecordDecl::classofKind(D->getKind()) &&
305f4a2713aSLionel Sambuc       !D->getIntegerTypeSourceInfo() &&
306f4a2713aSLionel Sambuc       !D->getMemberSpecializationInfo() &&
307*0a6a1f1dSLionel Sambuc       !needsAnonymousDeclarationNumber(D) &&
308f4a2713aSLionel Sambuc       D->getDeclName().getNameKind() == DeclarationName::Identifier)
309f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclEnumAbbrev();
310f4a2713aSLionel Sambuc 
311f4a2713aSLionel Sambuc   Code = serialization::DECL_ENUM;
312f4a2713aSLionel Sambuc }
313f4a2713aSLionel Sambuc 
VisitRecordDecl(RecordDecl * D)314f4a2713aSLionel Sambuc void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
315f4a2713aSLionel Sambuc   VisitTagDecl(D);
316f4a2713aSLionel Sambuc   Record.push_back(D->hasFlexibleArrayMember());
317f4a2713aSLionel Sambuc   Record.push_back(D->isAnonymousStructOrUnion());
318f4a2713aSLionel Sambuc   Record.push_back(D->hasObjectMember());
319f4a2713aSLionel Sambuc   Record.push_back(D->hasVolatileMember());
320f4a2713aSLionel Sambuc 
321f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
322f4a2713aSLionel Sambuc       !D->isImplicit() &&
323f4a2713aSLionel Sambuc       !D->isUsed(false) &&
324f4a2713aSLionel Sambuc       !D->hasExtInfo() &&
325*0a6a1f1dSLionel Sambuc       !D->getTypedefNameForAnonDecl() &&
326*0a6a1f1dSLionel Sambuc       !D->getDeclaratorForAnonDecl() &&
327f4a2713aSLionel Sambuc       D->getFirstDecl() == D->getMostRecentDecl() &&
328f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
329f4a2713aSLionel Sambuc       !D->isReferenced() &&
330f4a2713aSLionel Sambuc       !D->isTopLevelDeclInObjCContainer() &&
331f4a2713aSLionel Sambuc       D->getAccess() == AS_none &&
332f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
333f4a2713aSLionel Sambuc       !CXXRecordDecl::classofKind(D->getKind()) &&
334*0a6a1f1dSLionel Sambuc       !needsAnonymousDeclarationNumber(D) &&
335f4a2713aSLionel Sambuc       D->getDeclName().getNameKind() == DeclarationName::Identifier)
336f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclRecordAbbrev();
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc   Code = serialization::DECL_RECORD;
339f4a2713aSLionel Sambuc }
340f4a2713aSLionel Sambuc 
VisitValueDecl(ValueDecl * D)341f4a2713aSLionel Sambuc void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
342f4a2713aSLionel Sambuc   VisitNamedDecl(D);
343f4a2713aSLionel Sambuc   Writer.AddTypeRef(D->getType(), Record);
344f4a2713aSLionel Sambuc }
345f4a2713aSLionel Sambuc 
VisitEnumConstantDecl(EnumConstantDecl * D)346f4a2713aSLionel Sambuc void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
347f4a2713aSLionel Sambuc   VisitValueDecl(D);
348f4a2713aSLionel Sambuc   Record.push_back(D->getInitExpr()? 1 : 0);
349f4a2713aSLionel Sambuc   if (D->getInitExpr())
350f4a2713aSLionel Sambuc     Writer.AddStmt(D->getInitExpr());
351f4a2713aSLionel Sambuc   Writer.AddAPSInt(D->getInitVal(), Record);
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc   Code = serialization::DECL_ENUM_CONSTANT;
354f4a2713aSLionel Sambuc }
355f4a2713aSLionel Sambuc 
VisitDeclaratorDecl(DeclaratorDecl * D)356f4a2713aSLionel Sambuc void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
357f4a2713aSLionel Sambuc   VisitValueDecl(D);
358f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getInnerLocStart(), Record);
359f4a2713aSLionel Sambuc   Record.push_back(D->hasExtInfo());
360f4a2713aSLionel Sambuc   if (D->hasExtInfo())
361f4a2713aSLionel Sambuc     Writer.AddQualifierInfo(*D->getExtInfo(), Record);
362f4a2713aSLionel Sambuc }
363f4a2713aSLionel Sambuc 
VisitFunctionDecl(FunctionDecl * D)364f4a2713aSLionel Sambuc void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
365f4a2713aSLionel Sambuc   VisitRedeclarable(D);
366f4a2713aSLionel Sambuc   VisitDeclaratorDecl(D);
367f4a2713aSLionel Sambuc   Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
368f4a2713aSLionel Sambuc   Record.push_back(D->getIdentifierNamespace());
369f4a2713aSLionel Sambuc 
370f4a2713aSLionel Sambuc   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
371f4a2713aSLionel Sambuc   // after everything else is written.
372f4a2713aSLionel Sambuc 
373*0a6a1f1dSLionel Sambuc   Record.push_back((int)D->SClass); // FIXME: stable encoding
374f4a2713aSLionel Sambuc   Record.push_back(D->IsInline);
375*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsInlineSpecified);
376*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsVirtualAsWritten);
377*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsPure);
378*0a6a1f1dSLionel Sambuc   Record.push_back(D->HasInheritedPrototype);
379*0a6a1f1dSLionel Sambuc   Record.push_back(D->HasWrittenPrototype);
380*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsDeleted);
381*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsTrivial);
382*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsDefaulted);
383*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsExplicitlyDefaulted);
384*0a6a1f1dSLionel Sambuc   Record.push_back(D->HasImplicitReturnZero);
385*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsConstexpr);
386f4a2713aSLionel Sambuc   Record.push_back(D->HasSkippedBody);
387*0a6a1f1dSLionel Sambuc   Record.push_back(D->IsLateTemplateParsed);
388f4a2713aSLionel Sambuc   Record.push_back(D->getLinkageInternal());
389f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLocEnd(), Record);
390f4a2713aSLionel Sambuc 
391f4a2713aSLionel Sambuc   Record.push_back(D->getTemplatedKind());
392f4a2713aSLionel Sambuc   switch (D->getTemplatedKind()) {
393f4a2713aSLionel Sambuc   case FunctionDecl::TK_NonTemplate:
394f4a2713aSLionel Sambuc     break;
395f4a2713aSLionel Sambuc   case FunctionDecl::TK_FunctionTemplate:
396f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getDescribedFunctionTemplate(), Record);
397f4a2713aSLionel Sambuc     break;
398f4a2713aSLionel Sambuc   case FunctionDecl::TK_MemberSpecialization: {
399f4a2713aSLionel Sambuc     MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
400f4a2713aSLionel Sambuc     Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);
401f4a2713aSLionel Sambuc     Record.push_back(MemberInfo->getTemplateSpecializationKind());
402f4a2713aSLionel Sambuc     Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
403f4a2713aSLionel Sambuc     break;
404f4a2713aSLionel Sambuc   }
405f4a2713aSLionel Sambuc   case FunctionDecl::TK_FunctionTemplateSpecialization: {
406f4a2713aSLionel Sambuc     FunctionTemplateSpecializationInfo *
407f4a2713aSLionel Sambuc       FTSInfo = D->getTemplateSpecializationInfo();
408f4a2713aSLionel Sambuc     Writer.AddDeclRef(FTSInfo->getTemplate(), Record);
409f4a2713aSLionel Sambuc     Record.push_back(FTSInfo->getTemplateSpecializationKind());
410f4a2713aSLionel Sambuc 
411f4a2713aSLionel Sambuc     // Template arguments.
412f4a2713aSLionel Sambuc     Writer.AddTemplateArgumentList(FTSInfo->TemplateArguments, Record);
413f4a2713aSLionel Sambuc 
414f4a2713aSLionel Sambuc     // Template args as written.
415*0a6a1f1dSLionel Sambuc     Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
416f4a2713aSLionel Sambuc     if (FTSInfo->TemplateArgumentsAsWritten) {
417f4a2713aSLionel Sambuc       Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
418f4a2713aSLionel Sambuc       for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
419f4a2713aSLionel Sambuc              i!=e; ++i)
420f4a2713aSLionel Sambuc         Writer.AddTemplateArgumentLoc((*FTSInfo->TemplateArgumentsAsWritten)[i],
421f4a2713aSLionel Sambuc                                       Record);
422f4a2713aSLionel Sambuc       Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc,
423f4a2713aSLionel Sambuc                                Record);
424f4a2713aSLionel Sambuc       Writer.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc,
425f4a2713aSLionel Sambuc                                Record);
426f4a2713aSLionel Sambuc     }
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc     Writer.AddSourceLocation(FTSInfo->getPointOfInstantiation(), Record);
429f4a2713aSLionel Sambuc 
430f4a2713aSLionel Sambuc     if (D->isCanonicalDecl()) {
431f4a2713aSLionel Sambuc       // Write the template that contains the specializations set. We will
432f4a2713aSLionel Sambuc       // add a FunctionTemplateSpecializationInfo to it when reading.
433f4a2713aSLionel Sambuc       Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record);
434f4a2713aSLionel Sambuc     }
435f4a2713aSLionel Sambuc     break;
436f4a2713aSLionel Sambuc   }
437f4a2713aSLionel Sambuc   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
438f4a2713aSLionel Sambuc     DependentFunctionTemplateSpecializationInfo *
439f4a2713aSLionel Sambuc       DFTSInfo = D->getDependentSpecializationInfo();
440f4a2713aSLionel Sambuc 
441f4a2713aSLionel Sambuc     // Templates.
442f4a2713aSLionel Sambuc     Record.push_back(DFTSInfo->getNumTemplates());
443f4a2713aSLionel Sambuc     for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
444f4a2713aSLionel Sambuc       Writer.AddDeclRef(DFTSInfo->getTemplate(i), Record);
445f4a2713aSLionel Sambuc 
446f4a2713aSLionel Sambuc     // Templates args.
447f4a2713aSLionel Sambuc     Record.push_back(DFTSInfo->getNumTemplateArgs());
448f4a2713aSLionel Sambuc     for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
449f4a2713aSLionel Sambuc       Writer.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i), Record);
450f4a2713aSLionel Sambuc     Writer.AddSourceLocation(DFTSInfo->getLAngleLoc(), Record);
451f4a2713aSLionel Sambuc     Writer.AddSourceLocation(DFTSInfo->getRAngleLoc(), Record);
452f4a2713aSLionel Sambuc     break;
453f4a2713aSLionel Sambuc   }
454f4a2713aSLionel Sambuc   }
455f4a2713aSLionel Sambuc 
456f4a2713aSLionel Sambuc   Record.push_back(D->param_size());
457*0a6a1f1dSLionel Sambuc   for (auto P : D->params())
458*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(P, Record);
459f4a2713aSLionel Sambuc   Code = serialization::DECL_FUNCTION;
460f4a2713aSLionel Sambuc }
461f4a2713aSLionel Sambuc 
VisitObjCMethodDecl(ObjCMethodDecl * D)462f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
463f4a2713aSLionel Sambuc   VisitNamedDecl(D);
464f4a2713aSLionel Sambuc   // FIXME: convert to LazyStmtPtr?
465f4a2713aSLionel Sambuc   // Unlike C/C++, method bodies will never be in header files.
466*0a6a1f1dSLionel Sambuc   bool HasBodyStuff = D->getBody() != nullptr     ||
467*0a6a1f1dSLionel Sambuc                       D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr;
468f4a2713aSLionel Sambuc   Record.push_back(HasBodyStuff);
469f4a2713aSLionel Sambuc   if (HasBodyStuff) {
470f4a2713aSLionel Sambuc     Writer.AddStmt(D->getBody());
471f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getSelfDecl(), Record);
472f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getCmdDecl(), Record);
473f4a2713aSLionel Sambuc   }
474f4a2713aSLionel Sambuc   Record.push_back(D->isInstanceMethod());
475f4a2713aSLionel Sambuc   Record.push_back(D->isVariadic());
476f4a2713aSLionel Sambuc   Record.push_back(D->isPropertyAccessor());
477f4a2713aSLionel Sambuc   Record.push_back(D->isDefined());
478f4a2713aSLionel Sambuc   Record.push_back(D->IsOverriding);
479f4a2713aSLionel Sambuc   Record.push_back(D->HasSkippedBody);
480f4a2713aSLionel Sambuc 
481f4a2713aSLionel Sambuc   Record.push_back(D->IsRedeclaration);
482f4a2713aSLionel Sambuc   Record.push_back(D->HasRedeclaration);
483f4a2713aSLionel Sambuc   if (D->HasRedeclaration) {
484f4a2713aSLionel Sambuc     assert(Context.getObjCMethodRedeclaration(D));
485f4a2713aSLionel Sambuc     Writer.AddDeclRef(Context.getObjCMethodRedeclaration(D), Record);
486f4a2713aSLionel Sambuc   }
487f4a2713aSLionel Sambuc 
488f4a2713aSLionel Sambuc   // FIXME: stable encoding for @required/@optional
489f4a2713aSLionel Sambuc   Record.push_back(D->getImplementationControl());
490f4a2713aSLionel Sambuc   // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
491f4a2713aSLionel Sambuc   Record.push_back(D->getObjCDeclQualifier());
492f4a2713aSLionel Sambuc   Record.push_back(D->hasRelatedResultType());
493*0a6a1f1dSLionel Sambuc   Writer.AddTypeRef(D->getReturnType(), Record);
494*0a6a1f1dSLionel Sambuc   Writer.AddTypeSourceInfo(D->getReturnTypeSourceInfo(), Record);
495f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLocEnd(), Record);
496f4a2713aSLionel Sambuc   Record.push_back(D->param_size());
497*0a6a1f1dSLionel Sambuc   for (const auto *P : D->params())
498*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(P, Record);
499f4a2713aSLionel Sambuc 
500f4a2713aSLionel Sambuc   Record.push_back(D->SelLocsKind);
501f4a2713aSLionel Sambuc   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
502f4a2713aSLionel Sambuc   SourceLocation *SelLocs = D->getStoredSelLocs();
503f4a2713aSLionel Sambuc   Record.push_back(NumStoredSelLocs);
504f4a2713aSLionel Sambuc   for (unsigned i = 0; i != NumStoredSelLocs; ++i)
505f4a2713aSLionel Sambuc     Writer.AddSourceLocation(SelLocs[i], Record);
506f4a2713aSLionel Sambuc 
507f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_METHOD;
508f4a2713aSLionel Sambuc }
509f4a2713aSLionel Sambuc 
VisitObjCContainerDecl(ObjCContainerDecl * D)510f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
511f4a2713aSLionel Sambuc   VisitNamedDecl(D);
512f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getAtStartLoc(), Record);
513f4a2713aSLionel Sambuc   Writer.AddSourceRange(D->getAtEndRange(), Record);
514f4a2713aSLionel Sambuc   // Abstract class (no need to define a stable serialization::DECL code).
515f4a2713aSLionel Sambuc }
516f4a2713aSLionel Sambuc 
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)517f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
518f4a2713aSLionel Sambuc   VisitRedeclarable(D);
519f4a2713aSLionel Sambuc   VisitObjCContainerDecl(D);
520f4a2713aSLionel Sambuc   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
521f4a2713aSLionel Sambuc 
522f4a2713aSLionel Sambuc   Record.push_back(D->isThisDeclarationADefinition());
523f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition()) {
524f4a2713aSLionel Sambuc     // Write the DefinitionData
525f4a2713aSLionel Sambuc     ObjCInterfaceDecl::DefinitionData &Data = D->data();
526f4a2713aSLionel Sambuc 
527f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getSuperClass(), Record);
528f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
529f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getEndOfDefinitionLoc(), Record);
530*0a6a1f1dSLionel Sambuc     Record.push_back(Data.HasDesignatedInitializers);
531f4a2713aSLionel Sambuc 
532f4a2713aSLionel Sambuc     // Write out the protocols that are directly referenced by the @interface.
533f4a2713aSLionel Sambuc     Record.push_back(Data.ReferencedProtocols.size());
534*0a6a1f1dSLionel Sambuc     for (const auto *P : D->protocols())
535*0a6a1f1dSLionel Sambuc       Writer.AddDeclRef(P, Record);
536*0a6a1f1dSLionel Sambuc     for (const auto &PL : D->protocol_locs())
537*0a6a1f1dSLionel Sambuc       Writer.AddSourceLocation(PL, Record);
538f4a2713aSLionel Sambuc 
539f4a2713aSLionel Sambuc     // Write out the protocols that are transitively referenced.
540f4a2713aSLionel Sambuc     Record.push_back(Data.AllReferencedProtocols.size());
541f4a2713aSLionel Sambuc     for (ObjCList<ObjCProtocolDecl>::iterator
542f4a2713aSLionel Sambuc               P = Data.AllReferencedProtocols.begin(),
543f4a2713aSLionel Sambuc            PEnd = Data.AllReferencedProtocols.end();
544f4a2713aSLionel Sambuc          P != PEnd; ++P)
545f4a2713aSLionel Sambuc       Writer.AddDeclRef(*P, Record);
546f4a2713aSLionel Sambuc 
547f4a2713aSLionel Sambuc 
548f4a2713aSLionel Sambuc     if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
549f4a2713aSLionel Sambuc       // Ensure that we write out the set of categories for this class.
550f4a2713aSLionel Sambuc       Writer.ObjCClassesWithCategories.insert(D);
551f4a2713aSLionel Sambuc 
552f4a2713aSLionel Sambuc       // Make sure that the categories get serialized.
553f4a2713aSLionel Sambuc       for (; Cat; Cat = Cat->getNextClassCategoryRaw())
554f4a2713aSLionel Sambuc         (void)Writer.GetDeclRef(Cat);
555f4a2713aSLionel Sambuc     }
556f4a2713aSLionel Sambuc   }
557f4a2713aSLionel Sambuc 
558f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_INTERFACE;
559f4a2713aSLionel Sambuc }
560f4a2713aSLionel Sambuc 
VisitObjCIvarDecl(ObjCIvarDecl * D)561f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
562f4a2713aSLionel Sambuc   VisitFieldDecl(D);
563f4a2713aSLionel Sambuc   // FIXME: stable encoding for @public/@private/@protected/@package
564f4a2713aSLionel Sambuc   Record.push_back(D->getAccessControl());
565f4a2713aSLionel Sambuc   Record.push_back(D->getSynthesize());
566f4a2713aSLionel Sambuc 
567f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
568f4a2713aSLionel Sambuc       !D->isImplicit() &&
569f4a2713aSLionel Sambuc       !D->isUsed(false) &&
570f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
571f4a2713aSLionel Sambuc       !D->isReferenced() &&
572f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
573f4a2713aSLionel Sambuc       !D->getBitWidth() &&
574f4a2713aSLionel Sambuc       !D->hasExtInfo() &&
575f4a2713aSLionel Sambuc       D->getDeclName())
576f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclObjCIvarAbbrev();
577f4a2713aSLionel Sambuc 
578f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_IVAR;
579f4a2713aSLionel Sambuc }
580f4a2713aSLionel Sambuc 
VisitObjCProtocolDecl(ObjCProtocolDecl * D)581f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
582f4a2713aSLionel Sambuc   VisitRedeclarable(D);
583f4a2713aSLionel Sambuc   VisitObjCContainerDecl(D);
584f4a2713aSLionel Sambuc 
585f4a2713aSLionel Sambuc   Record.push_back(D->isThisDeclarationADefinition());
586f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition()) {
587f4a2713aSLionel Sambuc     Record.push_back(D->protocol_size());
588*0a6a1f1dSLionel Sambuc     for (const auto *I : D->protocols())
589*0a6a1f1dSLionel Sambuc       Writer.AddDeclRef(I, Record);
590*0a6a1f1dSLionel Sambuc     for (const auto &PL : D->protocol_locs())
591*0a6a1f1dSLionel Sambuc       Writer.AddSourceLocation(PL, Record);
592f4a2713aSLionel Sambuc   }
593f4a2713aSLionel Sambuc 
594f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_PROTOCOL;
595f4a2713aSLionel Sambuc }
596f4a2713aSLionel Sambuc 
VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl * D)597f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
598f4a2713aSLionel Sambuc   VisitFieldDecl(D);
599f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
600f4a2713aSLionel Sambuc }
601f4a2713aSLionel Sambuc 
VisitObjCCategoryDecl(ObjCCategoryDecl * D)602f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
603f4a2713aSLionel Sambuc   VisitObjCContainerDecl(D);
604f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
605f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record);
606f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
607f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getClassInterface(), Record);
608f4a2713aSLionel Sambuc   Record.push_back(D->protocol_size());
609*0a6a1f1dSLionel Sambuc   for (const auto *I : D->protocols())
610*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(I, Record);
611*0a6a1f1dSLionel Sambuc   for (const auto &PL : D->protocol_locs())
612*0a6a1f1dSLionel Sambuc     Writer.AddSourceLocation(PL, Record);
613f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_CATEGORY;
614f4a2713aSLionel Sambuc }
615f4a2713aSLionel Sambuc 
VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl * D)616f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
617f4a2713aSLionel Sambuc   VisitNamedDecl(D);
618f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getClassInterface(), Record);
619f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
620f4a2713aSLionel Sambuc }
621f4a2713aSLionel Sambuc 
VisitObjCPropertyDecl(ObjCPropertyDecl * D)622f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
623f4a2713aSLionel Sambuc   VisitNamedDecl(D);
624f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getAtLoc(), Record);
625f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLParenLoc(), Record);
626f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
627f4a2713aSLionel Sambuc   // FIXME: stable encoding
628f4a2713aSLionel Sambuc   Record.push_back((unsigned)D->getPropertyAttributes());
629f4a2713aSLionel Sambuc   Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
630f4a2713aSLionel Sambuc   // FIXME: stable encoding
631f4a2713aSLionel Sambuc   Record.push_back((unsigned)D->getPropertyImplementation());
632f4a2713aSLionel Sambuc   Writer.AddDeclarationName(D->getGetterName(), Record);
633f4a2713aSLionel Sambuc   Writer.AddDeclarationName(D->getSetterName(), Record);
634f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getGetterMethodDecl(), Record);
635f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getSetterMethodDecl(), Record);
636f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
637f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_PROPERTY;
638f4a2713aSLionel Sambuc }
639f4a2713aSLionel Sambuc 
VisitObjCImplDecl(ObjCImplDecl * D)640f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
641f4a2713aSLionel Sambuc   VisitObjCContainerDecl(D);
642f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getClassInterface(), Record);
643f4a2713aSLionel Sambuc   // Abstract class (no need to define a stable serialization::DECL code).
644f4a2713aSLionel Sambuc }
645f4a2713aSLionel Sambuc 
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)646f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
647f4a2713aSLionel Sambuc   VisitObjCImplDecl(D);
648f4a2713aSLionel Sambuc   Writer.AddIdentifierRef(D->getIdentifier(), Record);
649f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getCategoryNameLoc(), Record);
650f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_CATEGORY_IMPL;
651f4a2713aSLionel Sambuc }
652f4a2713aSLionel Sambuc 
VisitObjCImplementationDecl(ObjCImplementationDecl * D)653f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
654f4a2713aSLionel Sambuc   VisitObjCImplDecl(D);
655f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getSuperClass(), Record);
656f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
657f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record);
658f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
659f4a2713aSLionel Sambuc   Record.push_back(D->hasNonZeroConstructors());
660f4a2713aSLionel Sambuc   Record.push_back(D->hasDestructors());
661f4a2713aSLionel Sambuc   Writer.AddCXXCtorInitializers(D->IvarInitializers, D->NumIvarInitializers,
662f4a2713aSLionel Sambuc                                 Record);
663f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_IMPLEMENTATION;
664f4a2713aSLionel Sambuc }
665f4a2713aSLionel Sambuc 
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * D)666f4a2713aSLionel Sambuc void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
667f4a2713aSLionel Sambuc   VisitDecl(D);
668f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLocStart(), Record);
669f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getPropertyDecl(), Record);
670f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
671f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getPropertyIvarDeclLoc(), Record);
672f4a2713aSLionel Sambuc   Writer.AddStmt(D->getGetterCXXConstructor());
673f4a2713aSLionel Sambuc   Writer.AddStmt(D->getSetterCXXAssignment());
674f4a2713aSLionel Sambuc   Code = serialization::DECL_OBJC_PROPERTY_IMPL;
675f4a2713aSLionel Sambuc }
676f4a2713aSLionel Sambuc 
VisitFieldDecl(FieldDecl * D)677f4a2713aSLionel Sambuc void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
678f4a2713aSLionel Sambuc   VisitDeclaratorDecl(D);
679f4a2713aSLionel Sambuc   Record.push_back(D->isMutable());
680*0a6a1f1dSLionel Sambuc   if (D->InitStorage.getInt() == FieldDecl::ISK_BitWidthOrNothing &&
681*0a6a1f1dSLionel Sambuc       D->InitStorage.getPointer() == nullptr) {
682f4a2713aSLionel Sambuc     Record.push_back(0);
683*0a6a1f1dSLionel Sambuc   } else if (D->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
684*0a6a1f1dSLionel Sambuc     Record.push_back(D->InitStorage.getInt() + 1);
685*0a6a1f1dSLionel Sambuc     Writer.AddTypeRef(
686*0a6a1f1dSLionel Sambuc         QualType(static_cast<Type *>(D->InitStorage.getPointer()), 0),
687*0a6a1f1dSLionel Sambuc         Record);
688*0a6a1f1dSLionel Sambuc   } else {
689*0a6a1f1dSLionel Sambuc     Record.push_back(D->InitStorage.getInt() + 1);
690*0a6a1f1dSLionel Sambuc     Writer.AddStmt(static_cast<Expr *>(D->InitStorage.getPointer()));
691f4a2713aSLionel Sambuc   }
692f4a2713aSLionel Sambuc   if (!D->getDeclName())
693f4a2713aSLionel Sambuc     Writer.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D), Record);
694f4a2713aSLionel Sambuc 
695f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
696f4a2713aSLionel Sambuc       !D->isImplicit() &&
697f4a2713aSLionel Sambuc       !D->isUsed(false) &&
698f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
699f4a2713aSLionel Sambuc       !D->isReferenced() &&
700f4a2713aSLionel Sambuc       !D->isTopLevelDeclInObjCContainer() &&
701f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
702f4a2713aSLionel Sambuc       !D->getBitWidth() &&
703f4a2713aSLionel Sambuc       !D->hasInClassInitializer() &&
704f4a2713aSLionel Sambuc       !D->hasExtInfo() &&
705f4a2713aSLionel Sambuc       !ObjCIvarDecl::classofKind(D->getKind()) &&
706f4a2713aSLionel Sambuc       !ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
707f4a2713aSLionel Sambuc       D->getDeclName())
708f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclFieldAbbrev();
709f4a2713aSLionel Sambuc 
710f4a2713aSLionel Sambuc   Code = serialization::DECL_FIELD;
711f4a2713aSLionel Sambuc }
712f4a2713aSLionel Sambuc 
VisitMSPropertyDecl(MSPropertyDecl * D)713f4a2713aSLionel Sambuc void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
714f4a2713aSLionel Sambuc   VisitDeclaratorDecl(D);
715f4a2713aSLionel Sambuc   Writer.AddIdentifierRef(D->getGetterId(), Record);
716f4a2713aSLionel Sambuc   Writer.AddIdentifierRef(D->getSetterId(), Record);
717f4a2713aSLionel Sambuc   Code = serialization::DECL_MS_PROPERTY;
718f4a2713aSLionel Sambuc }
719f4a2713aSLionel Sambuc 
VisitIndirectFieldDecl(IndirectFieldDecl * D)720f4a2713aSLionel Sambuc void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
721f4a2713aSLionel Sambuc   VisitValueDecl(D);
722f4a2713aSLionel Sambuc   Record.push_back(D->getChainingSize());
723f4a2713aSLionel Sambuc 
724*0a6a1f1dSLionel Sambuc   for (const auto *P : D->chain())
725*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(P, Record);
726f4a2713aSLionel Sambuc   Code = serialization::DECL_INDIRECTFIELD;
727f4a2713aSLionel Sambuc }
728f4a2713aSLionel Sambuc 
VisitVarDecl(VarDecl * D)729f4a2713aSLionel Sambuc void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
730f4a2713aSLionel Sambuc   VisitRedeclarable(D);
731f4a2713aSLionel Sambuc   VisitDeclaratorDecl(D);
732f4a2713aSLionel Sambuc   Record.push_back(D->getStorageClass());
733f4a2713aSLionel Sambuc   Record.push_back(D->getTSCSpec());
734f4a2713aSLionel Sambuc   Record.push_back(D->getInitStyle());
735f4a2713aSLionel Sambuc   Record.push_back(D->isExceptionVariable());
736f4a2713aSLionel Sambuc   Record.push_back(D->isNRVOVariable());
737f4a2713aSLionel Sambuc   Record.push_back(D->isCXXForRangeDecl());
738f4a2713aSLionel Sambuc   Record.push_back(D->isARCPseudoStrong());
739f4a2713aSLionel Sambuc   Record.push_back(D->isConstexpr());
740f4a2713aSLionel Sambuc   Record.push_back(D->isInitCapture());
741f4a2713aSLionel Sambuc   Record.push_back(D->isPreviousDeclInSameBlockScope());
742f4a2713aSLionel Sambuc   Record.push_back(D->getLinkageInternal());
743f4a2713aSLionel Sambuc 
744f4a2713aSLionel Sambuc   if (D->getInit()) {
745f4a2713aSLionel Sambuc     Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2));
746f4a2713aSLionel Sambuc     Writer.AddStmt(D->getInit());
747f4a2713aSLionel Sambuc   } else {
748f4a2713aSLionel Sambuc     Record.push_back(0);
749f4a2713aSLionel Sambuc   }
750f4a2713aSLionel Sambuc 
751f4a2713aSLionel Sambuc   enum {
752f4a2713aSLionel Sambuc     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
753f4a2713aSLionel Sambuc   };
754f4a2713aSLionel Sambuc   if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
755f4a2713aSLionel Sambuc     Record.push_back(VarTemplate);
756f4a2713aSLionel Sambuc     Writer.AddDeclRef(TemplD, Record);
757f4a2713aSLionel Sambuc   } else if (MemberSpecializationInfo *SpecInfo
758f4a2713aSLionel Sambuc                = D->getMemberSpecializationInfo()) {
759f4a2713aSLionel Sambuc     Record.push_back(StaticDataMemberSpecialization);
760f4a2713aSLionel Sambuc     Writer.AddDeclRef(SpecInfo->getInstantiatedFrom(), Record);
761f4a2713aSLionel Sambuc     Record.push_back(SpecInfo->getTemplateSpecializationKind());
762f4a2713aSLionel Sambuc     Writer.AddSourceLocation(SpecInfo->getPointOfInstantiation(), Record);
763f4a2713aSLionel Sambuc   } else {
764f4a2713aSLionel Sambuc     Record.push_back(VarNotTemplate);
765f4a2713aSLionel Sambuc   }
766f4a2713aSLionel Sambuc 
767f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
768f4a2713aSLionel Sambuc       !D->isImplicit() &&
769f4a2713aSLionel Sambuc       !D->isUsed(false) &&
770f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
771f4a2713aSLionel Sambuc       !D->isReferenced() &&
772f4a2713aSLionel Sambuc       !D->isTopLevelDeclInObjCContainer() &&
773f4a2713aSLionel Sambuc       D->getAccess() == AS_none &&
774f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
775*0a6a1f1dSLionel Sambuc       !needsAnonymousDeclarationNumber(D) &&
776f4a2713aSLionel Sambuc       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
777f4a2713aSLionel Sambuc       !D->hasExtInfo() &&
778f4a2713aSLionel Sambuc       D->getFirstDecl() == D->getMostRecentDecl() &&
779f4a2713aSLionel Sambuc       D->getInitStyle() == VarDecl::CInit &&
780*0a6a1f1dSLionel Sambuc       D->getInit() == nullptr &&
781f4a2713aSLionel Sambuc       !isa<ParmVarDecl>(D) &&
782f4a2713aSLionel Sambuc       !isa<VarTemplateSpecializationDecl>(D) &&
783f4a2713aSLionel Sambuc       !D->isConstexpr() &&
784f4a2713aSLionel Sambuc       !D->isInitCapture() &&
785f4a2713aSLionel Sambuc       !D->isPreviousDeclInSameBlockScope() &&
786f4a2713aSLionel Sambuc       !D->getMemberSpecializationInfo())
787f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclVarAbbrev();
788f4a2713aSLionel Sambuc 
789f4a2713aSLionel Sambuc   Code = serialization::DECL_VAR;
790f4a2713aSLionel Sambuc }
791f4a2713aSLionel Sambuc 
VisitImplicitParamDecl(ImplicitParamDecl * D)792f4a2713aSLionel Sambuc void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
793f4a2713aSLionel Sambuc   VisitVarDecl(D);
794f4a2713aSLionel Sambuc   Code = serialization::DECL_IMPLICIT_PARAM;
795f4a2713aSLionel Sambuc }
796f4a2713aSLionel Sambuc 
VisitParmVarDecl(ParmVarDecl * D)797f4a2713aSLionel Sambuc void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
798f4a2713aSLionel Sambuc   VisitVarDecl(D);
799f4a2713aSLionel Sambuc   Record.push_back(D->isObjCMethodParameter());
800f4a2713aSLionel Sambuc   Record.push_back(D->getFunctionScopeDepth());
801f4a2713aSLionel Sambuc   Record.push_back(D->getFunctionScopeIndex());
802f4a2713aSLionel Sambuc   Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
803f4a2713aSLionel Sambuc   Record.push_back(D->isKNRPromoted());
804f4a2713aSLionel Sambuc   Record.push_back(D->hasInheritedDefaultArg());
805f4a2713aSLionel Sambuc   Record.push_back(D->hasUninstantiatedDefaultArg());
806f4a2713aSLionel Sambuc   if (D->hasUninstantiatedDefaultArg())
807f4a2713aSLionel Sambuc     Writer.AddStmt(D->getUninstantiatedDefaultArg());
808f4a2713aSLionel Sambuc   Code = serialization::DECL_PARM_VAR;
809f4a2713aSLionel Sambuc 
810f4a2713aSLionel Sambuc   assert(!D->isARCPseudoStrong()); // can be true of ImplicitParamDecl
811f4a2713aSLionel Sambuc 
812f4a2713aSLionel Sambuc   // If the assumptions about the DECL_PARM_VAR abbrev are true, use it.  Here
813f4a2713aSLionel Sambuc   // we dynamically check for the properties that we optimize for, but don't
814f4a2713aSLionel Sambuc   // know are true of all PARM_VAR_DECLs.
815f4a2713aSLionel Sambuc   if (!D->hasAttrs() &&
816f4a2713aSLionel Sambuc       !D->hasExtInfo() &&
817f4a2713aSLionel Sambuc       !D->isImplicit() &&
818f4a2713aSLionel Sambuc       !D->isUsed(false) &&
819f4a2713aSLionel Sambuc       !D->isInvalidDecl() &&
820f4a2713aSLionel Sambuc       !D->isReferenced() &&
821f4a2713aSLionel Sambuc       D->getAccess() == AS_none &&
822f4a2713aSLionel Sambuc       !D->isModulePrivate() &&
823f4a2713aSLionel Sambuc       D->getStorageClass() == 0 &&
824f4a2713aSLionel Sambuc       D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
825f4a2713aSLionel Sambuc       D->getFunctionScopeDepth() == 0 &&
826f4a2713aSLionel Sambuc       D->getObjCDeclQualifier() == 0 &&
827f4a2713aSLionel Sambuc       !D->isKNRPromoted() &&
828f4a2713aSLionel Sambuc       !D->hasInheritedDefaultArg() &&
829*0a6a1f1dSLionel Sambuc       D->getInit() == nullptr &&
830f4a2713aSLionel Sambuc       !D->hasUninstantiatedDefaultArg())  // No default expr.
831f4a2713aSLionel Sambuc     AbbrevToUse = Writer.getDeclParmVarAbbrev();
832f4a2713aSLionel Sambuc 
833f4a2713aSLionel Sambuc   // Check things we know are true of *every* PARM_VAR_DECL, which is more than
834f4a2713aSLionel Sambuc   // just us assuming it.
835f4a2713aSLionel Sambuc   assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
836f4a2713aSLionel Sambuc   assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
837f4a2713aSLionel Sambuc   assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
838*0a6a1f1dSLionel Sambuc   assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
839f4a2713aSLionel Sambuc   assert(!D->isStaticDataMember() &&
840f4a2713aSLionel Sambuc          "PARM_VAR_DECL can't be static data member");
841f4a2713aSLionel Sambuc }
842f4a2713aSLionel Sambuc 
VisitFileScopeAsmDecl(FileScopeAsmDecl * D)843f4a2713aSLionel Sambuc void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
844f4a2713aSLionel Sambuc   VisitDecl(D);
845f4a2713aSLionel Sambuc   Writer.AddStmt(D->getAsmString());
846f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getRParenLoc(), Record);
847f4a2713aSLionel Sambuc   Code = serialization::DECL_FILE_SCOPE_ASM;
848f4a2713aSLionel Sambuc }
849f4a2713aSLionel Sambuc 
VisitEmptyDecl(EmptyDecl * D)850f4a2713aSLionel Sambuc void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
851f4a2713aSLionel Sambuc   VisitDecl(D);
852f4a2713aSLionel Sambuc   Code = serialization::DECL_EMPTY;
853f4a2713aSLionel Sambuc }
854f4a2713aSLionel Sambuc 
VisitBlockDecl(BlockDecl * D)855f4a2713aSLionel Sambuc void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
856f4a2713aSLionel Sambuc   VisitDecl(D);
857f4a2713aSLionel Sambuc   Writer.AddStmt(D->getBody());
858f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getSignatureAsWritten(), Record);
859f4a2713aSLionel Sambuc   Record.push_back(D->param_size());
860f4a2713aSLionel Sambuc   for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
861f4a2713aSLionel Sambuc        P != PEnd; ++P)
862f4a2713aSLionel Sambuc     Writer.AddDeclRef(*P, Record);
863f4a2713aSLionel Sambuc   Record.push_back(D->isVariadic());
864f4a2713aSLionel Sambuc   Record.push_back(D->blockMissingReturnType());
865f4a2713aSLionel Sambuc   Record.push_back(D->isConversionFromLambda());
866f4a2713aSLionel Sambuc   Record.push_back(D->capturesCXXThis());
867f4a2713aSLionel Sambuc   Record.push_back(D->getNumCaptures());
868*0a6a1f1dSLionel Sambuc   for (const auto &capture : D->captures()) {
869f4a2713aSLionel Sambuc     Writer.AddDeclRef(capture.getVariable(), Record);
870f4a2713aSLionel Sambuc 
871f4a2713aSLionel Sambuc     unsigned flags = 0;
872f4a2713aSLionel Sambuc     if (capture.isByRef()) flags |= 1;
873f4a2713aSLionel Sambuc     if (capture.isNested()) flags |= 2;
874f4a2713aSLionel Sambuc     if (capture.hasCopyExpr()) flags |= 4;
875f4a2713aSLionel Sambuc     Record.push_back(flags);
876f4a2713aSLionel Sambuc 
877f4a2713aSLionel Sambuc     if (capture.hasCopyExpr()) Writer.AddStmt(capture.getCopyExpr());
878f4a2713aSLionel Sambuc   }
879f4a2713aSLionel Sambuc 
880f4a2713aSLionel Sambuc   Code = serialization::DECL_BLOCK;
881f4a2713aSLionel Sambuc }
882f4a2713aSLionel Sambuc 
VisitCapturedDecl(CapturedDecl * CD)883f4a2713aSLionel Sambuc void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
884f4a2713aSLionel Sambuc   Record.push_back(CD->getNumParams());
885f4a2713aSLionel Sambuc   VisitDecl(CD);
886*0a6a1f1dSLionel Sambuc   Record.push_back(CD->getContextParamPosition());
887*0a6a1f1dSLionel Sambuc   Record.push_back(CD->isNothrow() ? 1 : 0);
888f4a2713aSLionel Sambuc   // Body is stored by VisitCapturedStmt.
889*0a6a1f1dSLionel Sambuc   for (unsigned I = 0; I < CD->getNumParams(); ++I)
890*0a6a1f1dSLionel Sambuc     Writer.AddDeclRef(CD->getParam(I), Record);
891f4a2713aSLionel Sambuc   Code = serialization::DECL_CAPTURED;
892f4a2713aSLionel Sambuc }
893f4a2713aSLionel Sambuc 
VisitLinkageSpecDecl(LinkageSpecDecl * D)894f4a2713aSLionel Sambuc void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
895f4a2713aSLionel Sambuc   VisitDecl(D);
896f4a2713aSLionel Sambuc   Record.push_back(D->getLanguage());
897f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getExternLoc(), Record);
898f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getRBraceLoc(), Record);
899f4a2713aSLionel Sambuc   Code = serialization::DECL_LINKAGE_SPEC;
900f4a2713aSLionel Sambuc }
901f4a2713aSLionel Sambuc 
VisitLabelDecl(LabelDecl * D)902f4a2713aSLionel Sambuc void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
903f4a2713aSLionel Sambuc   VisitNamedDecl(D);
904f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLocStart(), Record);
905f4a2713aSLionel Sambuc   Code = serialization::DECL_LABEL;
906f4a2713aSLionel Sambuc }
907f4a2713aSLionel Sambuc 
908f4a2713aSLionel Sambuc 
VisitNamespaceDecl(NamespaceDecl * D)909f4a2713aSLionel Sambuc void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
910f4a2713aSLionel Sambuc   VisitRedeclarable(D);
911f4a2713aSLionel Sambuc   VisitNamedDecl(D);
912f4a2713aSLionel Sambuc   Record.push_back(D->isInline());
913f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getLocStart(), Record);
914f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getRBraceLoc(), Record);
915f4a2713aSLionel Sambuc 
916f4a2713aSLionel Sambuc   if (D->isOriginalNamespace())
917f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
918f4a2713aSLionel Sambuc   Code = serialization::DECL_NAMESPACE;
919f4a2713aSLionel Sambuc 
920f4a2713aSLionel Sambuc   if (Writer.hasChain() && !D->isOriginalNamespace() &&
921f4a2713aSLionel Sambuc       D->getOriginalNamespace()->isFromASTFile()) {
922f4a2713aSLionel Sambuc     NamespaceDecl *NS = D->getOriginalNamespace();
923f4a2713aSLionel Sambuc     Writer.AddUpdatedDeclContext(NS);
924f4a2713aSLionel Sambuc 
925f4a2713aSLionel Sambuc     // Make sure all visible decls are written. They will be recorded later.
926f4a2713aSLionel Sambuc     if (StoredDeclsMap *Map = NS->buildLookup()) {
927f4a2713aSLionel Sambuc       for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
928f4a2713aSLionel Sambuc            D != DEnd; ++D) {
929f4a2713aSLionel Sambuc         DeclContext::lookup_result R = D->second.getLookupResult();
930f4a2713aSLionel Sambuc         for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
931f4a2713aSLionel Sambuc              ++I)
932f4a2713aSLionel Sambuc           Writer.GetDeclRef(*I);
933f4a2713aSLionel Sambuc       }
934f4a2713aSLionel Sambuc     }
935f4a2713aSLionel Sambuc   }
936f4a2713aSLionel Sambuc 
937f4a2713aSLionel Sambuc   if (Writer.hasChain() && D->isAnonymousNamespace() &&
938f4a2713aSLionel Sambuc       D == D->getMostRecentDecl()) {
939f4a2713aSLionel Sambuc     // This is a most recent reopening of the anonymous namespace. If its parent
940f4a2713aSLionel Sambuc     // is in a previous PCH (or is the TU), mark that parent for update, because
941f4a2713aSLionel Sambuc     // the original namespace always points to the latest re-opening of its
942f4a2713aSLionel Sambuc     // anonymous namespace.
943f4a2713aSLionel Sambuc     Decl *Parent = cast<Decl>(
944f4a2713aSLionel Sambuc         D->getParent()->getRedeclContext()->getPrimaryContext());
945f4a2713aSLionel Sambuc     if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
946*0a6a1f1dSLionel Sambuc       Writer.DeclUpdates[Parent].push_back(
947*0a6a1f1dSLionel Sambuc           ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
948f4a2713aSLionel Sambuc     }
949f4a2713aSLionel Sambuc   }
950f4a2713aSLionel Sambuc }
951f4a2713aSLionel Sambuc 
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)952f4a2713aSLionel Sambuc void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
953*0a6a1f1dSLionel Sambuc   VisitRedeclarable(D);
954f4a2713aSLionel Sambuc   VisitNamedDecl(D);
955f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getNamespaceLoc(), Record);
956f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getTargetNameLoc(), Record);
957f4a2713aSLionel Sambuc   Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
958f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getNamespace(), Record);
959f4a2713aSLionel Sambuc   Code = serialization::DECL_NAMESPACE_ALIAS;
960f4a2713aSLionel Sambuc }
961f4a2713aSLionel Sambuc 
VisitUsingDecl(UsingDecl * D)962f4a2713aSLionel Sambuc void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
963f4a2713aSLionel Sambuc   VisitNamedDecl(D);
964f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getUsingLoc(), Record);
965f4a2713aSLionel Sambuc   Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
966f4a2713aSLionel Sambuc   Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
967f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->FirstUsingShadow.getPointer(), Record);
968f4a2713aSLionel Sambuc   Record.push_back(D->hasTypename());
969f4a2713aSLionel Sambuc   Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record);
970f4a2713aSLionel Sambuc   Code = serialization::DECL_USING;
971f4a2713aSLionel Sambuc }
972f4a2713aSLionel Sambuc 
VisitUsingShadowDecl(UsingShadowDecl * D)973f4a2713aSLionel Sambuc void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
974f4a2713aSLionel Sambuc   VisitRedeclarable(D);
975f4a2713aSLionel Sambuc   VisitNamedDecl(D);
976f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getTargetDecl(), Record);
977f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->UsingOrNextShadow, Record);
978f4a2713aSLionel Sambuc   Writer.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D), Record);
979f4a2713aSLionel Sambuc   Code = serialization::DECL_USING_SHADOW;
980f4a2713aSLionel Sambuc }
981f4a2713aSLionel Sambuc 
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)982f4a2713aSLionel Sambuc void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
983f4a2713aSLionel Sambuc   VisitNamedDecl(D);
984f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getUsingLoc(), Record);
985f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getNamespaceKeyLocation(), Record);
986f4a2713aSLionel Sambuc   Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
987f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getNominatedNamespace(), Record);
988f4a2713aSLionel Sambuc   Writer.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()), Record);
989f4a2713aSLionel Sambuc   Code = serialization::DECL_USING_DIRECTIVE;
990f4a2713aSLionel Sambuc }
991f4a2713aSLionel Sambuc 
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)992f4a2713aSLionel Sambuc void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
993f4a2713aSLionel Sambuc   VisitValueDecl(D);
994f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getUsingLoc(), Record);
995f4a2713aSLionel Sambuc   Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
996f4a2713aSLionel Sambuc   Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
997f4a2713aSLionel Sambuc   Code = serialization::DECL_UNRESOLVED_USING_VALUE;
998f4a2713aSLionel Sambuc }
999f4a2713aSLionel Sambuc 
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1000f4a2713aSLionel Sambuc void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
1001f4a2713aSLionel Sambuc                                                UnresolvedUsingTypenameDecl *D) {
1002f4a2713aSLionel Sambuc   VisitTypeDecl(D);
1003f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getTypenameLoc(), Record);
1004f4a2713aSLionel Sambuc   Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
1005f4a2713aSLionel Sambuc   Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
1006f4a2713aSLionel Sambuc }
1007f4a2713aSLionel Sambuc 
VisitCXXRecordDecl(CXXRecordDecl * D)1008f4a2713aSLionel Sambuc void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
1009f4a2713aSLionel Sambuc   VisitRecordDecl(D);
1010f4a2713aSLionel Sambuc 
1011f4a2713aSLionel Sambuc   enum {
1012f4a2713aSLionel Sambuc     CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
1013f4a2713aSLionel Sambuc   };
1014f4a2713aSLionel Sambuc   if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
1015f4a2713aSLionel Sambuc     Record.push_back(CXXRecTemplate);
1016f4a2713aSLionel Sambuc     Writer.AddDeclRef(TemplD, Record);
1017f4a2713aSLionel Sambuc   } else if (MemberSpecializationInfo *MSInfo
1018f4a2713aSLionel Sambuc                = D->getMemberSpecializationInfo()) {
1019f4a2713aSLionel Sambuc     Record.push_back(CXXRecMemberSpecialization);
1020f4a2713aSLionel Sambuc     Writer.AddDeclRef(MSInfo->getInstantiatedFrom(), Record);
1021f4a2713aSLionel Sambuc     Record.push_back(MSInfo->getTemplateSpecializationKind());
1022f4a2713aSLionel Sambuc     Writer.AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
1023f4a2713aSLionel Sambuc   } else {
1024f4a2713aSLionel Sambuc     Record.push_back(CXXRecNotTemplate);
1025f4a2713aSLionel Sambuc   }
1026f4a2713aSLionel Sambuc 
1027*0a6a1f1dSLionel Sambuc   Record.push_back(D->isThisDeclarationADefinition());
1028*0a6a1f1dSLionel Sambuc   if (D->isThisDeclarationADefinition())
1029*0a6a1f1dSLionel Sambuc     Writer.AddCXXDefinitionData(D, Record);
1030*0a6a1f1dSLionel Sambuc 
1031f4a2713aSLionel Sambuc   // Store (what we currently believe to be) the key function to avoid
1032f4a2713aSLionel Sambuc   // deserializing every method so we can compute it.
1033f4a2713aSLionel Sambuc   if (D->IsCompleteDefinition)
1034f4a2713aSLionel Sambuc     Writer.AddDeclRef(Context.getCurrentKeyFunction(D), Record);
1035f4a2713aSLionel Sambuc 
1036f4a2713aSLionel Sambuc   Code = serialization::DECL_CXX_RECORD;
1037f4a2713aSLionel Sambuc }
1038f4a2713aSLionel Sambuc 
VisitCXXMethodDecl(CXXMethodDecl * D)1039f4a2713aSLionel Sambuc void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
1040f4a2713aSLionel Sambuc   VisitFunctionDecl(D);
1041f4a2713aSLionel Sambuc   if (D->isCanonicalDecl()) {
1042f4a2713aSLionel Sambuc     Record.push_back(D->size_overridden_methods());
1043f4a2713aSLionel Sambuc     for (CXXMethodDecl::method_iterator
1044f4a2713aSLionel Sambuc            I = D->begin_overridden_methods(), E = D->end_overridden_methods();
1045f4a2713aSLionel Sambuc            I != E; ++I)
1046f4a2713aSLionel Sambuc       Writer.AddDeclRef(*I, Record);
1047f4a2713aSLionel Sambuc   } else {
1048f4a2713aSLionel Sambuc     // We only need to record overridden methods once for the canonical decl.
1049f4a2713aSLionel Sambuc     Record.push_back(0);
1050f4a2713aSLionel Sambuc   }
1051*0a6a1f1dSLionel Sambuc 
1052*0a6a1f1dSLionel Sambuc   if (D->getFirstDecl() == D->getMostRecentDecl() &&
1053*0a6a1f1dSLionel Sambuc       !D->isInvalidDecl() &&
1054*0a6a1f1dSLionel Sambuc       !D->hasAttrs() &&
1055*0a6a1f1dSLionel Sambuc       !D->isTopLevelDeclInObjCContainer() &&
1056*0a6a1f1dSLionel Sambuc       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
1057*0a6a1f1dSLionel Sambuc       !D->hasExtInfo() &&
1058*0a6a1f1dSLionel Sambuc       !D->hasInheritedPrototype() &&
1059*0a6a1f1dSLionel Sambuc       D->hasWrittenPrototype())
1060*0a6a1f1dSLionel Sambuc     AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
1061*0a6a1f1dSLionel Sambuc 
1062f4a2713aSLionel Sambuc   Code = serialization::DECL_CXX_METHOD;
1063f4a2713aSLionel Sambuc }
1064f4a2713aSLionel Sambuc 
VisitCXXConstructorDecl(CXXConstructorDecl * D)1065f4a2713aSLionel Sambuc void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1066f4a2713aSLionel Sambuc   VisitCXXMethodDecl(D);
1067f4a2713aSLionel Sambuc 
1068*0a6a1f1dSLionel Sambuc   Writer.AddDeclRef(D->getInheritedConstructor(), Record);
1069f4a2713aSLionel Sambuc   Record.push_back(D->IsExplicitSpecified);
1070f4a2713aSLionel Sambuc   Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers,
1071f4a2713aSLionel Sambuc                                 Record);
1072f4a2713aSLionel Sambuc 
1073f4a2713aSLionel Sambuc   Code = serialization::DECL_CXX_CONSTRUCTOR;
1074f4a2713aSLionel Sambuc }
1075f4a2713aSLionel Sambuc 
VisitCXXDestructorDecl(CXXDestructorDecl * D)1076f4a2713aSLionel Sambuc void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
1077f4a2713aSLionel Sambuc   VisitCXXMethodDecl(D);
1078f4a2713aSLionel Sambuc 
1079f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->OperatorDelete, Record);
1080f4a2713aSLionel Sambuc 
1081f4a2713aSLionel Sambuc   Code = serialization::DECL_CXX_DESTRUCTOR;
1082f4a2713aSLionel Sambuc }
1083f4a2713aSLionel Sambuc 
VisitCXXConversionDecl(CXXConversionDecl * D)1084f4a2713aSLionel Sambuc void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
1085f4a2713aSLionel Sambuc   VisitCXXMethodDecl(D);
1086f4a2713aSLionel Sambuc   Record.push_back(D->IsExplicitSpecified);
1087f4a2713aSLionel Sambuc   Code = serialization::DECL_CXX_CONVERSION;
1088f4a2713aSLionel Sambuc }
1089f4a2713aSLionel Sambuc 
VisitImportDecl(ImportDecl * D)1090f4a2713aSLionel Sambuc void ASTDeclWriter::VisitImportDecl(ImportDecl *D) {
1091f4a2713aSLionel Sambuc   VisitDecl(D);
1092f4a2713aSLionel Sambuc   Record.push_back(Writer.getSubmoduleID(D->getImportedModule()));
1093f4a2713aSLionel Sambuc   ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
1094f4a2713aSLionel Sambuc   Record.push_back(!IdentifierLocs.empty());
1095f4a2713aSLionel Sambuc   if (IdentifierLocs.empty()) {
1096f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getLocEnd(), Record);
1097f4a2713aSLionel Sambuc     Record.push_back(1);
1098f4a2713aSLionel Sambuc   } else {
1099f4a2713aSLionel Sambuc     for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
1100f4a2713aSLionel Sambuc       Writer.AddSourceLocation(IdentifierLocs[I], Record);
1101f4a2713aSLionel Sambuc     Record.push_back(IdentifierLocs.size());
1102f4a2713aSLionel Sambuc   }
1103f4a2713aSLionel Sambuc   // Note: the number of source locations must always be the last element in
1104f4a2713aSLionel Sambuc   // the record.
1105f4a2713aSLionel Sambuc   Code = serialization::DECL_IMPORT;
1106f4a2713aSLionel Sambuc }
1107f4a2713aSLionel Sambuc 
VisitAccessSpecDecl(AccessSpecDecl * D)1108f4a2713aSLionel Sambuc void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
1109f4a2713aSLionel Sambuc   VisitDecl(D);
1110f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getColonLoc(), Record);
1111f4a2713aSLionel Sambuc   Code = serialization::DECL_ACCESS_SPEC;
1112f4a2713aSLionel Sambuc }
1113f4a2713aSLionel Sambuc 
VisitFriendDecl(FriendDecl * D)1114f4a2713aSLionel Sambuc void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
1115f4a2713aSLionel Sambuc   // Record the number of friend type template parameter lists here
1116f4a2713aSLionel Sambuc   // so as to simplify memory allocation during deserialization.
1117f4a2713aSLionel Sambuc   Record.push_back(D->NumTPLists);
1118f4a2713aSLionel Sambuc   VisitDecl(D);
1119f4a2713aSLionel Sambuc   bool hasFriendDecl = D->Friend.is<NamedDecl*>();
1120f4a2713aSLionel Sambuc   Record.push_back(hasFriendDecl);
1121f4a2713aSLionel Sambuc   if (hasFriendDecl)
1122f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getFriendDecl(), Record);
1123f4a2713aSLionel Sambuc   else
1124f4a2713aSLionel Sambuc     Writer.AddTypeSourceInfo(D->getFriendType(), Record);
1125f4a2713aSLionel Sambuc   for (unsigned i = 0; i < D->NumTPLists; ++i)
1126f4a2713aSLionel Sambuc     Writer.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i),
1127f4a2713aSLionel Sambuc                                     Record);
1128f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getNextFriend(), Record);
1129f4a2713aSLionel Sambuc   Record.push_back(D->UnsupportedFriend);
1130f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->FriendLoc, Record);
1131f4a2713aSLionel Sambuc   Code = serialization::DECL_FRIEND;
1132f4a2713aSLionel Sambuc }
1133f4a2713aSLionel Sambuc 
VisitFriendTemplateDecl(FriendTemplateDecl * D)1134f4a2713aSLionel Sambuc void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
1135f4a2713aSLionel Sambuc   VisitDecl(D);
1136f4a2713aSLionel Sambuc   Record.push_back(D->getNumTemplateParameters());
1137f4a2713aSLionel Sambuc   for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
1138f4a2713aSLionel Sambuc     Writer.AddTemplateParameterList(D->getTemplateParameterList(i), Record);
1139*0a6a1f1dSLionel Sambuc   Record.push_back(D->getFriendDecl() != nullptr);
1140f4a2713aSLionel Sambuc   if (D->getFriendDecl())
1141f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getFriendDecl(), Record);
1142f4a2713aSLionel Sambuc   else
1143f4a2713aSLionel Sambuc     Writer.AddTypeSourceInfo(D->getFriendType(), Record);
1144f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getFriendLoc(), Record);
1145f4a2713aSLionel Sambuc   Code = serialization::DECL_FRIEND_TEMPLATE;
1146f4a2713aSLionel Sambuc }
1147f4a2713aSLionel Sambuc 
VisitTemplateDecl(TemplateDecl * D)1148f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
1149f4a2713aSLionel Sambuc   VisitNamedDecl(D);
1150f4a2713aSLionel Sambuc 
1151f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getTemplatedDecl(), Record);
1152f4a2713aSLionel Sambuc   Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
1153f4a2713aSLionel Sambuc }
1154f4a2713aSLionel Sambuc 
VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl * D)1155f4a2713aSLionel Sambuc void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
1156f4a2713aSLionel Sambuc   VisitRedeclarable(D);
1157f4a2713aSLionel Sambuc 
1158f4a2713aSLionel Sambuc   // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
1159f4a2713aSLionel Sambuc   // getCommonPtr() can be used while this is still initializing.
1160f4a2713aSLionel Sambuc   if (D->isFirstDecl()) {
1161f4a2713aSLionel Sambuc     // This declaration owns the 'common' pointer, so serialize that data now.
1162f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
1163f4a2713aSLionel Sambuc     if (D->getInstantiatedFromMemberTemplate())
1164f4a2713aSLionel Sambuc       Record.push_back(D->isMemberSpecialization());
1165f4a2713aSLionel Sambuc   }
1166f4a2713aSLionel Sambuc 
1167f4a2713aSLionel Sambuc   VisitTemplateDecl(D);
1168f4a2713aSLionel Sambuc   Record.push_back(D->getIdentifierNamespace());
1169f4a2713aSLionel Sambuc }
1170f4a2713aSLionel Sambuc 
VisitClassTemplateDecl(ClassTemplateDecl * D)1171f4a2713aSLionel Sambuc void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1172f4a2713aSLionel Sambuc   VisitRedeclarableTemplateDecl(D);
1173f4a2713aSLionel Sambuc 
1174f4a2713aSLionel Sambuc   if (D->isFirstDecl()) {
1175f4a2713aSLionel Sambuc     typedef llvm::FoldingSetVector<ClassTemplateSpecializationDecl> CTSDSetTy;
1176f4a2713aSLionel Sambuc     CTSDSetTy &CTSDSet = D->getSpecializations();
1177f4a2713aSLionel Sambuc     Record.push_back(CTSDSet.size());
1178f4a2713aSLionel Sambuc     for (CTSDSetTy::iterator I=CTSDSet.begin(), E = CTSDSet.end(); I!=E; ++I) {
1179f4a2713aSLionel Sambuc       assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
1180f4a2713aSLionel Sambuc       Writer.AddDeclRef(&*I, Record);
1181f4a2713aSLionel Sambuc     }
1182f4a2713aSLionel Sambuc 
1183f4a2713aSLionel Sambuc     typedef llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
1184f4a2713aSLionel Sambuc       CTPSDSetTy;
1185f4a2713aSLionel Sambuc     CTPSDSetTy &CTPSDSet = D->getPartialSpecializations();
1186f4a2713aSLionel Sambuc     Record.push_back(CTPSDSet.size());
1187f4a2713aSLionel Sambuc     for (CTPSDSetTy::iterator I=CTPSDSet.begin(), E=CTPSDSet.end(); I!=E; ++I) {
1188f4a2713aSLionel Sambuc       assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
1189f4a2713aSLionel Sambuc       Writer.AddDeclRef(&*I, Record);
1190f4a2713aSLionel Sambuc     }
1191f4a2713aSLionel Sambuc   }
1192f4a2713aSLionel Sambuc   Code = serialization::DECL_CLASS_TEMPLATE;
1193f4a2713aSLionel Sambuc }
1194f4a2713aSLionel Sambuc 
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)1195f4a2713aSLionel Sambuc void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
1196f4a2713aSLionel Sambuc                                            ClassTemplateSpecializationDecl *D) {
1197f4a2713aSLionel Sambuc   VisitCXXRecordDecl(D);
1198f4a2713aSLionel Sambuc 
1199f4a2713aSLionel Sambuc   llvm::PointerUnion<ClassTemplateDecl *,
1200f4a2713aSLionel Sambuc                      ClassTemplatePartialSpecializationDecl *> InstFrom
1201f4a2713aSLionel Sambuc     = D->getSpecializedTemplateOrPartial();
1202f4a2713aSLionel Sambuc   if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
1203f4a2713aSLionel Sambuc     Writer.AddDeclRef(InstFromD, Record);
1204f4a2713aSLionel Sambuc   } else {
1205f4a2713aSLionel Sambuc     Writer.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>(),
1206f4a2713aSLionel Sambuc                       Record);
1207f4a2713aSLionel Sambuc     Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
1208f4a2713aSLionel Sambuc   }
1209f4a2713aSLionel Sambuc 
1210f4a2713aSLionel Sambuc   Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
1211f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
1212f4a2713aSLionel Sambuc   Record.push_back(D->getSpecializationKind());
1213f4a2713aSLionel Sambuc   Record.push_back(D->isCanonicalDecl());
1214f4a2713aSLionel Sambuc 
1215f4a2713aSLionel Sambuc   if (D->isCanonicalDecl()) {
1216f4a2713aSLionel Sambuc     // When reading, we'll add it to the folding set of the following template.
1217f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record);
1218f4a2713aSLionel Sambuc   }
1219f4a2713aSLionel Sambuc 
1220f4a2713aSLionel Sambuc   // Explicit info.
1221f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
1222f4a2713aSLionel Sambuc   if (D->getTypeAsWritten()) {
1223f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getExternLoc(), Record);
1224f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
1225f4a2713aSLionel Sambuc   }
1226f4a2713aSLionel Sambuc 
1227f4a2713aSLionel Sambuc   Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
1228f4a2713aSLionel Sambuc }
1229f4a2713aSLionel Sambuc 
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)1230f4a2713aSLionel Sambuc void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
1231f4a2713aSLionel Sambuc                                     ClassTemplatePartialSpecializationDecl *D) {
1232f4a2713aSLionel Sambuc   VisitClassTemplateSpecializationDecl(D);
1233f4a2713aSLionel Sambuc 
1234f4a2713aSLionel Sambuc   Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
1235f4a2713aSLionel Sambuc   Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record);
1236f4a2713aSLionel Sambuc 
1237f4a2713aSLionel Sambuc   // These are read/set from/to the first declaration.
1238*0a6a1f1dSLionel Sambuc   if (D->getPreviousDecl() == nullptr) {
1239f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
1240f4a2713aSLionel Sambuc     Record.push_back(D->isMemberSpecialization());
1241f4a2713aSLionel Sambuc   }
1242f4a2713aSLionel Sambuc 
1243f4a2713aSLionel Sambuc   Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
1244f4a2713aSLionel Sambuc }
1245f4a2713aSLionel Sambuc 
VisitVarTemplateDecl(VarTemplateDecl * D)1246f4a2713aSLionel Sambuc void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
1247f4a2713aSLionel Sambuc   VisitRedeclarableTemplateDecl(D);
1248f4a2713aSLionel Sambuc 
1249f4a2713aSLionel Sambuc   if (D->isFirstDecl()) {
1250f4a2713aSLionel Sambuc     typedef llvm::FoldingSetVector<VarTemplateSpecializationDecl> VTSDSetTy;
1251f4a2713aSLionel Sambuc     VTSDSetTy &VTSDSet = D->getSpecializations();
1252f4a2713aSLionel Sambuc     Record.push_back(VTSDSet.size());
1253f4a2713aSLionel Sambuc     for (VTSDSetTy::iterator I = VTSDSet.begin(), E = VTSDSet.end(); I != E;
1254f4a2713aSLionel Sambuc          ++I) {
1255f4a2713aSLionel Sambuc       assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
1256f4a2713aSLionel Sambuc       Writer.AddDeclRef(&*I, Record);
1257f4a2713aSLionel Sambuc     }
1258f4a2713aSLionel Sambuc 
1259f4a2713aSLionel Sambuc     typedef llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
1260f4a2713aSLionel Sambuc     VTPSDSetTy;
1261f4a2713aSLionel Sambuc     VTPSDSetTy &VTPSDSet = D->getPartialSpecializations();
1262f4a2713aSLionel Sambuc     Record.push_back(VTPSDSet.size());
1263f4a2713aSLionel Sambuc     for (VTPSDSetTy::iterator I = VTPSDSet.begin(), E = VTPSDSet.end(); I != E;
1264f4a2713aSLionel Sambuc          ++I) {
1265f4a2713aSLionel Sambuc       assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
1266f4a2713aSLionel Sambuc       Writer.AddDeclRef(&*I, Record);
1267f4a2713aSLionel Sambuc     }
1268f4a2713aSLionel Sambuc   }
1269f4a2713aSLionel Sambuc   Code = serialization::DECL_VAR_TEMPLATE;
1270f4a2713aSLionel Sambuc }
1271f4a2713aSLionel Sambuc 
VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * D)1272f4a2713aSLionel Sambuc void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
1273f4a2713aSLionel Sambuc     VarTemplateSpecializationDecl *D) {
1274f4a2713aSLionel Sambuc   VisitVarDecl(D);
1275f4a2713aSLionel Sambuc 
1276f4a2713aSLionel Sambuc   llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
1277f4a2713aSLionel Sambuc   InstFrom = D->getSpecializedTemplateOrPartial();
1278f4a2713aSLionel Sambuc   if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
1279f4a2713aSLionel Sambuc     Writer.AddDeclRef(InstFromD, Record);
1280f4a2713aSLionel Sambuc   } else {
1281f4a2713aSLionel Sambuc     Writer.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>(),
1282f4a2713aSLionel Sambuc                       Record);
1283f4a2713aSLionel Sambuc     Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record);
1284f4a2713aSLionel Sambuc   }
1285f4a2713aSLionel Sambuc 
1286f4a2713aSLionel Sambuc   // Explicit info.
1287f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);
1288f4a2713aSLionel Sambuc   if (D->getTypeAsWritten()) {
1289f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getExternLoc(), Record);
1290f4a2713aSLionel Sambuc     Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record);
1291f4a2713aSLionel Sambuc   }
1292f4a2713aSLionel Sambuc 
1293f4a2713aSLionel Sambuc   Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record);
1294f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getPointOfInstantiation(), Record);
1295f4a2713aSLionel Sambuc   Record.push_back(D->getSpecializationKind());
1296f4a2713aSLionel Sambuc   Record.push_back(D->isCanonicalDecl());
1297f4a2713aSLionel Sambuc 
1298f4a2713aSLionel Sambuc   if (D->isCanonicalDecl()) {
1299f4a2713aSLionel Sambuc     // When reading, we'll add it to the folding set of the following template.
1300f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record);
1301f4a2713aSLionel Sambuc   }
1302f4a2713aSLionel Sambuc 
1303f4a2713aSLionel Sambuc   Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
1304f4a2713aSLionel Sambuc }
1305f4a2713aSLionel Sambuc 
VisitVarTemplatePartialSpecializationDecl(VarTemplatePartialSpecializationDecl * D)1306f4a2713aSLionel Sambuc void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
1307f4a2713aSLionel Sambuc     VarTemplatePartialSpecializationDecl *D) {
1308f4a2713aSLionel Sambuc   VisitVarTemplateSpecializationDecl(D);
1309f4a2713aSLionel Sambuc 
1310f4a2713aSLionel Sambuc   Writer.AddTemplateParameterList(D->getTemplateParameters(), Record);
1311f4a2713aSLionel Sambuc   Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record);
1312f4a2713aSLionel Sambuc 
1313f4a2713aSLionel Sambuc   // These are read/set from/to the first declaration.
1314*0a6a1f1dSLionel Sambuc   if (D->getPreviousDecl() == nullptr) {
1315f4a2713aSLionel Sambuc     Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
1316f4a2713aSLionel Sambuc     Record.push_back(D->isMemberSpecialization());
1317f4a2713aSLionel Sambuc   }
1318f4a2713aSLionel Sambuc 
1319f4a2713aSLionel Sambuc   Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
1320f4a2713aSLionel Sambuc }
1321f4a2713aSLionel Sambuc 
VisitClassScopeFunctionSpecializationDecl(ClassScopeFunctionSpecializationDecl * D)1322f4a2713aSLionel Sambuc void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
1323f4a2713aSLionel Sambuc                                     ClassScopeFunctionSpecializationDecl *D) {
1324f4a2713aSLionel Sambuc   VisitDecl(D);
1325f4a2713aSLionel Sambuc   Writer.AddDeclRef(D->getSpecialization(), Record);
1326f4a2713aSLionel Sambuc   Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
1327f4a2713aSLionel Sambuc }
1328f4a2713aSLionel Sambuc 
1329f4a2713aSLionel Sambuc 
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)1330f4a2713aSLionel Sambuc void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1331f4a2713aSLionel Sambuc   VisitRedeclarableTemplateDecl(D);
1332f4a2713aSLionel Sambuc 
1333f4a2713aSLionel Sambuc   if (D->isFirstDecl()) {
1334f4a2713aSLionel Sambuc     // This FunctionTemplateDecl owns the CommonPtr; write it.
1335f4a2713aSLionel Sambuc 
1336f4a2713aSLionel Sambuc     // Write the function specialization declarations.
1337f4a2713aSLionel Sambuc     Record.push_back(D->getSpecializations().size());
1338f4a2713aSLionel Sambuc     for (llvm::FoldingSetVector<FunctionTemplateSpecializationInfo>::iterator
1339f4a2713aSLionel Sambuc            I = D->getSpecializations().begin(),
1340f4a2713aSLionel Sambuc            E = D->getSpecializations().end()   ; I != E; ++I) {
1341f4a2713aSLionel Sambuc       assert(I->Function->isCanonicalDecl() &&
1342f4a2713aSLionel Sambuc              "Expected only canonical decls in set");
1343f4a2713aSLionel Sambuc       Writer.AddDeclRef(I->Function, Record);
1344f4a2713aSLionel Sambuc     }
1345f4a2713aSLionel Sambuc   }
1346f4a2713aSLionel Sambuc   Code = serialization::DECL_FUNCTION_TEMPLATE;
1347f4a2713aSLionel Sambuc }
1348f4a2713aSLionel Sambuc 
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)1349f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
1350f4a2713aSLionel Sambuc   VisitTypeDecl(D);
1351f4a2713aSLionel Sambuc 
1352f4a2713aSLionel Sambuc   Record.push_back(D->wasDeclaredWithTypename());
1353f4a2713aSLionel Sambuc   Record.push_back(D->defaultArgumentWasInherited());
1354f4a2713aSLionel Sambuc   Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
1355f4a2713aSLionel Sambuc 
1356f4a2713aSLionel Sambuc   Code = serialization::DECL_TEMPLATE_TYPE_PARM;
1357f4a2713aSLionel Sambuc }
1358f4a2713aSLionel Sambuc 
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)1359f4a2713aSLionel Sambuc void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
1360f4a2713aSLionel Sambuc   // For an expanded parameter pack, record the number of expansion types here
1361f4a2713aSLionel Sambuc   // so that it's easier for deserialization to allocate the right amount of
1362f4a2713aSLionel Sambuc   // memory.
1363f4a2713aSLionel Sambuc   if (D->isExpandedParameterPack())
1364f4a2713aSLionel Sambuc     Record.push_back(D->getNumExpansionTypes());
1365f4a2713aSLionel Sambuc 
1366f4a2713aSLionel Sambuc   VisitDeclaratorDecl(D);
1367f4a2713aSLionel Sambuc   // TemplateParmPosition.
1368f4a2713aSLionel Sambuc   Record.push_back(D->getDepth());
1369f4a2713aSLionel Sambuc   Record.push_back(D->getPosition());
1370f4a2713aSLionel Sambuc 
1371f4a2713aSLionel Sambuc   if (D->isExpandedParameterPack()) {
1372f4a2713aSLionel Sambuc     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
1373f4a2713aSLionel Sambuc       Writer.AddTypeRef(D->getExpansionType(I), Record);
1374f4a2713aSLionel Sambuc       Writer.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I), Record);
1375f4a2713aSLionel Sambuc     }
1376f4a2713aSLionel Sambuc 
1377f4a2713aSLionel Sambuc     Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
1378f4a2713aSLionel Sambuc   } else {
1379f4a2713aSLionel Sambuc     // Rest of NonTypeTemplateParmDecl.
1380f4a2713aSLionel Sambuc     Record.push_back(D->isParameterPack());
1381*0a6a1f1dSLionel Sambuc     Record.push_back(D->getDefaultArgument() != nullptr);
1382f4a2713aSLionel Sambuc     if (D->getDefaultArgument()) {
1383f4a2713aSLionel Sambuc       Writer.AddStmt(D->getDefaultArgument());
1384f4a2713aSLionel Sambuc       Record.push_back(D->defaultArgumentWasInherited());
1385f4a2713aSLionel Sambuc     }
1386f4a2713aSLionel Sambuc     Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
1387f4a2713aSLionel Sambuc   }
1388f4a2713aSLionel Sambuc }
1389f4a2713aSLionel Sambuc 
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)1390f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
1391f4a2713aSLionel Sambuc   // For an expanded parameter pack, record the number of expansion types here
1392f4a2713aSLionel Sambuc   // so that it's easier for deserialization to allocate the right amount of
1393f4a2713aSLionel Sambuc   // memory.
1394f4a2713aSLionel Sambuc   if (D->isExpandedParameterPack())
1395f4a2713aSLionel Sambuc     Record.push_back(D->getNumExpansionTemplateParameters());
1396f4a2713aSLionel Sambuc 
1397f4a2713aSLionel Sambuc   VisitTemplateDecl(D);
1398f4a2713aSLionel Sambuc   // TemplateParmPosition.
1399f4a2713aSLionel Sambuc   Record.push_back(D->getDepth());
1400f4a2713aSLionel Sambuc   Record.push_back(D->getPosition());
1401f4a2713aSLionel Sambuc 
1402f4a2713aSLionel Sambuc   if (D->isExpandedParameterPack()) {
1403f4a2713aSLionel Sambuc     for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
1404f4a2713aSLionel Sambuc          I != N; ++I)
1405f4a2713aSLionel Sambuc       Writer.AddTemplateParameterList(D->getExpansionTemplateParameters(I),
1406f4a2713aSLionel Sambuc                                       Record);
1407f4a2713aSLionel Sambuc     Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
1408f4a2713aSLionel Sambuc   } else {
1409f4a2713aSLionel Sambuc     // Rest of TemplateTemplateParmDecl.
1410f4a2713aSLionel Sambuc     Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
1411f4a2713aSLionel Sambuc     Record.push_back(D->defaultArgumentWasInherited());
1412f4a2713aSLionel Sambuc     Record.push_back(D->isParameterPack());
1413f4a2713aSLionel Sambuc     Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
1414f4a2713aSLionel Sambuc   }
1415f4a2713aSLionel Sambuc }
1416f4a2713aSLionel Sambuc 
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)1417f4a2713aSLionel Sambuc void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
1418f4a2713aSLionel Sambuc   VisitRedeclarableTemplateDecl(D);
1419f4a2713aSLionel Sambuc   Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
1420f4a2713aSLionel Sambuc }
1421f4a2713aSLionel Sambuc 
VisitStaticAssertDecl(StaticAssertDecl * D)1422f4a2713aSLionel Sambuc void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1423f4a2713aSLionel Sambuc   VisitDecl(D);
1424f4a2713aSLionel Sambuc   Writer.AddStmt(D->getAssertExpr());
1425f4a2713aSLionel Sambuc   Record.push_back(D->isFailed());
1426f4a2713aSLionel Sambuc   Writer.AddStmt(D->getMessage());
1427f4a2713aSLionel Sambuc   Writer.AddSourceLocation(D->getRParenLoc(), Record);
1428f4a2713aSLionel Sambuc   Code = serialization::DECL_STATIC_ASSERT;
1429f4a2713aSLionel Sambuc }
1430f4a2713aSLionel Sambuc 
1431f4a2713aSLionel Sambuc /// \brief Emit the DeclContext part of a declaration context decl.
1432f4a2713aSLionel Sambuc ///
1433f4a2713aSLionel Sambuc /// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
1434f4a2713aSLionel Sambuc /// block for this declaration context is stored. May be 0 to indicate
1435f4a2713aSLionel Sambuc /// that there are no declarations stored within this context.
1436f4a2713aSLionel Sambuc ///
1437f4a2713aSLionel Sambuc /// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
1438f4a2713aSLionel Sambuc /// block for this declaration context is stored. May be 0 to indicate
1439f4a2713aSLionel Sambuc /// that there are no declarations visible from this context. Note
1440f4a2713aSLionel Sambuc /// that this value will not be emitted for non-primary declaration
1441f4a2713aSLionel Sambuc /// contexts.
VisitDeclContext(DeclContext * DC,uint64_t LexicalOffset,uint64_t VisibleOffset)1442f4a2713aSLionel Sambuc void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
1443f4a2713aSLionel Sambuc                                      uint64_t VisibleOffset) {
1444f4a2713aSLionel Sambuc   Record.push_back(LexicalOffset);
1445f4a2713aSLionel Sambuc   Record.push_back(VisibleOffset);
1446f4a2713aSLionel Sambuc }
1447f4a2713aSLionel Sambuc 
1448f4a2713aSLionel Sambuc template <typename T>
VisitRedeclarable(Redeclarable<T> * D)1449f4a2713aSLionel Sambuc void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
1450f4a2713aSLionel Sambuc   T *First = D->getFirstDecl();
1451f4a2713aSLionel Sambuc   if (First->getMostRecentDecl() != First) {
1452f4a2713aSLionel Sambuc     assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) &&
1453f4a2713aSLionel Sambuc            "Not considered redeclarable?");
1454f4a2713aSLionel Sambuc 
1455f4a2713aSLionel Sambuc     // There is more than one declaration of this entity, so we will need to
1456f4a2713aSLionel Sambuc     // write a redeclaration chain.
1457f4a2713aSLionel Sambuc     Writer.AddDeclRef(First, Record);
1458f4a2713aSLionel Sambuc     Writer.Redeclarations.insert(First);
1459f4a2713aSLionel Sambuc 
1460f4a2713aSLionel Sambuc     // Make sure that we serialize both the previous and the most-recent
1461f4a2713aSLionel Sambuc     // declarations, which (transitively) ensures that all declarations in the
1462f4a2713aSLionel Sambuc     // chain get serialized.
1463f4a2713aSLionel Sambuc     (void)Writer.GetDeclRef(D->getPreviousDecl());
1464f4a2713aSLionel Sambuc     (void)Writer.GetDeclRef(First->getMostRecentDecl());
1465f4a2713aSLionel Sambuc   } else {
1466f4a2713aSLionel Sambuc     // We use the sentinel value 0 to indicate an only declaration.
1467f4a2713aSLionel Sambuc     Record.push_back(0);
1468f4a2713aSLionel Sambuc   }
1469f4a2713aSLionel Sambuc 
1470f4a2713aSLionel Sambuc }
1471f4a2713aSLionel Sambuc 
VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl * D)1472f4a2713aSLionel Sambuc void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1473f4a2713aSLionel Sambuc   Record.push_back(D->varlist_size());
1474f4a2713aSLionel Sambuc   VisitDecl(D);
1475*0a6a1f1dSLionel Sambuc   for (auto *I : D->varlists())
1476*0a6a1f1dSLionel Sambuc     Writer.AddStmt(I);
1477f4a2713aSLionel Sambuc   Code = serialization::DECL_OMP_THREADPRIVATE;
1478f4a2713aSLionel Sambuc }
1479f4a2713aSLionel Sambuc 
1480f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1481f4a2713aSLionel Sambuc // ASTWriter Implementation
1482f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1483f4a2713aSLionel Sambuc 
WriteDeclAbbrevs()1484*0a6a1f1dSLionel Sambuc void ASTWriter::WriteDeclAbbrevs() {
1485f4a2713aSLionel Sambuc   using namespace llvm;
1486f4a2713aSLionel Sambuc 
1487f4a2713aSLionel Sambuc   BitCodeAbbrev *Abv;
1488f4a2713aSLionel Sambuc 
1489f4a2713aSLionel Sambuc   // Abbreviation for DECL_FIELD
1490f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1491f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
1492f4a2713aSLionel Sambuc   // Decl
1493f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1494f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1495f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1496f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1497f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1498f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1499f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1500f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1501f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // AccessSpecifier
1502f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1503f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1504f4a2713aSLionel Sambuc   // NamedDecl
1505f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1506f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1507f4a2713aSLionel Sambuc   // ValueDecl
1508f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1509f4a2713aSLionel Sambuc   // DeclaratorDecl
1510f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
1511f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
1512f4a2713aSLionel Sambuc   // FieldDecl
1513f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
1514f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       //getBitWidth
1515f4a2713aSLionel Sambuc   // Type Source Info
1516f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1517f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1518f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
1519f4a2713aSLionel Sambuc   DeclFieldAbbrev = Stream.EmitAbbrev(Abv);
1520f4a2713aSLionel Sambuc 
1521f4a2713aSLionel Sambuc   // Abbreviation for DECL_OBJC_IVAR
1522f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1523f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
1524f4a2713aSLionel Sambuc   // Decl
1525f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1526f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1527f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1528f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1529f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1530f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1531f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1532f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1533f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));  // AccessSpecifier
1534f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1535f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1536f4a2713aSLionel Sambuc   // NamedDecl
1537f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1538f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1539f4a2713aSLionel Sambuc   // ValueDecl
1540f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1541f4a2713aSLionel Sambuc   // DeclaratorDecl
1542f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
1543f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
1544f4a2713aSLionel Sambuc   // FieldDecl
1545f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
1546f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       //getBitWidth
1547f4a2713aSLionel Sambuc   // ObjC Ivar
1548f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
1549f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
1550f4a2713aSLionel Sambuc   // Type Source Info
1551f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1552f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1553f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
1554f4a2713aSLionel Sambuc   DeclObjCIvarAbbrev = Stream.EmitAbbrev(Abv);
1555f4a2713aSLionel Sambuc 
1556f4a2713aSLionel Sambuc   // Abbreviation for DECL_ENUM
1557f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1558f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
1559f4a2713aSLionel Sambuc   // Redeclarable
1560f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
1561f4a2713aSLionel Sambuc   // Decl
1562f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1563f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1564f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1565f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1566f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1567f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1568f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1569f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1570f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
1571f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1572f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1573f4a2713aSLionel Sambuc   // NamedDecl
1574f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1575f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1576f4a2713aSLionel Sambuc   // TypeDecl
1577f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
1578f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
1579f4a2713aSLionel Sambuc   // TagDecl
1580f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
1581f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getTagKind
1582f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
1583f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
1584f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
1585f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
1586f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
1587*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind
1588f4a2713aSLionel Sambuc   // EnumDecl
1589f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // AddTypeRef
1590f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IntegerType
1591f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getPromotionType
1592f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getNumPositiveBits
1593f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getNumNegativeBits
1594f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScoped
1595f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScopedUsingClassTag
1596f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isFixed
1597f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum
1598f4a2713aSLionel Sambuc   // DC
1599f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
1600f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
1601f4a2713aSLionel Sambuc   DeclEnumAbbrev = Stream.EmitAbbrev(Abv);
1602f4a2713aSLionel Sambuc 
1603f4a2713aSLionel Sambuc   // Abbreviation for DECL_RECORD
1604f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1605f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
1606f4a2713aSLionel Sambuc   // Redeclarable
1607f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
1608f4a2713aSLionel Sambuc   // Decl
1609f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1610f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1611f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1612f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1613f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1614f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1615f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1616f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1617f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
1618f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1619f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1620f4a2713aSLionel Sambuc   // NamedDecl
1621f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1622f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1623f4a2713aSLionel Sambuc   // TypeDecl
1624f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
1625f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
1626f4a2713aSLionel Sambuc   // TagDecl
1627f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // IdentifierNamespace
1628f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getTagKind
1629f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
1630f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
1631f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
1632f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
1633f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SourceLocation
1634*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // ExtInfoKind
1635f4a2713aSLionel Sambuc   // RecordDecl
1636f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
1637f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
1638f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
1639f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember
1640f4a2713aSLionel Sambuc   // DC
1641f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
1642f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
1643f4a2713aSLionel Sambuc   DeclRecordAbbrev = Stream.EmitAbbrev(Abv);
1644f4a2713aSLionel Sambuc 
1645f4a2713aSLionel Sambuc   // Abbreviation for DECL_PARM_VAR
1646f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1647f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
1648f4a2713aSLionel Sambuc   // Redeclarable
1649f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
1650f4a2713aSLionel Sambuc   // Decl
1651f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1652f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1653f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1654f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1655f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1656f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1657f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1658f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1659f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
1660f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1661f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1662f4a2713aSLionel Sambuc   // NamedDecl
1663f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1664f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1665f4a2713aSLionel Sambuc   // ValueDecl
1666f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1667f4a2713aSLionel Sambuc   // DeclaratorDecl
1668f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
1669f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
1670f4a2713aSLionel Sambuc   // VarDecl
1671f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // StorageClass
1672f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // getTSCSpec
1673f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // hasCXXDirectInitializer
1674f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isExceptionVariable
1675f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isNRVOVariable
1676f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isCXXForRangeDecl
1677f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isARCPseudoStrong
1678f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isConstexpr
1679f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInitCapture
1680f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isPrevDeclInSameScope
1681f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // Linkage
1682f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasInit
1683f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // HasMemberSpecializationInfo
1684f4a2713aSLionel Sambuc   // ParmVarDecl
1685f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
1686f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ScopeDepth
1687f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
1688f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ObjCDeclQualifier
1689f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // KNRPromoted
1690f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasInheritedDefaultArg
1691f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // HasUninstantiatedDefaultArg
1692f4a2713aSLionel Sambuc   // Type Source Info
1693f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1694f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1695f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
1696f4a2713aSLionel Sambuc   DeclParmVarAbbrev = Stream.EmitAbbrev(Abv);
1697f4a2713aSLionel Sambuc 
1698f4a2713aSLionel Sambuc   // Abbreviation for DECL_TYPEDEF
1699f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1700f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
1701f4a2713aSLionel Sambuc   // Redeclarable
1702f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
1703f4a2713aSLionel Sambuc   // Decl
1704f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1705f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1706f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1707f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1708f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1709*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
1710*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
1711f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1712*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
1713f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1714f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1715f4a2713aSLionel Sambuc   // NamedDecl
1716f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1717f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1718f4a2713aSLionel Sambuc   // TypeDecl
1719f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
1720f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
1721f4a2713aSLionel Sambuc   // TypedefDecl
1722f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1723f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
1724f4a2713aSLionel Sambuc   DeclTypedefAbbrev = Stream.EmitAbbrev(Abv);
1725f4a2713aSLionel Sambuc 
1726f4a2713aSLionel Sambuc   // Abbreviation for DECL_VAR
1727f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1728f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
1729f4a2713aSLionel Sambuc   // Redeclarable
1730f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
1731f4a2713aSLionel Sambuc   // Decl
1732f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1733f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
1734f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isInvalidDecl
1735f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // HasAttrs
1736f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit
1737f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isUsed
1738f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // isReferenced
1739f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                   // TopLevelDeclInObjCContainer
1740f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier
1741f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // ModulePrivate
1742f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1743f4a2713aSLionel Sambuc   // NamedDecl
1744f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
1745f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1746f4a2713aSLionel Sambuc   // ValueDecl
1747f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1748f4a2713aSLionel Sambuc   // DeclaratorDecl
1749f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
1750f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                       // hasExtInfo
1751f4a2713aSLionel Sambuc   // VarDecl
1752f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass
1753f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getTSCSpec
1754f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CXXDirectInitializer
1755f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
1756f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
1757f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
1758f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
1759f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // isConstexpr
1760f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // isInitCapture
1761f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // isPrevDeclInSameScope
1762f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
1763f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasInit
1764f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasMemberSpecInfo
1765f4a2713aSLionel Sambuc   // Type Source Info
1766f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1767f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1768f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
1769f4a2713aSLionel Sambuc   DeclVarAbbrev = Stream.EmitAbbrev(Abv);
1770f4a2713aSLionel Sambuc 
1771*0a6a1f1dSLionel Sambuc   // Abbreviation for DECL_CXX_METHOD
1772*0a6a1f1dSLionel Sambuc   Abv = new BitCodeAbbrev();
1773*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
1774*0a6a1f1dSLionel Sambuc   // RedeclarableDecl
1775*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // CanonicalDecl
1776*0a6a1f1dSLionel Sambuc   // Decl
1777*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // DeclContext
1778*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalDeclContext
1779*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // Invalid
1780*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // HasAttrs
1781*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
1782*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
1783*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
1784*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // InObjCContainer
1785*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
1786*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModulePrivate
1787*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // SubmoduleID
1788*0a6a1f1dSLionel Sambuc   // NamedDecl
1789*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
1790*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Identifier
1791*0a6a1f1dSLionel Sambuc   // ValueDecl
1792*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // Type
1793*0a6a1f1dSLionel Sambuc   // DeclaratorDecl
1794*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InnerLocStart
1795*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // HasExtInfo
1796*0a6a1f1dSLionel Sambuc   // FunctionDecl
1797*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
1798*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
1799*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
1800*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
1801*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
1802*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
1803*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0));                         // HasInheritedProto
1804*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(1));                         // HasWrittenProto
1805*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Deleted
1806*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
1807*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
1808*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
1809*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
1810*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constexpr
1811*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
1812*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
1813*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
1814*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LocEnd
1815*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind
1816*0a6a1f1dSLionel Sambuc   // This Array slurps the rest of the record. Fortunately we want to encode
1817*0a6a1f1dSLionel Sambuc   // (nearly) all the remaining (variable number of) fields in the same way.
1818*0a6a1f1dSLionel Sambuc   //
1819*0a6a1f1dSLionel Sambuc   // This is the function template information if any, then
1820*0a6a1f1dSLionel Sambuc   //         NumParams and Params[] from FunctionDecl, and
1821*0a6a1f1dSLionel Sambuc   //         NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
1822*0a6a1f1dSLionel Sambuc   //
1823*0a6a1f1dSLionel Sambuc   //  Add an AbbrevOp for 'size then elements' and use it here.
1824*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1825*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1826*0a6a1f1dSLionel Sambuc   DeclCXXMethodAbbrev = Stream.EmitAbbrev(Abv);
1827*0a6a1f1dSLionel Sambuc 
1828f4a2713aSLionel Sambuc   // Abbreviation for EXPR_DECL_REF
1829f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1830f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
1831f4a2713aSLionel Sambuc   //Stmt
1832f4a2713aSLionel Sambuc   //Expr
1833f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1834f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
1835f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
1836f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
1837f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
1838f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
1839f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
1840f4a2713aSLionel Sambuc   //DeclRefExpr
1841f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
1842f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
1843f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
1844f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
1845*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
1846*0a6a1f1dSLionel Sambuc                            1)); // RefersToEnclosingVariableOrCapture
1847f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
1848f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
1849f4a2713aSLionel Sambuc   DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);
1850f4a2713aSLionel Sambuc 
1851f4a2713aSLionel Sambuc   // Abbreviation for EXPR_INTEGER_LITERAL
1852f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1853f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
1854f4a2713aSLionel Sambuc   //Stmt
1855f4a2713aSLionel Sambuc   //Expr
1856f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1857f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
1858f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
1859f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
1860f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
1861f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
1862f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
1863f4a2713aSLionel Sambuc   //Integer Literal
1864f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
1865f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(32));                      // Bit Width
1866f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
1867f4a2713aSLionel Sambuc   IntegerLiteralAbbrev = Stream.EmitAbbrev(Abv);
1868f4a2713aSLionel Sambuc 
1869f4a2713aSLionel Sambuc   // Abbreviation for EXPR_CHARACTER_LITERAL
1870f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1871f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
1872f4a2713aSLionel Sambuc   //Stmt
1873f4a2713aSLionel Sambuc   //Expr
1874f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1875f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
1876f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
1877f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
1878f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
1879f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
1880f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
1881f4a2713aSLionel Sambuc   //Character Literal
1882f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
1883f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
1884f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getKind
1885f4a2713aSLionel Sambuc   CharacterLiteralAbbrev = Stream.EmitAbbrev(Abv);
1886f4a2713aSLionel Sambuc 
1887*0a6a1f1dSLionel Sambuc   // Abbreviation for EXPR_IMPLICIT_CAST
1888*0a6a1f1dSLionel Sambuc   Abv = new BitCodeAbbrev();
1889*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
1890*0a6a1f1dSLionel Sambuc   // Stmt
1891*0a6a1f1dSLionel Sambuc   // Expr
1892*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1893*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
1894*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
1895*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //InstantiationDependent
1896*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //UnexpandedParamPack
1897*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
1898*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
1899*0a6a1f1dSLionel Sambuc   // CastExpr
1900*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(0)); // PathSize
1901*0a6a1f1dSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
1902*0a6a1f1dSLionel Sambuc   // ImplicitCastExpr
1903*0a6a1f1dSLionel Sambuc   ExprImplicitCastAbbrev = Stream.EmitAbbrev(Abv);
1904*0a6a1f1dSLionel Sambuc 
1905f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1906f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
1907f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1908f4a2713aSLionel Sambuc   DeclContextLexicalAbbrev = Stream.EmitAbbrev(Abv);
1909f4a2713aSLionel Sambuc 
1910f4a2713aSLionel Sambuc   Abv = new BitCodeAbbrev();
1911f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
1912f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1913f4a2713aSLionel Sambuc   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1914f4a2713aSLionel Sambuc   DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(Abv);
1915f4a2713aSLionel Sambuc }
1916f4a2713aSLionel Sambuc 
1917f4a2713aSLionel Sambuc /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
1918f4a2713aSLionel Sambuc /// consumers of the AST.
1919f4a2713aSLionel Sambuc ///
1920f4a2713aSLionel Sambuc /// Such decls will always be deserialized from the AST file, so we would like
1921f4a2713aSLionel Sambuc /// this to be as restrictive as possible. Currently the predicate is driven by
1922f4a2713aSLionel Sambuc /// code generation requirements, if other clients have a different notion of
1923f4a2713aSLionel Sambuc /// what is "required" then we may have to consider an alternate scheme where
1924f4a2713aSLionel Sambuc /// clients can iterate over the top-level decls and get information on them,
1925f4a2713aSLionel Sambuc /// without necessary deserializing them. We could explicitly require such
1926f4a2713aSLionel Sambuc /// clients to use a separate API call to "realize" the decl. This should be
1927f4a2713aSLionel Sambuc /// relatively painless since they would presumably only do it for top-level
1928f4a2713aSLionel Sambuc /// decls.
isRequiredDecl(const Decl * D,ASTContext & Context)1929f4a2713aSLionel Sambuc static bool isRequiredDecl(const Decl *D, ASTContext &Context) {
1930f4a2713aSLionel Sambuc   // An ObjCMethodDecl is never considered as "required" because its
1931f4a2713aSLionel Sambuc   // implementation container always is.
1932f4a2713aSLionel Sambuc 
1933*0a6a1f1dSLionel Sambuc   // File scoped assembly or obj-c implementation must be seen. ImportDecl is
1934*0a6a1f1dSLionel Sambuc   // used by codegen to determine the set of imported modules to search for
1935*0a6a1f1dSLionel Sambuc   // inputs for automatic linking.
1936*0a6a1f1dSLionel Sambuc   if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D) || isa<ImportDecl>(D))
1937f4a2713aSLionel Sambuc     return true;
1938f4a2713aSLionel Sambuc 
1939f4a2713aSLionel Sambuc   return Context.DeclMustBeEmitted(D);
1940f4a2713aSLionel Sambuc }
1941f4a2713aSLionel Sambuc 
WriteDecl(ASTContext & Context,Decl * D)1942f4a2713aSLionel Sambuc void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
1943f4a2713aSLionel Sambuc   // Switch case IDs are per Decl.
1944f4a2713aSLionel Sambuc   ClearSwitchCaseIDs();
1945f4a2713aSLionel Sambuc 
1946f4a2713aSLionel Sambuc   RecordData Record;
1947f4a2713aSLionel Sambuc   ASTDeclWriter W(*this, Context, Record);
1948f4a2713aSLionel Sambuc 
1949f4a2713aSLionel Sambuc   // Determine the ID for this declaration.
1950f4a2713aSLionel Sambuc   serialization::DeclID ID;
1951f4a2713aSLionel Sambuc   if (D->isFromASTFile())
1952f4a2713aSLionel Sambuc     ID = getDeclID(D);
1953f4a2713aSLionel Sambuc   else {
1954f4a2713aSLionel Sambuc     serialization::DeclID &IDR = DeclIDs[D];
1955f4a2713aSLionel Sambuc     if (IDR == 0)
1956f4a2713aSLionel Sambuc       IDR = NextDeclID++;
1957f4a2713aSLionel Sambuc 
1958f4a2713aSLionel Sambuc     ID= IDR;
1959f4a2713aSLionel Sambuc   }
1960f4a2713aSLionel Sambuc 
1961f4a2713aSLionel Sambuc   bool isReplacingADecl = ID < FirstDeclID;
1962f4a2713aSLionel Sambuc 
1963f4a2713aSLionel Sambuc   // If this declaration is also a DeclContext, write blocks for the
1964f4a2713aSLionel Sambuc   // declarations that lexically stored inside its context and those
1965f4a2713aSLionel Sambuc   // declarations that are visible from its context. These blocks
1966f4a2713aSLionel Sambuc   // are written before the declaration itself so that we can put
1967f4a2713aSLionel Sambuc   // their offsets into the record for the declaration.
1968f4a2713aSLionel Sambuc   uint64_t LexicalOffset = 0;
1969f4a2713aSLionel Sambuc   uint64_t VisibleOffset = 0;
1970f4a2713aSLionel Sambuc   DeclContext *DC = dyn_cast<DeclContext>(D);
1971f4a2713aSLionel Sambuc   if (DC) {
1972f4a2713aSLionel Sambuc     if (isReplacingADecl) {
1973f4a2713aSLionel Sambuc       // It is replacing a decl from a chained PCH; make sure that the
1974f4a2713aSLionel Sambuc       // DeclContext is fully loaded.
1975f4a2713aSLionel Sambuc       if (DC->hasExternalLexicalStorage())
1976f4a2713aSLionel Sambuc         DC->LoadLexicalDeclsFromExternalStorage();
1977f4a2713aSLionel Sambuc       if (DC->hasExternalVisibleStorage())
1978f4a2713aSLionel Sambuc         Chain->completeVisibleDeclsMap(DC);
1979f4a2713aSLionel Sambuc     }
1980f4a2713aSLionel Sambuc     LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
1981f4a2713aSLionel Sambuc     VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
1982f4a2713aSLionel Sambuc   }
1983f4a2713aSLionel Sambuc 
1984f4a2713aSLionel Sambuc   if (isReplacingADecl) {
1985f4a2713aSLionel Sambuc     // We're replacing a decl in a previous file.
1986f4a2713aSLionel Sambuc     ReplacedDecls.push_back(ReplacedDeclInfo(ID, Stream.GetCurrentBitNo(),
1987f4a2713aSLionel Sambuc                                              D->getLocation()));
1988f4a2713aSLionel Sambuc   } else {
1989f4a2713aSLionel Sambuc     unsigned Index = ID - FirstDeclID;
1990f4a2713aSLionel Sambuc 
1991f4a2713aSLionel Sambuc     // Record the offset for this declaration
1992f4a2713aSLionel Sambuc     SourceLocation Loc = D->getLocation();
1993f4a2713aSLionel Sambuc     if (DeclOffsets.size() == Index)
1994f4a2713aSLionel Sambuc       DeclOffsets.push_back(DeclOffset(Loc, Stream.GetCurrentBitNo()));
1995f4a2713aSLionel Sambuc     else if (DeclOffsets.size() < Index) {
1996f4a2713aSLionel Sambuc       DeclOffsets.resize(Index+1);
1997f4a2713aSLionel Sambuc       DeclOffsets[Index].setLocation(Loc);
1998f4a2713aSLionel Sambuc       DeclOffsets[Index].BitOffset = Stream.GetCurrentBitNo();
1999f4a2713aSLionel Sambuc     }
2000f4a2713aSLionel Sambuc 
2001f4a2713aSLionel Sambuc     SourceManager &SM = Context.getSourceManager();
2002f4a2713aSLionel Sambuc     if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
2003f4a2713aSLionel Sambuc       associateDeclWithFile(D, ID);
2004f4a2713aSLionel Sambuc   }
2005f4a2713aSLionel Sambuc 
2006f4a2713aSLionel Sambuc   // Build and emit a record for this declaration
2007f4a2713aSLionel Sambuc   Record.clear();
2008f4a2713aSLionel Sambuc   W.Code = (serialization::DeclCode)0;
2009f4a2713aSLionel Sambuc   W.AbbrevToUse = 0;
2010f4a2713aSLionel Sambuc   W.Visit(D);
2011f4a2713aSLionel Sambuc   if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
2012f4a2713aSLionel Sambuc 
2013f4a2713aSLionel Sambuc   if (!W.Code)
2014f4a2713aSLionel Sambuc     llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
2015f4a2713aSLionel Sambuc                             D->getDeclKindName() + "'");
2016f4a2713aSLionel Sambuc   Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
2017f4a2713aSLionel Sambuc 
2018f4a2713aSLionel Sambuc   // Flush any expressions that were written as part of this declaration.
2019f4a2713aSLionel Sambuc   FlushStmts();
2020f4a2713aSLionel Sambuc 
2021f4a2713aSLionel Sambuc   // Flush C++ base specifiers, if there are any.
2022f4a2713aSLionel Sambuc   FlushCXXBaseSpecifiers();
2023f4a2713aSLionel Sambuc 
2024*0a6a1f1dSLionel Sambuc   // Note declarations that should be deserialized eagerly so that we can add
2025*0a6a1f1dSLionel Sambuc   // them to a record in the AST file later.
2026f4a2713aSLionel Sambuc   if (isRequiredDecl(D, Context))
2027*0a6a1f1dSLionel Sambuc     EagerlyDeserializedDecls.push_back(ID);
2028*0a6a1f1dSLionel Sambuc }
2029*0a6a1f1dSLionel Sambuc 
AddFunctionDefinition(const FunctionDecl * FD,RecordData & Record)2030*0a6a1f1dSLionel Sambuc void ASTWriter::AddFunctionDefinition(const FunctionDecl *FD,
2031*0a6a1f1dSLionel Sambuc                                       RecordData &Record) {
2032*0a6a1f1dSLionel Sambuc   ClearSwitchCaseIDs();
2033*0a6a1f1dSLionel Sambuc 
2034*0a6a1f1dSLionel Sambuc   ASTDeclWriter W(*this, FD->getASTContext(), Record);
2035*0a6a1f1dSLionel Sambuc   W.AddFunctionDefinition(FD);
2036f4a2713aSLionel Sambuc }
2037