1f4a2713aSLionel Sambuc //===--- ASTReaderDecl.cpp - Decl Deserialization ---------------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the ASTReader::ReadDeclRecord method, which is the
11f4a2713aSLionel Sambuc // entrypoint for loading a decl.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "clang/Serialization/ASTReader.h"
16f4a2713aSLionel Sambuc #include "ASTCommon.h"
17f4a2713aSLionel Sambuc #include "ASTReaderInternals.h"
18f4a2713aSLionel Sambuc #include "clang/AST/ASTConsumer.h"
19f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
20f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
21f4a2713aSLionel Sambuc #include "clang/AST/DeclGroup.h"
22f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
23f4a2713aSLionel Sambuc #include "clang/AST/DeclVisitor.h"
24f4a2713aSLionel Sambuc #include "clang/AST/Expr.h"
25f4a2713aSLionel Sambuc #include "clang/Sema/IdentifierResolver.h"
26f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
27f4a2713aSLionel Sambuc #include "clang/Sema/SemaDiagnostic.h"
28f4a2713aSLionel Sambuc #include "llvm/Support/SaveAndRestore.h"
29f4a2713aSLionel Sambuc using namespace clang;
30f4a2713aSLionel Sambuc using namespace clang::serialization;
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
33f4a2713aSLionel Sambuc // Declaration deserialization
34f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
35f4a2713aSLionel Sambuc
36f4a2713aSLionel Sambuc namespace clang {
37f4a2713aSLionel Sambuc class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> {
38f4a2713aSLionel Sambuc ASTReader &Reader;
39f4a2713aSLionel Sambuc ModuleFile &F;
40f4a2713aSLionel Sambuc const DeclID ThisDeclID;
41f4a2713aSLionel Sambuc const unsigned RawLocation;
42f4a2713aSLionel Sambuc typedef ASTReader::RecordData RecordData;
43f4a2713aSLionel Sambuc const RecordData &Record;
44f4a2713aSLionel Sambuc unsigned &Idx;
45f4a2713aSLionel Sambuc TypeID TypeIDForTypeDecl;
46*0a6a1f1dSLionel Sambuc unsigned AnonymousDeclNumber;
47*0a6a1f1dSLionel Sambuc GlobalDeclID NamedDeclForTagDecl;
48*0a6a1f1dSLionel Sambuc IdentifierInfo *TypedefNameForLinkage;
49f4a2713aSLionel Sambuc
50f4a2713aSLionel Sambuc bool HasPendingBody;
51f4a2713aSLionel Sambuc
52f4a2713aSLionel Sambuc uint64_t GetCurrentCursorOffset();
53f4a2713aSLionel Sambuc
ReadSourceLocation(const RecordData & R,unsigned & I)54f4a2713aSLionel Sambuc SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) {
55f4a2713aSLionel Sambuc return Reader.ReadSourceLocation(F, R, I);
56f4a2713aSLionel Sambuc }
57f4a2713aSLionel Sambuc
ReadSourceRange(const RecordData & R,unsigned & I)58f4a2713aSLionel Sambuc SourceRange ReadSourceRange(const RecordData &R, unsigned &I) {
59f4a2713aSLionel Sambuc return Reader.ReadSourceRange(F, R, I);
60f4a2713aSLionel Sambuc }
61f4a2713aSLionel Sambuc
GetTypeSourceInfo(const RecordData & R,unsigned & I)62f4a2713aSLionel Sambuc TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) {
63f4a2713aSLionel Sambuc return Reader.GetTypeSourceInfo(F, R, I);
64f4a2713aSLionel Sambuc }
65f4a2713aSLionel Sambuc
ReadDeclID(const RecordData & R,unsigned & I)66f4a2713aSLionel Sambuc serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
67f4a2713aSLionel Sambuc return Reader.ReadDeclID(F, R, I);
68f4a2713aSLionel Sambuc }
69f4a2713aSLionel Sambuc
ReadDecl(const RecordData & R,unsigned & I)70f4a2713aSLionel Sambuc Decl *ReadDecl(const RecordData &R, unsigned &I) {
71f4a2713aSLionel Sambuc return Reader.ReadDecl(F, R, I);
72f4a2713aSLionel Sambuc }
73f4a2713aSLionel Sambuc
74f4a2713aSLionel Sambuc template<typename T>
ReadDeclAs(const RecordData & R,unsigned & I)75f4a2713aSLionel Sambuc T *ReadDeclAs(const RecordData &R, unsigned &I) {
76f4a2713aSLionel Sambuc return Reader.ReadDeclAs<T>(F, R, I);
77f4a2713aSLionel Sambuc }
78f4a2713aSLionel Sambuc
ReadQualifierInfo(QualifierInfo & Info,const RecordData & R,unsigned & I)79f4a2713aSLionel Sambuc void ReadQualifierInfo(QualifierInfo &Info,
80f4a2713aSLionel Sambuc const RecordData &R, unsigned &I) {
81f4a2713aSLionel Sambuc Reader.ReadQualifierInfo(F, Info, R, I);
82f4a2713aSLionel Sambuc }
83f4a2713aSLionel Sambuc
ReadDeclarationNameLoc(DeclarationNameLoc & DNLoc,DeclarationName Name,const RecordData & R,unsigned & I)84f4a2713aSLionel Sambuc void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name,
85f4a2713aSLionel Sambuc const RecordData &R, unsigned &I) {
86f4a2713aSLionel Sambuc Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I);
87f4a2713aSLionel Sambuc }
88f4a2713aSLionel Sambuc
ReadDeclarationNameInfo(DeclarationNameInfo & NameInfo,const RecordData & R,unsigned & I)89f4a2713aSLionel Sambuc void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo,
90f4a2713aSLionel Sambuc const RecordData &R, unsigned &I) {
91f4a2713aSLionel Sambuc Reader.ReadDeclarationNameInfo(F, NameInfo, R, I);
92f4a2713aSLionel Sambuc }
93f4a2713aSLionel Sambuc
readSubmoduleID(const RecordData & R,unsigned & I)94f4a2713aSLionel Sambuc serialization::SubmoduleID readSubmoduleID(const RecordData &R,
95f4a2713aSLionel Sambuc unsigned &I) {
96f4a2713aSLionel Sambuc if (I >= R.size())
97f4a2713aSLionel Sambuc return 0;
98f4a2713aSLionel Sambuc
99f4a2713aSLionel Sambuc return Reader.getGlobalSubmoduleID(F, R[I++]);
100f4a2713aSLionel Sambuc }
101f4a2713aSLionel Sambuc
readModule(const RecordData & R,unsigned & I)102f4a2713aSLionel Sambuc Module *readModule(const RecordData &R, unsigned &I) {
103f4a2713aSLionel Sambuc return Reader.getSubmodule(readSubmoduleID(R, I));
104f4a2713aSLionel Sambuc }
105f4a2713aSLionel Sambuc
106*0a6a1f1dSLionel Sambuc void ReadCXXRecordDefinition(CXXRecordDecl *D);
107f4a2713aSLionel Sambuc void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,
108f4a2713aSLionel Sambuc const RecordData &R, unsigned &I);
109*0a6a1f1dSLionel Sambuc void MergeDefinitionData(CXXRecordDecl *D,
110*0a6a1f1dSLionel Sambuc struct CXXRecordDecl::DefinitionData &NewDD);
111*0a6a1f1dSLionel Sambuc
112*0a6a1f1dSLionel Sambuc static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader,
113*0a6a1f1dSLionel Sambuc DeclContext *DC,
114*0a6a1f1dSLionel Sambuc unsigned Index);
115*0a6a1f1dSLionel Sambuc static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC,
116*0a6a1f1dSLionel Sambuc unsigned Index, NamedDecl *D);
117f4a2713aSLionel Sambuc
118f4a2713aSLionel Sambuc /// \brief RAII class used to capture the first ID within a redeclaration
119f4a2713aSLionel Sambuc /// chain and to introduce it into the list of pending redeclaration chains
120f4a2713aSLionel Sambuc /// on destruction.
121f4a2713aSLionel Sambuc ///
122*0a6a1f1dSLionel Sambuc /// The caller can choose not to introduce this ID into the list of pending
123*0a6a1f1dSLionel Sambuc /// redeclaration chains by calling \c suppress().
124f4a2713aSLionel Sambuc class RedeclarableResult {
125f4a2713aSLionel Sambuc ASTReader &Reader;
126f4a2713aSLionel Sambuc GlobalDeclID FirstID;
127f4a2713aSLionel Sambuc mutable bool Owning;
128f4a2713aSLionel Sambuc Decl::Kind DeclKind;
129f4a2713aSLionel Sambuc
130f4a2713aSLionel Sambuc void operator=(RedeclarableResult &) LLVM_DELETED_FUNCTION;
131f4a2713aSLionel Sambuc
132f4a2713aSLionel Sambuc public:
RedeclarableResult(ASTReader & Reader,GlobalDeclID FirstID,Decl::Kind DeclKind)133f4a2713aSLionel Sambuc RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
134f4a2713aSLionel Sambuc Decl::Kind DeclKind)
135f4a2713aSLionel Sambuc : Reader(Reader), FirstID(FirstID), Owning(true), DeclKind(DeclKind) { }
136f4a2713aSLionel Sambuc
RedeclarableResult(const RedeclarableResult & Other)137f4a2713aSLionel Sambuc RedeclarableResult(const RedeclarableResult &Other)
138f4a2713aSLionel Sambuc : Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning) ,
139f4a2713aSLionel Sambuc DeclKind(Other.DeclKind)
140f4a2713aSLionel Sambuc {
141f4a2713aSLionel Sambuc Other.Owning = false;
142f4a2713aSLionel Sambuc }
143f4a2713aSLionel Sambuc
~RedeclarableResult()144f4a2713aSLionel Sambuc ~RedeclarableResult() {
145f4a2713aSLionel Sambuc if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) &&
146*0a6a1f1dSLionel Sambuc Reader.PendingDeclChainsKnown.insert(FirstID).second)
147f4a2713aSLionel Sambuc Reader.PendingDeclChains.push_back(FirstID);
148f4a2713aSLionel Sambuc }
149f4a2713aSLionel Sambuc
150f4a2713aSLionel Sambuc /// \brief Retrieve the first ID.
getFirstID() const151f4a2713aSLionel Sambuc GlobalDeclID getFirstID() const { return FirstID; }
152f4a2713aSLionel Sambuc
153f4a2713aSLionel Sambuc /// \brief Do not introduce this declaration ID into the set of pending
154f4a2713aSLionel Sambuc /// declaration chains.
suppress()155f4a2713aSLionel Sambuc void suppress() {
156f4a2713aSLionel Sambuc Owning = false;
157f4a2713aSLionel Sambuc }
158f4a2713aSLionel Sambuc };
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambuc /// \brief Class used to capture the result of searching for an existing
161f4a2713aSLionel Sambuc /// declaration of a specific kind and name, along with the ability
162f4a2713aSLionel Sambuc /// to update the place where this result was found (the declaration
163f4a2713aSLionel Sambuc /// chain hanging off an identifier or the DeclContext we searched in)
164f4a2713aSLionel Sambuc /// if requested.
165f4a2713aSLionel Sambuc class FindExistingResult {
166f4a2713aSLionel Sambuc ASTReader &Reader;
167f4a2713aSLionel Sambuc NamedDecl *New;
168f4a2713aSLionel Sambuc NamedDecl *Existing;
169f4a2713aSLionel Sambuc mutable bool AddResult;
170f4a2713aSLionel Sambuc
171*0a6a1f1dSLionel Sambuc unsigned AnonymousDeclNumber;
172*0a6a1f1dSLionel Sambuc IdentifierInfo *TypedefNameForLinkage;
173*0a6a1f1dSLionel Sambuc
174f4a2713aSLionel Sambuc void operator=(FindExistingResult&) LLVM_DELETED_FUNCTION;
175f4a2713aSLionel Sambuc
176f4a2713aSLionel Sambuc public:
FindExistingResult(ASTReader & Reader)177f4a2713aSLionel Sambuc FindExistingResult(ASTReader &Reader)
178*0a6a1f1dSLionel Sambuc : Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false),
179*0a6a1f1dSLionel Sambuc AnonymousDeclNumber(0), TypedefNameForLinkage(0) {}
180f4a2713aSLionel Sambuc
FindExistingResult(ASTReader & Reader,NamedDecl * New,NamedDecl * Existing,unsigned AnonymousDeclNumber,IdentifierInfo * TypedefNameForLinkage)181*0a6a1f1dSLionel Sambuc FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing,
182*0a6a1f1dSLionel Sambuc unsigned AnonymousDeclNumber,
183*0a6a1f1dSLionel Sambuc IdentifierInfo *TypedefNameForLinkage)
184*0a6a1f1dSLionel Sambuc : Reader(Reader), New(New), Existing(Existing), AddResult(true),
185*0a6a1f1dSLionel Sambuc AnonymousDeclNumber(AnonymousDeclNumber),
186*0a6a1f1dSLionel Sambuc TypedefNameForLinkage(TypedefNameForLinkage) {}
187f4a2713aSLionel Sambuc
FindExistingResult(const FindExistingResult & Other)188f4a2713aSLionel Sambuc FindExistingResult(const FindExistingResult &Other)
189f4a2713aSLionel Sambuc : Reader(Other.Reader), New(Other.New), Existing(Other.Existing),
190*0a6a1f1dSLionel Sambuc AddResult(Other.AddResult),
191*0a6a1f1dSLionel Sambuc AnonymousDeclNumber(Other.AnonymousDeclNumber),
192*0a6a1f1dSLionel Sambuc TypedefNameForLinkage(Other.TypedefNameForLinkage) {
193f4a2713aSLionel Sambuc Other.AddResult = false;
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc ~FindExistingResult();
197f4a2713aSLionel Sambuc
198f4a2713aSLionel Sambuc /// \brief Suppress the addition of this result into the known set of
199f4a2713aSLionel Sambuc /// names.
suppress()200f4a2713aSLionel Sambuc void suppress() { AddResult = false; }
201f4a2713aSLionel Sambuc
operator NamedDecl*() const202f4a2713aSLionel Sambuc operator NamedDecl*() const { return Existing; }
203f4a2713aSLionel Sambuc
204f4a2713aSLionel Sambuc template<typename T>
operator T*() const205f4a2713aSLionel Sambuc operator T*() const { return dyn_cast_or_null<T>(Existing); }
206f4a2713aSLionel Sambuc };
207f4a2713aSLionel Sambuc
208f4a2713aSLionel Sambuc FindExistingResult findExisting(NamedDecl *D);
209f4a2713aSLionel Sambuc
210f4a2713aSLionel Sambuc public:
ASTDeclReader(ASTReader & Reader,ModuleFile & F,DeclID thisDeclID,unsigned RawLocation,const RecordData & Record,unsigned & Idx)211*0a6a1f1dSLionel Sambuc ASTDeclReader(ASTReader &Reader, ModuleFile &F, DeclID thisDeclID,
212*0a6a1f1dSLionel Sambuc unsigned RawLocation, const RecordData &Record, unsigned &Idx)
213f4a2713aSLionel Sambuc : Reader(Reader), F(F), ThisDeclID(thisDeclID),
214f4a2713aSLionel Sambuc RawLocation(RawLocation), Record(Record), Idx(Idx),
215*0a6a1f1dSLionel Sambuc TypeIDForTypeDecl(0), NamedDeclForTagDecl(0),
216*0a6a1f1dSLionel Sambuc TypedefNameForLinkage(nullptr), HasPendingBody(false) {}
217f4a2713aSLionel Sambuc
218*0a6a1f1dSLionel Sambuc template <typename DeclT>
219*0a6a1f1dSLionel Sambuc static void attachPreviousDeclImpl(ASTReader &Reader,
220*0a6a1f1dSLionel Sambuc Redeclarable<DeclT> *D, Decl *Previous);
221*0a6a1f1dSLionel Sambuc static void attachPreviousDeclImpl(ASTReader &Reader, ...);
222*0a6a1f1dSLionel Sambuc static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous);
223*0a6a1f1dSLionel Sambuc
224*0a6a1f1dSLionel Sambuc template <typename DeclT>
225*0a6a1f1dSLionel Sambuc static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest);
226*0a6a1f1dSLionel Sambuc static void attachLatestDeclImpl(...);
227f4a2713aSLionel Sambuc static void attachLatestDecl(Decl *D, Decl *latest);
228f4a2713aSLionel Sambuc
229*0a6a1f1dSLionel Sambuc template <typename DeclT>
230*0a6a1f1dSLionel Sambuc static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
231*0a6a1f1dSLionel Sambuc static void markIncompleteDeclChainImpl(...);
232*0a6a1f1dSLionel Sambuc
233f4a2713aSLionel Sambuc /// \brief Determine whether this declaration has a pending body.
hasPendingBody() const234f4a2713aSLionel Sambuc bool hasPendingBody() const { return HasPendingBody; }
235f4a2713aSLionel Sambuc
236f4a2713aSLionel Sambuc void Visit(Decl *D);
237f4a2713aSLionel Sambuc
238f4a2713aSLionel Sambuc void UpdateDecl(Decl *D, ModuleFile &ModuleFile,
239f4a2713aSLionel Sambuc const RecordData &Record);
240f4a2713aSLionel Sambuc
setNextObjCCategory(ObjCCategoryDecl * Cat,ObjCCategoryDecl * Next)241f4a2713aSLionel Sambuc static void setNextObjCCategory(ObjCCategoryDecl *Cat,
242f4a2713aSLionel Sambuc ObjCCategoryDecl *Next) {
243f4a2713aSLionel Sambuc Cat->NextClassCategory = Next;
244f4a2713aSLionel Sambuc }
245f4a2713aSLionel Sambuc
246f4a2713aSLionel Sambuc void VisitDecl(Decl *D);
247f4a2713aSLionel Sambuc void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
248f4a2713aSLionel Sambuc void VisitNamedDecl(NamedDecl *ND);
249f4a2713aSLionel Sambuc void VisitLabelDecl(LabelDecl *LD);
250f4a2713aSLionel Sambuc void VisitNamespaceDecl(NamespaceDecl *D);
251f4a2713aSLionel Sambuc void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
252f4a2713aSLionel Sambuc void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
253f4a2713aSLionel Sambuc void VisitTypeDecl(TypeDecl *TD);
254*0a6a1f1dSLionel Sambuc RedeclarableResult VisitTypedefNameDecl(TypedefNameDecl *TD);
255f4a2713aSLionel Sambuc void VisitTypedefDecl(TypedefDecl *TD);
256f4a2713aSLionel Sambuc void VisitTypeAliasDecl(TypeAliasDecl *TD);
257f4a2713aSLionel Sambuc void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
258f4a2713aSLionel Sambuc RedeclarableResult VisitTagDecl(TagDecl *TD);
259f4a2713aSLionel Sambuc void VisitEnumDecl(EnumDecl *ED);
260f4a2713aSLionel Sambuc RedeclarableResult VisitRecordDeclImpl(RecordDecl *RD);
VisitRecordDecl(RecordDecl * RD)261f4a2713aSLionel Sambuc void VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); }
262f4a2713aSLionel Sambuc RedeclarableResult VisitCXXRecordDeclImpl(CXXRecordDecl *D);
VisitCXXRecordDecl(CXXRecordDecl * D)263f4a2713aSLionel Sambuc void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); }
264f4a2713aSLionel Sambuc RedeclarableResult VisitClassTemplateSpecializationDeclImpl(
265f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl *D);
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)266f4a2713aSLionel Sambuc void VisitClassTemplateSpecializationDecl(
267f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl *D) {
268f4a2713aSLionel Sambuc VisitClassTemplateSpecializationDeclImpl(D);
269f4a2713aSLionel Sambuc }
270f4a2713aSLionel Sambuc void VisitClassTemplatePartialSpecializationDecl(
271f4a2713aSLionel Sambuc ClassTemplatePartialSpecializationDecl *D);
272f4a2713aSLionel Sambuc void VisitClassScopeFunctionSpecializationDecl(
273f4a2713aSLionel Sambuc ClassScopeFunctionSpecializationDecl *D);
274f4a2713aSLionel Sambuc RedeclarableResult
275f4a2713aSLionel Sambuc VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl *D);
VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * D)276f4a2713aSLionel Sambuc void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) {
277f4a2713aSLionel Sambuc VisitVarTemplateSpecializationDeclImpl(D);
278f4a2713aSLionel Sambuc }
279f4a2713aSLionel Sambuc void VisitVarTemplatePartialSpecializationDecl(
280f4a2713aSLionel Sambuc VarTemplatePartialSpecializationDecl *D);
281f4a2713aSLionel Sambuc void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
282f4a2713aSLionel Sambuc void VisitValueDecl(ValueDecl *VD);
283f4a2713aSLionel Sambuc void VisitEnumConstantDecl(EnumConstantDecl *ECD);
284f4a2713aSLionel Sambuc void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
285f4a2713aSLionel Sambuc void VisitDeclaratorDecl(DeclaratorDecl *DD);
286f4a2713aSLionel Sambuc void VisitFunctionDecl(FunctionDecl *FD);
287f4a2713aSLionel Sambuc void VisitCXXMethodDecl(CXXMethodDecl *D);
288f4a2713aSLionel Sambuc void VisitCXXConstructorDecl(CXXConstructorDecl *D);
289f4a2713aSLionel Sambuc void VisitCXXDestructorDecl(CXXDestructorDecl *D);
290f4a2713aSLionel Sambuc void VisitCXXConversionDecl(CXXConversionDecl *D);
291f4a2713aSLionel Sambuc void VisitFieldDecl(FieldDecl *FD);
292f4a2713aSLionel Sambuc void VisitMSPropertyDecl(MSPropertyDecl *FD);
293f4a2713aSLionel Sambuc void VisitIndirectFieldDecl(IndirectFieldDecl *FD);
294f4a2713aSLionel Sambuc RedeclarableResult VisitVarDeclImpl(VarDecl *D);
VisitVarDecl(VarDecl * VD)295f4a2713aSLionel Sambuc void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); }
296f4a2713aSLionel Sambuc void VisitImplicitParamDecl(ImplicitParamDecl *PD);
297f4a2713aSLionel Sambuc void VisitParmVarDecl(ParmVarDecl *PD);
298f4a2713aSLionel Sambuc void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
299*0a6a1f1dSLionel Sambuc DeclID VisitTemplateDecl(TemplateDecl *D);
300f4a2713aSLionel Sambuc RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
301f4a2713aSLionel Sambuc void VisitClassTemplateDecl(ClassTemplateDecl *D);
302f4a2713aSLionel Sambuc void VisitVarTemplateDecl(VarTemplateDecl *D);
303f4a2713aSLionel Sambuc void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
304f4a2713aSLionel Sambuc void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
305f4a2713aSLionel Sambuc void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
306f4a2713aSLionel Sambuc void VisitUsingDecl(UsingDecl *D);
307f4a2713aSLionel Sambuc void VisitUsingShadowDecl(UsingShadowDecl *D);
308f4a2713aSLionel Sambuc void VisitLinkageSpecDecl(LinkageSpecDecl *D);
309f4a2713aSLionel Sambuc void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
310f4a2713aSLionel Sambuc void VisitImportDecl(ImportDecl *D);
311f4a2713aSLionel Sambuc void VisitAccessSpecDecl(AccessSpecDecl *D);
312f4a2713aSLionel Sambuc void VisitFriendDecl(FriendDecl *D);
313f4a2713aSLionel Sambuc void VisitFriendTemplateDecl(FriendTemplateDecl *D);
314f4a2713aSLionel Sambuc void VisitStaticAssertDecl(StaticAssertDecl *D);
315f4a2713aSLionel Sambuc void VisitBlockDecl(BlockDecl *BD);
316f4a2713aSLionel Sambuc void VisitCapturedDecl(CapturedDecl *CD);
317f4a2713aSLionel Sambuc void VisitEmptyDecl(EmptyDecl *D);
318f4a2713aSLionel Sambuc
319f4a2713aSLionel Sambuc std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
320f4a2713aSLionel Sambuc
321f4a2713aSLionel Sambuc template<typename T>
322f4a2713aSLionel Sambuc RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
323f4a2713aSLionel Sambuc
324f4a2713aSLionel Sambuc template<typename T>
325*0a6a1f1dSLionel Sambuc void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl,
326*0a6a1f1dSLionel Sambuc DeclID TemplatePatternID = 0);
327f4a2713aSLionel Sambuc
328f4a2713aSLionel Sambuc template<typename T>
329f4a2713aSLionel Sambuc void mergeRedeclarable(Redeclarable<T> *D, T *Existing,
330*0a6a1f1dSLionel Sambuc RedeclarableResult &Redecl,
331*0a6a1f1dSLionel Sambuc DeclID TemplatePatternID = 0);
332f4a2713aSLionel Sambuc
333f4a2713aSLionel Sambuc template<typename T>
334f4a2713aSLionel Sambuc void mergeMergeable(Mergeable<T> *D);
335f4a2713aSLionel Sambuc
336*0a6a1f1dSLionel Sambuc void mergeTemplatePattern(RedeclarableTemplateDecl *D,
337*0a6a1f1dSLionel Sambuc RedeclarableTemplateDecl *Existing,
338*0a6a1f1dSLionel Sambuc DeclID DsID);
339*0a6a1f1dSLionel Sambuc
340f4a2713aSLionel Sambuc // FIXME: Reorder according to DeclNodes.td?
341f4a2713aSLionel Sambuc void VisitObjCMethodDecl(ObjCMethodDecl *D);
342f4a2713aSLionel Sambuc void VisitObjCContainerDecl(ObjCContainerDecl *D);
343f4a2713aSLionel Sambuc void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
344f4a2713aSLionel Sambuc void VisitObjCIvarDecl(ObjCIvarDecl *D);
345f4a2713aSLionel Sambuc void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
346f4a2713aSLionel Sambuc void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
347f4a2713aSLionel Sambuc void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
348f4a2713aSLionel Sambuc void VisitObjCImplDecl(ObjCImplDecl *D);
349f4a2713aSLionel Sambuc void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
350f4a2713aSLionel Sambuc void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
351f4a2713aSLionel Sambuc void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
352f4a2713aSLionel Sambuc void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
353f4a2713aSLionel Sambuc void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
354f4a2713aSLionel Sambuc void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
355f4a2713aSLionel Sambuc };
356f4a2713aSLionel Sambuc }
357f4a2713aSLionel Sambuc
GetCurrentCursorOffset()358f4a2713aSLionel Sambuc uint64_t ASTDeclReader::GetCurrentCursorOffset() {
359f4a2713aSLionel Sambuc return F.DeclsCursor.GetCurrentBitNo() + F.GlobalBitOffset;
360f4a2713aSLionel Sambuc }
361f4a2713aSLionel Sambuc
Visit(Decl * D)362f4a2713aSLionel Sambuc void ASTDeclReader::Visit(Decl *D) {
363f4a2713aSLionel Sambuc DeclVisitor<ASTDeclReader, void>::Visit(D);
364f4a2713aSLionel Sambuc
365f4a2713aSLionel Sambuc if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
366f4a2713aSLionel Sambuc if (DD->DeclInfo) {
367f4a2713aSLionel Sambuc DeclaratorDecl::ExtInfo *Info =
368f4a2713aSLionel Sambuc DD->DeclInfo.get<DeclaratorDecl::ExtInfo *>();
369f4a2713aSLionel Sambuc Info->TInfo =
370f4a2713aSLionel Sambuc GetTypeSourceInfo(Record, Idx);
371f4a2713aSLionel Sambuc }
372f4a2713aSLionel Sambuc else {
373f4a2713aSLionel Sambuc DD->DeclInfo = GetTypeSourceInfo(Record, Idx);
374f4a2713aSLionel Sambuc }
375f4a2713aSLionel Sambuc }
376f4a2713aSLionel Sambuc
377f4a2713aSLionel Sambuc if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
378*0a6a1f1dSLionel Sambuc // We have a fully initialized TypeDecl. Read its type now.
379f4a2713aSLionel Sambuc TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
380*0a6a1f1dSLionel Sambuc
381*0a6a1f1dSLionel Sambuc // If this is a tag declaration with a typedef name for linkage, it's safe
382*0a6a1f1dSLionel Sambuc // to load that typedef now.
383*0a6a1f1dSLionel Sambuc if (NamedDeclForTagDecl)
384*0a6a1f1dSLionel Sambuc cast<TagDecl>(D)->NamedDeclOrQualifier =
385*0a6a1f1dSLionel Sambuc cast<NamedDecl>(Reader.GetDecl(NamedDeclForTagDecl));
386f4a2713aSLionel Sambuc } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
387f4a2713aSLionel Sambuc // if we have a fully initialized TypeDecl, we can safely read its type now.
388f4a2713aSLionel Sambuc ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
389f4a2713aSLionel Sambuc } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
390f4a2713aSLionel Sambuc // FunctionDecl's body was written last after all other Stmts/Exprs.
391f4a2713aSLionel Sambuc // We only read it if FD doesn't already have a body (e.g., from another
392f4a2713aSLionel Sambuc // module).
393f4a2713aSLionel Sambuc // FIXME: Also consider = default and = delete.
394f4a2713aSLionel Sambuc // FIXME: Can we diagnose ODR violations somehow?
395f4a2713aSLionel Sambuc if (Record[Idx++]) {
396f4a2713aSLionel Sambuc Reader.PendingBodies[FD] = GetCurrentCursorOffset();
397f4a2713aSLionel Sambuc HasPendingBody = true;
398f4a2713aSLionel Sambuc }
399f4a2713aSLionel Sambuc }
400f4a2713aSLionel Sambuc }
401f4a2713aSLionel Sambuc
VisitDecl(Decl * D)402f4a2713aSLionel Sambuc void ASTDeclReader::VisitDecl(Decl *D) {
403*0a6a1f1dSLionel Sambuc if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
404*0a6a1f1dSLionel Sambuc isa<ParmVarDecl>(D)) {
405f4a2713aSLionel Sambuc // We don't want to deserialize the DeclContext of a template
406*0a6a1f1dSLionel Sambuc // parameter or of a parameter of a function template immediately. These
407*0a6a1f1dSLionel Sambuc // entities might be used in the formulation of its DeclContext (for
408*0a6a1f1dSLionel Sambuc // example, a function parameter can be used in decltype() in trailing
409*0a6a1f1dSLionel Sambuc // return type of the function). Use the translation unit DeclContext as a
410*0a6a1f1dSLionel Sambuc // placeholder.
411f4a2713aSLionel Sambuc GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
412f4a2713aSLionel Sambuc GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx);
413f4a2713aSLionel Sambuc Reader.addPendingDeclContextInfo(D,
414f4a2713aSLionel Sambuc SemaDCIDForTemplateParmDecl,
415f4a2713aSLionel Sambuc LexicalDCIDForTemplateParmDecl);
416f4a2713aSLionel Sambuc D->setDeclContext(Reader.getContext().getTranslationUnitDecl());
417f4a2713aSLionel Sambuc } else {
418f4a2713aSLionel Sambuc DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
419f4a2713aSLionel Sambuc DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx);
420f4a2713aSLionel Sambuc DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC);
421f4a2713aSLionel Sambuc // Avoid calling setLexicalDeclContext() directly because it uses
422f4a2713aSLionel Sambuc // Decl::getASTContext() internally which is unsafe during derialization.
423f4a2713aSLionel Sambuc D->setDeclContextsImpl(MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC,
424f4a2713aSLionel Sambuc Reader.getContext());
425f4a2713aSLionel Sambuc }
426f4a2713aSLionel Sambuc D->setLocation(Reader.ReadSourceLocation(F, RawLocation));
427f4a2713aSLionel Sambuc D->setInvalidDecl(Record[Idx++]);
428f4a2713aSLionel Sambuc if (Record[Idx++]) { // hasAttrs
429f4a2713aSLionel Sambuc AttrVec Attrs;
430f4a2713aSLionel Sambuc Reader.ReadAttributes(F, Attrs, Record, Idx);
431f4a2713aSLionel Sambuc // Avoid calling setAttrs() directly because it uses Decl::getASTContext()
432f4a2713aSLionel Sambuc // internally which is unsafe during derialization.
433f4a2713aSLionel Sambuc D->setAttrsImpl(Attrs, Reader.getContext());
434f4a2713aSLionel Sambuc }
435f4a2713aSLionel Sambuc D->setImplicit(Record[Idx++]);
436f4a2713aSLionel Sambuc D->Used = Record[Idx++];
437f4a2713aSLionel Sambuc D->setReferenced(Record[Idx++]);
438f4a2713aSLionel Sambuc D->setTopLevelDeclInObjCContainer(Record[Idx++]);
439f4a2713aSLionel Sambuc D->setAccess((AccessSpecifier)Record[Idx++]);
440f4a2713aSLionel Sambuc D->FromASTFile = true;
441f4a2713aSLionel Sambuc D->setModulePrivate(Record[Idx++]);
442f4a2713aSLionel Sambuc D->Hidden = D->isModulePrivate();
443f4a2713aSLionel Sambuc
444f4a2713aSLionel Sambuc // Determine whether this declaration is part of a (sub)module. If so, it
445f4a2713aSLionel Sambuc // may not yet be visible.
446f4a2713aSLionel Sambuc if (unsigned SubmoduleID = readSubmoduleID(Record, Idx)) {
447f4a2713aSLionel Sambuc // Store the owning submodule ID in the declaration.
448f4a2713aSLionel Sambuc D->setOwningModuleID(SubmoduleID);
449f4a2713aSLionel Sambuc
450f4a2713aSLionel Sambuc // Module-private declarations are never visible, so there is no work to do.
451f4a2713aSLionel Sambuc if (!D->isModulePrivate()) {
452f4a2713aSLionel Sambuc if (Module *Owner = Reader.getSubmodule(SubmoduleID)) {
453f4a2713aSLionel Sambuc if (Owner->NameVisibility != Module::AllVisible) {
454f4a2713aSLionel Sambuc // The owning module is not visible. Mark this declaration as hidden.
455f4a2713aSLionel Sambuc D->Hidden = true;
456f4a2713aSLionel Sambuc
457f4a2713aSLionel Sambuc // Note that this declaration was hidden because its owning module is
458f4a2713aSLionel Sambuc // not yet visible.
459*0a6a1f1dSLionel Sambuc Reader.HiddenNamesMap[Owner].HiddenDecls.push_back(D);
460f4a2713aSLionel Sambuc }
461f4a2713aSLionel Sambuc }
462f4a2713aSLionel Sambuc }
463f4a2713aSLionel Sambuc }
464f4a2713aSLionel Sambuc }
465f4a2713aSLionel Sambuc
VisitTranslationUnitDecl(TranslationUnitDecl * TU)466f4a2713aSLionel Sambuc void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
467f4a2713aSLionel Sambuc llvm_unreachable("Translation units are not serialized");
468f4a2713aSLionel Sambuc }
469f4a2713aSLionel Sambuc
VisitNamedDecl(NamedDecl * ND)470f4a2713aSLionel Sambuc void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) {
471f4a2713aSLionel Sambuc VisitDecl(ND);
472f4a2713aSLionel Sambuc ND->setDeclName(Reader.ReadDeclarationName(F, Record, Idx));
473*0a6a1f1dSLionel Sambuc if (needsAnonymousDeclarationNumber(ND))
474*0a6a1f1dSLionel Sambuc AnonymousDeclNumber = Record[Idx++];
475f4a2713aSLionel Sambuc }
476f4a2713aSLionel Sambuc
VisitTypeDecl(TypeDecl * TD)477f4a2713aSLionel Sambuc void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
478f4a2713aSLionel Sambuc VisitNamedDecl(TD);
479f4a2713aSLionel Sambuc TD->setLocStart(ReadSourceLocation(Record, Idx));
480f4a2713aSLionel Sambuc // Delay type reading until after we have fully initialized the decl.
481f4a2713aSLionel Sambuc TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
482f4a2713aSLionel Sambuc }
483f4a2713aSLionel Sambuc
484*0a6a1f1dSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitTypedefNameDecl(TypedefNameDecl * TD)485*0a6a1f1dSLionel Sambuc ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
486f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(TD);
487f4a2713aSLionel Sambuc VisitTypeDecl(TD);
488f4a2713aSLionel Sambuc TypeSourceInfo *TInfo = GetTypeSourceInfo(Record, Idx);
489f4a2713aSLionel Sambuc if (Record[Idx++]) { // isModed
490f4a2713aSLionel Sambuc QualType modedT = Reader.readType(F, Record, Idx);
491f4a2713aSLionel Sambuc TD->setModedTypeSourceInfo(TInfo, modedT);
492f4a2713aSLionel Sambuc } else
493f4a2713aSLionel Sambuc TD->setTypeSourceInfo(TInfo);
494*0a6a1f1dSLionel Sambuc return Redecl;
495f4a2713aSLionel Sambuc }
496f4a2713aSLionel Sambuc
VisitTypedefDecl(TypedefDecl * TD)497f4a2713aSLionel Sambuc void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
498*0a6a1f1dSLionel Sambuc RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
499*0a6a1f1dSLionel Sambuc mergeRedeclarable(TD, Redecl);
500f4a2713aSLionel Sambuc }
501f4a2713aSLionel Sambuc
VisitTypeAliasDecl(TypeAliasDecl * TD)502f4a2713aSLionel Sambuc void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) {
503*0a6a1f1dSLionel Sambuc RedeclarableResult Redecl = VisitTypedefNameDecl(TD);
504*0a6a1f1dSLionel Sambuc if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>(Record, Idx))
505*0a6a1f1dSLionel Sambuc // Merged when we merge the template.
506*0a6a1f1dSLionel Sambuc TD->setDescribedAliasTemplate(Template);
507*0a6a1f1dSLionel Sambuc else
508*0a6a1f1dSLionel Sambuc mergeRedeclarable(TD, Redecl);
509f4a2713aSLionel Sambuc }
510f4a2713aSLionel Sambuc
VisitTagDecl(TagDecl * TD)511f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) {
512f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(TD);
513f4a2713aSLionel Sambuc VisitTypeDecl(TD);
514f4a2713aSLionel Sambuc
515f4a2713aSLionel Sambuc TD->IdentifierNamespace = Record[Idx++];
516f4a2713aSLionel Sambuc TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
517*0a6a1f1dSLionel Sambuc if (!isa<CXXRecordDecl>(TD))
518f4a2713aSLionel Sambuc TD->setCompleteDefinition(Record[Idx++]);
519f4a2713aSLionel Sambuc TD->setEmbeddedInDeclarator(Record[Idx++]);
520f4a2713aSLionel Sambuc TD->setFreeStanding(Record[Idx++]);
521f4a2713aSLionel Sambuc TD->setCompleteDefinitionRequired(Record[Idx++]);
522f4a2713aSLionel Sambuc TD->setRBraceLoc(ReadSourceLocation(Record, Idx));
523f4a2713aSLionel Sambuc
524*0a6a1f1dSLionel Sambuc switch (Record[Idx++]) {
525*0a6a1f1dSLionel Sambuc case 0:
526*0a6a1f1dSLionel Sambuc break;
527*0a6a1f1dSLionel Sambuc case 1: { // ExtInfo
528f4a2713aSLionel Sambuc TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo();
529f4a2713aSLionel Sambuc ReadQualifierInfo(*Info, Record, Idx);
530f4a2713aSLionel Sambuc TD->NamedDeclOrQualifier = Info;
531*0a6a1f1dSLionel Sambuc break;
532*0a6a1f1dSLionel Sambuc }
533*0a6a1f1dSLionel Sambuc case 2: // TypedefNameForAnonDecl
534*0a6a1f1dSLionel Sambuc NamedDeclForTagDecl = ReadDeclID(Record, Idx);
535*0a6a1f1dSLionel Sambuc TypedefNameForLinkage = Reader.GetIdentifierInfo(F, Record, Idx);
536*0a6a1f1dSLionel Sambuc break;
537*0a6a1f1dSLionel Sambuc case 3: // DeclaratorForAnonDecl
538*0a6a1f1dSLionel Sambuc NamedDeclForTagDecl = ReadDeclID(Record, Idx);
539*0a6a1f1dSLionel Sambuc break;
540*0a6a1f1dSLionel Sambuc default:
541*0a6a1f1dSLionel Sambuc llvm_unreachable("unexpected tag info kind");
542*0a6a1f1dSLionel Sambuc }
543f4a2713aSLionel Sambuc
544*0a6a1f1dSLionel Sambuc if (!isa<CXXRecordDecl>(TD))
545f4a2713aSLionel Sambuc mergeRedeclarable(TD, Redecl);
546f4a2713aSLionel Sambuc return Redecl;
547f4a2713aSLionel Sambuc }
548f4a2713aSLionel Sambuc
VisitEnumDecl(EnumDecl * ED)549f4a2713aSLionel Sambuc void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
550f4a2713aSLionel Sambuc VisitTagDecl(ED);
551f4a2713aSLionel Sambuc if (TypeSourceInfo *TI = Reader.GetTypeSourceInfo(F, Record, Idx))
552f4a2713aSLionel Sambuc ED->setIntegerTypeSourceInfo(TI);
553f4a2713aSLionel Sambuc else
554f4a2713aSLionel Sambuc ED->setIntegerType(Reader.readType(F, Record, Idx));
555f4a2713aSLionel Sambuc ED->setPromotionType(Reader.readType(F, Record, Idx));
556f4a2713aSLionel Sambuc ED->setNumPositiveBits(Record[Idx++]);
557f4a2713aSLionel Sambuc ED->setNumNegativeBits(Record[Idx++]);
558f4a2713aSLionel Sambuc ED->IsScoped = Record[Idx++];
559f4a2713aSLionel Sambuc ED->IsScopedUsingClassTag = Record[Idx++];
560f4a2713aSLionel Sambuc ED->IsFixed = Record[Idx++];
561f4a2713aSLionel Sambuc
562f4a2713aSLionel Sambuc // If this is a definition subject to the ODR, and we already have a
563f4a2713aSLionel Sambuc // definition, merge this one into it.
564f4a2713aSLionel Sambuc if (ED->IsCompleteDefinition &&
565f4a2713aSLionel Sambuc Reader.getContext().getLangOpts().Modules &&
566f4a2713aSLionel Sambuc Reader.getContext().getLangOpts().CPlusPlus) {
567f4a2713aSLionel Sambuc if (EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]) {
568f4a2713aSLionel Sambuc Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
569f4a2713aSLionel Sambuc ED->IsCompleteDefinition = false;
570f4a2713aSLionel Sambuc } else {
571f4a2713aSLionel Sambuc OldDef = ED;
572f4a2713aSLionel Sambuc }
573f4a2713aSLionel Sambuc }
574f4a2713aSLionel Sambuc
575f4a2713aSLionel Sambuc if (EnumDecl *InstED = ReadDeclAs<EnumDecl>(Record, Idx)) {
576f4a2713aSLionel Sambuc TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
577f4a2713aSLionel Sambuc SourceLocation POI = ReadSourceLocation(Record, Idx);
578f4a2713aSLionel Sambuc ED->setInstantiationOfMemberEnum(Reader.getContext(), InstED, TSK);
579f4a2713aSLionel Sambuc ED->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
580f4a2713aSLionel Sambuc }
581f4a2713aSLionel Sambuc }
582f4a2713aSLionel Sambuc
583f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitRecordDeclImpl(RecordDecl * RD)584f4a2713aSLionel Sambuc ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
585f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitTagDecl(RD);
586f4a2713aSLionel Sambuc RD->setHasFlexibleArrayMember(Record[Idx++]);
587f4a2713aSLionel Sambuc RD->setAnonymousStructOrUnion(Record[Idx++]);
588f4a2713aSLionel Sambuc RD->setHasObjectMember(Record[Idx++]);
589f4a2713aSLionel Sambuc RD->setHasVolatileMember(Record[Idx++]);
590f4a2713aSLionel Sambuc return Redecl;
591f4a2713aSLionel Sambuc }
592f4a2713aSLionel Sambuc
VisitValueDecl(ValueDecl * VD)593f4a2713aSLionel Sambuc void ASTDeclReader::VisitValueDecl(ValueDecl *VD) {
594f4a2713aSLionel Sambuc VisitNamedDecl(VD);
595f4a2713aSLionel Sambuc VD->setType(Reader.readType(F, Record, Idx));
596f4a2713aSLionel Sambuc }
597f4a2713aSLionel Sambuc
VisitEnumConstantDecl(EnumConstantDecl * ECD)598f4a2713aSLionel Sambuc void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
599f4a2713aSLionel Sambuc VisitValueDecl(ECD);
600f4a2713aSLionel Sambuc if (Record[Idx++])
601f4a2713aSLionel Sambuc ECD->setInitExpr(Reader.ReadExpr(F));
602f4a2713aSLionel Sambuc ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
603f4a2713aSLionel Sambuc mergeMergeable(ECD);
604f4a2713aSLionel Sambuc }
605f4a2713aSLionel Sambuc
VisitDeclaratorDecl(DeclaratorDecl * DD)606f4a2713aSLionel Sambuc void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {
607f4a2713aSLionel Sambuc VisitValueDecl(DD);
608f4a2713aSLionel Sambuc DD->setInnerLocStart(ReadSourceLocation(Record, Idx));
609f4a2713aSLionel Sambuc if (Record[Idx++]) { // hasExtInfo
610f4a2713aSLionel Sambuc DeclaratorDecl::ExtInfo *Info
611f4a2713aSLionel Sambuc = new (Reader.getContext()) DeclaratorDecl::ExtInfo();
612f4a2713aSLionel Sambuc ReadQualifierInfo(*Info, Record, Idx);
613f4a2713aSLionel Sambuc DD->DeclInfo = Info;
614f4a2713aSLionel Sambuc }
615f4a2713aSLionel Sambuc }
616f4a2713aSLionel Sambuc
VisitFunctionDecl(FunctionDecl * FD)617f4a2713aSLionel Sambuc void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
618f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(FD);
619f4a2713aSLionel Sambuc VisitDeclaratorDecl(FD);
620f4a2713aSLionel Sambuc
621f4a2713aSLionel Sambuc ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName(), Record, Idx);
622f4a2713aSLionel Sambuc FD->IdentifierNamespace = Record[Idx++];
623f4a2713aSLionel Sambuc
624f4a2713aSLionel Sambuc // FunctionDecl's body is handled last at ASTDeclReader::Visit,
625f4a2713aSLionel Sambuc // after everything else is read.
626f4a2713aSLionel Sambuc
627f4a2713aSLionel Sambuc FD->SClass = (StorageClass)Record[Idx++];
628f4a2713aSLionel Sambuc FD->IsInline = Record[Idx++];
629f4a2713aSLionel Sambuc FD->IsInlineSpecified = Record[Idx++];
630f4a2713aSLionel Sambuc FD->IsVirtualAsWritten = Record[Idx++];
631f4a2713aSLionel Sambuc FD->IsPure = Record[Idx++];
632f4a2713aSLionel Sambuc FD->HasInheritedPrototype = Record[Idx++];
633f4a2713aSLionel Sambuc FD->HasWrittenPrototype = Record[Idx++];
634f4a2713aSLionel Sambuc FD->IsDeleted = Record[Idx++];
635f4a2713aSLionel Sambuc FD->IsTrivial = Record[Idx++];
636f4a2713aSLionel Sambuc FD->IsDefaulted = Record[Idx++];
637f4a2713aSLionel Sambuc FD->IsExplicitlyDefaulted = Record[Idx++];
638f4a2713aSLionel Sambuc FD->HasImplicitReturnZero = Record[Idx++];
639f4a2713aSLionel Sambuc FD->IsConstexpr = Record[Idx++];
640f4a2713aSLionel Sambuc FD->HasSkippedBody = Record[Idx++];
641f4a2713aSLionel Sambuc FD->IsLateTemplateParsed = Record[Idx++];
642f4a2713aSLionel Sambuc FD->setCachedLinkage(Linkage(Record[Idx++]));
643f4a2713aSLionel Sambuc FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
644f4a2713aSLionel Sambuc
645f4a2713aSLionel Sambuc switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
646f4a2713aSLionel Sambuc case FunctionDecl::TK_NonTemplate:
647f4a2713aSLionel Sambuc mergeRedeclarable(FD, Redecl);
648f4a2713aSLionel Sambuc break;
649f4a2713aSLionel Sambuc case FunctionDecl::TK_FunctionTemplate:
650*0a6a1f1dSLionel Sambuc // Merged when we merge the template.
651f4a2713aSLionel Sambuc FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>(Record,
652f4a2713aSLionel Sambuc Idx));
653f4a2713aSLionel Sambuc break;
654f4a2713aSLionel Sambuc case FunctionDecl::TK_MemberSpecialization: {
655f4a2713aSLionel Sambuc FunctionDecl *InstFD = ReadDeclAs<FunctionDecl>(Record, Idx);
656f4a2713aSLionel Sambuc TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
657f4a2713aSLionel Sambuc SourceLocation POI = ReadSourceLocation(Record, Idx);
658f4a2713aSLionel Sambuc FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
659f4a2713aSLionel Sambuc FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
660*0a6a1f1dSLionel Sambuc mergeRedeclarable(FD, Redecl);
661f4a2713aSLionel Sambuc break;
662f4a2713aSLionel Sambuc }
663f4a2713aSLionel Sambuc case FunctionDecl::TK_FunctionTemplateSpecialization: {
664f4a2713aSLionel Sambuc FunctionTemplateDecl *Template = ReadDeclAs<FunctionTemplateDecl>(Record,
665f4a2713aSLionel Sambuc Idx);
666f4a2713aSLionel Sambuc TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
667f4a2713aSLionel Sambuc
668f4a2713aSLionel Sambuc // Template arguments.
669f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> TemplArgs;
670f4a2713aSLionel Sambuc Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
671f4a2713aSLionel Sambuc
672f4a2713aSLionel Sambuc // Template args as written.
673f4a2713aSLionel Sambuc SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
674f4a2713aSLionel Sambuc SourceLocation LAngleLoc, RAngleLoc;
675f4a2713aSLionel Sambuc bool HasTemplateArgumentsAsWritten = Record[Idx++];
676f4a2713aSLionel Sambuc if (HasTemplateArgumentsAsWritten) {
677f4a2713aSLionel Sambuc unsigned NumTemplateArgLocs = Record[Idx++];
678f4a2713aSLionel Sambuc TemplArgLocs.reserve(NumTemplateArgLocs);
679f4a2713aSLionel Sambuc for (unsigned i=0; i != NumTemplateArgLocs; ++i)
680f4a2713aSLionel Sambuc TemplArgLocs.push_back(
681f4a2713aSLionel Sambuc Reader.ReadTemplateArgumentLoc(F, Record, Idx));
682f4a2713aSLionel Sambuc
683f4a2713aSLionel Sambuc LAngleLoc = ReadSourceLocation(Record, Idx);
684f4a2713aSLionel Sambuc RAngleLoc = ReadSourceLocation(Record, Idx);
685f4a2713aSLionel Sambuc }
686f4a2713aSLionel Sambuc
687f4a2713aSLionel Sambuc SourceLocation POI = ReadSourceLocation(Record, Idx);
688f4a2713aSLionel Sambuc
689f4a2713aSLionel Sambuc ASTContext &C = Reader.getContext();
690f4a2713aSLionel Sambuc TemplateArgumentList *TemplArgList
691f4a2713aSLionel Sambuc = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
692f4a2713aSLionel Sambuc TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
693f4a2713aSLionel Sambuc for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
694f4a2713aSLionel Sambuc TemplArgsInfo.addArgument(TemplArgLocs[i]);
695f4a2713aSLionel Sambuc FunctionTemplateSpecializationInfo *FTInfo
696f4a2713aSLionel Sambuc = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
697f4a2713aSLionel Sambuc TemplArgList,
698*0a6a1f1dSLionel Sambuc HasTemplateArgumentsAsWritten ? &TemplArgsInfo
699*0a6a1f1dSLionel Sambuc : nullptr,
700f4a2713aSLionel Sambuc POI);
701f4a2713aSLionel Sambuc FD->TemplateOrSpecialization = FTInfo;
702f4a2713aSLionel Sambuc
703f4a2713aSLionel Sambuc if (FD->isCanonicalDecl()) { // if canonical add to template's set.
704f4a2713aSLionel Sambuc // The template that contains the specializations set. It's not safe to
705f4a2713aSLionel Sambuc // use getCanonicalDecl on Template since it may still be initializing.
706f4a2713aSLionel Sambuc FunctionTemplateDecl *CanonTemplate
707f4a2713aSLionel Sambuc = ReadDeclAs<FunctionTemplateDecl>(Record, Idx);
708f4a2713aSLionel Sambuc // Get the InsertPos by FindNodeOrInsertPos() instead of calling
709f4a2713aSLionel Sambuc // InsertNode(FTInfo) directly to avoid the getASTContext() call in
710f4a2713aSLionel Sambuc // FunctionTemplateSpecializationInfo's Profile().
711f4a2713aSLionel Sambuc // We avoid getASTContext because a decl in the parent hierarchy may
712f4a2713aSLionel Sambuc // be initializing.
713f4a2713aSLionel Sambuc llvm::FoldingSetNodeID ID;
714*0a6a1f1dSLionel Sambuc FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C);
715*0a6a1f1dSLionel Sambuc void *InsertPos = nullptr;
716f4a2713aSLionel Sambuc FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
717f4a2713aSLionel Sambuc CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
718f4a2713aSLionel Sambuc if (InsertPos)
719f4a2713aSLionel Sambuc CommonPtr->Specializations.InsertNode(FTInfo, InsertPos);
720f4a2713aSLionel Sambuc else {
721f4a2713aSLionel Sambuc assert(Reader.getContext().getLangOpts().Modules &&
722f4a2713aSLionel Sambuc "already deserialized this template specialization");
723f4a2713aSLionel Sambuc // FIXME: This specialization is a redeclaration of one from another
724f4a2713aSLionel Sambuc // module. Merge it.
725f4a2713aSLionel Sambuc }
726f4a2713aSLionel Sambuc }
727f4a2713aSLionel Sambuc break;
728f4a2713aSLionel Sambuc }
729f4a2713aSLionel Sambuc case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
730f4a2713aSLionel Sambuc // Templates.
731f4a2713aSLionel Sambuc UnresolvedSet<8> TemplDecls;
732f4a2713aSLionel Sambuc unsigned NumTemplates = Record[Idx++];
733f4a2713aSLionel Sambuc while (NumTemplates--)
734f4a2713aSLionel Sambuc TemplDecls.addDecl(ReadDeclAs<NamedDecl>(Record, Idx));
735f4a2713aSLionel Sambuc
736f4a2713aSLionel Sambuc // Templates args.
737f4a2713aSLionel Sambuc TemplateArgumentListInfo TemplArgs;
738f4a2713aSLionel Sambuc unsigned NumArgs = Record[Idx++];
739f4a2713aSLionel Sambuc while (NumArgs--)
740f4a2713aSLionel Sambuc TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(F, Record, Idx));
741f4a2713aSLionel Sambuc TemplArgs.setLAngleLoc(ReadSourceLocation(Record, Idx));
742f4a2713aSLionel Sambuc TemplArgs.setRAngleLoc(ReadSourceLocation(Record, Idx));
743f4a2713aSLionel Sambuc
744f4a2713aSLionel Sambuc FD->setDependentTemplateSpecialization(Reader.getContext(),
745f4a2713aSLionel Sambuc TemplDecls, TemplArgs);
746*0a6a1f1dSLionel Sambuc
747*0a6a1f1dSLionel Sambuc // FIXME: Merging.
748f4a2713aSLionel Sambuc break;
749f4a2713aSLionel Sambuc }
750f4a2713aSLionel Sambuc }
751f4a2713aSLionel Sambuc
752f4a2713aSLionel Sambuc // Read in the parameters.
753f4a2713aSLionel Sambuc unsigned NumParams = Record[Idx++];
754f4a2713aSLionel Sambuc SmallVector<ParmVarDecl *, 16> Params;
755f4a2713aSLionel Sambuc Params.reserve(NumParams);
756f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumParams; ++I)
757f4a2713aSLionel Sambuc Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
758f4a2713aSLionel Sambuc FD->setParams(Reader.getContext(), Params);
759f4a2713aSLionel Sambuc }
760f4a2713aSLionel Sambuc
VisitObjCMethodDecl(ObjCMethodDecl * MD)761f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
762f4a2713aSLionel Sambuc VisitNamedDecl(MD);
763f4a2713aSLionel Sambuc if (Record[Idx++]) {
764f4a2713aSLionel Sambuc // Load the body on-demand. Most clients won't care, because method
765f4a2713aSLionel Sambuc // definitions rarely show up in headers.
766f4a2713aSLionel Sambuc Reader.PendingBodies[MD] = GetCurrentCursorOffset();
767f4a2713aSLionel Sambuc HasPendingBody = true;
768f4a2713aSLionel Sambuc MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
769f4a2713aSLionel Sambuc MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
770f4a2713aSLionel Sambuc }
771f4a2713aSLionel Sambuc MD->setInstanceMethod(Record[Idx++]);
772f4a2713aSLionel Sambuc MD->setVariadic(Record[Idx++]);
773f4a2713aSLionel Sambuc MD->setPropertyAccessor(Record[Idx++]);
774f4a2713aSLionel Sambuc MD->setDefined(Record[Idx++]);
775f4a2713aSLionel Sambuc MD->IsOverriding = Record[Idx++];
776f4a2713aSLionel Sambuc MD->HasSkippedBody = Record[Idx++];
777f4a2713aSLionel Sambuc
778f4a2713aSLionel Sambuc MD->IsRedeclaration = Record[Idx++];
779f4a2713aSLionel Sambuc MD->HasRedeclaration = Record[Idx++];
780f4a2713aSLionel Sambuc if (MD->HasRedeclaration)
781f4a2713aSLionel Sambuc Reader.getContext().setObjCMethodRedeclaration(MD,
782f4a2713aSLionel Sambuc ReadDeclAs<ObjCMethodDecl>(Record, Idx));
783f4a2713aSLionel Sambuc
784f4a2713aSLionel Sambuc MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
785f4a2713aSLionel Sambuc MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
786f4a2713aSLionel Sambuc MD->SetRelatedResultType(Record[Idx++]);
787*0a6a1f1dSLionel Sambuc MD->setReturnType(Reader.readType(F, Record, Idx));
788*0a6a1f1dSLionel Sambuc MD->setReturnTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
789f4a2713aSLionel Sambuc MD->DeclEndLoc = ReadSourceLocation(Record, Idx);
790f4a2713aSLionel Sambuc unsigned NumParams = Record[Idx++];
791f4a2713aSLionel Sambuc SmallVector<ParmVarDecl *, 16> Params;
792f4a2713aSLionel Sambuc Params.reserve(NumParams);
793f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumParams; ++I)
794f4a2713aSLionel Sambuc Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
795f4a2713aSLionel Sambuc
796f4a2713aSLionel Sambuc MD->SelLocsKind = Record[Idx++];
797f4a2713aSLionel Sambuc unsigned NumStoredSelLocs = Record[Idx++];
798f4a2713aSLionel Sambuc SmallVector<SourceLocation, 16> SelLocs;
799f4a2713aSLionel Sambuc SelLocs.reserve(NumStoredSelLocs);
800f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumStoredSelLocs; ++i)
801f4a2713aSLionel Sambuc SelLocs.push_back(ReadSourceLocation(Record, Idx));
802f4a2713aSLionel Sambuc
803f4a2713aSLionel Sambuc MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs);
804f4a2713aSLionel Sambuc }
805f4a2713aSLionel Sambuc
VisitObjCContainerDecl(ObjCContainerDecl * CD)806f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
807f4a2713aSLionel Sambuc VisitNamedDecl(CD);
808f4a2713aSLionel Sambuc CD->setAtStartLoc(ReadSourceLocation(Record, Idx));
809f4a2713aSLionel Sambuc CD->setAtEndRange(ReadSourceRange(Record, Idx));
810f4a2713aSLionel Sambuc }
811f4a2713aSLionel Sambuc
VisitObjCInterfaceDecl(ObjCInterfaceDecl * ID)812f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
813f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(ID);
814f4a2713aSLionel Sambuc VisitObjCContainerDecl(ID);
815f4a2713aSLionel Sambuc TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
816f4a2713aSLionel Sambuc mergeRedeclarable(ID, Redecl);
817f4a2713aSLionel Sambuc
818f4a2713aSLionel Sambuc if (Record[Idx++]) {
819f4a2713aSLionel Sambuc // Read the definition.
820f4a2713aSLionel Sambuc ID->allocateDefinitionData();
821f4a2713aSLionel Sambuc
822f4a2713aSLionel Sambuc // Set the definition data of the canonical declaration, so other
823f4a2713aSLionel Sambuc // redeclarations will see it.
824f4a2713aSLionel Sambuc ID->getCanonicalDecl()->Data = ID->Data;
825f4a2713aSLionel Sambuc
826f4a2713aSLionel Sambuc ObjCInterfaceDecl::DefinitionData &Data = ID->data();
827f4a2713aSLionel Sambuc
828f4a2713aSLionel Sambuc // Read the superclass.
829f4a2713aSLionel Sambuc Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
830f4a2713aSLionel Sambuc Data.SuperClassLoc = ReadSourceLocation(Record, Idx);
831f4a2713aSLionel Sambuc
832f4a2713aSLionel Sambuc Data.EndLoc = ReadSourceLocation(Record, Idx);
833*0a6a1f1dSLionel Sambuc Data.HasDesignatedInitializers = Record[Idx++];
834f4a2713aSLionel Sambuc
835f4a2713aSLionel Sambuc // Read the directly referenced protocols and their SourceLocations.
836f4a2713aSLionel Sambuc unsigned NumProtocols = Record[Idx++];
837f4a2713aSLionel Sambuc SmallVector<ObjCProtocolDecl *, 16> Protocols;
838f4a2713aSLionel Sambuc Protocols.reserve(NumProtocols);
839f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtocols; ++I)
840f4a2713aSLionel Sambuc Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
841f4a2713aSLionel Sambuc SmallVector<SourceLocation, 16> ProtoLocs;
842f4a2713aSLionel Sambuc ProtoLocs.reserve(NumProtocols);
843f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtocols; ++I)
844f4a2713aSLionel Sambuc ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
845f4a2713aSLionel Sambuc ID->setProtocolList(Protocols.data(), NumProtocols, ProtoLocs.data(),
846f4a2713aSLionel Sambuc Reader.getContext());
847f4a2713aSLionel Sambuc
848f4a2713aSLionel Sambuc // Read the transitive closure of protocols referenced by this class.
849f4a2713aSLionel Sambuc NumProtocols = Record[Idx++];
850f4a2713aSLionel Sambuc Protocols.clear();
851f4a2713aSLionel Sambuc Protocols.reserve(NumProtocols);
852f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtocols; ++I)
853f4a2713aSLionel Sambuc Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
854f4a2713aSLionel Sambuc ID->data().AllReferencedProtocols.set(Protocols.data(), NumProtocols,
855f4a2713aSLionel Sambuc Reader.getContext());
856f4a2713aSLionel Sambuc
857f4a2713aSLionel Sambuc // We will rebuild this list lazily.
858*0a6a1f1dSLionel Sambuc ID->setIvarList(nullptr);
859f4a2713aSLionel Sambuc
860f4a2713aSLionel Sambuc // Note that we have deserialized a definition.
861f4a2713aSLionel Sambuc Reader.PendingDefinitions.insert(ID);
862f4a2713aSLionel Sambuc
863f4a2713aSLionel Sambuc // Note that we've loaded this Objective-C class.
864f4a2713aSLionel Sambuc Reader.ObjCClassesLoaded.push_back(ID);
865f4a2713aSLionel Sambuc } else {
866f4a2713aSLionel Sambuc ID->Data = ID->getCanonicalDecl()->Data;
867f4a2713aSLionel Sambuc }
868f4a2713aSLionel Sambuc }
869f4a2713aSLionel Sambuc
VisitObjCIvarDecl(ObjCIvarDecl * IVD)870f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
871f4a2713aSLionel Sambuc VisitFieldDecl(IVD);
872f4a2713aSLionel Sambuc IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
873f4a2713aSLionel Sambuc // This field will be built lazily.
874*0a6a1f1dSLionel Sambuc IVD->setNextIvar(nullptr);
875f4a2713aSLionel Sambuc bool synth = Record[Idx++];
876f4a2713aSLionel Sambuc IVD->setSynthesize(synth);
877f4a2713aSLionel Sambuc }
878f4a2713aSLionel Sambuc
VisitObjCProtocolDecl(ObjCProtocolDecl * PD)879f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
880f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(PD);
881f4a2713aSLionel Sambuc VisitObjCContainerDecl(PD);
882f4a2713aSLionel Sambuc mergeRedeclarable(PD, Redecl);
883f4a2713aSLionel Sambuc
884f4a2713aSLionel Sambuc if (Record[Idx++]) {
885f4a2713aSLionel Sambuc // Read the definition.
886f4a2713aSLionel Sambuc PD->allocateDefinitionData();
887f4a2713aSLionel Sambuc
888f4a2713aSLionel Sambuc // Set the definition data of the canonical declaration, so other
889f4a2713aSLionel Sambuc // redeclarations will see it.
890f4a2713aSLionel Sambuc PD->getCanonicalDecl()->Data = PD->Data;
891f4a2713aSLionel Sambuc
892f4a2713aSLionel Sambuc unsigned NumProtoRefs = Record[Idx++];
893f4a2713aSLionel Sambuc SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
894f4a2713aSLionel Sambuc ProtoRefs.reserve(NumProtoRefs);
895f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtoRefs; ++I)
896f4a2713aSLionel Sambuc ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
897f4a2713aSLionel Sambuc SmallVector<SourceLocation, 16> ProtoLocs;
898f4a2713aSLionel Sambuc ProtoLocs.reserve(NumProtoRefs);
899f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtoRefs; ++I)
900f4a2713aSLionel Sambuc ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
901f4a2713aSLionel Sambuc PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
902f4a2713aSLionel Sambuc Reader.getContext());
903f4a2713aSLionel Sambuc
904f4a2713aSLionel Sambuc // Note that we have deserialized a definition.
905f4a2713aSLionel Sambuc Reader.PendingDefinitions.insert(PD);
906f4a2713aSLionel Sambuc } else {
907f4a2713aSLionel Sambuc PD->Data = PD->getCanonicalDecl()->Data;
908f4a2713aSLionel Sambuc }
909f4a2713aSLionel Sambuc }
910f4a2713aSLionel Sambuc
VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl * FD)911f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
912f4a2713aSLionel Sambuc VisitFieldDecl(FD);
913f4a2713aSLionel Sambuc }
914f4a2713aSLionel Sambuc
VisitObjCCategoryDecl(ObjCCategoryDecl * CD)915f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
916f4a2713aSLionel Sambuc VisitObjCContainerDecl(CD);
917f4a2713aSLionel Sambuc CD->setCategoryNameLoc(ReadSourceLocation(Record, Idx));
918f4a2713aSLionel Sambuc CD->setIvarLBraceLoc(ReadSourceLocation(Record, Idx));
919f4a2713aSLionel Sambuc CD->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
920f4a2713aSLionel Sambuc
921f4a2713aSLionel Sambuc // Note that this category has been deserialized. We do this before
922f4a2713aSLionel Sambuc // deserializing the interface declaration, so that it will consider this
923f4a2713aSLionel Sambuc /// category.
924f4a2713aSLionel Sambuc Reader.CategoriesDeserialized.insert(CD);
925f4a2713aSLionel Sambuc
926f4a2713aSLionel Sambuc CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
927f4a2713aSLionel Sambuc unsigned NumProtoRefs = Record[Idx++];
928f4a2713aSLionel Sambuc SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
929f4a2713aSLionel Sambuc ProtoRefs.reserve(NumProtoRefs);
930f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtoRefs; ++I)
931f4a2713aSLionel Sambuc ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
932f4a2713aSLionel Sambuc SmallVector<SourceLocation, 16> ProtoLocs;
933f4a2713aSLionel Sambuc ProtoLocs.reserve(NumProtoRefs);
934f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumProtoRefs; ++I)
935f4a2713aSLionel Sambuc ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
936f4a2713aSLionel Sambuc CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
937f4a2713aSLionel Sambuc Reader.getContext());
938f4a2713aSLionel Sambuc }
939f4a2713aSLionel Sambuc
VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl * CAD)940f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
941f4a2713aSLionel Sambuc VisitNamedDecl(CAD);
942f4a2713aSLionel Sambuc CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
943f4a2713aSLionel Sambuc }
944f4a2713aSLionel Sambuc
VisitObjCPropertyDecl(ObjCPropertyDecl * D)945f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
946f4a2713aSLionel Sambuc VisitNamedDecl(D);
947f4a2713aSLionel Sambuc D->setAtLoc(ReadSourceLocation(Record, Idx));
948f4a2713aSLionel Sambuc D->setLParenLoc(ReadSourceLocation(Record, Idx));
949f4a2713aSLionel Sambuc D->setType(GetTypeSourceInfo(Record, Idx));
950f4a2713aSLionel Sambuc // FIXME: stable encoding
951f4a2713aSLionel Sambuc D->setPropertyAttributes(
952f4a2713aSLionel Sambuc (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
953f4a2713aSLionel Sambuc D->setPropertyAttributesAsWritten(
954f4a2713aSLionel Sambuc (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
955f4a2713aSLionel Sambuc // FIXME: stable encoding
956f4a2713aSLionel Sambuc D->setPropertyImplementation(
957f4a2713aSLionel Sambuc (ObjCPropertyDecl::PropertyControl)Record[Idx++]);
958f4a2713aSLionel Sambuc D->setGetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
959f4a2713aSLionel Sambuc D->setSetterName(Reader.ReadDeclarationName(F,Record, Idx).getObjCSelector());
960f4a2713aSLionel Sambuc D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
961f4a2713aSLionel Sambuc D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
962f4a2713aSLionel Sambuc D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
963f4a2713aSLionel Sambuc }
964f4a2713aSLionel Sambuc
VisitObjCImplDecl(ObjCImplDecl * D)965f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
966f4a2713aSLionel Sambuc VisitObjCContainerDecl(D);
967f4a2713aSLionel Sambuc D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
968f4a2713aSLionel Sambuc }
969f4a2713aSLionel Sambuc
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)970f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
971f4a2713aSLionel Sambuc VisitObjCImplDecl(D);
972f4a2713aSLionel Sambuc D->setIdentifier(Reader.GetIdentifierInfo(F, Record, Idx));
973f4a2713aSLionel Sambuc D->CategoryNameLoc = ReadSourceLocation(Record, Idx);
974f4a2713aSLionel Sambuc }
975f4a2713aSLionel Sambuc
VisitObjCImplementationDecl(ObjCImplementationDecl * D)976f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
977f4a2713aSLionel Sambuc VisitObjCImplDecl(D);
978f4a2713aSLionel Sambuc D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
979f4a2713aSLionel Sambuc D->SuperLoc = ReadSourceLocation(Record, Idx);
980f4a2713aSLionel Sambuc D->setIvarLBraceLoc(ReadSourceLocation(Record, Idx));
981f4a2713aSLionel Sambuc D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
982f4a2713aSLionel Sambuc D->setHasNonZeroConstructors(Record[Idx++]);
983f4a2713aSLionel Sambuc D->setHasDestructors(Record[Idx++]);
984*0a6a1f1dSLionel Sambuc std::tie(D->IvarInitializers, D->NumIvarInitializers) =
985*0a6a1f1dSLionel Sambuc Reader.ReadCXXCtorInitializers(F, Record, Idx);
986f4a2713aSLionel Sambuc }
987f4a2713aSLionel Sambuc
988f4a2713aSLionel Sambuc
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * D)989f4a2713aSLionel Sambuc void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
990f4a2713aSLionel Sambuc VisitDecl(D);
991f4a2713aSLionel Sambuc D->setAtLoc(ReadSourceLocation(Record, Idx));
992f4a2713aSLionel Sambuc D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
993f4a2713aSLionel Sambuc D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>(Record, Idx);
994f4a2713aSLionel Sambuc D->IvarLoc = ReadSourceLocation(Record, Idx);
995f4a2713aSLionel Sambuc D->setGetterCXXConstructor(Reader.ReadExpr(F));
996f4a2713aSLionel Sambuc D->setSetterCXXAssignment(Reader.ReadExpr(F));
997f4a2713aSLionel Sambuc }
998f4a2713aSLionel Sambuc
VisitFieldDecl(FieldDecl * FD)999f4a2713aSLionel Sambuc void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) {
1000f4a2713aSLionel Sambuc VisitDeclaratorDecl(FD);
1001f4a2713aSLionel Sambuc FD->Mutable = Record[Idx++];
1002f4a2713aSLionel Sambuc if (int BitWidthOrInitializer = Record[Idx++]) {
1003*0a6a1f1dSLionel Sambuc FD->InitStorage.setInt(
1004*0a6a1f1dSLionel Sambuc static_cast<FieldDecl::InitStorageKind>(BitWidthOrInitializer - 1));
1005*0a6a1f1dSLionel Sambuc if (FD->InitStorage.getInt() == FieldDecl::ISK_CapturedVLAType) {
1006*0a6a1f1dSLionel Sambuc // Read captured variable length array.
1007*0a6a1f1dSLionel Sambuc FD->InitStorage.setPointer(
1008*0a6a1f1dSLionel Sambuc Reader.readType(F, Record, Idx).getAsOpaquePtr());
1009*0a6a1f1dSLionel Sambuc } else {
1010*0a6a1f1dSLionel Sambuc FD->InitStorage.setPointer(Reader.ReadExpr(F));
1011*0a6a1f1dSLionel Sambuc }
1012f4a2713aSLionel Sambuc }
1013f4a2713aSLionel Sambuc if (!FD->getDeclName()) {
1014f4a2713aSLionel Sambuc if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx))
1015f4a2713aSLionel Sambuc Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl);
1016f4a2713aSLionel Sambuc }
1017f4a2713aSLionel Sambuc mergeMergeable(FD);
1018f4a2713aSLionel Sambuc }
1019f4a2713aSLionel Sambuc
VisitMSPropertyDecl(MSPropertyDecl * PD)1020f4a2713aSLionel Sambuc void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) {
1021f4a2713aSLionel Sambuc VisitDeclaratorDecl(PD);
1022f4a2713aSLionel Sambuc PD->GetterId = Reader.GetIdentifierInfo(F, Record, Idx);
1023f4a2713aSLionel Sambuc PD->SetterId = Reader.GetIdentifierInfo(F, Record, Idx);
1024f4a2713aSLionel Sambuc }
1025f4a2713aSLionel Sambuc
VisitIndirectFieldDecl(IndirectFieldDecl * FD)1026f4a2713aSLionel Sambuc void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
1027f4a2713aSLionel Sambuc VisitValueDecl(FD);
1028f4a2713aSLionel Sambuc
1029f4a2713aSLionel Sambuc FD->ChainingSize = Record[Idx++];
1030f4a2713aSLionel Sambuc assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2");
1031f4a2713aSLionel Sambuc FD->Chaining = new (Reader.getContext())NamedDecl*[FD->ChainingSize];
1032f4a2713aSLionel Sambuc
1033f4a2713aSLionel Sambuc for (unsigned I = 0; I != FD->ChainingSize; ++I)
1034f4a2713aSLionel Sambuc FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx);
1035f4a2713aSLionel Sambuc }
1036f4a2713aSLionel Sambuc
VisitVarDeclImpl(VarDecl * VD)1037f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
1038f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(VD);
1039f4a2713aSLionel Sambuc VisitDeclaratorDecl(VD);
1040f4a2713aSLionel Sambuc
1041f4a2713aSLionel Sambuc VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
1042f4a2713aSLionel Sambuc VD->VarDeclBits.TSCSpec = Record[Idx++];
1043f4a2713aSLionel Sambuc VD->VarDeclBits.InitStyle = Record[Idx++];
1044f4a2713aSLionel Sambuc VD->VarDeclBits.ExceptionVar = Record[Idx++];
1045f4a2713aSLionel Sambuc VD->VarDeclBits.NRVOVariable = Record[Idx++];
1046f4a2713aSLionel Sambuc VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];
1047f4a2713aSLionel Sambuc VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];
1048f4a2713aSLionel Sambuc VD->VarDeclBits.IsConstexpr = Record[Idx++];
1049f4a2713aSLionel Sambuc VD->VarDeclBits.IsInitCapture = Record[Idx++];
1050f4a2713aSLionel Sambuc VD->VarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++];
1051f4a2713aSLionel Sambuc Linkage VarLinkage = Linkage(Record[Idx++]);
1052f4a2713aSLionel Sambuc VD->setCachedLinkage(VarLinkage);
1053f4a2713aSLionel Sambuc
1054f4a2713aSLionel Sambuc // Reconstruct the one piece of the IdentifierNamespace that we need.
1055*0a6a1f1dSLionel Sambuc if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage &&
1056f4a2713aSLionel Sambuc VD->getLexicalDeclContext()->isFunctionOrMethod())
1057f4a2713aSLionel Sambuc VD->setLocalExternDecl();
1058f4a2713aSLionel Sambuc
1059f4a2713aSLionel Sambuc if (uint64_t Val = Record[Idx++]) {
1060f4a2713aSLionel Sambuc VD->setInit(Reader.ReadExpr(F));
1061f4a2713aSLionel Sambuc if (Val > 1) {
1062f4a2713aSLionel Sambuc EvaluatedStmt *Eval = VD->ensureEvaluatedStmt();
1063f4a2713aSLionel Sambuc Eval->CheckedICE = true;
1064f4a2713aSLionel Sambuc Eval->IsICE = Val == 3;
1065f4a2713aSLionel Sambuc }
1066f4a2713aSLionel Sambuc }
1067f4a2713aSLionel Sambuc
1068f4a2713aSLionel Sambuc enum VarKind {
1069f4a2713aSLionel Sambuc VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
1070f4a2713aSLionel Sambuc };
1071f4a2713aSLionel Sambuc switch ((VarKind)Record[Idx++]) {
1072f4a2713aSLionel Sambuc case VarNotTemplate:
1073*0a6a1f1dSLionel Sambuc // Only true variables (not parameters or implicit parameters) can be merged
1074*0a6a1f1dSLionel Sambuc if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam &&
1075*0a6a1f1dSLionel Sambuc !isa<VarTemplateSpecializationDecl>(VD))
1076*0a6a1f1dSLionel Sambuc mergeRedeclarable(VD, Redecl);
1077f4a2713aSLionel Sambuc break;
1078f4a2713aSLionel Sambuc case VarTemplate:
1079*0a6a1f1dSLionel Sambuc // Merged when we merge the template.
1080f4a2713aSLionel Sambuc VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>(Record, Idx));
1081f4a2713aSLionel Sambuc break;
1082f4a2713aSLionel Sambuc case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo.
1083f4a2713aSLionel Sambuc VarDecl *Tmpl = ReadDeclAs<VarDecl>(Record, Idx);
1084f4a2713aSLionel Sambuc TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
1085f4a2713aSLionel Sambuc SourceLocation POI = ReadSourceLocation(Record, Idx);
1086f4a2713aSLionel Sambuc Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
1087*0a6a1f1dSLionel Sambuc mergeRedeclarable(VD, Redecl);
1088f4a2713aSLionel Sambuc break;
1089f4a2713aSLionel Sambuc }
1090f4a2713aSLionel Sambuc }
1091f4a2713aSLionel Sambuc
1092f4a2713aSLionel Sambuc return Redecl;
1093f4a2713aSLionel Sambuc }
1094f4a2713aSLionel Sambuc
VisitImplicitParamDecl(ImplicitParamDecl * PD)1095f4a2713aSLionel Sambuc void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
1096f4a2713aSLionel Sambuc VisitVarDecl(PD);
1097f4a2713aSLionel Sambuc }
1098f4a2713aSLionel Sambuc
VisitParmVarDecl(ParmVarDecl * PD)1099f4a2713aSLionel Sambuc void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
1100f4a2713aSLionel Sambuc VisitVarDecl(PD);
1101f4a2713aSLionel Sambuc unsigned isObjCMethodParam = Record[Idx++];
1102f4a2713aSLionel Sambuc unsigned scopeDepth = Record[Idx++];
1103f4a2713aSLionel Sambuc unsigned scopeIndex = Record[Idx++];
1104f4a2713aSLionel Sambuc unsigned declQualifier = Record[Idx++];
1105f4a2713aSLionel Sambuc if (isObjCMethodParam) {
1106f4a2713aSLionel Sambuc assert(scopeDepth == 0);
1107f4a2713aSLionel Sambuc PD->setObjCMethodScopeInfo(scopeIndex);
1108f4a2713aSLionel Sambuc PD->ParmVarDeclBits.ScopeDepthOrObjCQuals = declQualifier;
1109f4a2713aSLionel Sambuc } else {
1110f4a2713aSLionel Sambuc PD->setScopeInfo(scopeDepth, scopeIndex);
1111f4a2713aSLionel Sambuc }
1112f4a2713aSLionel Sambuc PD->ParmVarDeclBits.IsKNRPromoted = Record[Idx++];
1113f4a2713aSLionel Sambuc PD->ParmVarDeclBits.HasInheritedDefaultArg = Record[Idx++];
1114f4a2713aSLionel Sambuc if (Record[Idx++]) // hasUninstantiatedDefaultArg.
1115f4a2713aSLionel Sambuc PD->setUninstantiatedDefaultArg(Reader.ReadExpr(F));
1116f4a2713aSLionel Sambuc
1117f4a2713aSLionel Sambuc // FIXME: If this is a redeclaration of a function from another module, handle
1118f4a2713aSLionel Sambuc // inheritance of default arguments.
1119f4a2713aSLionel Sambuc }
1120f4a2713aSLionel Sambuc
VisitFileScopeAsmDecl(FileScopeAsmDecl * AD)1121f4a2713aSLionel Sambuc void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
1122f4a2713aSLionel Sambuc VisitDecl(AD);
1123f4a2713aSLionel Sambuc AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr(F)));
1124f4a2713aSLionel Sambuc AD->setRParenLoc(ReadSourceLocation(Record, Idx));
1125f4a2713aSLionel Sambuc }
1126f4a2713aSLionel Sambuc
VisitBlockDecl(BlockDecl * BD)1127f4a2713aSLionel Sambuc void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
1128f4a2713aSLionel Sambuc VisitDecl(BD);
1129f4a2713aSLionel Sambuc BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(F)));
1130f4a2713aSLionel Sambuc BD->setSignatureAsWritten(GetTypeSourceInfo(Record, Idx));
1131f4a2713aSLionel Sambuc unsigned NumParams = Record[Idx++];
1132f4a2713aSLionel Sambuc SmallVector<ParmVarDecl *, 16> Params;
1133f4a2713aSLionel Sambuc Params.reserve(NumParams);
1134f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumParams; ++I)
1135f4a2713aSLionel Sambuc Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
1136f4a2713aSLionel Sambuc BD->setParams(Params);
1137f4a2713aSLionel Sambuc
1138f4a2713aSLionel Sambuc BD->setIsVariadic(Record[Idx++]);
1139f4a2713aSLionel Sambuc BD->setBlockMissingReturnType(Record[Idx++]);
1140f4a2713aSLionel Sambuc BD->setIsConversionFromLambda(Record[Idx++]);
1141f4a2713aSLionel Sambuc
1142f4a2713aSLionel Sambuc bool capturesCXXThis = Record[Idx++];
1143f4a2713aSLionel Sambuc unsigned numCaptures = Record[Idx++];
1144f4a2713aSLionel Sambuc SmallVector<BlockDecl::Capture, 16> captures;
1145f4a2713aSLionel Sambuc captures.reserve(numCaptures);
1146f4a2713aSLionel Sambuc for (unsigned i = 0; i != numCaptures; ++i) {
1147f4a2713aSLionel Sambuc VarDecl *decl = ReadDeclAs<VarDecl>(Record, Idx);
1148f4a2713aSLionel Sambuc unsigned flags = Record[Idx++];
1149f4a2713aSLionel Sambuc bool byRef = (flags & 1);
1150f4a2713aSLionel Sambuc bool nested = (flags & 2);
1151*0a6a1f1dSLionel Sambuc Expr *copyExpr = ((flags & 4) ? Reader.ReadExpr(F) : nullptr);
1152f4a2713aSLionel Sambuc
1153f4a2713aSLionel Sambuc captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
1154f4a2713aSLionel Sambuc }
1155f4a2713aSLionel Sambuc BD->setCaptures(Reader.getContext(), captures.begin(),
1156f4a2713aSLionel Sambuc captures.end(), capturesCXXThis);
1157f4a2713aSLionel Sambuc }
1158f4a2713aSLionel Sambuc
VisitCapturedDecl(CapturedDecl * CD)1159f4a2713aSLionel Sambuc void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {
1160f4a2713aSLionel Sambuc VisitDecl(CD);
1161*0a6a1f1dSLionel Sambuc unsigned ContextParamPos = Record[Idx++];
1162*0a6a1f1dSLionel Sambuc CD->setNothrow(Record[Idx++] != 0);
1163f4a2713aSLionel Sambuc // Body is set by VisitCapturedStmt.
1164*0a6a1f1dSLionel Sambuc for (unsigned I = 0; I < CD->NumParams; ++I) {
1165*0a6a1f1dSLionel Sambuc if (I != ContextParamPos)
1166*0a6a1f1dSLionel Sambuc CD->setParam(I, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
1167*0a6a1f1dSLionel Sambuc else
1168*0a6a1f1dSLionel Sambuc CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
1169*0a6a1f1dSLionel Sambuc }
1170f4a2713aSLionel Sambuc }
1171f4a2713aSLionel Sambuc
VisitLinkageSpecDecl(LinkageSpecDecl * D)1172f4a2713aSLionel Sambuc void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1173f4a2713aSLionel Sambuc VisitDecl(D);
1174f4a2713aSLionel Sambuc D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]);
1175f4a2713aSLionel Sambuc D->setExternLoc(ReadSourceLocation(Record, Idx));
1176f4a2713aSLionel Sambuc D->setRBraceLoc(ReadSourceLocation(Record, Idx));
1177f4a2713aSLionel Sambuc }
1178f4a2713aSLionel Sambuc
VisitLabelDecl(LabelDecl * D)1179f4a2713aSLionel Sambuc void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
1180f4a2713aSLionel Sambuc VisitNamedDecl(D);
1181f4a2713aSLionel Sambuc D->setLocStart(ReadSourceLocation(Record, Idx));
1182f4a2713aSLionel Sambuc }
1183f4a2713aSLionel Sambuc
1184f4a2713aSLionel Sambuc
VisitNamespaceDecl(NamespaceDecl * D)1185f4a2713aSLionel Sambuc void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
1186f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(D);
1187f4a2713aSLionel Sambuc VisitNamedDecl(D);
1188f4a2713aSLionel Sambuc D->setInline(Record[Idx++]);
1189f4a2713aSLionel Sambuc D->LocStart = ReadSourceLocation(Record, Idx);
1190f4a2713aSLionel Sambuc D->RBraceLoc = ReadSourceLocation(Record, Idx);
1191f4a2713aSLionel Sambuc
1192f4a2713aSLionel Sambuc if (Redecl.getFirstID() == ThisDeclID) {
1193f4a2713aSLionel Sambuc // Each module has its own anonymous namespace, which is disjoint from
1194f4a2713aSLionel Sambuc // any other module's anonymous namespaces, so don't attach the anonymous
1195f4a2713aSLionel Sambuc // namespace at all.
1196f4a2713aSLionel Sambuc NamespaceDecl *Anon = ReadDeclAs<NamespaceDecl>(Record, Idx);
1197*0a6a1f1dSLionel Sambuc if (F.Kind != MK_ImplicitModule && F.Kind != MK_ExplicitModule)
1198f4a2713aSLionel Sambuc D->setAnonymousNamespace(Anon);
1199f4a2713aSLionel Sambuc } else {
1200f4a2713aSLionel Sambuc // Link this namespace back to the first declaration, which has already
1201f4a2713aSLionel Sambuc // been deserialized.
1202f4a2713aSLionel Sambuc D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl());
1203f4a2713aSLionel Sambuc }
1204*0a6a1f1dSLionel Sambuc
1205*0a6a1f1dSLionel Sambuc mergeRedeclarable(D, Redecl);
1206f4a2713aSLionel Sambuc }
1207f4a2713aSLionel Sambuc
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1208f4a2713aSLionel Sambuc void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1209*0a6a1f1dSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(D);
1210f4a2713aSLionel Sambuc VisitNamedDecl(D);
1211f4a2713aSLionel Sambuc D->NamespaceLoc = ReadSourceLocation(Record, Idx);
1212f4a2713aSLionel Sambuc D->IdentLoc = ReadSourceLocation(Record, Idx);
1213f4a2713aSLionel Sambuc D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
1214f4a2713aSLionel Sambuc D->Namespace = ReadDeclAs<NamedDecl>(Record, Idx);
1215*0a6a1f1dSLionel Sambuc mergeRedeclarable(D, Redecl);
1216f4a2713aSLionel Sambuc }
1217f4a2713aSLionel Sambuc
VisitUsingDecl(UsingDecl * D)1218f4a2713aSLionel Sambuc void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
1219f4a2713aSLionel Sambuc VisitNamedDecl(D);
1220f4a2713aSLionel Sambuc D->setUsingLoc(ReadSourceLocation(Record, Idx));
1221f4a2713aSLionel Sambuc D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
1222f4a2713aSLionel Sambuc ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
1223f4a2713aSLionel Sambuc D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>(Record, Idx));
1224f4a2713aSLionel Sambuc D->setTypename(Record[Idx++]);
1225f4a2713aSLionel Sambuc if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx))
1226f4a2713aSLionel Sambuc Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern);
1227*0a6a1f1dSLionel Sambuc mergeMergeable(D);
1228f4a2713aSLionel Sambuc }
1229f4a2713aSLionel Sambuc
VisitUsingShadowDecl(UsingShadowDecl * D)1230f4a2713aSLionel Sambuc void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {
1231f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(D);
1232f4a2713aSLionel Sambuc VisitNamedDecl(D);
1233f4a2713aSLionel Sambuc D->setTargetDecl(ReadDeclAs<NamedDecl>(Record, Idx));
1234f4a2713aSLionel Sambuc D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(Record, Idx);
1235f4a2713aSLionel Sambuc UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(Record, Idx);
1236f4a2713aSLionel Sambuc if (Pattern)
1237f4a2713aSLionel Sambuc Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern);
1238f4a2713aSLionel Sambuc mergeRedeclarable(D, Redecl);
1239f4a2713aSLionel Sambuc }
1240f4a2713aSLionel Sambuc
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1241f4a2713aSLionel Sambuc void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1242f4a2713aSLionel Sambuc VisitNamedDecl(D);
1243f4a2713aSLionel Sambuc D->UsingLoc = ReadSourceLocation(Record, Idx);
1244f4a2713aSLionel Sambuc D->NamespaceLoc = ReadSourceLocation(Record, Idx);
1245f4a2713aSLionel Sambuc D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
1246f4a2713aSLionel Sambuc D->NominatedNamespace = ReadDeclAs<NamedDecl>(Record, Idx);
1247f4a2713aSLionel Sambuc D->CommonAncestor = ReadDeclAs<DeclContext>(Record, Idx);
1248f4a2713aSLionel Sambuc }
1249f4a2713aSLionel Sambuc
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1250f4a2713aSLionel Sambuc void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1251f4a2713aSLionel Sambuc VisitValueDecl(D);
1252f4a2713aSLionel Sambuc D->setUsingLoc(ReadSourceLocation(Record, Idx));
1253f4a2713aSLionel Sambuc D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
1254f4a2713aSLionel Sambuc ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
1255*0a6a1f1dSLionel Sambuc mergeMergeable(D);
1256f4a2713aSLionel Sambuc }
1257f4a2713aSLionel Sambuc
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1258f4a2713aSLionel Sambuc void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
1259f4a2713aSLionel Sambuc UnresolvedUsingTypenameDecl *D) {
1260f4a2713aSLionel Sambuc VisitTypeDecl(D);
1261f4a2713aSLionel Sambuc D->TypenameLocation = ReadSourceLocation(Record, Idx);
1262f4a2713aSLionel Sambuc D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
1263*0a6a1f1dSLionel Sambuc mergeMergeable(D);
1264f4a2713aSLionel Sambuc }
1265f4a2713aSLionel Sambuc
ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData & Data,const RecordData & Record,unsigned & Idx)1266f4a2713aSLionel Sambuc void ASTDeclReader::ReadCXXDefinitionData(
1267f4a2713aSLionel Sambuc struct CXXRecordDecl::DefinitionData &Data,
1268f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
1269f4a2713aSLionel Sambuc // Note: the caller has deserialized the IsLambda bit already.
1270f4a2713aSLionel Sambuc Data.UserDeclaredConstructor = Record[Idx++];
1271f4a2713aSLionel Sambuc Data.UserDeclaredSpecialMembers = Record[Idx++];
1272f4a2713aSLionel Sambuc Data.Aggregate = Record[Idx++];
1273f4a2713aSLionel Sambuc Data.PlainOldData = Record[Idx++];
1274f4a2713aSLionel Sambuc Data.Empty = Record[Idx++];
1275f4a2713aSLionel Sambuc Data.Polymorphic = Record[Idx++];
1276f4a2713aSLionel Sambuc Data.Abstract = Record[Idx++];
1277f4a2713aSLionel Sambuc Data.IsStandardLayout = Record[Idx++];
1278f4a2713aSLionel Sambuc Data.HasNoNonEmptyBases = Record[Idx++];
1279f4a2713aSLionel Sambuc Data.HasPrivateFields = Record[Idx++];
1280f4a2713aSLionel Sambuc Data.HasProtectedFields = Record[Idx++];
1281f4a2713aSLionel Sambuc Data.HasPublicFields = Record[Idx++];
1282f4a2713aSLionel Sambuc Data.HasMutableFields = Record[Idx++];
1283*0a6a1f1dSLionel Sambuc Data.HasVariantMembers = Record[Idx++];
1284f4a2713aSLionel Sambuc Data.HasOnlyCMembers = Record[Idx++];
1285f4a2713aSLionel Sambuc Data.HasInClassInitializer = Record[Idx++];
1286f4a2713aSLionel Sambuc Data.HasUninitializedReferenceMember = Record[Idx++];
1287f4a2713aSLionel Sambuc Data.NeedOverloadResolutionForMoveConstructor = Record[Idx++];
1288f4a2713aSLionel Sambuc Data.NeedOverloadResolutionForMoveAssignment = Record[Idx++];
1289f4a2713aSLionel Sambuc Data.NeedOverloadResolutionForDestructor = Record[Idx++];
1290f4a2713aSLionel Sambuc Data.DefaultedMoveConstructorIsDeleted = Record[Idx++];
1291f4a2713aSLionel Sambuc Data.DefaultedMoveAssignmentIsDeleted = Record[Idx++];
1292f4a2713aSLionel Sambuc Data.DefaultedDestructorIsDeleted = Record[Idx++];
1293f4a2713aSLionel Sambuc Data.HasTrivialSpecialMembers = Record[Idx++];
1294*0a6a1f1dSLionel Sambuc Data.DeclaredNonTrivialSpecialMembers = Record[Idx++];
1295f4a2713aSLionel Sambuc Data.HasIrrelevantDestructor = Record[Idx++];
1296f4a2713aSLionel Sambuc Data.HasConstexprNonCopyMoveConstructor = Record[Idx++];
1297f4a2713aSLionel Sambuc Data.DefaultedDefaultConstructorIsConstexpr = Record[Idx++];
1298f4a2713aSLionel Sambuc Data.HasConstexprDefaultConstructor = Record[Idx++];
1299f4a2713aSLionel Sambuc Data.HasNonLiteralTypeFieldsOrBases = Record[Idx++];
1300f4a2713aSLionel Sambuc Data.ComputedVisibleConversions = Record[Idx++];
1301f4a2713aSLionel Sambuc Data.UserProvidedDefaultConstructor = Record[Idx++];
1302f4a2713aSLionel Sambuc Data.DeclaredSpecialMembers = Record[Idx++];
1303f4a2713aSLionel Sambuc Data.ImplicitCopyConstructorHasConstParam = Record[Idx++];
1304f4a2713aSLionel Sambuc Data.ImplicitCopyAssignmentHasConstParam = Record[Idx++];
1305f4a2713aSLionel Sambuc Data.HasDeclaredCopyConstructorWithConstParam = Record[Idx++];
1306f4a2713aSLionel Sambuc Data.HasDeclaredCopyAssignmentWithConstParam = Record[Idx++];
1307f4a2713aSLionel Sambuc
1308f4a2713aSLionel Sambuc Data.NumBases = Record[Idx++];
1309f4a2713aSLionel Sambuc if (Data.NumBases)
1310f4a2713aSLionel Sambuc Data.Bases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
1311f4a2713aSLionel Sambuc Data.NumVBases = Record[Idx++];
1312f4a2713aSLionel Sambuc if (Data.NumVBases)
1313f4a2713aSLionel Sambuc Data.VBases = Reader.readCXXBaseSpecifiers(F, Record, Idx);
1314f4a2713aSLionel Sambuc
1315f4a2713aSLionel Sambuc Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx);
1316f4a2713aSLionel Sambuc Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx);
1317f4a2713aSLionel Sambuc assert(Data.Definition && "Data.Definition should be already set!");
1318f4a2713aSLionel Sambuc Data.FirstFriend = ReadDeclID(Record, Idx);
1319f4a2713aSLionel Sambuc
1320f4a2713aSLionel Sambuc if (Data.IsLambda) {
1321*0a6a1f1dSLionel Sambuc typedef LambdaCapture Capture;
1322f4a2713aSLionel Sambuc CXXRecordDecl::LambdaDefinitionData &Lambda
1323f4a2713aSLionel Sambuc = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
1324f4a2713aSLionel Sambuc Lambda.Dependent = Record[Idx++];
1325f4a2713aSLionel Sambuc Lambda.IsGenericLambda = Record[Idx++];
1326f4a2713aSLionel Sambuc Lambda.CaptureDefault = Record[Idx++];
1327f4a2713aSLionel Sambuc Lambda.NumCaptures = Record[Idx++];
1328f4a2713aSLionel Sambuc Lambda.NumExplicitCaptures = Record[Idx++];
1329f4a2713aSLionel Sambuc Lambda.ManglingNumber = Record[Idx++];
1330f4a2713aSLionel Sambuc Lambda.ContextDecl = ReadDecl(Record, Idx);
1331f4a2713aSLionel Sambuc Lambda.Captures
1332f4a2713aSLionel Sambuc = (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures);
1333f4a2713aSLionel Sambuc Capture *ToCapture = Lambda.Captures;
1334f4a2713aSLionel Sambuc Lambda.MethodTyInfo = GetTypeSourceInfo(Record, Idx);
1335f4a2713aSLionel Sambuc for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
1336f4a2713aSLionel Sambuc SourceLocation Loc = ReadSourceLocation(Record, Idx);
1337f4a2713aSLionel Sambuc bool IsImplicit = Record[Idx++];
1338f4a2713aSLionel Sambuc LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record[Idx++]);
1339f4a2713aSLionel Sambuc switch (Kind) {
1340f4a2713aSLionel Sambuc case LCK_This:
1341*0a6a1f1dSLionel Sambuc case LCK_VLAType:
1342*0a6a1f1dSLionel Sambuc *ToCapture++ = Capture(Loc, IsImplicit, Kind, nullptr,SourceLocation());
1343f4a2713aSLionel Sambuc break;
1344f4a2713aSLionel Sambuc case LCK_ByCopy:
1345f4a2713aSLionel Sambuc case LCK_ByRef:
1346f4a2713aSLionel Sambuc VarDecl *Var = ReadDeclAs<VarDecl>(Record, Idx);
1347f4a2713aSLionel Sambuc SourceLocation EllipsisLoc = ReadSourceLocation(Record, Idx);
1348f4a2713aSLionel Sambuc *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc);
1349f4a2713aSLionel Sambuc break;
1350f4a2713aSLionel Sambuc }
1351f4a2713aSLionel Sambuc }
1352f4a2713aSLionel Sambuc }
1353f4a2713aSLionel Sambuc }
1354f4a2713aSLionel Sambuc
MergeDefinitionData(CXXRecordDecl * D,struct CXXRecordDecl::DefinitionData & MergeDD)1355*0a6a1f1dSLionel Sambuc void ASTDeclReader::MergeDefinitionData(
1356*0a6a1f1dSLionel Sambuc CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &MergeDD) {
1357*0a6a1f1dSLionel Sambuc assert(D->DefinitionData.getNotUpdated() &&
1358*0a6a1f1dSLionel Sambuc "merging class definition into non-definition");
1359*0a6a1f1dSLionel Sambuc auto &DD = *D->DefinitionData.getNotUpdated();
1360f4a2713aSLionel Sambuc
1361*0a6a1f1dSLionel Sambuc // If the new definition has new special members, let the name lookup
1362*0a6a1f1dSLionel Sambuc // code know that it needs to look in the new definition too.
1363*0a6a1f1dSLionel Sambuc //
1364*0a6a1f1dSLionel Sambuc // FIXME: We only need to do this if the merged definition declares members
1365*0a6a1f1dSLionel Sambuc // that this definition did not declare, or if it defines members that this
1366*0a6a1f1dSLionel Sambuc // definition did not define.
1367*0a6a1f1dSLionel Sambuc if (MergeDD.DeclaredSpecialMembers && DD.Definition != MergeDD.Definition) {
1368*0a6a1f1dSLionel Sambuc Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition);
1369*0a6a1f1dSLionel Sambuc DD.Definition->setHasExternalVisibleStorage();
1370*0a6a1f1dSLionel Sambuc }
1371*0a6a1f1dSLionel Sambuc
1372*0a6a1f1dSLionel Sambuc // FIXME: Move this out into a .def file?
1373*0a6a1f1dSLionel Sambuc // FIXME: Issue a diagnostic on a mismatched MATCH_FIELD, rather than
1374*0a6a1f1dSLionel Sambuc // asserting; this can happen in the case of an ODR violation.
1375*0a6a1f1dSLionel Sambuc bool DetectedOdrViolation = false;
1376*0a6a1f1dSLionel Sambuc #define OR_FIELD(Field) DD.Field |= MergeDD.Field;
1377*0a6a1f1dSLionel Sambuc #define MATCH_FIELD(Field) \
1378*0a6a1f1dSLionel Sambuc DetectedOdrViolation |= DD.Field != MergeDD.Field; \
1379*0a6a1f1dSLionel Sambuc OR_FIELD(Field)
1380*0a6a1f1dSLionel Sambuc MATCH_FIELD(UserDeclaredConstructor)
1381*0a6a1f1dSLionel Sambuc MATCH_FIELD(UserDeclaredSpecialMembers)
1382*0a6a1f1dSLionel Sambuc MATCH_FIELD(Aggregate)
1383*0a6a1f1dSLionel Sambuc MATCH_FIELD(PlainOldData)
1384*0a6a1f1dSLionel Sambuc MATCH_FIELD(Empty)
1385*0a6a1f1dSLionel Sambuc MATCH_FIELD(Polymorphic)
1386*0a6a1f1dSLionel Sambuc MATCH_FIELD(Abstract)
1387*0a6a1f1dSLionel Sambuc MATCH_FIELD(IsStandardLayout)
1388*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasNoNonEmptyBases)
1389*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasPrivateFields)
1390*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasProtectedFields)
1391*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasPublicFields)
1392*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasMutableFields)
1393*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasVariantMembers)
1394*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasOnlyCMembers)
1395*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasInClassInitializer)
1396*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasUninitializedReferenceMember)
1397*0a6a1f1dSLionel Sambuc MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
1398*0a6a1f1dSLionel Sambuc MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
1399*0a6a1f1dSLionel Sambuc MATCH_FIELD(NeedOverloadResolutionForDestructor)
1400*0a6a1f1dSLionel Sambuc MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
1401*0a6a1f1dSLionel Sambuc MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
1402*0a6a1f1dSLionel Sambuc MATCH_FIELD(DefaultedDestructorIsDeleted)
1403*0a6a1f1dSLionel Sambuc OR_FIELD(HasTrivialSpecialMembers)
1404*0a6a1f1dSLionel Sambuc OR_FIELD(DeclaredNonTrivialSpecialMembers)
1405*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasIrrelevantDestructor)
1406*0a6a1f1dSLionel Sambuc OR_FIELD(HasConstexprNonCopyMoveConstructor)
1407*0a6a1f1dSLionel Sambuc MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
1408*0a6a1f1dSLionel Sambuc OR_FIELD(HasConstexprDefaultConstructor)
1409*0a6a1f1dSLionel Sambuc MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
1410*0a6a1f1dSLionel Sambuc // ComputedVisibleConversions is handled below.
1411*0a6a1f1dSLionel Sambuc MATCH_FIELD(UserProvidedDefaultConstructor)
1412*0a6a1f1dSLionel Sambuc OR_FIELD(DeclaredSpecialMembers)
1413*0a6a1f1dSLionel Sambuc MATCH_FIELD(ImplicitCopyConstructorHasConstParam)
1414*0a6a1f1dSLionel Sambuc MATCH_FIELD(ImplicitCopyAssignmentHasConstParam)
1415*0a6a1f1dSLionel Sambuc OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
1416*0a6a1f1dSLionel Sambuc OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
1417*0a6a1f1dSLionel Sambuc MATCH_FIELD(IsLambda)
1418*0a6a1f1dSLionel Sambuc #undef OR_FIELD
1419*0a6a1f1dSLionel Sambuc #undef MATCH_FIELD
1420*0a6a1f1dSLionel Sambuc
1421*0a6a1f1dSLionel Sambuc if (DD.NumBases != MergeDD.NumBases || DD.NumVBases != MergeDD.NumVBases)
1422*0a6a1f1dSLionel Sambuc DetectedOdrViolation = true;
1423*0a6a1f1dSLionel Sambuc // FIXME: Issue a diagnostic if the base classes don't match when we come
1424*0a6a1f1dSLionel Sambuc // to lazily load them.
1425*0a6a1f1dSLionel Sambuc
1426*0a6a1f1dSLionel Sambuc // FIXME: Issue a diagnostic if the list of conversion functions doesn't
1427*0a6a1f1dSLionel Sambuc // match when we come to lazily load them.
1428*0a6a1f1dSLionel Sambuc if (MergeDD.ComputedVisibleConversions && !DD.ComputedVisibleConversions) {
1429*0a6a1f1dSLionel Sambuc DD.VisibleConversions = std::move(MergeDD.VisibleConversions);
1430*0a6a1f1dSLionel Sambuc DD.ComputedVisibleConversions = true;
1431*0a6a1f1dSLionel Sambuc }
1432*0a6a1f1dSLionel Sambuc
1433*0a6a1f1dSLionel Sambuc // FIXME: Issue a diagnostic if FirstFriend doesn't match when we come to
1434*0a6a1f1dSLionel Sambuc // lazily load it.
1435*0a6a1f1dSLionel Sambuc
1436*0a6a1f1dSLionel Sambuc if (DD.IsLambda) {
1437*0a6a1f1dSLionel Sambuc // FIXME: ODR-checking for merging lambdas (this happens, for instance,
1438*0a6a1f1dSLionel Sambuc // when they occur within the body of a function template specialization).
1439*0a6a1f1dSLionel Sambuc }
1440*0a6a1f1dSLionel Sambuc
1441*0a6a1f1dSLionel Sambuc if (DetectedOdrViolation)
1442*0a6a1f1dSLionel Sambuc Reader.PendingOdrMergeFailures[DD.Definition].push_back(MergeDD.Definition);
1443*0a6a1f1dSLionel Sambuc }
1444*0a6a1f1dSLionel Sambuc
ReadCXXRecordDefinition(CXXRecordDecl * D)1445*0a6a1f1dSLionel Sambuc void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) {
1446*0a6a1f1dSLionel Sambuc struct CXXRecordDecl::DefinitionData *DD;
1447f4a2713aSLionel Sambuc ASTContext &C = Reader.getContext();
1448*0a6a1f1dSLionel Sambuc
1449f4a2713aSLionel Sambuc // Determine whether this is a lambda closure type, so that we can
1450f4a2713aSLionel Sambuc // allocate the appropriate DefinitionData structure.
1451f4a2713aSLionel Sambuc bool IsLambda = Record[Idx++];
1452f4a2713aSLionel Sambuc if (IsLambda)
1453*0a6a1f1dSLionel Sambuc DD = new (C) CXXRecordDecl::LambdaDefinitionData(D, nullptr, false, false,
1454*0a6a1f1dSLionel Sambuc LCD_None);
1455f4a2713aSLionel Sambuc else
1456*0a6a1f1dSLionel Sambuc DD = new (C) struct CXXRecordDecl::DefinitionData(D);
1457f4a2713aSLionel Sambuc
1458*0a6a1f1dSLionel Sambuc ReadCXXDefinitionData(*DD, Record, Idx);
1459*0a6a1f1dSLionel Sambuc
1460*0a6a1f1dSLionel Sambuc // If we're reading an update record, we might already have a definition for
1461*0a6a1f1dSLionel Sambuc // this record. If so, just merge into it.
1462*0a6a1f1dSLionel Sambuc if (D->DefinitionData.getNotUpdated()) {
1463*0a6a1f1dSLionel Sambuc MergeDefinitionData(D, *DD);
1464*0a6a1f1dSLionel Sambuc return;
1465*0a6a1f1dSLionel Sambuc }
1466f4a2713aSLionel Sambuc
1467f4a2713aSLionel Sambuc // Propagate the DefinitionData pointer to the canonical declaration, so
1468f4a2713aSLionel Sambuc // that all other deserialized declarations will see it.
1469f4a2713aSLionel Sambuc CXXRecordDecl *Canon = D->getCanonicalDecl();
1470f4a2713aSLionel Sambuc if (Canon == D) {
1471*0a6a1f1dSLionel Sambuc D->DefinitionData = DD;
1472*0a6a1f1dSLionel Sambuc D->IsCompleteDefinition = true;
1473*0a6a1f1dSLionel Sambuc } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
1474*0a6a1f1dSLionel Sambuc // We have already deserialized a definition of this record. This
1475*0a6a1f1dSLionel Sambuc // definition is no longer really a definition. Note that the pre-existing
1476*0a6a1f1dSLionel Sambuc // definition is the *real* definition.
1477*0a6a1f1dSLionel Sambuc Reader.MergedDeclContexts.insert(
1478*0a6a1f1dSLionel Sambuc std::make_pair(D, CanonDD->Definition));
1479*0a6a1f1dSLionel Sambuc D->DefinitionData = Canon->DefinitionData;
1480*0a6a1f1dSLionel Sambuc D->IsCompleteDefinition = false;
1481*0a6a1f1dSLionel Sambuc MergeDefinitionData(D, *DD);
1482*0a6a1f1dSLionel Sambuc } else {
1483*0a6a1f1dSLionel Sambuc Canon->DefinitionData = DD;
1484*0a6a1f1dSLionel Sambuc D->DefinitionData = Canon->DefinitionData;
1485*0a6a1f1dSLionel Sambuc D->IsCompleteDefinition = true;
1486f4a2713aSLionel Sambuc
1487f4a2713aSLionel Sambuc // Note that we have deserialized a definition. Any declarations
1488f4a2713aSLionel Sambuc // deserialized before this one will be be given the DefinitionData
1489f4a2713aSLionel Sambuc // pointer at the end.
1490f4a2713aSLionel Sambuc Reader.PendingDefinitions.insert(D);
1491f4a2713aSLionel Sambuc }
1492f4a2713aSLionel Sambuc }
1493f4a2713aSLionel Sambuc
1494*0a6a1f1dSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitCXXRecordDeclImpl(CXXRecordDecl * D)1495*0a6a1f1dSLionel Sambuc ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
1496*0a6a1f1dSLionel Sambuc RedeclarableResult Redecl = VisitRecordDeclImpl(D);
1497*0a6a1f1dSLionel Sambuc
1498*0a6a1f1dSLionel Sambuc ASTContext &C = Reader.getContext();
1499*0a6a1f1dSLionel Sambuc
1500f4a2713aSLionel Sambuc enum CXXRecKind {
1501f4a2713aSLionel Sambuc CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
1502f4a2713aSLionel Sambuc };
1503f4a2713aSLionel Sambuc switch ((CXXRecKind)Record[Idx++]) {
1504f4a2713aSLionel Sambuc case CXXRecNotTemplate:
1505*0a6a1f1dSLionel Sambuc // Merged when we merge the folding set entry in the primary template.
1506*0a6a1f1dSLionel Sambuc if (!isa<ClassTemplateSpecializationDecl>(D))
1507*0a6a1f1dSLionel Sambuc mergeRedeclarable(D, Redecl);
1508f4a2713aSLionel Sambuc break;
1509*0a6a1f1dSLionel Sambuc case CXXRecTemplate: {
1510*0a6a1f1dSLionel Sambuc // Merged when we merge the template.
1511*0a6a1f1dSLionel Sambuc ClassTemplateDecl *Template = ReadDeclAs<ClassTemplateDecl>(Record, Idx);
1512*0a6a1f1dSLionel Sambuc D->TemplateOrInstantiation = Template;
1513*0a6a1f1dSLionel Sambuc if (!Template->getTemplatedDecl()) {
1514*0a6a1f1dSLionel Sambuc // We've not actually loaded the ClassTemplateDecl yet, because we're
1515*0a6a1f1dSLionel Sambuc // currently being loaded as its pattern. Rely on it to set up our
1516*0a6a1f1dSLionel Sambuc // TypeForDecl (see VisitClassTemplateDecl).
1517*0a6a1f1dSLionel Sambuc //
1518*0a6a1f1dSLionel Sambuc // Beware: we do not yet know our canonical declaration, and may still
1519*0a6a1f1dSLionel Sambuc // get merged once the surrounding class template has got off the ground.
1520*0a6a1f1dSLionel Sambuc TypeIDForTypeDecl = 0;
1521*0a6a1f1dSLionel Sambuc }
1522f4a2713aSLionel Sambuc break;
1523*0a6a1f1dSLionel Sambuc }
1524f4a2713aSLionel Sambuc case CXXRecMemberSpecialization: {
1525f4a2713aSLionel Sambuc CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(Record, Idx);
1526f4a2713aSLionel Sambuc TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
1527f4a2713aSLionel Sambuc SourceLocation POI = ReadSourceLocation(Record, Idx);
1528f4a2713aSLionel Sambuc MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
1529f4a2713aSLionel Sambuc MSI->setPointOfInstantiation(POI);
1530f4a2713aSLionel Sambuc D->TemplateOrInstantiation = MSI;
1531*0a6a1f1dSLionel Sambuc mergeRedeclarable(D, Redecl);
1532f4a2713aSLionel Sambuc break;
1533f4a2713aSLionel Sambuc }
1534f4a2713aSLionel Sambuc }
1535f4a2713aSLionel Sambuc
1536*0a6a1f1dSLionel Sambuc bool WasDefinition = Record[Idx++];
1537*0a6a1f1dSLionel Sambuc if (WasDefinition)
1538*0a6a1f1dSLionel Sambuc ReadCXXRecordDefinition(D);
1539*0a6a1f1dSLionel Sambuc else
1540*0a6a1f1dSLionel Sambuc // Propagate DefinitionData pointer from the canonical declaration.
1541*0a6a1f1dSLionel Sambuc D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
1542*0a6a1f1dSLionel Sambuc
1543f4a2713aSLionel Sambuc // Lazily load the key function to avoid deserializing every method so we can
1544f4a2713aSLionel Sambuc // compute it.
1545f4a2713aSLionel Sambuc if (WasDefinition) {
1546f4a2713aSLionel Sambuc DeclID KeyFn = ReadDeclID(Record, Idx);
1547f4a2713aSLionel Sambuc if (KeyFn && D->IsCompleteDefinition)
1548*0a6a1f1dSLionel Sambuc // FIXME: This is wrong for the ARM ABI, where some other module may have
1549*0a6a1f1dSLionel Sambuc // made this function no longer be a key function. We need an update
1550*0a6a1f1dSLionel Sambuc // record or similar for that case.
1551f4a2713aSLionel Sambuc C.KeyFunctions[D] = KeyFn;
1552f4a2713aSLionel Sambuc }
1553f4a2713aSLionel Sambuc
1554f4a2713aSLionel Sambuc return Redecl;
1555f4a2713aSLionel Sambuc }
1556f4a2713aSLionel Sambuc
VisitCXXMethodDecl(CXXMethodDecl * D)1557f4a2713aSLionel Sambuc void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
1558f4a2713aSLionel Sambuc VisitFunctionDecl(D);
1559*0a6a1f1dSLionel Sambuc
1560f4a2713aSLionel Sambuc unsigned NumOverridenMethods = Record[Idx++];
1561*0a6a1f1dSLionel Sambuc if (D->isCanonicalDecl()) {
1562f4a2713aSLionel Sambuc while (NumOverridenMethods--) {
1563f4a2713aSLionel Sambuc // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
1564f4a2713aSLionel Sambuc // MD may be initializing.
1565f4a2713aSLionel Sambuc if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
1566*0a6a1f1dSLionel Sambuc Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl());
1567*0a6a1f1dSLionel Sambuc }
1568*0a6a1f1dSLionel Sambuc } else {
1569*0a6a1f1dSLionel Sambuc // We don't care about which declarations this used to override; we get
1570*0a6a1f1dSLionel Sambuc // the relevant information from the canonical declaration.
1571*0a6a1f1dSLionel Sambuc Idx += NumOverridenMethods;
1572f4a2713aSLionel Sambuc }
1573f4a2713aSLionel Sambuc }
1574f4a2713aSLionel Sambuc
VisitCXXConstructorDecl(CXXConstructorDecl * D)1575f4a2713aSLionel Sambuc void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
1576f4a2713aSLionel Sambuc VisitCXXMethodDecl(D);
1577f4a2713aSLionel Sambuc
1578*0a6a1f1dSLionel Sambuc if (auto *CD = ReadDeclAs<CXXConstructorDecl>(Record, Idx))
1579*0a6a1f1dSLionel Sambuc D->setInheritedConstructor(CD);
1580f4a2713aSLionel Sambuc D->IsExplicitSpecified = Record[Idx++];
1581*0a6a1f1dSLionel Sambuc // FIXME: We should defer loading this until we need the constructor's body.
1582*0a6a1f1dSLionel Sambuc std::tie(D->CtorInitializers, D->NumCtorInitializers) =
1583*0a6a1f1dSLionel Sambuc Reader.ReadCXXCtorInitializers(F, Record, Idx);
1584f4a2713aSLionel Sambuc }
1585f4a2713aSLionel Sambuc
VisitCXXDestructorDecl(CXXDestructorDecl * D)1586f4a2713aSLionel Sambuc void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
1587f4a2713aSLionel Sambuc VisitCXXMethodDecl(D);
1588f4a2713aSLionel Sambuc
1589f4a2713aSLionel Sambuc D->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx);
1590f4a2713aSLionel Sambuc }
1591f4a2713aSLionel Sambuc
VisitCXXConversionDecl(CXXConversionDecl * D)1592f4a2713aSLionel Sambuc void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
1593f4a2713aSLionel Sambuc VisitCXXMethodDecl(D);
1594f4a2713aSLionel Sambuc D->IsExplicitSpecified = Record[Idx++];
1595f4a2713aSLionel Sambuc }
1596f4a2713aSLionel Sambuc
VisitImportDecl(ImportDecl * D)1597f4a2713aSLionel Sambuc void ASTDeclReader::VisitImportDecl(ImportDecl *D) {
1598f4a2713aSLionel Sambuc VisitDecl(D);
1599f4a2713aSLionel Sambuc D->ImportedAndComplete.setPointer(readModule(Record, Idx));
1600f4a2713aSLionel Sambuc D->ImportedAndComplete.setInt(Record[Idx++]);
1601f4a2713aSLionel Sambuc SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(D + 1);
1602f4a2713aSLionel Sambuc for (unsigned I = 0, N = Record.back(); I != N; ++I)
1603f4a2713aSLionel Sambuc StoredLocs[I] = ReadSourceLocation(Record, Idx);
1604f4a2713aSLionel Sambuc ++Idx; // The number of stored source locations.
1605f4a2713aSLionel Sambuc }
1606f4a2713aSLionel Sambuc
VisitAccessSpecDecl(AccessSpecDecl * D)1607f4a2713aSLionel Sambuc void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
1608f4a2713aSLionel Sambuc VisitDecl(D);
1609f4a2713aSLionel Sambuc D->setColonLoc(ReadSourceLocation(Record, Idx));
1610f4a2713aSLionel Sambuc }
1611f4a2713aSLionel Sambuc
VisitFriendDecl(FriendDecl * D)1612f4a2713aSLionel Sambuc void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
1613f4a2713aSLionel Sambuc VisitDecl(D);
1614f4a2713aSLionel Sambuc if (Record[Idx++]) // hasFriendDecl
1615f4a2713aSLionel Sambuc D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
1616f4a2713aSLionel Sambuc else
1617f4a2713aSLionel Sambuc D->Friend = GetTypeSourceInfo(Record, Idx);
1618f4a2713aSLionel Sambuc for (unsigned i = 0; i != D->NumTPLists; ++i)
1619f4a2713aSLionel Sambuc D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
1620f4a2713aSLionel Sambuc D->NextFriend = ReadDeclID(Record, Idx);
1621f4a2713aSLionel Sambuc D->UnsupportedFriend = (Record[Idx++] != 0);
1622f4a2713aSLionel Sambuc D->FriendLoc = ReadSourceLocation(Record, Idx);
1623f4a2713aSLionel Sambuc }
1624f4a2713aSLionel Sambuc
VisitFriendTemplateDecl(FriendTemplateDecl * D)1625f4a2713aSLionel Sambuc void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
1626f4a2713aSLionel Sambuc VisitDecl(D);
1627f4a2713aSLionel Sambuc unsigned NumParams = Record[Idx++];
1628f4a2713aSLionel Sambuc D->NumParams = NumParams;
1629f4a2713aSLionel Sambuc D->Params = new TemplateParameterList*[NumParams];
1630f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumParams; ++i)
1631f4a2713aSLionel Sambuc D->Params[i] = Reader.ReadTemplateParameterList(F, Record, Idx);
1632f4a2713aSLionel Sambuc if (Record[Idx++]) // HasFriendDecl
1633f4a2713aSLionel Sambuc D->Friend = ReadDeclAs<NamedDecl>(Record, Idx);
1634f4a2713aSLionel Sambuc else
1635f4a2713aSLionel Sambuc D->Friend = GetTypeSourceInfo(Record, Idx);
1636f4a2713aSLionel Sambuc D->FriendLoc = ReadSourceLocation(Record, Idx);
1637f4a2713aSLionel Sambuc }
1638f4a2713aSLionel Sambuc
VisitTemplateDecl(TemplateDecl * D)1639*0a6a1f1dSLionel Sambuc DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
1640f4a2713aSLionel Sambuc VisitNamedDecl(D);
1641f4a2713aSLionel Sambuc
1642*0a6a1f1dSLionel Sambuc DeclID PatternID = ReadDeclID(Record, Idx);
1643*0a6a1f1dSLionel Sambuc NamedDecl *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
1644f4a2713aSLionel Sambuc TemplateParameterList* TemplateParams
1645f4a2713aSLionel Sambuc = Reader.ReadTemplateParameterList(F, Record, Idx);
1646f4a2713aSLionel Sambuc D->init(TemplatedDecl, TemplateParams);
1647f4a2713aSLionel Sambuc
1648f4a2713aSLionel Sambuc // FIXME: If this is a redeclaration of a template from another module, handle
1649f4a2713aSLionel Sambuc // inheritance of default template arguments.
1650*0a6a1f1dSLionel Sambuc
1651*0a6a1f1dSLionel Sambuc return PatternID;
1652f4a2713aSLionel Sambuc }
1653f4a2713aSLionel Sambuc
1654f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl * D)1655f4a2713aSLionel Sambuc ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
1656f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarable(D);
1657f4a2713aSLionel Sambuc
1658f4a2713aSLionel Sambuc // Make sure we've allocated the Common pointer first. We do this before
1659f4a2713aSLionel Sambuc // VisitTemplateDecl so that getCommonPtr() can be used during initialization.
1660f4a2713aSLionel Sambuc RedeclarableTemplateDecl *CanonD = D->getCanonicalDecl();
1661f4a2713aSLionel Sambuc if (!CanonD->Common) {
1662f4a2713aSLionel Sambuc CanonD->Common = CanonD->newCommon(Reader.getContext());
1663f4a2713aSLionel Sambuc Reader.PendingDefinitions.insert(CanonD);
1664f4a2713aSLionel Sambuc }
1665f4a2713aSLionel Sambuc D->Common = CanonD->Common;
1666f4a2713aSLionel Sambuc
1667f4a2713aSLionel Sambuc // If this is the first declaration of the template, fill in the information
1668f4a2713aSLionel Sambuc // for the 'common' pointer.
1669f4a2713aSLionel Sambuc if (ThisDeclID == Redecl.getFirstID()) {
1670f4a2713aSLionel Sambuc if (RedeclarableTemplateDecl *RTD
1671f4a2713aSLionel Sambuc = ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
1672f4a2713aSLionel Sambuc assert(RTD->getKind() == D->getKind() &&
1673f4a2713aSLionel Sambuc "InstantiatedFromMemberTemplate kind mismatch");
1674f4a2713aSLionel Sambuc D->setInstantiatedFromMemberTemplate(RTD);
1675f4a2713aSLionel Sambuc if (Record[Idx++])
1676f4a2713aSLionel Sambuc D->setMemberSpecialization();
1677f4a2713aSLionel Sambuc }
1678f4a2713aSLionel Sambuc }
1679f4a2713aSLionel Sambuc
1680*0a6a1f1dSLionel Sambuc DeclID PatternID = VisitTemplateDecl(D);
1681f4a2713aSLionel Sambuc D->IdentifierNamespace = Record[Idx++];
1682f4a2713aSLionel Sambuc
1683*0a6a1f1dSLionel Sambuc mergeRedeclarable(D, Redecl, PatternID);
1684f4a2713aSLionel Sambuc
1685f4a2713aSLionel Sambuc // If we merged the template with a prior declaration chain, merge the common
1686f4a2713aSLionel Sambuc // pointer.
1687f4a2713aSLionel Sambuc // FIXME: Actually merge here, don't just overwrite.
1688f4a2713aSLionel Sambuc D->Common = D->getCanonicalDecl()->Common;
1689f4a2713aSLionel Sambuc
1690f4a2713aSLionel Sambuc return Redecl;
1691f4a2713aSLionel Sambuc }
1692f4a2713aSLionel Sambuc
VisitClassTemplateDecl(ClassTemplateDecl * D)1693f4a2713aSLionel Sambuc void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1694f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
1695f4a2713aSLionel Sambuc
1696f4a2713aSLionel Sambuc if (ThisDeclID == Redecl.getFirstID()) {
1697f4a2713aSLionel Sambuc // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
1698f4a2713aSLionel Sambuc // the specializations.
1699f4a2713aSLionel Sambuc SmallVector<serialization::DeclID, 2> SpecIDs;
1700f4a2713aSLionel Sambuc SpecIDs.push_back(0);
1701f4a2713aSLionel Sambuc
1702f4a2713aSLionel Sambuc // Specializations.
1703f4a2713aSLionel Sambuc unsigned Size = Record[Idx++];
1704f4a2713aSLionel Sambuc SpecIDs[0] += Size;
1705f4a2713aSLionel Sambuc for (unsigned I = 0; I != Size; ++I)
1706f4a2713aSLionel Sambuc SpecIDs.push_back(ReadDeclID(Record, Idx));
1707f4a2713aSLionel Sambuc
1708f4a2713aSLionel Sambuc // Partial specializations.
1709f4a2713aSLionel Sambuc Size = Record[Idx++];
1710f4a2713aSLionel Sambuc SpecIDs[0] += Size;
1711f4a2713aSLionel Sambuc for (unsigned I = 0; I != Size; ++I)
1712f4a2713aSLionel Sambuc SpecIDs.push_back(ReadDeclID(Record, Idx));
1713f4a2713aSLionel Sambuc
1714f4a2713aSLionel Sambuc ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
1715f4a2713aSLionel Sambuc if (SpecIDs[0]) {
1716f4a2713aSLionel Sambuc typedef serialization::DeclID DeclID;
1717f4a2713aSLionel Sambuc
1718f4a2713aSLionel Sambuc // FIXME: Append specializations!
1719f4a2713aSLionel Sambuc CommonPtr->LazySpecializations
1720f4a2713aSLionel Sambuc = new (Reader.getContext()) DeclID [SpecIDs.size()];
1721f4a2713aSLionel Sambuc memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
1722f4a2713aSLionel Sambuc SpecIDs.size() * sizeof(DeclID));
1723f4a2713aSLionel Sambuc }
1724*0a6a1f1dSLionel Sambuc }
1725f4a2713aSLionel Sambuc
1726*0a6a1f1dSLionel Sambuc if (D->getTemplatedDecl()->TemplateOrInstantiation) {
1727*0a6a1f1dSLionel Sambuc // We were loaded before our templated declaration was. We've not set up
1728*0a6a1f1dSLionel Sambuc // its corresponding type yet (see VisitCXXRecordDeclImpl), so reconstruct
1729*0a6a1f1dSLionel Sambuc // it now.
1730*0a6a1f1dSLionel Sambuc Reader.Context.getInjectedClassNameType(
1731*0a6a1f1dSLionel Sambuc D->getTemplatedDecl(), D->getInjectedClassNameSpecialization());
1732f4a2713aSLionel Sambuc }
1733f4a2713aSLionel Sambuc }
1734f4a2713aSLionel Sambuc
1735f4a2713aSLionel Sambuc /// TODO: Unify with ClassTemplateDecl version?
1736f4a2713aSLionel Sambuc /// May require unifying ClassTemplateDecl and
1737f4a2713aSLionel Sambuc /// VarTemplateDecl beyond TemplateDecl...
VisitVarTemplateDecl(VarTemplateDecl * D)1738f4a2713aSLionel Sambuc void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
1739f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
1740f4a2713aSLionel Sambuc
1741f4a2713aSLionel Sambuc if (ThisDeclID == Redecl.getFirstID()) {
1742f4a2713aSLionel Sambuc // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of
1743f4a2713aSLionel Sambuc // the specializations.
1744f4a2713aSLionel Sambuc SmallVector<serialization::DeclID, 2> SpecIDs;
1745f4a2713aSLionel Sambuc SpecIDs.push_back(0);
1746f4a2713aSLionel Sambuc
1747f4a2713aSLionel Sambuc // Specializations.
1748f4a2713aSLionel Sambuc unsigned Size = Record[Idx++];
1749f4a2713aSLionel Sambuc SpecIDs[0] += Size;
1750f4a2713aSLionel Sambuc for (unsigned I = 0; I != Size; ++I)
1751f4a2713aSLionel Sambuc SpecIDs.push_back(ReadDeclID(Record, Idx));
1752f4a2713aSLionel Sambuc
1753f4a2713aSLionel Sambuc // Partial specializations.
1754f4a2713aSLionel Sambuc Size = Record[Idx++];
1755f4a2713aSLionel Sambuc SpecIDs[0] += Size;
1756f4a2713aSLionel Sambuc for (unsigned I = 0; I != Size; ++I)
1757f4a2713aSLionel Sambuc SpecIDs.push_back(ReadDeclID(Record, Idx));
1758f4a2713aSLionel Sambuc
1759f4a2713aSLionel Sambuc VarTemplateDecl::Common *CommonPtr = D->getCommonPtr();
1760f4a2713aSLionel Sambuc if (SpecIDs[0]) {
1761f4a2713aSLionel Sambuc typedef serialization::DeclID DeclID;
1762f4a2713aSLionel Sambuc
1763f4a2713aSLionel Sambuc // FIXME: Append specializations!
1764f4a2713aSLionel Sambuc CommonPtr->LazySpecializations =
1765f4a2713aSLionel Sambuc new (Reader.getContext()) DeclID[SpecIDs.size()];
1766f4a2713aSLionel Sambuc memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
1767f4a2713aSLionel Sambuc SpecIDs.size() * sizeof(DeclID));
1768f4a2713aSLionel Sambuc }
1769f4a2713aSLionel Sambuc }
1770f4a2713aSLionel Sambuc }
1771f4a2713aSLionel Sambuc
1772f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitClassTemplateSpecializationDeclImpl(ClassTemplateSpecializationDecl * D)1773f4a2713aSLionel Sambuc ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
1774f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl *D) {
1775f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitCXXRecordDeclImpl(D);
1776f4a2713aSLionel Sambuc
1777f4a2713aSLionel Sambuc ASTContext &C = Reader.getContext();
1778f4a2713aSLionel Sambuc if (Decl *InstD = ReadDecl(Record, Idx)) {
1779f4a2713aSLionel Sambuc if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
1780f4a2713aSLionel Sambuc D->SpecializedTemplate = CTD;
1781f4a2713aSLionel Sambuc } else {
1782f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> TemplArgs;
1783f4a2713aSLionel Sambuc Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
1784f4a2713aSLionel Sambuc TemplateArgumentList *ArgList
1785f4a2713aSLionel Sambuc = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
1786f4a2713aSLionel Sambuc TemplArgs.size());
1787f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl::SpecializedPartialSpecialization *PS
1788f4a2713aSLionel Sambuc = new (C) ClassTemplateSpecializationDecl::
1789f4a2713aSLionel Sambuc SpecializedPartialSpecialization();
1790f4a2713aSLionel Sambuc PS->PartialSpecialization
1791f4a2713aSLionel Sambuc = cast<ClassTemplatePartialSpecializationDecl>(InstD);
1792f4a2713aSLionel Sambuc PS->TemplateArgs = ArgList;
1793f4a2713aSLionel Sambuc D->SpecializedTemplate = PS;
1794f4a2713aSLionel Sambuc }
1795f4a2713aSLionel Sambuc }
1796f4a2713aSLionel Sambuc
1797f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> TemplArgs;
1798f4a2713aSLionel Sambuc Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
1799f4a2713aSLionel Sambuc D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(),
1800f4a2713aSLionel Sambuc TemplArgs.size());
1801f4a2713aSLionel Sambuc D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
1802f4a2713aSLionel Sambuc D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
1803f4a2713aSLionel Sambuc
1804f4a2713aSLionel Sambuc bool writtenAsCanonicalDecl = Record[Idx++];
1805f4a2713aSLionel Sambuc if (writtenAsCanonicalDecl) {
1806f4a2713aSLionel Sambuc ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx);
1807f4a2713aSLionel Sambuc if (D->isCanonicalDecl()) { // It's kept in the folding set.
1808f4a2713aSLionel Sambuc // Set this as, or find, the canonical declaration for this specialization
1809f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl *CanonSpec;
1810f4a2713aSLionel Sambuc if (ClassTemplatePartialSpecializationDecl *Partial =
1811f4a2713aSLionel Sambuc dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
1812f4a2713aSLionel Sambuc CanonSpec = CanonPattern->getCommonPtr()->PartialSpecializations
1813f4a2713aSLionel Sambuc .GetOrInsertNode(Partial);
1814f4a2713aSLionel Sambuc } else {
1815f4a2713aSLionel Sambuc CanonSpec =
1816f4a2713aSLionel Sambuc CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
1817f4a2713aSLionel Sambuc }
1818f4a2713aSLionel Sambuc // If there was already a canonical specialization, merge into it.
1819f4a2713aSLionel Sambuc if (CanonSpec != D) {
1820f4a2713aSLionel Sambuc mergeRedeclarable<TagDecl>(D, CanonSpec, Redecl);
1821f4a2713aSLionel Sambuc
1822f4a2713aSLionel Sambuc // This declaration might be a definition. Merge with any existing
1823f4a2713aSLionel Sambuc // definition.
1824*0a6a1f1dSLionel Sambuc if (auto *DDD = D->DefinitionData.getNotUpdated()) {
1825*0a6a1f1dSLionel Sambuc if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) {
1826*0a6a1f1dSLionel Sambuc MergeDefinitionData(CanonSpec, *DDD);
1827f4a2713aSLionel Sambuc Reader.PendingDefinitions.erase(D);
1828f4a2713aSLionel Sambuc Reader.MergedDeclContexts.insert(
1829*0a6a1f1dSLionel Sambuc std::make_pair(D, CanonDD->Definition));
1830f4a2713aSLionel Sambuc D->IsCompleteDefinition = false;
1831*0a6a1f1dSLionel Sambuc } else {
1832*0a6a1f1dSLionel Sambuc CanonSpec->DefinitionData = D->DefinitionData;
1833*0a6a1f1dSLionel Sambuc }
1834*0a6a1f1dSLionel Sambuc }
1835f4a2713aSLionel Sambuc D->DefinitionData = CanonSpec->DefinitionData;
1836f4a2713aSLionel Sambuc }
1837f4a2713aSLionel Sambuc }
1838f4a2713aSLionel Sambuc }
1839f4a2713aSLionel Sambuc
1840f4a2713aSLionel Sambuc // Explicit info.
1841f4a2713aSLionel Sambuc if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) {
1842f4a2713aSLionel Sambuc ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo
1843f4a2713aSLionel Sambuc = new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
1844f4a2713aSLionel Sambuc ExplicitInfo->TypeAsWritten = TyInfo;
1845f4a2713aSLionel Sambuc ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx);
1846f4a2713aSLionel Sambuc ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx);
1847f4a2713aSLionel Sambuc D->ExplicitInfo = ExplicitInfo;
1848f4a2713aSLionel Sambuc }
1849f4a2713aSLionel Sambuc
1850f4a2713aSLionel Sambuc return Redecl;
1851f4a2713aSLionel Sambuc }
1852f4a2713aSLionel Sambuc
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)1853f4a2713aSLionel Sambuc void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
1854f4a2713aSLionel Sambuc ClassTemplatePartialSpecializationDecl *D) {
1855f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
1856f4a2713aSLionel Sambuc
1857f4a2713aSLionel Sambuc D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx);
1858f4a2713aSLionel Sambuc D->ArgsAsWritten = Reader.ReadASTTemplateArgumentListInfo(F, Record, Idx);
1859f4a2713aSLionel Sambuc
1860f4a2713aSLionel Sambuc // These are read/set from/to the first declaration.
1861f4a2713aSLionel Sambuc if (ThisDeclID == Redecl.getFirstID()) {
1862f4a2713aSLionel Sambuc D->InstantiatedFromMember.setPointer(
1863f4a2713aSLionel Sambuc ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx));
1864f4a2713aSLionel Sambuc D->InstantiatedFromMember.setInt(Record[Idx++]);
1865f4a2713aSLionel Sambuc }
1866f4a2713aSLionel Sambuc }
1867f4a2713aSLionel Sambuc
VisitClassScopeFunctionSpecializationDecl(ClassScopeFunctionSpecializationDecl * D)1868f4a2713aSLionel Sambuc void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
1869f4a2713aSLionel Sambuc ClassScopeFunctionSpecializationDecl *D) {
1870f4a2713aSLionel Sambuc VisitDecl(D);
1871f4a2713aSLionel Sambuc D->Specialization = ReadDeclAs<CXXMethodDecl>(Record, Idx);
1872f4a2713aSLionel Sambuc }
1873f4a2713aSLionel Sambuc
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)1874f4a2713aSLionel Sambuc void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1875f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
1876f4a2713aSLionel Sambuc
1877f4a2713aSLionel Sambuc if (ThisDeclID == Redecl.getFirstID()) {
1878f4a2713aSLionel Sambuc // This FunctionTemplateDecl owns a CommonPtr; read it.
1879f4a2713aSLionel Sambuc
1880f4a2713aSLionel Sambuc // Read the function specialization declaration IDs. The specializations
1881f4a2713aSLionel Sambuc // themselves will be loaded if they're needed.
1882f4a2713aSLionel Sambuc if (unsigned NumSpecs = Record[Idx++]) {
1883f4a2713aSLionel Sambuc // FIXME: Append specializations!
1884f4a2713aSLionel Sambuc FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr();
1885f4a2713aSLionel Sambuc CommonPtr->LazySpecializations = new (Reader.getContext())
1886f4a2713aSLionel Sambuc serialization::DeclID[NumSpecs + 1];
1887f4a2713aSLionel Sambuc CommonPtr->LazySpecializations[0] = NumSpecs;
1888f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumSpecs; ++I)
1889f4a2713aSLionel Sambuc CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx);
1890f4a2713aSLionel Sambuc }
1891f4a2713aSLionel Sambuc }
1892f4a2713aSLionel Sambuc }
1893f4a2713aSLionel Sambuc
1894f4a2713aSLionel Sambuc /// TODO: Unify with ClassTemplateSpecializationDecl version?
1895f4a2713aSLionel Sambuc /// May require unifying ClassTemplate(Partial)SpecializationDecl and
1896f4a2713aSLionel Sambuc /// VarTemplate(Partial)SpecializationDecl with a new data
1897f4a2713aSLionel Sambuc /// structure Template(Partial)SpecializationDecl, and
1898f4a2713aSLionel Sambuc /// using Template(Partial)SpecializationDecl as input type.
1899f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl * D)1900f4a2713aSLionel Sambuc ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
1901f4a2713aSLionel Sambuc VarTemplateSpecializationDecl *D) {
1902f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitVarDeclImpl(D);
1903f4a2713aSLionel Sambuc
1904f4a2713aSLionel Sambuc ASTContext &C = Reader.getContext();
1905f4a2713aSLionel Sambuc if (Decl *InstD = ReadDecl(Record, Idx)) {
1906f4a2713aSLionel Sambuc if (VarTemplateDecl *VTD = dyn_cast<VarTemplateDecl>(InstD)) {
1907f4a2713aSLionel Sambuc D->SpecializedTemplate = VTD;
1908f4a2713aSLionel Sambuc } else {
1909f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> TemplArgs;
1910f4a2713aSLionel Sambuc Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
1911f4a2713aSLionel Sambuc TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy(
1912f4a2713aSLionel Sambuc C, TemplArgs.data(), TemplArgs.size());
1913f4a2713aSLionel Sambuc VarTemplateSpecializationDecl::SpecializedPartialSpecialization *PS =
1914f4a2713aSLionel Sambuc new (C)
1915f4a2713aSLionel Sambuc VarTemplateSpecializationDecl::SpecializedPartialSpecialization();
1916f4a2713aSLionel Sambuc PS->PartialSpecialization =
1917f4a2713aSLionel Sambuc cast<VarTemplatePartialSpecializationDecl>(InstD);
1918f4a2713aSLionel Sambuc PS->TemplateArgs = ArgList;
1919f4a2713aSLionel Sambuc D->SpecializedTemplate = PS;
1920f4a2713aSLionel Sambuc }
1921f4a2713aSLionel Sambuc }
1922f4a2713aSLionel Sambuc
1923f4a2713aSLionel Sambuc // Explicit info.
1924f4a2713aSLionel Sambuc if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) {
1925f4a2713aSLionel Sambuc VarTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo =
1926f4a2713aSLionel Sambuc new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
1927f4a2713aSLionel Sambuc ExplicitInfo->TypeAsWritten = TyInfo;
1928f4a2713aSLionel Sambuc ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx);
1929f4a2713aSLionel Sambuc ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx);
1930f4a2713aSLionel Sambuc D->ExplicitInfo = ExplicitInfo;
1931f4a2713aSLionel Sambuc }
1932f4a2713aSLionel Sambuc
1933f4a2713aSLionel Sambuc SmallVector<TemplateArgument, 8> TemplArgs;
1934f4a2713aSLionel Sambuc Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
1935f4a2713aSLionel Sambuc D->TemplateArgs =
1936f4a2713aSLionel Sambuc TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
1937f4a2713aSLionel Sambuc D->PointOfInstantiation = ReadSourceLocation(Record, Idx);
1938f4a2713aSLionel Sambuc D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++];
1939f4a2713aSLionel Sambuc
1940f4a2713aSLionel Sambuc bool writtenAsCanonicalDecl = Record[Idx++];
1941f4a2713aSLionel Sambuc if (writtenAsCanonicalDecl) {
1942f4a2713aSLionel Sambuc VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>(Record, Idx);
1943f4a2713aSLionel Sambuc if (D->isCanonicalDecl()) { // It's kept in the folding set.
1944f4a2713aSLionel Sambuc if (VarTemplatePartialSpecializationDecl *Partial =
1945f4a2713aSLionel Sambuc dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
1946f4a2713aSLionel Sambuc CanonPattern->getCommonPtr()->PartialSpecializations
1947f4a2713aSLionel Sambuc .GetOrInsertNode(Partial);
1948f4a2713aSLionel Sambuc } else {
1949f4a2713aSLionel Sambuc CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D);
1950f4a2713aSLionel Sambuc }
1951f4a2713aSLionel Sambuc }
1952f4a2713aSLionel Sambuc }
1953f4a2713aSLionel Sambuc
1954f4a2713aSLionel Sambuc return Redecl;
1955f4a2713aSLionel Sambuc }
1956f4a2713aSLionel Sambuc
1957f4a2713aSLionel Sambuc /// TODO: Unify with ClassTemplatePartialSpecializationDecl version?
1958f4a2713aSLionel Sambuc /// May require unifying ClassTemplate(Partial)SpecializationDecl and
1959f4a2713aSLionel Sambuc /// VarTemplate(Partial)SpecializationDecl with a new data
1960f4a2713aSLionel Sambuc /// structure Template(Partial)SpecializationDecl, and
1961f4a2713aSLionel Sambuc /// using Template(Partial)SpecializationDecl as input type.
VisitVarTemplatePartialSpecializationDecl(VarTemplatePartialSpecializationDecl * D)1962f4a2713aSLionel Sambuc void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl(
1963f4a2713aSLionel Sambuc VarTemplatePartialSpecializationDecl *D) {
1964f4a2713aSLionel Sambuc RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
1965f4a2713aSLionel Sambuc
1966f4a2713aSLionel Sambuc D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx);
1967f4a2713aSLionel Sambuc D->ArgsAsWritten = Reader.ReadASTTemplateArgumentListInfo(F, Record, Idx);
1968f4a2713aSLionel Sambuc
1969f4a2713aSLionel Sambuc // These are read/set from/to the first declaration.
1970f4a2713aSLionel Sambuc if (ThisDeclID == Redecl.getFirstID()) {
1971f4a2713aSLionel Sambuc D->InstantiatedFromMember.setPointer(
1972f4a2713aSLionel Sambuc ReadDeclAs<VarTemplatePartialSpecializationDecl>(Record, Idx));
1973f4a2713aSLionel Sambuc D->InstantiatedFromMember.setInt(Record[Idx++]);
1974f4a2713aSLionel Sambuc }
1975f4a2713aSLionel Sambuc }
1976f4a2713aSLionel Sambuc
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)1977f4a2713aSLionel Sambuc void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
1978f4a2713aSLionel Sambuc VisitTypeDecl(D);
1979f4a2713aSLionel Sambuc
1980f4a2713aSLionel Sambuc D->setDeclaredWithTypename(Record[Idx++]);
1981f4a2713aSLionel Sambuc
1982f4a2713aSLionel Sambuc bool Inherited = Record[Idx++];
1983f4a2713aSLionel Sambuc TypeSourceInfo *DefArg = GetTypeSourceInfo(Record, Idx);
1984f4a2713aSLionel Sambuc D->setDefaultArgument(DefArg, Inherited);
1985f4a2713aSLionel Sambuc }
1986f4a2713aSLionel Sambuc
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)1987f4a2713aSLionel Sambuc void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
1988f4a2713aSLionel Sambuc VisitDeclaratorDecl(D);
1989f4a2713aSLionel Sambuc // TemplateParmPosition.
1990f4a2713aSLionel Sambuc D->setDepth(Record[Idx++]);
1991f4a2713aSLionel Sambuc D->setPosition(Record[Idx++]);
1992f4a2713aSLionel Sambuc if (D->isExpandedParameterPack()) {
1993f4a2713aSLionel Sambuc void **Data = reinterpret_cast<void **>(D + 1);
1994f4a2713aSLionel Sambuc for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
1995f4a2713aSLionel Sambuc Data[2*I] = Reader.readType(F, Record, Idx).getAsOpaquePtr();
1996f4a2713aSLionel Sambuc Data[2*I + 1] = GetTypeSourceInfo(Record, Idx);
1997f4a2713aSLionel Sambuc }
1998f4a2713aSLionel Sambuc } else {
1999f4a2713aSLionel Sambuc // Rest of NonTypeTemplateParmDecl.
2000f4a2713aSLionel Sambuc D->ParameterPack = Record[Idx++];
2001f4a2713aSLionel Sambuc if (Record[Idx++]) {
2002f4a2713aSLionel Sambuc Expr *DefArg = Reader.ReadExpr(F);
2003f4a2713aSLionel Sambuc bool Inherited = Record[Idx++];
2004f4a2713aSLionel Sambuc D->setDefaultArgument(DefArg, Inherited);
2005f4a2713aSLionel Sambuc }
2006f4a2713aSLionel Sambuc }
2007f4a2713aSLionel Sambuc }
2008f4a2713aSLionel Sambuc
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)2009f4a2713aSLionel Sambuc void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
2010f4a2713aSLionel Sambuc VisitTemplateDecl(D);
2011f4a2713aSLionel Sambuc // TemplateParmPosition.
2012f4a2713aSLionel Sambuc D->setDepth(Record[Idx++]);
2013f4a2713aSLionel Sambuc D->setPosition(Record[Idx++]);
2014f4a2713aSLionel Sambuc if (D->isExpandedParameterPack()) {
2015f4a2713aSLionel Sambuc void **Data = reinterpret_cast<void **>(D + 1);
2016f4a2713aSLionel Sambuc for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
2017f4a2713aSLionel Sambuc I != N; ++I)
2018f4a2713aSLionel Sambuc Data[I] = Reader.ReadTemplateParameterList(F, Record, Idx);
2019f4a2713aSLionel Sambuc } else {
2020f4a2713aSLionel Sambuc // Rest of TemplateTemplateParmDecl.
2021f4a2713aSLionel Sambuc TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(F, Record, Idx);
2022f4a2713aSLionel Sambuc bool IsInherited = Record[Idx++];
2023f4a2713aSLionel Sambuc D->setDefaultArgument(Arg, IsInherited);
2024f4a2713aSLionel Sambuc D->ParameterPack = Record[Idx++];
2025f4a2713aSLionel Sambuc }
2026f4a2713aSLionel Sambuc }
2027f4a2713aSLionel Sambuc
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)2028f4a2713aSLionel Sambuc void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
2029f4a2713aSLionel Sambuc VisitRedeclarableTemplateDecl(D);
2030f4a2713aSLionel Sambuc }
2031f4a2713aSLionel Sambuc
VisitStaticAssertDecl(StaticAssertDecl * D)2032f4a2713aSLionel Sambuc void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
2033f4a2713aSLionel Sambuc VisitDecl(D);
2034f4a2713aSLionel Sambuc D->AssertExprAndFailed.setPointer(Reader.ReadExpr(F));
2035f4a2713aSLionel Sambuc D->AssertExprAndFailed.setInt(Record[Idx++]);
2036f4a2713aSLionel Sambuc D->Message = cast<StringLiteral>(Reader.ReadExpr(F));
2037f4a2713aSLionel Sambuc D->RParenLoc = ReadSourceLocation(Record, Idx);
2038f4a2713aSLionel Sambuc }
2039f4a2713aSLionel Sambuc
VisitEmptyDecl(EmptyDecl * D)2040f4a2713aSLionel Sambuc void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {
2041f4a2713aSLionel Sambuc VisitDecl(D);
2042f4a2713aSLionel Sambuc }
2043f4a2713aSLionel Sambuc
2044f4a2713aSLionel Sambuc std::pair<uint64_t, uint64_t>
VisitDeclContext(DeclContext * DC)2045f4a2713aSLionel Sambuc ASTDeclReader::VisitDeclContext(DeclContext *DC) {
2046f4a2713aSLionel Sambuc uint64_t LexicalOffset = Record[Idx++];
2047f4a2713aSLionel Sambuc uint64_t VisibleOffset = Record[Idx++];
2048f4a2713aSLionel Sambuc return std::make_pair(LexicalOffset, VisibleOffset);
2049f4a2713aSLionel Sambuc }
2050f4a2713aSLionel Sambuc
2051f4a2713aSLionel Sambuc template <typename T>
2052f4a2713aSLionel Sambuc ASTDeclReader::RedeclarableResult
VisitRedeclarable(Redeclarable<T> * D)2053f4a2713aSLionel Sambuc ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
2054f4a2713aSLionel Sambuc DeclID FirstDeclID = ReadDeclID(Record, Idx);
2055f4a2713aSLionel Sambuc
2056f4a2713aSLionel Sambuc // 0 indicates that this declaration was the only declaration of its entity,
2057f4a2713aSLionel Sambuc // and is used for space optimization.
2058f4a2713aSLionel Sambuc if (FirstDeclID == 0)
2059f4a2713aSLionel Sambuc FirstDeclID = ThisDeclID;
2060f4a2713aSLionel Sambuc
2061f4a2713aSLionel Sambuc T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID));
2062f4a2713aSLionel Sambuc if (FirstDecl != D) {
2063f4a2713aSLionel Sambuc // We delay loading of the redeclaration chain to avoid deeply nested calls.
2064f4a2713aSLionel Sambuc // We temporarily set the first (canonical) declaration as the previous one
2065f4a2713aSLionel Sambuc // which is the one that matters and mark the real previous DeclID to be
2066f4a2713aSLionel Sambuc // loaded & attached later on.
2067f4a2713aSLionel Sambuc D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl);
2068f4a2713aSLionel Sambuc }
2069f4a2713aSLionel Sambuc
2070f4a2713aSLionel Sambuc // Note that this declaration has been deserialized.
2071f4a2713aSLionel Sambuc Reader.RedeclsDeserialized.insert(static_cast<T *>(D));
2072f4a2713aSLionel Sambuc
2073f4a2713aSLionel Sambuc // The result structure takes care to note that we need to load the
2074f4a2713aSLionel Sambuc // other declaration chains for this ID.
2075f4a2713aSLionel Sambuc return RedeclarableResult(Reader, FirstDeclID,
2076f4a2713aSLionel Sambuc static_cast<T *>(D)->getKind());
2077f4a2713aSLionel Sambuc }
2078f4a2713aSLionel Sambuc
2079f4a2713aSLionel Sambuc /// \brief Attempts to merge the given declaration (D) with another declaration
2080f4a2713aSLionel Sambuc /// of the same entity.
2081f4a2713aSLionel Sambuc template<typename T>
mergeRedeclarable(Redeclarable<T> * DBase,RedeclarableResult & Redecl,DeclID TemplatePatternID)2082*0a6a1f1dSLionel Sambuc void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
2083*0a6a1f1dSLionel Sambuc RedeclarableResult &Redecl,
2084*0a6a1f1dSLionel Sambuc DeclID TemplatePatternID) {
2085*0a6a1f1dSLionel Sambuc T *D = static_cast<T*>(DBase);
2086*0a6a1f1dSLionel Sambuc T *DCanon = D->getCanonicalDecl();
2087*0a6a1f1dSLionel Sambuc if (D != DCanon &&
2088*0a6a1f1dSLionel Sambuc // IDs < NUM_PREDEF_DECL_IDS are not loaded from an AST file.
2089*0a6a1f1dSLionel Sambuc Redecl.getFirstID() >= NUM_PREDEF_DECL_IDS &&
2090*0a6a1f1dSLionel Sambuc (!Reader.getContext().getLangOpts().Modules ||
2091*0a6a1f1dSLionel Sambuc Reader.getOwningModuleFile(DCanon) == Reader.getOwningModuleFile(D))) {
2092*0a6a1f1dSLionel Sambuc // All redeclarations between this declaration and its originally-canonical
2093*0a6a1f1dSLionel Sambuc // declaration get pulled in when we load DCanon; we don't need to
2094*0a6a1f1dSLionel Sambuc // perform any more merging now.
2095*0a6a1f1dSLionel Sambuc Redecl.suppress();
2096*0a6a1f1dSLionel Sambuc }
2097*0a6a1f1dSLionel Sambuc
2098f4a2713aSLionel Sambuc // If modules are not available, there is no reason to perform this merge.
2099f4a2713aSLionel Sambuc if (!Reader.getContext().getLangOpts().Modules)
2100f4a2713aSLionel Sambuc return;
2101f4a2713aSLionel Sambuc
2102*0a6a1f1dSLionel Sambuc if (FindExistingResult ExistingRes = findExisting(D))
2103f4a2713aSLionel Sambuc if (T *Existing = ExistingRes)
2104*0a6a1f1dSLionel Sambuc mergeRedeclarable(D, Existing, Redecl, TemplatePatternID);
2105*0a6a1f1dSLionel Sambuc }
2106*0a6a1f1dSLionel Sambuc
2107*0a6a1f1dSLionel Sambuc /// \brief "Cast" to type T, asserting if we don't have an implicit conversion.
2108*0a6a1f1dSLionel Sambuc /// We use this to put code in a template that will only be valid for certain
2109*0a6a1f1dSLionel Sambuc /// instantiations.
assert_cast(T t)2110*0a6a1f1dSLionel Sambuc template<typename T> static T assert_cast(T t) { return t; }
assert_cast(...)2111*0a6a1f1dSLionel Sambuc template<typename T> static T assert_cast(...) {
2112*0a6a1f1dSLionel Sambuc llvm_unreachable("bad assert_cast");
2113*0a6a1f1dSLionel Sambuc }
2114*0a6a1f1dSLionel Sambuc
2115*0a6a1f1dSLionel Sambuc /// \brief Merge together the pattern declarations from two template
2116*0a6a1f1dSLionel Sambuc /// declarations.
mergeTemplatePattern(RedeclarableTemplateDecl * D,RedeclarableTemplateDecl * Existing,DeclID DsID)2117*0a6a1f1dSLionel Sambuc void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
2118*0a6a1f1dSLionel Sambuc RedeclarableTemplateDecl *Existing,
2119*0a6a1f1dSLionel Sambuc DeclID DsID) {
2120*0a6a1f1dSLionel Sambuc auto *DPattern = D->getTemplatedDecl();
2121*0a6a1f1dSLionel Sambuc auto *ExistingPattern = Existing->getTemplatedDecl();
2122*0a6a1f1dSLionel Sambuc RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(),
2123*0a6a1f1dSLionel Sambuc DPattern->getKind());
2124*0a6a1f1dSLionel Sambuc if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
2125*0a6a1f1dSLionel Sambuc // Merge with any existing definition.
2126*0a6a1f1dSLionel Sambuc // FIXME: This is duplicated in several places. Refactor.
2127*0a6a1f1dSLionel Sambuc auto *ExistingClass =
2128*0a6a1f1dSLionel Sambuc cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();
2129*0a6a1f1dSLionel Sambuc if (auto *DDD = DClass->DefinitionData.getNotUpdated()) {
2130*0a6a1f1dSLionel Sambuc if (auto *ExistingDD = ExistingClass->DefinitionData.getNotUpdated()) {
2131*0a6a1f1dSLionel Sambuc MergeDefinitionData(ExistingClass, *DDD);
2132*0a6a1f1dSLionel Sambuc Reader.PendingDefinitions.erase(DClass);
2133*0a6a1f1dSLionel Sambuc Reader.MergedDeclContexts.insert(
2134*0a6a1f1dSLionel Sambuc std::make_pair(DClass, ExistingDD->Definition));
2135*0a6a1f1dSLionel Sambuc DClass->IsCompleteDefinition = false;
2136*0a6a1f1dSLionel Sambuc } else {
2137*0a6a1f1dSLionel Sambuc ExistingClass->DefinitionData = DClass->DefinitionData;
2138*0a6a1f1dSLionel Sambuc }
2139*0a6a1f1dSLionel Sambuc }
2140*0a6a1f1dSLionel Sambuc DClass->DefinitionData = ExistingClass->DefinitionData;
2141*0a6a1f1dSLionel Sambuc
2142*0a6a1f1dSLionel Sambuc return mergeRedeclarable(DClass, cast<TagDecl>(ExistingPattern),
2143*0a6a1f1dSLionel Sambuc Result);
2144*0a6a1f1dSLionel Sambuc }
2145*0a6a1f1dSLionel Sambuc if (auto *DFunction = dyn_cast<FunctionDecl>(DPattern))
2146*0a6a1f1dSLionel Sambuc return mergeRedeclarable(DFunction, cast<FunctionDecl>(ExistingPattern),
2147*0a6a1f1dSLionel Sambuc Result);
2148*0a6a1f1dSLionel Sambuc if (auto *DVar = dyn_cast<VarDecl>(DPattern))
2149*0a6a1f1dSLionel Sambuc return mergeRedeclarable(DVar, cast<VarDecl>(ExistingPattern), Result);
2150*0a6a1f1dSLionel Sambuc if (auto *DAlias = dyn_cast<TypeAliasDecl>(DPattern))
2151*0a6a1f1dSLionel Sambuc return mergeRedeclarable(DAlias, cast<TypedefNameDecl>(ExistingPattern),
2152*0a6a1f1dSLionel Sambuc Result);
2153*0a6a1f1dSLionel Sambuc llvm_unreachable("merged an unknown kind of redeclarable template");
2154f4a2713aSLionel Sambuc }
2155f4a2713aSLionel Sambuc
2156f4a2713aSLionel Sambuc /// \brief Attempts to merge the given declaration (D) with another declaration
2157f4a2713aSLionel Sambuc /// of the same entity.
2158f4a2713aSLionel Sambuc template<typename T>
mergeRedeclarable(Redeclarable<T> * DBase,T * Existing,RedeclarableResult & Redecl,DeclID TemplatePatternID)2159*0a6a1f1dSLionel Sambuc void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
2160*0a6a1f1dSLionel Sambuc RedeclarableResult &Redecl,
2161*0a6a1f1dSLionel Sambuc DeclID TemplatePatternID) {
2162*0a6a1f1dSLionel Sambuc T *D = static_cast<T*>(DBase);
2163f4a2713aSLionel Sambuc T *ExistingCanon = Existing->getCanonicalDecl();
2164*0a6a1f1dSLionel Sambuc T *DCanon = D->getCanonicalDecl();
2165f4a2713aSLionel Sambuc if (ExistingCanon != DCanon) {
2166*0a6a1f1dSLionel Sambuc assert(DCanon->getGlobalID() == Redecl.getFirstID());
2167*0a6a1f1dSLionel Sambuc
2168f4a2713aSLionel Sambuc // Have our redeclaration link point back at the canonical declaration
2169f4a2713aSLionel Sambuc // of the existing declaration, so that this declaration has the
2170f4a2713aSLionel Sambuc // appropriate canonical declaration.
2171f4a2713aSLionel Sambuc D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon);
2172f4a2713aSLionel Sambuc
2173f4a2713aSLionel Sambuc // When we merge a namespace, update its pointer to the first namespace.
2174*0a6a1f1dSLionel Sambuc if (auto *Namespace = dyn_cast<NamespaceDecl>(D))
2175f4a2713aSLionel Sambuc Namespace->AnonOrFirstNamespaceAndInline.setPointer(
2176*0a6a1f1dSLionel Sambuc assert_cast<NamespaceDecl*>(ExistingCanon));
2177f4a2713aSLionel Sambuc
2178*0a6a1f1dSLionel Sambuc // When we merge a template, merge its pattern.
2179*0a6a1f1dSLionel Sambuc if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
2180*0a6a1f1dSLionel Sambuc mergeTemplatePattern(
2181*0a6a1f1dSLionel Sambuc DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
2182*0a6a1f1dSLionel Sambuc TemplatePatternID);
2183f4a2713aSLionel Sambuc
2184f4a2713aSLionel Sambuc // If this declaration was the canonical declaration, make a note of
2185f4a2713aSLionel Sambuc // that. We accept the linear algorithm here because the number of
2186f4a2713aSLionel Sambuc // unique canonical declarations of an entity should always be tiny.
2187*0a6a1f1dSLionel Sambuc if (DCanon == D) {
2188f4a2713aSLionel Sambuc SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
2189f4a2713aSLionel Sambuc if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
2190f4a2713aSLionel Sambuc == Merged.end())
2191f4a2713aSLionel Sambuc Merged.push_back(Redecl.getFirstID());
2192f4a2713aSLionel Sambuc }
2193f4a2713aSLionel Sambuc }
2194f4a2713aSLionel Sambuc }
2195f4a2713aSLionel Sambuc
2196f4a2713aSLionel Sambuc /// \brief Attempts to merge the given declaration (D) with another declaration
2197f4a2713aSLionel Sambuc /// of the same entity, for the case where the entity is not actually
2198f4a2713aSLionel Sambuc /// redeclarable. This happens, for instance, when merging the fields of
2199f4a2713aSLionel Sambuc /// identical class definitions from two different modules.
2200f4a2713aSLionel Sambuc template<typename T>
mergeMergeable(Mergeable<T> * D)2201f4a2713aSLionel Sambuc void ASTDeclReader::mergeMergeable(Mergeable<T> *D) {
2202f4a2713aSLionel Sambuc // If modules are not available, there is no reason to perform this merge.
2203f4a2713aSLionel Sambuc if (!Reader.getContext().getLangOpts().Modules)
2204f4a2713aSLionel Sambuc return;
2205f4a2713aSLionel Sambuc
2206f4a2713aSLionel Sambuc // ODR-based merging is only performed in C++. In C, identically-named things
2207f4a2713aSLionel Sambuc // in different translation units are not redeclarations (but may still have
2208f4a2713aSLionel Sambuc // compatible types).
2209f4a2713aSLionel Sambuc if (!Reader.getContext().getLangOpts().CPlusPlus)
2210f4a2713aSLionel Sambuc return;
2211f4a2713aSLionel Sambuc
2212f4a2713aSLionel Sambuc if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D)))
2213f4a2713aSLionel Sambuc if (T *Existing = ExistingRes)
2214f4a2713aSLionel Sambuc Reader.Context.setPrimaryMergedDecl(static_cast<T*>(D),
2215f4a2713aSLionel Sambuc Existing->getCanonicalDecl());
2216f4a2713aSLionel Sambuc }
2217f4a2713aSLionel Sambuc
VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl * D)2218f4a2713aSLionel Sambuc void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
2219f4a2713aSLionel Sambuc VisitDecl(D);
2220f4a2713aSLionel Sambuc unsigned NumVars = D->varlist_size();
2221f4a2713aSLionel Sambuc SmallVector<Expr *, 16> Vars;
2222f4a2713aSLionel Sambuc Vars.reserve(NumVars);
2223f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumVars; ++i) {
2224f4a2713aSLionel Sambuc Vars.push_back(Reader.ReadExpr(F));
2225f4a2713aSLionel Sambuc }
2226f4a2713aSLionel Sambuc D->setVars(Vars);
2227f4a2713aSLionel Sambuc }
2228f4a2713aSLionel Sambuc
2229f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2230f4a2713aSLionel Sambuc // Attribute Reading
2231f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2232f4a2713aSLionel Sambuc
2233f4a2713aSLionel Sambuc /// \brief Reads attributes from the current stream position.
ReadAttributes(ModuleFile & F,AttrVec & Attrs,const RecordData & Record,unsigned & Idx)2234f4a2713aSLionel Sambuc void ASTReader::ReadAttributes(ModuleFile &F, AttrVec &Attrs,
2235f4a2713aSLionel Sambuc const RecordData &Record, unsigned &Idx) {
2236f4a2713aSLionel Sambuc for (unsigned i = 0, e = Record[Idx++]; i != e; ++i) {
2237*0a6a1f1dSLionel Sambuc Attr *New = nullptr;
2238f4a2713aSLionel Sambuc attr::Kind Kind = (attr::Kind)Record[Idx++];
2239f4a2713aSLionel Sambuc SourceRange Range = ReadSourceRange(F, Record, Idx);
2240f4a2713aSLionel Sambuc
2241f4a2713aSLionel Sambuc #include "clang/Serialization/AttrPCHRead.inc"
2242f4a2713aSLionel Sambuc
2243f4a2713aSLionel Sambuc assert(New && "Unable to decode attribute?");
2244f4a2713aSLionel Sambuc Attrs.push_back(New);
2245f4a2713aSLionel Sambuc }
2246f4a2713aSLionel Sambuc }
2247f4a2713aSLionel Sambuc
2248f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2249f4a2713aSLionel Sambuc // ASTReader Implementation
2250f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2251f4a2713aSLionel Sambuc
2252f4a2713aSLionel Sambuc /// \brief Note that we have loaded the declaration with the given
2253f4a2713aSLionel Sambuc /// Index.
2254f4a2713aSLionel Sambuc ///
2255f4a2713aSLionel Sambuc /// This routine notes that this declaration has already been loaded,
2256f4a2713aSLionel Sambuc /// so that future GetDecl calls will return this declaration rather
2257f4a2713aSLionel Sambuc /// than trying to load a new declaration.
LoadedDecl(unsigned Index,Decl * D)2258f4a2713aSLionel Sambuc inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) {
2259f4a2713aSLionel Sambuc assert(!DeclsLoaded[Index] && "Decl loaded twice?");
2260f4a2713aSLionel Sambuc DeclsLoaded[Index] = D;
2261f4a2713aSLionel Sambuc }
2262f4a2713aSLionel Sambuc
2263f4a2713aSLionel Sambuc
2264f4a2713aSLionel Sambuc /// \brief Determine whether the consumer will be interested in seeing
2265f4a2713aSLionel Sambuc /// this declaration (via HandleTopLevelDecl).
2266f4a2713aSLionel Sambuc ///
2267f4a2713aSLionel Sambuc /// This routine should return true for anything that might affect
2268f4a2713aSLionel Sambuc /// code generation, e.g., inline function definitions, Objective-C
2269f4a2713aSLionel Sambuc /// declarations with metadata, etc.
isConsumerInterestedIn(Decl * D,bool HasBody)2270f4a2713aSLionel Sambuc static bool isConsumerInterestedIn(Decl *D, bool HasBody) {
2271f4a2713aSLionel Sambuc // An ObjCMethodDecl is never considered as "interesting" because its
2272f4a2713aSLionel Sambuc // implementation container always is.
2273f4a2713aSLionel Sambuc
2274f4a2713aSLionel Sambuc if (isa<FileScopeAsmDecl>(D) ||
2275f4a2713aSLionel Sambuc isa<ObjCProtocolDecl>(D) ||
2276*0a6a1f1dSLionel Sambuc isa<ObjCImplDecl>(D) ||
2277*0a6a1f1dSLionel Sambuc isa<ImportDecl>(D) ||
2278*0a6a1f1dSLionel Sambuc isa<OMPThreadPrivateDecl>(D))
2279f4a2713aSLionel Sambuc return true;
2280f4a2713aSLionel Sambuc if (VarDecl *Var = dyn_cast<VarDecl>(D))
2281f4a2713aSLionel Sambuc return Var->isFileVarDecl() &&
2282f4a2713aSLionel Sambuc Var->isThisDeclarationADefinition() == VarDecl::Definition;
2283f4a2713aSLionel Sambuc if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D))
2284f4a2713aSLionel Sambuc return Func->doesThisDeclarationHaveABody() || HasBody;
2285f4a2713aSLionel Sambuc
2286f4a2713aSLionel Sambuc return false;
2287f4a2713aSLionel Sambuc }
2288f4a2713aSLionel Sambuc
2289f4a2713aSLionel Sambuc /// \brief Get the correct cursor and offset for loading a declaration.
2290f4a2713aSLionel Sambuc ASTReader::RecordLocation
DeclCursorForID(DeclID ID,unsigned & RawLocation)2291f4a2713aSLionel Sambuc ASTReader::DeclCursorForID(DeclID ID, unsigned &RawLocation) {
2292f4a2713aSLionel Sambuc // See if there's an override.
2293f4a2713aSLionel Sambuc DeclReplacementMap::iterator It = ReplacedDecls.find(ID);
2294f4a2713aSLionel Sambuc if (It != ReplacedDecls.end()) {
2295f4a2713aSLionel Sambuc RawLocation = It->second.RawLoc;
2296f4a2713aSLionel Sambuc return RecordLocation(It->second.Mod, It->second.Offset);
2297f4a2713aSLionel Sambuc }
2298f4a2713aSLionel Sambuc
2299f4a2713aSLionel Sambuc GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID);
2300f4a2713aSLionel Sambuc assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
2301f4a2713aSLionel Sambuc ModuleFile *M = I->second;
2302f4a2713aSLionel Sambuc const DeclOffset &
2303f4a2713aSLionel Sambuc DOffs = M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS];
2304f4a2713aSLionel Sambuc RawLocation = DOffs.Loc;
2305f4a2713aSLionel Sambuc return RecordLocation(M, DOffs.BitOffset);
2306f4a2713aSLionel Sambuc }
2307f4a2713aSLionel Sambuc
getLocalBitOffset(uint64_t GlobalOffset)2308f4a2713aSLionel Sambuc ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) {
2309f4a2713aSLionel Sambuc ContinuousRangeMap<uint64_t, ModuleFile*, 4>::iterator I
2310f4a2713aSLionel Sambuc = GlobalBitOffsetsMap.find(GlobalOffset);
2311f4a2713aSLionel Sambuc
2312f4a2713aSLionel Sambuc assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map");
2313f4a2713aSLionel Sambuc return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset);
2314f4a2713aSLionel Sambuc }
2315f4a2713aSLionel Sambuc
getGlobalBitOffset(ModuleFile & M,uint32_t LocalOffset)2316f4a2713aSLionel Sambuc uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) {
2317f4a2713aSLionel Sambuc return LocalOffset + M.GlobalBitOffset;
2318f4a2713aSLionel Sambuc }
2319f4a2713aSLionel Sambuc
2320f4a2713aSLionel Sambuc static bool isSameTemplateParameterList(const TemplateParameterList *X,
2321f4a2713aSLionel Sambuc const TemplateParameterList *Y);
2322f4a2713aSLionel Sambuc
2323f4a2713aSLionel Sambuc /// \brief Determine whether two template parameters are similar enough
2324f4a2713aSLionel Sambuc /// that they may be used in declarations of the same template.
isSameTemplateParameter(const NamedDecl * X,const NamedDecl * Y)2325f4a2713aSLionel Sambuc static bool isSameTemplateParameter(const NamedDecl *X,
2326f4a2713aSLionel Sambuc const NamedDecl *Y) {
2327f4a2713aSLionel Sambuc if (X->getKind() != Y->getKind())
2328f4a2713aSLionel Sambuc return false;
2329f4a2713aSLionel Sambuc
2330f4a2713aSLionel Sambuc if (const TemplateTypeParmDecl *TX = dyn_cast<TemplateTypeParmDecl>(X)) {
2331f4a2713aSLionel Sambuc const TemplateTypeParmDecl *TY = cast<TemplateTypeParmDecl>(Y);
2332f4a2713aSLionel Sambuc return TX->isParameterPack() == TY->isParameterPack();
2333f4a2713aSLionel Sambuc }
2334f4a2713aSLionel Sambuc
2335f4a2713aSLionel Sambuc if (const NonTypeTemplateParmDecl *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) {
2336f4a2713aSLionel Sambuc const NonTypeTemplateParmDecl *TY = cast<NonTypeTemplateParmDecl>(Y);
2337f4a2713aSLionel Sambuc return TX->isParameterPack() == TY->isParameterPack() &&
2338f4a2713aSLionel Sambuc TX->getASTContext().hasSameType(TX->getType(), TY->getType());
2339f4a2713aSLionel Sambuc }
2340f4a2713aSLionel Sambuc
2341f4a2713aSLionel Sambuc const TemplateTemplateParmDecl *TX = cast<TemplateTemplateParmDecl>(X);
2342f4a2713aSLionel Sambuc const TemplateTemplateParmDecl *TY = cast<TemplateTemplateParmDecl>(Y);
2343f4a2713aSLionel Sambuc return TX->isParameterPack() == TY->isParameterPack() &&
2344f4a2713aSLionel Sambuc isSameTemplateParameterList(TX->getTemplateParameters(),
2345f4a2713aSLionel Sambuc TY->getTemplateParameters());
2346f4a2713aSLionel Sambuc }
2347f4a2713aSLionel Sambuc
getNamespace(const NestedNameSpecifier * X)2348*0a6a1f1dSLionel Sambuc static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) {
2349*0a6a1f1dSLionel Sambuc if (auto *NS = X->getAsNamespace())
2350*0a6a1f1dSLionel Sambuc return NS;
2351*0a6a1f1dSLionel Sambuc if (auto *NAS = X->getAsNamespaceAlias())
2352*0a6a1f1dSLionel Sambuc return NAS->getNamespace();
2353*0a6a1f1dSLionel Sambuc return nullptr;
2354*0a6a1f1dSLionel Sambuc }
2355*0a6a1f1dSLionel Sambuc
isSameQualifier(const NestedNameSpecifier * X,const NestedNameSpecifier * Y)2356*0a6a1f1dSLionel Sambuc static bool isSameQualifier(const NestedNameSpecifier *X,
2357*0a6a1f1dSLionel Sambuc const NestedNameSpecifier *Y) {
2358*0a6a1f1dSLionel Sambuc if (auto *NSX = getNamespace(X)) {
2359*0a6a1f1dSLionel Sambuc auto *NSY = getNamespace(Y);
2360*0a6a1f1dSLionel Sambuc if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl())
2361*0a6a1f1dSLionel Sambuc return false;
2362*0a6a1f1dSLionel Sambuc } else if (X->getKind() != Y->getKind())
2363*0a6a1f1dSLionel Sambuc return false;
2364*0a6a1f1dSLionel Sambuc
2365*0a6a1f1dSLionel Sambuc // FIXME: For namespaces and types, we're permitted to check that the entity
2366*0a6a1f1dSLionel Sambuc // is named via the same tokens. We should probably do so.
2367*0a6a1f1dSLionel Sambuc switch (X->getKind()) {
2368*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Identifier:
2369*0a6a1f1dSLionel Sambuc if (X->getAsIdentifier() != Y->getAsIdentifier())
2370*0a6a1f1dSLionel Sambuc return false;
2371*0a6a1f1dSLionel Sambuc break;
2372*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Namespace:
2373*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::NamespaceAlias:
2374*0a6a1f1dSLionel Sambuc // We've already checked that we named the same namespace.
2375*0a6a1f1dSLionel Sambuc break;
2376*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::TypeSpec:
2377*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::TypeSpecWithTemplate:
2378*0a6a1f1dSLionel Sambuc if (X->getAsType()->getCanonicalTypeInternal() !=
2379*0a6a1f1dSLionel Sambuc Y->getAsType()->getCanonicalTypeInternal())
2380*0a6a1f1dSLionel Sambuc return false;
2381*0a6a1f1dSLionel Sambuc break;
2382*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Global:
2383*0a6a1f1dSLionel Sambuc case NestedNameSpecifier::Super:
2384*0a6a1f1dSLionel Sambuc return true;
2385*0a6a1f1dSLionel Sambuc }
2386*0a6a1f1dSLionel Sambuc
2387*0a6a1f1dSLionel Sambuc // Recurse into earlier portion of NNS, if any.
2388*0a6a1f1dSLionel Sambuc auto *PX = X->getPrefix();
2389*0a6a1f1dSLionel Sambuc auto *PY = Y->getPrefix();
2390*0a6a1f1dSLionel Sambuc if (PX && PY)
2391*0a6a1f1dSLionel Sambuc return isSameQualifier(PX, PY);
2392*0a6a1f1dSLionel Sambuc return !PX && !PY;
2393*0a6a1f1dSLionel Sambuc }
2394*0a6a1f1dSLionel Sambuc
2395f4a2713aSLionel Sambuc /// \brief Determine whether two template parameter lists are similar enough
2396f4a2713aSLionel Sambuc /// that they may be used in declarations of the same template.
isSameTemplateParameterList(const TemplateParameterList * X,const TemplateParameterList * Y)2397f4a2713aSLionel Sambuc static bool isSameTemplateParameterList(const TemplateParameterList *X,
2398f4a2713aSLionel Sambuc const TemplateParameterList *Y) {
2399f4a2713aSLionel Sambuc if (X->size() != Y->size())
2400f4a2713aSLionel Sambuc return false;
2401f4a2713aSLionel Sambuc
2402f4a2713aSLionel Sambuc for (unsigned I = 0, N = X->size(); I != N; ++I)
2403f4a2713aSLionel Sambuc if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I)))
2404f4a2713aSLionel Sambuc return false;
2405f4a2713aSLionel Sambuc
2406f4a2713aSLionel Sambuc return true;
2407f4a2713aSLionel Sambuc }
2408f4a2713aSLionel Sambuc
2409f4a2713aSLionel Sambuc /// \brief Determine whether the two declarations refer to the same entity.
isSameEntity(NamedDecl * X,NamedDecl * Y)2410f4a2713aSLionel Sambuc static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
2411f4a2713aSLionel Sambuc assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!");
2412f4a2713aSLionel Sambuc
2413f4a2713aSLionel Sambuc if (X == Y)
2414f4a2713aSLionel Sambuc return true;
2415f4a2713aSLionel Sambuc
2416f4a2713aSLionel Sambuc // Must be in the same context.
2417f4a2713aSLionel Sambuc if (!X->getDeclContext()->getRedeclContext()->Equals(
2418f4a2713aSLionel Sambuc Y->getDeclContext()->getRedeclContext()))
2419f4a2713aSLionel Sambuc return false;
2420f4a2713aSLionel Sambuc
2421f4a2713aSLionel Sambuc // Two typedefs refer to the same entity if they have the same underlying
2422f4a2713aSLionel Sambuc // type.
2423f4a2713aSLionel Sambuc if (TypedefNameDecl *TypedefX = dyn_cast<TypedefNameDecl>(X))
2424f4a2713aSLionel Sambuc if (TypedefNameDecl *TypedefY = dyn_cast<TypedefNameDecl>(Y))
2425f4a2713aSLionel Sambuc return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(),
2426f4a2713aSLionel Sambuc TypedefY->getUnderlyingType());
2427f4a2713aSLionel Sambuc
2428f4a2713aSLionel Sambuc // Must have the same kind.
2429f4a2713aSLionel Sambuc if (X->getKind() != Y->getKind())
2430f4a2713aSLionel Sambuc return false;
2431f4a2713aSLionel Sambuc
2432f4a2713aSLionel Sambuc // Objective-C classes and protocols with the same name always match.
2433f4a2713aSLionel Sambuc if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))
2434f4a2713aSLionel Sambuc return true;
2435f4a2713aSLionel Sambuc
2436f4a2713aSLionel Sambuc if (isa<ClassTemplateSpecializationDecl>(X)) {
2437f4a2713aSLionel Sambuc // No need to handle these here: we merge them when adding them to the
2438f4a2713aSLionel Sambuc // template.
2439f4a2713aSLionel Sambuc return false;
2440f4a2713aSLionel Sambuc }
2441f4a2713aSLionel Sambuc
2442f4a2713aSLionel Sambuc // Compatible tags match.
2443f4a2713aSLionel Sambuc if (TagDecl *TagX = dyn_cast<TagDecl>(X)) {
2444f4a2713aSLionel Sambuc TagDecl *TagY = cast<TagDecl>(Y);
2445f4a2713aSLionel Sambuc return (TagX->getTagKind() == TagY->getTagKind()) ||
2446f4a2713aSLionel Sambuc ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class ||
2447f4a2713aSLionel Sambuc TagX->getTagKind() == TTK_Interface) &&
2448f4a2713aSLionel Sambuc (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class ||
2449f4a2713aSLionel Sambuc TagY->getTagKind() == TTK_Interface));
2450f4a2713aSLionel Sambuc }
2451f4a2713aSLionel Sambuc
2452f4a2713aSLionel Sambuc // Functions with the same type and linkage match.
2453*0a6a1f1dSLionel Sambuc // FIXME: This needs to cope with merging of prototyped/non-prototyped
2454*0a6a1f1dSLionel Sambuc // functions, etc.
2455f4a2713aSLionel Sambuc if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) {
2456f4a2713aSLionel Sambuc FunctionDecl *FuncY = cast<FunctionDecl>(Y);
2457f4a2713aSLionel Sambuc return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) &&
2458f4a2713aSLionel Sambuc FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
2459f4a2713aSLionel Sambuc }
2460f4a2713aSLionel Sambuc
2461f4a2713aSLionel Sambuc // Variables with the same type and linkage match.
2462f4a2713aSLionel Sambuc if (VarDecl *VarX = dyn_cast<VarDecl>(X)) {
2463f4a2713aSLionel Sambuc VarDecl *VarY = cast<VarDecl>(Y);
2464f4a2713aSLionel Sambuc return (VarX->getLinkageInternal() == VarY->getLinkageInternal()) &&
2465f4a2713aSLionel Sambuc VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType());
2466f4a2713aSLionel Sambuc }
2467f4a2713aSLionel Sambuc
2468f4a2713aSLionel Sambuc // Namespaces with the same name and inlinedness match.
2469f4a2713aSLionel Sambuc if (NamespaceDecl *NamespaceX = dyn_cast<NamespaceDecl>(X)) {
2470f4a2713aSLionel Sambuc NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y);
2471f4a2713aSLionel Sambuc return NamespaceX->isInline() == NamespaceY->isInline();
2472f4a2713aSLionel Sambuc }
2473f4a2713aSLionel Sambuc
2474f4a2713aSLionel Sambuc // Identical template names and kinds match if their template parameter lists
2475f4a2713aSLionel Sambuc // and patterns match.
2476f4a2713aSLionel Sambuc if (TemplateDecl *TemplateX = dyn_cast<TemplateDecl>(X)) {
2477f4a2713aSLionel Sambuc TemplateDecl *TemplateY = cast<TemplateDecl>(Y);
2478f4a2713aSLionel Sambuc return isSameEntity(TemplateX->getTemplatedDecl(),
2479f4a2713aSLionel Sambuc TemplateY->getTemplatedDecl()) &&
2480f4a2713aSLionel Sambuc isSameTemplateParameterList(TemplateX->getTemplateParameters(),
2481f4a2713aSLionel Sambuc TemplateY->getTemplateParameters());
2482f4a2713aSLionel Sambuc }
2483f4a2713aSLionel Sambuc
2484f4a2713aSLionel Sambuc // Fields with the same name and the same type match.
2485f4a2713aSLionel Sambuc if (FieldDecl *FDX = dyn_cast<FieldDecl>(X)) {
2486f4a2713aSLionel Sambuc FieldDecl *FDY = cast<FieldDecl>(Y);
2487f4a2713aSLionel Sambuc // FIXME: Also check the bitwidth is odr-equivalent, if any.
2488f4a2713aSLionel Sambuc return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());
2489f4a2713aSLionel Sambuc }
2490f4a2713aSLionel Sambuc
2491f4a2713aSLionel Sambuc // Enumerators with the same name match.
2492f4a2713aSLionel Sambuc if (isa<EnumConstantDecl>(X))
2493f4a2713aSLionel Sambuc // FIXME: Also check the value is odr-equivalent.
2494f4a2713aSLionel Sambuc return true;
2495f4a2713aSLionel Sambuc
2496f4a2713aSLionel Sambuc // Using shadow declarations with the same target match.
2497f4a2713aSLionel Sambuc if (UsingShadowDecl *USX = dyn_cast<UsingShadowDecl>(X)) {
2498f4a2713aSLionel Sambuc UsingShadowDecl *USY = cast<UsingShadowDecl>(Y);
2499f4a2713aSLionel Sambuc return USX->getTargetDecl() == USY->getTargetDecl();
2500f4a2713aSLionel Sambuc }
2501f4a2713aSLionel Sambuc
2502*0a6a1f1dSLionel Sambuc // Using declarations with the same qualifier match. (We already know that
2503*0a6a1f1dSLionel Sambuc // the name matches.)
2504*0a6a1f1dSLionel Sambuc if (auto *UX = dyn_cast<UsingDecl>(X)) {
2505*0a6a1f1dSLionel Sambuc auto *UY = cast<UsingDecl>(Y);
2506*0a6a1f1dSLionel Sambuc return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
2507*0a6a1f1dSLionel Sambuc UX->hasTypename() == UY->hasTypename() &&
2508*0a6a1f1dSLionel Sambuc UX->isAccessDeclaration() == UY->isAccessDeclaration();
2509*0a6a1f1dSLionel Sambuc }
2510*0a6a1f1dSLionel Sambuc if (auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) {
2511*0a6a1f1dSLionel Sambuc auto *UY = cast<UnresolvedUsingValueDecl>(Y);
2512*0a6a1f1dSLionel Sambuc return isSameQualifier(UX->getQualifier(), UY->getQualifier()) &&
2513*0a6a1f1dSLionel Sambuc UX->isAccessDeclaration() == UY->isAccessDeclaration();
2514*0a6a1f1dSLionel Sambuc }
2515*0a6a1f1dSLionel Sambuc if (auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X))
2516*0a6a1f1dSLionel Sambuc return isSameQualifier(
2517*0a6a1f1dSLionel Sambuc UX->getQualifier(),
2518*0a6a1f1dSLionel Sambuc cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier());
2519*0a6a1f1dSLionel Sambuc
2520*0a6a1f1dSLionel Sambuc // Namespace alias definitions with the same target match.
2521*0a6a1f1dSLionel Sambuc if (auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) {
2522*0a6a1f1dSLionel Sambuc auto *NAY = cast<NamespaceAliasDecl>(Y);
2523*0a6a1f1dSLionel Sambuc return NAX->getNamespace()->Equals(NAY->getNamespace());
2524*0a6a1f1dSLionel Sambuc }
2525*0a6a1f1dSLionel Sambuc
2526f4a2713aSLionel Sambuc // FIXME: Many other cases to implement.
2527f4a2713aSLionel Sambuc return false;
2528f4a2713aSLionel Sambuc }
2529f4a2713aSLionel Sambuc
2530f4a2713aSLionel Sambuc /// Find the context in which we should search for previous declarations when
2531f4a2713aSLionel Sambuc /// looking for declarations to merge.
getPrimaryContextForMerging(DeclContext * DC)2532f4a2713aSLionel Sambuc static DeclContext *getPrimaryContextForMerging(DeclContext *DC) {
2533f4a2713aSLionel Sambuc if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
2534f4a2713aSLionel Sambuc return ND->getOriginalNamespace();
2535f4a2713aSLionel Sambuc
2536*0a6a1f1dSLionel Sambuc // There is one tricky case here: if DC is a class with no definition, then
2537*0a6a1f1dSLionel Sambuc // we're merging a declaration whose definition is added by an update record,
2538*0a6a1f1dSLionel Sambuc // but we've not yet loaded that update record. In this case, we use the
2539*0a6a1f1dSLionel Sambuc // canonical declaration for merging until we get a real definition.
2540*0a6a1f1dSLionel Sambuc // FIXME: When we add a definition, we may need to move the partial lookup
2541*0a6a1f1dSLionel Sambuc // information from the canonical declaration onto the chosen definition.
2542f4a2713aSLionel Sambuc if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
2543*0a6a1f1dSLionel Sambuc return RD->getPrimaryContext();
2544f4a2713aSLionel Sambuc
2545f4a2713aSLionel Sambuc if (EnumDecl *ED = dyn_cast<EnumDecl>(DC))
2546*0a6a1f1dSLionel Sambuc return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
2547*0a6a1f1dSLionel Sambuc : nullptr;
2548f4a2713aSLionel Sambuc
2549*0a6a1f1dSLionel Sambuc return nullptr;
2550f4a2713aSLionel Sambuc }
2551f4a2713aSLionel Sambuc
~FindExistingResult()2552f4a2713aSLionel Sambuc ASTDeclReader::FindExistingResult::~FindExistingResult() {
2553f4a2713aSLionel Sambuc if (!AddResult || Existing)
2554f4a2713aSLionel Sambuc return;
2555f4a2713aSLionel Sambuc
2556*0a6a1f1dSLionel Sambuc DeclarationName Name = New->getDeclName();
2557f4a2713aSLionel Sambuc DeclContext *DC = New->getDeclContext()->getRedeclContext();
2558*0a6a1f1dSLionel Sambuc if (TypedefNameForLinkage) {
2559*0a6a1f1dSLionel Sambuc Reader.ImportedTypedefNamesForLinkage.insert(
2560*0a6a1f1dSLionel Sambuc std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New));
2561*0a6a1f1dSLionel Sambuc } else if (!Name) {
2562*0a6a1f1dSLionel Sambuc assert(needsAnonymousDeclarationNumber(New));
2563*0a6a1f1dSLionel Sambuc setAnonymousDeclForMerging(Reader, New->getLexicalDeclContext(),
2564*0a6a1f1dSLionel Sambuc AnonymousDeclNumber, New);
2565*0a6a1f1dSLionel Sambuc } else if (DC->isTranslationUnit() && Reader.SemaObj) {
2566*0a6a1f1dSLionel Sambuc Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, Name);
2567f4a2713aSLionel Sambuc } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) {
2568f4a2713aSLionel Sambuc // Add the declaration to its redeclaration context so later merging
2569f4a2713aSLionel Sambuc // lookups will find it.
2570f4a2713aSLionel Sambuc MergeDC->makeDeclVisibleInContextImpl(New, /*Internal*/true);
2571f4a2713aSLionel Sambuc }
2572f4a2713aSLionel Sambuc }
2573f4a2713aSLionel Sambuc
2574*0a6a1f1dSLionel Sambuc /// Find the declaration that should be merged into, given the declaration found
2575*0a6a1f1dSLionel Sambuc /// by name lookup. If we're merging an anonymous declaration within a typedef,
2576*0a6a1f1dSLionel Sambuc /// we need a matching typedef, and we merge with the type inside it.
getDeclForMerging(NamedDecl * Found,bool IsTypedefNameForLinkage)2577*0a6a1f1dSLionel Sambuc static NamedDecl *getDeclForMerging(NamedDecl *Found,
2578*0a6a1f1dSLionel Sambuc bool IsTypedefNameForLinkage) {
2579*0a6a1f1dSLionel Sambuc if (!IsTypedefNameForLinkage)
2580*0a6a1f1dSLionel Sambuc return Found;
2581*0a6a1f1dSLionel Sambuc
2582*0a6a1f1dSLionel Sambuc // If we found a typedef declaration that gives a name to some other
2583*0a6a1f1dSLionel Sambuc // declaration, then we want that inner declaration. Declarations from
2584*0a6a1f1dSLionel Sambuc // AST files are handled via ImportedTypedefNamesForLinkage.
2585*0a6a1f1dSLionel Sambuc if (Found->isFromASTFile()) return 0;
2586*0a6a1f1dSLionel Sambuc if (auto *TND = dyn_cast<TypedefNameDecl>(Found)) {
2587*0a6a1f1dSLionel Sambuc if (auto *TT = TND->getTypeSourceInfo()->getType()->getAs<TagType>())
2588*0a6a1f1dSLionel Sambuc if (TT->getDecl()->getTypedefNameForAnonDecl() == TND)
2589*0a6a1f1dSLionel Sambuc return TT->getDecl();
2590*0a6a1f1dSLionel Sambuc }
2591*0a6a1f1dSLionel Sambuc
2592*0a6a1f1dSLionel Sambuc return 0;
2593*0a6a1f1dSLionel Sambuc }
2594*0a6a1f1dSLionel Sambuc
getAnonymousDeclForMerging(ASTReader & Reader,DeclContext * DC,unsigned Index)2595*0a6a1f1dSLionel Sambuc NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,
2596*0a6a1f1dSLionel Sambuc DeclContext *DC,
2597*0a6a1f1dSLionel Sambuc unsigned Index) {
2598*0a6a1f1dSLionel Sambuc // If the lexical context has been merged, look into the now-canonical
2599*0a6a1f1dSLionel Sambuc // definition.
2600*0a6a1f1dSLionel Sambuc if (auto *Merged = Reader.MergedDeclContexts.lookup(DC))
2601*0a6a1f1dSLionel Sambuc DC = Merged;
2602*0a6a1f1dSLionel Sambuc
2603*0a6a1f1dSLionel Sambuc // If we've seen this before, return the canonical declaration.
2604*0a6a1f1dSLionel Sambuc auto &Previous = Reader.AnonymousDeclarationsForMerging[DC];
2605*0a6a1f1dSLionel Sambuc if (Index < Previous.size() && Previous[Index])
2606*0a6a1f1dSLionel Sambuc return Previous[Index];
2607*0a6a1f1dSLionel Sambuc
2608*0a6a1f1dSLionel Sambuc // If this is the first time, but we have parsed a declaration of the context,
2609*0a6a1f1dSLionel Sambuc // build the anonymous declaration list from the parsed declaration.
2610*0a6a1f1dSLionel Sambuc if (!cast<Decl>(DC)->isFromASTFile()) {
2611*0a6a1f1dSLionel Sambuc unsigned Index = 0;
2612*0a6a1f1dSLionel Sambuc for (Decl *LexicalD : DC->decls()) {
2613*0a6a1f1dSLionel Sambuc auto *ND = dyn_cast<NamedDecl>(LexicalD);
2614*0a6a1f1dSLionel Sambuc if (!ND || !needsAnonymousDeclarationNumber(ND))
2615*0a6a1f1dSLionel Sambuc continue;
2616*0a6a1f1dSLionel Sambuc if (Previous.size() == Index)
2617*0a6a1f1dSLionel Sambuc Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl()));
2618*0a6a1f1dSLionel Sambuc else
2619*0a6a1f1dSLionel Sambuc Previous[Index] = cast<NamedDecl>(ND->getCanonicalDecl());
2620*0a6a1f1dSLionel Sambuc ++Index;
2621*0a6a1f1dSLionel Sambuc }
2622*0a6a1f1dSLionel Sambuc }
2623*0a6a1f1dSLionel Sambuc
2624*0a6a1f1dSLionel Sambuc return Index < Previous.size() ? Previous[Index] : nullptr;
2625*0a6a1f1dSLionel Sambuc }
2626*0a6a1f1dSLionel Sambuc
setAnonymousDeclForMerging(ASTReader & Reader,DeclContext * DC,unsigned Index,NamedDecl * D)2627*0a6a1f1dSLionel Sambuc void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader,
2628*0a6a1f1dSLionel Sambuc DeclContext *DC, unsigned Index,
2629*0a6a1f1dSLionel Sambuc NamedDecl *D) {
2630*0a6a1f1dSLionel Sambuc if (auto *Merged = Reader.MergedDeclContexts.lookup(DC))
2631*0a6a1f1dSLionel Sambuc DC = Merged;
2632*0a6a1f1dSLionel Sambuc
2633*0a6a1f1dSLionel Sambuc auto &Previous = Reader.AnonymousDeclarationsForMerging[DC];
2634*0a6a1f1dSLionel Sambuc if (Index >= Previous.size())
2635*0a6a1f1dSLionel Sambuc Previous.resize(Index + 1);
2636*0a6a1f1dSLionel Sambuc if (!Previous[Index])
2637*0a6a1f1dSLionel Sambuc Previous[Index] = D;
2638*0a6a1f1dSLionel Sambuc }
2639*0a6a1f1dSLionel Sambuc
findExisting(NamedDecl * D)2640f4a2713aSLionel Sambuc ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
2641*0a6a1f1dSLionel Sambuc DeclarationName Name = TypedefNameForLinkage ? TypedefNameForLinkage
2642*0a6a1f1dSLionel Sambuc : D->getDeclName();
2643*0a6a1f1dSLionel Sambuc
2644*0a6a1f1dSLionel Sambuc if (!Name && !needsAnonymousDeclarationNumber(D)) {
2645*0a6a1f1dSLionel Sambuc // Don't bother trying to find unnamed declarations that are in
2646*0a6a1f1dSLionel Sambuc // unmergeable contexts.
2647*0a6a1f1dSLionel Sambuc FindExistingResult Result(Reader, D, /*Existing=*/nullptr,
2648*0a6a1f1dSLionel Sambuc AnonymousDeclNumber, TypedefNameForLinkage);
2649*0a6a1f1dSLionel Sambuc // FIXME: We may still need to pull in the redeclaration chain; there can
2650*0a6a1f1dSLionel Sambuc // be redeclarations via 'decltype'.
2651f4a2713aSLionel Sambuc Result.suppress();
2652f4a2713aSLionel Sambuc return Result;
2653f4a2713aSLionel Sambuc }
2654f4a2713aSLionel Sambuc
2655f4a2713aSLionel Sambuc // FIXME: Bail out for non-canonical declarations. We will have performed any
2656f4a2713aSLionel Sambuc // necessary merging already.
2657f4a2713aSLionel Sambuc
2658f4a2713aSLionel Sambuc DeclContext *DC = D->getDeclContext()->getRedeclContext();
2659*0a6a1f1dSLionel Sambuc if (TypedefNameForLinkage) {
2660*0a6a1f1dSLionel Sambuc auto It = Reader.ImportedTypedefNamesForLinkage.find(
2661*0a6a1f1dSLionel Sambuc std::make_pair(DC, TypedefNameForLinkage));
2662*0a6a1f1dSLionel Sambuc if (It != Reader.ImportedTypedefNamesForLinkage.end())
2663*0a6a1f1dSLionel Sambuc if (isSameEntity(It->second, D))
2664*0a6a1f1dSLionel Sambuc return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber,
2665*0a6a1f1dSLionel Sambuc TypedefNameForLinkage);
2666*0a6a1f1dSLionel Sambuc // Go on to check in other places in case an existing typedef name
2667*0a6a1f1dSLionel Sambuc // was not imported.
2668*0a6a1f1dSLionel Sambuc }
2669*0a6a1f1dSLionel Sambuc
2670*0a6a1f1dSLionel Sambuc if (!Name) {
2671*0a6a1f1dSLionel Sambuc // This is an anonymous declaration that we may need to merge. Look it up
2672*0a6a1f1dSLionel Sambuc // in its context by number.
2673*0a6a1f1dSLionel Sambuc assert(needsAnonymousDeclarationNumber(D));
2674*0a6a1f1dSLionel Sambuc if (auto *Existing = getAnonymousDeclForMerging(
2675*0a6a1f1dSLionel Sambuc Reader, D->getLexicalDeclContext(), AnonymousDeclNumber))
2676*0a6a1f1dSLionel Sambuc if (isSameEntity(Existing, D))
2677*0a6a1f1dSLionel Sambuc return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
2678*0a6a1f1dSLionel Sambuc TypedefNameForLinkage);
2679*0a6a1f1dSLionel Sambuc } else if (DC->isTranslationUnit() && Reader.SemaObj) {
2680f4a2713aSLionel Sambuc IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver;
2681f4a2713aSLionel Sambuc
2682f4a2713aSLionel Sambuc // Temporarily consider the identifier to be up-to-date. We don't want to
2683f4a2713aSLionel Sambuc // cause additional lookups here.
2684f4a2713aSLionel Sambuc class UpToDateIdentifierRAII {
2685f4a2713aSLionel Sambuc IdentifierInfo *II;
2686f4a2713aSLionel Sambuc bool WasOutToDate;
2687f4a2713aSLionel Sambuc
2688f4a2713aSLionel Sambuc public:
2689f4a2713aSLionel Sambuc explicit UpToDateIdentifierRAII(IdentifierInfo *II)
2690f4a2713aSLionel Sambuc : II(II), WasOutToDate(false)
2691f4a2713aSLionel Sambuc {
2692f4a2713aSLionel Sambuc if (II) {
2693f4a2713aSLionel Sambuc WasOutToDate = II->isOutOfDate();
2694f4a2713aSLionel Sambuc if (WasOutToDate)
2695f4a2713aSLionel Sambuc II->setOutOfDate(false);
2696f4a2713aSLionel Sambuc }
2697f4a2713aSLionel Sambuc }
2698f4a2713aSLionel Sambuc
2699f4a2713aSLionel Sambuc ~UpToDateIdentifierRAII() {
2700f4a2713aSLionel Sambuc if (WasOutToDate)
2701f4a2713aSLionel Sambuc II->setOutOfDate(true);
2702f4a2713aSLionel Sambuc }
2703f4a2713aSLionel Sambuc } UpToDate(Name.getAsIdentifierInfo());
2704f4a2713aSLionel Sambuc
2705f4a2713aSLionel Sambuc for (IdentifierResolver::iterator I = IdResolver.begin(Name),
2706f4a2713aSLionel Sambuc IEnd = IdResolver.end();
2707f4a2713aSLionel Sambuc I != IEnd; ++I) {
2708*0a6a1f1dSLionel Sambuc if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
2709*0a6a1f1dSLionel Sambuc if (isSameEntity(Existing, D))
2710*0a6a1f1dSLionel Sambuc return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
2711*0a6a1f1dSLionel Sambuc TypedefNameForLinkage);
2712f4a2713aSLionel Sambuc }
2713f4a2713aSLionel Sambuc } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) {
2714f4a2713aSLionel Sambuc DeclContext::lookup_result R = MergeDC->noload_lookup(Name);
2715f4a2713aSLionel Sambuc for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) {
2716*0a6a1f1dSLionel Sambuc if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
2717*0a6a1f1dSLionel Sambuc if (isSameEntity(Existing, D))
2718*0a6a1f1dSLionel Sambuc return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
2719*0a6a1f1dSLionel Sambuc TypedefNameForLinkage);
2720f4a2713aSLionel Sambuc }
2721f4a2713aSLionel Sambuc } else {
2722f4a2713aSLionel Sambuc // Not in a mergeable context.
2723f4a2713aSLionel Sambuc return FindExistingResult(Reader);
2724f4a2713aSLionel Sambuc }
2725f4a2713aSLionel Sambuc
2726f4a2713aSLionel Sambuc // If this declaration is from a merged context, make a note that we need to
2727f4a2713aSLionel Sambuc // check that the canonical definition of that context contains the decl.
2728*0a6a1f1dSLionel Sambuc //
2729*0a6a1f1dSLionel Sambuc // FIXME: We should do something similar if we merge two definitions of the
2730*0a6a1f1dSLionel Sambuc // same template specialization into the same CXXRecordDecl.
2731*0a6a1f1dSLionel Sambuc auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext());
2732*0a6a1f1dSLionel Sambuc if (MergedDCIt != Reader.MergedDeclContexts.end() &&
2733*0a6a1f1dSLionel Sambuc MergedDCIt->second == D->getDeclContext())
2734f4a2713aSLionel Sambuc Reader.PendingOdrMergeChecks.push_back(D);
2735f4a2713aSLionel Sambuc
2736*0a6a1f1dSLionel Sambuc return FindExistingResult(Reader, D, /*Existing=*/nullptr,
2737*0a6a1f1dSLionel Sambuc AnonymousDeclNumber, TypedefNameForLinkage);
2738f4a2713aSLionel Sambuc }
2739f4a2713aSLionel Sambuc
2740*0a6a1f1dSLionel Sambuc template<typename DeclT>
attachPreviousDeclImpl(ASTReader & Reader,Redeclarable<DeclT> * D,Decl * Previous)2741*0a6a1f1dSLionel Sambuc void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
2742*0a6a1f1dSLionel Sambuc Redeclarable<DeclT> *D,
2743*0a6a1f1dSLionel Sambuc Decl *Previous) {
2744*0a6a1f1dSLionel Sambuc D->RedeclLink.setPrevious(cast<DeclT>(Previous));
2745*0a6a1f1dSLionel Sambuc }
2746*0a6a1f1dSLionel Sambuc namespace clang {
2747*0a6a1f1dSLionel Sambuc template<>
attachPreviousDeclImpl(ASTReader & Reader,Redeclarable<FunctionDecl> * D,Decl * Previous)2748*0a6a1f1dSLionel Sambuc void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader,
2749*0a6a1f1dSLionel Sambuc Redeclarable<FunctionDecl> *D,
2750*0a6a1f1dSLionel Sambuc Decl *Previous) {
2751*0a6a1f1dSLionel Sambuc FunctionDecl *FD = static_cast<FunctionDecl*>(D);
2752*0a6a1f1dSLionel Sambuc FunctionDecl *PrevFD = cast<FunctionDecl>(Previous);
2753*0a6a1f1dSLionel Sambuc
2754*0a6a1f1dSLionel Sambuc FD->RedeclLink.setPrevious(PrevFD);
2755*0a6a1f1dSLionel Sambuc
2756*0a6a1f1dSLionel Sambuc // If the previous declaration is an inline function declaration, then this
2757*0a6a1f1dSLionel Sambuc // declaration is too.
2758*0a6a1f1dSLionel Sambuc if (PrevFD->IsInline != FD->IsInline) {
2759*0a6a1f1dSLionel Sambuc // FIXME: [dcl.fct.spec]p4:
2760*0a6a1f1dSLionel Sambuc // If a function with external linkage is declared inline in one
2761*0a6a1f1dSLionel Sambuc // translation unit, it shall be declared inline in all translation
2762*0a6a1f1dSLionel Sambuc // units in which it appears.
2763*0a6a1f1dSLionel Sambuc //
2764*0a6a1f1dSLionel Sambuc // Be careful of this case:
2765*0a6a1f1dSLionel Sambuc //
2766*0a6a1f1dSLionel Sambuc // module A:
2767*0a6a1f1dSLionel Sambuc // template<typename T> struct X { void f(); };
2768*0a6a1f1dSLionel Sambuc // template<typename T> inline void X<T>::f() {}
2769*0a6a1f1dSLionel Sambuc //
2770*0a6a1f1dSLionel Sambuc // module B instantiates the declaration of X<int>::f
2771*0a6a1f1dSLionel Sambuc // module C instantiates the definition of X<int>::f
2772*0a6a1f1dSLionel Sambuc //
2773*0a6a1f1dSLionel Sambuc // If module B and C are merged, we do not have a violation of this rule.
2774*0a6a1f1dSLionel Sambuc FD->IsInline = true;
2775*0a6a1f1dSLionel Sambuc }
2776*0a6a1f1dSLionel Sambuc
2777*0a6a1f1dSLionel Sambuc // If this declaration has an unresolved exception specification but the
2778*0a6a1f1dSLionel Sambuc // previous declaration had a resolved one, resolve the exception
2779*0a6a1f1dSLionel Sambuc // specification now.
2780*0a6a1f1dSLionel Sambuc auto *FPT = FD->getType()->getAs<FunctionProtoType>();
2781*0a6a1f1dSLionel Sambuc auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>();
2782*0a6a1f1dSLionel Sambuc if (FPT && PrevFPT &&
2783*0a6a1f1dSLionel Sambuc isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
2784*0a6a1f1dSLionel Sambuc !isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType())) {
2785*0a6a1f1dSLionel Sambuc Reader.Context.adjustExceptionSpec(
2786*0a6a1f1dSLionel Sambuc FD, PrevFPT->getExtProtoInfo().ExceptionSpec);
2787*0a6a1f1dSLionel Sambuc }
2788*0a6a1f1dSLionel Sambuc }
2789*0a6a1f1dSLionel Sambuc }
attachPreviousDeclImpl(ASTReader & Reader,...)2790*0a6a1f1dSLionel Sambuc void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {
2791*0a6a1f1dSLionel Sambuc llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
2792*0a6a1f1dSLionel Sambuc }
2793*0a6a1f1dSLionel Sambuc
attachPreviousDecl(ASTReader & Reader,Decl * D,Decl * Previous)2794*0a6a1f1dSLionel Sambuc void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
2795*0a6a1f1dSLionel Sambuc Decl *Previous) {
2796*0a6a1f1dSLionel Sambuc assert(D && Previous);
2797*0a6a1f1dSLionel Sambuc
2798*0a6a1f1dSLionel Sambuc switch (D->getKind()) {
2799*0a6a1f1dSLionel Sambuc #define ABSTRACT_DECL(TYPE)
2800*0a6a1f1dSLionel Sambuc #define DECL(TYPE, BASE) \
2801*0a6a1f1dSLionel Sambuc case Decl::TYPE: \
2802*0a6a1f1dSLionel Sambuc attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous); \
2803*0a6a1f1dSLionel Sambuc break;
2804*0a6a1f1dSLionel Sambuc #include "clang/AST/DeclNodes.inc"
2805f4a2713aSLionel Sambuc }
2806f4a2713aSLionel Sambuc
2807f4a2713aSLionel Sambuc // If the declaration was visible in one module, a redeclaration of it in
2808f4a2713aSLionel Sambuc // another module remains visible even if it wouldn't be visible by itself.
2809f4a2713aSLionel Sambuc //
2810f4a2713aSLionel Sambuc // FIXME: In this case, the declaration should only be visible if a module
2811f4a2713aSLionel Sambuc // that makes it visible has been imported.
2812f4a2713aSLionel Sambuc D->IdentifierNamespace |=
2813*0a6a1f1dSLionel Sambuc Previous->IdentifierNamespace &
2814f4a2713aSLionel Sambuc (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
2815*0a6a1f1dSLionel Sambuc
2816*0a6a1f1dSLionel Sambuc // If the previous declaration is marked as used, then this declaration should
2817*0a6a1f1dSLionel Sambuc // be too.
2818*0a6a1f1dSLionel Sambuc if (Previous->Used)
2819*0a6a1f1dSLionel Sambuc D->Used = true;
2820*0a6a1f1dSLionel Sambuc }
2821*0a6a1f1dSLionel Sambuc
2822*0a6a1f1dSLionel Sambuc template<typename DeclT>
attachLatestDeclImpl(Redeclarable<DeclT> * D,Decl * Latest)2823*0a6a1f1dSLionel Sambuc void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) {
2824*0a6a1f1dSLionel Sambuc D->RedeclLink.setLatest(cast<DeclT>(Latest));
2825*0a6a1f1dSLionel Sambuc }
attachLatestDeclImpl(...)2826*0a6a1f1dSLionel Sambuc void ASTDeclReader::attachLatestDeclImpl(...) {
2827*0a6a1f1dSLionel Sambuc llvm_unreachable("attachLatestDecl on non-redeclarable declaration");
2828f4a2713aSLionel Sambuc }
2829f4a2713aSLionel Sambuc
attachLatestDecl(Decl * D,Decl * Latest)2830f4a2713aSLionel Sambuc void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
2831f4a2713aSLionel Sambuc assert(D && Latest);
2832*0a6a1f1dSLionel Sambuc
2833*0a6a1f1dSLionel Sambuc switch (D->getKind()) {
2834*0a6a1f1dSLionel Sambuc #define ABSTRACT_DECL(TYPE)
2835*0a6a1f1dSLionel Sambuc #define DECL(TYPE, BASE) \
2836*0a6a1f1dSLionel Sambuc case Decl::TYPE: \
2837*0a6a1f1dSLionel Sambuc attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \
2838*0a6a1f1dSLionel Sambuc break;
2839*0a6a1f1dSLionel Sambuc #include "clang/AST/DeclNodes.inc"
2840*0a6a1f1dSLionel Sambuc }
2841*0a6a1f1dSLionel Sambuc }
2842*0a6a1f1dSLionel Sambuc
2843*0a6a1f1dSLionel Sambuc template<typename DeclT>
markIncompleteDeclChainImpl(Redeclarable<DeclT> * D)2844*0a6a1f1dSLionel Sambuc void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) {
2845*0a6a1f1dSLionel Sambuc D->RedeclLink.markIncomplete();
2846*0a6a1f1dSLionel Sambuc }
markIncompleteDeclChainImpl(...)2847*0a6a1f1dSLionel Sambuc void ASTDeclReader::markIncompleteDeclChainImpl(...) {
2848*0a6a1f1dSLionel Sambuc llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration");
2849*0a6a1f1dSLionel Sambuc }
2850*0a6a1f1dSLionel Sambuc
markIncompleteDeclChain(Decl * D)2851*0a6a1f1dSLionel Sambuc void ASTReader::markIncompleteDeclChain(Decl *D) {
2852*0a6a1f1dSLionel Sambuc switch (D->getKind()) {
2853*0a6a1f1dSLionel Sambuc #define ABSTRACT_DECL(TYPE)
2854*0a6a1f1dSLionel Sambuc #define DECL(TYPE, BASE) \
2855*0a6a1f1dSLionel Sambuc case Decl::TYPE: \
2856*0a6a1f1dSLionel Sambuc ASTDeclReader::markIncompleteDeclChainImpl(cast<TYPE##Decl>(D)); \
2857*0a6a1f1dSLionel Sambuc break;
2858*0a6a1f1dSLionel Sambuc #include "clang/AST/DeclNodes.inc"
2859f4a2713aSLionel Sambuc }
2860f4a2713aSLionel Sambuc }
2861f4a2713aSLionel Sambuc
2862f4a2713aSLionel Sambuc ASTReader::MergedDeclsMap::iterator
combineStoredMergedDecls(Decl * Canon,GlobalDeclID CanonID)2863f4a2713aSLionel Sambuc ASTReader::combineStoredMergedDecls(Decl *Canon, GlobalDeclID CanonID) {
2864f4a2713aSLionel Sambuc // If we don't have any stored merged declarations, just look in the
2865f4a2713aSLionel Sambuc // merged declarations set.
2866f4a2713aSLionel Sambuc StoredMergedDeclsMap::iterator StoredPos = StoredMergedDecls.find(CanonID);
2867f4a2713aSLionel Sambuc if (StoredPos == StoredMergedDecls.end())
2868f4a2713aSLionel Sambuc return MergedDecls.find(Canon);
2869f4a2713aSLionel Sambuc
2870f4a2713aSLionel Sambuc // Append the stored merged declarations to the merged declarations set.
2871f4a2713aSLionel Sambuc MergedDeclsMap::iterator Pos = MergedDecls.find(Canon);
2872f4a2713aSLionel Sambuc if (Pos == MergedDecls.end())
2873f4a2713aSLionel Sambuc Pos = MergedDecls.insert(std::make_pair(Canon,
2874f4a2713aSLionel Sambuc SmallVector<DeclID, 2>())).first;
2875f4a2713aSLionel Sambuc Pos->second.append(StoredPos->second.begin(), StoredPos->second.end());
2876f4a2713aSLionel Sambuc StoredMergedDecls.erase(StoredPos);
2877f4a2713aSLionel Sambuc
2878f4a2713aSLionel Sambuc // Sort and uniquify the set of merged declarations.
2879f4a2713aSLionel Sambuc llvm::array_pod_sort(Pos->second.begin(), Pos->second.end());
2880f4a2713aSLionel Sambuc Pos->second.erase(std::unique(Pos->second.begin(), Pos->second.end()),
2881f4a2713aSLionel Sambuc Pos->second.end());
2882f4a2713aSLionel Sambuc return Pos;
2883f4a2713aSLionel Sambuc }
2884f4a2713aSLionel Sambuc
2885f4a2713aSLionel Sambuc /// \brief Read the declaration at the given offset from the AST file.
ReadDeclRecord(DeclID ID)2886f4a2713aSLionel Sambuc Decl *ASTReader::ReadDeclRecord(DeclID ID) {
2887f4a2713aSLionel Sambuc unsigned Index = ID - NUM_PREDEF_DECL_IDS;
2888f4a2713aSLionel Sambuc unsigned RawLocation = 0;
2889f4a2713aSLionel Sambuc RecordLocation Loc = DeclCursorForID(ID, RawLocation);
2890f4a2713aSLionel Sambuc llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor;
2891f4a2713aSLionel Sambuc // Keep track of where we are in the stream, then jump back there
2892f4a2713aSLionel Sambuc // after reading this declaration.
2893f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(DeclsCursor);
2894f4a2713aSLionel Sambuc
2895f4a2713aSLionel Sambuc ReadingKindTracker ReadingKind(Read_Decl, *this);
2896f4a2713aSLionel Sambuc
2897f4a2713aSLionel Sambuc // Note that we are loading a declaration record.
2898f4a2713aSLionel Sambuc Deserializing ADecl(this);
2899f4a2713aSLionel Sambuc
2900f4a2713aSLionel Sambuc DeclsCursor.JumpToBit(Loc.Offset);
2901f4a2713aSLionel Sambuc RecordData Record;
2902f4a2713aSLionel Sambuc unsigned Code = DeclsCursor.ReadCode();
2903f4a2713aSLionel Sambuc unsigned Idx = 0;
2904f4a2713aSLionel Sambuc ASTDeclReader Reader(*this, *Loc.F, ID, RawLocation, Record,Idx);
2905f4a2713aSLionel Sambuc
2906*0a6a1f1dSLionel Sambuc Decl *D = nullptr;
2907f4a2713aSLionel Sambuc switch ((DeclCode)DeclsCursor.readRecord(Code, Record)) {
2908f4a2713aSLionel Sambuc case DECL_CONTEXT_LEXICAL:
2909f4a2713aSLionel Sambuc case DECL_CONTEXT_VISIBLE:
2910f4a2713aSLionel Sambuc llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord");
2911f4a2713aSLionel Sambuc case DECL_TYPEDEF:
2912f4a2713aSLionel Sambuc D = TypedefDecl::CreateDeserialized(Context, ID);
2913f4a2713aSLionel Sambuc break;
2914f4a2713aSLionel Sambuc case DECL_TYPEALIAS:
2915f4a2713aSLionel Sambuc D = TypeAliasDecl::CreateDeserialized(Context, ID);
2916f4a2713aSLionel Sambuc break;
2917f4a2713aSLionel Sambuc case DECL_ENUM:
2918f4a2713aSLionel Sambuc D = EnumDecl::CreateDeserialized(Context, ID);
2919f4a2713aSLionel Sambuc break;
2920f4a2713aSLionel Sambuc case DECL_RECORD:
2921f4a2713aSLionel Sambuc D = RecordDecl::CreateDeserialized(Context, ID);
2922f4a2713aSLionel Sambuc break;
2923f4a2713aSLionel Sambuc case DECL_ENUM_CONSTANT:
2924f4a2713aSLionel Sambuc D = EnumConstantDecl::CreateDeserialized(Context, ID);
2925f4a2713aSLionel Sambuc break;
2926f4a2713aSLionel Sambuc case DECL_FUNCTION:
2927f4a2713aSLionel Sambuc D = FunctionDecl::CreateDeserialized(Context, ID);
2928f4a2713aSLionel Sambuc break;
2929f4a2713aSLionel Sambuc case DECL_LINKAGE_SPEC:
2930f4a2713aSLionel Sambuc D = LinkageSpecDecl::CreateDeserialized(Context, ID);
2931f4a2713aSLionel Sambuc break;
2932f4a2713aSLionel Sambuc case DECL_LABEL:
2933f4a2713aSLionel Sambuc D = LabelDecl::CreateDeserialized(Context, ID);
2934f4a2713aSLionel Sambuc break;
2935f4a2713aSLionel Sambuc case DECL_NAMESPACE:
2936f4a2713aSLionel Sambuc D = NamespaceDecl::CreateDeserialized(Context, ID);
2937f4a2713aSLionel Sambuc break;
2938f4a2713aSLionel Sambuc case DECL_NAMESPACE_ALIAS:
2939f4a2713aSLionel Sambuc D = NamespaceAliasDecl::CreateDeserialized(Context, ID);
2940f4a2713aSLionel Sambuc break;
2941f4a2713aSLionel Sambuc case DECL_USING:
2942f4a2713aSLionel Sambuc D = UsingDecl::CreateDeserialized(Context, ID);
2943f4a2713aSLionel Sambuc break;
2944f4a2713aSLionel Sambuc case DECL_USING_SHADOW:
2945f4a2713aSLionel Sambuc D = UsingShadowDecl::CreateDeserialized(Context, ID);
2946f4a2713aSLionel Sambuc break;
2947f4a2713aSLionel Sambuc case DECL_USING_DIRECTIVE:
2948f4a2713aSLionel Sambuc D = UsingDirectiveDecl::CreateDeserialized(Context, ID);
2949f4a2713aSLionel Sambuc break;
2950f4a2713aSLionel Sambuc case DECL_UNRESOLVED_USING_VALUE:
2951f4a2713aSLionel Sambuc D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID);
2952f4a2713aSLionel Sambuc break;
2953f4a2713aSLionel Sambuc case DECL_UNRESOLVED_USING_TYPENAME:
2954f4a2713aSLionel Sambuc D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID);
2955f4a2713aSLionel Sambuc break;
2956f4a2713aSLionel Sambuc case DECL_CXX_RECORD:
2957f4a2713aSLionel Sambuc D = CXXRecordDecl::CreateDeserialized(Context, ID);
2958f4a2713aSLionel Sambuc break;
2959f4a2713aSLionel Sambuc case DECL_CXX_METHOD:
2960f4a2713aSLionel Sambuc D = CXXMethodDecl::CreateDeserialized(Context, ID);
2961f4a2713aSLionel Sambuc break;
2962f4a2713aSLionel Sambuc case DECL_CXX_CONSTRUCTOR:
2963f4a2713aSLionel Sambuc D = CXXConstructorDecl::CreateDeserialized(Context, ID);
2964f4a2713aSLionel Sambuc break;
2965f4a2713aSLionel Sambuc case DECL_CXX_DESTRUCTOR:
2966f4a2713aSLionel Sambuc D = CXXDestructorDecl::CreateDeserialized(Context, ID);
2967f4a2713aSLionel Sambuc break;
2968f4a2713aSLionel Sambuc case DECL_CXX_CONVERSION:
2969f4a2713aSLionel Sambuc D = CXXConversionDecl::CreateDeserialized(Context, ID);
2970f4a2713aSLionel Sambuc break;
2971f4a2713aSLionel Sambuc case DECL_ACCESS_SPEC:
2972f4a2713aSLionel Sambuc D = AccessSpecDecl::CreateDeserialized(Context, ID);
2973f4a2713aSLionel Sambuc break;
2974f4a2713aSLionel Sambuc case DECL_FRIEND:
2975f4a2713aSLionel Sambuc D = FriendDecl::CreateDeserialized(Context, ID, Record[Idx++]);
2976f4a2713aSLionel Sambuc break;
2977f4a2713aSLionel Sambuc case DECL_FRIEND_TEMPLATE:
2978f4a2713aSLionel Sambuc D = FriendTemplateDecl::CreateDeserialized(Context, ID);
2979f4a2713aSLionel Sambuc break;
2980f4a2713aSLionel Sambuc case DECL_CLASS_TEMPLATE:
2981f4a2713aSLionel Sambuc D = ClassTemplateDecl::CreateDeserialized(Context, ID);
2982f4a2713aSLionel Sambuc break;
2983f4a2713aSLionel Sambuc case DECL_CLASS_TEMPLATE_SPECIALIZATION:
2984f4a2713aSLionel Sambuc D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID);
2985f4a2713aSLionel Sambuc break;
2986f4a2713aSLionel Sambuc case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION:
2987f4a2713aSLionel Sambuc D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID);
2988f4a2713aSLionel Sambuc break;
2989f4a2713aSLionel Sambuc case DECL_VAR_TEMPLATE:
2990f4a2713aSLionel Sambuc D = VarTemplateDecl::CreateDeserialized(Context, ID);
2991f4a2713aSLionel Sambuc break;
2992f4a2713aSLionel Sambuc case DECL_VAR_TEMPLATE_SPECIALIZATION:
2993f4a2713aSLionel Sambuc D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID);
2994f4a2713aSLionel Sambuc break;
2995f4a2713aSLionel Sambuc case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION:
2996f4a2713aSLionel Sambuc D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID);
2997f4a2713aSLionel Sambuc break;
2998f4a2713aSLionel Sambuc case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
2999f4a2713aSLionel Sambuc D = ClassScopeFunctionSpecializationDecl::CreateDeserialized(Context, ID);
3000f4a2713aSLionel Sambuc break;
3001f4a2713aSLionel Sambuc case DECL_FUNCTION_TEMPLATE:
3002f4a2713aSLionel Sambuc D = FunctionTemplateDecl::CreateDeserialized(Context, ID);
3003f4a2713aSLionel Sambuc break;
3004f4a2713aSLionel Sambuc case DECL_TEMPLATE_TYPE_PARM:
3005f4a2713aSLionel Sambuc D = TemplateTypeParmDecl::CreateDeserialized(Context, ID);
3006f4a2713aSLionel Sambuc break;
3007f4a2713aSLionel Sambuc case DECL_NON_TYPE_TEMPLATE_PARM:
3008f4a2713aSLionel Sambuc D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID);
3009f4a2713aSLionel Sambuc break;
3010f4a2713aSLionel Sambuc case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK:
3011f4a2713aSLionel Sambuc D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, Record[Idx++]);
3012f4a2713aSLionel Sambuc break;
3013f4a2713aSLionel Sambuc case DECL_TEMPLATE_TEMPLATE_PARM:
3014f4a2713aSLionel Sambuc D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID);
3015f4a2713aSLionel Sambuc break;
3016f4a2713aSLionel Sambuc case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK:
3017f4a2713aSLionel Sambuc D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID,
3018f4a2713aSLionel Sambuc Record[Idx++]);
3019f4a2713aSLionel Sambuc break;
3020f4a2713aSLionel Sambuc case DECL_TYPE_ALIAS_TEMPLATE:
3021f4a2713aSLionel Sambuc D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID);
3022f4a2713aSLionel Sambuc break;
3023f4a2713aSLionel Sambuc case DECL_STATIC_ASSERT:
3024f4a2713aSLionel Sambuc D = StaticAssertDecl::CreateDeserialized(Context, ID);
3025f4a2713aSLionel Sambuc break;
3026f4a2713aSLionel Sambuc case DECL_OBJC_METHOD:
3027f4a2713aSLionel Sambuc D = ObjCMethodDecl::CreateDeserialized(Context, ID);
3028f4a2713aSLionel Sambuc break;
3029f4a2713aSLionel Sambuc case DECL_OBJC_INTERFACE:
3030f4a2713aSLionel Sambuc D = ObjCInterfaceDecl::CreateDeserialized(Context, ID);
3031f4a2713aSLionel Sambuc break;
3032f4a2713aSLionel Sambuc case DECL_OBJC_IVAR:
3033f4a2713aSLionel Sambuc D = ObjCIvarDecl::CreateDeserialized(Context, ID);
3034f4a2713aSLionel Sambuc break;
3035f4a2713aSLionel Sambuc case DECL_OBJC_PROTOCOL:
3036f4a2713aSLionel Sambuc D = ObjCProtocolDecl::CreateDeserialized(Context, ID);
3037f4a2713aSLionel Sambuc break;
3038f4a2713aSLionel Sambuc case DECL_OBJC_AT_DEFS_FIELD:
3039f4a2713aSLionel Sambuc D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID);
3040f4a2713aSLionel Sambuc break;
3041f4a2713aSLionel Sambuc case DECL_OBJC_CATEGORY:
3042f4a2713aSLionel Sambuc D = ObjCCategoryDecl::CreateDeserialized(Context, ID);
3043f4a2713aSLionel Sambuc break;
3044f4a2713aSLionel Sambuc case DECL_OBJC_CATEGORY_IMPL:
3045f4a2713aSLionel Sambuc D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID);
3046f4a2713aSLionel Sambuc break;
3047f4a2713aSLionel Sambuc case DECL_OBJC_IMPLEMENTATION:
3048f4a2713aSLionel Sambuc D = ObjCImplementationDecl::CreateDeserialized(Context, ID);
3049f4a2713aSLionel Sambuc break;
3050f4a2713aSLionel Sambuc case DECL_OBJC_COMPATIBLE_ALIAS:
3051f4a2713aSLionel Sambuc D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID);
3052f4a2713aSLionel Sambuc break;
3053f4a2713aSLionel Sambuc case DECL_OBJC_PROPERTY:
3054f4a2713aSLionel Sambuc D = ObjCPropertyDecl::CreateDeserialized(Context, ID);
3055f4a2713aSLionel Sambuc break;
3056f4a2713aSLionel Sambuc case DECL_OBJC_PROPERTY_IMPL:
3057f4a2713aSLionel Sambuc D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID);
3058f4a2713aSLionel Sambuc break;
3059f4a2713aSLionel Sambuc case DECL_FIELD:
3060f4a2713aSLionel Sambuc D = FieldDecl::CreateDeserialized(Context, ID);
3061f4a2713aSLionel Sambuc break;
3062f4a2713aSLionel Sambuc case DECL_INDIRECTFIELD:
3063f4a2713aSLionel Sambuc D = IndirectFieldDecl::CreateDeserialized(Context, ID);
3064f4a2713aSLionel Sambuc break;
3065f4a2713aSLionel Sambuc case DECL_VAR:
3066f4a2713aSLionel Sambuc D = VarDecl::CreateDeserialized(Context, ID);
3067f4a2713aSLionel Sambuc break;
3068f4a2713aSLionel Sambuc case DECL_IMPLICIT_PARAM:
3069f4a2713aSLionel Sambuc D = ImplicitParamDecl::CreateDeserialized(Context, ID);
3070f4a2713aSLionel Sambuc break;
3071f4a2713aSLionel Sambuc case DECL_PARM_VAR:
3072f4a2713aSLionel Sambuc D = ParmVarDecl::CreateDeserialized(Context, ID);
3073f4a2713aSLionel Sambuc break;
3074f4a2713aSLionel Sambuc case DECL_FILE_SCOPE_ASM:
3075f4a2713aSLionel Sambuc D = FileScopeAsmDecl::CreateDeserialized(Context, ID);
3076f4a2713aSLionel Sambuc break;
3077f4a2713aSLionel Sambuc case DECL_BLOCK:
3078f4a2713aSLionel Sambuc D = BlockDecl::CreateDeserialized(Context, ID);
3079f4a2713aSLionel Sambuc break;
3080f4a2713aSLionel Sambuc case DECL_MS_PROPERTY:
3081f4a2713aSLionel Sambuc D = MSPropertyDecl::CreateDeserialized(Context, ID);
3082f4a2713aSLionel Sambuc break;
3083f4a2713aSLionel Sambuc case DECL_CAPTURED:
3084f4a2713aSLionel Sambuc D = CapturedDecl::CreateDeserialized(Context, ID, Record[Idx++]);
3085f4a2713aSLionel Sambuc break;
3086f4a2713aSLionel Sambuc case DECL_CXX_BASE_SPECIFIERS:
3087f4a2713aSLionel Sambuc Error("attempt to read a C++ base-specifier record as a declaration");
3088*0a6a1f1dSLionel Sambuc return nullptr;
3089f4a2713aSLionel Sambuc case DECL_IMPORT:
3090f4a2713aSLionel Sambuc // Note: last entry of the ImportDecl record is the number of stored source
3091f4a2713aSLionel Sambuc // locations.
3092f4a2713aSLionel Sambuc D = ImportDecl::CreateDeserialized(Context, ID, Record.back());
3093f4a2713aSLionel Sambuc break;
3094f4a2713aSLionel Sambuc case DECL_OMP_THREADPRIVATE:
3095f4a2713aSLionel Sambuc D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record[Idx++]);
3096f4a2713aSLionel Sambuc break;
3097f4a2713aSLionel Sambuc case DECL_EMPTY:
3098f4a2713aSLionel Sambuc D = EmptyDecl::CreateDeserialized(Context, ID);
3099f4a2713aSLionel Sambuc break;
3100f4a2713aSLionel Sambuc }
3101f4a2713aSLionel Sambuc
3102f4a2713aSLionel Sambuc assert(D && "Unknown declaration reading AST file");
3103f4a2713aSLionel Sambuc LoadedDecl(Index, D);
3104f4a2713aSLionel Sambuc // Set the DeclContext before doing any deserialization, to make sure internal
3105f4a2713aSLionel Sambuc // calls to Decl::getASTContext() by Decl's methods will find the
3106f4a2713aSLionel Sambuc // TranslationUnitDecl without crashing.
3107f4a2713aSLionel Sambuc D->setDeclContext(Context.getTranslationUnitDecl());
3108f4a2713aSLionel Sambuc Reader.Visit(D);
3109f4a2713aSLionel Sambuc
3110f4a2713aSLionel Sambuc // If this declaration is also a declaration context, get the
3111f4a2713aSLionel Sambuc // offsets for its tables of lexical and visible declarations.
3112f4a2713aSLionel Sambuc if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
3113f4a2713aSLionel Sambuc // FIXME: This should really be
3114f4a2713aSLionel Sambuc // DeclContext *LookupDC = DC->getPrimaryContext();
3115f4a2713aSLionel Sambuc // but that can walk the redeclaration chain, which might not work yet.
3116f4a2713aSLionel Sambuc DeclContext *LookupDC = DC;
3117f4a2713aSLionel Sambuc if (isa<NamespaceDecl>(DC))
3118f4a2713aSLionel Sambuc LookupDC = DC->getPrimaryContext();
3119f4a2713aSLionel Sambuc std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
3120f4a2713aSLionel Sambuc if (Offsets.first || Offsets.second) {
3121f4a2713aSLionel Sambuc if (Offsets.first != 0)
3122f4a2713aSLionel Sambuc DC->setHasExternalLexicalStorage(true);
3123f4a2713aSLionel Sambuc if (Offsets.second != 0)
3124f4a2713aSLionel Sambuc LookupDC->setHasExternalVisibleStorage(true);
3125f4a2713aSLionel Sambuc if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets,
3126f4a2713aSLionel Sambuc Loc.F->DeclContextInfos[DC]))
3127*0a6a1f1dSLionel Sambuc return nullptr;
3128f4a2713aSLionel Sambuc }
3129f4a2713aSLionel Sambuc
3130f4a2713aSLionel Sambuc // Now add the pending visible updates for this decl context, if it has any.
3131f4a2713aSLionel Sambuc DeclContextVisibleUpdatesPending::iterator I =
3132f4a2713aSLionel Sambuc PendingVisibleUpdates.find(ID);
3133f4a2713aSLionel Sambuc if (I != PendingVisibleUpdates.end()) {
3134f4a2713aSLionel Sambuc // There are updates. This means the context has external visible
3135f4a2713aSLionel Sambuc // storage, even if the original stored version didn't.
3136f4a2713aSLionel Sambuc LookupDC->setHasExternalVisibleStorage(true);
3137*0a6a1f1dSLionel Sambuc for (const auto &Update : I->second) {
3138*0a6a1f1dSLionel Sambuc DeclContextInfo &Info = Update.second->DeclContextInfos[DC];
3139f4a2713aSLionel Sambuc delete Info.NameLookupTableData;
3140*0a6a1f1dSLionel Sambuc Info.NameLookupTableData = Update.first;
3141f4a2713aSLionel Sambuc }
3142f4a2713aSLionel Sambuc PendingVisibleUpdates.erase(I);
3143f4a2713aSLionel Sambuc }
3144f4a2713aSLionel Sambuc }
3145f4a2713aSLionel Sambuc assert(Idx == Record.size());
3146f4a2713aSLionel Sambuc
3147f4a2713aSLionel Sambuc // Load any relevant update records.
3148*0a6a1f1dSLionel Sambuc PendingUpdateRecords.push_back(std::make_pair(ID, D));
3149f4a2713aSLionel Sambuc
3150f4a2713aSLionel Sambuc // Load the categories after recursive loading is finished.
3151f4a2713aSLionel Sambuc if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
3152f4a2713aSLionel Sambuc if (Class->isThisDeclarationADefinition())
3153f4a2713aSLionel Sambuc loadObjCCategories(ID, Class);
3154f4a2713aSLionel Sambuc
3155f4a2713aSLionel Sambuc // If we have deserialized a declaration that has a definition the
3156f4a2713aSLionel Sambuc // AST consumer might need to know about, queue it.
3157f4a2713aSLionel Sambuc // We don't pass it to the consumer immediately because we may be in recursive
3158f4a2713aSLionel Sambuc // loading, and some declarations may still be initializing.
3159f4a2713aSLionel Sambuc if (isConsumerInterestedIn(D, Reader.hasPendingBody()))
3160f4a2713aSLionel Sambuc InterestingDecls.push_back(D);
3161f4a2713aSLionel Sambuc
3162f4a2713aSLionel Sambuc return D;
3163f4a2713aSLionel Sambuc }
3164f4a2713aSLionel Sambuc
loadDeclUpdateRecords(serialization::DeclID ID,Decl * D)3165f4a2713aSLionel Sambuc void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
3166f4a2713aSLionel Sambuc // The declaration may have been modified by files later in the chain.
3167f4a2713aSLionel Sambuc // If this is the case, read the record containing the updates from each file
3168f4a2713aSLionel Sambuc // and pass it to ASTDeclReader to make the modifications.
3169f4a2713aSLionel Sambuc DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
3170f4a2713aSLionel Sambuc if (UpdI != DeclUpdateOffsets.end()) {
3171f4a2713aSLionel Sambuc FileOffsetsTy &UpdateOffsets = UpdI->second;
3172*0a6a1f1dSLionel Sambuc bool WasInteresting = isConsumerInterestedIn(D, false);
3173f4a2713aSLionel Sambuc for (FileOffsetsTy::iterator
3174f4a2713aSLionel Sambuc I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
3175f4a2713aSLionel Sambuc ModuleFile *F = I->first;
3176f4a2713aSLionel Sambuc uint64_t Offset = I->second;
3177f4a2713aSLionel Sambuc llvm::BitstreamCursor &Cursor = F->DeclsCursor;
3178f4a2713aSLionel Sambuc SavedStreamPosition SavedPosition(Cursor);
3179f4a2713aSLionel Sambuc Cursor.JumpToBit(Offset);
3180f4a2713aSLionel Sambuc RecordData Record;
3181f4a2713aSLionel Sambuc unsigned Code = Cursor.ReadCode();
3182f4a2713aSLionel Sambuc unsigned RecCode = Cursor.readRecord(Code, Record);
3183f4a2713aSLionel Sambuc (void)RecCode;
3184f4a2713aSLionel Sambuc assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
3185f4a2713aSLionel Sambuc
3186f4a2713aSLionel Sambuc unsigned Idx = 0;
3187f4a2713aSLionel Sambuc ASTDeclReader Reader(*this, *F, ID, 0, Record, Idx);
3188f4a2713aSLionel Sambuc Reader.UpdateDecl(D, *F, Record);
3189*0a6a1f1dSLionel Sambuc
3190*0a6a1f1dSLionel Sambuc // We might have made this declaration interesting. If so, remember that
3191*0a6a1f1dSLionel Sambuc // we need to hand it off to the consumer.
3192*0a6a1f1dSLionel Sambuc if (!WasInteresting &&
3193*0a6a1f1dSLionel Sambuc isConsumerInterestedIn(D, Reader.hasPendingBody())) {
3194*0a6a1f1dSLionel Sambuc InterestingDecls.push_back(D);
3195*0a6a1f1dSLionel Sambuc WasInteresting = true;
3196*0a6a1f1dSLionel Sambuc }
3197f4a2713aSLionel Sambuc }
3198f4a2713aSLionel Sambuc }
3199f4a2713aSLionel Sambuc }
3200f4a2713aSLionel Sambuc
3201f4a2713aSLionel Sambuc namespace {
3202f4a2713aSLionel Sambuc /// \brief Module visitor class that finds all of the redeclarations of a
3203f4a2713aSLionel Sambuc ///
3204f4a2713aSLionel Sambuc class RedeclChainVisitor {
3205f4a2713aSLionel Sambuc ASTReader &Reader;
3206f4a2713aSLionel Sambuc SmallVectorImpl<DeclID> &SearchDecls;
3207*0a6a1f1dSLionel Sambuc llvm::SmallPtrSetImpl<Decl *> &Deserialized;
3208f4a2713aSLionel Sambuc GlobalDeclID CanonID;
3209f4a2713aSLionel Sambuc SmallVector<Decl *, 4> Chain;
3210f4a2713aSLionel Sambuc
3211f4a2713aSLionel Sambuc public:
RedeclChainVisitor(ASTReader & Reader,SmallVectorImpl<DeclID> & SearchDecls,llvm::SmallPtrSetImpl<Decl * > & Deserialized,GlobalDeclID CanonID)3212f4a2713aSLionel Sambuc RedeclChainVisitor(ASTReader &Reader, SmallVectorImpl<DeclID> &SearchDecls,
3213*0a6a1f1dSLionel Sambuc llvm::SmallPtrSetImpl<Decl *> &Deserialized,
3214f4a2713aSLionel Sambuc GlobalDeclID CanonID)
3215f4a2713aSLionel Sambuc : Reader(Reader), SearchDecls(SearchDecls), Deserialized(Deserialized),
3216f4a2713aSLionel Sambuc CanonID(CanonID) {
3217f4a2713aSLionel Sambuc for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
3218f4a2713aSLionel Sambuc addToChain(Reader.GetDecl(SearchDecls[I]));
3219f4a2713aSLionel Sambuc }
3220f4a2713aSLionel Sambuc
visit(ModuleFile & M,bool Preorder,void * UserData)3221f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, bool Preorder, void *UserData) {
3222f4a2713aSLionel Sambuc if (Preorder)
3223f4a2713aSLionel Sambuc return false;
3224f4a2713aSLionel Sambuc
3225f4a2713aSLionel Sambuc return static_cast<RedeclChainVisitor *>(UserData)->visit(M);
3226f4a2713aSLionel Sambuc }
3227f4a2713aSLionel Sambuc
addToChain(Decl * D)3228f4a2713aSLionel Sambuc void addToChain(Decl *D) {
3229f4a2713aSLionel Sambuc if (!D)
3230f4a2713aSLionel Sambuc return;
3231f4a2713aSLionel Sambuc
3232f4a2713aSLionel Sambuc if (Deserialized.erase(D))
3233f4a2713aSLionel Sambuc Chain.push_back(D);
3234f4a2713aSLionel Sambuc }
3235f4a2713aSLionel Sambuc
searchForID(ModuleFile & M,GlobalDeclID GlobalID)3236f4a2713aSLionel Sambuc void searchForID(ModuleFile &M, GlobalDeclID GlobalID) {
3237f4a2713aSLionel Sambuc // Map global ID of the first declaration down to the local ID
3238f4a2713aSLionel Sambuc // used in this module file.
3239f4a2713aSLionel Sambuc DeclID ID = Reader.mapGlobalIDToModuleFileGlobalID(M, GlobalID);
3240f4a2713aSLionel Sambuc if (!ID)
3241f4a2713aSLionel Sambuc return;
3242f4a2713aSLionel Sambuc
3243f4a2713aSLionel Sambuc // Perform a binary search to find the local redeclarations for this
3244f4a2713aSLionel Sambuc // declaration (if any).
3245*0a6a1f1dSLionel Sambuc const LocalRedeclarationsInfo Compare = { ID, 0 };
3246f4a2713aSLionel Sambuc const LocalRedeclarationsInfo *Result
3247f4a2713aSLionel Sambuc = std::lower_bound(M.RedeclarationsMap,
3248f4a2713aSLionel Sambuc M.RedeclarationsMap + M.LocalNumRedeclarationsInMap,
3249*0a6a1f1dSLionel Sambuc Compare);
3250f4a2713aSLionel Sambuc if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap ||
3251f4a2713aSLionel Sambuc Result->FirstID != ID) {
3252f4a2713aSLionel Sambuc // If we have a previously-canonical singleton declaration that was
3253f4a2713aSLionel Sambuc // merged into another redeclaration chain, create a trivial chain
3254f4a2713aSLionel Sambuc // for this single declaration so that it will get wired into the
3255f4a2713aSLionel Sambuc // complete redeclaration chain.
3256f4a2713aSLionel Sambuc if (GlobalID != CanonID &&
3257f4a2713aSLionel Sambuc GlobalID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID &&
3258f4a2713aSLionel Sambuc GlobalID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls) {
3259f4a2713aSLionel Sambuc addToChain(Reader.GetDecl(GlobalID));
3260f4a2713aSLionel Sambuc }
3261f4a2713aSLionel Sambuc
3262f4a2713aSLionel Sambuc return;
3263f4a2713aSLionel Sambuc }
3264f4a2713aSLionel Sambuc
3265f4a2713aSLionel Sambuc // Dig out all of the redeclarations.
3266f4a2713aSLionel Sambuc unsigned Offset = Result->Offset;
3267f4a2713aSLionel Sambuc unsigned N = M.RedeclarationChains[Offset];
3268f4a2713aSLionel Sambuc M.RedeclarationChains[Offset++] = 0; // Don't try to deserialize again
3269f4a2713aSLionel Sambuc for (unsigned I = 0; I != N; ++I)
3270f4a2713aSLionel Sambuc addToChain(Reader.GetLocalDecl(M, M.RedeclarationChains[Offset++]));
3271f4a2713aSLionel Sambuc }
3272f4a2713aSLionel Sambuc
visit(ModuleFile & M)3273f4a2713aSLionel Sambuc bool visit(ModuleFile &M) {
3274f4a2713aSLionel Sambuc // Visit each of the declarations.
3275f4a2713aSLionel Sambuc for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
3276f4a2713aSLionel Sambuc searchForID(M, SearchDecls[I]);
3277*0a6a1f1dSLionel Sambuc // FIXME: If none of the SearchDecls had local IDs in this module, can
3278*0a6a1f1dSLionel Sambuc // we avoid searching any ancestor module files?
3279f4a2713aSLionel Sambuc return false;
3280f4a2713aSLionel Sambuc }
3281f4a2713aSLionel Sambuc
getChain() const3282f4a2713aSLionel Sambuc ArrayRef<Decl *> getChain() const {
3283f4a2713aSLionel Sambuc return Chain;
3284f4a2713aSLionel Sambuc }
3285f4a2713aSLionel Sambuc };
3286f4a2713aSLionel Sambuc }
3287f4a2713aSLionel Sambuc
loadPendingDeclChain(serialization::GlobalDeclID ID)3288f4a2713aSLionel Sambuc void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) {
3289f4a2713aSLionel Sambuc Decl *D = GetDecl(ID);
3290f4a2713aSLionel Sambuc Decl *CanonDecl = D->getCanonicalDecl();
3291f4a2713aSLionel Sambuc
3292f4a2713aSLionel Sambuc // Determine the set of declaration IDs we'll be searching for.
3293f4a2713aSLionel Sambuc SmallVector<DeclID, 1> SearchDecls;
3294f4a2713aSLionel Sambuc GlobalDeclID CanonID = 0;
3295f4a2713aSLionel Sambuc if (D == CanonDecl) {
3296f4a2713aSLionel Sambuc SearchDecls.push_back(ID); // Always first.
3297f4a2713aSLionel Sambuc CanonID = ID;
3298f4a2713aSLionel Sambuc }
3299f4a2713aSLionel Sambuc MergedDeclsMap::iterator MergedPos = combineStoredMergedDecls(CanonDecl, ID);
3300f4a2713aSLionel Sambuc if (MergedPos != MergedDecls.end())
3301f4a2713aSLionel Sambuc SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end());
3302f4a2713aSLionel Sambuc
3303f4a2713aSLionel Sambuc // Build up the list of redeclarations.
3304f4a2713aSLionel Sambuc RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID);
3305f4a2713aSLionel Sambuc ModuleMgr.visitDepthFirst(&RedeclChainVisitor::visit, &Visitor);
3306f4a2713aSLionel Sambuc
3307f4a2713aSLionel Sambuc // Retrieve the chains.
3308f4a2713aSLionel Sambuc ArrayRef<Decl *> Chain = Visitor.getChain();
3309f4a2713aSLionel Sambuc if (Chain.empty())
3310f4a2713aSLionel Sambuc return;
3311f4a2713aSLionel Sambuc
3312f4a2713aSLionel Sambuc // Hook up the chains.
3313f4a2713aSLionel Sambuc Decl *MostRecent = CanonDecl->getMostRecentDecl();
3314f4a2713aSLionel Sambuc for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
3315f4a2713aSLionel Sambuc if (Chain[I] == CanonDecl)
3316f4a2713aSLionel Sambuc continue;
3317f4a2713aSLionel Sambuc
3318*0a6a1f1dSLionel Sambuc ASTDeclReader::attachPreviousDecl(*this, Chain[I], MostRecent);
3319f4a2713aSLionel Sambuc MostRecent = Chain[I];
3320f4a2713aSLionel Sambuc }
3321f4a2713aSLionel Sambuc
3322f4a2713aSLionel Sambuc ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent);
3323f4a2713aSLionel Sambuc }
3324f4a2713aSLionel Sambuc
3325f4a2713aSLionel Sambuc namespace {
3326f4a2713aSLionel Sambuc /// \brief Given an ObjC interface, goes through the modules and links to the
3327f4a2713aSLionel Sambuc /// interface all the categories for it.
3328f4a2713aSLionel Sambuc class ObjCCategoriesVisitor {
3329f4a2713aSLionel Sambuc ASTReader &Reader;
3330f4a2713aSLionel Sambuc serialization::GlobalDeclID InterfaceID;
3331f4a2713aSLionel Sambuc ObjCInterfaceDecl *Interface;
3332*0a6a1f1dSLionel Sambuc llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized;
3333f4a2713aSLionel Sambuc unsigned PreviousGeneration;
3334f4a2713aSLionel Sambuc ObjCCategoryDecl *Tail;
3335f4a2713aSLionel Sambuc llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap;
3336f4a2713aSLionel Sambuc
add(ObjCCategoryDecl * Cat)3337f4a2713aSLionel Sambuc void add(ObjCCategoryDecl *Cat) {
3338f4a2713aSLionel Sambuc // Only process each category once.
3339f4a2713aSLionel Sambuc if (!Deserialized.erase(Cat))
3340f4a2713aSLionel Sambuc return;
3341f4a2713aSLionel Sambuc
3342f4a2713aSLionel Sambuc // Check for duplicate categories.
3343f4a2713aSLionel Sambuc if (Cat->getDeclName()) {
3344f4a2713aSLionel Sambuc ObjCCategoryDecl *&Existing = NameCategoryMap[Cat->getDeclName()];
3345f4a2713aSLionel Sambuc if (Existing &&
3346f4a2713aSLionel Sambuc Reader.getOwningModuleFile(Existing)
3347f4a2713aSLionel Sambuc != Reader.getOwningModuleFile(Cat)) {
3348f4a2713aSLionel Sambuc // FIXME: We should not warn for duplicates in diamond:
3349f4a2713aSLionel Sambuc //
3350f4a2713aSLionel Sambuc // MT //
3351f4a2713aSLionel Sambuc // / \ //
3352f4a2713aSLionel Sambuc // ML MR //
3353f4a2713aSLionel Sambuc // \ / //
3354f4a2713aSLionel Sambuc // MB //
3355f4a2713aSLionel Sambuc //
3356f4a2713aSLionel Sambuc // If there are duplicates in ML/MR, there will be warning when
3357f4a2713aSLionel Sambuc // creating MB *and* when importing MB. We should not warn when
3358f4a2713aSLionel Sambuc // importing.
3359f4a2713aSLionel Sambuc Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def)
3360f4a2713aSLionel Sambuc << Interface->getDeclName() << Cat->getDeclName();
3361f4a2713aSLionel Sambuc Reader.Diag(Existing->getLocation(), diag::note_previous_definition);
3362f4a2713aSLionel Sambuc } else if (!Existing) {
3363f4a2713aSLionel Sambuc // Record this category.
3364f4a2713aSLionel Sambuc Existing = Cat;
3365f4a2713aSLionel Sambuc }
3366f4a2713aSLionel Sambuc }
3367f4a2713aSLionel Sambuc
3368f4a2713aSLionel Sambuc // Add this category to the end of the chain.
3369f4a2713aSLionel Sambuc if (Tail)
3370f4a2713aSLionel Sambuc ASTDeclReader::setNextObjCCategory(Tail, Cat);
3371f4a2713aSLionel Sambuc else
3372f4a2713aSLionel Sambuc Interface->setCategoryListRaw(Cat);
3373f4a2713aSLionel Sambuc Tail = Cat;
3374f4a2713aSLionel Sambuc }
3375f4a2713aSLionel Sambuc
3376f4a2713aSLionel Sambuc public:
ObjCCategoriesVisitor(ASTReader & Reader,serialization::GlobalDeclID InterfaceID,ObjCInterfaceDecl * Interface,llvm::SmallPtrSetImpl<ObjCCategoryDecl * > & Deserialized,unsigned PreviousGeneration)3377f4a2713aSLionel Sambuc ObjCCategoriesVisitor(ASTReader &Reader,
3378f4a2713aSLionel Sambuc serialization::GlobalDeclID InterfaceID,
3379f4a2713aSLionel Sambuc ObjCInterfaceDecl *Interface,
3380*0a6a1f1dSLionel Sambuc llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized,
3381f4a2713aSLionel Sambuc unsigned PreviousGeneration)
3382f4a2713aSLionel Sambuc : Reader(Reader), InterfaceID(InterfaceID), Interface(Interface),
3383f4a2713aSLionel Sambuc Deserialized(Deserialized), PreviousGeneration(PreviousGeneration),
3384*0a6a1f1dSLionel Sambuc Tail(nullptr)
3385f4a2713aSLionel Sambuc {
3386f4a2713aSLionel Sambuc // Populate the name -> category map with the set of known categories.
3387*0a6a1f1dSLionel Sambuc for (auto *Cat : Interface->known_categories()) {
3388f4a2713aSLionel Sambuc if (Cat->getDeclName())
3389*0a6a1f1dSLionel Sambuc NameCategoryMap[Cat->getDeclName()] = Cat;
3390f4a2713aSLionel Sambuc
3391f4a2713aSLionel Sambuc // Keep track of the tail of the category list.
3392*0a6a1f1dSLionel Sambuc Tail = Cat;
3393f4a2713aSLionel Sambuc }
3394f4a2713aSLionel Sambuc }
3395f4a2713aSLionel Sambuc
visit(ModuleFile & M,void * UserData)3396f4a2713aSLionel Sambuc static bool visit(ModuleFile &M, void *UserData) {
3397f4a2713aSLionel Sambuc return static_cast<ObjCCategoriesVisitor *>(UserData)->visit(M);
3398f4a2713aSLionel Sambuc }
3399f4a2713aSLionel Sambuc
visit(ModuleFile & M)3400f4a2713aSLionel Sambuc bool visit(ModuleFile &M) {
3401f4a2713aSLionel Sambuc // If we've loaded all of the category information we care about from
3402f4a2713aSLionel Sambuc // this module file, we're done.
3403f4a2713aSLionel Sambuc if (M.Generation <= PreviousGeneration)
3404f4a2713aSLionel Sambuc return true;
3405f4a2713aSLionel Sambuc
3406f4a2713aSLionel Sambuc // Map global ID of the definition down to the local ID used in this
3407f4a2713aSLionel Sambuc // module file. If there is no such mapping, we'll find nothing here
3408f4a2713aSLionel Sambuc // (or in any module it imports).
3409f4a2713aSLionel Sambuc DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID);
3410f4a2713aSLionel Sambuc if (!LocalID)
3411f4a2713aSLionel Sambuc return true;
3412f4a2713aSLionel Sambuc
3413f4a2713aSLionel Sambuc // Perform a binary search to find the local redeclarations for this
3414f4a2713aSLionel Sambuc // declaration (if any).
3415*0a6a1f1dSLionel Sambuc const ObjCCategoriesInfo Compare = { LocalID, 0 };
3416f4a2713aSLionel Sambuc const ObjCCategoriesInfo *Result
3417f4a2713aSLionel Sambuc = std::lower_bound(M.ObjCCategoriesMap,
3418f4a2713aSLionel Sambuc M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap,
3419*0a6a1f1dSLionel Sambuc Compare);
3420f4a2713aSLionel Sambuc if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap ||
3421f4a2713aSLionel Sambuc Result->DefinitionID != LocalID) {
3422f4a2713aSLionel Sambuc // We didn't find anything. If the class definition is in this module
3423f4a2713aSLionel Sambuc // file, then the module files it depends on cannot have any categories,
3424f4a2713aSLionel Sambuc // so suppress further lookup.
3425f4a2713aSLionel Sambuc return Reader.isDeclIDFromModule(InterfaceID, M);
3426f4a2713aSLionel Sambuc }
3427f4a2713aSLionel Sambuc
3428f4a2713aSLionel Sambuc // We found something. Dig out all of the categories.
3429f4a2713aSLionel Sambuc unsigned Offset = Result->Offset;
3430f4a2713aSLionel Sambuc unsigned N = M.ObjCCategories[Offset];
3431f4a2713aSLionel Sambuc M.ObjCCategories[Offset++] = 0; // Don't try to deserialize again
3432f4a2713aSLionel Sambuc for (unsigned I = 0; I != N; ++I)
3433f4a2713aSLionel Sambuc add(cast_or_null<ObjCCategoryDecl>(
3434f4a2713aSLionel Sambuc Reader.GetLocalDecl(M, M.ObjCCategories[Offset++])));
3435f4a2713aSLionel Sambuc return true;
3436f4a2713aSLionel Sambuc }
3437f4a2713aSLionel Sambuc };
3438f4a2713aSLionel Sambuc }
3439f4a2713aSLionel Sambuc
loadObjCCategories(serialization::GlobalDeclID ID,ObjCInterfaceDecl * D,unsigned PreviousGeneration)3440f4a2713aSLionel Sambuc void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID,
3441f4a2713aSLionel Sambuc ObjCInterfaceDecl *D,
3442f4a2713aSLionel Sambuc unsigned PreviousGeneration) {
3443f4a2713aSLionel Sambuc ObjCCategoriesVisitor Visitor(*this, ID, D, CategoriesDeserialized,
3444f4a2713aSLionel Sambuc PreviousGeneration);
3445f4a2713aSLionel Sambuc ModuleMgr.visit(ObjCCategoriesVisitor::visit, &Visitor);
3446f4a2713aSLionel Sambuc }
3447f4a2713aSLionel Sambuc
3448*0a6a1f1dSLionel Sambuc namespace {
3449*0a6a1f1dSLionel Sambuc /// Iterator over the redeclarations of a declaration that have already
3450*0a6a1f1dSLionel Sambuc /// been merged into the same redeclaration chain.
3451*0a6a1f1dSLionel Sambuc template<typename DeclT>
3452*0a6a1f1dSLionel Sambuc class MergedRedeclIterator {
3453*0a6a1f1dSLionel Sambuc DeclT *Start, *Canonical, *Current;
3454*0a6a1f1dSLionel Sambuc public:
MergedRedeclIterator()3455*0a6a1f1dSLionel Sambuc MergedRedeclIterator() : Current(nullptr) {}
MergedRedeclIterator(DeclT * Start)3456*0a6a1f1dSLionel Sambuc MergedRedeclIterator(DeclT *Start)
3457*0a6a1f1dSLionel Sambuc : Start(Start), Canonical(nullptr), Current(Start) {}
3458*0a6a1f1dSLionel Sambuc
operator *()3459*0a6a1f1dSLionel Sambuc DeclT *operator*() { return Current; }
3460*0a6a1f1dSLionel Sambuc
operator ++()3461*0a6a1f1dSLionel Sambuc MergedRedeclIterator &operator++() {
3462*0a6a1f1dSLionel Sambuc if (Current->isFirstDecl()) {
3463*0a6a1f1dSLionel Sambuc Canonical = Current;
3464*0a6a1f1dSLionel Sambuc Current = Current->getMostRecentDecl();
3465*0a6a1f1dSLionel Sambuc } else
3466*0a6a1f1dSLionel Sambuc Current = Current->getPreviousDecl();
3467*0a6a1f1dSLionel Sambuc
3468*0a6a1f1dSLionel Sambuc // If we started in the merged portion, we'll reach our start position
3469*0a6a1f1dSLionel Sambuc // eventually. Otherwise, we'll never reach it, but the second declaration
3470*0a6a1f1dSLionel Sambuc // we reached was the canonical declaration, so stop when we see that one
3471*0a6a1f1dSLionel Sambuc // again.
3472*0a6a1f1dSLionel Sambuc if (Current == Start || Current == Canonical)
3473*0a6a1f1dSLionel Sambuc Current = nullptr;
3474*0a6a1f1dSLionel Sambuc return *this;
3475*0a6a1f1dSLionel Sambuc }
3476*0a6a1f1dSLionel Sambuc
operator !=(const MergedRedeclIterator & A,const MergedRedeclIterator & B)3477*0a6a1f1dSLionel Sambuc friend bool operator!=(const MergedRedeclIterator &A,
3478*0a6a1f1dSLionel Sambuc const MergedRedeclIterator &B) {
3479*0a6a1f1dSLionel Sambuc return A.Current != B.Current;
3480*0a6a1f1dSLionel Sambuc }
3481*0a6a1f1dSLionel Sambuc };
3482*0a6a1f1dSLionel Sambuc }
3483*0a6a1f1dSLionel Sambuc template<typename DeclT>
merged_redecls(DeclT * D)3484*0a6a1f1dSLionel Sambuc llvm::iterator_range<MergedRedeclIterator<DeclT>> merged_redecls(DeclT *D) {
3485*0a6a1f1dSLionel Sambuc return llvm::iterator_range<MergedRedeclIterator<DeclT>>(
3486*0a6a1f1dSLionel Sambuc MergedRedeclIterator<DeclT>(D),
3487*0a6a1f1dSLionel Sambuc MergedRedeclIterator<DeclT>());
3488*0a6a1f1dSLionel Sambuc }
3489*0a6a1f1dSLionel Sambuc
3490*0a6a1f1dSLionel Sambuc template<typename DeclT, typename Fn>
forAllLaterRedecls(DeclT * D,Fn F)3491*0a6a1f1dSLionel Sambuc static void forAllLaterRedecls(DeclT *D, Fn F) {
3492*0a6a1f1dSLionel Sambuc F(D);
3493*0a6a1f1dSLionel Sambuc
3494*0a6a1f1dSLionel Sambuc // Check whether we've already merged D into its redeclaration chain.
3495*0a6a1f1dSLionel Sambuc // MostRecent may or may not be nullptr if D has not been merged. If
3496*0a6a1f1dSLionel Sambuc // not, walk the merged redecl chain and see if it's there.
3497*0a6a1f1dSLionel Sambuc auto *MostRecent = D->getMostRecentDecl();
3498*0a6a1f1dSLionel Sambuc bool Found = false;
3499*0a6a1f1dSLionel Sambuc for (auto *Redecl = MostRecent; Redecl && !Found;
3500*0a6a1f1dSLionel Sambuc Redecl = Redecl->getPreviousDecl())
3501*0a6a1f1dSLionel Sambuc Found = (Redecl == D);
3502*0a6a1f1dSLionel Sambuc
3503*0a6a1f1dSLionel Sambuc // If this declaration is merged, apply the functor to all later decls.
3504*0a6a1f1dSLionel Sambuc if (Found) {
3505*0a6a1f1dSLionel Sambuc for (auto *Redecl = MostRecent; Redecl != D;
3506*0a6a1f1dSLionel Sambuc Redecl = Redecl->getPreviousDecl())
3507*0a6a1f1dSLionel Sambuc F(Redecl);
3508*0a6a1f1dSLionel Sambuc }
3509*0a6a1f1dSLionel Sambuc }
3510*0a6a1f1dSLionel Sambuc
UpdateDecl(Decl * D,ModuleFile & ModuleFile,const RecordData & Record)3511f4a2713aSLionel Sambuc void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
3512f4a2713aSLionel Sambuc const RecordData &Record) {
3513f4a2713aSLionel Sambuc while (Idx < Record.size()) {
3514f4a2713aSLionel Sambuc switch ((DeclUpdateKind)Record[Idx++]) {
3515*0a6a1f1dSLionel Sambuc case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
3516*0a6a1f1dSLionel Sambuc // FIXME: If we also have an update record for instantiating the
3517*0a6a1f1dSLionel Sambuc // definition of D, we need that to happen before we get here.
3518*0a6a1f1dSLionel Sambuc Decl *MD = Reader.ReadDecl(ModuleFile, Record, Idx);
3519*0a6a1f1dSLionel Sambuc assert(MD && "couldn't read decl from update record");
3520*0a6a1f1dSLionel Sambuc // FIXME: We should call addHiddenDecl instead, to add the member
3521*0a6a1f1dSLionel Sambuc // to its DeclContext.
3522*0a6a1f1dSLionel Sambuc cast<CXXRecordDecl>(D)->addedMember(MD);
3523f4a2713aSLionel Sambuc break;
3524*0a6a1f1dSLionel Sambuc }
3525f4a2713aSLionel Sambuc
3526f4a2713aSLionel Sambuc case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
3527f4a2713aSLionel Sambuc // It will be added to the template's specializations set when loaded.
3528f4a2713aSLionel Sambuc (void)Reader.ReadDecl(ModuleFile, Record, Idx);
3529f4a2713aSLionel Sambuc break;
3530f4a2713aSLionel Sambuc
3531f4a2713aSLionel Sambuc case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
3532f4a2713aSLionel Sambuc NamespaceDecl *Anon
3533f4a2713aSLionel Sambuc = Reader.ReadDeclAs<NamespaceDecl>(ModuleFile, Record, Idx);
3534f4a2713aSLionel Sambuc
3535f4a2713aSLionel Sambuc // Each module has its own anonymous namespace, which is disjoint from
3536f4a2713aSLionel Sambuc // any other module's anonymous namespaces, so don't attach the anonymous
3537f4a2713aSLionel Sambuc // namespace at all.
3538*0a6a1f1dSLionel Sambuc if (ModuleFile.Kind != MK_ImplicitModule &&
3539*0a6a1f1dSLionel Sambuc ModuleFile.Kind != MK_ExplicitModule) {
3540f4a2713aSLionel Sambuc if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
3541f4a2713aSLionel Sambuc TU->setAnonymousNamespace(Anon);
3542f4a2713aSLionel Sambuc else
3543f4a2713aSLionel Sambuc cast<NamespaceDecl>(D)->setAnonymousNamespace(Anon);
3544f4a2713aSLionel Sambuc }
3545f4a2713aSLionel Sambuc break;
3546f4a2713aSLionel Sambuc }
3547f4a2713aSLionel Sambuc
3548f4a2713aSLionel Sambuc case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
3549f4a2713aSLionel Sambuc cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation(
3550f4a2713aSLionel Sambuc Reader.ReadSourceLocation(ModuleFile, Record, Idx));
3551f4a2713aSLionel Sambuc break;
3552f4a2713aSLionel Sambuc
3553*0a6a1f1dSLionel Sambuc case UPD_CXX_ADDED_FUNCTION_DEFINITION: {
3554f4a2713aSLionel Sambuc FunctionDecl *FD = cast<FunctionDecl>(D);
3555*0a6a1f1dSLionel Sambuc if (Reader.PendingBodies[FD]) {
3556*0a6a1f1dSLionel Sambuc // FIXME: Maybe check for ODR violations.
3557*0a6a1f1dSLionel Sambuc // It's safe to stop now because this update record is always last.
3558*0a6a1f1dSLionel Sambuc return;
3559*0a6a1f1dSLionel Sambuc }
3560*0a6a1f1dSLionel Sambuc
3561*0a6a1f1dSLionel Sambuc if (Record[Idx++]) {
3562*0a6a1f1dSLionel Sambuc // Maintain AST consistency: any later redeclarations of this function
3563*0a6a1f1dSLionel Sambuc // are inline if this one is. (We might have merged another declaration
3564*0a6a1f1dSLionel Sambuc // into this one.)
3565*0a6a1f1dSLionel Sambuc forAllLaterRedecls(FD, [](FunctionDecl *FD) {
3566*0a6a1f1dSLionel Sambuc FD->setImplicitlyInline();
3567*0a6a1f1dSLionel Sambuc });
3568*0a6a1f1dSLionel Sambuc }
3569*0a6a1f1dSLionel Sambuc FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
3570*0a6a1f1dSLionel Sambuc if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
3571*0a6a1f1dSLionel Sambuc std::tie(CD->CtorInitializers, CD->NumCtorInitializers) =
3572*0a6a1f1dSLionel Sambuc Reader.ReadCXXCtorInitializers(ModuleFile, Record, Idx);
3573*0a6a1f1dSLionel Sambuc if (auto *DD = dyn_cast<CXXDestructorDecl>(FD))
3574*0a6a1f1dSLionel Sambuc // FIXME: Check consistency.
3575*0a6a1f1dSLionel Sambuc DD->setOperatorDelete(Reader.ReadDeclAs<FunctionDecl>(ModuleFile,
3576*0a6a1f1dSLionel Sambuc Record, Idx));
3577*0a6a1f1dSLionel Sambuc // Store the offset of the body so we can lazily load it later.
3578*0a6a1f1dSLionel Sambuc Reader.PendingBodies[FD] = GetCurrentCursorOffset();
3579*0a6a1f1dSLionel Sambuc HasPendingBody = true;
3580*0a6a1f1dSLionel Sambuc assert(Idx == Record.size() && "lazy body must be last");
3581*0a6a1f1dSLionel Sambuc break;
3582*0a6a1f1dSLionel Sambuc }
3583*0a6a1f1dSLionel Sambuc
3584*0a6a1f1dSLionel Sambuc case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
3585*0a6a1f1dSLionel Sambuc auto *RD = cast<CXXRecordDecl>(D);
3586*0a6a1f1dSLionel Sambuc bool HadDefinition = RD->getDefinition();
3587*0a6a1f1dSLionel Sambuc ReadCXXRecordDefinition(RD);
3588*0a6a1f1dSLionel Sambuc // Visible update is handled separately.
3589*0a6a1f1dSLionel Sambuc uint64_t LexicalOffset = Record[Idx++];
3590*0a6a1f1dSLionel Sambuc if (!HadDefinition && LexicalOffset) {
3591*0a6a1f1dSLionel Sambuc RD->setHasExternalLexicalStorage(true);
3592*0a6a1f1dSLionel Sambuc Reader.ReadDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor,
3593*0a6a1f1dSLionel Sambuc std::make_pair(LexicalOffset, 0),
3594*0a6a1f1dSLionel Sambuc ModuleFile.DeclContextInfos[RD]);
3595*0a6a1f1dSLionel Sambuc Reader.PendingDefinitions.insert(RD);
3596*0a6a1f1dSLionel Sambuc }
3597*0a6a1f1dSLionel Sambuc
3598*0a6a1f1dSLionel Sambuc auto TSK = (TemplateSpecializationKind)Record[Idx++];
3599*0a6a1f1dSLionel Sambuc SourceLocation POI = Reader.ReadSourceLocation(ModuleFile, Record, Idx);
3600*0a6a1f1dSLionel Sambuc if (MemberSpecializationInfo *MSInfo =
3601*0a6a1f1dSLionel Sambuc RD->getMemberSpecializationInfo()) {
3602*0a6a1f1dSLionel Sambuc MSInfo->setTemplateSpecializationKind(TSK);
3603*0a6a1f1dSLionel Sambuc MSInfo->setPointOfInstantiation(POI);
3604*0a6a1f1dSLionel Sambuc } else {
3605*0a6a1f1dSLionel Sambuc ClassTemplateSpecializationDecl *Spec =
3606*0a6a1f1dSLionel Sambuc cast<ClassTemplateSpecializationDecl>(RD);
3607*0a6a1f1dSLionel Sambuc Spec->setTemplateSpecializationKind(TSK);
3608*0a6a1f1dSLionel Sambuc Spec->setPointOfInstantiation(POI);
3609*0a6a1f1dSLionel Sambuc
3610*0a6a1f1dSLionel Sambuc if (Record[Idx++]) {
3611*0a6a1f1dSLionel Sambuc auto PartialSpec =
3612*0a6a1f1dSLionel Sambuc ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx);
3613*0a6a1f1dSLionel Sambuc SmallVector<TemplateArgument, 8> TemplArgs;
3614*0a6a1f1dSLionel Sambuc Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
3615*0a6a1f1dSLionel Sambuc auto *TemplArgList = TemplateArgumentList::CreateCopy(
3616*0a6a1f1dSLionel Sambuc Reader.getContext(), TemplArgs.data(), TemplArgs.size());
3617*0a6a1f1dSLionel Sambuc
3618*0a6a1f1dSLionel Sambuc // FIXME: If we already have a partial specialization set,
3619*0a6a1f1dSLionel Sambuc // check that it matches.
3620*0a6a1f1dSLionel Sambuc if (!Spec->getSpecializedTemplateOrPartial()
3621*0a6a1f1dSLionel Sambuc .is<ClassTemplatePartialSpecializationDecl *>())
3622*0a6a1f1dSLionel Sambuc Spec->setInstantiationOf(PartialSpec, TemplArgList);
3623*0a6a1f1dSLionel Sambuc }
3624*0a6a1f1dSLionel Sambuc }
3625*0a6a1f1dSLionel Sambuc
3626*0a6a1f1dSLionel Sambuc RD->setTagKind((TagTypeKind)Record[Idx++]);
3627*0a6a1f1dSLionel Sambuc RD->setLocation(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
3628*0a6a1f1dSLionel Sambuc RD->setLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
3629*0a6a1f1dSLionel Sambuc RD->setRBraceLoc(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
3630*0a6a1f1dSLionel Sambuc
3631*0a6a1f1dSLionel Sambuc if (Record[Idx++]) {
3632*0a6a1f1dSLionel Sambuc AttrVec Attrs;
3633*0a6a1f1dSLionel Sambuc Reader.ReadAttributes(F, Attrs, Record, Idx);
3634*0a6a1f1dSLionel Sambuc D->setAttrsImpl(Attrs, Reader.getContext());
3635*0a6a1f1dSLionel Sambuc }
3636*0a6a1f1dSLionel Sambuc break;
3637*0a6a1f1dSLionel Sambuc }
3638*0a6a1f1dSLionel Sambuc
3639*0a6a1f1dSLionel Sambuc case UPD_CXX_RESOLVED_EXCEPTION_SPEC: {
3640*0a6a1f1dSLionel Sambuc // FIXME: This doesn't send the right notifications if there are
3641*0a6a1f1dSLionel Sambuc // ASTMutationListeners other than an ASTWriter.
3642*0a6a1f1dSLionel Sambuc FunctionProtoType::ExceptionSpecInfo ESI;
3643*0a6a1f1dSLionel Sambuc SmallVector<QualType, 8> ExceptionStorage;
3644*0a6a1f1dSLionel Sambuc Reader.readExceptionSpec(ModuleFile, ExceptionStorage, ESI, Record, Idx);
3645*0a6a1f1dSLionel Sambuc for (auto *Redecl : merged_redecls(D)) {
3646*0a6a1f1dSLionel Sambuc auto *FD = cast<FunctionDecl>(Redecl);
3647*0a6a1f1dSLionel Sambuc auto *FPT = FD->getType()->castAs<FunctionProtoType>();
3648*0a6a1f1dSLionel Sambuc if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
3649*0a6a1f1dSLionel Sambuc // AST invariant: if any exception spec in the redecl chain is
3650*0a6a1f1dSLionel Sambuc // resolved, all are resolved. We don't need to go any further.
3651*0a6a1f1dSLionel Sambuc // FIXME: If the exception spec is resolved, check that it matches.
3652*0a6a1f1dSLionel Sambuc break;
3653*0a6a1f1dSLionel Sambuc }
3654*0a6a1f1dSLionel Sambuc FD->setType(Reader.Context.getFunctionType(
3655*0a6a1f1dSLionel Sambuc FPT->getReturnType(), FPT->getParamTypes(),
3656*0a6a1f1dSLionel Sambuc FPT->getExtProtoInfo().withExceptionSpec(ESI)));
3657*0a6a1f1dSLionel Sambuc }
3658*0a6a1f1dSLionel Sambuc break;
3659*0a6a1f1dSLionel Sambuc }
3660*0a6a1f1dSLionel Sambuc
3661*0a6a1f1dSLionel Sambuc case UPD_CXX_DEDUCED_RETURN_TYPE: {
3662*0a6a1f1dSLionel Sambuc // FIXME: Also do this when merging redecls.
3663*0a6a1f1dSLionel Sambuc QualType DeducedResultType = Reader.readType(ModuleFile, Record, Idx);
3664*0a6a1f1dSLionel Sambuc for (auto *Redecl : merged_redecls(D)) {
3665*0a6a1f1dSLionel Sambuc // FIXME: If the return type is already deduced, check that it matches.
3666*0a6a1f1dSLionel Sambuc FunctionDecl *FD = cast<FunctionDecl>(Redecl);
3667*0a6a1f1dSLionel Sambuc Reader.Context.adjustDeducedFunctionResultType(FD, DeducedResultType);
3668*0a6a1f1dSLionel Sambuc }
3669f4a2713aSLionel Sambuc break;
3670f4a2713aSLionel Sambuc }
3671f4a2713aSLionel Sambuc
3672f4a2713aSLionel Sambuc case UPD_DECL_MARKED_USED: {
3673f4a2713aSLionel Sambuc // FIXME: This doesn't send the right notifications if there are
3674f4a2713aSLionel Sambuc // ASTMutationListeners other than an ASTWriter.
3675*0a6a1f1dSLionel Sambuc
3676*0a6a1f1dSLionel Sambuc // Maintain AST consistency: any later redeclarations are used too.
3677*0a6a1f1dSLionel Sambuc forAllLaterRedecls(D, [](Decl *D) { D->Used = true; });
3678f4a2713aSLionel Sambuc break;
3679f4a2713aSLionel Sambuc }
3680*0a6a1f1dSLionel Sambuc
3681*0a6a1f1dSLionel Sambuc case UPD_MANGLING_NUMBER:
3682*0a6a1f1dSLionel Sambuc Reader.Context.setManglingNumber(cast<NamedDecl>(D), Record[Idx++]);
3683*0a6a1f1dSLionel Sambuc break;
3684*0a6a1f1dSLionel Sambuc
3685*0a6a1f1dSLionel Sambuc case UPD_STATIC_LOCAL_NUMBER:
3686*0a6a1f1dSLionel Sambuc Reader.Context.setStaticLocalNumber(cast<VarDecl>(D), Record[Idx++]);
3687*0a6a1f1dSLionel Sambuc break;
3688*0a6a1f1dSLionel Sambuc case UPD_DECL_MARKED_OPENMP_THREADPRIVATE:
3689*0a6a1f1dSLionel Sambuc D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3690*0a6a1f1dSLionel Sambuc Reader.Context, ReadSourceRange(Record, Idx)));
3691*0a6a1f1dSLionel Sambuc break;
3692f4a2713aSLionel Sambuc }
3693f4a2713aSLionel Sambuc }
3694f4a2713aSLionel Sambuc }
3695