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