diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 14 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 26 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 27 |
5 files changed, 52 insertions, 23 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index a72e74b5aa..fd2ce1749f 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -5471,7 +5471,7 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S, M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.second; MethList && MethList->Method; - MethList = MethList->Next) { + MethList = MethList->getNext()) { if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, NumSelIdents)) continue; @@ -5644,7 +5644,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver, M != MEnd; ++M) { for (ObjCMethodList *MethList = &M->second.first; MethList && MethList->Method; - MethList = MethList->Next) { + MethList = MethList->getNext()) { if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, NumSelIdents)) continue; @@ -7085,7 +7085,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first : &M->second.second; MethList && MethList->Method; - MethList = MethList->Next) { + MethList = MethList->getNext()) { if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, NumSelIdents)) continue; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 48f0decc2c..a6f8bf7f57 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -2085,17 +2085,23 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, } void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { + // Record at the head of the list whether there were 0, 1, or >= 2 methods + // inside categories. + if (isa<ObjCCategoryDecl>(Method->getDeclContext())) + if (List->getBits() < 2) + List->setBits(List->getBits()+1); + // If the list is empty, make it a singleton list. if (List->Method == 0) { List->Method = Method; - List->Next = 0; + List->setNext(0); return; } // We've seen a method with this name, see if we have already seen this type // signature. ObjCMethodList *Previous = List; - for (; List; Previous = List, List = List->Next) { + for (; List; Previous = List, List = List->getNext()) { if (!MatchTwoMethodDeclarations(Method, List->Method)) continue; @@ -2124,7 +2130,7 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { // We have a new signature for an existing method - add it. // This is extremely rare. Only 1% of Cocoa selectors are "overloaded". ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>(); - Previous->Next = new (Mem) ObjCMethodList(Method, 0); + Previous->setNext(new (Mem) ObjCMethodList(Method, 0)); } /// \brief Read the contents of the method pool for a given selector from @@ -2186,7 +2192,7 @@ ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R, // Gather the non-hidden methods. ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second; llvm::SmallVector<ObjCMethodDecl *, 4> Methods; - for (ObjCMethodList *M = &MethList; M; M = M->Next) { + for (ObjCMethodList *M = &MethList; M; M = M->getNext()) { if (M->Method && !M->Method->isHidden()) { // If we're not supposed to warn about mismatches, we're done. if (!warn) diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 4302f8bb53..9893823a12 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -428,8 +428,12 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, data_type Result; Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d)); - unsigned NumInstanceMethods = ReadUnalignedLE16(d); - unsigned NumFactoryMethods = ReadUnalignedLE16(d); + unsigned NumInstanceMethodsAndBits = ReadUnalignedLE16(d); + unsigned NumFactoryMethodsAndBits = ReadUnalignedLE16(d); + Result.InstanceBits = NumInstanceMethodsAndBits & 0x3; + Result.FactoryBits = NumFactoryMethodsAndBits & 0x3; + unsigned NumInstanceMethods = NumInstanceMethodsAndBits >> 2; + unsigned NumFactoryMethods = NumFactoryMethodsAndBits >> 2; // Load instance methods for (unsigned I = 0; I != NumInstanceMethods; ++I) { @@ -2736,7 +2740,7 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { ObjCMethodList &Start = Method->isInstanceMethod()? Known->second.first : Known->second.second; bool Found = false; - for (ObjCMethodList *List = &Start; List; List = List->Next) { + for (ObjCMethodList *List = &Start; List; List = List->getNext()) { if (!Found) { if (List->Method == Method) { Found = true; @@ -2746,8 +2750,8 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { } } - if (List->Next) - List->Method = List->Next->Method; + if (List->getNext()) + List->Method = List->getNext()->Method; else List->Method = Method; } @@ -6114,13 +6118,16 @@ namespace clang { namespace serialization { ASTReader &Reader; Selector Sel; unsigned PriorGeneration; + unsigned InstanceBits; + unsigned FactoryBits; SmallVector<ObjCMethodDecl *, 4> InstanceMethods; SmallVector<ObjCMethodDecl *, 4> FactoryMethods; public: ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel, unsigned PriorGeneration) - : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) { } + : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration), + InstanceBits(0), FactoryBits(0) { } static bool visit(ModuleFile &M, void *UserData) { ReadMethodPoolVisitor *This @@ -6153,6 +6160,8 @@ namespace clang { namespace serialization { This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end()); This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end()); + This->InstanceBits = Data.InstanceBits; + This->FactoryBits = Data.FactoryBits; return true; } @@ -6165,6 +6174,9 @@ namespace clang { namespace serialization { ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { return FactoryMethods; } + + unsigned getInstanceBits() const { return InstanceBits; } + unsigned getFactoryBits() const { return FactoryBits; } }; } } // end namespace clang::serialization @@ -6202,6 +6214,8 @@ void ASTReader::ReadMethodPool(Selector Sel) { addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first); addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second); + Pos->second.first.setBits(Visitor.getInstanceBits()); + Pos->second.second.setBits(Visitor.getFactoryBits()); } void ASTReader::ReadKnownNamespaces( diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h index 327da4403a..9149b18480 100644 --- a/lib/Serialization/ASTReaderInternals.h +++ b/lib/Serialization/ASTReaderInternals.h @@ -152,6 +152,8 @@ class ASTSelectorLookupTrait { public: struct data_type { SelectorID ID; + unsigned InstanceBits; + unsigned FactoryBits; SmallVector<ObjCMethodDecl *, 2> Instance; SmallVector<ObjCMethodDecl *, 2> Factory; }; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index e98708d8f5..b6d25d22d5 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2692,11 +2692,11 @@ public: clang::io::Emit16(Out, KeyLen); unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts for (const ObjCMethodList *Method = &Methods.Instance; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) DataLen += 4; for (const ObjCMethodList *Method = &Methods.Factory; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) DataLen += 4; clang::io::Emit16(Out, DataLen); @@ -2722,24 +2722,31 @@ public: clang::io::Emit32(Out, Methods.ID); unsigned NumInstanceMethods = 0; for (const ObjCMethodList *Method = &Methods.Instance; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) ++NumInstanceMethods; unsigned NumFactoryMethods = 0; for (const ObjCMethodList *Method = &Methods.Factory; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) ++NumFactoryMethods; - clang::io::Emit16(Out, NumInstanceMethods); - clang::io::Emit16(Out, NumFactoryMethods); + unsigned InstanceBits = Methods.Instance.getBits(); + assert(InstanceBits < 4); + unsigned NumInstanceMethodsAndBits = + (NumInstanceMethods << 2) | InstanceBits; + unsigned FactoryBits = Methods.Factory.getBits(); + assert(FactoryBits < 4); + unsigned NumFactoryMethodsAndBits = (NumFactoryMethods << 2) | FactoryBits; + clang::io::Emit16(Out, NumInstanceMethodsAndBits); + clang::io::Emit16(Out, NumFactoryMethodsAndBits); for (const ObjCMethodList *Method = &Methods.Instance; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); for (const ObjCMethodList *Method = &Methods.Factory; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); @@ -2788,12 +2795,12 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { // Selector already exists. Did it change? bool changed = false; for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; - M = M->Next) { + M = M->getNext()) { if (!M->Method->isFromASTFile()) changed = true; } for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; - M = M->Next) { + M = M->getNext()) { if (!M->Method->isFromASTFile()) changed = true; } |