SemaExprObjC.cpp revision 14108da7f7fc059772711e4ffee1322a27b152a7
185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//                     The LLVM Compiler Infrastructure
485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// This file is distributed under the University of Illinois Open Source
685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// License. See LICENSE.TXT for details.
785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//  This file implements semantic analysis for Objective-C expressions.
1185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
1385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
1485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "Sema.h"
1585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/ASTContext.h"
1685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/DeclObjC.h"
17f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h"
1839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner#include "llvm/ADT/SmallString.h"
1961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff#include "clang/Lex/Preprocessor.h"
2061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
2185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattnerusing namespace clang;
2285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
2385a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
2439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                                              ExprTy **strings,
2585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                              unsigned NumStrings) {
2639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
2739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
28f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // Most ObjC strings are formed out of a single piece.  However, we *can*
29f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // have strings formed out of multiple @ strings with multiple pptokens in
30f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
31f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // StringLiteral for ObjCStringLiteral to hold onto.
3239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral *S = Strings[0];
33f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner
34f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // If we have a multi-part string, merge it all together.
35f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  if (NumStrings != 1) {
3685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    // Concatenate objc strings.
3739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallString<128> StrBuf;
3839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallVector<SourceLocation, 8> StrLocs;
39726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner
40726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    for (unsigned i = 0; i != NumStrings; ++i) {
4139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      S = Strings[i];
4239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
4339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // ObjC strings can't be wide.
44f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      if (S->isWide()) {
45f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant)
46f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner          << S->getSourceRange();
47f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        return true;
48f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      }
49f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner
5039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the string data.
5139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
5239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
5339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the locations of the string tokens.
5439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrLocs.append(S->tokloc_begin(), S->tokloc_end());
5539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
5639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Free the temporary string.
578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek      S->Destroy(Context);
5885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
5939c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
6039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // Create the aggregate string with the appropriate content and location
6139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // information.
6239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false,
632085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner                              Context.getPointerType(Context.CharTy),
6439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                              &StrLocs[0], StrLocs.size());
6585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
6685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
67690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  // Verify that this composite string is acceptable for ObjC strings.
68690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  if (CheckObjCString(S))
6985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
70a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner
71a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  // Initialize the constant string interface lazily. This assumes
72d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // the NSString interface is seen in this translation unit. Note: We
73d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // don't use NSConstantString, since the runtime team considers this
74d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // interface private (even though it appears in the header files).
75a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCConstantStringInterface();
76a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (!Ty.isNull()) {
7714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    Ty = Context.getObjCObjectPointerType(Ty);
7813fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  } else {
79d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
80a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    NamedDecl *IF = LookupName(TUScope, NSIdent, LookupOrdinaryName);
81a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
82a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Context.setObjCConstantStringInterface(StrIF);
83a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCConstantStringInterface();
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  }
91a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner
92f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
9385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
9485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
95fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders CarlssonExpr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
96fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                      QualType EncodedType,
97fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson                                      SourceLocation RParenLoc) {
98fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  QualType StrTy;
99fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  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  }
114fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson
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) {
123a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType EncodedType = QualType::getFromOpaquePtr(ty);
12485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
125fc0f021b492cf28ee7b3a6bd4445ae569e6f15deAnders Carlsson  return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc);
12685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
12785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
12885a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
12985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation AtLoc,
13085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation SelLoc,
13185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation LParenLoc,
13285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation RParenLoc) {
1337ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
1347ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian                             SourceRange(LParenLoc, RParenLoc));
1357ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  if (!Method)
1367ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian    Method = LookupFactoryMethodInGlobalPool(Sel,
1377ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian                                          SourceRange(LParenLoc, RParenLoc));
1387ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian  if (!Method)
1397ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian    Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
1407ff22ded2221f442b1f8ff78172938d04ec8c926Fariborz Jahanian
141a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCSelType();
142a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
14385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
14485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
14585a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
14685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation AtLoc,
14785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation ProtoLoc,
14885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation LParenLoc,
14985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation RParenLoc) {
1506e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor  ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId);
15185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  if (!PDecl) {
1523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
15385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
15485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
15585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
156a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCProtoType();
157a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (Ty.isNull())
15885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
15914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  Ty = Context.getObjCObjectPointerType(Ty);
160a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
16185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
16285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
16391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbarbool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
16491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar                                     Selector Sel, ObjCMethodDecl *Method,
165077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner                                     bool isClassMessage,
166637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                     SourceLocation lbrac, SourceLocation rbrac,
167637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                     QualType &ReturnType) {
168637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  if (!Method) {
1696660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    // Apply default argument promotion as for (C99 6.5.2.2p6).
1706660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    for (unsigned i = 0; i != NumArgs; i++)
1716660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar      DefaultArgumentPromotion(Args[i]);
1726660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar
173077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
174077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner                                       diag::warn_inst_method_not_found;
175077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    Diag(lbrac, DiagID)
176077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner      << Sel << isClassMessage << SourceRange(lbrac, rbrac);
177637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    ReturnType = Context.getObjCIdType();
178637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return false;
179637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  }
180077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner
181077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  ReturnType = Method->getResultType();
182637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar
18391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  unsigned NumNamedArgs = Sel.getNumArgs();
18491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
18591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
186312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  bool IsError = false;
18791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  for (unsigned i = 0; i < NumNamedArgs; i++) {
18885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    Expr *argExpr = Args[i];
18985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
19085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
19189951a86b594513c2a013532ed45d197413b1087Chris Lattner    QualType lhsType = Method->param_begin()[i]->getType();
19285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    QualType rhsType = argExpr->getType();
19385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
19485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
195987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner    if (lhsType->isArrayType())
196987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner      lhsType = Context.getArrayDecayedType(lhsType);
19785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    else if (lhsType->isFunctionType())
19885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      lhsType = Context.getPointerType(lhsType);
19985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
200987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner    AssignConvertType Result =
201987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner      CheckSingleAssignmentConstraints(lhsType, argExpr);
20285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    if (Args[i] != argExpr) // The expression was converted.
20385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      Args[i] = argExpr; // Make sure we store the converted expression.
20485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
205312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner    IsError |=
20685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
20785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                               argExpr, "sending");
20885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
20991e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
21091e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  // Promote additional arguments to variadic methods.
21191e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  if (Method->isVariadic()) {
212dce5e2cabf07ff25eb4d9e1859c0a21c69f588d2Anders Carlsson    for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
213312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
21491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  } else {
21591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    // Check for extra arguments to non-variadic methods.
21691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    if (NumArgs != NumNamedArgs) {
21791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar      Diag(Args[NumNamedArgs]->getLocStart(),
218fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner           diag::err_typecheck_call_too_many_args)
2192c21a073525cdfa68e4439b7af551385dc2796abChris Lattner        << 2 /*method*/ << Method->getSourceRange()
220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << SourceRange(Args[NumNamedArgs]->getLocStart(),
221fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner                       Args[NumArgs-1]->getLocEnd());
22291e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    }
22391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  }
22491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
225312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  return IsError;
22685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
22785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
2286b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroffbool Sema::isSelfExpr(Expr *RExpr) {
2296b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr))
2306b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
2316b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      return true;
2326b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff  return false;
2336b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff}
2346b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
235f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Helper method for ActOnClassMethod/ActOnInstanceMethod.
236f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Will search "local" class/category implementations for a method decl.
237175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian// If failed, then we search in class's root for an instance method.
238f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Returns 0 if no method is found.
2395609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
240f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff                                          ObjCInterfaceDecl *ClassDecl) {
241f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  ObjCMethodDecl *Method = 0;
2425609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  // lookup in class and all superclasses
2435609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
2448fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor    if (ObjCImplementationDecl *ImpDecl
2458fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor          = LookupObjCImplementation(ClassDecl->getIdentifier()))
24617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ImpDecl->getClassMethod(Sel);
247f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff
2485609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
2495609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method) {
2505609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
2515609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
25217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
2535609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      }
2545609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    }
2555609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2565609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Before we give up, check if the selector is an instance method.
2575609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // But only in the root. This matches gcc's behaviour and what the
2585609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // runtime expects.
2595609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method && !ClassDecl->getSuperClass()) {
26017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ClassDecl->lookupInstanceMethod(Sel);
2615609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // Look through local category implementations associated
2625609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // with the root class.
2635609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      if (!Method)
2645609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
265f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff    }
2665609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2675609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
268f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  }
2695609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  return Method;
2705609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff}
2715609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2725609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
2735609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff                                              ObjCInterfaceDecl *ClassDecl) {
2745609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  ObjCMethodDecl *Method = 0;
2755609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
2765609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // If we have implementations in scope, check "private" methods.
2778fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor    if (ObjCImplementationDecl *ImpDecl
2788fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor          = LookupObjCImplementation(ClassDecl->getIdentifier()))
27917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      Method = ImpDecl->getInstanceMethod(Sel);
2805609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2815609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
2825609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method) {
2835609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
2845609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
28517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
2865609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      }
2875609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    }
2885609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
289175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian  }
290f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  return Method;
291f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff}
292f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff
29361f72cbd037e58f12cfe90cd442373f44092f030Steve NaroffAction::OwningExprResult Sema::ActOnClassPropertyRefExpr(
29461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  IdentifierInfo &receiverName,
29561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  IdentifierInfo &propertyName,
29661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  SourceLocation &receiverNameLoc,
29761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  SourceLocation &propertyNameLoc) {
29861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
29961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(&receiverName);
30061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
30161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Search for a declared property first.
30261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
30361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
30417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
30561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
30661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // If this reference is in an @implementation, check for 'private' methods.
30761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Getter)
30861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
30961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
3108fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor        if (ObjCImplementationDecl *ImpDecl
3118fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor              = LookupObjCImplementation(ClassDecl->getIdentifier()))
31217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Getter = ImpDecl->getClassMethod(Sel);
31361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
31461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter) {
31561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // FIXME: refactor/share with ActOnMemberReference().
31661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // Check if we can reference this property.
31761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
31861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      return ExprError();
31961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
32061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
32161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look for the matching setter, in case it is needed.
322fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff  Selector SetterSel =
323fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff    SelectorTable::constructSetterName(PP.getIdentifierTable(),
324fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                       PP.getSelectorTable(), &propertyName);
32561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
32617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
32761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Setter) {
32861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // If this reference is in an @implementation, also check for 'private'
32961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // methods.
33061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
33161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
3328fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor        if (ObjCImplementationDecl *ImpDecl
3338fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor              = LookupObjCImplementation(ClassDecl->getIdentifier()))
33417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis          Setter = ImpDecl->getClassMethod(SetterSel);
33561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
33661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look through local category implementations associated with the class.
33761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Setter) {
33861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
33961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
34017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis        Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
34161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    }
34261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
34361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
34461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
34561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    return ExprError();
34661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
34761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter || Setter) {
34861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    QualType PType;
34961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
35061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (Getter)
35161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      PType = Getter->getResultType();
35261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    else {
35361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
35461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff           E = Setter->param_end(); PI != E; ++PI)
35561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff        PType = (*PI)->getType();
35661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    }
35761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    return Owned(new (Context) ObjCKVCRefExpr(Getter, PType, Setter,
35861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                                  propertyNameLoc, IFace, receiverNameLoc));
35961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
36061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
36161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                     << &propertyName << Context.getObjCInterfaceType(IFace));
36261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff}
36361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
36461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
36585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnClassMessage - used for both unary and keyword messages.
36685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions
36785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs().
36885a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ActOnClassMessage(
36985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Scope *S,
37085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  IdentifierInfo *receiverName, Selector Sel,
371ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson  SourceLocation lbrac, SourceLocation receiverLoc,
372ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson  SourceLocation selectorLoc, SourceLocation rbrac,
3735cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff  ExprTy **Args, unsigned NumArgs)
37485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner{
37585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  assert(receiverName && "missing receiver class name");
37685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
37785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
378a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl* ClassDecl = 0;
379fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff  bool isSuper = false;
380fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff
3818469265156c6344fa1100a6a7bf6349acc187d9fChris Lattner  if (receiverName->isStr("super")) {
3825cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    if (getCurMethodDecl()) {
3835cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      isSuper = true;
3844b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      ObjCInterfaceDecl *OID = getCurMethodDecl()->getClassInterface();
3854b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      if (!OID)
3864b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian        return Diag(lbrac, diag::error_no_super_class_message)
3874b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian                      << getCurMethodDecl()->getDeclName();
3884b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      ClassDecl = OID->getSuperClass();
3895cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      if (!ClassDecl)
3904b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian        return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName();
391f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor      if (getCurMethodDecl()->isInstanceMethod()) {
3925cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        QualType superTy = Context.getObjCInterfaceType(ClassDecl);
39314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        superTy = Context.getObjCObjectPointerType(superTy);
3948189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(),
3958189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                                              superTy);
3965cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        // We are really in an instance method, redirect.
397ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
398ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                    selectorLoc, rbrac, Args, NumArgs);
3995cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      }
4005cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // We are sending a message to 'super' within a class method. Do nothing,
4015cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // the receiver will pass through as 'super' (how convenient:-).
4025cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    } else {
4035cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // 'super' has been used outside a method context. If a variable named
4045cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // 'super' has been declared, redirect. If not, produce a diagnostic.
40547b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor      NamedDecl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName);
4065cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
4075cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      if (VD) {
4088189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(),
4098189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                                            receiverLoc);
4105cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        // We are really in an instance method, redirect.
411ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
412ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                    selectorLoc, rbrac, Args, NumArgs);
4135cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      }
41408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner      return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName;
4155cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    }
41685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  } else
41785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    ClassDecl = getObjCInterfaceDecl(receiverName);
41885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
4197c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // The following code allows for the following GCC-ism:
420cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
421cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  typedef XCElementDisplayRect XCElementGraphicsRect;
422cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
423cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  @implementation XCRASlice
424cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  - whatever { // Note that XCElementGraphicsRect is a typedef name.
425cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //    _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
426cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  }
427cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
4287c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // If necessary, the following lookup could move to getObjCInterfaceDecl().
4297c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  if (!ClassDecl) {
43047b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor    NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName);
4317c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff    if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
4327c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff      const ObjCInterfaceType *OCIT;
4337c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff      OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
43464540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner      if (!OCIT) {
43564540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner        Diag(receiverLoc, diag::err_invalid_receiver_to_message);
43664540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner        return true;
43764540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner      }
438ebff1fed660fac9c50a7b7571da797bb489254a4Fariborz Jahanian      ClassDecl = OCIT->getDecl();
4397c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff    }
4407c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  }
4417c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  assert(ClassDecl && "missing interface declaration");
442cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  ObjCMethodDecl *Method = 0;
44385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  QualType returnType;
44489bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian  if (ClassDecl->isForwardDecl()) {
44589bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian    // A forward class used in messaging is tread as a 'Class'
4469f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian    Diag(lbrac, diag::warn_receiver_forward_class) << ClassDecl->getDeclName();
44789bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian    Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
44889bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian    if (Method)
4499f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian      Diag(Method->getLocation(), diag::note_method_sent_forward_class)
4509f8f026fc1cd1aa2942a2850a037398415128f8aFariborz Jahanian        << Method->getDeclName();
45189bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian  }
45289bc314c6ddf3b851ccf68bc34d3f1b5927a10f6Fariborz Jahanian  if (!Method)
45317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    Method = ClassDecl->lookupClassMethod(Sel);
4547c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff
4557c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // If we have an implementation in scope, check "private" methods.
456f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  if (!Method)
4575609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    Method = LookupPrivateClassMethod(Sel, ClassDecl);
4587c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff
45948f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor  if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
46048f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    return true;
46159843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson
462077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true,
463637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
464637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
4654df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek
466187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson  returnType = returnType.getNonReferenceType();
467187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson
468390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // If we have the ObjCInterfaceDecl* for the class that is receiving the
469390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // message, use that to construct the ObjCMessageExpr.  Otherwise pass on the
470390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // IdentifierInfo* for the class.
471390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: need to do a better job handling 'super' usage within a class.  For
472390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // now, we simply pass the "super" identifier through (which isn't consistent
473390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // with instance methods.
4747c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  if (isSuper)
4758189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(receiverName, Sel, returnType, Method,
4768189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         lbrac, rbrac, ArgExprs, NumArgs);
4774df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek  else
4788189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(ClassDecl, Sel, returnType, Method,
4798189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         lbrac, rbrac, ArgExprs, 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,
486b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            SourceLocation lbrac,
487ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                            SourceLocation receiverLoc,
488b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            SourceLocation rbrac,
489b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            ExprTy **Args, unsigned NumArgs) {
49085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  assert(receiver && "missing receiver expression");
49185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
49285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
49385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr *RExpr = static_cast<Expr *>(receiver);
494d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner
495d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  // If necessary, apply function/array conversion to the receiver.
496d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  // C99 6.7.5.3p[7,8].
497d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  DefaultFunctionArrayConversion(RExpr);
498d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner
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);
5115609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
5125609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          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;
524187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson
525187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson    returnType = returnType.getNonReferenceType();
5268189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5278189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
52887d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  }
52987d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
53014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // Handle messages to id.
5316c4088e5fc0ce98bf3213d47f6f38bfbfa20c813Steve Naroff  if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
532636bed1b8185099ef40a4f7fd192fc4242b385a4Fariborz Jahanian      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));
538077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
539637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
540637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
541187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson    returnType = returnType.getNonReferenceType();
5428189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5438189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
544fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
545fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
546fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  // Handle messages to Class.
547b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
5482b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    ObjCMethodDecl *Method = 0;
5496b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
5506562fdad21432377f0cc5e0c627c28f0c85df4ddChris Lattner    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
551d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
552d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff        // First check the public methods in the class interface.
55317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis        Method = ClassDecl->lookupClassMethod(Sel);
554d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff
555f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff        if (!Method)
5565609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          Method = LookupPrivateClassMethod(Sel, ClassDecl);
557d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      }
55848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
55948f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor        return true;
560d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff    }
5616b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (!Method) {
5626b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      // If not messaging 'self', look for any factory method named 'Sel'.
5636b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      if (!isSelfExpr(RExpr)) {
564f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor        Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
565b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        if (!Method) {
566041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          // If no class (factory) method was found, check if an _instance_
567041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          // method of the same name exists in the root class only.
5686b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
5696b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                                   Sel, SourceRange(lbrac,rbrac));
570041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          if (Method)
571041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian              if (const ObjCInterfaceDecl *ID =
572041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
573041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian              if (ID->getSuperClass())
574041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                Diag(lbrac, diag::warn_root_inst_method_not_found)
575041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                  << Sel << SourceRange(lbrac, rbrac);
576041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian            }
577b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        }
5786b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      }
5796b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    }
580077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
581637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
582637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
583187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson    returnType = returnType.getNonReferenceType();
5848189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5858189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
586fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
587fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
5882b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  ObjCMethodDecl *Method = 0;
589fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  ObjCInterfaceDecl* ClassDecl = 0;
5902b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner
5912b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
5922b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // long as one of the protocols implements the selector (if not, warn).
593d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (const ObjCObjectPointerType *QIdTy =
594d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff        ReceiverCType->getAsObjCQualifiedIdType()) {
595f7f52e7bf5a4dc36d45b98531e0b21e343fc19deSteve Naroff    // Search protocols for instance methods.
596d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
597446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff         E = QIdTy->qual_end(); I != E; ++I) {
598446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff      ObjCProtocolDecl *PDecl = *I;
59917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
600fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner        break;
601ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff      // Since we aren't supporting "Class<foo>", look for a class method.
60217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis      if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
603ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff        break;
604fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    }
60514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  } else if (const ObjCObjectPointerType *OCIType =
60614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff                ReceiverCType->getAsObjCInterfacePointerType()) {
6072b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    // We allow sending a message to a pointer to an interface (an object).
608fb8cc1dfd87a1cbbaa17d64ec753d3fe8a9e9c38Chris Lattner
60914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    ClassDecl = OCIType->getInterfaceDecl();
610037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
611390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // faster than the following method (which can do *many* linear searches).
612037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // The idea is to add class info to InstanceMethodPool.
61317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis    Method = ClassDecl->lookupInstanceMethod(Sel);
614fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
615fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    if (!Method) {
616fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      // Search protocol qualifiers.
61714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
618279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff           E = OCIType->qual_end(); QI != E; ++QI) {
61917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis        if ((Method = (*QI)->lookupInstanceMethod(Sel)))
62085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner          break;
62185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      }
62285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
6230de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    if (!Method) {
6245609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // If we have implementations in scope, check "private" methods.
6255609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
6265609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
6275609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      if (!Method && !isSelfExpr(RExpr)) {
6286b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // If we still haven't found a method, look in the global pool. This
6296b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // behavior isn't very desirable, however we need it for GCC
6306b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // compatibility. FIXME: should we deviate??
6315609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (OCIType->qual_empty()) {
6326b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
6336b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                               Sel, SourceRange(lbrac,rbrac));
63414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
6356b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff            Diag(lbrac, diag::warn_maynot_respond)
63614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff              << OCIType->getInterfaceDecl()->getIdentifier()->getName() << Sel;
6376b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        }
638268bc8c1f3a27d2fbd73c3115e4d633d31422ca5Fariborz Jahanian      }
6390de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    }
64048f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
64148f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
6420c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else if (!Context.getObjCIdType().isNull() &&
6430c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner             (ReceiverCType->isPointerType() ||
6440c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner              (ReceiverCType->isIntegerType() &&
6450c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner               ReceiverCType->isScalarType()))) {
6460c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Implicitly convert integers and pointers to 'id' but emit a warning.
6478e2945ad9104f0ce4928c386faf458b6b83d9060Steve Naroff    Diag(lbrac, diag::warn_bad_receiver_type)
648d162584991885ab004a02573a73ce06422b921fcChris Lattner      << RExpr->getType() << RExpr->getSourceRange();
6490c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    ImpCastExprToType(RExpr, Context.getObjCIdType());
6500c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else {
6510c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Reject other random receiver types (e.g. structs).
6520c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    Diag(lbrac, diag::err_bad_receiver_type)
6530c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner      << RExpr->getType() << RExpr->getSourceRange();
6542b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    return true;
655fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
656fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
6575b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian  if (Method)
6585b53005fb9ef24b8bdfe995f29b4662de468128aFariborz Jahanian    DiagnoseSentinelCalls(Method, receiverLoc, ArgExprs, NumArgs);
659077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
660637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
661637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
662187ba159b04d8cc760daeee5cfbbc69450b2d50dAnders Carlsson  returnType = returnType.getNonReferenceType();
6638189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek  return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
6648189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                       rbrac, ArgExprs, NumArgs);
66585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
666eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
667eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===//
668eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
669eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===//
670eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
671eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
672eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// inheritance hierarchy of 'rProto'.
673eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
674eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                           ObjCProtocolDecl *rProto) {
675eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (lProto == rProto)
676eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    return true;
677780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
678780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner       E = rProto->protocol_end(); PI != E; ++PI)
679780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner    if (ProtocolCompatibleWithProtocol(lProto, *PI))
680eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
681eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  return false;
682eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
683eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
684eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ClassImplementsProtocol - Checks that 'lProto' protocol
685eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// has been implemented in IDecl class, its super class or categories (if
686eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// lookupCategory is true).
687eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
688eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                    ObjCInterfaceDecl *IDecl,
68926631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                                    bool lookupCategory,
69026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                                    bool RHSIsQualifiedID = false) {
691eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
692eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 1st, look up the class.
6933db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  const ObjCList<ObjCProtocolDecl> &Protocols =
6943db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    IDecl->getReferencedProtocols();
6953db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
6963db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
6973db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner       E = Protocols.end(); PI != E; ++PI) {
6983db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    if (ProtocolCompatibleWithProtocol(lProto, *PI))
699eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
700390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // This is dubious and is added to be compatible with gcc.  In gcc, it is
701390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // also allowed assigning a protocol-qualified 'id' type to a LHS object
702390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // when protocol in qualified LHS is in list of protocols in the rhs 'id'
703390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // object. This IMO, should be a bug.
704390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Treat this as an extension, and flag this as an error when GCC
705390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // extensions are not enabled.
7063db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    if (RHSIsQualifiedID && ProtocolCompatibleWithProtocol(*PI, lProto))
70726631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      return true;
708eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
709eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
710eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 2nd, look up the category.
711eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (lookupCategory)
712eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
713eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner         CDecl = CDecl->getNextClassCategory()) {
714780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner      for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
715780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner           E = CDecl->protocol_end(); PI != E; ++PI)
716780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner        if (ProtocolCompatibleWithProtocol(lProto, *PI))
717eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          return true;
718eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
719eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
720eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 3rd, look up the super class(s)
721eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (IDecl->getSuperClass())
722eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    return
72326631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory,
72426631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                              RHSIsQualifiedID);
725eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
726eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  return false;
727eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
728eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
7292574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian/// QualifiedIdConformsQualifiedId - compare id<p,...> with id<p1,...>
7302574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian/// return true if lhs's protocols conform to rhs's protocol; false
7312574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian/// otherwise.
7322574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanianbool Sema::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) {
7332574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian  if (lhs->isObjCQualifiedIdType() && rhs->isObjCQualifiedIdType())
7342574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian    return ObjCQualifiedIdTypesAreCompatible(lhs, rhs, false);
7352574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian  return false;
7362574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian}
7372574a68e5cca0171f1e8c09373cb2f7e612ab77eFariborz Jahanian
738b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
739b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIDType.
74015edf0de6b5bc9ae227bcc9658a157ac30efd92eSteve Naroff/// FIXME: Move to ASTContext::typesAreCompatible() and friends.
741eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerbool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
742eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                             bool compare) {
743eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // Allow id<P..> and an 'id' or void* type in all cases.
74414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  if (lhs->isVoidPointerType() ||
74514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      lhs->isObjCIdType() || lhs->isObjCClassType())
74614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return true;
74714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  else if (rhs->isVoidPointerType() ||
74814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff           rhs->isObjCIdType() || rhs->isObjCClassType())
74914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return true;
75014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
751d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
75214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    const ObjCObjectPointerType *rhsOPT = rhs->getAsObjCObjectPointerType();
753289d9f243d9074513368d27eef3b647f72a38324Steve Naroff
75414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    if (!rhsOPT) return false;
755eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
75614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    if (rhsOPT->qual_empty()) {
75714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // If the RHS is a unqualified interface pointer "NSString*",
75814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // make sure we check the class hierarchy.
75914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
76014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
76114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff             E = lhsQID->qual_end(); I != E; ++I) {
76214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // when comparing an id<P> on lhs with a static type on rhs,
76314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // see if static class implements all of id's protocols, directly or
76414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // through its super class and categories.
76514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          if (!ClassImplementsProtocol(*I, rhsID, true))
76614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff            return false;
76714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        }
76814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        return true;
76914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      }
77014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // If there are no qualifiers and no interface, we have an 'id'.
77114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      return true;
772eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
77314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    // Both the right and left sides have qualifiers.
774d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
775446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff         E = lhsQID->qual_end(); I != E; ++I) {
776446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff      ObjCProtocolDecl *lhsProto = *I;
777eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      bool match = false;
778eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
779eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // when comparing an id<P> on lhs with a static type on rhs,
780eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // see if static class implements all of id's protocols, directly or
781eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // through its super class and categories.
78214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
78314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff           E = rhsOPT->qual_end(); J != E; ++J) {
78414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        ObjCProtocolDecl *rhsProto = *J;
785b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
78682b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
787eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          match = true;
788b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          break;
789eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        }
790eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      }
79114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // If the RHS is a qualified interface pointer "NSString<P>*",
79214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // make sure we check the class hierarchy.
79314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
79414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
79514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff             E = lhsQID->qual_end(); I != E; ++I) {
79614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // when comparing an id<P> on lhs with a static type on rhs,
79714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // see if static class implements all of id's protocols, directly or
79814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // through its super class and categories.
79914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          if (ClassImplementsProtocol(*I, rhsID, true)) {
80014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff            match = true;
80114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff            break;
802289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          }
803289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        }
804289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      }
805eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      if (!match)
806eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        return false;
807eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
808eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
809b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
810b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  }
811b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
812d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff  const ObjCObjectPointerType *rhsQID = rhs->getAsObjCQualifiedIdType();
813b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  assert(rhsQID && "One of the LHS/RHS should be id<x>");
81414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
81514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  if (const ObjCObjectPointerType *lhsOPT =
81614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        lhs->getAsObjCInterfacePointerType()) {
81714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    if (lhsOPT->qual_empty()) {
81814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      bool match = false;
81914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) {
82014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
82114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff             E = rhsQID->qual_end(); I != E; ++I) {
82214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // when comparing an id<P> on lhs with a static type on rhs,
82314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // see if static class implements all of id's protocols, directly or
82414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          // through its super class and categories.
82514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          if (ClassImplementsProtocol(*I, lhsID, true)) {
82614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff            match = true;
82714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff            break;
82814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          }
82914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        }
83014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        if (!match)
83114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          return false;
83214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      }
83314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      return true;
83414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    }
83514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    // Both the right and left sides have qualifiers.
83614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),
83714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff         E = lhsOPT->qual_end(); I != E; ++I) {
83814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      ObjCProtocolDecl *lhsProto = *I;
83914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      bool match = false;
84014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff
84114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // when comparing an id<P> on lhs with a static type on rhs,
84214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // see if static class implements all of id's protocols, directly or
84314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      // through its super class and categories.
84414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
84514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff           E = rhsQID->qual_end(); J != E; ++J) {
84614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        ObjCProtocolDecl *rhsProto = *J;
84714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
84814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
84914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          match = true;
85014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff          break;
85114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        }
85214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      }
85314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff      if (!match)
85414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff        return false;
85514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    }
85614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    return true;
85714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  }
85814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // FIXME: The code below will be removed when ObjCQualifiedInterfaceType is
85914108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  // removed.
860b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (!lhs->isPointerType())
861b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return false;
862b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
863b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  QualType ltype = lhs->getAsPointerType()->getPointeeType();
864b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCQualifiedInterfaceType *lhsQI =
865b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner         ltype->getAsObjCQualifiedInterfaceType()) {
866d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCObjectPointerType::qual_iterator LHSProtoI = lhsQI->qual_begin();
867d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff    ObjCObjectPointerType::qual_iterator LHSProtoE = lhsQI->qual_end();
868b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    for (; LHSProtoI != LHSProtoE; ++LHSProtoI) {
869b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      bool match = false;
870b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      ObjCProtocolDecl *lhsProto = *LHSProtoI;
871d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff      for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
872446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff           E = rhsQID->qual_end(); I != E; ++I) {
873446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff        ObjCProtocolDecl *rhsProto = *I;
874b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
87582b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
876eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          match = true;
877eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          break;
878eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        }
879eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      }
880b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (!match)
881b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        return false;
882eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
883b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
884b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  }
885b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
886b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  return false;
887eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
888eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
889