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 #include "llvm/ADT/SmallString.h"
     38 
     39 using namespace clang;
     40 using namespace sema;
     41 
     42 namespace {
     43   // Basically just a very focused copy of TreeTransform.
     44   template <class T> struct Rebuilder {
     45     Sema &S;
     46     Rebuilder(Sema &S) : S(S) {}
     47 
     48     T &getDerived() { return static_cast<T&>(*this); }
     49 
     50     Expr *rebuild(Expr *e) {
     51       // Fast path: nothing to look through.
     52       if (typename T::specific_type *specific
     53             = dyn_cast<typename T::specific_type>(e))
     54         return getDerived().rebuildSpecific(specific);
     55 
     56       // Otherwise, we should look through and rebuild anything that
     57       // IgnoreParens would.
     58 
     59       if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
     60         e = rebuild(parens->getSubExpr());
     61         return new (S.Context) ParenExpr(parens->getLParen(),
     62                                          parens->getRParen(),
     63                                          e);
     64       }
     65 
     66       if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
     67         assert(uop->getOpcode() == UO_Extension);
     68         e = rebuild(uop->getSubExpr());
     69         return new (S.Context) UnaryOperator(e, uop->getOpcode(),
     70                                              uop->getType(),
     71                                              uop->getValueKind(),
     72                                              uop->getObjectKind(),
     73                                              uop->getOperatorLoc());
     74       }
     75 
     76       if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
     77         assert(!gse->isResultDependent());
     78         unsigned resultIndex = gse->getResultIndex();
     79         unsigned numAssocs = gse->getNumAssocs();
     80 
     81         SmallVector<Expr*, 8> assocs(numAssocs);
     82         SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
     83 
     84         for (unsigned i = 0; i != numAssocs; ++i) {
     85           Expr *assoc = gse->getAssocExpr(i);
     86           if (i == resultIndex) assoc = rebuild(assoc);
     87           assocs[i] = assoc;
     88           assocTypes[i] = gse->getAssocTypeSourceInfo(i);
     89         }
     90 
     91         return new (S.Context) GenericSelectionExpr(S.Context,
     92                                                     gse->getGenericLoc(),
     93                                                     gse->getControllingExpr(),
     94                                                     assocTypes,
     95                                                     assocs,
     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(bool warn=true);
    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 /// \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(bool warn) {
    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     if (setter->isSynthesized() && warn)
    535       if (const ObjCInterfaceDecl *IFace =
    536           dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
    537         const StringRef thisPropertyName(prop->getName());
    538         char front = thisPropertyName.front();
    539         front = islower(front) ? toupper(front) : tolower(front);
    540         SmallString<100> PropertyName = thisPropertyName;
    541         PropertyName[0] = front;
    542         IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName);
    543         if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(AltMember))
    544           if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
    545             S.Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use)
    546               << prop->getName() << prop1->getName() << setter->getSelector();
    547             S.Diag(prop->getLocation(), diag::note_property_declare);
    548             S.Diag(prop1->getLocation(), diag::note_property_declare);
    549           }
    550       }
    551     Setter = setter;
    552     return true;
    553   }
    554 
    555   // That can fail in the somewhat crazy situation that we're
    556   // type-checking a message send within the @interface declaration
    557   // that declared the @property.  But it's not clear that that's
    558   // valuable to support.
    559 
    560   return false;
    561 }
    562 
    563 /// Capture the base object of an Objective-C property expression.
    564 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
    565   assert(InstanceReceiver == 0);
    566 
    567   // If we have a base, capture it in an OVE and rebuild the syntactic
    568   // form to use the OVE as its base.
    569   if (RefExpr->isObjectReceiver()) {
    570     InstanceReceiver = capture(RefExpr->getBase());
    571 
    572     syntacticBase =
    573       ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
    574   }
    575 
    576   if (ObjCPropertyRefExpr *
    577         refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
    578     SyntacticRefExpr = refE;
    579 
    580   return syntacticBase;
    581 }
    582 
    583 /// Load from an Objective-C property reference.
    584 ExprResult ObjCPropertyOpBuilder::buildGet() {
    585   findGetter();
    586   assert(Getter);
    587 
    588   if (SyntacticRefExpr)
    589     SyntacticRefExpr->setIsMessagingGetter();
    590 
    591   QualType receiverType;
    592   if (RefExpr->isClassReceiver()) {
    593     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
    594   } else if (RefExpr->isSuperReceiver()) {
    595     receiverType = RefExpr->getSuperReceiverType();
    596   } else {
    597     assert(InstanceReceiver);
    598     receiverType = InstanceReceiver->getType();
    599   }
    600 
    601   // Build a message-send.
    602   ExprResult msg;
    603   if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
    604     assert(InstanceReceiver || RefExpr->isSuperReceiver());
    605     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
    606                                          GenericLoc, Getter->getSelector(),
    607                                          Getter, MultiExprArg());
    608   } else {
    609     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
    610                                       GenericLoc,
    611                                       Getter->getSelector(), Getter,
    612                                       MultiExprArg());
    613   }
    614   return msg;
    615 }
    616 
    617 /// Store to an Objective-C property reference.
    618 ///
    619 /// \param captureSetValueAsResult If true, capture the actual
    620 ///   value being set as the value of the property operation.
    621 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
    622                                            bool captureSetValueAsResult) {
    623   bool hasSetter = findSetter(false);
    624   assert(hasSetter); (void) hasSetter;
    625 
    626   if (SyntacticRefExpr)
    627     SyntacticRefExpr->setIsMessagingSetter();
    628 
    629   QualType receiverType;
    630   if (RefExpr->isClassReceiver()) {
    631     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
    632   } else if (RefExpr->isSuperReceiver()) {
    633     receiverType = RefExpr->getSuperReceiverType();
    634   } else {
    635     assert(InstanceReceiver);
    636     receiverType = InstanceReceiver->getType();
    637   }
    638 
    639   // Use assignment constraints when possible; they give us better
    640   // diagnostics.  "When possible" basically means anything except a
    641   // C++ class type.
    642   if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) {
    643     QualType paramType = (*Setter->param_begin())->getType();
    644     if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) {
    645       ExprResult opResult = op;
    646       Sema::AssignConvertType assignResult
    647         = S.CheckSingleAssignmentConstraints(paramType, opResult);
    648       if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
    649                                      op->getType(), opResult.get(),
    650                                      Sema::AA_Assigning))
    651         return ExprError();
    652 
    653       op = opResult.take();
    654       assert(op && "successful assignment left argument invalid?");
    655     }
    656   }
    657 
    658   // Arguments.
    659   Expr *args[] = { op };
    660 
    661   // Build a message-send.
    662   ExprResult msg;
    663   if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
    664     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
    665                                          GenericLoc, SetterSelector, Setter,
    666                                          MultiExprArg(args, 1));
    667   } else {
    668     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
    669                                       GenericLoc,
    670                                       SetterSelector, Setter,
    671                                       MultiExprArg(args, 1));
    672   }
    673 
    674   if (!msg.isInvalid() && captureSetValueAsResult) {
    675     ObjCMessageExpr *msgExpr =
    676       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
    677     Expr *arg = msgExpr->getArg(0);
    678     msgExpr->setArg(0, captureValueAsResult(arg));
    679   }
    680 
    681   return msg;
    682 }
    683 
    684 /// @property-specific behavior for doing lvalue-to-rvalue conversion.
    685 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
    686   // Explicit properties always have getters, but implicit ones don't.
    687   // Check that before proceeding.
    688   if (RefExpr->isImplicitProperty() &&
    689       !RefExpr->getImplicitPropertyGetter()) {
    690     S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
    691       << RefExpr->getBase()->getType();
    692     return ExprError();
    693   }
    694 
    695   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
    696   if (result.isInvalid()) return ExprError();
    697 
    698   if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
    699     S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
    700                                        Getter, RefExpr->getLocation());
    701 
    702   // As a special case, if the method returns 'id', try to get
    703   // a better type from the property.
    704   if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
    705       result.get()->getType()->isObjCIdType()) {
    706     QualType propType = RefExpr->getExplicitProperty()->getType();
    707     if (const ObjCObjectPointerType *ptr
    708           = propType->getAs<ObjCObjectPointerType>()) {
    709       if (!ptr->isObjCIdType())
    710         result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
    711     }
    712   }
    713 
    714   return result;
    715 }
    716 
    717 /// Try to build this as a call to a getter that returns a reference.
    718 ///
    719 /// \return true if it was possible, whether or not it actually
    720 ///   succeeded
    721 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
    722                                                    ExprResult &result) {
    723   if (!S.getLangOpts().CPlusPlus) return false;
    724 
    725   findGetter();
    726   assert(Getter && "property has no setter and no getter!");
    727 
    728   // Only do this if the getter returns an l-value reference type.
    729   QualType resultType = Getter->getResultType();
    730   if (!resultType->isLValueReferenceType()) return false;
    731 
    732   result = buildRValueOperation(op);
    733   return true;
    734 }
    735 
    736 /// @property-specific behavior for doing assignments.
    737 ExprResult
    738 ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
    739                                                 SourceLocation opcLoc,
    740                                                 BinaryOperatorKind opcode,
    741                                                 Expr *LHS, Expr *RHS) {
    742   assert(BinaryOperator::isAssignmentOp(opcode));
    743 
    744   // If there's no setter, we have no choice but to try to assign to
    745   // the result of the getter.
    746   if (!findSetter()) {
    747     ExprResult result;
    748     if (tryBuildGetOfReference(LHS, result)) {
    749       if (result.isInvalid()) return ExprError();
    750       return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
    751     }
    752 
    753     // Otherwise, it's an error.
    754     S.Diag(opcLoc, diag::err_nosetter_property_assignment)
    755       << unsigned(RefExpr->isImplicitProperty())
    756       << SetterSelector
    757       << LHS->getSourceRange() << RHS->getSourceRange();
    758     return ExprError();
    759   }
    760 
    761   // If there is a setter, we definitely want to use it.
    762 
    763   // Verify that we can do a compound assignment.
    764   if (opcode != BO_Assign && !findGetter()) {
    765     S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
    766       << LHS->getSourceRange() << RHS->getSourceRange();
    767     return ExprError();
    768   }
    769 
    770   ExprResult result =
    771     PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
    772   if (result.isInvalid()) return ExprError();
    773 
    774   // Various warnings about property assignments in ARC.
    775   if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
    776     S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
    777     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
    778   }
    779 
    780   return result;
    781 }
    782 
    783 /// @property-specific behavior for doing increments and decrements.
    784 ExprResult
    785 ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
    786                                             UnaryOperatorKind opcode,
    787                                             Expr *op) {
    788   // If there's no setter, we have no choice but to try to assign to
    789   // the result of the getter.
    790   if (!findSetter()) {
    791     ExprResult result;
    792     if (tryBuildGetOfReference(op, result)) {
    793       if (result.isInvalid()) return ExprError();
    794       return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
    795     }
    796 
    797     // Otherwise, it's an error.
    798     S.Diag(opcLoc, diag::err_nosetter_property_incdec)
    799       << unsigned(RefExpr->isImplicitProperty())
    800       << unsigned(UnaryOperator::isDecrementOp(opcode))
    801       << SetterSelector
    802       << op->getSourceRange();
    803     return ExprError();
    804   }
    805 
    806   // If there is a setter, we definitely want to use it.
    807 
    808   // We also need a getter.
    809   if (!findGetter()) {
    810     assert(RefExpr->isImplicitProperty());
    811     S.Diag(opcLoc, diag::err_nogetter_property_incdec)
    812       << unsigned(UnaryOperator::isDecrementOp(opcode))
    813       << GetterSelector
    814       << op->getSourceRange();
    815     return ExprError();
    816   }
    817 
    818   return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
    819 }
    820 
    821 // ObjCSubscript build stuff.
    822 //
    823 
    824 /// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
    825 /// conversion.
    826 /// FIXME. Remove this routine if it is proven that no additional
    827 /// specifity is needed.
    828 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
    829   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
    830   if (result.isInvalid()) return ExprError();
    831   return result;
    832 }
    833 
    834 /// objective-c subscripting-specific  behavior for doing assignments.
    835 ExprResult
    836 ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
    837                                                 SourceLocation opcLoc,
    838                                                 BinaryOperatorKind opcode,
    839                                                 Expr *LHS, Expr *RHS) {
    840   assert(BinaryOperator::isAssignmentOp(opcode));
    841   // There must be a method to do the Index'ed assignment.
    842   if (!findAtIndexSetter())
    843     return ExprError();
    844 
    845   // Verify that we can do a compound assignment.
    846   if (opcode != BO_Assign && !findAtIndexGetter())
    847     return ExprError();
    848 
    849   ExprResult result =
    850   PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
    851   if (result.isInvalid()) return ExprError();
    852 
    853   // Various warnings about objc Index'ed assignments in ARC.
    854   if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {
    855     S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
    856     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
    857   }
    858 
    859   return result;
    860 }
    861 
    862 /// Capture the base object of an Objective-C Index'ed expression.
    863 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
    864   assert(InstanceBase == 0);
    865 
    866   // Capture base expression in an OVE and rebuild the syntactic
    867   // form to use the OVE as its base expression.
    868   InstanceBase = capture(RefExpr->getBaseExpr());
    869   InstanceKey = capture(RefExpr->getKeyExpr());
    870 
    871   syntacticBase =
    872     ObjCSubscriptRefRebuilder(S, InstanceBase,
    873                               InstanceKey).rebuild(syntacticBase);
    874 
    875   return syntacticBase;
    876 }
    877 
    878 /// CheckSubscriptingKind - This routine decide what type
    879 /// of indexing represented by "FromE" is being done.
    880 Sema::ObjCSubscriptKind
    881   Sema::CheckSubscriptingKind(Expr *FromE) {
    882   // If the expression already has integral or enumeration type, we're golden.
    883   QualType T = FromE->getType();
    884   if (T->isIntegralOrEnumerationType())
    885     return OS_Array;
    886 
    887   // If we don't have a class type in C++, there's no way we can get an
    888   // expression of integral or enumeration type.
    889   const RecordType *RecordTy = T->getAs<RecordType>();
    890   if (!RecordTy && T->isObjCObjectPointerType())
    891     // All other scalar cases are assumed to be dictionary indexing which
    892     // caller handles, with diagnostics if needed.
    893     return OS_Dictionary;
    894   if (!getLangOpts().CPlusPlus ||
    895       !RecordTy || RecordTy->isIncompleteType()) {
    896     // No indexing can be done. Issue diagnostics and quit.
    897     const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
    898     if (isa<StringLiteral>(IndexExpr))
    899       Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
    900         << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
    901     else
    902       Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
    903         << T;
    904     return OS_Error;
    905   }
    906 
    907   // We must have a complete class type.
    908   if (RequireCompleteType(FromE->getExprLoc(), T,
    909                           diag::err_objc_index_incomplete_class_type, FromE))
    910     return OS_Error;
    911 
    912   // Look for a conversion to an integral, enumeration type, or
    913   // objective-C pointer type.
    914   UnresolvedSet<4> ViableConversions;
    915   UnresolvedSet<4> ExplicitConversions;
    916   const UnresolvedSetImpl *Conversions
    917     = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
    918 
    919   int NoIntegrals=0, NoObjCIdPointers=0;
    920   SmallVector<CXXConversionDecl *, 4> ConversionDecls;
    921 
    922   for (UnresolvedSetImpl::iterator I = Conversions->begin(),
    923        E = Conversions->end();
    924        I != E;
    925        ++I) {
    926     if (CXXConversionDecl *Conversion
    927         = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
    928       QualType CT = Conversion->getConversionType().getNonReferenceType();
    929       if (CT->isIntegralOrEnumerationType()) {
    930         ++NoIntegrals;
    931         ConversionDecls.push_back(Conversion);
    932       }
    933       else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
    934         ++NoObjCIdPointers;
    935         ConversionDecls.push_back(Conversion);
    936       }
    937     }
    938   }
    939   if (NoIntegrals ==1 && NoObjCIdPointers == 0)
    940     return OS_Array;
    941   if (NoIntegrals == 0 && NoObjCIdPointers == 1)
    942     return OS_Dictionary;
    943   if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
    944     // No conversion function was found. Issue diagnostic and return.
    945     Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
    946       << FromE->getType();
    947     return OS_Error;
    948   }
    949   Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
    950       << FromE->getType();
    951   for (unsigned int i = 0; i < ConversionDecls.size(); i++)
    952     Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
    953 
    954   return OS_Error;
    955 }
    956 
    957 /// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
    958 /// objects used as dictionary subscript key objects.
    959 static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT,
    960                                          Expr *Key) {
    961   if (ContainerT.isNull())
    962     return;
    963   // dictionary subscripting.
    964   // - (id)objectForKeyedSubscript:(id)key;
    965   IdentifierInfo *KeyIdents[] = {
    966     &S.Context.Idents.get("objectForKeyedSubscript")
    967   };
    968   Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
    969   ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT,
    970                                                       true /*instance*/);
    971   if (!Getter)
    972     return;
    973   QualType T = Getter->param_begin()[0]->getType();
    974   S.CheckObjCARCConversion(Key->getSourceRange(),
    975                          T, Key, Sema::CCK_ImplicitConversion);
    976 }
    977 
    978 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
    979   if (AtIndexGetter)
    980     return true;
    981 
    982   Expr *BaseExpr = RefExpr->getBaseExpr();
    983   QualType BaseT = BaseExpr->getType();
    984 
    985   QualType ResultType;
    986   if (const ObjCObjectPointerType *PTy =
    987       BaseT->getAs<ObjCObjectPointerType>()) {
    988     ResultType = PTy->getPointeeType();
    989     if (const ObjCObjectType *iQFaceTy =
    990         ResultType->getAsObjCQualifiedInterfaceType())
    991       ResultType = iQFaceTy->getBaseType();
    992   }
    993   Sema::ObjCSubscriptKind Res =
    994     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
    995   if (Res == Sema::OS_Error) {
    996     if (S.getLangOpts().ObjCAutoRefCount)
    997       CheckKeyForObjCARCConversion(S, ResultType,
    998                                    RefExpr->getKeyExpr());
    999     return false;
   1000   }
   1001   bool arrayRef = (Res == Sema::OS_Array);
   1002 
   1003   if (ResultType.isNull()) {
   1004     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
   1005       << BaseExpr->getType() << arrayRef;
   1006     return false;
   1007   }
   1008   if (!arrayRef) {
   1009     // dictionary subscripting.
   1010     // - (id)objectForKeyedSubscript:(id)key;
   1011     IdentifierInfo *KeyIdents[] = {
   1012       &S.Context.Idents.get("objectForKeyedSubscript")
   1013     };
   1014     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
   1015   }
   1016   else {
   1017     // - (id)objectAtIndexedSubscript:(size_t)index;
   1018     IdentifierInfo *KeyIdents[] = {
   1019       &S.Context.Idents.get("objectAtIndexedSubscript")
   1020     };
   1021 
   1022     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
   1023   }
   1024 
   1025   AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType,
   1026                                              true /*instance*/);
   1027   bool receiverIdType = (BaseT->isObjCIdType() ||
   1028                          BaseT->isObjCQualifiedIdType());
   1029 
   1030   if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {
   1031     AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
   1032                            SourceLocation(), AtIndexGetterSelector,
   1033                            S.Context.getObjCIdType() /*ReturnType*/,
   1034                            0 /*TypeSourceInfo */,
   1035                            S.Context.getTranslationUnitDecl(),
   1036                            true /*Instance*/, false/*isVariadic*/,
   1037                            /*isSynthesized=*/false,
   1038                            /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
   1039                            ObjCMethodDecl::Required,
   1040                            false);
   1041     ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
   1042                                                 SourceLocation(), SourceLocation(),
   1043                                                 arrayRef ? &S.Context.Idents.get("index")
   1044                                                          : &S.Context.Idents.get("key"),
   1045                                                 arrayRef ? S.Context.UnsignedLongTy
   1046                                                          : S.Context.getObjCIdType(),
   1047                                                 /*TInfo=*/0,
   1048                                                 SC_None,
   1049                                                 SC_None,
   1050                                                 0);
   1051     AtIndexGetter->setMethodParams(S.Context, Argument,
   1052                                    ArrayRef<SourceLocation>());
   1053   }
   1054 
   1055   if (!AtIndexGetter) {
   1056     if (!receiverIdType) {
   1057       S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
   1058       << BaseExpr->getType() << 0 << arrayRef;
   1059       return false;
   1060     }
   1061     AtIndexGetter =
   1062       S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector,
   1063                                          RefExpr->getSourceRange(),
   1064                                          true, false);
   1065   }
   1066 
   1067   if (AtIndexGetter) {
   1068     QualType T = AtIndexGetter->param_begin()[0]->getType();
   1069     if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
   1070         (!arrayRef && !T->isObjCObjectPointerType())) {
   1071       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1072              arrayRef ? diag::err_objc_subscript_index_type
   1073                       : diag::err_objc_subscript_key_type) << T;
   1074       S.Diag(AtIndexGetter->param_begin()[0]->getLocation(),
   1075              diag::note_parameter_type) << T;
   1076       return false;
   1077     }
   1078     QualType R = AtIndexGetter->getResultType();
   1079     if (!R->isObjCObjectPointerType()) {
   1080       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1081              diag::err_objc_indexing_method_result_type) << R << arrayRef;
   1082       S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
   1083         AtIndexGetter->getDeclName();
   1084     }
   1085   }
   1086   return true;
   1087 }
   1088 
   1089 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
   1090   if (AtIndexSetter)
   1091     return true;
   1092 
   1093   Expr *BaseExpr = RefExpr->getBaseExpr();
   1094   QualType BaseT = BaseExpr->getType();
   1095 
   1096   QualType ResultType;
   1097   if (const ObjCObjectPointerType *PTy =
   1098       BaseT->getAs<ObjCObjectPointerType>()) {
   1099     ResultType = PTy->getPointeeType();
   1100     if (const ObjCObjectType *iQFaceTy =
   1101         ResultType->getAsObjCQualifiedInterfaceType())
   1102       ResultType = iQFaceTy->getBaseType();
   1103   }
   1104 
   1105   Sema::ObjCSubscriptKind Res =
   1106     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
   1107   if (Res == Sema::OS_Error) {
   1108     if (S.getLangOpts().ObjCAutoRefCount)
   1109       CheckKeyForObjCARCConversion(S, ResultType,
   1110                                    RefExpr->getKeyExpr());
   1111     return false;
   1112   }
   1113   bool arrayRef = (Res == Sema::OS_Array);
   1114 
   1115   if (ResultType.isNull()) {
   1116     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
   1117       << BaseExpr->getType() << arrayRef;
   1118     return false;
   1119   }
   1120 
   1121   if (!arrayRef) {
   1122     // dictionary subscripting.
   1123     // - (void)setObject:(id)object forKeyedSubscript:(id)key;
   1124     IdentifierInfo *KeyIdents[] = {
   1125       &S.Context.Idents.get("setObject"),
   1126       &S.Context.Idents.get("forKeyedSubscript")
   1127     };
   1128     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
   1129   }
   1130   else {
   1131     // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
   1132     IdentifierInfo *KeyIdents[] = {
   1133       &S.Context.Idents.get("setObject"),
   1134       &S.Context.Idents.get("atIndexedSubscript")
   1135     };
   1136     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
   1137   }
   1138   AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType,
   1139                                              true /*instance*/);
   1140 
   1141   bool receiverIdType = (BaseT->isObjCIdType() ||
   1142                          BaseT->isObjCQualifiedIdType());
   1143 
   1144   if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
   1145     TypeSourceInfo *ResultTInfo = 0;
   1146     QualType ReturnType = S.Context.VoidTy;
   1147     AtIndexSetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
   1148                            SourceLocation(), AtIndexSetterSelector,
   1149                            ReturnType,
   1150                            ResultTInfo,
   1151                            S.Context.getTranslationUnitDecl(),
   1152                            true /*Instance*/, false/*isVariadic*/,
   1153                            /*isSynthesized=*/false,
   1154                            /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
   1155                            ObjCMethodDecl::Required,
   1156                            false);
   1157     SmallVector<ParmVarDecl *, 2> Params;
   1158     ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
   1159                                                 SourceLocation(), SourceLocation(),
   1160                                                 &S.Context.Idents.get("object"),
   1161                                                 S.Context.getObjCIdType(),
   1162                                                 /*TInfo=*/0,
   1163                                                 SC_None,
   1164                                                 SC_None,
   1165                                                 0);
   1166     Params.push_back(object);
   1167     ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
   1168                                                 SourceLocation(), SourceLocation(),
   1169                                                 arrayRef ?  &S.Context.Idents.get("index")
   1170                                                          :  &S.Context.Idents.get("key"),
   1171                                                 arrayRef ? S.Context.UnsignedLongTy
   1172                                                          : S.Context.getObjCIdType(),
   1173                                                 /*TInfo=*/0,
   1174                                                 SC_None,
   1175                                                 SC_None,
   1176                                                 0);
   1177     Params.push_back(key);
   1178     AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
   1179   }
   1180 
   1181   if (!AtIndexSetter) {
   1182     if (!receiverIdType) {
   1183       S.Diag(BaseExpr->getExprLoc(),
   1184              diag::err_objc_subscript_method_not_found)
   1185       << BaseExpr->getType() << 1 << arrayRef;
   1186       return false;
   1187     }
   1188     AtIndexSetter =
   1189       S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector,
   1190                                          RefExpr->getSourceRange(),
   1191                                          true, false);
   1192   }
   1193 
   1194   bool err = false;
   1195   if (AtIndexSetter && arrayRef) {
   1196     QualType T = AtIndexSetter->param_begin()[1]->getType();
   1197     if (!T->isIntegralOrEnumerationType()) {
   1198       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1199              diag::err_objc_subscript_index_type) << T;
   1200       S.Diag(AtIndexSetter->param_begin()[1]->getLocation(),
   1201              diag::note_parameter_type) << T;
   1202       err = true;
   1203     }
   1204     T = AtIndexSetter->param_begin()[0]->getType();
   1205     if (!T->isObjCObjectPointerType()) {
   1206       S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
   1207              diag::err_objc_subscript_object_type) << T << arrayRef;
   1208       S.Diag(AtIndexSetter->param_begin()[0]->getLocation(),
   1209              diag::note_parameter_type) << T;
   1210       err = true;
   1211     }
   1212   }
   1213   else if (AtIndexSetter && !arrayRef)
   1214     for (unsigned i=0; i <2; i++) {
   1215       QualType T = AtIndexSetter->param_begin()[i]->getType();
   1216       if (!T->isObjCObjectPointerType()) {
   1217         if (i == 1)
   1218           S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1219                  diag::err_objc_subscript_key_type) << T;
   1220         else
   1221           S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
   1222                  diag::err_objc_subscript_dic_object_type) << T;
   1223         S.Diag(AtIndexSetter->param_begin()[i]->getLocation(),
   1224                diag::note_parameter_type) << T;
   1225         err = true;
   1226       }
   1227     }
   1228 
   1229   return !err;
   1230 }
   1231 
   1232 // Get the object at "Index" position in the container.
   1233 // [BaseExpr objectAtIndexedSubscript : IndexExpr];
   1234 ExprResult ObjCSubscriptOpBuilder::buildGet() {
   1235   if (!findAtIndexGetter())
   1236     return ExprError();
   1237 
   1238   QualType receiverType = InstanceBase->getType();
   1239 
   1240   // Build a message-send.
   1241   ExprResult msg;
   1242   Expr *Index = InstanceKey;
   1243 
   1244   // Arguments.
   1245   Expr *args[] = { Index };
   1246   assert(InstanceBase);
   1247   msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
   1248                                        GenericLoc,
   1249                                        AtIndexGetterSelector, AtIndexGetter,
   1250                                        MultiExprArg(args, 1));
   1251   return msg;
   1252 }
   1253 
   1254 /// Store into the container the "op" object at "Index"'ed location
   1255 /// by building this messaging expression:
   1256 /// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
   1257 /// \param captureSetValueAsResult If true, capture the actual
   1258 ///   value being set as the value of the property operation.
   1259 ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
   1260                                            bool captureSetValueAsResult) {
   1261   if (!findAtIndexSetter())
   1262     return ExprError();
   1263 
   1264   QualType receiverType = InstanceBase->getType();
   1265   Expr *Index = InstanceKey;
   1266 
   1267   // Arguments.
   1268   Expr *args[] = { op, Index };
   1269 
   1270   // Build a message-send.
   1271   ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
   1272                                                   GenericLoc,
   1273                                                   AtIndexSetterSelector,
   1274                                                   AtIndexSetter,
   1275                                                   MultiExprArg(args, 2));
   1276 
   1277   if (!msg.isInvalid() && captureSetValueAsResult) {
   1278     ObjCMessageExpr *msgExpr =
   1279       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
   1280     Expr *arg = msgExpr->getArg(0);
   1281     msgExpr->setArg(0, captureValueAsResult(arg));
   1282   }
   1283 
   1284   return msg;
   1285 }
   1286 
   1287 //===----------------------------------------------------------------------===//
   1288 //  General Sema routines.
   1289 //===----------------------------------------------------------------------===//
   1290 
   1291 ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
   1292   Expr *opaqueRef = E->IgnoreParens();
   1293   if (ObjCPropertyRefExpr *refExpr
   1294         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1295     ObjCPropertyOpBuilder builder(*this, refExpr);
   1296     return builder.buildRValueOperation(E);
   1297   }
   1298   else if (ObjCSubscriptRefExpr *refExpr
   1299            = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
   1300     ObjCSubscriptOpBuilder builder(*this, refExpr);
   1301     return builder.buildRValueOperation(E);
   1302   } else {
   1303     llvm_unreachable("unknown pseudo-object kind!");
   1304   }
   1305 }
   1306 
   1307 /// Check an increment or decrement of a pseudo-object expression.
   1308 ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
   1309                                          UnaryOperatorKind opcode, Expr *op) {
   1310   // Do nothing if the operand is dependent.
   1311   if (op->isTypeDependent())
   1312     return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
   1313                                        VK_RValue, OK_Ordinary, opcLoc);
   1314 
   1315   assert(UnaryOperator::isIncrementDecrementOp(opcode));
   1316   Expr *opaqueRef = op->IgnoreParens();
   1317   if (ObjCPropertyRefExpr *refExpr
   1318         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1319     ObjCPropertyOpBuilder builder(*this, refExpr);
   1320     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
   1321   } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
   1322     Diag(opcLoc, diag::err_illegal_container_subscripting_op);
   1323     return ExprError();
   1324   } else {
   1325     llvm_unreachable("unknown pseudo-object kind!");
   1326   }
   1327 }
   1328 
   1329 ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
   1330                                              BinaryOperatorKind opcode,
   1331                                              Expr *LHS, Expr *RHS) {
   1332   // Do nothing if either argument is dependent.
   1333   if (LHS->isTypeDependent() || RHS->isTypeDependent())
   1334     return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
   1335                                         VK_RValue, OK_Ordinary, opcLoc);
   1336 
   1337   // Filter out non-overload placeholder types in the RHS.
   1338   if (RHS->getType()->isNonOverloadPlaceholderType()) {
   1339     ExprResult result = CheckPlaceholderExpr(RHS);
   1340     if (result.isInvalid()) return ExprError();
   1341     RHS = result.take();
   1342   }
   1343 
   1344   Expr *opaqueRef = LHS->IgnoreParens();
   1345   if (ObjCPropertyRefExpr *refExpr
   1346         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1347     ObjCPropertyOpBuilder builder(*this, refExpr);
   1348     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
   1349   } else if (ObjCSubscriptRefExpr *refExpr
   1350              = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
   1351     ObjCSubscriptOpBuilder builder(*this, refExpr);
   1352     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
   1353   } else {
   1354     llvm_unreachable("unknown pseudo-object kind!");
   1355   }
   1356 }
   1357 
   1358 /// Given a pseudo-object reference, rebuild it without the opaque
   1359 /// values.  Basically, undo the behavior of rebuildAndCaptureObject.
   1360 /// This should never operate in-place.
   1361 static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
   1362   Expr *opaqueRef = E->IgnoreParens();
   1363   if (ObjCPropertyRefExpr *refExpr
   1364         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1365     // Class and super property references don't have opaque values in them.
   1366     if (refExpr->isClassReceiver() || refExpr->isSuperReceiver())
   1367       return E;
   1368 
   1369     assert(refExpr->isObjectReceiver() && "Unknown receiver kind?");
   1370     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
   1371     return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
   1372   } else if (ObjCSubscriptRefExpr *refExpr
   1373                = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
   1374     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
   1375     OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
   1376     return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
   1377                                      keyOVE->getSourceExpr()).rebuild(E);
   1378   } else {
   1379     llvm_unreachable("unknown pseudo-object kind!");
   1380   }
   1381 }
   1382 
   1383 /// Given a pseudo-object expression, recreate what it looks like
   1384 /// syntactically without the attendant OpaqueValueExprs.
   1385 ///
   1386 /// This is a hack which should be removed when TreeTransform is
   1387 /// capable of rebuilding a tree without stripping implicit
   1388 /// operations.
   1389 Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
   1390   Expr *syntax = E->getSyntacticForm();
   1391   if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
   1392     Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
   1393     return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
   1394                                        uop->getValueKind(), uop->getObjectKind(),
   1395                                        uop->getOperatorLoc());
   1396   } else if (CompoundAssignOperator *cop
   1397                = dyn_cast<CompoundAssignOperator>(syntax)) {
   1398     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
   1399     Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
   1400     return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
   1401                                                 cop->getType(),
   1402                                                 cop->getValueKind(),
   1403                                                 cop->getObjectKind(),
   1404                                                 cop->getComputationLHSType(),
   1405                                                 cop->getComputationResultType(),
   1406                                                 cop->getOperatorLoc());
   1407   } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
   1408     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
   1409     Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
   1410     return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
   1411                                         bop->getType(), bop->getValueKind(),
   1412                                         bop->getObjectKind(),
   1413                                         bop->getOperatorLoc());
   1414   } else {
   1415     assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
   1416     return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
   1417   }
   1418 }
   1419