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