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