SemaExprObjC.cpp revision 041f2fd6237c7ce72864e42c66c6b12b52f35f9c
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) {
1316e378de1aebdfeb44f2a7677ed207b32b3a41fbfDouglas Gregor  ObjCProtocolDecl* PDecl = LookupProtocol(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
167312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  bool IsError = 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
186312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner    IsError |=
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)
194312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner      IsError |= 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
206312531a8cd69c562d5687bd69fd334be99d87320Chris Lattner  return IsError;
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) {
2258fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor    if (ObjCImplementationDecl *ImpDecl
2268fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor          = LookupObjCImplementation(ClassDecl->getIdentifier()))
227653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor      Method = ImpDecl->getClassMethod(Context, 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)
233653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor          Method = ObjCCategoryImpls[i]->getClassMethod(Context, 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()) {
2416ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor      Method = ClassDecl->lookupInstanceMethod(Context, 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.
2588fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor    if (ObjCImplementationDecl *ImpDecl
2598fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor          = LookupObjCImplementation(ClassDecl->getIdentifier()))
260653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor      Method = ImpDecl->getInstanceMethod(Context, 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)
266653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor          Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, 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);
2856ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Context, 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())
2918fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor        if (ObjCImplementationDecl *ImpDecl
2928fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor              = LookupObjCImplementation(ClassDecl->getIdentifier()))
293653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor          Getter = ImpDecl->getClassMethod(Context, 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
3076ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, 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())
3138fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor        if (ObjCImplementationDecl *ImpDecl
3148fc463adf0116fdcbff86e9cca11955aad1649feDouglas Gregor              = LookupObjCImplementation(ClassDecl->getIdentifier()))
315653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor          Setter = ImpDecl->getClassMethod(Context, 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)
321653f1b1bf293a9bd96fd4dd6372e779cc7af1597Douglas Gregor        Setter = ObjCCategoryImpls[i]->getClassMethod(Context, 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;
4256ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Method = ClassDecl->lookupClassMethod(Context, 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);
464d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner
465d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  // If necessary, apply function/array conversion to the receiver.
466d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  // C99 6.7.5.3p[7,8].
467d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner  DefaultFunctionArrayConversion(RExpr);
468d0d4599d8ff308ac34db9e38c578f5b8d32afa7eChris Lattner
46985a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner  QualType returnType;
470b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  QualType ReceiverCType =
471b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner    Context.getCanonicalType(RExpr->getType()).getUnqualifiedType();
47287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
47387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  // Handle messages to 'super'.
474279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff  if (isa<ObjCSuperExpr>(RExpr)) {
47587d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    ObjCMethodDecl *Method = 0;
47687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
47787d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      // If we have an interface in scope, check 'super' methods.
47887d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
4795609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
4806ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor          Method = SuperDecl->lookupInstanceMethod(Context, Sel);
4815609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
4825609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          if (!Method)
4835609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff            // If we have implementations in scope, check "private" methods.
4845609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff            Method = LookupPrivateInstanceMethod(Sel, SuperDecl);
4855609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        }
48687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff    }
487ff975cfab9ada27df86038286d1678084aeb3428Anders Carlsson
48848f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
48948f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
49059843ad8835d497cd3c17ff91aa039e31d607791Anders Carlsson
491077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
49287d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff                                  lbrac, rbrac, returnType))
49387d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff      return true;
4948189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
4958189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
49687d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff  }
49787d3ef08d892df8264bd51adb6ddd4a22422cd29Steve Naroff
498fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  // Handle messages to id.
4996c4088e5fc0ce98bf3213d47f6f38bfbfa20c813Steve Naroff  if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
5000c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner      ReceiverCType->isBlockPointerType()) {
501037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
502037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff                               Sel, SourceRange(lbrac,rbrac));
5036e10a08fe0427ab34c463dd59d9c0997d4f72170Chris Lattner    if (!Method)
504f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor      Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac, rbrac));
505077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
506637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
507637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
5088189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5098189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
510fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
511fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
512fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  // Handle messages to Class.
513b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
5142b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    ObjCMethodDecl *Method = 0;
5156b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff
5166562fdad21432377f0cc5e0c627c28f0c85df4ddChris Lattner    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
517d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
518d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff        // First check the public methods in the class interface.
5196ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor        Method = ClassDecl->lookupClassMethod(Context, Sel);
520d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff
521f1afaf6fe2d94ab265299853f288b676694f7554Steve Naroff        if (!Method)
5225609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff          Method = LookupPrivateClassMethod(Sel, ClassDecl);
523d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff      }
52448f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
52548f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor        return true;
526d526c2f2ef28643c15589135b59eb4a8d9f9414cSteve Naroff    }
5276b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    if (!Method) {
5286b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      // If not messaging 'self', look for any factory method named 'Sel'.
5296b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      if (!isSelfExpr(RExpr)) {
530f0aaf7a59729a4ae0146e3464ee987745be95829Douglas Gregor        Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
531b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        if (!Method) {
532041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          // If no class (factory) method was found, check if an _instance_
533041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          // method of the same name exists in the root class only.
5346b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
5356b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                                   Sel, SourceRange(lbrac,rbrac));
536041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian          if (Method)
537041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian              if (const ObjCInterfaceDecl *ID =
538041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
539041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian              if (ID->getSuperClass())
540041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                Diag(lbrac, diag::warn_root_inst_method_not_found)
541041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian                  << Sel << SourceRange(lbrac, rbrac);
542041f2fd6237c7ce72864e42c66c6b12b52f35f9cFariborz Jahanian            }
543b1006c7f5647025541b1b1cc64a196a417e6c6acFariborz Jahanian        }
5446b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff      }
5456b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff    }
546077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
547637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                  lbrac, rbrac, returnType))
548637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar      return true;
5498189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
5508189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                         rbrac, ArgExprs, NumArgs);
551fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
552fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
5532b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  ObjCMethodDecl *Method = 0;
554fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  ObjCInterfaceDecl* ClassDecl = 0;
5552b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner
5562b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
5572b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner  // long as one of the protocols implements the selector (if not, warn).
558b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
559f7f52e7bf5a4dc36d45b98531e0b21e343fc19deSteve Naroff    // Search protocols for instance methods.
560fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
561fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
5626ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor      if (PDecl && (Method = PDecl->lookupInstanceMethod(Context, Sel)))
563fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner        break;
564ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff      // Since we aren't supporting "Class<foo>", look for a class method.
5656ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor      if (PDecl && (Method = PDecl->lookupClassMethod(Context, Sel)))
566ebaa768521cfd5318d77f1efaf7ae47020863a9dSteve Naroff        break;
567fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    }
568279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff  } else if (const ObjCInterfaceType *OCIType =
569b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner                ReceiverCType->getAsPointerToObjCInterfaceType()) {
5702b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    // We allow sending a message to a pointer to an interface (an object).
571fb8cc1dfd87a1cbbaa17d64ec753d3fe8a9e9c38Chris Lattner
572279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff    ClassDecl = OCIType->getDecl();
573037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
574037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // faster than the following method (which can do *many* linear searches).
575037cda5282e73f30bb09fa316047554b1af1e2efSteve Naroff    // The idea is to add class info to InstanceMethodPool.
5766ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor    Method = ClassDecl->lookupInstanceMethod(Context, Sel);
577fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
578fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner    if (!Method) {
579fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner      // Search protocol qualifiers.
580279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff      for (ObjCQualifiedInterfaceType::qual_iterator QI = OCIType->qual_begin(),
581279d896d4972417f62537fe4a87a8c3c3d675108Steve Naroff           E = OCIType->qual_end(); QI != E; ++QI) {
5826ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor        if ((Method = (*QI)->lookupInstanceMethod(Context, Sel)))
58385a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner          break;
58485a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner      }
58585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner    }
5860de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    if (!Method) {
5875609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      // If we have implementations in scope, check "private" methods.
5885609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
5895609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff
5905609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff      if (!Method && !isSelfExpr(RExpr)) {
5916b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // If we still haven't found a method, look in the global pool. This
5926b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // behavior isn't very desirable, however we need it for GCC
5936b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        // compatibility. FIXME: should we deviate??
5945609ec04ed9a4fd58c3203d210cf32e9283feb5eSteve Naroff        if (OCIType->qual_empty()) {
5956b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          Method = LookupInstanceMethodInGlobalPool(
5966b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff                               Sel, SourceRange(lbrac,rbrac));
5976b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff          if (Method && !OCIType->getDecl()->isForwardDecl())
5986b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff            Diag(lbrac, diag::warn_maynot_respond)
5996b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff              << OCIType->getDecl()->getIdentifier()->getName() << Sel;
6006b9dfd4257b85c388a9e3cd345cf28acb7351006Steve Naroff        }
601268bc8c1f3a27d2fbd73c3115e4d633d31422ca5Fariborz Jahanian      }
6020de21fd85d79bccd32f04256f5b3328ab5ed7c95Steve Naroff    }
60348f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
60448f3bb9f780f6e64ab71ba0202ca04b07473805aDouglas Gregor      return true;
6050c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else if (!Context.getObjCIdType().isNull() &&
6060c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner             (ReceiverCType->isPointerType() ||
6070c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner              (ReceiverCType->isIntegerType() &&
6080c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner               ReceiverCType->isScalarType()))) {
6090c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Implicitly convert integers and pointers to 'id' but emit a warning.
6108e2945ad9104f0ce4928c386faf458b6b83d9060Steve Naroff    Diag(lbrac, diag::warn_bad_receiver_type)
611d162584991885ab004a02573a73ce06422b921fcChris Lattner      << RExpr->getType() << RExpr->getSourceRange();
6120c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    ImpCastExprToType(RExpr, Context.getObjCIdType());
6130c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner  } else {
6140c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    // Reject other random receiver types (e.g. structs).
6150c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner    Diag(lbrac, diag::err_bad_receiver_type)
6160c73f37f0a48a1512bc0477a71f0d6cffcb78fc0Chris Lattner      << RExpr->getType() << RExpr->getSourceRange();
6172b1cc8be4dda4cd122485be0168b3c43d7dff15fChris Lattner    return true;
618fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner  }
619fe1a553256b46fad3c0a9e9967481bcf571339ecChris Lattner
620077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattner  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
621637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar                                lbrac, rbrac, returnType))
622637cebb67c59765e1412c589550c8c9ba001baebDaniel Dunbar    return true;
6238189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek  return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
6248189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek                                       rbrac, ArgExprs, NumArgs);
62585a932e26f3c3faae6bad639a6d32e92794dfda9Chris Lattner}
626eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
627eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===//
628eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner// ObjCQualifiedIdTypesAreCompatible - Compatibility testing for qualified id's.
629eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner//===----------------------------------------------------------------------===//
630eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
631eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ProtocolCompatibleWithProtocol - return 'true' if 'lProto' is in the
632eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// inheritance hierarchy of 'rProto'.
633eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
634eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                           ObjCProtocolDecl *rProto) {
635eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (lProto == rProto)
636eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    return true;
637780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner  for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
638780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner       E = rProto->protocol_end(); PI != E; ++PI)
639780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner    if (ProtocolCompatibleWithProtocol(lProto, *PI))
640eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
641eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  return false;
642eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
643eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
644eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// ClassImplementsProtocol - Checks that 'lProto' protocol
645eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// has been implemented in IDecl class, its super class or categories (if
646eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner/// lookupCategory is true).
647eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerstatic bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
648eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                    ObjCInterfaceDecl *IDecl,
64926631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                                    bool lookupCategory,
65026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                                    bool RHSIsQualifiedID = false) {
651eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
652eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 1st, look up the class.
6533db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  const ObjCList<ObjCProtocolDecl> &Protocols =
6543db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    IDecl->getReferencedProtocols();
6553db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner
6563db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner  for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
6573db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner       E = Protocols.end(); PI != E; ++PI) {
6583db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    if (ProtocolCompatibleWithProtocol(lProto, *PI))
659eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
66026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // This is dubious and is added to be compatible with gcc.
66126631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // In gcc, it is also allowed assigning a protocol-qualified 'id'
66226631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // type to a LHS object when protocol in qualified LHS is in list
66326631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian    // of protocols in the rhs 'id' object. This IMO, should be a bug.
664fd5b2ce150185d8d8fc3d7789983bbd2b0b8103fTed Kremenek    // FIXME: Treat this as an extension, and flag this as an error when
665fd5b2ce150185d8d8fc3d7789983bbd2b0b8103fTed Kremenek    //  GCC extensions are not enabled.
6663db6cae19c236fe2cef343c90105ce7cca7de965Chris Lattner    if (RHSIsQualifiedID && ProtocolCompatibleWithProtocol(*PI, lProto))
66726631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      return true;
668eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
669eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
670eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 2nd, look up the category.
671eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (lookupCategory)
672eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    for (ObjCCategoryDecl *CDecl = IDecl->getCategoryList(); CDecl;
673eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner         CDecl = CDecl->getNextClassCategory()) {
674780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner      for (ObjCCategoryDecl::protocol_iterator PI = CDecl->protocol_begin(),
675780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner           E = CDecl->protocol_end(); PI != E; ++PI)
676780f329cb011bff0da5763e2e9744eec093d0509Chris Lattner        if (ProtocolCompatibleWithProtocol(lProto, *PI))
677eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          return true;
678eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
679eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
680eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // 3rd, look up the super class(s)
681eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (IDecl->getSuperClass())
682eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    return
68326631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory,
68426631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian                              RHSIsQualifiedID);
685eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
686eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  return false;
687eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
688eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
689b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an
690b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner/// ObjCQualifiedIDType.
69115edf0de6b5bc9ae227bcc9658a157ac30efd92eSteve Naroff/// FIXME: Move to ASTContext::typesAreCompatible() and friends.
692eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattnerbool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
693eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner                                             bool compare) {
694eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  // Allow id<P..> and an 'id' or void* type in all cases.
695eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  if (const PointerType *PT = lhs->getAsPointerType()) {
696eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    QualType PointeeTy = PT->getPointeeType();
6972c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner    if (PointeeTy->isVoidType() ||
6982c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner        Context.isObjCIdStructType(PointeeTy) ||
6992c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner        Context.isObjCClassStructType(PointeeTy))
700eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
701eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  } else if (const PointerType *PT = rhs->getAsPointerType()) {
702eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    QualType PointeeTy = PT->getPointeeType();
7032c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner    if (PointeeTy->isVoidType() ||
7042c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner        Context.isObjCIdStructType(PointeeTy) ||
7052c4463f744487e242f7c88b6daa0abf5cb24219eChris Lattner        Context.isObjCClassStructType(PointeeTy))
706eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      return true;
707eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
708eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
709b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
710b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
711b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    const ObjCQualifiedInterfaceType *rhsQI = 0;
712289d9f243d9074513368d27eef3b647f72a38324Steve Naroff    QualType rtype;
713289d9f243d9074513368d27eef3b647f72a38324Steve Naroff
714b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    if (!rhsQID) {
715b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      // Not comparing two ObjCQualifiedIdType's?
716b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (!rhs->isPointerType()) return false;
717289d9f243d9074513368d27eef3b647f72a38324Steve Naroff
718289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      rtype = rhs->getAsPointerType()->getPointeeType();
719eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      rhsQI = rtype->getAsObjCQualifiedInterfaceType();
720b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (rhsQI == 0) {
721289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // If the RHS is a unqualified interface pointer "NSString*",
722289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // make sure we check the class hierarchy.
723b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
724b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          ObjCInterfaceDecl *rhsID = IT->getDecl();
725b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
726b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            // when comparing an id<P> on lhs with a static type on rhs,
727b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            // see if static class implements all of id's protocols, directly or
728b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            // through its super class and categories.
729b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner            if (!ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true))
730b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner              return false;
731b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          }
732b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          return true;
733b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        }
734b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      }
735eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
736eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
737eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE;
738289d9f243d9074513368d27eef3b647f72a38324Steve Naroff    if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *").
739eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoI = rhsQI->qual_begin();
740eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoE = rhsQI->qual_end();
741289d9f243d9074513368d27eef3b647f72a38324Steve Naroff    } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *").
742eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoI = rhsQID->qual_begin();
743eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      RHSProtoE = rhsQID->qual_end();
744b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    } else {
745b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      return false;
746eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
747eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
748eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) {
749eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      ObjCProtocolDecl *lhsProto = lhsQID->getProtocols(i);
750eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      bool match = false;
751eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
752eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // when comparing an id<P> on lhs with a static type on rhs,
753eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // see if static class implements all of id's protocols, directly or
754eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      // through its super class and categories.
755b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      for (; RHSProtoI != RHSProtoE; ++RHSProtoI) {
756b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        ObjCProtocolDecl *rhsProto = *RHSProtoI;
757b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
75882b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
759eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          match = true;
760b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner          break;
761eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        }
762eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      }
763289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      if (rhsQI) {
764289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // If the RHS is a qualified interface pointer "NSString<P>*",
765289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        // make sure we check the class hierarchy.
766289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) {
767289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          ObjCInterfaceDecl *rhsID = IT->getDecl();
768289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) {
769289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            // when comparing an id<P> on lhs with a static type on rhs,
770289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            // see if static class implements all of id's protocols, directly or
771289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            // through its super class and categories.
772289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) {
773289d9f243d9074513368d27eef3b647f72a38324Steve Naroff              match = true;
774289d9f243d9074513368d27eef3b647f72a38324Steve Naroff              break;
775289d9f243d9074513368d27eef3b647f72a38324Steve Naroff            }
776289d9f243d9074513368d27eef3b647f72a38324Steve Naroff          }
777289d9f243d9074513368d27eef3b647f72a38324Steve Naroff        }
778289d9f243d9074513368d27eef3b647f72a38324Steve Naroff      }
779eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      if (!match)
780eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        return false;
781eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
782eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
783b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
784b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  }
785b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
786b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType();
787b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  assert(rhsQID && "One of the LHS/RHS should be id<x>");
788eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
789b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (!lhs->isPointerType())
790b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return false;
791b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
792b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  QualType ltype = lhs->getAsPointerType()->getPointeeType();
793b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCQualifiedInterfaceType *lhsQI =
794b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner         ltype->getAsObjCQualifiedInterfaceType()) {
795b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    ObjCQualifiedIdType::qual_iterator LHSProtoI = lhsQI->qual_begin();
796b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    ObjCQualifiedIdType::qual_iterator LHSProtoE = lhsQI->qual_end();
797b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    for (; LHSProtoI != LHSProtoE; ++LHSProtoI) {
798b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      bool match = false;
799b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      ObjCProtocolDecl *lhsProto = *LHSProtoI;
800eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
801eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
802b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
80382b4e768d38c12ceba7db23a96e8d845e00fdeb7Eli Friedman            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
804eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          match = true;
805eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner          break;
806eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner        }
807eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner      }
808b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      if (!match)
809b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        return false;
810eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner    }
811b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
812b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  }
813b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner
814b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  if (const ObjCInterfaceType *IT = ltype->getAsObjCInterfaceType()) {
815b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    // for static type vs. qualified 'id' type, check that class implements
816b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    // all of 'id's protocols.
817b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    ObjCInterfaceDecl *lhsID = IT->getDecl();
818b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
819b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner      ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
82026631704d15e2fe19bae8a22939e0a473407c20dFariborz Jahanian      if (!ClassImplementsProtocol(rhsProto, lhsID, compare, true))
821b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner        return false;
822b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    }
823b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner    return true;
824eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner  }
825b1698cf972be75084d760c82389ab5b49a386c31Chris Lattner  return false;
826eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner}
827eca7be6b7ebd93682eeaab2c71d59f2995dacdccChris Lattner
828