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