1e5dd7070Spatrick //===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements serialization for Declarations.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "ASTCommon.h"
14e5dd7070Spatrick #include "clang/AST/Attr.h"
15e5dd7070Spatrick #include "clang/AST/DeclCXX.h"
16e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
17e5dd7070Spatrick #include "clang/AST/DeclVisitor.h"
18e5dd7070Spatrick #include "clang/AST/Expr.h"
19e5dd7070Spatrick #include "clang/AST/OpenMPClause.h"
20e5dd7070Spatrick #include "clang/AST/PrettyDeclStackTrace.h"
21e5dd7070Spatrick #include "clang/Basic/SourceManager.h"
22e5dd7070Spatrick #include "clang/Serialization/ASTReader.h"
23e5dd7070Spatrick #include "clang/Serialization/ASTRecordWriter.h"
24e5dd7070Spatrick #include "llvm/Bitstream/BitstreamWriter.h"
25e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
26*12c85518Srobert #include <optional>
27e5dd7070Spatrick using namespace clang;
28e5dd7070Spatrick using namespace serialization;
29e5dd7070Spatrick
30e5dd7070Spatrick //===----------------------------------------------------------------------===//
31e5dd7070Spatrick // Declaration serialization
32e5dd7070Spatrick //===----------------------------------------------------------------------===//
33e5dd7070Spatrick
34e5dd7070Spatrick namespace clang {
35e5dd7070Spatrick class ASTDeclWriter : public DeclVisitor<ASTDeclWriter, void> {
36e5dd7070Spatrick ASTWriter &Writer;
37e5dd7070Spatrick ASTContext &Context;
38e5dd7070Spatrick ASTRecordWriter Record;
39e5dd7070Spatrick
40e5dd7070Spatrick serialization::DeclCode Code;
41e5dd7070Spatrick unsigned AbbrevToUse;
42e5dd7070Spatrick
43e5dd7070Spatrick public:
ASTDeclWriter(ASTWriter & Writer,ASTContext & Context,ASTWriter::RecordDataImpl & Record)44e5dd7070Spatrick ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
45e5dd7070Spatrick ASTWriter::RecordDataImpl &Record)
46e5dd7070Spatrick : Writer(Writer), Context(Context), Record(Writer, Record),
47e5dd7070Spatrick Code((serialization::DeclCode)0), AbbrevToUse(0) {}
48e5dd7070Spatrick
Emit(Decl * D)49e5dd7070Spatrick uint64_t Emit(Decl *D) {
50e5dd7070Spatrick if (!Code)
51e5dd7070Spatrick llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
52e5dd7070Spatrick D->getDeclKindName() + "'");
53e5dd7070Spatrick return Record.Emit(Code, AbbrevToUse);
54e5dd7070Spatrick }
55e5dd7070Spatrick
56e5dd7070Spatrick void Visit(Decl *D);
57e5dd7070Spatrick
58e5dd7070Spatrick void VisitDecl(Decl *D);
59e5dd7070Spatrick void VisitPragmaCommentDecl(PragmaCommentDecl *D);
60e5dd7070Spatrick void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D);
61e5dd7070Spatrick void VisitTranslationUnitDecl(TranslationUnitDecl *D);
62e5dd7070Spatrick void VisitNamedDecl(NamedDecl *D);
63e5dd7070Spatrick void VisitLabelDecl(LabelDecl *LD);
64e5dd7070Spatrick void VisitNamespaceDecl(NamespaceDecl *D);
65e5dd7070Spatrick void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
66e5dd7070Spatrick void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
67e5dd7070Spatrick void VisitTypeDecl(TypeDecl *D);
68e5dd7070Spatrick void VisitTypedefNameDecl(TypedefNameDecl *D);
69e5dd7070Spatrick void VisitTypedefDecl(TypedefDecl *D);
70e5dd7070Spatrick void VisitTypeAliasDecl(TypeAliasDecl *D);
71e5dd7070Spatrick void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
72a9ac8606Spatrick void VisitUnresolvedUsingIfExistsDecl(UnresolvedUsingIfExistsDecl *D);
73e5dd7070Spatrick void VisitTagDecl(TagDecl *D);
74e5dd7070Spatrick void VisitEnumDecl(EnumDecl *D);
75e5dd7070Spatrick void VisitRecordDecl(RecordDecl *D);
76e5dd7070Spatrick void VisitCXXRecordDecl(CXXRecordDecl *D);
77e5dd7070Spatrick void VisitClassTemplateSpecializationDecl(
78e5dd7070Spatrick ClassTemplateSpecializationDecl *D);
79e5dd7070Spatrick void VisitClassTemplatePartialSpecializationDecl(
80e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *D);
81e5dd7070Spatrick void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
82e5dd7070Spatrick void VisitVarTemplatePartialSpecializationDecl(
83e5dd7070Spatrick VarTemplatePartialSpecializationDecl *D);
84e5dd7070Spatrick void VisitClassScopeFunctionSpecializationDecl(
85e5dd7070Spatrick ClassScopeFunctionSpecializationDecl *D);
86e5dd7070Spatrick void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
87e5dd7070Spatrick void VisitValueDecl(ValueDecl *D);
88e5dd7070Spatrick void VisitEnumConstantDecl(EnumConstantDecl *D);
89e5dd7070Spatrick void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
90e5dd7070Spatrick void VisitDeclaratorDecl(DeclaratorDecl *D);
91e5dd7070Spatrick void VisitFunctionDecl(FunctionDecl *D);
92e5dd7070Spatrick void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D);
93e5dd7070Spatrick void VisitCXXMethodDecl(CXXMethodDecl *D);
94e5dd7070Spatrick void VisitCXXConstructorDecl(CXXConstructorDecl *D);
95e5dd7070Spatrick void VisitCXXDestructorDecl(CXXDestructorDecl *D);
96e5dd7070Spatrick void VisitCXXConversionDecl(CXXConversionDecl *D);
97e5dd7070Spatrick void VisitFieldDecl(FieldDecl *D);
98e5dd7070Spatrick void VisitMSPropertyDecl(MSPropertyDecl *D);
99ec727ea7Spatrick void VisitMSGuidDecl(MSGuidDecl *D);
100*12c85518Srobert void VisitUnnamedGlobalConstantDecl(UnnamedGlobalConstantDecl *D);
101a9ac8606Spatrick void VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D);
102e5dd7070Spatrick void VisitIndirectFieldDecl(IndirectFieldDecl *D);
103e5dd7070Spatrick void VisitVarDecl(VarDecl *D);
104e5dd7070Spatrick void VisitImplicitParamDecl(ImplicitParamDecl *D);
105e5dd7070Spatrick void VisitParmVarDecl(ParmVarDecl *D);
106e5dd7070Spatrick void VisitDecompositionDecl(DecompositionDecl *D);
107e5dd7070Spatrick void VisitBindingDecl(BindingDecl *D);
108e5dd7070Spatrick void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
109e5dd7070Spatrick void VisitTemplateDecl(TemplateDecl *D);
110e5dd7070Spatrick void VisitConceptDecl(ConceptDecl *D);
111*12c85518Srobert void VisitImplicitConceptSpecializationDecl(
112*12c85518Srobert ImplicitConceptSpecializationDecl *D);
113e5dd7070Spatrick void VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
114e5dd7070Spatrick void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
115e5dd7070Spatrick void VisitClassTemplateDecl(ClassTemplateDecl *D);
116e5dd7070Spatrick void VisitVarTemplateDecl(VarTemplateDecl *D);
117e5dd7070Spatrick void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
118e5dd7070Spatrick void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
119e5dd7070Spatrick void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
120e5dd7070Spatrick void VisitUsingDecl(UsingDecl *D);
121a9ac8606Spatrick void VisitUsingEnumDecl(UsingEnumDecl *D);
122e5dd7070Spatrick void VisitUsingPackDecl(UsingPackDecl *D);
123e5dd7070Spatrick void VisitUsingShadowDecl(UsingShadowDecl *D);
124e5dd7070Spatrick void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D);
125e5dd7070Spatrick void VisitLinkageSpecDecl(LinkageSpecDecl *D);
126e5dd7070Spatrick void VisitExportDecl(ExportDecl *D);
127e5dd7070Spatrick void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
128*12c85518Srobert void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
129e5dd7070Spatrick void VisitImportDecl(ImportDecl *D);
130e5dd7070Spatrick void VisitAccessSpecDecl(AccessSpecDecl *D);
131e5dd7070Spatrick void VisitFriendDecl(FriendDecl *D);
132e5dd7070Spatrick void VisitFriendTemplateDecl(FriendTemplateDecl *D);
133e5dd7070Spatrick void VisitStaticAssertDecl(StaticAssertDecl *D);
134e5dd7070Spatrick void VisitBlockDecl(BlockDecl *D);
135e5dd7070Spatrick void VisitCapturedDecl(CapturedDecl *D);
136e5dd7070Spatrick void VisitEmptyDecl(EmptyDecl *D);
137e5dd7070Spatrick void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
138e5dd7070Spatrick void VisitDeclContext(DeclContext *DC);
139e5dd7070Spatrick template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
140*12c85518Srobert void VisitHLSLBufferDecl(HLSLBufferDecl *D);
141e5dd7070Spatrick
142e5dd7070Spatrick // FIXME: Put in the same order is DeclNodes.td?
143e5dd7070Spatrick void VisitObjCMethodDecl(ObjCMethodDecl *D);
144e5dd7070Spatrick void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
145e5dd7070Spatrick void VisitObjCContainerDecl(ObjCContainerDecl *D);
146e5dd7070Spatrick void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
147e5dd7070Spatrick void VisitObjCIvarDecl(ObjCIvarDecl *D);
148e5dd7070Spatrick void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
149e5dd7070Spatrick void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
150e5dd7070Spatrick void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
151e5dd7070Spatrick void VisitObjCImplDecl(ObjCImplDecl *D);
152e5dd7070Spatrick void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
153e5dd7070Spatrick void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
154e5dd7070Spatrick void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
155e5dd7070Spatrick void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
156e5dd7070Spatrick void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
157e5dd7070Spatrick void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
158e5dd7070Spatrick void VisitOMPAllocateDecl(OMPAllocateDecl *D);
159e5dd7070Spatrick void VisitOMPRequiresDecl(OMPRequiresDecl *D);
160e5dd7070Spatrick void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
161e5dd7070Spatrick void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
162e5dd7070Spatrick void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
163e5dd7070Spatrick
164e5dd7070Spatrick /// Add an Objective-C type parameter list to the given record.
AddObjCTypeParamList(ObjCTypeParamList * typeParams)165e5dd7070Spatrick void AddObjCTypeParamList(ObjCTypeParamList *typeParams) {
166e5dd7070Spatrick // Empty type parameter list.
167e5dd7070Spatrick if (!typeParams) {
168e5dd7070Spatrick Record.push_back(0);
169e5dd7070Spatrick return;
170e5dd7070Spatrick }
171e5dd7070Spatrick
172e5dd7070Spatrick Record.push_back(typeParams->size());
173*12c85518Srobert for (auto *typeParam : *typeParams) {
174e5dd7070Spatrick Record.AddDeclRef(typeParam);
175e5dd7070Spatrick }
176e5dd7070Spatrick Record.AddSourceLocation(typeParams->getLAngleLoc());
177e5dd7070Spatrick Record.AddSourceLocation(typeParams->getRAngleLoc());
178e5dd7070Spatrick }
179e5dd7070Spatrick
180e5dd7070Spatrick /// Add to the record the first declaration from each module file that
181e5dd7070Spatrick /// provides a declaration of D. The intent is to provide a sufficient
182e5dd7070Spatrick /// set such that reloading this set will load all current redeclarations.
AddFirstDeclFromEachModule(const Decl * D,bool IncludeLocal)183e5dd7070Spatrick void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
184e5dd7070Spatrick llvm::MapVector<ModuleFile*, const Decl*> Firsts;
185e5dd7070Spatrick // FIXME: We can skip entries that we know are implied by others.
186e5dd7070Spatrick for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
187e5dd7070Spatrick if (R->isFromASTFile())
188e5dd7070Spatrick Firsts[Writer.Chain->getOwningModuleFile(R)] = R;
189e5dd7070Spatrick else if (IncludeLocal)
190e5dd7070Spatrick Firsts[nullptr] = R;
191e5dd7070Spatrick }
192e5dd7070Spatrick for (const auto &F : Firsts)
193e5dd7070Spatrick Record.AddDeclRef(F.second);
194e5dd7070Spatrick }
195e5dd7070Spatrick
196e5dd7070Spatrick /// Get the specialization decl from an entry in the specialization list.
197e5dd7070Spatrick template <typename EntryType>
198e5dd7070Spatrick typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
getSpecializationDecl(EntryType & T)199e5dd7070Spatrick getSpecializationDecl(EntryType &T) {
200e5dd7070Spatrick return RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::getDecl(&T);
201e5dd7070Spatrick }
202e5dd7070Spatrick
203e5dd7070Spatrick /// Get the list of partial specializations from a template's common ptr.
204e5dd7070Spatrick template<typename T>
getPartialSpecializations(T * Common)205e5dd7070Spatrick decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) {
206e5dd7070Spatrick return Common->PartialSpecializations;
207e5dd7070Spatrick }
getPartialSpecializations(FunctionTemplateDecl::Common *)208e5dd7070Spatrick ArrayRef<Decl> getPartialSpecializations(FunctionTemplateDecl::Common *) {
209*12c85518Srobert return std::nullopt;
210e5dd7070Spatrick }
211e5dd7070Spatrick
212e5dd7070Spatrick template<typename DeclTy>
AddTemplateSpecializations(DeclTy * D)213e5dd7070Spatrick void AddTemplateSpecializations(DeclTy *D) {
214e5dd7070Spatrick auto *Common = D->getCommonPtr();
215e5dd7070Spatrick
216e5dd7070Spatrick // If we have any lazy specializations, and the external AST source is
217e5dd7070Spatrick // our chained AST reader, we can just write out the DeclIDs. Otherwise,
218e5dd7070Spatrick // we need to resolve them to actual declarations.
219e5dd7070Spatrick if (Writer.Chain != Writer.Context->getExternalSource() &&
220e5dd7070Spatrick Common->LazySpecializations) {
221e5dd7070Spatrick D->LoadLazySpecializations();
222e5dd7070Spatrick assert(!Common->LazySpecializations);
223e5dd7070Spatrick }
224e5dd7070Spatrick
225e5dd7070Spatrick ArrayRef<DeclID> LazySpecializations;
226e5dd7070Spatrick if (auto *LS = Common->LazySpecializations)
227*12c85518Srobert LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]);
228e5dd7070Spatrick
229e5dd7070Spatrick // Add a slot to the record for the number of specializations.
230e5dd7070Spatrick unsigned I = Record.size();
231e5dd7070Spatrick Record.push_back(0);
232e5dd7070Spatrick
233e5dd7070Spatrick // AddFirstDeclFromEachModule might trigger deserialization, invalidating
234e5dd7070Spatrick // *Specializations iterators.
235e5dd7070Spatrick llvm::SmallVector<const Decl*, 16> Specs;
236e5dd7070Spatrick for (auto &Entry : Common->Specializations)
237e5dd7070Spatrick Specs.push_back(getSpecializationDecl(Entry));
238e5dd7070Spatrick for (auto &Entry : getPartialSpecializations(Common))
239e5dd7070Spatrick Specs.push_back(getSpecializationDecl(Entry));
240e5dd7070Spatrick
241e5dd7070Spatrick for (auto *D : Specs) {
242e5dd7070Spatrick assert(D->isCanonicalDecl() && "non-canonical decl in set");
243e5dd7070Spatrick AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
244e5dd7070Spatrick }
245e5dd7070Spatrick Record.append(LazySpecializations.begin(), LazySpecializations.end());
246e5dd7070Spatrick
247e5dd7070Spatrick // Update the size entry we added earlier.
248e5dd7070Spatrick Record[I] = Record.size() - I - 1;
249e5dd7070Spatrick }
250e5dd7070Spatrick
251e5dd7070Spatrick /// Ensure that this template specialization is associated with the specified
252e5dd7070Spatrick /// template on reload.
RegisterTemplateSpecialization(const Decl * Template,const Decl * Specialization)253e5dd7070Spatrick void RegisterTemplateSpecialization(const Decl *Template,
254e5dd7070Spatrick const Decl *Specialization) {
255e5dd7070Spatrick Template = Template->getCanonicalDecl();
256e5dd7070Spatrick
257e5dd7070Spatrick // If the canonical template is local, we'll write out this specialization
258e5dd7070Spatrick // when we emit it.
259e5dd7070Spatrick // FIXME: We can do the same thing if there is any local declaration of
260e5dd7070Spatrick // the template, to avoid emitting an update record.
261e5dd7070Spatrick if (!Template->isFromASTFile())
262e5dd7070Spatrick return;
263e5dd7070Spatrick
264e5dd7070Spatrick // We only need to associate the first local declaration of the
265e5dd7070Spatrick // specialization. The other declarations will get pulled in by it.
266e5dd7070Spatrick if (Writer.getFirstLocalDecl(Specialization) != Specialization)
267e5dd7070Spatrick return;
268e5dd7070Spatrick
269e5dd7070Spatrick Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate(
270e5dd7070Spatrick UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization));
271e5dd7070Spatrick }
272e5dd7070Spatrick };
273e5dd7070Spatrick }
274e5dd7070Spatrick
Visit(Decl * D)275e5dd7070Spatrick void ASTDeclWriter::Visit(Decl *D) {
276e5dd7070Spatrick DeclVisitor<ASTDeclWriter>::Visit(D);
277e5dd7070Spatrick
278e5dd7070Spatrick // Source locations require array (variable-length) abbreviations. The
279e5dd7070Spatrick // abbreviation infrastructure requires that arrays are encoded last, so
280e5dd7070Spatrick // we handle it here in the case of those classes derived from DeclaratorDecl
281e5dd7070Spatrick if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
282e5dd7070Spatrick if (auto *TInfo = DD->getTypeSourceInfo())
283e5dd7070Spatrick Record.AddTypeLoc(TInfo->getTypeLoc());
284e5dd7070Spatrick }
285e5dd7070Spatrick
286e5dd7070Spatrick // Handle FunctionDecl's body here and write it after all other Stmts/Exprs
287e5dd7070Spatrick // have been written. We want it last because we will not read it back when
288e5dd7070Spatrick // retrieving it from the AST, we'll just lazily set the offset.
289e5dd7070Spatrick if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
290e5dd7070Spatrick Record.push_back(FD->doesThisDeclarationHaveABody());
291e5dd7070Spatrick if (FD->doesThisDeclarationHaveABody())
292e5dd7070Spatrick Record.AddFunctionDefinition(FD);
293e5dd7070Spatrick }
294e5dd7070Spatrick
295e5dd7070Spatrick // If this declaration is also a DeclContext, write blocks for the
296e5dd7070Spatrick // declarations that lexically stored inside its context and those
297e5dd7070Spatrick // declarations that are visible from its context.
298e5dd7070Spatrick if (DeclContext *DC = dyn_cast<DeclContext>(D))
299e5dd7070Spatrick VisitDeclContext(DC);
300e5dd7070Spatrick }
301e5dd7070Spatrick
VisitDecl(Decl * D)302e5dd7070Spatrick void ASTDeclWriter::VisitDecl(Decl *D) {
303e5dd7070Spatrick Record.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()));
304e5dd7070Spatrick if (D->getDeclContext() != D->getLexicalDeclContext())
305e5dd7070Spatrick Record.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()));
306e5dd7070Spatrick else
307e5dd7070Spatrick Record.push_back(0);
308e5dd7070Spatrick Record.push_back(D->isInvalidDecl());
309e5dd7070Spatrick Record.push_back(D->hasAttrs());
310e5dd7070Spatrick if (D->hasAttrs())
311e5dd7070Spatrick Record.AddAttributes(D->getAttrs());
312e5dd7070Spatrick Record.push_back(D->isImplicit());
313e5dd7070Spatrick Record.push_back(D->isUsed(false));
314e5dd7070Spatrick Record.push_back(D->isReferenced());
315e5dd7070Spatrick Record.push_back(D->isTopLevelDeclInObjCContainer());
316e5dd7070Spatrick Record.push_back(D->getAccess());
317*12c85518Srobert Record.push_back((uint64_t)D->getModuleOwnershipKind());
318e5dd7070Spatrick Record.push_back(Writer.getSubmoduleID(D->getOwningModule()));
319e5dd7070Spatrick
320e5dd7070Spatrick // If this declaration injected a name into a context different from its
321e5dd7070Spatrick // lexical context, and that context is an imported namespace, we need to
322e5dd7070Spatrick // update its visible declarations to include this name.
323e5dd7070Spatrick //
324e5dd7070Spatrick // This happens when we instantiate a class with a friend declaration or a
325e5dd7070Spatrick // function with a local extern declaration, for instance.
326e5dd7070Spatrick //
327e5dd7070Spatrick // FIXME: Can we handle this in AddedVisibleDecl instead?
328e5dd7070Spatrick if (D->isOutOfLine()) {
329e5dd7070Spatrick auto *DC = D->getDeclContext();
330e5dd7070Spatrick while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
331e5dd7070Spatrick if (!NS->isFromASTFile())
332e5dd7070Spatrick break;
333e5dd7070Spatrick Writer.UpdatedDeclContexts.insert(NS->getPrimaryContext());
334e5dd7070Spatrick if (!NS->isInlineNamespace())
335e5dd7070Spatrick break;
336e5dd7070Spatrick DC = NS->getParent();
337e5dd7070Spatrick }
338e5dd7070Spatrick }
339e5dd7070Spatrick }
340e5dd7070Spatrick
VisitPragmaCommentDecl(PragmaCommentDecl * D)341e5dd7070Spatrick void ASTDeclWriter::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
342e5dd7070Spatrick StringRef Arg = D->getArg();
343e5dd7070Spatrick Record.push_back(Arg.size());
344e5dd7070Spatrick VisitDecl(D);
345e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
346e5dd7070Spatrick Record.push_back(D->getCommentKind());
347e5dd7070Spatrick Record.AddString(Arg);
348e5dd7070Spatrick Code = serialization::DECL_PRAGMA_COMMENT;
349e5dd7070Spatrick }
350e5dd7070Spatrick
VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl * D)351e5dd7070Spatrick void ASTDeclWriter::VisitPragmaDetectMismatchDecl(
352e5dd7070Spatrick PragmaDetectMismatchDecl *D) {
353e5dd7070Spatrick StringRef Name = D->getName();
354e5dd7070Spatrick StringRef Value = D->getValue();
355e5dd7070Spatrick Record.push_back(Name.size() + 1 + Value.size());
356e5dd7070Spatrick VisitDecl(D);
357e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
358e5dd7070Spatrick Record.AddString(Name);
359e5dd7070Spatrick Record.AddString(Value);
360e5dd7070Spatrick Code = serialization::DECL_PRAGMA_DETECT_MISMATCH;
361e5dd7070Spatrick }
362e5dd7070Spatrick
VisitTranslationUnitDecl(TranslationUnitDecl * D)363e5dd7070Spatrick void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
364e5dd7070Spatrick llvm_unreachable("Translation units aren't directly serialized");
365e5dd7070Spatrick }
366e5dd7070Spatrick
VisitNamedDecl(NamedDecl * D)367e5dd7070Spatrick void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
368e5dd7070Spatrick VisitDecl(D);
369e5dd7070Spatrick Record.AddDeclarationName(D->getDeclName());
370e5dd7070Spatrick Record.push_back(needsAnonymousDeclarationNumber(D)
371e5dd7070Spatrick ? Writer.getAnonymousDeclarationNumber(D)
372e5dd7070Spatrick : 0);
373e5dd7070Spatrick }
374e5dd7070Spatrick
VisitTypeDecl(TypeDecl * D)375e5dd7070Spatrick void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
376e5dd7070Spatrick VisitNamedDecl(D);
377e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
378e5dd7070Spatrick Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
379e5dd7070Spatrick }
380e5dd7070Spatrick
VisitTypedefNameDecl(TypedefNameDecl * D)381e5dd7070Spatrick void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
382e5dd7070Spatrick VisitRedeclarable(D);
383e5dd7070Spatrick VisitTypeDecl(D);
384e5dd7070Spatrick Record.AddTypeSourceInfo(D->getTypeSourceInfo());
385e5dd7070Spatrick Record.push_back(D->isModed());
386e5dd7070Spatrick if (D->isModed())
387e5dd7070Spatrick Record.AddTypeRef(D->getUnderlyingType());
388e5dd7070Spatrick Record.AddDeclRef(D->getAnonDeclWithTypedefName(false));
389e5dd7070Spatrick }
390e5dd7070Spatrick
VisitTypedefDecl(TypedefDecl * D)391e5dd7070Spatrick void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
392e5dd7070Spatrick VisitTypedefNameDecl(D);
393e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
394e5dd7070Spatrick !D->hasAttrs() &&
395e5dd7070Spatrick !D->isImplicit() &&
396e5dd7070Spatrick D->getFirstDecl() == D->getMostRecentDecl() &&
397e5dd7070Spatrick !D->isInvalidDecl() &&
398e5dd7070Spatrick !D->isTopLevelDeclInObjCContainer() &&
399e5dd7070Spatrick !D->isModulePrivate() &&
400e5dd7070Spatrick !needsAnonymousDeclarationNumber(D) &&
401e5dd7070Spatrick D->getDeclName().getNameKind() == DeclarationName::Identifier)
402e5dd7070Spatrick AbbrevToUse = Writer.getDeclTypedefAbbrev();
403e5dd7070Spatrick
404e5dd7070Spatrick Code = serialization::DECL_TYPEDEF;
405e5dd7070Spatrick }
406e5dd7070Spatrick
VisitTypeAliasDecl(TypeAliasDecl * D)407e5dd7070Spatrick void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
408e5dd7070Spatrick VisitTypedefNameDecl(D);
409e5dd7070Spatrick Record.AddDeclRef(D->getDescribedAliasTemplate());
410e5dd7070Spatrick Code = serialization::DECL_TYPEALIAS;
411e5dd7070Spatrick }
412e5dd7070Spatrick
VisitTagDecl(TagDecl * D)413e5dd7070Spatrick void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
414e5dd7070Spatrick VisitRedeclarable(D);
415e5dd7070Spatrick VisitTypeDecl(D);
416e5dd7070Spatrick Record.push_back(D->getIdentifierNamespace());
417e5dd7070Spatrick Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
418e5dd7070Spatrick if (!isa<CXXRecordDecl>(D))
419e5dd7070Spatrick Record.push_back(D->isCompleteDefinition());
420e5dd7070Spatrick Record.push_back(D->isEmbeddedInDeclarator());
421e5dd7070Spatrick Record.push_back(D->isFreeStanding());
422e5dd7070Spatrick Record.push_back(D->isCompleteDefinitionRequired());
423e5dd7070Spatrick Record.AddSourceRange(D->getBraceRange());
424e5dd7070Spatrick
425e5dd7070Spatrick if (D->hasExtInfo()) {
426e5dd7070Spatrick Record.push_back(1);
427e5dd7070Spatrick Record.AddQualifierInfo(*D->getExtInfo());
428e5dd7070Spatrick } else if (auto *TD = D->getTypedefNameForAnonDecl()) {
429e5dd7070Spatrick Record.push_back(2);
430e5dd7070Spatrick Record.AddDeclRef(TD);
431e5dd7070Spatrick Record.AddIdentifierRef(TD->getDeclName().getAsIdentifierInfo());
432e5dd7070Spatrick } else {
433e5dd7070Spatrick Record.push_back(0);
434e5dd7070Spatrick }
435e5dd7070Spatrick }
436e5dd7070Spatrick
VisitEnumDecl(EnumDecl * D)437e5dd7070Spatrick void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
438e5dd7070Spatrick VisitTagDecl(D);
439e5dd7070Spatrick Record.AddTypeSourceInfo(D->getIntegerTypeSourceInfo());
440e5dd7070Spatrick if (!D->getIntegerTypeSourceInfo())
441e5dd7070Spatrick Record.AddTypeRef(D->getIntegerType());
442e5dd7070Spatrick Record.AddTypeRef(D->getPromotionType());
443e5dd7070Spatrick Record.push_back(D->getNumPositiveBits());
444e5dd7070Spatrick Record.push_back(D->getNumNegativeBits());
445e5dd7070Spatrick Record.push_back(D->isScoped());
446e5dd7070Spatrick Record.push_back(D->isScopedUsingClassTag());
447e5dd7070Spatrick Record.push_back(D->isFixed());
448e5dd7070Spatrick Record.push_back(D->getODRHash());
449e5dd7070Spatrick
450e5dd7070Spatrick if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
451e5dd7070Spatrick Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
452e5dd7070Spatrick Record.push_back(MemberInfo->getTemplateSpecializationKind());
453e5dd7070Spatrick Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
454e5dd7070Spatrick } else {
455e5dd7070Spatrick Record.AddDeclRef(nullptr);
456e5dd7070Spatrick }
457e5dd7070Spatrick
458e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
459e5dd7070Spatrick !D->hasAttrs() &&
460e5dd7070Spatrick !D->isImplicit() &&
461e5dd7070Spatrick !D->isUsed(false) &&
462e5dd7070Spatrick !D->hasExtInfo() &&
463e5dd7070Spatrick !D->getTypedefNameForAnonDecl() &&
464e5dd7070Spatrick D->getFirstDecl() == D->getMostRecentDecl() &&
465e5dd7070Spatrick !D->isInvalidDecl() &&
466e5dd7070Spatrick !D->isReferenced() &&
467e5dd7070Spatrick !D->isTopLevelDeclInObjCContainer() &&
468e5dd7070Spatrick D->getAccess() == AS_none &&
469e5dd7070Spatrick !D->isModulePrivate() &&
470e5dd7070Spatrick !CXXRecordDecl::classofKind(D->getKind()) &&
471e5dd7070Spatrick !D->getIntegerTypeSourceInfo() &&
472e5dd7070Spatrick !D->getMemberSpecializationInfo() &&
473e5dd7070Spatrick !needsAnonymousDeclarationNumber(D) &&
474e5dd7070Spatrick D->getDeclName().getNameKind() == DeclarationName::Identifier)
475e5dd7070Spatrick AbbrevToUse = Writer.getDeclEnumAbbrev();
476e5dd7070Spatrick
477e5dd7070Spatrick Code = serialization::DECL_ENUM;
478e5dd7070Spatrick }
479e5dd7070Spatrick
VisitRecordDecl(RecordDecl * D)480e5dd7070Spatrick void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
481e5dd7070Spatrick VisitTagDecl(D);
482e5dd7070Spatrick Record.push_back(D->hasFlexibleArrayMember());
483e5dd7070Spatrick Record.push_back(D->isAnonymousStructOrUnion());
484e5dd7070Spatrick Record.push_back(D->hasObjectMember());
485e5dd7070Spatrick Record.push_back(D->hasVolatileMember());
486e5dd7070Spatrick Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize());
487e5dd7070Spatrick Record.push_back(D->isNonTrivialToPrimitiveCopy());
488e5dd7070Spatrick Record.push_back(D->isNonTrivialToPrimitiveDestroy());
489e5dd7070Spatrick Record.push_back(D->hasNonTrivialToPrimitiveDefaultInitializeCUnion());
490e5dd7070Spatrick Record.push_back(D->hasNonTrivialToPrimitiveDestructCUnion());
491e5dd7070Spatrick Record.push_back(D->hasNonTrivialToPrimitiveCopyCUnion());
492e5dd7070Spatrick Record.push_back(D->isParamDestroyedInCallee());
493e5dd7070Spatrick Record.push_back(D->getArgPassingRestrictions());
494*12c85518Srobert // Only compute this for C/Objective-C, in C++ this is computed as part
495*12c85518Srobert // of CXXRecordDecl.
496*12c85518Srobert if (!isa<CXXRecordDecl>(D))
497*12c85518Srobert Record.push_back(D->getODRHash());
498e5dd7070Spatrick
499e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
500e5dd7070Spatrick !D->hasAttrs() &&
501e5dd7070Spatrick !D->isImplicit() &&
502e5dd7070Spatrick !D->isUsed(false) &&
503e5dd7070Spatrick !D->hasExtInfo() &&
504e5dd7070Spatrick !D->getTypedefNameForAnonDecl() &&
505e5dd7070Spatrick D->getFirstDecl() == D->getMostRecentDecl() &&
506e5dd7070Spatrick !D->isInvalidDecl() &&
507e5dd7070Spatrick !D->isReferenced() &&
508e5dd7070Spatrick !D->isTopLevelDeclInObjCContainer() &&
509e5dd7070Spatrick D->getAccess() == AS_none &&
510e5dd7070Spatrick !D->isModulePrivate() &&
511e5dd7070Spatrick !CXXRecordDecl::classofKind(D->getKind()) &&
512e5dd7070Spatrick !needsAnonymousDeclarationNumber(D) &&
513e5dd7070Spatrick D->getDeclName().getNameKind() == DeclarationName::Identifier)
514e5dd7070Spatrick AbbrevToUse = Writer.getDeclRecordAbbrev();
515e5dd7070Spatrick
516e5dd7070Spatrick Code = serialization::DECL_RECORD;
517e5dd7070Spatrick }
518e5dd7070Spatrick
VisitValueDecl(ValueDecl * D)519e5dd7070Spatrick void ASTDeclWriter::VisitValueDecl(ValueDecl *D) {
520e5dd7070Spatrick VisitNamedDecl(D);
521e5dd7070Spatrick Record.AddTypeRef(D->getType());
522e5dd7070Spatrick }
523e5dd7070Spatrick
VisitEnumConstantDecl(EnumConstantDecl * D)524e5dd7070Spatrick void ASTDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
525e5dd7070Spatrick VisitValueDecl(D);
526e5dd7070Spatrick Record.push_back(D->getInitExpr()? 1 : 0);
527e5dd7070Spatrick if (D->getInitExpr())
528e5dd7070Spatrick Record.AddStmt(D->getInitExpr());
529e5dd7070Spatrick Record.AddAPSInt(D->getInitVal());
530e5dd7070Spatrick
531e5dd7070Spatrick Code = serialization::DECL_ENUM_CONSTANT;
532e5dd7070Spatrick }
533e5dd7070Spatrick
VisitDeclaratorDecl(DeclaratorDecl * D)534e5dd7070Spatrick void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
535e5dd7070Spatrick VisitValueDecl(D);
536e5dd7070Spatrick Record.AddSourceLocation(D->getInnerLocStart());
537e5dd7070Spatrick Record.push_back(D->hasExtInfo());
538e5dd7070Spatrick if (D->hasExtInfo()) {
539e5dd7070Spatrick DeclaratorDecl::ExtInfo *Info = D->getExtInfo();
540e5dd7070Spatrick Record.AddQualifierInfo(*Info);
541e5dd7070Spatrick Record.AddStmt(Info->TrailingRequiresClause);
542e5dd7070Spatrick }
543e5dd7070Spatrick // The location information is deferred until the end of the record.
544e5dd7070Spatrick Record.AddTypeRef(D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType()
545e5dd7070Spatrick : QualType());
546e5dd7070Spatrick }
547e5dd7070Spatrick
VisitFunctionDecl(FunctionDecl * D)548e5dd7070Spatrick void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
549e5dd7070Spatrick VisitRedeclarable(D);
550e5dd7070Spatrick
551e5dd7070Spatrick Record.push_back(D->getTemplatedKind());
552e5dd7070Spatrick switch (D->getTemplatedKind()) {
553e5dd7070Spatrick case FunctionDecl::TK_NonTemplate:
554e5dd7070Spatrick break;
555*12c85518Srobert case FunctionDecl::TK_DependentNonTemplate:
556*12c85518Srobert Record.AddDeclRef(D->getInstantiatedFromDecl());
557*12c85518Srobert break;
558e5dd7070Spatrick case FunctionDecl::TK_FunctionTemplate:
559e5dd7070Spatrick Record.AddDeclRef(D->getDescribedFunctionTemplate());
560e5dd7070Spatrick break;
561e5dd7070Spatrick case FunctionDecl::TK_MemberSpecialization: {
562e5dd7070Spatrick MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo();
563e5dd7070Spatrick Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
564e5dd7070Spatrick Record.push_back(MemberInfo->getTemplateSpecializationKind());
565e5dd7070Spatrick Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
566e5dd7070Spatrick break;
567e5dd7070Spatrick }
568e5dd7070Spatrick case FunctionDecl::TK_FunctionTemplateSpecialization: {
569e5dd7070Spatrick FunctionTemplateSpecializationInfo *
570e5dd7070Spatrick FTSInfo = D->getTemplateSpecializationInfo();
571e5dd7070Spatrick
572e5dd7070Spatrick RegisterTemplateSpecialization(FTSInfo->getTemplate(), D);
573e5dd7070Spatrick
574e5dd7070Spatrick Record.AddDeclRef(FTSInfo->getTemplate());
575e5dd7070Spatrick Record.push_back(FTSInfo->getTemplateSpecializationKind());
576e5dd7070Spatrick
577e5dd7070Spatrick // Template arguments.
578e5dd7070Spatrick Record.AddTemplateArgumentList(FTSInfo->TemplateArguments);
579e5dd7070Spatrick
580e5dd7070Spatrick // Template args as written.
581e5dd7070Spatrick Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
582e5dd7070Spatrick if (FTSInfo->TemplateArgumentsAsWritten) {
583e5dd7070Spatrick Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
584e5dd7070Spatrick for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
585e5dd7070Spatrick i!=e; ++i)
586e5dd7070Spatrick Record.AddTemplateArgumentLoc(
587e5dd7070Spatrick (*FTSInfo->TemplateArgumentsAsWritten)[i]);
588e5dd7070Spatrick Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->LAngleLoc);
589e5dd7070Spatrick Record.AddSourceLocation(FTSInfo->TemplateArgumentsAsWritten->RAngleLoc);
590e5dd7070Spatrick }
591e5dd7070Spatrick
592e5dd7070Spatrick Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
593e5dd7070Spatrick
594e5dd7070Spatrick if (MemberSpecializationInfo *MemberInfo =
595e5dd7070Spatrick FTSInfo->getMemberSpecializationInfo()) {
596e5dd7070Spatrick Record.push_back(1);
597e5dd7070Spatrick Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
598e5dd7070Spatrick Record.push_back(MemberInfo->getTemplateSpecializationKind());
599e5dd7070Spatrick Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
600e5dd7070Spatrick } else {
601e5dd7070Spatrick Record.push_back(0);
602e5dd7070Spatrick }
603e5dd7070Spatrick
604e5dd7070Spatrick if (D->isCanonicalDecl()) {
605e5dd7070Spatrick // Write the template that contains the specializations set. We will
606e5dd7070Spatrick // add a FunctionTemplateSpecializationInfo to it when reading.
607e5dd7070Spatrick Record.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl());
608e5dd7070Spatrick }
609e5dd7070Spatrick break;
610e5dd7070Spatrick }
611e5dd7070Spatrick case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
612e5dd7070Spatrick DependentFunctionTemplateSpecializationInfo *
613e5dd7070Spatrick DFTSInfo = D->getDependentSpecializationInfo();
614e5dd7070Spatrick
615e5dd7070Spatrick // Templates.
616e5dd7070Spatrick Record.push_back(DFTSInfo->getNumTemplates());
617e5dd7070Spatrick for (int i=0, e = DFTSInfo->getNumTemplates(); i != e; ++i)
618e5dd7070Spatrick Record.AddDeclRef(DFTSInfo->getTemplate(i));
619e5dd7070Spatrick
620e5dd7070Spatrick // Templates args.
621e5dd7070Spatrick Record.push_back(DFTSInfo->getNumTemplateArgs());
622e5dd7070Spatrick for (int i=0, e = DFTSInfo->getNumTemplateArgs(); i != e; ++i)
623e5dd7070Spatrick Record.AddTemplateArgumentLoc(DFTSInfo->getTemplateArg(i));
624e5dd7070Spatrick Record.AddSourceLocation(DFTSInfo->getLAngleLoc());
625e5dd7070Spatrick Record.AddSourceLocation(DFTSInfo->getRAngleLoc());
626e5dd7070Spatrick break;
627e5dd7070Spatrick }
628e5dd7070Spatrick }
629e5dd7070Spatrick
630*12c85518Srobert VisitDeclaratorDecl(D);
631*12c85518Srobert Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
632*12c85518Srobert Record.push_back(D->getIdentifierNamespace());
633*12c85518Srobert
634*12c85518Srobert // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
635*12c85518Srobert // after everything else is written.
636*12c85518Srobert Record.push_back(
637*12c85518Srobert static_cast<int>(D->getStorageClass())); // FIXME: stable encoding
638*12c85518Srobert Record.push_back(D->isInlineSpecified());
639*12c85518Srobert Record.push_back(D->isInlined());
640*12c85518Srobert Record.push_back(D->isVirtualAsWritten());
641*12c85518Srobert Record.push_back(D->isPure());
642*12c85518Srobert Record.push_back(D->hasInheritedPrototype());
643*12c85518Srobert Record.push_back(D->hasWrittenPrototype());
644*12c85518Srobert Record.push_back(D->isDeletedBit());
645*12c85518Srobert Record.push_back(D->isTrivial());
646*12c85518Srobert Record.push_back(D->isTrivialForCall());
647*12c85518Srobert Record.push_back(D->isDefaulted());
648*12c85518Srobert Record.push_back(D->isExplicitlyDefaulted());
649*12c85518Srobert Record.push_back(D->isIneligibleOrNotSelected());
650*12c85518Srobert Record.push_back(D->hasImplicitReturnZero());
651*12c85518Srobert Record.push_back(static_cast<uint64_t>(D->getConstexprKind()));
652*12c85518Srobert Record.push_back(D->usesSEHTry());
653*12c85518Srobert Record.push_back(D->hasSkippedBody());
654*12c85518Srobert Record.push_back(D->isMultiVersion());
655*12c85518Srobert Record.push_back(D->isLateTemplateParsed());
656*12c85518Srobert Record.push_back(D->FriendConstraintRefersToEnclosingTemplate());
657*12c85518Srobert Record.push_back(D->getLinkageInternal());
658*12c85518Srobert Record.AddSourceLocation(D->getEndLoc());
659*12c85518Srobert Record.AddSourceLocation(D->getDefaultLoc());
660*12c85518Srobert
661*12c85518Srobert Record.push_back(D->getODRHash());
662*12c85518Srobert
663*12c85518Srobert if (D->isDefaulted()) {
664*12c85518Srobert if (auto *FDI = D->getDefaultedFunctionInfo()) {
665*12c85518Srobert Record.push_back(FDI->getUnqualifiedLookups().size());
666*12c85518Srobert for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
667*12c85518Srobert Record.AddDeclRef(P.getDecl());
668*12c85518Srobert Record.push_back(P.getAccess());
669*12c85518Srobert }
670*12c85518Srobert } else {
671*12c85518Srobert Record.push_back(0);
672*12c85518Srobert }
673*12c85518Srobert }
674*12c85518Srobert
675e5dd7070Spatrick Record.push_back(D->param_size());
676*12c85518Srobert for (auto *P : D->parameters())
677e5dd7070Spatrick Record.AddDeclRef(P);
678e5dd7070Spatrick Code = serialization::DECL_FUNCTION;
679e5dd7070Spatrick }
680e5dd7070Spatrick
addExplicitSpecifier(ExplicitSpecifier ES,ASTRecordWriter & Record)681e5dd7070Spatrick static void addExplicitSpecifier(ExplicitSpecifier ES,
682e5dd7070Spatrick ASTRecordWriter &Record) {
683e5dd7070Spatrick uint64_t Kind = static_cast<uint64_t>(ES.getKind());
684e5dd7070Spatrick Kind = Kind << 1 | static_cast<bool>(ES.getExpr());
685e5dd7070Spatrick Record.push_back(Kind);
686e5dd7070Spatrick if (ES.getExpr()) {
687e5dd7070Spatrick Record.AddStmt(ES.getExpr());
688e5dd7070Spatrick }
689e5dd7070Spatrick }
690e5dd7070Spatrick
VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl * D)691e5dd7070Spatrick void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
692e5dd7070Spatrick addExplicitSpecifier(D->getExplicitSpecifier(), Record);
693a9ac8606Spatrick Record.AddDeclRef(D->Ctor);
694e5dd7070Spatrick VisitFunctionDecl(D);
695e5dd7070Spatrick Record.push_back(D->isCopyDeductionCandidate());
696e5dd7070Spatrick Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
697e5dd7070Spatrick }
698e5dd7070Spatrick
VisitObjCMethodDecl(ObjCMethodDecl * D)699e5dd7070Spatrick void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
700e5dd7070Spatrick VisitNamedDecl(D);
701e5dd7070Spatrick // FIXME: convert to LazyStmtPtr?
702e5dd7070Spatrick // Unlike C/C++, method bodies will never be in header files.
703e5dd7070Spatrick bool HasBodyStuff = D->getBody() != nullptr;
704e5dd7070Spatrick Record.push_back(HasBodyStuff);
705e5dd7070Spatrick if (HasBodyStuff) {
706e5dd7070Spatrick Record.AddStmt(D->getBody());
707e5dd7070Spatrick }
708e5dd7070Spatrick Record.AddDeclRef(D->getSelfDecl());
709e5dd7070Spatrick Record.AddDeclRef(D->getCmdDecl());
710e5dd7070Spatrick Record.push_back(D->isInstanceMethod());
711e5dd7070Spatrick Record.push_back(D->isVariadic());
712e5dd7070Spatrick Record.push_back(D->isPropertyAccessor());
713e5dd7070Spatrick Record.push_back(D->isSynthesizedAccessorStub());
714e5dd7070Spatrick Record.push_back(D->isDefined());
715e5dd7070Spatrick Record.push_back(D->isOverriding());
716e5dd7070Spatrick Record.push_back(D->hasSkippedBody());
717e5dd7070Spatrick
718e5dd7070Spatrick Record.push_back(D->isRedeclaration());
719e5dd7070Spatrick Record.push_back(D->hasRedeclaration());
720e5dd7070Spatrick if (D->hasRedeclaration()) {
721e5dd7070Spatrick assert(Context.getObjCMethodRedeclaration(D));
722e5dd7070Spatrick Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
723e5dd7070Spatrick }
724e5dd7070Spatrick
725e5dd7070Spatrick // FIXME: stable encoding for @required/@optional
726e5dd7070Spatrick Record.push_back(D->getImplementationControl());
727e5dd7070Spatrick // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway/nullability
728e5dd7070Spatrick Record.push_back(D->getObjCDeclQualifier());
729e5dd7070Spatrick Record.push_back(D->hasRelatedResultType());
730e5dd7070Spatrick Record.AddTypeRef(D->getReturnType());
731e5dd7070Spatrick Record.AddTypeSourceInfo(D->getReturnTypeSourceInfo());
732e5dd7070Spatrick Record.AddSourceLocation(D->getEndLoc());
733e5dd7070Spatrick Record.push_back(D->param_size());
734e5dd7070Spatrick for (const auto *P : D->parameters())
735e5dd7070Spatrick Record.AddDeclRef(P);
736e5dd7070Spatrick
737e5dd7070Spatrick Record.push_back(D->getSelLocsKind());
738e5dd7070Spatrick unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
739e5dd7070Spatrick SourceLocation *SelLocs = D->getStoredSelLocs();
740e5dd7070Spatrick Record.push_back(NumStoredSelLocs);
741e5dd7070Spatrick for (unsigned i = 0; i != NumStoredSelLocs; ++i)
742e5dd7070Spatrick Record.AddSourceLocation(SelLocs[i]);
743e5dd7070Spatrick
744e5dd7070Spatrick Code = serialization::DECL_OBJC_METHOD;
745e5dd7070Spatrick }
746e5dd7070Spatrick
VisitObjCTypeParamDecl(ObjCTypeParamDecl * D)747e5dd7070Spatrick void ASTDeclWriter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
748e5dd7070Spatrick VisitTypedefNameDecl(D);
749e5dd7070Spatrick Record.push_back(D->Variance);
750e5dd7070Spatrick Record.push_back(D->Index);
751e5dd7070Spatrick Record.AddSourceLocation(D->VarianceLoc);
752e5dd7070Spatrick Record.AddSourceLocation(D->ColonLoc);
753e5dd7070Spatrick
754e5dd7070Spatrick Code = serialization::DECL_OBJC_TYPE_PARAM;
755e5dd7070Spatrick }
756e5dd7070Spatrick
VisitObjCContainerDecl(ObjCContainerDecl * D)757e5dd7070Spatrick void ASTDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
758e5dd7070Spatrick VisitNamedDecl(D);
759e5dd7070Spatrick Record.AddSourceLocation(D->getAtStartLoc());
760e5dd7070Spatrick Record.AddSourceRange(D->getAtEndRange());
761e5dd7070Spatrick // Abstract class (no need to define a stable serialization::DECL code).
762e5dd7070Spatrick }
763e5dd7070Spatrick
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)764e5dd7070Spatrick void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
765e5dd7070Spatrick VisitRedeclarable(D);
766e5dd7070Spatrick VisitObjCContainerDecl(D);
767e5dd7070Spatrick Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
768e5dd7070Spatrick AddObjCTypeParamList(D->TypeParamList);
769e5dd7070Spatrick
770e5dd7070Spatrick Record.push_back(D->isThisDeclarationADefinition());
771e5dd7070Spatrick if (D->isThisDeclarationADefinition()) {
772e5dd7070Spatrick // Write the DefinitionData
773e5dd7070Spatrick ObjCInterfaceDecl::DefinitionData &Data = D->data();
774e5dd7070Spatrick
775e5dd7070Spatrick Record.AddTypeSourceInfo(D->getSuperClassTInfo());
776e5dd7070Spatrick Record.AddSourceLocation(D->getEndOfDefinitionLoc());
777e5dd7070Spatrick Record.push_back(Data.HasDesignatedInitializers);
778*12c85518Srobert Record.push_back(D->getODRHash());
779e5dd7070Spatrick
780e5dd7070Spatrick // Write out the protocols that are directly referenced by the @interface.
781e5dd7070Spatrick Record.push_back(Data.ReferencedProtocols.size());
782e5dd7070Spatrick for (const auto *P : D->protocols())
783e5dd7070Spatrick Record.AddDeclRef(P);
784e5dd7070Spatrick for (const auto &PL : D->protocol_locs())
785e5dd7070Spatrick Record.AddSourceLocation(PL);
786e5dd7070Spatrick
787e5dd7070Spatrick // Write out the protocols that are transitively referenced.
788e5dd7070Spatrick Record.push_back(Data.AllReferencedProtocols.size());
789e5dd7070Spatrick for (ObjCList<ObjCProtocolDecl>::iterator
790e5dd7070Spatrick P = Data.AllReferencedProtocols.begin(),
791e5dd7070Spatrick PEnd = Data.AllReferencedProtocols.end();
792e5dd7070Spatrick P != PEnd; ++P)
793e5dd7070Spatrick Record.AddDeclRef(*P);
794e5dd7070Spatrick
795e5dd7070Spatrick
796e5dd7070Spatrick if (ObjCCategoryDecl *Cat = D->getCategoryListRaw()) {
797e5dd7070Spatrick // Ensure that we write out the set of categories for this class.
798e5dd7070Spatrick Writer.ObjCClassesWithCategories.insert(D);
799e5dd7070Spatrick
800e5dd7070Spatrick // Make sure that the categories get serialized.
801e5dd7070Spatrick for (; Cat; Cat = Cat->getNextClassCategoryRaw())
802e5dd7070Spatrick (void)Writer.GetDeclRef(Cat);
803e5dd7070Spatrick }
804e5dd7070Spatrick }
805e5dd7070Spatrick
806e5dd7070Spatrick Code = serialization::DECL_OBJC_INTERFACE;
807e5dd7070Spatrick }
808e5dd7070Spatrick
VisitObjCIvarDecl(ObjCIvarDecl * D)809e5dd7070Spatrick void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
810e5dd7070Spatrick VisitFieldDecl(D);
811e5dd7070Spatrick // FIXME: stable encoding for @public/@private/@protected/@package
812e5dd7070Spatrick Record.push_back(D->getAccessControl());
813e5dd7070Spatrick Record.push_back(D->getSynthesize());
814e5dd7070Spatrick
815e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
816e5dd7070Spatrick !D->hasAttrs() &&
817e5dd7070Spatrick !D->isImplicit() &&
818e5dd7070Spatrick !D->isUsed(false) &&
819e5dd7070Spatrick !D->isInvalidDecl() &&
820e5dd7070Spatrick !D->isReferenced() &&
821e5dd7070Spatrick !D->isModulePrivate() &&
822e5dd7070Spatrick !D->getBitWidth() &&
823e5dd7070Spatrick !D->hasExtInfo() &&
824e5dd7070Spatrick D->getDeclName())
825e5dd7070Spatrick AbbrevToUse = Writer.getDeclObjCIvarAbbrev();
826e5dd7070Spatrick
827e5dd7070Spatrick Code = serialization::DECL_OBJC_IVAR;
828e5dd7070Spatrick }
829e5dd7070Spatrick
VisitObjCProtocolDecl(ObjCProtocolDecl * D)830e5dd7070Spatrick void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
831e5dd7070Spatrick VisitRedeclarable(D);
832e5dd7070Spatrick VisitObjCContainerDecl(D);
833e5dd7070Spatrick
834e5dd7070Spatrick Record.push_back(D->isThisDeclarationADefinition());
835e5dd7070Spatrick if (D->isThisDeclarationADefinition()) {
836e5dd7070Spatrick Record.push_back(D->protocol_size());
837e5dd7070Spatrick for (const auto *I : D->protocols())
838e5dd7070Spatrick Record.AddDeclRef(I);
839e5dd7070Spatrick for (const auto &PL : D->protocol_locs())
840e5dd7070Spatrick Record.AddSourceLocation(PL);
841*12c85518Srobert Record.push_back(D->getODRHash());
842e5dd7070Spatrick }
843e5dd7070Spatrick
844e5dd7070Spatrick Code = serialization::DECL_OBJC_PROTOCOL;
845e5dd7070Spatrick }
846e5dd7070Spatrick
VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl * D)847e5dd7070Spatrick void ASTDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
848e5dd7070Spatrick VisitFieldDecl(D);
849e5dd7070Spatrick Code = serialization::DECL_OBJC_AT_DEFS_FIELD;
850e5dd7070Spatrick }
851e5dd7070Spatrick
VisitObjCCategoryDecl(ObjCCategoryDecl * D)852e5dd7070Spatrick void ASTDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
853e5dd7070Spatrick VisitObjCContainerDecl(D);
854e5dd7070Spatrick Record.AddSourceLocation(D->getCategoryNameLoc());
855e5dd7070Spatrick Record.AddSourceLocation(D->getIvarLBraceLoc());
856e5dd7070Spatrick Record.AddSourceLocation(D->getIvarRBraceLoc());
857e5dd7070Spatrick Record.AddDeclRef(D->getClassInterface());
858e5dd7070Spatrick AddObjCTypeParamList(D->TypeParamList);
859e5dd7070Spatrick Record.push_back(D->protocol_size());
860e5dd7070Spatrick for (const auto *I : D->protocols())
861e5dd7070Spatrick Record.AddDeclRef(I);
862e5dd7070Spatrick for (const auto &PL : D->protocol_locs())
863e5dd7070Spatrick Record.AddSourceLocation(PL);
864e5dd7070Spatrick Code = serialization::DECL_OBJC_CATEGORY;
865e5dd7070Spatrick }
866e5dd7070Spatrick
VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl * D)867e5dd7070Spatrick void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
868e5dd7070Spatrick VisitNamedDecl(D);
869e5dd7070Spatrick Record.AddDeclRef(D->getClassInterface());
870e5dd7070Spatrick Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
871e5dd7070Spatrick }
872e5dd7070Spatrick
VisitObjCPropertyDecl(ObjCPropertyDecl * D)873e5dd7070Spatrick void ASTDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
874e5dd7070Spatrick VisitNamedDecl(D);
875e5dd7070Spatrick Record.AddSourceLocation(D->getAtLoc());
876e5dd7070Spatrick Record.AddSourceLocation(D->getLParenLoc());
877e5dd7070Spatrick Record.AddTypeRef(D->getType());
878e5dd7070Spatrick Record.AddTypeSourceInfo(D->getTypeSourceInfo());
879e5dd7070Spatrick // FIXME: stable encoding
880e5dd7070Spatrick Record.push_back((unsigned)D->getPropertyAttributes());
881e5dd7070Spatrick Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
882e5dd7070Spatrick // FIXME: stable encoding
883e5dd7070Spatrick Record.push_back((unsigned)D->getPropertyImplementation());
884e5dd7070Spatrick Record.AddDeclarationName(D->getGetterName());
885e5dd7070Spatrick Record.AddSourceLocation(D->getGetterNameLoc());
886e5dd7070Spatrick Record.AddDeclarationName(D->getSetterName());
887e5dd7070Spatrick Record.AddSourceLocation(D->getSetterNameLoc());
888e5dd7070Spatrick Record.AddDeclRef(D->getGetterMethodDecl());
889e5dd7070Spatrick Record.AddDeclRef(D->getSetterMethodDecl());
890e5dd7070Spatrick Record.AddDeclRef(D->getPropertyIvarDecl());
891e5dd7070Spatrick Code = serialization::DECL_OBJC_PROPERTY;
892e5dd7070Spatrick }
893e5dd7070Spatrick
VisitObjCImplDecl(ObjCImplDecl * D)894e5dd7070Spatrick void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
895e5dd7070Spatrick VisitObjCContainerDecl(D);
896e5dd7070Spatrick Record.AddDeclRef(D->getClassInterface());
897e5dd7070Spatrick // Abstract class (no need to define a stable serialization::DECL code).
898e5dd7070Spatrick }
899e5dd7070Spatrick
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)900e5dd7070Spatrick void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
901e5dd7070Spatrick VisitObjCImplDecl(D);
902e5dd7070Spatrick Record.AddSourceLocation(D->getCategoryNameLoc());
903e5dd7070Spatrick Code = serialization::DECL_OBJC_CATEGORY_IMPL;
904e5dd7070Spatrick }
905e5dd7070Spatrick
VisitObjCImplementationDecl(ObjCImplementationDecl * D)906e5dd7070Spatrick void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
907e5dd7070Spatrick VisitObjCImplDecl(D);
908e5dd7070Spatrick Record.AddDeclRef(D->getSuperClass());
909e5dd7070Spatrick Record.AddSourceLocation(D->getSuperClassLoc());
910e5dd7070Spatrick Record.AddSourceLocation(D->getIvarLBraceLoc());
911e5dd7070Spatrick Record.AddSourceLocation(D->getIvarRBraceLoc());
912e5dd7070Spatrick Record.push_back(D->hasNonZeroConstructors());
913e5dd7070Spatrick Record.push_back(D->hasDestructors());
914e5dd7070Spatrick Record.push_back(D->NumIvarInitializers);
915e5dd7070Spatrick if (D->NumIvarInitializers)
916e5dd7070Spatrick Record.AddCXXCtorInitializers(
917*12c85518Srobert llvm::ArrayRef(D->init_begin(), D->init_end()));
918e5dd7070Spatrick Code = serialization::DECL_OBJC_IMPLEMENTATION;
919e5dd7070Spatrick }
920e5dd7070Spatrick
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * D)921e5dd7070Spatrick void ASTDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
922e5dd7070Spatrick VisitDecl(D);
923e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
924e5dd7070Spatrick Record.AddDeclRef(D->getPropertyDecl());
925e5dd7070Spatrick Record.AddDeclRef(D->getPropertyIvarDecl());
926e5dd7070Spatrick Record.AddSourceLocation(D->getPropertyIvarDeclLoc());
927e5dd7070Spatrick Record.AddDeclRef(D->getGetterMethodDecl());
928e5dd7070Spatrick Record.AddDeclRef(D->getSetterMethodDecl());
929e5dd7070Spatrick Record.AddStmt(D->getGetterCXXConstructor());
930e5dd7070Spatrick Record.AddStmt(D->getSetterCXXAssignment());
931e5dd7070Spatrick Code = serialization::DECL_OBJC_PROPERTY_IMPL;
932e5dd7070Spatrick }
933e5dd7070Spatrick
VisitFieldDecl(FieldDecl * D)934e5dd7070Spatrick void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) {
935e5dd7070Spatrick VisitDeclaratorDecl(D);
936e5dd7070Spatrick Record.push_back(D->isMutable());
937e5dd7070Spatrick
938e5dd7070Spatrick FieldDecl::InitStorageKind ISK = D->InitStorage.getInt();
939e5dd7070Spatrick Record.push_back(ISK);
940e5dd7070Spatrick if (ISK == FieldDecl::ISK_CapturedVLAType)
941e5dd7070Spatrick Record.AddTypeRef(QualType(D->getCapturedVLAType(), 0));
942e5dd7070Spatrick else if (ISK)
943e5dd7070Spatrick Record.AddStmt(D->getInClassInitializer());
944e5dd7070Spatrick
945e5dd7070Spatrick Record.AddStmt(D->getBitWidth());
946e5dd7070Spatrick
947e5dd7070Spatrick if (!D->getDeclName())
948e5dd7070Spatrick Record.AddDeclRef(Context.getInstantiatedFromUnnamedFieldDecl(D));
949e5dd7070Spatrick
950e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
951e5dd7070Spatrick !D->hasAttrs() &&
952e5dd7070Spatrick !D->isImplicit() &&
953e5dd7070Spatrick !D->isUsed(false) &&
954e5dd7070Spatrick !D->isInvalidDecl() &&
955e5dd7070Spatrick !D->isReferenced() &&
956e5dd7070Spatrick !D->isTopLevelDeclInObjCContainer() &&
957e5dd7070Spatrick !D->isModulePrivate() &&
958e5dd7070Spatrick !D->getBitWidth() &&
959e5dd7070Spatrick !D->hasInClassInitializer() &&
960e5dd7070Spatrick !D->hasCapturedVLAType() &&
961e5dd7070Spatrick !D->hasExtInfo() &&
962e5dd7070Spatrick !ObjCIvarDecl::classofKind(D->getKind()) &&
963e5dd7070Spatrick !ObjCAtDefsFieldDecl::classofKind(D->getKind()) &&
964e5dd7070Spatrick D->getDeclName())
965e5dd7070Spatrick AbbrevToUse = Writer.getDeclFieldAbbrev();
966e5dd7070Spatrick
967e5dd7070Spatrick Code = serialization::DECL_FIELD;
968e5dd7070Spatrick }
969e5dd7070Spatrick
VisitMSPropertyDecl(MSPropertyDecl * D)970e5dd7070Spatrick void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) {
971e5dd7070Spatrick VisitDeclaratorDecl(D);
972e5dd7070Spatrick Record.AddIdentifierRef(D->getGetterId());
973e5dd7070Spatrick Record.AddIdentifierRef(D->getSetterId());
974e5dd7070Spatrick Code = serialization::DECL_MS_PROPERTY;
975e5dd7070Spatrick }
976e5dd7070Spatrick
VisitMSGuidDecl(MSGuidDecl * D)977ec727ea7Spatrick void ASTDeclWriter::VisitMSGuidDecl(MSGuidDecl *D) {
978ec727ea7Spatrick VisitValueDecl(D);
979ec727ea7Spatrick MSGuidDecl::Parts Parts = D->getParts();
980ec727ea7Spatrick Record.push_back(Parts.Part1);
981ec727ea7Spatrick Record.push_back(Parts.Part2);
982ec727ea7Spatrick Record.push_back(Parts.Part3);
983*12c85518Srobert Record.append(std::begin(Parts.Part4And5), std::end(Parts.Part4And5));
984ec727ea7Spatrick Code = serialization::DECL_MS_GUID;
985ec727ea7Spatrick }
986ec727ea7Spatrick
VisitUnnamedGlobalConstantDecl(UnnamedGlobalConstantDecl * D)987*12c85518Srobert void ASTDeclWriter::VisitUnnamedGlobalConstantDecl(
988*12c85518Srobert UnnamedGlobalConstantDecl *D) {
989*12c85518Srobert VisitValueDecl(D);
990*12c85518Srobert Record.AddAPValue(D->getValue());
991*12c85518Srobert Code = serialization::DECL_UNNAMED_GLOBAL_CONSTANT;
992*12c85518Srobert }
993*12c85518Srobert
VisitTemplateParamObjectDecl(TemplateParamObjectDecl * D)994a9ac8606Spatrick void ASTDeclWriter::VisitTemplateParamObjectDecl(TemplateParamObjectDecl *D) {
995a9ac8606Spatrick VisitValueDecl(D);
996a9ac8606Spatrick Record.AddAPValue(D->getValue());
997a9ac8606Spatrick Code = serialization::DECL_TEMPLATE_PARAM_OBJECT;
998a9ac8606Spatrick }
999a9ac8606Spatrick
VisitIndirectFieldDecl(IndirectFieldDecl * D)1000e5dd7070Spatrick void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
1001e5dd7070Spatrick VisitValueDecl(D);
1002e5dd7070Spatrick Record.push_back(D->getChainingSize());
1003e5dd7070Spatrick
1004e5dd7070Spatrick for (const auto *P : D->chain())
1005e5dd7070Spatrick Record.AddDeclRef(P);
1006e5dd7070Spatrick Code = serialization::DECL_INDIRECTFIELD;
1007e5dd7070Spatrick }
1008e5dd7070Spatrick
VisitVarDecl(VarDecl * D)1009e5dd7070Spatrick void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
1010e5dd7070Spatrick VisitRedeclarable(D);
1011e5dd7070Spatrick VisitDeclaratorDecl(D);
1012e5dd7070Spatrick Record.push_back(D->getStorageClass());
1013e5dd7070Spatrick Record.push_back(D->getTSCSpec());
1014e5dd7070Spatrick Record.push_back(D->getInitStyle());
1015e5dd7070Spatrick Record.push_back(D->isARCPseudoStrong());
1016e5dd7070Spatrick if (!isa<ParmVarDecl>(D)) {
1017e5dd7070Spatrick Record.push_back(D->isThisDeclarationADemotedDefinition());
1018e5dd7070Spatrick Record.push_back(D->isExceptionVariable());
1019e5dd7070Spatrick Record.push_back(D->isNRVOVariable());
1020e5dd7070Spatrick Record.push_back(D->isCXXForRangeDecl());
1021e5dd7070Spatrick Record.push_back(D->isObjCForDecl());
1022e5dd7070Spatrick Record.push_back(D->isInline());
1023e5dd7070Spatrick Record.push_back(D->isInlineSpecified());
1024e5dd7070Spatrick Record.push_back(D->isConstexpr());
1025e5dd7070Spatrick Record.push_back(D->isInitCapture());
1026e5dd7070Spatrick Record.push_back(D->isPreviousDeclInSameBlockScope());
1027e5dd7070Spatrick if (const auto *IPD = dyn_cast<ImplicitParamDecl>(D))
1028e5dd7070Spatrick Record.push_back(static_cast<unsigned>(IPD->getParameterKind()));
1029e5dd7070Spatrick else
1030e5dd7070Spatrick Record.push_back(0);
1031e5dd7070Spatrick Record.push_back(D->isEscapingByref());
1032e5dd7070Spatrick }
1033e5dd7070Spatrick Record.push_back(D->getLinkageInternal());
1034e5dd7070Spatrick
1035a9ac8606Spatrick Record.AddVarDeclInit(D);
1036e5dd7070Spatrick
1037e5dd7070Spatrick if (D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) {
1038e5dd7070Spatrick BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
1039e5dd7070Spatrick Record.AddStmt(Init.getCopyExpr());
1040e5dd7070Spatrick if (Init.getCopyExpr())
1041e5dd7070Spatrick Record.push_back(Init.canThrow());
1042e5dd7070Spatrick }
1043e5dd7070Spatrick
1044e5dd7070Spatrick if (D->getStorageDuration() == SD_Static) {
1045e5dd7070Spatrick bool ModulesCodegen = false;
1046e5dd7070Spatrick if (Writer.WritingModule &&
1047*12c85518Srobert !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo()) {
1048*12c85518Srobert // When building a C++20 module interface unit or a partition unit, a
1049*12c85518Srobert // strong definition in the module interface is provided by the
1050*12c85518Srobert // compilation of that unit, not by its users. (Inline variables are still
1051*12c85518Srobert // emitted in module users.)
1052e5dd7070Spatrick ModulesCodegen =
1053*12c85518Srobert (Writer.WritingModule->isInterfaceOrPartition() ||
1054a9ac8606Spatrick (D->hasAttr<DLLExportAttr>() &&
1055a9ac8606Spatrick Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
1056a9ac8606Spatrick Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
1057e5dd7070Spatrick }
1058e5dd7070Spatrick Record.push_back(ModulesCodegen);
1059e5dd7070Spatrick if (ModulesCodegen)
1060e5dd7070Spatrick Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
1061e5dd7070Spatrick }
1062e5dd7070Spatrick
1063e5dd7070Spatrick enum {
1064e5dd7070Spatrick VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
1065e5dd7070Spatrick };
1066e5dd7070Spatrick if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) {
1067e5dd7070Spatrick Record.push_back(VarTemplate);
1068e5dd7070Spatrick Record.AddDeclRef(TemplD);
1069e5dd7070Spatrick } else if (MemberSpecializationInfo *SpecInfo
1070e5dd7070Spatrick = D->getMemberSpecializationInfo()) {
1071e5dd7070Spatrick Record.push_back(StaticDataMemberSpecialization);
1072e5dd7070Spatrick Record.AddDeclRef(SpecInfo->getInstantiatedFrom());
1073e5dd7070Spatrick Record.push_back(SpecInfo->getTemplateSpecializationKind());
1074e5dd7070Spatrick Record.AddSourceLocation(SpecInfo->getPointOfInstantiation());
1075e5dd7070Spatrick } else {
1076e5dd7070Spatrick Record.push_back(VarNotTemplate);
1077e5dd7070Spatrick }
1078e5dd7070Spatrick
1079e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
1080e5dd7070Spatrick !D->hasAttrs() &&
1081e5dd7070Spatrick !D->isImplicit() &&
1082e5dd7070Spatrick !D->isUsed(false) &&
1083e5dd7070Spatrick !D->isInvalidDecl() &&
1084e5dd7070Spatrick !D->isReferenced() &&
1085e5dd7070Spatrick !D->isTopLevelDeclInObjCContainer() &&
1086e5dd7070Spatrick D->getAccess() == AS_none &&
1087e5dd7070Spatrick !D->isModulePrivate() &&
1088e5dd7070Spatrick !needsAnonymousDeclarationNumber(D) &&
1089e5dd7070Spatrick D->getDeclName().getNameKind() == DeclarationName::Identifier &&
1090e5dd7070Spatrick !D->hasExtInfo() &&
1091e5dd7070Spatrick D->getFirstDecl() == D->getMostRecentDecl() &&
1092e5dd7070Spatrick D->getKind() == Decl::Var &&
1093e5dd7070Spatrick !D->isInline() &&
1094e5dd7070Spatrick !D->isConstexpr() &&
1095e5dd7070Spatrick !D->isInitCapture() &&
1096e5dd7070Spatrick !D->isPreviousDeclInSameBlockScope() &&
1097e5dd7070Spatrick !(D->hasAttr<BlocksAttr>() && D->getType()->getAsCXXRecordDecl()) &&
1098e5dd7070Spatrick !D->isEscapingByref() &&
1099e5dd7070Spatrick D->getStorageDuration() != SD_Static &&
1100e5dd7070Spatrick !D->getMemberSpecializationInfo())
1101e5dd7070Spatrick AbbrevToUse = Writer.getDeclVarAbbrev();
1102e5dd7070Spatrick
1103e5dd7070Spatrick Code = serialization::DECL_VAR;
1104e5dd7070Spatrick }
1105e5dd7070Spatrick
VisitImplicitParamDecl(ImplicitParamDecl * D)1106e5dd7070Spatrick void ASTDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
1107e5dd7070Spatrick VisitVarDecl(D);
1108e5dd7070Spatrick Code = serialization::DECL_IMPLICIT_PARAM;
1109e5dd7070Spatrick }
1110e5dd7070Spatrick
VisitParmVarDecl(ParmVarDecl * D)1111e5dd7070Spatrick void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
1112e5dd7070Spatrick VisitVarDecl(D);
1113e5dd7070Spatrick Record.push_back(D->isObjCMethodParameter());
1114e5dd7070Spatrick Record.push_back(D->getFunctionScopeDepth());
1115e5dd7070Spatrick Record.push_back(D->getFunctionScopeIndex());
1116e5dd7070Spatrick Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
1117e5dd7070Spatrick Record.push_back(D->isKNRPromoted());
1118e5dd7070Spatrick Record.push_back(D->hasInheritedDefaultArg());
1119e5dd7070Spatrick Record.push_back(D->hasUninstantiatedDefaultArg());
1120e5dd7070Spatrick if (D->hasUninstantiatedDefaultArg())
1121e5dd7070Spatrick Record.AddStmt(D->getUninstantiatedDefaultArg());
1122e5dd7070Spatrick Code = serialization::DECL_PARM_VAR;
1123e5dd7070Spatrick
1124e5dd7070Spatrick // If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here
1125e5dd7070Spatrick // we dynamically check for the properties that we optimize for, but don't
1126e5dd7070Spatrick // know are true of all PARM_VAR_DECLs.
1127e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
1128e5dd7070Spatrick !D->hasAttrs() &&
1129e5dd7070Spatrick !D->hasExtInfo() &&
1130e5dd7070Spatrick !D->isImplicit() &&
1131e5dd7070Spatrick !D->isUsed(false) &&
1132e5dd7070Spatrick !D->isInvalidDecl() &&
1133e5dd7070Spatrick !D->isReferenced() &&
1134e5dd7070Spatrick D->getAccess() == AS_none &&
1135e5dd7070Spatrick !D->isModulePrivate() &&
1136e5dd7070Spatrick D->getStorageClass() == 0 &&
1137e5dd7070Spatrick D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
1138e5dd7070Spatrick D->getFunctionScopeDepth() == 0 &&
1139e5dd7070Spatrick D->getObjCDeclQualifier() == 0 &&
1140e5dd7070Spatrick !D->isKNRPromoted() &&
1141e5dd7070Spatrick !D->hasInheritedDefaultArg() &&
1142e5dd7070Spatrick D->getInit() == nullptr &&
1143e5dd7070Spatrick !D->hasUninstantiatedDefaultArg()) // No default expr.
1144e5dd7070Spatrick AbbrevToUse = Writer.getDeclParmVarAbbrev();
1145e5dd7070Spatrick
1146e5dd7070Spatrick // Check things we know are true of *every* PARM_VAR_DECL, which is more than
1147e5dd7070Spatrick // just us assuming it.
1148e5dd7070Spatrick assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
1149e5dd7070Spatrick assert(!D->isThisDeclarationADemotedDefinition()
1150e5dd7070Spatrick && "PARM_VAR_DECL can't be demoted definition.");
1151e5dd7070Spatrick assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
1152e5dd7070Spatrick assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
1153e5dd7070Spatrick assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
1154e5dd7070Spatrick assert(!D->isStaticDataMember() &&
1155e5dd7070Spatrick "PARM_VAR_DECL can't be static data member");
1156e5dd7070Spatrick }
1157e5dd7070Spatrick
VisitDecompositionDecl(DecompositionDecl * D)1158e5dd7070Spatrick void ASTDeclWriter::VisitDecompositionDecl(DecompositionDecl *D) {
1159e5dd7070Spatrick // Record the number of bindings first to simplify deserialization.
1160e5dd7070Spatrick Record.push_back(D->bindings().size());
1161e5dd7070Spatrick
1162e5dd7070Spatrick VisitVarDecl(D);
1163e5dd7070Spatrick for (auto *B : D->bindings())
1164e5dd7070Spatrick Record.AddDeclRef(B);
1165e5dd7070Spatrick Code = serialization::DECL_DECOMPOSITION;
1166e5dd7070Spatrick }
1167e5dd7070Spatrick
VisitBindingDecl(BindingDecl * D)1168e5dd7070Spatrick void ASTDeclWriter::VisitBindingDecl(BindingDecl *D) {
1169e5dd7070Spatrick VisitValueDecl(D);
1170e5dd7070Spatrick Record.AddStmt(D->getBinding());
1171e5dd7070Spatrick Code = serialization::DECL_BINDING;
1172e5dd7070Spatrick }
1173e5dd7070Spatrick
VisitFileScopeAsmDecl(FileScopeAsmDecl * D)1174e5dd7070Spatrick void ASTDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
1175e5dd7070Spatrick VisitDecl(D);
1176e5dd7070Spatrick Record.AddStmt(D->getAsmString());
1177e5dd7070Spatrick Record.AddSourceLocation(D->getRParenLoc());
1178e5dd7070Spatrick Code = serialization::DECL_FILE_SCOPE_ASM;
1179e5dd7070Spatrick }
1180e5dd7070Spatrick
VisitTopLevelStmtDecl(TopLevelStmtDecl * D)1181*12c85518Srobert void ASTDeclWriter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
1182*12c85518Srobert VisitDecl(D);
1183*12c85518Srobert Record.AddStmt(D->getStmt());
1184*12c85518Srobert Code = serialization::DECL_TOP_LEVEL_STMT_DECL;
1185*12c85518Srobert }
1186*12c85518Srobert
VisitEmptyDecl(EmptyDecl * D)1187e5dd7070Spatrick void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
1188e5dd7070Spatrick VisitDecl(D);
1189e5dd7070Spatrick Code = serialization::DECL_EMPTY;
1190e5dd7070Spatrick }
1191e5dd7070Spatrick
VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl * D)1192e5dd7070Spatrick void ASTDeclWriter::VisitLifetimeExtendedTemporaryDecl(
1193e5dd7070Spatrick LifetimeExtendedTemporaryDecl *D) {
1194e5dd7070Spatrick VisitDecl(D);
1195e5dd7070Spatrick Record.AddDeclRef(D->getExtendingDecl());
1196e5dd7070Spatrick Record.AddStmt(D->getTemporaryExpr());
1197e5dd7070Spatrick Record.push_back(static_cast<bool>(D->getValue()));
1198e5dd7070Spatrick if (D->getValue())
1199e5dd7070Spatrick Record.AddAPValue(*D->getValue());
1200e5dd7070Spatrick Record.push_back(D->getManglingNumber());
1201e5dd7070Spatrick Code = serialization::DECL_LIFETIME_EXTENDED_TEMPORARY;
1202e5dd7070Spatrick }
VisitBlockDecl(BlockDecl * D)1203e5dd7070Spatrick void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
1204e5dd7070Spatrick VisitDecl(D);
1205e5dd7070Spatrick Record.AddStmt(D->getBody());
1206e5dd7070Spatrick Record.AddTypeSourceInfo(D->getSignatureAsWritten());
1207e5dd7070Spatrick Record.push_back(D->param_size());
1208e5dd7070Spatrick for (ParmVarDecl *P : D->parameters())
1209e5dd7070Spatrick Record.AddDeclRef(P);
1210e5dd7070Spatrick Record.push_back(D->isVariadic());
1211e5dd7070Spatrick Record.push_back(D->blockMissingReturnType());
1212e5dd7070Spatrick Record.push_back(D->isConversionFromLambda());
1213e5dd7070Spatrick Record.push_back(D->doesNotEscape());
1214e5dd7070Spatrick Record.push_back(D->canAvoidCopyToHeap());
1215e5dd7070Spatrick Record.push_back(D->capturesCXXThis());
1216e5dd7070Spatrick Record.push_back(D->getNumCaptures());
1217e5dd7070Spatrick for (const auto &capture : D->captures()) {
1218e5dd7070Spatrick Record.AddDeclRef(capture.getVariable());
1219e5dd7070Spatrick
1220e5dd7070Spatrick unsigned flags = 0;
1221e5dd7070Spatrick if (capture.isByRef()) flags |= 1;
1222e5dd7070Spatrick if (capture.isNested()) flags |= 2;
1223e5dd7070Spatrick if (capture.hasCopyExpr()) flags |= 4;
1224e5dd7070Spatrick Record.push_back(flags);
1225e5dd7070Spatrick
1226e5dd7070Spatrick if (capture.hasCopyExpr()) Record.AddStmt(capture.getCopyExpr());
1227e5dd7070Spatrick }
1228e5dd7070Spatrick
1229e5dd7070Spatrick Code = serialization::DECL_BLOCK;
1230e5dd7070Spatrick }
1231e5dd7070Spatrick
VisitCapturedDecl(CapturedDecl * CD)1232e5dd7070Spatrick void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
1233e5dd7070Spatrick Record.push_back(CD->getNumParams());
1234e5dd7070Spatrick VisitDecl(CD);
1235e5dd7070Spatrick Record.push_back(CD->getContextParamPosition());
1236e5dd7070Spatrick Record.push_back(CD->isNothrow() ? 1 : 0);
1237e5dd7070Spatrick // Body is stored by VisitCapturedStmt.
1238e5dd7070Spatrick for (unsigned I = 0; I < CD->getNumParams(); ++I)
1239e5dd7070Spatrick Record.AddDeclRef(CD->getParam(I));
1240e5dd7070Spatrick Code = serialization::DECL_CAPTURED;
1241e5dd7070Spatrick }
1242e5dd7070Spatrick
VisitLinkageSpecDecl(LinkageSpecDecl * D)1243e5dd7070Spatrick void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1244e5dd7070Spatrick VisitDecl(D);
1245e5dd7070Spatrick Record.push_back(D->getLanguage());
1246e5dd7070Spatrick Record.AddSourceLocation(D->getExternLoc());
1247e5dd7070Spatrick Record.AddSourceLocation(D->getRBraceLoc());
1248e5dd7070Spatrick Code = serialization::DECL_LINKAGE_SPEC;
1249e5dd7070Spatrick }
1250e5dd7070Spatrick
VisitExportDecl(ExportDecl * D)1251e5dd7070Spatrick void ASTDeclWriter::VisitExportDecl(ExportDecl *D) {
1252e5dd7070Spatrick VisitDecl(D);
1253e5dd7070Spatrick Record.AddSourceLocation(D->getRBraceLoc());
1254e5dd7070Spatrick Code = serialization::DECL_EXPORT;
1255e5dd7070Spatrick }
1256e5dd7070Spatrick
VisitLabelDecl(LabelDecl * D)1257e5dd7070Spatrick void ASTDeclWriter::VisitLabelDecl(LabelDecl *D) {
1258e5dd7070Spatrick VisitNamedDecl(D);
1259e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
1260e5dd7070Spatrick Code = serialization::DECL_LABEL;
1261e5dd7070Spatrick }
1262e5dd7070Spatrick
1263e5dd7070Spatrick
VisitNamespaceDecl(NamespaceDecl * D)1264e5dd7070Spatrick void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
1265e5dd7070Spatrick VisitRedeclarable(D);
1266e5dd7070Spatrick VisitNamedDecl(D);
1267e5dd7070Spatrick Record.push_back(D->isInline());
1268*12c85518Srobert Record.push_back(D->isNested());
1269e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
1270e5dd7070Spatrick Record.AddSourceLocation(D->getRBraceLoc());
1271e5dd7070Spatrick
1272e5dd7070Spatrick if (D->isOriginalNamespace())
1273e5dd7070Spatrick Record.AddDeclRef(D->getAnonymousNamespace());
1274e5dd7070Spatrick Code = serialization::DECL_NAMESPACE;
1275e5dd7070Spatrick
1276e5dd7070Spatrick if (Writer.hasChain() && D->isAnonymousNamespace() &&
1277e5dd7070Spatrick D == D->getMostRecentDecl()) {
1278e5dd7070Spatrick // This is a most recent reopening of the anonymous namespace. If its parent
1279e5dd7070Spatrick // is in a previous PCH (or is the TU), mark that parent for update, because
1280e5dd7070Spatrick // the original namespace always points to the latest re-opening of its
1281e5dd7070Spatrick // anonymous namespace.
1282e5dd7070Spatrick Decl *Parent = cast<Decl>(
1283e5dd7070Spatrick D->getParent()->getRedeclContext()->getPrimaryContext());
1284e5dd7070Spatrick if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
1285e5dd7070Spatrick Writer.DeclUpdates[Parent].push_back(
1286e5dd7070Spatrick ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
1287e5dd7070Spatrick }
1288e5dd7070Spatrick }
1289e5dd7070Spatrick }
1290e5dd7070Spatrick
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1291e5dd7070Spatrick void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1292e5dd7070Spatrick VisitRedeclarable(D);
1293e5dd7070Spatrick VisitNamedDecl(D);
1294e5dd7070Spatrick Record.AddSourceLocation(D->getNamespaceLoc());
1295e5dd7070Spatrick Record.AddSourceLocation(D->getTargetNameLoc());
1296e5dd7070Spatrick Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
1297e5dd7070Spatrick Record.AddDeclRef(D->getNamespace());
1298e5dd7070Spatrick Code = serialization::DECL_NAMESPACE_ALIAS;
1299e5dd7070Spatrick }
1300e5dd7070Spatrick
VisitUsingDecl(UsingDecl * D)1301e5dd7070Spatrick void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
1302e5dd7070Spatrick VisitNamedDecl(D);
1303e5dd7070Spatrick Record.AddSourceLocation(D->getUsingLoc());
1304e5dd7070Spatrick Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
1305e5dd7070Spatrick Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
1306e5dd7070Spatrick Record.AddDeclRef(D->FirstUsingShadow.getPointer());
1307e5dd7070Spatrick Record.push_back(D->hasTypename());
1308e5dd7070Spatrick Record.AddDeclRef(Context.getInstantiatedFromUsingDecl(D));
1309e5dd7070Spatrick Code = serialization::DECL_USING;
1310e5dd7070Spatrick }
1311e5dd7070Spatrick
VisitUsingEnumDecl(UsingEnumDecl * D)1312a9ac8606Spatrick void ASTDeclWriter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1313a9ac8606Spatrick VisitNamedDecl(D);
1314a9ac8606Spatrick Record.AddSourceLocation(D->getUsingLoc());
1315a9ac8606Spatrick Record.AddSourceLocation(D->getEnumLoc());
1316*12c85518Srobert Record.AddTypeSourceInfo(D->getEnumType());
1317a9ac8606Spatrick Record.AddDeclRef(D->FirstUsingShadow.getPointer());
1318a9ac8606Spatrick Record.AddDeclRef(Context.getInstantiatedFromUsingEnumDecl(D));
1319a9ac8606Spatrick Code = serialization::DECL_USING_ENUM;
1320a9ac8606Spatrick }
1321a9ac8606Spatrick
VisitUsingPackDecl(UsingPackDecl * D)1322e5dd7070Spatrick void ASTDeclWriter::VisitUsingPackDecl(UsingPackDecl *D) {
1323e5dd7070Spatrick Record.push_back(D->NumExpansions);
1324e5dd7070Spatrick VisitNamedDecl(D);
1325e5dd7070Spatrick Record.AddDeclRef(D->getInstantiatedFromUsingDecl());
1326e5dd7070Spatrick for (auto *E : D->expansions())
1327e5dd7070Spatrick Record.AddDeclRef(E);
1328e5dd7070Spatrick Code = serialization::DECL_USING_PACK;
1329e5dd7070Spatrick }
1330e5dd7070Spatrick
VisitUsingShadowDecl(UsingShadowDecl * D)1331e5dd7070Spatrick void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1332e5dd7070Spatrick VisitRedeclarable(D);
1333e5dd7070Spatrick VisitNamedDecl(D);
1334e5dd7070Spatrick Record.AddDeclRef(D->getTargetDecl());
1335e5dd7070Spatrick Record.push_back(D->getIdentifierNamespace());
1336e5dd7070Spatrick Record.AddDeclRef(D->UsingOrNextShadow);
1337e5dd7070Spatrick Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D));
1338e5dd7070Spatrick Code = serialization::DECL_USING_SHADOW;
1339e5dd7070Spatrick }
1340e5dd7070Spatrick
VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl * D)1341e5dd7070Spatrick void ASTDeclWriter::VisitConstructorUsingShadowDecl(
1342e5dd7070Spatrick ConstructorUsingShadowDecl *D) {
1343e5dd7070Spatrick VisitUsingShadowDecl(D);
1344e5dd7070Spatrick Record.AddDeclRef(D->NominatedBaseClassShadowDecl);
1345e5dd7070Spatrick Record.AddDeclRef(D->ConstructedBaseClassShadowDecl);
1346e5dd7070Spatrick Record.push_back(D->IsVirtual);
1347e5dd7070Spatrick Code = serialization::DECL_CONSTRUCTOR_USING_SHADOW;
1348e5dd7070Spatrick }
1349e5dd7070Spatrick
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1350e5dd7070Spatrick void ASTDeclWriter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1351e5dd7070Spatrick VisitNamedDecl(D);
1352e5dd7070Spatrick Record.AddSourceLocation(D->getUsingLoc());
1353e5dd7070Spatrick Record.AddSourceLocation(D->getNamespaceKeyLocation());
1354e5dd7070Spatrick Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
1355e5dd7070Spatrick Record.AddDeclRef(D->getNominatedNamespace());
1356e5dd7070Spatrick Record.AddDeclRef(dyn_cast<Decl>(D->getCommonAncestor()));
1357e5dd7070Spatrick Code = serialization::DECL_USING_DIRECTIVE;
1358e5dd7070Spatrick }
1359e5dd7070Spatrick
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1360e5dd7070Spatrick void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1361e5dd7070Spatrick VisitValueDecl(D);
1362e5dd7070Spatrick Record.AddSourceLocation(D->getUsingLoc());
1363e5dd7070Spatrick Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
1364e5dd7070Spatrick Record.AddDeclarationNameLoc(D->DNLoc, D->getDeclName());
1365e5dd7070Spatrick Record.AddSourceLocation(D->getEllipsisLoc());
1366e5dd7070Spatrick Code = serialization::DECL_UNRESOLVED_USING_VALUE;
1367e5dd7070Spatrick }
1368e5dd7070Spatrick
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1369e5dd7070Spatrick void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
1370e5dd7070Spatrick UnresolvedUsingTypenameDecl *D) {
1371e5dd7070Spatrick VisitTypeDecl(D);
1372e5dd7070Spatrick Record.AddSourceLocation(D->getTypenameLoc());
1373e5dd7070Spatrick Record.AddNestedNameSpecifierLoc(D->getQualifierLoc());
1374e5dd7070Spatrick Record.AddSourceLocation(D->getEllipsisLoc());
1375e5dd7070Spatrick Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
1376e5dd7070Spatrick }
1377e5dd7070Spatrick
VisitUnresolvedUsingIfExistsDecl(UnresolvedUsingIfExistsDecl * D)1378a9ac8606Spatrick void ASTDeclWriter::VisitUnresolvedUsingIfExistsDecl(
1379a9ac8606Spatrick UnresolvedUsingIfExistsDecl *D) {
1380a9ac8606Spatrick VisitNamedDecl(D);
1381a9ac8606Spatrick Code = serialization::DECL_UNRESOLVED_USING_IF_EXISTS;
1382a9ac8606Spatrick }
1383a9ac8606Spatrick
VisitCXXRecordDecl(CXXRecordDecl * D)1384e5dd7070Spatrick void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
1385e5dd7070Spatrick VisitRecordDecl(D);
1386e5dd7070Spatrick
1387e5dd7070Spatrick enum {
1388e5dd7070Spatrick CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
1389e5dd7070Spatrick };
1390e5dd7070Spatrick if (ClassTemplateDecl *TemplD = D->getDescribedClassTemplate()) {
1391e5dd7070Spatrick Record.push_back(CXXRecTemplate);
1392e5dd7070Spatrick Record.AddDeclRef(TemplD);
1393e5dd7070Spatrick } else if (MemberSpecializationInfo *MSInfo
1394e5dd7070Spatrick = D->getMemberSpecializationInfo()) {
1395e5dd7070Spatrick Record.push_back(CXXRecMemberSpecialization);
1396e5dd7070Spatrick Record.AddDeclRef(MSInfo->getInstantiatedFrom());
1397e5dd7070Spatrick Record.push_back(MSInfo->getTemplateSpecializationKind());
1398e5dd7070Spatrick Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
1399e5dd7070Spatrick } else {
1400e5dd7070Spatrick Record.push_back(CXXRecNotTemplate);
1401e5dd7070Spatrick }
1402e5dd7070Spatrick
1403e5dd7070Spatrick Record.push_back(D->isThisDeclarationADefinition());
1404e5dd7070Spatrick if (D->isThisDeclarationADefinition())
1405e5dd7070Spatrick Record.AddCXXDefinitionData(D);
1406e5dd7070Spatrick
1407e5dd7070Spatrick // Store (what we currently believe to be) the key function to avoid
1408e5dd7070Spatrick // deserializing every method so we can compute it.
1409e5dd7070Spatrick if (D->isCompleteDefinition())
1410e5dd7070Spatrick Record.AddDeclRef(Context.getCurrentKeyFunction(D));
1411e5dd7070Spatrick
1412e5dd7070Spatrick Code = serialization::DECL_CXX_RECORD;
1413e5dd7070Spatrick }
1414e5dd7070Spatrick
VisitCXXMethodDecl(CXXMethodDecl * D)1415e5dd7070Spatrick void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
1416e5dd7070Spatrick VisitFunctionDecl(D);
1417e5dd7070Spatrick if (D->isCanonicalDecl()) {
1418e5dd7070Spatrick Record.push_back(D->size_overridden_methods());
1419e5dd7070Spatrick for (const CXXMethodDecl *MD : D->overridden_methods())
1420e5dd7070Spatrick Record.AddDeclRef(MD);
1421e5dd7070Spatrick } else {
1422e5dd7070Spatrick // We only need to record overridden methods once for the canonical decl.
1423e5dd7070Spatrick Record.push_back(0);
1424e5dd7070Spatrick }
1425e5dd7070Spatrick
1426e5dd7070Spatrick if (D->getDeclContext() == D->getLexicalDeclContext() &&
1427*12c85518Srobert D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
1428*12c85518Srobert !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
1429e5dd7070Spatrick D->getDeclName().getNameKind() == DeclarationName::Identifier &&
1430*12c85518Srobert !D->hasExtInfo() && !D->hasInheritedPrototype() &&
1431*12c85518Srobert D->hasWrittenPrototype() &&
1432*12c85518Srobert D->getTemplatedKind() == FunctionDecl::TK_NonTemplate)
1433e5dd7070Spatrick AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
1434e5dd7070Spatrick
1435e5dd7070Spatrick Code = serialization::DECL_CXX_METHOD;
1436e5dd7070Spatrick }
1437e5dd7070Spatrick
VisitCXXConstructorDecl(CXXConstructorDecl * D)1438e5dd7070Spatrick void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1439a9ac8606Spatrick Record.push_back(D->getTrailingAllocKind());
1440e5dd7070Spatrick addExplicitSpecifier(D->getExplicitSpecifier(), Record);
1441e5dd7070Spatrick if (auto Inherited = D->getInheritedConstructor()) {
1442e5dd7070Spatrick Record.AddDeclRef(Inherited.getShadowDecl());
1443e5dd7070Spatrick Record.AddDeclRef(Inherited.getConstructor());
1444e5dd7070Spatrick }
1445e5dd7070Spatrick
1446e5dd7070Spatrick VisitCXXMethodDecl(D);
1447e5dd7070Spatrick Code = serialization::DECL_CXX_CONSTRUCTOR;
1448e5dd7070Spatrick }
1449e5dd7070Spatrick
VisitCXXDestructorDecl(CXXDestructorDecl * D)1450e5dd7070Spatrick void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
1451e5dd7070Spatrick VisitCXXMethodDecl(D);
1452e5dd7070Spatrick
1453e5dd7070Spatrick Record.AddDeclRef(D->getOperatorDelete());
1454e5dd7070Spatrick if (D->getOperatorDelete())
1455e5dd7070Spatrick Record.AddStmt(D->getOperatorDeleteThisArg());
1456e5dd7070Spatrick
1457e5dd7070Spatrick Code = serialization::DECL_CXX_DESTRUCTOR;
1458e5dd7070Spatrick }
1459e5dd7070Spatrick
VisitCXXConversionDecl(CXXConversionDecl * D)1460e5dd7070Spatrick void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
1461e5dd7070Spatrick addExplicitSpecifier(D->getExplicitSpecifier(), Record);
1462e5dd7070Spatrick VisitCXXMethodDecl(D);
1463e5dd7070Spatrick Code = serialization::DECL_CXX_CONVERSION;
1464e5dd7070Spatrick }
1465e5dd7070Spatrick
VisitImportDecl(ImportDecl * D)1466e5dd7070Spatrick void ASTDeclWriter::VisitImportDecl(ImportDecl *D) {
1467e5dd7070Spatrick VisitDecl(D);
1468e5dd7070Spatrick Record.push_back(Writer.getSubmoduleID(D->getImportedModule()));
1469e5dd7070Spatrick ArrayRef<SourceLocation> IdentifierLocs = D->getIdentifierLocs();
1470e5dd7070Spatrick Record.push_back(!IdentifierLocs.empty());
1471e5dd7070Spatrick if (IdentifierLocs.empty()) {
1472e5dd7070Spatrick Record.AddSourceLocation(D->getEndLoc());
1473e5dd7070Spatrick Record.push_back(1);
1474e5dd7070Spatrick } else {
1475e5dd7070Spatrick for (unsigned I = 0, N = IdentifierLocs.size(); I != N; ++I)
1476e5dd7070Spatrick Record.AddSourceLocation(IdentifierLocs[I]);
1477e5dd7070Spatrick Record.push_back(IdentifierLocs.size());
1478e5dd7070Spatrick }
1479e5dd7070Spatrick // Note: the number of source locations must always be the last element in
1480e5dd7070Spatrick // the record.
1481e5dd7070Spatrick Code = serialization::DECL_IMPORT;
1482e5dd7070Spatrick }
1483e5dd7070Spatrick
VisitAccessSpecDecl(AccessSpecDecl * D)1484e5dd7070Spatrick void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
1485e5dd7070Spatrick VisitDecl(D);
1486e5dd7070Spatrick Record.AddSourceLocation(D->getColonLoc());
1487e5dd7070Spatrick Code = serialization::DECL_ACCESS_SPEC;
1488e5dd7070Spatrick }
1489e5dd7070Spatrick
VisitFriendDecl(FriendDecl * D)1490e5dd7070Spatrick void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
1491e5dd7070Spatrick // Record the number of friend type template parameter lists here
1492e5dd7070Spatrick // so as to simplify memory allocation during deserialization.
1493e5dd7070Spatrick Record.push_back(D->NumTPLists);
1494e5dd7070Spatrick VisitDecl(D);
1495e5dd7070Spatrick bool hasFriendDecl = D->Friend.is<NamedDecl*>();
1496e5dd7070Spatrick Record.push_back(hasFriendDecl);
1497e5dd7070Spatrick if (hasFriendDecl)
1498e5dd7070Spatrick Record.AddDeclRef(D->getFriendDecl());
1499e5dd7070Spatrick else
1500e5dd7070Spatrick Record.AddTypeSourceInfo(D->getFriendType());
1501e5dd7070Spatrick for (unsigned i = 0; i < D->NumTPLists; ++i)
1502e5dd7070Spatrick Record.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i));
1503e5dd7070Spatrick Record.AddDeclRef(D->getNextFriend());
1504e5dd7070Spatrick Record.push_back(D->UnsupportedFriend);
1505e5dd7070Spatrick Record.AddSourceLocation(D->FriendLoc);
1506e5dd7070Spatrick Code = serialization::DECL_FRIEND;
1507e5dd7070Spatrick }
1508e5dd7070Spatrick
VisitFriendTemplateDecl(FriendTemplateDecl * D)1509e5dd7070Spatrick void ASTDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
1510e5dd7070Spatrick VisitDecl(D);
1511e5dd7070Spatrick Record.push_back(D->getNumTemplateParameters());
1512e5dd7070Spatrick for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
1513e5dd7070Spatrick Record.AddTemplateParameterList(D->getTemplateParameterList(i));
1514e5dd7070Spatrick Record.push_back(D->getFriendDecl() != nullptr);
1515e5dd7070Spatrick if (D->getFriendDecl())
1516e5dd7070Spatrick Record.AddDeclRef(D->getFriendDecl());
1517e5dd7070Spatrick else
1518e5dd7070Spatrick Record.AddTypeSourceInfo(D->getFriendType());
1519e5dd7070Spatrick Record.AddSourceLocation(D->getFriendLoc());
1520e5dd7070Spatrick Code = serialization::DECL_FRIEND_TEMPLATE;
1521e5dd7070Spatrick }
1522e5dd7070Spatrick
VisitTemplateDecl(TemplateDecl * D)1523e5dd7070Spatrick void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
1524e5dd7070Spatrick VisitNamedDecl(D);
1525e5dd7070Spatrick
1526e5dd7070Spatrick Record.AddTemplateParameterList(D->getTemplateParameters());
1527*12c85518Srobert Record.AddDeclRef(D->getTemplatedDecl());
1528e5dd7070Spatrick }
1529e5dd7070Spatrick
VisitConceptDecl(ConceptDecl * D)1530e5dd7070Spatrick void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
1531e5dd7070Spatrick VisitTemplateDecl(D);
1532e5dd7070Spatrick Record.AddStmt(D->getConstraintExpr());
1533e5dd7070Spatrick Code = serialization::DECL_CONCEPT;
1534e5dd7070Spatrick }
1535e5dd7070Spatrick
VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl * D)1536*12c85518Srobert void ASTDeclWriter::VisitImplicitConceptSpecializationDecl(
1537*12c85518Srobert ImplicitConceptSpecializationDecl *D) {
1538*12c85518Srobert Record.push_back(D->getTemplateArguments().size());
1539*12c85518Srobert VisitDecl(D);
1540*12c85518Srobert for (const TemplateArgument &Arg : D->getTemplateArguments())
1541*12c85518Srobert Record.AddTemplateArgument(Arg);
1542*12c85518Srobert Code = serialization::DECL_IMPLICIT_CONCEPT_SPECIALIZATION;
1543*12c85518Srobert }
1544*12c85518Srobert
VisitRequiresExprBodyDecl(RequiresExprBodyDecl * D)1545e5dd7070Spatrick void ASTDeclWriter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
1546e5dd7070Spatrick Code = serialization::DECL_REQUIRES_EXPR_BODY;
1547e5dd7070Spatrick }
1548e5dd7070Spatrick
VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl * D)1549e5dd7070Spatrick void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
1550e5dd7070Spatrick VisitRedeclarable(D);
1551e5dd7070Spatrick
1552e5dd7070Spatrick // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
1553e5dd7070Spatrick // getCommonPtr() can be used while this is still initializing.
1554e5dd7070Spatrick if (D->isFirstDecl()) {
1555e5dd7070Spatrick // This declaration owns the 'common' pointer, so serialize that data now.
1556e5dd7070Spatrick Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
1557e5dd7070Spatrick if (D->getInstantiatedFromMemberTemplate())
1558e5dd7070Spatrick Record.push_back(D->isMemberSpecialization());
1559e5dd7070Spatrick }
1560e5dd7070Spatrick
1561e5dd7070Spatrick VisitTemplateDecl(D);
1562e5dd7070Spatrick Record.push_back(D->getIdentifierNamespace());
1563e5dd7070Spatrick }
1564e5dd7070Spatrick
VisitClassTemplateDecl(ClassTemplateDecl * D)1565e5dd7070Spatrick void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1566e5dd7070Spatrick VisitRedeclarableTemplateDecl(D);
1567e5dd7070Spatrick
1568e5dd7070Spatrick if (D->isFirstDecl())
1569e5dd7070Spatrick AddTemplateSpecializations(D);
1570e5dd7070Spatrick Code = serialization::DECL_CLASS_TEMPLATE;
1571e5dd7070Spatrick }
1572e5dd7070Spatrick
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)1573e5dd7070Spatrick void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
1574e5dd7070Spatrick ClassTemplateSpecializationDecl *D) {
1575e5dd7070Spatrick RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
1576e5dd7070Spatrick
1577e5dd7070Spatrick VisitCXXRecordDecl(D);
1578e5dd7070Spatrick
1579e5dd7070Spatrick llvm::PointerUnion<ClassTemplateDecl *,
1580e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *> InstFrom
1581e5dd7070Spatrick = D->getSpecializedTemplateOrPartial();
1582e5dd7070Spatrick if (Decl *InstFromD = InstFrom.dyn_cast<ClassTemplateDecl *>()) {
1583e5dd7070Spatrick Record.AddDeclRef(InstFromD);
1584e5dd7070Spatrick } else {
1585e5dd7070Spatrick Record.AddDeclRef(InstFrom.get<ClassTemplatePartialSpecializationDecl *>());
1586e5dd7070Spatrick Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
1587e5dd7070Spatrick }
1588e5dd7070Spatrick
1589e5dd7070Spatrick Record.AddTemplateArgumentList(&D->getTemplateArgs());
1590e5dd7070Spatrick Record.AddSourceLocation(D->getPointOfInstantiation());
1591e5dd7070Spatrick Record.push_back(D->getSpecializationKind());
1592e5dd7070Spatrick Record.push_back(D->isCanonicalDecl());
1593e5dd7070Spatrick
1594e5dd7070Spatrick if (D->isCanonicalDecl()) {
1595e5dd7070Spatrick // When reading, we'll add it to the folding set of the following template.
1596e5dd7070Spatrick Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
1597e5dd7070Spatrick }
1598e5dd7070Spatrick
1599e5dd7070Spatrick // Explicit info.
1600e5dd7070Spatrick Record.AddTypeSourceInfo(D->getTypeAsWritten());
1601e5dd7070Spatrick if (D->getTypeAsWritten()) {
1602e5dd7070Spatrick Record.AddSourceLocation(D->getExternLoc());
1603e5dd7070Spatrick Record.AddSourceLocation(D->getTemplateKeywordLoc());
1604e5dd7070Spatrick }
1605e5dd7070Spatrick
1606e5dd7070Spatrick Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
1607e5dd7070Spatrick }
1608e5dd7070Spatrick
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)1609e5dd7070Spatrick void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
1610e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *D) {
1611e5dd7070Spatrick Record.AddTemplateParameterList(D->getTemplateParameters());
1612e5dd7070Spatrick Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
1613e5dd7070Spatrick
1614e5dd7070Spatrick VisitClassTemplateSpecializationDecl(D);
1615e5dd7070Spatrick
1616e5dd7070Spatrick // These are read/set from/to the first declaration.
1617e5dd7070Spatrick if (D->getPreviousDecl() == nullptr) {
1618e5dd7070Spatrick Record.AddDeclRef(D->getInstantiatedFromMember());
1619e5dd7070Spatrick Record.push_back(D->isMemberSpecialization());
1620e5dd7070Spatrick }
1621e5dd7070Spatrick
1622e5dd7070Spatrick Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
1623e5dd7070Spatrick }
1624e5dd7070Spatrick
VisitVarTemplateDecl(VarTemplateDecl * D)1625e5dd7070Spatrick void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) {
1626e5dd7070Spatrick VisitRedeclarableTemplateDecl(D);
1627e5dd7070Spatrick
1628e5dd7070Spatrick if (D->isFirstDecl())
1629e5dd7070Spatrick AddTemplateSpecializations(D);
1630e5dd7070Spatrick Code = serialization::DECL_VAR_TEMPLATE;
1631e5dd7070Spatrick }
1632e5dd7070Spatrick
VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * D)1633e5dd7070Spatrick void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
1634e5dd7070Spatrick VarTemplateSpecializationDecl *D) {
1635e5dd7070Spatrick RegisterTemplateSpecialization(D->getSpecializedTemplate(), D);
1636e5dd7070Spatrick
1637e5dd7070Spatrick llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
1638e5dd7070Spatrick InstFrom = D->getSpecializedTemplateOrPartial();
1639e5dd7070Spatrick if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) {
1640e5dd7070Spatrick Record.AddDeclRef(InstFromD);
1641e5dd7070Spatrick } else {
1642e5dd7070Spatrick Record.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>());
1643e5dd7070Spatrick Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
1644e5dd7070Spatrick }
1645e5dd7070Spatrick
1646e5dd7070Spatrick // Explicit info.
1647e5dd7070Spatrick Record.AddTypeSourceInfo(D->getTypeAsWritten());
1648e5dd7070Spatrick if (D->getTypeAsWritten()) {
1649e5dd7070Spatrick Record.AddSourceLocation(D->getExternLoc());
1650e5dd7070Spatrick Record.AddSourceLocation(D->getTemplateKeywordLoc());
1651e5dd7070Spatrick }
1652e5dd7070Spatrick
1653e5dd7070Spatrick Record.AddTemplateArgumentList(&D->getTemplateArgs());
1654e5dd7070Spatrick Record.AddSourceLocation(D->getPointOfInstantiation());
1655e5dd7070Spatrick Record.push_back(D->getSpecializationKind());
1656e5dd7070Spatrick Record.push_back(D->IsCompleteDefinition);
1657*12c85518Srobert
1658*12c85518Srobert VisitVarDecl(D);
1659*12c85518Srobert
1660e5dd7070Spatrick Record.push_back(D->isCanonicalDecl());
1661e5dd7070Spatrick
1662e5dd7070Spatrick if (D->isCanonicalDecl()) {
1663e5dd7070Spatrick // When reading, we'll add it to the folding set of the following template.
1664e5dd7070Spatrick Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
1665e5dd7070Spatrick }
1666e5dd7070Spatrick
1667e5dd7070Spatrick Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION;
1668e5dd7070Spatrick }
1669e5dd7070Spatrick
VisitVarTemplatePartialSpecializationDecl(VarTemplatePartialSpecializationDecl * D)1670e5dd7070Spatrick void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
1671e5dd7070Spatrick VarTemplatePartialSpecializationDecl *D) {
1672e5dd7070Spatrick Record.AddTemplateParameterList(D->getTemplateParameters());
1673e5dd7070Spatrick Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
1674e5dd7070Spatrick
1675e5dd7070Spatrick VisitVarTemplateSpecializationDecl(D);
1676e5dd7070Spatrick
1677e5dd7070Spatrick // These are read/set from/to the first declaration.
1678e5dd7070Spatrick if (D->getPreviousDecl() == nullptr) {
1679e5dd7070Spatrick Record.AddDeclRef(D->getInstantiatedFromMember());
1680e5dd7070Spatrick Record.push_back(D->isMemberSpecialization());
1681e5dd7070Spatrick }
1682e5dd7070Spatrick
1683e5dd7070Spatrick Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
1684e5dd7070Spatrick }
1685e5dd7070Spatrick
VisitClassScopeFunctionSpecializationDecl(ClassScopeFunctionSpecializationDecl * D)1686e5dd7070Spatrick void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
1687e5dd7070Spatrick ClassScopeFunctionSpecializationDecl *D) {
1688e5dd7070Spatrick VisitDecl(D);
1689e5dd7070Spatrick Record.AddDeclRef(D->getSpecialization());
1690e5dd7070Spatrick Record.push_back(D->hasExplicitTemplateArgs());
1691e5dd7070Spatrick if (D->hasExplicitTemplateArgs())
1692e5dd7070Spatrick Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
1693e5dd7070Spatrick Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
1694e5dd7070Spatrick }
1695e5dd7070Spatrick
1696e5dd7070Spatrick
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)1697e5dd7070Spatrick void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1698e5dd7070Spatrick VisitRedeclarableTemplateDecl(D);
1699e5dd7070Spatrick
1700e5dd7070Spatrick if (D->isFirstDecl())
1701e5dd7070Spatrick AddTemplateSpecializations(D);
1702e5dd7070Spatrick Code = serialization::DECL_FUNCTION_TEMPLATE;
1703e5dd7070Spatrick }
1704e5dd7070Spatrick
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)1705e5dd7070Spatrick void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
1706e5dd7070Spatrick Record.push_back(D->hasTypeConstraint());
1707e5dd7070Spatrick VisitTypeDecl(D);
1708e5dd7070Spatrick
1709e5dd7070Spatrick Record.push_back(D->wasDeclaredWithTypename());
1710e5dd7070Spatrick
1711e5dd7070Spatrick const TypeConstraint *TC = D->getTypeConstraint();
1712e5dd7070Spatrick Record.push_back(TC != nullptr);
1713e5dd7070Spatrick if (TC) {
1714e5dd7070Spatrick Record.AddNestedNameSpecifierLoc(TC->getNestedNameSpecifierLoc());
1715e5dd7070Spatrick Record.AddDeclarationNameInfo(TC->getConceptNameInfo());
1716e5dd7070Spatrick Record.AddDeclRef(TC->getNamedConcept());
1717e5dd7070Spatrick Record.push_back(TC->getTemplateArgsAsWritten() != nullptr);
1718e5dd7070Spatrick if (TC->getTemplateArgsAsWritten())
1719e5dd7070Spatrick Record.AddASTTemplateArgumentListInfo(TC->getTemplateArgsAsWritten());
1720e5dd7070Spatrick Record.AddStmt(TC->getImmediatelyDeclaredConstraint());
1721e5dd7070Spatrick Record.push_back(D->isExpandedParameterPack());
1722e5dd7070Spatrick if (D->isExpandedParameterPack())
1723e5dd7070Spatrick Record.push_back(D->getNumExpansionParameters());
1724e5dd7070Spatrick }
1725e5dd7070Spatrick
1726e5dd7070Spatrick bool OwnsDefaultArg = D->hasDefaultArgument() &&
1727e5dd7070Spatrick !D->defaultArgumentWasInherited();
1728e5dd7070Spatrick Record.push_back(OwnsDefaultArg);
1729e5dd7070Spatrick if (OwnsDefaultArg)
1730e5dd7070Spatrick Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
1731e5dd7070Spatrick
1732e5dd7070Spatrick Code = serialization::DECL_TEMPLATE_TYPE_PARM;
1733e5dd7070Spatrick }
1734e5dd7070Spatrick
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)1735e5dd7070Spatrick void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
1736e5dd7070Spatrick // For an expanded parameter pack, record the number of expansion types here
1737e5dd7070Spatrick // so that it's easier for deserialization to allocate the right amount of
1738e5dd7070Spatrick // memory.
1739e5dd7070Spatrick Expr *TypeConstraint = D->getPlaceholderTypeConstraint();
1740e5dd7070Spatrick Record.push_back(!!TypeConstraint);
1741e5dd7070Spatrick if (D->isExpandedParameterPack())
1742e5dd7070Spatrick Record.push_back(D->getNumExpansionTypes());
1743e5dd7070Spatrick
1744e5dd7070Spatrick VisitDeclaratorDecl(D);
1745e5dd7070Spatrick // TemplateParmPosition.
1746e5dd7070Spatrick Record.push_back(D->getDepth());
1747e5dd7070Spatrick Record.push_back(D->getPosition());
1748e5dd7070Spatrick if (TypeConstraint)
1749e5dd7070Spatrick Record.AddStmt(TypeConstraint);
1750e5dd7070Spatrick
1751e5dd7070Spatrick if (D->isExpandedParameterPack()) {
1752e5dd7070Spatrick for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
1753e5dd7070Spatrick Record.AddTypeRef(D->getExpansionType(I));
1754e5dd7070Spatrick Record.AddTypeSourceInfo(D->getExpansionTypeSourceInfo(I));
1755e5dd7070Spatrick }
1756e5dd7070Spatrick
1757e5dd7070Spatrick Code = serialization::DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK;
1758e5dd7070Spatrick } else {
1759e5dd7070Spatrick // Rest of NonTypeTemplateParmDecl.
1760e5dd7070Spatrick Record.push_back(D->isParameterPack());
1761e5dd7070Spatrick bool OwnsDefaultArg = D->hasDefaultArgument() &&
1762e5dd7070Spatrick !D->defaultArgumentWasInherited();
1763e5dd7070Spatrick Record.push_back(OwnsDefaultArg);
1764e5dd7070Spatrick if (OwnsDefaultArg)
1765e5dd7070Spatrick Record.AddStmt(D->getDefaultArgument());
1766e5dd7070Spatrick Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
1767e5dd7070Spatrick }
1768e5dd7070Spatrick }
1769e5dd7070Spatrick
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)1770e5dd7070Spatrick void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
1771e5dd7070Spatrick // For an expanded parameter pack, record the number of expansion types here
1772e5dd7070Spatrick // so that it's easier for deserialization to allocate the right amount of
1773e5dd7070Spatrick // memory.
1774e5dd7070Spatrick if (D->isExpandedParameterPack())
1775e5dd7070Spatrick Record.push_back(D->getNumExpansionTemplateParameters());
1776e5dd7070Spatrick
1777e5dd7070Spatrick VisitTemplateDecl(D);
1778e5dd7070Spatrick // TemplateParmPosition.
1779e5dd7070Spatrick Record.push_back(D->getDepth());
1780e5dd7070Spatrick Record.push_back(D->getPosition());
1781e5dd7070Spatrick
1782e5dd7070Spatrick if (D->isExpandedParameterPack()) {
1783e5dd7070Spatrick for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
1784e5dd7070Spatrick I != N; ++I)
1785e5dd7070Spatrick Record.AddTemplateParameterList(D->getExpansionTemplateParameters(I));
1786e5dd7070Spatrick Code = serialization::DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK;
1787e5dd7070Spatrick } else {
1788e5dd7070Spatrick // Rest of TemplateTemplateParmDecl.
1789e5dd7070Spatrick Record.push_back(D->isParameterPack());
1790e5dd7070Spatrick bool OwnsDefaultArg = D->hasDefaultArgument() &&
1791e5dd7070Spatrick !D->defaultArgumentWasInherited();
1792e5dd7070Spatrick Record.push_back(OwnsDefaultArg);
1793e5dd7070Spatrick if (OwnsDefaultArg)
1794e5dd7070Spatrick Record.AddTemplateArgumentLoc(D->getDefaultArgument());
1795e5dd7070Spatrick Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
1796e5dd7070Spatrick }
1797e5dd7070Spatrick }
1798e5dd7070Spatrick
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)1799e5dd7070Spatrick void ASTDeclWriter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
1800e5dd7070Spatrick VisitRedeclarableTemplateDecl(D);
1801e5dd7070Spatrick Code = serialization::DECL_TYPE_ALIAS_TEMPLATE;
1802e5dd7070Spatrick }
1803e5dd7070Spatrick
VisitStaticAssertDecl(StaticAssertDecl * D)1804e5dd7070Spatrick void ASTDeclWriter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1805e5dd7070Spatrick VisitDecl(D);
1806e5dd7070Spatrick Record.AddStmt(D->getAssertExpr());
1807e5dd7070Spatrick Record.push_back(D->isFailed());
1808e5dd7070Spatrick Record.AddStmt(D->getMessage());
1809e5dd7070Spatrick Record.AddSourceLocation(D->getRParenLoc());
1810e5dd7070Spatrick Code = serialization::DECL_STATIC_ASSERT;
1811e5dd7070Spatrick }
1812e5dd7070Spatrick
1813e5dd7070Spatrick /// Emit the DeclContext part of a declaration context decl.
VisitDeclContext(DeclContext * DC)1814e5dd7070Spatrick void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
1815e5dd7070Spatrick Record.AddOffset(Writer.WriteDeclContextLexicalBlock(Context, DC));
1816e5dd7070Spatrick Record.AddOffset(Writer.WriteDeclContextVisibleBlock(Context, DC));
1817e5dd7070Spatrick }
1818e5dd7070Spatrick
getFirstLocalDecl(const Decl * D)1819e5dd7070Spatrick const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
1820e5dd7070Spatrick assert(IsLocalDecl(D) && "expected a local declaration");
1821e5dd7070Spatrick
1822e5dd7070Spatrick const Decl *Canon = D->getCanonicalDecl();
1823e5dd7070Spatrick if (IsLocalDecl(Canon))
1824e5dd7070Spatrick return Canon;
1825e5dd7070Spatrick
1826e5dd7070Spatrick const Decl *&CacheEntry = FirstLocalDeclCache[Canon];
1827e5dd7070Spatrick if (CacheEntry)
1828e5dd7070Spatrick return CacheEntry;
1829e5dd7070Spatrick
1830e5dd7070Spatrick for (const Decl *Redecl = D; Redecl; Redecl = Redecl->getPreviousDecl())
1831e5dd7070Spatrick if (IsLocalDecl(Redecl))
1832e5dd7070Spatrick D = Redecl;
1833e5dd7070Spatrick return CacheEntry = D;
1834e5dd7070Spatrick }
1835e5dd7070Spatrick
1836e5dd7070Spatrick template <typename T>
VisitRedeclarable(Redeclarable<T> * D)1837e5dd7070Spatrick void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
1838e5dd7070Spatrick T *First = D->getFirstDecl();
1839e5dd7070Spatrick T *MostRecent = First->getMostRecentDecl();
1840e5dd7070Spatrick T *DAsT = static_cast<T *>(D);
1841e5dd7070Spatrick if (MostRecent != First) {
1842e5dd7070Spatrick assert(isRedeclarableDeclKind(DAsT->getKind()) &&
1843e5dd7070Spatrick "Not considered redeclarable?");
1844e5dd7070Spatrick
1845e5dd7070Spatrick Record.AddDeclRef(First);
1846e5dd7070Spatrick
1847e5dd7070Spatrick // Write out a list of local redeclarations of this declaration if it's the
1848e5dd7070Spatrick // first local declaration in the chain.
1849e5dd7070Spatrick const Decl *FirstLocal = Writer.getFirstLocalDecl(DAsT);
1850e5dd7070Spatrick if (DAsT == FirstLocal) {
1851e5dd7070Spatrick // Emit a list of all imported first declarations so that we can be sure
1852e5dd7070Spatrick // that all redeclarations visible to this module are before D in the
1853e5dd7070Spatrick // redecl chain.
1854e5dd7070Spatrick unsigned I = Record.size();
1855e5dd7070Spatrick Record.push_back(0);
1856e5dd7070Spatrick if (Writer.Chain)
1857e5dd7070Spatrick AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
1858e5dd7070Spatrick // This is the number of imported first declarations + 1.
1859e5dd7070Spatrick Record[I] = Record.size() - I;
1860e5dd7070Spatrick
1861e5dd7070Spatrick // Collect the set of local redeclarations of this declaration, from
1862e5dd7070Spatrick // newest to oldest.
1863e5dd7070Spatrick ASTWriter::RecordData LocalRedecls;
1864e5dd7070Spatrick ASTRecordWriter LocalRedeclWriter(Record, LocalRedecls);
1865e5dd7070Spatrick for (const Decl *Prev = FirstLocal->getMostRecentDecl();
1866e5dd7070Spatrick Prev != FirstLocal; Prev = Prev->getPreviousDecl())
1867e5dd7070Spatrick if (!Prev->isFromASTFile())
1868e5dd7070Spatrick LocalRedeclWriter.AddDeclRef(Prev);
1869e5dd7070Spatrick
1870e5dd7070Spatrick // If we have any redecls, write them now as a separate record preceding
1871e5dd7070Spatrick // the declaration itself.
1872e5dd7070Spatrick if (LocalRedecls.empty())
1873e5dd7070Spatrick Record.push_back(0);
1874e5dd7070Spatrick else
1875e5dd7070Spatrick Record.AddOffset(LocalRedeclWriter.Emit(LOCAL_REDECLARATIONS));
1876e5dd7070Spatrick } else {
1877e5dd7070Spatrick Record.push_back(0);
1878e5dd7070Spatrick Record.AddDeclRef(FirstLocal);
1879e5dd7070Spatrick }
1880e5dd7070Spatrick
1881e5dd7070Spatrick // Make sure that we serialize both the previous and the most-recent
1882e5dd7070Spatrick // declarations, which (transitively) ensures that all declarations in the
1883e5dd7070Spatrick // chain get serialized.
1884e5dd7070Spatrick //
1885e5dd7070Spatrick // FIXME: This is not correct; when we reach an imported declaration we
1886e5dd7070Spatrick // won't emit its previous declaration.
1887e5dd7070Spatrick (void)Writer.GetDeclRef(D->getPreviousDecl());
1888e5dd7070Spatrick (void)Writer.GetDeclRef(MostRecent);
1889e5dd7070Spatrick } else {
1890e5dd7070Spatrick // We use the sentinel value 0 to indicate an only declaration.
1891e5dd7070Spatrick Record.push_back(0);
1892e5dd7070Spatrick }
1893e5dd7070Spatrick }
1894e5dd7070Spatrick
VisitHLSLBufferDecl(HLSLBufferDecl * D)1895*12c85518Srobert void ASTDeclWriter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
1896*12c85518Srobert VisitNamedDecl(D);
1897*12c85518Srobert VisitDeclContext(D);
1898*12c85518Srobert Record.push_back(D->isCBuffer());
1899*12c85518Srobert Record.AddSourceLocation(D->getLocStart());
1900*12c85518Srobert Record.AddSourceLocation(D->getLBraceLoc());
1901*12c85518Srobert Record.AddSourceLocation(D->getRBraceLoc());
1902*12c85518Srobert
1903*12c85518Srobert Code = serialization::DECL_HLSL_BUFFER;
1904*12c85518Srobert }
1905*12c85518Srobert
VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl * D)1906e5dd7070Spatrick void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1907a9ac8606Spatrick Record.writeOMPChildren(D->Data);
1908e5dd7070Spatrick VisitDecl(D);
1909e5dd7070Spatrick Code = serialization::DECL_OMP_THREADPRIVATE;
1910e5dd7070Spatrick }
1911e5dd7070Spatrick
VisitOMPAllocateDecl(OMPAllocateDecl * D)1912e5dd7070Spatrick void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1913a9ac8606Spatrick Record.writeOMPChildren(D->Data);
1914e5dd7070Spatrick VisitDecl(D);
1915e5dd7070Spatrick Code = serialization::DECL_OMP_ALLOCATE;
1916e5dd7070Spatrick }
1917e5dd7070Spatrick
VisitOMPRequiresDecl(OMPRequiresDecl * D)1918e5dd7070Spatrick void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1919a9ac8606Spatrick Record.writeOMPChildren(D->Data);
1920e5dd7070Spatrick VisitDecl(D);
1921e5dd7070Spatrick Code = serialization::DECL_OMP_REQUIRES;
1922e5dd7070Spatrick }
1923e5dd7070Spatrick
VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl * D)1924e5dd7070Spatrick void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
1925e5dd7070Spatrick VisitValueDecl(D);
1926e5dd7070Spatrick Record.AddSourceLocation(D->getBeginLoc());
1927e5dd7070Spatrick Record.AddStmt(D->getCombinerIn());
1928e5dd7070Spatrick Record.AddStmt(D->getCombinerOut());
1929e5dd7070Spatrick Record.AddStmt(D->getCombiner());
1930e5dd7070Spatrick Record.AddStmt(D->getInitOrig());
1931e5dd7070Spatrick Record.AddStmt(D->getInitPriv());
1932e5dd7070Spatrick Record.AddStmt(D->getInitializer());
1933e5dd7070Spatrick Record.push_back(D->getInitializerKind());
1934e5dd7070Spatrick Record.AddDeclRef(D->getPrevDeclInScope());
1935e5dd7070Spatrick Code = serialization::DECL_OMP_DECLARE_REDUCTION;
1936e5dd7070Spatrick }
1937e5dd7070Spatrick
VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl * D)1938e5dd7070Spatrick void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1939a9ac8606Spatrick Record.writeOMPChildren(D->Data);
1940e5dd7070Spatrick VisitValueDecl(D);
1941e5dd7070Spatrick Record.AddDeclarationName(D->getVarName());
1942e5dd7070Spatrick Record.AddDeclRef(D->getPrevDeclInScope());
1943e5dd7070Spatrick Code = serialization::DECL_OMP_DECLARE_MAPPER;
1944e5dd7070Spatrick }
1945e5dd7070Spatrick
VisitOMPCapturedExprDecl(OMPCapturedExprDecl * D)1946e5dd7070Spatrick void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
1947e5dd7070Spatrick VisitVarDecl(D);
1948e5dd7070Spatrick Code = serialization::DECL_OMP_CAPTUREDEXPR;
1949e5dd7070Spatrick }
1950e5dd7070Spatrick
1951e5dd7070Spatrick //===----------------------------------------------------------------------===//
1952e5dd7070Spatrick // ASTWriter Implementation
1953e5dd7070Spatrick //===----------------------------------------------------------------------===//
1954e5dd7070Spatrick
WriteDeclAbbrevs()1955e5dd7070Spatrick void ASTWriter::WriteDeclAbbrevs() {
1956e5dd7070Spatrick using namespace llvm;
1957e5dd7070Spatrick
1958e5dd7070Spatrick std::shared_ptr<BitCodeAbbrev> Abv;
1959e5dd7070Spatrick
1960e5dd7070Spatrick // Abbreviation for DECL_FIELD
1961e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
1962e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_FIELD));
1963e5dd7070Spatrick // Decl
1964e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1965e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
1966e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
1967e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
1968e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
1969e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isUsed
1970e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
1971e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
1972e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
1973*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
1974e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
1975e5dd7070Spatrick // NamedDecl
1976e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
1977e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
1978e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
1979e5dd7070Spatrick // ValueDecl
1980e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
1981e5dd7070Spatrick // DeclaratorDecl
1982e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
1983e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
1984e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
1985e5dd7070Spatrick // FieldDecl
1986e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
1987e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
1988e5dd7070Spatrick // Type Source Info
1989e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1990e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
1991e5dd7070Spatrick DeclFieldAbbrev = Stream.EmitAbbrev(std::move(Abv));
1992e5dd7070Spatrick
1993e5dd7070Spatrick // Abbreviation for DECL_OBJC_IVAR
1994e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
1995e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_OBJC_IVAR));
1996e5dd7070Spatrick // Decl
1997e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
1998e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
1999e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
2000e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2001e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
2002e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isUsed
2003e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
2004e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
2005e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // AccessSpecifier
2006*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2007e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2008e5dd7070Spatrick // NamedDecl
2009e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
2010e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2011e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2012e5dd7070Spatrick // ValueDecl
2013e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2014e5dd7070Spatrick // DeclaratorDecl
2015e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
2016e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
2017e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
2018e5dd7070Spatrick // FieldDecl
2019e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isMutable
2020e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
2021e5dd7070Spatrick // ObjC Ivar
2022e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
2023e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
2024e5dd7070Spatrick // Type Source Info
2025e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2026e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
2027e5dd7070Spatrick DeclObjCIvarAbbrev = Stream.EmitAbbrev(std::move(Abv));
2028e5dd7070Spatrick
2029e5dd7070Spatrick // Abbreviation for DECL_ENUM
2030e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2031e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
2032e5dd7070Spatrick // Redeclarable
2033e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
2034e5dd7070Spatrick // Decl
2035e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2036e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
2037e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
2038e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2039e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
2040e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isUsed
2041e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
2042e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
2043e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
2044*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2045e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2046e5dd7070Spatrick // NamedDecl
2047e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
2048e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2049e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2050e5dd7070Spatrick // TypeDecl
2051e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2052e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
2053e5dd7070Spatrick // TagDecl
2054e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
2055e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
2056e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
2057e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
2058e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
2059e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
2060e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
2061e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
2062e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // ExtInfoKind
2063e5dd7070Spatrick // EnumDecl
2064e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddTypeRef
2065e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IntegerType
2066e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getPromotionType
2067e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getNumPositiveBits
2068e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getNumNegativeBits
2069e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScoped
2070e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isScopedUsingClassTag
2071e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isFixed
2072e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
2073e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedMembEnum
2074e5dd7070Spatrick // DC
2075e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
2076e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
2077e5dd7070Spatrick DeclEnumAbbrev = Stream.EmitAbbrev(std::move(Abv));
2078e5dd7070Spatrick
2079e5dd7070Spatrick // Abbreviation for DECL_RECORD
2080e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2081e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
2082e5dd7070Spatrick // Redeclarable
2083e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
2084e5dd7070Spatrick // Decl
2085e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2086e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
2087e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
2088e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2089e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
2090e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isUsed
2091e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
2092e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
2093e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
2094*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2095e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2096e5dd7070Spatrick // NamedDecl
2097e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
2098e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2099e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2100e5dd7070Spatrick // TypeDecl
2101e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2102e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
2103e5dd7070Spatrick // TagDecl
2104e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
2105e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getTagKind
2106e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition
2107e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator
2108e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding
2109e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired
2110e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
2111e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation
2112e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // ExtInfoKind
2113e5dd7070Spatrick // RecordDecl
2114e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FlexibleArrayMember
2115e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // AnonymousStructUnion
2116e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasObjectMember
2117e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // hasVolatileMember
2118e5dd7070Spatrick
2119e5dd7070Spatrick // isNonTrivialToPrimitiveDefaultInitialize
2120e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2121e5dd7070Spatrick // isNonTrivialToPrimitiveCopy
2122e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2123e5dd7070Spatrick // isNonTrivialToPrimitiveDestroy
2124e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2125e5dd7070Spatrick // hasNonTrivialToPrimitiveDefaultInitializeCUnion
2126e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2127e5dd7070Spatrick // hasNonTrivialToPrimitiveDestructCUnion
2128e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2129e5dd7070Spatrick // hasNonTrivialToPrimitiveCopyCUnion
2130e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2131e5dd7070Spatrick // isParamDestroyedInCallee
2132e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2133e5dd7070Spatrick // getArgPassingRestrictions
2134e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
2135*12c85518Srobert // ODRHash
2136*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 26));
2137e5dd7070Spatrick
2138e5dd7070Spatrick // DC
2139e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
2140e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // VisibleOffset
2141e5dd7070Spatrick DeclRecordAbbrev = Stream.EmitAbbrev(std::move(Abv));
2142e5dd7070Spatrick
2143e5dd7070Spatrick // Abbreviation for DECL_PARM_VAR
2144e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2145e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
2146e5dd7070Spatrick // Redeclarable
2147e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
2148e5dd7070Spatrick // Decl
2149e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2150e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
2151e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
2152e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2153e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
2154e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isUsed
2155e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
2156e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
2157e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
2158*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2159e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2160e5dd7070Spatrick // NamedDecl
2161e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
2162e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2163e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2164e5dd7070Spatrick // ValueDecl
2165e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2166e5dd7070Spatrick // DeclaratorDecl
2167e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
2168e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
2169e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
2170e5dd7070Spatrick // VarDecl
2171e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // SClass
2172e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TSCSpec
2173e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // InitStyle
2174ec727ea7Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
2175e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // Linkage
2176e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasInit
2177e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo
2178e5dd7070Spatrick // ParmVarDecl
2179e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsObjCMethodParameter
2180e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // ScopeDepth
2181e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ScopeIndex
2182e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // ObjCDeclQualifier
2183e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // KNRPromoted
2184e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedDefaultArg
2185e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasUninstantiatedDefaultArg
2186e5dd7070Spatrick // Type Source Info
2187e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2188e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
2189e5dd7070Spatrick DeclParmVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
2190e5dd7070Spatrick
2191e5dd7070Spatrick // Abbreviation for DECL_TYPEDEF
2192e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2193e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
2194e5dd7070Spatrick // Redeclarable
2195e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
2196e5dd7070Spatrick // Decl
2197e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2198e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
2199e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
2200e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2201e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
2202e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isUsed
2203e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isReferenced
2204e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
2205e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // C++ AccessSpecifier
2206*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2207e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2208e5dd7070Spatrick // NamedDecl
2209e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
2210e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2211e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2212e5dd7070Spatrick // TypeDecl
2213e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
2214e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
2215e5dd7070Spatrick // TypedefDecl
2216e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2217e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
2218e5dd7070Spatrick DeclTypedefAbbrev = Stream.EmitAbbrev(std::move(Abv));
2219e5dd7070Spatrick
2220e5dd7070Spatrick // Abbreviation for DECL_VAR
2221e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2222e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
2223e5dd7070Spatrick // Redeclarable
2224e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
2225e5dd7070Spatrick // Decl
2226e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2227e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
2228e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl
2229e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2230e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
2231e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isUsed
2232e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isReferenced
2233e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // TopLevelDeclInObjCContainer
2234e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
2235*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2236e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2237e5dd7070Spatrick // NamedDecl
2238e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
2239e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
2240e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2241e5dd7070Spatrick // ValueDecl
2242e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2243e5dd7070Spatrick // DeclaratorDecl
2244e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerStartLoc
2245e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo
2246e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
2247e5dd7070Spatrick // VarDecl
2248e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // SClass
2249e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // TSCSpec
2250e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // InitStyle
2251e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong
2252e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsThisDeclarationADemotedDefinition
2253e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable
2254e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable
2255e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl
2256e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isObjCForDecl
2257e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInline
2258e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInlineSpecified
2259e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr
2260e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture
2261e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope
2262e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // ImplicitParamKind
2263e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // EscapingByref
2264e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
2265a9ac8606Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // HasConstant*
2266e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // VarKind (local enum)
2267e5dd7070Spatrick // Type Source Info
2268e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2269e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypeLoc
2270e5dd7070Spatrick DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
2271e5dd7070Spatrick
2272e5dd7070Spatrick // Abbreviation for DECL_CXX_METHOD
2273e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2274e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD));
2275e5dd7070Spatrick // RedeclarableDecl
2276e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
2277*12c85518Srobert // FIXME: Implement abbreviation for other template kinds.
2278*12c85518Srobert Abv->Add(BitCodeAbbrevOp(FunctionDecl::TK_NonTemplate)); // TemplateKind
2279e5dd7070Spatrick // Decl
2280e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
2281e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // LexicalDeclContext
2282e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // Invalid
2283e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
2284e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Implicit
2285e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Used
2286e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Referenced
2287e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // InObjCContainer
2288e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Access
2289*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // ModuleOwnershipKind
2290e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
2291e5dd7070Spatrick // NamedDecl
2292e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
2293e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier
2294e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
2295e5dd7070Spatrick // ValueDecl
2296e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2297e5dd7070Spatrick // DeclaratorDecl
2298e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart
2299e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo
2300e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType
2301e5dd7070Spatrick // FunctionDecl
2302e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
2303e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
2304e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
2305e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
2306e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
2307e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
2308e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedProto
2309e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(1)); // HasWrittenProto
2310e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Deleted
2311e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Trivial
2312e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // TrivialForCall
2313e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Defaulted
2314e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitlyDefaulted
2315*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsIneligibleOrNotSelected
2316e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ImplicitReturnZero
2317*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Constexpr
2318e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // UsesSEHTry
2319e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // SkippedBody
2320e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // MultiVersion
2321e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed
2322*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // FriendConstraintRefersToEnclosingTemplate
2323e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage
2324e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
2325*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Default
2326e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
2327e5dd7070Spatrick // This Array slurps the rest of the record. Fortunately we want to encode
2328e5dd7070Spatrick // (nearly) all the remaining (variable number of) fields in the same way.
2329e5dd7070Spatrick //
2330*12c85518Srobert // This is:
2331e5dd7070Spatrick // NumParams and Params[] from FunctionDecl, and
2332e5dd7070Spatrick // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl.
2333e5dd7070Spatrick //
2334e5dd7070Spatrick // Add an AbbrevOp for 'size then elements' and use it here.
2335e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
2336e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2337e5dd7070Spatrick DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv));
2338e5dd7070Spatrick
2339*12c85518Srobert unsigned ExprDependenceBits = llvm::BitWidth<ExprDependence>;
2340e5dd7070Spatrick // Abbreviation for EXPR_DECL_REF
2341e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2342e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
2343e5dd7070Spatrick //Stmt
2344e5dd7070Spatrick // Expr
2345e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2346*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, ExprDependenceBits));
2347e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
2348e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
2349e5dd7070Spatrick //DeclRefExpr
2350e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
2351e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
2352e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
2353e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
2354e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture
2355e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason
2356e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
2357e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
2358e5dd7070Spatrick DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
2359e5dd7070Spatrick
2360e5dd7070Spatrick // Abbreviation for EXPR_INTEGER_LITERAL
2361e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2362e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
2363e5dd7070Spatrick //Stmt
2364e5dd7070Spatrick // Expr
2365e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2366*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, ExprDependenceBits));
2367e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
2368e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
2369e5dd7070Spatrick //Integer Literal
2370e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
2371e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(32)); // Bit Width
2372e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
2373e5dd7070Spatrick IntegerLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
2374e5dd7070Spatrick
2375e5dd7070Spatrick // Abbreviation for EXPR_CHARACTER_LITERAL
2376e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2377e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
2378e5dd7070Spatrick //Stmt
2379e5dd7070Spatrick // Expr
2380e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2381*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, ExprDependenceBits));
2382e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
2383e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
2384e5dd7070Spatrick //Character Literal
2385e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
2386e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
2387e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
2388e5dd7070Spatrick CharacterLiteralAbbrev = Stream.EmitAbbrev(std::move(Abv));
2389e5dd7070Spatrick
2390e5dd7070Spatrick // Abbreviation for EXPR_IMPLICIT_CAST
2391e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2392e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
2393e5dd7070Spatrick // Stmt
2394e5dd7070Spatrick // Expr
2395e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
2396*12c85518Srobert Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, ExprDependenceBits));
2397e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetValueKind
2398e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); //GetObjectKind
2399e5dd7070Spatrick // CastExpr
2400e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(0)); // PathSize
2401a9ac8606Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasFPFeatures
2402e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
2403e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast
2404e5dd7070Spatrick // ImplicitCastExpr
2405e5dd7070Spatrick ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
2406e5dd7070Spatrick
2407e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2408e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL));
2409e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2410e5dd7070Spatrick DeclContextLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
2411e5dd7070Spatrick
2412e5dd7070Spatrick Abv = std::make_shared<BitCodeAbbrev>();
2413e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE));
2414e5dd7070Spatrick Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2415e5dd7070Spatrick DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv));
2416e5dd7070Spatrick }
2417e5dd7070Spatrick
2418e5dd7070Spatrick /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by
2419e5dd7070Spatrick /// consumers of the AST.
2420e5dd7070Spatrick ///
2421e5dd7070Spatrick /// Such decls will always be deserialized from the AST file, so we would like
2422e5dd7070Spatrick /// this to be as restrictive as possible. Currently the predicate is driven by
2423e5dd7070Spatrick /// code generation requirements, if other clients have a different notion of
2424e5dd7070Spatrick /// what is "required" then we may have to consider an alternate scheme where
2425e5dd7070Spatrick /// clients can iterate over the top-level decls and get information on them,
2426e5dd7070Spatrick /// without necessary deserializing them. We could explicitly require such
2427e5dd7070Spatrick /// clients to use a separate API call to "realize" the decl. This should be
2428e5dd7070Spatrick /// relatively painless since they would presumably only do it for top-level
2429e5dd7070Spatrick /// decls.
isRequiredDecl(const Decl * D,ASTContext & Context,bool WritingModule)2430e5dd7070Spatrick static bool isRequiredDecl(const Decl *D, ASTContext &Context,
2431e5dd7070Spatrick bool WritingModule) {
2432e5dd7070Spatrick // An ObjCMethodDecl is never considered as "required" because its
2433e5dd7070Spatrick // implementation container always is.
2434e5dd7070Spatrick
2435e5dd7070Spatrick // File scoped assembly or obj-c or OMP declare target implementation must be
2436e5dd7070Spatrick // seen.
2437*12c85518Srobert if (isa<FileScopeAsmDecl, TopLevelStmtDecl, ObjCImplDecl>(D))
2438e5dd7070Spatrick return true;
2439e5dd7070Spatrick
2440e5dd7070Spatrick if (WritingModule && isPartOfPerModuleInitializer(D)) {
2441e5dd7070Spatrick // These declarations are part of the module initializer, and are emitted
2442e5dd7070Spatrick // if and when the module is imported, rather than being emitted eagerly.
2443e5dd7070Spatrick return false;
2444e5dd7070Spatrick }
2445e5dd7070Spatrick
2446e5dd7070Spatrick return Context.DeclMustBeEmitted(D);
2447e5dd7070Spatrick }
2448e5dd7070Spatrick
WriteDecl(ASTContext & Context,Decl * D)2449e5dd7070Spatrick void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
2450e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, D, SourceLocation(),
2451e5dd7070Spatrick "serializing");
2452e5dd7070Spatrick
2453e5dd7070Spatrick // Determine the ID for this declaration.
2454e5dd7070Spatrick serialization::DeclID ID;
2455e5dd7070Spatrick assert(!D->isFromASTFile() && "should not be emitting imported decl");
2456e5dd7070Spatrick serialization::DeclID &IDR = DeclIDs[D];
2457e5dd7070Spatrick if (IDR == 0)
2458e5dd7070Spatrick IDR = NextDeclID++;
2459e5dd7070Spatrick
2460e5dd7070Spatrick ID = IDR;
2461e5dd7070Spatrick
2462e5dd7070Spatrick assert(ID >= FirstDeclID && "invalid decl ID");
2463e5dd7070Spatrick
2464e5dd7070Spatrick RecordData Record;
2465e5dd7070Spatrick ASTDeclWriter W(*this, Context, Record);
2466e5dd7070Spatrick
2467e5dd7070Spatrick // Build a record for this declaration
2468e5dd7070Spatrick W.Visit(D);
2469e5dd7070Spatrick
2470e5dd7070Spatrick // Emit this declaration to the bitstream.
2471e5dd7070Spatrick uint64_t Offset = W.Emit(D);
2472e5dd7070Spatrick
2473e5dd7070Spatrick // Record the offset for this declaration
2474e5dd7070Spatrick SourceLocation Loc = D->getLocation();
2475e5dd7070Spatrick unsigned Index = ID - FirstDeclID;
2476e5dd7070Spatrick if (DeclOffsets.size() == Index)
2477*12c85518Srobert DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset,
2478*12c85518Srobert DeclTypesBlockStartOffset);
2479e5dd7070Spatrick else if (DeclOffsets.size() < Index) {
2480e5dd7070Spatrick // FIXME: Can/should this happen?
2481e5dd7070Spatrick DeclOffsets.resize(Index+1);
2482*12c85518Srobert DeclOffsets[Index].setLocation(getAdjustedLocation(Loc));
2483ec727ea7Spatrick DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset);
2484e5dd7070Spatrick } else {
2485e5dd7070Spatrick llvm_unreachable("declarations should be emitted in ID order");
2486e5dd7070Spatrick }
2487e5dd7070Spatrick
2488e5dd7070Spatrick SourceManager &SM = Context.getSourceManager();
2489e5dd7070Spatrick if (Loc.isValid() && SM.isLocalSourceLocation(Loc))
2490e5dd7070Spatrick associateDeclWithFile(D, ID);
2491e5dd7070Spatrick
2492e5dd7070Spatrick // Note declarations that should be deserialized eagerly so that we can add
2493e5dd7070Spatrick // them to a record in the AST file later.
2494e5dd7070Spatrick if (isRequiredDecl(D, Context, WritingModule))
2495e5dd7070Spatrick EagerlyDeserializedDecls.push_back(ID);
2496e5dd7070Spatrick }
2497e5dd7070Spatrick
AddFunctionDefinition(const FunctionDecl * FD)2498e5dd7070Spatrick void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
2499e5dd7070Spatrick // Switch case IDs are per function body.
2500e5dd7070Spatrick Writer->ClearSwitchCaseIDs();
2501e5dd7070Spatrick
2502e5dd7070Spatrick assert(FD->doesThisDeclarationHaveABody());
2503e5dd7070Spatrick bool ModulesCodegen = false;
2504ec727ea7Spatrick if (!FD->isDependentContext()) {
2505*12c85518Srobert std::optional<GVALinkage> Linkage;
2506ec727ea7Spatrick if (Writer->WritingModule &&
2507*12c85518Srobert Writer->WritingModule->isInterfaceOrPartition()) {
2508*12c85518Srobert // When building a C++20 module interface unit or a partition unit, a
2509*12c85518Srobert // strong definition in the module interface is provided by the
2510*12c85518Srobert // compilation of that unit, not by its users. (Inline functions are still
2511*12c85518Srobert // emitted in module users.)
2512e5dd7070Spatrick Linkage = Writer->Context->GetGVALinkageForFunction(FD);
2513e5dd7070Spatrick ModulesCodegen = *Linkage == GVA_StrongExternal;
2514e5dd7070Spatrick }
2515a9ac8606Spatrick if (Writer->Context->getLangOpts().ModulesCodegen ||
2516a9ac8606Spatrick (FD->hasAttr<DLLExportAttr>() &&
2517a9ac8606Spatrick Writer->Context->getLangOpts().BuildingPCHWithObjectFile)) {
2518a9ac8606Spatrick
2519e5dd7070Spatrick // Under -fmodules-codegen, codegen is performed for all non-internal,
2520e5dd7070Spatrick // non-always_inline functions, unless they are available elsewhere.
2521e5dd7070Spatrick if (!FD->hasAttr<AlwaysInlineAttr>()) {
2522e5dd7070Spatrick if (!Linkage)
2523e5dd7070Spatrick Linkage = Writer->Context->GetGVALinkageForFunction(FD);
2524e5dd7070Spatrick ModulesCodegen =
2525e5dd7070Spatrick *Linkage != GVA_Internal && *Linkage != GVA_AvailableExternally;
2526e5dd7070Spatrick }
2527e5dd7070Spatrick }
2528e5dd7070Spatrick }
2529e5dd7070Spatrick Record->push_back(ModulesCodegen);
2530e5dd7070Spatrick if (ModulesCodegen)
2531e5dd7070Spatrick Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD));
2532e5dd7070Spatrick if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
2533e5dd7070Spatrick Record->push_back(CD->getNumCtorInitializers());
2534e5dd7070Spatrick if (CD->getNumCtorInitializers())
2535*12c85518Srobert AddCXXCtorInitializers(llvm::ArrayRef(CD->init_begin(), CD->init_end()));
2536e5dd7070Spatrick }
2537e5dd7070Spatrick AddStmt(FD->getBody());
2538e5dd7070Spatrick }
2539