clang API Documentation

SemaPseudoObject.cpp
Go to the documentation of this file.
00001 //===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements semantic analysis for expressions involving
00011 //  pseudo-object references.  Pseudo-objects are conceptual objects
00012 //  whose storage is entirely abstract and all accesses to which are
00013 //  translated through some sort of abstraction barrier.
00014 //
00015 //  For example, Objective-C objects can have "properties", either
00016 //  declared or undeclared.  A property may be accessed by writing
00017 //    expr.prop
00018 //  where 'expr' is an r-value of Objective-C pointer type and 'prop'
00019 //  is the name of the property.  If this expression is used in a context
00020 //  needing an r-value, it is treated as if it were a message-send
00021 //  of the associated 'getter' selector, typically:
00022 //    [expr prop]
00023 //  If it is used as the LHS of a simple assignment, it is treated
00024 //  as a message-send of the associated 'setter' selector, typically:
00025 //    [expr setProp: RHS]
00026 //  If it is used as the LHS of a compound assignment, or the operand
00027 //  of a unary increment or decrement, both are required;  for example,
00028 //  'expr.prop *= 100' would be translated to:
00029 //    [expr setProp: [expr prop] * 100]
00030 //
00031 //===----------------------------------------------------------------------===//
00032 
00033 #include "clang/Sema/SemaInternal.h"
00034 #include "clang/Sema/Initialization.h"
00035 #include "clang/AST/ExprObjC.h"
00036 #include "clang/Lex/Preprocessor.h"
00037 
00038 using namespace clang;
00039 using namespace sema;
00040 
00041 namespace {
00042   // Basically just a very focused copy of TreeTransform.
00043   template <class T> struct Rebuilder {
00044     Sema &S;
00045     Rebuilder(Sema &S) : S(S) {}
00046 
00047     T &getDerived() { return static_cast<T&>(*this); }
00048 
00049     Expr *rebuild(Expr *e) {
00050       // Fast path: nothing to look through.
00051       if (typename T::specific_type *specific
00052             = dyn_cast<typename T::specific_type>(e))
00053         return getDerived().rebuildSpecific(specific);
00054 
00055       // Otherwise, we should look through and rebuild anything that
00056       // IgnoreParens would.
00057 
00058       if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
00059         e = rebuild(parens->getSubExpr());
00060         return new (S.Context) ParenExpr(parens->getLParen(),
00061                                          parens->getRParen(),
00062                                          e);
00063       }
00064 
00065       if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
00066         assert(uop->getOpcode() == UO_Extension);
00067         e = rebuild(uop->getSubExpr());
00068         return new (S.Context) UnaryOperator(e, uop->getOpcode(),
00069                                              uop->getType(),
00070                                              uop->getValueKind(),
00071                                              uop->getObjectKind(),
00072                                              uop->getOperatorLoc());
00073       }
00074 
00075       if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
00076         assert(!gse->isResultDependent());
00077         unsigned resultIndex = gse->getResultIndex();
00078         unsigned numAssocs = gse->getNumAssocs();
00079 
00080         SmallVector<Expr*, 8> assocs(numAssocs);
00081         SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
00082 
00083         for (unsigned i = 0; i != numAssocs; ++i) {
00084           Expr *assoc = gse->getAssocExpr(i);
00085           if (i == resultIndex) assoc = rebuild(assoc);
00086           assocs[i] = assoc;
00087           assocTypes[i] = gse->getAssocTypeSourceInfo(i);
00088         }
00089 
00090         return new (S.Context) GenericSelectionExpr(S.Context,
00091                                                     gse->getGenericLoc(),
00092                                                     gse->getControllingExpr(),
00093                                                     assocTypes.data(),
00094                                                     assocs.data(),
00095                                                     numAssocs,
00096                                                     gse->getDefaultLoc(),
00097                                                     gse->getRParenLoc(),
00098                                       gse->containsUnexpandedParameterPack(),
00099                                                     resultIndex);
00100       }
00101 
00102       llvm_unreachable("bad expression to rebuild!");
00103     }
00104   };
00105 
00106   struct ObjCPropertyRefRebuilder : Rebuilder<ObjCPropertyRefRebuilder> {
00107     Expr *NewBase;
00108     ObjCPropertyRefRebuilder(Sema &S, Expr *newBase)
00109       : Rebuilder<ObjCPropertyRefRebuilder>(S), NewBase(newBase) {}
00110 
00111     typedef ObjCPropertyRefExpr specific_type;
00112     Expr *rebuildSpecific(ObjCPropertyRefExpr *refExpr) {
00113       // Fortunately, the constraint that we're rebuilding something
00114       // with a base limits the number of cases here.
00115       assert(refExpr->getBase());
00116 
00117       if (refExpr->isExplicitProperty()) {
00118         return new (S.Context)
00119           ObjCPropertyRefExpr(refExpr->getExplicitProperty(),
00120                               refExpr->getType(), refExpr->getValueKind(),
00121                               refExpr->getObjectKind(), refExpr->getLocation(),
00122                               NewBase);
00123       }
00124       return new (S.Context)
00125         ObjCPropertyRefExpr(refExpr->getImplicitPropertyGetter(),
00126                             refExpr->getImplicitPropertySetter(),
00127                             refExpr->getType(), refExpr->getValueKind(),
00128                             refExpr->getObjectKind(),refExpr->getLocation(),
00129                             NewBase);
00130     }
00131   };
00132 
00133   struct ObjCSubscriptRefRebuilder : Rebuilder<ObjCSubscriptRefRebuilder> {
00134     Expr *NewBase;
00135     Expr *NewKeyExpr;
00136     ObjCSubscriptRefRebuilder(Sema &S, Expr *newBase, Expr *newKeyExpr)
00137     : Rebuilder<ObjCSubscriptRefRebuilder>(S), 
00138       NewBase(newBase), NewKeyExpr(newKeyExpr) {}
00139     
00140     typedef ObjCSubscriptRefExpr specific_type;
00141     Expr *rebuildSpecific(ObjCSubscriptRefExpr *refExpr) {
00142       assert(refExpr->getBaseExpr());
00143       assert(refExpr->getKeyExpr());
00144       
00145       return new (S.Context)
00146         ObjCSubscriptRefExpr(NewBase,
00147                              NewKeyExpr,
00148                              refExpr->getType(), refExpr->getValueKind(),
00149                              refExpr->getObjectKind(),refExpr->getAtIndexMethodDecl(),
00150                              refExpr->setAtIndexMethodDecl(),
00151                              refExpr->getRBracket());
00152     }
00153   };
00154   
00155   class PseudoOpBuilder {
00156   public:
00157     Sema &S;
00158     unsigned ResultIndex;
00159     SourceLocation GenericLoc;
00160     SmallVector<Expr *, 4> Semantics;
00161 
00162     PseudoOpBuilder(Sema &S, SourceLocation genericLoc)
00163       : S(S), ResultIndex(PseudoObjectExpr::NoResult),
00164         GenericLoc(genericLoc) {}
00165 
00166     virtual ~PseudoOpBuilder() {}
00167 
00168     /// Add a normal semantic expression.
00169     void addSemanticExpr(Expr *semantic) {
00170       Semantics.push_back(semantic);
00171     }
00172 
00173     /// Add the 'result' semantic expression.
00174     void addResultSemanticExpr(Expr *resultExpr) {
00175       assert(ResultIndex == PseudoObjectExpr::NoResult);
00176       ResultIndex = Semantics.size();
00177       Semantics.push_back(resultExpr);
00178     }
00179 
00180     ExprResult buildRValueOperation(Expr *op);
00181     ExprResult buildAssignmentOperation(Scope *Sc,
00182                                         SourceLocation opLoc,
00183                                         BinaryOperatorKind opcode,
00184                                         Expr *LHS, Expr *RHS);
00185     ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
00186                                     UnaryOperatorKind opcode,
00187                                     Expr *op);
00188 
00189     ExprResult complete(Expr *syntacticForm);
00190 
00191     OpaqueValueExpr *capture(Expr *op);
00192     OpaqueValueExpr *captureValueAsResult(Expr *op);
00193 
00194     void setResultToLastSemantic() {
00195       assert(ResultIndex == PseudoObjectExpr::NoResult);
00196       ResultIndex = Semantics.size() - 1;
00197     }
00198 
00199     /// Return true if assignments have a non-void result.
00200     virtual bool assignmentsHaveResult() { return true; }
00201 
00202     virtual Expr *rebuildAndCaptureObject(Expr *) = 0;
00203     virtual ExprResult buildGet() = 0;
00204     virtual ExprResult buildSet(Expr *, SourceLocation,
00205                                 bool captureSetValueAsResult) = 0;
00206   };
00207 
00208   /// A PseudoOpBuilder for Objective-C @properties.
00209   class ObjCPropertyOpBuilder : public PseudoOpBuilder {
00210     ObjCPropertyRefExpr *RefExpr;
00211     ObjCPropertyRefExpr *SyntacticRefExpr;
00212     OpaqueValueExpr *InstanceReceiver;
00213     ObjCMethodDecl *Getter;
00214 
00215     ObjCMethodDecl *Setter;
00216     Selector SetterSelector;
00217     Selector GetterSelector;
00218 
00219   public:
00220     ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
00221       PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
00222       SyntacticRefExpr(0), InstanceReceiver(0), Getter(0), Setter(0) {
00223     }
00224 
00225     ExprResult buildRValueOperation(Expr *op);
00226     ExprResult buildAssignmentOperation(Scope *Sc,
00227                                         SourceLocation opLoc,
00228                                         BinaryOperatorKind opcode,
00229                                         Expr *LHS, Expr *RHS);
00230     ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
00231                                     UnaryOperatorKind opcode,
00232                                     Expr *op);
00233 
00234     bool tryBuildGetOfReference(Expr *op, ExprResult &result);
00235     bool findSetter();
00236     bool findGetter();
00237 
00238     Expr *rebuildAndCaptureObject(Expr *syntacticBase);
00239     ExprResult buildGet();
00240     ExprResult buildSet(Expr *op, SourceLocation, bool);
00241   };
00242 
00243  /// A PseudoOpBuilder for Objective-C array/dictionary indexing.
00244  class ObjCSubscriptOpBuilder : public PseudoOpBuilder {
00245    ObjCSubscriptRefExpr *RefExpr;
00246    OpaqueValueExpr *InstanceBase;
00247    OpaqueValueExpr *InstanceKey;
00248    ObjCMethodDecl *AtIndexGetter;
00249    Selector AtIndexGetterSelector;
00250   
00251    ObjCMethodDecl *AtIndexSetter;
00252    Selector AtIndexSetterSelector;
00253   
00254  public:
00255     ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) :
00256       PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), 
00257       RefExpr(refExpr),
00258     InstanceBase(0), InstanceKey(0), 
00259     AtIndexGetter(0), AtIndexSetter(0) { }
00260   
00261    ExprResult buildRValueOperation(Expr *op);
00262    ExprResult buildAssignmentOperation(Scope *Sc,
00263                                        SourceLocation opLoc,
00264                                        BinaryOperatorKind opcode,
00265                                        Expr *LHS, Expr *RHS);
00266    Expr *rebuildAndCaptureObject(Expr *syntacticBase);
00267    
00268    bool findAtIndexGetter();
00269    bool findAtIndexSetter();
00270   
00271    ExprResult buildGet();
00272    ExprResult buildSet(Expr *op, SourceLocation, bool);
00273  };
00274 
00275 }
00276 
00277 /// Capture the given expression in an OpaqueValueExpr.
00278 OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
00279   // Make a new OVE whose source is the given expression.
00280   OpaqueValueExpr *captured = 
00281     new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
00282                                     e->getValueKind(), e->getObjectKind(),
00283                                     e);
00284   
00285   // Make sure we bind that in the semantics.
00286   addSemanticExpr(captured);
00287   return captured;
00288 }
00289 
00290 /// Capture the given expression as the result of this pseudo-object
00291 /// operation.  This routine is safe against expressions which may
00292 /// already be captured.
00293 ///
00294 /// \param Returns the captured expression, which will be the
00295 ///   same as the input if the input was already captured
00296 OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
00297   assert(ResultIndex == PseudoObjectExpr::NoResult);
00298 
00299   // If the expression hasn't already been captured, just capture it
00300   // and set the new semantic 
00301   if (!isa<OpaqueValueExpr>(e)) {
00302     OpaqueValueExpr *cap = capture(e);
00303     setResultToLastSemantic();
00304     return cap;
00305   }
00306 
00307   // Otherwise, it must already be one of our semantic expressions;
00308   // set ResultIndex to its index.
00309   unsigned index = 0;
00310   for (;; ++index) {
00311     assert(index < Semantics.size() &&
00312            "captured expression not found in semantics!");
00313     if (e == Semantics[index]) break;
00314   }
00315   ResultIndex = index;
00316   return cast<OpaqueValueExpr>(e);
00317 }
00318 
00319 /// The routine which creates the final PseudoObjectExpr.
00320 ExprResult PseudoOpBuilder::complete(Expr *syntactic) {
00321   return PseudoObjectExpr::Create(S.Context, syntactic,
00322                                   Semantics, ResultIndex);
00323 }
00324 
00325 /// The main skeleton for building an r-value operation.
00326 ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {
00327   Expr *syntacticBase = rebuildAndCaptureObject(op);
00328 
00329   ExprResult getExpr = buildGet();
00330   if (getExpr.isInvalid()) return ExprError();
00331   addResultSemanticExpr(getExpr.take());
00332 
00333   return complete(syntacticBase);
00334 }
00335 
00336 /// The basic skeleton for building a simple or compound
00337 /// assignment operation.
00338 ExprResult
00339 PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
00340                                           BinaryOperatorKind opcode,
00341                                           Expr *LHS, Expr *RHS) {
00342   assert(BinaryOperator::isAssignmentOp(opcode));
00343 
00344   Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
00345   OpaqueValueExpr *capturedRHS = capture(RHS);
00346 
00347   Expr *syntactic;
00348 
00349   ExprResult result;
00350   if (opcode == BO_Assign) {
00351     result = capturedRHS;
00352     syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
00353                                                opcode, capturedRHS->getType(),
00354                                                capturedRHS->getValueKind(),
00355                                                OK_Ordinary, opcLoc);
00356   } else {
00357     ExprResult opLHS = buildGet();
00358     if (opLHS.isInvalid()) return ExprError();
00359 
00360     // Build an ordinary, non-compound operation.
00361     BinaryOperatorKind nonCompound =
00362       BinaryOperator::getOpForCompoundAssignment(opcode);
00363     result = S.BuildBinOp(Sc, opcLoc, nonCompound,
00364                           opLHS.take(), capturedRHS);
00365     if (result.isInvalid()) return ExprError();
00366 
00367     syntactic =
00368       new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
00369                                              result.get()->getType(),
00370                                              result.get()->getValueKind(),
00371                                              OK_Ordinary,
00372                                              opLHS.get()->getType(),
00373                                              result.get()->getType(),
00374                                              opcLoc);
00375   }
00376 
00377   // The result of the assignment, if not void, is the value set into
00378   // the l-value.
00379   result = buildSet(result.take(), opcLoc, assignmentsHaveResult());
00380   if (result.isInvalid()) return ExprError();
00381   addSemanticExpr(result.take());
00382 
00383   return complete(syntactic);
00384 }
00385 
00386 /// The basic skeleton for building an increment or decrement
00387 /// operation.
00388 ExprResult
00389 PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
00390                                       UnaryOperatorKind opcode,
00391                                       Expr *op) {
00392   assert(UnaryOperator::isIncrementDecrementOp(opcode));
00393 
00394   Expr *syntacticOp = rebuildAndCaptureObject(op);
00395 
00396   // Load the value.
00397   ExprResult result = buildGet();
00398   if (result.isInvalid()) return ExprError();
00399 
00400   QualType resultType = result.get()->getType();
00401 
00402   // That's the postfix result.
00403   if (UnaryOperator::isPostfix(opcode) && assignmentsHaveResult()) {
00404     result = capture(result.take());
00405     setResultToLastSemantic();
00406   }
00407 
00408   // Add or subtract a literal 1.
00409   llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
00410   Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
00411                                      GenericLoc);
00412 
00413   if (UnaryOperator::isIncrementOp(opcode)) {
00414     result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
00415   } else {
00416     result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
00417   }
00418   if (result.isInvalid()) return ExprError();
00419 
00420   // Store that back into the result.  The value stored is the result
00421   // of a prefix operation.
00422   result = buildSet(result.take(), opcLoc,
00423              UnaryOperator::isPrefix(opcode) && assignmentsHaveResult());
00424   if (result.isInvalid()) return ExprError();
00425   addSemanticExpr(result.take());
00426 
00427   UnaryOperator *syntactic =
00428     new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
00429                                   VK_LValue, OK_Ordinary, opcLoc);
00430   return complete(syntactic);
00431 }
00432 
00433 
00434 //===----------------------------------------------------------------------===//
00435 //  Objective-C @property and implicit property references
00436 //===----------------------------------------------------------------------===//
00437 
00438 /// Look up a method in the receiver type of an Objective-C property
00439 /// reference.
00440 static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
00441                                             const ObjCPropertyRefExpr *PRE) {
00442   if (PRE->isObjectReceiver()) {
00443     const ObjCObjectPointerType *PT =
00444       PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
00445 
00446     // Special case for 'self' in class method implementations.
00447     if (PT->isObjCClassType() &&
00448         S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) {
00449       // This cast is safe because isSelfExpr is only true within
00450       // methods.
00451       ObjCMethodDecl *method =
00452         cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
00453       return S.LookupMethodInObjectType(sel,
00454                  S.Context.getObjCInterfaceType(method->getClassInterface()),
00455                                         /*instance*/ false);
00456     }
00457 
00458     return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
00459   }
00460 
00461   if (PRE->isSuperReceiver()) {
00462     if (const ObjCObjectPointerType *PT =
00463         PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>())
00464       return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
00465 
00466     return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false);
00467   }
00468 
00469   assert(PRE->isClassReceiver() && "Invalid expression");
00470   QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
00471   return S.LookupMethodInObjectType(sel, IT, false);
00472 }
00473 
00474 bool ObjCPropertyOpBuilder::findGetter() {
00475   if (Getter) return true;
00476 
00477   // For implicit properties, just trust the lookup we already did.
00478   if (RefExpr->isImplicitProperty()) {
00479     if ((Getter = RefExpr->getImplicitPropertyGetter())) {
00480       GetterSelector = Getter->getSelector();
00481       return true;
00482     }
00483     else {
00484       // Must build the getter selector the hard way.
00485       ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter();
00486       assert(setter && "both setter and getter are null - cannot happen");
00487       IdentifierInfo *setterName = 
00488         setter->getSelector().getIdentifierInfoForSlot(0);
00489       const char *compStr = setterName->getNameStart();
00490       compStr += 3;
00491       IdentifierInfo *getterName = &S.Context.Idents.get(compStr);
00492       GetterSelector = 
00493         S.PP.getSelectorTable().getNullarySelector(getterName);
00494       return false;
00495 
00496     }
00497   }
00498 
00499   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
00500   Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
00501   return (Getter != 0);
00502 }
00503 
00504 /// Try to find the most accurate setter declaration for the property
00505 /// reference.
00506 ///
00507 /// \return true if a setter was found, in which case Setter 
00508 bool ObjCPropertyOpBuilder::findSetter() {
00509   // For implicit properties, just trust the lookup we already did.
00510   if (RefExpr->isImplicitProperty()) {
00511     if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
00512       Setter = setter;
00513       SetterSelector = setter->getSelector();
00514       return true;
00515     } else {
00516       IdentifierInfo *getterName =
00517         RefExpr->getImplicitPropertyGetter()->getSelector()
00518           .getIdentifierInfoForSlot(0);
00519       SetterSelector =
00520         SelectorTable::constructSetterName(S.PP.getIdentifierTable(),
00521                                            S.PP.getSelectorTable(),
00522                                            getterName);
00523       return false;
00524     }
00525   }
00526 
00527   // For explicit properties, this is more involved.
00528   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
00529   SetterSelector = prop->getSetterName();
00530 
00531   // Do a normal method lookup first.
00532   if (ObjCMethodDecl *setter =
00533         LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
00534     Setter = setter;
00535     return true;
00536   }
00537 
00538   // That can fail in the somewhat crazy situation that we're
00539   // type-checking a message send within the @interface declaration
00540   // that declared the @property.  But it's not clear that that's
00541   // valuable to support.
00542 
00543   return false;
00544 }
00545 
00546 /// Capture the base object of an Objective-C property expression.
00547 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
00548   assert(InstanceReceiver == 0);
00549 
00550   // If we have a base, capture it in an OVE and rebuild the syntactic
00551   // form to use the OVE as its base.
00552   if (RefExpr->isObjectReceiver()) {
00553     InstanceReceiver = capture(RefExpr->getBase());
00554 
00555     syntacticBase =
00556       ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
00557   }
00558 
00559   if (ObjCPropertyRefExpr *
00560         refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
00561     SyntacticRefExpr = refE;
00562 
00563   return syntacticBase;
00564 }
00565 
00566 /// Load from an Objective-C property reference.
00567 ExprResult ObjCPropertyOpBuilder::buildGet() {
00568   findGetter();
00569   assert(Getter);
00570 
00571   if (SyntacticRefExpr)
00572     SyntacticRefExpr->setIsMessagingGetter();
00573 
00574   QualType receiverType;
00575   if (RefExpr->isClassReceiver()) {
00576     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
00577   } else if (RefExpr->isSuperReceiver()) {
00578     receiverType = RefExpr->getSuperReceiverType();
00579   } else {
00580     assert(InstanceReceiver);
00581     receiverType = InstanceReceiver->getType();
00582   }
00583 
00584   // Build a message-send.
00585   ExprResult msg;
00586   if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
00587     assert(InstanceReceiver || RefExpr->isSuperReceiver());
00588     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
00589                                          GenericLoc, Getter->getSelector(),
00590                                          Getter, MultiExprArg());
00591   } else {
00592     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
00593                                       GenericLoc,
00594                                       Getter->getSelector(), Getter,
00595                                       MultiExprArg());
00596   }
00597   return msg;
00598 }
00599 
00600 /// Store to an Objective-C property reference.
00601 ///
00602 /// \param bindSetValueAsResult - If true, capture the actual
00603 ///   value being set as the value of the property operation.
00604 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
00605                                            bool captureSetValueAsResult) {
00606   bool hasSetter = findSetter();
00607   assert(hasSetter); (void) hasSetter;
00608 
00609   if (SyntacticRefExpr)
00610     SyntacticRefExpr->setIsMessagingSetter();
00611 
00612   QualType receiverType;
00613   if (RefExpr->isClassReceiver()) {
00614     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
00615   } else if (RefExpr->isSuperReceiver()) {
00616     receiverType = RefExpr->getSuperReceiverType();
00617   } else {
00618     assert(InstanceReceiver);
00619     receiverType = InstanceReceiver->getType();
00620   }
00621 
00622   // Use assignment constraints when possible; they give us better
00623   // diagnostics.  "When possible" basically means anything except a
00624   // C++ class type.
00625   if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) {
00626     QualType paramType = (*Setter->param_begin())->getType();
00627     if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) {
00628       ExprResult opResult = op;
00629       Sema::AssignConvertType assignResult
00630         = S.CheckSingleAssignmentConstraints(paramType, opResult);
00631       if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
00632                                      op->getType(), opResult.get(),
00633                                      Sema::AA_Assigning))
00634         return ExprError();
00635 
00636       op = opResult.take();
00637       assert(op && "successful assignment left argument invalid?");
00638     }
00639   }
00640 
00641   // Arguments.
00642   Expr *args[] = { op };
00643 
00644   // Build a message-send.
00645   ExprResult msg;
00646   if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
00647     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
00648                                          GenericLoc, SetterSelector, Setter,
00649                                          MultiExprArg(args, 1));
00650   } else {
00651     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
00652                                       GenericLoc,
00653                                       SetterSelector, Setter,
00654                                       MultiExprArg(args, 1));
00655   }
00656 
00657   if (!msg.isInvalid() && captureSetValueAsResult) {
00658     ObjCMessageExpr *msgExpr =
00659       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
00660     Expr *arg = msgExpr->getArg(0);
00661     msgExpr->setArg(0, captureValueAsResult(arg));
00662   }
00663 
00664   return msg;
00665 }
00666 
00667 /// @property-specific behavior for doing lvalue-to-rvalue conversion.
00668 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
00669   // Explicit properties always have getters, but implicit ones don't.
00670   // Check that before proceeding.
00671   if (RefExpr->isImplicitProperty() &&
00672       !RefExpr->getImplicitPropertyGetter()) {
00673     S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
00674       << RefExpr->getBase()->getType();
00675     return ExprError();
00676   }
00677 
00678   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
00679   if (result.isInvalid()) return ExprError();
00680 
00681   if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
00682     S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
00683                                        Getter, RefExpr->getLocation());
00684 
00685   // As a special case, if the method returns 'id', try to get
00686   // a better type from the property.
00687   if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
00688       result.get()->getType()->isObjCIdType()) {
00689     QualType propType = RefExpr->getExplicitProperty()->getType();
00690     if (const ObjCObjectPointerType *ptr
00691           = propType->getAs<ObjCObjectPointerType>()) {
00692       if (!ptr->isObjCIdType())
00693         result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
00694     }
00695   }
00696 
00697   return result;
00698 }
00699 
00700 /// Try to build this as a call to a getter that returns a reference.
00701 ///
00702 /// \return true if it was possible, whether or not it actually
00703 ///   succeeded
00704 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
00705                                                    ExprResult &result) {
00706   if (!S.getLangOpts().CPlusPlus) return false;
00707 
00708   findGetter();
00709   assert(Getter && "property has no setter and no getter!");
00710 
00711   // Only do this if the getter returns an l-value reference type.
00712   QualType resultType = Getter->getResultType();
00713   if (!resultType->isLValueReferenceType()) return false;
00714 
00715   result = buildRValueOperation(op);
00716   return true;
00717 }
00718 
00719 /// @property-specific behavior for doing assignments.
00720 ExprResult
00721 ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
00722                                                 SourceLocation opcLoc,
00723                                                 BinaryOperatorKind opcode,
00724                                                 Expr *LHS, Expr *RHS) {
00725   assert(BinaryOperator::isAssignmentOp(opcode));
00726 
00727   // If there's no setter, we have no choice but to try to assign to
00728   // the result of the getter.
00729   if (!findSetter()) {
00730     ExprResult result;
00731     if (tryBuildGetOfReference(LHS, result)) {
00732       if (result.isInvalid()) return ExprError();
00733       return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
00734     }
00735 
00736     // Otherwise, it's an error.
00737     S.Diag(opcLoc, diag::err_nosetter_property_assignment)
00738       << unsigned(RefExpr->isImplicitProperty())
00739       << SetterSelector
00740       << LHS->getSourceRange() << RHS->getSourceRange();
00741     return ExprError();
00742   }
00743 
00744   // If there is a setter, we definitely want to use it.
00745 
00746   // Verify that we can do a compound assignment.
00747   if (opcode != BO_Assign && !findGetter()) {
00748     S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
00749       << LHS->getSourceRange() << RHS->getSourceRange();
00750     return ExprError();
00751   }
00752 
00753   ExprResult result =
00754     PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
00755   if (result.isInvalid()) return ExprError();
00756 
00757   // Various warnings about property assignments in ARC.
00758   if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
00759     S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
00760     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
00761   }
00762 
00763   return result;
00764 }
00765 
00766 /// @property-specific behavior for doing increments and decrements.
00767 ExprResult
00768 ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
00769                                             UnaryOperatorKind opcode,
00770                                             Expr *op) {
00771   // If there's no setter, we have no choice but to try to assign to
00772   // the result of the getter.
00773   if (!findSetter()) {
00774     ExprResult result;
00775     if (tryBuildGetOfReference(op, result)) {
00776       if (result.isInvalid()) return ExprError();
00777       return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
00778     }
00779 
00780     // Otherwise, it's an error.
00781     S.Diag(opcLoc, diag::err_nosetter_property_incdec)
00782       << unsigned(RefExpr->isImplicitProperty())
00783       << unsigned(UnaryOperator::isDecrementOp(opcode))
00784       << SetterSelector
00785       << op->getSourceRange();
00786     return ExprError();
00787   }
00788 
00789   // If there is a setter, we definitely want to use it.
00790 
00791   // We also need a getter.
00792   if (!findGetter()) {
00793     assert(RefExpr->isImplicitProperty());
00794     S.Diag(opcLoc, diag::err_nogetter_property_incdec)
00795       << unsigned(UnaryOperator::isDecrementOp(opcode))
00796       << GetterSelector
00797       << op->getSourceRange();
00798     return ExprError();
00799   }
00800 
00801   return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
00802 }
00803 
00804 // ObjCSubscript build stuff.
00805 //
00806 
00807 /// objective-c subscripting-specific behavior for doing lvalue-to-rvalue 
00808 /// conversion.
00809 /// FIXME. Remove this routine if it is proven that no additional 
00810 /// specifity is needed.
00811 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
00812   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
00813   if (result.isInvalid()) return ExprError();
00814   return result;
00815 }
00816 
00817 /// objective-c subscripting-specific  behavior for doing assignments.
00818 ExprResult
00819 ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
00820                                                 SourceLocation opcLoc,
00821                                                 BinaryOperatorKind opcode,
00822                                                 Expr *LHS, Expr *RHS) {
00823   assert(BinaryOperator::isAssignmentOp(opcode));
00824   // There must be a method to do the Index'ed assignment.
00825   if (!findAtIndexSetter())
00826     return ExprError();
00827   
00828   // Verify that we can do a compound assignment.
00829   if (opcode != BO_Assign && !findAtIndexGetter())
00830     return ExprError();
00831   
00832   ExprResult result =
00833   PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
00834   if (result.isInvalid()) return ExprError();
00835   
00836   // Various warnings about objc Index'ed assignments in ARC.
00837   if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {
00838     S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
00839     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
00840   }
00841   
00842   return result;
00843 }
00844 
00845 /// Capture the base object of an Objective-C Index'ed expression.
00846 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
00847   assert(InstanceBase == 0);
00848   
00849   // Capture base expression in an OVE and rebuild the syntactic
00850   // form to use the OVE as its base expression.
00851   InstanceBase = capture(RefExpr->getBaseExpr());
00852   InstanceKey = capture(RefExpr->getKeyExpr());
00853     
00854   syntacticBase =
00855     ObjCSubscriptRefRebuilder(S, InstanceBase, 
00856                               InstanceKey).rebuild(syntacticBase);
00857   
00858   return syntacticBase;
00859 }
00860 
00861 /// CheckSubscriptingKind - This routine decide what type 
00862 /// of indexing represented by "FromE" is being done.
00863 Sema::ObjCSubscriptKind 
00864   Sema::CheckSubscriptingKind(Expr *FromE) {
00865   // If the expression already has integral or enumeration type, we're golden.
00866   QualType T = FromE->getType();
00867   if (T->isIntegralOrEnumerationType())
00868     return OS_Array;
00869   
00870   // If we don't have a class type in C++, there's no way we can get an
00871   // expression of integral or enumeration type.
00872   const RecordType *RecordTy = T->getAs<RecordType>();
00873   if (!RecordTy && T->isObjCObjectPointerType())
00874     // All other scalar cases are assumed to be dictionary indexing which
00875     // caller handles, with diagnostics if needed.
00876     return OS_Dictionary;
00877   if (!getLangOpts().CPlusPlus || 
00878       !RecordTy || RecordTy->isIncompleteType()) {
00879     // No indexing can be done. Issue diagnostics and quit.
00880     const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
00881     if (isa<StringLiteral>(IndexExpr))
00882       Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
00883         << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
00884     else
00885       Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
00886         << T;
00887     return OS_Error;
00888   }
00889   
00890   // We must have a complete class type.
00891   if (RequireCompleteType(FromE->getExprLoc(), T, 
00892                           diag::err_objc_index_incomplete_class_type, FromE))
00893     return OS_Error;
00894   
00895   // Look for a conversion to an integral, enumeration type, or
00896   // objective-C pointer type.
00897   UnresolvedSet<4> ViableConversions;
00898   UnresolvedSet<4> ExplicitConversions;
00899   const UnresolvedSetImpl *Conversions
00900     = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
00901   
00902   int NoIntegrals=0, NoObjCIdPointers=0;
00903   SmallVector<CXXConversionDecl *, 4> ConversionDecls;
00904     
00905   for (UnresolvedSetImpl::iterator I = Conversions->begin(),
00906        E = Conversions->end();
00907        I != E;
00908        ++I) {
00909     if (CXXConversionDecl *Conversion
00910         = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
00911       QualType CT = Conversion->getConversionType().getNonReferenceType();
00912       if (CT->isIntegralOrEnumerationType()) {
00913         ++NoIntegrals;
00914         ConversionDecls.push_back(Conversion);
00915       }
00916       else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
00917         ++NoObjCIdPointers;
00918         ConversionDecls.push_back(Conversion);
00919       }
00920     }
00921   }
00922   if (NoIntegrals ==1 && NoObjCIdPointers == 0)
00923     return OS_Array;
00924   if (NoIntegrals == 0 && NoObjCIdPointers == 1)
00925     return OS_Dictionary;
00926   if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
00927     // No conversion function was found. Issue diagnostic and return.
00928     Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
00929       << FromE->getType();
00930     return OS_Error;
00931   }
00932   Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
00933       << FromE->getType();
00934   for (unsigned int i = 0; i < ConversionDecls.size(); i++)
00935     Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
00936     
00937   return OS_Error;
00938 }
00939 
00940 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
00941   if (AtIndexGetter)
00942     return true;
00943   
00944   Expr *BaseExpr = RefExpr->getBaseExpr();
00945   QualType BaseT = BaseExpr->getType();
00946   
00947   QualType ResultType;
00948   if (const ObjCObjectPointerType *PTy =
00949       BaseT->getAs<ObjCObjectPointerType>()) {
00950     ResultType = PTy->getPointeeType();
00951     if (const ObjCObjectType *iQFaceTy = 
00952         ResultType->getAsObjCQualifiedInterfaceType())
00953       ResultType = iQFaceTy->getBaseType();
00954   }
00955   Sema::ObjCSubscriptKind Res = 
00956     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
00957   if (Res == Sema::OS_Error)
00958     return false;
00959   bool arrayRef = (Res == Sema::OS_Array);
00960   
00961   if (ResultType.isNull()) {
00962     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
00963       << BaseExpr->getType() << arrayRef;
00964     return false;
00965   }
00966   if (!arrayRef) {
00967     // dictionary subscripting.
00968     // - (id)objectForKeyedSubscript:(id)key;
00969     IdentifierInfo *KeyIdents[] = {
00970       &S.Context.Idents.get("objectForKeyedSubscript")  
00971     };
00972     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
00973   }
00974   else {
00975     // - (id)objectAtIndexedSubscript:(size_t)index;
00976     IdentifierInfo *KeyIdents[] = {
00977       &S.Context.Idents.get("objectAtIndexedSubscript")  
00978     };
00979   
00980     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
00981   }
00982   
00983   AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType, 
00984                                              true /*instance*/);
00985   bool receiverIdType = (BaseT->isObjCIdType() ||
00986                          BaseT->isObjCQualifiedIdType());
00987   
00988   if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {
00989     AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(), 
00990                            SourceLocation(), AtIndexGetterSelector,
00991                            S.Context.getObjCIdType() /*ReturnType*/,
00992                            0 /*TypeSourceInfo */,
00993                            S.Context.getTranslationUnitDecl(),
00994                            true /*Instance*/, false/*isVariadic*/,
00995                            /*isSynthesized=*/false,
00996                            /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
00997                            ObjCMethodDecl::Required,
00998                            false);
00999     ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
01000                                                 SourceLocation(), SourceLocation(),
01001                                                 arrayRef ? &S.Context.Idents.get("index")
01002                                                          : &S.Context.Idents.get("key"),
01003                                                 arrayRef ? S.Context.UnsignedLongTy
01004                                                          : S.Context.getObjCIdType(),
01005                                                 /*TInfo=*/0,
01006                                                 SC_None,
01007                                                 SC_None,
01008                                                 0);
01009     AtIndexGetter->setMethodParams(S.Context, Argument, 
01010                                    ArrayRef<SourceLocation>());
01011   }
01012 
01013   if (!AtIndexGetter) {
01014     if (!receiverIdType) {
01015       S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
01016       << BaseExpr->getType() << 0 << arrayRef;
01017       return false;
01018     }
01019     AtIndexGetter = 
01020       S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, 
01021                                          RefExpr->getSourceRange(), 
01022                                          true, false);
01023   }
01024   
01025   if (AtIndexGetter) {
01026     QualType T = AtIndexGetter->param_begin()[0]->getType();
01027     if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
01028         (!arrayRef && !T->isObjCObjectPointerType())) {
01029       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
01030              arrayRef ? diag::err_objc_subscript_index_type
01031                       : diag::err_objc_subscript_key_type) << T;
01032       S.Diag(AtIndexGetter->param_begin()[0]->getLocation(), 
01033              diag::note_parameter_type) << T;
01034       return false;
01035     }
01036     QualType R = AtIndexGetter->getResultType();
01037     if (!R->isObjCObjectPointerType()) {
01038       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
01039              diag::err_objc_indexing_method_result_type) << R << arrayRef;
01040       S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
01041         AtIndexGetter->getDeclName();
01042     }
01043   }
01044   return true;
01045 }
01046 
01047 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
01048   if (AtIndexSetter)
01049     return true;
01050   
01051   Expr *BaseExpr = RefExpr->getBaseExpr();
01052   QualType BaseT = BaseExpr->getType();
01053   
01054   QualType ResultType;
01055   if (const ObjCObjectPointerType *PTy =
01056       BaseT->getAs<ObjCObjectPointerType>()) {
01057     ResultType = PTy->getPointeeType();
01058     if (const ObjCObjectType *iQFaceTy = 
01059         ResultType->getAsObjCQualifiedInterfaceType())
01060       ResultType = iQFaceTy->getBaseType();
01061   }
01062   
01063   Sema::ObjCSubscriptKind Res = 
01064     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
01065   if (Res == Sema::OS_Error)
01066     return false;
01067   bool arrayRef = (Res == Sema::OS_Array);
01068   
01069   if (ResultType.isNull()) {
01070     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
01071       << BaseExpr->getType() << arrayRef;
01072     return false;
01073   }
01074   
01075   if (!arrayRef) {
01076     // dictionary subscripting.
01077     // - (void)setObject:(id)object forKeyedSubscript:(id)key;
01078     IdentifierInfo *KeyIdents[] = {
01079       &S.Context.Idents.get("setObject"),
01080       &S.Context.Idents.get("forKeyedSubscript")
01081     };
01082     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
01083   }
01084   else {
01085     // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
01086     IdentifierInfo *KeyIdents[] = {
01087       &S.Context.Idents.get("setObject"),
01088       &S.Context.Idents.get("atIndexedSubscript")
01089     };
01090     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
01091   }
01092   AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType, 
01093                                              true /*instance*/);
01094   
01095   bool receiverIdType = (BaseT->isObjCIdType() ||
01096                          BaseT->isObjCQualifiedIdType());
01097 
01098   if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
01099     TypeSourceInfo *ResultTInfo = 0;
01100     QualType ReturnType = S.Context.VoidTy;
01101     AtIndexSetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
01102                            SourceLocation(), AtIndexSetterSelector,
01103                            ReturnType,
01104                            ResultTInfo,
01105                            S.Context.getTranslationUnitDecl(),
01106                            true /*Instance*/, false/*isVariadic*/,
01107                            /*isSynthesized=*/false,
01108                            /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
01109                            ObjCMethodDecl::Required,
01110                            false); 
01111     SmallVector<ParmVarDecl *, 2> Params;
01112     ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
01113                                                 SourceLocation(), SourceLocation(),
01114                                                 &S.Context.Idents.get("object"),
01115                                                 S.Context.getObjCIdType(),
01116                                                 /*TInfo=*/0,
01117                                                 SC_None,
01118                                                 SC_None,
01119                                                 0);
01120     Params.push_back(object);
01121     ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
01122                                                 SourceLocation(), SourceLocation(),
01123                                                 arrayRef ?  &S.Context.Idents.get("index")
01124                                                          :  &S.Context.Idents.get("key"),
01125                                                 arrayRef ? S.Context.UnsignedLongTy
01126                                                          : S.Context.getObjCIdType(),
01127                                                 /*TInfo=*/0,
01128                                                 SC_None,
01129                                                 SC_None,
01130                                                 0);
01131     Params.push_back(key);
01132     AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
01133   }
01134   
01135   if (!AtIndexSetter) {
01136     if (!receiverIdType) {
01137       S.Diag(BaseExpr->getExprLoc(), 
01138              diag::err_objc_subscript_method_not_found)
01139       << BaseExpr->getType() << 1 << arrayRef;
01140       return false;
01141     }
01142     AtIndexSetter = 
01143       S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, 
01144                                          RefExpr->getSourceRange(), 
01145                                          true, false);
01146   }
01147   
01148   bool err = false;
01149   if (AtIndexSetter && arrayRef) {
01150     QualType T = AtIndexSetter->param_begin()[1]->getType();
01151     if (!T->isIntegralOrEnumerationType()) {
01152       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
01153              diag::err_objc_subscript_index_type) << T;
01154       S.Diag(AtIndexSetter->param_begin()[1]->getLocation(), 
01155              diag::note_parameter_type) << T;
01156       err = true;
01157     }
01158     T = AtIndexSetter->param_begin()[0]->getType();
01159     if (!T->isObjCObjectPointerType()) {
01160       S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 
01161              diag::err_objc_subscript_object_type) << T << arrayRef;
01162       S.Diag(AtIndexSetter->param_begin()[0]->getLocation(), 
01163              diag::note_parameter_type) << T;
01164       err = true;
01165     }
01166   }
01167   else if (AtIndexSetter && !arrayRef)
01168     for (unsigned i=0; i <2; i++) {
01169       QualType T = AtIndexSetter->param_begin()[i]->getType();
01170       if (!T->isObjCObjectPointerType()) {
01171         if (i == 1)
01172           S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
01173                  diag::err_objc_subscript_key_type) << T;
01174         else
01175           S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
01176                  diag::err_objc_subscript_dic_object_type) << T;
01177         S.Diag(AtIndexSetter->param_begin()[i]->getLocation(), 
01178                diag::note_parameter_type) << T;
01179         err = true;
01180       }
01181     }
01182 
01183   return !err;
01184 }
01185 
01186 // Get the object at "Index" position in the container.
01187 // [BaseExpr objectAtIndexedSubscript : IndexExpr];
01188 ExprResult ObjCSubscriptOpBuilder::buildGet() {
01189   if (!findAtIndexGetter())
01190     return ExprError();
01191   
01192   QualType receiverType = InstanceBase->getType();
01193     
01194   // Build a message-send.
01195   ExprResult msg;
01196   Expr *Index = InstanceKey;
01197   
01198   // Arguments.
01199   Expr *args[] = { Index };
01200   assert(InstanceBase);
01201   msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
01202                                        GenericLoc,
01203                                        AtIndexGetterSelector, AtIndexGetter,
01204                                        MultiExprArg(args, 1));
01205   return msg;
01206 }
01207 
01208 /// Store into the container the "op" object at "Index"'ed location
01209 /// by building this messaging expression:
01210 /// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
01211 /// \param bindSetValueAsResult - If true, capture the actual
01212 ///   value being set as the value of the property operation.
01213 ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
01214                                            bool captureSetValueAsResult) {
01215   if (!findAtIndexSetter())
01216     return ExprError();
01217   
01218   QualType receiverType = InstanceBase->getType();
01219   Expr *Index = InstanceKey;
01220   
01221   // Arguments.
01222   Expr *args[] = { op, Index };
01223   
01224   // Build a message-send.
01225   ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
01226                                                   GenericLoc,
01227                                                   AtIndexSetterSelector,
01228                                                   AtIndexSetter,
01229                                                   MultiExprArg(args, 2));
01230   
01231   if (!msg.isInvalid() && captureSetValueAsResult) {
01232     ObjCMessageExpr *msgExpr =
01233       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
01234     Expr *arg = msgExpr->getArg(0);
01235     msgExpr->setArg(0, captureValueAsResult(arg));
01236   }
01237   
01238   return msg;
01239 }
01240 
01241 //===----------------------------------------------------------------------===//
01242 //  General Sema routines.
01243 //===----------------------------------------------------------------------===//
01244 
01245 ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
01246   Expr *opaqueRef = E->IgnoreParens();
01247   if (ObjCPropertyRefExpr *refExpr
01248         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01249     ObjCPropertyOpBuilder builder(*this, refExpr);
01250     return builder.buildRValueOperation(E);
01251   }
01252   else if (ObjCSubscriptRefExpr *refExpr
01253            = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
01254     ObjCSubscriptOpBuilder builder(*this, refExpr);
01255     return builder.buildRValueOperation(E);
01256   } else {
01257     llvm_unreachable("unknown pseudo-object kind!");
01258   }
01259 }
01260 
01261 /// Check an increment or decrement of a pseudo-object expression.
01262 ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
01263                                          UnaryOperatorKind opcode, Expr *op) {
01264   // Do nothing if the operand is dependent.
01265   if (op->isTypeDependent())
01266     return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
01267                                        VK_RValue, OK_Ordinary, opcLoc);
01268 
01269   assert(UnaryOperator::isIncrementDecrementOp(opcode));
01270   Expr *opaqueRef = op->IgnoreParens();
01271   if (ObjCPropertyRefExpr *refExpr
01272         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01273     ObjCPropertyOpBuilder builder(*this, refExpr);
01274     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
01275   } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
01276     Diag(opcLoc, diag::err_illegal_container_subscripting_op);
01277     return ExprError();
01278   } else {
01279     llvm_unreachable("unknown pseudo-object kind!");
01280   }
01281 }
01282 
01283 ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
01284                                              BinaryOperatorKind opcode,
01285                                              Expr *LHS, Expr *RHS) {
01286   // Do nothing if either argument is dependent.
01287   if (LHS->isTypeDependent() || RHS->isTypeDependent())
01288     return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
01289                                         VK_RValue, OK_Ordinary, opcLoc);
01290 
01291   // Filter out non-overload placeholder types in the RHS.
01292   if (RHS->getType()->isNonOverloadPlaceholderType()) {
01293     ExprResult result = CheckPlaceholderExpr(RHS);
01294     if (result.isInvalid()) return ExprError();
01295     RHS = result.take();
01296   }
01297 
01298   Expr *opaqueRef = LHS->IgnoreParens();
01299   if (ObjCPropertyRefExpr *refExpr
01300         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01301     ObjCPropertyOpBuilder builder(*this, refExpr);
01302     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
01303   } else if (ObjCSubscriptRefExpr *refExpr
01304              = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
01305     ObjCSubscriptOpBuilder builder(*this, refExpr);
01306     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
01307   } else {
01308     llvm_unreachable("unknown pseudo-object kind!");
01309   }
01310 }
01311 
01312 /// Given a pseudo-object reference, rebuild it without the opaque
01313 /// values.  Basically, undo the behavior of rebuildAndCaptureObject.
01314 /// This should never operate in-place.
01315 static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
01316   Expr *opaqueRef = E->IgnoreParens();
01317   if (ObjCPropertyRefExpr *refExpr
01318         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01319     // Class and super property references don't have opaque values in them.
01320     if (refExpr->isClassReceiver() || refExpr->isSuperReceiver())
01321       return E;
01322     
01323     assert(refExpr->isObjectReceiver() && "Unknown receiver kind?");
01324     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
01325     return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
01326   } else if (ObjCSubscriptRefExpr *refExpr
01327                = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
01328     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
01329     OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
01330     return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(), 
01331                                      keyOVE->getSourceExpr()).rebuild(E);
01332   } else {
01333     llvm_unreachable("unknown pseudo-object kind!");
01334   }
01335 }
01336 
01337 /// Given a pseudo-object expression, recreate what it looks like
01338 /// syntactically without the attendant OpaqueValueExprs.
01339 ///
01340 /// This is a hack which should be removed when TreeTransform is
01341 /// capable of rebuilding a tree without stripping implicit
01342 /// operations.
01343 Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
01344   Expr *syntax = E->getSyntacticForm();
01345   if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
01346     Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
01347     return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
01348                                        uop->getValueKind(), uop->getObjectKind(),
01349                                        uop->getOperatorLoc());
01350   } else if (CompoundAssignOperator *cop
01351                = dyn_cast<CompoundAssignOperator>(syntax)) {
01352     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
01353     Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
01354     return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
01355                                                 cop->getType(),
01356                                                 cop->getValueKind(),
01357                                                 cop->getObjectKind(),
01358                                                 cop->getComputationLHSType(),
01359                                                 cop->getComputationResultType(),
01360                                                 cop->getOperatorLoc());
01361   } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
01362     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
01363     Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
01364     return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
01365                                         bop->getType(), bop->getValueKind(),
01366                                         bop->getObjectKind(),
01367                                         bop->getOperatorLoc());
01368   } else {
01369     assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
01370     return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
01371   }
01372 }