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