SemaPseudoObject.cpp revision d314abeffba04dffc101e4e71cc3a32ddeed4ae6
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, MultiExprArg());
667  } else {
668    msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
669                                      GenericLoc,
670                                      Getter->getSelector(), Getter,
671                                      MultiExprArg());
672  }
673  return msg;
674}
675
676/// Store to an Objective-C property reference.
677///
678/// \param captureSetValueAsResult If true, capture the actual
679///   value being set as the value of the property operation.
680ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
681                                           bool captureSetValueAsResult) {
682  bool hasSetter = findSetter(false);
683  assert(hasSetter); (void) hasSetter;
684
685  if (SyntacticRefExpr)
686    SyntacticRefExpr->setIsMessagingSetter();
687
688  QualType receiverType;
689  if (RefExpr->isClassReceiver()) {
690    receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
691  } else if (RefExpr->isSuperReceiver()) {
692    receiverType = RefExpr->getSuperReceiverType();
693  } else {
694    assert(InstanceReceiver);
695    receiverType = InstanceReceiver->getType();
696  }
697
698  // Use assignment constraints when possible; they give us better
699  // diagnostics.  "When possible" basically means anything except a
700  // C++ class type.
701  if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) {
702    QualType paramType = (*Setter->param_begin())->getType();
703    if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) {
704      ExprResult opResult = op;
705      Sema::AssignConvertType assignResult
706        = S.CheckSingleAssignmentConstraints(paramType, opResult);
707      if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
708                                     op->getType(), opResult.get(),
709                                     Sema::AA_Assigning))
710        return ExprError();
711
712      op = opResult.take();
713      assert(op && "successful assignment left argument invalid?");
714    }
715  }
716
717  // Arguments.
718  Expr *args[] = { op };
719
720  // Build a message-send.
721  ExprResult msg;
722  if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
723    msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
724                                         GenericLoc, SetterSelector, Setter,
725                                         MultiExprArg(args, 1));
726  } else {
727    msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
728                                      GenericLoc,
729                                      SetterSelector, Setter,
730                                      MultiExprArg(args, 1));
731  }
732
733  if (!msg.isInvalid() && captureSetValueAsResult) {
734    ObjCMessageExpr *msgExpr =
735      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
736    Expr *arg = msgExpr->getArg(0);
737    if (CanCaptureValueOfType(arg->getType()))
738      msgExpr->setArg(0, captureValueAsResult(arg));
739  }
740
741  return msg;
742}
743
744/// @property-specific behavior for doing lvalue-to-rvalue conversion.
745ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
746  // Explicit properties always have getters, but implicit ones don't.
747  // Check that before proceeding.
748  if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
749    S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
750        << RefExpr->getSourceRange();
751    return ExprError();
752  }
753
754  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
755  if (result.isInvalid()) return ExprError();
756
757  if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
758    S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
759                                       Getter, RefExpr->getLocation());
760
761  // As a special case, if the method returns 'id', try to get
762  // a better type from the property.
763  if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
764      result.get()->getType()->isObjCIdType()) {
765    QualType propType = RefExpr->getExplicitProperty()->getType();
766    if (const ObjCObjectPointerType *ptr
767          = propType->getAs<ObjCObjectPointerType>()) {
768      if (!ptr->isObjCIdType())
769        result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
770    }
771  }
772
773  return result;
774}
775
776/// Try to build this as a call to a getter that returns a reference.
777///
778/// \return true if it was possible, whether or not it actually
779///   succeeded
780bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
781                                                   ExprResult &result) {
782  if (!S.getLangOpts().CPlusPlus) return false;
783
784  findGetter();
785  assert(Getter && "property has no setter and no getter!");
786
787  // Only do this if the getter returns an l-value reference type.
788  QualType resultType = Getter->getResultType();
789  if (!resultType->isLValueReferenceType()) return false;
790
791  result = buildRValueOperation(op);
792  return true;
793}
794
795/// @property-specific behavior for doing assignments.
796ExprResult
797ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
798                                                SourceLocation opcLoc,
799                                                BinaryOperatorKind opcode,
800                                                Expr *LHS, Expr *RHS) {
801  assert(BinaryOperator::isAssignmentOp(opcode));
802
803  // If there's no setter, we have no choice but to try to assign to
804  // the result of the getter.
805  if (!findSetter()) {
806    ExprResult result;
807    if (tryBuildGetOfReference(LHS, result)) {
808      if (result.isInvalid()) return ExprError();
809      return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
810    }
811
812    // Otherwise, it's an error.
813    S.Diag(opcLoc, diag::err_nosetter_property_assignment)
814      << unsigned(RefExpr->isImplicitProperty())
815      << SetterSelector
816      << LHS->getSourceRange() << RHS->getSourceRange();
817    return ExprError();
818  }
819
820  // If there is a setter, we definitely want to use it.
821
822  // Verify that we can do a compound assignment.
823  if (opcode != BO_Assign && !findGetter()) {
824    S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
825      << LHS->getSourceRange() << RHS->getSourceRange();
826    return ExprError();
827  }
828
829  ExprResult result =
830    PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
831  if (result.isInvalid()) return ExprError();
832
833  // Various warnings about property assignments in ARC.
834  if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
835    S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
836    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
837  }
838
839  return result;
840}
841
842/// @property-specific behavior for doing increments and decrements.
843ExprResult
844ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
845                                            UnaryOperatorKind opcode,
846                                            Expr *op) {
847  // If there's no setter, we have no choice but to try to assign to
848  // the result of the getter.
849  if (!findSetter()) {
850    ExprResult result;
851    if (tryBuildGetOfReference(op, result)) {
852      if (result.isInvalid()) return ExprError();
853      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
854    }
855
856    // Otherwise, it's an error.
857    S.Diag(opcLoc, diag::err_nosetter_property_incdec)
858      << unsigned(RefExpr->isImplicitProperty())
859      << unsigned(UnaryOperator::isDecrementOp(opcode))
860      << SetterSelector
861      << op->getSourceRange();
862    return ExprError();
863  }
864
865  // If there is a setter, we definitely want to use it.
866
867  // We also need a getter.
868  if (!findGetter()) {
869    assert(RefExpr->isImplicitProperty());
870    S.Diag(opcLoc, diag::err_nogetter_property_incdec)
871      << unsigned(UnaryOperator::isDecrementOp(opcode))
872      << GetterSelector
873      << op->getSourceRange();
874    return ExprError();
875  }
876
877  return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
878}
879
880ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
881  if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty()) {
882    DiagnosticsEngine::Level Level =
883      S.Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
884                                 SyntacticForm->getLocStart());
885    if (Level != DiagnosticsEngine::Ignored)
886      S.getCurFunction()->recordUseOfWeak(SyntacticRefExpr,
887                                         SyntacticRefExpr->isMessagingGetter());
888  }
889
890  return PseudoOpBuilder::complete(SyntacticForm);
891}
892
893// ObjCSubscript build stuff.
894//
895
896/// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
897/// conversion.
898/// FIXME. Remove this routine if it is proven that no additional
899/// specifity is needed.
900ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
901  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
902  if (result.isInvalid()) return ExprError();
903  return result;
904}
905
906/// objective-c subscripting-specific  behavior for doing assignments.
907ExprResult
908ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
909                                                SourceLocation opcLoc,
910                                                BinaryOperatorKind opcode,
911                                                Expr *LHS, Expr *RHS) {
912  assert(BinaryOperator::isAssignmentOp(opcode));
913  // There must be a method to do the Index'ed assignment.
914  if (!findAtIndexSetter())
915    return ExprError();
916
917  // Verify that we can do a compound assignment.
918  if (opcode != BO_Assign && !findAtIndexGetter())
919    return ExprError();
920
921  ExprResult result =
922  PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
923  if (result.isInvalid()) return ExprError();
924
925  // Various warnings about objc Index'ed assignments in ARC.
926  if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {
927    S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
928    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
929  }
930
931  return result;
932}
933
934/// Capture the base object of an Objective-C Index'ed expression.
935Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
936  assert(InstanceBase == 0);
937
938  // Capture base expression in an OVE and rebuild the syntactic
939  // form to use the OVE as its base expression.
940  InstanceBase = capture(RefExpr->getBaseExpr());
941  InstanceKey = capture(RefExpr->getKeyExpr());
942
943  syntacticBase =
944    ObjCSubscriptRefRebuilder(S, InstanceBase,
945                              InstanceKey).rebuild(syntacticBase);
946
947  return syntacticBase;
948}
949
950/// CheckSubscriptingKind - This routine decide what type
951/// of indexing represented by "FromE" is being done.
952Sema::ObjCSubscriptKind
953  Sema::CheckSubscriptingKind(Expr *FromE) {
954  // If the expression already has integral or enumeration type, we're golden.
955  QualType T = FromE->getType();
956  if (T->isIntegralOrEnumerationType())
957    return OS_Array;
958
959  // If we don't have a class type in C++, there's no way we can get an
960  // expression of integral or enumeration type.
961  const RecordType *RecordTy = T->getAs<RecordType>();
962  if (!RecordTy && T->isObjCObjectPointerType())
963    // All other scalar cases are assumed to be dictionary indexing which
964    // caller handles, with diagnostics if needed.
965    return OS_Dictionary;
966  if (!getLangOpts().CPlusPlus ||
967      !RecordTy || RecordTy->isIncompleteType()) {
968    // No indexing can be done. Issue diagnostics and quit.
969    const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
970    if (isa<StringLiteral>(IndexExpr))
971      Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
972        << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
973    else
974      Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
975        << T;
976    return OS_Error;
977  }
978
979  // We must have a complete class type.
980  if (RequireCompleteType(FromE->getExprLoc(), T,
981                          diag::err_objc_index_incomplete_class_type, FromE))
982    return OS_Error;
983
984  // Look for a conversion to an integral, enumeration type, or
985  // objective-C pointer type.
986  UnresolvedSet<4> ViableConversions;
987  UnresolvedSet<4> ExplicitConversions;
988  std::pair<CXXRecordDecl::conversion_iterator,
989            CXXRecordDecl::conversion_iterator> Conversions
990    = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
991
992  int NoIntegrals=0, NoObjCIdPointers=0;
993  SmallVector<CXXConversionDecl *, 4> ConversionDecls;
994
995  for (CXXRecordDecl::conversion_iterator
996         I = Conversions.first, E = Conversions.second; I != E; ++I) {
997    if (CXXConversionDecl *Conversion
998        = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
999      QualType CT = Conversion->getConversionType().getNonReferenceType();
1000      if (CT->isIntegralOrEnumerationType()) {
1001        ++NoIntegrals;
1002        ConversionDecls.push_back(Conversion);
1003      }
1004      else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
1005        ++NoObjCIdPointers;
1006        ConversionDecls.push_back(Conversion);
1007      }
1008    }
1009  }
1010  if (NoIntegrals ==1 && NoObjCIdPointers == 0)
1011    return OS_Array;
1012  if (NoIntegrals == 0 && NoObjCIdPointers == 1)
1013    return OS_Dictionary;
1014  if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
1015    // No conversion function was found. Issue diagnostic and return.
1016    Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
1017      << FromE->getType();
1018    return OS_Error;
1019  }
1020  Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1021      << FromE->getType();
1022  for (unsigned int i = 0; i < ConversionDecls.size(); i++)
1023    Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
1024
1025  return OS_Error;
1026}
1027
1028/// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
1029/// objects used as dictionary subscript key objects.
1030static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT,
1031                                         Expr *Key) {
1032  if (ContainerT.isNull())
1033    return;
1034  // dictionary subscripting.
1035  // - (id)objectForKeyedSubscript:(id)key;
1036  IdentifierInfo *KeyIdents[] = {
1037    &S.Context.Idents.get("objectForKeyedSubscript")
1038  };
1039  Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
1040  ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT,
1041                                                      true /*instance*/);
1042  if (!Getter)
1043    return;
1044  QualType T = Getter->param_begin()[0]->getType();
1045  S.CheckObjCARCConversion(Key->getSourceRange(),
1046                         T, Key, Sema::CCK_ImplicitConversion);
1047}
1048
1049bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1050  if (AtIndexGetter)
1051    return true;
1052
1053  Expr *BaseExpr = RefExpr->getBaseExpr();
1054  QualType BaseT = BaseExpr->getType();
1055
1056  QualType ResultType;
1057  if (const ObjCObjectPointerType *PTy =
1058      BaseT->getAs<ObjCObjectPointerType>()) {
1059    ResultType = PTy->getPointeeType();
1060    if (const ObjCObjectType *iQFaceTy =
1061        ResultType->getAsObjCQualifiedInterfaceType())
1062      ResultType = iQFaceTy->getBaseType();
1063  }
1064  Sema::ObjCSubscriptKind Res =
1065    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
1066  if (Res == Sema::OS_Error) {
1067    if (S.getLangOpts().ObjCAutoRefCount)
1068      CheckKeyForObjCARCConversion(S, ResultType,
1069                                   RefExpr->getKeyExpr());
1070    return false;
1071  }
1072  bool arrayRef = (Res == Sema::OS_Array);
1073
1074  if (ResultType.isNull()) {
1075    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
1076      << BaseExpr->getType() << arrayRef;
1077    return false;
1078  }
1079  if (!arrayRef) {
1080    // dictionary subscripting.
1081    // - (id)objectForKeyedSubscript:(id)key;
1082    IdentifierInfo *KeyIdents[] = {
1083      &S.Context.Idents.get("objectForKeyedSubscript")
1084    };
1085    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
1086  }
1087  else {
1088    // - (id)objectAtIndexedSubscript:(size_t)index;
1089    IdentifierInfo *KeyIdents[] = {
1090      &S.Context.Idents.get("objectAtIndexedSubscript")
1091    };
1092
1093    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
1094  }
1095
1096  AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType,
1097                                             true /*instance*/);
1098  bool receiverIdType = (BaseT->isObjCIdType() ||
1099                         BaseT->isObjCQualifiedIdType());
1100
1101  if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {
1102    AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
1103                           SourceLocation(), AtIndexGetterSelector,
1104                           S.Context.getObjCIdType() /*ReturnType*/,
1105                           0 /*TypeSourceInfo */,
1106                           S.Context.getTranslationUnitDecl(),
1107                           true /*Instance*/, false/*isVariadic*/,
1108                           /*isPropertyAccessor=*/false,
1109                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1110                           ObjCMethodDecl::Required,
1111                           false);
1112    ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
1113                                                SourceLocation(), SourceLocation(),
1114                                                arrayRef ? &S.Context.Idents.get("index")
1115                                                         : &S.Context.Idents.get("key"),
1116                                                arrayRef ? S.Context.UnsignedLongTy
1117                                                         : S.Context.getObjCIdType(),
1118                                                /*TInfo=*/0,
1119                                                SC_None,
1120                                                0);
1121    AtIndexGetter->setMethodParams(S.Context, Argument,
1122                                   ArrayRef<SourceLocation>());
1123  }
1124
1125  if (!AtIndexGetter) {
1126    if (!receiverIdType) {
1127      S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
1128      << BaseExpr->getType() << 0 << arrayRef;
1129      return false;
1130    }
1131    AtIndexGetter =
1132      S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector,
1133                                         RefExpr->getSourceRange(),
1134                                         true, false);
1135  }
1136
1137  if (AtIndexGetter) {
1138    QualType T = AtIndexGetter->param_begin()[0]->getType();
1139    if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
1140        (!arrayRef && !T->isObjCObjectPointerType())) {
1141      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1142             arrayRef ? diag::err_objc_subscript_index_type
1143                      : diag::err_objc_subscript_key_type) << T;
1144      S.Diag(AtIndexGetter->param_begin()[0]->getLocation(),
1145             diag::note_parameter_type) << T;
1146      return false;
1147    }
1148    QualType R = AtIndexGetter->getResultType();
1149    if (!R->isObjCObjectPointerType()) {
1150      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1151             diag::err_objc_indexing_method_result_type) << R << arrayRef;
1152      S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1153        AtIndexGetter->getDeclName();
1154    }
1155  }
1156  return true;
1157}
1158
1159bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1160  if (AtIndexSetter)
1161    return true;
1162
1163  Expr *BaseExpr = RefExpr->getBaseExpr();
1164  QualType BaseT = BaseExpr->getType();
1165
1166  QualType ResultType;
1167  if (const ObjCObjectPointerType *PTy =
1168      BaseT->getAs<ObjCObjectPointerType>()) {
1169    ResultType = PTy->getPointeeType();
1170    if (const ObjCObjectType *iQFaceTy =
1171        ResultType->getAsObjCQualifiedInterfaceType())
1172      ResultType = iQFaceTy->getBaseType();
1173  }
1174
1175  Sema::ObjCSubscriptKind Res =
1176    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
1177  if (Res == Sema::OS_Error) {
1178    if (S.getLangOpts().ObjCAutoRefCount)
1179      CheckKeyForObjCARCConversion(S, ResultType,
1180                                   RefExpr->getKeyExpr());
1181    return false;
1182  }
1183  bool arrayRef = (Res == Sema::OS_Array);
1184
1185  if (ResultType.isNull()) {
1186    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
1187      << BaseExpr->getType() << arrayRef;
1188    return false;
1189  }
1190
1191  if (!arrayRef) {
1192    // dictionary subscripting.
1193    // - (void)setObject:(id)object forKeyedSubscript:(id)key;
1194    IdentifierInfo *KeyIdents[] = {
1195      &S.Context.Idents.get("setObject"),
1196      &S.Context.Idents.get("forKeyedSubscript")
1197    };
1198    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
1199  }
1200  else {
1201    // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1202    IdentifierInfo *KeyIdents[] = {
1203      &S.Context.Idents.get("setObject"),
1204      &S.Context.Idents.get("atIndexedSubscript")
1205    };
1206    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
1207  }
1208  AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType,
1209                                             true /*instance*/);
1210
1211  bool receiverIdType = (BaseT->isObjCIdType() ||
1212                         BaseT->isObjCQualifiedIdType());
1213
1214  if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
1215    TypeSourceInfo *ResultTInfo = 0;
1216    QualType ReturnType = S.Context.VoidTy;
1217    AtIndexSetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
1218                           SourceLocation(), AtIndexSetterSelector,
1219                           ReturnType,
1220                           ResultTInfo,
1221                           S.Context.getTranslationUnitDecl(),
1222                           true /*Instance*/, false/*isVariadic*/,
1223                           /*isPropertyAccessor=*/false,
1224                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1225                           ObjCMethodDecl::Required,
1226                           false);
1227    SmallVector<ParmVarDecl *, 2> Params;
1228    ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
1229                                                SourceLocation(), SourceLocation(),
1230                                                &S.Context.Idents.get("object"),
1231                                                S.Context.getObjCIdType(),
1232                                                /*TInfo=*/0,
1233                                                SC_None,
1234                                                0);
1235    Params.push_back(object);
1236    ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
1237                                                SourceLocation(), SourceLocation(),
1238                                                arrayRef ?  &S.Context.Idents.get("index")
1239                                                         :  &S.Context.Idents.get("key"),
1240                                                arrayRef ? S.Context.UnsignedLongTy
1241                                                         : S.Context.getObjCIdType(),
1242                                                /*TInfo=*/0,
1243                                                SC_None,
1244                                                0);
1245    Params.push_back(key);
1246    AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
1247  }
1248
1249  if (!AtIndexSetter) {
1250    if (!receiverIdType) {
1251      S.Diag(BaseExpr->getExprLoc(),
1252             diag::err_objc_subscript_method_not_found)
1253      << BaseExpr->getType() << 1 << arrayRef;
1254      return false;
1255    }
1256    AtIndexSetter =
1257      S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector,
1258                                         RefExpr->getSourceRange(),
1259                                         true, false);
1260  }
1261
1262  bool err = false;
1263  if (AtIndexSetter && arrayRef) {
1264    QualType T = AtIndexSetter->param_begin()[1]->getType();
1265    if (!T->isIntegralOrEnumerationType()) {
1266      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1267             diag::err_objc_subscript_index_type) << T;
1268      S.Diag(AtIndexSetter->param_begin()[1]->getLocation(),
1269             diag::note_parameter_type) << T;
1270      err = true;
1271    }
1272    T = AtIndexSetter->param_begin()[0]->getType();
1273    if (!T->isObjCObjectPointerType()) {
1274      S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
1275             diag::err_objc_subscript_object_type) << T << arrayRef;
1276      S.Diag(AtIndexSetter->param_begin()[0]->getLocation(),
1277             diag::note_parameter_type) << T;
1278      err = true;
1279    }
1280  }
1281  else if (AtIndexSetter && !arrayRef)
1282    for (unsigned i=0; i <2; i++) {
1283      QualType T = AtIndexSetter->param_begin()[i]->getType();
1284      if (!T->isObjCObjectPointerType()) {
1285        if (i == 1)
1286          S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1287                 diag::err_objc_subscript_key_type) << T;
1288        else
1289          S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
1290                 diag::err_objc_subscript_dic_object_type) << T;
1291        S.Diag(AtIndexSetter->param_begin()[i]->getLocation(),
1292               diag::note_parameter_type) << T;
1293        err = true;
1294      }
1295    }
1296
1297  return !err;
1298}
1299
1300// Get the object at "Index" position in the container.
1301// [BaseExpr objectAtIndexedSubscript : IndexExpr];
1302ExprResult ObjCSubscriptOpBuilder::buildGet() {
1303  if (!findAtIndexGetter())
1304    return ExprError();
1305
1306  QualType receiverType = InstanceBase->getType();
1307
1308  // Build a message-send.
1309  ExprResult msg;
1310  Expr *Index = InstanceKey;
1311
1312  // Arguments.
1313  Expr *args[] = { Index };
1314  assert(InstanceBase);
1315  msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
1316                                       GenericLoc,
1317                                       AtIndexGetterSelector, AtIndexGetter,
1318                                       MultiExprArg(args, 1));
1319  return msg;
1320}
1321
1322/// Store into the container the "op" object at "Index"'ed location
1323/// by building this messaging expression:
1324/// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1325/// \param captureSetValueAsResult If true, capture the actual
1326///   value being set as the value of the property operation.
1327ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
1328                                           bool captureSetValueAsResult) {
1329  if (!findAtIndexSetter())
1330    return ExprError();
1331
1332  QualType receiverType = InstanceBase->getType();
1333  Expr *Index = InstanceKey;
1334
1335  // Arguments.
1336  Expr *args[] = { op, Index };
1337
1338  // Build a message-send.
1339  ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
1340                                                  GenericLoc,
1341                                                  AtIndexSetterSelector,
1342                                                  AtIndexSetter,
1343                                                  MultiExprArg(args, 2));
1344
1345  if (!msg.isInvalid() && captureSetValueAsResult) {
1346    ObjCMessageExpr *msgExpr =
1347      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
1348    Expr *arg = msgExpr->getArg(0);
1349    if (CanCaptureValueOfType(arg->getType()))
1350      msgExpr->setArg(0, captureValueAsResult(arg));
1351  }
1352
1353  return msg;
1354}
1355
1356//===----------------------------------------------------------------------===//
1357//  MSVC __declspec(property) references
1358//===----------------------------------------------------------------------===//
1359
1360Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
1361  Expr *NewBase = capture(RefExpr->getBaseExpr());
1362
1363  syntacticBase =
1364    MSPropertyRefRebuilder(S, NewBase).rebuild(syntacticBase);
1365
1366  return syntacticBase;
1367}
1368
1369ExprResult MSPropertyOpBuilder::buildGet() {
1370  if (!RefExpr->getPropertyDecl()->hasGetter()) {
1371    S.Diag(RefExpr->getMemberLoc(), diag::err_no_getter_for_property)
1372      << RefExpr->getPropertyDecl()->getName();
1373    return ExprError();
1374  }
1375
1376  UnqualifiedId GetterName;
1377  IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
1378  GetterName.setIdentifier(II, RefExpr->getMemberLoc());
1379  CXXScopeSpec SS;
1380  SS.Adopt(RefExpr->getQualifierLoc());
1381  ExprResult GetterExpr = S.ActOnMemberAccessExpr(
1382    S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
1383    RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
1384    GetterName, 0, true);
1385  if (GetterExpr.isInvalid()) {
1386    S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_getter)
1387      << RefExpr->getPropertyDecl()->getName();
1388    return ExprError();
1389  }
1390
1391  MultiExprArg ArgExprs;
1392  return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
1393                         RefExpr->getSourceRange().getBegin(), ArgExprs,
1394                         RefExpr->getSourceRange().getEnd());
1395}
1396
1397ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
1398                                         bool captureSetValueAsResult) {
1399  if (!RefExpr->getPropertyDecl()->hasSetter()) {
1400    S.Diag(RefExpr->getMemberLoc(), diag::err_no_setter_for_property)
1401      << RefExpr->getPropertyDecl()->getName();
1402    return ExprError();
1403  }
1404
1405  UnqualifiedId SetterName;
1406  IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
1407  SetterName.setIdentifier(II, RefExpr->getMemberLoc());
1408  CXXScopeSpec SS;
1409  SS.Adopt(RefExpr->getQualifierLoc());
1410  ExprResult SetterExpr = S.ActOnMemberAccessExpr(
1411    S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
1412    RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
1413    SetterName, 0, true);
1414  if (SetterExpr.isInvalid()) {
1415    S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_setter)
1416      << RefExpr->getPropertyDecl()->getName();
1417    return ExprError();
1418  }
1419
1420  SmallVector<Expr*, 1> ArgExprs;
1421  ArgExprs.push_back(op);
1422  return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
1423                         RefExpr->getSourceRange().getBegin(), ArgExprs,
1424                         op->getSourceRange().getEnd());
1425}
1426
1427//===----------------------------------------------------------------------===//
1428//  General Sema routines.
1429//===----------------------------------------------------------------------===//
1430
1431ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
1432  Expr *opaqueRef = E->IgnoreParens();
1433  if (ObjCPropertyRefExpr *refExpr
1434        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1435    ObjCPropertyOpBuilder builder(*this, refExpr);
1436    return builder.buildRValueOperation(E);
1437  }
1438  else if (ObjCSubscriptRefExpr *refExpr
1439           = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1440    ObjCSubscriptOpBuilder builder(*this, refExpr);
1441    return builder.buildRValueOperation(E);
1442  } else if (MSPropertyRefExpr *refExpr
1443             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1444    MSPropertyOpBuilder builder(*this, refExpr);
1445    return builder.buildRValueOperation(E);
1446  } else {
1447    llvm_unreachable("unknown pseudo-object kind!");
1448  }
1449}
1450
1451/// Check an increment or decrement of a pseudo-object expression.
1452ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
1453                                         UnaryOperatorKind opcode, Expr *op) {
1454  // Do nothing if the operand is dependent.
1455  if (op->isTypeDependent())
1456    return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
1457                                       VK_RValue, OK_Ordinary, opcLoc);
1458
1459  assert(UnaryOperator::isIncrementDecrementOp(opcode));
1460  Expr *opaqueRef = op->IgnoreParens();
1461  if (ObjCPropertyRefExpr *refExpr
1462        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1463    ObjCPropertyOpBuilder builder(*this, refExpr);
1464    return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1465  } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
1466    Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1467    return ExprError();
1468  } else if (MSPropertyRefExpr *refExpr
1469             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1470    MSPropertyOpBuilder builder(*this, refExpr);
1471    return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1472  } else {
1473    llvm_unreachable("unknown pseudo-object kind!");
1474  }
1475}
1476
1477ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
1478                                             BinaryOperatorKind opcode,
1479                                             Expr *LHS, Expr *RHS) {
1480  // Do nothing if either argument is dependent.
1481  if (LHS->isTypeDependent() || RHS->isTypeDependent())
1482    return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
1483                                        VK_RValue, OK_Ordinary, opcLoc, false);
1484
1485  // Filter out non-overload placeholder types in the RHS.
1486  if (RHS->getType()->isNonOverloadPlaceholderType()) {
1487    ExprResult result = CheckPlaceholderExpr(RHS);
1488    if (result.isInvalid()) return ExprError();
1489    RHS = result.take();
1490  }
1491
1492  Expr *opaqueRef = LHS->IgnoreParens();
1493  if (ObjCPropertyRefExpr *refExpr
1494        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1495    ObjCPropertyOpBuilder builder(*this, refExpr);
1496    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1497  } else if (ObjCSubscriptRefExpr *refExpr
1498             = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1499    ObjCSubscriptOpBuilder builder(*this, refExpr);
1500    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1501  } else if (MSPropertyRefExpr *refExpr
1502             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1503    MSPropertyOpBuilder builder(*this, refExpr);
1504    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1505  } else {
1506    llvm_unreachable("unknown pseudo-object kind!");
1507  }
1508}
1509
1510/// Given a pseudo-object reference, rebuild it without the opaque
1511/// values.  Basically, undo the behavior of rebuildAndCaptureObject.
1512/// This should never operate in-place.
1513static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
1514  Expr *opaqueRef = E->IgnoreParens();
1515  if (ObjCPropertyRefExpr *refExpr
1516        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1517    // Class and super property references don't have opaque values in them.
1518    if (refExpr->isClassReceiver() || refExpr->isSuperReceiver())
1519      return E;
1520
1521    assert(refExpr->isObjectReceiver() && "Unknown receiver kind?");
1522    OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
1523    return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
1524  } else if (ObjCSubscriptRefExpr *refExpr
1525               = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1526    OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
1527    OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
1528    return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
1529                                     keyOVE->getSourceExpr()).rebuild(E);
1530  } else if (MSPropertyRefExpr *refExpr
1531             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1532    OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
1533    return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
1534  } else {
1535    llvm_unreachable("unknown pseudo-object kind!");
1536  }
1537}
1538
1539/// Given a pseudo-object expression, recreate what it looks like
1540/// syntactically without the attendant OpaqueValueExprs.
1541///
1542/// This is a hack which should be removed when TreeTransform is
1543/// capable of rebuilding a tree without stripping implicit
1544/// operations.
1545Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
1546  Expr *syntax = E->getSyntacticForm();
1547  if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
1548    Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
1549    return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
1550                                       uop->getValueKind(), uop->getObjectKind(),
1551                                       uop->getOperatorLoc());
1552  } else if (CompoundAssignOperator *cop
1553               = dyn_cast<CompoundAssignOperator>(syntax)) {
1554    Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
1555    Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1556    return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
1557                                                cop->getType(),
1558                                                cop->getValueKind(),
1559                                                cop->getObjectKind(),
1560                                                cop->getComputationLHSType(),
1561                                                cop->getComputationResultType(),
1562                                                cop->getOperatorLoc(), false);
1563  } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1564    Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
1565    Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1566    return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
1567                                        bop->getType(), bop->getValueKind(),
1568                                        bop->getObjectKind(),
1569                                        bop->getOperatorLoc(), false);
1570  } else {
1571    assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
1572    return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
1573  }
1574}
1575