diff options
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 102 |
1 files changed, 68 insertions, 34 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index b23c33c55188..1a0c5b58e7f6 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -128,20 +128,22 @@ namespace clang { GlobalDeclID FirstID; Decl *MergeWith; mutable bool Owning; + bool IsKeyDecl; Decl::Kind DeclKind; void operator=(RedeclarableResult &) = delete; public: RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID, - Decl *MergeWith, Decl::Kind DeclKind) + Decl *MergeWith, Decl::Kind DeclKind, + bool IsKeyDecl) : Reader(Reader), FirstID(FirstID), MergeWith(MergeWith), - Owning(true), DeclKind(DeclKind) {} + Owning(true), IsKeyDecl(IsKeyDecl), DeclKind(DeclKind) {} RedeclarableResult(RedeclarableResult &&Other) : Reader(Other.Reader), FirstID(Other.FirstID), MergeWith(Other.MergeWith), Owning(Other.Owning), - DeclKind(Other.DeclKind) { + IsKeyDecl(Other.IsKeyDecl), DeclKind(Other.DeclKind) { Other.Owning = false; } @@ -156,6 +158,9 @@ namespace clang { /// \brief Retrieve the first ID. GlobalDeclID getFirstID() const { return FirstID; } + /// \brief Is this declaration the key declaration? + bool isKeyDecl() const { return IsKeyDecl; } + /// \brief Get a known declaration that this should be merged with, if /// any. Decl *getKnownMergeTarget() const { return MergeWith; } @@ -348,10 +353,13 @@ namespace clang { void mergeTemplatePattern(RedeclarableTemplateDecl *D, RedeclarableTemplateDecl *Existing, - DeclID DsID); + 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); @@ -899,18 +907,49 @@ void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { MD->setParamsAndSelLocs(Reader.getContext(), Params, SelLocs); } +void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { + VisitTypedefNameDecl(D); + D->Variance = Record[Idx++]; + D->Index = Record[Idx++]; + D->VarianceLoc = ReadSourceLocation(Record, Idx); + D->ColonLoc = ReadSourceLocation(Record, Idx); +} + void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) { VisitNamedDecl(CD); CD->setAtStartLoc(ReadSourceLocation(Record, Idx)); CD->setAtEndRange(ReadSourceRange(Record, Idx)); } +ObjCTypeParamList *ASTDeclReader::ReadObjCTypeParamList() { + unsigned numParams = Record[Idx++]; + if (numParams == 0) + return nullptr; + + SmallVector<ObjCTypeParamDecl *, 4> typeParams; + typeParams.reserve(numParams); + for (unsigned i = 0; i != numParams; ++i) { + auto typeParam = ReadDeclAs<ObjCTypeParamDecl>(Record, Idx); + if (!typeParam) + return nullptr; + + typeParams.push_back(typeParam); + } + + SourceLocation lAngleLoc = ReadSourceLocation(Record, Idx); + SourceLocation rAngleLoc = ReadSourceLocation(Record, Idx); + + return ObjCTypeParamList::create(Reader.getContext(), lAngleLoc, + typeParams, rAngleLoc); +} + void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { RedeclarableResult Redecl = VisitRedeclarable(ID); VisitObjCContainerDecl(ID); TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]); mergeRedeclarable(ID, Redecl); - + + ID->TypeParamList = ReadObjCTypeParamList(); if (Record[Idx++]) { // Read the definition. ID->allocateDefinitionData(); @@ -922,8 +961,7 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { ObjCInterfaceDecl::DefinitionData &Data = ID->data(); // Read the superclass. - Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx); - Data.SuperClassLoc = ReadSourceLocation(Record, Idx); + Data.SuperClassTInfo = GetTypeSourceInfo(Record, Idx); Data.EndLoc = ReadSourceLocation(Record, Idx); Data.HasDesignatedInitializers = Record[Idx++]; @@ -1020,6 +1058,7 @@ void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { Reader.CategoriesDeserialized.insert(CD); CD->ClassInterface = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx); + CD->TypeParamList = ReadObjCTypeParamList(); unsigned NumProtoRefs = Record[Idx++]; SmallVector<ObjCProtocolDecl *, 16> ProtoRefs; ProtoRefs.reserve(NumProtoRefs); @@ -2139,12 +2178,16 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { DeclID FirstDeclID = ReadDeclID(Record, Idx); Decl *MergeWith = nullptr; + bool IsKeyDecl = ThisDeclID == FirstDeclID; // 0 indicates that this declaration was the only declaration of its entity, // and is used for space optimization. - if (FirstDeclID == 0) + if (FirstDeclID == 0) { FirstDeclID = ThisDeclID; - else if (unsigned N = Record[Idx++]) { + IsKeyDecl = true; + } else if (unsigned N = Record[Idx++]) { + IsKeyDecl = false; + // 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. @@ -2170,7 +2213,7 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { // The result structure takes care to note that we need to load the // other declaration chains for this ID. return RedeclarableResult(Reader, FirstDeclID, MergeWith, - static_cast<T *>(D)->getKind()); + static_cast<T *>(D)->getKind(), IsKeyDecl); } /// \brief Attempts to merge the given declaration (D) with another declaration @@ -2209,11 +2252,12 @@ template<typename T> static T assert_cast(...) { /// declarations. void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, RedeclarableTemplateDecl *Existing, - DeclID DsID) { + DeclID DsID, bool IsKeyDecl) { auto *DPattern = D->getTemplatedDecl(); auto *ExistingPattern = Existing->getTemplatedDecl(); RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(), - /*MergeWith*/ExistingPattern, DPattern->getKind()); + /*MergeWith*/ExistingPattern, DPattern->getKind(), + IsKeyDecl); if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) { // Merge with any existing definition. @@ -2276,11 +2320,11 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing, if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D)) mergeTemplatePattern( DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon), - TemplatePatternID); + TemplatePatternID, Redecl.isKeyDecl()); - // If this declaration was the canonical declaration, make a note of that. - if (DCanon == D) { - Reader.MergedDecls[ExistingCanon].push_back(Redecl.getFirstID()); + // If this declaration is a key declaration, make a note of that. + if (Redecl.isKeyDecl()) { + Reader.KeyDecls[ExistingCanon].push_back(Redecl.getFirstID()); if (Reader.PendingDeclChainsKnown.insert(ExistingCanon).second) Reader.PendingDeclChains.push_back(ExistingCanon); } @@ -3259,6 +3303,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_EMPTY: D = EmptyDecl::CreateDeserialized(Context, ID); break; + case DECL_OBJC_TYPE_PARAM: + D = ObjCTypeParamDecl::CreateDeserialized(Context, ID); + break; } assert(D && "Unknown declaration reading AST file"); @@ -3418,20 +3465,9 @@ namespace { M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, Compare); if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap || - Result->FirstID != ID) { - // If we have a previously-canonical singleton declaration that was - // merged into another redeclaration chain, create a trivial chain - // for this single declaration so that it will get wired into the - // complete redeclaration chain. - if (GlobalID != CanonID && - GlobalID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && - GlobalID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls) { - addToChain(Reader.GetDecl(GlobalID)); - } - + Result->FirstID != ID) return; - } - + // Dig out all of the redeclarations. unsigned Offset = Result->Offset; unsigned N = M.RedeclarationChains[Offset]; @@ -3472,8 +3508,6 @@ namespace { // Visit each of the declarations. for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I) searchForID(M, SearchDecls[I]); - // FIXME: If none of the SearchDecls had local IDs in this module, can - // we avoid searching any ancestor module files? return false; } @@ -3494,9 +3528,9 @@ void ASTReader::loadPendingDeclChain(Decl *CanonDecl) { GlobalDeclID CanonID = CanonDecl->getGlobalID(); if (CanonID) SearchDecls.push_back(CanonDecl->getGlobalID()); // Always first. - MergedDeclsMap::iterator MergedPos = MergedDecls.find(CanonDecl); - if (MergedPos != MergedDecls.end()) - SearchDecls.append(MergedPos->second.begin(), MergedPos->second.end()); + KeyDeclsMap::iterator KeyPos = KeyDecls.find(CanonDecl); + if (KeyPos != KeyDecls.end()) + SearchDecls.append(KeyPos->second.begin(), KeyPos->second.end()); // Build up the list of redeclarations. RedeclChainVisitor Visitor(*this, SearchDecls, RedeclsDeserialized, CanonID); |