SemaExprObjC.cpp revision ebaa768521cfd5318d77f1efaf7ae47020863a9d
185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//                     The LLVM Compiler Infrastructure
485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// This file is distributed under the University of Illinois Open Source
685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// License. See LICENSE.TXT for details.
785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//  This file implements semantic analysis for Objective-C expressions.
1185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//
1285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner//===----------------------------------------------------------------------===//
1385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
1485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "Sema.h"
1585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/ASTContext.h"
1685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner#include "clang/AST/DeclObjC.h"
17f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h"
1839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner#include "llvm/ADT/SmallString.h"
1961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff#include "clang/Lex/Preprocessor.h"
2061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
2185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattnerusing namespace clang;
2285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
2385a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
2439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                                              ExprTy **strings,
2585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                              unsigned NumStrings) {
2639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
2739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
28f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // Most ObjC strings are formed out of a single piece.  However, we *can*
29f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // have strings formed out of multiple @ strings with multiple pptokens in
30f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
31f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // StringLiteral for ObjCStringLiteral to hold onto.
3239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner  StringLiteral *S = Strings[0];
33f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner
34f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  // If we have a multi-part string, merge it all together.
35f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  if (NumStrings != 1) {
3685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    // Concatenate objc strings.
3739c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallString<128> StrBuf;
3839c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    llvm::SmallVector<SourceLocation, 8> StrLocs;
39726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner
40726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    for (unsigned i = 0; i != NumStrings; ++i) {
4139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      S = Strings[i];
4239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
4339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // ObjC strings can't be wide.
44f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      if (S->isWide()) {
45f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant)
46f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner          << S->getSourceRange();
47f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner        return true;
48f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner      }
49f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner
5039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the string data.
5139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
5239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
5339c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Get the locations of the string tokens.
5439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      StrLocs.append(S->tokloc_begin(), S->tokloc_end());
5539c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
5639c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner      // Free the temporary string.
578189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek      S->Destroy(Context);
5885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
5939c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner
6039c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // Create the aggregate string with the appropriate content and location
6139c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    // information.
6239c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner    S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false,
632085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner                              Context.getPointerType(Context.CharTy),
6439c28bbbf235533e9ae7d06fb9b13371dfcc542dChris Lattner                              &StrLocs[0], StrLocs.size());
6585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
6685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
67690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  // Verify that this composite string is acceptable for ObjC strings.
68690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  if (CheckObjCString(S))
6985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
70a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner
71a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  // Initialize the constant string interface lazily. This assumes
72d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // the NSString interface is seen in this translation unit. Note: We
73d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // don't use NSConstantString, since the runtime team considers this
74d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff  // interface private (even though it appears in the header files).
75a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCConstantStringInterface();
76a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (!Ty.isNull()) {
77a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    Ty = Context.getPointerType(Ty);
7813fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  } else {
79d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
80a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    NamedDecl *IF = LookupName(TUScope, NSIdent, LookupOrdinaryName);
81a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
82a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Context.setObjCConstantStringInterface(StrIF);
83a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCConstantStringInterface();
84a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getPointerType(Ty);
85a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    } else {
86d9fd7647e286723d100db4cfeab31ec022eec629Steve Naroff      // If there is no NSString interface defined then treat constant
87a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      // strings as untyped objects and let the runtime figure it out later.
88a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner      Ty = Context.getObjCIdType();
89a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner    }
9013fd7e5111032f54b538dd66d035b0ccc1f82467Chris Lattner  }
91a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner
92f4b136fb40aeedeaaa6ce7cdff22f375eb76c47bChris Lattner  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
9385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
9485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
9585a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
9685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                 SourceLocation EncodeLoc,
9785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                 SourceLocation LParenLoc,
98a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner                                                 TypeTy *ty,
9985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                 SourceLocation RParenLoc) {
100a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType EncodedType = QualType::getFromOpaquePtr(ty);
10185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
102eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  std::string Str;
103eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  Context.getObjCEncodingForType(EncodedType, Str);
104eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner
105eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  // The type of @encode is the same as the type of the corresponding string,
106eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  // which is an array type.
107eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  QualType StrTy = Context.CharTy;
108eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
109eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  if (getLangOptions().CPlusPlus)
110eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner    StrTy.addConst();
111eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
112eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner                                       ArrayType::Normal, 0);
113eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner
114eaf2bb89eb2aad3b80673de30febe52df43c10ecChris Lattner  return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
11585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
11685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
11785a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
11885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation AtLoc,
11985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation SelLoc,
12085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation LParenLoc,
12185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation RParenLoc) {
122a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCSelType();
123a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
12485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
12585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
12685a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
12785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation AtLoc,
12885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation ProtoLoc,
12985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation LParenLoc,
13085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                                                   SourceLocation RParenLoc) {
131a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCProtocolDecl* PDecl = ObjCProtocols[ProtocolId];
13285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  if (!PDecl) {
1333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
13485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
13585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
13685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
137a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  QualType Ty = Context.getObjCProtoType();
138a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  if (Ty.isNull())
13985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    return true;
140a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  Ty = Context.getPointerType(Ty);
141a0af1fe67da29343cd182c51cd48d91b740ecef2Chris Lattner  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
14285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
14385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
14491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbarbool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
14591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar                                     Selector Sel, ObjCMethodDecl *Method,
146077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner                                     bool isClassMessage,
147637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                     SourceLocation lbrac, SourceLocation rbrac,
148637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                     QualType &ReturnType) {
149637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  if (!Method) {
1506660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    // Apply default argument promotion as for (C99 6.5.2.2p6).
1516660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar    for (unsigned i = 0; i != NumArgs; i++)
1526660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar      DefaultArgumentPromotion(Args[i]);
1536660c8a4cc2115929d92be83bbc54c307002a321Daniel Dunbar
154077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
155077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner                                       diag::warn_inst_method_not_found;
156077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    Diag(lbrac, DiagID)
157077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner      << Sel << isClassMessage << SourceRange(lbrac, rbrac);
158637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    ReturnType = Context.getObjCIdType();
159637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return false;
160637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar  }
161077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner
162077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  ReturnType = Method->getResultType();
163637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar
16491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  unsigned NumNamedArgs = Sel.getNumArgs();
16591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
16691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
16785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  bool anyIncompatibleArgs = false;
16891e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  for (unsigned i = 0; i < NumNamedArgs; i++) {
16985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    Expr *argExpr = Args[i];
17085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
17185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
17289951a86b594513c2a013532ed45d197413b1087Chris Lattner    QualType lhsType = Method->param_begin()[i]->getType();
17385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    QualType rhsType = argExpr->getType();
17485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
17585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
176987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner    if (lhsType->isArrayType())
177987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner      lhsType = Context.getArrayDecayedType(lhsType);
17885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    else if (lhsType->isFunctionType())
17985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      lhsType = Context.getPointerType(lhsType);
18085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
181987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner    AssignConvertType Result =
182987798ad1d5db2a8ec26cd5bbe434b35ad32659cChris Lattner      CheckSingleAssignmentConstraints(lhsType, argExpr);
18385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    if (Args[i] != argExpr) // The expression was converted.
18485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      Args[i] = argExpr; // Make sure we store the converted expression.
18585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
18685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    anyIncompatibleArgs |=
18785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
18885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner                               argExpr, "sending");
18985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  }
19091e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
19191e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  // Promote additional arguments to variadic methods.
19291e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  if (Method->isVariadic()) {
193dce5e2cabf07ff25eb4d9e1859c0a21c69f588d2Anders Carlsson    for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
194dce5e2cabf07ff25eb4d9e1859c0a21c69f588d2Anders Carlsson      DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
19591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  } else {
19691e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    // Check for extra arguments to non-variadic methods.
19791e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    if (NumArgs != NumNamedArgs) {
19891e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar      Diag(Args[NumNamedArgs]->getLocStart(),
199fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner           diag::err_typecheck_call_too_many_args)
2002c21a073525cdfa68e4439b7af551385dc2796abChris Lattner        << 2 /*method*/ << Method->getSourceRange()
201fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << SourceRange(Args[NumNamedArgs]->getLocStart(),
202fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner                       Args[NumArgs-1]->getLocEnd());
20391e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar    }
20491e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar  }
20591e19b2029447e75d2c7730ff888cc396874685bDaniel Dunbar
20685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  return anyIncompatibleArgs;
20785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
20885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
2096b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroffbool Sema::isSelfExpr(Expr *RExpr) {
2106b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr))
2116b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
2126b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      return true;
2136b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff  return false;
2146b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff}
2156b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
216f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Helper method for ActOnClassMethod/ActOnInstanceMethod.
217f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Will search "local" class/category implementations for a method decl.
218175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian// If failed, then we search in class's root for an instance method.
219f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff// Returns 0 if no method is found.
2205609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
221f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff                                          ObjCInterfaceDecl *ClassDecl) {
222f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  ObjCMethodDecl *Method = 0;
2235609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  // lookup in class and all superclasses
2245609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
2255609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (ObjCImplementationDecl *ImpDecl =
2265609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        ObjCImplementations[ClassDecl->getIdentifier()])
2275609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = ImpDecl->getClassMethod(Sel);
228f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff
2295609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
2305609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method) {
2315609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
2325609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
2335609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
2345609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      }
2355609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    }
2365609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2375609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Before we give up, check if the selector is an instance method.
2385609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // But only in the root. This matches gcc's behaviour and what the
2395609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // runtime expects.
2405609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method && !ClassDecl->getSuperClass()) {
2415609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = ClassDecl->lookupInstanceMethod(Sel);
2425609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // Look through local category implementations associated
2435609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // with the root class.
2445609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      if (!Method)
2455609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
246f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff    }
2475609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2485609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
249f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  }
2505609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  return Method;
2515609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff}
2525609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2535609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve NaroffObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
2545609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff                                              ObjCInterfaceDecl *ClassDecl) {
2555609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  ObjCMethodDecl *Method = 0;
2565609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff  while (ClassDecl && !Method) {
2575609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // If we have implementations in scope, check "private" methods.
2585609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (ObjCImplementationDecl *ImpDecl =
2595609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        ObjCImplementations[ClassDecl->getIdentifier()])
2605609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = ImpDecl->getInstanceMethod(Sel);
2615609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
2625609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    // Look through local category implementations associated with the class.
2635609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    if (!Method) {
2645609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
2655609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
2665609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
2675609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      }
2685609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    }
2695609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    ClassDecl = ClassDecl->getSuperClass();
270175ba1e8180083927aabd7cc8137baa16be75646Fariborz Jahanian  }
271f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  return Method;
272f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff}
273f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff
27461f72cbd037e58f12cfe90cd442373f44092f030Steve NaroffAction::OwningExprResult Sema::ActOnClassPropertyRefExpr(
27561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  IdentifierInfo &receiverName,
27661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  IdentifierInfo &propertyName,
27761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  SourceLocation &receiverNameLoc,
27861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  SourceLocation &propertyNameLoc) {
27961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
28061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(&receiverName);
28161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
28261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Search for a declared property first.
28361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
28461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
28561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
28661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
28761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // If this reference is in an @implementation, check for 'private' methods.
28861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Getter)
28961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
29061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
29161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff        if (ObjCImplementationDecl *ImpDecl =
29261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff            ObjCImplementations[ClassDecl->getIdentifier()])
29361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff          Getter = ImpDecl->getClassMethod(Sel);
29461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
29561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter) {
29661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // FIXME: refactor/share with ActOnMemberReference().
29761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // Check if we can reference this property.
29861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
29961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      return ExprError();
30061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
30161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
30261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look for the matching setter, in case it is needed.
303fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff  Selector SetterSel =
304fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff    SelectorTable::constructSetterName(PP.getIdentifierTable(),
305fdc92b7877535e6264fe43cfbdc8f01e9b224f81Steve Naroff                                       PP.getSelectorTable(), &propertyName);
30661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
30761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
30861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Setter) {
30961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // If this reference is in an @implementation, also check for 'private'
31061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    // methods.
31161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
31261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
31361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff        if (ObjCImplementationDecl *ImpDecl =
31461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff              ObjCImplementations[ClassDecl->getIdentifier()])
31561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff          Setter = ImpDecl->getClassMethod(SetterSel);
31661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
31761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  // Look through local category implementations associated with the class.
31861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (!Setter) {
31961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
32061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
32161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff        Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
32261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    }
32361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
32461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
32561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
32661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    return ExprError();
32761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
32861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  if (Getter || Setter) {
32961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    QualType PType;
33061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
33161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    if (Getter)
33261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      PType = Getter->getResultType();
33361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    else {
33461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff      for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
33561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff           E = Setter->param_end(); PI != E; ++PI)
33661f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff        PType = (*PI)->getType();
33761f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    }
33861f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff    return Owned(new (Context) ObjCKVCRefExpr(Getter, PType, Setter,
33961f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                                  propertyNameLoc, IFace, receiverNameLoc));
34061f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  }
34161f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
34261f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff                     << &propertyName << Context.getObjCInterfaceType(IFace));
34361f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff}
34461f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
34561f72cbd037e58f12cfe90cd442373f44092f030Steve Naroff
34685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnClassMessage - used for both unary and keyword messages.
34785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions
34885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs().
34985a932e26f3c3faae6bad639a6d32e92794dfda9Chris LattnerSema::ExprResult Sema::ActOnClassMessage(
35085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Scope *S,
35185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  IdentifierInfo *receiverName, Selector Sel,
352ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson  SourceLocation lbrac, SourceLocation receiverLoc,
353ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson  SourceLocation selectorLoc, SourceLocation rbrac,
3545cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff  ExprTy **Args, unsigned NumArgs)
35585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner{
35685a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  assert(receiverName && "missing receiver class name");
35785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
35885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
359a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  ObjCInterfaceDecl* ClassDecl = 0;
360fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff  bool isSuper = false;
361fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff
3628469265156c6344fa1100a6a7bf6349acc187d9fChris Lattner  if (receiverName->isStr("super")) {
3635cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    if (getCurMethodDecl()) {
3645cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      isSuper = true;
3654b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      ObjCInterfaceDecl *OID = getCurMethodDecl()->getClassInterface();
3664b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      if (!OID)
3674b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian        return Diag(lbrac, diag::error_no_super_class_message)
3684b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian                      << getCurMethodDecl()->getDeclName();
3694b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian      ClassDecl = OID->getSuperClass();
3705cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      if (!ClassDecl)
3714b1e275eb743b46cd10153bb58743d89af7242eaFariborz Jahanian        return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName();
372f8d49f64ef6ab7e632717a31631fc289aab69428Douglas Gregor      if (getCurMethodDecl()->isInstanceMethod()) {
3735cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        QualType superTy = Context.getObjCInterfaceType(ClassDecl);
3745cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        superTy = Context.getPointerType(superTy);
3758189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(),
3768189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                                              superTy);
3775cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        // We are really in an instance method, redirect.
378ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
379ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                    selectorLoc, rbrac, Args, NumArgs);
3805cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      }
3815cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // We are sending a message to 'super' within a class method. Do nothing,
3825cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // the receiver will pass through as 'super' (how convenient:-).
3835cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    } else {
3845cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // 'super' has been used outside a method context. If a variable named
3855cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      // 'super' has been declared, redirect. If not, produce a diagnostic.
38647b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor      NamedDecl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName);
3875cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
3885cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      if (VD) {
3898189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek        ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(),
3908189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                                            receiverLoc);
3915cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff        // We are really in an instance method, redirect.
392ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
393ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                    selectorLoc, rbrac, Args, NumArgs);
3945cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff      }
39508631c5fa053867146b5ee8be658c229f6bf127cChris Lattner      return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName;
3965cb93b8bf009c4b0ae09b71ba85f54b2a7ea8022Steve Naroff    }
39785a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  } else
39885a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    ClassDecl = getObjCInterfaceDecl(receiverName);
39985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
4007c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // The following code allows for the following GCC-ism:
401cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
402cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  typedef XCElementDisplayRect XCElementGraphicsRect;
403cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
404cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  @implementation XCRASlice
405cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  - whatever { // Note that XCElementGraphicsRect is a typedef name.
406cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //    _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
407cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //  }
408cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  //
4097c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // If necessary, the following lookup could move to getObjCInterfaceDecl().
4107c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  if (!ClassDecl) {
41147b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor    NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName);
4127c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff    if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
4137c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff      const ObjCInterfaceType *OCIT;
4147c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff      OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
41564540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner      if (!OCIT) {
41664540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner        Diag(receiverLoc, diag::err_invalid_receiver_to_message);
41764540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner        return true;
41864540d71b4aaab07d93cb3593ce462d26a83d326Chris Lattner      }
419ebff1fed660fac9c50a7b7571da797bb489254a4Fariborz Jahanian      ClassDecl = OCIT->getDecl();
4207c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff    }
4217c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  }
4227c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  assert(ClassDecl && "missing interface declaration");
423cb28be6e82809f9f514585ac2692fa04bb56978aSteve Naroff  ObjCMethodDecl *Method = 0;
42485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  QualType returnType;
4257c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  Method = ClassDecl->lookupClassMethod(Sel);
4267c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff
4277c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  // If we have an implementation in scope, check "private" methods.
428f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff  if (!Method)
4295609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff    Method = LookupPrivateClassMethod(Sel, ClassDecl);
4307c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff
43148f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor  if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
43248f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    return true;
43359843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson
434077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true,
435637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
436637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
4374df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek
4384df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek  // If we have the ObjCInterfaceDecl* for the class that is receiving
4394df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek  // the message, use that to construct the ObjCMessageExpr.  Otherwise
4404df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek  // pass on the IdentifierInfo* for the class.
441fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff  // FIXME: need to do a better job handling 'super' usage within a class
442fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff  // For now, we simply pass the "super" identifier through (which isn't
443fc93d52ada07d52de0ad4fd051b6a08e21d421ffSteve Naroff  // consistent with instance methods.
4447c778f1c549a8ae95d50a819fd537df78da16426Steve Naroff  if (isSuper)
4458189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(receiverName, Sel, returnType, Method,
4468189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         lbrac, rbrac, ArgExprs, NumArgs);
4474df728e368fa1f65ffc57572fed613dcca5b4fe8Ted Kremenek  else
4488189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(ClassDecl, Sel, returnType, Method,
4498189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         lbrac, rbrac, ArgExprs, NumArgs);
45085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
45185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
45285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ActOnInstanceMessage - used for both unary and keyword messages.
45385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// ArgExprs is optional - if it is present, the number of expressions
45485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner// is obtained from Sel.getNumArgs().
4551565e0364b05d163640dd2b6feed43bae67df4fdChris LattnerSema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
456b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            SourceLocation lbrac,
457ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson                                            SourceLocation receiverLoc,
458b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            SourceLocation rbrac,
459b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                                            ExprTy **Args, unsigned NumArgs) {
46085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  assert(receiver && "missing receiver expression");
46185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner
46285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
46385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  Expr *RExpr = static_cast<Expr *>(receiver);
46485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  QualType returnType;
46594a82c930278809a04976ee13013e6e980b18345Steve Naroff
466b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  QualType ReceiverCType =
467b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner    Context.getCanonicalType(RExpr->getType()).getUnqualifiedType();
46887d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
46987d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  // Handle messages to 'super'.
470279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff  if (isa<ObjCSuperExpr>(RExpr)) {
47187d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    ObjCMethodDecl *Method = 0;
47287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
47387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      // If we have an interface in scope, check 'super' methods.
47487d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
4755609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
47687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff          Method = SuperDecl->lookupInstanceMethod(Sel);
4775609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
4785609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          if (!Method)
4795609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff            // If we have implementations in scope, check "private" methods.
4805609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff            Method = LookupPrivateInstanceMethod(Sel, SuperDecl);
4815609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        }
48287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    }
483ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson
48448f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
48548f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
48659843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson
487077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
48887d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff                                  lbrac, rbrac, returnType))
48987d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      return true;
4908189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
4918189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
49287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  }
49387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
494fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  // Handle messages to id.
4956c4088e5fc0ce98bf3213d47f6f38bfbfa20c813Steve Naroff  if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
4960c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner      ReceiverCType->isBlockPointerType()) {
497037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
498037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff                               Sel, SourceRange(lbrac,rbrac));
4996e10a08fe0427ab34c463dd59d9c0997d4f72170Chris Lattner    if (!Method)
5006e10a08fe0427ab34c463dd59d9c0997d4f72170Chris Lattner      Method = FactoryMethodPool[Sel].Method;
501077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
502637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
503637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
5048189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5058189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
506fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
507fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
508fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  // Handle messages to Class.
509b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
5102b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    ObjCMethodDecl *Method = 0;
5116b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
5126562fdad21432377f0cc5e0c627c28f0c85df4ddChris Lattner    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
513d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
514d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff        // First check the public methods in the class interface.
515d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff        Method = ClassDecl->lookupClassMethod(Sel);
516d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff
517f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff        if (!Method)
5185609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          Method = LookupPrivateClassMethod(Sel, ClassDecl);
519d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      }
52048f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
52148f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor        return true;
522d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff    }
5236b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (!Method) {
5246b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      // If not messaging 'self', look for any factory method named 'Sel'.
5256b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      if (!isSelfExpr(RExpr)) {
5266b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        Method = FactoryMethodPool[Sel].Method;
527b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        if (!Method) {
5286b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
5296b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                                   Sel, SourceRange(lbrac,rbrac));
530b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        }
5316b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      }
5326b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    }
533077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
534637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
535637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
5368189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5378189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
538fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
539fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
5402b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  ObjCMethodDecl *Method = 0;
541fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  ObjCInterfaceDecl* ClassDecl = 0;
5422b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner
5432b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
5442b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // long as one of the protocols implements the selector (if not, warn).
545b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
546f7f52e7bf5a4dc36d45b98531e0b21e343fc19deSteve Naroff    // Search protocols for instance methods.
547fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
548fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
549fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
550fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner        break;
551ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff      // Since we aren't supporting "Class<foo>", look for a class method.
552ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff      if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
553ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff        break;
554fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    }
555279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff  } else if (const ObjCInterfaceType *OCIType =
556b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                ReceiverCType->getAsPointerToObjCInterfaceType()) {
5572b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    // We allow sending a message to a pointer to an interface (an object).
558fb8cc1dfd87a1cbbaa17d64ec753d3fe8a9e9c38Chris Lattner
559279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff    ClassDecl = OCIType->getDecl();
560037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
561037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // faster than the following method (which can do *many* linear searches).
562037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // The idea is to add class info to InstanceMethodPool.
563fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    Method = ClassDecl->lookupInstanceMethod(Sel);
564fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
565fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    if (!Method) {
566fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      // Search protocol qualifiers.
567279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff      for (ObjCQualifiedInterfaceType::qual_iterator QI = OCIType->qual_begin(),
568279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff           E = OCIType->qual_end(); QI != E; ++QI) {
569fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner        if ((Method = (*QI)->lookupInstanceMethod(Sel)))
57085a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner          break;
57185a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      }
57285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
5730de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    if (!Method) {
5745609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // If we have implementations in scope, check "private" methods.
5755609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
5765609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
5775609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      if (!Method && !isSelfExpr(RExpr)) {
5786b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // If we still haven't found a method, look in the global pool. This
5796b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // behavior isn't very desirable, however we need it for GCC
5806b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // compatibility. FIXME: should we deviate??
5815609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (OCIType->qual_empty()) {
5826b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
5836b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                               Sel, SourceRange(lbrac,rbrac));
5846b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          if (Method && !OCIType->getDecl()->isForwardDecl())
5856b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff            Diag(lbrac, diag::warn_maynot_respond)
5866b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff              << OCIType->getDecl()->getIdentifier()->getName() << Sel;
5876b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        }
588268bc8c1f3a27d2fbd73c3115e4d633d31422ca5Fariborz Jahanian      }
5890de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    }
59048f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
59148f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
5920c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else if (!Context.getObjCIdType().isNull() &&
5930c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner             (ReceiverCType->isPointerType() ||
5940c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner              (ReceiverCType->isIntegerType() &&
5950c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner               ReceiverCType->isScalarType()))) {
5960c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Implicitly convert integers and pointers to 'id' but emit a warning.
5978e2945ad9104f0ce4928c386faf458b6b83d9060Steve Naroff    Diag(lbrac, diag::warn_bad_receiver_type)
598d162584991885ab004a02573a73ce06422b921fcChris Lattner      << RExpr->getType() << RExpr->getSourceRange();
5990c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    ImpCastExprToType(RExpr, Context.getObjCIdType());
6000c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else {
6010c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Reject other random receiver types (e.g. structs).
6020c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    Diag(lbrac, diag::err_bad_receiver_type)
6030c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner      << RExpr->getType() << RExpr->getSourceRange();
6042b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    return true;
605fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
606fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
607077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
608637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
609637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
6108189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek  return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
6118189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                       rbrac, ArgExprs, NumArgs);
61285a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
613eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
614eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===//
615eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
616eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===//
617eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
618eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
619eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// inheritance hierarchy of 'rProto'.
620eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
621eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                           ObjCProtocolDecl *rProto) {
622eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (lProto == rProto)
623eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    return true;
624780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
625780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner       E = rProto->protocol_end(); PI != E; ++PI)
626780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner    if (ProtocolCompatibleWithProtocol(lProto, *PI))
627eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
628eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  return false;
629eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
630eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
631eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ClassImplementsProtocol - Checks that 'lProto' protocol
632eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// has been implemented in IDecl class, its super class or categories (if
633eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// lookupCategory is true).
634eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
635eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                    ObjCInterfaceDecl *IDecl,
63626631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                                    bool lookupCategory,
63726631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                                    bool RHSIsQualifiedID = false) {
638eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
639eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 1st, look up the class.
6403db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  const ObjCList<ObjCProtocolDecl> &Protocols =
6413db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    IDecl->getReferencedProtocols();
6423db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
6433db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
6443db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner       E = Protocols.end(); PI != E; ++PI) {
6453db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    if (ProtocolCompatibleWithProtocol(lProto, *PI))
646eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
64726631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // This is dubious and is added to be compatible with gcc.
64826631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // In gcc, it is also allowed assigning a protocol-qualified 'id'
64926631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // type to a LHS object when protocol in qualified LHS is in list
65026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // of protocols in the rhs 'id' object. This IMO, should be a bug.
651fd5b2ce150185d8d8fc3d7789983bbd2b0b8103fTed Kremenek    // FIXME: Treat this as an extension, and flag this as an error when
652fd5b2ce150185d8d8fc3d7789983bbd2b0b8103fTed Kremenek    //  GCC extensions are not enabled.
6533db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    if (RHSIsQualifiedID && ProtocolCompatibleWithProtocol(*PI, lProto))
65426631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      return true;
655eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
656eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
657eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 2nd, look up the category.
658eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (lookupCategory)
659eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
660eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner         CDecl = CDecl->getNextClassCategory()) {
661780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner      for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
662780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner           E = CDecl->protocol_end(); PI != E; ++PI)
663780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner        if (ProtocolCompatibleWithProtocol(lProto, *PI))
664eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          return true;
665eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
666eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
667eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 3rd, look up the super class(s)
668eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (IDecl->getSuperClass())
669eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    return
67026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory,
67126631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                              RHSIsQualifiedID);
672eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
673eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  return false;
674eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
675eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
676b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
677b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIDType.
67815edf0de6b5bc9ae227bcc9658a157ac30efd92eSteve Naroff/// FIXME: Move to ASTContext::typesAreCompatible() and friends.
679eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerbool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
680eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                             bool compare) {
681eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // Allow id<P..> and an 'id' or void* type in all cases.
682eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (const PointerType *PT = lhs->getAsPointerType()) {
683eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    QualType PointeeTy = PT->getPointeeType();
684389bf46ae41241a656ed71b00ac2177d7f385651Steve Naroff    if (Context.isObjCIdStructType(PointeeTy) || PointeeTy->isVoidType())
685eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
686eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  } else if (const PointerType *PT = rhs->getAsPointerType()) {
687eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    QualType PointeeTy = PT->getPointeeType();
688389bf46ae41241a656ed71b00ac2177d7f385651Steve Naroff    if (Context.isObjCIdStructType(PointeeTy) || PointeeTy->isVoidType())
689eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
690eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
691eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
692b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
693b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
694b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    const ObjCQualifiedInterfaceType *rhsQI = 0;
695289d9f243d9074513368d27eef3b647f72a38324Steve Naroff    QualType rtype;
696289d9f243d9074513368d27eef3b647f72a38324Steve Naroff
697b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    if (!rhsQID) {
698b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      // Not comparing two ObjCQualifiedIdType's?
699b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (!rhs->isPointerType()) return false;
700289d9f243d9074513368d27eef3b647f72a38324Steve Naroff
701289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      rtype = rhs->getAsPointerType()->getPointeeType();
702eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      rhsQI = rtype->getAsObjCQualifiedInterfaceType();
703b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (rhsQI == 0) {
704289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // If the RHS is a unqualified interface pointer "NSString*",
705289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // make sure we check the class hierarchy.
706b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
707b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          ObjCInterfaceDecl *rhsID = IT->getDecl();
708b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
709b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            // when comparing an id<P> on lhs with a static type on rhs,
710b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            // see if static class implements all of id's protocols, directly or
711b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            // through its super class and categories.
712b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            if (!ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true))
713b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner              return false;
714b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          }
715b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          return true;
716b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        }
717b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      }
718eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
719eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
720eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE;
721289d9f243d9074513368d27eef3b647f72a38324Steve Naroff    if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *").
722eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoI = rhsQI->qual_begin();
723eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoE = rhsQI->qual_end();
724289d9f243d9074513368d27eef3b647f72a38324Steve Naroff    } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *").
725eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoI = rhsQID->qual_begin();
726eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoE = rhsQID->qual_end();
727b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    } else {
728b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      return false;
729eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
730eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
731eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) {
732eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      ObjCProtocolDecl *lhsProto = lhsQID->getProtocols(i);
733eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      bool match = false;
734eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
735eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // when comparing an id<P> on lhs with a static type on rhs,
736eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // see if static class implements all of id's protocols, directly or
737eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // through its super class and categories.
738b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      for (; RHSProtoI != RHSProtoE; ++RHSProtoI) {
739b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        ObjCProtocolDecl *rhsProto = *RHSProtoI;
740b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
74182b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
742eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          match = true;
743b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          break;
744eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        }
745eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      }
746289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      if (rhsQI) {
747289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // If the RHS is a qualified interface pointer "NSString<P>*",
748289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // make sure we check the class hierarchy.
749289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
750289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          ObjCInterfaceDecl *rhsID = IT->getDecl();
751289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
752289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            // when comparing an id<P> on lhs with a static type on rhs,
753289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            // see if static class implements all of id's protocols, directly or
754289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            // through its super class and categories.
755289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) {
756289d9f243d9074513368d27eef3b647f72a38324Steve Naroff              match = true;
757289d9f243d9074513368d27eef3b647f72a38324Steve Naroff              break;
758289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            }
759289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          }
760289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        }
761289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      }
762eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      if (!match)
763eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        return false;
764eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
765eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
766b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
767b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  }
768b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
769b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
770b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  assert(rhsQID && "One of the LHS/RHS should be id<x>");
771eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
772b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (!lhs->isPointerType())
773b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return false;
774b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
775b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  QualType ltype = lhs->getAsPointerType()->getPointeeType();
776b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCQualifiedInterfaceType *lhsQI =
777b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner         ltype->getAsObjCQualifiedInterfaceType()) {
778b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin();
779b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end();
780b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    for (; LHSProtoI != LHSProtoE; ++LHSProtoI) {
781b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      bool match = false;
782b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      ObjCProtocolDecl *lhsProto = *LHSProtoI;
783eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
784eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
785b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
78682b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
787eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          match = true;
788eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          break;
789eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        }
790eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      }
791b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (!match)
792b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        return false;
793eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
794b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
795b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  }
796b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
797b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) {
798b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    // for static type vs. qualified 'id' type, check that class implements
799b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    // all of 'id's protocols.
800b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    ObjCInterfaceDecl *lhsID = IT->getDecl();
801b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
802b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
80326631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      if (!ClassImplementsProtocol(rhsProto, lhsID, compare, true))
804b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        return false;
805b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    }
806b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
807eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
808b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  return false;
809eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
810eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
811