SemaPseudoObject.cpp revision 88507ddf6f83b929454c04470924cf56b4b8147a
1//===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===//
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 expressions involving
11//  pseudo-object references.  Pseudo-objects are conceptual objects
12//  whose storage is entirely abstract and all accesses to which are
13//  translated through some sort of abstraction barrier.
14//
15//  For example, Objective-C objects can have "properties", either
16//  declared or undeclared.  A property may be accessed by writing
17//    expr.prop
18//  where 'expr' is an r-value of Objective-C pointer type and 'prop'
19//  is the name of the property.  If this expression is used in a context
20//  needing an r-value, it is treated as if it were a message-send
21//  of the associated 'getter' selector, typically:
22//    [expr prop]
23//  If it is used as the LHS of a simple assignment, it is treated
24//  as a message-send of the associated 'setter' selector, typically:
25//    [expr setProp: RHS]
26//  If it is used as the LHS of a compound assignment, or the operand
27//  of a unary increment or decrement, both are required;  for example,
28//  'expr.prop *= 100' would be translated to:
29//    [expr setProp: [expr prop] * 100]
30//
31//===----------------------------------------------------------------------===//
32
33#include "clang/Sema/SemaInternal.h"
34#include "clang/Sema/Initialization.h"
35#include "clang/AST/ExprObjC.h"
36#include "clang/Lex/Preprocessor.h"
37
38using namespace clang;
39using namespace sema;
40
41namespace {
42  // Basically just a very focused copy of TreeTransform.
43  template <class T> struct Rebuilder {
44    Sema &S;
45    Rebuilder(Sema &S) : S(S) {}
46
47    T &getDerived() { return static_cast<T&>(*this); }
48
49    Expr *rebuild(Expr *e) {
50      // Fast path: nothing to look through.
51      if (typename T::specific_type *specific
52            = dyn_cast<typename T::specific_type>(e))
53        return getDerived().rebuildSpecific(specific);
54
55      // Otherwise, we should look through and rebuild anything that
56      // IgnoreParens would.
57
58      if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
59        e = rebuild(parens->getSubExpr());
60        return new (S.Context) ParenExpr(parens->getLParen(),
61                                         parens->getRParen(),
62                                         e);
63      }
64
65      if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
66        assert(uop->getOpcode() == UO_Extension);
67        e = rebuild(uop->getSubExpr());
68        return new (S.Context) UnaryOperator(e, uop->getOpcode(),
69                                             uop->getType(),
70                                             uop->getValueKind(),
71                                             uop->getObjectKind(),
72                                             uop->getOperatorLoc());
73      }
74
75      if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
76        assert(!gse->isResultDependent());
77        unsigned resultIndex = gse->getResultIndex();
78        unsigned numAssocs = gse->getNumAssocs();
79
80        SmallVector<Expr*, 8> assocs(numAssocs);
81        SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
82
83        for (unsigned i = 0; i != numAssocs; ++i) {
84          Expr *assoc = gse->getAssocExpr(i);
85          if (i == resultIndex) assoc = rebuild(assoc);
86          assocs[i] = assoc;
87          assocTypes[i] = gse->getAssocTypeSourceInfo(i);
88        }
89
90        return new (S.Context) GenericSelectionExpr(S.Context,
91                                                    gse->getGenericLoc(),
92                                                    gse->getControllingExpr(),
93                                                    assocTypes.data(),
94                                                    assocs.data(),
95                                                    numAssocs,
96                                                    gse->getDefaultLoc(),
97                                                    gse->getRParenLoc(),
98                                      gse->containsUnexpandedParameterPack(),
99                                                    resultIndex);
100      }
101
102      llvm_unreachable("bad expression to rebuild!");
103    }
104  };
105
106  struct ObjCPropertyRefRebuilder : Rebuilder<ObjCPropertyRefRebuilder> {
107    Expr *NewBase;
108    ObjCPropertyRefRebuilder(Sema &S, Expr *newBase)
109      : Rebuilder<ObjCPropertyRefRebuilder>(S), NewBase(newBase) {}
110
111    typedef ObjCPropertyRefExpr specific_type;
112    Expr *rebuildSpecific(ObjCPropertyRefExpr *refExpr) {
113      // Fortunately, the constraint that we're rebuilding something
114      // with a base limits the number of cases here.
115      assert(refExpr->getBase());
116
117      if (refExpr->isExplicitProperty()) {
118        return new (S.Context)
119          ObjCPropertyRefExpr(refExpr->getExplicitProperty(),
120                              refExpr->getType(), refExpr->getValueKind(),
121                              refExpr->getObjectKind(), refExpr->getLocation(),
122                              NewBase);
123      }
124      return new (S.Context)
125        ObjCPropertyRefExpr(refExpr->getImplicitPropertyGetter(),
126                            refExpr->getImplicitPropertySetter(),
127                            refExpr->getType(), refExpr->getValueKind(),
128                            refExpr->getObjectKind(),refExpr->getLocation(),
129                            NewBase);
130    }
131  };
132
133  struct ObjCSubscriptRefRebuilder : Rebuilder<ObjCSubscriptRefRebuilder> {
134    Expr *NewBase;
135    Expr *NewKeyExpr;
136    ObjCSubscriptRefRebuilder(Sema &S, Expr *newBase, Expr *newKeyExpr)
137    : Rebuilder<ObjCSubscriptRefRebuilder>(S),
138      NewBase(newBase), NewKeyExpr(newKeyExpr) {}
139
140    typedef ObjCSubscriptRefExpr specific_type;
141    Expr *rebuildSpecific(ObjCSubscriptRefExpr *refExpr) {
142      assert(refExpr->getBaseExpr());
143      assert(refExpr->getKeyExpr());
144
145      return new (S.Context)
146        ObjCSubscriptRefExpr(NewBase,
147                             NewKeyExpr,
148                             refExpr->getType(), refExpr->getValueKind(),
149                             refExpr->getObjectKind(),refExpr->getAtIndexMethodDecl(),
150                             refExpr->setAtIndexMethodDecl(),
151                             refExpr->getRBracket());
152    }
153  };
154
155  class PseudoOpBuilder {
156  public:
157    Sema &S;
158    unsigned ResultIndex;
159    SourceLocation GenericLoc;
160    SmallVector<Expr *, 4> Semantics;
161
162    PseudoOpBuilder(Sema &S, SourceLocation genericLoc)
163      : S(S), ResultIndex(PseudoObjectExpr::NoResult),
164        GenericLoc(genericLoc) {}
165
166    virtual ~PseudoOpBuilder() {}
167
168    /// Add a normal semantic expression.
169    void addSemanticExpr(Expr *semantic) {
170      Semantics.push_back(semantic);
171    }
172
173    /// Add the 'result' semantic expression.
174    void addResultSemanticExpr(Expr *resultExpr) {
175      assert(ResultIndex == PseudoObjectExpr::NoResult);
176      ResultIndex = Semantics.size();
177      Semantics.push_back(resultExpr);
178    }
179
180    ExprResult buildRValueOperation(Expr *op);
181    ExprResult buildAssignmentOperation(Scope *Sc,
182                                        SourceLocation opLoc,
183                                        BinaryOperatorKind opcode,
184                                        Expr *LHS, Expr *RHS);
185    ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
186                                    UnaryOperatorKind opcode,
187                                    Expr *op);
188
189    ExprResult complete(Expr *syntacticForm);
190
191    OpaqueValueExpr *capture(Expr *op);
192    OpaqueValueExpr *captureValueAsResult(Expr *op);
193
194    void setResultToLastSemantic() {
195      assert(ResultIndex == PseudoObjectExpr::NoResult);
196      ResultIndex = Semantics.size() - 1;
197    }
198
199    /// Return true if assignments have a non-void result.
200    virtual bool assignmentsHaveResult() { return true; }
201
202    virtual Expr *rebuildAndCaptureObject(Expr *) = 0;
203    virtual ExprResult buildGet() = 0;
204    virtual ExprResult buildSet(Expr *, SourceLocation,
205                                bool captureSetValueAsResult) = 0;
206  };
207
208  /// A PseudoOpBuilder for Objective-C @properties.
209  class ObjCPropertyOpBuilder : public PseudoOpBuilder {
210    ObjCPropertyRefExpr *RefExpr;
211    ObjCPropertyRefExpr *SyntacticRefExpr;
212    OpaqueValueExpr *InstanceReceiver;
213    ObjCMethodDecl *Getter;
214
215    ObjCMethodDecl *Setter;
216    Selector SetterSelector;
217
218  public:
219    ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
220      PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
221      SyntacticRefExpr(0), InstanceReceiver(0), Getter(0), Setter(0) {
222    }
223
224    ExprResult buildRValueOperation(Expr *op);
225    ExprResult buildAssignmentOperation(Scope *Sc,
226                                        SourceLocation opLoc,
227                                        BinaryOperatorKind opcode,
228                                        Expr *LHS, Expr *RHS);
229    ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
230                                    UnaryOperatorKind opcode,
231                                    Expr *op);
232
233    bool tryBuildGetOfReference(Expr *op, ExprResult &result);
234    bool findSetter();
235    bool findGetter();
236
237    Expr *rebuildAndCaptureObject(Expr *syntacticBase);
238    ExprResult buildGet();
239    ExprResult buildSet(Expr *op, SourceLocation, bool);
240  };
241
242 /// A PseudoOpBuilder for Objective-C array/dictionary indexing.
243 class ObjCSubscriptOpBuilder : public PseudoOpBuilder {
244   ObjCSubscriptRefExpr *RefExpr;
245   OpaqueValueExpr *InstanceBase;
246   OpaqueValueExpr *InstanceKey;
247   ObjCMethodDecl *AtIndexGetter;
248   Selector AtIndexGetterSelector;
249
250   ObjCMethodDecl *AtIndexSetter;
251   Selector AtIndexSetterSelector;
252
253 public:
254    ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) :
255      PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
256      RefExpr(refExpr),
257    InstanceBase(0), InstanceKey(0),
258    AtIndexGetter(0), AtIndexSetter(0) { }
259
260   ExprResult buildRValueOperation(Expr *op);
261   ExprResult buildAssignmentOperation(Scope *Sc,
262                                       SourceLocation opLoc,
263                                       BinaryOperatorKind opcode,
264                                       Expr *LHS, Expr *RHS);
265   Expr *rebuildAndCaptureObject(Expr *syntacticBase);
266
267   bool findAtIndexGetter();
268   bool findAtIndexSetter();
269
270   ExprResult buildGet();
271   ExprResult buildSet(Expr *op, SourceLocation, bool);
272 };
273
274}
275
276/// Capture the given expression in an OpaqueValueExpr.
277OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
278  // Make a new OVE whose source is the given expression.
279  OpaqueValueExpr *captured =
280    new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
281                                    e->getValueKind(), e->getObjectKind(),
282                                    e);
283
284  // Make sure we bind that in the semantics.
285  addSemanticExpr(captured);
286  return captured;
287}
288
289/// Capture the given expression as the result of this pseudo-object
290/// operation.  This routine is safe against expressions which may
291/// already be captured.
292///
293/// \param Returns the captured expression, which will be the
294///   same as the input if the input was already captured
295OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
296  assert(ResultIndex == PseudoObjectExpr::NoResult);
297
298  // If the expression hasn't already been captured, just capture it
299  // and set the new semantic
300  if (!isa<OpaqueValueExpr>(e)) {
301    OpaqueValueExpr *cap = capture(e);
302    setResultToLastSemantic();
303    return cap;
304  }
305
306  // Otherwise, it must already be one of our semantic expressions;
307  // set ResultIndex to its index.
308  unsigned index = 0;
309  for (;; ++index) {
310    assert(index < Semantics.size() &&
311           "captured expression not found in semantics!");
312    if (e == Semantics[index]) break;
313  }
314  ResultIndex = index;
315  return cast<OpaqueValueExpr>(e);
316}
317
318/// The routine which creates the final PseudoObjectExpr.
319ExprResult PseudoOpBuilder::complete(Expr *syntactic) {
320  return PseudoObjectExpr::Create(S.Context, syntactic,
321                                  Semantics, ResultIndex);
322}
323
324/// The main skeleton for building an r-value operation.
325ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {
326  Expr *syntacticBase = rebuildAndCaptureObject(op);
327
328  ExprResult getExpr = buildGet();
329  if (getExpr.isInvalid()) return ExprError();
330  addResultSemanticExpr(getExpr.take());
331
332  return complete(syntacticBase);
333}
334
335/// The basic skeleton for building a simple or compound
336/// assignment operation.
337ExprResult
338PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
339                                          BinaryOperatorKind opcode,
340                                          Expr *LHS, Expr *RHS) {
341  assert(BinaryOperator::isAssignmentOp(opcode));
342
343  Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
344  OpaqueValueExpr *capturedRHS = capture(RHS);
345
346  Expr *syntactic;
347
348  ExprResult result;
349  if (opcode == BO_Assign) {
350    result = capturedRHS;
351    syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
352                                               opcode, capturedRHS->getType(),
353                                               capturedRHS->getValueKind(),
354                                               OK_Ordinary, opcLoc);
355  } else {
356    ExprResult opLHS = buildGet();
357    if (opLHS.isInvalid()) return ExprError();
358
359    // Build an ordinary, non-compound operation.
360    BinaryOperatorKind nonCompound =
361      BinaryOperator::getOpForCompoundAssignment(opcode);
362    result = S.BuildBinOp(Sc, opcLoc, nonCompound,
363                          opLHS.take(), capturedRHS);
364    if (result.isInvalid()) return ExprError();
365
366    syntactic =
367      new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
368                                             result.get()->getType(),
369                                             result.get()->getValueKind(),
370                                             OK_Ordinary,
371                                             opLHS.get()->getType(),
372                                             result.get()->getType(),
373                                             opcLoc);
374  }
375
376  // The result of the assignment, if not void, is the value set into
377  // the l-value.
378  result = buildSet(result.take(), opcLoc, assignmentsHaveResult());
379  if (result.isInvalid()) return ExprError();
380  addSemanticExpr(result.take());
381
382  return complete(syntactic);
383}
384
385/// The basic skeleton for building an increment or decrement
386/// operation.
387ExprResult
388PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
389                                      UnaryOperatorKind opcode,
390                                      Expr *op) {
391  assert(UnaryOperator::isIncrementDecrementOp(opcode));
392
393  Expr *syntacticOp = rebuildAndCaptureObject(op);
394
395  // Load the value.
396  ExprResult result = buildGet();
397  if (result.isInvalid()) return ExprError();
398
399  QualType resultType = result.get()->getType();
400
401  // That's the postfix result.
402  if (UnaryOperator::isPostfix(opcode) && assignmentsHaveResult()) {
403    result = capture(result.take());
404    setResultToLastSemantic();
405  }
406
407  // Add or subtract a literal 1.
408  llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
409  Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
410                                     GenericLoc);
411
412  if (UnaryOperator::isIncrementOp(opcode)) {
413    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
414  } else {
415    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
416  }
417  if (result.isInvalid()) return ExprError();
418
419  // Store that back into the result.  The value stored is the result
420  // of a prefix operation.
421  result = buildSet(result.take(), opcLoc,
422             UnaryOperator::isPrefix(opcode) && assignmentsHaveResult());
423  if (result.isInvalid()) return ExprError();
424  addSemanticExpr(result.take());
425
426  UnaryOperator *syntactic =
427    new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
428                                  VK_LValue, OK_Ordinary, opcLoc);
429  return complete(syntactic);
430}
431
432
433//===----------------------------------------------------------------------===//
434//  Objective-C @property and implicit property references
435//===----------------------------------------------------------------------===//
436
437/// Look up a method in the receiver type of an Objective-C property
438/// reference.
439static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
440                                            const ObjCPropertyRefExpr *PRE) {
441  if (PRE->isObjectReceiver()) {
442    const ObjCObjectPointerType *PT =
443      PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
444
445    // Special case for 'self' in class method implementations.
446    if (PT->isObjCClassType() &&
447        S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) {
448      // This cast is safe because isSelfExpr is only true within
449      // methods.
450      ObjCMethodDecl *method =
451        cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
452      return S.LookupMethodInObjectType(sel,
453                 S.Context.getObjCInterfaceType(method->getClassInterface()),
454                                        /*instance*/ false);
455    }
456
457    return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
458  }
459
460  if (PRE->isSuperReceiver()) {
461    if (const ObjCObjectPointerType *PT =
462        PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>())
463      return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
464
465    return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false);
466  }
467
468  assert(PRE->isClassReceiver() && "Invalid expression");
469  QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
470  return S.LookupMethodInObjectType(sel, IT, false);
471}
472
473bool ObjCPropertyOpBuilder::findGetter() {
474  if (Getter) return true;
475
476  // For implicit properties, just trust the lookup we already did.
477  if (RefExpr->isImplicitProperty()) {
478    Getter = RefExpr->getImplicitPropertyGetter();
479    return (Getter != 0);
480  }
481
482  ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
483  Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
484  return (Getter != 0);
485}
486
487/// Try to find the most accurate setter declaration for the property
488/// reference.
489///
490/// \return true if a setter was found, in which case Setter
491bool ObjCPropertyOpBuilder::findSetter() {
492  // For implicit properties, just trust the lookup we already did.
493  if (RefExpr->isImplicitProperty()) {
494    if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
495      Setter = setter;
496      SetterSelector = setter->getSelector();
497      return true;
498    } else {
499      IdentifierInfo *getterName =
500        RefExpr->getImplicitPropertyGetter()->getSelector()
501          .getIdentifierInfoForSlot(0);
502      SetterSelector =
503        SelectorTable::constructSetterName(S.PP.getIdentifierTable(),
504                                           S.PP.getSelectorTable(),
505                                           getterName);
506      return false;
507    }
508  }
509
510  // For explicit properties, this is more involved.
511  ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
512  SetterSelector = prop->getSetterName();
513
514  // Do a normal method lookup first.
515  if (ObjCMethodDecl *setter =
516        LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
517    Setter = setter;
518    return true;
519  }
520
521  // That can fail in the somewhat crazy situation that we're
522  // type-checking a message send within the @interface declaration
523  // that declared the @property.  But it's not clear that that's
524  // valuable to support.
525
526  return false;
527}
528
529/// Capture the base object of an Objective-C property expression.
530Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
531  assert(InstanceReceiver == 0);
532
533  // If we have a base, capture it in an OVE and rebuild the syntactic
534  // form to use the OVE as its base.
535  if (RefExpr->isObjectReceiver()) {
536    InstanceReceiver = capture(RefExpr->getBase());
537
538    syntacticBase =
539      ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
540  }
541
542  if (ObjCPropertyRefExpr *
543        refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
544    SyntacticRefExpr = refE;
545
546  return syntacticBase;
547}
548
549/// Load from an Objective-C property reference.
550ExprResult ObjCPropertyOpBuilder::buildGet() {
551  findGetter();
552  assert(Getter);
553
554  if (SyntacticRefExpr)
555    SyntacticRefExpr->setIsMessagingGetter();
556
557  QualType receiverType;
558  if (RefExpr->isClassReceiver()) {
559    receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
560  } else if (RefExpr->isSuperReceiver()) {
561    receiverType = RefExpr->getSuperReceiverType();
562  } else {
563    assert(InstanceReceiver);
564    receiverType = InstanceReceiver->getType();
565  }
566
567  // Build a message-send.
568  ExprResult msg;
569  if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
570    assert(InstanceReceiver || RefExpr->isSuperReceiver());
571    msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
572                                         GenericLoc, Getter->getSelector(),
573                                         Getter, MultiExprArg());
574  } else {
575    msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
576                                      GenericLoc,
577                                      Getter->getSelector(), Getter,
578                                      MultiExprArg());
579  }
580  return msg;
581}
582
583/// Store to an Objective-C property reference.
584///
585/// \param bindSetValueAsResult - If true, capture the actual
586///   value being set as the value of the property operation.
587ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
588                                           bool captureSetValueAsResult) {
589  bool hasSetter = findSetter();
590  assert(hasSetter); (void) hasSetter;
591
592  if (SyntacticRefExpr)
593    SyntacticRefExpr->setIsMessagingSetter();
594
595  QualType receiverType;
596  if (RefExpr->isClassReceiver()) {
597    receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
598  } else if (RefExpr->isSuperReceiver()) {
599    receiverType = RefExpr->getSuperReceiverType();
600  } else {
601    assert(InstanceReceiver);
602    receiverType = InstanceReceiver->getType();
603  }
604
605  // Use assignment constraints when possible; they give us better
606  // diagnostics.  "When possible" basically means anything except a
607  // C++ class type.
608  if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) {
609    QualType paramType = (*Setter->param_begin())->getType();
610    if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) {
611      ExprResult opResult = op;
612      Sema::AssignConvertType assignResult
613        = S.CheckSingleAssignmentConstraints(paramType, opResult);
614      if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
615                                     op->getType(), opResult.get(),
616                                     Sema::AA_Assigning))
617        return ExprError();
618
619      op = opResult.take();
620      assert(op && "successful assignment left argument invalid?");
621    }
622  }
623
624  // Arguments.
625  Expr *args[] = { op };
626
627  // Build a message-send.
628  ExprResult msg;
629  if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
630    msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
631                                         GenericLoc, SetterSelector, Setter,
632                                         MultiExprArg(args, 1));
633  } else {
634    msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
635                                      GenericLoc,
636                                      SetterSelector, Setter,
637                                      MultiExprArg(args, 1));
638  }
639
640  if (!msg.isInvalid() && captureSetValueAsResult) {
641    ObjCMessageExpr *msgExpr =
642      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
643    Expr *arg = msgExpr->getArg(0);
644    msgExpr->setArg(0, captureValueAsResult(arg));
645  }
646
647  return msg;
648}
649
650/// @property-specific behavior for doing lvalue-to-rvalue conversion.
651ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
652  // Explicit properties always have getters, but implicit ones don't.
653  // Check that before proceeding.
654  if (RefExpr->isImplicitProperty() &&
655      !RefExpr->getImplicitPropertyGetter()) {
656    S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
657      << RefExpr->getBase()->getType();
658    return ExprError();
659  }
660
661  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
662  if (result.isInvalid()) return ExprError();
663
664  if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
665    S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
666                                       Getter, RefExpr->getLocation());
667
668  // As a special case, if the method returns 'id', try to get
669  // a better type from the property.
670  if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
671      result.get()->getType()->isObjCIdType()) {
672    QualType propType = RefExpr->getExplicitProperty()->getType();
673    if (const ObjCObjectPointerType *ptr
674          = propType->getAs<ObjCObjectPointerType>()) {
675      if (!ptr->isObjCIdType())
676        result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
677    }
678  }
679
680  return result;
681}
682
683/// Try to build this as a call to a getter that returns a reference.
684///
685/// \return true if it was possible, whether or not it actually
686///   succeeded
687bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
688                                                   ExprResult &result) {
689  if (!S.getLangOpts().CPlusPlus) return false;
690
691  findGetter();
692  assert(Getter && "property has no setter and no getter!");
693
694  // Only do this if the getter returns an l-value reference type.
695  QualType resultType = Getter->getResultType();
696  if (!resultType->isLValueReferenceType()) return false;
697
698  result = buildRValueOperation(op);
699  return true;
700}
701
702/// @property-specific behavior for doing assignments.
703ExprResult
704ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
705                                                SourceLocation opcLoc,
706                                                BinaryOperatorKind opcode,
707                                                Expr *LHS, Expr *RHS) {
708  assert(BinaryOperator::isAssignmentOp(opcode));
709
710  // If there's no setter, we have no choice but to try to assign to
711  // the result of the getter.
712  if (!findSetter()) {
713    ExprResult result;
714    if (tryBuildGetOfReference(LHS, result)) {
715      if (result.isInvalid()) return ExprError();
716      return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
717    }
718
719    // Otherwise, it's an error.
720    S.Diag(opcLoc, diag::err_nosetter_property_assignment)
721      << unsigned(RefExpr->isImplicitProperty())
722      << SetterSelector
723      << LHS->getSourceRange() << RHS->getSourceRange();
724    return ExprError();
725  }
726
727  // If there is a setter, we definitely want to use it.
728
729  // Verify that we can do a compound assignment.
730  if (opcode != BO_Assign && !findGetter()) {
731    S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
732      << LHS->getSourceRange() << RHS->getSourceRange();
733    return ExprError();
734  }
735
736  ExprResult result =
737    PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
738  if (result.isInvalid()) return ExprError();
739
740  // Various warnings about property assignments in ARC.
741  if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
742    S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
743    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
744  }
745
746  return result;
747}
748
749/// @property-specific behavior for doing increments and decrements.
750ExprResult
751ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
752                                            UnaryOperatorKind opcode,
753                                            Expr *op) {
754  // If there's no setter, we have no choice but to try to assign to
755  // the result of the getter.
756  if (!findSetter()) {
757    ExprResult result;
758    if (tryBuildGetOfReference(op, result)) {
759      if (result.isInvalid()) return ExprError();
760      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
761    }
762
763    // Otherwise, it's an error.
764    S.Diag(opcLoc, diag::err_nosetter_property_incdec)
765      << unsigned(RefExpr->isImplicitProperty())
766      << unsigned(UnaryOperator::isDecrementOp(opcode))
767      << SetterSelector
768      << op->getSourceRange();
769    return ExprError();
770  }
771
772  // If there is a setter, we definitely want to use it.
773
774  // We also need a getter.
775  if (!findGetter()) {
776    assert(RefExpr->isImplicitProperty());
777    S.Diag(opcLoc, diag::err_nogetter_property_incdec)
778      << unsigned(UnaryOperator::isDecrementOp(opcode))
779      << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME!
780      << op->getSourceRange();
781    return ExprError();
782  }
783
784  return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
785}
786
787// ObjCSubscript build stuff.
788//
789
790/// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
791/// conversion.
792/// FIXME. Remove this routine if it is proven that no additional
793/// specifity is needed.
794ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
795  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
796  if (result.isInvalid()) return ExprError();
797  return result;
798}
799
800/// objective-c subscripting-specific  behavior for doing assignments.
801ExprResult
802ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
803                                                SourceLocation opcLoc,
804                                                BinaryOperatorKind opcode,
805                                                Expr *LHS, Expr *RHS) {
806  assert(BinaryOperator::isAssignmentOp(opcode));
807  // There must be a method to do the Index'ed assignment.
808  if (!findAtIndexSetter())
809    return ExprError();
810
811  // Verify that we can do a compound assignment.
812  if (opcode != BO_Assign && !findAtIndexGetter())
813    return ExprError();
814
815  ExprResult result =
816  PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
817  if (result.isInvalid()) return ExprError();
818
819  // Various warnings about objc Index'ed assignments in ARC.
820  if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {
821    S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
822    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
823  }
824
825  return result;
826}
827
828/// Capture the base object of an Objective-C Index'ed expression.
829Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
830  assert(InstanceBase == 0);
831
832  // Capture base expression in an OVE and rebuild the syntactic
833  // form to use the OVE as its base expression.
834  InstanceBase = capture(RefExpr->getBaseExpr());
835  InstanceKey = capture(RefExpr->getKeyExpr());
836
837  syntacticBase =
838    ObjCSubscriptRefRebuilder(S, InstanceBase,
839                              InstanceKey).rebuild(syntacticBase);
840
841  return syntacticBase;
842}
843
844/// CheckSubscriptingKind - This routine decide what type
845/// of indexing represented by "FromE" is being done.
846Sema::ObjCSubscriptKind
847  Sema::CheckSubscriptingKind(Expr *FromE) {
848  // If the expression already has integral or enumeration type, we're golden.
849  QualType T = FromE->getType();
850  if (T->isIntegralOrEnumerationType())
851    return OS_Array;
852
853  // If we don't have a class type in C++, there's no way we can get an
854  // expression of integral or enumeration type.
855  const RecordType *RecordTy = T->getAs<RecordType>();
856  if (!RecordTy && T->isObjCObjectPointerType())
857    // All other scalar cases are assumed to be dictionary indexing which
858    // caller handles, with diagnostics if needed.
859    return OS_Dictionary;
860  if (!getLangOpts().CPlusPlus ||
861      !RecordTy || RecordTy->isIncompleteType()) {
862    // No indexing can be done. Issue diagnostics and quit.
863    const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
864    if (isa<StringLiteral>(IndexExpr))
865      Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
866        << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
867    else
868      Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
869        << T;
870    return OS_Error;
871  }
872
873  // We must have a complete class type.
874  if (RequireCompleteType(FromE->getExprLoc(), T,
875                          PDiag(diag::err_objc_index_incomplete_class_type)
876                          << FromE->getSourceRange()))
877    return OS_Error;
878
879  // Look for a conversion to an integral, enumeration type, or
880  // objective-C pointer type.
881  UnresolvedSet<4> ViableConversions;
882  UnresolvedSet<4> ExplicitConversions;
883  const UnresolvedSetImpl *Conversions
884    = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
885
886  int NoIntegrals=0, NoObjCIdPointers=0;
887  SmallVector<CXXConversionDecl *, 4> ConversionDecls;
888
889  for (UnresolvedSetImpl::iterator I = Conversions->begin(),
890       E = Conversions->end();
891       I != E;
892       ++I) {
893    if (CXXConversionDecl *Conversion
894        = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
895      QualType CT = Conversion->getConversionType().getNonReferenceType();
896      if (CT->isIntegralOrEnumerationType()) {
897        ++NoIntegrals;
898        ConversionDecls.push_back(Conversion);
899      }
900      else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
901        ++NoObjCIdPointers;
902        ConversionDecls.push_back(Conversion);
903      }
904    }
905  }
906  if (NoIntegrals ==1 && NoObjCIdPointers == 0)
907    return OS_Array;
908  if (NoIntegrals == 0 && NoObjCIdPointers == 1)
909    return OS_Dictionary;
910  if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
911    // No conversion function was found. Issue diagnostic and return.
912    Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
913      << FromE->getType();
914    return OS_Error;
915  }
916  Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
917      << FromE->getType();
918  for (unsigned int i = 0; i < ConversionDecls.size(); i++)
919    Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
920
921  return OS_Error;
922}
923
924bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
925  if (AtIndexGetter)
926    return true;
927
928  Expr *BaseExpr = RefExpr->getBaseExpr();
929  QualType BaseT = BaseExpr->getType();
930
931  QualType ResultType;
932  if (const ObjCObjectPointerType *PTy =
933      BaseT->getAs<ObjCObjectPointerType>()) {
934    ResultType = PTy->getPointeeType();
935    if (const ObjCObjectType *iQFaceTy =
936        ResultType->getAsObjCQualifiedInterfaceType())
937      ResultType = iQFaceTy->getBaseType();
938  }
939  Sema::ObjCSubscriptKind Res =
940    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
941  if (Res == Sema::OS_Error)
942    return false;
943  bool arrayRef = (Res == Sema::OS_Array);
944
945  if (ResultType.isNull()) {
946    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
947      << BaseExpr->getType() << arrayRef;
948    return false;
949  }
950  if (!arrayRef) {
951    // dictionary subscripting.
952    // - (id)objectForKeyedSubscript:(id)key;
953    IdentifierInfo *KeyIdents[] = {
954      &S.Context.Idents.get("objectForKeyedSubscript")
955    };
956    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
957  }
958  else {
959    // - (id)objectAtIndexedSubscript:(size_t)index;
960    IdentifierInfo *KeyIdents[] = {
961      &S.Context.Idents.get("objectAtIndexedSubscript")
962    };
963
964    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
965  }
966
967  AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType,
968                                             true /*instance*/);
969  bool receiverIdType = (BaseT->isObjCIdType() ||
970                         BaseT->isObjCQualifiedIdType());
971
972  if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {
973    AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
974                           SourceLocation(), AtIndexGetterSelector,
975                           S.Context.getObjCIdType() /*ReturnType*/,
976                           0 /*TypeSourceInfo */,
977                           S.Context.getTranslationUnitDecl(),
978                           true /*Instance*/, false/*isVariadic*/,
979                           /*isSynthesized=*/false,
980                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
981                           ObjCMethodDecl::Required,
982                           false);
983    ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
984                                                SourceLocation(), SourceLocation(),
985                                                arrayRef ? &S.Context.Idents.get("index")
986                                                         : &S.Context.Idents.get("key"),
987                                                arrayRef ? S.Context.UnsignedLongTy
988                                                         : S.Context.getObjCIdType(),
989                                                /*TInfo=*/0,
990                                                SC_None,
991                                                SC_None,
992                                                0);
993    AtIndexGetter->setMethodParams(S.Context, Argument,
994                                   ArrayRef<SourceLocation>());
995  }
996
997  if (!AtIndexGetter) {
998    if (!receiverIdType) {
999      S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
1000      << BaseExpr->getType() << 0 << arrayRef;
1001      return false;
1002    }
1003    AtIndexGetter =
1004      S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector,
1005                                         RefExpr->getSourceRange(),
1006                                         true, false);
1007  }
1008
1009  if (AtIndexGetter) {
1010    QualType T = AtIndexGetter->param_begin()[0]->getType();
1011    if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
1012        (!arrayRef && !T->isObjCObjectPointerType())) {
1013      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1014             arrayRef ? diag::err_objc_subscript_index_type
1015                      : diag::err_objc_subscript_key_type) << T;
1016      S.Diag(AtIndexGetter->param_begin()[0]->getLocation(),
1017             diag::note_parameter_type) << T;
1018      return false;
1019    }
1020    QualType R = AtIndexGetter->getResultType();
1021    if (!R->isObjCObjectPointerType()) {
1022      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1023             diag::err_objc_indexing_method_result_type) << R << arrayRef;
1024      S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1025        AtIndexGetter->getDeclName();
1026    }
1027  }
1028  return true;
1029}
1030
1031bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1032  if (AtIndexSetter)
1033    return true;
1034
1035  Expr *BaseExpr = RefExpr->getBaseExpr();
1036  QualType BaseT = BaseExpr->getType();
1037
1038  QualType ResultType;
1039  if (const ObjCObjectPointerType *PTy =
1040      BaseT->getAs<ObjCObjectPointerType>()) {
1041    ResultType = PTy->getPointeeType();
1042    if (const ObjCObjectType *iQFaceTy =
1043        ResultType->getAsObjCQualifiedInterfaceType())
1044      ResultType = iQFaceTy->getBaseType();
1045  }
1046
1047  Sema::ObjCSubscriptKind Res =
1048    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
1049  if (Res == Sema::OS_Error)
1050    return false;
1051  bool arrayRef = (Res == Sema::OS_Array);
1052
1053  if (ResultType.isNull()) {
1054    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
1055      << BaseExpr->getType() << arrayRef;
1056    return false;
1057  }
1058
1059  if (!arrayRef) {
1060    // dictionary subscripting.
1061    // - (void)setObject:(id)object forKeyedSubscript:(id)key;
1062    IdentifierInfo *KeyIdents[] = {
1063      &S.Context.Idents.get("setObject"),
1064      &S.Context.Idents.get("forKeyedSubscript")
1065    };
1066    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
1067  }
1068  else {
1069    // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1070    IdentifierInfo *KeyIdents[] = {
1071      &S.Context.Idents.get("setObject"),
1072      &S.Context.Idents.get("atIndexedSubscript")
1073    };
1074    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
1075  }
1076  AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType,
1077                                             true /*instance*/);
1078
1079  bool receiverIdType = (BaseT->isObjCIdType() ||
1080                         BaseT->isObjCQualifiedIdType());
1081
1082  if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
1083    TypeSourceInfo *ResultTInfo = 0;
1084    QualType ReturnType = S.Context.VoidTy;
1085    AtIndexSetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
1086                           SourceLocation(), AtIndexSetterSelector,
1087                           ReturnType,
1088                           ResultTInfo,
1089                           S.Context.getTranslationUnitDecl(),
1090                           true /*Instance*/, false/*isVariadic*/,
1091                           /*isSynthesized=*/false,
1092                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1093                           ObjCMethodDecl::Required,
1094                           false);
1095    SmallVector<ParmVarDecl *, 2> Params;
1096    ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
1097                                                SourceLocation(), SourceLocation(),
1098                                                &S.Context.Idents.get("object"),
1099                                                S.Context.getObjCIdType(),
1100                                                /*TInfo=*/0,
1101                                                SC_None,
1102                                                SC_None,
1103                                                0);
1104    Params.push_back(object);
1105    ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
1106                                                SourceLocation(), SourceLocation(),
1107                                                arrayRef ?  &S.Context.Idents.get("index")
1108                                                         :  &S.Context.Idents.get("key"),
1109                                                arrayRef ? S.Context.UnsignedLongTy
1110                                                         : S.Context.getObjCIdType(),
1111                                                /*TInfo=*/0,
1112                                                SC_None,
1113                                                SC_None,
1114                                                0);
1115    Params.push_back(key);
1116    AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
1117  }
1118
1119  if (!AtIndexSetter) {
1120    if (!receiverIdType) {
1121      S.Diag(BaseExpr->getExprLoc(),
1122             diag::err_objc_subscript_method_not_found)
1123      << BaseExpr->getType() << 1 << arrayRef;
1124      return false;
1125    }
1126    AtIndexSetter =
1127      S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector,
1128                                         RefExpr->getSourceRange(),
1129                                         true, false);
1130  }
1131
1132  bool err = false;
1133  if (AtIndexSetter && arrayRef) {
1134    QualType T = AtIndexSetter->param_begin()[1]->getType();
1135    if (!T->isIntegralOrEnumerationType()) {
1136      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1137             diag::err_objc_subscript_index_type) << T;
1138      S.Diag(AtIndexSetter->param_begin()[1]->getLocation(),
1139             diag::note_parameter_type) << T;
1140      err = true;
1141    }
1142    T = AtIndexSetter->param_begin()[0]->getType();
1143    if (!T->isObjCObjectPointerType()) {
1144      S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
1145             diag::err_objc_subscript_object_type) << T << arrayRef;
1146      S.Diag(AtIndexSetter->param_begin()[0]->getLocation(),
1147             diag::note_parameter_type) << T;
1148      err = true;
1149    }
1150  }
1151  else if (AtIndexSetter && !arrayRef)
1152    for (unsigned i=0; i <2; i++) {
1153      QualType T = AtIndexSetter->param_begin()[i]->getType();
1154      if (!T->isObjCObjectPointerType()) {
1155        if (i == 1)
1156          S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1157                 diag::err_objc_subscript_key_type) << T;
1158        else
1159          S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
1160                 diag::err_objc_subscript_dic_object_type) << T;
1161        S.Diag(AtIndexSetter->param_begin()[i]->getLocation(),
1162               diag::note_parameter_type) << T;
1163        err = true;
1164      }
1165    }
1166
1167  return !err;
1168}
1169
1170// Get the object at "Index" position in the container.
1171// [BaseExpr objectAtIndexedSubscript : IndexExpr];
1172ExprResult ObjCSubscriptOpBuilder::buildGet() {
1173  if (!findAtIndexGetter())
1174    return ExprError();
1175
1176  QualType receiverType = InstanceBase->getType();
1177
1178  // Build a message-send.
1179  ExprResult msg;
1180  Expr *Index = InstanceKey;
1181
1182  // Arguments.
1183  Expr *args[] = { Index };
1184  assert(InstanceBase);
1185  msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
1186                                       GenericLoc,
1187                                       AtIndexGetterSelector, AtIndexGetter,
1188                                       MultiExprArg(args, 1));
1189  return msg;
1190}
1191
1192/// Store into the container the "op" object at "Index"'ed location
1193/// by building this messaging expression:
1194/// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1195/// \param bindSetValueAsResult - If true, capture the actual
1196///   value being set as the value of the property operation.
1197ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
1198                                           bool captureSetValueAsResult) {
1199  if (!findAtIndexSetter())
1200    return ExprError();
1201
1202  QualType receiverType = InstanceBase->getType();
1203  Expr *Index = InstanceKey;
1204
1205  // Arguments.
1206  Expr *args[] = { op, Index };
1207
1208  // Build a message-send.
1209  ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
1210                                                  GenericLoc,
1211                                                  AtIndexSetterSelector,
1212                                                  AtIndexSetter,
1213                                                  MultiExprArg(args, 2));
1214
1215  if (!msg.isInvalid() && captureSetValueAsResult) {
1216    ObjCMessageExpr *msgExpr =
1217      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
1218    Expr *arg = msgExpr->getArg(0);
1219    msgExpr->setArg(0, captureValueAsResult(arg));
1220  }
1221
1222  return msg;
1223}
1224
1225//===----------------------------------------------------------------------===//
1226//  General Sema routines.
1227//===----------------------------------------------------------------------===//
1228
1229ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
1230  Expr *opaqueRef = E->IgnoreParens();
1231  if (ObjCPropertyRefExpr *refExpr
1232        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1233    ObjCPropertyOpBuilder builder(*this, refExpr);
1234    return builder.buildRValueOperation(E);
1235  }
1236  else if (ObjCSubscriptRefExpr *refExpr
1237           = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1238    ObjCSubscriptOpBuilder builder(*this, refExpr);
1239    return builder.buildRValueOperation(E);
1240  } else {
1241    llvm_unreachable("unknown pseudo-object kind!");
1242  }
1243}
1244
1245/// Check an increment or decrement of a pseudo-object expression.
1246ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
1247                                         UnaryOperatorKind opcode, Expr *op) {
1248  // Do nothing if the operand is dependent.
1249  if (op->isTypeDependent())
1250    return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
1251                                       VK_RValue, OK_Ordinary, opcLoc);
1252
1253  assert(UnaryOperator::isIncrementDecrementOp(opcode));
1254  Expr *opaqueRef = op->IgnoreParens();
1255  if (ObjCPropertyRefExpr *refExpr
1256        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1257    ObjCPropertyOpBuilder builder(*this, refExpr);
1258    return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1259  } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1260    Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1261    return ExprError();
1262  } else {
1263    llvm_unreachable("unknown pseudo-object kind!");
1264  }
1265}
1266
1267ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
1268                                             BinaryOperatorKind opcode,
1269                                             Expr *LHS, Expr *RHS) {
1270  // Do nothing if either argument is dependent.
1271  if (LHS->isTypeDependent() || RHS->isTypeDependent())
1272    return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
1273                                        VK_RValue, OK_Ordinary, opcLoc);
1274
1275  // Filter out non-overload placeholder types in the RHS.
1276  if (RHS->getType()->isNonOverloadPlaceholderType()) {
1277    ExprResult result = CheckPlaceholderExpr(RHS);
1278    if (result.isInvalid()) return ExprError();
1279    RHS = result.take();
1280  }
1281
1282  Expr *opaqueRef = LHS->IgnoreParens();
1283  if (ObjCPropertyRefExpr *refExpr
1284        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1285    ObjCPropertyOpBuilder builder(*this, refExpr);
1286    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1287  } else if (ObjCSubscriptRefExpr *refExpr
1288             = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1289    ObjCSubscriptOpBuilder builder(*this, refExpr);
1290    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1291  } else {
1292    llvm_unreachable("unknown pseudo-object kind!");
1293  }
1294}
1295
1296/// Given a pseudo-object reference, rebuild it without the opaque
1297/// values.  Basically, undo the behavior of rebuildAndCaptureObject.
1298/// This should never operate in-place.
1299static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
1300  Expr *opaqueRef = E->IgnoreParens();
1301  if (ObjCPropertyRefExpr *refExpr
1302        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1303    // Class and super property references don't have opaque values in them.
1304    if (refExpr->isClassReceiver() || refExpr->isSuperReceiver())
1305      return E;
1306
1307    assert(refExpr->isObjectReceiver() && "Unknown receiver kind?");
1308    OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
1309    return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
1310  } else if (ObjCSubscriptRefExpr *refExpr
1311               = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1312    OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
1313    OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
1314    return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
1315                                     keyOVE->getSourceExpr()).rebuild(E);
1316  } else {
1317    llvm_unreachable("unknown pseudo-object kind!");
1318  }
1319}
1320
1321/// Given a pseudo-object expression, recreate what it looks like
1322/// syntactically without the attendant OpaqueValueExprs.
1323///
1324/// This is a hack which should be removed when TreeTransform is
1325/// capable of rebuilding a tree without stripping implicit
1326/// operations.
1327Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
1328  Expr *syntax = E->getSyntacticForm();
1329  if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
1330    Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
1331    return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
1332                                       uop->getValueKind(), uop->getObjectKind(),
1333                                       uop->getOperatorLoc());
1334  } else if (CompoundAssignOperator *cop
1335               = dyn_cast<CompoundAssignOperator>(syntax)) {
1336    Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
1337    Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1338    return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
1339                                                cop->getType(),
1340                                                cop->getValueKind(),
1341                                                cop->getObjectKind(),
1342                                                cop->getComputationLHSType(),
1343                                                cop->getComputationResultType(),
1344                                                cop->getOperatorLoc());
1345  } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1346    Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
1347    Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1348    return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
1349                                        bop->getType(), bop->getValueKind(),
1350                                        bop->getObjectKind(),
1351                                        bop->getOperatorLoc());
1352  } else {
1353    assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
1354    return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
1355  }
1356}
1357