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