diff options
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r-- | lib/AST/DeclObjC.cpp | 75 |
1 files changed, 16 insertions, 59 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 5f5ba52..4ddbb22 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -443,9 +443,12 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass( /// lookupMethod - This method returns an instance/class method by looking in /// the class, its categories, and its super classes (using a linear search). +/// When argument category "C" is specified, any implicit method found +/// in this category is ignored. ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, bool isInstance, - bool shallowCategoryLookup) const { + bool shallowCategoryLookup, + const ObjCCategoryDecl *C) const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return 0; @@ -469,20 +472,22 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, // Didn't find one yet - now look through categories. for (ObjCInterfaceDecl::visible_categories_iterator - Cat = ClassDecl->visible_categories_begin(), - CatEnd = ClassDecl->visible_categories_end(); + Cat = ClassDecl->visible_categories_begin(), + CatEnd = ClassDecl->visible_categories_end(); Cat != CatEnd; ++Cat) { if ((MethodDecl = Cat->getMethod(Sel, isInstance))) - return MethodDecl; + if (C != (*Cat) || !MethodDecl->isImplicit()) + return MethodDecl; if (!shallowCategoryLookup) { // Didn't find one yet - look through protocols. const ObjCList<ObjCProtocolDecl> &Protocols = - Cat->getReferencedProtocols(); + Cat->getReferencedProtocols(); for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), E = Protocols.end(); I != E; ++I) if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance))) - return MethodDecl; + if (C != (*Cat) || !MethodDecl->isImplicit()) + return MethodDecl; } } @@ -599,12 +604,12 @@ void ObjCMethodDecl::setMethodParams(ASTContext &C, assert((!SelLocs.empty() || isImplicit()) && "No selector locs for non-implicit method"); if (isImplicit()) - return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>()); + return setParamsAndSelLocs(C, Params, llvm::None); SelLocsKind = hasStandardSelectorLocs(getSelector(), SelLocs, Params, DeclEndLoc); if (SelLocsKind != SelLoc_NonStandard) - return setParamsAndSelLocs(C, Params, ArrayRef<SourceLocation>()); + return setParamsAndSelLocs(C, Params, llvm::None); setParamsAndSelLocs(C, Params, SelLocs); } @@ -959,52 +964,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 +973,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"); @@ -1692,12 +1648,13 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *SuperDecl, SourceLocation nameLoc, SourceLocation atStartLoc, + SourceLocation superLoc, SourceLocation IvarLBraceLoc, SourceLocation IvarRBraceLoc) { if (ClassInterface && ClassInterface->hasDefinition()) ClassInterface = ClassInterface->getDefinition(); return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl, - nameLoc, atStartLoc, + nameLoc, atStartLoc, superLoc, IvarLBraceLoc, IvarRBraceLoc); } |