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/AST/ExprCXX.h"
00035 #include "clang/AST/ExprObjC.h"
00036 #include "clang/Basic/CharInfo.h"
00037 #include "clang/Lex/Preprocessor.h"
00038 #include "clang/Sema/Initialization.h"
00039 #include "clang/Sema/ScopeInfo.h"
00040 #include "llvm/ADT/SmallString.h"
00041 
00042 using namespace clang;
00043 using namespace sema;
00044 
00045 namespace {
00046   // Basically just a very focused copy of TreeTransform.
00047   template <class T> struct Rebuilder {
00048     Sema &S;
00049     Rebuilder(Sema &S) : S(S) {}
00050 
00051     T &getDerived() { return static_cast<T&>(*this); }
00052 
00053     Expr *rebuild(Expr *e) {
00054       // Fast path: nothing to look through.
00055       if (typename T::specific_type *specific
00056             = dyn_cast<typename T::specific_type>(e))
00057         return getDerived().rebuildSpecific(specific);
00058 
00059       // Otherwise, we should look through and rebuild anything that
00060       // IgnoreParens would.
00061 
00062       if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
00063         e = rebuild(parens->getSubExpr());
00064         return new (S.Context) ParenExpr(parens->getLParen(),
00065                                          parens->getRParen(),
00066                                          e);
00067       }
00068 
00069       if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
00070         assert(uop->getOpcode() == UO_Extension);
00071         e = rebuild(uop->getSubExpr());
00072         return new (S.Context) UnaryOperator(e, uop->getOpcode(),
00073                                              uop->getType(),
00074                                              uop->getValueKind(),
00075                                              uop->getObjectKind(),
00076                                              uop->getOperatorLoc());
00077       }
00078 
00079       if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
00080         assert(!gse->isResultDependent());
00081         unsigned resultIndex = gse->getResultIndex();
00082         unsigned numAssocs = gse->getNumAssocs();
00083 
00084         SmallVector<Expr*, 8> assocs(numAssocs);
00085         SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
00086 
00087         for (unsigned i = 0; i != numAssocs; ++i) {
00088           Expr *assoc = gse->getAssocExpr(i);
00089           if (i == resultIndex) assoc = rebuild(assoc);
00090           assocs[i] = assoc;
00091           assocTypes[i] = gse->getAssocTypeSourceInfo(i);
00092         }
00093 
00094         return new (S.Context) GenericSelectionExpr(S.Context,
00095                                                     gse->getGenericLoc(),
00096                                                     gse->getControllingExpr(),
00097                                                     assocTypes,
00098                                                     assocs,
00099                                                     gse->getDefaultLoc(),
00100                                                     gse->getRParenLoc(),
00101                                       gse->containsUnexpandedParameterPack(),
00102                                                     resultIndex);
00103       }
00104 
00105       if (ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
00106         assert(!ce->isConditionDependent());
00107 
00108         Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
00109         Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS;
00110         rebuiltExpr = rebuild(rebuiltExpr);
00111 
00112         return new (S.Context) ChooseExpr(ce->getBuiltinLoc(),
00113                                           ce->getCond(),
00114                                           LHS, RHS,
00115                                           rebuiltExpr->getType(),
00116                                           rebuiltExpr->getValueKind(),
00117                                           rebuiltExpr->getObjectKind(),
00118                                           ce->getRParenLoc(),
00119                                           ce->isConditionTrue(),
00120                                           rebuiltExpr->isTypeDependent(),
00121                                           rebuiltExpr->isValueDependent());
00122       }
00123 
00124       llvm_unreachable("bad expression to rebuild!");
00125     }
00126   };
00127 
00128   struct ObjCPropertyRefRebuilder : Rebuilder<ObjCPropertyRefRebuilder> {
00129     Expr *NewBase;
00130     ObjCPropertyRefRebuilder(Sema &S, Expr *newBase)
00131       : Rebuilder<ObjCPropertyRefRebuilder>(S), NewBase(newBase) {}
00132 
00133     typedef ObjCPropertyRefExpr specific_type;
00134     Expr *rebuildSpecific(ObjCPropertyRefExpr *refExpr) {
00135       // Fortunately, the constraint that we're rebuilding something
00136       // with a base limits the number of cases here.
00137       assert(refExpr->isObjectReceiver());
00138 
00139       if (refExpr->isExplicitProperty()) {
00140         return new (S.Context)
00141           ObjCPropertyRefExpr(refExpr->getExplicitProperty(),
00142                               refExpr->getType(), refExpr->getValueKind(),
00143                               refExpr->getObjectKind(), refExpr->getLocation(),
00144                               NewBase);
00145       }
00146       return new (S.Context)
00147         ObjCPropertyRefExpr(refExpr->getImplicitPropertyGetter(),
00148                             refExpr->getImplicitPropertySetter(),
00149                             refExpr->getType(), refExpr->getValueKind(),
00150                             refExpr->getObjectKind(),refExpr->getLocation(),
00151                             NewBase);
00152     }
00153   };
00154 
00155   struct ObjCSubscriptRefRebuilder : Rebuilder<ObjCSubscriptRefRebuilder> {
00156     Expr *NewBase;
00157     Expr *NewKeyExpr;
00158     ObjCSubscriptRefRebuilder(Sema &S, Expr *newBase, Expr *newKeyExpr)
00159     : Rebuilder<ObjCSubscriptRefRebuilder>(S), 
00160       NewBase(newBase), NewKeyExpr(newKeyExpr) {}
00161     
00162     typedef ObjCSubscriptRefExpr specific_type;
00163     Expr *rebuildSpecific(ObjCSubscriptRefExpr *refExpr) {
00164       assert(refExpr->getBaseExpr());
00165       assert(refExpr->getKeyExpr());
00166       
00167       return new (S.Context)
00168         ObjCSubscriptRefExpr(NewBase,
00169                              NewKeyExpr,
00170                              refExpr->getType(), refExpr->getValueKind(),
00171                              refExpr->getObjectKind(),refExpr->getAtIndexMethodDecl(),
00172                              refExpr->setAtIndexMethodDecl(),
00173                              refExpr->getRBracket());
00174     }
00175   };
00176 
00177   struct MSPropertyRefRebuilder : Rebuilder<MSPropertyRefRebuilder> {
00178     Expr *NewBase;
00179     MSPropertyRefRebuilder(Sema &S, Expr *newBase)
00180     : Rebuilder<MSPropertyRefRebuilder>(S), NewBase(newBase) {}
00181 
00182     typedef MSPropertyRefExpr specific_type;
00183     Expr *rebuildSpecific(MSPropertyRefExpr *refExpr) {
00184       assert(refExpr->getBaseExpr());
00185 
00186       return new (S.Context)
00187         MSPropertyRefExpr(NewBase, refExpr->getPropertyDecl(),
00188                        refExpr->isArrow(), refExpr->getType(),
00189                        refExpr->getValueKind(), refExpr->getQualifierLoc(),
00190                        refExpr->getMemberLoc());
00191     }
00192   };
00193   
00194   class PseudoOpBuilder {
00195   public:
00196     Sema &S;
00197     unsigned ResultIndex;
00198     SourceLocation GenericLoc;
00199     SmallVector<Expr *, 4> Semantics;
00200 
00201     PseudoOpBuilder(Sema &S, SourceLocation genericLoc)
00202       : S(S), ResultIndex(PseudoObjectExpr::NoResult),
00203         GenericLoc(genericLoc) {}
00204 
00205     virtual ~PseudoOpBuilder() {}
00206 
00207     /// Add a normal semantic expression.
00208     void addSemanticExpr(Expr *semantic) {
00209       Semantics.push_back(semantic);
00210     }
00211 
00212     /// Add the 'result' semantic expression.
00213     void addResultSemanticExpr(Expr *resultExpr) {
00214       assert(ResultIndex == PseudoObjectExpr::NoResult);
00215       ResultIndex = Semantics.size();
00216       Semantics.push_back(resultExpr);
00217     }
00218 
00219     ExprResult buildRValueOperation(Expr *op);
00220     ExprResult buildAssignmentOperation(Scope *Sc,
00221                                         SourceLocation opLoc,
00222                                         BinaryOperatorKind opcode,
00223                                         Expr *LHS, Expr *RHS);
00224     ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
00225                                     UnaryOperatorKind opcode,
00226                                     Expr *op);
00227 
00228     virtual ExprResult complete(Expr *syntacticForm);
00229 
00230     OpaqueValueExpr *capture(Expr *op);
00231     OpaqueValueExpr *captureValueAsResult(Expr *op);
00232 
00233     void setResultToLastSemantic() {
00234       assert(ResultIndex == PseudoObjectExpr::NoResult);
00235       ResultIndex = Semantics.size() - 1;
00236     }
00237 
00238     /// Return true if assignments have a non-void result.
00239     bool CanCaptureValue(Expr *exp) {
00240       if (exp->isGLValue())
00241         return true;
00242       QualType ty = exp->getType();
00243       assert(!ty->isIncompleteType());
00244       assert(!ty->isDependentType());
00245 
00246       if (const CXXRecordDecl *ClassDecl = ty->getAsCXXRecordDecl())
00247         return ClassDecl->isTriviallyCopyable();
00248       return true;
00249     }
00250 
00251     virtual Expr *rebuildAndCaptureObject(Expr *) = 0;
00252     virtual ExprResult buildGet() = 0;
00253     virtual ExprResult buildSet(Expr *, SourceLocation,
00254                                 bool captureSetValueAsResult) = 0;
00255   };
00256 
00257   /// A PseudoOpBuilder for Objective-C \@properties.
00258   class ObjCPropertyOpBuilder : public PseudoOpBuilder {
00259     ObjCPropertyRefExpr *RefExpr;
00260     ObjCPropertyRefExpr *SyntacticRefExpr;
00261     OpaqueValueExpr *InstanceReceiver;
00262     ObjCMethodDecl *Getter;
00263 
00264     ObjCMethodDecl *Setter;
00265     Selector SetterSelector;
00266     Selector GetterSelector;
00267 
00268   public:
00269     ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
00270       PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
00271       SyntacticRefExpr(nullptr), InstanceReceiver(nullptr), Getter(nullptr),
00272       Setter(nullptr) {
00273     }
00274 
00275     ExprResult buildRValueOperation(Expr *op);
00276     ExprResult buildAssignmentOperation(Scope *Sc,
00277                                         SourceLocation opLoc,
00278                                         BinaryOperatorKind opcode,
00279                                         Expr *LHS, Expr *RHS);
00280     ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
00281                                     UnaryOperatorKind opcode,
00282                                     Expr *op);
00283 
00284     bool tryBuildGetOfReference(Expr *op, ExprResult &result);
00285     bool findSetter(bool warn=true);
00286     bool findGetter();
00287     void DiagnoseUnsupportedPropertyUse();
00288 
00289     Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
00290     ExprResult buildGet() override;
00291     ExprResult buildSet(Expr *op, SourceLocation, bool) override;
00292     ExprResult complete(Expr *SyntacticForm) override;
00293 
00294     bool isWeakProperty() const;
00295   };
00296 
00297  /// A PseudoOpBuilder for Objective-C array/dictionary indexing.
00298  class ObjCSubscriptOpBuilder : public PseudoOpBuilder {
00299    ObjCSubscriptRefExpr *RefExpr;
00300    OpaqueValueExpr *InstanceBase;
00301    OpaqueValueExpr *InstanceKey;
00302    ObjCMethodDecl *AtIndexGetter;
00303    Selector AtIndexGetterSelector;
00304   
00305    ObjCMethodDecl *AtIndexSetter;
00306    Selector AtIndexSetterSelector;
00307   
00308  public:
00309     ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) :
00310       PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), 
00311       RefExpr(refExpr),
00312       InstanceBase(nullptr), InstanceKey(nullptr),
00313       AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
00314 
00315    ExprResult buildRValueOperation(Expr *op);
00316    ExprResult buildAssignmentOperation(Scope *Sc,
00317                                        SourceLocation opLoc,
00318                                        BinaryOperatorKind opcode,
00319                                        Expr *LHS, Expr *RHS);
00320    Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
00321 
00322    bool findAtIndexGetter();
00323    bool findAtIndexSetter();
00324 
00325    ExprResult buildGet() override;
00326    ExprResult buildSet(Expr *op, SourceLocation, bool) override;
00327  };
00328 
00329  class MSPropertyOpBuilder : public PseudoOpBuilder {
00330    MSPropertyRefExpr *RefExpr;
00331 
00332  public:
00333    MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
00334      PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
00335      RefExpr(refExpr) {}
00336 
00337    Expr *rebuildAndCaptureObject(Expr *) override;
00338    ExprResult buildGet() override;
00339    ExprResult buildSet(Expr *op, SourceLocation, bool) override;
00340  };
00341 }
00342 
00343 /// Capture the given expression in an OpaqueValueExpr.
00344 OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
00345   // Make a new OVE whose source is the given expression.
00346   OpaqueValueExpr *captured = 
00347     new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
00348                                     e->getValueKind(), e->getObjectKind(),
00349                                     e);
00350   
00351   // Make sure we bind that in the semantics.
00352   addSemanticExpr(captured);
00353   return captured;
00354 }
00355 
00356 /// Capture the given expression as the result of this pseudo-object
00357 /// operation.  This routine is safe against expressions which may
00358 /// already be captured.
00359 ///
00360 /// \returns the captured expression, which will be the
00361 ///   same as the input if the input was already captured
00362 OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
00363   assert(ResultIndex == PseudoObjectExpr::NoResult);
00364 
00365   // If the expression hasn't already been captured, just capture it
00366   // and set the new semantic 
00367   if (!isa<OpaqueValueExpr>(e)) {
00368     OpaqueValueExpr *cap = capture(e);
00369     setResultToLastSemantic();
00370     return cap;
00371   }
00372 
00373   // Otherwise, it must already be one of our semantic expressions;
00374   // set ResultIndex to its index.
00375   unsigned index = 0;
00376   for (;; ++index) {
00377     assert(index < Semantics.size() &&
00378            "captured expression not found in semantics!");
00379     if (e == Semantics[index]) break;
00380   }
00381   ResultIndex = index;
00382   return cast<OpaqueValueExpr>(e);
00383 }
00384 
00385 /// The routine which creates the final PseudoObjectExpr.
00386 ExprResult PseudoOpBuilder::complete(Expr *syntactic) {
00387   return PseudoObjectExpr::Create(S.Context, syntactic,
00388                                   Semantics, ResultIndex);
00389 }
00390 
00391 /// The main skeleton for building an r-value operation.
00392 ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {
00393   Expr *syntacticBase = rebuildAndCaptureObject(op);
00394 
00395   ExprResult getExpr = buildGet();
00396   if (getExpr.isInvalid()) return ExprError();
00397   addResultSemanticExpr(getExpr.get());
00398 
00399   return complete(syntacticBase);
00400 }
00401 
00402 /// The basic skeleton for building a simple or compound
00403 /// assignment operation.
00404 ExprResult
00405 PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
00406                                           BinaryOperatorKind opcode,
00407                                           Expr *LHS, Expr *RHS) {
00408   assert(BinaryOperator::isAssignmentOp(opcode));
00409   
00410   // Recover from user error
00411   if (isa<UnresolvedLookupExpr>(RHS))
00412     return ExprError();
00413 
00414   Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
00415   OpaqueValueExpr *capturedRHS = capture(RHS);
00416 
00417   Expr *syntactic;
00418 
00419   ExprResult result;
00420   if (opcode == BO_Assign) {
00421     result = capturedRHS;
00422     syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
00423                                                opcode, capturedRHS->getType(),
00424                                                capturedRHS->getValueKind(),
00425                                                OK_Ordinary, opcLoc, false);
00426   } else {
00427     ExprResult opLHS = buildGet();
00428     if (opLHS.isInvalid()) return ExprError();
00429 
00430     // Build an ordinary, non-compound operation.
00431     BinaryOperatorKind nonCompound =
00432       BinaryOperator::getOpForCompoundAssignment(opcode);
00433     result = S.BuildBinOp(Sc, opcLoc, nonCompound,
00434                           opLHS.get(), capturedRHS);
00435     if (result.isInvalid()) return ExprError();
00436 
00437     syntactic =
00438       new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
00439                                              result.get()->getType(),
00440                                              result.get()->getValueKind(),
00441                                              OK_Ordinary,
00442                                              opLHS.get()->getType(),
00443                                              result.get()->getType(),
00444                                              opcLoc, false);
00445   }
00446 
00447   // The result of the assignment, if not void, is the value set into
00448   // the l-value.
00449   result = buildSet(result.get(), opcLoc, /*captureSetValueAsResult*/ true);
00450   if (result.isInvalid()) return ExprError();
00451   addSemanticExpr(result.get());
00452 
00453   return complete(syntactic);
00454 }
00455 
00456 /// The basic skeleton for building an increment or decrement
00457 /// operation.
00458 ExprResult
00459 PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
00460                                       UnaryOperatorKind opcode,
00461                                       Expr *op) {
00462   assert(UnaryOperator::isIncrementDecrementOp(opcode));
00463 
00464   Expr *syntacticOp = rebuildAndCaptureObject(op);
00465 
00466   // Load the value.
00467   ExprResult result = buildGet();
00468   if (result.isInvalid()) return ExprError();
00469 
00470   QualType resultType = result.get()->getType();
00471 
00472   // That's the postfix result.
00473   if (UnaryOperator::isPostfix(opcode) &&
00474       (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) {
00475     result = capture(result.get());
00476     setResultToLastSemantic();
00477   }
00478 
00479   // Add or subtract a literal 1.
00480   llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
00481   Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
00482                                      GenericLoc);
00483 
00484   if (UnaryOperator::isIncrementOp(opcode)) {
00485     result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);
00486   } else {
00487     result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);
00488   }
00489   if (result.isInvalid()) return ExprError();
00490 
00491   // Store that back into the result.  The value stored is the result
00492   // of a prefix operation.
00493   result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode));
00494   if (result.isInvalid()) return ExprError();
00495   addSemanticExpr(result.get());
00496 
00497   UnaryOperator *syntactic =
00498     new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
00499                                   VK_LValue, OK_Ordinary, opcLoc);
00500   return complete(syntactic);
00501 }
00502 
00503 
00504 //===----------------------------------------------------------------------===//
00505 //  Objective-C @property and implicit property references
00506 //===----------------------------------------------------------------------===//
00507 
00508 /// Look up a method in the receiver type of an Objective-C property
00509 /// reference.
00510 static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
00511                                             const ObjCPropertyRefExpr *PRE) {
00512   if (PRE->isObjectReceiver()) {
00513     const ObjCObjectPointerType *PT =
00514       PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
00515 
00516     // Special case for 'self' in class method implementations.
00517     if (PT->isObjCClassType() &&
00518         S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) {
00519       // This cast is safe because isSelfExpr is only true within
00520       // methods.
00521       ObjCMethodDecl *method =
00522         cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
00523       return S.LookupMethodInObjectType(sel,
00524                  S.Context.getObjCInterfaceType(method->getClassInterface()),
00525                                         /*instance*/ false);
00526     }
00527 
00528     return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
00529   }
00530 
00531   if (PRE->isSuperReceiver()) {
00532     if (const ObjCObjectPointerType *PT =
00533         PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>())
00534       return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
00535 
00536     return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false);
00537   }
00538 
00539   assert(PRE->isClassReceiver() && "Invalid expression");
00540   QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
00541   return S.LookupMethodInObjectType(sel, IT, false);
00542 }
00543 
00544 bool ObjCPropertyOpBuilder::isWeakProperty() const {
00545   QualType T;
00546   if (RefExpr->isExplicitProperty()) {
00547     const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
00548     if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
00549       return !Prop->hasAttr<IBOutletAttr>();
00550 
00551     T = Prop->getType();
00552   } else if (Getter) {
00553     T = Getter->getReturnType();
00554   } else {
00555     return false;
00556   }
00557 
00558   return T.getObjCLifetime() == Qualifiers::OCL_Weak;
00559 }
00560 
00561 bool ObjCPropertyOpBuilder::findGetter() {
00562   if (Getter) return true;
00563 
00564   // For implicit properties, just trust the lookup we already did.
00565   if (RefExpr->isImplicitProperty()) {
00566     if ((Getter = RefExpr->getImplicitPropertyGetter())) {
00567       GetterSelector = Getter->getSelector();
00568       return true;
00569     }
00570     else {
00571       // Must build the getter selector the hard way.
00572       ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter();
00573       assert(setter && "both setter and getter are null - cannot happen");
00574       IdentifierInfo *setterName = 
00575         setter->getSelector().getIdentifierInfoForSlot(0);
00576       IdentifierInfo *getterName =
00577           &S.Context.Idents.get(setterName->getName().substr(3));
00578       GetterSelector = 
00579         S.PP.getSelectorTable().getNullarySelector(getterName);
00580       return false;
00581     }
00582   }
00583 
00584   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
00585   Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
00586   return (Getter != nullptr);
00587 }
00588 
00589 /// Try to find the most accurate setter declaration for the property
00590 /// reference.
00591 ///
00592 /// \return true if a setter was found, in which case Setter 
00593 bool ObjCPropertyOpBuilder::findSetter(bool warn) {
00594   // For implicit properties, just trust the lookup we already did.
00595   if (RefExpr->isImplicitProperty()) {
00596     if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
00597       Setter = setter;
00598       SetterSelector = setter->getSelector();
00599       return true;
00600     } else {
00601       IdentifierInfo *getterName =
00602         RefExpr->getImplicitPropertyGetter()->getSelector()
00603           .getIdentifierInfoForSlot(0);
00604       SetterSelector =
00605         SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
00606                                                S.PP.getSelectorTable(),
00607                                                getterName);
00608       return false;
00609     }
00610   }
00611 
00612   // For explicit properties, this is more involved.
00613   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
00614   SetterSelector = prop->getSetterName();
00615 
00616   // Do a normal method lookup first.
00617   if (ObjCMethodDecl *setter =
00618         LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
00619     if (setter->isPropertyAccessor() && warn)
00620       if (const ObjCInterfaceDecl *IFace =
00621           dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
00622         StringRef thisPropertyName = prop->getName();
00623         // Try flipping the case of the first character.
00624         char front = thisPropertyName.front();
00625         front = isLowercase(front) ? toUppercase(front) : toLowercase(front);
00626         SmallString<100> PropertyName = thisPropertyName;
00627         PropertyName[0] = front;
00628         IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName);
00629         if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(AltMember))
00630           if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
00631             S.Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use)
00632               << prop << prop1 << setter->getSelector();
00633             S.Diag(prop->getLocation(), diag::note_property_declare);
00634             S.Diag(prop1->getLocation(), diag::note_property_declare);
00635           }
00636       }
00637     Setter = setter;
00638     return true;
00639   }
00640 
00641   // That can fail in the somewhat crazy situation that we're
00642   // type-checking a message send within the @interface declaration
00643   // that declared the @property.  But it's not clear that that's
00644   // valuable to support.
00645 
00646   return false;
00647 }
00648 
00649 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
00650   if (S.getCurLexicalContext()->isObjCContainer() &&
00651       S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
00652       S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
00653     if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
00654         S.Diag(RefExpr->getLocation(),
00655                diag::err_property_function_in_objc_container);
00656         S.Diag(prop->getLocation(), diag::note_property_declare);
00657     }
00658   }
00659 }
00660 
00661 /// Capture the base object of an Objective-C property expression.
00662 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
00663   assert(InstanceReceiver == nullptr);
00664 
00665   // If we have a base, capture it in an OVE and rebuild the syntactic
00666   // form to use the OVE as its base.
00667   if (RefExpr->isObjectReceiver()) {
00668     InstanceReceiver = capture(RefExpr->getBase());
00669 
00670     syntacticBase =
00671       ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
00672   }
00673 
00674   if (ObjCPropertyRefExpr *
00675         refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
00676     SyntacticRefExpr = refE;
00677 
00678   return syntacticBase;
00679 }
00680 
00681 /// Load from an Objective-C property reference.
00682 ExprResult ObjCPropertyOpBuilder::buildGet() {
00683   findGetter();
00684   if (!Getter) {
00685     DiagnoseUnsupportedPropertyUse();
00686     return ExprError();
00687   }
00688 
00689   if (SyntacticRefExpr)
00690     SyntacticRefExpr->setIsMessagingGetter();
00691 
00692   QualType receiverType;
00693   if (RefExpr->isClassReceiver()) {
00694     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
00695   } else if (RefExpr->isSuperReceiver()) {
00696     receiverType = RefExpr->getSuperReceiverType();
00697   } else {
00698     assert(InstanceReceiver);
00699     receiverType = InstanceReceiver->getType();
00700   }
00701   if (!Getter->isImplicit())
00702     S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
00703   // Build a message-send.
00704   ExprResult msg;
00705   if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
00706       RefExpr->isObjectReceiver()) {
00707     assert(InstanceReceiver || RefExpr->isSuperReceiver());
00708     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
00709                                          GenericLoc, Getter->getSelector(),
00710                                          Getter, None);
00711   } else {
00712     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
00713                                       GenericLoc, Getter->getSelector(),
00714                                       Getter, None);
00715   }
00716   return msg;
00717 }
00718 
00719 /// Store to an Objective-C property reference.
00720 ///
00721 /// \param captureSetValueAsResult If true, capture the actual
00722 ///   value being set as the value of the property operation.
00723 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
00724                                            bool captureSetValueAsResult) {
00725   if (!findSetter(false)) {
00726     DiagnoseUnsupportedPropertyUse();
00727     return ExprError();
00728   }
00729 
00730   if (SyntacticRefExpr)
00731     SyntacticRefExpr->setIsMessagingSetter();
00732 
00733   QualType receiverType;
00734   if (RefExpr->isClassReceiver()) {
00735     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
00736   } else if (RefExpr->isSuperReceiver()) {
00737     receiverType = RefExpr->getSuperReceiverType();
00738   } else {
00739     assert(InstanceReceiver);
00740     receiverType = InstanceReceiver->getType();
00741   }
00742 
00743   // Use assignment constraints when possible; they give us better
00744   // diagnostics.  "When possible" basically means anything except a
00745   // C++ class type.
00746   if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) {
00747     QualType paramType = (*Setter->param_begin())->getType();
00748     if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) {
00749       ExprResult opResult = op;
00750       Sema::AssignConvertType assignResult
00751         = S.CheckSingleAssignmentConstraints(paramType, opResult);
00752       if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
00753                                      op->getType(), opResult.get(),
00754                                      Sema::AA_Assigning))
00755         return ExprError();
00756 
00757       op = opResult.get();
00758       assert(op && "successful assignment left argument invalid?");
00759     }
00760     else if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(op)) {
00761       Expr *Initializer = OVE->getSourceExpr();
00762       // passing C++11 style initialized temporaries to objc++ properties
00763       // requires special treatment by removing OpaqueValueExpr so type
00764       // conversion takes place and adding the OpaqueValueExpr later on.
00765       if (isa<InitListExpr>(Initializer) &&
00766           Initializer->getType()->isVoidType()) {
00767         op = Initializer;
00768       }
00769     }
00770   }
00771 
00772   // Arguments.
00773   Expr *args[] = { op };
00774 
00775   // Build a message-send.
00776   ExprResult msg;
00777   if (!Setter->isImplicit())
00778     S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
00779   if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
00780       RefExpr->isObjectReceiver()) {
00781     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
00782                                          GenericLoc, SetterSelector, Setter,
00783                                          MultiExprArg(args, 1));
00784   } else {
00785     msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
00786                                       GenericLoc,
00787                                       SetterSelector, Setter,
00788                                       MultiExprArg(args, 1));
00789   }
00790 
00791   if (!msg.isInvalid() && captureSetValueAsResult) {
00792     ObjCMessageExpr *msgExpr =
00793       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
00794     Expr *arg = msgExpr->getArg(0);
00795     if (CanCaptureValue(arg))
00796       msgExpr->setArg(0, captureValueAsResult(arg));
00797   }
00798 
00799   return msg;
00800 }
00801 
00802 /// @property-specific behavior for doing lvalue-to-rvalue conversion.
00803 ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
00804   // Explicit properties always have getters, but implicit ones don't.
00805   // Check that before proceeding.
00806   if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) {
00807     S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
00808         << RefExpr->getSourceRange();
00809     return ExprError();
00810   }
00811 
00812   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
00813   if (result.isInvalid()) return ExprError();
00814 
00815   if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType())
00816     S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
00817                                        Getter, RefExpr->getLocation());
00818 
00819   // As a special case, if the method returns 'id', try to get
00820   // a better type from the property.
00821   if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
00822     QualType propType = RefExpr->getExplicitProperty()->getType();
00823     if (result.get()->getType()->isObjCIdType()) {
00824       if (const ObjCObjectPointerType *ptr
00825             = propType->getAs<ObjCObjectPointerType>()) {
00826         if (!ptr->isObjCIdType())
00827           result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
00828       }
00829     }
00830     if (S.getLangOpts().ObjCAutoRefCount) {
00831       Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
00832       if (LT == Qualifiers::OCL_Weak)
00833         if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
00834               S.getCurFunction()->markSafeWeakUse(RefExpr);
00835     }
00836   }
00837 
00838   return result;
00839 }
00840 
00841 /// Try to build this as a call to a getter that returns a reference.
00842 ///
00843 /// \return true if it was possible, whether or not it actually
00844 ///   succeeded
00845 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
00846                                                    ExprResult &result) {
00847   if (!S.getLangOpts().CPlusPlus) return false;
00848 
00849   findGetter();
00850   if (!Getter) {
00851     // The property has no setter and no getter! This can happen if the type is
00852     // invalid. Error have already been reported.
00853     result = ExprError();
00854     return true;
00855   }
00856 
00857   // Only do this if the getter returns an l-value reference type.
00858   QualType resultType = Getter->getReturnType();
00859   if (!resultType->isLValueReferenceType()) return false;
00860 
00861   result = buildRValueOperation(op);
00862   return true;
00863 }
00864 
00865 /// @property-specific behavior for doing assignments.
00866 ExprResult
00867 ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
00868                                                 SourceLocation opcLoc,
00869                                                 BinaryOperatorKind opcode,
00870                                                 Expr *LHS, Expr *RHS) {
00871   assert(BinaryOperator::isAssignmentOp(opcode));
00872 
00873   // If there's no setter, we have no choice but to try to assign to
00874   // the result of the getter.
00875   if (!findSetter()) {
00876     ExprResult result;
00877     if (tryBuildGetOfReference(LHS, result)) {
00878       if (result.isInvalid()) return ExprError();
00879       return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);
00880     }
00881 
00882     // Otherwise, it's an error.
00883     S.Diag(opcLoc, diag::err_nosetter_property_assignment)
00884       << unsigned(RefExpr->isImplicitProperty())
00885       << SetterSelector
00886       << LHS->getSourceRange() << RHS->getSourceRange();
00887     return ExprError();
00888   }
00889 
00890   // If there is a setter, we definitely want to use it.
00891 
00892   // Verify that we can do a compound assignment.
00893   if (opcode != BO_Assign && !findGetter()) {
00894     S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
00895       << LHS->getSourceRange() << RHS->getSourceRange();
00896     return ExprError();
00897   }
00898 
00899   ExprResult result =
00900     PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
00901   if (result.isInvalid()) return ExprError();
00902 
00903   // Various warnings about property assignments in ARC.
00904   if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) {
00905     S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
00906     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
00907   }
00908 
00909   return result;
00910 }
00911 
00912 /// @property-specific behavior for doing increments and decrements.
00913 ExprResult
00914 ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
00915                                             UnaryOperatorKind opcode,
00916                                             Expr *op) {
00917   // If there's no setter, we have no choice but to try to assign to
00918   // the result of the getter.
00919   if (!findSetter()) {
00920     ExprResult result;
00921     if (tryBuildGetOfReference(op, result)) {
00922       if (result.isInvalid()) return ExprError();
00923       return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get());
00924     }
00925 
00926     // Otherwise, it's an error.
00927     S.Diag(opcLoc, diag::err_nosetter_property_incdec)
00928       << unsigned(RefExpr->isImplicitProperty())
00929       << unsigned(UnaryOperator::isDecrementOp(opcode))
00930       << SetterSelector
00931       << op->getSourceRange();
00932     return ExprError();
00933   }
00934 
00935   // If there is a setter, we definitely want to use it.
00936 
00937   // We also need a getter.
00938   if (!findGetter()) {
00939     assert(RefExpr->isImplicitProperty());
00940     S.Diag(opcLoc, diag::err_nogetter_property_incdec)
00941       << unsigned(UnaryOperator::isDecrementOp(opcode))
00942       << GetterSelector
00943       << op->getSourceRange();
00944     return ExprError();
00945   }
00946 
00947   return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
00948 }
00949 
00950 ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
00951   if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
00952       !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
00953                          SyntacticForm->getLocStart()))
00954       S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
00955                                  SyntacticRefExpr->isMessagingGetter());
00956 
00957   return PseudoOpBuilder::complete(SyntacticForm);
00958 }
00959 
00960 // ObjCSubscript build stuff.
00961 //
00962 
00963 /// objective-c subscripting-specific behavior for doing lvalue-to-rvalue 
00964 /// conversion.
00965 /// FIXME. Remove this routine if it is proven that no additional 
00966 /// specifity is needed.
00967 ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
00968   ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
00969   if (result.isInvalid()) return ExprError();
00970   return result;
00971 }
00972 
00973 /// objective-c subscripting-specific  behavior for doing assignments.
00974 ExprResult
00975 ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
00976                                                 SourceLocation opcLoc,
00977                                                 BinaryOperatorKind opcode,
00978                                                 Expr *LHS, Expr *RHS) {
00979   assert(BinaryOperator::isAssignmentOp(opcode));
00980   // There must be a method to do the Index'ed assignment.
00981   if (!findAtIndexSetter())
00982     return ExprError();
00983   
00984   // Verify that we can do a compound assignment.
00985   if (opcode != BO_Assign && !findAtIndexGetter())
00986     return ExprError();
00987   
00988   ExprResult result =
00989   PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
00990   if (result.isInvalid()) return ExprError();
00991   
00992   // Various warnings about objc Index'ed assignments in ARC.
00993   if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) {
00994     S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
00995     S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
00996   }
00997   
00998   return result;
00999 }
01000 
01001 /// Capture the base object of an Objective-C Index'ed expression.
01002 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
01003   assert(InstanceBase == nullptr);
01004 
01005   // Capture base expression in an OVE and rebuild the syntactic
01006   // form to use the OVE as its base expression.
01007   InstanceBase = capture(RefExpr->getBaseExpr());
01008   InstanceKey = capture(RefExpr->getKeyExpr());
01009     
01010   syntacticBase =
01011     ObjCSubscriptRefRebuilder(S, InstanceBase, 
01012                               InstanceKey).rebuild(syntacticBase);
01013   
01014   return syntacticBase;
01015 }
01016 
01017 /// CheckSubscriptingKind - This routine decide what type 
01018 /// of indexing represented by "FromE" is being done.
01019 Sema::ObjCSubscriptKind 
01020   Sema::CheckSubscriptingKind(Expr *FromE) {
01021   // If the expression already has integral or enumeration type, we're golden.
01022   QualType T = FromE->getType();
01023   if (T->isIntegralOrEnumerationType())
01024     return OS_Array;
01025   
01026   // If we don't have a class type in C++, there's no way we can get an
01027   // expression of integral or enumeration type.
01028   const RecordType *RecordTy = T->getAs<RecordType>();
01029   if (!RecordTy &&
01030       (T->isObjCObjectPointerType() || T->isVoidPointerType()))
01031     // All other scalar cases are assumed to be dictionary indexing which
01032     // caller handles, with diagnostics if needed.
01033     return OS_Dictionary;
01034   if (!getLangOpts().CPlusPlus || 
01035       !RecordTy || RecordTy->isIncompleteType()) {
01036     // No indexing can be done. Issue diagnostics and quit.
01037     const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
01038     if (isa<StringLiteral>(IndexExpr))
01039       Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
01040         << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
01041     else
01042       Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
01043         << T;
01044     return OS_Error;
01045   }
01046   
01047   // We must have a complete class type.
01048   if (RequireCompleteType(FromE->getExprLoc(), T, 
01049                           diag::err_objc_index_incomplete_class_type, FromE))
01050     return OS_Error;
01051   
01052   // Look for a conversion to an integral, enumeration type, or
01053   // objective-C pointer type.
01054   std::pair<CXXRecordDecl::conversion_iterator,
01055             CXXRecordDecl::conversion_iterator> Conversions
01056     = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
01057   
01058   int NoIntegrals=0, NoObjCIdPointers=0;
01059   SmallVector<CXXConversionDecl *, 4> ConversionDecls;
01060     
01061   for (CXXRecordDecl::conversion_iterator
01062          I = Conversions.first, E = Conversions.second; I != E; ++I) {
01063     if (CXXConversionDecl *Conversion
01064         = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
01065       QualType CT = Conversion->getConversionType().getNonReferenceType();
01066       if (CT->isIntegralOrEnumerationType()) {
01067         ++NoIntegrals;
01068         ConversionDecls.push_back(Conversion);
01069       }
01070       else if (CT->isObjCIdType() ||CT->isBlockPointerType()) {
01071         ++NoObjCIdPointers;
01072         ConversionDecls.push_back(Conversion);
01073       }
01074     }
01075   }
01076   if (NoIntegrals ==1 && NoObjCIdPointers == 0)
01077     return OS_Array;
01078   if (NoIntegrals == 0 && NoObjCIdPointers == 1)
01079     return OS_Dictionary;
01080   if (NoIntegrals == 0 && NoObjCIdPointers == 0) {
01081     // No conversion function was found. Issue diagnostic and return.
01082     Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
01083       << FromE->getType();
01084     return OS_Error;
01085   }
01086   Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
01087       << FromE->getType();
01088   for (unsigned int i = 0; i < ConversionDecls.size(); i++)
01089     Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at);
01090     
01091   return OS_Error;
01092 }
01093 
01094 /// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
01095 /// objects used as dictionary subscript key objects.
01096 static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, 
01097                                          Expr *Key) {
01098   if (ContainerT.isNull())
01099     return;
01100   // dictionary subscripting.
01101   // - (id)objectForKeyedSubscript:(id)key;
01102   IdentifierInfo *KeyIdents[] = {
01103     &S.Context.Idents.get("objectForKeyedSubscript")  
01104   };
01105   Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
01106   ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT, 
01107                                                       true /*instance*/);
01108   if (!Getter)
01109     return;
01110   QualType T = Getter->parameters()[0]->getType();
01111   S.CheckObjCARCConversion(Key->getSourceRange(), 
01112                          T, Key, Sema::CCK_ImplicitConversion);
01113 }
01114 
01115 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
01116   if (AtIndexGetter)
01117     return true;
01118   
01119   Expr *BaseExpr = RefExpr->getBaseExpr();
01120   QualType BaseT = BaseExpr->getType();
01121   
01122   QualType ResultType;
01123   if (const ObjCObjectPointerType *PTy =
01124       BaseT->getAs<ObjCObjectPointerType>()) {
01125     ResultType = PTy->getPointeeType();
01126     if (const ObjCObjectType *iQFaceTy = 
01127         ResultType->getAsObjCQualifiedInterfaceType())
01128       ResultType = iQFaceTy->getBaseType();
01129   }
01130   Sema::ObjCSubscriptKind Res = 
01131     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
01132   if (Res == Sema::OS_Error) {
01133     if (S.getLangOpts().ObjCAutoRefCount)
01134       CheckKeyForObjCARCConversion(S, ResultType, 
01135                                    RefExpr->getKeyExpr());
01136     return false;
01137   }
01138   bool arrayRef = (Res == Sema::OS_Array);
01139   
01140   if (ResultType.isNull()) {
01141     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
01142       << BaseExpr->getType() << arrayRef;
01143     return false;
01144   }
01145   if (!arrayRef) {
01146     // dictionary subscripting.
01147     // - (id)objectForKeyedSubscript:(id)key;
01148     IdentifierInfo *KeyIdents[] = {
01149       &S.Context.Idents.get("objectForKeyedSubscript")  
01150     };
01151     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
01152   }
01153   else {
01154     // - (id)objectAtIndexedSubscript:(size_t)index;
01155     IdentifierInfo *KeyIdents[] = {
01156       &S.Context.Idents.get("objectAtIndexedSubscript")  
01157     };
01158   
01159     AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
01160   }
01161   
01162   AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType, 
01163                                              true /*instance*/);
01164   bool receiverIdType = (BaseT->isObjCIdType() ||
01165                          BaseT->isObjCQualifiedIdType());
01166   
01167   if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) {
01168     AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(), 
01169                            SourceLocation(), AtIndexGetterSelector,
01170                            S.Context.getObjCIdType() /*ReturnType*/,
01171                            nullptr /*TypeSourceInfo */,
01172                            S.Context.getTranslationUnitDecl(),
01173                            true /*Instance*/, false/*isVariadic*/,
01174                            /*isPropertyAccessor=*/false,
01175                            /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
01176                            ObjCMethodDecl::Required,
01177                            false);
01178     ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
01179                                                 SourceLocation(), SourceLocation(),
01180                                                 arrayRef ? &S.Context.Idents.get("index")
01181                                                          : &S.Context.Idents.get("key"),
01182                                                 arrayRef ? S.Context.UnsignedLongTy
01183                                                          : S.Context.getObjCIdType(),
01184                                                 /*TInfo=*/nullptr,
01185                                                 SC_None,
01186                                                 nullptr);
01187     AtIndexGetter->setMethodParams(S.Context, Argument, None);
01188   }
01189 
01190   if (!AtIndexGetter) {
01191     if (!receiverIdType) {
01192       S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
01193       << BaseExpr->getType() << 0 << arrayRef;
01194       return false;
01195     }
01196     AtIndexGetter = 
01197       S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, 
01198                                          RefExpr->getSourceRange(), 
01199                                          true, false);
01200   }
01201   
01202   if (AtIndexGetter) {
01203     QualType T = AtIndexGetter->parameters()[0]->getType();
01204     if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
01205         (!arrayRef && !T->isObjCObjectPointerType())) {
01206       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
01207              arrayRef ? diag::err_objc_subscript_index_type
01208                       : diag::err_objc_subscript_key_type) << T;
01209       S.Diag(AtIndexGetter->parameters()[0]->getLocation(), 
01210              diag::note_parameter_type) << T;
01211       return false;
01212     }
01213     QualType R = AtIndexGetter->getReturnType();
01214     if (!R->isObjCObjectPointerType()) {
01215       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
01216              diag::err_objc_indexing_method_result_type) << R << arrayRef;
01217       S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
01218         AtIndexGetter->getDeclName();
01219     }
01220   }
01221   return true;
01222 }
01223 
01224 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
01225   if (AtIndexSetter)
01226     return true;
01227   
01228   Expr *BaseExpr = RefExpr->getBaseExpr();
01229   QualType BaseT = BaseExpr->getType();
01230   
01231   QualType ResultType;
01232   if (const ObjCObjectPointerType *PTy =
01233       BaseT->getAs<ObjCObjectPointerType>()) {
01234     ResultType = PTy->getPointeeType();
01235     if (const ObjCObjectType *iQFaceTy = 
01236         ResultType->getAsObjCQualifiedInterfaceType())
01237       ResultType = iQFaceTy->getBaseType();
01238   }
01239   
01240   Sema::ObjCSubscriptKind Res = 
01241     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
01242   if (Res == Sema::OS_Error) {
01243     if (S.getLangOpts().ObjCAutoRefCount)
01244       CheckKeyForObjCARCConversion(S, ResultType, 
01245                                    RefExpr->getKeyExpr());
01246     return false;
01247   }
01248   bool arrayRef = (Res == Sema::OS_Array);
01249   
01250   if (ResultType.isNull()) {
01251     S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
01252       << BaseExpr->getType() << arrayRef;
01253     return false;
01254   }
01255   
01256   if (!arrayRef) {
01257     // dictionary subscripting.
01258     // - (void)setObject:(id)object forKeyedSubscript:(id)key;
01259     IdentifierInfo *KeyIdents[] = {
01260       &S.Context.Idents.get("setObject"),
01261       &S.Context.Idents.get("forKeyedSubscript")
01262     };
01263     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
01264   }
01265   else {
01266     // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
01267     IdentifierInfo *KeyIdents[] = {
01268       &S.Context.Idents.get("setObject"),
01269       &S.Context.Idents.get("atIndexedSubscript")
01270     };
01271     AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
01272   }
01273   AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType, 
01274                                              true /*instance*/);
01275   
01276   bool receiverIdType = (BaseT->isObjCIdType() ||
01277                          BaseT->isObjCQualifiedIdType());
01278 
01279   if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
01280     TypeSourceInfo *ReturnTInfo = nullptr;
01281     QualType ReturnType = S.Context.VoidTy;
01282     AtIndexSetter = ObjCMethodDecl::Create(
01283         S.Context, SourceLocation(), SourceLocation(), AtIndexSetterSelector,
01284         ReturnType, ReturnTInfo, S.Context.getTranslationUnitDecl(),
01285         true /*Instance*/, false /*isVariadic*/,
01286         /*isPropertyAccessor=*/false,
01287         /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
01288         ObjCMethodDecl::Required, false);
01289     SmallVector<ParmVarDecl *, 2> Params;
01290     ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
01291                                                 SourceLocation(), SourceLocation(),
01292                                                 &S.Context.Idents.get("object"),
01293                                                 S.Context.getObjCIdType(),
01294                                                 /*TInfo=*/nullptr,
01295                                                 SC_None,
01296                                                 nullptr);
01297     Params.push_back(object);
01298     ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
01299                                                 SourceLocation(), SourceLocation(),
01300                                                 arrayRef ?  &S.Context.Idents.get("index")
01301                                                          :  &S.Context.Idents.get("key"),
01302                                                 arrayRef ? S.Context.UnsignedLongTy
01303                                                          : S.Context.getObjCIdType(),
01304                                                 /*TInfo=*/nullptr,
01305                                                 SC_None,
01306                                                 nullptr);
01307     Params.push_back(key);
01308     AtIndexSetter->setMethodParams(S.Context, Params, None);
01309   }
01310   
01311   if (!AtIndexSetter) {
01312     if (!receiverIdType) {
01313       S.Diag(BaseExpr->getExprLoc(), 
01314              diag::err_objc_subscript_method_not_found)
01315       << BaseExpr->getType() << 1 << arrayRef;
01316       return false;
01317     }
01318     AtIndexSetter = 
01319       S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, 
01320                                          RefExpr->getSourceRange(), 
01321                                          true, false);
01322   }
01323   
01324   bool err = false;
01325   if (AtIndexSetter && arrayRef) {
01326     QualType T = AtIndexSetter->parameters()[1]->getType();
01327     if (!T->isIntegralOrEnumerationType()) {
01328       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
01329              diag::err_objc_subscript_index_type) << T;
01330       S.Diag(AtIndexSetter->parameters()[1]->getLocation(), 
01331              diag::note_parameter_type) << T;
01332       err = true;
01333     }
01334     T = AtIndexSetter->parameters()[0]->getType();
01335     if (!T->isObjCObjectPointerType()) {
01336       S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 
01337              diag::err_objc_subscript_object_type) << T << arrayRef;
01338       S.Diag(AtIndexSetter->parameters()[0]->getLocation(), 
01339              diag::note_parameter_type) << T;
01340       err = true;
01341     }
01342   }
01343   else if (AtIndexSetter && !arrayRef)
01344     for (unsigned i=0; i <2; i++) {
01345       QualType T = AtIndexSetter->parameters()[i]->getType();
01346       if (!T->isObjCObjectPointerType()) {
01347         if (i == 1)
01348           S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
01349                  diag::err_objc_subscript_key_type) << T;
01350         else
01351           S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
01352                  diag::err_objc_subscript_dic_object_type) << T;
01353         S.Diag(AtIndexSetter->parameters()[i]->getLocation(), 
01354                diag::note_parameter_type) << T;
01355         err = true;
01356       }
01357     }
01358 
01359   return !err;
01360 }
01361 
01362 // Get the object at "Index" position in the container.
01363 // [BaseExpr objectAtIndexedSubscript : IndexExpr];
01364 ExprResult ObjCSubscriptOpBuilder::buildGet() {
01365   if (!findAtIndexGetter())
01366     return ExprError();
01367   
01368   QualType receiverType = InstanceBase->getType();
01369     
01370   // Build a message-send.
01371   ExprResult msg;
01372   Expr *Index = InstanceKey;
01373   
01374   // Arguments.
01375   Expr *args[] = { Index };
01376   assert(InstanceBase);
01377   if (AtIndexGetter)
01378     S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc);
01379   msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
01380                                        GenericLoc,
01381                                        AtIndexGetterSelector, AtIndexGetter,
01382                                        MultiExprArg(args, 1));
01383   return msg;
01384 }
01385 
01386 /// Store into the container the "op" object at "Index"'ed location
01387 /// by building this messaging expression:
01388 /// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
01389 /// \param captureSetValueAsResult If true, capture the actual
01390 ///   value being set as the value of the property operation.
01391 ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
01392                                            bool captureSetValueAsResult) {
01393   if (!findAtIndexSetter())
01394     return ExprError();
01395   if (AtIndexSetter)
01396     S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc);
01397   QualType receiverType = InstanceBase->getType();
01398   Expr *Index = InstanceKey;
01399   
01400   // Arguments.
01401   Expr *args[] = { op, Index };
01402   
01403   // Build a message-send.
01404   ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
01405                                                   GenericLoc,
01406                                                   AtIndexSetterSelector,
01407                                                   AtIndexSetter,
01408                                                   MultiExprArg(args, 2));
01409   
01410   if (!msg.isInvalid() && captureSetValueAsResult) {
01411     ObjCMessageExpr *msgExpr =
01412       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
01413     Expr *arg = msgExpr->getArg(0);
01414     if (CanCaptureValue(arg))
01415       msgExpr->setArg(0, captureValueAsResult(arg));
01416   }
01417   
01418   return msg;
01419 }
01420 
01421 //===----------------------------------------------------------------------===//
01422 //  MSVC __declspec(property) references
01423 //===----------------------------------------------------------------------===//
01424 
01425 Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
01426   Expr *NewBase = capture(RefExpr->getBaseExpr());
01427 
01428   syntacticBase =
01429     MSPropertyRefRebuilder(S, NewBase).rebuild(syntacticBase);
01430 
01431   return syntacticBase;
01432 }
01433 
01434 ExprResult MSPropertyOpBuilder::buildGet() {
01435   if (!RefExpr->getPropertyDecl()->hasGetter()) {
01436     S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
01437       << 0 /* getter */ << RefExpr->getPropertyDecl();
01438     return ExprError();
01439   }
01440 
01441   UnqualifiedId GetterName;
01442   IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
01443   GetterName.setIdentifier(II, RefExpr->getMemberLoc());
01444   CXXScopeSpec SS;
01445   SS.Adopt(RefExpr->getQualifierLoc());
01446   ExprResult GetterExpr = S.ActOnMemberAccessExpr(
01447     S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
01448     RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
01449     GetterName, nullptr, true);
01450   if (GetterExpr.isInvalid()) {
01451     S.Diag(RefExpr->getMemberLoc(),
01452            diag::error_cannot_find_suitable_accessor) << 0 /* getter */
01453       << RefExpr->getPropertyDecl();
01454     return ExprError();
01455   }
01456 
01457   MultiExprArg ArgExprs;
01458   return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(),
01459                          RefExpr->getSourceRange().getBegin(), ArgExprs,
01460                          RefExpr->getSourceRange().getEnd());
01461 }
01462 
01463 ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
01464                                          bool captureSetValueAsResult) {
01465   if (!RefExpr->getPropertyDecl()->hasSetter()) {
01466     S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
01467       << 1 /* setter */ << RefExpr->getPropertyDecl();
01468     return ExprError();
01469   }
01470 
01471   UnqualifiedId SetterName;
01472   IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
01473   SetterName.setIdentifier(II, RefExpr->getMemberLoc());
01474   CXXScopeSpec SS;
01475   SS.Adopt(RefExpr->getQualifierLoc());
01476   ExprResult SetterExpr = S.ActOnMemberAccessExpr(
01477     S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
01478     RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
01479     SetterName, nullptr, true);
01480   if (SetterExpr.isInvalid()) {
01481     S.Diag(RefExpr->getMemberLoc(),
01482            diag::error_cannot_find_suitable_accessor) << 1 /* setter */
01483       << RefExpr->getPropertyDecl();
01484     return ExprError();
01485   }
01486 
01487   SmallVector<Expr*, 1> ArgExprs;
01488   ArgExprs.push_back(op);
01489   return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(),
01490                          RefExpr->getSourceRange().getBegin(), ArgExprs,
01491                          op->getSourceRange().getEnd());
01492 }
01493 
01494 //===----------------------------------------------------------------------===//
01495 //  General Sema routines.
01496 //===----------------------------------------------------------------------===//
01497 
01498 ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
01499   Expr *opaqueRef = E->IgnoreParens();
01500   if (ObjCPropertyRefExpr *refExpr
01501         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01502     ObjCPropertyOpBuilder builder(*this, refExpr);
01503     return builder.buildRValueOperation(E);
01504   }
01505   else if (ObjCSubscriptRefExpr *refExpr
01506            = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
01507     ObjCSubscriptOpBuilder builder(*this, refExpr);
01508     return builder.buildRValueOperation(E);
01509   } else if (MSPropertyRefExpr *refExpr
01510              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
01511     MSPropertyOpBuilder builder(*this, refExpr);
01512     return builder.buildRValueOperation(E);
01513   } else {
01514     llvm_unreachable("unknown pseudo-object kind!");
01515   }
01516 }
01517 
01518 /// Check an increment or decrement of a pseudo-object expression.
01519 ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
01520                                          UnaryOperatorKind opcode, Expr *op) {
01521   // Do nothing if the operand is dependent.
01522   if (op->isTypeDependent())
01523     return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
01524                                        VK_RValue, OK_Ordinary, opcLoc);
01525 
01526   assert(UnaryOperator::isIncrementDecrementOp(opcode));
01527   Expr *opaqueRef = op->IgnoreParens();
01528   if (ObjCPropertyRefExpr *refExpr
01529         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01530     ObjCPropertyOpBuilder builder(*this, refExpr);
01531     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
01532   } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
01533     Diag(opcLoc, diag::err_illegal_container_subscripting_op);
01534     return ExprError();
01535   } else if (MSPropertyRefExpr *refExpr
01536              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
01537     MSPropertyOpBuilder builder(*this, refExpr);
01538     return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
01539   } else {
01540     llvm_unreachable("unknown pseudo-object kind!");
01541   }
01542 }
01543 
01544 ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
01545                                              BinaryOperatorKind opcode,
01546                                              Expr *LHS, Expr *RHS) {
01547   // Do nothing if either argument is dependent.
01548   if (LHS->isTypeDependent() || RHS->isTypeDependent())
01549     return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
01550                                         VK_RValue, OK_Ordinary, opcLoc, false);
01551 
01552   // Filter out non-overload placeholder types in the RHS.
01553   if (RHS->getType()->isNonOverloadPlaceholderType()) {
01554     ExprResult result = CheckPlaceholderExpr(RHS);
01555     if (result.isInvalid()) return ExprError();
01556     RHS = result.get();
01557   }
01558 
01559   Expr *opaqueRef = LHS->IgnoreParens();
01560   if (ObjCPropertyRefExpr *refExpr
01561         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01562     ObjCPropertyOpBuilder builder(*this, refExpr);
01563     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
01564   } else if (ObjCSubscriptRefExpr *refExpr
01565              = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
01566     ObjCSubscriptOpBuilder builder(*this, refExpr);
01567     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
01568   } else if (MSPropertyRefExpr *refExpr
01569              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
01570     MSPropertyOpBuilder builder(*this, refExpr);
01571     return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
01572   } else {
01573     llvm_unreachable("unknown pseudo-object kind!");
01574   }
01575 }
01576 
01577 /// Given a pseudo-object reference, rebuild it without the opaque
01578 /// values.  Basically, undo the behavior of rebuildAndCaptureObject.
01579 /// This should never operate in-place.
01580 static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
01581   Expr *opaqueRef = E->IgnoreParens();
01582   if (ObjCPropertyRefExpr *refExpr
01583         = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
01584     // Class and super property references don't have opaque values in them.
01585     if (refExpr->isClassReceiver() || refExpr->isSuperReceiver())
01586       return E;
01587     
01588     assert(refExpr->isObjectReceiver() && "Unknown receiver kind?");
01589     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBase());
01590     return ObjCPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
01591   } else if (ObjCSubscriptRefExpr *refExpr
01592                = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
01593     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
01594     OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
01595     return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(), 
01596                                      keyOVE->getSourceExpr()).rebuild(E);
01597   } else if (MSPropertyRefExpr *refExpr
01598              = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
01599     OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
01600     return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
01601   } else {
01602     llvm_unreachable("unknown pseudo-object kind!");
01603   }
01604 }
01605 
01606 /// Given a pseudo-object expression, recreate what it looks like
01607 /// syntactically without the attendant OpaqueValueExprs.
01608 ///
01609 /// This is a hack which should be removed when TreeTransform is
01610 /// capable of rebuilding a tree without stripping implicit
01611 /// operations.
01612 Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
01613   Expr *syntax = E->getSyntacticForm();
01614   if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
01615     Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
01616     return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(),
01617                                        uop->getValueKind(), uop->getObjectKind(),
01618                                        uop->getOperatorLoc());
01619   } else if (CompoundAssignOperator *cop
01620                = dyn_cast<CompoundAssignOperator>(syntax)) {
01621     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
01622     Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
01623     return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
01624                                                 cop->getType(),
01625                                                 cop->getValueKind(),
01626                                                 cop->getObjectKind(),
01627                                                 cop->getComputationLHSType(),
01628                                                 cop->getComputationResultType(),
01629                                                 cop->getOperatorLoc(), false);
01630   } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
01631     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
01632     Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
01633     return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
01634                                         bop->getType(), bop->getValueKind(),
01635                                         bop->getObjectKind(),
01636                                         bop->getOperatorLoc(), false);
01637   } else {
01638     assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
01639     return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
01640   }
01641 }