1 1.1 joerg //===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg // 9 1.1 joerg // This file implements semantic analysis for expressions involving 10 1.1 joerg // pseudo-object references. Pseudo-objects are conceptual objects 11 1.1 joerg // whose storage is entirely abstract and all accesses to which are 12 1.1 joerg // translated through some sort of abstraction barrier. 13 1.1 joerg // 14 1.1 joerg // For example, Objective-C objects can have "properties", either 15 1.1 joerg // declared or undeclared. A property may be accessed by writing 16 1.1 joerg // expr.prop 17 1.1 joerg // where 'expr' is an r-value of Objective-C pointer type and 'prop' 18 1.1 joerg // is the name of the property. If this expression is used in a context 19 1.1 joerg // needing an r-value, it is treated as if it were a message-send 20 1.1 joerg // of the associated 'getter' selector, typically: 21 1.1 joerg // [expr prop] 22 1.1 joerg // If it is used as the LHS of a simple assignment, it is treated 23 1.1 joerg // as a message-send of the associated 'setter' selector, typically: 24 1.1 joerg // [expr setProp: RHS] 25 1.1 joerg // If it is used as the LHS of a compound assignment, or the operand 26 1.1 joerg // of a unary increment or decrement, both are required; for example, 27 1.1 joerg // 'expr.prop *= 100' would be translated to: 28 1.1 joerg // [expr setProp: [expr prop] * 100] 29 1.1 joerg // 30 1.1 joerg //===----------------------------------------------------------------------===// 31 1.1 joerg 32 1.1 joerg #include "clang/Sema/SemaInternal.h" 33 1.1 joerg #include "clang/AST/ExprCXX.h" 34 1.1 joerg #include "clang/AST/ExprObjC.h" 35 1.1 joerg #include "clang/Basic/CharInfo.h" 36 1.1 joerg #include "clang/Lex/Preprocessor.h" 37 1.1 joerg #include "clang/Sema/Initialization.h" 38 1.1 joerg #include "clang/Sema/ScopeInfo.h" 39 1.1 joerg #include "llvm/ADT/SmallString.h" 40 1.1 joerg 41 1.1 joerg using namespace clang; 42 1.1 joerg using namespace sema; 43 1.1 joerg 44 1.1 joerg namespace { 45 1.1 joerg // Basically just a very focused copy of TreeTransform. 46 1.1 joerg struct Rebuilder { 47 1.1 joerg Sema &S; 48 1.1 joerg unsigned MSPropertySubscriptCount; 49 1.1 joerg typedef llvm::function_ref<Expr *(Expr *, unsigned)> SpecificRebuilderRefTy; 50 1.1 joerg const SpecificRebuilderRefTy &SpecificCallback; 51 1.1 joerg Rebuilder(Sema &S, const SpecificRebuilderRefTy &SpecificCallback) 52 1.1 joerg : S(S), MSPropertySubscriptCount(0), 53 1.1 joerg SpecificCallback(SpecificCallback) {} 54 1.1 joerg 55 1.1 joerg Expr *rebuildObjCPropertyRefExpr(ObjCPropertyRefExpr *refExpr) { 56 1.1 joerg // Fortunately, the constraint that we're rebuilding something 57 1.1 joerg // with a base limits the number of cases here. 58 1.1 joerg if (refExpr->isClassReceiver() || refExpr->isSuperReceiver()) 59 1.1 joerg return refExpr; 60 1.1 joerg 61 1.1 joerg if (refExpr->isExplicitProperty()) { 62 1.1 joerg return new (S.Context) ObjCPropertyRefExpr( 63 1.1 joerg refExpr->getExplicitProperty(), refExpr->getType(), 64 1.1 joerg refExpr->getValueKind(), refExpr->getObjectKind(), 65 1.1 joerg refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0)); 66 1.1 joerg } 67 1.1 joerg return new (S.Context) ObjCPropertyRefExpr( 68 1.1 joerg refExpr->getImplicitPropertyGetter(), 69 1.1 joerg refExpr->getImplicitPropertySetter(), refExpr->getType(), 70 1.1 joerg refExpr->getValueKind(), refExpr->getObjectKind(), 71 1.1 joerg refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0)); 72 1.1 joerg } 73 1.1 joerg Expr *rebuildObjCSubscriptRefExpr(ObjCSubscriptRefExpr *refExpr) { 74 1.1 joerg assert(refExpr->getBaseExpr()); 75 1.1 joerg assert(refExpr->getKeyExpr()); 76 1.1 joerg 77 1.1 joerg return new (S.Context) ObjCSubscriptRefExpr( 78 1.1 joerg SpecificCallback(refExpr->getBaseExpr(), 0), 79 1.1 joerg SpecificCallback(refExpr->getKeyExpr(), 1), refExpr->getType(), 80 1.1 joerg refExpr->getValueKind(), refExpr->getObjectKind(), 81 1.1 joerg refExpr->getAtIndexMethodDecl(), refExpr->setAtIndexMethodDecl(), 82 1.1 joerg refExpr->getRBracket()); 83 1.1 joerg } 84 1.1 joerg Expr *rebuildMSPropertyRefExpr(MSPropertyRefExpr *refExpr) { 85 1.1 joerg assert(refExpr->getBaseExpr()); 86 1.1 joerg 87 1.1 joerg return new (S.Context) MSPropertyRefExpr( 88 1.1 joerg SpecificCallback(refExpr->getBaseExpr(), 0), 89 1.1 joerg refExpr->getPropertyDecl(), refExpr->isArrow(), refExpr->getType(), 90 1.1 joerg refExpr->getValueKind(), refExpr->getQualifierLoc(), 91 1.1 joerg refExpr->getMemberLoc()); 92 1.1 joerg } 93 1.1 joerg Expr *rebuildMSPropertySubscriptExpr(MSPropertySubscriptExpr *refExpr) { 94 1.1 joerg assert(refExpr->getBase()); 95 1.1 joerg assert(refExpr->getIdx()); 96 1.1 joerg 97 1.1 joerg auto *NewBase = rebuild(refExpr->getBase()); 98 1.1 joerg ++MSPropertySubscriptCount; 99 1.1 joerg return new (S.Context) MSPropertySubscriptExpr( 100 1.1 joerg NewBase, 101 1.1 joerg SpecificCallback(refExpr->getIdx(), MSPropertySubscriptCount), 102 1.1 joerg refExpr->getType(), refExpr->getValueKind(), refExpr->getObjectKind(), 103 1.1 joerg refExpr->getRBracketLoc()); 104 1.1 joerg } 105 1.1 joerg 106 1.1 joerg Expr *rebuild(Expr *e) { 107 1.1 joerg // Fast path: nothing to look through. 108 1.1 joerg if (auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e)) 109 1.1 joerg return rebuildObjCPropertyRefExpr(PRE); 110 1.1 joerg if (auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e)) 111 1.1 joerg return rebuildObjCSubscriptRefExpr(SRE); 112 1.1 joerg if (auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e)) 113 1.1 joerg return rebuildMSPropertyRefExpr(MSPRE); 114 1.1 joerg if (auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e)) 115 1.1 joerg return rebuildMSPropertySubscriptExpr(MSPSE); 116 1.1 joerg 117 1.1 joerg // Otherwise, we should look through and rebuild anything that 118 1.1 joerg // IgnoreParens would. 119 1.1 joerg 120 1.1 joerg if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) { 121 1.1 joerg e = rebuild(parens->getSubExpr()); 122 1.1 joerg return new (S.Context) ParenExpr(parens->getLParen(), 123 1.1 joerg parens->getRParen(), 124 1.1 joerg e); 125 1.1 joerg } 126 1.1 joerg 127 1.1 joerg if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) { 128 1.1 joerg assert(uop->getOpcode() == UO_Extension); 129 1.1 joerg e = rebuild(uop->getSubExpr()); 130 1.1.1.2 joerg return UnaryOperator::Create( 131 1.1.1.2 joerg S.Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(), 132 1.1.1.2 joerg uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(), 133 1.1.1.2 joerg S.CurFPFeatureOverrides()); 134 1.1 joerg } 135 1.1 joerg 136 1.1 joerg if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) { 137 1.1 joerg assert(!gse->isResultDependent()); 138 1.1 joerg unsigned resultIndex = gse->getResultIndex(); 139 1.1 joerg unsigned numAssocs = gse->getNumAssocs(); 140 1.1 joerg 141 1.1 joerg SmallVector<Expr *, 8> assocExprs; 142 1.1 joerg SmallVector<TypeSourceInfo *, 8> assocTypes; 143 1.1 joerg assocExprs.reserve(numAssocs); 144 1.1 joerg assocTypes.reserve(numAssocs); 145 1.1 joerg 146 1.1.1.2 joerg for (const GenericSelectionExpr::Association assoc : 147 1.1 joerg gse->associations()) { 148 1.1 joerg Expr *assocExpr = assoc.getAssociationExpr(); 149 1.1 joerg if (assoc.isSelected()) 150 1.1 joerg assocExpr = rebuild(assocExpr); 151 1.1 joerg assocExprs.push_back(assocExpr); 152 1.1 joerg assocTypes.push_back(assoc.getTypeSourceInfo()); 153 1.1 joerg } 154 1.1 joerg 155 1.1 joerg return GenericSelectionExpr::Create( 156 1.1 joerg S.Context, gse->getGenericLoc(), gse->getControllingExpr(), 157 1.1 joerg assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(), 158 1.1 joerg gse->containsUnexpandedParameterPack(), resultIndex); 159 1.1 joerg } 160 1.1 joerg 161 1.1 joerg if (ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) { 162 1.1 joerg assert(!ce->isConditionDependent()); 163 1.1 joerg 164 1.1 joerg Expr *LHS = ce->getLHS(), *RHS = ce->getRHS(); 165 1.1 joerg Expr *&rebuiltExpr = ce->isConditionTrue() ? LHS : RHS; 166 1.1 joerg rebuiltExpr = rebuild(rebuiltExpr); 167 1.1 joerg 168 1.1.1.2 joerg return new (S.Context) 169 1.1.1.2 joerg ChooseExpr(ce->getBuiltinLoc(), ce->getCond(), LHS, RHS, 170 1.1.1.2 joerg rebuiltExpr->getType(), rebuiltExpr->getValueKind(), 171 1.1.1.2 joerg rebuiltExpr->getObjectKind(), ce->getRParenLoc(), 172 1.1.1.2 joerg ce->isConditionTrue()); 173 1.1 joerg } 174 1.1 joerg 175 1.1 joerg llvm_unreachable("bad expression to rebuild!"); 176 1.1 joerg } 177 1.1 joerg }; 178 1.1 joerg 179 1.1 joerg class PseudoOpBuilder { 180 1.1 joerg public: 181 1.1 joerg Sema &S; 182 1.1 joerg unsigned ResultIndex; 183 1.1 joerg SourceLocation GenericLoc; 184 1.1 joerg bool IsUnique; 185 1.1 joerg SmallVector<Expr *, 4> Semantics; 186 1.1 joerg 187 1.1 joerg PseudoOpBuilder(Sema &S, SourceLocation genericLoc, bool IsUnique) 188 1.1 joerg : S(S), ResultIndex(PseudoObjectExpr::NoResult), 189 1.1 joerg GenericLoc(genericLoc), IsUnique(IsUnique) {} 190 1.1 joerg 191 1.1 joerg virtual ~PseudoOpBuilder() {} 192 1.1 joerg 193 1.1 joerg /// Add a normal semantic expression. 194 1.1 joerg void addSemanticExpr(Expr *semantic) { 195 1.1 joerg Semantics.push_back(semantic); 196 1.1 joerg } 197 1.1 joerg 198 1.1 joerg /// Add the 'result' semantic expression. 199 1.1 joerg void addResultSemanticExpr(Expr *resultExpr) { 200 1.1 joerg assert(ResultIndex == PseudoObjectExpr::NoResult); 201 1.1 joerg ResultIndex = Semantics.size(); 202 1.1 joerg Semantics.push_back(resultExpr); 203 1.1 joerg // An OVE is not unique if it is used as the result expression. 204 1.1 joerg if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back())) 205 1.1 joerg OVE->setIsUnique(false); 206 1.1 joerg } 207 1.1 joerg 208 1.1 joerg ExprResult buildRValueOperation(Expr *op); 209 1.1 joerg ExprResult buildAssignmentOperation(Scope *Sc, 210 1.1 joerg SourceLocation opLoc, 211 1.1 joerg BinaryOperatorKind opcode, 212 1.1 joerg Expr *LHS, Expr *RHS); 213 1.1 joerg ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc, 214 1.1 joerg UnaryOperatorKind opcode, 215 1.1 joerg Expr *op); 216 1.1 joerg 217 1.1 joerg virtual ExprResult complete(Expr *syntacticForm); 218 1.1 joerg 219 1.1 joerg OpaqueValueExpr *capture(Expr *op); 220 1.1 joerg OpaqueValueExpr *captureValueAsResult(Expr *op); 221 1.1 joerg 222 1.1 joerg void setResultToLastSemantic() { 223 1.1 joerg assert(ResultIndex == PseudoObjectExpr::NoResult); 224 1.1 joerg ResultIndex = Semantics.size() - 1; 225 1.1 joerg // An OVE is not unique if it is used as the result expression. 226 1.1 joerg if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back())) 227 1.1 joerg OVE->setIsUnique(false); 228 1.1 joerg } 229 1.1 joerg 230 1.1 joerg /// Return true if assignments have a non-void result. 231 1.1 joerg static bool CanCaptureValue(Expr *exp) { 232 1.1 joerg if (exp->isGLValue()) 233 1.1 joerg return true; 234 1.1 joerg QualType ty = exp->getType(); 235 1.1 joerg assert(!ty->isIncompleteType()); 236 1.1 joerg assert(!ty->isDependentType()); 237 1.1 joerg 238 1.1 joerg if (const CXXRecordDecl *ClassDecl = ty->getAsCXXRecordDecl()) 239 1.1 joerg return ClassDecl->isTriviallyCopyable(); 240 1.1 joerg return true; 241 1.1 joerg } 242 1.1 joerg 243 1.1 joerg virtual Expr *rebuildAndCaptureObject(Expr *) = 0; 244 1.1 joerg virtual ExprResult buildGet() = 0; 245 1.1 joerg virtual ExprResult buildSet(Expr *, SourceLocation, 246 1.1 joerg bool captureSetValueAsResult) = 0; 247 1.1 joerg /// Should the result of an assignment be the formal result of the 248 1.1 joerg /// setter call or the value that was passed to the setter? 249 1.1 joerg /// 250 1.1 joerg /// Different pseudo-object language features use different language rules 251 1.1 joerg /// for this. 252 1.1 joerg /// The default is to use the set value. Currently, this affects the 253 1.1 joerg /// behavior of simple assignments, compound assignments, and prefix 254 1.1 joerg /// increment and decrement. 255 1.1 joerg /// Postfix increment and decrement always use the getter result as the 256 1.1 joerg /// expression result. 257 1.1 joerg /// 258 1.1 joerg /// If this method returns true, and the set value isn't capturable for 259 1.1 joerg /// some reason, the result of the expression will be void. 260 1.1 joerg virtual bool captureSetValueAsResult() const { return true; } 261 1.1 joerg }; 262 1.1 joerg 263 1.1 joerg /// A PseudoOpBuilder for Objective-C \@properties. 264 1.1 joerg class ObjCPropertyOpBuilder : public PseudoOpBuilder { 265 1.1 joerg ObjCPropertyRefExpr *RefExpr; 266 1.1 joerg ObjCPropertyRefExpr *SyntacticRefExpr; 267 1.1 joerg OpaqueValueExpr *InstanceReceiver; 268 1.1 joerg ObjCMethodDecl *Getter; 269 1.1 joerg 270 1.1 joerg ObjCMethodDecl *Setter; 271 1.1 joerg Selector SetterSelector; 272 1.1 joerg Selector GetterSelector; 273 1.1 joerg 274 1.1 joerg public: 275 1.1 joerg ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr, bool IsUnique) 276 1.1 joerg : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique), 277 1.1 joerg RefExpr(refExpr), SyntacticRefExpr(nullptr), 278 1.1 joerg InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) { 279 1.1 joerg } 280 1.1 joerg 281 1.1 joerg ExprResult buildRValueOperation(Expr *op); 282 1.1 joerg ExprResult buildAssignmentOperation(Scope *Sc, 283 1.1 joerg SourceLocation opLoc, 284 1.1 joerg BinaryOperatorKind opcode, 285 1.1 joerg Expr *LHS, Expr *RHS); 286 1.1 joerg ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc, 287 1.1 joerg UnaryOperatorKind opcode, 288 1.1 joerg Expr *op); 289 1.1 joerg 290 1.1 joerg bool tryBuildGetOfReference(Expr *op, ExprResult &result); 291 1.1 joerg bool findSetter(bool warn=true); 292 1.1 joerg bool findGetter(); 293 1.1 joerg void DiagnoseUnsupportedPropertyUse(); 294 1.1 joerg 295 1.1 joerg Expr *rebuildAndCaptureObject(Expr *syntacticBase) override; 296 1.1 joerg ExprResult buildGet() override; 297 1.1 joerg ExprResult buildSet(Expr *op, SourceLocation, bool) override; 298 1.1 joerg ExprResult complete(Expr *SyntacticForm) override; 299 1.1 joerg 300 1.1 joerg bool isWeakProperty() const; 301 1.1 joerg }; 302 1.1 joerg 303 1.1 joerg /// A PseudoOpBuilder for Objective-C array/dictionary indexing. 304 1.1 joerg class ObjCSubscriptOpBuilder : public PseudoOpBuilder { 305 1.1 joerg ObjCSubscriptRefExpr *RefExpr; 306 1.1 joerg OpaqueValueExpr *InstanceBase; 307 1.1 joerg OpaqueValueExpr *InstanceKey; 308 1.1 joerg ObjCMethodDecl *AtIndexGetter; 309 1.1 joerg Selector AtIndexGetterSelector; 310 1.1 joerg 311 1.1 joerg ObjCMethodDecl *AtIndexSetter; 312 1.1 joerg Selector AtIndexSetterSelector; 313 1.1 joerg 314 1.1 joerg public: 315 1.1 joerg ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr, bool IsUnique) 316 1.1 joerg : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique), 317 1.1 joerg RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr), 318 1.1 joerg AtIndexGetter(nullptr), AtIndexSetter(nullptr) {} 319 1.1 joerg 320 1.1 joerg ExprResult buildRValueOperation(Expr *op); 321 1.1 joerg ExprResult buildAssignmentOperation(Scope *Sc, 322 1.1 joerg SourceLocation opLoc, 323 1.1 joerg BinaryOperatorKind opcode, 324 1.1 joerg Expr *LHS, Expr *RHS); 325 1.1 joerg Expr *rebuildAndCaptureObject(Expr *syntacticBase) override; 326 1.1 joerg 327 1.1 joerg bool findAtIndexGetter(); 328 1.1 joerg bool findAtIndexSetter(); 329 1.1 joerg 330 1.1 joerg ExprResult buildGet() override; 331 1.1 joerg ExprResult buildSet(Expr *op, SourceLocation, bool) override; 332 1.1 joerg }; 333 1.1 joerg 334 1.1 joerg class MSPropertyOpBuilder : public PseudoOpBuilder { 335 1.1 joerg MSPropertyRefExpr *RefExpr; 336 1.1 joerg OpaqueValueExpr *InstanceBase; 337 1.1 joerg SmallVector<Expr *, 4> CallArgs; 338 1.1 joerg 339 1.1 joerg MSPropertyRefExpr *getBaseMSProperty(MSPropertySubscriptExpr *E); 340 1.1 joerg 341 1.1 joerg public: 342 1.1 joerg MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr, bool IsUnique) 343 1.1 joerg : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique), 344 1.1 joerg RefExpr(refExpr), InstanceBase(nullptr) {} 345 1.1 joerg MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr, bool IsUnique) 346 1.1 joerg : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique), 347 1.1 joerg InstanceBase(nullptr) { 348 1.1 joerg RefExpr = getBaseMSProperty(refExpr); 349 1.1 joerg } 350 1.1 joerg 351 1.1 joerg Expr *rebuildAndCaptureObject(Expr *) override; 352 1.1 joerg ExprResult buildGet() override; 353 1.1 joerg ExprResult buildSet(Expr *op, SourceLocation, bool) override; 354 1.1 joerg bool captureSetValueAsResult() const override { return false; } 355 1.1 joerg }; 356 1.1 joerg } 357 1.1 joerg 358 1.1 joerg /// Capture the given expression in an OpaqueValueExpr. 359 1.1 joerg OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) { 360 1.1 joerg // Make a new OVE whose source is the given expression. 361 1.1 joerg OpaqueValueExpr *captured = 362 1.1 joerg new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(), 363 1.1 joerg e->getValueKind(), e->getObjectKind(), 364 1.1 joerg e); 365 1.1 joerg if (IsUnique) 366 1.1 joerg captured->setIsUnique(true); 367 1.1 joerg 368 1.1 joerg // Make sure we bind that in the semantics. 369 1.1 joerg addSemanticExpr(captured); 370 1.1 joerg return captured; 371 1.1 joerg } 372 1.1 joerg 373 1.1 joerg /// Capture the given expression as the result of this pseudo-object 374 1.1 joerg /// operation. This routine is safe against expressions which may 375 1.1 joerg /// already be captured. 376 1.1 joerg /// 377 1.1 joerg /// \returns the captured expression, which will be the 378 1.1 joerg /// same as the input if the input was already captured 379 1.1 joerg OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) { 380 1.1 joerg assert(ResultIndex == PseudoObjectExpr::NoResult); 381 1.1 joerg 382 1.1 joerg // If the expression hasn't already been captured, just capture it 383 1.1 joerg // and set the new semantic 384 1.1 joerg if (!isa<OpaqueValueExpr>(e)) { 385 1.1 joerg OpaqueValueExpr *cap = capture(e); 386 1.1 joerg setResultToLastSemantic(); 387 1.1 joerg return cap; 388 1.1 joerg } 389 1.1 joerg 390 1.1 joerg // Otherwise, it must already be one of our semantic expressions; 391 1.1 joerg // set ResultIndex to its index. 392 1.1 joerg unsigned index = 0; 393 1.1 joerg for (;; ++index) { 394 1.1 joerg assert(index < Semantics.size() && 395 1.1 joerg "captured expression not found in semantics!"); 396 1.1 joerg if (e == Semantics[index]) break; 397 1.1 joerg } 398 1.1 joerg ResultIndex = index; 399 1.1 joerg // An OVE is not unique if it is used as the result expression. 400 1.1 joerg cast<OpaqueValueExpr>(e)->setIsUnique(false); 401 1.1 joerg return cast<OpaqueValueExpr>(e); 402 1.1 joerg } 403 1.1 joerg 404 1.1 joerg /// The routine which creates the final PseudoObjectExpr. 405 1.1 joerg ExprResult PseudoOpBuilder::complete(Expr *syntactic) { 406 1.1 joerg return PseudoObjectExpr::Create(S.Context, syntactic, 407 1.1 joerg Semantics, ResultIndex); 408 1.1 joerg } 409 1.1 joerg 410 1.1 joerg /// The main skeleton for building an r-value operation. 411 1.1 joerg ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) { 412 1.1 joerg Expr *syntacticBase = rebuildAndCaptureObject(op); 413 1.1 joerg 414 1.1 joerg ExprResult getExpr = buildGet(); 415 1.1 joerg if (getExpr.isInvalid()) return ExprError(); 416 1.1 joerg addResultSemanticExpr(getExpr.get()); 417 1.1 joerg 418 1.1 joerg return complete(syntacticBase); 419 1.1 joerg } 420 1.1 joerg 421 1.1 joerg /// The basic skeleton for building a simple or compound 422 1.1 joerg /// assignment operation. 423 1.1 joerg ExprResult 424 1.1 joerg PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, 425 1.1 joerg BinaryOperatorKind opcode, 426 1.1 joerg Expr *LHS, Expr *RHS) { 427 1.1 joerg assert(BinaryOperator::isAssignmentOp(opcode)); 428 1.1 joerg 429 1.1 joerg Expr *syntacticLHS = rebuildAndCaptureObject(LHS); 430 1.1 joerg OpaqueValueExpr *capturedRHS = capture(RHS); 431 1.1 joerg 432 1.1 joerg // In some very specific cases, semantic analysis of the RHS as an 433 1.1 joerg // expression may require it to be rewritten. In these cases, we 434 1.1 joerg // cannot safely keep the OVE around. Fortunately, we don't really 435 1.1 joerg // need to: we don't use this particular OVE in multiple places, and 436 1.1 joerg // no clients rely that closely on matching up expressions in the 437 1.1 joerg // semantic expression with expressions from the syntactic form. 438 1.1 joerg Expr *semanticRHS = capturedRHS; 439 1.1 joerg if (RHS->hasPlaceholderType() || isa<InitListExpr>(RHS)) { 440 1.1 joerg semanticRHS = RHS; 441 1.1 joerg Semantics.pop_back(); 442 1.1 joerg } 443 1.1 joerg 444 1.1 joerg Expr *syntactic; 445 1.1 joerg 446 1.1 joerg ExprResult result; 447 1.1 joerg if (opcode == BO_Assign) { 448 1.1 joerg result = semanticRHS; 449 1.1.1.2 joerg syntactic = BinaryOperator::Create(S.Context, syntacticLHS, capturedRHS, 450 1.1.1.2 joerg opcode, capturedRHS->getType(), 451 1.1.1.2 joerg capturedRHS->getValueKind(), OK_Ordinary, 452 1.1.1.2 joerg opcLoc, S.CurFPFeatureOverrides()); 453 1.1.1.2 joerg 454 1.1 joerg } else { 455 1.1 joerg ExprResult opLHS = buildGet(); 456 1.1 joerg if (opLHS.isInvalid()) return ExprError(); 457 1.1 joerg 458 1.1 joerg // Build an ordinary, non-compound operation. 459 1.1 joerg BinaryOperatorKind nonCompound = 460 1.1 joerg BinaryOperator::getOpForCompoundAssignment(opcode); 461 1.1 joerg result = S.BuildBinOp(Sc, opcLoc, nonCompound, opLHS.get(), semanticRHS); 462 1.1 joerg if (result.isInvalid()) return ExprError(); 463 1.1 joerg 464 1.1.1.2 joerg syntactic = CompoundAssignOperator::Create( 465 1.1.1.2 joerg S.Context, syntacticLHS, capturedRHS, opcode, result.get()->getType(), 466 1.1.1.2 joerg result.get()->getValueKind(), OK_Ordinary, opcLoc, 467 1.1.1.2 joerg S.CurFPFeatureOverrides(), opLHS.get()->getType(), 468 1.1.1.2 joerg result.get()->getType()); 469 1.1 joerg } 470 1.1 joerg 471 1.1 joerg // The result of the assignment, if not void, is the value set into 472 1.1 joerg // the l-value. 473 1.1 joerg result = buildSet(result.get(), opcLoc, captureSetValueAsResult()); 474 1.1 joerg if (result.isInvalid()) return ExprError(); 475 1.1 joerg addSemanticExpr(result.get()); 476 1.1 joerg if (!captureSetValueAsResult() && !result.get()->getType()->isVoidType() && 477 1.1 joerg (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) 478 1.1 joerg setResultToLastSemantic(); 479 1.1 joerg 480 1.1 joerg return complete(syntactic); 481 1.1 joerg } 482 1.1 joerg 483 1.1 joerg /// The basic skeleton for building an increment or decrement 484 1.1 joerg /// operation. 485 1.1 joerg ExprResult 486 1.1 joerg PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, 487 1.1 joerg UnaryOperatorKind opcode, 488 1.1 joerg Expr *op) { 489 1.1 joerg assert(UnaryOperator::isIncrementDecrementOp(opcode)); 490 1.1 joerg 491 1.1 joerg Expr *syntacticOp = rebuildAndCaptureObject(op); 492 1.1 joerg 493 1.1 joerg // Load the value. 494 1.1 joerg ExprResult result = buildGet(); 495 1.1 joerg if (result.isInvalid()) return ExprError(); 496 1.1 joerg 497 1.1 joerg QualType resultType = result.get()->getType(); 498 1.1 joerg 499 1.1 joerg // That's the postfix result. 500 1.1 joerg if (UnaryOperator::isPostfix(opcode) && 501 1.1 joerg (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) { 502 1.1 joerg result = capture(result.get()); 503 1.1 joerg setResultToLastSemantic(); 504 1.1 joerg } 505 1.1 joerg 506 1.1 joerg // Add or subtract a literal 1. 507 1.1 joerg llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1); 508 1.1 joerg Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy, 509 1.1 joerg GenericLoc); 510 1.1 joerg 511 1.1 joerg if (UnaryOperator::isIncrementOp(opcode)) { 512 1.1 joerg result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one); 513 1.1 joerg } else { 514 1.1 joerg result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one); 515 1.1 joerg } 516 1.1 joerg if (result.isInvalid()) return ExprError(); 517 1.1 joerg 518 1.1 joerg // Store that back into the result. The value stored is the result 519 1.1 joerg // of a prefix operation. 520 1.1 joerg result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode) && 521 1.1 joerg captureSetValueAsResult()); 522 1.1 joerg if (result.isInvalid()) return ExprError(); 523 1.1 joerg addSemanticExpr(result.get()); 524 1.1 joerg if (UnaryOperator::isPrefix(opcode) && !captureSetValueAsResult() && 525 1.1 joerg !result.get()->getType()->isVoidType() && 526 1.1 joerg (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) 527 1.1 joerg setResultToLastSemantic(); 528 1.1 joerg 529 1.1.1.2 joerg UnaryOperator *syntactic = 530 1.1.1.2 joerg UnaryOperator::Create(S.Context, syntacticOp, opcode, resultType, 531 1.1.1.2 joerg VK_LValue, OK_Ordinary, opcLoc, 532 1.1.1.2 joerg !resultType->isDependentType() 533 1.1.1.2 joerg ? S.Context.getTypeSize(resultType) >= 534 1.1.1.2 joerg S.Context.getTypeSize(S.Context.IntTy) 535 1.1.1.2 joerg : false, 536 1.1.1.2 joerg S.CurFPFeatureOverrides()); 537 1.1 joerg return complete(syntactic); 538 1.1 joerg } 539 1.1 joerg 540 1.1 joerg 541 1.1 joerg //===----------------------------------------------------------------------===// 542 1.1 joerg // Objective-C @property and implicit property references 543 1.1 joerg //===----------------------------------------------------------------------===// 544 1.1 joerg 545 1.1 joerg /// Look up a method in the receiver type of an Objective-C property 546 1.1 joerg /// reference. 547 1.1 joerg static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel, 548 1.1 joerg const ObjCPropertyRefExpr *PRE) { 549 1.1 joerg if (PRE->isObjectReceiver()) { 550 1.1 joerg const ObjCObjectPointerType *PT = 551 1.1 joerg PRE->getBase()->getType()->castAs<ObjCObjectPointerType>(); 552 1.1 joerg 553 1.1 joerg // Special case for 'self' in class method implementations. 554 1.1 joerg if (PT->isObjCClassType() && 555 1.1 joerg S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))) { 556 1.1 joerg // This cast is safe because isSelfExpr is only true within 557 1.1 joerg // methods. 558 1.1 joerg ObjCMethodDecl *method = 559 1.1 joerg cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor()); 560 1.1 joerg return S.LookupMethodInObjectType(sel, 561 1.1 joerg S.Context.getObjCInterfaceType(method->getClassInterface()), 562 1.1 joerg /*instance*/ false); 563 1.1 joerg } 564 1.1 joerg 565 1.1 joerg return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true); 566 1.1 joerg } 567 1.1 joerg 568 1.1 joerg if (PRE->isSuperReceiver()) { 569 1.1 joerg if (const ObjCObjectPointerType *PT = 570 1.1 joerg PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>()) 571 1.1 joerg return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true); 572 1.1 joerg 573 1.1 joerg return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false); 574 1.1 joerg } 575 1.1 joerg 576 1.1 joerg assert(PRE->isClassReceiver() && "Invalid expression"); 577 1.1 joerg QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver()); 578 1.1 joerg return S.LookupMethodInObjectType(sel, IT, false); 579 1.1 joerg } 580 1.1 joerg 581 1.1 joerg bool ObjCPropertyOpBuilder::isWeakProperty() const { 582 1.1 joerg QualType T; 583 1.1 joerg if (RefExpr->isExplicitProperty()) { 584 1.1 joerg const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty(); 585 1.1.1.2 joerg if (Prop->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak) 586 1.1 joerg return true; 587 1.1 joerg 588 1.1 joerg T = Prop->getType(); 589 1.1 joerg } else if (Getter) { 590 1.1 joerg T = Getter->getReturnType(); 591 1.1 joerg } else { 592 1.1 joerg return false; 593 1.1 joerg } 594 1.1 joerg 595 1.1 joerg return T.getObjCLifetime() == Qualifiers::OCL_Weak; 596 1.1 joerg } 597 1.1 joerg 598 1.1 joerg bool ObjCPropertyOpBuilder::findGetter() { 599 1.1 joerg if (Getter) return true; 600 1.1 joerg 601 1.1 joerg // For implicit properties, just trust the lookup we already did. 602 1.1 joerg if (RefExpr->isImplicitProperty()) { 603 1.1 joerg if ((Getter = RefExpr->getImplicitPropertyGetter())) { 604 1.1 joerg GetterSelector = Getter->getSelector(); 605 1.1 joerg return true; 606 1.1 joerg } 607 1.1 joerg else { 608 1.1 joerg // Must build the getter selector the hard way. 609 1.1 joerg ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter(); 610 1.1 joerg assert(setter && "both setter and getter are null - cannot happen"); 611 1.1 joerg IdentifierInfo *setterName = 612 1.1 joerg setter->getSelector().getIdentifierInfoForSlot(0); 613 1.1 joerg IdentifierInfo *getterName = 614 1.1 joerg &S.Context.Idents.get(setterName->getName().substr(3)); 615 1.1 joerg GetterSelector = 616 1.1 joerg S.PP.getSelectorTable().getNullarySelector(getterName); 617 1.1 joerg return false; 618 1.1 joerg } 619 1.1 joerg } 620 1.1 joerg 621 1.1 joerg ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); 622 1.1 joerg Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr); 623 1.1 joerg return (Getter != nullptr); 624 1.1 joerg } 625 1.1 joerg 626 1.1 joerg /// Try to find the most accurate setter declaration for the property 627 1.1 joerg /// reference. 628 1.1 joerg /// 629 1.1 joerg /// \return true if a setter was found, in which case Setter 630 1.1 joerg bool ObjCPropertyOpBuilder::findSetter(bool warn) { 631 1.1 joerg // For implicit properties, just trust the lookup we already did. 632 1.1 joerg if (RefExpr->isImplicitProperty()) { 633 1.1 joerg if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) { 634 1.1 joerg Setter = setter; 635 1.1 joerg SetterSelector = setter->getSelector(); 636 1.1 joerg return true; 637 1.1 joerg } else { 638 1.1 joerg IdentifierInfo *getterName = 639 1.1 joerg RefExpr->getImplicitPropertyGetter()->getSelector() 640 1.1 joerg .getIdentifierInfoForSlot(0); 641 1.1 joerg SetterSelector = 642 1.1 joerg SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(), 643 1.1 joerg S.PP.getSelectorTable(), 644 1.1 joerg getterName); 645 1.1 joerg return false; 646 1.1 joerg } 647 1.1 joerg } 648 1.1 joerg 649 1.1 joerg // For explicit properties, this is more involved. 650 1.1 joerg ObjCPropertyDecl *prop = RefExpr->getExplicitProperty(); 651 1.1 joerg SetterSelector = prop->getSetterName(); 652 1.1 joerg 653 1.1 joerg // Do a normal method lookup first. 654 1.1 joerg if (ObjCMethodDecl *setter = 655 1.1 joerg LookupMethodInReceiverType(S, SetterSelector, RefExpr)) { 656 1.1 joerg if (setter->isPropertyAccessor() && warn) 657 1.1 joerg if (const ObjCInterfaceDecl *IFace = 658 1.1 joerg dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) { 659 1.1 joerg StringRef thisPropertyName = prop->getName(); 660 1.1 joerg // Try flipping the case of the first character. 661 1.1 joerg char front = thisPropertyName.front(); 662 1.1 joerg front = isLowercase(front) ? toUppercase(front) : toLowercase(front); 663 1.1 joerg SmallString<100> PropertyName = thisPropertyName; 664 1.1 joerg PropertyName[0] = front; 665 1.1 joerg IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName); 666 1.1 joerg if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration( 667 1.1 joerg AltMember, prop->getQueryKind())) 668 1.1 joerg if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) { 669 1.1 joerg S.Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use) 670 1.1 joerg << prop << prop1 << setter->getSelector(); 671 1.1 joerg S.Diag(prop->getLocation(), diag::note_property_declare); 672 1.1 joerg S.Diag(prop1->getLocation(), diag::note_property_declare); 673 1.1 joerg } 674 1.1 joerg } 675 1.1 joerg Setter = setter; 676 1.1 joerg return true; 677 1.1 joerg } 678 1.1 joerg 679 1.1 joerg // That can fail in the somewhat crazy situation that we're 680 1.1 joerg // type-checking a message send within the @interface declaration 681 1.1 joerg // that declared the @property. But it's not clear that that's 682 1.1 joerg // valuable to support. 683 1.1 joerg 684 1.1 joerg return false; 685 1.1 joerg } 686 1.1 joerg 687 1.1 joerg void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() { 688 1.1 joerg if (S.getCurLexicalContext()->isObjCContainer() && 689 1.1 joerg S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl && 690 1.1 joerg S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) { 691 1.1 joerg if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) { 692 1.1 joerg S.Diag(RefExpr->getLocation(), 693 1.1 joerg diag::err_property_function_in_objc_container); 694 1.1 joerg S.Diag(prop->getLocation(), diag::note_property_declare); 695 1.1 joerg } 696 1.1 joerg } 697 1.1 joerg } 698 1.1 joerg 699 1.1 joerg /// Capture the base object of an Objective-C property expression. 700 1.1 joerg Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { 701 1.1 joerg assert(InstanceReceiver == nullptr); 702 1.1 joerg 703 1.1 joerg // If we have a base, capture it in an OVE and rebuild the syntactic 704 1.1 joerg // form to use the OVE as its base. 705 1.1 joerg if (RefExpr->isObjectReceiver()) { 706 1.1 joerg InstanceReceiver = capture(RefExpr->getBase()); 707 1.1 joerg syntacticBase = Rebuilder(S, [=](Expr *, unsigned) -> Expr * { 708 1.1 joerg return InstanceReceiver; 709 1.1 joerg }).rebuild(syntacticBase); 710 1.1 joerg } 711 1.1 joerg 712 1.1 joerg if (ObjCPropertyRefExpr * 713 1.1 joerg refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens())) 714 1.1 joerg SyntacticRefExpr = refE; 715 1.1 joerg 716 1.1 joerg return syntacticBase; 717 1.1 joerg } 718 1.1 joerg 719 1.1 joerg /// Load from an Objective-C property reference. 720 1.1 joerg ExprResult ObjCPropertyOpBuilder::buildGet() { 721 1.1 joerg findGetter(); 722 1.1 joerg if (!Getter) { 723 1.1 joerg DiagnoseUnsupportedPropertyUse(); 724 1.1 joerg return ExprError(); 725 1.1 joerg } 726 1.1 joerg 727 1.1 joerg if (SyntacticRefExpr) 728 1.1 joerg SyntacticRefExpr->setIsMessagingGetter(); 729 1.1 joerg 730 1.1 joerg QualType receiverType = RefExpr->getReceiverType(S.Context); 731 1.1 joerg if (!Getter->isImplicit()) 732 1.1 joerg S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true); 733 1.1 joerg // Build a message-send. 734 1.1 joerg ExprResult msg; 735 1.1 joerg if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) || 736 1.1 joerg RefExpr->isObjectReceiver()) { 737 1.1 joerg assert(InstanceReceiver || RefExpr->isSuperReceiver()); 738 1.1 joerg msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, 739 1.1 joerg GenericLoc, Getter->getSelector(), 740 1.1 joerg Getter, None); 741 1.1 joerg } else { 742 1.1 joerg msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), 743 1.1 joerg GenericLoc, Getter->getSelector(), 744 1.1 joerg Getter, None); 745 1.1 joerg } 746 1.1 joerg return msg; 747 1.1 joerg } 748 1.1 joerg 749 1.1 joerg /// Store to an Objective-C property reference. 750 1.1 joerg /// 751 1.1 joerg /// \param captureSetValueAsResult If true, capture the actual 752 1.1 joerg /// value being set as the value of the property operation. 753 1.1 joerg ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, 754 1.1 joerg bool captureSetValueAsResult) { 755 1.1 joerg if (!findSetter(false)) { 756 1.1 joerg DiagnoseUnsupportedPropertyUse(); 757 1.1 joerg return ExprError(); 758 1.1 joerg } 759 1.1 joerg 760 1.1 joerg if (SyntacticRefExpr) 761 1.1 joerg SyntacticRefExpr->setIsMessagingSetter(); 762 1.1 joerg 763 1.1 joerg QualType receiverType = RefExpr->getReceiverType(S.Context); 764 1.1 joerg 765 1.1 joerg // Use assignment constraints when possible; they give us better 766 1.1 joerg // diagnostics. "When possible" basically means anything except a 767 1.1 joerg // C++ class type. 768 1.1 joerg if (!S.getLangOpts().CPlusPlus || !op->getType()->isRecordType()) { 769 1.1 joerg QualType paramType = (*Setter->param_begin())->getType() 770 1.1 joerg .substObjCMemberType( 771 1.1 joerg receiverType, 772 1.1 joerg Setter->getDeclContext(), 773 1.1 joerg ObjCSubstitutionContext::Parameter); 774 1.1 joerg if (!S.getLangOpts().CPlusPlus || !paramType->isRecordType()) { 775 1.1 joerg ExprResult opResult = op; 776 1.1 joerg Sema::AssignConvertType assignResult 777 1.1 joerg = S.CheckSingleAssignmentConstraints(paramType, opResult); 778 1.1 joerg if (opResult.isInvalid() || 779 1.1 joerg S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType, 780 1.1 joerg op->getType(), opResult.get(), 781 1.1 joerg Sema::AA_Assigning)) 782 1.1 joerg return ExprError(); 783 1.1 joerg 784 1.1 joerg op = opResult.get(); 785 1.1 joerg assert(op && "successful assignment left argument invalid?"); 786 1.1 joerg } 787 1.1 joerg } 788 1.1 joerg 789 1.1 joerg // Arguments. 790 1.1 joerg Expr *args[] = { op }; 791 1.1 joerg 792 1.1 joerg // Build a message-send. 793 1.1 joerg ExprResult msg; 794 1.1 joerg if (!Setter->isImplicit()) 795 1.1 joerg S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true); 796 1.1 joerg if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) || 797 1.1 joerg RefExpr->isObjectReceiver()) { 798 1.1 joerg msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType, 799 1.1 joerg GenericLoc, SetterSelector, Setter, 800 1.1 joerg MultiExprArg(args, 1)); 801 1.1 joerg } else { 802 1.1 joerg msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(), 803 1.1 joerg GenericLoc, 804 1.1 joerg SetterSelector, Setter, 805 1.1 joerg MultiExprArg(args, 1)); 806 1.1 joerg } 807 1.1 joerg 808 1.1 joerg if (!msg.isInvalid() && captureSetValueAsResult) { 809 1.1 joerg ObjCMessageExpr *msgExpr = 810 1.1 joerg cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit()); 811 1.1 joerg Expr *arg = msgExpr->getArg(0); 812 1.1 joerg if (CanCaptureValue(arg)) 813 1.1 joerg msgExpr->setArg(0, captureValueAsResult(arg)); 814 1.1 joerg } 815 1.1 joerg 816 1.1 joerg return msg; 817 1.1 joerg } 818 1.1 joerg 819 1.1 joerg /// @property-specific behavior for doing lvalue-to-rvalue conversion. 820 1.1 joerg ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) { 821 1.1 joerg // Explicit properties always have getters, but implicit ones don't. 822 1.1 joerg // Check that before proceeding. 823 1.1 joerg if (RefExpr->isImplicitProperty() && !RefExpr->getImplicitPropertyGetter()) { 824 1.1 joerg S.Diag(RefExpr->getLocation(), diag::err_getter_not_found) 825 1.1 joerg << RefExpr->getSourceRange(); 826 1.1 joerg return ExprError(); 827 1.1 joerg } 828 1.1 joerg 829 1.1 joerg ExprResult result = PseudoOpBuilder::buildRValueOperation(op); 830 1.1 joerg if (result.isInvalid()) return ExprError(); 831 1.1 joerg 832 1.1 joerg if (RefExpr->isExplicitProperty() && !Getter->hasRelatedResultType()) 833 1.1 joerg S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(), 834 1.1 joerg Getter, RefExpr->getLocation()); 835 1.1 joerg 836 1.1 joerg // As a special case, if the method returns 'id', try to get 837 1.1 joerg // a better type from the property. 838 1.1 joerg if (RefExpr->isExplicitProperty() && result.get()->isRValue()) { 839 1.1 joerg QualType receiverType = RefExpr->getReceiverType(S.Context); 840 1.1 joerg QualType propType = RefExpr->getExplicitProperty() 841 1.1 joerg ->getUsageType(receiverType); 842 1.1 joerg if (result.get()->getType()->isObjCIdType()) { 843 1.1 joerg if (const ObjCObjectPointerType *ptr 844 1.1 joerg = propType->getAs<ObjCObjectPointerType>()) { 845 1.1 joerg if (!ptr->isObjCIdType()) 846 1.1 joerg result = S.ImpCastExprToType(result.get(), propType, CK_BitCast); 847 1.1 joerg } 848 1.1 joerg } 849 1.1 joerg if (propType.getObjCLifetime() == Qualifiers::OCL_Weak && 850 1.1 joerg !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, 851 1.1 joerg RefExpr->getLocation())) 852 1.1 joerg S.getCurFunction()->markSafeWeakUse(RefExpr); 853 1.1 joerg } 854 1.1 joerg 855 1.1 joerg return result; 856 1.1 joerg } 857 1.1 joerg 858 1.1 joerg /// Try to build this as a call to a getter that returns a reference. 859 1.1 joerg /// 860 1.1 joerg /// \return true if it was possible, whether or not it actually 861 1.1 joerg /// succeeded 862 1.1 joerg bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op, 863 1.1 joerg ExprResult &result) { 864 1.1 joerg if (!S.getLangOpts().CPlusPlus) return false; 865 1.1 joerg 866 1.1 joerg findGetter(); 867 1.1 joerg if (!Getter) { 868 1.1 joerg // The property has no setter and no getter! This can happen if the type is 869 1.1 joerg // invalid. Error have already been reported. 870 1.1 joerg result = ExprError(); 871 1.1 joerg return true; 872 1.1 joerg } 873 1.1 joerg 874 1.1 joerg // Only do this if the getter returns an l-value reference type. 875 1.1 joerg QualType resultType = Getter->getReturnType(); 876 1.1 joerg if (!resultType->isLValueReferenceType()) return false; 877 1.1 joerg 878 1.1 joerg result = buildRValueOperation(op); 879 1.1 joerg return true; 880 1.1 joerg } 881 1.1 joerg 882 1.1 joerg /// @property-specific behavior for doing assignments. 883 1.1 joerg ExprResult 884 1.1 joerg ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc, 885 1.1 joerg SourceLocation opcLoc, 886 1.1 joerg BinaryOperatorKind opcode, 887 1.1 joerg Expr *LHS, Expr *RHS) { 888 1.1 joerg assert(BinaryOperator::isAssignmentOp(opcode)); 889 1.1 joerg 890 1.1 joerg // If there's no setter, we have no choice but to try to assign to 891 1.1 joerg // the result of the getter. 892 1.1 joerg if (!findSetter()) { 893 1.1 joerg ExprResult result; 894 1.1 joerg if (tryBuildGetOfReference(LHS, result)) { 895 1.1 joerg if (result.isInvalid()) return ExprError(); 896 1.1 joerg return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS); 897 1.1 joerg } 898 1.1 joerg 899 1.1 joerg // Otherwise, it's an error. 900 1.1 joerg S.Diag(opcLoc, diag::err_nosetter_property_assignment) 901 1.1 joerg << unsigned(RefExpr->isImplicitProperty()) 902 1.1 joerg << SetterSelector 903 1.1 joerg << LHS->getSourceRange() << RHS->getSourceRange(); 904 1.1 joerg return ExprError(); 905 1.1 joerg } 906 1.1 joerg 907 1.1 joerg // If there is a setter, we definitely want to use it. 908 1.1 joerg 909 1.1 joerg // Verify that we can do a compound assignment. 910 1.1 joerg if (opcode != BO_Assign && !findGetter()) { 911 1.1 joerg S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment) 912 1.1 joerg << LHS->getSourceRange() << RHS->getSourceRange(); 913 1.1 joerg return ExprError(); 914 1.1 joerg } 915 1.1 joerg 916 1.1 joerg ExprResult result = 917 1.1 joerg PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS); 918 1.1 joerg if (result.isInvalid()) return ExprError(); 919 1.1 joerg 920 1.1 joerg // Various warnings about property assignments in ARC. 921 1.1 joerg if (S.getLangOpts().ObjCAutoRefCount && InstanceReceiver) { 922 1.1 joerg S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS); 923 1.1 joerg S.checkUnsafeExprAssigns(opcLoc, LHS, RHS); 924 1.1 joerg } 925 1.1 joerg 926 1.1 joerg return result; 927 1.1 joerg } 928 1.1 joerg 929 1.1 joerg /// @property-specific behavior for doing increments and decrements. 930 1.1 joerg ExprResult 931 1.1 joerg ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, 932 1.1 joerg UnaryOperatorKind opcode, 933 1.1 joerg Expr *op) { 934 1.1 joerg // If there's no setter, we have no choice but to try to assign to 935 1.1 joerg // the result of the getter. 936 1.1 joerg if (!findSetter()) { 937 1.1 joerg ExprResult result; 938 1.1 joerg if (tryBuildGetOfReference(op, result)) { 939 1.1 joerg if (result.isInvalid()) return ExprError(); 940 1.1 joerg return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get()); 941 1.1 joerg } 942 1.1 joerg 943 1.1 joerg // Otherwise, it's an error. 944 1.1 joerg S.Diag(opcLoc, diag::err_nosetter_property_incdec) 945 1.1 joerg << unsigned(RefExpr->isImplicitProperty()) 946 1.1 joerg << unsigned(UnaryOperator::isDecrementOp(opcode)) 947 1.1 joerg << SetterSelector 948 1.1 joerg << op->getSourceRange(); 949 1.1 joerg return ExprError(); 950 1.1 joerg } 951 1.1 joerg 952 1.1 joerg // If there is a setter, we definitely want to use it. 953 1.1 joerg 954 1.1 joerg // We also need a getter. 955 1.1 joerg if (!findGetter()) { 956 1.1 joerg assert(RefExpr->isImplicitProperty()); 957 1.1 joerg S.Diag(opcLoc, diag::err_nogetter_property_incdec) 958 1.1 joerg << unsigned(UnaryOperator::isDecrementOp(opcode)) 959 1.1 joerg << GetterSelector 960 1.1 joerg << op->getSourceRange(); 961 1.1 joerg return ExprError(); 962 1.1 joerg } 963 1.1 joerg 964 1.1 joerg return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op); 965 1.1 joerg } 966 1.1 joerg 967 1.1 joerg ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) { 968 1.1 joerg if (isWeakProperty() && !S.isUnevaluatedContext() && 969 1.1 joerg !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, 970 1.1 joerg SyntacticForm->getBeginLoc())) 971 1.1 joerg S.getCurFunction()->recordUseOfWeak(SyntacticRefExpr, 972 1.1 joerg SyntacticRefExpr->isMessagingGetter()); 973 1.1 joerg 974 1.1 joerg return PseudoOpBuilder::complete(SyntacticForm); 975 1.1 joerg } 976 1.1 joerg 977 1.1 joerg // ObjCSubscript build stuff. 978 1.1 joerg // 979 1.1 joerg 980 1.1 joerg /// objective-c subscripting-specific behavior for doing lvalue-to-rvalue 981 1.1 joerg /// conversion. 982 1.1 joerg /// FIXME. Remove this routine if it is proven that no additional 983 1.1 joerg /// specifity is needed. 984 1.1 joerg ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) { 985 1.1 joerg ExprResult result = PseudoOpBuilder::buildRValueOperation(op); 986 1.1 joerg if (result.isInvalid()) return ExprError(); 987 1.1 joerg return result; 988 1.1 joerg } 989 1.1 joerg 990 1.1 joerg /// objective-c subscripting-specific behavior for doing assignments. 991 1.1 joerg ExprResult 992 1.1 joerg ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc, 993 1.1 joerg SourceLocation opcLoc, 994 1.1 joerg BinaryOperatorKind opcode, 995 1.1 joerg Expr *LHS, Expr *RHS) { 996 1.1 joerg assert(BinaryOperator::isAssignmentOp(opcode)); 997 1.1 joerg // There must be a method to do the Index'ed assignment. 998 1.1 joerg if (!findAtIndexSetter()) 999 1.1 joerg return ExprError(); 1000 1.1 joerg 1001 1.1 joerg // Verify that we can do a compound assignment. 1002 1.1 joerg if (opcode != BO_Assign && !findAtIndexGetter()) 1003 1.1 joerg return ExprError(); 1004 1.1 joerg 1005 1.1 joerg ExprResult result = 1006 1.1 joerg PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS); 1007 1.1 joerg if (result.isInvalid()) return ExprError(); 1008 1.1 joerg 1009 1.1 joerg // Various warnings about objc Index'ed assignments in ARC. 1010 1.1 joerg if (S.getLangOpts().ObjCAutoRefCount && InstanceBase) { 1011 1.1 joerg S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS); 1012 1.1 joerg S.checkUnsafeExprAssigns(opcLoc, LHS, RHS); 1013 1.1 joerg } 1014 1.1 joerg 1015 1.1 joerg return result; 1016 1.1 joerg } 1017 1.1 joerg 1018 1.1 joerg /// Capture the base object of an Objective-C Index'ed expression. 1019 1.1 joerg Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { 1020 1.1 joerg assert(InstanceBase == nullptr); 1021 1.1 joerg 1022 1.1 joerg // Capture base expression in an OVE and rebuild the syntactic 1023 1.1 joerg // form to use the OVE as its base expression. 1024 1.1 joerg InstanceBase = capture(RefExpr->getBaseExpr()); 1025 1.1 joerg InstanceKey = capture(RefExpr->getKeyExpr()); 1026 1.1 joerg 1027 1.1 joerg syntacticBase = 1028 1.1 joerg Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { 1029 1.1 joerg switch (Idx) { 1030 1.1 joerg case 0: 1031 1.1 joerg return InstanceBase; 1032 1.1 joerg case 1: 1033 1.1 joerg return InstanceKey; 1034 1.1 joerg default: 1035 1.1 joerg llvm_unreachable("Unexpected index for ObjCSubscriptExpr"); 1036 1.1 joerg } 1037 1.1 joerg }).rebuild(syntacticBase); 1038 1.1 joerg 1039 1.1 joerg return syntacticBase; 1040 1.1 joerg } 1041 1.1 joerg 1042 1.1 joerg /// CheckSubscriptingKind - This routine decide what type 1043 1.1 joerg /// of indexing represented by "FromE" is being done. 1044 1.1 joerg Sema::ObjCSubscriptKind 1045 1.1 joerg Sema::CheckSubscriptingKind(Expr *FromE) { 1046 1.1 joerg // If the expression already has integral or enumeration type, we're golden. 1047 1.1 joerg QualType T = FromE->getType(); 1048 1.1 joerg if (T->isIntegralOrEnumerationType()) 1049 1.1 joerg return OS_Array; 1050 1.1 joerg 1051 1.1 joerg // If we don't have a class type in C++, there's no way we can get an 1052 1.1 joerg // expression of integral or enumeration type. 1053 1.1 joerg const RecordType *RecordTy = T->getAs<RecordType>(); 1054 1.1 joerg if (!RecordTy && 1055 1.1 joerg (T->isObjCObjectPointerType() || T->isVoidPointerType())) 1056 1.1 joerg // All other scalar cases are assumed to be dictionary indexing which 1057 1.1 joerg // caller handles, with diagnostics if needed. 1058 1.1 joerg return OS_Dictionary; 1059 1.1 joerg if (!getLangOpts().CPlusPlus || 1060 1.1 joerg !RecordTy || RecordTy->isIncompleteType()) { 1061 1.1 joerg // No indexing can be done. Issue diagnostics and quit. 1062 1.1 joerg const Expr *IndexExpr = FromE->IgnoreParenImpCasts(); 1063 1.1 joerg if (isa<StringLiteral>(IndexExpr)) 1064 1.1 joerg Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer) 1065 1.1 joerg << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@"); 1066 1.1 joerg else 1067 1.1 joerg Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) 1068 1.1 joerg << T; 1069 1.1 joerg return OS_Error; 1070 1.1 joerg } 1071 1.1 joerg 1072 1.1 joerg // We must have a complete class type. 1073 1.1 joerg if (RequireCompleteType(FromE->getExprLoc(), T, 1074 1.1 joerg diag::err_objc_index_incomplete_class_type, FromE)) 1075 1.1 joerg return OS_Error; 1076 1.1 joerg 1077 1.1 joerg // Look for a conversion to an integral, enumeration type, or 1078 1.1 joerg // objective-C pointer type. 1079 1.1 joerg int NoIntegrals=0, NoObjCIdPointers=0; 1080 1.1 joerg SmallVector<CXXConversionDecl *, 4> ConversionDecls; 1081 1.1 joerg 1082 1.1 joerg for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl()) 1083 1.1 joerg ->getVisibleConversionFunctions()) { 1084 1.1 joerg if (CXXConversionDecl *Conversion = 1085 1.1 joerg dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) { 1086 1.1 joerg QualType CT = Conversion->getConversionType().getNonReferenceType(); 1087 1.1 joerg if (CT->isIntegralOrEnumerationType()) { 1088 1.1 joerg ++NoIntegrals; 1089 1.1 joerg ConversionDecls.push_back(Conversion); 1090 1.1 joerg } 1091 1.1 joerg else if (CT->isObjCIdType() ||CT->isBlockPointerType()) { 1092 1.1 joerg ++NoObjCIdPointers; 1093 1.1 joerg ConversionDecls.push_back(Conversion); 1094 1.1 joerg } 1095 1.1 joerg } 1096 1.1 joerg } 1097 1.1 joerg if (NoIntegrals ==1 && NoObjCIdPointers == 0) 1098 1.1 joerg return OS_Array; 1099 1.1 joerg if (NoIntegrals == 0 && NoObjCIdPointers == 1) 1100 1.1 joerg return OS_Dictionary; 1101 1.1 joerg if (NoIntegrals == 0 && NoObjCIdPointers == 0) { 1102 1.1 joerg // No conversion function was found. Issue diagnostic and return. 1103 1.1 joerg Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion) 1104 1.1 joerg << FromE->getType(); 1105 1.1 joerg return OS_Error; 1106 1.1 joerg } 1107 1.1 joerg Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion) 1108 1.1 joerg << FromE->getType(); 1109 1.1 joerg for (unsigned int i = 0; i < ConversionDecls.size(); i++) 1110 1.1 joerg Diag(ConversionDecls[i]->getLocation(), 1111 1.1 joerg diag::note_conv_function_declared_at); 1112 1.1 joerg 1113 1.1 joerg return OS_Error; 1114 1.1 joerg } 1115 1.1 joerg 1116 1.1 joerg /// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF 1117 1.1 joerg /// objects used as dictionary subscript key objects. 1118 1.1 joerg static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, 1119 1.1 joerg Expr *Key) { 1120 1.1 joerg if (ContainerT.isNull()) 1121 1.1 joerg return; 1122 1.1 joerg // dictionary subscripting. 1123 1.1 joerg // - (id)objectForKeyedSubscript:(id)key; 1124 1.1 joerg IdentifierInfo *KeyIdents[] = { 1125 1.1 joerg &S.Context.Idents.get("objectForKeyedSubscript") 1126 1.1 joerg }; 1127 1.1 joerg Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); 1128 1.1 joerg ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT, 1129 1.1 joerg true /*instance*/); 1130 1.1 joerg if (!Getter) 1131 1.1 joerg return; 1132 1.1 joerg QualType T = Getter->parameters()[0]->getType(); 1133 1.1 joerg S.CheckObjCConversion(Key->getSourceRange(), T, Key, 1134 1.1 joerg Sema::CCK_ImplicitConversion); 1135 1.1 joerg } 1136 1.1 joerg 1137 1.1 joerg bool ObjCSubscriptOpBuilder::findAtIndexGetter() { 1138 1.1 joerg if (AtIndexGetter) 1139 1.1 joerg return true; 1140 1.1 joerg 1141 1.1 joerg Expr *BaseExpr = RefExpr->getBaseExpr(); 1142 1.1 joerg QualType BaseT = BaseExpr->getType(); 1143 1.1 joerg 1144 1.1 joerg QualType ResultType; 1145 1.1 joerg if (const ObjCObjectPointerType *PTy = 1146 1.1 joerg BaseT->getAs<ObjCObjectPointerType>()) { 1147 1.1 joerg ResultType = PTy->getPointeeType(); 1148 1.1 joerg } 1149 1.1 joerg Sema::ObjCSubscriptKind Res = 1150 1.1 joerg S.CheckSubscriptingKind(RefExpr->getKeyExpr()); 1151 1.1 joerg if (Res == Sema::OS_Error) { 1152 1.1 joerg if (S.getLangOpts().ObjCAutoRefCount) 1153 1.1 joerg CheckKeyForObjCARCConversion(S, ResultType, 1154 1.1 joerg RefExpr->getKeyExpr()); 1155 1.1 joerg return false; 1156 1.1 joerg } 1157 1.1 joerg bool arrayRef = (Res == Sema::OS_Array); 1158 1.1 joerg 1159 1.1 joerg if (ResultType.isNull()) { 1160 1.1 joerg S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type) 1161 1.1 joerg << BaseExpr->getType() << arrayRef; 1162 1.1 joerg return false; 1163 1.1 joerg } 1164 1.1 joerg if (!arrayRef) { 1165 1.1 joerg // dictionary subscripting. 1166 1.1 joerg // - (id)objectForKeyedSubscript:(id)key; 1167 1.1 joerg IdentifierInfo *KeyIdents[] = { 1168 1.1 joerg &S.Context.Idents.get("objectForKeyedSubscript") 1169 1.1 joerg }; 1170 1.1 joerg AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); 1171 1.1 joerg } 1172 1.1 joerg else { 1173 1.1 joerg // - (id)objectAtIndexedSubscript:(size_t)index; 1174 1.1 joerg IdentifierInfo *KeyIdents[] = { 1175 1.1 joerg &S.Context.Idents.get("objectAtIndexedSubscript") 1176 1.1 joerg }; 1177 1.1 joerg 1178 1.1 joerg AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents); 1179 1.1 joerg } 1180 1.1 joerg 1181 1.1 joerg AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType, 1182 1.1 joerg true /*instance*/); 1183 1.1 joerg 1184 1.1 joerg if (!AtIndexGetter && S.getLangOpts().DebuggerObjCLiteral) { 1185 1.1.1.2 joerg AtIndexGetter = ObjCMethodDecl::Create( 1186 1.1.1.2 joerg S.Context, SourceLocation(), SourceLocation(), AtIndexGetterSelector, 1187 1.1.1.2 joerg S.Context.getObjCIdType() /*ReturnType*/, nullptr /*TypeSourceInfo */, 1188 1.1.1.2 joerg S.Context.getTranslationUnitDecl(), true /*Instance*/, 1189 1.1.1.2 joerg false /*isVariadic*/, 1190 1.1.1.2 joerg /*isPropertyAccessor=*/false, 1191 1.1.1.2 joerg /*isSynthesizedAccessorStub=*/false, 1192 1.1.1.2 joerg /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1193 1.1.1.2 joerg ObjCMethodDecl::Required, false); 1194 1.1 joerg ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter, 1195 1.1 joerg SourceLocation(), SourceLocation(), 1196 1.1 joerg arrayRef ? &S.Context.Idents.get("index") 1197 1.1 joerg : &S.Context.Idents.get("key"), 1198 1.1 joerg arrayRef ? S.Context.UnsignedLongTy 1199 1.1 joerg : S.Context.getObjCIdType(), 1200 1.1 joerg /*TInfo=*/nullptr, 1201 1.1 joerg SC_None, 1202 1.1 joerg nullptr); 1203 1.1 joerg AtIndexGetter->setMethodParams(S.Context, Argument, None); 1204 1.1 joerg } 1205 1.1 joerg 1206 1.1 joerg if (!AtIndexGetter) { 1207 1.1 joerg if (!BaseT->isObjCIdType()) { 1208 1.1 joerg S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found) 1209 1.1 joerg << BaseExpr->getType() << 0 << arrayRef; 1210 1.1 joerg return false; 1211 1.1 joerg } 1212 1.1 joerg AtIndexGetter = 1213 1.1 joerg S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector, 1214 1.1 joerg RefExpr->getSourceRange(), 1215 1.1 joerg true); 1216 1.1 joerg } 1217 1.1 joerg 1218 1.1 joerg if (AtIndexGetter) { 1219 1.1 joerg QualType T = AtIndexGetter->parameters()[0]->getType(); 1220 1.1 joerg if ((arrayRef && !T->isIntegralOrEnumerationType()) || 1221 1.1 joerg (!arrayRef && !T->isObjCObjectPointerType())) { 1222 1.1 joerg S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1223 1.1 joerg arrayRef ? diag::err_objc_subscript_index_type 1224 1.1 joerg : diag::err_objc_subscript_key_type) << T; 1225 1.1 joerg S.Diag(AtIndexGetter->parameters()[0]->getLocation(), 1226 1.1 joerg diag::note_parameter_type) << T; 1227 1.1 joerg return false; 1228 1.1 joerg } 1229 1.1 joerg QualType R = AtIndexGetter->getReturnType(); 1230 1.1 joerg if (!R->isObjCObjectPointerType()) { 1231 1.1 joerg S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1232 1.1 joerg diag::err_objc_indexing_method_result_type) << R << arrayRef; 1233 1.1 joerg S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) << 1234 1.1 joerg AtIndexGetter->getDeclName(); 1235 1.1 joerg } 1236 1.1 joerg } 1237 1.1 joerg return true; 1238 1.1 joerg } 1239 1.1 joerg 1240 1.1 joerg bool ObjCSubscriptOpBuilder::findAtIndexSetter() { 1241 1.1 joerg if (AtIndexSetter) 1242 1.1 joerg return true; 1243 1.1 joerg 1244 1.1 joerg Expr *BaseExpr = RefExpr->getBaseExpr(); 1245 1.1 joerg QualType BaseT = BaseExpr->getType(); 1246 1.1 joerg 1247 1.1 joerg QualType ResultType; 1248 1.1 joerg if (const ObjCObjectPointerType *PTy = 1249 1.1 joerg BaseT->getAs<ObjCObjectPointerType>()) { 1250 1.1 joerg ResultType = PTy->getPointeeType(); 1251 1.1 joerg } 1252 1.1 joerg 1253 1.1 joerg Sema::ObjCSubscriptKind Res = 1254 1.1 joerg S.CheckSubscriptingKind(RefExpr->getKeyExpr()); 1255 1.1 joerg if (Res == Sema::OS_Error) { 1256 1.1 joerg if (S.getLangOpts().ObjCAutoRefCount) 1257 1.1 joerg CheckKeyForObjCARCConversion(S, ResultType, 1258 1.1 joerg RefExpr->getKeyExpr()); 1259 1.1 joerg return false; 1260 1.1 joerg } 1261 1.1 joerg bool arrayRef = (Res == Sema::OS_Array); 1262 1.1 joerg 1263 1.1 joerg if (ResultType.isNull()) { 1264 1.1 joerg S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type) 1265 1.1 joerg << BaseExpr->getType() << arrayRef; 1266 1.1 joerg return false; 1267 1.1 joerg } 1268 1.1 joerg 1269 1.1 joerg if (!arrayRef) { 1270 1.1 joerg // dictionary subscripting. 1271 1.1 joerg // - (void)setObject:(id)object forKeyedSubscript:(id)key; 1272 1.1 joerg IdentifierInfo *KeyIdents[] = { 1273 1.1 joerg &S.Context.Idents.get("setObject"), 1274 1.1 joerg &S.Context.Idents.get("forKeyedSubscript") 1275 1.1 joerg }; 1276 1.1 joerg AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents); 1277 1.1 joerg } 1278 1.1 joerg else { 1279 1.1 joerg // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index; 1280 1.1 joerg IdentifierInfo *KeyIdents[] = { 1281 1.1 joerg &S.Context.Idents.get("setObject"), 1282 1.1 joerg &S.Context.Idents.get("atIndexedSubscript") 1283 1.1 joerg }; 1284 1.1 joerg AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents); 1285 1.1 joerg } 1286 1.1 joerg AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType, 1287 1.1 joerg true /*instance*/); 1288 1.1 joerg 1289 1.1 joerg if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) { 1290 1.1 joerg TypeSourceInfo *ReturnTInfo = nullptr; 1291 1.1 joerg QualType ReturnType = S.Context.VoidTy; 1292 1.1 joerg AtIndexSetter = ObjCMethodDecl::Create( 1293 1.1 joerg S.Context, SourceLocation(), SourceLocation(), AtIndexSetterSelector, 1294 1.1 joerg ReturnType, ReturnTInfo, S.Context.getTranslationUnitDecl(), 1295 1.1 joerg true /*Instance*/, false /*isVariadic*/, 1296 1.1 joerg /*isPropertyAccessor=*/false, 1297 1.1.1.2 joerg /*isSynthesizedAccessorStub=*/false, 1298 1.1 joerg /*isImplicitlyDeclared=*/true, /*isDefined=*/false, 1299 1.1 joerg ObjCMethodDecl::Required, false); 1300 1.1 joerg SmallVector<ParmVarDecl *, 2> Params; 1301 1.1 joerg ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter, 1302 1.1 joerg SourceLocation(), SourceLocation(), 1303 1.1 joerg &S.Context.Idents.get("object"), 1304 1.1 joerg S.Context.getObjCIdType(), 1305 1.1 joerg /*TInfo=*/nullptr, 1306 1.1 joerg SC_None, 1307 1.1 joerg nullptr); 1308 1.1 joerg Params.push_back(object); 1309 1.1 joerg ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter, 1310 1.1 joerg SourceLocation(), SourceLocation(), 1311 1.1 joerg arrayRef ? &S.Context.Idents.get("index") 1312 1.1 joerg : &S.Context.Idents.get("key"), 1313 1.1 joerg arrayRef ? S.Context.UnsignedLongTy 1314 1.1 joerg : S.Context.getObjCIdType(), 1315 1.1 joerg /*TInfo=*/nullptr, 1316 1.1 joerg SC_None, 1317 1.1 joerg nullptr); 1318 1.1 joerg Params.push_back(key); 1319 1.1 joerg AtIndexSetter->setMethodParams(S.Context, Params, None); 1320 1.1 joerg } 1321 1.1 joerg 1322 1.1 joerg if (!AtIndexSetter) { 1323 1.1 joerg if (!BaseT->isObjCIdType()) { 1324 1.1 joerg S.Diag(BaseExpr->getExprLoc(), 1325 1.1 joerg diag::err_objc_subscript_method_not_found) 1326 1.1 joerg << BaseExpr->getType() << 1 << arrayRef; 1327 1.1 joerg return false; 1328 1.1 joerg } 1329 1.1 joerg AtIndexSetter = 1330 1.1 joerg S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector, 1331 1.1 joerg RefExpr->getSourceRange(), 1332 1.1 joerg true); 1333 1.1 joerg } 1334 1.1 joerg 1335 1.1 joerg bool err = false; 1336 1.1 joerg if (AtIndexSetter && arrayRef) { 1337 1.1 joerg QualType T = AtIndexSetter->parameters()[1]->getType(); 1338 1.1 joerg if (!T->isIntegralOrEnumerationType()) { 1339 1.1 joerg S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1340 1.1 joerg diag::err_objc_subscript_index_type) << T; 1341 1.1 joerg S.Diag(AtIndexSetter->parameters()[1]->getLocation(), 1342 1.1 joerg diag::note_parameter_type) << T; 1343 1.1 joerg err = true; 1344 1.1 joerg } 1345 1.1 joerg T = AtIndexSetter->parameters()[0]->getType(); 1346 1.1 joerg if (!T->isObjCObjectPointerType()) { 1347 1.1 joerg S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 1348 1.1 joerg diag::err_objc_subscript_object_type) << T << arrayRef; 1349 1.1 joerg S.Diag(AtIndexSetter->parameters()[0]->getLocation(), 1350 1.1 joerg diag::note_parameter_type) << T; 1351 1.1 joerg err = true; 1352 1.1 joerg } 1353 1.1 joerg } 1354 1.1 joerg else if (AtIndexSetter && !arrayRef) 1355 1.1 joerg for (unsigned i=0; i <2; i++) { 1356 1.1 joerg QualType T = AtIndexSetter->parameters()[i]->getType(); 1357 1.1 joerg if (!T->isObjCObjectPointerType()) { 1358 1.1 joerg if (i == 1) 1359 1.1 joerg S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 1360 1.1 joerg diag::err_objc_subscript_key_type) << T; 1361 1.1 joerg else 1362 1.1 joerg S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 1363 1.1 joerg diag::err_objc_subscript_dic_object_type) << T; 1364 1.1 joerg S.Diag(AtIndexSetter->parameters()[i]->getLocation(), 1365 1.1 joerg diag::note_parameter_type) << T; 1366 1.1 joerg err = true; 1367 1.1 joerg } 1368 1.1 joerg } 1369 1.1 joerg 1370 1.1 joerg return !err; 1371 1.1 joerg } 1372 1.1 joerg 1373 1.1 joerg // Get the object at "Index" position in the container. 1374 1.1 joerg // [BaseExpr objectAtIndexedSubscript : IndexExpr]; 1375 1.1 joerg ExprResult ObjCSubscriptOpBuilder::buildGet() { 1376 1.1 joerg if (!findAtIndexGetter()) 1377 1.1 joerg return ExprError(); 1378 1.1 joerg 1379 1.1 joerg QualType receiverType = InstanceBase->getType(); 1380 1.1 joerg 1381 1.1 joerg // Build a message-send. 1382 1.1 joerg ExprResult msg; 1383 1.1 joerg Expr *Index = InstanceKey; 1384 1.1 joerg 1385 1.1 joerg // Arguments. 1386 1.1 joerg Expr *args[] = { Index }; 1387 1.1 joerg assert(InstanceBase); 1388 1.1 joerg if (AtIndexGetter) 1389 1.1 joerg S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc); 1390 1.1 joerg msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType, 1391 1.1 joerg GenericLoc, 1392 1.1 joerg AtIndexGetterSelector, AtIndexGetter, 1393 1.1 joerg MultiExprArg(args, 1)); 1394 1.1 joerg return msg; 1395 1.1 joerg } 1396 1.1 joerg 1397 1.1 joerg /// Store into the container the "op" object at "Index"'ed location 1398 1.1 joerg /// by building this messaging expression: 1399 1.1 joerg /// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index; 1400 1.1 joerg /// \param captureSetValueAsResult If true, capture the actual 1401 1.1 joerg /// value being set as the value of the property operation. 1402 1.1 joerg ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc, 1403 1.1 joerg bool captureSetValueAsResult) { 1404 1.1 joerg if (!findAtIndexSetter()) 1405 1.1 joerg return ExprError(); 1406 1.1 joerg if (AtIndexSetter) 1407 1.1 joerg S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc); 1408 1.1 joerg QualType receiverType = InstanceBase->getType(); 1409 1.1 joerg Expr *Index = InstanceKey; 1410 1.1 joerg 1411 1.1 joerg // Arguments. 1412 1.1 joerg Expr *args[] = { op, Index }; 1413 1.1 joerg 1414 1.1 joerg // Build a message-send. 1415 1.1 joerg ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType, 1416 1.1 joerg GenericLoc, 1417 1.1 joerg AtIndexSetterSelector, 1418 1.1 joerg AtIndexSetter, 1419 1.1 joerg MultiExprArg(args, 2)); 1420 1.1 joerg 1421 1.1 joerg if (!msg.isInvalid() && captureSetValueAsResult) { 1422 1.1 joerg ObjCMessageExpr *msgExpr = 1423 1.1 joerg cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit()); 1424 1.1 joerg Expr *arg = msgExpr->getArg(0); 1425 1.1 joerg if (CanCaptureValue(arg)) 1426 1.1 joerg msgExpr->setArg(0, captureValueAsResult(arg)); 1427 1.1 joerg } 1428 1.1 joerg 1429 1.1 joerg return msg; 1430 1.1 joerg } 1431 1.1 joerg 1432 1.1 joerg //===----------------------------------------------------------------------===// 1433 1.1 joerg // MSVC __declspec(property) references 1434 1.1 joerg //===----------------------------------------------------------------------===// 1435 1.1 joerg 1436 1.1 joerg MSPropertyRefExpr * 1437 1.1 joerg MSPropertyOpBuilder::getBaseMSProperty(MSPropertySubscriptExpr *E) { 1438 1.1 joerg CallArgs.insert(CallArgs.begin(), E->getIdx()); 1439 1.1 joerg Expr *Base = E->getBase()->IgnoreParens(); 1440 1.1 joerg while (auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) { 1441 1.1 joerg CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx()); 1442 1.1 joerg Base = MSPropSubscript->getBase()->IgnoreParens(); 1443 1.1 joerg } 1444 1.1 joerg return cast<MSPropertyRefExpr>(Base); 1445 1.1 joerg } 1446 1.1 joerg 1447 1.1 joerg Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { 1448 1.1 joerg InstanceBase = capture(RefExpr->getBaseExpr()); 1449 1.1 joerg llvm::for_each(CallArgs, [this](Expr *&Arg) { Arg = capture(Arg); }); 1450 1.1 joerg syntacticBase = Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { 1451 1.1 joerg switch (Idx) { 1452 1.1 joerg case 0: 1453 1.1 joerg return InstanceBase; 1454 1.1 joerg default: 1455 1.1 joerg assert(Idx <= CallArgs.size()); 1456 1.1 joerg return CallArgs[Idx - 1]; 1457 1.1 joerg } 1458 1.1 joerg }).rebuild(syntacticBase); 1459 1.1 joerg 1460 1.1 joerg return syntacticBase; 1461 1.1 joerg } 1462 1.1 joerg 1463 1.1 joerg ExprResult MSPropertyOpBuilder::buildGet() { 1464 1.1 joerg if (!RefExpr->getPropertyDecl()->hasGetter()) { 1465 1.1 joerg S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property) 1466 1.1 joerg << 0 /* getter */ << RefExpr->getPropertyDecl(); 1467 1.1 joerg return ExprError(); 1468 1.1 joerg } 1469 1.1 joerg 1470 1.1 joerg UnqualifiedId GetterName; 1471 1.1 joerg IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId(); 1472 1.1 joerg GetterName.setIdentifier(II, RefExpr->getMemberLoc()); 1473 1.1 joerg CXXScopeSpec SS; 1474 1.1 joerg SS.Adopt(RefExpr->getQualifierLoc()); 1475 1.1 joerg ExprResult GetterExpr = 1476 1.1 joerg S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(), 1477 1.1 joerg RefExpr->isArrow() ? tok::arrow : tok::period, SS, 1478 1.1 joerg SourceLocation(), GetterName, nullptr); 1479 1.1 joerg if (GetterExpr.isInvalid()) { 1480 1.1 joerg S.Diag(RefExpr->getMemberLoc(), 1481 1.1 joerg diag::err_cannot_find_suitable_accessor) << 0 /* getter */ 1482 1.1 joerg << RefExpr->getPropertyDecl(); 1483 1.1 joerg return ExprError(); 1484 1.1 joerg } 1485 1.1 joerg 1486 1.1 joerg return S.BuildCallExpr(S.getCurScope(), GetterExpr.get(), 1487 1.1 joerg RefExpr->getSourceRange().getBegin(), CallArgs, 1488 1.1 joerg RefExpr->getSourceRange().getEnd()); 1489 1.1 joerg } 1490 1.1 joerg 1491 1.1 joerg ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl, 1492 1.1 joerg bool captureSetValueAsResult) { 1493 1.1 joerg if (!RefExpr->getPropertyDecl()->hasSetter()) { 1494 1.1 joerg S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property) 1495 1.1 joerg << 1 /* setter */ << RefExpr->getPropertyDecl(); 1496 1.1 joerg return ExprError(); 1497 1.1 joerg } 1498 1.1 joerg 1499 1.1 joerg UnqualifiedId SetterName; 1500 1.1 joerg IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId(); 1501 1.1 joerg SetterName.setIdentifier(II, RefExpr->getMemberLoc()); 1502 1.1 joerg CXXScopeSpec SS; 1503 1.1 joerg SS.Adopt(RefExpr->getQualifierLoc()); 1504 1.1 joerg ExprResult SetterExpr = 1505 1.1 joerg S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(), 1506 1.1 joerg RefExpr->isArrow() ? tok::arrow : tok::period, SS, 1507 1.1 joerg SourceLocation(), SetterName, nullptr); 1508 1.1 joerg if (SetterExpr.isInvalid()) { 1509 1.1 joerg S.Diag(RefExpr->getMemberLoc(), 1510 1.1 joerg diag::err_cannot_find_suitable_accessor) << 1 /* setter */ 1511 1.1 joerg << RefExpr->getPropertyDecl(); 1512 1.1 joerg return ExprError(); 1513 1.1 joerg } 1514 1.1 joerg 1515 1.1 joerg SmallVector<Expr*, 4> ArgExprs; 1516 1.1 joerg ArgExprs.append(CallArgs.begin(), CallArgs.end()); 1517 1.1 joerg ArgExprs.push_back(op); 1518 1.1 joerg return S.BuildCallExpr(S.getCurScope(), SetterExpr.get(), 1519 1.1 joerg RefExpr->getSourceRange().getBegin(), ArgExprs, 1520 1.1 joerg op->getSourceRange().getEnd()); 1521 1.1 joerg } 1522 1.1 joerg 1523 1.1 joerg //===----------------------------------------------------------------------===// 1524 1.1 joerg // General Sema routines. 1525 1.1 joerg //===----------------------------------------------------------------------===// 1526 1.1 joerg 1527 1.1 joerg ExprResult Sema::checkPseudoObjectRValue(Expr *E) { 1528 1.1 joerg Expr *opaqueRef = E->IgnoreParens(); 1529 1.1 joerg if (ObjCPropertyRefExpr *refExpr 1530 1.1 joerg = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { 1531 1.1 joerg ObjCPropertyOpBuilder builder(*this, refExpr, true); 1532 1.1 joerg return builder.buildRValueOperation(E); 1533 1.1 joerg } 1534 1.1 joerg else if (ObjCSubscriptRefExpr *refExpr 1535 1.1 joerg = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { 1536 1.1 joerg ObjCSubscriptOpBuilder builder(*this, refExpr, true); 1537 1.1 joerg return builder.buildRValueOperation(E); 1538 1.1 joerg } else if (MSPropertyRefExpr *refExpr 1539 1.1 joerg = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { 1540 1.1 joerg MSPropertyOpBuilder builder(*this, refExpr, true); 1541 1.1 joerg return builder.buildRValueOperation(E); 1542 1.1 joerg } else if (MSPropertySubscriptExpr *RefExpr = 1543 1.1 joerg dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { 1544 1.1 joerg MSPropertyOpBuilder Builder(*this, RefExpr, true); 1545 1.1 joerg return Builder.buildRValueOperation(E); 1546 1.1 joerg } else { 1547 1.1 joerg llvm_unreachable("unknown pseudo-object kind!"); 1548 1.1 joerg } 1549 1.1 joerg } 1550 1.1 joerg 1551 1.1 joerg /// Check an increment or decrement of a pseudo-object expression. 1552 1.1 joerg ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, 1553 1.1 joerg UnaryOperatorKind opcode, Expr *op) { 1554 1.1 joerg // Do nothing if the operand is dependent. 1555 1.1 joerg if (op->isTypeDependent()) 1556 1.1.1.2 joerg return UnaryOperator::Create(Context, op, opcode, Context.DependentTy, 1557 1.1.1.2 joerg VK_RValue, OK_Ordinary, opcLoc, false, 1558 1.1.1.2 joerg CurFPFeatureOverrides()); 1559 1.1 joerg 1560 1.1 joerg assert(UnaryOperator::isIncrementDecrementOp(opcode)); 1561 1.1 joerg Expr *opaqueRef = op->IgnoreParens(); 1562 1.1 joerg if (ObjCPropertyRefExpr *refExpr 1563 1.1 joerg = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { 1564 1.1 joerg ObjCPropertyOpBuilder builder(*this, refExpr, false); 1565 1.1 joerg return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); 1566 1.1 joerg } else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) { 1567 1.1 joerg Diag(opcLoc, diag::err_illegal_container_subscripting_op); 1568 1.1 joerg return ExprError(); 1569 1.1 joerg } else if (MSPropertyRefExpr *refExpr 1570 1.1 joerg = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { 1571 1.1 joerg MSPropertyOpBuilder builder(*this, refExpr, false); 1572 1.1 joerg return builder.buildIncDecOperation(Sc, opcLoc, opcode, op); 1573 1.1 joerg } else if (MSPropertySubscriptExpr *RefExpr 1574 1.1 joerg = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { 1575 1.1 joerg MSPropertyOpBuilder Builder(*this, RefExpr, false); 1576 1.1 joerg return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op); 1577 1.1 joerg } else { 1578 1.1 joerg llvm_unreachable("unknown pseudo-object kind!"); 1579 1.1 joerg } 1580 1.1 joerg } 1581 1.1 joerg 1582 1.1 joerg ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, 1583 1.1 joerg BinaryOperatorKind opcode, 1584 1.1 joerg Expr *LHS, Expr *RHS) { 1585 1.1 joerg // Do nothing if either argument is dependent. 1586 1.1 joerg if (LHS->isTypeDependent() || RHS->isTypeDependent()) 1587 1.1.1.2 joerg return BinaryOperator::Create(Context, LHS, RHS, opcode, 1588 1.1.1.2 joerg Context.DependentTy, VK_RValue, OK_Ordinary, 1589 1.1.1.2 joerg opcLoc, CurFPFeatureOverrides()); 1590 1.1 joerg 1591 1.1 joerg // Filter out non-overload placeholder types in the RHS. 1592 1.1 joerg if (RHS->getType()->isNonOverloadPlaceholderType()) { 1593 1.1 joerg ExprResult result = CheckPlaceholderExpr(RHS); 1594 1.1 joerg if (result.isInvalid()) return ExprError(); 1595 1.1 joerg RHS = result.get(); 1596 1.1 joerg } 1597 1.1 joerg 1598 1.1 joerg bool IsSimpleAssign = opcode == BO_Assign; 1599 1.1 joerg Expr *opaqueRef = LHS->IgnoreParens(); 1600 1.1 joerg if (ObjCPropertyRefExpr *refExpr 1601 1.1 joerg = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) { 1602 1.1 joerg ObjCPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign); 1603 1.1 joerg return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 1604 1.1 joerg } else if (ObjCSubscriptRefExpr *refExpr 1605 1.1 joerg = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) { 1606 1.1 joerg ObjCSubscriptOpBuilder builder(*this, refExpr, IsSimpleAssign); 1607 1.1 joerg return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 1608 1.1 joerg } else if (MSPropertyRefExpr *refExpr 1609 1.1 joerg = dyn_cast<MSPropertyRefExpr>(opaqueRef)) { 1610 1.1 joerg MSPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign); 1611 1.1 joerg return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 1612 1.1 joerg } else if (MSPropertySubscriptExpr *RefExpr 1613 1.1 joerg = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) { 1614 1.1 joerg MSPropertyOpBuilder Builder(*this, RefExpr, IsSimpleAssign); 1615 1.1 joerg return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS); 1616 1.1 joerg } else { 1617 1.1 joerg llvm_unreachable("unknown pseudo-object kind!"); 1618 1.1 joerg } 1619 1.1 joerg } 1620 1.1 joerg 1621 1.1 joerg /// Given a pseudo-object reference, rebuild it without the opaque 1622 1.1 joerg /// values. Basically, undo the behavior of rebuildAndCaptureObject. 1623 1.1 joerg /// This should never operate in-place. 1624 1.1 joerg static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) { 1625 1.1 joerg return Rebuilder(S, 1626 1.1 joerg [=](Expr *E, unsigned) -> Expr * { 1627 1.1 joerg return cast<OpaqueValueExpr>(E)->getSourceExpr(); 1628 1.1 joerg }) 1629 1.1 joerg .rebuild(E); 1630 1.1 joerg } 1631 1.1 joerg 1632 1.1 joerg /// Given a pseudo-object expression, recreate what it looks like 1633 1.1 joerg /// syntactically without the attendant OpaqueValueExprs. 1634 1.1 joerg /// 1635 1.1 joerg /// This is a hack which should be removed when TreeTransform is 1636 1.1 joerg /// capable of rebuilding a tree without stripping implicit 1637 1.1 joerg /// operations. 1638 1.1 joerg Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { 1639 1.1 joerg Expr *syntax = E->getSyntacticForm(); 1640 1.1 joerg if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) { 1641 1.1 joerg Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); 1642 1.1.1.2 joerg return UnaryOperator::Create(Context, op, uop->getOpcode(), uop->getType(), 1643 1.1.1.2 joerg uop->getValueKind(), uop->getObjectKind(), 1644 1.1.1.2 joerg uop->getOperatorLoc(), uop->canOverflow(), 1645 1.1.1.2 joerg CurFPFeatureOverrides()); 1646 1.1 joerg } else if (CompoundAssignOperator *cop 1647 1.1 joerg = dyn_cast<CompoundAssignOperator>(syntax)) { 1648 1.1 joerg Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); 1649 1.1 joerg Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr(); 1650 1.1.1.2 joerg return CompoundAssignOperator::Create( 1651 1.1.1.2 joerg Context, lhs, rhs, cop->getOpcode(), cop->getType(), 1652 1.1.1.2 joerg cop->getValueKind(), cop->getObjectKind(), cop->getOperatorLoc(), 1653 1.1.1.2 joerg CurFPFeatureOverrides(), cop->getComputationLHSType(), 1654 1.1.1.2 joerg cop->getComputationResultType()); 1655 1.1.1.2 joerg 1656 1.1 joerg } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) { 1657 1.1 joerg Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS()); 1658 1.1 joerg Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr(); 1659 1.1.1.2 joerg return BinaryOperator::Create(Context, lhs, rhs, bop->getOpcode(), 1660 1.1.1.2 joerg bop->getType(), bop->getValueKind(), 1661 1.1.1.2 joerg bop->getObjectKind(), bop->getOperatorLoc(), 1662 1.1.1.2 joerg CurFPFeatureOverrides()); 1663 1.1.1.2 joerg 1664 1.1.1.2 joerg } else if (isa<CallExpr>(syntax)) { 1665 1.1.1.2 joerg return syntax; 1666 1.1 joerg } else { 1667 1.1 joerg assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject)); 1668 1.1 joerg return stripOpaqueValuesFromPseudoObjectRef(*this, syntax); 1669 1.1 joerg } 1670 1.1 joerg } 1671