|  | //===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file implements the ASTReader::ReadDeclRecord method, which is the | 
|  | // entrypoint for loading a decl. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "ASTCommon.h" | 
|  | #include "ASTReaderInternals.h" | 
|  | #include "clang/AST/ASTContext.h" | 
|  | #include "clang/AST/Attr.h" | 
|  | #include "clang/AST/AttrIterator.h" | 
|  | #include "clang/AST/Decl.h" | 
|  | #include "clang/AST/DeclBase.h" | 
|  | #include "clang/AST/DeclCXX.h" | 
|  | #include "clang/AST/DeclFriend.h" | 
|  | #include "clang/AST/DeclObjC.h" | 
|  | #include "clang/AST/DeclOpenMP.h" | 
|  | #include "clang/AST/DeclTemplate.h" | 
|  | #include "clang/AST/DeclVisitor.h" | 
|  | #include "clang/AST/DeclarationName.h" | 
|  | #include "clang/AST/Expr.h" | 
|  | #include "clang/AST/ExternalASTSource.h" | 
|  | #include "clang/AST/LambdaCapture.h" | 
|  | #include "clang/AST/NestedNameSpecifier.h" | 
|  | #include "clang/AST/OpenMPClause.h" | 
|  | #include "clang/AST/Redeclarable.h" | 
|  | #include "clang/AST/Stmt.h" | 
|  | #include "clang/AST/TemplateBase.h" | 
|  | #include "clang/AST/Type.h" | 
|  | #include "clang/AST/UnresolvedSet.h" | 
|  | #include "clang/Basic/AttrKinds.h" | 
|  | #include "clang/Basic/ExceptionSpecificationType.h" | 
|  | #include "clang/Basic/IdentifierTable.h" | 
|  | #include "clang/Basic/LLVM.h" | 
|  | #include "clang/Basic/Lambda.h" | 
|  | #include "clang/Basic/LangOptions.h" | 
|  | #include "clang/Basic/Linkage.h" | 
|  | #include "clang/Basic/Module.h" | 
|  | #include "clang/Basic/PragmaKinds.h" | 
|  | #include "clang/Basic/SourceLocation.h" | 
|  | #include "clang/Basic/Specifiers.h" | 
|  | #include "clang/Sema/IdentifierResolver.h" | 
|  | #include "clang/Serialization/ASTBitCodes.h" | 
|  | #include "clang/Serialization/ASTReader.h" | 
|  | #include "clang/Serialization/ContinuousRangeMap.h" | 
|  | #include "clang/Serialization/ModuleFile.h" | 
|  | #include "llvm/ADT/DenseMap.h" | 
|  | #include "llvm/ADT/FoldingSet.h" | 
|  | #include "llvm/ADT/STLExtras.h" | 
|  | #include "llvm/ADT/SmallPtrSet.h" | 
|  | #include "llvm/ADT/SmallVector.h" | 
|  | #include "llvm/ADT/iterator_range.h" | 
|  | #include "llvm/Bitstream/BitstreamReader.h" | 
|  | #include "llvm/Support/Casting.h" | 
|  | #include "llvm/Support/ErrorHandling.h" | 
|  | #include "llvm/Support/SaveAndRestore.h" | 
|  | #include <algorithm> | 
|  | #include <cassert> | 
|  | #include <cstdint> | 
|  | #include <cstring> | 
|  | #include <string> | 
|  | #include <utility> | 
|  |  | 
|  | using namespace clang; | 
|  | using namespace serialization; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Declaration deserialization | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | namespace clang { | 
|  |  | 
|  | class ASTDeclReader : public DeclVisitor<ASTDeclReader, void> { | 
|  | ASTReader &Reader; | 
|  | ASTRecordReader &Record; | 
|  | ASTReader::RecordLocation Loc; | 
|  | const DeclID ThisDeclID; | 
|  | const SourceLocation ThisDeclLoc; | 
|  |  | 
|  | using RecordData = ASTReader::RecordData; | 
|  |  | 
|  | TypeID DeferredTypeID = 0; | 
|  | unsigned AnonymousDeclNumber; | 
|  | GlobalDeclID NamedDeclForTagDecl = 0; | 
|  | IdentifierInfo *TypedefNameForLinkage = nullptr; | 
|  |  | 
|  | bool HasPendingBody = false; | 
|  |  | 
|  | ///A flag to carry the information for a decl from the entity is | 
|  | /// used. We use it to delay the marking of the canonical decl as used until | 
|  | /// the entire declaration is deserialized and merged. | 
|  | bool IsDeclMarkedUsed = false; | 
|  |  | 
|  | uint64_t GetCurrentCursorOffset(); | 
|  |  | 
|  | uint64_t ReadLocalOffset() { | 
|  | uint64_t LocalOffset = Record.readInt(); | 
|  | assert(LocalOffset < Loc.Offset && "offset point after current record"); | 
|  | return LocalOffset ? Loc.Offset - LocalOffset : 0; | 
|  | } | 
|  |  | 
|  | uint64_t ReadGlobalOffset() { | 
|  | uint64_t Local = ReadLocalOffset(); | 
|  | return Local ? Record.getGlobalBitOffset(Local) : 0; | 
|  | } | 
|  |  | 
|  | SourceLocation ReadSourceLocation() { | 
|  | return Record.readSourceLocation(); | 
|  | } | 
|  |  | 
|  | SourceRange ReadSourceRange() { | 
|  | return Record.readSourceRange(); | 
|  | } | 
|  |  | 
|  | TypeSourceInfo *GetTypeSourceInfo() { | 
|  | return Record.getTypeSourceInfo(); | 
|  | } | 
|  |  | 
|  | serialization::DeclID ReadDeclID() { | 
|  | return Record.readDeclID(); | 
|  | } | 
|  |  | 
|  | std::string ReadString() { | 
|  | return Record.readString(); | 
|  | } | 
|  |  | 
|  | void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) { | 
|  | for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I) | 
|  | IDs.push_back(ReadDeclID()); | 
|  | } | 
|  |  | 
|  | Decl *ReadDecl() { | 
|  | return Record.readDecl(); | 
|  | } | 
|  |  | 
|  | template<typename T> | 
|  | T *ReadDeclAs() { | 
|  | return Record.readDeclAs<T>(); | 
|  | } | 
|  |  | 
|  | void ReadQualifierInfo(QualifierInfo &Info) { | 
|  | Record.readQualifierInfo(Info); | 
|  | } | 
|  |  | 
|  | void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name) { | 
|  | Record.readDeclarationNameLoc(DNLoc, Name); | 
|  | } | 
|  |  | 
|  | serialization::SubmoduleID readSubmoduleID() { | 
|  | if (Record.getIdx() == Record.size()) | 
|  | return 0; | 
|  |  | 
|  | return Record.getGlobalSubmoduleID(Record.readInt()); | 
|  | } | 
|  |  | 
|  | Module *readModule() { | 
|  | return Record.getSubmodule(readSubmoduleID()); | 
|  | } | 
|  |  | 
|  | void ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update); | 
|  | void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data, | 
|  | const CXXRecordDecl *D); | 
|  | void MergeDefinitionData(CXXRecordDecl *D, | 
|  | struct CXXRecordDecl::DefinitionData &&NewDD); | 
|  | void ReadObjCDefinitionData(struct ObjCInterfaceDecl::DefinitionData &Data); | 
|  | void MergeDefinitionData(ObjCInterfaceDecl *D, | 
|  | struct ObjCInterfaceDecl::DefinitionData &&NewDD); | 
|  | void ReadObjCDefinitionData(struct ObjCProtocolDecl::DefinitionData &Data); | 
|  | void MergeDefinitionData(ObjCProtocolDecl *D, | 
|  | struct ObjCProtocolDecl::DefinitionData &&NewDD); | 
|  |  | 
|  | static DeclContext *getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC); | 
|  |  | 
|  | static NamedDecl *getAnonymousDeclForMerging(ASTReader &Reader, | 
|  | DeclContext *DC, | 
|  | unsigned Index); | 
|  | static void setAnonymousDeclForMerging(ASTReader &Reader, DeclContext *DC, | 
|  | unsigned Index, NamedDecl *D); | 
|  |  | 
|  | /// Results from loading a RedeclarableDecl. | 
|  | class RedeclarableResult { | 
|  | Decl *MergeWith; | 
|  | GlobalDeclID FirstID; | 
|  | bool IsKeyDecl; | 
|  |  | 
|  | public: | 
|  | RedeclarableResult(Decl *MergeWith, GlobalDeclID FirstID, bool IsKeyDecl) | 
|  | : MergeWith(MergeWith), FirstID(FirstID), IsKeyDecl(IsKeyDecl) {} | 
|  |  | 
|  | /// Retrieve the first ID. | 
|  | GlobalDeclID getFirstID() const { return FirstID; } | 
|  |  | 
|  | /// Is this declaration a key declaration? | 
|  | bool isKeyDecl() const { return IsKeyDecl; } | 
|  |  | 
|  | /// Get a known declaration that this should be merged with, if | 
|  | /// any. | 
|  | Decl *getKnownMergeTarget() const { return MergeWith; } | 
|  | }; | 
|  |  | 
|  | /// Class used to capture the result of searching for an existing | 
|  | /// declaration of a specific kind and name, along with the ability | 
|  | /// to update the place where this result was found (the declaration | 
|  | /// chain hanging off an identifier or the DeclContext we searched in) | 
|  | /// if requested. | 
|  | class FindExistingResult { | 
|  | ASTReader &Reader; | 
|  | NamedDecl *New = nullptr; | 
|  | NamedDecl *Existing = nullptr; | 
|  | bool AddResult = false; | 
|  | unsigned AnonymousDeclNumber = 0; | 
|  | IdentifierInfo *TypedefNameForLinkage = nullptr; | 
|  |  | 
|  | public: | 
|  | FindExistingResult(ASTReader &Reader) : Reader(Reader) {} | 
|  |  | 
|  | FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing, | 
|  | unsigned AnonymousDeclNumber, | 
|  | IdentifierInfo *TypedefNameForLinkage) | 
|  | : Reader(Reader), New(New), Existing(Existing), AddResult(true), | 
|  | AnonymousDeclNumber(AnonymousDeclNumber), | 
|  | TypedefNameForLinkage(TypedefNameForLinkage) {} | 
|  |  | 
|  | FindExistingResult(FindExistingResult &&Other) | 
|  | : Reader(Other.Reader), New(Other.New), Existing(Other.Existing), | 
|  | AddResult(Other.AddResult), | 
|  | AnonymousDeclNumber(Other.AnonymousDeclNumber), | 
|  | TypedefNameForLinkage(Other.TypedefNameForLinkage) { | 
|  | Other.AddResult = false; | 
|  | } | 
|  |  | 
|  | FindExistingResult &operator=(FindExistingResult &&) = delete; | 
|  | ~FindExistingResult(); | 
|  |  | 
|  | /// Suppress the addition of this result into the known set of | 
|  | /// names. | 
|  | void suppress() { AddResult = false; } | 
|  |  | 
|  | operator NamedDecl*() const { return Existing; } | 
|  |  | 
|  | template<typename T> | 
|  | operator T*() const { return dyn_cast_or_null<T>(Existing); } | 
|  | }; | 
|  |  | 
|  | static DeclContext *getPrimaryContextForMerging(ASTReader &Reader, | 
|  | DeclContext *DC); | 
|  | FindExistingResult findExisting(NamedDecl *D); | 
|  |  | 
|  | public: | 
|  | ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record, | 
|  | ASTReader::RecordLocation Loc, | 
|  | DeclID thisDeclID, SourceLocation ThisDeclLoc) | 
|  | : Reader(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID), | 
|  | ThisDeclLoc(ThisDeclLoc) {} | 
|  |  | 
|  | template <typename T> static | 
|  | void AddLazySpecializations(T *D, | 
|  | SmallVectorImpl<serialization::DeclID>& IDs) { | 
|  | if (IDs.empty()) | 
|  | return; | 
|  |  | 
|  | // FIXME: We should avoid this pattern of getting the ASTContext. | 
|  | ASTContext &C = D->getASTContext(); | 
|  |  | 
|  | auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations; | 
|  |  | 
|  | if (auto &Old = LazySpecializations) { | 
|  | IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]); | 
|  | llvm::sort(IDs); | 
|  | IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); | 
|  | } | 
|  |  | 
|  | auto *Result = new (C) serialization::DeclID[1 + IDs.size()]; | 
|  | *Result = IDs.size(); | 
|  | std::copy(IDs.begin(), IDs.end(), Result + 1); | 
|  |  | 
|  | LazySpecializations = Result; | 
|  | } | 
|  |  | 
|  | template <typename DeclT> | 
|  | static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D); | 
|  | static Decl *getMostRecentDeclImpl(...); | 
|  | static Decl *getMostRecentDecl(Decl *D); | 
|  |  | 
|  | template <typename DeclT> | 
|  | static void attachPreviousDeclImpl(ASTReader &Reader, | 
|  | Redeclarable<DeclT> *D, Decl *Previous, | 
|  | Decl *Canon); | 
|  | static void attachPreviousDeclImpl(ASTReader &Reader, ...); | 
|  | static void attachPreviousDecl(ASTReader &Reader, Decl *D, Decl *Previous, | 
|  | Decl *Canon); | 
|  |  | 
|  | template <typename DeclT> | 
|  | static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest); | 
|  | static void attachLatestDeclImpl(...); | 
|  | static void attachLatestDecl(Decl *D, Decl *latest); | 
|  |  | 
|  | template <typename DeclT> | 
|  | static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D); | 
|  | static void markIncompleteDeclChainImpl(...); | 
|  |  | 
|  | /// Determine whether this declaration has a pending body. | 
|  | bool hasPendingBody() const { return HasPendingBody; } | 
|  |  | 
|  | void ReadFunctionDefinition(FunctionDecl *FD); | 
|  | void Visit(Decl *D); | 
|  |  | 
|  | void UpdateDecl(Decl *D, SmallVectorImpl<serialization::DeclID> &); | 
|  |  | 
|  | static void setNextObjCCategory(ObjCCategoryDecl *Cat, | 
|  | ObjCCategoryDecl *Next) { | 
|  | Cat->NextClassCategory = Next; | 
|  | } | 
|  |  | 
|  | void VisitDecl(Decl *D); | 
|  | void VisitPragmaCommentDecl(PragmaCommentDecl *D); | 
|  | void VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D); | 
|  | void VisitTranslationUnitDecl(TranslationUnitDecl *TU); | 
|  | void VisitNamedDecl(NamedDecl *ND); | 
|  | void VisitLabelDecl(LabelDecl *LD); | 
|  | void VisitNamespaceDecl(NamespaceDecl *D); | 
|  | void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); | 
|  | void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); | 
|  | void VisitTypeDecl(TypeDecl *TD); | 
|  | RedeclarableResult VisitTypedefNameDecl(TypedefNameDecl *TD); | 
|  | void VisitTypedefDecl(TypedefDecl *TD); | 
|  | void VisitTypeAliasDecl(TypeAliasDecl *TD); | 
|  | void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); | 
|  | RedeclarableResult VisitTagDecl(TagDecl *TD); | 
|  | void VisitEnumDecl(EnumDecl *ED); | 
|  | RedeclarableResult VisitRecordDeclImpl(RecordDecl *RD); | 
|  | void VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); } | 
|  | RedeclarableResult VisitCXXRecordDeclImpl(CXXRecordDecl *D); | 
|  | void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); } | 
|  | RedeclarableResult VisitClassTemplateSpecializationDeclImpl( | 
|  | ClassTemplateSpecializationDecl *D); | 
|  |  | 
|  | void VisitClassTemplateSpecializationDecl( | 
|  | ClassTemplateSpecializationDecl *D) { | 
|  | VisitClassTemplateSpecializationDeclImpl(D); | 
|  | } | 
|  |  | 
|  | void VisitClassTemplatePartialSpecializationDecl( | 
|  | ClassTemplatePartialSpecializationDecl *D); | 
|  | void VisitClassScopeFunctionSpecializationDecl( | 
|  | ClassScopeFunctionSpecializationDecl *D); | 
|  | RedeclarableResult | 
|  | VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl *D); | 
|  |  | 
|  | void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) { | 
|  | VisitVarTemplateSpecializationDeclImpl(D); | 
|  | } | 
|  |  | 
|  | void VisitVarTemplatePartialSpecializationDecl( | 
|  | VarTemplatePartialSpecializationDecl *D); | 
|  | void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); | 
|  | void VisitValueDecl(ValueDecl *VD); | 
|  | void VisitEnumConstantDecl(EnumConstantDecl *ECD); | 
|  | void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); | 
|  | void VisitDeclaratorDecl(DeclaratorDecl *DD); | 
|  | void VisitFunctionDecl(FunctionDecl *FD); | 
|  | void VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *GD); | 
|  | void VisitCXXMethodDecl(CXXMethodDecl *D); | 
|  | void VisitCXXConstructorDecl(CXXConstructorDecl *D); | 
|  | void VisitCXXDestructorDecl(CXXDestructorDecl *D); | 
|  | void VisitCXXConversionDecl(CXXConversionDecl *D); | 
|  | void VisitFieldDecl(FieldDecl *FD); | 
|  | void VisitMSPropertyDecl(MSPropertyDecl *FD); | 
|  | void VisitIndirectFieldDecl(IndirectFieldDecl *FD); | 
|  | RedeclarableResult VisitVarDeclImpl(VarDecl *D); | 
|  | void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); } | 
|  | void VisitImplicitParamDecl(ImplicitParamDecl *PD); | 
|  | void VisitParmVarDecl(ParmVarDecl *PD); | 
|  | void VisitDecompositionDecl(DecompositionDecl *DD); | 
|  | void VisitBindingDecl(BindingDecl *BD); | 
|  | void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); | 
|  | DeclID VisitTemplateDecl(TemplateDecl *D); | 
|  | void VisitConceptDecl(ConceptDecl *D); | 
|  | RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); | 
|  | void VisitClassTemplateDecl(ClassTemplateDecl *D); | 
|  | void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D); | 
|  | void VisitVarTemplateDecl(VarTemplateDecl *D); | 
|  | void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); | 
|  | void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); | 
|  | void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); | 
|  | void VisitUsingDecl(UsingDecl *D); | 
|  | void VisitUsingPackDecl(UsingPackDecl *D); | 
|  | void VisitUsingShadowDecl(UsingShadowDecl *D); | 
|  | void VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl *D); | 
|  | void VisitLinkageSpecDecl(LinkageSpecDecl *D); | 
|  | void VisitExportDecl(ExportDecl *D); | 
|  | void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD); | 
|  | void VisitImportDecl(ImportDecl *D); | 
|  | void VisitAccessSpecDecl(AccessSpecDecl *D); | 
|  | void VisitFriendDecl(FriendDecl *D); | 
|  | void VisitFriendTemplateDecl(FriendTemplateDecl *D); | 
|  | void VisitStaticAssertDecl(StaticAssertDecl *D); | 
|  | void VisitBlockDecl(BlockDecl *BD); | 
|  | void VisitCapturedDecl(CapturedDecl *CD); | 
|  | void VisitEmptyDecl(EmptyDecl *D); | 
|  | void VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D); | 
|  |  | 
|  | std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC); | 
|  |  | 
|  | template<typename T> | 
|  | RedeclarableResult VisitRedeclarable(Redeclarable<T> *D); | 
|  |  | 
|  | template<typename T> | 
|  | void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl, | 
|  | DeclID TemplatePatternID = 0); | 
|  |  | 
|  | template<typename T> | 
|  | void mergeRedeclarable(Redeclarable<T> *D, T *Existing, | 
|  | RedeclarableResult &Redecl, | 
|  | DeclID TemplatePatternID = 0); | 
|  |  | 
|  | template<typename T> | 
|  | void mergeMergeable(Mergeable<T> *D); | 
|  |  | 
|  | void mergeMergeable(LifetimeExtendedTemporaryDecl *D); | 
|  |  | 
|  | void mergeTemplatePattern(RedeclarableTemplateDecl *D, | 
|  | RedeclarableTemplateDecl *Existing, | 
|  | DeclID DsID, bool IsKeyDecl); | 
|  |  | 
|  | ObjCTypeParamList *ReadObjCTypeParamList(); | 
|  |  | 
|  | // FIXME: Reorder according to DeclNodes.td? | 
|  | void VisitObjCMethodDecl(ObjCMethodDecl *D); | 
|  | void VisitObjCTypeParamDecl(ObjCTypeParamDecl *D); | 
|  | void VisitObjCContainerDecl(ObjCContainerDecl *D); | 
|  | void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); | 
|  | void VisitObjCIvarDecl(ObjCIvarDecl *D); | 
|  | void VisitObjCProtocolDecl(ObjCProtocolDecl *D); | 
|  | void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D); | 
|  | void VisitObjCCategoryDecl(ObjCCategoryDecl *D); | 
|  | void VisitObjCImplDecl(ObjCImplDecl *D); | 
|  | void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); | 
|  | void VisitObjCImplementationDecl(ObjCImplementationDecl *D); | 
|  | void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D); | 
|  | void VisitObjCPropertyDecl(ObjCPropertyDecl *D); | 
|  | void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); | 
|  | void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); | 
|  | void VisitOMPAllocateDecl(OMPAllocateDecl *D); | 
|  | void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); | 
|  | void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); | 
|  | void VisitOMPRequiresDecl(OMPRequiresDecl *D); | 
|  | void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); | 
|  | }; | 
|  |  | 
|  | } // namespace clang | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | /// Iterator over the redeclarations of a declaration that have already | 
|  | /// been merged into the same redeclaration chain. | 
|  | template<typename DeclT> | 
|  | class MergedRedeclIterator { | 
|  | DeclT *Start; | 
|  | DeclT *Canonical = nullptr; | 
|  | DeclT *Current = nullptr; | 
|  |  | 
|  | public: | 
|  | MergedRedeclIterator() = default; | 
|  | MergedRedeclIterator(DeclT *Start) : Start(Start), Current(Start) {} | 
|  |  | 
|  | DeclT *operator*() { return Current; } | 
|  |  | 
|  | MergedRedeclIterator &operator++() { | 
|  | if (Current->isFirstDecl()) { | 
|  | Canonical = Current; | 
|  | Current = Current->getMostRecentDecl(); | 
|  | } else | 
|  | Current = Current->getPreviousDecl(); | 
|  |  | 
|  | // If we started in the merged portion, we'll reach our start position | 
|  | // eventually. Otherwise, we'll never reach it, but the second declaration | 
|  | // we reached was the canonical declaration, so stop when we see that one | 
|  | // again. | 
|  | if (Current == Start || Current == Canonical) | 
|  | Current = nullptr; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | friend bool operator!=(const MergedRedeclIterator &A, | 
|  | const MergedRedeclIterator &B) { | 
|  | return A.Current != B.Current; | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // namespace | 
|  |  | 
|  | template <typename DeclT> | 
|  | static llvm::iterator_range<MergedRedeclIterator<DeclT>> | 
|  | merged_redecls(DeclT *D) { | 
|  | return llvm::make_range(MergedRedeclIterator<DeclT>(D), | 
|  | MergedRedeclIterator<DeclT>()); | 
|  | } | 
|  |  | 
|  | uint64_t ASTDeclReader::GetCurrentCursorOffset() { | 
|  | return Loc.F->DeclsCursor.GetCurrentBitNo() + Loc.F->GlobalBitOffset; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) { | 
|  | if (Record.readInt()) | 
|  | Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile; | 
|  | if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) { | 
|  | CD->setNumCtorInitializers(Record.readInt()); | 
|  | if (CD->getNumCtorInitializers()) | 
|  | CD->CtorInitializers = ReadGlobalOffset(); | 
|  | } | 
|  | // Store the offset of the body so we can lazily load it later. | 
|  | Reader.PendingBodies[FD] = GetCurrentCursorOffset(); | 
|  | HasPendingBody = true; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::Visit(Decl *D) { | 
|  | DeclVisitor<ASTDeclReader, void>::Visit(D); | 
|  |  | 
|  | // At this point we have deserialized and merged the decl and it is safe to | 
|  | // update its canonical decl to signal that the entire entity is used. | 
|  | D->getCanonicalDecl()->Used |= IsDeclMarkedUsed; | 
|  | IsDeclMarkedUsed = false; | 
|  |  | 
|  | if (auto *DD = dyn_cast<DeclaratorDecl>(D)) { | 
|  | if (auto *TInfo = DD->getTypeSourceInfo()) | 
|  | Record.readTypeLoc(TInfo->getTypeLoc()); | 
|  | } | 
|  |  | 
|  | if (auto *TD = dyn_cast<TypeDecl>(D)) { | 
|  | // We have a fully initialized TypeDecl. Read its type now. | 
|  | TD->setTypeForDecl(Reader.GetType(DeferredTypeID).getTypePtrOrNull()); | 
|  |  | 
|  | // If this is a tag declaration with a typedef name for linkage, it's safe | 
|  | // to load that typedef now. | 
|  | if (NamedDeclForTagDecl) | 
|  | cast<TagDecl>(D)->TypedefNameDeclOrQualifier = | 
|  | cast<TypedefNameDecl>(Reader.GetDecl(NamedDeclForTagDecl)); | 
|  | } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) { | 
|  | // if we have a fully initialized TypeDecl, we can safely read its type now. | 
|  | ID->TypeForDecl = Reader.GetType(DeferredTypeID).getTypePtrOrNull(); | 
|  | } else if (auto *FD = dyn_cast<FunctionDecl>(D)) { | 
|  | // FunctionDecl's body was written last after all other Stmts/Exprs. | 
|  | // We only read it if FD doesn't already have a body (e.g., from another | 
|  | // module). | 
|  | // FIXME: Can we diagnose ODR violations somehow? | 
|  | if (Record.readInt()) | 
|  | ReadFunctionDefinition(FD); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitDecl(Decl *D) { | 
|  | if (D->isTemplateParameter() || D->isTemplateParameterPack() || | 
|  | isa<ParmVarDecl>(D)) { | 
|  | // We don't want to deserialize the DeclContext of a template | 
|  | // parameter or of a parameter of a function template immediately.   These | 
|  | // entities might be used in the formulation of its DeclContext (for | 
|  | // example, a function parameter can be used in decltype() in trailing | 
|  | // return type of the function).  Use the translation unit DeclContext as a | 
|  | // placeholder. | 
|  | GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(); | 
|  | GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(); | 
|  | if (!LexicalDCIDForTemplateParmDecl) | 
|  | LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl; | 
|  | Reader.addPendingDeclContextInfo(D, | 
|  | SemaDCIDForTemplateParmDecl, | 
|  | LexicalDCIDForTemplateParmDecl); | 
|  | D->setDeclContext(Reader.getContext().getTranslationUnitDecl()); | 
|  | } else { | 
|  | auto *SemaDC = ReadDeclAs<DeclContext>(); | 
|  | auto *LexicalDC = ReadDeclAs<DeclContext>(); | 
|  | if (!LexicalDC) | 
|  | LexicalDC = SemaDC; | 
|  | DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC); | 
|  | // Avoid calling setLexicalDeclContext() directly because it uses | 
|  | // Decl::getASTContext() internally which is unsafe during derialization. | 
|  | D->setDeclContextsImpl(MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC, | 
|  | Reader.getContext()); | 
|  | } | 
|  | D->setLocation(ThisDeclLoc); | 
|  | D->setInvalidDecl(Record.readInt()); | 
|  | if (Record.readInt()) { // hasAttrs | 
|  | AttrVec Attrs; | 
|  | Record.readAttributes(Attrs); | 
|  | // Avoid calling setAttrs() directly because it uses Decl::getASTContext() | 
|  | // internally which is unsafe during derialization. | 
|  | D->setAttrsImpl(Attrs, Reader.getContext()); | 
|  | } | 
|  | D->setImplicit(Record.readInt()); | 
|  | D->Used = Record.readInt(); | 
|  | IsDeclMarkedUsed |= D->Used; | 
|  | D->setReferenced(Record.readInt()); | 
|  | D->setTopLevelDeclInObjCContainer(Record.readInt()); | 
|  | D->setAccess((AccessSpecifier)Record.readInt()); | 
|  | D->FromASTFile = true; | 
|  | bool ModulePrivate = Record.readInt(); | 
|  |  | 
|  | // Determine whether this declaration is part of a (sub)module. If so, it | 
|  | // may not yet be visible. | 
|  | if (unsigned SubmoduleID = readSubmoduleID()) { | 
|  | // Store the owning submodule ID in the declaration. | 
|  | D->setModuleOwnershipKind( | 
|  | ModulePrivate ? Decl::ModuleOwnershipKind::ModulePrivate | 
|  | : Decl::ModuleOwnershipKind::VisibleWhenImported); | 
|  | D->setOwningModuleID(SubmoduleID); | 
|  |  | 
|  | if (ModulePrivate) { | 
|  | // Module-private declarations are never visible, so there is no work to | 
|  | // do. | 
|  | } else if (Reader.getContext().getLangOpts().ModulesLocalVisibility) { | 
|  | // If local visibility is being tracked, this declaration will become | 
|  | // hidden and visible as the owning module does. | 
|  | } else if (Module *Owner = Reader.getSubmodule(SubmoduleID)) { | 
|  | // Mark the declaration as visible when its owning module becomes visible. | 
|  | if (Owner->NameVisibility == Module::AllVisible) | 
|  | D->setVisibleDespiteOwningModule(); | 
|  | else | 
|  | Reader.HiddenNamesMap[Owner].push_back(D); | 
|  | } | 
|  | } else if (ModulePrivate) { | 
|  | D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->setLocation(ReadSourceLocation()); | 
|  | D->CommentKind = (PragmaMSCommentKind)Record.readInt(); | 
|  | std::string Arg = ReadString(); | 
|  | memcpy(D->getTrailingObjects<char>(), Arg.data(), Arg.size()); | 
|  | D->getTrailingObjects<char>()[Arg.size()] = '\0'; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->setLocation(ReadSourceLocation()); | 
|  | std::string Name = ReadString(); | 
|  | memcpy(D->getTrailingObjects<char>(), Name.data(), Name.size()); | 
|  | D->getTrailingObjects<char>()[Name.size()] = '\0'; | 
|  |  | 
|  | D->ValueStart = Name.size() + 1; | 
|  | std::string Value = ReadString(); | 
|  | memcpy(D->getTrailingObjects<char>() + D->ValueStart, Value.data(), | 
|  | Value.size()); | 
|  | D->getTrailingObjects<char>()[D->ValueStart + Value.size()] = '\0'; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { | 
|  | llvm_unreachable("Translation units are not serialized"); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitNamedDecl(NamedDecl *ND) { | 
|  | VisitDecl(ND); | 
|  | ND->setDeclName(Record.readDeclarationName()); | 
|  | AnonymousDeclNumber = Record.readInt(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { | 
|  | VisitNamedDecl(TD); | 
|  | TD->setLocStart(ReadSourceLocation()); | 
|  | // Delay type reading until after we have fully initialized the decl. | 
|  | DeferredTypeID = Record.getGlobalTypeID(Record.readInt()); | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(TD); | 
|  | VisitTypeDecl(TD); | 
|  | TypeSourceInfo *TInfo = GetTypeSourceInfo(); | 
|  | if (Record.readInt()) { // isModed | 
|  | QualType modedT = Record.readType(); | 
|  | TD->setModedTypeSourceInfo(TInfo, modedT); | 
|  | } else | 
|  | TD->setTypeSourceInfo(TInfo); | 
|  | // Read and discard the declaration for which this is a typedef name for | 
|  | // linkage, if it exists. We cannot rely on our type to pull in this decl, | 
|  | // because it might have been merged with a type from another module and | 
|  | // thus might not refer to our version of the declaration. | 
|  | ReadDecl(); | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) { | 
|  | RedeclarableResult Redecl = VisitTypedefNameDecl(TD); | 
|  | mergeRedeclarable(TD, Redecl); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { | 
|  | RedeclarableResult Redecl = VisitTypedefNameDecl(TD); | 
|  | if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>()) | 
|  | // Merged when we merge the template. | 
|  | TD->setDescribedAliasTemplate(Template); | 
|  | else | 
|  | mergeRedeclarable(TD, Redecl); | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(TD); | 
|  | VisitTypeDecl(TD); | 
|  |  | 
|  | TD->IdentifierNamespace = Record.readInt(); | 
|  | TD->setTagKind((TagDecl::TagKind)Record.readInt()); | 
|  | if (!isa<CXXRecordDecl>(TD)) | 
|  | TD->setCompleteDefinition(Record.readInt()); | 
|  | TD->setEmbeddedInDeclarator(Record.readInt()); | 
|  | TD->setFreeStanding(Record.readInt()); | 
|  | TD->setCompleteDefinitionRequired(Record.readInt()); | 
|  | TD->setBraceRange(ReadSourceRange()); | 
|  |  | 
|  | switch (Record.readInt()) { | 
|  | case 0: | 
|  | break; | 
|  | case 1: { // ExtInfo | 
|  | auto *Info = new (Reader.getContext()) TagDecl::ExtInfo(); | 
|  | ReadQualifierInfo(*Info); | 
|  | TD->TypedefNameDeclOrQualifier = Info; | 
|  | break; | 
|  | } | 
|  | case 2: // TypedefNameForAnonDecl | 
|  | NamedDeclForTagDecl = ReadDeclID(); | 
|  | TypedefNameForLinkage = Record.getIdentifierInfo(); | 
|  | break; | 
|  | default: | 
|  | llvm_unreachable("unexpected tag info kind"); | 
|  | } | 
|  |  | 
|  | if (!isa<CXXRecordDecl>(TD)) | 
|  | mergeRedeclarable(TD, Redecl); | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { | 
|  | VisitTagDecl(ED); | 
|  | if (TypeSourceInfo *TI = GetTypeSourceInfo()) | 
|  | ED->setIntegerTypeSourceInfo(TI); | 
|  | else | 
|  | ED->setIntegerType(Record.readType()); | 
|  | ED->setPromotionType(Record.readType()); | 
|  | ED->setNumPositiveBits(Record.readInt()); | 
|  | ED->setNumNegativeBits(Record.readInt()); | 
|  | ED->setScoped(Record.readInt()); | 
|  | ED->setScopedUsingClassTag(Record.readInt()); | 
|  | ED->setFixed(Record.readInt()); | 
|  |  | 
|  | ED->setHasODRHash(true); | 
|  | ED->ODRHash = Record.readInt(); | 
|  |  | 
|  | // If this is a definition subject to the ODR, and we already have a | 
|  | // definition, merge this one into it. | 
|  | if (ED->isCompleteDefinition() && | 
|  | Reader.getContext().getLangOpts().Modules && | 
|  | Reader.getContext().getLangOpts().CPlusPlus) { | 
|  | EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]; | 
|  | if (!OldDef) { | 
|  | // This is the first time we've seen an imported definition. Look for a | 
|  | // local definition before deciding that we are the first definition. | 
|  | for (auto *D : merged_redecls(ED->getCanonicalDecl())) { | 
|  | if (!D->isFromASTFile() && D->isCompleteDefinition()) { | 
|  | OldDef = D; | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | if (OldDef) { | 
|  | Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef)); | 
|  | ED->setCompleteDefinition(false); | 
|  | Reader.mergeDefinitionVisibility(OldDef, ED); | 
|  | if (OldDef->getODRHash() != ED->getODRHash()) | 
|  | Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED); | 
|  | } else { | 
|  | OldDef = ED; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (auto *InstED = ReadDeclAs<EnumDecl>()) { | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  | ED->setInstantiationOfMemberEnum(Reader.getContext(), InstED, TSK); | 
|  | ED->getMemberSpecializationInfo()->setPointOfInstantiation(POI); | 
|  | } | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) { | 
|  | RedeclarableResult Redecl = VisitTagDecl(RD); | 
|  | RD->setHasFlexibleArrayMember(Record.readInt()); | 
|  | RD->setAnonymousStructOrUnion(Record.readInt()); | 
|  | RD->setHasObjectMember(Record.readInt()); | 
|  | RD->setHasVolatileMember(Record.readInt()); | 
|  | RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt()); | 
|  | RD->setNonTrivialToPrimitiveCopy(Record.readInt()); | 
|  | RD->setNonTrivialToPrimitiveDestroy(Record.readInt()); | 
|  | RD->setHasNonTrivialToPrimitiveDefaultInitializeCUnion(Record.readInt()); | 
|  | RD->setHasNonTrivialToPrimitiveDestructCUnion(Record.readInt()); | 
|  | RD->setHasNonTrivialToPrimitiveCopyCUnion(Record.readInt()); | 
|  | RD->setParamDestroyedInCallee(Record.readInt()); | 
|  | RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt()); | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitValueDecl(ValueDecl *VD) { | 
|  | VisitNamedDecl(VD); | 
|  | // For function declarations, defer reading the type in case the function has | 
|  | // a deduced return type that references an entity declared within the | 
|  | // function. | 
|  | if (isa<FunctionDecl>(VD)) | 
|  | DeferredTypeID = Record.getGlobalTypeID(Record.readInt()); | 
|  | else | 
|  | VD->setType(Record.readType()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { | 
|  | VisitValueDecl(ECD); | 
|  | if (Record.readInt()) | 
|  | ECD->setInitExpr(Record.readExpr()); | 
|  | ECD->setInitVal(Record.readAPSInt()); | 
|  | mergeMergeable(ECD); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { | 
|  | VisitValueDecl(DD); | 
|  | DD->setInnerLocStart(ReadSourceLocation()); | 
|  | if (Record.readInt()) { // hasExtInfo | 
|  | auto *Info = new (Reader.getContext()) DeclaratorDecl::ExtInfo(); | 
|  | ReadQualifierInfo(*Info); | 
|  | DD->DeclInfo = Info; | 
|  | } | 
|  | QualType TSIType = Record.readType(); | 
|  | DD->setTypeSourceInfo( | 
|  | TSIType.isNull() ? nullptr | 
|  | : Reader.getContext().CreateTypeSourceInfo(TSIType)); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(FD); | 
|  | VisitDeclaratorDecl(FD); | 
|  |  | 
|  | // Attach a type to this function. Use the real type if possible, but fall | 
|  | // back to the type as written if it involves a deduced return type. | 
|  | if (FD->getTypeSourceInfo() && | 
|  | FD->getTypeSourceInfo()->getType()->castAs<FunctionType>() | 
|  | ->getReturnType()->getContainedAutoType()) { | 
|  | // We'll set up the real type in Visit, once we've finished loading the | 
|  | // function. | 
|  | FD->setType(FD->getTypeSourceInfo()->getType()); | 
|  | Reader.PendingFunctionTypes.push_back({FD, DeferredTypeID}); | 
|  | } else { | 
|  | FD->setType(Reader.GetType(DeferredTypeID)); | 
|  | } | 
|  | DeferredTypeID = 0; | 
|  |  | 
|  | ReadDeclarationNameLoc(FD->DNLoc, FD->getDeclName()); | 
|  | FD->IdentifierNamespace = Record.readInt(); | 
|  |  | 
|  | // FunctionDecl's body is handled last at ASTDeclReader::Visit, | 
|  | // after everything else is read. | 
|  |  | 
|  | FD->setStorageClass(static_cast<StorageClass>(Record.readInt())); | 
|  | FD->setInlineSpecified(Record.readInt()); | 
|  | FD->setImplicitlyInline(Record.readInt()); | 
|  | FD->setVirtualAsWritten(Record.readInt()); | 
|  | FD->setPure(Record.readInt()); | 
|  | FD->setHasInheritedPrototype(Record.readInt()); | 
|  | FD->setHasWrittenPrototype(Record.readInt()); | 
|  | FD->setDeletedAsWritten(Record.readInt()); | 
|  | FD->setTrivial(Record.readInt()); | 
|  | FD->setTrivialForCall(Record.readInt()); | 
|  | FD->setDefaulted(Record.readInt()); | 
|  | FD->setExplicitlyDefaulted(Record.readInt()); | 
|  | FD->setHasImplicitReturnZero(Record.readInt()); | 
|  | FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt())); | 
|  | FD->setUsesSEHTry(Record.readInt()); | 
|  | FD->setHasSkippedBody(Record.readInt()); | 
|  | FD->setIsMultiVersion(Record.readInt()); | 
|  | FD->setLateTemplateParsed(Record.readInt()); | 
|  |  | 
|  | FD->setCachedLinkage(static_cast<Linkage>(Record.readInt())); | 
|  | FD->EndRangeLoc = ReadSourceLocation(); | 
|  |  | 
|  | FD->ODRHash = Record.readInt(); | 
|  | FD->setHasODRHash(true); | 
|  | FD->setUsesFPIntrin(Record.readInt()); | 
|  |  | 
|  | switch ((FunctionDecl::TemplatedKind)Record.readInt()) { | 
|  | case FunctionDecl::TK_NonTemplate: | 
|  | mergeRedeclarable(FD, Redecl); | 
|  | break; | 
|  | case FunctionDecl::TK_FunctionTemplate: | 
|  | // Merged when we merge the template. | 
|  | FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>()); | 
|  | break; | 
|  | case FunctionDecl::TK_MemberSpecialization: { | 
|  | auto *InstFD = ReadDeclAs<FunctionDecl>(); | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  | FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK); | 
|  | FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); | 
|  | mergeRedeclarable(FD, Redecl); | 
|  | break; | 
|  | } | 
|  | case FunctionDecl::TK_FunctionTemplateSpecialization: { | 
|  | auto *Template = ReadDeclAs<FunctionTemplateDecl>(); | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  |  | 
|  | // Template arguments. | 
|  | SmallVector<TemplateArgument, 8> TemplArgs; | 
|  | Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); | 
|  |  | 
|  | // Template args as written. | 
|  | SmallVector<TemplateArgumentLoc, 8> TemplArgLocs; | 
|  | SourceLocation LAngleLoc, RAngleLoc; | 
|  | bool HasTemplateArgumentsAsWritten = Record.readInt(); | 
|  | if (HasTemplateArgumentsAsWritten) { | 
|  | unsigned NumTemplateArgLocs = Record.readInt(); | 
|  | TemplArgLocs.reserve(NumTemplateArgLocs); | 
|  | for (unsigned i = 0; i != NumTemplateArgLocs; ++i) | 
|  | TemplArgLocs.push_back(Record.readTemplateArgumentLoc()); | 
|  |  | 
|  | LAngleLoc = ReadSourceLocation(); | 
|  | RAngleLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  |  | 
|  | ASTContext &C = Reader.getContext(); | 
|  | TemplateArgumentList *TemplArgList | 
|  | = TemplateArgumentList::CreateCopy(C, TemplArgs); | 
|  | TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc); | 
|  | for (unsigned i = 0, e = TemplArgLocs.size(); i != e; ++i) | 
|  | TemplArgsInfo.addArgument(TemplArgLocs[i]); | 
|  |  | 
|  | MemberSpecializationInfo *MSInfo = nullptr; | 
|  | if (Record.readInt()) { | 
|  | auto *FD = ReadDeclAs<FunctionDecl>(); | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  |  | 
|  | MSInfo = new (C) MemberSpecializationInfo(FD, TSK); | 
|  | MSInfo->setPointOfInstantiation(POI); | 
|  | } | 
|  |  | 
|  | FunctionTemplateSpecializationInfo *FTInfo = | 
|  | FunctionTemplateSpecializationInfo::Create( | 
|  | C, FD, Template, TSK, TemplArgList, | 
|  | HasTemplateArgumentsAsWritten ? &TemplArgsInfo : nullptr, POI, | 
|  | MSInfo); | 
|  | FD->TemplateOrSpecialization = FTInfo; | 
|  |  | 
|  | if (FD->isCanonicalDecl()) { // if canonical add to template's set. | 
|  | // The template that contains the specializations set. It's not safe to | 
|  | // use getCanonicalDecl on Template since it may still be initializing. | 
|  | auto *CanonTemplate = ReadDeclAs<FunctionTemplateDecl>(); | 
|  | // Get the InsertPos by FindNodeOrInsertPos() instead of calling | 
|  | // InsertNode(FTInfo) directly to avoid the getASTContext() call in | 
|  | // FunctionTemplateSpecializationInfo's Profile(). | 
|  | // We avoid getASTContext because a decl in the parent hierarchy may | 
|  | // be initializing. | 
|  | llvm::FoldingSetNodeID ID; | 
|  | FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C); | 
|  | void *InsertPos = nullptr; | 
|  | FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr(); | 
|  | FunctionTemplateSpecializationInfo *ExistingInfo = | 
|  | CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos); | 
|  | if (InsertPos) | 
|  | CommonPtr->Specializations.InsertNode(FTInfo, InsertPos); | 
|  | else { | 
|  | assert(Reader.getContext().getLangOpts().Modules && | 
|  | "already deserialized this template specialization"); | 
|  | mergeRedeclarable(FD, ExistingInfo->getFunction(), Redecl); | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  | case FunctionDecl::TK_DependentFunctionTemplateSpecialization: { | 
|  | // Templates. | 
|  | UnresolvedSet<8> TemplDecls; | 
|  | unsigned NumTemplates = Record.readInt(); | 
|  | while (NumTemplates--) | 
|  | TemplDecls.addDecl(ReadDeclAs<NamedDecl>()); | 
|  |  | 
|  | // Templates args. | 
|  | TemplateArgumentListInfo TemplArgs; | 
|  | unsigned NumArgs = Record.readInt(); | 
|  | while (NumArgs--) | 
|  | TemplArgs.addArgument(Record.readTemplateArgumentLoc()); | 
|  | TemplArgs.setLAngleLoc(ReadSourceLocation()); | 
|  | TemplArgs.setRAngleLoc(ReadSourceLocation()); | 
|  |  | 
|  | FD->setDependentTemplateSpecialization(Reader.getContext(), | 
|  | TemplDecls, TemplArgs); | 
|  | // These are not merged; we don't need to merge redeclarations of dependent | 
|  | // template friends. | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Read in the parameters. | 
|  | unsigned NumParams = Record.readInt(); | 
|  | SmallVector<ParmVarDecl *, 16> Params; | 
|  | Params.reserve(NumParams); | 
|  | for (unsigned I = 0; I != NumParams; ++I) | 
|  | Params.push_back(ReadDeclAs<ParmVarDecl>()); | 
|  | FD->setParams(Reader.getContext(), Params); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { | 
|  | VisitNamedDecl(MD); | 
|  | if (Record.readInt()) { | 
|  | // Load the body on-demand. Most clients won't care, because method | 
|  | // definitions rarely show up in headers. | 
|  | Reader.PendingBodies[MD] = GetCurrentCursorOffset(); | 
|  | HasPendingBody = true; | 
|  | } | 
|  | MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>()); | 
|  | MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>()); | 
|  | MD->setInstanceMethod(Record.readInt()); | 
|  | MD->setVariadic(Record.readInt()); | 
|  | MD->setPropertyAccessor(Record.readInt()); | 
|  | MD->setSynthesizedAccessorStub(Record.readInt()); | 
|  | MD->setDefined(Record.readInt()); | 
|  | MD->setOverriding(Record.readInt()); | 
|  | MD->setHasSkippedBody(Record.readInt()); | 
|  |  | 
|  | MD->setIsRedeclaration(Record.readInt()); | 
|  | MD->setHasRedeclaration(Record.readInt()); | 
|  | if (MD->hasRedeclaration()) | 
|  | Reader.getContext().setObjCMethodRedeclaration(MD, | 
|  | ReadDeclAs<ObjCMethodDecl>()); | 
|  |  | 
|  | MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt()); | 
|  | MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt()); | 
|  | MD->setRelatedResultType(Record.readInt()); | 
|  | MD->setReturnType(Record.readType()); | 
|  | MD->setReturnTypeSourceInfo(GetTypeSourceInfo()); | 
|  | MD->DeclEndLoc = ReadSourceLocation(); | 
|  | unsigned NumParams = Record.readInt(); | 
|  | SmallVector<ParmVarDecl *, 16> Params; | 
|  | Params.reserve(NumParams); | 
|  | for (unsigned I = 0; I != NumParams; ++I) | 
|  | Params.push_back(ReadDeclAs<ParmVarDecl>()); | 
|  |  | 
|  | MD->setSelLocsKind((SelectorLocationsKind)Record.readInt()); | 
|  | unsigned NumStoredSelLocs = Record.readInt(); | 
|  | SmallVector<SourceLocation, 16> SelLocs; | 
|  | SelLocs.reserve(NumStoredSelLocs); | 
|  | for (unsigned i = 0; i != NumStoredSelLocs; ++i) | 
|  | SelLocs.push_back(ReadSourceLocation()); | 
|  |  | 
|  | MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { | 
|  | VisitTypedefNameDecl(D); | 
|  |  | 
|  | D->Variance = Record.readInt(); | 
|  | D->Index = Record.readInt(); | 
|  | D->VarianceLoc = ReadSourceLocation(); | 
|  | D->ColonLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) { | 
|  | VisitNamedDecl(CD); | 
|  | CD->setAtStartLoc(ReadSourceLocation()); | 
|  | CD->setAtEndRange(ReadSourceRange()); | 
|  | } | 
|  |  | 
|  | ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() { | 
|  | unsigned numParams = Record.readInt(); | 
|  | if (numParams == 0) | 
|  | return nullptr; | 
|  |  | 
|  | SmallVector<ObjCTypeParamDecl *, 4> typeParams; | 
|  | typeParams.reserve(numParams); | 
|  | for (unsigned i = 0; i != numParams; ++i) { | 
|  | auto *typeParam = ReadDeclAs<ObjCTypeParamDecl>(); | 
|  | if (!typeParam) | 
|  | return nullptr; | 
|  |  | 
|  | typeParams.push_back(typeParam); | 
|  | } | 
|  |  | 
|  | SourceLocation lAngleLoc = ReadSourceLocation(); | 
|  | SourceLocation rAngleLoc = ReadSourceLocation(); | 
|  |  | 
|  | return ObjCTypeParamList::create(Reader.getContext(), lAngleLoc, | 
|  | typeParams, rAngleLoc); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::ReadObjCDefinitionData( | 
|  | struct ObjCInterfaceDecl::DefinitionData &Data) { | 
|  | // Read the superclass. | 
|  | Data.SuperClassTInfo = GetTypeSourceInfo(); | 
|  |  | 
|  | Data.EndLoc = ReadSourceLocation(); | 
|  | Data.HasDesignatedInitializers = Record.readInt(); | 
|  |  | 
|  | // Read the directly referenced protocols and their SourceLocations. | 
|  | unsigned NumProtocols = Record.readInt(); | 
|  | SmallVector<ObjCProtocolDecl *, 16> Protocols; | 
|  | Protocols.reserve(NumProtocols); | 
|  | for (unsigned I = 0; I != NumProtocols; ++I) | 
|  | Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>()); | 
|  | SmallVector<SourceLocation, 16> ProtoLocs; | 
|  | ProtoLocs.reserve(NumProtocols); | 
|  | for (unsigned I = 0; I != NumProtocols; ++I) | 
|  | ProtoLocs.push_back(ReadSourceLocation()); | 
|  | Data.ReferencedProtocols.set(Protocols.data(), NumProtocols, ProtoLocs.data(), | 
|  | Reader.getContext()); | 
|  |  | 
|  | // Read the transitive closure of protocols referenced by this class. | 
|  | NumProtocols = Record.readInt(); | 
|  | Protocols.clear(); | 
|  | Protocols.reserve(NumProtocols); | 
|  | for (unsigned I = 0; I != NumProtocols; ++I) | 
|  | Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>()); | 
|  | Data.AllReferencedProtocols.set(Protocols.data(), NumProtocols, | 
|  | Reader.getContext()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::MergeDefinitionData(ObjCInterfaceDecl *D, | 
|  | struct ObjCInterfaceDecl::DefinitionData &&NewDD) { | 
|  | // FIXME: odr checking? | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(ID); | 
|  | VisitObjCContainerDecl(ID); | 
|  | DeferredTypeID = Record.getGlobalTypeID(Record.readInt()); | 
|  | mergeRedeclarable(ID, Redecl); | 
|  |  | 
|  | ID->TypeParamList = ReadObjCTypeParamList(); | 
|  | if (Record.readInt()) { | 
|  | // Read the definition. | 
|  | ID->allocateDefinitionData(); | 
|  |  | 
|  | ReadObjCDefinitionData(ID->data()); | 
|  | ObjCInterfaceDecl *Canon = ID->getCanonicalDecl(); | 
|  | if (Canon->Data.getPointer()) { | 
|  | // If we already have a definition, keep the definition invariant and | 
|  | // merge the data. | 
|  | MergeDefinitionData(Canon, std::move(ID->data())); | 
|  | ID->Data = Canon->Data; | 
|  | } else { | 
|  | // Set the definition data of the canonical declaration, so other | 
|  | // redeclarations will see it. | 
|  | ID->getCanonicalDecl()->Data = ID->Data; | 
|  |  | 
|  | // We will rebuild this list lazily. | 
|  | ID->setIvarList(nullptr); | 
|  | } | 
|  |  | 
|  | // Note that we have deserialized a definition. | 
|  | Reader.PendingDefinitions.insert(ID); | 
|  |  | 
|  | // Note that we've loaded this Objective-C class. | 
|  | Reader.ObjCClassesLoaded.push_back(ID); | 
|  | } else { | 
|  | ID->Data = ID->getCanonicalDecl()->Data; | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { | 
|  | VisitFieldDecl(IVD); | 
|  | IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record.readInt()); | 
|  | // This field will be built lazily. | 
|  | IVD->setNextIvar(nullptr); | 
|  | bool synth = Record.readInt(); | 
|  | IVD->setSynthesize(synth); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::ReadObjCDefinitionData( | 
|  | struct ObjCProtocolDecl::DefinitionData &Data) { | 
|  | unsigned NumProtoRefs = Record.readInt(); | 
|  | SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; | 
|  | ProtoRefs.reserve(NumProtoRefs); | 
|  | for (unsigned I = 0; I != NumProtoRefs; ++I) | 
|  | ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>()); | 
|  | SmallVector<SourceLocation, 16> ProtoLocs; | 
|  | ProtoLocs.reserve(NumProtoRefs); | 
|  | for (unsigned I = 0; I != NumProtoRefs; ++I) | 
|  | ProtoLocs.push_back(ReadSourceLocation()); | 
|  | Data.ReferencedProtocols.set(ProtoRefs.data(), NumProtoRefs, | 
|  | ProtoLocs.data(), Reader.getContext()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::MergeDefinitionData(ObjCProtocolDecl *D, | 
|  | struct ObjCProtocolDecl::DefinitionData &&NewDD) { | 
|  | // FIXME: odr checking? | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(PD); | 
|  | VisitObjCContainerDecl(PD); | 
|  | mergeRedeclarable(PD, Redecl); | 
|  |  | 
|  | if (Record.readInt()) { | 
|  | // Read the definition. | 
|  | PD->allocateDefinitionData(); | 
|  |  | 
|  | ReadObjCDefinitionData(PD->data()); | 
|  |  | 
|  | ObjCProtocolDecl *Canon = PD->getCanonicalDecl(); | 
|  | if (Canon->Data.getPointer()) { | 
|  | // If we already have a definition, keep the definition invariant and | 
|  | // merge the data. | 
|  | MergeDefinitionData(Canon, std::move(PD->data())); | 
|  | PD->Data = Canon->Data; | 
|  | } else { | 
|  | // Set the definition data of the canonical declaration, so other | 
|  | // redeclarations will see it. | 
|  | PD->getCanonicalDecl()->Data = PD->Data; | 
|  | } | 
|  | // Note that we have deserialized a definition. | 
|  | Reader.PendingDefinitions.insert(PD); | 
|  | } else { | 
|  | PD->Data = PD->getCanonicalDecl()->Data; | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) { | 
|  | VisitFieldDecl(FD); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { | 
|  | VisitObjCContainerDecl(CD); | 
|  | CD->setCategoryNameLoc(ReadSourceLocation()); | 
|  | CD->setIvarLBraceLoc(ReadSourceLocation()); | 
|  | CD->setIvarRBraceLoc(ReadSourceLocation()); | 
|  |  | 
|  | // Note that this category has been deserialized. We do this before | 
|  | // deserializing the interface declaration, so that it will consider this | 
|  | /// category. | 
|  | Reader.CategoriesDeserialized.insert(CD); | 
|  |  | 
|  | CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(); | 
|  | CD->TypeParamList = ReadObjCTypeParamList(); | 
|  | unsigned NumProtoRefs = Record.readInt(); | 
|  | SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; | 
|  | ProtoRefs.reserve(NumProtoRefs); | 
|  | for (unsigned I = 0; I != NumProtoRefs; ++I) | 
|  | ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>()); | 
|  | SmallVector<SourceLocation, 16> ProtoLocs; | 
|  | ProtoLocs.reserve(NumProtoRefs); | 
|  | for (unsigned I = 0; I != NumProtoRefs; ++I) | 
|  | ProtoLocs.push_back(ReadSourceLocation()); | 
|  | CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(), | 
|  | Reader.getContext()); | 
|  |  | 
|  | // Protocols in the class extension belong to the class. | 
|  | if (NumProtoRefs > 0 && CD->ClassInterface && CD->IsClassExtension()) | 
|  | CD->ClassInterface->mergeClassExtensionProtocolList( | 
|  | (ObjCProtocolDecl *const *)ProtoRefs.data(), NumProtoRefs, | 
|  | Reader.getContext()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) { | 
|  | VisitNamedDecl(CAD); | 
|  | CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { | 
|  | VisitNamedDecl(D); | 
|  | D->setAtLoc(ReadSourceLocation()); | 
|  | D->setLParenLoc(ReadSourceLocation()); | 
|  | QualType T = Record.readType(); | 
|  | TypeSourceInfo *TSI = GetTypeSourceInfo(); | 
|  | D->setType(T, TSI); | 
|  | D->setPropertyAttributes( | 
|  | (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt()); | 
|  | D->setPropertyAttributesAsWritten( | 
|  | (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt()); | 
|  | D->setPropertyImplementation( | 
|  | (ObjCPropertyDecl::PropertyControl)Record.readInt()); | 
|  | DeclarationName GetterName = Record.readDeclarationName(); | 
|  | SourceLocation GetterLoc = ReadSourceLocation(); | 
|  | D->setGetterName(GetterName.getObjCSelector(), GetterLoc); | 
|  | DeclarationName SetterName = Record.readDeclarationName(); | 
|  | SourceLocation SetterLoc = ReadSourceLocation(); | 
|  | D->setSetterName(SetterName.getObjCSelector(), SetterLoc); | 
|  | D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>()); | 
|  | D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>()); | 
|  | D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) { | 
|  | VisitObjCContainerDecl(D); | 
|  | D->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { | 
|  | VisitObjCImplDecl(D); | 
|  | D->CategoryNameLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { | 
|  | VisitObjCImplDecl(D); | 
|  | D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>()); | 
|  | D->SuperLoc = ReadSourceLocation(); | 
|  | D->setIvarLBraceLoc(ReadSourceLocation()); | 
|  | D->setIvarRBraceLoc(ReadSourceLocation()); | 
|  | D->setHasNonZeroConstructors(Record.readInt()); | 
|  | D->setHasDestructors(Record.readInt()); | 
|  | D->NumIvarInitializers = Record.readInt(); | 
|  | if (D->NumIvarInitializers) | 
|  | D->IvarInitializers = ReadGlobalOffset(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->setAtLoc(ReadSourceLocation()); | 
|  | D->setPropertyDecl(ReadDeclAs<ObjCPropertyDecl>()); | 
|  | D->PropertyIvarDecl = ReadDeclAs<ObjCIvarDecl>(); | 
|  | D->IvarLoc = ReadSourceLocation(); | 
|  | D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>()); | 
|  | D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>()); | 
|  | D->setGetterCXXConstructor(Record.readExpr()); | 
|  | D->setSetterCXXAssignment(Record.readExpr()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { | 
|  | VisitDeclaratorDecl(FD); | 
|  | FD->Mutable = Record.readInt(); | 
|  |  | 
|  | if (auto ISK = static_cast<FieldDecl::InitStorageKind>(Record.readInt())) { | 
|  | FD->InitStorage.setInt(ISK); | 
|  | FD->InitStorage.setPointer(ISK == FieldDecl::ISK_CapturedVLAType | 
|  | ? Record.readType().getAsOpaquePtr() | 
|  | : Record.readExpr()); | 
|  | } | 
|  |  | 
|  | if (auto *BW = Record.readExpr()) | 
|  | FD->setBitWidth(BW); | 
|  |  | 
|  | if (!FD->getDeclName()) { | 
|  | if (auto *Tmpl = ReadDeclAs<FieldDecl>()) | 
|  | Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl); | 
|  | } | 
|  | mergeMergeable(FD); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) { | 
|  | VisitDeclaratorDecl(PD); | 
|  | PD->GetterId = Record.getIdentifierInfo(); | 
|  | PD->SetterId = Record.getIdentifierInfo(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { | 
|  | VisitValueDecl(FD); | 
|  |  | 
|  | FD->ChainingSize = Record.readInt(); | 
|  | assert(FD->ChainingSize >= 2 && "Anonymous chaining must be >= 2"); | 
|  | FD->Chaining = new (Reader.getContext())NamedDecl*[FD->ChainingSize]; | 
|  |  | 
|  | for (unsigned I = 0; I != FD->ChainingSize; ++I) | 
|  | FD->Chaining[I] = ReadDeclAs<NamedDecl>(); | 
|  |  | 
|  | mergeMergeable(FD); | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(VD); | 
|  | VisitDeclaratorDecl(VD); | 
|  |  | 
|  | VD->VarDeclBits.SClass = (StorageClass)Record.readInt(); | 
|  | VD->VarDeclBits.TSCSpec = Record.readInt(); | 
|  | VD->VarDeclBits.InitStyle = Record.readInt(); | 
|  | VD->VarDeclBits.ARCPseudoStrong = Record.readInt(); | 
|  | if (!isa<ParmVarDecl>(VD)) { | 
|  | VD->NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = | 
|  | Record.readInt(); | 
|  | VD->NonParmVarDeclBits.ExceptionVar = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.NRVOVariable = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.CXXForRangeDecl = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.ObjCForDecl = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.IsInline = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.IsConstexpr = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.IsInitCapture = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.PreviousDeclInSameBlockScope = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.ImplicitParamKind = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.EscapingByref = Record.readInt(); | 
|  | } | 
|  | auto VarLinkage = Linkage(Record.readInt()); | 
|  | VD->setCachedLinkage(VarLinkage); | 
|  |  | 
|  | // Reconstruct the one piece of the IdentifierNamespace that we need. | 
|  | if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage && | 
|  | VD->getLexicalDeclContext()->isFunctionOrMethod()) | 
|  | VD->setLocalExternDecl(); | 
|  |  | 
|  | if (uint64_t Val = Record.readInt()) { | 
|  | VD->setInit(Record.readExpr()); | 
|  | if (Val > 1) { | 
|  | EvaluatedStmt *Eval = VD->ensureEvaluatedStmt(); | 
|  | Eval->CheckedICE = true; | 
|  | Eval->IsICE = (Val & 1) != 0; | 
|  | Eval->HasConstantDestruction = (Val & 4) != 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (VD->hasAttr<BlocksAttr>() && VD->getType()->getAsCXXRecordDecl()) { | 
|  | Expr *CopyExpr = Record.readExpr(); | 
|  | if (CopyExpr) | 
|  | Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt()); | 
|  | } | 
|  |  | 
|  | if (VD->getStorageDuration() == SD_Static && Record.readInt()) | 
|  | Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile; | 
|  |  | 
|  | enum VarKind { | 
|  | VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization | 
|  | }; | 
|  | switch ((VarKind)Record.readInt()) { | 
|  | case VarNotTemplate: | 
|  | // Only true variables (not parameters or implicit parameters) can be | 
|  | // merged; the other kinds are not really redeclarable at all. | 
|  | if (!isa<ParmVarDecl>(VD) && !isa<ImplicitParamDecl>(VD) && | 
|  | !isa<VarTemplateSpecializationDecl>(VD)) | 
|  | mergeRedeclarable(VD, Redecl); | 
|  | break; | 
|  | case VarTemplate: | 
|  | // Merged when we merge the template. | 
|  | VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>()); | 
|  | break; | 
|  | case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo. | 
|  | auto *Tmpl = ReadDeclAs<VarDecl>(); | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  | Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI); | 
|  | mergeRedeclarable(VD, Redecl); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { | 
|  | VisitVarDecl(PD); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { | 
|  | VisitVarDecl(PD); | 
|  | unsigned isObjCMethodParam = Record.readInt(); | 
|  | unsigned scopeDepth = Record.readInt(); | 
|  | unsigned scopeIndex = Record.readInt(); | 
|  | unsigned declQualifier = Record.readInt(); | 
|  | if (isObjCMethodParam) { | 
|  | assert(scopeDepth == 0); | 
|  | PD->setObjCMethodScopeInfo(scopeIndex); | 
|  | PD->ParmVarDeclBits.ScopeDepthOrObjCQuals = declQualifier; | 
|  | } else { | 
|  | PD->setScopeInfo(scopeDepth, scopeIndex); | 
|  | } | 
|  | PD->ParmVarDeclBits.IsKNRPromoted = Record.readInt(); | 
|  | PD->ParmVarDeclBits.HasInheritedDefaultArg = Record.readInt(); | 
|  | if (Record.readInt()) // hasUninstantiatedDefaultArg. | 
|  | PD->setUninstantiatedDefaultArg(Record.readExpr()); | 
|  |  | 
|  | // FIXME: If this is a redeclaration of a function from another module, handle | 
|  | // inheritance of default arguments. | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) { | 
|  | VisitVarDecl(DD); | 
|  | auto **BDs = DD->getTrailingObjects<BindingDecl *>(); | 
|  | for (unsigned I = 0; I != DD->NumBindings; ++I) { | 
|  | BDs[I] = ReadDeclAs<BindingDecl>(); | 
|  | BDs[I]->setDecomposedDecl(DD); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) { | 
|  | VisitValueDecl(BD); | 
|  | BD->Binding = Record.readExpr(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) { | 
|  | VisitDecl(AD); | 
|  | AD->setAsmString(cast<StringLiteral>(Record.readExpr())); | 
|  | AD->setRParenLoc(ReadSourceLocation()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { | 
|  | VisitDecl(BD); | 
|  | BD->setBody(cast_or_null<CompoundStmt>(Record.readStmt())); | 
|  | BD->setSignatureAsWritten(GetTypeSourceInfo()); | 
|  | unsigned NumParams = Record.readInt(); | 
|  | SmallVector<ParmVarDecl *, 16> Params; | 
|  | Params.reserve(NumParams); | 
|  | for (unsigned I = 0; I != NumParams; ++I) | 
|  | Params.push_back(ReadDeclAs<ParmVarDecl>()); | 
|  | BD->setParams(Params); | 
|  |  | 
|  | BD->setIsVariadic(Record.readInt()); | 
|  | BD->setBlockMissingReturnType(Record.readInt()); | 
|  | BD->setIsConversionFromLambda(Record.readInt()); | 
|  | BD->setDoesNotEscape(Record.readInt()); | 
|  | BD->setCanAvoidCopyToHeap(Record.readInt()); | 
|  |  | 
|  | bool capturesCXXThis = Record.readInt(); | 
|  | unsigned numCaptures = Record.readInt(); | 
|  | SmallVector<BlockDecl::Capture, 16> captures; | 
|  | captures.reserve(numCaptures); | 
|  | for (unsigned i = 0; i != numCaptures; ++i) { | 
|  | auto *decl = ReadDeclAs<VarDecl>(); | 
|  | unsigned flags = Record.readInt(); | 
|  | bool byRef = (flags & 1); | 
|  | bool nested = (flags & 2); | 
|  | Expr *copyExpr = ((flags & 4) ? Record.readExpr() : nullptr); | 
|  |  | 
|  | captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr)); | 
|  | } | 
|  | BD->setCaptures(Reader.getContext(), captures, capturesCXXThis); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) { | 
|  | VisitDecl(CD); | 
|  | unsigned ContextParamPos = Record.readInt(); | 
|  | CD->setNothrow(Record.readInt() != 0); | 
|  | // Body is set by VisitCapturedStmt. | 
|  | for (unsigned I = 0; I < CD->NumParams; ++I) { | 
|  | if (I != ContextParamPos) | 
|  | CD->setParam(I, ReadDeclAs<ImplicitParamDecl>()); | 
|  | else | 
|  | CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->setLanguage((LinkageSpecDecl::LanguageIDs)Record.readInt()); | 
|  | D->setExternLoc(ReadSourceLocation()); | 
|  | D->setRBraceLoc(ReadSourceLocation()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitExportDecl(ExportDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->RBraceLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitLabelDecl(LabelDecl *D) { | 
|  | VisitNamedDecl(D); | 
|  | D->setLocStart(ReadSourceLocation()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(D); | 
|  | VisitNamedDecl(D); | 
|  | D->setInline(Record.readInt()); | 
|  | D->LocStart = ReadSourceLocation(); | 
|  | D->RBraceLoc = ReadSourceLocation(); | 
|  |  | 
|  | // Defer loading the anonymous namespace until we've finished merging | 
|  | // this namespace; loading it might load a later declaration of the | 
|  | // same namespace, and we have an invariant that older declarations | 
|  | // get merged before newer ones try to merge. | 
|  | GlobalDeclID AnonNamespace = 0; | 
|  | if (Redecl.getFirstID() == ThisDeclID) { | 
|  | AnonNamespace = ReadDeclID(); | 
|  | } else { | 
|  | // Link this namespace back to the first declaration, which has already | 
|  | // been deserialized. | 
|  | D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl()); | 
|  | } | 
|  |  | 
|  | mergeRedeclarable(D, Redecl); | 
|  |  | 
|  | if (AnonNamespace) { | 
|  | // Each module has its own anonymous namespace, which is disjoint from | 
|  | // any other module's anonymous namespaces, so don't attach the anonymous | 
|  | // namespace at all. | 
|  | auto *Anon = cast<NamespaceDecl>(Reader.GetDecl(AnonNamespace)); | 
|  | if (!Record.isModule()) | 
|  | D->setAnonymousNamespace(Anon); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(D); | 
|  | VisitNamedDecl(D); | 
|  | D->NamespaceLoc = ReadSourceLocation(); | 
|  | D->IdentLoc = ReadSourceLocation(); | 
|  | D->QualifierLoc = Record.readNestedNameSpecifierLoc(); | 
|  | D->Namespace = ReadDeclAs<NamedDecl>(); | 
|  | mergeRedeclarable(D, Redecl); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { | 
|  | VisitNamedDecl(D); | 
|  | D->setUsingLoc(ReadSourceLocation()); | 
|  | D->QualifierLoc = Record.readNestedNameSpecifierLoc(); | 
|  | ReadDeclarationNameLoc(D->DNLoc, D->getDeclName()); | 
|  | D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>()); | 
|  | D->setTypename(Record.readInt()); | 
|  | if (auto *Pattern = ReadDeclAs<NamedDecl>()) | 
|  | Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern); | 
|  | mergeMergeable(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitUsingPackDecl(UsingPackDecl *D) { | 
|  | VisitNamedDecl(D); | 
|  | D->InstantiatedFrom = ReadDeclAs<NamedDecl>(); | 
|  | auto **Expansions = D->getTrailingObjects<NamedDecl *>(); | 
|  | for (unsigned I = 0; I != D->NumExpansions; ++I) | 
|  | Expansions[I] = ReadDeclAs<NamedDecl>(); | 
|  | mergeMergeable(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(D); | 
|  | VisitNamedDecl(D); | 
|  | D->Underlying = ReadDeclAs<NamedDecl>(); | 
|  | D->IdentifierNamespace = Record.readInt(); | 
|  | D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(); | 
|  | auto *Pattern = ReadDeclAs<UsingShadowDecl>(); | 
|  | if (Pattern) | 
|  | Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern); | 
|  | mergeRedeclarable(D, Redecl); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitConstructorUsingShadowDecl( | 
|  | ConstructorUsingShadowDecl *D) { | 
|  | VisitUsingShadowDecl(D); | 
|  | D->NominatedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>(); | 
|  | D->ConstructedBaseClassShadowDecl = ReadDeclAs<ConstructorUsingShadowDecl>(); | 
|  | D->IsVirtual = Record.readInt(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { | 
|  | VisitNamedDecl(D); | 
|  | D->UsingLoc = ReadSourceLocation(); | 
|  | D->NamespaceLoc = ReadSourceLocation(); | 
|  | D->QualifierLoc = Record.readNestedNameSpecifierLoc(); | 
|  | D->NominatedNamespace = ReadDeclAs<NamedDecl>(); | 
|  | D->CommonAncestor = ReadDeclAs<DeclContext>(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { | 
|  | VisitValueDecl(D); | 
|  | D->setUsingLoc(ReadSourceLocation()); | 
|  | D->QualifierLoc = Record.readNestedNameSpecifierLoc(); | 
|  | ReadDeclarationNameLoc(D->DNLoc, D->getDeclName()); | 
|  | D->EllipsisLoc = ReadSourceLocation(); | 
|  | mergeMergeable(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitUnresolvedUsingTypenameDecl( | 
|  | UnresolvedUsingTypenameDecl *D) { | 
|  | VisitTypeDecl(D); | 
|  | D->TypenameLocation = ReadSourceLocation(); | 
|  | D->QualifierLoc = Record.readNestedNameSpecifierLoc(); | 
|  | D->EllipsisLoc = ReadSourceLocation(); | 
|  | mergeMergeable(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::ReadCXXDefinitionData( | 
|  | struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D) { | 
|  | #define FIELD(Name, Width, Merge) \ | 
|  | Data.Name = Record.readInt(); | 
|  | #include "clang/AST/CXXRecordDeclDefinitionBits.def" | 
|  |  | 
|  | // Note: the caller has deserialized the IsLambda bit already. | 
|  | Data.ODRHash = Record.readInt(); | 
|  | Data.HasODRHash = true; | 
|  |  | 
|  | if (Record.readInt()) | 
|  | Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile; | 
|  |  | 
|  | Data.NumBases = Record.readInt(); | 
|  | if (Data.NumBases) | 
|  | Data.Bases = ReadGlobalOffset(); | 
|  | Data.NumVBases = Record.readInt(); | 
|  | if (Data.NumVBases) | 
|  | Data.VBases = ReadGlobalOffset(); | 
|  |  | 
|  | Record.readUnresolvedSet(Data.Conversions); | 
|  | Data.ComputedVisibleConversions = Record.readInt(); | 
|  | if (Data.ComputedVisibleConversions) | 
|  | Record.readUnresolvedSet(Data.VisibleConversions); | 
|  | assert(Data.Definition && "Data.Definition should be already set!"); | 
|  | Data.FirstFriend = ReadDeclID(); | 
|  |  | 
|  | if (Data.IsLambda) { | 
|  | using Capture = LambdaCapture; | 
|  |  | 
|  | auto &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data); | 
|  | Lambda.Dependent = Record.readInt(); | 
|  | Lambda.IsGenericLambda = Record.readInt(); | 
|  | Lambda.CaptureDefault = Record.readInt(); | 
|  | Lambda.NumCaptures = Record.readInt(); | 
|  | Lambda.NumExplicitCaptures = Record.readInt(); | 
|  | Lambda.HasKnownInternalLinkage = Record.readInt(); | 
|  | Lambda.ManglingNumber = Record.readInt(); | 
|  | Lambda.ContextDecl = ReadDeclID(); | 
|  | Lambda.Captures = (Capture *)Reader.getContext().Allocate( | 
|  | sizeof(Capture) * Lambda.NumCaptures); | 
|  | Capture *ToCapture = Lambda.Captures; | 
|  | Lambda.MethodTyInfo = GetTypeSourceInfo(); | 
|  | for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { | 
|  | SourceLocation Loc = ReadSourceLocation(); | 
|  | bool IsImplicit = Record.readInt(); | 
|  | auto Kind = static_cast<LambdaCaptureKind>(Record.readInt()); | 
|  | switch (Kind) { | 
|  | case LCK_StarThis: | 
|  | case LCK_This: | 
|  | case LCK_VLAType: | 
|  | *ToCapture++ = Capture(Loc, IsImplicit, Kind, nullptr,SourceLocation()); | 
|  | break; | 
|  | case LCK_ByCopy: | 
|  | case LCK_ByRef: | 
|  | auto *Var = ReadDeclAs<VarDecl>(); | 
|  | SourceLocation EllipsisLoc = ReadSourceLocation(); | 
|  | *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::MergeDefinitionData( | 
|  | CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &&MergeDD) { | 
|  | assert(D->DefinitionData && | 
|  | "merging class definition into non-definition"); | 
|  | auto &DD = *D->DefinitionData; | 
|  |  | 
|  | if (DD.Definition != MergeDD.Definition) { | 
|  | // Track that we merged the definitions. | 
|  | Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition, | 
|  | DD.Definition)); | 
|  | Reader.PendingDefinitions.erase(MergeDD.Definition); | 
|  | MergeDD.Definition->setCompleteDefinition(false); | 
|  | Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition); | 
|  | assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() && | 
|  | "already loaded pending lookups for merged definition"); | 
|  | } | 
|  |  | 
|  | auto PFDI = Reader.PendingFakeDefinitionData.find(&DD); | 
|  | if (PFDI != Reader.PendingFakeDefinitionData.end() && | 
|  | PFDI->second == ASTReader::PendingFakeDefinitionKind::Fake) { | 
|  | // We faked up this definition data because we found a class for which we'd | 
|  | // not yet loaded the definition. Replace it with the real thing now. | 
|  | assert(!DD.IsLambda && !MergeDD.IsLambda && "faked up lambda definition?"); | 
|  | PFDI->second = ASTReader::PendingFakeDefinitionKind::FakeLoaded; | 
|  |  | 
|  | // Don't change which declaration is the definition; that is required | 
|  | // to be invariant once we select it. | 
|  | auto *Def = DD.Definition; | 
|  | DD = std::move(MergeDD); | 
|  | DD.Definition = Def; | 
|  | return; | 
|  | } | 
|  |  | 
|  | bool DetectedOdrViolation = false; | 
|  |  | 
|  | #define FIELD(Name, Width, Merge) Merge(Name) | 
|  | #define MERGE_OR(Field) DD.Field |= MergeDD.Field; | 
|  | #define NO_MERGE(Field) \ | 
|  | DetectedOdrViolation |= DD.Field != MergeDD.Field; \ | 
|  | MERGE_OR(Field) | 
|  | #include "clang/AST/CXXRecordDeclDefinitionBits.def" | 
|  | NO_MERGE(IsLambda) | 
|  | #undef NO_MERGE | 
|  | #undef MERGE_OR | 
|  |  | 
|  | if (DD.NumBases != MergeDD.NumBases || DD.NumVBases != MergeDD.NumVBases) | 
|  | DetectedOdrViolation = true; | 
|  | // FIXME: Issue a diagnostic if the base classes don't match when we come | 
|  | // to lazily load them. | 
|  |  | 
|  | // FIXME: Issue a diagnostic if the list of conversion functions doesn't | 
|  | // match when we come to lazily load them. | 
|  | if (MergeDD.ComputedVisibleConversions && !DD.ComputedVisibleConversions) { | 
|  | DD.VisibleConversions = std::move(MergeDD.VisibleConversions); | 
|  | DD.ComputedVisibleConversions = true; | 
|  | } | 
|  |  | 
|  | // FIXME: Issue a diagnostic if FirstFriend doesn't match when we come to | 
|  | // lazily load it. | 
|  |  | 
|  | if (DD.IsLambda) { | 
|  | // FIXME: ODR-checking for merging lambdas (this happens, for instance, | 
|  | // when they occur within the body of a function template specialization). | 
|  | } | 
|  |  | 
|  | if (D->getODRHash() != MergeDD.ODRHash) { | 
|  | DetectedOdrViolation = true; | 
|  | } | 
|  |  | 
|  | if (DetectedOdrViolation) | 
|  | Reader.PendingOdrMergeFailures[DD.Definition].push_back( | 
|  | {MergeDD.Definition, &MergeDD}); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update) { | 
|  | struct CXXRecordDecl::DefinitionData *DD; | 
|  | ASTContext &C = Reader.getContext(); | 
|  |  | 
|  | // Determine whether this is a lambda closure type, so that we can | 
|  | // allocate the appropriate DefinitionData structure. | 
|  | bool IsLambda = Record.readInt(); | 
|  | if (IsLambda) | 
|  | DD = new (C) CXXRecordDecl::LambdaDefinitionData(D, nullptr, false, false, | 
|  | LCD_None); | 
|  | else | 
|  | DD = new (C) struct CXXRecordDecl::DefinitionData(D); | 
|  |  | 
|  | CXXRecordDecl *Canon = D->getCanonicalDecl(); | 
|  | // Set decl definition data before reading it, so that during deserialization | 
|  | // when we read CXXRecordDecl, it already has definition data and we don't | 
|  | // set fake one. | 
|  | if (!Canon->DefinitionData) | 
|  | Canon->DefinitionData = DD; | 
|  | D->DefinitionData = Canon->DefinitionData; | 
|  | ReadCXXDefinitionData(*DD, D); | 
|  |  | 
|  | // We might already have a different definition for this record. This can | 
|  | // happen either because we're reading an update record, or because we've | 
|  | // already done some merging. Either way, just merge into it. | 
|  | if (Canon->DefinitionData != DD) { | 
|  | MergeDefinitionData(Canon, std::move(*DD)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Mark this declaration as being a definition. | 
|  | D->setCompleteDefinition(true); | 
|  |  | 
|  | // If this is not the first declaration or is an update record, we can have | 
|  | // other redeclarations already. Make a note that we need to propagate the | 
|  | // DefinitionData pointer onto them. | 
|  | if (Update || Canon != D) | 
|  | Reader.PendingDefinitions.insert(D); | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRecordDeclImpl(D); | 
|  |  | 
|  | ASTContext &C = Reader.getContext(); | 
|  |  | 
|  | enum CXXRecKind { | 
|  | CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization | 
|  | }; | 
|  | switch ((CXXRecKind)Record.readInt()) { | 
|  | case CXXRecNotTemplate: | 
|  | // Merged when we merge the folding set entry in the primary template. | 
|  | if (!isa<ClassTemplateSpecializationDecl>(D)) | 
|  | mergeRedeclarable(D, Redecl); | 
|  | break; | 
|  | case CXXRecTemplate: { | 
|  | // Merged when we merge the template. | 
|  | auto *Template = ReadDeclAs<ClassTemplateDecl>(); | 
|  | D->TemplateOrInstantiation = Template; | 
|  | if (!Template->getTemplatedDecl()) { | 
|  | // We've not actually loaded the ClassTemplateDecl yet, because we're | 
|  | // currently being loaded as its pattern. Rely on it to set up our | 
|  | // TypeForDecl (see VisitClassTemplateDecl). | 
|  | // | 
|  | // Beware: we do not yet know our canonical declaration, and may still | 
|  | // get merged once the surrounding class template has got off the ground. | 
|  | DeferredTypeID = 0; | 
|  | } | 
|  | break; | 
|  | } | 
|  | case CXXRecMemberSpecialization: { | 
|  | auto *RD = ReadDeclAs<CXXRecordDecl>(); | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  | MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK); | 
|  | MSI->setPointOfInstantiation(POI); | 
|  | D->TemplateOrInstantiation = MSI; | 
|  | mergeRedeclarable(D, Redecl); | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool WasDefinition = Record.readInt(); | 
|  | if (WasDefinition) | 
|  | ReadCXXRecordDefinition(D, /*Update*/false); | 
|  | else | 
|  | // Propagate DefinitionData pointer from the canonical declaration. | 
|  | D->DefinitionData = D->getCanonicalDecl()->DefinitionData; | 
|  |  | 
|  | // Lazily load the key function to avoid deserializing every method so we can | 
|  | // compute it. | 
|  | if (WasDefinition) { | 
|  | DeclID KeyFn = ReadDeclID(); | 
|  | if (KeyFn && D->isCompleteDefinition()) | 
|  | // FIXME: This is wrong for the ARM ABI, where some other module may have | 
|  | // made this function no longer be a key function. We need an update | 
|  | // record or similar for that case. | 
|  | C.KeyFunctions[D] = KeyFn; | 
|  | } | 
|  |  | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { | 
|  | D->setExplicitSpecifier(Record.readExplicitSpec()); | 
|  | VisitFunctionDecl(D); | 
|  | D->setIsCopyDeductionCandidate(Record.readInt()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { | 
|  | VisitFunctionDecl(D); | 
|  |  | 
|  | unsigned NumOverridenMethods = Record.readInt(); | 
|  | if (D->isCanonicalDecl()) { | 
|  | while (NumOverridenMethods--) { | 
|  | // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod, | 
|  | // MD may be initializing. | 
|  | if (auto *MD = ReadDeclAs<CXXMethodDecl>()) | 
|  | Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl()); | 
|  | } | 
|  | } else { | 
|  | // We don't care about which declarations this used to override; we get | 
|  | // the relevant information from the canonical declaration. | 
|  | Record.skipInts(NumOverridenMethods); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { | 
|  | // We need the inherited constructor information to merge the declaration, | 
|  | // so we have to read it before we call VisitCXXMethodDecl. | 
|  | D->setExplicitSpecifier(Record.readExplicitSpec()); | 
|  | if (D->isInheritingConstructor()) { | 
|  | auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>(); | 
|  | auto *Ctor = ReadDeclAs<CXXConstructorDecl>(); | 
|  | *D->getTrailingObjects<InheritedConstructor>() = | 
|  | InheritedConstructor(Shadow, Ctor); | 
|  | } | 
|  |  | 
|  | VisitCXXMethodDecl(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { | 
|  | VisitCXXMethodDecl(D); | 
|  |  | 
|  | if (auto *OperatorDelete = ReadDeclAs<FunctionDecl>()) { | 
|  | CXXDestructorDecl *Canon = D->getCanonicalDecl(); | 
|  | auto *ThisArg = Record.readExpr(); | 
|  | // FIXME: Check consistency if we have an old and new operator delete. | 
|  | if (!Canon->OperatorDelete) { | 
|  | Canon->OperatorDelete = OperatorDelete; | 
|  | Canon->OperatorDeleteThisArg = ThisArg; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { | 
|  | D->setExplicitSpecifier(Record.readExplicitSpec()); | 
|  | VisitCXXMethodDecl(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitImportDecl(ImportDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->ImportedAndComplete.setPointer(readModule()); | 
|  | D->ImportedAndComplete.setInt(Record.readInt()); | 
|  | auto *StoredLocs = D->getTrailingObjects<SourceLocation>(); | 
|  | for (unsigned I = 0, N = Record.back(); I != N; ++I) | 
|  | StoredLocs[I] = ReadSourceLocation(); | 
|  | Record.skipInts(1); // The number of stored source locations. | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->setColonLoc(ReadSourceLocation()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { | 
|  | VisitDecl(D); | 
|  | if (Record.readInt()) // hasFriendDecl | 
|  | D->Friend = ReadDeclAs<NamedDecl>(); | 
|  | else | 
|  | D->Friend = GetTypeSourceInfo(); | 
|  | for (unsigned i = 0; i != D->NumTPLists; ++i) | 
|  | D->getTrailingObjects<TemplateParameterList *>()[i] = | 
|  | Record.readTemplateParameterList(); | 
|  | D->NextFriend = ReadDeclID(); | 
|  | D->UnsupportedFriend = (Record.readInt() != 0); | 
|  | D->FriendLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) { | 
|  | VisitDecl(D); | 
|  | unsigned NumParams = Record.readInt(); | 
|  | D->NumParams = NumParams; | 
|  | D->Params = new TemplateParameterList*[NumParams]; | 
|  | for (unsigned i = 0; i != NumParams; ++i) | 
|  | D->Params[i] = Record.readTemplateParameterList(); | 
|  | if (Record.readInt()) // HasFriendDecl | 
|  | D->Friend = ReadDeclAs<NamedDecl>(); | 
|  | else | 
|  | D->Friend = GetTypeSourceInfo(); | 
|  | D->FriendLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { | 
|  | VisitNamedDecl(D); | 
|  |  | 
|  | DeclID PatternID = ReadDeclID(); | 
|  | auto *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID)); | 
|  | TemplateParameterList *TemplateParams = Record.readTemplateParameterList(); | 
|  | D->init(TemplatedDecl, TemplateParams); | 
|  |  | 
|  | return PatternID; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) { | 
|  | VisitTemplateDecl(D); | 
|  | D->ConstraintExpr = Record.readExpr(); | 
|  | mergeMergeable(D); | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarable(D); | 
|  |  | 
|  | // Make sure we've allocated the Common pointer first. We do this before | 
|  | // VisitTemplateDecl so that getCommonPtr() can be used during initialization. | 
|  | RedeclarableTemplateDecl *CanonD = D->getCanonicalDecl(); | 
|  | if (!CanonD->Common) { | 
|  | CanonD->Common = CanonD->newCommon(Reader.getContext()); | 
|  | Reader.PendingDefinitions.insert(CanonD); | 
|  | } | 
|  | D->Common = CanonD->Common; | 
|  |  | 
|  | // If this is the first declaration of the template, fill in the information | 
|  | // for the 'common' pointer. | 
|  | if (ThisDeclID == Redecl.getFirstID()) { | 
|  | if (auto *RTD = ReadDeclAs<RedeclarableTemplateDecl>()) { | 
|  | assert(RTD->getKind() == D->getKind() && | 
|  | "InstantiatedFromMemberTemplate kind mismatch"); | 
|  | D->setInstantiatedFromMemberTemplate(RTD); | 
|  | if (Record.readInt()) | 
|  | D->setMemberSpecialization(); | 
|  | } | 
|  | } | 
|  |  | 
|  | DeclID PatternID = VisitTemplateDecl(D); | 
|  | D->IdentifierNamespace = Record.readInt(); | 
|  |  | 
|  | mergeRedeclarable(D, Redecl, PatternID); | 
|  |  | 
|  | // If we merged the template with a prior declaration chain, merge the common | 
|  | // pointer. | 
|  | // FIXME: Actually merge here, don't just overwrite. | 
|  | D->Common = D->getCanonicalDecl()->Common; | 
|  |  | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); | 
|  |  | 
|  | if (ThisDeclID == Redecl.getFirstID()) { | 
|  | // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of | 
|  | // the specializations. | 
|  | SmallVector<serialization::DeclID, 32> SpecIDs; | 
|  | ReadDeclIDList(SpecIDs); | 
|  | ASTDeclReader::AddLazySpecializations(D, SpecIDs); | 
|  | } | 
|  |  | 
|  | if (D->getTemplatedDecl()->TemplateOrInstantiation) { | 
|  | // We were loaded before our templated declaration was. We've not set up | 
|  | // its corresponding type yet (see VisitCXXRecordDeclImpl), so reconstruct | 
|  | // it now. | 
|  | Reader.getContext().getInjectedClassNameType( | 
|  | D->getTemplatedDecl(), D->getInjectedClassNameSpecialization()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) { | 
|  | llvm_unreachable("BuiltinTemplates are not serialized"); | 
|  | } | 
|  |  | 
|  | /// TODO: Unify with ClassTemplateDecl version? | 
|  | ///       May require unifying ClassTemplateDecl and | 
|  | ///        VarTemplateDecl beyond TemplateDecl... | 
|  | void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); | 
|  |  | 
|  | if (ThisDeclID == Redecl.getFirstID()) { | 
|  | // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of | 
|  | // the specializations. | 
|  | SmallVector<serialization::DeclID, 32> SpecIDs; | 
|  | ReadDeclIDList(SpecIDs); | 
|  | ASTDeclReader::AddLazySpecializations(D, SpecIDs); | 
|  | } | 
|  | } | 
|  |  | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( | 
|  | ClassTemplateSpecializationDecl *D) { | 
|  | RedeclarableResult Redecl = VisitCXXRecordDeclImpl(D); | 
|  |  | 
|  | ASTContext &C = Reader.getContext(); | 
|  | if (Decl *InstD = ReadDecl()) { | 
|  | if (auto *CTD = dyn_cast<ClassTemplateDecl>(InstD)) { | 
|  | D->SpecializedTemplate = CTD; | 
|  | } else { | 
|  | SmallVector<TemplateArgument, 8> TemplArgs; | 
|  | Record.readTemplateArgumentList(TemplArgs); | 
|  | TemplateArgumentList *ArgList | 
|  | = TemplateArgumentList::CreateCopy(C, TemplArgs); | 
|  | auto *PS = | 
|  | new (C) ClassTemplateSpecializationDecl:: | 
|  | SpecializedPartialSpecialization(); | 
|  | PS->PartialSpecialization | 
|  | = cast<ClassTemplatePartialSpecializationDecl>(InstD); | 
|  | PS->TemplateArgs = ArgList; | 
|  | D->SpecializedTemplate = PS; | 
|  | } | 
|  | } | 
|  |  | 
|  | SmallVector<TemplateArgument, 8> TemplArgs; | 
|  | Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); | 
|  | D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs); | 
|  | D->PointOfInstantiation = ReadSourceLocation(); | 
|  | D->SpecializationKind = (TemplateSpecializationKind)Record.readInt(); | 
|  |  | 
|  | bool writtenAsCanonicalDecl = Record.readInt(); | 
|  | if (writtenAsCanonicalDecl) { | 
|  | auto *CanonPattern = ReadDeclAs<ClassTemplateDecl>(); | 
|  | if (D->isCanonicalDecl()) { // It's kept in the folding set. | 
|  | // Set this as, or find, the canonical declaration for this specialization | 
|  | ClassTemplateSpecializationDecl *CanonSpec; | 
|  | if (auto *Partial = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { | 
|  | CanonSpec = CanonPattern->getCommonPtr()->PartialSpecializations | 
|  | .GetOrInsertNode(Partial); | 
|  | } else { | 
|  | CanonSpec = | 
|  | CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); | 
|  | } | 
|  | // If there was already a canonical specialization, merge into it. | 
|  | if (CanonSpec != D) { | 
|  | mergeRedeclarable<TagDecl>(D, CanonSpec, Redecl); | 
|  |  | 
|  | // This declaration might be a definition. Merge with any existing | 
|  | // definition. | 
|  | if (auto *DDD = D->DefinitionData) { | 
|  | if (CanonSpec->DefinitionData) | 
|  | MergeDefinitionData(CanonSpec, std::move(*DDD)); | 
|  | else | 
|  | CanonSpec->DefinitionData = D->DefinitionData; | 
|  | } | 
|  | D->DefinitionData = CanonSpec->DefinitionData; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // Explicit info. | 
|  | if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) { | 
|  | auto *ExplicitInfo = | 
|  | new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; | 
|  | ExplicitInfo->TypeAsWritten = TyInfo; | 
|  | ExplicitInfo->ExternLoc = ReadSourceLocation(); | 
|  | ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(); | 
|  | D->ExplicitInfo = ExplicitInfo; | 
|  | } | 
|  |  | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( | 
|  | ClassTemplatePartialSpecializationDecl *D) { | 
|  | RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D); | 
|  |  | 
|  | TemplateParameterList *Params = Record.readTemplateParameterList(); | 
|  | D->TemplateParams = Params; | 
|  | D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); | 
|  |  | 
|  | // These are read/set from/to the first declaration. | 
|  | if (ThisDeclID == Redecl.getFirstID()) { | 
|  | D->InstantiatedFromMember.setPointer( | 
|  | ReadDeclAs<ClassTemplatePartialSpecializationDecl>()); | 
|  | D->InstantiatedFromMember.setInt(Record.readInt()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl( | 
|  | ClassScopeFunctionSpecializationDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->Specialization = ReadDeclAs<CXXMethodDecl>(); | 
|  | if (Record.readInt()) | 
|  | D->TemplateArgs = Record.readASTTemplateArgumentListInfo(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { | 
|  | RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); | 
|  |  | 
|  | if (ThisDeclID == Redecl.getFirstID()) { | 
|  | // This FunctionTemplateDecl owns a CommonPtr; read it. | 
|  | SmallVector<serialization::DeclID, 32> SpecIDs; | 
|  | ReadDeclIDList(SpecIDs); | 
|  | ASTDeclReader::AddLazySpecializations(D, SpecIDs); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// TODO: Unify with ClassTemplateSpecializationDecl version? | 
|  | ///       May require unifying ClassTemplate(Partial)SpecializationDecl and | 
|  | ///        VarTemplate(Partial)SpecializationDecl with a new data | 
|  | ///        structure Template(Partial)SpecializationDecl, and | 
|  | ///        using Template(Partial)SpecializationDecl as input type. | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( | 
|  | VarTemplateSpecializationDecl *D) { | 
|  | RedeclarableResult Redecl = VisitVarDeclImpl(D); | 
|  |  | 
|  | ASTContext &C = Reader.getContext(); | 
|  | if (Decl *InstD = ReadDecl()) { | 
|  | if (auto *VTD = dyn_cast<VarTemplateDecl>(InstD)) { | 
|  | D->SpecializedTemplate = VTD; | 
|  | } else { | 
|  | SmallVector<TemplateArgument, 8> TemplArgs; | 
|  | Record.readTemplateArgumentList(TemplArgs); | 
|  | TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy( | 
|  | C, TemplArgs); | 
|  | auto *PS = | 
|  | new (C) | 
|  | VarTemplateSpecializationDecl::SpecializedPartialSpecialization(); | 
|  | PS->PartialSpecialization = | 
|  | cast<VarTemplatePartialSpecializationDecl>(InstD); | 
|  | PS->TemplateArgs = ArgList; | 
|  | D->SpecializedTemplate = PS; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Explicit info. | 
|  | if (TypeSourceInfo *TyInfo = GetTypeSourceInfo()) { | 
|  | auto *ExplicitInfo = | 
|  | new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo; | 
|  | ExplicitInfo->TypeAsWritten = TyInfo; | 
|  | ExplicitInfo->ExternLoc = ReadSourceLocation(); | 
|  | ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(); | 
|  | D->ExplicitInfo = ExplicitInfo; | 
|  | } | 
|  |  | 
|  | SmallVector<TemplateArgument, 8> TemplArgs; | 
|  | Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); | 
|  | D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs); | 
|  | D->PointOfInstantiation = ReadSourceLocation(); | 
|  | D->SpecializationKind = (TemplateSpecializationKind)Record.readInt(); | 
|  | D->IsCompleteDefinition = Record.readInt(); | 
|  |  | 
|  | bool writtenAsCanonicalDecl = Record.readInt(); | 
|  | if (writtenAsCanonicalDecl) { | 
|  | auto *CanonPattern = ReadDeclAs<VarTemplateDecl>(); | 
|  | if (D->isCanonicalDecl()) { // It's kept in the folding set. | 
|  | // FIXME: If it's already present, merge it. | 
|  | if (auto *Partial = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { | 
|  | CanonPattern->getCommonPtr()->PartialSpecializations | 
|  | .GetOrInsertNode(Partial); | 
|  | } else { | 
|  | CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return Redecl; | 
|  | } | 
|  |  | 
|  | /// TODO: Unify with ClassTemplatePartialSpecializationDecl version? | 
|  | ///       May require unifying ClassTemplate(Partial)SpecializationDecl and | 
|  | ///        VarTemplate(Partial)SpecializationDecl with a new data | 
|  | ///        structure Template(Partial)SpecializationDecl, and | 
|  | ///        using Template(Partial)SpecializationDecl as input type. | 
|  | void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl( | 
|  | VarTemplatePartialSpecializationDecl *D) { | 
|  | RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D); | 
|  |  | 
|  | TemplateParameterList *Params = Record.readTemplateParameterList(); | 
|  | D->TemplateParams = Params; | 
|  | D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); | 
|  |  | 
|  | // These are read/set from/to the first declaration. | 
|  | if (ThisDeclID == Redecl.getFirstID()) { | 
|  | D->InstantiatedFromMember.setPointer( | 
|  | ReadDeclAs<VarTemplatePartialSpecializationDecl>()); | 
|  | D->InstantiatedFromMember.setInt(Record.readInt()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { | 
|  | VisitTypeDecl(D); | 
|  |  | 
|  | D->setDeclaredWithTypename(Record.readInt()); | 
|  |  | 
|  | // TODO: Concepts: Immediately introduced constraint | 
|  | if (Record.readInt()) | 
|  | D->setDefaultArgument(GetTypeSourceInfo()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { | 
|  | VisitDeclaratorDecl(D); | 
|  | // TemplateParmPosition. | 
|  | D->setDepth(Record.readInt()); | 
|  | D->setPosition(Record.readInt()); | 
|  | if (D->isExpandedParameterPack()) { | 
|  | auto TypesAndInfos = | 
|  | D->getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); | 
|  | for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { | 
|  | new (&TypesAndInfos[I].first) QualType(Record.readType()); | 
|  | TypesAndInfos[I].second = GetTypeSourceInfo(); | 
|  | } | 
|  | } else { | 
|  | // Rest of NonTypeTemplateParmDecl. | 
|  | D->ParameterPack = Record.readInt(); | 
|  | if (Record.readInt()) | 
|  | D->setDefaultArgument(Record.readExpr()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { | 
|  | VisitTemplateDecl(D); | 
|  | // TemplateParmPosition. | 
|  | D->setDepth(Record.readInt()); | 
|  | D->setPosition(Record.readInt()); | 
|  | if (D->isExpandedParameterPack()) { | 
|  | auto **Data = D->getTrailingObjects<TemplateParameterList *>(); | 
|  | for (unsigned I = 0, N = D->getNumExpansionTemplateParameters(); | 
|  | I != N; ++I) | 
|  | Data[I] = Record.readTemplateParameterList(); | 
|  | } else { | 
|  | // Rest of TemplateTemplateParmDecl. | 
|  | D->ParameterPack = Record.readInt(); | 
|  | if (Record.readInt()) | 
|  | D->setDefaultArgument(Reader.getContext(), | 
|  | Record.readTemplateArgumentLoc()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { | 
|  | VisitRedeclarableTemplateDecl(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->AssertExprAndFailed.setPointer(Record.readExpr()); | 
|  | D->AssertExprAndFailed.setInt(Record.readInt()); | 
|  | D->Message = cast_or_null<StringLiteral>(Record.readExpr()); | 
|  | D->RParenLoc = ReadSourceLocation(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) { | 
|  | VisitDecl(D); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitLifetimeExtendedTemporaryDecl( | 
|  | LifetimeExtendedTemporaryDecl *D) { | 
|  | VisitDecl(D); | 
|  | D->ExtendingDecl = ReadDeclAs<ValueDecl>(); | 
|  | D->ExprWithTemporary = Record.readStmt(); | 
|  | if (Record.readInt()) | 
|  | D->Value = new (D->getASTContext()) APValue(Record.readAPValue()); | 
|  | D->ManglingNumber = Record.readInt(); | 
|  | mergeMergeable(D); | 
|  | } | 
|  |  | 
|  | std::pair<uint64_t, uint64_t> | 
|  | ASTDeclReader::VisitDeclContext(DeclContext *DC) { | 
|  | uint64_t LexicalOffset = ReadLocalOffset(); | 
|  | uint64_t VisibleOffset = ReadLocalOffset(); | 
|  | return std::make_pair(LexicalOffset, VisibleOffset); | 
|  | } | 
|  |  | 
|  | template <typename T> | 
|  | ASTDeclReader::RedeclarableResult | 
|  | ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { | 
|  | DeclID FirstDeclID = ReadDeclID(); | 
|  | Decl *MergeWith = nullptr; | 
|  |  | 
|  | bool IsKeyDecl = ThisDeclID == FirstDeclID; | 
|  | bool IsFirstLocalDecl = false; | 
|  |  | 
|  | uint64_t RedeclOffset = 0; | 
|  |  | 
|  | // 0 indicates that this declaration was the only declaration of its entity, | 
|  | // and is used for space optimization. | 
|  | if (FirstDeclID == 0) { | 
|  | FirstDeclID = ThisDeclID; | 
|  | IsKeyDecl = true; | 
|  | IsFirstLocalDecl = true; | 
|  | } else if (unsigned N = Record.readInt()) { | 
|  | // This declaration was the first local declaration, but may have imported | 
|  | // other declarations. | 
|  | IsKeyDecl = N == 1; | 
|  | IsFirstLocalDecl = true; | 
|  |  | 
|  | // We have some declarations that must be before us in our redeclaration | 
|  | // chain. Read them now, and remember that we ought to merge with one of | 
|  | // them. | 
|  | // FIXME: Provide a known merge target to the second and subsequent such | 
|  | // declaration. | 
|  | for (unsigned I = 0; I != N - 1; ++I) | 
|  | MergeWith = ReadDecl(); | 
|  |  | 
|  | RedeclOffset = ReadLocalOffset(); | 
|  | } else { | 
|  | // This declaration was not the first local declaration. Read the first | 
|  | // local declaration now, to trigger the import of other redeclarations. | 
|  | (void)ReadDecl(); | 
|  | } | 
|  |  | 
|  | auto *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID)); | 
|  | if (FirstDecl != D) { | 
|  | // We delay loading of the redeclaration chain to avoid deeply nested calls. | 
|  | // We temporarily set the first (canonical) declaration as the previous one | 
|  | // which is the one that matters and mark the real previous DeclID to be | 
|  | // loaded & attached later on. | 
|  | D->RedeclLink = Redeclarable<T>::PreviousDeclLink(FirstDecl); | 
|  | D->First = FirstDecl->getCanonicalDecl(); | 
|  | } | 
|  |  | 
|  | auto *DAsT = static_cast<T *>(D); | 
|  |  | 
|  | // Note that we need to load local redeclarations of this decl and build a | 
|  | // decl chain for them. This must happen *after* we perform the preloading | 
|  | // above; this ensures that the redeclaration chain is built in the correct | 
|  | // order. | 
|  | if (IsFirstLocalDecl) | 
|  | Reader.PendingDeclChains.push_back(std::make_pair(DAsT, RedeclOffset)); | 
|  |  | 
|  | return RedeclarableResult(MergeWith, FirstDeclID, IsKeyDecl); | 
|  | } | 
|  |  | 
|  | /// Attempts to merge the given declaration (D) with another declaration | 
|  | /// of the same entity. | 
|  | template<typename T> | 
|  | void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, | 
|  | RedeclarableResult &Redecl, | 
|  | DeclID TemplatePatternID) { | 
|  | // If modules are not available, there is no reason to perform this merge. | 
|  | if (!Reader.getContext().getLangOpts().Modules) | 
|  | return; | 
|  |  | 
|  | // If we're not the canonical declaration, we don't need to merge. | 
|  | if (!DBase->isFirstDecl()) | 
|  | return; | 
|  |  | 
|  | auto *D = static_cast<T *>(DBase); | 
|  |  | 
|  | if (auto *Existing = Redecl.getKnownMergeTarget()) | 
|  | // We already know of an existing declaration we should merge with. | 
|  | mergeRedeclarable(D, cast<T>(Existing), Redecl, TemplatePatternID); | 
|  | else if (FindExistingResult ExistingRes = findExisting(D)) | 
|  | if (T *Existing = ExistingRes) | 
|  | mergeRedeclarable(D, Existing, Redecl, TemplatePatternID); | 
|  | } | 
|  |  | 
|  | /// "Cast" to type T, asserting if we don't have an implicit conversion. | 
|  | /// We use this to put code in a template that will only be valid for certain | 
|  | /// instantiations. | 
|  | template<typename T> static T assert_cast(T t) { return t; } | 
|  | template<typename T> static T assert_cast(...) { | 
|  | llvm_unreachable("bad assert_cast"); | 
|  | } | 
|  |  | 
|  | /// Merge together the pattern declarations from two template | 
|  | /// declarations. | 
|  | void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, | 
|  | RedeclarableTemplateDecl *Existing, | 
|  | DeclID DsID, bool IsKeyDecl) { | 
|  | auto *DPattern = D->getTemplatedDecl(); | 
|  | auto *ExistingPattern = Existing->getTemplatedDecl(); | 
|  | RedeclarableResult Result(/*MergeWith*/ ExistingPattern, | 
|  | DPattern->getCanonicalDecl()->getGlobalID(), | 
|  | IsKeyDecl); | 
|  |  | 
|  | if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) { | 
|  | // Merge with any existing definition. | 
|  | // FIXME: This is duplicated in several places. Refactor. | 
|  | auto *ExistingClass = | 
|  | cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl(); | 
|  | if (auto *DDD = DClass->DefinitionData) { | 
|  | if (ExistingClass->DefinitionData) { | 
|  | MergeDefinitionData(ExistingClass, std::move(*DDD)); | 
|  | } else { | 
|  | ExistingClass->DefinitionData = DClass->DefinitionData; | 
|  | // We may have skipped this before because we thought that DClass | 
|  | // was the canonical declaration. | 
|  | Reader.PendingDefinitions.insert(DClass); | 
|  | } | 
|  | } | 
|  | DClass->DefinitionData = ExistingClass->DefinitionData; | 
|  |  | 
|  | return mergeRedeclarable(DClass, cast<TagDecl>(ExistingPattern), | 
|  | Result); | 
|  | } | 
|  | if (auto *DFunction = dyn_cast<FunctionDecl>(DPattern)) | 
|  | return mergeRedeclarable(DFunction, cast<FunctionDecl>(ExistingPattern), | 
|  | Result); | 
|  | if (auto *DVar = dyn_cast<VarDecl>(DPattern)) | 
|  | return mergeRedeclarable(DVar, cast<VarDecl>(ExistingPattern), Result); | 
|  | if (auto *DAlias = dyn_cast<TypeAliasDecl>(DPattern)) | 
|  | return mergeRedeclarable(DAlias, cast<TypedefNameDecl>(ExistingPattern), | 
|  | Result); | 
|  | llvm_unreachable("merged an unknown kind of redeclarable template"); | 
|  | } | 
|  |  | 
|  | /// Attempts to merge the given declaration (D) with another declaration | 
|  | /// of the same entity. | 
|  | template<typename T> | 
|  | void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing, | 
|  | RedeclarableResult &Redecl, | 
|  | DeclID TemplatePatternID) { | 
|  | auto *D = static_cast<T *>(DBase); | 
|  | T *ExistingCanon = Existing->getCanonicalDecl(); | 
|  | T *DCanon = D->getCanonicalDecl(); | 
|  | if (ExistingCanon != DCanon) { | 
|  | assert(DCanon->getGlobalID() == Redecl.getFirstID() && | 
|  | "already merged this declaration"); | 
|  |  | 
|  | // Have our redeclaration link point back at the canonical declaration | 
|  | // of the existing declaration, so that this declaration has the | 
|  | // appropriate canonical declaration. | 
|  | D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon); | 
|  | D->First = ExistingCanon; | 
|  | ExistingCanon->Used |= D->Used; | 
|  | D->Used = false; | 
|  |  | 
|  | // When we merge a namespace, update its pointer to the first namespace. | 
|  | // We cannot have loaded any redeclarations of this declaration yet, so | 
|  | // there's nothing else that needs to be updated. | 
|  | if (auto *Namespace = dyn_cast<NamespaceDecl>(D)) | 
|  | Namespace->AnonOrFirstNamespaceAndInline.setPointer( | 
|  | assert_cast<NamespaceDecl*>(ExistingCanon)); | 
|  |  | 
|  | // When we merge a template, merge its pattern. | 
|  | if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D)) | 
|  | mergeTemplatePattern( | 
|  | DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon), | 
|  | TemplatePatternID, Redecl.isKeyDecl()); | 
|  |  | 
|  | // If this declaration is a key declaration, make a note of that. | 
|  | if (Redecl.isKeyDecl()) | 
|  | Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID()); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// ODR-like semantics for C/ObjC allow us to merge tag types and a structural | 
|  | /// check in Sema guarantees the types can be merged (see C11 6.2.7/1 or C89 | 
|  | /// 6.1.2.6/1). Although most merging is done in Sema, we need to guarantee | 
|  | /// that some types are mergeable during deserialization, otherwise name | 
|  | /// lookup fails. This is the case for EnumConstantDecl. | 
|  | static bool allowODRLikeMergeInC(NamedDecl *ND) { | 
|  | if (!ND) | 
|  | return false; | 
|  | // TODO: implement merge for other necessary decls. | 
|  | if (isa<EnumConstantDecl>(ND)) | 
|  | return true; | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Attempts to merge LifetimeExtendedTemporaryDecl with | 
|  | /// identical class definitions from two different modules. | 
|  | void ASTDeclReader::mergeMergeable(LifetimeExtendedTemporaryDecl *D) { | 
|  | // If modules are not available, there is no reason to perform this merge. | 
|  | if (!Reader.getContext().getLangOpts().Modules) | 
|  | return; | 
|  |  | 
|  | LifetimeExtendedTemporaryDecl *LETDecl = D; | 
|  |  | 
|  | LifetimeExtendedTemporaryDecl *&LookupResult = | 
|  | Reader.LETemporaryForMerging[std::make_pair( | 
|  | LETDecl->getExtendingDecl(), LETDecl->getManglingNumber())]; | 
|  | if (LookupResult) | 
|  | Reader.getContext().setPrimaryMergedDecl(LETDecl, | 
|  | LookupResult->getCanonicalDecl()); | 
|  | else | 
|  | LookupResult = LETDecl; | 
|  | } | 
|  |  | 
|  | /// Attempts to merge the given declaration (D) with another declaration | 
|  | /// of the same entity, for the case where the entity is not actually | 
|  | /// redeclarable. This happens, for instance, when merging the fields of | 
|  | /// identical class definitions from two different modules. | 
|  | template<typename T> | 
|  | void ASTDeclReader::mergeMergeable(Mergeable<T> *D) { | 
|  | // If modules are not available, there is no reason to perform this merge. | 
|  | if (!Reader.getContext().getLangOpts().Modules) | 
|  | return; | 
|  |  | 
|  | // ODR-based merging is performed in C++ and in some cases (tag types) in C. | 
|  | // Note that C identically-named things in different translation units are | 
|  | // not redeclarations, but may still have compatible types, where ODR-like | 
|  | // semantics may apply. | 
|  | if (!Reader.getContext().getLangOpts().CPlusPlus && | 
|  | !allowODRLikeMergeInC(dyn_cast<NamedDecl>(static_cast<T*>(D)))) | 
|  | return; | 
|  |  | 
|  | if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D))) | 
|  | if (T *Existing = ExistingRes) | 
|  | Reader.getContext().setPrimaryMergedDecl(static_cast<T *>(D), | 
|  | Existing->getCanonicalDecl()); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { | 
|  | VisitDecl(D); | 
|  | unsigned NumVars = D->varlist_size(); | 
|  | SmallVector<Expr *, 16> Vars; | 
|  | Vars.reserve(NumVars); | 
|  | for (unsigned i = 0; i != NumVars; ++i) { | 
|  | Vars.push_back(Record.readExpr()); | 
|  | } | 
|  | D->setVars(Vars); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) { | 
|  | VisitDecl(D); | 
|  | unsigned NumVars = D->varlist_size(); | 
|  | unsigned NumClauses = D->clauselist_size(); | 
|  | SmallVector<Expr *, 16> Vars; | 
|  | Vars.reserve(NumVars); | 
|  | for (unsigned i = 0; i != NumVars; ++i) { | 
|  | Vars.push_back(Record.readExpr()); | 
|  | } | 
|  | D->setVars(Vars); | 
|  | SmallVector<OMPClause *, 8> Clauses; | 
|  | Clauses.reserve(NumClauses); | 
|  | OMPClauseReader ClauseReader(Record); | 
|  | for (unsigned I = 0; I != NumClauses; ++I) | 
|  | Clauses.push_back(ClauseReader.readClause()); | 
|  | D->setClauses(Clauses); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) { | 
|  | VisitDecl(D); | 
|  | unsigned NumClauses = D->clauselist_size(); | 
|  | SmallVector<OMPClause *, 8> Clauses; | 
|  | Clauses.reserve(NumClauses); | 
|  | OMPClauseReader ClauseReader(Record); | 
|  | for (unsigned I = 0; I != NumClauses; ++I) | 
|  | Clauses.push_back(ClauseReader.readClause()); | 
|  | D->setClauses(Clauses); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { | 
|  | VisitValueDecl(D); | 
|  | D->setLocation(ReadSourceLocation()); | 
|  | Expr *In = Record.readExpr(); | 
|  | Expr *Out = Record.readExpr(); | 
|  | D->setCombinerData(In, Out); | 
|  | Expr *Combiner = Record.readExpr(); | 
|  | D->setCombiner(Combiner); | 
|  | Expr *Orig = Record.readExpr(); | 
|  | Expr *Priv = Record.readExpr(); | 
|  | D->setInitializerData(Orig, Priv); | 
|  | Expr *Init = Record.readExpr(); | 
|  | auto IK = static_cast<OMPDeclareReductionDecl::InitKind>(Record.readInt()); | 
|  | D->setInitializer(Init, IK); | 
|  | D->PrevDeclInScope = ReadDeclID(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { | 
|  | VisitValueDecl(D); | 
|  | D->setLocation(ReadSourceLocation()); | 
|  | Expr *MapperVarRefE = Record.readExpr(); | 
|  | D->setMapperVarRef(MapperVarRefE); | 
|  | D->VarName = Record.readDeclarationName(); | 
|  | D->PrevDeclInScope = ReadDeclID(); | 
|  | unsigned NumClauses = D->clauselist_size(); | 
|  | SmallVector<OMPClause *, 8> Clauses; | 
|  | Clauses.reserve(NumClauses); | 
|  | OMPClauseReader ClauseReader(Record); | 
|  | for (unsigned I = 0; I != NumClauses; ++I) | 
|  | Clauses.push_back(ClauseReader.readClause()); | 
|  | D->setClauses(Clauses); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { | 
|  | VisitVarDecl(D); | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Attribute Reading | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | namespace { | 
|  | class AttrReader { | 
|  | ModuleFile *F; | 
|  | ASTReader *Reader; | 
|  | const ASTReader::RecordData &Record; | 
|  | unsigned &Idx; | 
|  |  | 
|  | public: | 
|  | AttrReader(ModuleFile &F, ASTReader &Reader, | 
|  | const ASTReader::RecordData &Record, unsigned &Idx) | 
|  | : F(&F), Reader(&Reader), Record(Record), Idx(Idx) {} | 
|  |  | 
|  | const uint64_t &readInt() { return Record[Idx++]; } | 
|  |  | 
|  | SourceRange readSourceRange() { | 
|  | return Reader->ReadSourceRange(*F, Record, Idx); | 
|  | } | 
|  |  | 
|  | SourceLocation readSourceLocation() { | 
|  | return Reader->ReadSourceLocation(*F, Record, Idx); | 
|  | } | 
|  |  | 
|  | Expr *readExpr() { return Reader->ReadExpr(*F); } | 
|  |  | 
|  | std::string readString() { | 
|  | return Reader->ReadString(Record, Idx); | 
|  | } | 
|  |  | 
|  | TypeSourceInfo *getTypeSourceInfo() { | 
|  | return Reader->GetTypeSourceInfo(*F, Record, Idx); | 
|  | } | 
|  |  | 
|  | IdentifierInfo *getIdentifierInfo() { | 
|  | return Reader->GetIdentifierInfo(*F, Record, Idx); | 
|  | } | 
|  |  | 
|  | VersionTuple readVersionTuple() { | 
|  | return ASTReader::ReadVersionTuple(Record, Idx); | 
|  | } | 
|  |  | 
|  | template <typename T> T *GetLocalDeclAs(uint32_t LocalID) { | 
|  | return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | Attr *ASTReader::ReadAttr(ModuleFile &M, const RecordData &Rec, | 
|  | unsigned &Idx) { | 
|  | AttrReader Record(M, *this, Rec, Idx); | 
|  | auto V = Record.readInt(); | 
|  | if (!V) | 
|  | return nullptr; | 
|  |  | 
|  | Attr *New = nullptr; | 
|  | // Kind is stored as a 1-based integer because 0 is used to indicate a null | 
|  | // Attr pointer. | 
|  | auto Kind = static_cast<attr::Kind>(V - 1); | 
|  | ASTContext &Context = getContext(); | 
|  |  | 
|  | IdentifierInfo *AttrName = Record.getIdentifierInfo(); | 
|  | IdentifierInfo *ScopeName = Record.getIdentifierInfo(); | 
|  | SourceRange AttrRange = Record.readSourceRange(); | 
|  | SourceLocation ScopeLoc = Record.readSourceLocation(); | 
|  | unsigned ParsedKind = Record.readInt(); | 
|  | unsigned Syntax = Record.readInt(); | 
|  | unsigned SpellingIndex = Record.readInt(); | 
|  |  | 
|  | AttributeCommonInfo Info(AttrName, ScopeName, AttrRange, ScopeLoc, | 
|  | AttributeCommonInfo::Kind(ParsedKind), | 
|  | AttributeCommonInfo::Syntax(Syntax), SpellingIndex); | 
|  |  | 
|  | #include "clang/Serialization/AttrPCHRead.inc" | 
|  |  | 
|  | assert(New && "Unable to decode attribute?"); | 
|  | return New; | 
|  | } | 
|  |  | 
|  | /// Reads attributes from the current stream position. | 
|  | void ASTReader::ReadAttributes(ASTRecordReader &Record, AttrVec &Attrs) { | 
|  | for (unsigned I = 0, E = Record.readInt(); I != E; ++I) | 
|  | Attrs.push_back(Record.readAttr()); | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // ASTReader Implementation | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | /// Note that we have loaded the declaration with the given | 
|  | /// Index. | 
|  | /// | 
|  | /// This routine notes that this declaration has already been loaded, | 
|  | /// so that future GetDecl calls will return this declaration rather | 
|  | /// than trying to load a new declaration. | 
|  | inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) { | 
|  | assert(!DeclsLoaded[Index] && "Decl loaded twice?"); | 
|  | DeclsLoaded[Index] = D; | 
|  | } | 
|  |  | 
|  | /// Determine whether the consumer will be interested in seeing | 
|  | /// this declaration (via HandleTopLevelDecl). | 
|  | /// | 
|  | /// This routine should return true for anything that might affect | 
|  | /// code generation, e.g., inline function definitions, Objective-C | 
|  | /// declarations with metadata, etc. | 
|  | static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { | 
|  | // An ObjCMethodDecl is never considered as "interesting" because its | 
|  | // implementation container always is. | 
|  |  | 
|  | // An ImportDecl or VarDecl imported from a module map module will get | 
|  | // emitted when we import the relevant module. | 
|  | if (isPartOfPerModuleInitializer(D)) { | 
|  | auto *M = D->getImportedOwningModule(); | 
|  | if (M && M->Kind == Module::ModuleMapModule && | 
|  | Ctx.DeclMustBeEmitted(D)) | 
|  | return false; | 
|  | } | 
|  |  | 
|  | if (isa<FileScopeAsmDecl>(D) || | 
|  | isa<ObjCProtocolDecl>(D) || | 
|  | isa<ObjCImplDecl>(D) || | 
|  | isa<ImportDecl>(D) || | 
|  | isa<PragmaCommentDecl>(D) || | 
|  | isa<PragmaDetectMismatchDecl>(D)) | 
|  | return true; | 
|  | if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) || | 
|  | isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D)) | 
|  | return !D->getDeclContext()->isFunctionOrMethod(); | 
|  | if (const auto *Var = dyn_cast<VarDecl>(D)) | 
|  | return Var->isFileVarDecl() && | 
|  | (Var->isThisDeclarationADefinition() == VarDecl::Definition || | 
|  | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Var)); | 
|  | if (const auto *Func = dyn_cast<FunctionDecl>(D)) | 
|  | return Func->doesThisDeclarationHaveABody() || HasBody; | 
|  |  | 
|  | if (auto *ES = D->getASTContext().getExternalSource()) | 
|  | if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never) | 
|  | return true; | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Get the correct cursor and offset for loading a declaration. | 
|  | ASTReader::RecordLocation | 
|  | ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) { | 
|  | GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID); | 
|  | assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); | 
|  | ModuleFile *M = I->second; | 
|  | const DeclOffset &DOffs = | 
|  | M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; | 
|  | Loc = TranslateSourceLocation(*M, DOffs.getLocation()); | 
|  | return RecordLocation(M, DOffs.BitOffset); | 
|  | } | 
|  |  | 
|  | ASTReader::RecordLocation ASTReader::getLocalBitOffset(uint64_t GlobalOffset) { | 
|  | auto I = GlobalBitOffsetsMap.find(GlobalOffset); | 
|  |  | 
|  | assert(I != GlobalBitOffsetsMap.end() && "Corrupted global bit offsets map"); | 
|  | return RecordLocation(I->second, GlobalOffset - I->second->GlobalBitOffset); | 
|  | } | 
|  |  | 
|  | uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) { | 
|  | return LocalOffset + M.GlobalBitOffset; | 
|  | } | 
|  |  | 
|  | static bool isSameTemplateParameterList(const TemplateParameterList *X, | 
|  | const TemplateParameterList *Y); | 
|  |  | 
|  | /// Determine whether two template parameters are similar enough | 
|  | /// that they may be used in declarations of the same template. | 
|  | static bool isSameTemplateParameter(const NamedDecl *X, | 
|  | const NamedDecl *Y) { | 
|  | if (X->getKind() != Y->getKind()) | 
|  | return false; | 
|  |  | 
|  | if (const auto *TX = dyn_cast<TemplateTypeParmDecl>(X)) { | 
|  | const auto *TY = cast<TemplateTypeParmDecl>(Y); | 
|  | return TX->isParameterPack() == TY->isParameterPack(); | 
|  | } | 
|  |  | 
|  | if (const auto *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { | 
|  | const auto *TY = cast<NonTypeTemplateParmDecl>(Y); | 
|  | return TX->isParameterPack() == TY->isParameterPack() && | 
|  | TX->getASTContext().hasSameType(TX->getType(), TY->getType()); | 
|  | } | 
|  |  | 
|  | const auto *TX = cast<TemplateTemplateParmDecl>(X); | 
|  | const auto *TY = cast<TemplateTemplateParmDecl>(Y); | 
|  | return TX->isParameterPack() == TY->isParameterPack() && | 
|  | isSameTemplateParameterList(TX->getTemplateParameters(), | 
|  | TY->getTemplateParameters()); | 
|  | } | 
|  |  | 
|  | static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) { | 
|  | if (auto *NS = X->getAsNamespace()) | 
|  | return NS; | 
|  | if (auto *NAS = X->getAsNamespaceAlias()) | 
|  | return NAS->getNamespace(); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | static bool isSameQualifier(const NestedNameSpecifier *X, | 
|  | const NestedNameSpecifier *Y) { | 
|  | if (auto *NSX = getNamespace(X)) { | 
|  | auto *NSY = getNamespace(Y); | 
|  | if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl()) | 
|  | return false; | 
|  | } else if (X->getKind() != Y->getKind()) | 
|  | return false; | 
|  |  | 
|  | // FIXME: For namespaces and types, we're permitted to check that the entity | 
|  | // is named via the same tokens. We should probably do so. | 
|  | switch (X->getKind()) { | 
|  | case NestedNameSpecifier::Identifier: | 
|  | if (X->getAsIdentifier() != Y->getAsIdentifier()) | 
|  | return false; | 
|  | break; | 
|  | case NestedNameSpecifier::Namespace: | 
|  | case NestedNameSpecifier::NamespaceAlias: | 
|  | // We've already checked that we named the same namespace. | 
|  | break; | 
|  | case NestedNameSpecifier::TypeSpec: | 
|  | case NestedNameSpecifier::TypeSpecWithTemplate: | 
|  | if (X->getAsType()->getCanonicalTypeInternal() != | 
|  | Y->getAsType()->getCanonicalTypeInternal()) | 
|  | return false; | 
|  | break; | 
|  | case NestedNameSpecifier::Global: | 
|  | case NestedNameSpecifier::Super: | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Recurse into earlier portion of NNS, if any. | 
|  | auto *PX = X->getPrefix(); | 
|  | auto *PY = Y->getPrefix(); | 
|  | if (PX && PY) | 
|  | return isSameQualifier(PX, PY); | 
|  | return !PX && !PY; | 
|  | } | 
|  |  | 
|  | /// Determine whether two template parameter lists are similar enough | 
|  | /// that they may be used in declarations of the same template. | 
|  | static bool isSameTemplateParameterList(const TemplateParameterList *X, | 
|  | const TemplateParameterList *Y) { | 
|  | if (X->size() != Y->size()) | 
|  | return false; | 
|  |  | 
|  | for (unsigned I = 0, N = X->size(); I != N; ++I) | 
|  | if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I))) | 
|  | return false; | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /// Determine whether the attributes we can overload on are identical for A and | 
|  | /// B. Will ignore any overloadable attrs represented in the type of A and B. | 
|  | static bool hasSameOverloadableAttrs(const FunctionDecl *A, | 
|  | const FunctionDecl *B) { | 
|  | // Note that pass_object_size attributes are represented in the function's | 
|  | // ExtParameterInfo, so we don't need to check them here. | 
|  |  | 
|  | llvm::FoldingSetNodeID Cand1ID, Cand2ID; | 
|  | auto AEnableIfAttrs = A->specific_attrs<EnableIfAttr>(); | 
|  | auto BEnableIfAttrs = B->specific_attrs<EnableIfAttr>(); | 
|  |  | 
|  | for (auto Pair : zip_longest(AEnableIfAttrs, BEnableIfAttrs)) { | 
|  | Optional<EnableIfAttr *> Cand1A = std::get<0>(Pair); | 
|  | Optional<EnableIfAttr *> Cand2A = std::get<1>(Pair); | 
|  |  | 
|  | // Return false if the number of enable_if attributes is different. | 
|  | if (!Cand1A || !Cand2A) | 
|  | return false; | 
|  |  | 
|  | Cand1ID.clear(); | 
|  | Cand2ID.clear(); | 
|  |  | 
|  | (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true); | 
|  | (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true); | 
|  |  | 
|  | // Return false if any of the enable_if expressions of A and B are | 
|  | // different. | 
|  | if (Cand1ID != Cand2ID) | 
|  | return false; | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /// Determine whether the two declarations refer to the same entity. | 
|  | static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { | 
|  | assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!"); | 
|  |  | 
|  | if (X == Y) | 
|  | return true; | 
|  |  | 
|  | // Must be in the same context. | 
|  | // | 
|  | // Note that we can't use DeclContext::Equals here, because the DeclContexts | 
|  | // could be two different declarations of the same function. (We will fix the | 
|  | // semantic DC to refer to the primary definition after merging.) | 
|  | if (!declaresSameEntity(cast<Decl>(X->getDeclContext()->getRedeclContext()), | 
|  | cast<Decl>(Y->getDeclContext()->getRedeclContext()))) | 
|  | return false; | 
|  |  | 
|  | // Two typedefs refer to the same entity if they have the same underlying | 
|  | // type. | 
|  | if (const auto *TypedefX = dyn_cast<TypedefNameDecl>(X)) | 
|  | if (const auto *TypedefY = dyn_cast<TypedefNameDecl>(Y)) | 
|  | return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(), | 
|  | TypedefY->getUnderlyingType()); | 
|  |  | 
|  | // Must have the same kind. | 
|  | if (X->getKind() != Y->getKind()) | 
|  | return false; | 
|  |  | 
|  | // Objective-C classes and protocols with the same name always match. | 
|  | if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X)) | 
|  | return true; | 
|  |  | 
|  | if (isa<ClassTemplateSpecializationDecl>(X)) { | 
|  | // No need to handle these here: we merge them when adding them to the | 
|  | // template. | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // Compatible tags match. | 
|  | if (const auto *TagX = dyn_cast<TagDecl>(X)) { | 
|  | const auto *TagY = cast<TagDecl>(Y); | 
|  | return (TagX->getTagKind() == TagY->getTagKind()) || | 
|  | ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class || | 
|  | TagX->getTagKind() == TTK_Interface) && | 
|  | (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class || | 
|  | TagY->getTagKind() == TTK_Interface)); | 
|  | } | 
|  |  | 
|  | // Functions with the same type and linkage match. | 
|  | // FIXME: This needs to cope with merging of prototyped/non-prototyped | 
|  | // functions, etc. | 
|  | if (const auto *FuncX = dyn_cast<FunctionDecl>(X)) { | 
|  | const auto *FuncY = cast<FunctionDecl>(Y); | 
|  | if (const auto *CtorX = dyn_cast<CXXConstructorDecl>(X)) { | 
|  | const auto *CtorY = cast<CXXConstructorDecl>(Y); | 
|  | if (CtorX->getInheritedConstructor() && | 
|  | !isSameEntity(CtorX->getInheritedConstructor().getConstructor(), | 
|  | CtorY->getInheritedConstructor().getConstructor())) | 
|  | return false; | 
|  | } | 
|  |  | 
|  | if (FuncX->isMultiVersion() != FuncY->isMultiVersion()) | 
|  | return false; | 
|  |  | 
|  | // Multiversioned functions with different feature strings are represented | 
|  | // as separate declarations. | 
|  | if (FuncX->isMultiVersion()) { | 
|  | const auto *TAX = FuncX->getAttr<TargetAttr>(); | 
|  | const auto *TAY = FuncY->getAttr<TargetAttr>(); | 
|  | assert(TAX && TAY && "Multiversion Function without target attribute"); | 
|  |  | 
|  | if (TAX->getFeaturesStr() != TAY->getFeaturesStr()) | 
|  | return false; | 
|  | } | 
|  |  | 
|  | ASTContext &C = FuncX->getASTContext(); | 
|  | auto GetTypeAsWritten = [](const FunctionDecl *FD) { | 
|  | // Map to the first declaration that we've already merged into this one. | 
|  | // The TSI of redeclarations might not match (due to calling conventions | 
|  | // being inherited onto the type but not the TSI), but the TSI type of | 
|  | // the first declaration of the function should match across modules. | 
|  | FD = FD->getCanonicalDecl(); | 
|  | return FD->getTypeSourceInfo() ? FD->getTypeSourceInfo()->getType() | 
|  | : FD->getType(); | 
|  | }; | 
|  | QualType XT = GetTypeAsWritten(FuncX), YT = GetTypeAsWritten(FuncY); | 
|  | if (!C.hasSameType(XT, YT)) { | 
|  | // We can get functions with different types on the redecl chain in C++17 | 
|  | // if they have differing exception specifications and at least one of | 
|  | // the excpetion specs is unresolved. | 
|  | auto *XFPT = XT->getAs<FunctionProtoType>(); | 
|  | auto *YFPT = YT->getAs<FunctionProtoType>(); | 
|  | if (C.getLangOpts().CPlusPlus17 && XFPT && YFPT && | 
|  | (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) || | 
|  | isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) && | 
|  | C.hasSameFunctionTypeIgnoringExceptionSpec(XT, YT)) | 
|  | return true; | 
|  | return false; | 
|  | } | 
|  | return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() && | 
|  | hasSameOverloadableAttrs(FuncX, FuncY); | 
|  | } | 
|  |  | 
|  | // Variables with the same type and linkage match. | 
|  | if (const auto *VarX = dyn_cast<VarDecl>(X)) { | 
|  | const auto *VarY = cast<VarDecl>(Y); | 
|  | if (VarX->getLinkageInternal() == VarY->getLinkageInternal()) { | 
|  | ASTContext &C = VarX->getASTContext(); | 
|  | if (C.hasSameType(VarX->getType(), VarY->getType())) | 
|  | return true; | 
|  |  | 
|  | // We can get decls with different types on the redecl chain. Eg. | 
|  | // template <typename T> struct S { static T Var[]; }; // #1 | 
|  | // template <typename T> T S<T>::Var[sizeof(T)]; // #2 | 
|  | // Only? happens when completing an incomplete array type. In this case | 
|  | // when comparing #1 and #2 we should go through their element type. | 
|  | const ArrayType *VarXTy = C.getAsArrayType(VarX->getType()); | 
|  | const ArrayType *VarYTy = C.getAsArrayType(VarY->getType()); | 
|  | if (!VarXTy || !VarYTy) | 
|  | return false; | 
|  | if (VarXTy->isIncompleteArrayType() || VarYTy->isIncompleteArrayType()) | 
|  | return C.hasSameType(VarXTy->getElementType(), VarYTy->getElementType()); | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | // Namespaces with the same name and inlinedness match. | 
|  | if (const auto *NamespaceX = dyn_cast<NamespaceDecl>(X)) { | 
|  | const auto *NamespaceY = cast<NamespaceDecl>(Y); | 
|  | return NamespaceX->isInline() == NamespaceY->isInline(); | 
|  | } | 
|  |  | 
|  | // Identical template names and kinds match if their template parameter lists | 
|  | // and patterns match. | 
|  | if (const auto *TemplateX = dyn_cast<TemplateDecl>(X)) { | 
|  | const auto *TemplateY = cast<TemplateDecl>(Y); | 
|  | return isSameEntity(TemplateX->getTemplatedDecl(), | 
|  | TemplateY->getTemplatedDecl()) && | 
|  | isSameTemplateParameterList(TemplateX->getTemplateParameters(), | 
|  | TemplateY->getTemplateParameters()); | 
|  | } | 
|  |  | 
|  | // Fields with the same name and the same type match. | 
|  | if (const auto *FDX = dyn_cast<FieldDecl>(X)) { | 
|  | const auto *FDY = cast<FieldDecl>(Y); | 
|  | // FIXME: Also check the bitwidth is odr-equivalent, if any. | 
|  | return X->getASTContext().hasSameType(FDX->getType(), FDY->getType()); | 
|  | } | 
|  |  | 
|  | // Indirect fields with the same target field match. | 
|  | if (const auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) { | 
|  | const auto *IFDY = cast<IndirectFieldDecl>(Y); | 
|  | return IFDX->getAnonField()->getCanonicalDecl() == | 
|  | IFDY->getAnonField()->getCanonicalDecl(); | 
|  | } | 
|  |  | 
|  | // Enumerators with the same name match. | 
|  | if (isa<EnumConstantDecl>(X)) | 
|  | // FIXME: Also check the value is odr-equivalent. | 
|  | return true; | 
|  |  | 
|  | // Using shadow declarations with the same target match. | 
|  | if (const auto *USX = dyn_cast<UsingShadowDecl>(X)) { | 
|  | const auto *USY = cast<UsingShadowDecl>(Y); | 
|  | return USX->getTargetDecl() == USY->getTargetDecl(); | 
|  | } | 
|  |  | 
|  | // Using declarations with the same qualifier match. (We already know that | 
|  | // the name matches.) | 
|  | if (const auto *UX = dyn_cast<UsingDecl>(X)) { | 
|  | const auto *UY = cast<UsingDecl>(Y); | 
|  | return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && | 
|  | UX->hasTypename() == UY->hasTypename() && | 
|  | UX->isAccessDeclaration() == UY->isAccessDeclaration(); | 
|  | } | 
|  | if (const auto *UX = dyn_cast<UnresolvedUsingValueDecl>(X)) { | 
|  | const auto *UY = cast<UnresolvedUsingValueDecl>(Y); | 
|  | return isSameQualifier(UX->getQualifier(), UY->getQualifier()) && | 
|  | UX->isAccessDeclaration() == UY->isAccessDeclaration(); | 
|  | } | 
|  | if (const auto *UX = dyn_cast<UnresolvedUsingTypenameDecl>(X)) | 
|  | return isSameQualifier( | 
|  | UX->getQualifier(), | 
|  | cast<UnresolvedUsingTypenameDecl>(Y)->getQualifier()); | 
|  |  | 
|  | // Namespace alias definitions with the same target match. | 
|  | if (const auto *NAX = dyn_cast<NamespaceAliasDecl>(X)) { | 
|  | const auto *NAY = cast<NamespaceAliasDecl>(Y); | 
|  | return NAX->getNamespace()->Equals(NAY->getNamespace()); | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /// Find the context in which we should search for previous declarations when | 
|  | /// looking for declarations to merge. | 
|  | DeclContext *ASTDeclReader::getPrimaryContextForMerging(ASTReader &Reader, | 
|  | DeclContext *DC) { | 
|  | if (auto *ND = dyn_cast<NamespaceDecl>(DC)) | 
|  | return ND->getOriginalNamespace(); | 
|  |  | 
|  | if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) { | 
|  | // Try to dig out the definition. | 
|  | auto *DD = RD->DefinitionData; | 
|  | if (!DD) | 
|  | DD = RD->getCanonicalDecl()->DefinitionData; | 
|  |  | 
|  | // If there's no definition yet, then DC's definition is added by an update | 
|  | // record, but we've not yet loaded that update record. In this case, we | 
|  | // commit to DC being the canonical definition now, and will fix this when | 
|  | // we load the update record. | 
|  | if (!DD) { | 
|  | DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD); | 
|  | RD->setCompleteDefinition(true); | 
|  | RD->DefinitionData = DD; | 
|  | RD->getCanonicalDecl()->DefinitionData = DD; | 
|  |  | 
|  | // Track that we did this horrible thing so that we can fix it later. | 
|  | Reader.PendingFakeDefinitionData.insert( | 
|  | std::make_pair(DD, ASTReader::PendingFakeDefinitionKind::Fake)); | 
|  | } | 
|  |  | 
|  | return DD->Definition; | 
|  | } | 
|  |  | 
|  | if (auto *ED = dyn_cast<EnumDecl>(DC)) | 
|  | return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition() | 
|  | : nullptr; | 
|  |  | 
|  | // We can see the TU here only if we have no Sema object. In that case, | 
|  | // there's no TU scope to look in, so using the DC alone is sufficient. | 
|  | if (auto *TU = dyn_cast<TranslationUnitDecl>(DC)) | 
|  | return TU; | 
|  |  | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | ASTDeclReader::FindExistingResult::~FindExistingResult() { | 
|  | // Record that we had a typedef name for linkage whether or not we merge | 
|  | // with that declaration. | 
|  | if (TypedefNameForLinkage) { | 
|  | DeclContext *DC = New->getDeclContext()->getRedeclContext(); | 
|  | Reader.ImportedTypedefNamesForLinkage.insert( | 
|  | std::make_pair(std::make_pair(DC, TypedefNameForLinkage), New)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (!AddResult || Existing) | 
|  | return; | 
|  |  | 
|  | DeclarationName Name = New->getDeclName(); | 
|  | DeclContext *DC = New->getDeclContext()->getRedeclContext(); | 
|  | if (needsAnonymousDeclarationNumber(New)) { | 
|  | setAnonymousDeclForMerging(Reader, New->getLexicalDeclContext(), | 
|  | AnonymousDeclNumber, New); | 
|  | } else if (DC->isTranslationUnit() && | 
|  | !Reader.getContext().getLangOpts().CPlusPlus) { | 
|  | if (Reader.getIdResolver().tryAddTopLevelDecl(New, Name)) | 
|  | Reader.PendingFakeLookupResults[Name.getAsIdentifierInfo()] | 
|  | .push_back(New); | 
|  | } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) { | 
|  | // Add the declaration to its redeclaration context so later merging | 
|  | // lookups will find it. | 
|  | MergeDC->makeDeclVisibleInContextImpl(New, /*Internal*/true); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Find the declaration that should be merged into, given the declaration found | 
|  | /// by name lookup. If we're merging an anonymous declaration within a typedef, | 
|  | /// we need a matching typedef, and we merge with the type inside it. | 
|  | static NamedDecl *getDeclForMerging(NamedDecl *Found, | 
|  | bool IsTypedefNameForLinkage) { | 
|  | if (!IsTypedefNameForLinkage) | 
|  | return Found; | 
|  |  | 
|  | // If we found a typedef declaration that gives a name to some other | 
|  | // declaration, then we want that inner declaration. Declarations from | 
|  | // AST files are handled via ImportedTypedefNamesForLinkage. | 
|  | if (Found->isFromASTFile()) | 
|  | return nullptr; | 
|  |  | 
|  | if (auto *TND = dyn_cast<TypedefNameDecl>(Found)) | 
|  | return TND->getAnonDeclWithTypedefName(/*AnyRedecl*/true); | 
|  |  | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | /// Find the declaration to use to populate the anonymous declaration table | 
|  | /// for the given lexical DeclContext. We only care about finding local | 
|  | /// definitions of the context; we'll merge imported ones as we go. | 
|  | DeclContext * | 
|  | ASTDeclReader::getPrimaryDCForAnonymousDecl(DeclContext *LexicalDC) { | 
|  | // For classes, we track the definition as we merge. | 
|  | if (auto *RD = dyn_cast<CXXRecordDecl>(LexicalDC)) { | 
|  | auto *DD = RD->getCanonicalDecl()->DefinitionData; | 
|  | return DD ? DD->Definition : nullptr; | 
|  | } | 
|  |  | 
|  | // For anything else, walk its merged redeclarations looking for a definition. | 
|  | // Note that we can't just call getDefinition here because the redeclaration | 
|  | // chain isn't wired up. | 
|  | for (auto *D : merged_redecls(cast<Decl>(LexicalDC))) { | 
|  | if (auto *FD = dyn_cast<FunctionDecl>(D)) | 
|  | if (FD->isThisDeclarationADefinition()) | 
|  | return FD; | 
|  | if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) | 
|  | if (MD->isThisDeclarationADefinition()) | 
|  | return MD; | 
|  | } | 
|  |  | 
|  | // No merged definition yet. | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader, | 
|  | DeclContext *DC, | 
|  | unsigned Index) { | 
|  | // If the lexical context has been merged, look into the now-canonical | 
|  | // definition. | 
|  | auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl(); | 
|  |  | 
|  | // If we've seen this before, return the canonical declaration. | 
|  | auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC]; | 
|  | if (Index < Previous.size() && Previous[Index]) | 
|  | return Previous[Index]; | 
|  |  | 
|  | // If this is the first time, but we have parsed a declaration of the context, | 
|  | // build the anonymous declaration list from the parsed declaration. | 
|  | auto *PrimaryDC = getPrimaryDCForAnonymousDecl(DC); | 
|  | if (PrimaryDC && !cast<Decl>(PrimaryDC)->isFromASTFile()) { | 
|  | numberAnonymousDeclsWithin(PrimaryDC, [&](NamedDecl *ND, unsigned Number) { | 
|  | if (Previous.size() == Number) | 
|  | Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl())); | 
|  | else | 
|  | Previous[Number] = cast<NamedDecl>(ND->getCanonicalDecl()); | 
|  | }); | 
|  | } | 
|  |  | 
|  | return Index < Previous.size() ? Previous[Index] : nullptr; | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::setAnonymousDeclForMerging(ASTReader &Reader, | 
|  | DeclContext *DC, unsigned Index, | 
|  | NamedDecl *D) { | 
|  | auto *CanonDC = cast<Decl>(DC)->getCanonicalDecl(); | 
|  |  | 
|  | auto &Previous = Reader.AnonymousDeclarationsForMerging[CanonDC]; | 
|  | if (Index >= Previous.size()) | 
|  | Previous.resize(Index + 1); | 
|  | if (!Previous[Index]) | 
|  | Previous[Index] = D; | 
|  | } | 
|  |  | 
|  | ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { | 
|  | DeclarationName Name = TypedefNameForLinkage ? TypedefNameForLinkage | 
|  | : D->getDeclName(); | 
|  |  | 
|  | if (!Name && !needsAnonymousDeclarationNumber(D)) { | 
|  | // Don't bother trying to find unnamed declarations that are in | 
|  | // unmergeable contexts. | 
|  | FindExistingResult Result(Reader, D, /*Existing=*/nullptr, | 
|  | AnonymousDeclNumber, TypedefNameForLinkage); | 
|  | Result.suppress(); | 
|  | return Result; | 
|  | } | 
|  |  | 
|  | DeclContext *DC = D->getDeclContext()->getRedeclContext(); | 
|  | if (TypedefNameForLinkage) { | 
|  | auto It = Reader.ImportedTypedefNamesForLinkage.find( | 
|  | std::make_pair(DC, TypedefNameForLinkage)); | 
|  | if (It != Reader.ImportedTypedefNamesForLinkage.end()) | 
|  | if (isSameEntity(It->second, D)) | 
|  | return FindExistingResult(Reader, D, It->second, AnonymousDeclNumber, | 
|  | TypedefNameForLinkage); | 
|  | // Go on to check in other places in case an existing typedef name | 
|  | // was not imported. | 
|  | } | 
|  |  | 
|  | if (needsAnonymousDeclarationNumber(D)) { | 
|  | // This is an anonymous declaration that we may need to merge. Look it up | 
|  | // in its context by number. | 
|  | if (auto *Existing = getAnonymousDeclForMerging( | 
|  | Reader, D->getLexicalDeclContext(), AnonymousDeclNumber)) | 
|  | if (isSameEntity(Existing, D)) | 
|  | return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, | 
|  | TypedefNameForLinkage); | 
|  | } else if (DC->isTranslationUnit() && | 
|  | !Reader.getContext().getLangOpts().CPlusPlus) { | 
|  | IdentifierResolver &IdResolver = Reader.getIdResolver(); | 
|  |  | 
|  | // Temporarily consider the identifier to be up-to-date. We don't want to | 
|  | // cause additional lookups here. | 
|  | class UpToDateIdentifierRAII { | 
|  | IdentifierInfo *II; | 
|  | bool WasOutToDate = false; | 
|  |  | 
|  | public: | 
|  | explicit UpToDateIdentifierRAII(IdentifierInfo *II) : II(II) { | 
|  | if (II) { | 
|  | WasOutToDate = II->isOutOfDate(); | 
|  | if (WasOutToDate) | 
|  | II->setOutOfDate(false); | 
|  | } | 
|  | } | 
|  |  | 
|  | ~UpToDateIdentifierRAII() { | 
|  | if (WasOutToDate) | 
|  | II->setOutOfDate(true); | 
|  | } | 
|  | } UpToDate(Name.getAsIdentifierInfo()); | 
|  |  | 
|  | for (IdentifierResolver::iterator I = IdResolver.begin(Name), | 
|  | IEnd = IdResolver.end(); | 
|  | I != IEnd; ++I) { | 
|  | if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) | 
|  | if (isSameEntity(Existing, D)) | 
|  | return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, | 
|  | TypedefNameForLinkage); | 
|  | } | 
|  | } else if (DeclContext *MergeDC = getPrimaryContextForMerging(Reader, DC)) { | 
|  | DeclContext::lookup_result R = MergeDC->noload_lookup(Name); | 
|  | for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) { | 
|  | if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage)) | 
|  | if (isSameEntity(Existing, D)) | 
|  | return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber, | 
|  | TypedefNameForLinkage); | 
|  | } | 
|  | } else { | 
|  | // Not in a mergeable context. | 
|  | return FindExistingResult(Reader); | 
|  | } | 
|  |  | 
|  | // If this declaration is from a merged context, make a note that we need to | 
|  | // check that the canonical definition of that context contains the decl. | 
|  | // | 
|  | // FIXME: We should do something similar if we merge two definitions of the | 
|  | // same template specialization into the same CXXRecordDecl. | 
|  | auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext()); | 
|  | if (MergedDCIt != Reader.MergedDeclContexts.end() && | 
|  | MergedDCIt->second == D->getDeclContext()) | 
|  | Reader.PendingOdrMergeChecks.push_back(D); | 
|  |  | 
|  | return FindExistingResult(Reader, D, /*Existing=*/nullptr, | 
|  | AnonymousDeclNumber, TypedefNameForLinkage); | 
|  | } | 
|  |  | 
|  | template<typename DeclT> | 
|  | Decl *ASTDeclReader::getMostRecentDeclImpl(Redeclarable<DeclT> *D) { | 
|  | return D->RedeclLink.getLatestNotUpdated(); | 
|  | } | 
|  |  | 
|  | Decl *ASTDeclReader::getMostRecentDeclImpl(...) { | 
|  | llvm_unreachable("getMostRecentDecl on non-redeclarable declaration"); | 
|  | } | 
|  |  | 
|  | Decl *ASTDeclReader::getMostRecentDecl(Decl *D) { | 
|  | assert(D); | 
|  |  | 
|  | switch (D->getKind()) { | 
|  | #define ABSTRACT_DECL(TYPE) | 
|  | #define DECL(TYPE, BASE)                               \ | 
|  | case Decl::TYPE:                                     \ | 
|  | return getMostRecentDeclImpl(cast<TYPE##Decl>(D)); | 
|  | #include "clang/AST/DeclNodes.inc" | 
|  | } | 
|  | llvm_unreachable("unknown decl kind"); | 
|  | } | 
|  |  | 
|  | Decl *ASTReader::getMostRecentExistingDecl(Decl *D) { | 
|  | return ASTDeclReader::getMostRecentDecl(D->getCanonicalDecl()); | 
|  | } | 
|  |  | 
|  | template<typename DeclT> | 
|  | void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, | 
|  | Redeclarable<DeclT> *D, | 
|  | Decl *Previous, Decl *Canon) { | 
|  | D->RedeclLink.setPrevious(cast<DeclT>(Previous)); | 
|  | D->First = cast<DeclT>(Previous)->First; | 
|  | } | 
|  |  | 
|  | namespace clang { | 
|  |  | 
|  | template<> | 
|  | void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, | 
|  | Redeclarable<VarDecl> *D, | 
|  | Decl *Previous, Decl *Canon) { | 
|  | auto *VD = static_cast<VarDecl *>(D); | 
|  | auto *PrevVD = cast<VarDecl>(Previous); | 
|  | D->RedeclLink.setPrevious(PrevVD); | 
|  | D->First = PrevVD->First; | 
|  |  | 
|  | // We should keep at most one definition on the chain. | 
|  | // FIXME: Cache the definition once we've found it. Building a chain with | 
|  | // N definitions currently takes O(N^2) time here. | 
|  | if (VD->isThisDeclarationADefinition() == VarDecl::Definition) { | 
|  | for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) { | 
|  | if (CurD->isThisDeclarationADefinition() == VarDecl::Definition) { | 
|  | Reader.mergeDefinitionVisibility(CurD, VD); | 
|  | VD->demoteThisDefinitionToDeclaration(); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static bool isUndeducedReturnType(QualType T) { | 
|  | auto *DT = T->getContainedDeducedType(); | 
|  | return DT && !DT->isDeduced(); | 
|  | } | 
|  |  | 
|  | template<> | 
|  | void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, | 
|  | Redeclarable<FunctionDecl> *D, | 
|  | Decl *Previous, Decl *Canon) { | 
|  | auto *FD = static_cast<FunctionDecl *>(D); | 
|  | auto *PrevFD = cast<FunctionDecl>(Previous); | 
|  |  | 
|  | FD->RedeclLink.setPrevious(PrevFD); | 
|  | FD->First = PrevFD->First; | 
|  |  | 
|  | // If the previous declaration is an inline function declaration, then this | 
|  | // declaration is too. | 
|  | if (PrevFD->isInlined() != FD->isInlined()) { | 
|  | // FIXME: [dcl.fct.spec]p4: | 
|  | //   If a function with external linkage is declared inline in one | 
|  | //   translation unit, it shall be declared inline in all translation | 
|  | //   units in which it appears. | 
|  | // | 
|  | // Be careful of this case: | 
|  | // | 
|  | // module A: | 
|  | //   template<typename T> struct X { void f(); }; | 
|  | //   template<typename T> inline void X<T>::f() {} | 
|  | // | 
|  | // module B instantiates the declaration of X<int>::f | 
|  | // module C instantiates the definition of X<int>::f | 
|  | // | 
|  | // If module B and C are merged, we do not have a violation of this rule. | 
|  | FD->setImplicitlyInline(true); | 
|  | } | 
|  |  | 
|  | auto *FPT = FD->getType()->getAs<FunctionProtoType>(); | 
|  | auto *PrevFPT = PrevFD->getType()->getAs<FunctionProtoType>(); | 
|  | if (FPT && PrevFPT) { | 
|  | // If we need to propagate an exception specification along the redecl | 
|  | // chain, make a note of that so that we can do so later. | 
|  | bool IsUnresolved = isUnresolvedExceptionSpec(FPT->getExceptionSpecType()); | 
|  | bool WasUnresolved = | 
|  | isUnresolvedExceptionSpec(PrevFPT->getExceptionSpecType()); | 
|  | if (IsUnresolved != WasUnresolved) | 
|  | Reader.PendingExceptionSpecUpdates.insert( | 
|  | {Canon, IsUnresolved ? PrevFD : FD}); | 
|  |  | 
|  | // If we need to propagate a deduced return type along the redecl chain, | 
|  | // make a note of that so that we can do it later. | 
|  | bool IsUndeduced = isUndeducedReturnType(FPT->getReturnType()); | 
|  | bool WasUndeduced = isUndeducedReturnType(PrevFPT->getReturnType()); | 
|  | if (IsUndeduced != WasUndeduced) | 
|  | Reader.PendingDeducedTypeUpdates.insert( | 
|  | {cast<FunctionDecl>(Canon), | 
|  | (IsUndeduced ? PrevFPT : FPT)->getReturnType()}); | 
|  | } | 
|  | } | 
|  |  | 
|  | } // namespace clang | 
|  |  | 
|  | void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) { | 
|  | llvm_unreachable("attachPreviousDecl on non-redeclarable declaration"); | 
|  | } | 
|  |  | 
|  | /// Inherit the default template argument from \p From to \p To. Returns | 
|  | /// \c false if there is no default template for \p From. | 
|  | template <typename ParmDecl> | 
|  | static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From, | 
|  | Decl *ToD) { | 
|  | auto *To = cast<ParmDecl>(ToD); | 
|  | if (!From->hasDefaultArgument()) | 
|  | return false; | 
|  | To->setInheritedDefaultArgument(Context, From); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | static void inheritDefaultTemplateArguments(ASTContext &Context, | 
|  | TemplateDecl *From, | 
|  | TemplateDecl *To) { | 
|  | auto *FromTP = From->getTemplateParameters(); | 
|  | auto *ToTP = To->getTemplateParameters(); | 
|  | assert(FromTP->size() == ToTP->size() && "merged mismatched templates?"); | 
|  |  | 
|  | for (unsigned I = 0, N = FromTP->size(); I != N; ++I) { | 
|  | NamedDecl *FromParam = FromTP->getParam(I); | 
|  | NamedDecl *ToParam = ToTP->getParam(I); | 
|  |  | 
|  | if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) | 
|  | inheritDefaultTemplateArgument(Context, FTTP, ToParam); | 
|  | else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam)) | 
|  | inheritDefaultTemplateArgument(Context, FNTTP, ToParam); | 
|  | else | 
|  | inheritDefaultTemplateArgument( | 
|  | Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D, | 
|  | Decl *Previous, Decl *Canon) { | 
|  | assert(D && Previous); | 
|  |  | 
|  | switch (D->getKind()) { | 
|  | #define ABSTRACT_DECL(TYPE) | 
|  | #define DECL(TYPE, BASE)                                                  \ | 
|  | case Decl::TYPE:                                                        \ | 
|  | attachPreviousDeclImpl(Reader, cast<TYPE##Decl>(D), Previous, Canon); \ | 
|  | break; | 
|  | #include "clang/AST/DeclNodes.inc" | 
|  | } | 
|  |  | 
|  | // If the declaration was visible in one module, a redeclaration of it in | 
|  | // another module remains visible even if it wouldn't be visible by itself. | 
|  | // | 
|  | // FIXME: In this case, the declaration should only be visible if a module | 
|  | //        that makes it visible has been imported. | 
|  | D->IdentifierNamespace |= | 
|  | Previous->IdentifierNamespace & | 
|  | (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); | 
|  |  | 
|  | // If the declaration declares a template, it may inherit default arguments | 
|  | // from the previous declaration. | 
|  | if (auto *TD = dyn_cast<TemplateDecl>(D)) | 
|  | inheritDefaultTemplateArguments(Reader.getContext(), | 
|  | cast<TemplateDecl>(Previous), TD); | 
|  | } | 
|  |  | 
|  | template<typename DeclT> | 
|  | void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) { | 
|  | D->RedeclLink.setLatest(cast<DeclT>(Latest)); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::attachLatestDeclImpl(...) { | 
|  | llvm_unreachable("attachLatestDecl on non-redeclarable declaration"); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) { | 
|  | assert(D && Latest); | 
|  |  | 
|  | switch (D->getKind()) { | 
|  | #define ABSTRACT_DECL(TYPE) | 
|  | #define DECL(TYPE, BASE)                                  \ | 
|  | case Decl::TYPE:                                        \ | 
|  | attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \ | 
|  | break; | 
|  | #include "clang/AST/DeclNodes.inc" | 
|  | } | 
|  | } | 
|  |  | 
|  | template<typename DeclT> | 
|  | void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) { | 
|  | D->RedeclLink.markIncomplete(); | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::markIncompleteDeclChainImpl(...) { | 
|  | llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration"); | 
|  | } | 
|  |  | 
|  | void ASTReader::markIncompleteDeclChain(Decl *D) { | 
|  | switch (D->getKind()) { | 
|  | #define ABSTRACT_DECL(TYPE) | 
|  | #define DECL(TYPE, BASE)                                             \ | 
|  | case Decl::TYPE:                                                   \ | 
|  | ASTDeclReader::markIncompleteDeclChainImpl(cast<TYPE##Decl>(D)); \ | 
|  | break; | 
|  | #include "clang/AST/DeclNodes.inc" | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Read the declaration at the given offset from the AST file. | 
|  | Decl *ASTReader::ReadDeclRecord(DeclID ID) { | 
|  | unsigned Index = ID - NUM_PREDEF_DECL_IDS; | 
|  | SourceLocation DeclLoc; | 
|  | RecordLocation Loc = DeclCursorForID(ID, DeclLoc); | 
|  | llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; | 
|  | // Keep track of where we are in the stream, then jump back there | 
|  | // after reading this declaration. | 
|  | SavedStreamPosition SavedPosition(DeclsCursor); | 
|  |  | 
|  | ReadingKindTracker ReadingKind(Read_Decl, *this); | 
|  |  | 
|  | // Note that we are loading a declaration record. | 
|  | Deserializing ADecl(this); | 
|  |  | 
|  | auto Fail = [](const char *what, llvm::Error &&Err) { | 
|  | llvm::report_fatal_error(Twine("ASTReader::ReadDeclRecord failed ") + what + | 
|  | ": " + toString(std::move(Err))); | 
|  | }; | 
|  |  | 
|  | if (llvm::Error JumpFailed = DeclsCursor.JumpToBit(Loc.Offset)) | 
|  | Fail("jumping", std::move(JumpFailed)); | 
|  | ASTRecordReader Record(*this, *Loc.F); | 
|  | ASTDeclReader Reader(*this, Record, Loc, ID, DeclLoc); | 
|  | Expected<unsigned> MaybeCode = DeclsCursor.ReadCode(); | 
|  | if (!MaybeCode) | 
|  | Fail("reading code", MaybeCode.takeError()); | 
|  | unsigned Code = MaybeCode.get(); | 
|  |  | 
|  | ASTContext &Context = getContext(); | 
|  | Decl *D = nullptr; | 
|  | Expected<unsigned> MaybeDeclCode = Record.readRecord(DeclsCursor, Code); | 
|  | if (!MaybeDeclCode) | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::ReadDeclRecord failed reading decl code: " + | 
|  | toString(MaybeDeclCode.takeError())); | 
|  | switch ((DeclCode)MaybeDeclCode.get()) { | 
|  | case DECL_CONTEXT_LEXICAL: | 
|  | case DECL_CONTEXT_VISIBLE: | 
|  | llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord"); | 
|  | case DECL_TYPEDEF: | 
|  | D = TypedefDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_TYPEALIAS: | 
|  | D = TypeAliasDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_ENUM: | 
|  | D = EnumDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_RECORD: | 
|  | D = RecordDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_ENUM_CONSTANT: | 
|  | D = EnumConstantDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_FUNCTION: | 
|  | D = FunctionDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_LINKAGE_SPEC: | 
|  | D = LinkageSpecDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_EXPORT: | 
|  | D = ExportDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_LABEL: | 
|  | D = LabelDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_NAMESPACE: | 
|  | D = NamespaceDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_NAMESPACE_ALIAS: | 
|  | D = NamespaceAliasDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_USING: | 
|  | D = UsingDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_USING_PACK: | 
|  | D = UsingPackDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_USING_SHADOW: | 
|  | D = UsingShadowDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CONSTRUCTOR_USING_SHADOW: | 
|  | D = ConstructorUsingShadowDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_USING_DIRECTIVE: | 
|  | D = UsingDirectiveDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_UNRESOLVED_USING_VALUE: | 
|  | D = UnresolvedUsingValueDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_UNRESOLVED_USING_TYPENAME: | 
|  | D = UnresolvedUsingTypenameDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CXX_RECORD: | 
|  | D = CXXRecordDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CXX_DEDUCTION_GUIDE: | 
|  | D = CXXDeductionGuideDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CXX_METHOD: | 
|  | D = CXXMethodDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CXX_CONSTRUCTOR: | 
|  | D = CXXConstructorDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_CXX_DESTRUCTOR: | 
|  | D = CXXDestructorDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CXX_CONVERSION: | 
|  | D = CXXConversionDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_ACCESS_SPEC: | 
|  | D = AccessSpecDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_FRIEND: | 
|  | D = FriendDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_FRIEND_TEMPLATE: | 
|  | D = FriendTemplateDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CLASS_TEMPLATE: | 
|  | D = ClassTemplateDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CLASS_TEMPLATE_SPECIALIZATION: | 
|  | D = ClassTemplateSpecializationDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: | 
|  | D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_VAR_TEMPLATE: | 
|  | D = VarTemplateDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_VAR_TEMPLATE_SPECIALIZATION: | 
|  | D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION: | 
|  | D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION: | 
|  | D = ClassScopeFunctionSpecializationDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_FUNCTION_TEMPLATE: | 
|  | D = FunctionTemplateDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_TEMPLATE_TYPE_PARM: | 
|  | D = TemplateTypeParmDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_NON_TYPE_TEMPLATE_PARM: | 
|  | D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: | 
|  | D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, | 
|  | Record.readInt()); | 
|  | break; | 
|  | case DECL_TEMPLATE_TEMPLATE_PARM: | 
|  | D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK: | 
|  | D = TemplateTemplateParmDecl::CreateDeserialized(Context, ID, | 
|  | Record.readInt()); | 
|  | break; | 
|  | case DECL_TYPE_ALIAS_TEMPLATE: | 
|  | D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CONCEPT: | 
|  | D = ConceptDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_STATIC_ASSERT: | 
|  | D = StaticAssertDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_METHOD: | 
|  | D = ObjCMethodDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_INTERFACE: | 
|  | D = ObjCInterfaceDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_IVAR: | 
|  | D = ObjCIvarDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_PROTOCOL: | 
|  | D = ObjCProtocolDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_AT_DEFS_FIELD: | 
|  | D = ObjCAtDefsFieldDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_CATEGORY: | 
|  | D = ObjCCategoryDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_CATEGORY_IMPL: | 
|  | D = ObjCCategoryImplDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_IMPLEMENTATION: | 
|  | D = ObjCImplementationDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_COMPATIBLE_ALIAS: | 
|  | D = ObjCCompatibleAliasDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_PROPERTY: | 
|  | D = ObjCPropertyDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_PROPERTY_IMPL: | 
|  | D = ObjCPropertyImplDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_FIELD: | 
|  | D = FieldDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_INDIRECTFIELD: | 
|  | D = IndirectFieldDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_VAR: | 
|  | D = VarDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_IMPLICIT_PARAM: | 
|  | D = ImplicitParamDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_PARM_VAR: | 
|  | D = ParmVarDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_DECOMPOSITION: | 
|  | D = DecompositionDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_BINDING: | 
|  | D = BindingDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_FILE_SCOPE_ASM: | 
|  | D = FileScopeAsmDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_BLOCK: | 
|  | D = BlockDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_MS_PROPERTY: | 
|  | D = MSPropertyDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_CAPTURED: | 
|  | D = CapturedDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_CXX_BASE_SPECIFIERS: | 
|  | Error("attempt to read a C++ base-specifier record as a declaration"); | 
|  | return nullptr; | 
|  | case DECL_CXX_CTOR_INITIALIZERS: | 
|  | Error("attempt to read a C++ ctor initializer record as a declaration"); | 
|  | return nullptr; | 
|  | case DECL_IMPORT: | 
|  | // Note: last entry of the ImportDecl record is the number of stored source | 
|  | // locations. | 
|  | D = ImportDecl::CreateDeserialized(Context, ID, Record.back()); | 
|  | break; | 
|  | case DECL_OMP_THREADPRIVATE: | 
|  | D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_OMP_ALLOCATE: { | 
|  | unsigned NumVars = Record.readInt(); | 
|  | unsigned NumClauses = Record.readInt(); | 
|  | D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses); | 
|  | break; | 
|  | } | 
|  | case DECL_OMP_REQUIRES: | 
|  | D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_OMP_DECLARE_REDUCTION: | 
|  | D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OMP_DECLARE_MAPPER: | 
|  | D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_OMP_CAPTUREDEXPR: | 
|  | D = OMPCapturedExprDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_PRAGMA_COMMENT: | 
|  | D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record.readInt()); | 
|  | break; | 
|  | case DECL_PRAGMA_DETECT_MISMATCH: | 
|  | D = PragmaDetectMismatchDecl::CreateDeserialized(Context, ID, | 
|  | Record.readInt()); | 
|  | break; | 
|  | case DECL_EMPTY: | 
|  | D = EmptyDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_LIFETIME_EXTENDED_TEMPORARY: | 
|  | D = LifetimeExtendedTemporaryDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | case DECL_OBJC_TYPE_PARAM: | 
|  | D = ObjCTypeParamDecl::CreateDeserialized(Context, ID); | 
|  | break; | 
|  | } | 
|  |  | 
|  | assert(D && "Unknown declaration reading AST file"); | 
|  | LoadedDecl(Index, D); | 
|  | // Set the DeclContext before doing any deserialization, to make sure internal | 
|  | // calls to Decl::getASTContext() by Decl's methods will find the | 
|  | // TranslationUnitDecl without crashing. | 
|  | D->setDeclContext(Context.getTranslationUnitDecl()); | 
|  | Reader.Visit(D); | 
|  |  | 
|  | // If this declaration is also a declaration context, get the | 
|  | // offsets for its tables of lexical and visible declarations. | 
|  | if (auto *DC = dyn_cast<DeclContext>(D)) { | 
|  | std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC); | 
|  | if (Offsets.first && | 
|  | ReadLexicalDeclContextStorage(*Loc.F, DeclsCursor, Offsets.first, DC)) | 
|  | return nullptr; | 
|  | if (Offsets.second && | 
|  | ReadVisibleDeclContextStorage(*Loc.F, DeclsCursor, Offsets.second, ID)) | 
|  | return nullptr; | 
|  | } | 
|  | assert(Record.getIdx() == Record.size()); | 
|  |  | 
|  | // Load any relevant update records. | 
|  | PendingUpdateRecords.push_back( | 
|  | PendingUpdateRecord(ID, D, /*JustLoaded=*/true)); | 
|  |  | 
|  | // Load the categories after recursive loading is finished. | 
|  | if (auto *Class = dyn_cast<ObjCInterfaceDecl>(D)) | 
|  | // If we already have a definition when deserializing the ObjCInterfaceDecl, | 
|  | // we put the Decl in PendingDefinitions so we can pull the categories here. | 
|  | if (Class->isThisDeclarationADefinition() || | 
|  | PendingDefinitions.count(Class)) | 
|  | loadObjCCategories(ID, Class); | 
|  |  | 
|  | // If we have deserialized a declaration that has a definition the | 
|  | // AST consumer might need to know about, queue it. | 
|  | // We don't pass it to the consumer immediately because we may be in recursive | 
|  | // loading, and some declarations may still be initializing. | 
|  | PotentiallyInterestingDecls.push_back( | 
|  | InterestingDecl(D, Reader.hasPendingBody())); | 
|  |  | 
|  | return D; | 
|  | } | 
|  |  | 
|  | void ASTReader::PassInterestingDeclsToConsumer() { | 
|  | assert(Consumer); | 
|  |  | 
|  | if (PassingDeclsToConsumer) | 
|  | return; | 
|  |  | 
|  | // Guard variable to avoid recursively redoing the process of passing | 
|  | // decls to consumer. | 
|  | SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer, | 
|  | true); | 
|  |  | 
|  | // Ensure that we've loaded all potentially-interesting declarations | 
|  | // that need to be eagerly loaded. | 
|  | for (auto ID : EagerlyDeserializedDecls) | 
|  | GetDecl(ID); | 
|  | EagerlyDeserializedDecls.clear(); | 
|  |  | 
|  | while (!PotentiallyInterestingDecls.empty()) { | 
|  | InterestingDecl D = PotentiallyInterestingDecls.front(); | 
|  | PotentiallyInterestingDecls.pop_front(); | 
|  | if (isConsumerInterestedIn(getContext(), D.getDecl(), D.hasPendingBody())) | 
|  | PassInterestingDeclToConsumer(D.getDecl()); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { | 
|  | // The declaration may have been modified by files later in the chain. | 
|  | // If this is the case, read the record containing the updates from each file | 
|  | // and pass it to ASTDeclReader to make the modifications. | 
|  | serialization::GlobalDeclID ID = Record.ID; | 
|  | Decl *D = Record.D; | 
|  | ProcessingUpdatesRAIIObj ProcessingUpdates(*this); | 
|  | DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); | 
|  |  | 
|  | SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs; | 
|  |  | 
|  | if (UpdI != DeclUpdateOffsets.end()) { | 
|  | auto UpdateOffsets = std::move(UpdI->second); | 
|  | DeclUpdateOffsets.erase(UpdI); | 
|  |  | 
|  | // Check if this decl was interesting to the consumer. If we just loaded | 
|  | // the declaration, then we know it was interesting and we skip the call | 
|  | // to isConsumerInterestedIn because it is unsafe to call in the | 
|  | // current ASTReader state. | 
|  | bool WasInteresting = | 
|  | Record.JustLoaded || isConsumerInterestedIn(getContext(), D, false); | 
|  | for (auto &FileAndOffset : UpdateOffsets) { | 
|  | ModuleFile *F = FileAndOffset.first; | 
|  | uint64_t Offset = FileAndOffset.second; | 
|  | llvm::BitstreamCursor &Cursor = F->DeclsCursor; | 
|  | SavedStreamPosition SavedPosition(Cursor); | 
|  | if (llvm::Error JumpFailed = Cursor.JumpToBit(Offset)) | 
|  | // FIXME don't do a fatal error. | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::loadDeclUpdateRecords failed jumping: " + | 
|  | toString(std::move(JumpFailed))); | 
|  | Expected<unsigned> MaybeCode = Cursor.ReadCode(); | 
|  | if (!MaybeCode) | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::loadDeclUpdateRecords failed reading code: " + | 
|  | toString(MaybeCode.takeError())); | 
|  | unsigned Code = MaybeCode.get(); | 
|  | ASTRecordReader Record(*this, *F); | 
|  | if (Expected<unsigned> MaybeRecCode = Record.readRecord(Cursor, Code)) | 
|  | assert(MaybeRecCode.get() == DECL_UPDATES && | 
|  | "Expected DECL_UPDATES record!"); | 
|  | else | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::loadDeclUpdateRecords failed reading rec code: " + | 
|  | toString(MaybeCode.takeError())); | 
|  |  | 
|  | ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID, | 
|  | SourceLocation()); | 
|  | Reader.UpdateDecl(D, PendingLazySpecializationIDs); | 
|  |  | 
|  | // We might have made this declaration interesting. If so, remember that | 
|  | // we need to hand it off to the consumer. | 
|  | if (!WasInteresting && | 
|  | isConsumerInterestedIn(getContext(), D, Reader.hasPendingBody())) { | 
|  | PotentiallyInterestingDecls.push_back( | 
|  | InterestingDecl(D, Reader.hasPendingBody())); | 
|  | WasInteresting = true; | 
|  | } | 
|  | } | 
|  | } | 
|  | // Add the lazy specializations to the template. | 
|  | assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) || | 
|  | isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) && | 
|  | "Must not have pending specializations"); | 
|  | if (auto *CTD = dyn_cast<ClassTemplateDecl>(D)) | 
|  | ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs); | 
|  | else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) | 
|  | ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs); | 
|  | else if (auto *VTD = dyn_cast<VarTemplateDecl>(D)) | 
|  | ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs); | 
|  | PendingLazySpecializationIDs.clear(); | 
|  |  | 
|  | // Load the pending visible updates for this decl context, if it has any. | 
|  | auto I = PendingVisibleUpdates.find(ID); | 
|  | if (I != PendingVisibleUpdates.end()) { | 
|  | auto VisibleUpdates = std::move(I->second); | 
|  | PendingVisibleUpdates.erase(I); | 
|  |  | 
|  | auto *DC = cast<DeclContext>(D)->getPrimaryContext(); | 
|  | for (const auto &Update : VisibleUpdates) | 
|  | Lookups[DC].Table.add( | 
|  | Update.Mod, Update.Data, | 
|  | reader::ASTDeclContextNameLookupTrait(*this, *Update.Mod)); | 
|  | DC->setHasExternalVisibleStorage(true); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { | 
|  | // Attach FirstLocal to the end of the decl chain. | 
|  | Decl *CanonDecl = FirstLocal->getCanonicalDecl(); | 
|  | if (FirstLocal != CanonDecl) { | 
|  | Decl *PrevMostRecent = ASTDeclReader::getMostRecentDecl(CanonDecl); | 
|  | ASTDeclReader::attachPreviousDecl( | 
|  | *this, FirstLocal, PrevMostRecent ? PrevMostRecent : CanonDecl, | 
|  | CanonDecl); | 
|  | } | 
|  |  | 
|  | if (!LocalOffset) { | 
|  | ASTDeclReader::attachLatestDecl(CanonDecl, FirstLocal); | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Load the list of other redeclarations from this module file. | 
|  | ModuleFile *M = getOwningModuleFile(FirstLocal); | 
|  | assert(M && "imported decl from no module file"); | 
|  |  | 
|  | llvm::BitstreamCursor &Cursor = M->DeclsCursor; | 
|  | SavedStreamPosition SavedPosition(Cursor); | 
|  | if (llvm::Error JumpFailed = Cursor.JumpToBit(LocalOffset)) | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::loadPendingDeclChain failed jumping: " + | 
|  | toString(std::move(JumpFailed))); | 
|  |  | 
|  | RecordData Record; | 
|  | Expected<unsigned> MaybeCode = Cursor.ReadCode(); | 
|  | if (!MaybeCode) | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::loadPendingDeclChain failed reading code: " + | 
|  | toString(MaybeCode.takeError())); | 
|  | unsigned Code = MaybeCode.get(); | 
|  | if (Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record)) | 
|  | assert(MaybeRecCode.get() == LOCAL_REDECLARATIONS && | 
|  | "expected LOCAL_REDECLARATIONS record!"); | 
|  | else | 
|  | llvm::report_fatal_error( | 
|  | "ASTReader::loadPendingDeclChain failed reading rec code: " + | 
|  | toString(MaybeCode.takeError())); | 
|  |  | 
|  | // FIXME: We have several different dispatches on decl kind here; maybe | 
|  | // we should instead generate one loop per kind and dispatch up-front? | 
|  | Decl *MostRecent = FirstLocal; | 
|  | for (unsigned I = 0, N = Record.size(); I != N; ++I) { | 
|  | auto *D = GetLocalDecl(*M, Record[N - I - 1]); | 
|  | ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl); | 
|  | MostRecent = D; | 
|  | } | 
|  | ASTDeclReader::attachLatestDecl(CanonDecl, MostRecent); | 
|  | } | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | /// Given an ObjC interface, goes through the modules and links to the | 
|  | /// interface all the categories for it. | 
|  | class ObjCCategoriesVisitor { | 
|  | ASTReader &Reader; | 
|  | ObjCInterfaceDecl *Interface; | 
|  | llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized; | 
|  | ObjCCategoryDecl *Tail = nullptr; | 
|  | llvm::DenseMap<DeclarationName, ObjCCategoryDecl *> NameCategoryMap; | 
|  | serialization::GlobalDeclID InterfaceID; | 
|  | unsigned PreviousGeneration; | 
|  |  | 
|  | void add(ObjCCategoryDecl *Cat) { | 
|  | // Only process each category once. | 
|  | if (!Deserialized.erase(Cat)) | 
|  | return; | 
|  |  | 
|  | // Check for duplicate categories. | 
|  | if (Cat->getDeclName()) { | 
|  | ObjCCategoryDecl *&Existing = NameCategoryMap[Cat->getDeclName()]; | 
|  | if (Existing && | 
|  | Reader.getOwningModuleFile(Existing) | 
|  | != Reader.getOwningModuleFile(Cat)) { | 
|  | // FIXME: We should not warn for duplicates in diamond: | 
|  | // | 
|  | //   MT     // | 
|  | //  /  \    // | 
|  | // ML  MR   // | 
|  | //  \  /    // | 
|  | //   MB     // | 
|  | // | 
|  | // If there are duplicates in ML/MR, there will be warning when | 
|  | // creating MB *and* when importing MB. We should not warn when | 
|  | // importing. | 
|  | Reader.Diag(Cat->getLocation(), diag::warn_dup_category_def) | 
|  | << Interface->getDeclName() << Cat->getDeclName(); | 
|  | Reader.Diag(Existing->getLocation(), diag::note_previous_definition); | 
|  | } else if (!Existing) { | 
|  | // Record this category. | 
|  | Existing = Cat; | 
|  | } | 
|  | } | 
|  |  | 
|  | // Add this category to the end of the chain. | 
|  | if (Tail) | 
|  | ASTDeclReader::setNextObjCCategory(Tail, Cat); | 
|  | else | 
|  | Interface->setCategoryListRaw(Cat); | 
|  | Tail = Cat; | 
|  | } | 
|  |  | 
|  | public: | 
|  | ObjCCategoriesVisitor(ASTReader &Reader, | 
|  | ObjCInterfaceDecl *Interface, | 
|  | llvm::SmallPtrSetImpl<ObjCCategoryDecl *> &Deserialized, | 
|  | serialization::GlobalDeclID InterfaceID, | 
|  | unsigned PreviousGeneration) | 
|  | : Reader(Reader), Interface(Interface), Deserialized(Deserialized), | 
|  | InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) { | 
|  | // Populate the name -> category map with the set of known categories. | 
|  | for (auto *Cat : Interface->known_categories()) { | 
|  | if (Cat->getDeclName()) | 
|  | NameCategoryMap[Cat->getDeclName()] = Cat; | 
|  |  | 
|  | // Keep track of the tail of the category list. | 
|  | Tail = Cat; | 
|  | } | 
|  | } | 
|  |  | 
|  | bool operator()(ModuleFile &M) { | 
|  | // If we've loaded all of the category information we care about from | 
|  | // this module file, we're done. | 
|  | if (M.Generation <= PreviousGeneration) | 
|  | return true; | 
|  |  | 
|  | // Map global ID of the definition down to the local ID used in this | 
|  | // module file. If there is no such mapping, we'll find nothing here | 
|  | // (or in any module it imports). | 
|  | DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); | 
|  | if (!LocalID) | 
|  | return true; | 
|  |  | 
|  | // Perform a binary search to find the local redeclarations for this | 
|  | // declaration (if any). | 
|  | const ObjCCategoriesInfo Compare = { LocalID, 0 }; | 
|  | const ObjCCategoriesInfo *Result | 
|  | = std::lower_bound(M.ObjCCategoriesMap, | 
|  | M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap, | 
|  | Compare); | 
|  | if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap || | 
|  | Result->DefinitionID != LocalID) { | 
|  | // We didn't find anything. If the class definition is in this module | 
|  | // file, then the module files it depends on cannot have any categories, | 
|  | // so suppress further lookup. | 
|  | return Reader.isDeclIDFromModule(InterfaceID, M); | 
|  | } | 
|  |  | 
|  | // We found something. Dig out all of the categories. | 
|  | unsigned Offset = Result->Offset; | 
|  | unsigned N = M.ObjCCategories[Offset]; | 
|  | M.ObjCCategories[Offset++] = 0; // Don't try to deserialize again | 
|  | for (unsigned I = 0; I != N; ++I) | 
|  | add(cast_or_null<ObjCCategoryDecl>( | 
|  | Reader.GetLocalDecl(M, M.ObjCCategories[Offset++]))); | 
|  | return true; | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // namespace | 
|  |  | 
|  | void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID, | 
|  | ObjCInterfaceDecl *D, | 
|  | unsigned PreviousGeneration) { | 
|  | ObjCCategoriesVisitor Visitor(*this, D, CategoriesDeserialized, ID, | 
|  | PreviousGeneration); | 
|  | ModuleMgr.visit(Visitor); | 
|  | } | 
|  |  | 
|  | template<typename DeclT, typename Fn> | 
|  | static void forAllLaterRedecls(DeclT *D, Fn F) { | 
|  | F(D); | 
|  |  | 
|  | // Check whether we've already merged D into its redeclaration chain. | 
|  | // MostRecent may or may not be nullptr if D has not been merged. If | 
|  | // not, walk the merged redecl chain and see if it's there. | 
|  | auto *MostRecent = D->getMostRecentDecl(); | 
|  | bool Found = false; | 
|  | for (auto *Redecl = MostRecent; Redecl && !Found; | 
|  | Redecl = Redecl->getPreviousDecl()) | 
|  | Found = (Redecl == D); | 
|  |  | 
|  | // If this declaration is merged, apply the functor to all later decls. | 
|  | if (Found) { | 
|  | for (auto *Redecl = MostRecent; Redecl != D; | 
|  | Redecl = Redecl->getPreviousDecl()) | 
|  | F(Redecl); | 
|  | } | 
|  | } | 
|  |  | 
|  | void ASTDeclReader::UpdateDecl(Decl *D, | 
|  | llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) { | 
|  | while (Record.getIdx() < Record.size()) { | 
|  | switch ((DeclUpdateKind)Record.readInt()) { | 
|  | case UPD_CXX_ADDED_IMPLICIT_MEMBER: { | 
|  | auto *RD = cast<CXXRecordDecl>(D); | 
|  | // FIXME: If we also have an update record for instantiating the | 
|  | // definition of D, we need that to happen before we get here. | 
|  | Decl *MD = Record.readDecl(); | 
|  | assert(MD && "couldn't read decl from update record"); | 
|  | // FIXME: We should call addHiddenDecl instead, to add the member | 
|  | // to its DeclContext. | 
|  | RD->addedMember(MD); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: | 
|  | // It will be added to the template's lazy specialization set. | 
|  | PendingLazySpecializationIDs.push_back(ReadDeclID()); | 
|  | break; | 
|  |  | 
|  | case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: { | 
|  | auto *Anon = ReadDeclAs<NamespaceDecl>(); | 
|  |  | 
|  | // Each module has its own anonymous namespace, which is disjoint from | 
|  | // any other module's anonymous namespaces, so don't attach the anonymous | 
|  | // namespace at all. | 
|  | if (!Record.isModule()) { | 
|  | if (auto *TU = dyn_cast<TranslationUnitDecl>(D)) | 
|  | TU->setAnonymousNamespace(Anon); | 
|  | else | 
|  | cast<NamespaceDecl>(D)->setAnonymousNamespace(Anon); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_ADDED_VAR_DEFINITION: { | 
|  | auto *VD = cast<VarDecl>(D); | 
|  | VD->NonParmVarDeclBits.IsInline = Record.readInt(); | 
|  | VD->NonParmVarDeclBits.IsInlineSpecified = Record.readInt(); | 
|  | uint64_t Val = Record.readInt(); | 
|  | if (Val && !VD->getInit()) { | 
|  | VD->setInit(Record.readExpr()); | 
|  | if (Val > 1) { // IsInitKnownICE = 1, IsInitNotICE = 2, IsInitICE = 3 | 
|  | EvaluatedStmt *Eval = VD->ensureEvaluatedStmt(); | 
|  | Eval->CheckedICE = true; | 
|  | Eval->IsICE = Val == 3; | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_POINT_OF_INSTANTIATION: { | 
|  | SourceLocation POI = Record.readSourceLocation(); | 
|  | if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) { | 
|  | VTSD->setPointOfInstantiation(POI); | 
|  | } else if (auto *VD = dyn_cast<VarDecl>(D)) { | 
|  | VD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); | 
|  | } else { | 
|  | auto *FD = cast<FunctionDecl>(D); | 
|  | if (auto *FTSInfo = FD->TemplateOrSpecialization | 
|  | .dyn_cast<FunctionTemplateSpecializationInfo *>()) | 
|  | FTSInfo->setPointOfInstantiation(POI); | 
|  | else | 
|  | FD->TemplateOrSpecialization.get<MemberSpecializationInfo *>() | 
|  | ->setPointOfInstantiation(POI); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_INSTANTIATED_DEFAULT_ARGUMENT: { | 
|  | auto *Param = cast<ParmVarDecl>(D); | 
|  |  | 
|  | // We have to read the default argument regardless of whether we use it | 
|  | // so that hypothetical further update records aren't messed up. | 
|  | // TODO: Add a function to skip over the next expr record. | 
|  | auto *DefaultArg = Record.readExpr(); | 
|  |  | 
|  | // Only apply the update if the parameter still has an uninstantiated | 
|  | // default argument. | 
|  | if (Param->hasUninstantiatedDefaultArg()) | 
|  | Param->setDefaultArg(DefaultArg); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_INSTANTIATED_DEFAULT_MEMBER_INITIALIZER: { | 
|  | auto *FD = cast<FieldDecl>(D); | 
|  | auto *DefaultInit = Record.readExpr(); | 
|  |  | 
|  | // Only apply the update if the field still has an uninstantiated | 
|  | // default member initializer. | 
|  | if (FD->hasInClassInitializer() && !FD->getInClassInitializer()) { | 
|  | if (DefaultInit) | 
|  | FD->setInClassInitializer(DefaultInit); | 
|  | else | 
|  | // Instantiation failed. We can get here if we serialized an AST for | 
|  | // an invalid program. | 
|  | FD->removeInClassInitializer(); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_ADDED_FUNCTION_DEFINITION: { | 
|  | auto *FD = cast<FunctionDecl>(D); | 
|  | if (Reader.PendingBodies[FD]) { | 
|  | // FIXME: Maybe check for ODR violations. | 
|  | // It's safe to stop now because this update record is always last. | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (Record.readInt()) { | 
|  | // Maintain AST consistency: any later redeclarations of this function | 
|  | // are inline if this one is. (We might have merged another declaration | 
|  | // into this one.) | 
|  | forAllLaterRedecls(FD, [](FunctionDecl *FD) { | 
|  | FD->setImplicitlyInline(); | 
|  | }); | 
|  | } | 
|  | FD->setInnerLocStart(ReadSourceLocation()); | 
|  | ReadFunctionDefinition(FD); | 
|  | assert(Record.getIdx() == Record.size() && "lazy body must be last"); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: { | 
|  | auto *RD = cast<CXXRecordDecl>(D); | 
|  | auto *OldDD = RD->getCanonicalDecl()->DefinitionData; | 
|  | bool HadRealDefinition = | 
|  | OldDD && (OldDD->Definition != RD || | 
|  | !Reader.PendingFakeDefinitionData.count(OldDD)); | 
|  | RD->setParamDestroyedInCallee(Record.readInt()); | 
|  | RD->setArgPassingRestrictions( | 
|  | (RecordDecl::ArgPassingKind)Record.readInt()); | 
|  | ReadCXXRecordDefinition(RD, /*Update*/true); | 
|  |  | 
|  | // Visible update is handled separately. | 
|  | uint64_t LexicalOffset = ReadLocalOffset(); | 
|  | if (!HadRealDefinition && LexicalOffset) { | 
|  | Record.readLexicalDeclContextStorage(LexicalOffset, RD); | 
|  | Reader.PendingFakeDefinitionData.erase(OldDD); | 
|  | } | 
|  |  | 
|  | auto TSK = (TemplateSpecializationKind)Record.readInt(); | 
|  | SourceLocation POI = ReadSourceLocation(); | 
|  | if (MemberSpecializationInfo *MSInfo = | 
|  | RD->getMemberSpecializationInfo()) { | 
|  | MSInfo->setTemplateSpecializationKind(TSK); | 
|  | MSInfo->setPointOfInstantiation(POI); | 
|  | } else { | 
|  | auto *Spec = cast<ClassTemplateSpecializationDecl>(RD); | 
|  | Spec->setTemplateSpecializationKind(TSK); | 
|  | Spec->setPointOfInstantiation(POI); | 
|  |  | 
|  | if (Record.readInt()) { | 
|  | auto *PartialSpec = | 
|  | ReadDeclAs<ClassTemplatePartialSpecializationDecl>(); | 
|  | SmallVector<TemplateArgument, 8> TemplArgs; | 
|  | Record.readTemplateArgumentList(TemplArgs); | 
|  | auto *TemplArgList = TemplateArgumentList::CreateCopy( | 
|  | Reader.getContext(), TemplArgs); | 
|  |  | 
|  | // FIXME: If we already have a partial specialization set, | 
|  | // check that it matches. | 
|  | if (!Spec->getSpecializedTemplateOrPartial() | 
|  | .is<ClassTemplatePartialSpecializationDecl *>()) | 
|  | Spec->setInstantiationOf(PartialSpec, TemplArgList); | 
|  | } | 
|  | } | 
|  |  | 
|  | RD->setTagKind((TagTypeKind)Record.readInt()); | 
|  | RD->setLocation(ReadSourceLocation()); | 
|  | RD->setLocStart(ReadSourceLocation()); | 
|  | RD->setBraceRange(ReadSourceRange()); | 
|  |  | 
|  | if (Record.readInt()) { | 
|  | AttrVec Attrs; | 
|  | Record.readAttributes(Attrs); | 
|  | // If the declaration already has attributes, we assume that some other | 
|  | // AST file already loaded them. | 
|  | if (!D->hasAttrs()) | 
|  | D->setAttrsImpl(Attrs, Reader.getContext()); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_RESOLVED_DTOR_DELETE: { | 
|  | // Set the 'operator delete' directly to avoid emitting another update | 
|  | // record. | 
|  | auto *Del = ReadDeclAs<FunctionDecl>(); | 
|  | auto *First = cast<CXXDestructorDecl>(D->getCanonicalDecl()); | 
|  | auto *ThisArg = Record.readExpr(); | 
|  | // FIXME: Check consistency if we have an old and new operator delete. | 
|  | if (!First->OperatorDelete) { | 
|  | First->OperatorDelete = Del; | 
|  | First->OperatorDeleteThisArg = ThisArg; | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_RESOLVED_EXCEPTION_SPEC: { | 
|  | FunctionProtoType::ExceptionSpecInfo ESI; | 
|  | SmallVector<QualType, 8> ExceptionStorage; | 
|  | Record.readExceptionSpec(ExceptionStorage, ESI); | 
|  |  | 
|  | // Update this declaration's exception specification, if needed. | 
|  | auto *FD = cast<FunctionDecl>(D); | 
|  | auto *FPT = FD->getType()->castAs<FunctionProtoType>(); | 
|  | // FIXME: If the exception specification is already present, check that it | 
|  | // matches. | 
|  | if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { | 
|  | FD->setType(Reader.getContext().getFunctionType( | 
|  | FPT->getReturnType(), FPT->getParamTypes(), | 
|  | FPT->getExtProtoInfo().withExceptionSpec(ESI))); | 
|  |  | 
|  | // When we get to the end of deserializing, see if there are other decls | 
|  | // that we need to propagate this exception specification onto. | 
|  | Reader.PendingExceptionSpecUpdates.insert( | 
|  | std::make_pair(FD->getCanonicalDecl(), FD)); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_CXX_DEDUCED_RETURN_TYPE: { | 
|  | auto *FD = cast<FunctionDecl>(D); | 
|  | QualType DeducedResultType = Record.readType(); | 
|  | Reader.PendingDeducedTypeUpdates.insert( | 
|  | {FD->getCanonicalDecl(), DeducedResultType}); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_DECL_MARKED_USED: | 
|  | // Maintain AST consistency: any later redeclarations are used too. | 
|  | D->markUsed(Reader.getContext()); | 
|  | break; | 
|  |  | 
|  | case UPD_MANGLING_NUMBER: | 
|  | Reader.getContext().setManglingNumber(cast<NamedDecl>(D), | 
|  | Record.readInt()); | 
|  | break; | 
|  |  | 
|  | case UPD_STATIC_LOCAL_NUMBER: | 
|  | Reader.getContext().setStaticLocalNumber(cast<VarDecl>(D), | 
|  | Record.readInt()); | 
|  | break; | 
|  |  | 
|  | case UPD_DECL_MARKED_OPENMP_THREADPRIVATE: | 
|  | D->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( | 
|  | Reader.getContext(), ReadSourceRange(), | 
|  | AttributeCommonInfo::AS_Pragma)); | 
|  | break; | 
|  |  | 
|  | case UPD_DECL_MARKED_OPENMP_ALLOCATE: { | 
|  | auto AllocatorKind = | 
|  | static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(Record.readInt()); | 
|  | Expr *Allocator = Record.readExpr(); | 
|  | SourceRange SR = ReadSourceRange(); | 
|  | D->addAttr(OMPAllocateDeclAttr::CreateImplicit( | 
|  | Reader.getContext(), AllocatorKind, Allocator, SR, | 
|  | AttributeCommonInfo::AS_Pragma)); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_DECL_EXPORTED: { | 
|  | unsigned SubmoduleID = readSubmoduleID(); | 
|  | auto *Exported = cast<NamedDecl>(D); | 
|  | Module *Owner = SubmoduleID ? Reader.getSubmodule(SubmoduleID) : nullptr; | 
|  | Reader.getContext().mergeDefinitionIntoModule(Exported, Owner); | 
|  | Reader.PendingMergedDefinitionsToDeduplicate.insert(Exported); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_DECL_MARKED_OPENMP_DECLARETARGET: { | 
|  | OMPDeclareTargetDeclAttr::MapTypeTy MapType = | 
|  | static_cast<OMPDeclareTargetDeclAttr::MapTypeTy>(Record.readInt()); | 
|  | OMPDeclareTargetDeclAttr::DevTypeTy DevType = | 
|  | static_cast<OMPDeclareTargetDeclAttr::DevTypeTy>(Record.readInt()); | 
|  | D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit( | 
|  | Reader.getContext(), MapType, DevType, ReadSourceRange(), | 
|  | AttributeCommonInfo::AS_Pragma)); | 
|  | break; | 
|  | } | 
|  |  | 
|  | case UPD_ADDED_ATTR_TO_RECORD: | 
|  | AttrVec Attrs; | 
|  | Record.readAttributes(Attrs); | 
|  | assert(Attrs.size() == 1); | 
|  | D->addAttr(Attrs[0]); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } |