SemaExprObjC.cpp revision c5e77d5a97b495c41cb65c25b6f0ba2b62a14345
185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//                     The LLVM Compiler Infrastructure
485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// This file is distributed under the University of Illinois Open Source
685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// License. See LICENSE.TXT for details.
785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//  This file implements semantic analysis for Objective-C expressions.
1185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
1385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
1485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "Sema.h"
1585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/ASTContext.h"
1685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/DeclObjC.h"
17f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h"
1839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner#include "llvm/ADT/SmallString.h"
1961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff#include "clang/Lex/Preprocessor.h"
2061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
2185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattnerusing namespace clang;
2285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
231eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpSema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
2439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                                              ExprTy **strings,
2585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                              unsigned NumStrings) {
2639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
2739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
28f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // Most ObjC strings are formed out of a single piece.  However, we *can*
29f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // have strings formed out of multiple @ strings with multiple pptokens in
30f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
31f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // StringLiteral for ObjCStringLiteral to hold onto.
3239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral *S = Strings[0];
331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // If we have a multi-part string, merge it all together.
35f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  if (NumStrings != 1) {
3685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    // Concatenate objc strings.
3739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallString<128> StrBuf;
3839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallVector<SourceLocation, 8> StrLocs;
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    for (unsigned i = 0; i != NumStrings; ++i) {
4139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      S = Strings[i];
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // ObjC strings can't be wide.
44f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      if (S->isWide()) {
45f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant)
46f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner          << S->getSourceRange();
47f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        return true;
48f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      }
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the string data.
5139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the locations of the string tokens.
5439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrLocs.append(S->tokloc_begin(), S->tokloc_end());
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Free the temporary string.
578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek      S->Destroy(Context);
5885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // Create the aggregate string with the appropriate content and location
6139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // information.
6239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false,
632085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner                              Context.getPointerType(Context.CharTy),
6439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                              &StrLocs[0], StrLocs.size());
6585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  // Verify that this composite string is acceptable for ObjC strings.
68690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  if (CheckObjCString(S))
6985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
70a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner
71a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  // Initialize the constant string interface lazily. This assumes
72d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // the NSString interface is seen in this translation unit. Note: We
73d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // don't use NSConstantString, since the runtime team considers this
74d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // interface private (even though it appears in the header files).
75a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCConstantStringInterface();
76a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (!Ty.isNull()) {
7714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    Ty = Context.getObjCObjectPointerType(Ty);
7813fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  } else {
79d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
80f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, LookupOrdinaryName);
81a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
82a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Context.setObjCConstantStringInterface(StrIF);
83a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCConstantStringInterface();
8414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      Ty = Context.getObjCObjectPointerType(Ty);
85a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    } else {
86d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff      // If there is no NSString interface defined then treat constant
87a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      // strings as untyped objects and let the runtime figure it out later.
88a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCIdType();
89a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    }
9013fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  }
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
9385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
9485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
951eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpExpr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
96fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                      QualType EncodedType,
97fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                      SourceLocation RParenLoc) {
98fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  QualType StrTy;
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (EncodedType->isDependentType())
100fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    StrTy = Context.DependentTy;
101fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  else {
102fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    std::string Str;
103fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    Context.getObjCEncodingForType(EncodedType, Str);
104fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson
105fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    // The type of @encode is the same as the type of the corresponding string,
106fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    // which is an array type.
107fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    StrTy = Context.CharTy;
108fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
109fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    if (getLangOptions().CPlusPlus)
110fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson      StrTy.addConst();
111fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson    StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
112fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                         ArrayType::Normal, 0);
113fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  }
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
115fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
116fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson}
117fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson
11885a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
11985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                 SourceLocation EncodeLoc,
12085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                 SourceLocation LParenLoc,
121a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner                                                 TypeTy *ty,
12285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                 SourceLocation RParenLoc) {
123e8661906d49ef6c9694a9cc845ca62a85dbc016dArgyrios Kyrtzidis  // FIXME: Preserve type source info ?
124e8661906d49ef6c9694a9cc845ca62a85dbc016dArgyrios Kyrtzidis  QualType EncodedType = GetTypeFromParser(ty);
12585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
126fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc);
12785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
12885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
12985a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
13085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation AtLoc,
13185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation SelLoc,
13285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation LParenLoc,
13385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation RParenLoc) {
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
135835ed7f15bd8a89226fd7976d96be19995f1c1c8Fariborz Jahanian                             SourceRange(LParenLoc, RParenLoc), false);
1367ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  if (!Method)
1377ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian    Method = LookupFactoryMethodInGlobalPool(Sel,
1387ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian                                          SourceRange(LParenLoc, RParenLoc));
1397ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  if (!Method)
1407ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian    Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1417ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian
142a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCSelType();
1436d5a1c28593443f3973ef38f8fa042d59182412dDaniel Dunbar  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
14485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
14585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
14685a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
14785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation AtLoc,
14885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation ProtoLoc,
14985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation LParenLoc,
15085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation RParenLoc) {
1516e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor  ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId);
15285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  if (!PDecl) {
1533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
15485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
15585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCProtoType();
158a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (Ty.isNull())
15985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
16014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  Ty = Context.getObjCObjectPointerType(Ty);
161a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
16285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
16385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpbool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     Selector Sel, ObjCMethodDecl *Method,
166077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner                                     bool isClassMessage,
167637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                     SourceLocation lbrac, SourceLocation rbrac,
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     QualType &ReturnType) {
169637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  if (!Method) {
1706660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    // Apply default argument promotion as for (C99 6.5.2.2p6).
1716660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    for (unsigned i = 0; i != NumArgs; i++)
1726660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar      DefaultArgumentPromotion(Args[i]);
1736660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar
174077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
175077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner                                       diag::warn_inst_method_not_found;
176077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    Diag(lbrac, DiagID)
177077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner      << Sel << isClassMessage << SourceRange(lbrac, rbrac);
178637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    ReturnType = Context.getObjCIdType();
179637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return false;
180637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  }
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
182077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  ReturnType = Method->getResultType();
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  unsigned NumNamedArgs = Sel.getNumArgs();
18591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
18691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
187312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  bool IsError = false;
18891e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  for (unsigned i = 0; i < NumNamedArgs; i++) {
18985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    Expr *argExpr = Args[i];
19085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19289951a86b594513c2a013532ed45d197413b1087Chris Lattner    QualType lhsType = Method->param_begin()[i]->getType();
19385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    QualType rhsType = argExpr->getType();
19485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
196987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner    if (lhsType->isArrayType())
197987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner      lhsType = Context.getArrayDecayedType(lhsType);
19885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    else if (lhsType->isFunctionType())
19985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      lhsType = Context.getPointerType(lhsType);
20085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    AssignConvertType Result =
202987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner      CheckSingleAssignmentConstraints(lhsType, argExpr);
20385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    if (Args[i] != argExpr) // The expression was converted.
20485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      Args[i] = argExpr; // Make sure we store the converted expression.
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    IsError |=
20785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
2086864748fc9a780e6db0bb5a7bd20aa889882dc94Douglas Gregor                               argExpr, AA_Sending);
20985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
21091e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
21191e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  // Promote additional arguments to variadic methods.
21291e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  if (Method->isVariadic()) {
213dce5e2cabf07ff25eb4d9e1859c0a21c69f588d2Anders Carlsson    for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
214312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
21591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  } else {
21691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    // Check for extra arguments to non-variadic methods.
21791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    if (NumArgs != NumNamedArgs) {
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Diag(Args[NumNamedArgs]->getLocStart(),
219fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner           diag::err_typecheck_call_too_many_args)
2202c21a073525cdfa68e4439b7af551385dc2796abChris Lattner        << 2 /*method*/ << Method->getSourceRange()
221fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << SourceRange(Args[NumNamedArgs]->getLocStart(),
222fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner                       Args[NumArgs-1]->getLocEnd());
22391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    }
22491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  }
22591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
226312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  return IsError;
22785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
22885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
2296b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroffbool Sema::isSelfExpr(Expr *RExpr) {
2306b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr))
2316b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
2326b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      return true;
2336b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff  return false;
2346b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff}
2356b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
236f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Helper method for ActOnClassMethod/ActOnInstanceMethod.
237f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Will search "local" class/category implementations for a method decl.
238175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian// If failed, then we search in class's root for an instance method.
239f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Returns 0 if no method is found.
2405609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
241f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff                                          ObjCInterfaceDecl *ClassDecl) {
242f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  ObjCMethodDecl *Method = 0;
2435609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  // lookup in class and all superclasses
2445609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
24587018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
24617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ImpDecl->getClassMethod(Sel);
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2485609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
2491cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis    if (!Method)
2501cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis      Method = ClassDecl->getCategoryClassMethod(Sel);
2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2525609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Before we give up, check if the selector is an instance method.
2535609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // But only in the root. This matches gcc's behaviour and what the
2545609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // runtime expects.
2555609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method && !ClassDecl->getSuperClass()) {
25617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ClassDecl->lookupInstanceMethod(Sel);
2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // Look through local category implementations associated
2585609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // with the root class.
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (!Method)
2605609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
261f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff    }
2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2635609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
264f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  }
2655609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  return Method;
2665609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff}
2675609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2685609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
2695609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff                                              ObjCInterfaceDecl *ClassDecl) {
2705609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  ObjCMethodDecl *Method = 0;
2715609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
2725609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // If we have implementations in scope, check "private" methods.
27387018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
27417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ImpDecl->getInstanceMethod(Sel);
2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2765609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
2771cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis    if (!Method)
2781cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis      Method = ClassDecl->getCategoryInstanceMethod(Sel);
2795609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
280175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian  }
281f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  return Method;
282f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff}
283f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff
28461f72cbd037e58f12cfe90cd442373f44092f030Steve NaroffAction::OwningExprResult Sema::ActOnClassPropertyRefExpr(
28561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  IdentifierInfo &receiverName,
28661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  IdentifierInfo &propertyName,
28761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  SourceLocation &receiverNameLoc,
28861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  SourceLocation &propertyNameLoc) {
2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
290f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor  IdentifierInfo *receiverNamePtr = &receiverName;
291f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr);
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Search for a declared property first.
2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
29617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
29761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
29861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // If this reference is in an @implementation, check for 'private' methods.
29961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Getter)
30061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
30161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
30287018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
30317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Getter = ImpDecl->getClassMethod(Sel);
30461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
30561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter) {
30661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // FIXME: refactor/share with ActOnMemberReference().
30761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // Check if we can reference this property.
30861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
30961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      return ExprError();
31061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look for the matching setter, in case it is needed.
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Selector SetterSel =
3141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SelectorTable::constructSetterName(PP.getIdentifierTable(),
315fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                       PP.getSelectorTable(), &propertyName);
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
31861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Setter) {
31961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // If this reference is in an @implementation, also check for 'private'
32061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // methods.
32161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
32261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
32387018775ed689d0a67357cf767747166044b3a27Argyrios Kyrtzidis        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
32417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Setter = ImpDecl->getClassMethod(SetterSel);
32561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
32661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look through local category implementations associated with the class.
3271cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis  if (!Setter)
3281cb35dd4840d21cec58648361180d5688446a9caArgyrios Kyrtzidis    Setter = IFace->getCategoryClassMethod(SetterSel);
32961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
33061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
33161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    return ExprError();
33261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
33361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter || Setter) {
33461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    QualType PType;
33561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
33661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (Getter)
33761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      PType = Getter->getResultType();
33861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    else {
33961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
34061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff           E = Setter->param_end(); PI != E; ++PI)
34161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff        PType = (*PI)->getType();
34261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    }
34309105f52b1f28cbb1374c27c3c70f5517e2c465dFariborz Jahanian    return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(
3441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                  Getter, PType, Setter,
34561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                                  propertyNameLoc, IFace, receiverNameLoc));
34661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
34761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
34861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                     << &propertyName << Context.getObjCInterfaceType(IFace));
34961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff}
35061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
35161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
35285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnClassMessage - used for both unary and keyword messages.
35385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions
35485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs().
35585a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ActOnClassMessage(
35685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Scope *S,
35785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  IdentifierInfo *receiverName, Selector Sel,
358ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson  SourceLocation lbrac, SourceLocation receiverLoc,
3591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  SourceLocation selectorLoc, SourceLocation rbrac,
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExprTy **Args, unsigned NumArgs) {
36185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  assert(receiverName && "missing receiver class name");
36285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
36385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
364a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl* ClassDecl = 0;
365fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff  bool isSuper = false;
3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3678469265156c6344fa1100a6a7bf6349acc187d9fChris Lattner  if (receiverName->isStr("super")) {
3685cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    if (getCurMethodDecl()) {
3695cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      isSuper = true;
3704b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      ObjCInterfaceDecl *OID = getCurMethodDecl()->getClassInterface();
3714b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      if (!OID)
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return Diag(lbrac, diag::error_no_super_class_message)
3734b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian                      << getCurMethodDecl()->getDeclName();
3744b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      ClassDecl = OID->getSuperClass();
3755cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      if (!ClassDecl)
3764b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian        return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName();
377f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor      if (getCurMethodDecl()->isInstanceMethod()) {
3785cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        QualType superTy = Context.getObjCInterfaceType(ClassDecl);
37914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        superTy = Context.getObjCObjectPointerType(superTy);
3808189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(),
3818189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                                              superTy);
3825cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        // We are really in an instance method, redirect.
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
384ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                    selectorLoc, rbrac, Args, NumArgs);
3855cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      }
3865cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // We are sending a message to 'super' within a class method. Do nothing,
3875cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // the receiver will pass through as 'super' (how convenient:-).
3885cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    } else {
3895cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // 'super' has been used outside a method context. If a variable named
3905cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // 'super' has been declared, redirect. If not, produce a diagnostic.
391f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall      NamedDecl *SuperDecl
392f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall        = LookupSingleName(S, receiverName, LookupOrdinaryName);
3935cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
3945cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      if (VD) {
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(),
3968189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                                            receiverLoc);
3975cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        // We are really in an instance method, redirect.
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
399ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                    selectorLoc, rbrac, Args, NumArgs);
4005cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      }
401e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian      else if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(SuperDecl)) {
402e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian        const ObjCInterfaceType *OCIT;
403e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian        OCIT = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>();
404e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian        if (!OCIT) {
405e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian          Diag(receiverLoc, diag::err_invalid_receiver_to_message);
406e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian          return true;
407e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian        }
408e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian        ClassDecl = OCIT->getDecl();
409e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian      }
410e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian      else
411e4fb82839a762e632f63e195058015e2f1ca27a8Fariborz Jahanian        return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName;
4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
41385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  } else
414f06cdae9c68dfc4191fbf6b9e5ea0fd748488d88Douglas Gregor    ClassDecl = getObjCInterfaceDecl(receiverName, receiverLoc);
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4167c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // The following code allows for the following GCC-ism:
417cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
418cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  typedef XCElementDisplayRect XCElementGraphicsRect;
419cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
420cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  @implementation XCRASlice
421cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  - whatever { // Note that XCElementGraphicsRect is a typedef name.
422cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //    _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
423cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  }
424cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
4257c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // If necessary, the following lookup could move to getObjCInterfaceDecl().
4267c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  if (!ClassDecl) {
427f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall    NamedDecl *IDecl
428f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall      = LookupSingleName(TUScope, receiverName, LookupOrdinaryName);
429c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor    if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl))
430c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor      if (const ObjCInterfaceType *OCIT
431c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor                      = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>())
432c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor        ClassDecl = OCIT->getDecl();
433c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor
434c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor    if (!ClassDecl) {
435c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor      Diag(receiverLoc, diag::err_invalid_receiver_to_message);
436c5e77d5a97b495c41cb65c25b6f0ba2b62a14345Douglas Gregor      return true;
4377c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff    }
4387c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  }
4397c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  assert(ClassDecl && "missing interface declaration");
440cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  ObjCMethodDecl *Method = 0;
44185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  QualType returnType;
44289bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian  if (ClassDecl->isForwardDecl()) {
44389bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian    // A forward class used in messaging is tread as a 'Class'
4449f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian    Diag(lbrac, diag::warn_receiver_forward_class) << ClassDecl->getDeclName();
44589bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian    Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
44689bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian    if (Method)
4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Diag(Method->getLocation(), diag::note_method_sent_forward_class)
4489f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian        << Method->getDeclName();
44989bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian  }
45089bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian  if (!Method)
45117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    Method = ClassDecl->lookupClassMethod(Sel);
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4537c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // If we have an implementation in scope, check "private" methods.
454f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  if (!Method)
4555609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    Method = LookupPrivateClassMethod(Sel, ClassDecl);
4567c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff
45748f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor  if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
45848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    return true;
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true,
461637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
462637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
4634df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek
464187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson  returnType = returnType.getNonReferenceType();
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
466390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // If we have the ObjCInterfaceDecl* for the class that is receiving the
467390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // message, use that to construct the ObjCMessageExpr.  Otherwise pass on the
468390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // IdentifierInfo* for the class.
469390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: need to do a better job handling 'super' usage within a class.  For
470390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // now, we simply pass the "super" identifier through (which isn't consistent
471390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // with instance methods.
4727c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  if (isSuper)
473eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek    return new (Context) ObjCMessageExpr(Context, receiverName, Sel, returnType,
474eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         Method, lbrac, rbrac, ArgExprs,
475eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         NumArgs);
4764df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek  else
477eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek    return new (Context) ObjCMessageExpr(Context, ClassDecl, Sel, returnType,
478eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         Method, lbrac, rbrac, ArgExprs,
479eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         NumArgs);
48085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
48185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
48285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnInstanceMessage - used for both unary and keyword messages.
48385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions
48485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs().
4851565e0364b05d163640dd2b6feed43bae67df4fdChris LattnerSema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                            SourceLocation lbrac,
487ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                            SourceLocation receiverLoc,
488b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            SourceLocation rbrac,
489b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            ExprTy **Args, unsigned NumArgs) {
49085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  assert(receiver && "missing receiver expression");
4911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
49385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr *RExpr = static_cast<Expr *>(receiver);
4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
495d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  // If necessary, apply function/array conversion to the receiver.
496d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  // C99 6.7.5.3p[7,8].
497a873dfc9e7314681bb37efd9ab185045de121e43Douglas Gregor  DefaultFunctionArrayLvalueConversion(RExpr);
4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  QualType returnType;
500b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  QualType ReceiverCType =
501b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner    Context.getCanonicalType(RExpr->getType()).getUnqualifiedType();
50287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
50387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  // Handle messages to 'super'.
504279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff  if (isa<ObjCSuperExpr>(RExpr)) {
50587d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    ObjCMethodDecl *Method = 0;
50687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
50787d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      // If we have an interface in scope, check 'super' methods.
50887d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
5095609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
51017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Method = SuperDecl->lookupInstanceMethod(Sel);
5111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          if (!Method)
5135609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff            // If we have implementations in scope, check "private" methods.
5145609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff            Method = LookupPrivateInstanceMethod(Sel, SuperDecl);
5155609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        }
51687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    }
517ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson
51848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
51948f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
52059843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson
521077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
52287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff                                  lbrac, rbrac, returnType))
52387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      return true;
5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
525187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson    returnType = returnType.getNonReferenceType();
526eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
527eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         Method, lbrac, rbrac,
528eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         ArgExprs, NumArgs);
52987d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  }
53087d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Handle messages to id.
532470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff  if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() ||
533636bed1b8185099ef40a4f7fd192fc4242b385a4Fariborz Jahanian      Context.isObjCNSObjectType(RExpr->getType())) {
534037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
535037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff                               Sel, SourceRange(lbrac,rbrac));
5366e10a08fe0427ab34c463dd59d9c0997d4f72170Chris Lattner    if (!Method)
537f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor      Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac, rbrac));
5381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
539637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
540637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
541187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson    returnType = returnType.getNonReferenceType();
542eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
543eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         Method, lbrac, rbrac,
544eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         ArgExprs, NumArgs);
545fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
547fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  // Handle messages to Class.
5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (ReceiverCType->isObjCClassType() ||
549470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff      ReceiverCType->isObjCQualifiedClassType()) {
5502b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    ObjCMethodDecl *Method = 0;
5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5526562fdad21432377f0cc5e0c627c28f0c85df4ddChris Lattner    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
553d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
554d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff        // First check the public methods in the class interface.
55517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis        Method = ClassDecl->lookupClassMethod(Sel);
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
557f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff        if (!Method)
5585609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          Method = LookupPrivateClassMethod(Sel, ClassDecl);
5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // FIXME: if we still haven't found a method, we need to look in
561470301bac9c8abfc6b451b3b669c6695a9fd1518Steve Naroff        // protocols (if we have qualifiers).
562d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      }
56348f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
56448f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor        return true;
565d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff    }
5666b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (!Method) {
5676b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      // If not messaging 'self', look for any factory method named 'Sel'.
5686b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      if (!isSelfExpr(RExpr)) {
569f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor        Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
570b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        if (!Method) {
571041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          // If no class (factory) method was found, check if an _instance_
572041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          // method of the same name exists in the root class only.
5736b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
5746b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                                   Sel, SourceRange(lbrac,rbrac));
575041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          if (Method)
576041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian              if (const ObjCInterfaceDecl *ID =
577041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
578041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian              if (ID->getSuperClass())
579041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                Diag(lbrac, diag::warn_root_inst_method_not_found)
580041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                  << Sel << SourceRange(lbrac, rbrac);
581041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian            }
582b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        }
5836b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      }
5846b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    }
585077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
586637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
587637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
588187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson    returnType = returnType.getNonReferenceType();
589eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
590eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         Method, lbrac, rbrac,
591eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                         ArgExprs, NumArgs);
592fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5942b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  ObjCMethodDecl *Method = 0;
595fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  ObjCInterfaceDecl* ClassDecl = 0;
5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
5982b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // long as one of the protocols implements the selector (if not, warn).
5991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (const ObjCObjectPointerType *QIdTy =
600d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff        ReceiverCType->getAsObjCQualifiedIdType()) {
601f7f52e7bf5a4dc36d45b98531e0b21e343fc19deSteve Naroff    // Search protocols for instance methods.
602d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
603446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff         E = QIdTy->qual_end(); I != E; ++I) {
604446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff      ObjCProtocolDecl *PDecl = *I;
60517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
606fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner        break;
607ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff      // Since we aren't supporting "Class<foo>", look for a class method.
60817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
609ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff        break;
610fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    }
6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  } else if (const ObjCObjectPointerType *OCIType =
61214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff                ReceiverCType->getAsObjCInterfacePointerType()) {
6132b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    // We allow sending a message to a pointer to an interface (an object).
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    ClassDecl = OCIType->getInterfaceDecl();
616037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
617390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // faster than the following method (which can do *many* linear searches).
618037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // The idea is to add class info to InstanceMethodPool.
61917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    Method = ClassDecl->lookupInstanceMethod(Sel);
6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
621fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    if (!Method) {
622fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      // Search protocol qualifiers.
62314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
624279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff           E = OCIType->qual_end(); QI != E; ++QI) {
62517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis        if ((Method = (*QI)->lookupInstanceMethod(Sel)))
62685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner          break;
62785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      }
62885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
6290de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    if (!Method) {
6305609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // If we have implementations in scope, check "private" methods.
6315609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
6321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6335609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      if (!Method && !isSelfExpr(RExpr)) {
6346b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // If we still haven't found a method, look in the global pool. This
6356b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // behavior isn't very desirable, however we need it for GCC
6366b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // compatibility. FIXME: should we deviate??
6375609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (OCIType->qual_empty()) {
6386b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
6396b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                               Sel, SourceRange(lbrac,rbrac));
64014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Diag(lbrac, diag::warn_maynot_respond)
64214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff              << OCIType->getInterfaceDecl()->getIdentifier()->getName() << Sel;
6436b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        }
644268bc8c1f3a27d2fbd73c3115e4d633d31422ca5Fariborz Jahanian      }
6450de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    }
64648f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
64748f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
6480c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else if (!Context.getObjCIdType().isNull() &&
6490c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner             (ReceiverCType->isPointerType() ||
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              (ReceiverCType->isIntegerType() &&
6510c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner               ReceiverCType->isScalarType()))) {
6520c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Implicitly convert integers and pointers to 'id' but emit a warning.
6538e2945ad9104f0ce4928c386faf458b6b83d9060Steve Naroff    Diag(lbrac, diag::warn_bad_receiver_type)
654d162584991885ab004a02573a73ce06422b921fcChris Lattner      << RExpr->getType() << RExpr->getSourceRange();
65573c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman    if (ReceiverCType->isPointerType())
65673c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman      ImpCastExprToType(RExpr, Context.getObjCIdType(), CastExpr::CK_BitCast);
65773c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman    else
65873c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman      ImpCastExprToType(RExpr, Context.getObjCIdType(),
65973c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman                        CastExpr::CK_IntegralToPointer);
6600c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else {
6610c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Reject other random receiver types (e.g. structs).
6620c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    Diag(lbrac, diag::err_bad_receiver_type)
6630c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner      << RExpr->getType() << RExpr->getSourceRange();
6642b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    return true;
665fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6675b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian  if (Method)
6685b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian    DiagnoseSentinelCalls(Method, receiverLoc, ArgExprs, NumArgs);
669077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
670637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
671637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
672187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson  returnType = returnType.getNonReferenceType();
673eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek  return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, Method,
674eb3b324800598cc3d5385fbad95ae5cff2c79113Ted Kremenek                                       lbrac, rbrac, ArgExprs, NumArgs);
67585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
676eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
677