blob: 08b3fc82ca3402745be571b6764dcc796546af16 [file] [log] [blame]
John McCall3c3b7f92011-10-25 17:37:35 +00001//===--- 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
38using namespace clang;
39using namespace sema;
40
John McCall4b9c2d22011-11-06 09:01:30 +000041namespace {
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)
Benjamin Krameracf9e822011-11-06 09:50:13 +0000109 : Rebuilder<ObjCPropertyRefRebuilder>(S), NewBase(newBase) {}
John McCall4b9c2d22011-11-06 09:01:30 +0000110
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
Matt Beaumont-Gay1aa17212011-11-08 01:53:17 +0000144 virtual ~PseudoOpBuilder() {}
145
John McCall4b9c2d22011-11-06 09:01:30 +0000146 /// 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.
221OpaqueValueExpr *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
239OpaqueValueExpr *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.
263ExprResult 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.
269ExprResult 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.
281ExprResult
282PseudoOpBuilder::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.
331ExprResult
332PseudoOpBuilder::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.
John McCall3c3b7f92011-10-25 17:37:35 +0000383static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
384 const ObjCPropertyRefExpr *PRE) {
John McCall3c3b7f92011-10-25 17:37:35 +0000385 if (PRE->isObjectReceiver()) {
Benjamin Krameraa9807a2011-10-28 13:21:18 +0000386 const ObjCObjectPointerType *PT =
387 PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
John McCall4b9c2d22011-11-06 09:01:30 +0000388
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
Benjamin Krameraa9807a2011-10-28 13:21:18 +0000401 return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
John McCall3c3b7f92011-10-25 17:37:35 +0000402 }
403
Benjamin Krameraa9807a2011-10-28 13:21:18 +0000404 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);
John McCall3c3b7f92011-10-25 17:37:35 +0000415}
416
John McCall4b9c2d22011-11-06 09:01:30 +0000417bool ObjCPropertyOpBuilder::findGetter() {
418 if (Getter) return true;
John McCall3c3b7f92011-10-25 17:37:35 +0000419
John McCalldc4df512011-11-07 22:49:50 +0000420 // 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);
John McCall4b9c2d22011-11-06 09:01:30 +0000428 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
435bool 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;
John McCall3c3b7f92011-10-25 17:37:35 +0000442 } else {
John McCall4b9c2d22011-11-06 09:01:30 +0000443 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;
John McCall3c3b7f92011-10-25 17:37:35 +0000451 }
John McCall4b9c2d22011-11-06 09:01:30 +0000452 }
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.
474Expr *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.
490ExprResult ObjCPropertyOpBuilder::buildGet() {
491 findGetter();
492 assert(Getter);
493
494 QualType receiverType;
495 SourceLocation superLoc;
496 if (RefExpr->isClassReceiver()) {
497 receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
498 } else if (RefExpr->isSuperReceiver()) {
499 superLoc = RefExpr->getReceiverLocation();
500 receiverType = RefExpr->getSuperReceiverType();
John McCall3c3b7f92011-10-25 17:37:35 +0000501 } else {
John McCall4b9c2d22011-11-06 09:01:30 +0000502 assert(InstanceReceiver);
503 receiverType = InstanceReceiver->getType();
504 }
John McCall3c3b7f92011-10-25 17:37:35 +0000505
John McCall4b9c2d22011-11-06 09:01:30 +0000506 // Build a message-send.
507 ExprResult msg;
508 if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
509 assert(InstanceReceiver || RefExpr->isSuperReceiver());
510 msg = S.BuildInstanceMessage(InstanceReceiver, receiverType, superLoc,
511 Getter->getSelector(), Getter,
512 GenericLoc, GenericLoc, GenericLoc,
513 MultiExprArg());
514 } else {
515 TypeSourceInfo *receiverTypeInfo = 0;
516 if (!RefExpr->isSuperReceiver())
517 receiverTypeInfo = S.Context.getTrivialTypeSourceInfo(receiverType);
John McCall3c3b7f92011-10-25 17:37:35 +0000518
John McCall4b9c2d22011-11-06 09:01:30 +0000519 msg = S.BuildClassMessage(receiverTypeInfo, receiverType, superLoc,
520 Getter->getSelector(), Getter,
521 GenericLoc, GenericLoc, GenericLoc,
522 MultiExprArg());
523 }
524 return msg;
525}
John McCall3c3b7f92011-10-25 17:37:35 +0000526
John McCall4b9c2d22011-11-06 09:01:30 +0000527/// Store to an Objective-C property reference.
528///
529/// \param bindSetValueAsResult - If true, capture the actual
530/// value being set as the value of the property operation.
531ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
532 bool captureSetValueAsResult) {
533 bool hasSetter = findSetter();
534 assert(hasSetter); (void) hasSetter;
535
536 QualType receiverType;
537 SourceLocation superLoc;
538 if (RefExpr->isClassReceiver()) {
539 receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
540 } else if (RefExpr->isSuperReceiver()) {
541 superLoc = RefExpr->getReceiverLocation();
542 receiverType = RefExpr->getSuperReceiverType();
543 } else {
544 assert(InstanceReceiver);
545 receiverType = InstanceReceiver->getType();
546 }
547
548 // Use assignment constraints when possible; they give us better
549 // diagnostics. "When possible" basically means anything except a
550 // C++ class type.
551 if (!S.getLangOptions().CPlusPlus || !op->getType()->isRecordType()) {
552 QualType paramType = (*Setter->param_begin())->getType();
553 if (!S.getLangOptions().CPlusPlus || !paramType->isRecordType()) {
554 ExprResult opResult = op;
555 Sema::AssignConvertType assignResult
556 = S.CheckSingleAssignmentConstraints(paramType, opResult);
557 if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
558 op->getType(), opResult.get(),
559 Sema::AA_Assigning))
560 return ExprError();
561
562 op = opResult.take();
563 assert(op && "successful assignment left argument invalid?");
John McCall3c3b7f92011-10-25 17:37:35 +0000564 }
565 }
566
John McCall4b9c2d22011-11-06 09:01:30 +0000567 // Arguments.
568 Expr *args[] = { op };
John McCall3c3b7f92011-10-25 17:37:35 +0000569
John McCall4b9c2d22011-11-06 09:01:30 +0000570 // Build a message-send.
571 ExprResult msg;
572 if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
573 msg = S.BuildInstanceMessage(InstanceReceiver, receiverType, superLoc,
574 SetterSelector, Setter,
575 GenericLoc, GenericLoc, GenericLoc,
576 MultiExprArg(args, 1));
577 } else {
578 TypeSourceInfo *receiverTypeInfo = 0;
579 if (!RefExpr->isSuperReceiver())
580 receiverTypeInfo = S.Context.getTrivialTypeSourceInfo(receiverType);
581
582 msg = S.BuildClassMessage(receiverTypeInfo, receiverType, superLoc,
583 SetterSelector, Setter,
584 GenericLoc, GenericLoc, GenericLoc,
585 MultiExprArg(args, 1));
586 }
587
588 if (!msg.isInvalid() && captureSetValueAsResult) {
589 ObjCMessageExpr *msgExpr =
590 cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
591 Expr *arg = msgExpr->getArg(0);
592 msgExpr->setArg(0, captureValueAsResult(arg));
593 }
594
595 return msg;
John McCall3c3b7f92011-10-25 17:37:35 +0000596}
597
John McCall4b9c2d22011-11-06 09:01:30 +0000598/// @property-specific behavior for doing lvalue-to-rvalue conversion.
599ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
600 // Explicit properties always have getters, but implicit ones don't.
601 // Check that before proceeding.
602 if (RefExpr->isImplicitProperty() &&
603 !RefExpr->getImplicitPropertyGetter()) {
604 S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
605 << RefExpr->getBase()->getType();
John McCall3c3b7f92011-10-25 17:37:35 +0000606 return ExprError();
607 }
608
John McCall4b9c2d22011-11-06 09:01:30 +0000609 ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
John McCall3c3b7f92011-10-25 17:37:35 +0000610 if (result.isInvalid()) return ExprError();
611
John McCall4b9c2d22011-11-06 09:01:30 +0000612 if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
613 S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
614 Getter, RefExpr->getLocation());
615
616 // As a special case, if the method returns 'id', try to get
617 // a better type from the property.
618 if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
619 result.get()->getType()->isObjCIdType()) {
620 QualType propType = RefExpr->getExplicitProperty()->getType();
621 if (const ObjCObjectPointerType *ptr
622 = propType->getAs<ObjCObjectPointerType>()) {
623 if (!ptr->isObjCIdType())
624 result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
625 }
626 }
627
John McCall3c3b7f92011-10-25 17:37:35 +0000628 return result;
629}
630
John McCall4b9c2d22011-11-06 09:01:30 +0000631/// Try to build this as a call to a getter that returns a reference.
632///
633/// \return true if it was possible, whether or not it actually
634/// succeeded
635bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
636 ExprResult &result) {
637 if (!S.getLangOptions().CPlusPlus) return false;
638
639 findGetter();
640 assert(Getter && "property has no setter and no getter!");
641
642 // Only do this if the getter returns an l-value reference type.
643 QualType resultType = Getter->getResultType();
644 if (!resultType->isLValueReferenceType()) return false;
645
646 result = buildRValueOperation(op);
647 return true;
648}
649
650/// @property-specific behavior for doing assignments.
651ExprResult
652ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
653 SourceLocation opcLoc,
654 BinaryOperatorKind opcode,
655 Expr *LHS, Expr *RHS) {
John McCall3c3b7f92011-10-25 17:37:35 +0000656 assert(BinaryOperator::isAssignmentOp(opcode));
John McCall3c3b7f92011-10-25 17:37:35 +0000657
658 // If there's no setter, we have no choice but to try to assign to
659 // the result of the getter.
John McCall4b9c2d22011-11-06 09:01:30 +0000660 if (!findSetter()) {
661 ExprResult result;
662 if (tryBuildGetOfReference(LHS, result)) {
663 if (result.isInvalid()) return ExprError();
664 return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
John McCall3c3b7f92011-10-25 17:37:35 +0000665 }
666
667 // Otherwise, it's an error.
John McCall4b9c2d22011-11-06 09:01:30 +0000668 S.Diag(opcLoc, diag::err_nosetter_property_assignment)
669 << unsigned(RefExpr->isImplicitProperty())
670 << SetterSelector
John McCall3c3b7f92011-10-25 17:37:35 +0000671 << LHS->getSourceRange() << RHS->getSourceRange();
672 return ExprError();
673 }
674
675 // If there is a setter, we definitely want to use it.
676
John McCall4b9c2d22011-11-06 09:01:30 +0000677 // Verify that we can do a compound assignment.
678 if (opcode != BO_Assign && !findGetter()) {
679 S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
John McCall3c3b7f92011-10-25 17:37:35 +0000680 << LHS->getSourceRange() << RHS->getSourceRange();
681 return ExprError();
682 }
683
John McCall4b9c2d22011-11-06 09:01:30 +0000684 ExprResult result =
685 PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
John McCall3c3b7f92011-10-25 17:37:35 +0000686 if (result.isInvalid()) return ExprError();
687
John McCall4b9c2d22011-11-06 09:01:30 +0000688 // Various warnings about property assignments in ARC.
689 if (S.getLangOptions().ObjCAutoRefCount && InstanceReceiver) {
690 S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
691 S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
692 }
693
John McCall3c3b7f92011-10-25 17:37:35 +0000694 return result;
695}
John McCall4b9c2d22011-11-06 09:01:30 +0000696
697/// @property-specific behavior for doing increments and decrements.
698ExprResult
699ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
700 UnaryOperatorKind opcode,
701 Expr *op) {
702 // If there's no setter, we have no choice but to try to assign to
703 // the result of the getter.
704 if (!findSetter()) {
705 ExprResult result;
706 if (tryBuildGetOfReference(op, result)) {
707 if (result.isInvalid()) return ExprError();
708 return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
709 }
710
711 // Otherwise, it's an error.
712 S.Diag(opcLoc, diag::err_nosetter_property_incdec)
713 << unsigned(RefExpr->isImplicitProperty())
714 << unsigned(UnaryOperator::isDecrementOp(opcode))
715 << SetterSelector
716 << op->getSourceRange();
717 return ExprError();
718 }
719
720 // If there is a setter, we definitely want to use it.
721
722 // We also need a getter.
723 if (!findGetter()) {
724 assert(RefExpr->isImplicitProperty());
725 S.Diag(opcLoc, diag::err_nogetter_property_incdec)
726 << unsigned(UnaryOperator::isDecrementOp(opcode))
727 << RefExpr->getImplicitPropertyGetter()->getSelector() // FIXME!
728 << op->getSourceRange();
729 return ExprError();
730 }
731
732 return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
733}
734
735//===----------------------------------------------------------------------===//
736// General Sema routines.
737//===----------------------------------------------------------------------===//
738
739ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
740 Expr *opaqueRef = E->IgnoreParens();
741 if (ObjCPropertyRefExpr *refExpr
742 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
743 ObjCPropertyOpBuilder builder(*this, refExpr);
744 return builder.buildRValueOperation(E);
745 } else {
746 llvm_unreachable("unknown pseudo-object kind!");
747 }
748}
749
750/// Check an increment or decrement of a pseudo-object expression.
751ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
752 UnaryOperatorKind opcode, Expr *op) {
753 // Do nothing if the operand is dependent.
754 if (op->isTypeDependent())
755 return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
756 VK_RValue, OK_Ordinary, opcLoc);
757
758 assert(UnaryOperator::isIncrementDecrementOp(opcode));
759 Expr *opaqueRef = op->IgnoreParens();
760 if (ObjCPropertyRefExpr *refExpr
761 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
762 ObjCPropertyOpBuilder builder(*this, refExpr);
763 return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
764 } else {
765 llvm_unreachable("unknown pseudo-object kind!");
766 }
767}
768
769ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
770 BinaryOperatorKind opcode,
771 Expr *LHS, Expr *RHS) {
772 // Do nothing if either argument is dependent.
773 if (LHS->isTypeDependent() || RHS->isTypeDependent())
774 return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
775 VK_RValue, OK_Ordinary, opcLoc);
776
777 // Filter out non-overload placeholder types in the RHS.
John McCall32509f12011-11-15 01:35:18 +0000778 if (RHS->getType()->isNonOverloadPlaceholderType()) {
779 ExprResult result = CheckPlaceholderExpr(RHS);
780 if (result.isInvalid()) return ExprError();
781 RHS = result.take();
John McCall4b9c2d22011-11-06 09:01:30 +0000782 }
783
784 Expr *opaqueRef = LHS->IgnoreParens();
785 if (ObjCPropertyRefExpr *refExpr
786 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
787 ObjCPropertyOpBuilder builder(*this, refExpr);
788 return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
789 } else {
790 llvm_unreachable("unknown pseudo-object kind!");
791 }
792}
John McCall01e19be2011-11-30 04:42:31 +0000793
794/// Given a pseudo-object reference, rebuild it without the opaque
795/// values. Basically, undo the behavior of rebuildAndCaptureObject.
796/// This should never operate in-place.
797static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
798 Expr *opaqueRef = E->IgnoreParens();
799 if (ObjCPropertyRefExpr *refExpr
800 = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
801 OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
802 return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
803 } else {
804 llvm_unreachable("unknown pseudo-object kind!");
805 }
806}
807
808/// Given a pseudo-object expression, recreate what it looks like
809/// syntactically without the attendant OpaqueValueExprs.
810///
811/// This is a hack which should be removed when TreeTransform is
812/// capable of rebuilding a tree without stripping implicit
813/// operations.
814Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
815 Expr *syntax = E->getSyntacticForm();
816 if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
817 Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
818 return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
819 uop->getValueKind(), uop->getObjectKind(),
820 uop->getOperatorLoc());
821 } else if (CompoundAssignOperator *cop
822 = dyn_cast<CompoundAssignOperator>(syntax)) {
823 Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
824 Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
825 return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
826 cop->getType(),
827 cop->getValueKind(),
828 cop->getObjectKind(),
829 cop->getComputationLHSType(),
830 cop->getComputationResultType(),
831 cop->getOperatorLoc());
832 } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
833 Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
834 Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
835 return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
836 bop->getType(), bop->getValueKind(),
837 bop->getObjectKind(),
838 bop->getOperatorLoc());
839 } else {
840 assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
841 return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
842 }
843}