SemaExprObjC.cpp revision 1ce05a85971be4d02f9bb3f6ca8198364e32bfcb
1//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements semantic analysis for Objective-C expressions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/DeclObjC.h"
17#include "clang/AST/ExprObjC.h"
18#include "llvm/ADT/SmallString.h"
19#include "clang/Lex/Preprocessor.h"
20
21using namespace clang;
22
23Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
24                                              ExprTy **strings,
25                                              unsigned NumStrings) {
26  StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
27
28  // Most ObjC strings are formed out of a single piece.  However, we *can*
29  // have strings formed out of multiple @ strings with multiple pptokens in
30  // each one, e.g. @"foo" "bar" @"baz" "qux"   which need to be turned into one
31  // StringLiteral for ObjCStringLiteral to hold onto.
32  StringLiteral *S = Strings[0];
33
34  // If we have a multi-part string, merge it all together.
35  if (NumStrings != 1) {
36    // Concatenate objc strings.
37    llvm::SmallString<128> StrBuf;
38    llvm::SmallVector<SourceLocation, 8> StrLocs;
39
40    for (unsigned i = 0; i != NumStrings; ++i) {
41      S = Strings[i];
42
43      // ObjC strings can't be wide.
44      if (S->isWide()) {
45        Diag(S->getLocStart(), diag::err_cfstring_literal_not_string_constant)
46          << S->getSourceRange();
47        return true;
48      }
49
50      // Get the string data.
51      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
52
53      // Get the locations of the string tokens.
54      StrLocs.append(S->tokloc_begin(), S->tokloc_end());
55
56      // Free the temporary string.
57      S->Destroy(Context);
58    }
59
60    // Create the aggregate string with the appropriate content and location
61    // information.
62    S = StringLiteral::Create(Context, &StrBuf[0], StrBuf.size(), false,
63                              Context.getPointerType(Context.CharTy),
64                              &StrLocs[0], StrLocs.size());
65  }
66
67  // Verify that this composite string is acceptable for ObjC strings.
68  if (CheckObjCString(S))
69    return true;
70
71  // Initialize the constant string interface lazily. This assumes
72  // the NSString interface is seen in this translation unit. Note: We
73  // don't use NSConstantString, since the runtime team considers this
74  // interface private (even though it appears in the header files).
75  QualType Ty = Context.getObjCConstantStringInterface();
76  if (!Ty.isNull()) {
77    Ty = Context.getObjCObjectPointerType(Ty);
78  } else {
79    IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
80    NamedDecl *IF = LookupSingleName(TUScope, NSIdent, LookupOrdinaryName);
81    if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
82      Context.setObjCConstantStringInterface(StrIF);
83      Ty = Context.getObjCConstantStringInterface();
84      Ty = Context.getObjCObjectPointerType(Ty);
85    } else {
86      // If there is no NSString interface defined then treat constant
87      // strings as untyped objects and let the runtime figure it out later.
88      Ty = Context.getObjCIdType();
89    }
90  }
91
92  return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
93}
94
95Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
96                                      QualType EncodedType,
97                                      SourceLocation RParenLoc) {
98  QualType StrTy;
99  if (EncodedType->isDependentType())
100    StrTy = Context.DependentTy;
101  else {
102    std::string Str;
103    Context.getObjCEncodingForType(EncodedType, Str);
104
105    // The type of @encode is the same as the type of the corresponding string,
106    // which is an array type.
107    StrTy = Context.CharTy;
108    // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
109    if (getLangOptions().CPlusPlus)
110      StrTy.addConst();
111    StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
112                                         ArrayType::Normal, 0);
113  }
114
115  return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
116}
117
118Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
119                                                 SourceLocation EncodeLoc,
120                                                 SourceLocation LParenLoc,
121                                                 TypeTy *ty,
122                                                 SourceLocation RParenLoc) {
123  // FIXME: Preserve type source info ?
124  QualType EncodedType = GetTypeFromParser(ty);
125
126  return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc);
127}
128
129Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
130                                                   SourceLocation AtLoc,
131                                                   SourceLocation SelLoc,
132                                                   SourceLocation LParenLoc,
133                                                   SourceLocation RParenLoc) {
134  ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
135                             SourceRange(LParenLoc, RParenLoc), false);
136  if (!Method)
137    Method = LookupFactoryMethodInGlobalPool(Sel,
138                                          SourceRange(LParenLoc, RParenLoc));
139  if (!Method)
140    Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
141
142  QualType Ty = Context.getObjCSelType();
143  return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
144}
145
146Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
147                                                   SourceLocation AtLoc,
148                                                   SourceLocation ProtoLoc,
149                                                   SourceLocation LParenLoc,
150                                                   SourceLocation RParenLoc) {
151  ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId);
152  if (!PDecl) {
153    Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
154    return true;
155  }
156
157  QualType Ty = Context.getObjCProtoType();
158  if (Ty.isNull())
159    return true;
160  Ty = Context.getObjCObjectPointerType(Ty);
161  return new (Context) ObjCProtocolExpr(Ty, PDecl, AtLoc, RParenLoc);
162}
163
164bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
165                                     Selector Sel, ObjCMethodDecl *Method,
166                                     bool isClassMessage,
167                                     SourceLocation lbrac, SourceLocation rbrac,
168                                     QualType &ReturnType) {
169  if (!Method) {
170    // Apply default argument promotion as for (C99 6.5.2.2p6).
171    for (unsigned i = 0; i != NumArgs; i++)
172      DefaultArgumentPromotion(Args[i]);
173
174    unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
175                                       diag::warn_inst_method_not_found;
176    Diag(lbrac, DiagID)
177      << Sel << isClassMessage << SourceRange(lbrac, rbrac);
178    ReturnType = Context.getObjCIdType();
179    return false;
180  }
181
182  ReturnType = Method->getResultType();
183
184  unsigned NumNamedArgs = Sel.getNumArgs();
185  assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
186
187  bool IsError = false;
188  for (unsigned i = 0; i < NumNamedArgs; i++) {
189    Expr *argExpr = Args[i];
190    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
191
192    QualType lhsType = Method->param_begin()[i]->getType();
193    QualType rhsType = argExpr->getType();
194
195    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8].
196    if (lhsType->isArrayType())
197      lhsType = Context.getArrayDecayedType(lhsType);
198    else if (lhsType->isFunctionType())
199      lhsType = Context.getPointerType(lhsType);
200
201    AssignConvertType Result =
202      CheckSingleAssignmentConstraints(lhsType, argExpr);
203    if (Args[i] != argExpr) // The expression was converted.
204      Args[i] = argExpr; // Make sure we store the converted expression.
205
206    IsError |=
207      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
208                               argExpr, AA_Sending);
209  }
210
211  // Promote additional arguments to variadic methods.
212  if (Method->isVariadic()) {
213    for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
214      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
215  } else {
216    // Check for extra arguments to non-variadic methods.
217    if (NumArgs != NumNamedArgs) {
218      Diag(Args[NumNamedArgs]->getLocStart(),
219           diag::err_typecheck_call_too_many_args)
220        << 2 /*method*/ << Method->getSourceRange()
221        << SourceRange(Args[NumNamedArgs]->getLocStart(),
222                       Args[NumArgs-1]->getLocEnd());
223    }
224  }
225
226  return IsError;
227}
228
229bool Sema::isSelfExpr(Expr *RExpr) {
230  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr))
231    if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
232      return true;
233  return false;
234}
235
236// Helper method for ActOnClassMethod/ActOnInstanceMethod.
237// Will search "local" class/category implementations for a method decl.
238// If failed, then we search in class's root for an instance method.
239// Returns 0 if no method is found.
240ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
241                                          ObjCInterfaceDecl *ClassDecl) {
242  ObjCMethodDecl *Method = 0;
243  // lookup in class and all superclasses
244  while (ClassDecl && !Method) {
245    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
246      Method = ImpDecl->getClassMethod(Sel);
247
248    // Look through local category implementations associated with the class.
249    if (!Method)
250      Method = ClassDecl->getCategoryClassMethod(Sel);
251
252    // Before we give up, check if the selector is an instance method.
253    // But only in the root. This matches gcc's behaviour and what the
254    // runtime expects.
255    if (!Method && !ClassDecl->getSuperClass()) {
256      Method = ClassDecl->lookupInstanceMethod(Sel);
257      // Look through local category implementations associated
258      // with the root class.
259      if (!Method)
260        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
261    }
262
263    ClassDecl = ClassDecl->getSuperClass();
264  }
265  return Method;
266}
267
268ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
269                                              ObjCInterfaceDecl *ClassDecl) {
270  ObjCMethodDecl *Method = 0;
271  while (ClassDecl && !Method) {
272    // If we have implementations in scope, check "private" methods.
273    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
274      Method = ImpDecl->getInstanceMethod(Sel);
275
276    // Look through local category implementations associated with the class.
277    if (!Method)
278      Method = ClassDecl->getCategoryInstanceMethod(Sel);
279    ClassDecl = ClassDecl->getSuperClass();
280  }
281  return Method;
282}
283
284Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
285  IdentifierInfo &receiverName,
286  IdentifierInfo &propertyName,
287  SourceLocation &receiverNameLoc,
288  SourceLocation &propertyNameLoc) {
289
290  IdentifierInfo *receiverNamePtr = &receiverName;
291  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr);
292
293  // Search for a declared property first.
294
295  Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
296  ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
297
298  // If this reference is in an @implementation, check for 'private' methods.
299  if (!Getter)
300    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
301      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
302        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
303          Getter = ImpDecl->getClassMethod(Sel);
304
305  if (Getter) {
306    // FIXME: refactor/share with ActOnMemberReference().
307    // Check if we can reference this property.
308    if (DiagnoseUseOfDecl(Getter, propertyNameLoc))
309      return ExprError();
310  }
311
312  // Look for the matching setter, in case it is needed.
313  Selector SetterSel =
314    SelectorTable::constructSetterName(PP.getIdentifierTable(),
315                                       PP.getSelectorTable(), &propertyName);
316
317  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
318  if (!Setter) {
319    // If this reference is in an @implementation, also check for 'private'
320    // methods.
321    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
322      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
323        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
324          Setter = ImpDecl->getClassMethod(SetterSel);
325  }
326  // Look through local category implementations associated with the class.
327  if (!Setter)
328    Setter = IFace->getCategoryClassMethod(SetterSel);
329
330  if (Setter && DiagnoseUseOfDecl(Setter, propertyNameLoc))
331    return ExprError();
332
333  if (Getter || Setter) {
334    QualType PType;
335
336    if (Getter)
337      PType = Getter->getResultType();
338    else {
339      for (ObjCMethodDecl::param_iterator PI = Setter->param_begin(),
340           E = Setter->param_end(); PI != E; ++PI)
341        PType = (*PI)->getType();
342    }
343    return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(
344                                  Getter, PType, Setter,
345                                  propertyNameLoc, IFace, receiverNameLoc));
346  }
347  return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
348                     << &propertyName << Context.getObjCInterfaceType(IFace));
349}
350
351
352// ActOnClassMessage - used for both unary and keyword messages.
353// ArgExprs is optional - if it is present, the number of expressions
354// is obtained from Sel.getNumArgs().
355Sema::ExprResult Sema::ActOnClassMessage(
356  Scope *S,
357  IdentifierInfo *receiverName, Selector Sel,
358  SourceLocation lbrac, SourceLocation receiverLoc,
359  SourceLocation selectorLoc, SourceLocation rbrac,
360  ExprTy **Args, unsigned NumArgs) {
361  assert(receiverName && "missing receiver class name");
362
363  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
364  ObjCInterfaceDecl* ClassDecl = 0;
365  bool isSuper = false;
366
367  if (receiverName->isStr("super")) {
368    if (getCurMethodDecl()) {
369      isSuper = true;
370      ObjCInterfaceDecl *OID = getCurMethodDecl()->getClassInterface();
371      if (!OID)
372        return Diag(lbrac, diag::error_no_super_class_message)
373                      << getCurMethodDecl()->getDeclName();
374      ClassDecl = OID->getSuperClass();
375      if (!ClassDecl)
376        return Diag(lbrac, diag::error_no_super_class) << OID->getDeclName();
377      if (getCurMethodDecl()->isInstanceMethod()) {
378        QualType superTy = Context.getObjCInterfaceType(ClassDecl);
379        superTy = Context.getObjCObjectPointerType(superTy);
380        ExprResult ReceiverExpr = new (Context) ObjCSuperExpr(SourceLocation(),
381                                                              superTy);
382        // We are really in an instance method, redirect.
383        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
384                                    selectorLoc, rbrac, Args, NumArgs);
385      }
386      // We are sending a message to 'super' within a class method. Do nothing,
387      // the receiver will pass through as 'super' (how convenient:-).
388    } else {
389      // 'super' has been used outside a method context. If a variable named
390      // 'super' has been declared, redirect. If not, produce a diagnostic.
391      NamedDecl *SuperDecl
392        = LookupSingleName(S, receiverName, LookupOrdinaryName);
393      ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
394      if (VD) {
395        ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(),
396                                                            receiverLoc);
397        // We are really in an instance method, redirect.
398        return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac,
399                                    selectorLoc, rbrac, Args, NumArgs);
400      }
401      return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName;
402    }
403  } else
404    ClassDecl = getObjCInterfaceDecl(receiverName, receiverLoc);
405
406  // The following code allows for the following GCC-ism:
407  //
408  //  typedef XCElementDisplayRect XCElementGraphicsRect;
409  //
410  //  @implementation XCRASlice
411  //  - whatever { // Note that XCElementGraphicsRect is a typedef name.
412  //    _sGraphicsDelegate =[[XCElementGraphicsRect alloc] init];
413  //  }
414  //
415  // If necessary, the following lookup could move to getObjCInterfaceDecl().
416  if (!ClassDecl) {
417    NamedDecl *IDecl
418      = LookupSingleName(TUScope, receiverName, LookupOrdinaryName);
419    if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
420      const ObjCInterfaceType *OCIT;
421      OCIT = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>();
422      if (!OCIT) {
423        Diag(receiverLoc, diag::err_invalid_receiver_to_message);
424        return true;
425      }
426      ClassDecl = OCIT->getDecl();
427    }
428  }
429  assert(ClassDecl && "missing interface declaration");
430  ObjCMethodDecl *Method = 0;
431  QualType returnType;
432  if (ClassDecl->isForwardDecl()) {
433    // A forward class used in messaging is tread as a 'Class'
434    Diag(lbrac, diag::warn_receiver_forward_class) << ClassDecl->getDeclName();
435    Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
436    if (Method)
437      Diag(Method->getLocation(), diag::note_method_sent_forward_class)
438        << Method->getDeclName();
439  }
440  if (!Method)
441    Method = ClassDecl->lookupClassMethod(Sel);
442
443  // If we have an implementation in scope, check "private" methods.
444  if (!Method)
445    Method = LookupPrivateClassMethod(Sel, ClassDecl);
446
447  if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
448    return true;
449
450  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true,
451                                lbrac, rbrac, returnType))
452    return true;
453
454  returnType = returnType.getNonReferenceType();
455
456  // If we have the ObjCInterfaceDecl* for the class that is receiving the
457  // message, use that to construct the ObjCMessageExpr.  Otherwise pass on the
458  // IdentifierInfo* for the class.
459  // FIXME: need to do a better job handling 'super' usage within a class.  For
460  // now, we simply pass the "super" identifier through (which isn't consistent
461  // with instance methods.
462  if (isSuper)
463    return new (Context) ObjCMessageExpr(receiverName, Sel, returnType, Method,
464                                         lbrac, rbrac, ArgExprs, NumArgs);
465  else
466    return new (Context) ObjCMessageExpr(ClassDecl, Sel, returnType, Method,
467                                         lbrac, rbrac, ArgExprs, NumArgs);
468}
469
470// ActOnInstanceMessage - used for both unary and keyword messages.
471// ArgExprs is optional - if it is present, the number of expressions
472// is obtained from Sel.getNumArgs().
473Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
474                                            SourceLocation lbrac,
475                                            SourceLocation receiverLoc,
476                                            SourceLocation rbrac,
477                                            ExprTy **Args, unsigned NumArgs) {
478  assert(receiver && "missing receiver expression");
479
480  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
481  Expr *RExpr = static_cast<Expr *>(receiver);
482
483  // If necessary, apply function/array conversion to the receiver.
484  // C99 6.7.5.3p[7,8].
485  DefaultFunctionArrayConversion(RExpr);
486
487  QualType returnType;
488  QualType ReceiverCType =
489    Context.getCanonicalType(RExpr->getType()).getUnqualifiedType();
490
491  // Handle messages to 'super'.
492  if (isa<ObjCSuperExpr>(RExpr)) {
493    ObjCMethodDecl *Method = 0;
494    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
495      // If we have an interface in scope, check 'super' methods.
496      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
497        if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
498          Method = SuperDecl->lookupInstanceMethod(Sel);
499
500          if (!Method)
501            // If we have implementations in scope, check "private" methods.
502            Method = LookupPrivateInstanceMethod(Sel, SuperDecl);
503        }
504    }
505
506    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
507      return true;
508
509    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
510                                  lbrac, rbrac, returnType))
511      return true;
512
513    returnType = returnType.getNonReferenceType();
514    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
515                                         rbrac, ArgExprs, NumArgs);
516  }
517
518  // Handle messages to id.
519  if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() ||
520      Context.isObjCNSObjectType(RExpr->getType())) {
521    ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
522                               Sel, SourceRange(lbrac,rbrac));
523    if (!Method)
524      Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac, rbrac));
525    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
526                                  lbrac, rbrac, returnType))
527      return true;
528    returnType = returnType.getNonReferenceType();
529    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
530                                         rbrac, ArgExprs, NumArgs);
531  }
532
533  // Handle messages to Class.
534  if (ReceiverCType->isObjCClassType() ||
535      ReceiverCType->isObjCQualifiedClassType()) {
536    ObjCMethodDecl *Method = 0;
537
538    if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
539      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
540        // First check the public methods in the class interface.
541        Method = ClassDecl->lookupClassMethod(Sel);
542
543        if (!Method)
544          Method = LookupPrivateClassMethod(Sel, ClassDecl);
545
546        // FIXME: if we still haven't found a method, we need to look in
547        // protocols (if we have qualifiers).
548      }
549      if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
550        return true;
551    }
552    if (!Method) {
553      // If not messaging 'self', look for any factory method named 'Sel'.
554      if (!isSelfExpr(RExpr)) {
555        Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
556        if (!Method) {
557          // If no class (factory) method was found, check if an _instance_
558          // method of the same name exists in the root class only.
559          Method = LookupInstanceMethodInGlobalPool(
560                                   Sel, SourceRange(lbrac,rbrac));
561          if (Method)
562              if (const ObjCInterfaceDecl *ID =
563                dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
564              if (ID->getSuperClass())
565                Diag(lbrac, diag::warn_root_inst_method_not_found)
566                  << Sel << SourceRange(lbrac, rbrac);
567            }
568        }
569      }
570    }
571    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
572                                  lbrac, rbrac, returnType))
573      return true;
574    returnType = returnType.getNonReferenceType();
575    return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
576                                         rbrac, ArgExprs, NumArgs);
577  }
578
579  ObjCMethodDecl *Method = 0;
580  ObjCInterfaceDecl* ClassDecl = 0;
581
582  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
583  // long as one of the protocols implements the selector (if not, warn).
584  if (const ObjCObjectPointerType *QIdTy =
585        ReceiverCType->getAsObjCQualifiedIdType()) {
586    // Search protocols for instance methods.
587    for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
588         E = QIdTy->qual_end(); I != E; ++I) {
589      ObjCProtocolDecl *PDecl = *I;
590      if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
591        break;
592      // Since we aren't supporting "Class<foo>", look for a class method.
593      if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
594        break;
595    }
596  } else if (const ObjCObjectPointerType *OCIType =
597                ReceiverCType->getAsObjCInterfacePointerType()) {
598    // We allow sending a message to a pointer to an interface (an object).
599
600    ClassDecl = OCIType->getInterfaceDecl();
601    // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
602    // faster than the following method (which can do *many* linear searches).
603    // The idea is to add class info to InstanceMethodPool.
604    Method = ClassDecl->lookupInstanceMethod(Sel);
605
606    if (!Method) {
607      // Search protocol qualifiers.
608      for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
609           E = OCIType->qual_end(); QI != E; ++QI) {
610        if ((Method = (*QI)->lookupInstanceMethod(Sel)))
611          break;
612      }
613    }
614    if (!Method) {
615      // If we have implementations in scope, check "private" methods.
616      Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
617
618      if (!Method && !isSelfExpr(RExpr)) {
619        // If we still haven't found a method, look in the global pool. This
620        // behavior isn't very desirable, however we need it for GCC
621        // compatibility. FIXME: should we deviate??
622        if (OCIType->qual_empty()) {
623          Method = LookupInstanceMethodInGlobalPool(
624                               Sel, SourceRange(lbrac,rbrac));
625          if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
626            Diag(lbrac, diag::warn_maynot_respond)
627              << OCIType->getInterfaceDecl()->getIdentifier()->getName() << Sel;
628        }
629      }
630    }
631    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
632      return true;
633  } else if (!Context.getObjCIdType().isNull() &&
634             (ReceiverCType->isPointerType() ||
635              (ReceiverCType->isIntegerType() &&
636               ReceiverCType->isScalarType()))) {
637    // Implicitly convert integers and pointers to 'id' but emit a warning.
638    Diag(lbrac, diag::warn_bad_receiver_type)
639      << RExpr->getType() << RExpr->getSourceRange();
640    if (ReceiverCType->isPointerType())
641      ImpCastExprToType(RExpr, Context.getObjCIdType(), CastExpr::CK_BitCast);
642    else
643      ImpCastExprToType(RExpr, Context.getObjCIdType(),
644                        CastExpr::CK_IntegralToPointer);
645  } else {
646    // Reject other random receiver types (e.g. structs).
647    Diag(lbrac, diag::err_bad_receiver_type)
648      << RExpr->getType() << RExpr->getSourceRange();
649    return true;
650  }
651
652  if (Method)
653    DiagnoseSentinelCalls(Method, receiverLoc, ArgExprs, NumArgs);
654  if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
655                                lbrac, rbrac, returnType))
656    return true;
657  returnType = returnType.getNonReferenceType();
658  return new (Context) ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac,
659                                       rbrac, ArgExprs, NumArgs);
660}
661
662