clang API Documentation
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 }