From ff310c763eeb41a7aaa3b928cd0bc0a6e493d5dd Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 1 May 2012 23:37:00 +0000 Subject: [PATCH] Eliminate Sema::CompareMethodParamsInBaseAndSuper() entirely, by folding its one check into the normal path for checking overridden Objective-C methods. Good for another 3.6% speedup on the test case in . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155961 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 22 +++------- lib/Sema/SemaDeclObjC.cpp | 84 ++++++++++++++------------------------- 2 files changed, 35 insertions(+), 71 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 59de8c5519..fdd8d53b57 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2130,15 +2130,12 @@ public: void CheckCategoryVsClassMethodMatches(ObjCCategoryImplDecl *CatIMP); /// \brief Add the given method to the list of globally-known methods. - /// - /// \returns true if this is the first method in the list with the given - /// selector. - bool addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); + void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method); private: /// AddMethodToGlobalPool - Add an instance or factory method to the global /// pool. See descriptoin of AddInstanceMethodToGlobalPool. - bool AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); + void AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance); /// LookupMethodInGlobalPool - Returns the instance or factory method and /// optionally warns if there are multiple signatures. @@ -2151,17 +2148,13 @@ public: /// unit are added to a global pool. This allows us to efficiently associate /// a selector with a method declaraation for purposes of typechecking /// messages sent to "id" (where the class of the object is unknown). - /// - /// Returns true if the method was added, false if a method was already there. - bool AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { - return AddMethodToGlobalPool(Method, impl, /*instance*/true); + void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { + AddMethodToGlobalPool(Method, impl, /*instance*/true); } /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods. - /// - /// Returns true if the method was added, false if a method was already there. - bool AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { - return AddMethodToGlobalPool(Method, impl, /*instance*/false); + void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method, bool impl=false) { + AddMethodToGlobalPool(Method, impl, /*instance*/false); } /// AddAnyMethodToGlobalPool - Add any method, instance or factory to global @@ -5832,9 +5825,6 @@ public: const IdentifierInfo *Name); void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl); - void CompareMethodParamsInBaseAndSuper(Decl *IDecl, - ObjCMethodDecl *MethodDecl, - bool IsInstance); void CompareProperties(Decl *CDecl, Decl *MergeProtocols); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index efbc1d224e..ac6486de63 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1970,12 +1970,12 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left, return true; } -bool Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { +void Sema::addMethodToGlobalList(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 true; + return; } // We've seen a method with this name, see if we have already seen this type @@ -2004,14 +2004,13 @@ bool Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) { List->Method = Method; } - return false; + 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(); Previous->Next = new (Mem) ObjCMethodList(Method, 0); - return false; } /// \brief Read the contents of the method pool for a given selector from @@ -2021,11 +2020,11 @@ void Sema::ReadMethodPool(Selector Sel) { ExternalSource->ReadMethodPool(Sel); } -bool Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, +void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, bool instance) { // Ignore methods of invalid containers. if (cast(Method->getDeclContext())->isInvalidDecl()) - return false; + return; if (ExternalSource) ReadMethodPool(Method->getSelector()); @@ -2038,7 +2037,7 @@ bool Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl, Method->setDefined(impl); ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second; - return addMethodToGlobalList(&Entry, Method); + addMethodToGlobalList(&Entry, Method); } /// Determines if this is an "acceptable" loose mismatch in the global @@ -2141,43 +2140,6 @@ ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) { return 0; } -/// CompareMethodParamsInBaseAndSuper - This routine compares methods with -/// identical selector names in current and its super classes and issues -/// a warning if any of their argument types are incompatible. -void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl, - ObjCMethodDecl *Method, - bool IsInstance) { - ObjCInterfaceDecl *ID = dyn_cast(ClassDecl); - if (ID == 0) return; - - while (ObjCInterfaceDecl *SD = ID->getSuperClass()) { - ObjCMethodDecl *SuperMethodDecl = - SD->lookupMethod(Method->getSelector(), IsInstance); - if (SuperMethodDecl == 0) { - ID = SD; - continue; - } - ObjCMethodDecl::param_iterator ParamI = Method->param_begin(), - E = Method->param_end(); - ObjCMethodDecl::param_iterator PrevI = SuperMethodDecl->param_begin(); - for (; ParamI != E; ++ParamI, ++PrevI) { - // Number of parameters are the same and is guaranteed by selector match. - assert(PrevI != SuperMethodDecl->param_end() && "Param mismatch"); - QualType T1 = Context.getCanonicalType((*ParamI)->getType()); - QualType T2 = Context.getCanonicalType((*PrevI)->getType()); - // If type of argument of method in this class does not match its - // respective argument type in the super class method, issue warning; - if (!Context.typesAreCompatible(T1, T2)) { - Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super) - << T1 << T2; - Diag(SuperMethodDecl->getLocation(), diag::note_previous_declaration); - return; - } - } - ID = SD; - } -} - /// DiagnoseDuplicateIvars - /// Check for duplicate ivars in the entire class at the start of /// @implementation. This becomes necesssary because class extension can @@ -2273,11 +2235,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, } InsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "id". - if (!AddInstanceMethodToGlobalPool(Method)) { - // verify that the instance method conforms to the same definition of - // parent methods if it shadows one. - CompareMethodParamsInBaseAndSuper(ClassDecl, Method, true); - } + AddInstanceMethodToGlobalPool(Method); } } else { /// Check for class method of the same name with incompatible types @@ -2300,12 +2258,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, Diag(PrevMethod->getLocation(), diag::note_previous_declaration); } ClsMap[Method->getSelector()] = Method; - /// The following allows us to typecheck messages to "Class". - if (!AddFactoryMethodToGlobalPool(Method)) { - // verify that the class method conforms to the same definition of - // parent methods if it shadows one. - CompareMethodParamsInBaseAndSuper(ClassDecl, Method, false); - } + AddFactoryMethodToGlobalPool(Method); } } } @@ -2892,6 +2845,27 @@ Decl *Sema::ActOnMethodDeclaration( isa(ObjCMethod->getDeclContext())) CheckConflictingOverridingMethod(ObjCMethod, overridden, isa(overridden->getDeclContext())); + + if (CurrentClass && overridden->getDeclContext() != CurrentClass && + isa(overridden->getDeclContext())) { + ObjCMethodDecl::param_iterator ParamI = ObjCMethod->param_begin(), + E = ObjCMethod->param_end(); + ObjCMethodDecl::param_iterator PrevI = overridden->param_begin(); + for (; ParamI != E; ++ParamI, ++PrevI) { + // Number of parameters are the same and is guaranteed by selector match. + assert(PrevI != overridden->param_end() && "Param mismatch"); + QualType T1 = Context.getCanonicalType((*ParamI)->getType()); + QualType T2 = Context.getCanonicalType((*PrevI)->getType()); + // If type of argument of method in this class does not match its + // respective argument type in the super class method, issue warning; + if (!Context.typesAreCompatible(T1, T2)) { + Diag((*ParamI)->getLocation(), diag::ext_typecheck_base_super) + << T1 << T2; + Diag(overridden->getLocation(), diag::note_previous_declaration); + break; + } + } + } } bool ARCError = false; -- 2.40.0