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     void 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   // Recover from user error
    411   if (isa<UnresolvedLookupExpr>(RHS))
    412     return ExprError();
    413 
    414   Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
    415   OpaqueValueExpr *capturedRHS = capture(RHS);
    416 
    417   Expr *syntactic;
    418 
    419   ExprResult result;
    420   if (opcode == BO_Assign) {
    421     result = capturedRHS;
    422     syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
    423                                                opcode, capturedRHS->getType(),
    424                                                capturedRHS->getValueKind(),
    425                                                OK_Ordinary, opcLoc, false);
    426   } else {
    427     ExprResult opLHS = buildGet();
    428     if (opLHS.isInvalid()) return ExprError();
    429 
    430     // Build an ordinary, non-compound operation.
    431     BinaryOperatorKind nonCompound =
    432       BinaryOperator::getOpForCompoundAssignment(opcode);
    433     result = S.BuildBinOp(Sc, opcLoc, nonCompound,
    434                           opLHS.get(), capturedRHS);
    435     if (result.isInvalid()) return ExprError();
    436 
    437     syntactic =
    438       new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
    439                                              result.get()->getType(),
    440                                              result.get()->getValueKind(),
    441                                              OK_Ordinary,
    442                                              opLHS.get()->getType(),
    443                                              result.get()->getType(),
    444                                              opcLoc, false);
    445   }
    446 
    447   // The result of the assignment, if not void, is the value set into
    448   // the l-value.
    449   result = buildSet(result.get(), opcLoc, /*captureSetValueAsResult*/ true);
    450   if (result.isInvalid()) return ExprError();
    451   addSemanticExpr(result.get());
    452 
    453   return complete(syntactic);
    454 }
    455 
    456 /// The basic skeleton for building an increment or decrement
    457 /// operation.
    458 ExprResult
    459 PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
    460                                       UnaryOperatorKind opcode,
    461                                       Expr *op) {
    462   assert(UnaryOperator::isIncrementDecrementOp(opcode));
    463 
    464   Expr *syntacticOp = rebuildAndCaptureObject(op);
    465 
    466   // Load the value.
    467   ExprResult result = buildGet();
    468   if (result.isInvalid()) return ExprError();
    469 
    470   QualType resultType = result.get()->getType();
    471 
    472   // That's the postfix result.
    473   if (UnaryOperator::isPostfix(opcode) &&
    474       (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) {
    475     result = capture(result.get());
    476     setResultToLastSemantic();
    477   }
    478 
    479   // Add or subtract a literal 1.
    480   llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
    481   Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
    482                                      GenericLoc);
    483 
    484   if (UnaryOperator::isIncrementOp(opcode)) {
    485     result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);
    486   } else {
    487     result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);
    488   }
    489   if (result.isInvalid()) return ExprError();
    490 
    491   // Store that back into the result.  The value stored is the result
    492   // of a prefix operation.
    493   result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode));
    494   if (result.isInvalid()) return ExprError();
    495   addSemanticExpr(result.get());
    496 
    497   UnaryOperator *syntactic =
    498     new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
    499                                   VK_LValue, OK_Ordinary, opcLoc);
    500   return complete(syntactic);
    501 }
    502 
    503 
    504 //===----------------------------------------------------------------------===//
    505 //  Objective-C @property and implicit property references
    506 //===----------------------------------------------------------------------===//
    507 
    508 /// Look up a method in the receiver type of an Objective-C property
    509 /// reference.
    510 static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
    511                                             const ObjCPropertyRefExpr *PRE) {
    512   if (PRE->isObjectReceiver()) {
    513     const ObjCObjectPointerType *PT =
    514       PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
    515 
    516     // Special case for 'self' in class method implementations.
    517     if (PT->isObjCClassType() &&
    518         S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) {
    519       // This cast is safe because isSelfExpr is only true within
    520       // methods.
    521       ObjCMethodDecl *method =
    522         cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
    523       return S.LookupMethodInObjectType(sel,
    524                  S.Context.getObjCInterfaceType(method->getClassInterface()),
    525                                         /*instance*/ false);
    526     }
    527 
    528     return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
    529   }
    530 
    531   if (PRE->isSuperReceiver()) {
    532     if (const ObjCObjectPointerType *PT =
    533         PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>())
    534       return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
    535 
    536     return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false);
    537   }
    538 
    539   assert(PRE->isClassReceiver() && "Invalid expression");
    540   QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
    541   return S.LookupMethodInObjectType(sel, IT, false);
    542 }
    543 
    544 bool ObjCPropertyOpBuilder::isWeakProperty() const {
    545   QualType T;
    546   if (RefExpr->isExplicitProperty()) {
    547     const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
    548     if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
    549       return !Prop->hasAttr<IBOutletAttr>();
    550 
    551     T = Prop->getType();
    552   } else if (Getter) {
    553     T = Getter->getReturnType();
    554   } else {
    555     return false;
    556   }
    557 
    558   return T.getObjCLifetime() == Qualifiers::OCL_Weak;
    559 }
    560 
    561 bool ObjCPropertyOpBuilder::findGetter() {
    562   if (Getter) return true;
    563 
    564   // For implicit properties, just trust the lookup we already did.
    565   if (RefExpr->isImplicitProperty()) {
    566     if ((Getter = RefExpr->getImplicitPropertyGetter())) {
    567       GetterSelector = Getter->getSelector();
    568       return true;
    569     }
    570     else {
    571       // Must build the getter selector the hard way.
    572       ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter();
    573       assert(setter && "both setter and getter are null - cannot happen");
    574       IdentifierInfo *setterName =
    575         setter->getSelector().getIdentifierInfoForSlot(0);
    576       IdentifierInfo *getterName =
    577           &S.Context.Idents.get(setterName->getName().substr(3));
    578       GetterSelector =
    579         S.PP.getSelectorTable().getNullarySelector(getterName);
    580       return false;
    581     }
    582   }
    583 
    584   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
    585   Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
    586   return (Getter != nullptr);
    587 }
    588 
    589 /// Try to find the most accurate setter declaration for the property
    590 /// reference.
    591 ///
    592 /// \return true if a setter was found, in which case Setter
    593 bool ObjCPropertyOpBuilder::findSetter(bool warn) {
    594   // For implicit properties, just trust the lookup we already did.
    595   if (RefExpr->isImplicitProperty()) {
    596     if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
    597       Setter = setter;
    598       SetterSelector = setter->getSelector();
    599       return true;
    600     } else {
    601       IdentifierInfo *getterName =
    602         RefExpr->getImplicitPropertyGetter()->getSelector()
    603           .getIdentifierInfoForSlot(0);
    604       SetterSelector =
    605         SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
    606                                                S.PP.getSelectorTable(),
    607                                                getterName);
    608       return false;
    609     }
    610   }
    611 
    612   // For explicit properties, this is more involved.
    613   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
    614   SetterSelector = prop->getSetterName();
    615 
    616   // Do a normal method lookup first.
    617   if (ObjCMethodDecl *setter =
    618         LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
    619     if (setter->isPropertyAccessor() && warn)
    620       if (const ObjCInterfaceDecl *IFace =
    621           dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
    622         StringRef thisPropertyName = prop->getName();
    623         // Try flipping the case of the first character.
    624         char front = thisPropertyName.front();
    625         front = isLowercase(front) ? toUppercase(front) : toLowercase(front);
    626         SmallString<100> PropertyName = thisPropertyName;
    627         PropertyName[0] = front;
    628         IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName);
    629         if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(AltMember))
    630           if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
    631             S.Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use)
    632               << prop << prop1 << setter->getSelector();
    633             S.Diag(prop->getLocation(), diag::note_property_declare);
    634             S.Diag(prop1->getLocation(), diag::note_property_declare);
    635           }
    636       }
    637     Setter = setter;
    638     return true;
    639   }
    640 
    641   // That can fail in the somewhat crazy situation that we're
    642   // type-checking a message send within the @interface declaration
    643   // that declared the @property.  But it's not clear that that's
    644   // valuable to support.
    645 
    646   return false;
    647 }
    648 
    649 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
    650   if (S.getCurLexicalContext()->isObjCContainer() &&
    651       S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
    652       S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
    653     if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
    654         S.Diag(RefExpr->getLocation(),
    655                diag::err_property_function_in_objc_container);
    656         S.Diag(prop->getLocation(), diag::note_property_declare);
    657     }
    658   }
    659 }
    660 
    661 /// Capture the base object of an Objective-C property expression.
    662 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
    663   assert(InstanceReceiver == nullptr);
    664 
    665   // If we have a base, capture it in an OVE and rebuild the syntactic
    666   // form to use the OVE as its base.
    667   if (RefExpr->isObjectReceiver()) {
    668     InstanceReceiver = capture(RefExpr->getBase());
    669 
    670     syntacticBase =
    671       ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
    672   }
    673 
    674   if (ObjCPropertyRefExpr *
    675         refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
    676     SyntacticRefExpr = refE;
    677 
    678   return syntacticBase;
    679 }
    680 
    681 /// Load from an Objective-C property reference.
    682 ExprResult ObjCPropertyOpBuilder::buildGet() {
    683   findGetter();
    684   if (!Getter) {
    685     DiagnoseUnsupportedPropertyUse();
    686     return ExprError();
    687   }
    688 
    689   if (SyntacticRefExpr)
    690     SyntacticRefExpr->setIsMessagingGetter();
    691 
    692   QualType receiverType;
    693   if (RefExpr->isClassReceiver()) {
    694     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
    695   } else if (RefExpr->isSuperReceiver()) {
    696     receiverType = RefExpr->getSuperReceiverType();
    697   } else {
    698     assert(InstanceReceiver);
    699     receiverType = InstanceReceiver->getType();
    700   }
    701   if (!Getter->isImplicit())
    702     S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
    703   // Build a message-send.
    704   ExprResult msg;
    705   if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
    706       RefExpr->isObjectReceiver()) {
    707     assert(InstanceReceiver || RefExpr->isSuperReceiver());
    708     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
    709                                          GenericLoc, Getter->getSelector(),
    710                                          Getter, None);
    711   } else {
    712     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
    713                                       GenericLoc, Getter->getSelector(),
    714                                       Getter, None);
    715   }
    716   return msg;
    717 }
    718 
    719 /// Store to an Objective-C property reference.
    720 ///
    721 /// \param captureSetValueAsResult If true, capture the actual
    722 ///   value being set as the value of the property operation.
    723 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
    724                                            bool captureSetValueAsResult) {
    725   if (!findSetter(false)) {
    726     DiagnoseUnsupportedPropertyUse();
    727     return ExprError();
    728   }
    729 
    730   if (SyntacticRefExpr)
    731     SyntacticRefExpr->setIsMessagingSetter();
    732 
    733   QualType receiverType;
    734   if (RefExpr->isClassReceiver()) {
    735     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
    736   } else if (RefExpr->isSuperReceiver()) {
    737     receiverType = RefExpr->getSuperReceiverType();
    738   } else {
    739     assert(InstanceReceiver);
    740     receiverType = InstanceReceiver->getType();
    741   }
    742 
    743   // Use assignment constraints when possible; they give us better
    744   // diagnostics.  "When possible" basically means anything except a
    745   // C++ class type.
    746   if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) {
    747     QualType paramType = (*Setter->param_begin())->getType();
    748     if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) {
    749       ExprResult opResult = op;
    750       Sema::AssignConvertType assignResult
    751         = S.CheckSingleAssignmentConstraints(paramType, opResult);
    752       if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
    753                                      op->getType(), opResult.get(),
    754                                      Sema::AA_Assigning))
    755         return ExprError();
    756 
    757       op = opResult.get();
    758       assert(op && "successful assignment left argument invalid?");
    759     }
    760     else if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(op)) {
    761       Expr *Initializer = OVE->getSourceExpr();
    762       // passing C++11 style initialized temporaries to objc++ properties
    763       // requires special treatment by removing OpaqueValueExpr so type
    764       // conversion takes place and adding the OpaqueValueExpr later on.
    765       if (isa<InitListExpr>(Initializer) &&
    766           Initializer->getType()->isVoidType()) {
    767         op = Initializer;
    768       }
    769     }
    770   }
    771 
    772   // Arguments.
    773   Expr *args[] = { op };
    774 
    775   // Build a message-send.
    776   ExprResult msg;
    777   if (!Setter->isImplicit())
    778     S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
    779   if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
    780       RefExpr->isObjectReceiver()) {
    781     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
    782                                          GenericLoc, SetterSelector, Setter,
    783                                          MultiExprArg(args, 1));
    784   } else {
    785     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
    786                                       GenericLoc,
    787                                       SetterSelector, Setter,
    788                                       MultiExprArg(args, 1));
    789   }
    790 
    791   if (!msg.isInvalid() && captureSetValueAsResult) {
    792     ObjCMessageExpr *msgExpr =
    793       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
    794     Expr *arg = msgExpr->getArg(0);
    795     if (CanCaptureValue(arg))
    796       msgExpr->setArg(0, captureValueAsResult(arg));
    797   }
    798 
    799   return msg;
    800 }
    801 
    802 /// @property-specific behavior for doing lvalue-to-rvalue conversion.
    803 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
    804   // Explicit properties always have getters, but implicit ones don't.
    805   // Check that before proceeding.
    806   if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
    807     S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
    808         << RefExpr->getSourceRange();
    809     return ExprError();
    810   }
    811 
    812   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
    813   if (result.isInvalid()) return ExprError();
    814 
    815   if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
    816     S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
    817                                        Getter, RefExpr->getLocation());
    818 
    819   // As a special case, if the method returns 'id', try to get
    820   // a better type from the property.
    821   if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
    822     QualType propType = RefExpr->getExplicitProperty()->getType();
    823     if (result.get()->getType()->isObjCIdType()) {
    824       if (const ObjCObjectPointerType *ptr
    825             = propType->getAs<ObjCObjectPointerType>()) {
    826         if (!ptr->isObjCIdType())
    827           result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
    828       }
    829     }
    830     if (S.getLangOpts().ObjCAutoRefCount) {
    831       Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
    832       if (LT == Qualifiers::OCL_Weak)
    833         if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
    834               S.getCurFunction()->markSafeWeakUse(RefExpr);
    835     }
    836   }
    837 
    838   return result;
    839 }
    840 
    841 /// Try to build this as a call to a getter that returns a reference.
    842 ///
    843 /// \return true if it was possible, whether or not it actually
    844 ///   succeeded
    845 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
    846                                                    ExprResult &result) {
    847   if (!S.getLangOpts().CPlusPlus) return false;
    848 
    849   findGetter();
    850   if (!Getter) {
    851     // The property has no setter and no getter! This can happen if the type is
    852     // invalid. Error have already been reported.
    853     result = ExprError();
    854     return true;
    855   }
    856 
    857   // Only do this if the getter returns an l-value reference type.
    858   QualType resultType = Getter->getReturnType();
    859   if (!resultType->isLValueReferenceType()) return false;
    860 
    861   result = buildRValueOperation(op);
    862   return true;
    863 }
    864 
    865 /// @property-specific behavior for doing assignments.
    866 ExprResult
    867 ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
    868                                                 SourceLocation opcLoc,
    869                                                 BinaryOperatorKind opcode,
    870                                                 Expr *LHS, Expr *RHS) {
    871   assert(BinaryOperator::isAssignmentOp(opcode));
    872 
    873   // If there's no setter, we have no choice but to try to assign to
    874   // the result of the getter.
    875   if (!findSetter()) {
    876     ExprResult result;
    877     if (tryBuildGetOfReference(LHS, result)) {
    878       if (result.isInvalid()) return ExprError();
    879       return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);
    880     }
    881 
    882     // Otherwise, it's an error.
    883     S.Diag(opcLoc, diag::err_nosetter_property_assignment)
    884       << unsigned(RefExpr->isImplicitProperty())
    885       << SetterSelector
    886       << LHS->getSourceRange() << RHS->getSourceRange();
    887     return ExprError();
    888   }
    889 
    890   // If there is a setter, we definitely want to use it.
    891 
    892   // Verify that we can do a compound assignment.
    893   if (opcode != BO_Assign && !findGetter()) {
    894     S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
    895       << LHS->getSourceRange() << RHS->getSourceRange();
    896     return ExprError();
    897   }
    898 
    899   ExprResult result =
    900     PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
    901   if (result.isInvalid()) return ExprError();
    902 
    903   // Various warnings about property assignments in ARC.
    904   if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
    905     S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
    906     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
    907   }
    908 
    909   return result;
    910 }
    911 
    912 /// @property-specific behavior for doing increments and decrements.
    913 ExprResult
    914 ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
    915                                             UnaryOperatorKind opcode,
    916                                             Expr *op) {
    917   // If there's no setter, we have no choice but to try to assign to
    918   // the result of the getter.
    919   if (!findSetter()) {
    920     ExprResult result;
    921     if (tryBuildGetOfReference(op, result)) {
    922       if (result.isInvalid()) return ExprError();
    923       return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get());
    924     }
    925 
    926     // Otherwise, it's an error.
    927     S.Diag(opcLoc, diag::err_nosetter_property_incdec)
    928       << unsigned(RefExpr->isImplicitProperty())
    929       << unsigned(UnaryOperator::isDecrementOp(opcode))
    930       << SetterSelector
    931       << op->getSourceRange();
    932     return ExprError();
    933   }
    934 
    935   // If there is a setter, we definitely want to use it.
    936 
    937   // We also need a getter.
    938   if (!findGetter()) {
    939     assert(RefExpr->isImplicitProperty());
    940     S.Diag(opcLoc, diag::err_nogetter_property_incdec)
    941       << unsigned(UnaryOperator::isDecrementOp(opcode))
    942       << GetterSelector
    943       << op->getSourceRange();
    944     return ExprError();
    945   }
    946 
    947   return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
    948 }
    949 
    950 ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
    951   if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
    952       !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
    953                          SyntacticForm->getLocStart()))
    954       S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
    955                                  SyntacticRefExpr->isMessagingGetter());
    956 
    957   return PseudoOpBuilder::complete(SyntacticForm);
    958 }
    959 
    960 // ObjCSubscript build stuff.
    961 //
    962 
    963 /// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
    964 /// conversion.
    965 /// FIXME. Remove this routine if it is proven that no additional
    966 /// specifity is needed.
    967 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
    968   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
    969   if (result.isInvalid()) return ExprError();
    970   return result;
    971 }
    972 
    973 /// objective-c subscripting-specific  behavior for doing assignments.
    974 ExprResult
    975 ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
    976                                                 SourceLocation opcLoc,
    977                                                 BinaryOperatorKind opcode,
    978                                                 Expr *LHS, Expr *RHS) {
    979   assert(BinaryOperator::isAssignmentOp(opcode));
    980   // There must be a method to do the Index'ed assignment.
    981   if (!findAtIndexSetter())
    982     return ExprError();
    983 
    984   // Verify that we can do a compound assignment.
    985   if (opcode != BO_Assign && !findAtIndexGetter())
    986     return ExprError();
    987 
    988   ExprResult result =
    989   PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
    990   if (result.isInvalid()) return ExprError();
    991 
    992   // Various warnings about objc Index'ed assignments in ARC.
    993   if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {
    994     S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
    995     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
    996   }
    997 
    998   return result;
    999 }
   1000 
   1001 /// Capture the base object of an Objective-C Index'ed expression.
   1002 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
   1003   assert(InstanceBase == nullptr);
   1004 
   1005   // Capture base expression in an OVE and rebuild the syntactic
   1006   // form to use the OVE as its base expression.
   1007   InstanceBase = capture(RefExpr->getBaseExpr());
   1008   InstanceKey = capture(RefExpr->getKeyExpr());
   1009 
   1010   syntacticBase =
   1011     ObjCSubscriptRefRebuilder(S, InstanceBase,
   1012                               InstanceKey).rebuild(syntacticBase);
   1013 
   1014   return syntacticBase;
   1015 }
   1016 
   1017 /// CheckSubscriptingKind - This routine decide what type
   1018 /// of indexing represented by "FromE" is being done.
   1019 Sema::ObjCSubscriptKind
   1020   Sema::CheckSubscriptingKind(Expr *FromE) {
   1021   // If the expression already has integral or enumeration type, we're golden.
   1022   QualType T = FromE->getType();
   1023   if (T->isIntegralOrEnumerationType())
   1024     return OS_Array;
   1025 
   1026   // If we don't have a class type in C++, there's no way we can get an
   1027   // expression of integral or enumeration type.
   1028   const RecordType *RecordTy = T->getAs<RecordType>();
   1029   if (!RecordTy &&
   1030       (T->isObjCObjectPointerType() || T->isVoidPointerType()))
   1031     // All other scalar cases are assumed to be dictionary indexing which
   1032     // caller handles, with diagnostics if needed.
   1033     return OS_Dictionary;
   1034   if (!getLangOpts().CPlusPlus ||
   1035       !RecordTy || RecordTy->isIncompleteType()) {
   1036     // No indexing can be done. Issue diagnostics and quit.
   1037     const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
   1038     if (isa<StringLiteral>(IndexExpr))
   1039       Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
   1040         << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
   1041     else
   1042       Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
   1043         << T;
   1044     return OS_Error;
   1045   }
   1046 
   1047   // We must have a complete class type.
   1048   if (RequireCompleteType(FromE->getExprLoc(), T,
   1049                           diag::err_objc_index_incomplete_class_type, FromE))
   1050     return OS_Error;
   1051 
   1052   // Look for a conversion to an integral, enumeration type, or
   1053   // objective-C pointer type.
   1054   int NoIntegrals=0, NoObjCIdPointers=0;
   1055   SmallVector<CXXConversionDecl *, 4> ConversionDecls;
   1056 
   1057   for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl())
   1058                           ->getVisibleConversionFunctions()) {
   1059     if (CXXConversionDecl *Conversion =
   1060             dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
   1061       QualType CT = Conversion->getConversionType().getNonReferenceType();
   1062       if (CT->isIntegralOrEnumerationType()) {
   1063         ++NoIntegrals;
   1064         ConversionDecls.push_back(Conversion);
   1065       }
   1066       else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
   1067         ++NoObjCIdPointers;
   1068         ConversionDecls.push_back(Conversion);
   1069       }
   1070     }
   1071   }
   1072   if (NoIntegrals ==1 && NoObjCIdPointers == 0)
   1073     return OS_Array;
   1074   if (NoIntegrals == 0 && NoObjCIdPointers == 1)
   1075     return OS_Dictionary;
   1076   if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
   1077     // No conversion function was found. Issue diagnostic and return.
   1078     Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
   1079       << FromE->getType();
   1080     return OS_Error;
   1081   }
   1082   Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
   1083       << FromE->getType();
   1084   for (unsigned int i = 0; i < ConversionDecls.size(); i++)
   1085     Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
   1086 
   1087   return OS_Error;
   1088 }
   1089 
   1090 /// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
   1091 /// objects used as dictionary subscript key objects.
   1092 static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT,
   1093                                          Expr *Key) {
   1094   if (ContainerT.isNull())
   1095     return;
   1096   // dictionary subscripting.
   1097   // - (id)objectForKeyedSubscript:(id)key;
   1098   IdentifierInfo *KeyIdents[] = {
   1099     &S.Context.Idents.get("objectForKeyedSubscript")
   1100   };
   1101   Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
   1102   ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT,
   1103                                                       true /*instance*/);
   1104   if (!Getter)
   1105     return;
   1106   QualType T = Getter->parameters()[0]->getType();
   1107   S.CheckObjCARCConversion(Key->getSourceRange(),
   1108                          T, Key, Sema::CCK_ImplicitConversion);
   1109 }
   1110 
   1111 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
   1112   if (AtIndexGetter)
   1113     return true;
   1114 
   1115   Expr *BaseExpr = RefExpr->getBaseExpr();
   1116   QualType BaseT = BaseExpr->getType();
   1117 
   1118   QualType ResultType;
   1119   if (const ObjCObjectPointerType *PTy =
   1120       BaseT->getAs<ObjCObjectPointerType>()) {
   1121     ResultType = PTy->getPointeeType();
   1122     if (const ObjCObjectType *iQFaceTy =
   1123         ResultType->getAsObjCQualifiedInterfaceType())
   1124       ResultType = iQFaceTy->getBaseType();
   1125   }
   1126   Sema::ObjCSubscriptKind Res =
   1127     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
   1128   if (Res == Sema::OS_Error) {
   1129     if (S.getLangOpts().ObjCAutoRefCount)
   1130       CheckKeyForObjCARCConversion(S, ResultType,
   1131                                    RefExpr->getKeyExpr());
   1132     return false;
   1133   }
   1134   bool arrayRef = (Res == Sema::OS_Array);
   1135 
   1136   if (ResultType.isNull()) {
   1137     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
   1138       << BaseExpr->getType() << arrayRef;
   1139     return false;
   1140   }
   1141   if (!arrayRef) {
   1142     // dictionary subscripting.
   1143     // - (id)objectForKeyedSubscript:(id)key;
   1144     IdentifierInfo *KeyIdents[] = {
   1145       &S.Context.Idents.get("objectForKeyedSubscript")
   1146     };
   1147     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
   1148   }
   1149   else {
   1150     // - (id)objectAtIndexedSubscript:(size_t)index;
   1151     IdentifierInfo *KeyIdents[] = {
   1152       &S.Context.Idents.get("objectAtIndexedSubscript")
   1153     };
   1154 
   1155     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
   1156   }
   1157 
   1158   AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType,
   1159                                              true /*instance*/);
   1160   bool receiverIdType = (BaseT->isObjCIdType() ||
   1161                          BaseT->isObjCQualifiedIdType());
   1162 
   1163   if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {
   1164     AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
   1165                            SourceLocation(), AtIndexGetterSelector,
   1166                            S.Context.getObjCIdType() /*ReturnType*/,
   1167                            nullptr /*TypeSourceInfo */,
   1168                            S.Context.getTranslationUnitDecl(),
   1169                            true /*Instance*/, false/*isVariadic*/,
   1170                            /*isPropertyAccessor=*/false,
   1171                            /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
   1172                            ObjCMethodDecl::Required,
   1173                            false);
   1174     ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
   1175                                                 SourceLocation(), SourceLocation(),
   1176                                                 arrayRef ? &S.Context.Idents.get("index")
   1177                                                          : &S.Context.Idents.get("key"),
   1178                                                 arrayRef ? S.Context.UnsignedLongTy
   1179                                                          : S.Context.getObjCIdType(),
   1180                                                 /*TInfo=*/nullptr,
   1181                                                 SC_None,
   1182                                                 nullptr);
   1183     AtIndexGetter->setMethodParams(S.Context, Argument, None);
   1184   }
   1185 
   1186   if (!AtIndexGetter) {
   1187     if (!receiverIdType) {
   1188       S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
   1189       << BaseExpr->getType() << 0 << arrayRef;
   1190       return false;
   1191     }
   1192     AtIndexGetter =
   1193       S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector,
   1194                                          RefExpr->getSourceRange(),
   1195                                          true);
   1196   }
   1197 
   1198   if (AtIndexGetter) {
   1199     QualType T = AtIndexGetter->parameters()[0]->getType();
   1200     if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
   1201         (!arrayRef && !T->isObjCObjectPointerType())) {
   1202       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1203              arrayRef ? diag::err_objc_subscript_index_type
   1204                       : diag::err_objc_subscript_key_type) << T;
   1205       S.Diag(AtIndexGetter->parameters()[0]->getLocation(),
   1206              diag::note_parameter_type) << T;
   1207       return false;
   1208     }
   1209     QualType R = AtIndexGetter->getReturnType();
   1210     if (!R->isObjCObjectPointerType()) {
   1211       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1212              diag::err_objc_indexing_method_result_type) << R << arrayRef;
   1213       S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
   1214         AtIndexGetter->getDeclName();
   1215     }
   1216   }
   1217   return true;
   1218 }
   1219 
   1220 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
   1221   if (AtIndexSetter)
   1222     return true;
   1223 
   1224   Expr *BaseExpr = RefExpr->getBaseExpr();
   1225   QualType BaseT = BaseExpr->getType();
   1226 
   1227   QualType ResultType;
   1228   if (const ObjCObjectPointerType *PTy =
   1229       BaseT->getAs<ObjCObjectPointerType>()) {
   1230     ResultType = PTy->getPointeeType();
   1231     if (const ObjCObjectType *iQFaceTy =
   1232         ResultType->getAsObjCQualifiedInterfaceType())
   1233       ResultType = iQFaceTy->getBaseType();
   1234   }
   1235 
   1236   Sema::ObjCSubscriptKind Res =
   1237     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
   1238   if (Res == Sema::OS_Error) {
   1239     if (S.getLangOpts().ObjCAutoRefCount)
   1240       CheckKeyForObjCARCConversion(S, ResultType,
   1241                                    RefExpr->getKeyExpr());
   1242     return false;
   1243   }
   1244   bool arrayRef = (Res == Sema::OS_Array);
   1245 
   1246   if (ResultType.isNull()) {
   1247     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
   1248       << BaseExpr->getType() << arrayRef;
   1249     return false;
   1250   }
   1251 
   1252   if (!arrayRef) {
   1253     // dictionary subscripting.
   1254     // - (void)setObject:(id)object forKeyedSubscript:(id)key;
   1255     IdentifierInfo *KeyIdents[] = {
   1256       &S.Context.Idents.get("setObject"),
   1257       &S.Context.Idents.get("forKeyedSubscript")
   1258     };
   1259     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
   1260   }
   1261   else {
   1262     // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
   1263     IdentifierInfo *KeyIdents[] = {
   1264       &S.Context.Idents.get("setObject"),
   1265       &S.Context.Idents.get("atIndexedSubscript")
   1266     };
   1267     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
   1268   }
   1269   AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType,
   1270                                              true /*instance*/);
   1271 
   1272   bool receiverIdType = (BaseT->isObjCIdType() ||
   1273                          BaseT->isObjCQualifiedIdType());
   1274 
   1275   if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
   1276     TypeSourceInfo *ReturnTInfo = nullptr;
   1277     QualType ReturnType = S.Context.VoidTy;
   1278     AtIndexSetter = ObjCMethodDecl::Create(
   1279         S.Context, SourceLocation(), SourceLocation(), AtIndexSetterSelector,
   1280         ReturnType, ReturnTInfo, S.Context.getTranslationUnitDecl(),
   1281         true /*Instance*/, false /*isVariadic*/,
   1282         /*isPropertyAccessor=*/false,
   1283         /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
   1284         ObjCMethodDecl::Required, false);
   1285     SmallVector<ParmVarDecl *, 2> Params;
   1286     ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
   1287                                                 SourceLocation(), SourceLocation(),
   1288                                                 &S.Context.Idents.get("object"),
   1289                                                 S.Context.getObjCIdType(),
   1290                                                 /*TInfo=*/nullptr,
   1291                                                 SC_None,
   1292                                                 nullptr);
   1293     Params.push_back(object);
   1294     ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
   1295                                                 SourceLocation(), SourceLocation(),
   1296                                                 arrayRef ?  &S.Context.Idents.get("index")
   1297                                                          :  &S.Context.Idents.get("key"),
   1298                                                 arrayRef ? S.Context.UnsignedLongTy
   1299                                                          : S.Context.getObjCIdType(),
   1300                                                 /*TInfo=*/nullptr,
   1301                                                 SC_None,
   1302                                                 nullptr);
   1303     Params.push_back(key);
   1304     AtIndexSetter->setMethodParams(S.Context, Params, None);
   1305   }
   1306 
   1307   if (!AtIndexSetter) {
   1308     if (!receiverIdType) {
   1309       S.Diag(BaseExpr->getExprLoc(),
   1310              diag::err_objc_subscript_method_not_found)
   1311       << BaseExpr->getType() << 1 << arrayRef;
   1312       return false;
   1313     }
   1314     AtIndexSetter =
   1315       S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector,
   1316                                          RefExpr->getSourceRange(),
   1317                                          true);
   1318   }
   1319 
   1320   bool err = false;
   1321   if (AtIndexSetter && arrayRef) {
   1322     QualType T = AtIndexSetter->parameters()[1]->getType();
   1323     if (!T->isIntegralOrEnumerationType()) {
   1324       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1325              diag::err_objc_subscript_index_type) << T;
   1326       S.Diag(AtIndexSetter->parameters()[1]->getLocation(),
   1327              diag::note_parameter_type) << T;
   1328       err = true;
   1329     }
   1330     T = AtIndexSetter->parameters()[0]->getType();
   1331     if (!T->isObjCObjectPointerType()) {
   1332       S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
   1333              diag::err_objc_subscript_object_type) << T << arrayRef;
   1334       S.Diag(AtIndexSetter->parameters()[0]->getLocation(),
   1335              diag::note_parameter_type) << T;
   1336       err = true;
   1337     }
   1338   }
   1339   else if (AtIndexSetter && !arrayRef)
   1340     for (unsigned i=0; i <2; i++) {
   1341       QualType T = AtIndexSetter->parameters()[i]->getType();
   1342       if (!T->isObjCObjectPointerType()) {
   1343         if (i == 1)
   1344           S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
   1345                  diag::err_objc_subscript_key_type) << T;
   1346         else
   1347           S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
   1348                  diag::err_objc_subscript_dic_object_type) << T;
   1349         S.Diag(AtIndexSetter->parameters()[i]->getLocation(),
   1350                diag::note_parameter_type) << T;
   1351         err = true;
   1352       }
   1353     }
   1354 
   1355   return !err;
   1356 }
   1357 
   1358 // Get the object at "Index" position in the container.
   1359 // [BaseExpr objectAtIndexedSubscript : IndexExpr];
   1360 ExprResult ObjCSubscriptOpBuilder::buildGet() {
   1361   if (!findAtIndexGetter())
   1362     return ExprError();
   1363 
   1364   QualType receiverType = InstanceBase->getType();
   1365 
   1366   // Build a message-send.
   1367   ExprResult msg;
   1368   Expr *Index = InstanceKey;
   1369 
   1370   // Arguments.
   1371   Expr *args[] = { Index };
   1372   assert(InstanceBase);
   1373   if (AtIndexGetter)
   1374     S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc);
   1375   msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
   1376                                        GenericLoc,
   1377                                        AtIndexGetterSelector, AtIndexGetter,
   1378                                        MultiExprArg(args, 1));
   1379   return msg;
   1380 }
   1381 
   1382 /// Store into the container the "op" object at "Index"'ed location
   1383 /// by building this messaging expression:
   1384 /// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
   1385 /// \param captureSetValueAsResult If true, capture the actual
   1386 ///   value being set as the value of the property operation.
   1387 ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
   1388                                            bool captureSetValueAsResult) {
   1389   if (!findAtIndexSetter())
   1390     return ExprError();
   1391   if (AtIndexSetter)
   1392     S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc);
   1393   QualType receiverType = InstanceBase->getType();
   1394   Expr *Index = InstanceKey;
   1395 
   1396   // Arguments.
   1397   Expr *args[] = { op, Index };
   1398 
   1399   // Build a message-send.
   1400   ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
   1401                                                   GenericLoc,
   1402                                                   AtIndexSetterSelector,
   1403                                                   AtIndexSetter,
   1404                                                   MultiExprArg(args, 2));
   1405 
   1406   if (!msg.isInvalid() && captureSetValueAsResult) {
   1407     ObjCMessageExpr *msgExpr =
   1408       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
   1409     Expr *arg = msgExpr->getArg(0);
   1410     if (CanCaptureValue(arg))
   1411       msgExpr->setArg(0, captureValueAsResult(arg));
   1412   }
   1413 
   1414   return msg;
   1415 }
   1416 
   1417 //===----------------------------------------------------------------------===//
   1418 //  MSVC __declspec(property) references
   1419 //===----------------------------------------------------------------------===//
   1420 
   1421 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
   1422   Expr *NewBase = capture(RefExpr->getBaseExpr());
   1423 
   1424   syntacticBase =
   1425     MSPropertyRefRebuilder(S, NewBase).rebuild(syntacticBase);
   1426 
   1427   return syntacticBase;
   1428 }
   1429 
   1430 ExprResult MSPropertyOpBuilder::buildGet() {
   1431   if (!RefExpr->getPropertyDecl()->hasGetter()) {
   1432     S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
   1433       << 0 /* getter */ << RefExpr->getPropertyDecl();
   1434     return ExprError();
   1435   }
   1436 
   1437   UnqualifiedId GetterName;
   1438   IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
   1439   GetterName.setIdentifier(II, RefExpr->getMemberLoc());
   1440   CXXScopeSpec SS;
   1441   SS.Adopt(RefExpr->getQualifierLoc());
   1442   ExprResult GetterExpr = S.ActOnMemberAccessExpr(
   1443     S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
   1444     RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
   1445     GetterName, nullptr);
   1446   if (GetterExpr.isInvalid()) {
   1447     S.Diag(RefExpr->getMemberLoc(),
   1448            diag::error_cannot_find_suitable_accessor) << 0 /* getter */
   1449       << RefExpr->getPropertyDecl();
   1450     return ExprError();
   1451   }
   1452 
   1453   MultiExprArg ArgExprs;
   1454   return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(),
   1455                          RefExpr->getSourceRange().getBegin(), ArgExprs,
   1456                          RefExpr->getSourceRange().getEnd());
   1457 }
   1458 
   1459 ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
   1460                                          bool captureSetValueAsResult) {
   1461   if (!RefExpr->getPropertyDecl()->hasSetter()) {
   1462     S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
   1463       << 1 /* setter */ << RefExpr->getPropertyDecl();
   1464     return ExprError();
   1465   }
   1466 
   1467   UnqualifiedId SetterName;
   1468   IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
   1469   SetterName.setIdentifier(II, RefExpr->getMemberLoc());
   1470   CXXScopeSpec SS;
   1471   SS.Adopt(RefExpr->getQualifierLoc());
   1472   ExprResult SetterExpr = S.ActOnMemberAccessExpr(
   1473     S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
   1474     RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
   1475     SetterName, nullptr);
   1476   if (SetterExpr.isInvalid()) {
   1477     S.Diag(RefExpr->getMemberLoc(),
   1478            diag::error_cannot_find_suitable_accessor) << 1 /* setter */
   1479       << RefExpr->getPropertyDecl();
   1480     return ExprError();
   1481   }
   1482 
   1483   SmallVector<Expr*, 1> ArgExprs;
   1484   ArgExprs.push_back(op);
   1485   return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(),
   1486                          RefExpr->getSourceRange().getBegin(), ArgExprs,
   1487                          op->getSourceRange().getEnd());
   1488 }
   1489 
   1490 //===----------------------------------------------------------------------===//
   1491 //  General Sema routines.
   1492 //===----------------------------------------------------------------------===//
   1493 
   1494 ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
   1495   Expr *opaqueRef = E->IgnoreParens();
   1496   if (ObjCPropertyRefExpr *refExpr
   1497         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1498     ObjCPropertyOpBuilder builder(*this, refExpr);
   1499     return builder.buildRValueOperation(E);
   1500   }
   1501   else if (ObjCSubscriptRefExpr *refExpr
   1502            = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
   1503     ObjCSubscriptOpBuilder builder(*this, refExpr);
   1504     return builder.buildRValueOperation(E);
   1505   } else if (MSPropertyRefExpr *refExpr
   1506              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
   1507     MSPropertyOpBuilder builder(*this, refExpr);
   1508     return builder.buildRValueOperation(E);
   1509   } else {
   1510     llvm_unreachable("unknown pseudo-object kind!");
   1511   }
   1512 }
   1513 
   1514 /// Check an increment or decrement of a pseudo-object expression.
   1515 ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
   1516                                          UnaryOperatorKind opcode, Expr *op) {
   1517   // Do nothing if the operand is dependent.
   1518   if (op->isTypeDependent())
   1519     return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
   1520                                        VK_RValue, OK_Ordinary, opcLoc);
   1521 
   1522   assert(UnaryOperator::isIncrementDecrementOp(opcode));
   1523   Expr *opaqueRef = op->IgnoreParens();
   1524   if (ObjCPropertyRefExpr *refExpr
   1525         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1526     ObjCPropertyOpBuilder builder(*this, refExpr);
   1527     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
   1528   } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
   1529     Diag(opcLoc, diag::err_illegal_container_subscripting_op);
   1530     return ExprError();
   1531   } else if (MSPropertyRefExpr *refExpr
   1532              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
   1533     MSPropertyOpBuilder builder(*this, refExpr);
   1534     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
   1535   } else {
   1536     llvm_unreachable("unknown pseudo-object kind!");
   1537   }
   1538 }
   1539 
   1540 ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
   1541                                              BinaryOperatorKind opcode,
   1542                                              Expr *LHS, Expr *RHS) {
   1543   // Do nothing if either argument is dependent.
   1544   if (LHS->isTypeDependent() || RHS->isTypeDependent())
   1545     return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
   1546                                         VK_RValue, OK_Ordinary, opcLoc, false);
   1547 
   1548   // Filter out non-overload placeholder types in the RHS.
   1549   if (RHS->getType()->isNonOverloadPlaceholderType()) {
   1550     ExprResult result = CheckPlaceholderExpr(RHS);
   1551     if (result.isInvalid()) return ExprError();
   1552     RHS = result.get();
   1553   }
   1554 
   1555   Expr *opaqueRef = LHS->IgnoreParens();
   1556   if (ObjCPropertyRefExpr *refExpr
   1557         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1558     ObjCPropertyOpBuilder builder(*this, refExpr);
   1559     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
   1560   } else if (ObjCSubscriptRefExpr *refExpr
   1561              = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
   1562     ObjCSubscriptOpBuilder builder(*this, refExpr);
   1563     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
   1564   } else if (MSPropertyRefExpr *refExpr
   1565              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
   1566     MSPropertyOpBuilder builder(*this, refExpr);
   1567     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
   1568   } else {
   1569     llvm_unreachable("unknown pseudo-object kind!");
   1570   }
   1571 }
   1572 
   1573 /// Given a pseudo-object reference, rebuild it without the opaque
   1574 /// values.  Basically, undo the behavior of rebuildAndCaptureObject.
   1575 /// This should never operate in-place.
   1576 static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
   1577   Expr *opaqueRef = E->IgnoreParens();
   1578   if (ObjCPropertyRefExpr *refExpr
   1579         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
   1580     // Class and super property references don't have opaque values in them.
   1581     if (refExpr->isClassReceiver() || refExpr->isSuperReceiver())
   1582       return E;
   1583 
   1584     assert(refExpr->isObjectReceiver() && "Unknown receiver kind?");
   1585     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
   1586     return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
   1587   } else if (ObjCSubscriptRefExpr *refExpr
   1588                = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
   1589     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
   1590     OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
   1591     return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
   1592                                      keyOVE->getSourceExpr()).rebuild(E);
   1593   } else if (MSPropertyRefExpr *refExpr
   1594              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
   1595     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
   1596     return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
   1597   } else {
   1598     llvm_unreachable("unknown pseudo-object kind!");
   1599   }
   1600 }
   1601 
   1602 /// Given a pseudo-object expression, recreate what it looks like
   1603 /// syntactically without the attendant OpaqueValueExprs.
   1604 ///
   1605 /// This is a hack which should be removed when TreeTransform is
   1606 /// capable of rebuilding a tree without stripping implicit
   1607 /// operations.
   1608 Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
   1609   Expr *syntax = E->getSyntacticForm();
   1610   if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
   1611     Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
   1612     return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
   1613                                        uop->getValueKind(), uop->getObjectKind(),
   1614                                        uop->getOperatorLoc());
   1615   } else if (CompoundAssignOperator *cop
   1616                = dyn_cast<CompoundAssignOperator>(syntax)) {
   1617     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
   1618     Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
   1619     return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
   1620                                                 cop->getType(),
   1621                                                 cop->getValueKind(),
   1622                                                 cop->getObjectKind(),
   1623                                                 cop->getComputationLHSType(),
   1624                                                 cop->getComputationResultType(),
   1625                                                 cop->getOperatorLoc(), false);
   1626   } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
   1627     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
   1628     Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
   1629     return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
   1630                                         bop->getType(), bop->getValueKind(),
   1631                                         bop->getObjectKind(),
   1632                                         bop->getOperatorLoc(), false);
   1633   } else {
   1634     assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
   1635     return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
   1636   }
   1637 }
   1638