aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaCodeComplete.cpp6
-rw-r--r--lib/Sema/SemaDeclObjC.cpp14
-rw-r--r--lib/Serialization/ASTReader.cpp26
-rw-r--r--lib/Serialization/ASTReaderInternals.h2
-rw-r--r--lib/Serialization/ASTWriter.cpp27
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;
}