SemaExprObjC.cpp revision 390b4cc8b45a05612349269ef08faab3e4688f06
185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===// 285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// 385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// The LLVM Compiler Infrastructure 485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// 585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// This file is distributed under the University of Illinois Open Source 685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// License. See LICENSE.TXT for details. 785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// 885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===// 985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// 1085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// This file implements semantic analysis for Objective-C expressions. 1185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// 1285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===// 1385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 1485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "Sema.h" 1585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/ASTContext.h" 1685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/DeclObjC.h" 17f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h" 1839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner#include "llvm/ADT/SmallString.h" 1961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff#include "clang/Lex/Preprocessor.h" 2061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 2185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattnerusing namespace clang; 2285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 2385a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 2439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner ExprTy **strings, 2585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner unsigned NumStrings) { 2639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings); 2739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner 28f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // Most ObjC strings are formed out of a single piece. However, we *can* 29f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // have strings formed out of multiple @ strings with multiple pptokens in 30f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // each one, e.g. @"foo" "bar" @"baz" "qux" which need to be turned into one 31f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // StringLiteral for ObjCStringLiteral to hold onto. 3239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StringLiteral *S = Strings[0]; 33f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner 34f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // If we have a multi-part string, merge it all together. 35f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner if (NumStrings != 1) { 3685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner // Concatenate objc strings. 3739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner llvm::SmallString<128> StrBuf; 3839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner llvm::SmallVector<SourceLocation, 8> StrLocs; 39726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner 40726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner for (unsigned i = 0; i != NumStrings; ++i) { 4139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner S = Strings[i]; 4239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner 4339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // ObjC strings can't be wide. 44f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner if (S->isWide()) { 45f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant) 46f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner << S->getSourceRange(); 47f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner return true; 48f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner } 49f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner 5039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Get the string data. 5139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength()); 5239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner 5339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Get the locations of the string tokens. 5439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StrLocs.append(S->tokloc_begin(), S->tokloc_end()); 5539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner 5639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Free the temporary string. 578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek S->Destroy(Context); 5885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 5939c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner 6039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Create the aggregate string with the appropriate content and location 6139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // information. 6239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false, 632085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner Context.getPointerType(Context.CharTy), 6439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner &StrLocs[0], StrLocs.size()); 6585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 6685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 67690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner // Verify that this composite string is acceptable for ObjC strings. 68690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner if (CheckObjCString(S)) 6985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner return true; 70a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner 71a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner // Initialize the constant string interface lazily. This assumes 72d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // the NSString interface is seen in this translation unit. Note: We 73d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // don't use NSConstantString, since the runtime team considers this 74d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // interface private (even though it appears in the header files). 75a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType Ty = Context.getObjCConstantStringInterface(); 76a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner if (!Ty.isNull()) { 77a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getPointerType(Ty); 7813fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner } else { 79d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff IdentifierInfo *NSIdent = &Context.Idents.get("NSString"); 80a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner NamedDecl *IF = LookupName(TUScope, NSIdent, LookupOrdinaryName); 81a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) { 82a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Context.setObjCConstantStringInterface(StrIF); 83a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getObjCConstantStringInterface(); 84a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getPointerType(Ty); 85a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner } else { 86d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // If there is no NSString interface defined then treat constant 87a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner // strings as untyped objects and let the runtime figure it out later. 88a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getObjCIdType(); 89a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner } 9013fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner } 91a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner 92f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]); 9385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 9485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 9585a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc, 9685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation EncodeLoc, 9785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation LParenLoc, 98a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner TypeTy *ty, 9985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation RParenLoc) { 100a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType EncodedType = QualType::getFromOpaquePtr(ty); 10185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 102eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner std::string Str; 103eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner Context.getObjCEncodingForType(EncodedType, Str); 104eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner 105eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner // The type of @encode is the same as the type of the corresponding string, 106eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner // which is an array type. 107eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner QualType StrTy = Context.CharTy; 108eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). 109eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner if (getLangOptions().CPlusPlus) 110eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner StrTy.addConst(); 111eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1), 112eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner ArrayType::Normal, 0); 113eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner 114eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc); 11585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 11685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 11785a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, 11885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation AtLoc, 11985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation SelLoc, 12085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation LParenLoc, 12185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation RParenLoc) { 122a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType Ty = Context.getObjCSelType(); 123a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc); 12485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 12585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 12685a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, 12785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation AtLoc, 12885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation ProtoLoc, 12985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation LParenLoc, 13085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation RParenLoc) { 1316e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId); 13285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner if (!PDecl) { 1333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId; 13485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner return true; 13585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 13685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 137a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType Ty = Context.getObjCProtoType(); 138a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner if (Ty.isNull()) 13985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner return true; 140a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getPointerType(Ty); 141a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc); 14285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 14385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 14491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbarbool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, 14591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar Selector Sel, ObjCMethodDecl *Method, 146077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner bool isClassMessage, 147637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar SourceLocation lbrac, SourceLocation rbrac, 148637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar QualType &ReturnType) { 149637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar if (!Method) { 1506660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar // Apply default argument promotion as for (C99 6.5.2.2p6). 1516660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar for (unsigned i = 0; i != NumArgs; i++) 1526660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar DefaultArgumentPromotion(Args[i]); 1536660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar 154077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found : 155077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner diag::warn_inst_method_not_found; 156077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner Diag(lbrac, DiagID) 157077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << Sel << isClassMessage << SourceRange(lbrac, rbrac); 158637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar ReturnType = Context.getObjCIdType(); 159637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return false; 160637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar } 161077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner 162077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner ReturnType = Method->getResultType(); 163637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar 16491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar unsigned NumNamedArgs = Sel.getNumArgs(); 16591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!"); 16691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar 167312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner bool IsError = false; 16891e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar for (unsigned i = 0; i < NumNamedArgs; i++) { 16985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr *argExpr = Args[i]; 17085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); 17185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 17289951a86b594513c2a013532ed45d197413b1087Chris Lattner QualType lhsType = Method->param_begin()[i]->getType(); 17385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner QualType rhsType = argExpr->getType(); 17485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 17585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 176987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner if (lhsType->isArrayType()) 177987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner lhsType = Context.getArrayDecayedType(lhsType); 17885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner else if (lhsType->isFunctionType()) 17985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner lhsType = Context.getPointerType(lhsType); 18085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 181987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner AssignConvertType Result = 182987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner CheckSingleAssignmentConstraints(lhsType, argExpr); 18385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner if (Args[i] != argExpr) // The expression was converted. 18485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Args[i] = argExpr; // Make sure we store the converted expression. 18585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 186312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner IsError |= 18785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, 18885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner argExpr, "sending"); 18985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 19091e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar 19191e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar // Promote additional arguments to variadic methods. 19291e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar if (Method->isVariadic()) { 193dce5e2cabf07ff25eb4d9e1859c0a21c69f588d2Anders Carlsson for (unsigned i = NumNamedArgs; i < NumArgs; ++i) 194312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod); 19591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar } else { 19691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar // Check for extra arguments to non-variadic methods. 19791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar if (NumArgs != NumNamedArgs) { 19891e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar Diag(Args[NumNamedArgs]->getLocStart(), 199fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner diag::err_typecheck_call_too_many_args) 2002c21a073525cdfa68e4439b7af551385dc2796abChris Lattner << 2 /*method*/ << Method->getSourceRange() 201fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << SourceRange(Args[NumNamedArgs]->getLocStart(), 202fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Args[NumArgs-1]->getLocEnd()); 20391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar } 20491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar } 20591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar 206312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner return IsError; 20785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 20885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 2096b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroffbool Sema::isSelfExpr(Expr *RExpr) { 2106b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr)) 2116b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self")) 2126b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff return true; 2136b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff return false; 2146b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff} 2156b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff 216f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Helper method for ActOnClassMethod/ActOnInstanceMethod. 217f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Will search "local" class/category implementations for a method decl. 218175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian// If failed, then we search in class's root for an instance method. 219f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Returns 0 if no method is found. 2205609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel, 221f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff ObjCInterfaceDecl *ClassDecl) { 222f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff ObjCMethodDecl *Method = 0; 2235609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // lookup in class and all superclasses 2245609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff while (ClassDecl && !Method) { 2258fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor if (ObjCImplementationDecl *ImpDecl 2268fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor = LookupObjCImplementation(ClassDecl->getIdentifier())) 227653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Method = ImpDecl->getClassMethod(Context, Sel); 228f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff 2295609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Look through local category implementations associated with the class. 2305609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method) { 2315609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) { 2325609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl) 233653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Method = ObjCCategoryImpls[i]->getClassMethod(Context, Sel); 2345609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff } 2355609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff } 2365609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 2375609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Before we give up, check if the selector is an instance method. 2385609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // But only in the root. This matches gcc's behaviour and what the 2395609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // runtime expects. 2405609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method && !ClassDecl->getSuperClass()) { 2416ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor Method = ClassDecl->lookupInstanceMethod(Context, Sel); 2425609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Look through local category implementations associated 2435609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // with the root class. 2445609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method) 2455609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateInstanceMethod(Sel, ClassDecl); 246f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff } 2475609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 2485609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ClassDecl = ClassDecl->getSuperClass(); 249f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff } 2505609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff return Method; 2515609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff} 2525609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 2535609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel, 2545609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ObjCInterfaceDecl *ClassDecl) { 2555609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ObjCMethodDecl *Method = 0; 2565609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff while (ClassDecl && !Method) { 2575609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // If we have implementations in scope, check "private" methods. 2588fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor if (ObjCImplementationDecl *ImpDecl 2598fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor = LookupObjCImplementation(ClassDecl->getIdentifier())) 260653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Method = ImpDecl->getInstanceMethod(Context, Sel); 2615609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 2625609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Look through local category implementations associated with the class. 2635609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method) { 2645609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) { 2655609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl) 266653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel); 2675609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff } 2685609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff } 2695609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ClassDecl = ClassDecl->getSuperClass(); 270175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian } 271f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff return Method; 272f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff} 273f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff 27461f72cbd037e58f12cfe90cd442373f44092f030Steve NaroffAction::OwningExprResult Sema::ActOnClassPropertyRefExpr( 27561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff IdentifierInfo &receiverName, 27661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff IdentifierInfo &propertyName, 27761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SourceLocation &receiverNameLoc, 27861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff SourceLocation &propertyNameLoc) { 27961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 28061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(&receiverName); 28161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 28261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Search for a declared property first. 28361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 28461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName); 2856ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor ObjCMethodDecl *Getter = IFace->lookupClassMethod(Context, Sel); 28661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 28761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // If this reference is in an @implementation, check for 'private' methods. 28861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (!Getter) 28961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) 29061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 2918fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor if (ObjCImplementationDecl *ImpDecl 2928fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor = LookupObjCImplementation(ClassDecl->getIdentifier())) 293653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Getter = ImpDecl->getClassMethod(Context, Sel); 29461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 29561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Getter) { 29661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // FIXME: refactor/share with ActOnMemberReference(). 29761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Check if we can reference this property. 29861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (DiagnoseUseOfDecl(Getter, propertyNameLoc)) 29961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return ExprError(); 30061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 30161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 30261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Look for the matching setter, in case it is needed. 303fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff Selector SetterSel = 304fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff SelectorTable::constructSetterName(PP.getIdentifierTable(), 305fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff PP.getSelectorTable(), &propertyName); 30661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 3076ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel); 30861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (!Setter) { 30961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // If this reference is in an @implementation, also check for 'private' 31061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // methods. 31161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) 31261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 3138fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor if (ObjCImplementationDecl *ImpDecl 3148fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor = LookupObjCImplementation(ClassDecl->getIdentifier())) 315653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Setter = ImpDecl->getClassMethod(Context, SetterSel); 31661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 31761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Look through local category implementations associated with the class. 31861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (!Setter) { 31961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) { 32061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCCategoryImpls[i]->getClassInterface() == IFace) 321653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel); 32261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 32361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 32461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 32561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc)) 32661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return ExprError(); 32761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 32861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Getter || Setter) { 32961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff QualType PType; 33061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 33161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Getter) 33261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff PType = Getter->getResultType(); 33361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff else { 33461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(), 33561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff E = Setter->param_end(); PI != E; ++PI) 33661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff PType = (*PI)->getType(); 33761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 33861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return Owned(new (Context) ObjCKVCRefExpr(Getter, PType, Setter, 33961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff propertyNameLoc, IFace, receiverNameLoc)); 34061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 34161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return ExprError(Diag(propertyNameLoc, diag::err_property_not_found) 34261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff << &propertyName << Context.getObjCInterfaceType(IFace)); 34361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff} 34461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 34561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 34685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnClassMessage - used for both unary and keyword messages. 34785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions 34885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs(). 34985a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ActOnClassMessage( 35085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Scope *S, 35185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner IdentifierInfo *receiverName, Selector Sel, 352ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson SourceLocation lbrac, SourceLocation receiverLoc, 353ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson SourceLocation selectorLoc, SourceLocation rbrac, 3545cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff ExprTy **Args, unsigned NumArgs) 35585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner{ 35685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner assert(receiverName && "missing receiver class name"); 35785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 35885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 359a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek ObjCInterfaceDecl* ClassDecl = 0; 360fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff bool isSuper = false; 361fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff 3628469265156c6344fa1100a6a7bf6349acc187d9fChris Lattner if (receiverName->isStr("super")) { 3635cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff if (getCurMethodDecl()) { 3645cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff isSuper = true; 3654b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian ObjCInterfaceDecl *OID = getCurMethodDecl()->getClassInterface(); 3664b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian if (!OID) 3674b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian return Diag(lbrac, diag::error_no_super_class_message) 3684b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian << getCurMethodDecl()->getDeclName(); 3694b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian ClassDecl = OID->getSuperClass(); 3705cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff if (!ClassDecl) 3714b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName(); 372f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor if (getCurMethodDecl()->isInstanceMethod()) { 3735cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff QualType superTy = Context.getObjCInterfaceType(ClassDecl); 3745cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff superTy = Context.getPointerType(superTy); 3758189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(), 3768189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek superTy); 3775cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // We are really in an instance method, redirect. 378ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac, 379ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson selectorLoc, rbrac, Args, NumArgs); 3805cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff } 3815cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // We are sending a message to 'super' within a class method. Do nothing, 3825cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // the receiver will pass through as 'super' (how convenient:-). 3835cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff } else { 3845cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // 'super' has been used outside a method context. If a variable named 3855cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // 'super' has been declared, redirect. If not, produce a diagnostic. 38647b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor NamedDecl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName); 3875cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl); 3885cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff if (VD) { 3898189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(), 3908189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek receiverLoc); 3915cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // We are really in an instance method, redirect. 392ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac, 393ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson selectorLoc, rbrac, Args, NumArgs); 3945cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff } 39508631c5fa053867146b5ee8be658c229f6bf127cChris Lattner return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName; 3965cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff } 39785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } else 39885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner ClassDecl = getObjCInterfaceDecl(receiverName); 39985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 4007c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff // The following code allows for the following GCC-ism: 401cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // 402cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // typedef XCElementDisplayRect XCElementGraphicsRect; 403cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // 404cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // @implementation XCRASlice 405cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // - whatever { // Note that XCElementGraphicsRect is a typedef name. 406cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; 407cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // } 408cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // 4097c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff // If necessary, the following lookup could move to getObjCInterfaceDecl(). 4107c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff if (!ClassDecl) { 41147b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName); 4127c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) { 4137c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff const ObjCInterfaceType *OCIT; 4147c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType(); 41564540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner if (!OCIT) { 41664540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner Diag(receiverLoc, diag::err_invalid_receiver_to_message); 41764540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner return true; 41864540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner } 419ebff1fed660fac9c50a7b7571da797bb489254a4Fariborz Jahanian ClassDecl = OCIT->getDecl(); 4207c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff } 4217c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff } 4227c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff assert(ClassDecl && "missing interface declaration"); 423cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff ObjCMethodDecl *Method = 0; 42485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner QualType returnType; 42589bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian if (ClassDecl->isForwardDecl()) { 42689bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian // A forward class used in messaging is tread as a 'Class' 4279f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian Diag(lbrac, diag::warn_receiver_forward_class) << ClassDecl->getDeclName(); 42889bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac)); 42989bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian if (Method) 4309f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian Diag(Method->getLocation(), diag::note_method_sent_forward_class) 4319f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian << Method->getDeclName(); 43289bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian } 43389bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian if (!Method) 43489bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian Method = ClassDecl->lookupClassMethod(Context, Sel); 4357c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff 4367c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff // If we have an implementation in scope, check "private" methods. 437f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff if (!Method) 4385609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateClassMethod(Sel, ClassDecl); 4397c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff 44048f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 44148f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 44259843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson 443077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true, 444637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 445637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 4464df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek 447390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // If we have the ObjCInterfaceDecl* for the class that is receiving the 448390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // message, use that to construct the ObjCMessageExpr. Otherwise pass on the 449390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // IdentifierInfo* for the class. 450390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: need to do a better job handling 'super' usage within a class. For 451390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // now, we simply pass the "super" identifier through (which isn't consistent 452390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // with instance methods. 4537c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff if (isSuper) 4548189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek return new (Context) ObjCMessageExpr(receiverName, Sel, returnType, Method, 4558189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek lbrac, rbrac, ArgExprs, NumArgs); 4564df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek else 4578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek return new (Context) ObjCMessageExpr(ClassDecl, Sel, returnType, Method, 4588189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek lbrac, rbrac, ArgExprs, NumArgs); 45985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 46085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 46185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnInstanceMessage - used for both unary and keyword messages. 46285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions 46385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs(). 4641565e0364b05d163640dd2b6feed43bae67df4fdChris LattnerSema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, 465b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner SourceLocation lbrac, 466ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson SourceLocation receiverLoc, 467b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner SourceLocation rbrac, 468b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner ExprTy **Args, unsigned NumArgs) { 46985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner assert(receiver && "missing receiver expression"); 47085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 47185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 47285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr *RExpr = static_cast<Expr *>(receiver); 473d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner 474d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner // If necessary, apply function/array conversion to the receiver. 475d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner // C99 6.7.5.3p[7,8]. 476d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner DefaultFunctionArrayConversion(RExpr); 477d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner 47885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner QualType returnType; 479b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner QualType ReceiverCType = 480b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner Context.getCanonicalType(RExpr->getType()).getUnqualifiedType(); 48187d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff 48287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff // Handle messages to 'super'. 483279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff if (isa<ObjCSuperExpr>(RExpr)) { 48487d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff ObjCMethodDecl *Method = 0; 48587d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { 48687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff // If we have an interface in scope, check 'super' methods. 48787d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 4885609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) { 4896ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor Method = SuperDecl->lookupInstanceMethod(Context, Sel); 4905609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 4915609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method) 4925609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // If we have implementations in scope, check "private" methods. 4935609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateInstanceMethod(Sel, SuperDecl); 4945609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff } 49587d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff } 496ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson 49748f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 49848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 49959843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson 500077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 50187d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff lbrac, rbrac, returnType)) 50287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff return true; 5038189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, 5048189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek rbrac, ArgExprs, NumArgs); 50587d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff } 50687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff 507fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner // Handle messages to id. 5086c4088e5fc0ce98bf3213d47f6f38bfbfa20c813Steve Naroff if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) || 5090c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner ReceiverCType->isBlockPointerType()) { 510037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool( 511037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff Sel, SourceRange(lbrac,rbrac)); 5126e10a08fe0427ab34c463dd59d9c0997d4f72170Chris Lattner if (!Method) 513f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac, rbrac)); 514077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 515637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 516637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 5178189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, 5188189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek rbrac, ArgExprs, NumArgs); 519fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 520fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner 521fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner // Handle messages to Class. 522b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) { 5232b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner ObjCMethodDecl *Method = 0; 5246b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff 5256562fdad21432377f0cc5e0c627c28f0c85df4ddChris Lattner if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { 526d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { 527d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff // First check the public methods in the class interface. 5286ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor Method = ClassDecl->lookupClassMethod(Context, Sel); 529d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff 530f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff if (!Method) 5315609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateClassMethod(Sel, ClassDecl); 532d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff } 53348f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 53448f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 535d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff } 5366b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (!Method) { 5376b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // If not messaging 'self', look for any factory method named 'Sel'. 5386b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (!isSelfExpr(RExpr)) { 539f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac)); 540b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian if (!Method) { 541041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian // If no class (factory) method was found, check if an _instance_ 542041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian // method of the same name exists in the root class only. 5436b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Method = LookupInstanceMethodInGlobalPool( 5446b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Sel, SourceRange(lbrac,rbrac)); 545041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian if (Method) 546041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian if (const ObjCInterfaceDecl *ID = 547041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) { 548041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian if (ID->getSuperClass()) 549041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian Diag(lbrac, diag::warn_root_inst_method_not_found) 550041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian << Sel << SourceRange(lbrac, rbrac); 551041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian } 552b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian } 5536b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff } 5546b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff } 555077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 556637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 557637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 5588189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, 5598189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek rbrac, ArgExprs, NumArgs); 560fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 561fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner 5622b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner ObjCMethodDecl *Method = 0; 563fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner ObjCInterfaceDecl* ClassDecl = 0; 5642b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner 5652b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner // We allow sending a message to a qualified ID ("id<foo>"), which is ok as 5662b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner // long as one of the protocols implements the selector (if not, warn). 567b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) { 568f7f52e7bf5a4dc36d45b98531e0b21e343fc19deSteve Naroff // Search protocols for instance methods. 569fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner for (unsigned i = 0; i < QIT->getNumProtocols(); i++) { 570fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner ObjCProtocolDecl *PDecl = QIT->getProtocols(i); 5716ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor if (PDecl && (Method = PDecl->lookupInstanceMethod(Context, Sel))) 572fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner break; 573ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff // Since we aren't supporting "Class<foo>", look for a class method. 5746ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor if (PDecl && (Method = PDecl->lookupClassMethod(Context, Sel))) 575ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff break; 576fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 577279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff } else if (const ObjCInterfaceType *OCIType = 578b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner ReceiverCType->getAsPointerToObjCInterfaceType()) { 5792b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner // We allow sending a message to a pointer to an interface (an object). 580fb8cc1dfd87a1cbbaa17d64ec753d3fe8a9e9c38Chris Lattner 581279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff ClassDecl = OCIType->getDecl(); 582037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be 583390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // faster than the following method (which can do *many* linear searches). 584037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff // The idea is to add class info to InstanceMethodPool. 5856ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor Method = ClassDecl->lookupInstanceMethod(Context, Sel); 586fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner 587fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner if (!Method) { 588fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner // Search protocol qualifiers. 589279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff for (ObjCQualifiedInterfaceType::qual_iterator QI = OCIType->qual_begin(), 590279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff E = OCIType->qual_end(); QI != E; ++QI) { 5916ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor if ((Method = (*QI)->lookupInstanceMethod(Context, Sel))) 59285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner break; 59385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 59485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 5950de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff if (!Method) { 5965609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // If we have implementations in scope, check "private" methods. 5975609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateInstanceMethod(Sel, ClassDecl); 5985609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 5995609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method && !isSelfExpr(RExpr)) { 6006b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // If we still haven't found a method, look in the global pool. This 6016b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // behavior isn't very desirable, however we need it for GCC 6026b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // compatibility. FIXME: should we deviate?? 6035609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (OCIType->qual_empty()) { 6046b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Method = LookupInstanceMethodInGlobalPool( 6056b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Sel, SourceRange(lbrac,rbrac)); 6066b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (Method && !OCIType->getDecl()->isForwardDecl()) 6076b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Diag(lbrac, diag::warn_maynot_respond) 6086b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff << OCIType->getDecl()->getIdentifier()->getName() << Sel; 6096b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff } 610268bc8c1f3a27d2fbd73c3115e4d633d31422ca5Fariborz Jahanian } 6110de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff } 61248f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 61348f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 6140c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner } else if (!Context.getObjCIdType().isNull() && 6150c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner (ReceiverCType->isPointerType() || 6160c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner (ReceiverCType->isIntegerType() && 6170c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner ReceiverCType->isScalarType()))) { 6180c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner // Implicitly convert integers and pointers to 'id' but emit a warning. 6198e2945ad9104f0ce4928c386faf458b6b83d9060Steve Naroff Diag(lbrac, diag::warn_bad_receiver_type) 620d162584991885ab004a02573a73ce06422b921fcChris Lattner << RExpr->getType() << RExpr->getSourceRange(); 6210c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner ImpCastExprToType(RExpr, Context.getObjCIdType()); 6220c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner } else { 6230c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner // Reject other random receiver types (e.g. structs). 6240c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner Diag(lbrac, diag::err_bad_receiver_type) 6250c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner << RExpr->getType() << RExpr->getSourceRange(); 6262b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner return true; 627fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 628fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner 6295b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian if (Method) 6305b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian DiagnoseSentinelCalls(Method, receiverLoc, ArgExprs, NumArgs); 631077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 632637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 633637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 6348189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, 6358189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek rbrac, ArgExprs, NumArgs); 63685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 637eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 638eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===// 639eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's. 640eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===// 641eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 642eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the 643eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// inheritance hierarchy of 'rProto'. 644eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto, 645eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner ObjCProtocolDecl *rProto) { 646eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner if (lProto == rProto) 647eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return true; 648780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(), 649780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner E = rProto->protocol_end(); PI != E; ++PI) 650780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner if (ProtocolCompatibleWithProtocol(lProto, *PI)) 651eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return true; 652eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return false; 653eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner} 654eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 655eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ClassImplementsProtocol - Checks that 'lProto' protocol 656eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// has been implemented in IDecl class, its super class or categories (if 657eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// lookupCategory is true). 658eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, 659eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner ObjCInterfaceDecl *IDecl, 66026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian bool lookupCategory, 66126631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian bool RHSIsQualifiedID = false) { 662eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 663eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // 1st, look up the class. 6643db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner const ObjCList<ObjCProtocolDecl> &Protocols = 6653db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner IDecl->getReferencedProtocols(); 6663db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner 6673db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(), 6683db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner E = Protocols.end(); PI != E; ++PI) { 6693db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner if (ProtocolCompatibleWithProtocol(lProto, *PI)) 670eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return true; 671390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // This is dubious and is added to be compatible with gcc. In gcc, it is 672390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // also allowed assigning a protocol-qualified 'id' type to a LHS object 673390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // when protocol in qualified LHS is in list of protocols in the rhs 'id' 674390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // object. This IMO, should be a bug. 675390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Treat this as an extension, and flag this as an error when GCC 676390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // extensions are not enabled. 6773db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner if (RHSIsQualifiedID && ProtocolCompatibleWithProtocol(*PI, lProto)) 67826631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian return true; 679eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 680eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 681eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // 2nd, look up the category. 682eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner if (lookupCategory) 683eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl; 684eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner CDecl = CDecl->getNextClassCategory()) { 685780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(), 686780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner E = CDecl->protocol_end(); PI != E; ++PI) 687780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner if (ProtocolCompatibleWithProtocol(lProto, *PI)) 688eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return true; 689eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 690eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 691eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // 3rd, look up the super class(s) 692eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner if (IDecl->getSuperClass()) 693eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return 69426631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory, 69526631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian RHSIsQualifiedID); 696eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 697eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return false; 698eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner} 699eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 7002574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian/// QualifiedIdConformsQualifiedId - compare id<p,...> with id<p1,...> 7012574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian/// return true if lhs's protocols conform to rhs's protocol; false 7022574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian/// otherwise. 7032574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanianbool Sema::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) { 7042574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian if (lhs->isObjCQualifiedIdType() && rhs->isObjCQualifiedIdType()) 7052574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian return ObjCQualifiedIdTypesAreCompatible(lhs, rhs, false); 7062574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian return false; 7072574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian} 7082574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian 709b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an 710b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIDType. 71115edf0de6b5bc9ae227bcc9658a157ac30efd92eSteve Naroff/// FIXME: Move to ASTContext::typesAreCompatible() and friends. 712eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerbool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, 713eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner bool compare) { 714eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // Allow id<P..> and an 'id' or void* type in all cases. 715eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner if (const PointerType *PT = lhs->getAsPointerType()) { 716eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner QualType PointeeTy = PT->getPointeeType(); 7172c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner if (PointeeTy->isVoidType() || 7182c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner Context.isObjCIdStructType(PointeeTy) || 7192c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner Context.isObjCClassStructType(PointeeTy)) 720eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return true; 721eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } else if (const PointerType *PT = rhs->getAsPointerType()) { 722eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner QualType PointeeTy = PT->getPointeeType(); 7232c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner if (PointeeTy->isVoidType() || 7242c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner Context.isObjCIdStructType(PointeeTy) || 7252c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner Context.isObjCClassStructType(PointeeTy)) 726eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return true; 727eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 728eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 729b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) { 730b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); 731b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner const ObjCQualifiedInterfaceType *rhsQI = 0; 732289d9f243d9074513368d27eef3b647f72a38324Steve Naroff QualType rtype; 733289d9f243d9074513368d27eef3b647f72a38324Steve Naroff 734b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (!rhsQID) { 735b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner // Not comparing two ObjCQualifiedIdType's? 736b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (!rhs->isPointerType()) return false; 737289d9f243d9074513368d27eef3b647f72a38324Steve Naroff 738289d9f243d9074513368d27eef3b647f72a38324Steve Naroff rtype = rhs->getAsPointerType()->getPointeeType(); 739eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner rhsQI = rtype->getAsObjCQualifiedInterfaceType(); 740b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (rhsQI == 0) { 741289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // If the RHS is a unqualified interface pointer "NSString*", 742289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // make sure we check the class hierarchy. 743b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { 744b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCInterfaceDecl *rhsID = IT->getDecl(); 745b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { 746b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner // when comparing an id<P> on lhs with a static type on rhs, 747b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner // see if static class implements all of id's protocols, directly or 748b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner // through its super class and categories. 749b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (!ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) 750b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return false; 751b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } 752b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return true; 753b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } 754b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } 755eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 756eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 757eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE; 758289d9f243d9074513368d27eef3b647f72a38324Steve Naroff if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *"). 759eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner RHSProtoI = rhsQI->qual_begin(); 760eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner RHSProtoE = rhsQI->qual_end(); 761289d9f243d9074513368d27eef3b647f72a38324Steve Naroff } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *"). 762eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner RHSProtoI = rhsQID->qual_begin(); 763eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner RHSProtoE = rhsQID->qual_end(); 764b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } else { 765b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return false; 766eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 767eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 768eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) { 769eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner ObjCProtocolDecl *lhsProto = lhsQID->getProtocols(i); 770eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner bool match = false; 771eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 772eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // when comparing an id<P> on lhs with a static type on rhs, 773eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // see if static class implements all of id's protocols, directly or 774eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner // through its super class and categories. 775b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner for (; RHSProtoI != RHSProtoE; ++RHSProtoI) { 776b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCProtocolDecl *rhsProto = *RHSProtoI; 777b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 77882b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { 779eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner match = true; 780b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner break; 781eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 782eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 783289d9f243d9074513368d27eef3b647f72a38324Steve Naroff if (rhsQI) { 784289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // If the RHS is a qualified interface pointer "NSString<P>*", 785289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // make sure we check the class hierarchy. 786289d9f243d9074513368d27eef3b647f72a38324Steve Naroff if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { 787289d9f243d9074513368d27eef3b647f72a38324Steve Naroff ObjCInterfaceDecl *rhsID = IT->getDecl(); 788289d9f243d9074513368d27eef3b647f72a38324Steve Naroff for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { 789289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // when comparing an id<P> on lhs with a static type on rhs, 790289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // see if static class implements all of id's protocols, directly or 791289d9f243d9074513368d27eef3b647f72a38324Steve Naroff // through its super class and categories. 792289d9f243d9074513368d27eef3b647f72a38324Steve Naroff if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) { 793289d9f243d9074513368d27eef3b647f72a38324Steve Naroff match = true; 794289d9f243d9074513368d27eef3b647f72a38324Steve Naroff break; 795289d9f243d9074513368d27eef3b647f72a38324Steve Naroff } 796289d9f243d9074513368d27eef3b647f72a38324Steve Naroff } 797289d9f243d9074513368d27eef3b647f72a38324Steve Naroff } 798289d9f243d9074513368d27eef3b647f72a38324Steve Naroff } 799eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner if (!match) 800eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner return false; 801eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 802eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 803b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return true; 804b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } 805b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner 806b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); 807b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner assert(rhsQID && "One of the LHS/RHS should be id<x>"); 808eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 809b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (!lhs->isPointerType()) 810b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return false; 811b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner 812b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner QualType ltype = lhs->getAsPointerType()->getPointeeType(); 813b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (const ObjCQualifiedInterfaceType *lhsQI = 814b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ltype->getAsObjCQualifiedInterfaceType()) { 815b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin(); 816b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end(); 817b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner for (; LHSProtoI != LHSProtoE; ++LHSProtoI) { 818b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner bool match = false; 819b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCProtocolDecl *lhsProto = *LHSProtoI; 820eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { 821eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); 822b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || 82382b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { 824eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner match = true; 825eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner break; 826eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 827eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 828b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (!match) 829b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return false; 830eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 831b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return true; 832b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } 833b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner 834b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) { 835b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner // for static type vs. qualified 'id' type, check that class implements 836b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner // all of 'id's protocols. 837b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCInterfaceDecl *lhsID = IT->getDecl(); 838b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) { 839b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j); 84026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian if (!ClassImplementsProtocol(rhsProto, lhsID, compare, true)) 841b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return false; 842b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner } 843b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return true; 844eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner } 845b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner return false; 846eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner} 847eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 848