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