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/Sema/Initialization.h"
35 #include "clang/AST/ExprObjC.h"
36 #include "clang/Lex/Preprocessor.h"
37 
38 using namespace clang;
39 using namespace sema;
40 
41 namespace {
42   // Basically just a very focused copy of TreeTransform.
43   template <class T> struct Rebuilder {
44     Sema &S;
45     Rebuilder(Sema &S) : S(S) {}
46 
47     T &getDerived() { return static_cast<T&>(*this); }
48 
49     Expr *rebuild(Expr *e) {
50       // Fast path: nothing to look through.
51       if (typename T::specific_type *specific
52             = dyn_cast<typename T::specific_type>(e))
53         return getDerived().rebuildSpecific(specific);
54 
55       // Otherwise, we should look through and rebuild anything that
56       // IgnoreParens would.
57 
58       if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
59         e = rebuild(parens->getSubExpr());
60         return new (S.Context) ParenExpr(parens->getLParen(),
61                                          parens->getRParen(),
62                                          e);
63       }
64 
65       if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
66         assert(uop->getOpcode() == UO_Extension);
67         e = rebuild(uop->getSubExpr());
68         return new (S.Context) UnaryOperator(e, uop->getOpcode(),
69                                              uop->getType(),
70                                              uop->getValueKind(),
71                                              uop->getObjectKind(),
72                                              uop->getOperatorLoc());
73       }
74 
75       if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
76         assert(!gse->isResultDependent());
77         unsigned resultIndex = gse->getResultIndex();
78         unsigned numAssocs = gse->getNumAssocs();
79 
80         SmallVector<Expr*, 8> assocs(numAssocs);
81         SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
82 
83         for (unsigned i = 0; i != numAssocs; ++i) {
84           Expr *assoc = gse->getAssocExpr(i);
85           if (i == resultIndex) assoc = rebuild(assoc);
86           assocs[i] = assoc;
87           assocTypes[i] = gse->getAssocTypeSourceInfo(i);
88         }
89 
90         return new (S.Context) GenericSelectionExpr(S.Context,
91                                                     gse->getGenericLoc(),
92                                                     gse->getControllingExpr(),
93                                                     assocTypes.data(),
94                                                     assocs.data(),
95                                                     numAssocs,
96                                                     gse->getDefaultLoc(),
97                                                     gse->getRParenLoc(),
98                                       gse->containsUnexpandedParameterPack(),
99                                                     resultIndex);
100       }
101 
102       llvm_unreachable("bad expression to rebuild!");
103     }
104   };
105 
106   struct ObjCPropertyRefRebuilder : Rebuilder<ObjCPropertyRefRebuilder> {
107     Expr *NewBase;
108     ObjCPropertyRefRebuilder(Sema &S, Expr *newBase)
109       : Rebuilder<ObjCPropertyRefRebuilder>(S), NewBase(newBase) {}
110 
111     typedef ObjCPropertyRefExpr specific_type;
112     Expr *rebuildSpecific(ObjCPropertyRefExpr *refExpr) {
113       // Fortunately, the constraint that we're rebuilding something
114       // with a base limits the number of cases here.
115       assert(refExpr->getBase());
116 
117       if (refExpr->isExplicitProperty()) {
118         return new (S.Context)
119           ObjCPropertyRefExpr(refExpr->getExplicitProperty(),
120                               refExpr->getType(), refExpr->getValueKind(),
121                               refExpr->getObjectKind(), refExpr->getLocation(),
122                               NewBase);
123       }
124       return new (S.Context)
125         ObjCPropertyRefExpr(refExpr->getImplicitPropertyGetter(),
126                             refExpr->getImplicitPropertySetter(),
127                             refExpr->getType(), refExpr->getValueKind(),
128                             refExpr->getObjectKind(),refExpr->getLocation(),
129                             NewBase);
130     }
131   };
132 
133   class PseudoOpBuilder {
134   public:
135     Sema &S;
136     unsigned ResultIndex;
137     SourceLocation GenericLoc;
138     SmallVector<Expr *, 4> Semantics;
139 
140     PseudoOpBuilder(Sema &S, SourceLocation genericLoc)
141       : S(S), ResultIndex(PseudoObjectExpr::NoResult),
142         GenericLoc(genericLoc) {}
143 
144     virtual ~PseudoOpBuilder() {}
145 
146     /// Add a normal semantic expression.
147     void addSemanticExpr(Expr *semantic) {
148       Semantics.push_back(semantic);
149     }
150 
151     /// Add the 'result' semantic expression.
152     void addResultSemanticExpr(Expr *resultExpr) {
153       assert(ResultIndex == PseudoObjectExpr::NoResult);
154       ResultIndex = Semantics.size();
155       Semantics.push_back(resultExpr);
156     }
157 
158     ExprResult buildRValueOperation(Expr *op);
159     ExprResult buildAssignmentOperation(Scope *Sc,
160                                         SourceLocation opLoc,
161                                         BinaryOperatorKind opcode,
162                                         Expr *LHS, Expr *RHS);
163     ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
164                                     UnaryOperatorKind opcode,
165                                     Expr *op);
166 
167     ExprResult complete(Expr *syntacticForm);
168 
169     OpaqueValueExpr *capture(Expr *op);
170     OpaqueValueExpr *captureValueAsResult(Expr *op);
171 
172     void setResultToLastSemantic() {
173       assert(ResultIndex == PseudoObjectExpr::NoResult);
174       ResultIndex = Semantics.size() - 1;
175     }
176 
177     /// Return true if assignments have a non-void result.
178     virtual bool assignmentsHaveResult() { return true; }
179 
180     virtual Expr *rebuildAndCaptureObject(Expr *) = 0;
181     virtual ExprResult buildGet() = 0;
182     virtual ExprResult buildSet(Expr *, SourceLocation,
183                                 bool captureSetValueAsResult) = 0;
184   };
185 
186   /// A PseudoOpBuilder for Objective-C @properties.
187   class ObjCPropertyOpBuilder : public PseudoOpBuilder {
188     ObjCPropertyRefExpr *RefExpr;
189     OpaqueValueExpr *InstanceReceiver;
190     ObjCMethodDecl *Getter;
191 
192     ObjCMethodDecl *Setter;
193     Selector SetterSelector;
194 
195   public:
196     ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
197       PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
198       InstanceReceiver(0), Getter(0), Setter(0) {
199     }
200 
201     ExprResult buildRValueOperation(Expr *op);
202     ExprResult buildAssignmentOperation(Scope *Sc,
203                                         SourceLocation opLoc,
204                                         BinaryOperatorKind opcode,
205                                         Expr *LHS, Expr *RHS);
206     ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
207                                     UnaryOperatorKind opcode,
208                                     Expr *op);
209 
210     bool tryBuildGetOfReference(Expr *op, ExprResult &result);
211     bool findSetter();
212     bool findGetter();
213 
214     Expr *rebuildAndCaptureObject(Expr *syntacticBase);
215     ExprResult buildGet();
216     ExprResult buildSet(Expr *op, SourceLocation, bool);
217   };
218 }
219 
220 /// Capture the given expression in an OpaqueValueExpr.
221 OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
222   // Make a new OVE whose source is the given expression.
223   OpaqueValueExpr *captured =
224     new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
225                                     e->getValueKind());
226   captured->setSourceExpr(e);
227 
228   // Make sure we bind that in the semantics.
229   addSemanticExpr(captured);
230   return captured;
231 }
232 
233 /// Capture the given expression as the result of this pseudo-object
234 /// operation.  This routine is safe against expressions which may
235 /// already be captured.
236 ///
237 /// \param Returns the captured expression, which will be the
238 ///   same as the input if the input was already captured
239 OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
240   assert(ResultIndex == PseudoObjectExpr::NoResult);
241 
242   // If the expression hasn't already been captured, just capture it
243   // and set the new semantic
244   if (!isa<OpaqueValueExpr>(e)) {
245     OpaqueValueExpr *cap = capture(e);
246     setResultToLastSemantic();
247     return cap;
248   }
249 
250   // Otherwise, it must already be one of our semantic expressions;
251   // set ResultIndex to its index.
252   unsigned index = 0;
253   for (;; ++index) {
254     assert(index < Semantics.size() &&
255            "captured expression not found in semantics!");
256     if (e == Semantics[index]) break;
257   }
258   ResultIndex = index;
259   return cast<OpaqueValueExpr>(e);
260 }
261 
262 /// The routine which creates the final PseudoObjectExpr.
263 ExprResult PseudoOpBuilder::complete(Expr *syntactic) {
264   return PseudoObjectExpr::Create(S.Context, syntactic,
265                                   Semantics, ResultIndex);
266 }
267 
268 /// The main skeleton for building an r-value operation.
269 ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {
270   Expr *syntacticBase = rebuildAndCaptureObject(op);
271 
272   ExprResult getExpr = buildGet();
273   if (getExpr.isInvalid()) return ExprError();
274   addResultSemanticExpr(getExpr.take());
275 
276   return complete(syntacticBase);
277 }
278 
279 /// The basic skeleton for building a simple or compound
280 /// assignment operation.
281 ExprResult
282 PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
283                                           BinaryOperatorKind opcode,
284                                           Expr *LHS, Expr *RHS) {
285   assert(BinaryOperator::isAssignmentOp(opcode));
286 
287   Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
288   OpaqueValueExpr *capturedRHS = capture(RHS);
289 
290   Expr *syntactic;
291 
292   ExprResult result;
293   if (opcode == BO_Assign) {
294     result = capturedRHS;
295     syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
296                                                opcode, capturedRHS->getType(),
297                                                capturedRHS->getValueKind(),
298                                                OK_Ordinary, opcLoc);
299   } else {
300     ExprResult opLHS = buildGet();
301     if (opLHS.isInvalid()) return ExprError();
302 
303     // Build an ordinary, non-compound operation.
304     BinaryOperatorKind nonCompound =
305       BinaryOperator::getOpForCompoundAssignment(opcode);
306     result = S.BuildBinOp(Sc, opcLoc, nonCompound,
307                           opLHS.take(), capturedRHS);
308     if (result.isInvalid()) return ExprError();
309 
310     syntactic =
311       new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
312                                              result.get()->getType(),
313                                              result.get()->getValueKind(),
314                                              OK_Ordinary,
315                                              opLHS.get()->getType(),
316                                              result.get()->getType(),
317                                              opcLoc);
318   }
319 
320   // The result of the assignment, if not void, is the value set into
321   // the l-value.
322   result = buildSet(result.take(), opcLoc, assignmentsHaveResult());
323   if (result.isInvalid()) return ExprError();
324   addSemanticExpr(result.take());
325 
326   return complete(syntactic);
327 }
328 
329 /// The basic skeleton for building an increment or decrement
330 /// operation.
331 ExprResult
332 PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
333                                       UnaryOperatorKind opcode,
334                                       Expr *op) {
335   assert(UnaryOperator::isIncrementDecrementOp(opcode));
336 
337   Expr *syntacticOp = rebuildAndCaptureObject(op);
338 
339   // Load the value.
340   ExprResult result = buildGet();
341   if (result.isInvalid()) return ExprError();
342 
343   QualType resultType = result.get()->getType();
344 
345   // That's the postfix result.
346   if (UnaryOperator::isPostfix(opcode) && assignmentsHaveResult()) {
347     result = capture(result.take());
348     setResultToLastSemantic();
349   }
350 
351   // Add or subtract a literal 1.
352   llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
353   Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
354                                      GenericLoc);
355 
356   if (UnaryOperator::isIncrementOp(opcode)) {
357     result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
358   } else {
359     result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
360   }
361   if (result.isInvalid()) return ExprError();
362 
363   // Store that back into the result.  The value stored is the result
364   // of a prefix operation.
365   result = buildSet(result.take(), opcLoc,
366              UnaryOperator::isPrefix(opcode) && assignmentsHaveResult());
367   if (result.isInvalid()) return ExprError();
368   addSemanticExpr(result.take());
369 
370   UnaryOperator *syntactic =
371     new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
372                                   VK_LValue, OK_Ordinary, opcLoc);
373   return complete(syntactic);
374 }
375 
376 
377 //===----------------------------------------------------------------------===//
378 //  Objective-C @property and implicit property references
379 //===----------------------------------------------------------------------===//
380 
381 /// Look up a method in the receiver type of an Objective-C property
382 /// reference.
383 static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
384                                             const ObjCPropertyRefExpr *PRE) {
385   if (PRE->isObjectReceiver()) {
386     const ObjCObjectPointerType *PT =
387       PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
388 
389     // Special case for 'self' in class method implementations.
390     if (PT->isObjCClassType() &&
391         S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) {
392       // This cast is safe because isSelfExpr is only true within
393       // methods.
394       ObjCMethodDecl *method =
395         cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
396       return S.LookupMethodInObjectType(sel,
397                  S.Context.getObjCInterfaceType(method->getClassInterface()),
398                                         /*instance*/ false);
399     }
400 
401     return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
402   }
403 
404   if (PRE->isSuperReceiver()) {
405     if (const ObjCObjectPointerType *PT =
406         PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>())
407       return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
408 
409     return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false);
410   }
411 
412   assert(PRE->isClassReceiver() && "Invalid expression");
413   QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
414   return S.LookupMethodInObjectType(sel, IT, false);
415 }
416 
417 bool ObjCPropertyOpBuilder::findGetter() {
418   if (Getter) return true;
419 
420   // For implicit properties, just trust the lookup we already did.
421   if (RefExpr->isImplicitProperty()) {
422     Getter = RefExpr->getImplicitPropertyGetter();
423     return (Getter != 0);
424   }
425 
426   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
427   Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
428   return (Getter != 0);
429 }
430 
431 /// Try to find the most accurate setter declaration for the property
432 /// reference.
433 ///
434 /// \return true if a setter was found, in which case Setter
435 bool ObjCPropertyOpBuilder::findSetter() {
436   // For implicit properties, just trust the lookup we already did.
437   if (RefExpr->isImplicitProperty()) {
438     if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
439       Setter = setter;
440       SetterSelector = setter->getSelector();
441       return true;
442     } else {
443       IdentifierInfo *getterName =
444         RefExpr->getImplicitPropertyGetter()->getSelector()
445           .getIdentifierInfoForSlot(0);
446       SetterSelector =
447         SelectorTable::constructSetterName(S.PP.getIdentifierTable(),
448                                            S.PP.getSelectorTable(),
449                                            getterName);
450       return false;
451     }
452   }
453 
454   // For explicit properties, this is more involved.
455   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
456   SetterSelector = prop->getSetterName();
457 
458   // Do a normal method lookup first.
459   if (ObjCMethodDecl *setter =
460         LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
461     Setter = setter;
462     return true;
463   }
464 
465   // That can fail in the somewhat crazy situation that we're
466   // type-checking a message send within the @interface declaration
467   // that declared the @property.  But it's not clear that that's
468   // valuable to support.
469 
470   return false;
471 }
472 
473 /// Capture the base object of an Objective-C property expression.
474 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
475   assert(InstanceReceiver == 0);
476 
477   // If we have a base, capture it in an OVE and rebuild the syntactic
478   // form to use the OVE as its base.
479   if (RefExpr->isObjectReceiver()) {
480     InstanceReceiver = capture(RefExpr->getBase());
481 
482     syntacticBase =
483       ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
484   }
485 
486   return syntacticBase;
487 }
488 
489 /// Load from an Objective-C property reference.
490 ExprResult ObjCPropertyOpBuilder::buildGet() {
491   findGetter();
492   assert(Getter);
493 
494   QualType receiverType;
495   if (RefExpr->isClassReceiver()) {
496     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
497   } else if (RefExpr->isSuperReceiver()) {
498     receiverType = RefExpr->getSuperReceiverType();
499   } else {
500     assert(InstanceReceiver);
501     receiverType = InstanceReceiver->getType();
502   }
503 
504   // Build a message-send.
505   ExprResult msg;
506   if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
507     assert(InstanceReceiver || RefExpr->isSuperReceiver());
508     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
509                                          GenericLoc, Getter->getSelector(),
510                                          Getter, MultiExprArg());
511   } else {
512     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
513                                       GenericLoc,
514                                       Getter->getSelector(), Getter,
515                                       MultiExprArg());
516   }
517   return msg;
518 }
519 
520 /// Store to an Objective-C property reference.
521 ///
522 /// \param bindSetValueAsResult - If true, capture the actual
523 ///   value being set as the value of the property operation.
524 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
525                                            bool captureSetValueAsResult) {
526   bool hasSetter = findSetter();
527   assert(hasSetter); (void) hasSetter;
528 
529   QualType receiverType;
530   if (RefExpr->isClassReceiver()) {
531     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
532   } else if (RefExpr->isSuperReceiver()) {
533     receiverType = RefExpr->getSuperReceiverType();
534   } else {
535     assert(InstanceReceiver);
536     receiverType = InstanceReceiver->getType();
537   }
538 
539   // Use assignment constraints when possible; they give us better
540   // diagnostics.  "When possible" basically means anything except a
541   // C++ class type.
542   if (!S.getLangOptions().CPlusPlus || !op->getType()->isRecordType()) {
543     QualType paramType = (*Setter->param_begin())->getType();
544     if (!S.getLangOptions().CPlusPlus || !paramType->isRecordType()) {
545       ExprResult opResult = op;
546       Sema::AssignConvertType assignResult
547         = S.CheckSingleAssignmentConstraints(paramType, opResult);
548       if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
549                                      op->getType(), opResult.get(),
550                                      Sema::AA_Assigning))
551         return ExprError();
552 
553       op = opResult.take();
554       assert(op && "successful assignment left argument invalid?");
555     }
556   }
557 
558   // Arguments.
559   Expr *args[] = { op };
560 
561   // Build a message-send.
562   ExprResult msg;
563   if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
564     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
565                                          GenericLoc, SetterSelector, Setter,
566                                          MultiExprArg(args, 1));
567   } else {
568     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
569                                       GenericLoc,
570                                       SetterSelector, Setter,
571                                       MultiExprArg(args, 1));
572   }
573 
574   if (!msg.isInvalid() && captureSetValueAsResult) {
575     ObjCMessageExpr *msgExpr =
576       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
577     Expr *arg = msgExpr->getArg(0);
578     msgExpr->setArg(0, captureValueAsResult(arg));
579   }
580 
581   return msg;
582 }
583 
584 /// @property-specific behavior for doing lvalue-to-rvalue conversion.
585 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
586   // Explicit properties always have getters, but implicit ones don't.
587   // Check that before proceeding.
588   if (RefExpr->isImplicitProperty() &&
589       !RefExpr->getImplicitPropertyGetter()) {
590     S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
591       << RefExpr->getBase()->getType();
592     return ExprError();
593   }
594 
595   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
596   if (result.isInvalid()) return ExprError();
597 
598   if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
599     S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
600                                        Getter, RefExpr->getLocation());
601 
602   // As a special case, if the method returns 'id', try to get
603   // a better type from the property.
604   if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
605       result.get()->getType()->isObjCIdType()) {
606     QualType propType = RefExpr->getExplicitProperty()->getType();
607     if (const ObjCObjectPointerType *ptr
608           = propType->getAs<ObjCObjectPointerType>()) {
609       if (!ptr->isObjCIdType())
610         result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
611     }
612   }
613 
614   return result;
615 }
616 
617 /// Try to build this as a call to a getter that returns a reference.
618 ///
619 /// \return true if it was possible, whether or not it actually
620 ///   succeeded
621 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
622                                                    ExprResult &result) {
623   if (!S.getLangOptions().CPlusPlus) return false;
624 
625   findGetter();
626   assert(Getter && "property has no setter and no getter!");
627 
628   // Only do this if the getter returns an l-value reference type.
629   QualType resultType = Getter->getResultType();
630   if (!resultType->isLValueReferenceType()) return false;
631 
632   result = buildRValueOperation(op);
633   return true;
634 }
635 
636 /// @property-specific behavior for doing assignments.
637 ExprResult
638 ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
639                                                 SourceLocation opcLoc,
640                                                 BinaryOperatorKind opcode,
641                                                 Expr *LHS, Expr *RHS) {
642   assert(BinaryOperator::isAssignmentOp(opcode));
643 
644   // If there's no setter, we have no choice but to try to assign to
645   // the result of the getter.
646   if (!findSetter()) {
647     ExprResult result;
648     if (tryBuildGetOfReference(LHS, result)) {
649       if (result.isInvalid()) return ExprError();
650       return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
651     }
652 
653     // Otherwise, it's an error.
654     S.Diag(opcLoc, diag::err_nosetter_property_assignment)
655       << unsigned(RefExpr->isImplicitProperty())
656       << SetterSelector
657       << LHS->getSourceRange() << RHS->getSourceRange();
658     return ExprError();
659   }
660 
661   // If there is a setter, we definitely want to use it.
662 
663   // Verify that we can do a compound assignment.
664   if (opcode != BO_Assign && !findGetter()) {
665     S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
666       << LHS->getSourceRange() << RHS->getSourceRange();
667     return ExprError();
668   }
669 
670   ExprResult result =
671     PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
672   if (result.isInvalid()) return ExprError();
673 
674   // Various warnings about property assignments in ARC.
675   if (S.getLangOptions().ObjCAutoRefCount && InstanceReceiver) {
676     S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
677     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
678   }
679 
680   return result;
681 }
682 
683 /// @property-specific behavior for doing increments and decrements.
684 ExprResult
685 ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
686                                             UnaryOperatorKind opcode,
687                                             Expr *op) {
688   // If there's no setter, we have no choice but to try to assign to
689   // the result of the getter.
690   if (!findSetter()) {
691     ExprResult result;
692     if (tryBuildGetOfReference(op, result)) {
693       if (result.isInvalid()) return ExprError();
694       return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
695     }
696 
697     // Otherwise, it's an error.
698     S.Diag(opcLoc, diag::err_nosetter_property_incdec)
699       << unsigned(RefExpr->isImplicitProperty())
700       << unsigned(UnaryOperator::isDecrementOp(opcode))
701       << SetterSelector
702       << op->getSourceRange();
703     return ExprError();
704   }
705 
706   // If there is a setter, we definitely want to use it.
707 
708   // We also need a getter.
709   if (!findGetter()) {
710     assert(RefExpr->isImplicitProperty());
711     S.Diag(opcLoc, diag::err_nogetter_property_incdec)
712       << unsigned(UnaryOperator::isDecrementOp(opcode))
713       << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME!
714       << op->getSourceRange();
715     return ExprError();
716   }
717 
718   return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
719 }
720 
721 //===----------------------------------------------------------------------===//
722 //  General Sema routines.
723 //===----------------------------------------------------------------------===//
724 
725 ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
726   Expr *opaqueRef = E->IgnoreParens();
727   if (ObjCPropertyRefExpr *refExpr
728         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
729     ObjCPropertyOpBuilder builder(*this, refExpr);
730     return builder.buildRValueOperation(E);
731   } else {
732     llvm_unreachable("unknown pseudo-object kind!");
733   }
734 }
735 
736 /// Check an increment or decrement of a pseudo-object expression.
737 ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
738                                          UnaryOperatorKind opcode, Expr *op) {
739   // Do nothing if the operand is dependent.
740   if (op->isTypeDependent())
741     return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
742                                        VK_RValue, OK_Ordinary, opcLoc);
743 
744   assert(UnaryOperator::isIncrementDecrementOp(opcode));
745   Expr *opaqueRef = op->IgnoreParens();
746   if (ObjCPropertyRefExpr *refExpr
747         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
748     ObjCPropertyOpBuilder builder(*this, refExpr);
749     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
750   } else {
751     llvm_unreachable("unknown pseudo-object kind!");
752   }
753 }
754 
755 ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
756                                              BinaryOperatorKind opcode,
757                                              Expr *LHS, Expr *RHS) {
758   // Do nothing if either argument is dependent.
759   if (LHS->isTypeDependent() || RHS->isTypeDependent())
760     return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
761                                         VK_RValue, OK_Ordinary, opcLoc);
762 
763   // Filter out non-overload placeholder types in the RHS.
764   if (RHS->getType()->isNonOverloadPlaceholderType()) {
765     ExprResult result = CheckPlaceholderExpr(RHS);
766     if (result.isInvalid()) return ExprError();
767     RHS = result.take();
768   }
769 
770   Expr *opaqueRef = LHS->IgnoreParens();
771   if (ObjCPropertyRefExpr *refExpr
772         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
773     ObjCPropertyOpBuilder builder(*this, refExpr);
774     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
775   } else {
776     llvm_unreachable("unknown pseudo-object kind!");
777   }
778 }
779 
780 /// Given a pseudo-object reference, rebuild it without the opaque
781 /// values.  Basically, undo the behavior of rebuildAndCaptureObject.
782 /// This should never operate in-place.
783 static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
784   Expr *opaqueRef = E->IgnoreParens();
785   if (ObjCPropertyRefExpr *refExpr
786         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
787     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
788     return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
789   } else {
790     llvm_unreachable("unknown pseudo-object kind!");
791   }
792 }
793 
794 /// Given a pseudo-object expression, recreate what it looks like
795 /// syntactically without the attendant OpaqueValueExprs.
796 ///
797 /// This is a hack which should be removed when TreeTransform is
798 /// capable of rebuilding a tree without stripping implicit
799 /// operations.
800 Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
801   Expr *syntax = E->getSyntacticForm();
802   if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
803     Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
804     return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
805                                        uop->getValueKind(), uop->getObjectKind(),
806                                        uop->getOperatorLoc());
807   } else if (CompoundAssignOperator *cop
808                = dyn_cast<CompoundAssignOperator>(syntax)) {
809     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
810     Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
811     return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
812                                                 cop->getType(),
813                                                 cop->getValueKind(),
814                                                 cop->getObjectKind(),
815                                                 cop->getComputationLHSType(),
816                                                 cop->getComputationResultType(),
817                                                 cop->getOperatorLoc());
818   } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
819     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
820     Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
821     return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
822                                         bop->getType(), bop->getValueKind(),
823                                         bop->getObjectKind(),
824                                         bop->getOperatorLoc());
825   } else {
826     assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
827     return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
828   }
829 }
830