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