13c3b7f90a863af43fa63043d396553ecf205351cJohn McCall//===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===// 23c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 33c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// The LLVM Compiler Infrastructure 43c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 53c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// This file is distributed under the University of Illinois Open Source 63c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// License. See LICENSE.TXT for details. 73c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 83c3b7f90a863af43fa63043d396553ecf205351cJohn McCall//===----------------------------------------------------------------------===// 93c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 103c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// This file implements semantic analysis for expressions involving 113c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// pseudo-object references. Pseudo-objects are conceptual objects 123c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// whose storage is entirely abstract and all accesses to which are 133c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// translated through some sort of abstraction barrier. 143c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 153c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// For example, Objective-C objects can have "properties", either 163c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// declared or undeclared. A property may be accessed by writing 173c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// expr.prop 183c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// where 'expr' is an r-value of Objective-C pointer type and 'prop' 193c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// is the name of the property. If this expression is used in a context 203c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// needing an r-value, it is treated as if it were a message-send 213c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// of the associated 'getter' selector, typically: 223c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// [expr prop] 233c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// If it is used as the LHS of a simple assignment, it is treated 243c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// as a message-send of the associated 'setter' selector, typically: 253c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// [expr setProp: RHS] 263c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// If it is used as the LHS of a compound assignment, or the operand 273c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// of a unary increment or decrement, both are required; for example, 283c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 'expr.prop *= 100' would be translated to: 293c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// [expr setProp: [expr prop] * 100] 303c3b7f90a863af43fa63043d396553ecf205351cJohn McCall// 313c3b7f90a863af43fa63043d396553ecf205351cJohn McCall//===----------------------------------------------------------------------===// 323c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 333c3b7f90a863af43fa63043d396553ecf205351cJohn McCall#include "clang/Sema/SemaInternal.h" 346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/AST/ExprCXX.h" 353c3b7f90a863af43fa63043d396553ecf205351cJohn McCall#include "clang/AST/ExprObjC.h" 363f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose#include "clang/Basic/CharInfo.h" 373c3b7f90a863af43fa63043d396553ecf205351cJohn McCall#include "clang/Lex/Preprocessor.h" 3855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Initialization.h" 3955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h" 40b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian#include "llvm/ADT/SmallString.h" 413c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 423c3b7f90a863af43fa63043d396553ecf205351cJohn McCallusing namespace clang; 433c3b7f90a863af43fa63043d396553ecf205351cJohn McCallusing namespace sema; 443c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 454b9c2d235fb9449e249d74f48ecfec601650de93John McCallnamespace { 464b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Basically just a very focused copy of TreeTransform. 4787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar struct Rebuilder { 484b9c2d235fb9449e249d74f48ecfec601650de93John McCall Sema &S; 4987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar unsigned MSPropertySubscriptCount; 5087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar typedef llvm::function_ref<Expr *(Expr *, unsigned)> SpecificRebuilderRefTy; 5187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar const SpecificRebuilderRefTy &SpecificCallback; 5287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Rebuilder(Sema &S, const SpecificRebuilderRefTy &SpecificCallback) 5387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : S(S), MSPropertySubscriptCount(0), 5487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SpecificCallback(SpecificCallback) {} 5587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 5687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Expr *rebuildObjCPropertyRefExpr(ObjCPropertyRefExpr *refExpr) { 5787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // Fortunately, the constraint that we're rebuilding something 5887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // with a base limits the number of cases here. 5987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (refExpr->isClassReceiver() || refExpr->isSuperReceiver()) 6087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return refExpr; 6187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 6287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (refExpr->isExplicitProperty()) { 6387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return new (S.Context) ObjCPropertyRefExpr( 6487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getExplicitProperty(), refExpr->getType(), 6587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getValueKind(), refExpr->getObjectKind(), 6687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0)); 6787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 6887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return new (S.Context) ObjCPropertyRefExpr( 6987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getImplicitPropertyGetter(), 7087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getImplicitPropertySetter(), refExpr->getType(), 7187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getValueKind(), refExpr->getObjectKind(), 7287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0)); 7387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 7487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Expr *rebuildObjCSubscriptRefExpr(ObjCSubscriptRefExpr *refExpr) { 7587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(refExpr->getBaseExpr()); 7687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(refExpr->getKeyExpr()); 774b9c2d235fb9449e249d74f48ecfec601650de93John McCall 7887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return new (S.Context) ObjCSubscriptRefExpr( 7987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SpecificCallback(refExpr->getBaseExpr(), 0), 8087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SpecificCallback(refExpr->getKeyExpr(), 1), refExpr->getType(), 8187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getValueKind(), refExpr->getObjectKind(), 8287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getAtIndexMethodDecl(), refExpr->setAtIndexMethodDecl(), 8387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getRBracket()); 8487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 8587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Expr *rebuildMSPropertyRefExpr(MSPropertyRefExpr *refExpr) { 8687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(refExpr->getBaseExpr()); 8787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 8887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return new (S.Context) MSPropertyRefExpr( 8987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SpecificCallback(refExpr->getBaseExpr(), 0), 9087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getPropertyDecl(), refExpr->isArrow(), refExpr->getType(), 9187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getValueKind(), refExpr->getQualifierLoc(), 9287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getMemberLoc()); 9387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 9487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Expr *rebuildMSPropertySubscriptExpr(MSPropertySubscriptExpr *refExpr) { 9587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(refExpr->getBase()); 9687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(refExpr->getIdx()); 9787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 9887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto *NewBase = rebuild(refExpr->getBase()); 9987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ++MSPropertySubscriptCount; 10087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return new (S.Context) MSPropertySubscriptExpr( 10187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar NewBase, 10287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SpecificCallback(refExpr->getIdx(), MSPropertySubscriptCount), 10387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getType(), refExpr->getValueKind(), refExpr->getObjectKind(), 10487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar refExpr->getRBracketLoc()); 10587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 1064b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1074b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *rebuild(Expr *e) { 1084b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Fast path: nothing to look through. 10987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e)) 11087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return rebuildObjCPropertyRefExpr(PRE); 11187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e)) 11287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return rebuildObjCSubscriptRefExpr(SRE); 11387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e)) 11487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return rebuildMSPropertyRefExpr(MSPRE); 11587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e)) 11687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return rebuildMSPropertySubscriptExpr(MSPSE); 1174b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1184b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Otherwise, we should look through and rebuild anything that 1194b9c2d235fb9449e249d74f48ecfec601650de93John McCall // IgnoreParens would. 1204b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1214b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) { 1224b9c2d235fb9449e249d74f48ecfec601650de93John McCall e = rebuild(parens->getSubExpr()); 1234b9c2d235fb9449e249d74f48ecfec601650de93John McCall return new (S.Context) ParenExpr(parens->getLParen(), 1244b9c2d235fb9449e249d74f48ecfec601650de93John McCall parens->getRParen(), 1254b9c2d235fb9449e249d74f48ecfec601650de93John McCall e); 1264b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1274b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1284b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) { 1294b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(uop->getOpcode() == UO_Extension); 1304b9c2d235fb9449e249d74f48ecfec601650de93John McCall e = rebuild(uop->getSubExpr()); 1314b9c2d235fb9449e249d74f48ecfec601650de93John McCall return new (S.Context) UnaryOperator(e, uop->getOpcode(), 1324b9c2d235fb9449e249d74f48ecfec601650de93John McCall uop->getType(), 1334b9c2d235fb9449e249d74f48ecfec601650de93John McCall uop->getValueKind(), 1344b9c2d235fb9449e249d74f48ecfec601650de93John McCall uop->getObjectKind(), 1354b9c2d235fb9449e249d74f48ecfec601650de93John McCall uop->getOperatorLoc()); 1364b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1374b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1384b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { 1394b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(!gse->isResultDependent()); 1404b9c2d235fb9449e249d74f48ecfec601650de93John McCall unsigned resultIndex = gse->getResultIndex(); 1414b9c2d235fb9449e249d74f48ecfec601650de93John McCall unsigned numAssocs = gse->getNumAssocs(); 1424b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1434b9c2d235fb9449e249d74f48ecfec601650de93John McCall SmallVector<Expr*, 8> assocs(numAssocs); 1444b9c2d235fb9449e249d74f48ecfec601650de93John McCall SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs); 1454b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1464b9c2d235fb9449e249d74f48ecfec601650de93John McCall for (unsigned i = 0; i != numAssocs; ++i) { 1474b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *assoc = gse->getAssocExpr(i); 1484b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (i == resultIndex) assoc = rebuild(assoc); 1494b9c2d235fb9449e249d74f48ecfec601650de93John McCall assocs[i] = assoc; 1504b9c2d235fb9449e249d74f48ecfec601650de93John McCall assocTypes[i] = gse->getAssocTypeSourceInfo(i); 1514b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1524b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1534b9c2d235fb9449e249d74f48ecfec601650de93John McCall return new (S.Context) GenericSelectionExpr(S.Context, 1544b9c2d235fb9449e249d74f48ecfec601650de93John McCall gse->getGenericLoc(), 1554b9c2d235fb9449e249d74f48ecfec601650de93John McCall gse->getControllingExpr(), 1563b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer assocTypes, 1573b6bef9a213249c6ab6d67c07b1ac6380961be3eBenjamin Kramer assocs, 1584b9c2d235fb9449e249d74f48ecfec601650de93John McCall gse->getDefaultLoc(), 1594b9c2d235fb9449e249d74f48ecfec601650de93John McCall gse->getRParenLoc(), 1604b9c2d235fb9449e249d74f48ecfec601650de93John McCall gse->containsUnexpandedParameterPack(), 1614b9c2d235fb9449e249d74f48ecfec601650de93John McCall resultIndex); 1624b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1634b9c2d235fb9449e249d74f48ecfec601650de93John McCall 164a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman if (ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) { 165a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman assert(!ce->isConditionDependent()); 166a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman 167a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman Expr *LHS = ce->getLHS(), *RHS = ce->getRHS(); 168a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS; 169a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman rebuiltExpr = rebuild(rebuiltExpr); 170a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman 171a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman return new (S.Context) ChooseExpr(ce->getBuiltinLoc(), 172a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman ce->getCond(), 173a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman LHS, RHS, 174a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman rebuiltExpr->getType(), 175a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman rebuiltExpr->getValueKind(), 176a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman rebuiltExpr->getObjectKind(), 177a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman ce->getRParenLoc(), 178a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman ce->isConditionTrue(), 179a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman rebuiltExpr->isTypeDependent(), 180a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman rebuiltExpr->isValueDependent()); 181a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman } 182a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman 1834b9c2d235fb9449e249d74f48ecfec601650de93John McCall llvm_unreachable("bad expression to rebuild!"); 1844b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 1854b9c2d235fb9449e249d74f48ecfec601650de93John McCall }; 1864b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1874b9c2d235fb9449e249d74f48ecfec601650de93John McCall class PseudoOpBuilder { 1884b9c2d235fb9449e249d74f48ecfec601650de93John McCall public: 1894b9c2d235fb9449e249d74f48ecfec601650de93John McCall Sema &S; 1904b9c2d235fb9449e249d74f48ecfec601650de93John McCall unsigned ResultIndex; 1914b9c2d235fb9449e249d74f48ecfec601650de93John McCall SourceLocation GenericLoc; 1924b9c2d235fb9449e249d74f48ecfec601650de93John McCall SmallVector<Expr *, 4> Semantics; 1934b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1944b9c2d235fb9449e249d74f48ecfec601650de93John McCall PseudoOpBuilder(Sema &S, SourceLocation genericLoc) 1954b9c2d235fb9449e249d74f48ecfec601650de93John McCall : S(S), ResultIndex(PseudoObjectExpr::NoResult), 1964b9c2d235fb9449e249d74f48ecfec601650de93John McCall GenericLoc(genericLoc) {} 1974b9c2d235fb9449e249d74f48ecfec601650de93John McCall 1981aa1721f14f2162811f5393dbd84e01eadc2c963Matt Beaumont-Gay virtual ~PseudoOpBuilder() {} 1991aa1721f14f2162811f5393dbd84e01eadc2c963Matt Beaumont-Gay 2004b9c2d235fb9449e249d74f48ecfec601650de93John McCall /// Add a normal semantic expression. 2014b9c2d235fb9449e249d74f48ecfec601650de93John McCall void addSemanticExpr(Expr *semantic) { 2024b9c2d235fb9449e249d74f48ecfec601650de93John McCall Semantics.push_back(semantic); 2034b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2044b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2054b9c2d235fb9449e249d74f48ecfec601650de93John McCall /// Add the 'result' semantic expression. 2064b9c2d235fb9449e249d74f48ecfec601650de93John McCall void addResultSemanticExpr(Expr *resultExpr) { 2074b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(ResultIndex == PseudoObjectExpr::NoResult); 2084b9c2d235fb9449e249d74f48ecfec601650de93John McCall ResultIndex = Semantics.size(); 2094b9c2d235fb9449e249d74f48ecfec601650de93John McCall Semantics.push_back(resultExpr); 2104b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2114b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2124b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult buildRValueOperation(Expr *op); 2134b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult buildAssignmentOperation(Scope *Sc, 2144b9c2d235fb9449e249d74f48ecfec601650de93John McCall SourceLocation opLoc, 2154b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperatorKind opcode, 2164b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *LHS, Expr *RHS); 2174b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc, 2184b9c2d235fb9449e249d74f48ecfec601650de93John McCall UnaryOperatorKind opcode, 2194b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *op); 2204b9c2d235fb9449e249d74f48ecfec601650de93John McCall 22158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose virtual ExprResult complete(Expr *syntacticForm); 2224b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2234b9c2d235fb9449e249d74f48ecfec601650de93John McCall OpaqueValueExpr *capture(Expr *op); 2244b9c2d235fb9449e249d74f48ecfec601650de93John McCall OpaqueValueExpr *captureValueAsResult(Expr *op); 2254b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2264b9c2d235fb9449e249d74f48ecfec601650de93John McCall void setResultToLastSemantic() { 2274b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(ResultIndex == PseudoObjectExpr::NoResult); 2284b9c2d235fb9449e249d74f48ecfec601650de93John McCall ResultIndex = Semantics.size() - 1; 2294b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2304b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2314b9c2d235fb9449e249d74f48ecfec601650de93John McCall /// Return true if assignments have a non-void result. 23287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar static bool CanCaptureValue(Expr *exp) { 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (exp->isGLValue()) 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType ty = exp->getType(); 23625f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman assert(!ty->isIncompleteType()); 23725f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman assert(!ty->isDependentType()); 23825f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman 23925f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman if (const CXXRecordDecl *ClassDecl = ty->getAsCXXRecordDecl()) 24025f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman return ClassDecl->isTriviallyCopyable(); 24125f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman return true; 24225f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman } 2434b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2444b9c2d235fb9449e249d74f48ecfec601650de93John McCall virtual Expr *rebuildAndCaptureObject(Expr *) = 0; 2454b9c2d235fb9449e249d74f48ecfec601650de93John McCall virtual ExprResult buildGet() = 0; 2464b9c2d235fb9449e249d74f48ecfec601650de93John McCall virtual ExprResult buildSet(Expr *, SourceLocation, 2474b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool captureSetValueAsResult) = 0; 24887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// \brief Should the result of an assignment be the formal result of the 24987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// setter call or the value that was passed to the setter? 25087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// 25187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// Different pseudo-object language features use different language rules 25287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// for this. 25387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// The default is to use the set value. Currently, this affects the 25487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// behavior of simple assignments, compound assignments, and prefix 25587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// increment and decrement. 25687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// Postfix increment and decrement always use the getter result as the 25787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// expression result. 25887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// 25987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// If this method returns true, and the set value isn't capturable for 26087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar /// some reason, the result of the expression will be void. 26187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar virtual bool captureSetValueAsResult() const { return true; } 2624b9c2d235fb9449e249d74f48ecfec601650de93John McCall }; 2634b9c2d235fb9449e249d74f48ecfec601650de93John McCall 264e23fb90712233bdfa04387e48b54a7168e23cb3eDmitri Gribenko /// A PseudoOpBuilder for Objective-C \@properties. 2654b9c2d235fb9449e249d74f48ecfec601650de93John McCall class ObjCPropertyOpBuilder : public PseudoOpBuilder { 2664b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyRefExpr *RefExpr; 267b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis ObjCPropertyRefExpr *SyntacticRefExpr; 2684b9c2d235fb9449e249d74f48ecfec601650de93John McCall OpaqueValueExpr *InstanceReceiver; 2694b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCMethodDecl *Getter; 2704b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2714b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCMethodDecl *Setter; 2724b9c2d235fb9449e249d74f48ecfec601650de93John McCall Selector SetterSelector; 273a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian Selector GetterSelector; 2744b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2754b9c2d235fb9449e249d74f48ecfec601650de93John McCall public: 2764b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) : 2774b9c2d235fb9449e249d74f48ecfec601650de93John McCall PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr), 2786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SyntacticRefExpr(nullptr), InstanceReceiver(nullptr), Getter(nullptr), 2796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Setter(nullptr) { 2804b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 2814b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2824b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult buildRValueOperation(Expr *op); 2834b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult buildAssignmentOperation(Scope *Sc, 2844b9c2d235fb9449e249d74f48ecfec601650de93John McCall SourceLocation opLoc, 2854b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperatorKind opcode, 2864b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *LHS, Expr *RHS); 2874b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc, 2884b9c2d235fb9449e249d74f48ecfec601650de93John McCall UnaryOperatorKind opcode, 2894b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *op); 2904b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2914b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool tryBuildGetOfReference(Expr *op, ExprResult &result); 292b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian bool findSetter(bool warn=true); 2934b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool findGetter(); 294176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void DiagnoseUnsupportedPropertyUse(); 2954b9c2d235fb9449e249d74f48ecfec601650de93John McCall 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Expr *rebuildAndCaptureObject(Expr *syntacticBase) override; 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult buildGet() override; 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult buildSet(Expr *op, SourceLocation, bool) override; 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult complete(Expr *SyntacticForm) override; 30058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 30158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool isWeakProperty() const; 3024b9c2d235fb9449e249d74f48ecfec601650de93John McCall }; 303ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 304ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek /// A PseudoOpBuilder for Objective-C array/dictionary indexing. 305ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek class ObjCSubscriptOpBuilder : public PseudoOpBuilder { 306ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCSubscriptRefExpr *RefExpr; 307ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek OpaqueValueExpr *InstanceBase; 308ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek OpaqueValueExpr *InstanceKey; 309ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCMethodDecl *AtIndexGetter; 310ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Selector AtIndexGetterSelector; 311ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 312ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCMethodDecl *AtIndexSetter; 313ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Selector AtIndexSetterSelector; 314ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 315ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek public: 316ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) : 317ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), 318ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek RefExpr(refExpr), 3196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines InstanceBase(nullptr), InstanceKey(nullptr), 3206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AtIndexGetter(nullptr), AtIndexSetter(nullptr) {} 3216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 322ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ExprResult buildRValueOperation(Expr *op); 323ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ExprResult buildAssignmentOperation(Scope *Sc, 324ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SourceLocation opLoc, 325ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek BinaryOperatorKind opcode, 326ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *LHS, Expr *RHS); 327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Expr *rebuildAndCaptureObject(Expr *syntacticBase) override; 328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 329ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool findAtIndexGetter(); 330ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool findAtIndexSetter(); 331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult buildGet() override; 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult buildSet(Expr *op, SourceLocation, bool) override; 334ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek }; 335ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 33676da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall class MSPropertyOpBuilder : public PseudoOpBuilder { 33776da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall MSPropertyRefExpr *RefExpr; 33887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar OpaqueValueExpr *InstanceBase; 33987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SmallVector<Expr *, 4> CallArgs; 34087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 34187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MSPropertyRefExpr *getBaseMSProperty(MSPropertySubscriptExpr *E); 34276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 34376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall public: 34476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) : 34576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), 34687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar RefExpr(refExpr), InstanceBase(nullptr) {} 34787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr) 34887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), 34987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar InstanceBase(nullptr) { 35087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar RefExpr = getBaseMSProperty(refExpr); 35187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 35276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Expr *rebuildAndCaptureObject(Expr *) override; 354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult buildGet() override; 355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExprResult buildSet(Expr *op, SourceLocation, bool) override; 35687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar bool captureSetValueAsResult() const override { return false; } 35776da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall }; 3584b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 3594b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3604b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Capture the given expression in an OpaqueValueExpr. 3614b9c2d235fb9449e249d74f48ecfec601650de93John McCallOpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) { 3624b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Make a new OVE whose source is the given expression. 3634b9c2d235fb9449e249d74f48ecfec601650de93John McCall OpaqueValueExpr *captured = 3644b9c2d235fb9449e249d74f48ecfec601650de93John McCall new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(), 36597df54e0c075bc8d6a869597e771dad0c11a2180Douglas Gregor e->getValueKind(), e->getObjectKind(), 36697df54e0c075bc8d6a869597e771dad0c11a2180Douglas Gregor e); 3674b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3684b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Make sure we bind that in the semantics. 3694b9c2d235fb9449e249d74f48ecfec601650de93John McCall addSemanticExpr(captured); 3704b9c2d235fb9449e249d74f48ecfec601650de93John McCall return captured; 3714b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 3724b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3734b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Capture the given expression as the result of this pseudo-object 3744b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// operation. This routine is safe against expressions which may 3754b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// already be captured. 3764b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// 37770517ca5c07c4b41ff8662b94ee22047b0299f8cDmitri Gribenko/// \returns the captured expression, which will be the 3784b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// same as the input if the input was already captured 3794b9c2d235fb9449e249d74f48ecfec601650de93John McCallOpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) { 3804b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(ResultIndex == PseudoObjectExpr::NoResult); 3814b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3824b9c2d235fb9449e249d74f48ecfec601650de93John McCall // If the expression hasn't already been captured, just capture it 3834b9c2d235fb9449e249d74f48ecfec601650de93John McCall // and set the new semantic 3844b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!isa<OpaqueValueExpr>(e)) { 3854b9c2d235fb9449e249d74f48ecfec601650de93John McCall OpaqueValueExpr *cap = capture(e); 3864b9c2d235fb9449e249d74f48ecfec601650de93John McCall setResultToLastSemantic(); 3874b9c2d235fb9449e249d74f48ecfec601650de93John McCall return cap; 3884b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 3894b9c2d235fb9449e249d74f48ecfec601650de93John McCall 3904b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Otherwise, it must already be one of our semantic expressions; 3914b9c2d235fb9449e249d74f48ecfec601650de93John McCall // set ResultIndex to its index. 3924b9c2d235fb9449e249d74f48ecfec601650de93John McCall unsigned index = 0; 3934b9c2d235fb9449e249d74f48ecfec601650de93John McCall for (;; ++index) { 3944b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(index < Semantics.size() && 3954b9c2d235fb9449e249d74f48ecfec601650de93John McCall "captured expression not found in semantics!"); 3964b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (e == Semantics[index]) break; 3974b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 3984b9c2d235fb9449e249d74f48ecfec601650de93John McCall ResultIndex = index; 3994b9c2d235fb9449e249d74f48ecfec601650de93John McCall return cast<OpaqueValueExpr>(e); 4004b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 4014b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4024b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// The routine which creates the final PseudoObjectExpr. 4034b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult PseudoOpBuilder::complete(Expr *syntactic) { 4044b9c2d235fb9449e249d74f48ecfec601650de93John McCall return PseudoObjectExpr::Create(S.Context, syntactic, 4054b9c2d235fb9449e249d74f48ecfec601650de93John McCall Semantics, ResultIndex); 4064b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 4074b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4084b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// The main skeleton for building an r-value operation. 4094b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) { 4104b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *syntacticBase = rebuildAndCaptureObject(op); 4114b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4124b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult getExpr = buildGet(); 4134b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (getExpr.isInvalid()) return ExprError(); 414c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines addResultSemanticExpr(getExpr.get()); 4154b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4164b9c2d235fb9449e249d74f48ecfec601650de93John McCall return complete(syntacticBase); 4174b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 4184b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4194b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// The basic skeleton for building a simple or compound 4204b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// assignment operation. 4214b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult 4224b9c2d235fb9449e249d74f48ecfec601650de93John McCallPseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, 4234b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperatorKind opcode, 4244b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *LHS, Expr *RHS) { 4254b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(BinaryOperator::isAssignmentOp(opcode)); 4264b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4274b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *syntacticLHS = rebuildAndCaptureObject(LHS); 4284b9c2d235fb9449e249d74f48ecfec601650de93John McCall OpaqueValueExpr *capturedRHS = capture(RHS); 4294b9c2d235fb9449e249d74f48ecfec601650de93John McCall 43087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // In some very specific cases, semantic analysis of the RHS as an 43187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // expression may require it to be rewritten. In these cases, we 43287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // cannot safely keep the OVE around. Fortunately, we don't really 43387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // need to: we don't use this particular OVE in multiple places, and 43487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // no clients rely that closely on matching up expressions in the 43587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar // semantic expression with expressions from the syntactic form. 43687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Expr *semanticRHS = capturedRHS; 43787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (RHS->hasPlaceholderType() || isa<InitListExpr>(RHS)) { 43887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar semanticRHS = RHS; 43987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Semantics.pop_back(); 44087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 44187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 4424b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *syntactic; 4434b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4444b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult result; 4454b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (opcode == BO_Assign) { 44687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar result = semanticRHS; 4474b9c2d235fb9449e249d74f48ecfec601650de93John McCall syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS, 4484b9c2d235fb9449e249d74f48ecfec601650de93John McCall opcode, capturedRHS->getType(), 4494b9c2d235fb9449e249d74f48ecfec601650de93John McCall capturedRHS->getValueKind(), 450be9af1288881110e406b87914162eaa59f1e5918Lang Hames OK_Ordinary, opcLoc, false); 4514b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 4524b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult opLHS = buildGet(); 4534b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (opLHS.isInvalid()) return ExprError(); 4544b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4554b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Build an ordinary, non-compound operation. 4564b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperatorKind nonCompound = 4574b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperator::getOpForCompoundAssignment(opcode); 45887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar result = S.BuildBinOp(Sc, opcLoc, nonCompound, opLHS.get(), semanticRHS); 4594b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 4604b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4614b9c2d235fb9449e249d74f48ecfec601650de93John McCall syntactic = 4624b9c2d235fb9449e249d74f48ecfec601650de93John McCall new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode, 4634b9c2d235fb9449e249d74f48ecfec601650de93John McCall result.get()->getType(), 4644b9c2d235fb9449e249d74f48ecfec601650de93John McCall result.get()->getValueKind(), 4654b9c2d235fb9449e249d74f48ecfec601650de93John McCall OK_Ordinary, 4664b9c2d235fb9449e249d74f48ecfec601650de93John McCall opLHS.get()->getType(), 4674b9c2d235fb9449e249d74f48ecfec601650de93John McCall result.get()->getType(), 468be9af1288881110e406b87914162eaa59f1e5918Lang Hames opcLoc, false); 4694b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 4704b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4714b9c2d235fb9449e249d74f48ecfec601650de93John McCall // The result of the assignment, if not void, is the value set into 4724b9c2d235fb9449e249d74f48ecfec601650de93John McCall // the l-value. 47387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar result = buildSet(result.get(), opcLoc, captureSetValueAsResult()); 4744b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 475c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines addSemanticExpr(result.get()); 47687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (!captureSetValueAsResult() && !result.get()->getType()->isVoidType() && 47787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) 47887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar setResultToLastSemantic(); 4794b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4804b9c2d235fb9449e249d74f48ecfec601650de93John McCall return complete(syntactic); 4814b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 4824b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4834b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// The basic skeleton for building an increment or decrement 4844b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// operation. 4854b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult 4864b9c2d235fb9449e249d74f48ecfec601650de93John McCallPseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, 4874b9c2d235fb9449e249d74f48ecfec601650de93John McCall UnaryOperatorKind opcode, 4884b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *op) { 4894b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(UnaryOperator::isIncrementDecrementOp(opcode)); 4904b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4914b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *syntacticOp = rebuildAndCaptureObject(op); 4924b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4934b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Load the value. 4944b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult result = buildGet(); 4954b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 4964b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4974b9c2d235fb9449e249d74f48ecfec601650de93John McCall QualType resultType = result.get()->getType(); 4984b9c2d235fb9449e249d74f48ecfec601650de93John McCall 4994b9c2d235fb9449e249d74f48ecfec601650de93John McCall // That's the postfix result. 500d314abeffba04dffc101e4e71cc3a32ddeed4ae6John McCall if (UnaryOperator::isPostfix(opcode) && 501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) { 502c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines result = capture(result.get()); 5034b9c2d235fb9449e249d74f48ecfec601650de93John McCall setResultToLastSemantic(); 5044b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 5054b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5064b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Add or subtract a literal 1. 5074b9c2d235fb9449e249d74f48ecfec601650de93John McCall llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1); 5084b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy, 5094b9c2d235fb9449e249d74f48ecfec601650de93John McCall GenericLoc); 5104b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5114b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (UnaryOperator::isIncrementOp(opcode)) { 512c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one); 5134b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 514c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one); 5154b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 5164b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 5174b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5184b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Store that back into the result. The value stored is the result 5194b9c2d235fb9449e249d74f48ecfec601650de93John McCall // of a prefix operation. 52087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode) && 52187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar captureSetValueAsResult()); 5224b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 523c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines addSemanticExpr(result.get()); 52487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (UnaryOperator::isPrefix(opcode) && !captureSetValueAsResult() && 52587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar !result.get()->getType()->isVoidType() && 52687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) 52787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar setResultToLastSemantic(); 5284b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5294b9c2d235fb9449e249d74f48ecfec601650de93John McCall UnaryOperator *syntactic = 5304b9c2d235fb9449e249d74f48ecfec601650de93John McCall new (S.Context) UnaryOperator(syntacticOp, opcode, resultType, 5314b9c2d235fb9449e249d74f48ecfec601650de93John McCall VK_LValue, OK_Ordinary, opcLoc); 5324b9c2d235fb9449e249d74f48ecfec601650de93John McCall return complete(syntactic); 5334b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 5344b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5354b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5364b9c2d235fb9449e249d74f48ecfec601650de93John McCall//===----------------------------------------------------------------------===// 5374b9c2d235fb9449e249d74f48ecfec601650de93John McCall// Objective-C @property and implicit property references 5384b9c2d235fb9449e249d74f48ecfec601650de93John McCall//===----------------------------------------------------------------------===// 5394b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5404b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Look up a method in the receiver type of an Objective-C property 5414b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// reference. 5423c3b7f90a863af43fa63043d396553ecf205351cJohn McCallstatic ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel, 5433c3b7f90a863af43fa63043d396553ecf205351cJohn McCall const ObjCPropertyRefExpr *PRE) { 5443c3b7f90a863af43fa63043d396553ecf205351cJohn McCall if (PRE->isObjectReceiver()) { 545aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer const ObjCObjectPointerType *PT = 546aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer PRE->getBase()->getType()->castAs<ObjCObjectPointerType>(); 5474b9c2d235fb9449e249d74f48ecfec601650de93John McCall 5484b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Special case for 'self' in class method implementations. 5494b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (PT->isObjCClassType() && 5504b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) { 5514b9c2d235fb9449e249d74f48ecfec601650de93John McCall // This cast is safe because isSelfExpr is only true within 5524b9c2d235fb9449e249d74f48ecfec601650de93John McCall // methods. 5534b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCMethodDecl *method = 5544b9c2d235fb9449e249d74f48ecfec601650de93John McCall cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor()); 5554b9c2d235fb9449e249d74f48ecfec601650de93John McCall return S.LookupMethodInObjectType(sel, 5564b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.Context.getObjCInterfaceType(method->getClassInterface()), 5574b9c2d235fb9449e249d74f48ecfec601650de93John McCall /*instance*/ false); 5584b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 5594b9c2d235fb9449e249d74f48ecfec601650de93John McCall 560aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true); 5613c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 5623c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 563aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer if (PRE->isSuperReceiver()) { 564aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer if (const ObjCObjectPointerType *PT = 565aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>()) 566aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true); 567aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer 568aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false); 569aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer } 570aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer 571aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer assert(PRE->isClassReceiver() && "Invalid expression"); 572aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver()); 573aa9807a85959ffbdc5d9f649d7b24b9b2056d2cdBenjamin Kramer return S.LookupMethodInObjectType(sel, IT, false); 5743c3b7f90a863af43fa63043d396553ecf205351cJohn McCall} 5753c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 57658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosebool ObjCPropertyOpBuilder::isWeakProperty() const { 57758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose QualType T; 57858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (RefExpr->isExplicitProperty()) { 57958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty(); 58058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak) 5814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar return true; 58258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 58358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose T = Prop->getType(); 58458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } else if (Getter) { 585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines T = Getter->getReturnType(); 58658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } else { 58758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return false; 58858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 58958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 59058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return T.getObjCLifetime() == Qualifiers::OCL_Weak; 59158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose} 59258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 5934b9c2d235fb9449e249d74f48ecfec601650de93John McCallbool ObjCPropertyOpBuilder::findGetter() { 5944b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (Getter) return true; 5954b9c2d235fb9449e249d74f48ecfec601650de93John McCall 596dc4df51d32dea56fbec79037570832dffbcc14e6John McCall // For implicit properties, just trust the lookup we already did. 597dc4df51d32dea56fbec79037570832dffbcc14e6John McCall if (RefExpr->isImplicitProperty()) { 598a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian if ((Getter = RefExpr->getImplicitPropertyGetter())) { 599a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian GetterSelector = Getter->getSelector(); 600a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian return true; 601a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian } 602a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian else { 603a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian // Must build the getter selector the hard way. 604a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter(); 605a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian assert(setter && "both setter and getter are null - cannot happen"); 606a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian IdentifierInfo *setterName = 607a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian setter->getSelector().getIdentifierInfoForSlot(0); 608c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines IdentifierInfo *getterName = 609c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines &S.Context.Idents.get(setterName->getName().substr(3)); 610a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian GetterSelector = 611a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian S.PP.getSelectorTable().getNullarySelector(getterName); 612a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian return false; 613a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian } 614dc4df51d32dea56fbec79037570832dffbcc14e6John McCall } 615dc4df51d32dea56fbec79037570832dffbcc14e6John McCall 616dc4df51d32dea56fbec79037570832dffbcc14e6John McCall ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); 617dc4df51d32dea56fbec79037570832dffbcc14e6John McCall Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr); 6186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return (Getter != nullptr); 6194b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 6204b9c2d235fb9449e249d74f48ecfec601650de93John McCall 6214b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Try to find the most accurate setter declaration for the property 6224b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// reference. 6234b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// 6244b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// \return true if a setter was found, in which case Setter 625b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanianbool ObjCPropertyOpBuilder::findSetter(bool warn) { 6264b9c2d235fb9449e249d74f48ecfec601650de93John McCall // For implicit properties, just trust the lookup we already did. 6274b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (RefExpr->isImplicitProperty()) { 6284b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) { 6294b9c2d235fb9449e249d74f48ecfec601650de93John McCall Setter = setter; 6304b9c2d235fb9449e249d74f48ecfec601650de93John McCall SetterSelector = setter->getSelector(); 6314b9c2d235fb9449e249d74f48ecfec601650de93John McCall return true; 6323c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } else { 6334b9c2d235fb9449e249d74f48ecfec601650de93John McCall IdentifierInfo *getterName = 6344b9c2d235fb9449e249d74f48ecfec601650de93John McCall RefExpr->getImplicitPropertyGetter()->getSelector() 6354b9c2d235fb9449e249d74f48ecfec601650de93John McCall .getIdentifierInfoForSlot(0); 6364b9c2d235fb9449e249d74f48ecfec601650de93John McCall SetterSelector = 63780e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(), 63880e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl S.PP.getSelectorTable(), 63980e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl getterName); 6404b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 6413c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 6423c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 6433c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 6444b9c2d235fb9449e249d74f48ecfec601650de93John McCall // For explicit properties, this is more involved. 6454b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); 6464b9c2d235fb9449e249d74f48ecfec601650de93John McCall SetterSelector = prop->getSetterName(); 6474b9c2d235fb9449e249d74f48ecfec601650de93John McCall 6484b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Do a normal method lookup first. 6494b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCMethodDecl *setter = 6504b9c2d235fb9449e249d74f48ecfec601650de93John McCall LookupMethodInReceiverType(S, SetterSelector, RefExpr)) { 6511e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose if (setter->isPropertyAccessor() && warn) 652b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian if (const ObjCInterfaceDecl *IFace = 653b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) { 654176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StringRef thisPropertyName = prop->getName(); 6553f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose // Try flipping the case of the first character. 656b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian char front = thisPropertyName.front(); 6573f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose front = isLowercase(front) ? toUppercase(front) : toLowercase(front); 658b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian SmallString<100> PropertyName = thisPropertyName; 659b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian PropertyName[0] = front; 660b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName); 6614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration( 6624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar AltMember, prop->getQueryKind())) 663b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) { 664cba0ebce65667f76e291346d377f402579743ceaFariborz Jahanian S.Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use) 665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << prop << prop1 << setter->getSelector(); 666b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian S.Diag(prop->getLocation(), diag::note_property_declare); 667b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian S.Diag(prop1->getLocation(), diag::note_property_declare); 668b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian } 669b5b155cb8bd2460693572bab5ce14dabf1a27d2fFariborz Jahanian } 6704b9c2d235fb9449e249d74f48ecfec601650de93John McCall Setter = setter; 6714b9c2d235fb9449e249d74f48ecfec601650de93John McCall return true; 6724b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 6734b9c2d235fb9449e249d74f48ecfec601650de93John McCall 6744b9c2d235fb9449e249d74f48ecfec601650de93John McCall // That can fail in the somewhat crazy situation that we're 6754b9c2d235fb9449e249d74f48ecfec601650de93John McCall // type-checking a message send within the @interface declaration 6764b9c2d235fb9449e249d74f48ecfec601650de93John McCall // that declared the @property. But it's not clear that that's 6774b9c2d235fb9449e249d74f48ecfec601650de93John McCall // valuable to support. 6784b9c2d235fb9449e249d74f48ecfec601650de93John McCall 6794b9c2d235fb9449e249d74f48ecfec601650de93John McCall return false; 6804b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 6814b9c2d235fb9449e249d74f48ecfec601650de93John McCall 682176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() { 683c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (S.getCurLexicalContext()->isObjCContainer() && 684c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl && 685c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) { 686c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) { 687c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.Diag(RefExpr->getLocation(), 688c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines diag::err_property_function_in_objc_container); 689c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.Diag(prop->getLocation(), diag::note_property_declare); 690c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 691c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 692c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 693c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 6944b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Capture the base object of an Objective-C property expression. 6954b9c2d235fb9449e249d74f48ecfec601650de93John McCallExpr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { 6966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(InstanceReceiver == nullptr); 6974b9c2d235fb9449e249d74f48ecfec601650de93John McCall 6984b9c2d235fb9449e249d74f48ecfec601650de93John McCall // If we have a base, capture it in an OVE and rebuild the syntactic 6994b9c2d235fb9449e249d74f48ecfec601650de93John McCall // form to use the OVE as its base. 7004b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (RefExpr->isObjectReceiver()) { 7014b9c2d235fb9449e249d74f48ecfec601650de93John McCall InstanceReceiver = capture(RefExpr->getBase()); 70287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar syntacticBase = Rebuilder(S, [=](Expr *, unsigned) -> Expr * { 70387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return InstanceReceiver; 70487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }).rebuild(syntacticBase); 7054b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 7064b9c2d235fb9449e249d74f48ecfec601650de93John McCall 707b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis if (ObjCPropertyRefExpr * 708b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens())) 709b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis SyntacticRefExpr = refE; 710b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis 7114b9c2d235fb9449e249d74f48ecfec601650de93John McCall return syntacticBase; 7124b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 7134b9c2d235fb9449e249d74f48ecfec601650de93John McCall 7144b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Load from an Objective-C property reference. 7154b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult ObjCPropertyOpBuilder::buildGet() { 7164b9c2d235fb9449e249d74f48ecfec601650de93John McCall findGetter(); 717176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Getter) { 718176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DiagnoseUnsupportedPropertyUse(); 719176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ExprError(); 720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 721b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis 722b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis if (SyntacticRefExpr) 723b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis SyntacticRefExpr->setIsMessagingGetter(); 724b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis 72587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType receiverType = RefExpr->getReceiverType(S.Context); 726c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Getter->isImplicit()) 727c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true); 7284b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Build a message-send. 7294b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult msg; 7306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) || 7316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines RefExpr->isObjectReceiver()) { 7324b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(InstanceReceiver || RefExpr->isSuperReceiver()); 733746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, 734746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis GenericLoc, Getter->getSelector(), 73562ed889272d7e9da8e367d8682fdcdeeec0d83b5Dmitri Gribenko Getter, None); 7364b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 737746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), 73862ed889272d7e9da8e367d8682fdcdeeec0d83b5Dmitri Gribenko GenericLoc, Getter->getSelector(), 73962ed889272d7e9da8e367d8682fdcdeeec0d83b5Dmitri Gribenko Getter, None); 7404b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 7414b9c2d235fb9449e249d74f48ecfec601650de93John McCall return msg; 7423c3b7f90a863af43fa63043d396553ecf205351cJohn McCall} 7433c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 7444b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Store to an Objective-C property reference. 7454b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// 74670517ca5c07c4b41ff8662b94ee22047b0299f8cDmitri Gribenko/// \param captureSetValueAsResult If true, capture the actual 7474b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// value being set as the value of the property operation. 7484b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, 7494b9c2d235fb9449e249d74f48ecfec601650de93John McCall bool captureSetValueAsResult) { 750176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!findSetter(false)) { 751176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines DiagnoseUnsupportedPropertyUse(); 752176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return ExprError(); 753176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 7544b9c2d235fb9449e249d74f48ecfec601650de93John McCall 755b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis if (SyntacticRefExpr) 756b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis SyntacticRefExpr->setIsMessagingSetter(); 757b085d898bdfe35097eba45f4072b0f6865f561dcArgyrios Kyrtzidis 75887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType receiverType = RefExpr->getReceiverType(S.Context); 7593c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 7604b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Use assignment constraints when possible; they give us better 7614b9c2d235fb9449e249d74f48ecfec601650de93John McCall // diagnostics. "When possible" basically means anything except a 7624b9c2d235fb9449e249d74f48ecfec601650de93John McCall // C++ class type. 7634e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) { 76487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType paramType = (*Setter->param_begin())->getType() 76587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar .substObjCMemberType( 76687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar receiverType, 76787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Setter->getDeclContext(), 76887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ObjCSubstitutionContext::Parameter); 7694e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) { 7704b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult opResult = op; 7714b9c2d235fb9449e249d74f48ecfec601650de93John McCall Sema::AssignConvertType assignResult 7724b9c2d235fb9449e249d74f48ecfec601650de93John McCall = S.CheckSingleAssignmentConstraints(paramType, opResult); 7734b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType, 7744b9c2d235fb9449e249d74f48ecfec601650de93John McCall op->getType(), opResult.get(), 7754b9c2d235fb9449e249d74f48ecfec601650de93John McCall Sema::AA_Assigning)) 7764b9c2d235fb9449e249d74f48ecfec601650de93John McCall return ExprError(); 7774b9c2d235fb9449e249d74f48ecfec601650de93John McCall 778c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines op = opResult.get(); 7794b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(op && "successful assignment left argument invalid?"); 7803c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 7814b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 7823c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 7834b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Arguments. 7844b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *args[] = { op }; 7853c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 7864b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Build a message-send. 7874b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult msg; 788c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!Setter->isImplicit()) 789c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true); 7906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) || 7916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines RefExpr->isObjectReceiver()) { 792746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, 793746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis GenericLoc, SetterSelector, Setter, 794746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis MultiExprArg(args, 1)); 7954b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 796746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), 797746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis GenericLoc, 798746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis SetterSelector, Setter, 799746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis MultiExprArg(args, 1)); 8004b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 8013c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 8024b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!msg.isInvalid() && captureSetValueAsResult) { 8034b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCMessageExpr *msgExpr = 8044b9c2d235fb9449e249d74f48ecfec601650de93John McCall cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit()); 8054b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *arg = msgExpr->getArg(0); 806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CanCaptureValue(arg)) 80725f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman msgExpr->setArg(0, captureValueAsResult(arg)); 8084b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 8093c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 8104b9c2d235fb9449e249d74f48ecfec601650de93John McCall return msg; 8114b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 8124b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8134b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// @property-specific behavior for doing lvalue-to-rvalue conversion. 8144b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) { 8154b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Explicit properties always have getters, but implicit ones don't. 8164b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Check that before proceeding. 817a70779f6b9a8135c3459bdeb1f0197b82ea0cb2aEli Friedman if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) { 8184b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.Diag(RefExpr->getLocation(), diag::err_getter_not_found) 819a70779f6b9a8135c3459bdeb1f0197b82ea0cb2aEli Friedman << RefExpr->getSourceRange(); 8204b9c2d235fb9449e249d74f48ecfec601650de93John McCall return ExprError(); 8214b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 8224b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8234b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult result = PseudoOpBuilder::buildRValueOperation(op); 8244b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 8254b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8264b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType()) 8274b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(), 8284b9c2d235fb9449e249d74f48ecfec601650de93John McCall Getter, RefExpr->getLocation()); 8294b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8304b9c2d235fb9449e249d74f48ecfec601650de93John McCall // As a special case, if the method returns 'id', try to get 8314b9c2d235fb9449e249d74f48ecfec601650de93John McCall // a better type from the property. 832c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (RefExpr->isExplicitProperty() && result.get()->isRValue()) { 83387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType receiverType = RefExpr->getReceiverType(S.Context); 83487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar QualType propType = RefExpr->getExplicitProperty() 83587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ->getUsageType(receiverType); 836c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (result.get()->getType()->isObjCIdType()) { 837c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (const ObjCObjectPointerType *ptr 838c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines = propType->getAs<ObjCObjectPointerType>()) { 839c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!ptr->isObjCIdType()) 840c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines result = S.ImpCastExprToType(result.get(), propType, CK_BitCast); 841c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 842c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines } 843c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (S.getLangOpts().ObjCAutoRefCount) { 844c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Qualifiers::ObjCLifetime LT = propType.getObjCLifetime(); 845c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (LT == Qualifiers::OCL_Weak) 846c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation())) 847c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.getCurFunction()->markSafeWeakUse(RefExpr); 8483c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 8494b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 8504b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8514b9c2d235fb9449e249d74f48ecfec601650de93John McCall return result; 8523c3b7f90a863af43fa63043d396553ecf205351cJohn McCall} 8533c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 8544b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Try to build this as a call to a getter that returns a reference. 8554b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// 8564b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// \return true if it was possible, whether or not it actually 8574b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// succeeded 8584b9c2d235fb9449e249d74f48ecfec601650de93John McCallbool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op, 8594b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult &result) { 8604e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus) return false; 8614b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8624b9c2d235fb9449e249d74f48ecfec601650de93John McCall findGetter(); 863176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Getter) { 864176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // The property has no setter and no getter! This can happen if the type is 865176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // invalid. Error have already been reported. 866176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines result = ExprError(); 867176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 868176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 8694b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8704b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Only do this if the getter returns an l-value reference type. 871651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType resultType = Getter->getReturnType(); 8724b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!resultType->isLValueReferenceType()) return false; 8734b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8744b9c2d235fb9449e249d74f48ecfec601650de93John McCall result = buildRValueOperation(op); 8754b9c2d235fb9449e249d74f48ecfec601650de93John McCall return true; 8764b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 8774b9c2d235fb9449e249d74f48ecfec601650de93John McCall 8784b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// @property-specific behavior for doing assignments. 8794b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult 8804b9c2d235fb9449e249d74f48ecfec601650de93John McCallObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc, 8814b9c2d235fb9449e249d74f48ecfec601650de93John McCall SourceLocation opcLoc, 8824b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperatorKind opcode, 8834b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *LHS, Expr *RHS) { 8844b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(BinaryOperator::isAssignmentOp(opcode)); 8853c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 8863c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // If there's no setter, we have no choice but to try to assign to 8873c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // the result of the getter. 8884b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!findSetter()) { 8894b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult result; 8904b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (tryBuildGetOfReference(LHS, result)) { 8914b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 892c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS); 8933c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 8943c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 8953c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // Otherwise, it's an error. 8964b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.Diag(opcLoc, diag::err_nosetter_property_assignment) 8974b9c2d235fb9449e249d74f48ecfec601650de93John McCall << unsigned(RefExpr->isImplicitProperty()) 8984b9c2d235fb9449e249d74f48ecfec601650de93John McCall << SetterSelector 8994b9c2d235fb9449e249d74f48ecfec601650de93John McCall << LHS->getSourceRange() << RHS->getSourceRange(); 9003c3b7f90a863af43fa63043d396553ecf205351cJohn McCall return ExprError(); 9013c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 9023c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9034b9c2d235fb9449e249d74f48ecfec601650de93John McCall // If there is a setter, we definitely want to use it. 9044b9c2d235fb9449e249d74f48ecfec601650de93John McCall 9054b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Verify that we can do a compound assignment. 9064b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (opcode != BO_Assign && !findGetter()) { 9074b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment) 9084b9c2d235fb9449e249d74f48ecfec601650de93John McCall << LHS->getSourceRange() << RHS->getSourceRange(); 9093c3b7f90a863af43fa63043d396553ecf205351cJohn McCall return ExprError(); 9103c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 9113c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9124b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult result = 9134b9c2d235fb9449e249d74f48ecfec601650de93John McCall PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS); 9143c3b7f90a863af43fa63043d396553ecf205351cJohn McCall if (result.isInvalid()) return ExprError(); 9153c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9164b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Various warnings about property assignments in ARC. 9174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) { 9184b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS); 9194b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.checkUnsafeExprAssigns(opcLoc, LHS, RHS); 9204b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 9214b9c2d235fb9449e249d74f48ecfec601650de93John McCall 9223c3b7f90a863af43fa63043d396553ecf205351cJohn McCall return result; 9233c3b7f90a863af43fa63043d396553ecf205351cJohn McCall} 9243c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9254b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// @property-specific behavior for doing increments and decrements. 9264b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult 9274b9c2d235fb9449e249d74f48ecfec601650de93John McCallObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, 9284b9c2d235fb9449e249d74f48ecfec601650de93John McCall UnaryOperatorKind opcode, 9294b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *op) { 9303c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // If there's no setter, we have no choice but to try to assign to 9313c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // the result of the getter. 9324b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!findSetter()) { 9334b9c2d235fb9449e249d74f48ecfec601650de93John McCall ExprResult result; 9344b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (tryBuildGetOfReference(op, result)) { 9354b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (result.isInvalid()) return ExprError(); 936c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get()); 9373c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 9383c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9393c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // Otherwise, it's an error. 9404b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.Diag(opcLoc, diag::err_nosetter_property_incdec) 9414b9c2d235fb9449e249d74f48ecfec601650de93John McCall << unsigned(RefExpr->isImplicitProperty()) 9424b9c2d235fb9449e249d74f48ecfec601650de93John McCall << unsigned(UnaryOperator::isDecrementOp(opcode)) 9434b9c2d235fb9449e249d74f48ecfec601650de93John McCall << SetterSelector 9444b9c2d235fb9449e249d74f48ecfec601650de93John McCall << op->getSourceRange(); 9453c3b7f90a863af43fa63043d396553ecf205351cJohn McCall return ExprError(); 9463c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 9473c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9483c3b7f90a863af43fa63043d396553ecf205351cJohn McCall // If there is a setter, we definitely want to use it. 9493c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9504b9c2d235fb9449e249d74f48ecfec601650de93John McCall // We also need a getter. 9514b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (!findGetter()) { 9524b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(RefExpr->isImplicitProperty()); 9534b9c2d235fb9449e249d74f48ecfec601650de93John McCall S.Diag(opcLoc, diag::err_nogetter_property_incdec) 9544b9c2d235fb9449e249d74f48ecfec601650de93John McCall << unsigned(UnaryOperator::isDecrementOp(opcode)) 955a2c91e75c944e3599fb108db600f91c47c8b4342Fariborz Jahanian << GetterSelector 9564b9c2d235fb9449e249d74f48ecfec601650de93John McCall << op->getSourceRange(); 9574b9c2d235fb9449e249d74f48ecfec601650de93John McCall return ExprError(); 9584b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 9593c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 9604b9c2d235fb9449e249d74f48ecfec601650de93John McCall return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op); 9614b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 9623c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 96358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) { 964c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() && 965c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, 966c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SyntacticForm->getLocStart())) 967569b4ad6506960f1a7f191107c185cb1566a7fbbFariborz Jahanian S.recordUseOfEvaluatedWeak(SyntacticRefExpr, 968569b4ad6506960f1a7f191107c185cb1566a7fbbFariborz Jahanian SyntacticRefExpr->isMessagingGetter()); 96958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 97058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return PseudoOpBuilder::complete(SyntacticForm); 97158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose} 97258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 973ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek// ObjCSubscript build stuff. 974ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek// 975ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 976ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// objective-c subscripting-specific behavior for doing lvalue-to-rvalue 977ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// conversion. 978ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// FIXME. Remove this routine if it is proven that no additional 979ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// specifity is needed. 980ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) { 981ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ExprResult result = PseudoOpBuilder::buildRValueOperation(op); 982ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (result.isInvalid()) return ExprError(); 983ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return result; 984ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 985ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 986ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// objective-c subscripting-specific behavior for doing assignments. 987ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult 988ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc, 989ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SourceLocation opcLoc, 990ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek BinaryOperatorKind opcode, 991ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *LHS, Expr *RHS) { 992ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek assert(BinaryOperator::isAssignmentOp(opcode)); 993ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // There must be a method to do the Index'ed assignment. 994ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!findAtIndexSetter()) 995ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ExprError(); 996ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 997ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Verify that we can do a compound assignment. 998ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (opcode != BO_Assign && !findAtIndexGetter()) 999ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ExprError(); 1000ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1001ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ExprResult result = 1002ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS); 1003ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (result.isInvalid()) return ExprError(); 1004ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1005ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Various warnings about objc Index'ed assignments in ARC. 10064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) { 1007ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS); 1008ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.checkUnsafeExprAssigns(opcLoc, LHS, RHS); 1009ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1010ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1011ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return result; 1012ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1013ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1014ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// Capture the base object of an Objective-C Index'ed expression. 1015ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExpr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { 10166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(InstanceBase == nullptr); 10176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1018ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Capture base expression in an OVE and rebuild the syntactic 1019ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // form to use the OVE as its base expression. 1020ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek InstanceBase = capture(RefExpr->getBaseExpr()); 1021ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek InstanceKey = capture(RefExpr->getKeyExpr()); 102287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 1023ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek syntacticBase = 102487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { 102587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar switch (Idx) { 102687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case 0: 102787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return InstanceBase; 102887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case 1: 102987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return InstanceKey; 103087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar default: 103187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar llvm_unreachable("Unexpected index for ObjCSubscriptExpr"); 103287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 103387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }).rebuild(syntacticBase); 103487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 1035ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return syntacticBase; 1036ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1037ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1038ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// CheckSubscriptingKind - This routine decide what type 1039ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// of indexing represented by "FromE" is being done. 1040ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekSema::ObjCSubscriptKind 1041ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Sema::CheckSubscriptingKind(Expr *FromE) { 1042ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // If the expression already has integral or enumeration type, we're golden. 1043ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType T = FromE->getType(); 1044ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (T->isIntegralOrEnumerationType()) 1045ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Array; 1046ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1047ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // If we don't have a class type in C++, there's no way we can get an 1048ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // expression of integral or enumeration type. 1049ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek const RecordType *RecordTy = T->getAs<RecordType>(); 1050176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!RecordTy && 1051176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines (T->isObjCObjectPointerType() || T->isVoidPointerType())) 1052ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // All other scalar cases are assumed to be dictionary indexing which 1053ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // caller handles, with diagnostics if needed. 1054ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Dictionary; 1055a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian if (!getLangOpts().CPlusPlus || 1056a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian !RecordTy || RecordTy->isIncompleteType()) { 1057ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // No indexing can be done. Issue diagnostics and quit. 1058a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian const Expr *IndexExpr = FromE->IgnoreParenImpCasts(); 1059a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian if (isa<StringLiteral>(IndexExpr)) 1060a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer) 1061a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); 1062a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian else 1063a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) 1064a78eca20429e55b041bffcea1938cd0df07a6ebdFariborz Jahanian << T; 1065ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Error; 1066ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1067ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1068ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // We must have a complete class type. 1069ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (RequireCompleteType(FromE->getExprLoc(), T, 1070d10099e5c8238fa0327f03921cf2e3c8975c881eDouglas Gregor diag::err_objc_index_incomplete_class_type, FromE)) 1071ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Error; 1072ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1073ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Look for a conversion to an integral, enumeration type, or 1074ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // objective-C pointer type. 1075ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek int NoIntegrals=0, NoObjCIdPointers=0; 1076ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SmallVector<CXXConversionDecl *, 4> ConversionDecls; 10770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 10780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl()) 10790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines ->getVisibleConversionFunctions()) { 10800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines if (CXXConversionDecl *Conversion = 10810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) { 1082ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType CT = Conversion->getConversionType().getNonReferenceType(); 1083ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (CT->isIntegralOrEnumerationType()) { 1084ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ++NoIntegrals; 1085ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ConversionDecls.push_back(Conversion); 1086ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1087ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else if (CT->isObjCIdType() ||CT->isBlockPointerType()) { 1088ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ++NoObjCIdPointers; 1089ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ConversionDecls.push_back(Conversion); 1090ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1091ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1092ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1093ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (NoIntegrals ==1 && NoObjCIdPointers == 0) 1094ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Array; 1095ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (NoIntegrals == 0 && NoObjCIdPointers == 1) 1096ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Dictionary; 1097ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (NoIntegrals == 0 && NoObjCIdPointers == 0) { 1098ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // No conversion function was found. Issue diagnostic and return. 1099ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) 1100ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek << FromE->getType(); 1101ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Error; 1102ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1103ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion) 1104ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek << FromE->getType(); 1105ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek for (unsigned int i = 0; i < ConversionDecls.size(); i++) 1106ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Diag(ConversionDecls[i]->getLocation(), diag::not_conv_function_declared_at); 1107ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1108ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return OS_Error; 1109ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1110ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1111dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian/// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF 1112dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian/// objects used as dictionary subscript key objects. 1113dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanianstatic void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, 1114dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian Expr *Key) { 1115dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian if (ContainerT.isNull()) 1116dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian return; 1117dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian // dictionary subscripting. 1118dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian // - (id)objectForKeyedSubscript:(id)key; 1119dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian IdentifierInfo *KeyIdents[] = { 1120dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian &S.Context.Idents.get("objectForKeyedSubscript") 1121dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian }; 1122dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); 1123dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT, 1124dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian true /*instance*/); 1125dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian if (!Getter) 1126dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian return; 1127c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType T = Getter->parameters()[0]->getType(); 1128dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian S.CheckObjCARCConversion(Key->getSourceRange(), 1129dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian T, Key, Sema::CCK_ImplicitConversion); 1130dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian} 1131dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian 1132ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenekbool ObjCSubscriptOpBuilder::findAtIndexGetter() { 1133ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (AtIndexGetter) 1134ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return true; 1135ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1136ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *BaseExpr = RefExpr->getBaseExpr(); 1137ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType BaseT = BaseExpr->getType(); 1138ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1139ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType ResultType; 1140ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (const ObjCObjectPointerType *PTy = 1141ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek BaseT->getAs<ObjCObjectPointerType>()) { 1142ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ResultType = PTy->getPointeeType(); 1143ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1144ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Sema::ObjCSubscriptKind Res = 1145ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.CheckSubscriptingKind(RefExpr->getKeyExpr()); 1146dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian if (Res == Sema::OS_Error) { 1147dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian if (S.getLangOpts().ObjCAutoRefCount) 1148dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian CheckKeyForObjCARCConversion(S, ResultType, 1149dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian RefExpr->getKeyExpr()); 1150ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1151dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian } 1152ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool arrayRef = (Res == Sema::OS_Array); 1153ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1154ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (ResultType.isNull()) { 1155ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type) 1156ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek << BaseExpr->getType() << arrayRef; 1157ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1158ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1159ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!arrayRef) { 1160ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // dictionary subscripting. 1161ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // - (id)objectForKeyedSubscript:(id)key; 1162ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek IdentifierInfo *KeyIdents[] = { 1163ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("objectForKeyedSubscript") 1164ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek }; 1165ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); 1166ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1167ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else { 1168ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // - (id)objectAtIndexedSubscript:(size_t)index; 1169ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek IdentifierInfo *KeyIdents[] = { 1170ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("objectAtIndexedSubscript") 1171ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek }; 1172ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1173ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); 1174ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1175ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1176ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType, 1177ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek true /*instance*/); 1178ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool receiverIdType = (BaseT->isObjCIdType() || 1179ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek BaseT->isObjCQualifiedIdType()); 1180ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 11814e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) { 1182ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(), 1183ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SourceLocation(), AtIndexGetterSelector, 1184ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Context.getObjCIdType() /*ReturnType*/, 11856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr /*TypeSourceInfo */, 1186ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Context.getTranslationUnitDecl(), 1187ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek true /*Instance*/, false/*isVariadic*/, 11881e4691b9d8e1bdcc8ef62b323969d702c51b3c08Jordan Rose /*isPropertyAccessor=*/false, 1189ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1190ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCMethodDecl::Required, 1191ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek false); 1192ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter, 1193ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SourceLocation(), SourceLocation(), 1194ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek arrayRef ? &S.Context.Idents.get("index") 1195ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek : &S.Context.Idents.get("key"), 1196ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek arrayRef ? S.Context.UnsignedLongTy 1197ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek : S.Context.getObjCIdType(), 11986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*TInfo=*/nullptr, 1199ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SC_None, 12006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr); 12015543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko AtIndexGetter->setMethodParams(S.Context, Argument, None); 1202ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1203ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1204ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!AtIndexGetter) { 1205ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!receiverIdType) { 1206ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found) 1207ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek << BaseExpr->getType() << 0 << arrayRef; 1208ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1209ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1210ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetter = 1211ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, 1212ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek RefExpr->getSourceRange(), 121358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar true); 1214ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1215ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1216ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (AtIndexGetter) { 1217c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType T = AtIndexGetter->parameters()[0]->getType(); 1218ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if ((arrayRef && !T->isIntegralOrEnumerationType()) || 1219ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek (!arrayRef && !T->isObjCObjectPointerType())) { 1220ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1221ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek arrayRef ? diag::err_objc_subscript_index_type 1222ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek : diag::err_objc_subscript_key_type) << T; 1223c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.Diag(AtIndexGetter->parameters()[0]->getLocation(), 1224ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::note_parameter_type) << T; 1225ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1226ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType R = AtIndexGetter->getReturnType(); 1228ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!R->isObjCObjectPointerType()) { 1229ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1230ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::err_objc_indexing_method_result_type) << R << arrayRef; 1231ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) << 1232ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetter->getDeclName(); 1233ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1234ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1235ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return true; 1236ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1237ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1238ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenekbool ObjCSubscriptOpBuilder::findAtIndexSetter() { 1239ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (AtIndexSetter) 1240ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return true; 1241ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1242ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *BaseExpr = RefExpr->getBaseExpr(); 1243ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType BaseT = BaseExpr->getType(); 1244ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1245ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType ResultType; 1246ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (const ObjCObjectPointerType *PTy = 1247ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek BaseT->getAs<ObjCObjectPointerType>()) { 1248ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ResultType = PTy->getPointeeType(); 1249ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1250ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1251ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Sema::ObjCSubscriptKind Res = 1252ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.CheckSubscriptingKind(RefExpr->getKeyExpr()); 1253dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian if (Res == Sema::OS_Error) { 1254dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian if (S.getLangOpts().ObjCAutoRefCount) 1255dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian CheckKeyForObjCARCConversion(S, ResultType, 1256dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian RefExpr->getKeyExpr()); 1257ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1258dc48305e319c56f6f305c12b9faecdc378dfebdcFariborz Jahanian } 1259ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool arrayRef = (Res == Sema::OS_Array); 1260ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1261ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (ResultType.isNull()) { 1262ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type) 1263ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek << BaseExpr->getType() << arrayRef; 1264ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1265ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1266ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1267ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!arrayRef) { 1268ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // dictionary subscripting. 1269ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // - (void)setObject:(id)object forKeyedSubscript:(id)key; 1270ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek IdentifierInfo *KeyIdents[] = { 1271ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("setObject"), 1272ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("forKeyedSubscript") 1273ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek }; 1274ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents); 1275ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1276ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else { 1277ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index; 1278ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek IdentifierInfo *KeyIdents[] = { 1279ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("setObject"), 1280ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("atIndexedSubscript") 1281ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek }; 1282ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents); 1283ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1284ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType, 1285ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek true /*instance*/); 1286ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1287ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool receiverIdType = (BaseT->isObjCIdType() || 1288ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek BaseT->isObjCQualifiedIdType()); 1289ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 12904e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) { 12916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TypeSourceInfo *ReturnTInfo = nullptr; 1292ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType ReturnType = S.Context.VoidTy; 1293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AtIndexSetter = ObjCMethodDecl::Create( 1294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Context, SourceLocation(), SourceLocation(), AtIndexSetterSelector, 1295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnType, ReturnTInfo, S.Context.getTranslationUnitDecl(), 1296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines true /*Instance*/, false /*isVariadic*/, 1297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*isPropertyAccessor=*/false, 1298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCMethodDecl::Required, false); 1300ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SmallVector<ParmVarDecl *, 2> Params; 1301ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter, 1302ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SourceLocation(), SourceLocation(), 1303ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek &S.Context.Idents.get("object"), 1304ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Context.getObjCIdType(), 13056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*TInfo=*/nullptr, 1306ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SC_None, 13076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr); 1308ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Params.push_back(object); 1309ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter, 1310ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SourceLocation(), SourceLocation(), 1311ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek arrayRef ? &S.Context.Idents.get("index") 1312ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek : &S.Context.Idents.get("key"), 1313ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek arrayRef ? S.Context.UnsignedLongTy 1314ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek : S.Context.getObjCIdType(), 13156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*TInfo=*/nullptr, 1316ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek SC_None, 13176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr); 1318ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Params.push_back(key); 13195543169296beeb183b9c9392debc774fcf493eebDmitri Gribenko AtIndexSetter->setMethodParams(S.Context, Params, None); 1320ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1321ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1322ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!AtIndexSetter) { 1323ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!receiverIdType) { 1324ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(BaseExpr->getExprLoc(), 1325ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::err_objc_subscript_method_not_found) 1326ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek << BaseExpr->getType() << 1 << arrayRef; 1327ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return false; 1328ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1329ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexSetter = 1330ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, 1331ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek RefExpr->getSourceRange(), 133258878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar true); 1333ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1334ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1335ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool err = false; 1336ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (AtIndexSetter && arrayRef) { 1337c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType T = AtIndexSetter->parameters()[1]->getType(); 1338ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!T->isIntegralOrEnumerationType()) { 1339ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1340ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::err_objc_subscript_index_type) << T; 1341c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.Diag(AtIndexSetter->parameters()[1]->getLocation(), 1342ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::note_parameter_type) << T; 1343ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek err = true; 1344ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1345c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines T = AtIndexSetter->parameters()[0]->getType(); 1346ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!T->isObjCObjectPointerType()) { 1347ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 1348ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::err_objc_subscript_object_type) << T << arrayRef; 1349c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.Diag(AtIndexSetter->parameters()[0]->getLocation(), 1350ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::note_parameter_type) << T; 1351ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek err = true; 1352ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1353ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1354ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else if (AtIndexSetter && !arrayRef) 1355ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek for (unsigned i=0; i <2; i++) { 1356c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines QualType T = AtIndexSetter->parameters()[i]->getType(); 1357ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!T->isObjCObjectPointerType()) { 1358ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (i == 1) 1359ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1360ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::err_objc_subscript_key_type) << T; 1361ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else 1362ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 1363ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::err_objc_subscript_dic_object_type) << T; 1364c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.Diag(AtIndexSetter->parameters()[i]->getLocation(), 1365ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek diag::note_parameter_type) << T; 1366ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek err = true; 1367ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1368ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1369ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1370ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return !err; 1371ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1372ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1373ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek// Get the object at "Index" position in the container. 1374ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek// [BaseExpr objectAtIndexedSubscript : IndexExpr]; 1375ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult ObjCSubscriptOpBuilder::buildGet() { 1376ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!findAtIndexGetter()) 1377ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ExprError(); 1378ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1379ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType receiverType = InstanceBase->getType(); 1380ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1381ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Build a message-send. 1382ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ExprResult msg; 1383ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *Index = InstanceKey; 1384ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1385ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Arguments. 1386ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *args[] = { Index }; 1387ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek assert(InstanceBase); 1388c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (AtIndexGetter) 1389c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc); 1390ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType, 1391ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek GenericLoc, 1392ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexGetterSelector, AtIndexGetter, 1393ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek MultiExprArg(args, 1)); 1394ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return msg; 1395ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1396ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1397ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// Store into the container the "op" object at "Index"'ed location 1398ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// by building this messaging expression: 1399ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index; 140070517ca5c07c4b41ff8662b94ee22047b0299f8cDmitri Gribenko/// \param captureSetValueAsResult If true, capture the actual 1401ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek/// value being set as the value of the property operation. 1402ebcb57a8d298862c65043e88b2429591ab3c58d3Ted KremenekExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, 1403ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek bool captureSetValueAsResult) { 1404ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!findAtIndexSetter()) 1405ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ExprError(); 1406c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (AtIndexSetter) 1407c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc); 1408ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek QualType receiverType = InstanceBase->getType(); 1409ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *Index = InstanceKey; 1410ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1411ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Arguments. 1412ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *args[] = { op, Index }; 1413ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1414ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek // Build a message-send. 1415ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType, 1416ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek GenericLoc, 1417ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexSetterSelector, 1418ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek AtIndexSetter, 1419ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek MultiExprArg(args, 2)); 1420ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1421ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek if (!msg.isInvalid() && captureSetValueAsResult) { 1422ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCMessageExpr *msgExpr = 1423ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit()); 1424ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Expr *arg = msgExpr->getArg(0); 1425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CanCaptureValue(arg)) 142625f071eedf5d20faf9e1614d5ff5dc39b6de5041Eli Friedman msgExpr->setArg(0, captureValueAsResult(arg)); 1427ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1428ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 1429ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return msg; 1430ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek} 1431ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek 14324b9c2d235fb9449e249d74f48ecfec601650de93John McCall//===----------------------------------------------------------------------===// 143376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall// MSVC __declspec(property) references 143476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall//===----------------------------------------------------------------------===// 143576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 143687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarMSPropertyRefExpr * 143787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarMSPropertyOpBuilder::getBaseMSProperty(MSPropertySubscriptExpr *E) { 143887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CallArgs.insert(CallArgs.begin(), E->getIdx()); 143987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Expr *Base = E->getBase()->IgnoreParens(); 144087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar while (auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) { 144187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx()); 144287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar Base = MSPropSubscript->getBase()->IgnoreParens(); 144387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 144487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return cast<MSPropertyRefExpr>(Base); 144587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar} 144676da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 144787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarExpr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { 144887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar InstanceBase = capture(RefExpr->getBaseExpr()); 144987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar std::for_each(CallArgs.begin(), CallArgs.end(), 145087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar [this](Expr *&Arg) { Arg = capture(Arg); }); 145187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar syntacticBase = Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { 145287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar switch (Idx) { 145387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar case 0: 145487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return InstanceBase; 145587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar default: 145687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar assert(Idx <= CallArgs.size()); 145787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return CallArgs[Idx - 1]; 145887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } 145987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }).rebuild(syntacticBase); 146076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 146176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return syntacticBase; 146276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall} 146376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 146476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCallExprResult MSPropertyOpBuilder::buildGet() { 146576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall if (!RefExpr->getPropertyDecl()->hasGetter()) { 1466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property) 1467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << 0 /* getter */ << RefExpr->getPropertyDecl(); 146876da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return ExprError(); 146976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } 147076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 147176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall UnqualifiedId GetterName; 147276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId(); 147376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall GetterName.setIdentifier(II, RefExpr->getMemberLoc()); 147476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall CXXScopeSpec SS; 147576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall SS.Adopt(RefExpr->getQualifierLoc()); 147687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ExprResult GetterExpr = 147787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(), 147887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar RefExpr->isArrow() ? tok::arrow : tok::period, SS, 147987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), GetterName, nullptr); 148076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall if (GetterExpr.isInvalid()) { 1481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(RefExpr->getMemberLoc(), 1482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines diag::error_cannot_find_suitable_accessor) << 0 /* getter */ 1483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << RefExpr->getPropertyDecl(); 148476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return ExprError(); 148576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } 148676da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 1487c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(), 148887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar RefExpr->getSourceRange().getBegin(), CallArgs, 148976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall RefExpr->getSourceRange().getEnd()); 149076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall} 149176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 149276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCallExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl, 149376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall bool captureSetValueAsResult) { 149476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall if (!RefExpr->getPropertyDecl()->hasSetter()) { 1495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property) 1496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << 1 /* setter */ << RefExpr->getPropertyDecl(); 149776da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return ExprError(); 149876da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } 149976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 150076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall UnqualifiedId SetterName; 150176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId(); 150276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall SetterName.setIdentifier(II, RefExpr->getMemberLoc()); 150376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall CXXScopeSpec SS; 150476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall SS.Adopt(RefExpr->getQualifierLoc()); 150587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ExprResult SetterExpr = 150687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(), 150787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar RefExpr->isArrow() ? tok::arrow : tok::period, SS, 150887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SourceLocation(), SetterName, nullptr); 150976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall if (SetterExpr.isInvalid()) { 1510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines S.Diag(RefExpr->getMemberLoc(), 1511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines diag::error_cannot_find_suitable_accessor) << 1 /* setter */ 1512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << RefExpr->getPropertyDecl(); 151376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return ExprError(); 151476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } 151576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 151687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar SmallVector<Expr*, 4> ArgExprs; 151787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar ArgExprs.append(CallArgs.begin(), CallArgs.end()); 151876da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall ArgExprs.push_back(op); 1519c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(), 152076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall RefExpr->getSourceRange().getBegin(), ArgExprs, 152176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall op->getSourceRange().getEnd()); 152276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall} 152376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 152476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall//===----------------------------------------------------------------------===// 15254b9c2d235fb9449e249d74f48ecfec601650de93John McCall// General Sema routines. 15264b9c2d235fb9449e249d74f48ecfec601650de93John McCall//===----------------------------------------------------------------------===// 15273c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 15284b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult Sema::checkPseudoObjectRValue(Expr *E) { 15294b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *opaqueRef = E->IgnoreParens(); 15304b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCPropertyRefExpr *refExpr 15314b9c2d235fb9449e249d74f48ecfec601650de93John McCall = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { 15324b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyOpBuilder builder(*this, refExpr); 15334b9c2d235fb9449e249d74f48ecfec601650de93John McCall return builder.buildRValueOperation(E); 1534ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } 1535ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek else if (ObjCSubscriptRefExpr *refExpr 1536ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { 1537ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCSubscriptOpBuilder builder(*this, refExpr); 1538ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return builder.buildRValueOperation(E); 153976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } else if (MSPropertyRefExpr *refExpr 154076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { 154176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall MSPropertyOpBuilder builder(*this, refExpr); 154276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return builder.buildRValueOperation(E); 154387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (MSPropertySubscriptExpr *RefExpr = 154487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { 154587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MSPropertyOpBuilder Builder(*this, RefExpr); 154687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Builder.buildRValueOperation(E); 15474b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 15484b9c2d235fb9449e249d74f48ecfec601650de93John McCall llvm_unreachable("unknown pseudo-object kind!"); 15493c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 15504b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 15513c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 15524b9c2d235fb9449e249d74f48ecfec601650de93John McCall/// Check an increment or decrement of a pseudo-object expression. 15534b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, 15544b9c2d235fb9449e249d74f48ecfec601650de93John McCall UnaryOperatorKind opcode, Expr *op) { 15554b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Do nothing if the operand is dependent. 15564b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (op->isTypeDependent()) 15574b9c2d235fb9449e249d74f48ecfec601650de93John McCall return new (Context) UnaryOperator(op, opcode, Context.DependentTy, 15584b9c2d235fb9449e249d74f48ecfec601650de93John McCall VK_RValue, OK_Ordinary, opcLoc); 15594b9c2d235fb9449e249d74f48ecfec601650de93John McCall 15604b9c2d235fb9449e249d74f48ecfec601650de93John McCall assert(UnaryOperator::isIncrementDecrementOp(opcode)); 15614b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *opaqueRef = op->IgnoreParens(); 15624b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCPropertyRefExpr *refExpr 15634b9c2d235fb9449e249d74f48ecfec601650de93John McCall = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { 15644b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyOpBuilder builder(*this, refExpr); 15654b9c2d235fb9449e249d74f48ecfec601650de93John McCall return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); 1566ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) { 1567ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek Diag(opcLoc, diag::err_illegal_container_subscripting_op); 1568ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return ExprError(); 156976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } else if (MSPropertyRefExpr *refExpr 157076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { 157176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall MSPropertyOpBuilder builder(*this, refExpr); 157276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); 157387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (MSPropertySubscriptExpr *RefExpr 157487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { 157587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MSPropertyOpBuilder Builder(*this, RefExpr); 157687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op); 15774b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 15784b9c2d235fb9449e249d74f48ecfec601650de93John McCall llvm_unreachable("unknown pseudo-object kind!"); 15793c3b7f90a863af43fa63043d396553ecf205351cJohn McCall } 15804b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 15813c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 15824b9c2d235fb9449e249d74f48ecfec601650de93John McCallExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, 15834b9c2d235fb9449e249d74f48ecfec601650de93John McCall BinaryOperatorKind opcode, 15844b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *LHS, Expr *RHS) { 15854b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Do nothing if either argument is dependent. 15864b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (LHS->isTypeDependent() || RHS->isTypeDependent()) 15874b9c2d235fb9449e249d74f48ecfec601650de93John McCall return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy, 1588be9af1288881110e406b87914162eaa59f1e5918Lang Hames VK_RValue, OK_Ordinary, opcLoc, false); 15894b9c2d235fb9449e249d74f48ecfec601650de93John McCall 15904b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Filter out non-overload placeholder types in the RHS. 159132509f1e60451d86e9fbc473b6e853ba10b5fd1eJohn McCall if (RHS->getType()->isNonOverloadPlaceholderType()) { 159232509f1e60451d86e9fbc473b6e853ba10b5fd1eJohn McCall ExprResult result = CheckPlaceholderExpr(RHS); 159332509f1e60451d86e9fbc473b6e853ba10b5fd1eJohn McCall if (result.isInvalid()) return ExprError(); 1594c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines RHS = result.get(); 15954b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 15963c3b7f90a863af43fa63043d396553ecf205351cJohn McCall 15974b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *opaqueRef = LHS->IgnoreParens(); 15984b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (ObjCPropertyRefExpr *refExpr 15994b9c2d235fb9449e249d74f48ecfec601650de93John McCall = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { 16004b9c2d235fb9449e249d74f48ecfec601650de93John McCall ObjCPropertyOpBuilder builder(*this, refExpr); 16014b9c2d235fb9449e249d74f48ecfec601650de93John McCall return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 1602ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek } else if (ObjCSubscriptRefExpr *refExpr 1603ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { 1604ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek ObjCSubscriptOpBuilder builder(*this, refExpr); 1605ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 160676da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall } else if (MSPropertyRefExpr *refExpr 160776da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { 160887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MSPropertyOpBuilder builder(*this, refExpr); 160987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 161087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar } else if (MSPropertySubscriptExpr *RefExpr 161187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { 161287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar MSPropertyOpBuilder Builder(*this, RefExpr); 161387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 16144b9c2d235fb9449e249d74f48ecfec601650de93John McCall } else { 16154b9c2d235fb9449e249d74f48ecfec601650de93John McCall llvm_unreachable("unknown pseudo-object kind!"); 16164b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 16173c3b7f90a863af43fa63043d396553ecf205351cJohn McCall} 161801e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall 161901e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// Given a pseudo-object reference, rebuild it without the opaque 162001e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// values. Basically, undo the behavior of rebuildAndCaptureObject. 162101e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// This should never operate in-place. 162201e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCallstatic Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) { 162387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return Rebuilder(S, 162487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar [=](Expr *E, unsigned) -> Expr * { 162587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar return cast<OpaqueValueExpr>(E)->getSourceExpr(); 162687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar }) 162787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar .rebuild(E); 162801e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall} 162901e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall 163001e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// Given a pseudo-object expression, recreate what it looks like 163101e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// syntactically without the attendant OpaqueValueExprs. 163201e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// 163301e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// This is a hack which should be removed when TreeTransform is 163401e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// capable of rebuilding a tree without stripping implicit 163501e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall/// operations. 163601e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCallExpr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { 163701e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall Expr *syntax = E->getSyntacticForm(); 163801e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) { 163901e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); 164001e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall return new (Context) UnaryOperator(op, uop->getOpcode(), uop->getType(), 164101e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall uop->getValueKind(), uop->getObjectKind(), 164201e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall uop->getOperatorLoc()); 164301e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall } else if (CompoundAssignOperator *cop 164401e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall = dyn_cast<CompoundAssignOperator>(syntax)) { 164501e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); 164601e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr(); 164701e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(), 164801e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall cop->getType(), 164901e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall cop->getValueKind(), 165001e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall cop->getObjectKind(), 165101e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall cop->getComputationLHSType(), 165201e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall cop->getComputationResultType(), 1653be9af1288881110e406b87914162eaa59f1e5918Lang Hames cop->getOperatorLoc(), false); 165401e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) { 165501e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS()); 165601e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr(); 165701e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(), 165801e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall bop->getType(), bop->getValueKind(), 165901e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall bop->getObjectKind(), 1660be9af1288881110e406b87914162eaa59f1e5918Lang Hames bop->getOperatorLoc(), false); 166101e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall } else { 166201e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject)); 166301e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall return stripOpaqueValuesFromPseudoObjectRef(*this, syntax); 166401e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall } 166501e19be69a37bc4ab7746c454cfaa6aec7bb7c6aJohn McCall} 1666