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