From 7c778f1c549a8ae95d50a819fd537df78da16426 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Fri, 25 Jul 2008 19:39:00 +0000 Subject: [PATCH] Cleaunup Sema::ActOnClassMessage(). This commit: (a) removes a bogus warning. (b) removes an undesirable usage of the ObjCMessageExpr constructor that takes an IdentifierInfo * (which I will abolish). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54042 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprObjC.cpp | 39 +++++++++++++++++++++------------- test/Sema/objc-typedef-class.m | 2 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 5d168232fe..97e1579548 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -169,7 +169,7 @@ Sema::ExprResult Sema::ActOnClassMessage( } else ClassDecl = getObjCInterfaceDecl(receiverName); - // ClassDecl is null in the following case. + // The following code allows for the following GCC-ism: // // typedef XCElementDisplayRect XCElementGraphicsRect; // @@ -178,22 +178,31 @@ Sema::ExprResult Sema::ActOnClassMessage( // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; // } // - // FIXME: Investigate why GCC allows the above. + // If necessary, the following lookup could move to getObjCInterfaceDecl(). + if (!ClassDecl) { + Decl *IDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, 0, false); + if (TypedefDecl *OCTD = dyn_cast_or_null(IDecl)) { + const ObjCInterfaceType *OCIT; + OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType(); + if (OCIT) + ClassDecl = OCIT->getDecl(); + } + } + assert(ClassDecl && "missing interface declaration"); ObjCMethodDecl *Method = 0; QualType returnType; - if (ClassDecl) { - Method = ClassDecl->lookupClassMethod(Sel); - - // If we have an implementation in scope, check "private" methods. - if (!Method) { - if (ObjCImplementationDecl *ImpDecl = - ObjCImplementations[ClassDecl->getIdentifier()]) - Method = ImpDecl->getClassMethod(Sel); - } - // Before we give up, check if the selector is an instance method. - if (!Method) - Method = ClassDecl->lookupInstanceMethod(Sel); + Method = ClassDecl->lookupClassMethod(Sel); + + // If we have an implementation in scope, check "private" methods. + if (!Method) { + if (ObjCImplementationDecl *ImpDecl = + ObjCImplementations[ClassDecl->getIdentifier()]) + Method = ImpDecl->getClassMethod(Sel); } + // Before we give up, check if the selector is an instance method. + if (!Method) + Method = ClassDecl->lookupInstanceMethod(Sel); + if (!Method) { Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(), SourceRange(lbrac, rbrac)); @@ -212,7 +221,7 @@ Sema::ExprResult Sema::ActOnClassMessage( // FIXME: need to do a better job handling 'super' usage within a class // For now, we simply pass the "super" identifier through (which isn't // consistent with instance methods. - if (isSuper || !ClassDecl) + if (isSuper) return new ObjCMessageExpr(receiverName, Sel, returnType, Method, lbrac, rbrac, ArgExprs, NumArgs); else diff --git a/test/Sema/objc-typedef-class.m b/test/Sema/objc-typedef-class.m index 9518ab7a0e..1bb3f87aa5 100644 --- a/test/Sema/objc-typedef-class.m +++ b/test/Sema/objc-typedef-class.m @@ -72,7 +72,7 @@ typedef XCElementDisplayRect XCElementGraphicsRect; { static XCElementGraphicsRect *_sGraphicsDelegate = ((void *) 0); if (!_sGraphicsDelegate) { - _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; // expected-warning{{method '+alloc' not found (return type defaults to 'id')}} + _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; } } @end -- 2.40.0