SemaExprObjC.cpp revision 47bd54392a4fd0f10e04de6a0420fd4838caaa0e
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" 157f81652f97a69ae8b514893a69c0245253687e55Chris Lattner#include "Lookup.h" 1685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/ASTContext.h" 1785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/DeclObjC.h" 18f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h" 1939c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner#include "llvm/ADT/SmallString.h" 2061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff#include "clang/Lex/Preprocessor.h" 2161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 2285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattnerusing namespace clang; 2385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 241eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpSema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 2539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner ExprTy **strings, 2685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner unsigned NumStrings) { 2739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings); 2839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner 29f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // Most ObjC strings are formed out of a single piece. However, we *can* 30f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // have strings formed out of multiple @ strings with multiple pptokens in 31f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // each one, e.g. @"foo" "bar" @"baz" "qux" which need to be turned into one 32f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // StringLiteral for ObjCStringLiteral to hold onto. 3339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StringLiteral *S = Strings[0]; 341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner // If we have a multi-part string, merge it all together. 36f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner if (NumStrings != 1) { 3785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner // Concatenate objc strings. 3839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner llvm::SmallString<128> StrBuf; 3939c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner llvm::SmallVector<SourceLocation, 8> StrLocs; 401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 41726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner for (unsigned i = 0; i != NumStrings; ++i) { 4239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner S = Strings[i]; 431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // ObjC strings can't be wide. 45f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner if (S->isWide()) { 46f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant) 47f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner << S->getSourceRange(); 48f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner return true; 49f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner } 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Get the string data. 5239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength()); 531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Get the locations of the string tokens. 5539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner StrLocs.append(S->tokloc_begin(), S->tokloc_end()); 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Free the temporary string. 588189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek S->Destroy(Context); 5985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // Create the aggregate string with the appropriate content and location 6239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner // information. 6339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false, 642085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner Context.getPointerType(Context.CharTy), 6539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner &StrLocs[0], StrLocs.size()); 6685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner // Verify that this composite string is acceptable for ObjC strings. 69690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner if (CheckObjCString(S)) 7085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner return true; 71a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner 72a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner // Initialize the constant string interface lazily. This assumes 73d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // the NSString interface is seen in this translation unit. Note: We 74d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // don't use NSConstantString, since the runtime team considers this 75d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // interface private (even though it appears in the header files). 76a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType Ty = Context.getObjCConstantStringInterface(); 77a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner if (!Ty.isNull()) { 7814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff Ty = Context.getObjCObjectPointerType(Ty); 7913fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner } else { 80d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff IdentifierInfo *NSIdent = &Context.Idents.get("NSString"); 81f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *IF = LookupSingleName(TUScope, NSIdent, LookupOrdinaryName); 82a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) { 83a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Context.setObjCConstantStringInterface(StrIF); 84a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getObjCConstantStringInterface(); 8514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff Ty = Context.getObjCObjectPointerType(Ty); 86a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner } else { 87d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff // If there is no NSString interface defined then treat constant 88a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner // strings as untyped objects and let the runtime figure it out later. 89a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner Ty = Context.getObjCIdType(); 90a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner } 9113fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner } 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 93f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]); 9485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 9585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 961eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpExpr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, 97fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson QualType EncodedType, 98fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson SourceLocation RParenLoc) { 99fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson QualType StrTy; 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (EncodedType->isDependentType()) 101fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson StrTy = Context.DependentTy; 102fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson else { 103fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson std::string Str; 104fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson Context.getObjCEncodingForType(EncodedType, Str); 105fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson 106fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson // The type of @encode is the same as the type of the corresponding string, 107fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson // which is an array type. 108fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson StrTy = Context.CharTy; 109fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). 1104b7a834e0fecddd9eaf1f4567867c718e4eebf50John McCall if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings) 111fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson StrTy.addConst(); 112fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1), 113fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson ArrayType::Normal, 0); 114fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson } 1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 116fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc); 117fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson} 118fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson 11985a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc, 12085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation EncodeLoc, 12185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation LParenLoc, 122a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner TypeTy *ty, 12385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation RParenLoc) { 124e8661906d49ef6c9694a9cc845ca62a85dbc016dArgyrios Kyrtzidis // FIXME: Preserve type source info ? 125e8661906d49ef6c9694a9cc845ca62a85dbc016dArgyrios Kyrtzidis QualType EncodedType = GetTypeFromParser(ty); 12685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 127fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc); 12885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 12985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 13085a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel, 13185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation AtLoc, 13285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation SelLoc, 13385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation LParenLoc, 13485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation RParenLoc) { 1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel, 136835ed7f15bd8a89226fd7976d96be19995f1c1c8Fariborz Jahanian SourceRange(LParenLoc, RParenLoc), false); 1377ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian if (!Method) 1387ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian Method = LookupFactoryMethodInGlobalPool(Sel, 1397ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian SourceRange(LParenLoc, RParenLoc)); 1407ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian if (!Method) 1417ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian Diag(SelLoc, diag::warn_undeclared_selector) << Sel; 1427ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian 143a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType Ty = Context.getObjCSelType(); 1446d5a1c28593443f3973ef38f8fa042d59182412dDaniel Dunbar return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc); 14585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 14685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 14785a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, 14885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation AtLoc, 14985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation ProtoLoc, 15085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation LParenLoc, 15185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner SourceLocation RParenLoc) { 1526e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId); 15385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner if (!PDecl) { 1543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId; 15585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner return true; 15685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 158a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner QualType Ty = Context.getObjCProtoType(); 159a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner if (Ty.isNull()) 16085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner return true; 16114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff Ty = Context.getObjCObjectPointerType(Ty); 162a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc); 16385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 16485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpbool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, 1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Selector Sel, ObjCMethodDecl *Method, 167077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner bool isClassMessage, 168637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar SourceLocation lbrac, SourceLocation rbrac, 1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType &ReturnType) { 170637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar if (!Method) { 1716660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar // Apply default argument promotion as for (C99 6.5.2.2p6). 1726660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar for (unsigned i = 0; i != NumArgs; i++) 1736660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar DefaultArgumentPromotion(Args[i]); 1746660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar 175077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found : 176077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner diag::warn_inst_method_not_found; 177077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner Diag(lbrac, DiagID) 178077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner << Sel << isClassMessage << SourceRange(lbrac, rbrac); 179637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar ReturnType = Context.getObjCIdType(); 180637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return false; 181637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar } 1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 183077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner ReturnType = Method->getResultType(); 1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar unsigned NumNamedArgs = Sel.getNumArgs(); 1864f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian // Method might have more arguments than selector indicates. This is due 1874f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian // to addition of c-style arguments in method. 1884f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian if (Method->param_size() > Sel.getNumArgs()) 1894f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian NumNamedArgs = Method->param_size(); 1904f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian // FIXME. This need be cleaned up. 1914f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian if (NumArgs < NumNamedArgs) { 1924f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian Diag(lbrac, diag::err_typecheck_call_too_few_args) << 2; 1934f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian return false; 1944f4fd92c6c64ecbc65507f63ddd09211f732622cFariborz Jahanian } 19591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar 196312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner bool IsError = false; 19791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar for (unsigned i = 0; i < NumNamedArgs; i++) { 19885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr *argExpr = Args[i]; 19985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); 2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20189951a86b594513c2a013532ed45d197413b1087Chris Lattner QualType lhsType = Method->param_begin()[i]->getType(); 20285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner QualType rhsType = argExpr->getType(); 20385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 205987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner if (lhsType->isArrayType()) 206987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner lhsType = Context.getArrayDecayedType(lhsType); 20785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner else if (lhsType->isFunctionType()) 20885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner lhsType = Context.getPointerType(lhsType); 20985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump AssignConvertType Result = 211987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner CheckSingleAssignmentConstraints(lhsType, argExpr); 21285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner if (Args[i] != argExpr) // The expression was converted. 21385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Args[i] = argExpr; // Make sure we store the converted expression. 2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump IsError |= 21685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, 2176864748fc9a780e6db0bb5a7bd20aa889882dc94Douglas Gregor argExpr, AA_Sending); 21885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 21991e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar 22091e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar // Promote additional arguments to variadic methods. 22191e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar if (Method->isVariadic()) { 222dce5e2cabf07ff25eb4d9e1859c0a21c69f588d2Anders Carlsson for (unsigned i = NumNamedArgs; i < NumArgs; ++i) 223312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod); 22491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar } else { 22591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar // Check for extra arguments to non-variadic methods. 22691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar if (NumArgs != NumNamedArgs) { 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(Args[NumNamedArgs]->getLocStart(), 228fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner diag::err_typecheck_call_too_many_args) 2292c21a073525cdfa68e4439b7af551385dc2796abChris Lattner << 2 /*method*/ << Method->getSourceRange() 230fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << SourceRange(Args[NumNamedArgs]->getLocStart(), 231fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Args[NumArgs-1]->getLocEnd()); 23291e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar } 23391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar } 23491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar 235312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner return IsError; 23685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 23785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 2386b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroffbool Sema::isSelfExpr(Expr *RExpr) { 2396b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr)) 2406b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self")) 2416b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff return true; 2426b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff return false; 2436b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff} 2446b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff 245f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Helper method for ActOnClassMethod/ActOnInstanceMethod. 246f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Will search "local" class/category implementations for a method decl. 247175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian// If failed, then we search in class's root for an instance method. 248f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Returns 0 if no method is found. 2495609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel, 250f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff ObjCInterfaceDecl *ClassDecl) { 251f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff ObjCMethodDecl *Method = 0; 2525609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // lookup in class and all superclasses 2535609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff while (ClassDecl && !Method) { 25487018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation()) 25517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = ImpDecl->getClassMethod(Sel); 2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2575609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Look through local category implementations associated with the class. 2581cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis if (!Method) 2591cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis Method = ClassDecl->getCategoryClassMethod(Sel); 2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2615609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Before we give up, check if the selector is an instance method. 2625609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // But only in the root. This matches gcc's behaviour and what the 2635609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // runtime expects. 2645609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method && !ClassDecl->getSuperClass()) { 26517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = ClassDecl->lookupInstanceMethod(Sel); 2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Look through local category implementations associated 2675609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // with the root class. 2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!Method) 2695609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateInstanceMethod(Sel, ClassDecl); 270f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff } 2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2725609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ClassDecl = ClassDecl->getSuperClass(); 273f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff } 2745609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff return Method; 2755609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff} 2765609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff 2775609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel, 2785609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ObjCInterfaceDecl *ClassDecl) { 2795609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ObjCMethodDecl *Method = 0; 2805609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff while (ClassDecl && !Method) { 2815609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // If we have implementations in scope, check "private" methods. 28287018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation()) 28317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = ImpDecl->getInstanceMethod(Sel); 2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2855609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // Look through local category implementations associated with the class. 2861cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis if (!Method) 2871cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis Method = ClassDecl->getCategoryInstanceMethod(Sel); 2885609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff ClassDecl = ClassDecl->getSuperClass(); 289175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian } 290f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff return Method; 291f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff} 292f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff 2937f81652f97a69ae8b514893a69c0245253687e55Chris Lattner/// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an 2947f81652f97a69ae8b514893a69c0245253687e55Chris Lattner/// objective C interface. This is a property reference expression. 2957f81652f97a69ae8b514893a69c0245253687e55Chris LattnerAction::OwningExprResult Sema:: 2967f81652f97a69ae8b514893a69c0245253687e55Chris LattnerHandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, 297b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner Expr *BaseExpr, DeclarationName MemberName, 298b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner SourceLocation MemberLoc) { 2997f81652f97a69ae8b514893a69c0245253687e55Chris Lattner const ObjCInterfaceType *IFaceT = OPT->getInterfaceType(); 3007f81652f97a69ae8b514893a69c0245253687e55Chris Lattner ObjCInterfaceDecl *IFace = IFaceT->getDecl(); 3017f81652f97a69ae8b514893a69c0245253687e55Chris Lattner IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); 3027f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3037f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Search for a declared property first. 3047f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Member)) { 3057f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Check whether we can reference this property. 3067f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (DiagnoseUseOfDecl(PD, MemberLoc)) 3077f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return ExprError(); 3087f81652f97a69ae8b514893a69c0245253687e55Chris Lattner QualType ResTy = PD->getType(); 3097f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Selector Sel = PP.getSelectorTable().getNullarySelector(Member); 3107f81652f97a69ae8b514893a69c0245253687e55Chris Lattner ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); 3117f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc)) 3127f81652f97a69ae8b514893a69c0245253687e55Chris Lattner ResTy = Getter->getResultType(); 3137f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy, 3147f81652f97a69ae8b514893a69c0245253687e55Chris Lattner MemberLoc, BaseExpr)); 3157f81652f97a69ae8b514893a69c0245253687e55Chris Lattner } 3167f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Check protocols on qualified interfaces. 3177f81652f97a69ae8b514893a69c0245253687e55Chris Lattner for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), 3187f81652f97a69ae8b514893a69c0245253687e55Chris Lattner E = OPT->qual_end(); I != E; ++I) 3197f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) { 3207f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Check whether we can reference this property. 3217f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (DiagnoseUseOfDecl(PD, MemberLoc)) 3227f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return ExprError(); 3237f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3247f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), 3257f81652f97a69ae8b514893a69c0245253687e55Chris Lattner MemberLoc, BaseExpr)); 3267f81652f97a69ae8b514893a69c0245253687e55Chris Lattner } 3277f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // If that failed, look for an "implicit" property by seeing if the nullary 3287f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // selector is implemented. 3297f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3307f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // FIXME: The logic for looking up nullary and unary selectors should be 3317f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // shared with the code in ActOnInstanceMessage. 3327f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3337f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Selector Sel = PP.getSelectorTable().getNullarySelector(Member); 3347f81652f97a69ae8b514893a69c0245253687e55Chris Lattner ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); 3357f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3367f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // If this reference is in an @implementation, check for 'private' methods. 3377f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (!Getter) 3387f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Getter = IFace->lookupPrivateInstanceMethod(Sel); 3397f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3407f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Look through local category implementations associated with the class. 3417f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (!Getter) 3427f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Getter = IFace->getCategoryInstanceMethod(Sel); 3437f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (Getter) { 3447f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Check if we can reference this property. 3457f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (DiagnoseUseOfDecl(Getter, MemberLoc)) 3467f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return ExprError(); 3477f81652f97a69ae8b514893a69c0245253687e55Chris Lattner } 3487f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // If we found a getter then this may be a valid dot-reference, we 3497f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // will look for the matching setter, in case it is needed. 3507f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Selector SetterSel = 3517f81652f97a69ae8b514893a69c0245253687e55Chris Lattner SelectorTable::constructSetterName(PP.getIdentifierTable(), 3527f81652f97a69ae8b514893a69c0245253687e55Chris Lattner PP.getSelectorTable(), Member); 3537f81652f97a69ae8b514893a69c0245253687e55Chris Lattner ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel); 3547f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (!Setter) { 3557f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // If this reference is in an @implementation, also check for 'private' 3567f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // methods. 3577f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Setter = IFace->lookupPrivateInstanceMethod(SetterSel); 3587f81652f97a69ae8b514893a69c0245253687e55Chris Lattner } 3597f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Look through local category implementations associated with the class. 3607f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (!Setter) 3617f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Setter = IFace->getCategoryInstanceMethod(SetterSel); 3627f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3637f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc)) 3647f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return ExprError(); 3657f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3667f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (Getter) { 3677f81652f97a69ae8b514893a69c0245253687e55Chris Lattner QualType PType; 3687f81652f97a69ae8b514893a69c0245253687e55Chris Lattner PType = Getter->getResultType(); 3697f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, 3707f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Setter, MemberLoc, BaseExpr)); 3717f81652f97a69ae8b514893a69c0245253687e55Chris Lattner } 3727f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3737f81652f97a69ae8b514893a69c0245253687e55Chris Lattner // Attempt to correct for typos in property names. 3747f81652f97a69ae8b514893a69c0245253687e55Chris Lattner LookupResult Res(*this, MemberName, MemberLoc, LookupOrdinaryName); 3757f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (CorrectTypo(Res, 0, 0, IFace, false, OPT) && 3767f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Res.getAsSingle<ObjCPropertyDecl>()) { 377b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner DeclarationName TypoResult = Res.getLookupName(); 3787f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Diag(MemberLoc, diag::err_property_not_found_suggest) 379b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner << MemberName << QualType(OPT, 0) << TypoResult 380b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner << FixItHint::CreateReplacement(MemberLoc, TypoResult.getAsString()); 3817f81652f97a69ae8b514893a69c0245253687e55Chris Lattner ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>(); 3827f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Diag(Property->getLocation(), diag::note_previous_decl) 3837f81652f97a69ae8b514893a69c0245253687e55Chris Lattner << Property->getDeclName(); 384b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner return HandleExprPropertyRefExpr(OPT, BaseExpr, TypoResult, MemberLoc); 3857f81652f97a69ae8b514893a69c0245253687e55Chris Lattner } 386b9d4fc1f54924a7b242fb763192a40c19fa6103dChris Lattner 3877f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Diag(MemberLoc, diag::err_property_not_found) 3887f81652f97a69ae8b514893a69c0245253687e55Chris Lattner << MemberName << QualType(OPT, 0); 3897f81652f97a69ae8b514893a69c0245253687e55Chris Lattner if (Setter && !Getter) 3907f81652f97a69ae8b514893a69c0245253687e55Chris Lattner Diag(Setter->getLocation(), diag::note_getter_unavailable) 3917f81652f97a69ae8b514893a69c0245253687e55Chris Lattner << MemberName << BaseExpr->getSourceRange(); 3927f81652f97a69ae8b514893a69c0245253687e55Chris Lattner return ExprError(); 3937f81652f97a69ae8b514893a69c0245253687e55Chris Lattner} 3947f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3957f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 3967f81652f97a69ae8b514893a69c0245253687e55Chris Lattner 397eb483eb3ee80300f15d6d13573d82493c2194461Chris LattnerAction::OwningExprResult Sema:: 398eb483eb3ee80300f15d6d13573d82493c2194461Chris LattnerActOnClassPropertyRefExpr(IdentifierInfo &receiverName, 399eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner IdentifierInfo &propertyName, 400eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner SourceLocation receiverNameLoc, 401eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner SourceLocation propertyNameLoc) { 4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 403f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor IdentifierInfo *receiverNamePtr = &receiverName; 404f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr); 405eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (IFace == 0) { 406eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner // If the "receiver" is 'super' in a method, handle it as an expression-like 407eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner // property reference. 408eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) 409eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (receiverNamePtr->isStr("super")) { 410eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (CurMethod->isInstanceMethod()) { 411eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner QualType T = 412eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner Context.getObjCInterfaceType(CurMethod->getClassInterface()); 413eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner T = Context.getObjCObjectPointerType(T); 414eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner Expr *SuperExpr = new (Context) ObjCSuperExpr(receiverNameLoc, T); 415eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner 416eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(), 417eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner SuperExpr, &propertyName, 418eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner propertyNameLoc); 419eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner } 420eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner 421eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner // Otherwise, if this is a class method, try dispatching to our 422eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner // superclass. 423eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner IFace = CurMethod->getClassInterface()->getSuperClass(); 424eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner } 425eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner 426eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (IFace == 0) { 427eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner Diag(receiverNameLoc, diag::err_expected_ident_or_lparen); 428eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner return ExprError(); 429eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner } 4308149a5786def747af783a9e3c22714bb7ab42b9cFariborz Jahanian } 4311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 432eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner // Search for a declared property first. 43361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName); 43417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel); 43561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 43661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // If this reference is in an @implementation, check for 'private' methods. 43761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (!Getter) 43861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) 43961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 44087018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation()) 44117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Getter = ImpDecl->getClassMethod(Sel); 44261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 44361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Getter) { 44461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // FIXME: refactor/share with ActOnMemberReference(). 44561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Check if we can reference this property. 44661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (DiagnoseUseOfDecl(Getter, propertyNameLoc)) 44761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return ExprError(); 44861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 45061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Look for the matching setter, in case it is needed. 4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Selector SetterSel = 4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SelectorTable::constructSetterName(PP.getIdentifierTable(), 453fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff PP.getSelectorTable(), &propertyName); 4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 45517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); 45661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (!Setter) { 45761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // If this reference is in an @implementation, also check for 'private' 45861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // methods. 45961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) 46061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 46187018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation()) 46217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Setter = ImpDecl->getClassMethod(SetterSel); 46361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 46461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff // Look through local category implementations associated with the class. 4651cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis if (!Setter) 4661cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis Setter = IFace->getCategoryClassMethod(SetterSel); 46761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 46861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc)) 46961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return ExprError(); 47061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 47161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Getter || Setter) { 47261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff QualType PType; 47361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 47461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff if (Getter) 47561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff PType = Getter->getResultType(); 47661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff else { 47761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(), 47861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff E = Setter->param_end(); PI != E; ++PI) 47961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff PType = (*PI)->getType(); 48061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 48109105f52b1f28cbb1374c27c3c70f5517e2c465dFariborz Jahanian return Owned(new (Context) ObjCImplicitSetterGetterRefExpr( 4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Getter, PType, Setter, 48361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff propertyNameLoc, IFace, receiverNameLoc)); 48461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff } 48561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff return ExprError(Diag(propertyNameLoc, diag::err_property_not_found) 48661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff << &propertyName << Context.getObjCInterfaceType(IFace)); 48761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff} 48861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 48947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas GregorSema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, 49047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor IdentifierInfo *&Name, 49147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor SourceLocation NameLoc, 49247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor bool IsSuper, 49347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor bool HasTrailingDot) { 49447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor // If the identifier is "super" and there is no trailing dot, we're 49547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor // messaging super. 49647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope()) 49747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor return ObjCSuperMessage; 49847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 49947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName); 50047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor LookupName(Result, S); 50147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 50247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor switch (Result.getResultKind()) { 50347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor case LookupResult::NotFound: 50447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor // Break out; we'll perform typo correction below. 50547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor break; 50647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 50747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor case LookupResult::NotFoundInCurrentInstantiation: 50847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor case LookupResult::FoundOverloaded: 50947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor case LookupResult::FoundUnresolvedValue: 51047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor case LookupResult::Ambiguous: 51147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor Result.suppressDiagnostics(); 51247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor return ObjCInstanceMessage; 51347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 51447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor case LookupResult::Found: { 51547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor // We found something. If it's a type, then we have a class 51647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor // message. Otherwise, it's an instance message. 51747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor NamedDecl *ND = Result.getFoundDecl(); 51847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor if (isa<ObjCInterfaceDecl>(ND) || isa<TypeDecl>(ND) || 51947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor isa<UnresolvedUsingTypenameDecl>(ND)) 52047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor return ObjCClassMessage; 52147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 52247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor return ObjCInstanceMessage; 52347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor } 52447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor } 52547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 52647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor if (CorrectTypo(Result, S, 0) && Result.isSingleResult()) { 52747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor NamedDecl *ND = Result.getFoundDecl(); 52847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor if (isa<ObjCInterfaceDecl>(ND)) { 52947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor Diag(NameLoc, diag::err_unknown_receiver_suggest) 53047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor << Name << Result.getLookupName() 53147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor << FixItHint::CreateReplacement(SourceRange(NameLoc), 53247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor ND->getNameAsString()); 53347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor Diag(ND->getLocation(), diag::note_previous_decl) 53447bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor << ND->getDeclName(); 53547bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 53647bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor Name = ND->getIdentifier(); 53747bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor return ObjCClassMessage; 53847bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor } 53947bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor } 54047bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor 54147bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor // Fall back: let the parser try to parse it as an instance message. 54247bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor return ObjCInstanceMessage; 54347bd54392a4fd0f10e04de6a0420fd4838caaa0eDouglas Gregor} 54461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff 54585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnClassMessage - used for both unary and keyword messages. 54685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions 54785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs(). 548eb483eb3ee80300f15d6d13573d82493c2194461Chris LattnerSema::ExprResult Sema:: 549eb483eb3ee80300f15d6d13573d82493c2194461Chris LattnerActOnClassMessage(Scope *S, IdentifierInfo *receiverName, Selector Sel, 550eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner SourceLocation lbrac, SourceLocation receiverLoc, 551eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner SourceLocation selectorLoc, SourceLocation rbrac, 552eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner ExprTy **Args, unsigned NumArgs) { 55385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner assert(receiverName && "missing receiver class name"); 55485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 55585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 55615faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner ObjCInterfaceDecl *ClassDecl = 0; 557a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner bool isSuper = false; 5581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 55915faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner // Special case a message to super, which can be either a class message or an 56015faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner // instance message, depending on what CurMethodDecl is. 5618469265156c6344fa1100a6a7bf6349acc187d9fChris Lattner if (receiverName->isStr("super")) { 562eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) { 563eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner ObjCInterfaceDecl *OID = CurMethod->getClassInterface(); 5644b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian if (!OID) 5651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Diag(lbrac, diag::error_no_super_class_message) 566eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner << CurMethod->getDeclName(); 5674b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian ClassDecl = OID->getSuperClass(); 56815faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner if (ClassDecl == 0) 5694b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName(); 570eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (CurMethod->isInstanceMethod()) { 5715cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff QualType superTy = Context.getObjCInterfaceType(ClassDecl); 57214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff superTy = Context.getObjCObjectPointerType(superTy); 5738189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(), 5748189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek superTy); 5755cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff // We are really in an instance method, redirect. 5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac, 577ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson selectorLoc, rbrac, Args, NumArgs); 5785cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff } 579eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner 58015faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner // Otherwise, if this is a class method, try dispatching to our 58115faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner // superclass, which is in ClassDecl. 582a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner isSuper = true; 5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 58415faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner } 58515faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner 58615faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner if (ClassDecl == 0) 587f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor ClassDecl = getObjCInterfaceDecl(receiverName, receiverLoc); 5881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5897c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff // The following code allows for the following GCC-ism: 590cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // 591cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // typedef XCElementDisplayRect XCElementGraphicsRect; 592cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // 593cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // @implementation XCRASlice 594cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // - whatever { // Note that XCElementGraphicsRect is a typedef name. 595cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init]; 596cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // } 597cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff // 5987c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff // If necessary, the following lookup could move to getObjCInterfaceDecl(). 5997c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff if (!ClassDecl) { 600f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *IDecl 601f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall = LookupSingleName(TUScope, receiverName, LookupOrdinaryName); 602c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) 603c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor if (const ObjCInterfaceType *OCIT 604c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>()) 605c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor ClassDecl = OCIT->getDecl(); 606c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor 607c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor if (!ClassDecl) { 608eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner // Give a better error message for invalid use of super. 609eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner if (receiverName->isStr("super")) 610eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner Diag(receiverLoc, diag::err_invalid_receiver_to_message_super); 611eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner else 612eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner Diag(receiverLoc, diag::err_invalid_receiver_to_message); 613c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor return true; 6147c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff } 6157c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff } 6167c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff assert(ClassDecl && "missing interface declaration"); 617cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff ObjCMethodDecl *Method = 0; 61885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner QualType returnType; 61989bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian if (ClassDecl->isForwardDecl()) { 62089bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian // A forward class used in messaging is tread as a 'Class' 6219f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian Diag(lbrac, diag::warn_receiver_forward_class) << ClassDecl->getDeclName(); 62289bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac)); 62389bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian if (Method) 6241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(Method->getLocation(), diag::note_method_sent_forward_class) 6259f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian << Method->getDeclName(); 62689bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian } 62789bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian if (!Method) 62817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = ClassDecl->lookupClassMethod(Sel); 6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6307c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff // If we have an implementation in scope, check "private" methods. 631f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff if (!Method) 6325609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateClassMethod(Sel, ClassDecl); 6337c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff 63448f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 63548f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true, 638637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 639637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 6404df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek 641187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson returnType = returnType.getNonReferenceType(); 6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 643a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner // FIXME: need to do a better job handling 'super' usage within a class. For 644a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner // now, we simply pass the "super" identifier through (which isn't consistent 645a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner // with instance methods. 646a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner if (isSuper) 647a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner return new (Context) ObjCMessageExpr(Context, receiverName, receiverLoc, 648a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner Sel, returnType, Method, lbrac, rbrac, 649a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner ArgExprs, NumArgs); 650a7a98c97e650545e69f4d868c95f0e3370971b0fChris Lattner 651390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // If we have the ObjCInterfaceDecl* for the class that is receiving the 652390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // message, use that to construct the ObjCMessageExpr. Otherwise pass on the 653390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // IdentifierInfo* for the class. 65415faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner return new (Context) ObjCMessageExpr(Context, ClassDecl, receiverLoc, 65515faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner Sel, returnType, Method, lbrac, rbrac, 65615faee19fdb9017dd6d08a690427b18c3b062c2dChris Lattner ArgExprs, NumArgs); 65785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 65885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner 65985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnInstanceMessage - used for both unary and keyword messages. 66085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions 66185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs(). 6621565e0364b05d163640dd2b6feed43bae67df4fdChris LattnerSema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, 6631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SourceLocation lbrac, 664ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson SourceLocation receiverLoc, 665b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner SourceLocation rbrac, 666b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner ExprTy **Args, unsigned NumArgs) { 66785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner assert(receiver && "missing receiver expression"); 6681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr **ArgExprs = reinterpret_cast<Expr **>(Args); 67085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner Expr *RExpr = static_cast<Expr *>(receiver); 6711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 672d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner // If necessary, apply function/array conversion to the receiver. 673d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner // C99 6.7.5.3p[7,8]. 674a873dfc9e7314681bb37efd9ab185045de121e43Douglas Gregor DefaultFunctionArrayLvalueConversion(RExpr); 6751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 67685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner QualType returnType; 677b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner QualType ReceiverCType = 678b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner Context.getCanonicalType(RExpr->getType()).getUnqualifiedType(); 67987d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff 680eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner#if 0 68187d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff // Handle messages to 'super'. 682279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff if (isa<ObjCSuperExpr>(RExpr)) { 68387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff ObjCMethodDecl *Method = 0; 68487d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { 68587d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff // If we have an interface in scope, check 'super' methods. 68687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) 6875609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) { 68817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = SuperDecl->lookupInstanceMethod(Sel); 6891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!Method) 6915609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // If we have implementations in scope, check "private" methods. 6925609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateInstanceMethod(Sel, SuperDecl); 6935609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff } 69487d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff } 695ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson 69648f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 69748f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 69859843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson 699077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 70087d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff lbrac, rbrac, returnType)) 70187d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff return true; 7021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 703187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson returnType = returnType.getNonReferenceType(); 704eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, 705eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek Method, lbrac, rbrac, 706eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek ArgExprs, NumArgs); 70787d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff } 708eb483eb3ee80300f15d6d13573d82493c2194461Chris Lattner#endif 70987d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff 7101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Handle messages to id. 711470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() || 712636bed1b8185099ef40a4f7fd192fc4242b385a4Fariborz Jahanian Context.isObjCNSObjectType(RExpr->getType())) { 713037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool( 714037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff Sel, SourceRange(lbrac,rbrac)); 7156e10a08fe0427ab34c463dd59d9c0997d4f72170Chris Lattner if (!Method) 716f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac, rbrac)); 7171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 718637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 719637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 720187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson returnType = returnType.getNonReferenceType(); 721eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, 722eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek Method, lbrac, rbrac, 723eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek ArgExprs, NumArgs); 724fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 726fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner // Handle messages to Class. 7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (ReceiverCType->isObjCClassType() || 728470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff ReceiverCType->isObjCQualifiedClassType()) { 7292b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner ObjCMethodDecl *Method = 0; 7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7316562fdad21432377f0cc5e0c627c28f0c85df4ddChris Lattner if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) { 732d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) { 733d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff // First check the public methods in the class interface. 73417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = ClassDecl->lookupClassMethod(Sel); 7351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 736f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff if (!Method) 7375609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateClassMethod(Sel, ClassDecl); 7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // FIXME: if we still haven't found a method, we need to look in 740470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff // protocols (if we have qualifiers). 741d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff } 74248f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 74348f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 744d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff } 7456b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (!Method) { 7466b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // If not messaging 'self', look for any factory method named 'Sel'. 7476b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff if (!isSelfExpr(RExpr)) { 748f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac)); 749b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian if (!Method) { 750041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian // If no class (factory) method was found, check if an _instance_ 751041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian // method of the same name exists in the root class only. 7526b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Method = LookupInstanceMethodInGlobalPool( 7536b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Sel, SourceRange(lbrac,rbrac)); 754041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian if (Method) 755041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian if (const ObjCInterfaceDecl *ID = 756041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) { 757041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian if (ID->getSuperClass()) 758041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian Diag(lbrac, diag::warn_root_inst_method_not_found) 759041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian << Sel << SourceRange(lbrac, rbrac); 760041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian } 761b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian } 7626b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff } 7636b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff } 764077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 765637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 766637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 767187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson returnType = returnType.getNonReferenceType(); 768eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, 769eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek Method, lbrac, rbrac, 770eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek ArgExprs, NumArgs); 771fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 7721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7732b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner ObjCMethodDecl *Method = 0; 774fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner ObjCInterfaceDecl* ClassDecl = 0; 7751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // We allow sending a message to a qualified ID ("id<foo>"), which is ok as 7772b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner // long as one of the protocols implements the selector (if not, warn). 7781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (const ObjCObjectPointerType *QIdTy = 779d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff ReceiverCType->getAsObjCQualifiedIdType()) { 780f7f52e7bf5a4dc36d45b98531e0b21e343fc19deSteve Naroff // Search protocols for instance methods. 781d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(), 782446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff E = QIdTy->qual_end(); I != E; ++I) { 783446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff ObjCProtocolDecl *PDecl = *I; 78417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel))) 785fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner break; 786ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff // Since we aren't supporting "Class<foo>", look for a class method. 78717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis if (PDecl && (Method = PDecl->lookupClassMethod(Sel))) 788ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff break; 789fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 7901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else if (const ObjCObjectPointerType *OCIType = 79114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff ReceiverCType->getAsObjCInterfacePointerType()) { 7922b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner // We allow sending a message to a pointer to an interface (an object). 7931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 79414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff ClassDecl = OCIType->getInterfaceDecl(); 795037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be 796390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // faster than the following method (which can do *many* linear searches). 797037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff // The idea is to add class info to InstanceMethodPool. 79817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis Method = ClassDecl->lookupInstanceMethod(Sel); 7991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 800fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner if (!Method) { 801fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner // Search protocol qualifiers. 80214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(), 803279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff E = OCIType->qual_end(); QI != E; ++QI) { 80417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis if ((Method = (*QI)->lookupInstanceMethod(Sel))) 80585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner break; 80685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 80785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner } 8080de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff if (!Method) { 8095609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff // If we have implementations in scope, check "private" methods. 8105609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff Method = LookupPrivateInstanceMethod(Sel, ClassDecl); 8111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8125609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (!Method && !isSelfExpr(RExpr)) { 8136b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // If we still haven't found a method, look in the global pool. This 8146b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // behavior isn't very desirable, however we need it for GCC 8156b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff // compatibility. FIXME: should we deviate?? 8165609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff if (OCIType->qual_empty()) { 8176b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Method = LookupInstanceMethodInGlobalPool( 8186b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff Sel, SourceRange(lbrac,rbrac)); 81914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff if (Method && !OCIType->getInterfaceDecl()->isForwardDecl()) 8201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(lbrac, diag::warn_maynot_respond) 8210784fcddb4a399e57248704fc202f3f5c1254018Chris Lattner << OCIType->getInterfaceDecl()->getIdentifier() << Sel; 8226b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff } 823268bc8c1f3a27d2fbd73c3115e4d633d31422ca5Fariborz Jahanian } 8240de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff } 82548f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor if (Method && DiagnoseUseOfDecl(Method, receiverLoc)) 82648f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor return true; 8270c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner } else if (!Context.getObjCIdType().isNull() && 8280c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner (ReceiverCType->isPointerType() || 8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (ReceiverCType->isIntegerType() && 8300c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner ReceiverCType->isScalarType()))) { 8310c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner // Implicitly convert integers and pointers to 'id' but emit a warning. 8328e2945ad9104f0ce4928c386faf458b6b83d9060Steve Naroff Diag(lbrac, diag::warn_bad_receiver_type) 833d162584991885ab004a02573a73ce06422b921fcChris Lattner << RExpr->getType() << RExpr->getSourceRange(); 83473c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman if (ReceiverCType->isPointerType()) 83573c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman ImpCastExprToType(RExpr, Context.getObjCIdType(), CastExpr::CK_BitCast); 83673c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman else 83773c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman ImpCastExprToType(RExpr, Context.getObjCIdType(), 83873c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman CastExpr::CK_IntegralToPointer); 8390c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner } else { 8400c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner // Reject other random receiver types (e.g. structs). 8410c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner Diag(lbrac, diag::err_bad_receiver_type) 8420c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner << RExpr->getType() << RExpr->getSourceRange(); 8432b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner return true; 844fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner } 8451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8465b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian if (Method) 8475b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian DiagnoseSentinelCalls(Method, receiverLoc, ArgExprs, NumArgs); 848077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, 849637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar lbrac, rbrac, returnType)) 850637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar return true; 851187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson returnType = returnType.getNonReferenceType(); 852eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, Method, 853eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek lbrac, rbrac, ArgExprs, NumArgs); 85485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner} 855eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner 856