aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclObjC.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-17 00:09:08 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-17 00:09:08 +0000
commite7a77727804c12750cb39e8732e26f2a26e4ce0f (patch)
tree0495705ef5f494d3dd5e65439c3c89bd13b5f84f /lib/AST/DeclObjC.cpp
parent685d10462b875f8c056d27488c0a1b4e13ef680f (diff)
Use the extra info in global method pool to speed up looking for ObjC overridden methods.
When we are in a implementation, we check the global method pool whether there were category methods with the same selector. If there were none (common case) we don't need to do lookups for overridden methods again. Note that for an interface method (if we don't encounter its implementation), it is considered that it overrides methods that were declared before it, not for category methods introduced after it. This is tradeoff in favor of performance, since it is expensive to do lookups in case there was a category, and moving the global method pool to ASTContext (so we can check it) would increase complexity. rdar://13508196 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179654 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r--lib/AST/DeclObjC.cpp51
1 files changed, 1 insertions, 50 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 5f5ba52947..08c59b567d 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -959,52 +959,6 @@ static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
}
}
-static void collectOnCategoriesAfterLocation(SourceLocation Loc,
- const ObjCInterfaceDecl *Class,
- SourceManager &SM,
- const ObjCMethodDecl *Method,
- SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
- if (!Class)
- return;
-
- for (ObjCInterfaceDecl::known_categories_iterator
- Cat = Class->known_categories_begin(),
- CatEnd = Class->known_categories_end();
- Cat != CatEnd; ++Cat) {
- if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))
- CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);
- }
-
- collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
- Method, Methods);
-}
-
-/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
-/// returns false.
-/// You'd think that in that case there are no overrides but categories can
-/// "introduce" new overridden methods that are missed by Sema because the
-/// overrides lookup that it does for methods, inside implementations, will
-/// stop at the interface level (if there is a method there) and not look
-/// further in super classes.
-/// Methods in an implementation can overide methods in super class's category
-/// but not in current class's category. But, such methods
-static void collectOverriddenMethodsFast(SourceManager &SM,
- const ObjCMethodDecl *Method,
- SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
- assert(!Method->isOverriding());
-
- const ObjCContainerDecl *
- ContD = cast<ObjCContainerDecl>(Method->getDeclContext());
- if (isa<ObjCInterfaceDecl>(ContD) || isa<ObjCProtocolDecl>(ContD))
- return;
- const ObjCInterfaceDecl *Class = Method->getClassInterface();
- if (!Class)
- return;
-
- collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
- SM, Method, Methods);
-}
-
void ObjCMethodDecl::getOverriddenMethods(
SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const {
const ObjCMethodDecl *Method = this;
@@ -1014,10 +968,7 @@ void ObjCMethodDecl::getOverriddenMethods(
getMethod(Method->getSelector(), Method->isInstanceMethod());
}
- if (!Method->isOverriding()) {
- collectOverriddenMethodsFast(getASTContext().getSourceManager(),
- Method, Overridden);
- } else {
+ if (Method->isOverriding()) {
collectOverriddenMethodsSlow(Method, Overridden);
assert(!Overridden.empty() &&
"ObjCMethodDecl's overriding bit is not as expected");