aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-25 00:19:56 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-25 00:19:56 +0000
commit44fae525e792f09ecbe07c0a62cdbcb81e04306b (patch)
tree2f0f8aad4c213dbb54b22d0eda626d494244e4a2 /lib/Sema/SemaDeclObjC.cpp
parente6ca97f2aeb301e28d20988b27c4297a9b540991 (diff)
Factor out the addition of a method into the global method pool, and
teach it to always add the new method at the *end* of the list rather than as the second element in the list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148886 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--lib/Sema/SemaDeclObjC.cpp83
1 files changed, 48 insertions, 35 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 4264b7105a..02ba41546b 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1931,6 +1931,51 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
return true;
}
+/// \brief Add the given method to the given list of globally-known methods.
+static void addMethodToGlobalList(Sema &S, ObjCMethodList *List,
+ ObjCMethodDecl *Method) {
+ // If the list is empty, make it a singleton list.
+ if (List->Method == 0) {
+ List->Method = Method;
+ List->Next = 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) {
+ if (!S.MatchTwoMethodDeclarations(Method, List->Method))
+ continue;
+
+ ObjCMethodDecl *PrevObjCMethod = List->Method;
+
+ // Propagate the 'defined' bit.
+ if (Method->isDefined())
+ PrevObjCMethod->setDefined(true);
+
+ // If a method is deprecated, push it in the global pool.
+ // This is used for better diagnostics.
+ if (Method->isDeprecated()) {
+ if (!PrevObjCMethod->isDeprecated())
+ List->Method = Method;
+ }
+ // If new method is unavailable, push it into global pool
+ // unless previous one is deprecated.
+ if (Method->isUnavailable()) {
+ if (PrevObjCMethod->getAvailability() < AR_Deprecated)
+ List->Method = Method;
+ }
+
+ return;
+ }
+
+ // We have a new signature for an existing method - add it.
+ // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
+ ObjCMethodList *Mem = S.BumpAlloc.Allocate<ObjCMethodList>();
+ Previous->Next = new (Mem) ObjCMethodList(Method, 0);
+}
+
/// \brief Read the contents of the method pool for a given selector from
/// external storage.
///
@@ -1957,43 +2002,11 @@ void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
GlobalMethods())).first;
}
+
Method->setDefined(impl);
+
ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
- if (Entry.Method == 0) {
- // Haven't seen a method with this selector name yet - add it.
- Entry.Method = Method;
- Entry.Next = 0;
- return;
- }
-
- // We've seen a method with this name, see if we have already seen this type
- // signature.
- for (ObjCMethodList *List = &Entry; List; List = List->Next) {
- bool match = MatchTwoMethodDeclarations(Method, List->Method);
-
- if (match) {
- ObjCMethodDecl *PrevObjCMethod = List->Method;
- PrevObjCMethod->setDefined(impl);
- // If a method is deprecated, push it in the global pool.
- // This is used for better diagnostics.
- if (Method->isDeprecated()) {
- if (!PrevObjCMethod->isDeprecated())
- List->Method = Method;
- }
- // If new method is unavailable, push it into global pool
- // unless previous one is deprecated.
- if (Method->isUnavailable()) {
- if (PrevObjCMethod->getAvailability() < AR_Deprecated)
- List->Method = Method;
- }
- return;
- }
- }
-
- // 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>();
- Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);
+ addMethodToGlobalList(*this, &Entry, Method);
}
/// Determines if this is an "acceptable" loose mismatch in the global