1 //===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis for expressions involving
10 // pseudo-object references. Pseudo-objects are conceptual objects
11 // whose storage is entirely abstract and all accesses to which are
12 // translated through some sort of abstraction barrier.
14 // For example, Objective-C objects can have "properties", either
15 // declared or undeclared. A property may be accessed by writing
17 // where 'expr' is an r-value of Objective-C pointer type and 'prop'
18 // is the name of the property. If this expression is used in a context
19 // needing an r-value, it is treated as if it were a message-send
20 // of the associated 'getter' selector, typically:
22 // If it is used as the LHS of a simple assignment, it is treated
23 // as a message-send of the associated 'setter' selector, typically:
24 // [expr setProp: RHS]
25 // If it is used as the LHS of a compound assignment, or the operand
26 // of a unary increment or decrement, both are required; for example,
27 // 'expr.prop *= 100' would be translated to:
28 // [expr setProp: [expr prop] * 100]
30 //===----------------------------------------------------------------------===//
32 #include "clang/Sema/SemaInternal.h"
33 #include "clang/AST/ExprCXX.h"
34 #include "clang/AST/ExprObjC.h"
35 #include "clang/Basic/CharInfo.h"
36 #include "clang/Lex/Preprocessor.h"
37 #include "clang/Sema/Initialization.h"
38 #include "clang/Sema/ScopeInfo.h"
39 #include "llvm/ADT/SmallString.h"
41 using namespace clang
;
45 // Basically just a very focused copy of TreeTransform.
48 unsigned MSPropertySubscriptCount
;
49 typedef llvm::function_ref
<Expr
*(Expr
*, unsigned)> SpecificRebuilderRefTy
;
50 const SpecificRebuilderRefTy
&SpecificCallback
;
51 Rebuilder(Sema
&S
, const SpecificRebuilderRefTy
&SpecificCallback
)
52 : S(S
), MSPropertySubscriptCount(0),
53 SpecificCallback(SpecificCallback
) {}
55 Expr
*rebuildObjCPropertyRefExpr(ObjCPropertyRefExpr
*refExpr
) {
56 // Fortunately, the constraint that we're rebuilding something
57 // with a base limits the number of cases here.
58 if (refExpr
->isClassReceiver() || refExpr
->isSuperReceiver())
61 if (refExpr
->isExplicitProperty()) {
62 return new (S
.Context
) ObjCPropertyRefExpr(
63 refExpr
->getExplicitProperty(), refExpr
->getType(),
64 refExpr
->getValueKind(), refExpr
->getObjectKind(),
65 refExpr
->getLocation(), SpecificCallback(refExpr
->getBase(), 0));
67 return new (S
.Context
) ObjCPropertyRefExpr(
68 refExpr
->getImplicitPropertyGetter(),
69 refExpr
->getImplicitPropertySetter(), refExpr
->getType(),
70 refExpr
->getValueKind(), refExpr
->getObjectKind(),
71 refExpr
->getLocation(), SpecificCallback(refExpr
->getBase(), 0));
73 Expr
*rebuildObjCSubscriptRefExpr(ObjCSubscriptRefExpr
*refExpr
) {
74 assert(refExpr
->getBaseExpr());
75 assert(refExpr
->getKeyExpr());
77 return new (S
.Context
) ObjCSubscriptRefExpr(
78 SpecificCallback(refExpr
->getBaseExpr(), 0),
79 SpecificCallback(refExpr
->getKeyExpr(), 1), refExpr
->getType(),
80 refExpr
->getValueKind(), refExpr
->getObjectKind(),
81 refExpr
->getAtIndexMethodDecl(), refExpr
->setAtIndexMethodDecl(),
82 refExpr
->getRBracket());
84 Expr
*rebuildMSPropertyRefExpr(MSPropertyRefExpr
*refExpr
) {
85 assert(refExpr
->getBaseExpr());
87 return new (S
.Context
) MSPropertyRefExpr(
88 SpecificCallback(refExpr
->getBaseExpr(), 0),
89 refExpr
->getPropertyDecl(), refExpr
->isArrow(), refExpr
->getType(),
90 refExpr
->getValueKind(), refExpr
->getQualifierLoc(),
91 refExpr
->getMemberLoc());
93 Expr
*rebuildMSPropertySubscriptExpr(MSPropertySubscriptExpr
*refExpr
) {
94 assert(refExpr
->getBase());
95 assert(refExpr
->getIdx());
97 auto *NewBase
= rebuild(refExpr
->getBase());
98 ++MSPropertySubscriptCount
;
99 return new (S
.Context
) MSPropertySubscriptExpr(
101 SpecificCallback(refExpr
->getIdx(), MSPropertySubscriptCount
),
102 refExpr
->getType(), refExpr
->getValueKind(), refExpr
->getObjectKind(),
103 refExpr
->getRBracketLoc());
106 Expr
*rebuild(Expr
*e
) {
107 // Fast path: nothing to look through.
108 if (auto *PRE
= dyn_cast
<ObjCPropertyRefExpr
>(e
))
109 return rebuildObjCPropertyRefExpr(PRE
);
110 if (auto *SRE
= dyn_cast
<ObjCSubscriptRefExpr
>(e
))
111 return rebuildObjCSubscriptRefExpr(SRE
);
112 if (auto *MSPRE
= dyn_cast
<MSPropertyRefExpr
>(e
))
113 return rebuildMSPropertyRefExpr(MSPRE
);
114 if (auto *MSPSE
= dyn_cast
<MSPropertySubscriptExpr
>(e
))
115 return rebuildMSPropertySubscriptExpr(MSPSE
);
117 // Otherwise, we should look through and rebuild anything that
118 // IgnoreParens would.
120 if (ParenExpr
*parens
= dyn_cast
<ParenExpr
>(e
)) {
121 e
= rebuild(parens
->getSubExpr());
122 return new (S
.Context
) ParenExpr(parens
->getLParen(),
127 if (UnaryOperator
*uop
= dyn_cast
<UnaryOperator
>(e
)) {
128 assert(uop
->getOpcode() == UO_Extension
);
129 e
= rebuild(uop
->getSubExpr());
130 return UnaryOperator::Create(
131 S
.Context
, e
, uop
->getOpcode(), uop
->getType(), uop
->getValueKind(),
132 uop
->getObjectKind(), uop
->getOperatorLoc(), uop
->canOverflow(),
133 S
.CurFPFeatureOverrides());
136 if (GenericSelectionExpr
*gse
= dyn_cast
<GenericSelectionExpr
>(e
)) {
137 assert(!gse
->isResultDependent());
138 unsigned resultIndex
= gse
->getResultIndex();
139 unsigned numAssocs
= gse
->getNumAssocs();
141 SmallVector
<Expr
*, 8> assocExprs
;
142 SmallVector
<TypeSourceInfo
*, 8> assocTypes
;
143 assocExprs
.reserve(numAssocs
);
144 assocTypes
.reserve(numAssocs
);
146 for (const GenericSelectionExpr::Association assoc
:
147 gse
->associations()) {
148 Expr
*assocExpr
= assoc
.getAssociationExpr();
149 if (assoc
.isSelected())
150 assocExpr
= rebuild(assocExpr
);
151 assocExprs
.push_back(assocExpr
);
152 assocTypes
.push_back(assoc
.getTypeSourceInfo());
155 return GenericSelectionExpr::Create(
156 S
.Context
, gse
->getGenericLoc(), gse
->getControllingExpr(),
157 assocTypes
, assocExprs
, gse
->getDefaultLoc(), gse
->getRParenLoc(),
158 gse
->containsUnexpandedParameterPack(), resultIndex
);
161 if (ChooseExpr
*ce
= dyn_cast
<ChooseExpr
>(e
)) {
162 assert(!ce
->isConditionDependent());
164 Expr
*LHS
= ce
->getLHS(), *RHS
= ce
->getRHS();
165 Expr
*&rebuiltExpr
= ce
->isConditionTrue() ? LHS
: RHS
;
166 rebuiltExpr
= rebuild(rebuiltExpr
);
168 return new (S
.Context
)
169 ChooseExpr(ce
->getBuiltinLoc(), ce
->getCond(), LHS
, RHS
,
170 rebuiltExpr
->getType(), rebuiltExpr
->getValueKind(),
171 rebuiltExpr
->getObjectKind(), ce
->getRParenLoc(),
172 ce
->isConditionTrue());
175 llvm_unreachable("bad expression to rebuild!");
179 class PseudoOpBuilder
{
182 unsigned ResultIndex
;
183 SourceLocation GenericLoc
;
185 SmallVector
<Expr
*, 4> Semantics
;
187 PseudoOpBuilder(Sema
&S
, SourceLocation genericLoc
, bool IsUnique
)
188 : S(S
), ResultIndex(PseudoObjectExpr::NoResult
),
189 GenericLoc(genericLoc
), IsUnique(IsUnique
) {}
191 virtual ~PseudoOpBuilder() {}
193 /// Add a normal semantic expression.
194 void addSemanticExpr(Expr
*semantic
) {
195 Semantics
.push_back(semantic
);
198 /// Add the 'result' semantic expression.
199 void addResultSemanticExpr(Expr
*resultExpr
) {
200 assert(ResultIndex
== PseudoObjectExpr::NoResult
);
201 ResultIndex
= Semantics
.size();
202 Semantics
.push_back(resultExpr
);
203 // An OVE is not unique if it is used as the result expression.
204 if (auto *OVE
= dyn_cast
<OpaqueValueExpr
>(Semantics
.back()))
205 OVE
->setIsUnique(false);
208 ExprResult
buildRValueOperation(Expr
*op
);
209 ExprResult
buildAssignmentOperation(Scope
*Sc
,
210 SourceLocation opLoc
,
211 BinaryOperatorKind opcode
,
212 Expr
*LHS
, Expr
*RHS
);
213 ExprResult
buildIncDecOperation(Scope
*Sc
, SourceLocation opLoc
,
214 UnaryOperatorKind opcode
,
217 virtual ExprResult
complete(Expr
*syntacticForm
);
219 OpaqueValueExpr
*capture(Expr
*op
);
220 OpaqueValueExpr
*captureValueAsResult(Expr
*op
);
222 void setResultToLastSemantic() {
223 assert(ResultIndex
== PseudoObjectExpr::NoResult
);
224 ResultIndex
= Semantics
.size() - 1;
225 // An OVE is not unique if it is used as the result expression.
226 if (auto *OVE
= dyn_cast
<OpaqueValueExpr
>(Semantics
.back()))
227 OVE
->setIsUnique(false);
230 /// Return true if assignments have a non-void result.
231 static bool CanCaptureValue(Expr
*exp
) {
232 if (exp
->isGLValue())
234 QualType ty
= exp
->getType();
235 assert(!ty
->isIncompleteType());
236 assert(!ty
->isDependentType());
238 if (const CXXRecordDecl
*ClassDecl
= ty
->getAsCXXRecordDecl())
239 return ClassDecl
->isTriviallyCopyable();
243 virtual Expr
*rebuildAndCaptureObject(Expr
*) = 0;
244 virtual ExprResult
buildGet() = 0;
245 virtual ExprResult
buildSet(Expr
*, SourceLocation
,
246 bool captureSetValueAsResult
) = 0;
247 /// Should the result of an assignment be the formal result of the
248 /// setter call or the value that was passed to the setter?
250 /// Different pseudo-object language features use different language rules
252 /// The default is to use the set value. Currently, this affects the
253 /// behavior of simple assignments, compound assignments, and prefix
254 /// increment and decrement.
255 /// Postfix increment and decrement always use the getter result as the
256 /// expression result.
258 /// If this method returns true, and the set value isn't capturable for
259 /// some reason, the result of the expression will be void.
260 virtual bool captureSetValueAsResult() const { return true; }
263 /// A PseudoOpBuilder for Objective-C \@properties.
264 class ObjCPropertyOpBuilder
: public PseudoOpBuilder
{
265 ObjCPropertyRefExpr
*RefExpr
;
266 ObjCPropertyRefExpr
*SyntacticRefExpr
;
267 OpaqueValueExpr
*InstanceReceiver
;
268 ObjCMethodDecl
*Getter
;
270 ObjCMethodDecl
*Setter
;
271 Selector SetterSelector
;
272 Selector GetterSelector
;
275 ObjCPropertyOpBuilder(Sema
&S
, ObjCPropertyRefExpr
*refExpr
, bool IsUnique
)
276 : PseudoOpBuilder(S
, refExpr
->getLocation(), IsUnique
),
277 RefExpr(refExpr
), SyntacticRefExpr(nullptr),
278 InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
281 ExprResult
buildRValueOperation(Expr
*op
);
282 ExprResult
buildAssignmentOperation(Scope
*Sc
,
283 SourceLocation opLoc
,
284 BinaryOperatorKind opcode
,
285 Expr
*LHS
, Expr
*RHS
);
286 ExprResult
buildIncDecOperation(Scope
*Sc
, SourceLocation opLoc
,
287 UnaryOperatorKind opcode
,
290 bool tryBuildGetOfReference(Expr
*op
, ExprResult
&result
);
291 bool findSetter(bool warn
=true);
293 void DiagnoseUnsupportedPropertyUse();
295 Expr
*rebuildAndCaptureObject(Expr
*syntacticBase
) override
;
296 ExprResult
buildGet() override
;
297 ExprResult
buildSet(Expr
*op
, SourceLocation
, bool) override
;
298 ExprResult
complete(Expr
*SyntacticForm
) override
;
300 bool isWeakProperty() const;
303 /// A PseudoOpBuilder for Objective-C array/dictionary indexing.
304 class ObjCSubscriptOpBuilder
: public PseudoOpBuilder
{
305 ObjCSubscriptRefExpr
*RefExpr
;
306 OpaqueValueExpr
*InstanceBase
;
307 OpaqueValueExpr
*InstanceKey
;
308 ObjCMethodDecl
*AtIndexGetter
;
309 Selector AtIndexGetterSelector
;
311 ObjCMethodDecl
*AtIndexSetter
;
312 Selector AtIndexSetterSelector
;
315 ObjCSubscriptOpBuilder(Sema
&S
, ObjCSubscriptRefExpr
*refExpr
, bool IsUnique
)
316 : PseudoOpBuilder(S
, refExpr
->getSourceRange().getBegin(), IsUnique
),
317 RefExpr(refExpr
), InstanceBase(nullptr), InstanceKey(nullptr),
318 AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
320 ExprResult
buildRValueOperation(Expr
*op
);
321 ExprResult
buildAssignmentOperation(Scope
*Sc
,
322 SourceLocation opLoc
,
323 BinaryOperatorKind opcode
,
324 Expr
*LHS
, Expr
*RHS
);
325 Expr
*rebuildAndCaptureObject(Expr
*syntacticBase
) override
;
327 bool findAtIndexGetter();
328 bool findAtIndexSetter();
330 ExprResult
buildGet() override
;
331 ExprResult
buildSet(Expr
*op
, SourceLocation
, bool) override
;
334 class MSPropertyOpBuilder
: public PseudoOpBuilder
{
335 MSPropertyRefExpr
*RefExpr
;
336 OpaqueValueExpr
*InstanceBase
;
337 SmallVector
<Expr
*, 4> CallArgs
;
339 MSPropertyRefExpr
*getBaseMSProperty(MSPropertySubscriptExpr
*E
);
342 MSPropertyOpBuilder(Sema
&S
, MSPropertyRefExpr
*refExpr
, bool IsUnique
)
343 : PseudoOpBuilder(S
, refExpr
->getSourceRange().getBegin(), IsUnique
),
344 RefExpr(refExpr
), InstanceBase(nullptr) {}
345 MSPropertyOpBuilder(Sema
&S
, MSPropertySubscriptExpr
*refExpr
, bool IsUnique
)
346 : PseudoOpBuilder(S
, refExpr
->getSourceRange().getBegin(), IsUnique
),
347 InstanceBase(nullptr) {
348 RefExpr
= getBaseMSProperty(refExpr
);
351 Expr
*rebuildAndCaptureObject(Expr
*) override
;
352 ExprResult
buildGet() override
;
353 ExprResult
buildSet(Expr
*op
, SourceLocation
, bool) override
;
354 bool captureSetValueAsResult() const override
{ return false; }
358 /// Capture the given expression in an OpaqueValueExpr.
359 OpaqueValueExpr
*PseudoOpBuilder::capture(Expr
*e
) {
360 // Make a new OVE whose source is the given expression.
361 OpaqueValueExpr
*captured
=
362 new (S
.Context
) OpaqueValueExpr(GenericLoc
, e
->getType(),
363 e
->getValueKind(), e
->getObjectKind(),
366 captured
->setIsUnique(true);
368 // Make sure we bind that in the semantics.
369 addSemanticExpr(captured
);
373 /// Capture the given expression as the result of this pseudo-object
374 /// operation. This routine is safe against expressions which may
375 /// already be captured.
377 /// \returns the captured expression, which will be the
378 /// same as the input if the input was already captured
379 OpaqueValueExpr
*PseudoOpBuilder::captureValueAsResult(Expr
*e
) {
380 assert(ResultIndex
== PseudoObjectExpr::NoResult
);
382 // If the expression hasn't already been captured, just capture it
383 // and set the new semantic
384 if (!isa
<OpaqueValueExpr
>(e
)) {
385 OpaqueValueExpr
*cap
= capture(e
);
386 setResultToLastSemantic();
390 // Otherwise, it must already be one of our semantic expressions;
391 // set ResultIndex to its index.
394 assert(index
< Semantics
.size() &&
395 "captured expression not found in semantics!");
396 if (e
== Semantics
[index
]) break;
399 // An OVE is not unique if it is used as the result expression.
400 cast
<OpaqueValueExpr
>(e
)->setIsUnique(false);
401 return cast
<OpaqueValueExpr
>(e
);
404 /// The routine which creates the final PseudoObjectExpr.
405 ExprResult
PseudoOpBuilder::complete(Expr
*syntactic
) {
406 return PseudoObjectExpr::Create(S
.Context
, syntactic
,
407 Semantics
, ResultIndex
);
410 /// The main skeleton for building an r-value operation.
411 ExprResult
PseudoOpBuilder::buildRValueOperation(Expr
*op
) {
412 Expr
*syntacticBase
= rebuildAndCaptureObject(op
);
414 ExprResult getExpr
= buildGet();
415 if (getExpr
.isInvalid()) return ExprError();
416 addResultSemanticExpr(getExpr
.get());
418 return complete(syntacticBase
);
421 /// The basic skeleton for building a simple or compound
422 /// assignment operation.
424 PseudoOpBuilder::buildAssignmentOperation(Scope
*Sc
, SourceLocation opcLoc
,
425 BinaryOperatorKind opcode
,
426 Expr
*LHS
, Expr
*RHS
) {
427 assert(BinaryOperator::isAssignmentOp(opcode
));
429 Expr
*syntacticLHS
= rebuildAndCaptureObject(LHS
);
430 OpaqueValueExpr
*capturedRHS
= capture(RHS
);
432 // In some very specific cases, semantic analysis of the RHS as an
433 // expression may require it to be rewritten. In these cases, we
434 // cannot safely keep the OVE around. Fortunately, we don't really
435 // need to: we don't use this particular OVE in multiple places, and
436 // no clients rely that closely on matching up expressions in the
437 // semantic expression with expressions from the syntactic form.
438 Expr
*semanticRHS
= capturedRHS
;
439 if (RHS
->hasPlaceholderType() || isa
<InitListExpr
>(RHS
)) {
441 Semantics
.pop_back();
447 if (opcode
== BO_Assign
) {
448 result
= semanticRHS
;
449 syntactic
= BinaryOperator::Create(S
.Context
, syntacticLHS
, capturedRHS
,
450 opcode
, capturedRHS
->getType(),
451 capturedRHS
->getValueKind(), OK_Ordinary
,
452 opcLoc
, S
.CurFPFeatureOverrides());
455 ExprResult opLHS
= buildGet();
456 if (opLHS
.isInvalid()) return ExprError();
458 // Build an ordinary, non-compound operation.
459 BinaryOperatorKind nonCompound
=
460 BinaryOperator::getOpForCompoundAssignment(opcode
);
461 result
= S
.BuildBinOp(Sc
, opcLoc
, nonCompound
, opLHS
.get(), semanticRHS
);
462 if (result
.isInvalid()) return ExprError();
464 syntactic
= CompoundAssignOperator::Create(
465 S
.Context
, syntacticLHS
, capturedRHS
, opcode
, result
.get()->getType(),
466 result
.get()->getValueKind(), OK_Ordinary
, opcLoc
,
467 S
.CurFPFeatureOverrides(), opLHS
.get()->getType(),
468 result
.get()->getType());
471 // The result of the assignment, if not void, is the value set into
473 result
= buildSet(result
.get(), opcLoc
, captureSetValueAsResult());
474 if (result
.isInvalid()) return ExprError();
475 addSemanticExpr(result
.get());
476 if (!captureSetValueAsResult() && !result
.get()->getType()->isVoidType() &&
477 (result
.get()->isTypeDependent() || CanCaptureValue(result
.get())))
478 setResultToLastSemantic();
480 return complete(syntactic
);
483 /// The basic skeleton for building an increment or decrement
486 PseudoOpBuilder::buildIncDecOperation(Scope
*Sc
, SourceLocation opcLoc
,
487 UnaryOperatorKind opcode
,
489 assert(UnaryOperator::isIncrementDecrementOp(opcode
));
491 Expr
*syntacticOp
= rebuildAndCaptureObject(op
);
494 ExprResult result
= buildGet();
495 if (result
.isInvalid()) return ExprError();
497 QualType resultType
= result
.get()->getType();
499 // That's the postfix result.
500 if (UnaryOperator::isPostfix(opcode
) &&
501 (result
.get()->isTypeDependent() || CanCaptureValue(result
.get()))) {
502 result
= capture(result
.get());
503 setResultToLastSemantic();
506 // Add or subtract a literal 1.
507 llvm::APInt
oneV(S
.Context
.getTypeSize(S
.Context
.IntTy
), 1);
508 Expr
*one
= IntegerLiteral::Create(S
.Context
, oneV
, S
.Context
.IntTy
,
511 if (UnaryOperator::isIncrementOp(opcode
)) {
512 result
= S
.BuildBinOp(Sc
, opcLoc
, BO_Add
, result
.get(), one
);
514 result
= S
.BuildBinOp(Sc
, opcLoc
, BO_Sub
, result
.get(), one
);
516 if (result
.isInvalid()) return ExprError();
518 // Store that back into the result. The value stored is the result
519 // of a prefix operation.
520 result
= buildSet(result
.get(), opcLoc
, UnaryOperator::isPrefix(opcode
) &&
521 captureSetValueAsResult());
522 if (result
.isInvalid()) return ExprError();
523 addSemanticExpr(result
.get());
524 if (UnaryOperator::isPrefix(opcode
) && !captureSetValueAsResult() &&
525 !result
.get()->getType()->isVoidType() &&
526 (result
.get()->isTypeDependent() || CanCaptureValue(result
.get())))
527 setResultToLastSemantic();
529 UnaryOperator
*syntactic
=
530 UnaryOperator::Create(S
.Context
, syntacticOp
, opcode
, resultType
,
531 VK_LValue
, OK_Ordinary
, opcLoc
,
532 !resultType
->isDependentType()
533 ? S
.Context
.getTypeSize(resultType
) >=
534 S
.Context
.getTypeSize(S
.Context
.IntTy
)
536 S
.CurFPFeatureOverrides());
537 return complete(syntactic
);
541 //===----------------------------------------------------------------------===//
542 // Objective-C @property and implicit property references
543 //===----------------------------------------------------------------------===//
545 /// Look up a method in the receiver type of an Objective-C property
547 static ObjCMethodDecl
*LookupMethodInReceiverType(Sema
&S
, Selector sel
,
548 const ObjCPropertyRefExpr
*PRE
) {
549 if (PRE
->isObjectReceiver()) {
550 const ObjCObjectPointerType
*PT
=
551 PRE
->getBase()->getType()->castAs
<ObjCObjectPointerType
>();
553 // Special case for 'self' in class method implementations.
554 if (PT
->isObjCClassType() &&
555 S
.isSelfExpr(const_cast<Expr
*>(PRE
->getBase()))) {
556 // This cast is safe because isSelfExpr is only true within
558 ObjCMethodDecl
*method
=
559 cast
<ObjCMethodDecl
>(S
.CurContext
->getNonClosureAncestor());
560 return S
.LookupMethodInObjectType(sel
,
561 S
.Context
.getObjCInterfaceType(method
->getClassInterface()),
565 return S
.LookupMethodInObjectType(sel
, PT
->getPointeeType(), true);
568 if (PRE
->isSuperReceiver()) {
569 if (const ObjCObjectPointerType
*PT
=
570 PRE
->getSuperReceiverType()->getAs
<ObjCObjectPointerType
>())
571 return S
.LookupMethodInObjectType(sel
, PT
->getPointeeType(), true);
573 return S
.LookupMethodInObjectType(sel
, PRE
->getSuperReceiverType(), false);
576 assert(PRE
->isClassReceiver() && "Invalid expression");
577 QualType IT
= S
.Context
.getObjCInterfaceType(PRE
->getClassReceiver());
578 return S
.LookupMethodInObjectType(sel
, IT
, false);
581 bool ObjCPropertyOpBuilder::isWeakProperty() const {
583 if (RefExpr
->isExplicitProperty()) {
584 const ObjCPropertyDecl
*Prop
= RefExpr
->getExplicitProperty();
585 if (Prop
->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak
)
590 T
= Getter
->getReturnType();
595 return T
.getObjCLifetime() == Qualifiers::OCL_Weak
;
598 bool ObjCPropertyOpBuilder::findGetter() {
599 if (Getter
) return true;
601 // For implicit properties, just trust the lookup we already did.
602 if (RefExpr
->isImplicitProperty()) {
603 if ((Getter
= RefExpr
->getImplicitPropertyGetter())) {
604 GetterSelector
= Getter
->getSelector();
608 // Must build the getter selector the hard way.
609 ObjCMethodDecl
*setter
= RefExpr
->getImplicitPropertySetter();
610 assert(setter
&& "both setter and getter are null - cannot happen");
611 IdentifierInfo
*setterName
=
612 setter
->getSelector().getIdentifierInfoForSlot(0);
613 IdentifierInfo
*getterName
=
614 &S
.Context
.Idents
.get(setterName
->getName().substr(3));
616 S
.PP
.getSelectorTable().getNullarySelector(getterName
);
621 ObjCPropertyDecl
*prop
= RefExpr
->getExplicitProperty();
622 Getter
= LookupMethodInReceiverType(S
, prop
->getGetterName(), RefExpr
);
623 return (Getter
!= nullptr);
626 /// Try to find the most accurate setter declaration for the property
629 /// \return true if a setter was found, in which case Setter
630 bool ObjCPropertyOpBuilder::findSetter(bool warn
) {
631 // For implicit properties, just trust the lookup we already did.
632 if (RefExpr
->isImplicitProperty()) {
633 if (ObjCMethodDecl
*setter
= RefExpr
->getImplicitPropertySetter()) {
635 SetterSelector
= setter
->getSelector();
638 IdentifierInfo
*getterName
=
639 RefExpr
->getImplicitPropertyGetter()->getSelector()
640 .getIdentifierInfoForSlot(0);
642 SelectorTable::constructSetterSelector(S
.PP
.getIdentifierTable(),
643 S
.PP
.getSelectorTable(),
649 // For explicit properties, this is more involved.
650 ObjCPropertyDecl
*prop
= RefExpr
->getExplicitProperty();
651 SetterSelector
= prop
->getSetterName();
653 // Do a normal method lookup first.
654 if (ObjCMethodDecl
*setter
=
655 LookupMethodInReceiverType(S
, SetterSelector
, RefExpr
)) {
656 if (setter
->isPropertyAccessor() && warn
)
657 if (const ObjCInterfaceDecl
*IFace
=
658 dyn_cast
<ObjCInterfaceDecl
>(setter
->getDeclContext())) {
659 StringRef thisPropertyName
= prop
->getName();
660 // Try flipping the case of the first character.
661 char front
= thisPropertyName
.front();
662 front
= isLowercase(front
) ? toUppercase(front
) : toLowercase(front
);
663 SmallString
<100> PropertyName
= thisPropertyName
;
664 PropertyName
[0] = front
;
665 IdentifierInfo
*AltMember
= &S
.PP
.getIdentifierTable().get(PropertyName
);
666 if (ObjCPropertyDecl
*prop1
= IFace
->FindPropertyDeclaration(
667 AltMember
, prop
->getQueryKind()))
668 if (prop
!= prop1
&& (prop1
->getSetterMethodDecl() == setter
)) {
669 S
.Diag(RefExpr
->getExprLoc(), diag::err_property_setter_ambiguous_use
)
670 << prop
<< prop1
<< setter
->getSelector();
671 S
.Diag(prop
->getLocation(), diag::note_property_declare
);
672 S
.Diag(prop1
->getLocation(), diag::note_property_declare
);
679 // That can fail in the somewhat crazy situation that we're
680 // type-checking a message send within the @interface declaration
681 // that declared the @property. But it's not clear that that's
682 // valuable to support.
687 void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
688 if (S
.getCurLexicalContext()->isObjCContainer() &&
689 S
.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl
&&
690 S
.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation
) {
691 if (ObjCPropertyDecl
*prop
= RefExpr
->getExplicitProperty()) {
692 S
.Diag(RefExpr
->getLocation(),
693 diag::err_property_function_in_objc_container
);
694 S
.Diag(prop
->getLocation(), diag::note_property_declare
);
699 /// Capture the base object of an Objective-C property expression.
700 Expr
*ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr
*syntacticBase
) {
701 assert(InstanceReceiver
== nullptr);
703 // If we have a base, capture it in an OVE and rebuild the syntactic
704 // form to use the OVE as its base.
705 if (RefExpr
->isObjectReceiver()) {
706 InstanceReceiver
= capture(RefExpr
->getBase());
707 syntacticBase
= Rebuilder(S
, [=](Expr
*, unsigned) -> Expr
* {
708 return InstanceReceiver
;
709 }).rebuild(syntacticBase
);
712 if (ObjCPropertyRefExpr
*
713 refE
= dyn_cast
<ObjCPropertyRefExpr
>(syntacticBase
->IgnoreParens()))
714 SyntacticRefExpr
= refE
;
716 return syntacticBase
;
719 /// Load from an Objective-C property reference.
720 ExprResult
ObjCPropertyOpBuilder::buildGet() {
723 DiagnoseUnsupportedPropertyUse();
727 if (SyntacticRefExpr
)
728 SyntacticRefExpr
->setIsMessagingGetter();
730 QualType receiverType
= RefExpr
->getReceiverType(S
.Context
);
731 if (!Getter
->isImplicit())
732 S
.DiagnoseUseOfDecl(Getter
, GenericLoc
, nullptr, true);
733 // Build a message-send.
735 if ((Getter
->isInstanceMethod() && !RefExpr
->isClassReceiver()) ||
736 RefExpr
->isObjectReceiver()) {
737 assert(InstanceReceiver
|| RefExpr
->isSuperReceiver());
738 msg
= S
.BuildInstanceMessageImplicit(InstanceReceiver
, receiverType
,
739 GenericLoc
, Getter
->getSelector(),
742 msg
= S
.BuildClassMessageImplicit(receiverType
, RefExpr
->isSuperReceiver(),
743 GenericLoc
, Getter
->getSelector(),
749 /// Store to an Objective-C property reference.
751 /// \param captureSetValueAsResult If true, capture the actual
752 /// value being set as the value of the property operation.
753 ExprResult
ObjCPropertyOpBuilder::buildSet(Expr
*op
, SourceLocation opcLoc
,
754 bool captureSetValueAsResult
) {
755 if (!findSetter(false)) {
756 DiagnoseUnsupportedPropertyUse();
760 if (SyntacticRefExpr
)
761 SyntacticRefExpr
->setIsMessagingSetter();
763 QualType receiverType
= RefExpr
->getReceiverType(S
.Context
);
765 // Use assignment constraints when possible; they give us better
766 // diagnostics. "When possible" basically means anything except a
768 if (!S
.getLangOpts().CPlusPlus
|| !op
->getType()->isRecordType()) {
769 QualType paramType
= (*Setter
->param_begin())->getType()
770 .substObjCMemberType(
772 Setter
->getDeclContext(),
773 ObjCSubstitutionContext::Parameter
);
774 if (!S
.getLangOpts().CPlusPlus
|| !paramType
->isRecordType()) {
775 ExprResult opResult
= op
;
776 Sema::AssignConvertType assignResult
777 = S
.CheckSingleAssignmentConstraints(paramType
, opResult
);
778 if (opResult
.isInvalid() ||
779 S
.DiagnoseAssignmentResult(assignResult
, opcLoc
, paramType
,
780 op
->getType(), opResult
.get(),
785 assert(op
&& "successful assignment left argument invalid?");
790 Expr
*args
[] = { op
};
792 // Build a message-send.
794 if (!Setter
->isImplicit())
795 S
.DiagnoseUseOfDecl(Setter
, GenericLoc
, nullptr, true);
796 if ((Setter
->isInstanceMethod() && !RefExpr
->isClassReceiver()) ||
797 RefExpr
->isObjectReceiver()) {
798 msg
= S
.BuildInstanceMessageImplicit(InstanceReceiver
, receiverType
,
799 GenericLoc
, SetterSelector
, Setter
,
800 MultiExprArg(args
, 1));
802 msg
= S
.BuildClassMessageImplicit(receiverType
, RefExpr
->isSuperReceiver(),
804 SetterSelector
, Setter
,
805 MultiExprArg(args
, 1));
808 if (!msg
.isInvalid() && captureSetValueAsResult
) {
809 ObjCMessageExpr
*msgExpr
=
810 cast
<ObjCMessageExpr
>(msg
.get()->IgnoreImplicit());
811 Expr
*arg
= msgExpr
->getArg(0);
812 if (CanCaptureValue(arg
))
813 msgExpr
->setArg(0, captureValueAsResult(arg
));
819 /// @property-specific behavior for doing lvalue-to-rvalue conversion.
820 ExprResult
ObjCPropertyOpBuilder::buildRValueOperation(Expr
*op
) {
821 // Explicit properties always have getters, but implicit ones don't.
822 // Check that before proceeding.
823 if (RefExpr
->isImplicitProperty() && !RefExpr
->getImplicitPropertyGetter()) {
824 S
.Diag(RefExpr
->getLocation(), diag::err_getter_not_found
)
825 << RefExpr
->getSourceRange();
829 ExprResult result
= PseudoOpBuilder::buildRValueOperation(op
);
830 if (result
.isInvalid()) return ExprError();
832 if (RefExpr
->isExplicitProperty() && !Getter
->hasRelatedResultType())
833 S
.DiagnosePropertyAccessorMismatch(RefExpr
->getExplicitProperty(),
834 Getter
, RefExpr
->getLocation());
836 // As a special case, if the method returns 'id', try to get
837 // a better type from the property.
838 if (RefExpr
->isExplicitProperty() && result
.get()->isPRValue()) {
839 QualType receiverType
= RefExpr
->getReceiverType(S
.Context
);
840 QualType propType
= RefExpr
->getExplicitProperty()
841 ->getUsageType(receiverType
);
842 if (result
.get()->getType()->isObjCIdType()) {
843 if (const ObjCObjectPointerType
*ptr
844 = propType
->getAs
<ObjCObjectPointerType
>()) {
845 if (!ptr
->isObjCIdType())
846 result
= S
.ImpCastExprToType(result
.get(), propType
, CK_BitCast
);
849 if (propType
.getObjCLifetime() == Qualifiers::OCL_Weak
&&
850 !S
.Diags
.isIgnored(diag::warn_arc_repeated_use_of_weak
,
851 RefExpr
->getLocation()))
852 S
.getCurFunction()->markSafeWeakUse(RefExpr
);
858 /// Try to build this as a call to a getter that returns a reference.
860 /// \return true if it was possible, whether or not it actually
862 bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr
*op
,
863 ExprResult
&result
) {
864 if (!S
.getLangOpts().CPlusPlus
) return false;
868 // The property has no setter and no getter! This can happen if the type is
869 // invalid. Error have already been reported.
870 result
= ExprError();
874 // Only do this if the getter returns an l-value reference type.
875 QualType resultType
= Getter
->getReturnType();
876 if (!resultType
->isLValueReferenceType()) return false;
878 result
= buildRValueOperation(op
);
882 /// @property-specific behavior for doing assignments.
884 ObjCPropertyOpBuilder::buildAssignmentOperation(Scope
*Sc
,
885 SourceLocation opcLoc
,
886 BinaryOperatorKind opcode
,
887 Expr
*LHS
, Expr
*RHS
) {
888 assert(BinaryOperator::isAssignmentOp(opcode
));
890 // If there's no setter, we have no choice but to try to assign to
891 // the result of the getter.
894 if (tryBuildGetOfReference(LHS
, result
)) {
895 if (result
.isInvalid()) return ExprError();
896 return S
.BuildBinOp(Sc
, opcLoc
, opcode
, result
.get(), RHS
);
899 // Otherwise, it's an error.
900 S
.Diag(opcLoc
, diag::err_nosetter_property_assignment
)
901 << unsigned(RefExpr
->isImplicitProperty())
903 << LHS
->getSourceRange() << RHS
->getSourceRange();
907 // If there is a setter, we definitely want to use it.
909 // Verify that we can do a compound assignment.
910 if (opcode
!= BO_Assign
&& !findGetter()) {
911 S
.Diag(opcLoc
, diag::err_nogetter_property_compound_assignment
)
912 << LHS
->getSourceRange() << RHS
->getSourceRange();
917 PseudoOpBuilder::buildAssignmentOperation(Sc
, opcLoc
, opcode
, LHS
, RHS
);
918 if (result
.isInvalid()) return ExprError();
920 // Various warnings about property assignments in ARC.
921 if (S
.getLangOpts().ObjCAutoRefCount
&& InstanceReceiver
) {
922 S
.checkRetainCycles(InstanceReceiver
->getSourceExpr(), RHS
);
923 S
.checkUnsafeExprAssigns(opcLoc
, LHS
, RHS
);
929 /// @property-specific behavior for doing increments and decrements.
931 ObjCPropertyOpBuilder::buildIncDecOperation(Scope
*Sc
, SourceLocation opcLoc
,
932 UnaryOperatorKind opcode
,
934 // If there's no setter, we have no choice but to try to assign to
935 // the result of the getter.
938 if (tryBuildGetOfReference(op
, result
)) {
939 if (result
.isInvalid()) return ExprError();
940 return S
.BuildUnaryOp(Sc
, opcLoc
, opcode
, result
.get());
943 // Otherwise, it's an error.
944 S
.Diag(opcLoc
, diag::err_nosetter_property_incdec
)
945 << unsigned(RefExpr
->isImplicitProperty())
946 << unsigned(UnaryOperator::isDecrementOp(opcode
))
948 << op
->getSourceRange();
952 // If there is a setter, we definitely want to use it.
954 // We also need a getter.
956 assert(RefExpr
->isImplicitProperty());
957 S
.Diag(opcLoc
, diag::err_nogetter_property_incdec
)
958 << unsigned(UnaryOperator::isDecrementOp(opcode
))
960 << op
->getSourceRange();
964 return PseudoOpBuilder::buildIncDecOperation(Sc
, opcLoc
, opcode
, op
);
967 ExprResult
ObjCPropertyOpBuilder::complete(Expr
*SyntacticForm
) {
968 if (isWeakProperty() && !S
.isUnevaluatedContext() &&
969 !S
.Diags
.isIgnored(diag::warn_arc_repeated_use_of_weak
,
970 SyntacticForm
->getBeginLoc()))
971 S
.getCurFunction()->recordUseOfWeak(SyntacticRefExpr
,
972 SyntacticRefExpr
->isMessagingGetter());
974 return PseudoOpBuilder::complete(SyntacticForm
);
977 // ObjCSubscript build stuff.
980 /// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
982 /// FIXME. Remove this routine if it is proven that no additional
983 /// specifity is needed.
984 ExprResult
ObjCSubscriptOpBuilder::buildRValueOperation(Expr
*op
) {
985 ExprResult result
= PseudoOpBuilder::buildRValueOperation(op
);
986 if (result
.isInvalid()) return ExprError();
990 /// objective-c subscripting-specific behavior for doing assignments.
992 ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope
*Sc
,
993 SourceLocation opcLoc
,
994 BinaryOperatorKind opcode
,
995 Expr
*LHS
, Expr
*RHS
) {
996 assert(BinaryOperator::isAssignmentOp(opcode
));
997 // There must be a method to do the Index'ed assignment.
998 if (!findAtIndexSetter())
1001 // Verify that we can do a compound assignment.
1002 if (opcode
!= BO_Assign
&& !findAtIndexGetter())
1006 PseudoOpBuilder::buildAssignmentOperation(Sc
, opcLoc
, opcode
, LHS
, RHS
);
1007 if (result
.isInvalid()) return ExprError();
1009 // Various warnings about objc Index'ed assignments in ARC.
1010 if (S
.getLangOpts().ObjCAutoRefCount
&& InstanceBase
) {
1011 S
.checkRetainCycles(InstanceBase
->getSourceExpr(), RHS
);
1012 S
.checkUnsafeExprAssigns(opcLoc
, LHS
, RHS
);
1018 /// Capture the base object of an Objective-C Index'ed expression.
1019 Expr
*ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr
*syntacticBase
) {
1020 assert(InstanceBase
== nullptr);
1022 // Capture base expression in an OVE and rebuild the syntactic
1023 // form to use the OVE as its base expression.
1024 InstanceBase
= capture(RefExpr
->getBaseExpr());
1025 InstanceKey
= capture(RefExpr
->getKeyExpr());
1028 Rebuilder(S
, [=](Expr
*, unsigned Idx
) -> Expr
* {
1031 return InstanceBase
;
1035 llvm_unreachable("Unexpected index for ObjCSubscriptExpr");
1037 }).rebuild(syntacticBase
);
1039 return syntacticBase
;
1042 /// CheckSubscriptingKind - This routine decide what type
1043 /// of indexing represented by "FromE" is being done.
1044 Sema::ObjCSubscriptKind
1045 Sema::CheckSubscriptingKind(Expr
*FromE
) {
1046 // If the expression already has integral or enumeration type, we're golden.
1047 QualType T
= FromE
->getType();
1048 if (T
->isIntegralOrEnumerationType())
1051 // If we don't have a class type in C++, there's no way we can get an
1052 // expression of integral or enumeration type.
1053 const RecordType
*RecordTy
= T
->getAs
<RecordType
>();
1055 (T
->isObjCObjectPointerType() || T
->isVoidPointerType()))
1056 // All other scalar cases are assumed to be dictionary indexing which
1057 // caller handles, with diagnostics if needed.
1058 return OS_Dictionary
;
1059 if (!getLangOpts().CPlusPlus
||
1060 !RecordTy
|| RecordTy
->isIncompleteType()) {
1061 // No indexing can be done. Issue diagnostics and quit.
1062 const Expr
*IndexExpr
= FromE
->IgnoreParenImpCasts();
1063 if (isa
<StringLiteral
>(IndexExpr
))
1064 Diag(FromE
->getExprLoc(), diag::err_objc_subscript_pointer
)
1065 << T
<< FixItHint::CreateInsertion(FromE
->getExprLoc(), "@");
1067 Diag(FromE
->getExprLoc(), diag::err_objc_subscript_type_conversion
)
1072 // We must have a complete class type.
1073 if (RequireCompleteType(FromE
->getExprLoc(), T
,
1074 diag::err_objc_index_incomplete_class_type
, FromE
))
1077 // Look for a conversion to an integral, enumeration type, or
1078 // objective-C pointer type.
1079 int NoIntegrals
=0, NoObjCIdPointers
=0;
1080 SmallVector
<CXXConversionDecl
*, 4> ConversionDecls
;
1082 for (NamedDecl
*D
: cast
<CXXRecordDecl
>(RecordTy
->getDecl())
1083 ->getVisibleConversionFunctions()) {
1084 if (CXXConversionDecl
*Conversion
=
1085 dyn_cast
<CXXConversionDecl
>(D
->getUnderlyingDecl())) {
1086 QualType CT
= Conversion
->getConversionType().getNonReferenceType();
1087 if (CT
->isIntegralOrEnumerationType()) {
1089 ConversionDecls
.push_back(Conversion
);
1091 else if (CT
->isObjCIdType() ||CT
->isBlockPointerType()) {
1093 ConversionDecls
.push_back(Conversion
);
1097 if (NoIntegrals
==1 && NoObjCIdPointers
== 0)
1099 if (NoIntegrals
== 0 && NoObjCIdPointers
== 1)
1100 return OS_Dictionary
;
1101 if (NoIntegrals
== 0 && NoObjCIdPointers
== 0) {
1102 // No conversion function was found. Issue diagnostic and return.
1103 Diag(FromE
->getExprLoc(), diag::err_objc_subscript_type_conversion
)
1104 << FromE
->getType();
1107 Diag(FromE
->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion
)
1108 << FromE
->getType();
1109 for (unsigned int i
= 0; i
< ConversionDecls
.size(); i
++)
1110 Diag(ConversionDecls
[i
]->getLocation(),
1111 diag::note_conv_function_declared_at
);
1116 /// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
1117 /// objects used as dictionary subscript key objects.
1118 static void CheckKeyForObjCARCConversion(Sema
&S
, QualType ContainerT
,
1120 if (ContainerT
.isNull())
1122 // dictionary subscripting.
1123 // - (id)objectForKeyedSubscript:(id)key;
1124 IdentifierInfo
*KeyIdents
[] = {
1125 &S
.Context
.Idents
.get("objectForKeyedSubscript")
1127 Selector GetterSelector
= S
.Context
.Selectors
.getSelector(1, KeyIdents
);
1128 ObjCMethodDecl
*Getter
= S
.LookupMethodInObjectType(GetterSelector
, ContainerT
,
1132 QualType T
= Getter
->parameters()[0]->getType();
1133 S
.CheckObjCConversion(Key
->getSourceRange(), T
, Key
,
1134 Sema::CCK_ImplicitConversion
);
1137 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1141 Expr
*BaseExpr
= RefExpr
->getBaseExpr();
1142 QualType BaseT
= BaseExpr
->getType();
1144 QualType ResultType
;
1145 if (const ObjCObjectPointerType
*PTy
=
1146 BaseT
->getAs
<ObjCObjectPointerType
>()) {
1147 ResultType
= PTy
->getPointeeType();
1149 Sema::ObjCSubscriptKind Res
=
1150 S
.CheckSubscriptingKind(RefExpr
->getKeyExpr());
1151 if (Res
== Sema::OS_Error
) {
1152 if (S
.getLangOpts().ObjCAutoRefCount
)
1153 CheckKeyForObjCARCConversion(S
, ResultType
,
1154 RefExpr
->getKeyExpr());
1157 bool arrayRef
= (Res
== Sema::OS_Array
);
1159 if (ResultType
.isNull()) {
1160 S
.Diag(BaseExpr
->getExprLoc(), diag::err_objc_subscript_base_type
)
1161 << BaseExpr
->getType() << arrayRef
;
1165 // dictionary subscripting.
1166 // - (id)objectForKeyedSubscript:(id)key;
1167 IdentifierInfo
*KeyIdents
[] = {
1168 &S
.Context
.Idents
.get("objectForKeyedSubscript")
1170 AtIndexGetterSelector
= S
.Context
.Selectors
.getSelector(1, KeyIdents
);
1173 // - (id)objectAtIndexedSubscript:(size_t)index;
1174 IdentifierInfo
*KeyIdents
[] = {
1175 &S
.Context
.Idents
.get("objectAtIndexedSubscript")
1178 AtIndexGetterSelector
= S
.Context
.Selectors
.getSelector(1, KeyIdents
);
1181 AtIndexGetter
= S
.LookupMethodInObjectType(AtIndexGetterSelector
, ResultType
,
1184 if (!AtIndexGetter
&& S
.getLangOpts().DebuggerObjCLiteral
) {
1185 AtIndexGetter
= ObjCMethodDecl::Create(
1186 S
.Context
, SourceLocation(), SourceLocation(), AtIndexGetterSelector
,
1187 S
.Context
.getObjCIdType() /*ReturnType*/, nullptr /*TypeSourceInfo */,
1188 S
.Context
.getTranslationUnitDecl(), true /*Instance*/,
1189 false /*isVariadic*/,
1190 /*isPropertyAccessor=*/false,
1191 /*isSynthesizedAccessorStub=*/false,
1192 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1193 ObjCMethodDecl::Required
, false);
1194 ParmVarDecl
*Argument
= ParmVarDecl::Create(S
.Context
, AtIndexGetter
,
1195 SourceLocation(), SourceLocation(),
1196 arrayRef
? &S
.Context
.Idents
.get("index")
1197 : &S
.Context
.Idents
.get("key"),
1198 arrayRef
? S
.Context
.UnsignedLongTy
1199 : S
.Context
.getObjCIdType(),
1203 AtIndexGetter
->setMethodParams(S
.Context
, Argument
, None
);
1206 if (!AtIndexGetter
) {
1207 if (!BaseT
->isObjCIdType()) {
1208 S
.Diag(BaseExpr
->getExprLoc(), diag::err_objc_subscript_method_not_found
)
1209 << BaseExpr
->getType() << 0 << arrayRef
;
1213 S
.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector
,
1214 RefExpr
->getSourceRange(),
1218 if (AtIndexGetter
) {
1219 QualType T
= AtIndexGetter
->parameters()[0]->getType();
1220 if ((arrayRef
&& !T
->isIntegralOrEnumerationType()) ||
1221 (!arrayRef
&& !T
->isObjCObjectPointerType())) {
1222 S
.Diag(RefExpr
->getKeyExpr()->getExprLoc(),
1223 arrayRef
? diag::err_objc_subscript_index_type
1224 : diag::err_objc_subscript_key_type
) << T
;
1225 S
.Diag(AtIndexGetter
->parameters()[0]->getLocation(),
1226 diag::note_parameter_type
) << T
;
1229 QualType R
= AtIndexGetter
->getReturnType();
1230 if (!R
->isObjCObjectPointerType()) {
1231 S
.Diag(RefExpr
->getKeyExpr()->getExprLoc(),
1232 diag::err_objc_indexing_method_result_type
) << R
<< arrayRef
;
1233 S
.Diag(AtIndexGetter
->getLocation(), diag::note_method_declared_at
) <<
1234 AtIndexGetter
->getDeclName();
1240 bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1244 Expr
*BaseExpr
= RefExpr
->getBaseExpr();
1245 QualType BaseT
= BaseExpr
->getType();
1247 QualType ResultType
;
1248 if (const ObjCObjectPointerType
*PTy
=
1249 BaseT
->getAs
<ObjCObjectPointerType
>()) {
1250 ResultType
= PTy
->getPointeeType();
1253 Sema::ObjCSubscriptKind Res
=
1254 S
.CheckSubscriptingKind(RefExpr
->getKeyExpr());
1255 if (Res
== Sema::OS_Error
) {
1256 if (S
.getLangOpts().ObjCAutoRefCount
)
1257 CheckKeyForObjCARCConversion(S
, ResultType
,
1258 RefExpr
->getKeyExpr());
1261 bool arrayRef
= (Res
== Sema::OS_Array
);
1263 if (ResultType
.isNull()) {
1264 S
.Diag(BaseExpr
->getExprLoc(), diag::err_objc_subscript_base_type
)
1265 << BaseExpr
->getType() << arrayRef
;
1270 // dictionary subscripting.
1271 // - (void)setObject:(id)object forKeyedSubscript:(id)key;
1272 IdentifierInfo
*KeyIdents
[] = {
1273 &S
.Context
.Idents
.get("setObject"),
1274 &S
.Context
.Idents
.get("forKeyedSubscript")
1276 AtIndexSetterSelector
= S
.Context
.Selectors
.getSelector(2, KeyIdents
);
1279 // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1280 IdentifierInfo
*KeyIdents
[] = {
1281 &S
.Context
.Idents
.get("setObject"),
1282 &S
.Context
.Idents
.get("atIndexedSubscript")
1284 AtIndexSetterSelector
= S
.Context
.Selectors
.getSelector(2, KeyIdents
);
1286 AtIndexSetter
= S
.LookupMethodInObjectType(AtIndexSetterSelector
, ResultType
,
1289 if (!AtIndexSetter
&& S
.getLangOpts().DebuggerObjCLiteral
) {
1290 TypeSourceInfo
*ReturnTInfo
= nullptr;
1291 QualType ReturnType
= S
.Context
.VoidTy
;
1292 AtIndexSetter
= ObjCMethodDecl::Create(
1293 S
.Context
, SourceLocation(), SourceLocation(), AtIndexSetterSelector
,
1294 ReturnType
, ReturnTInfo
, S
.Context
.getTranslationUnitDecl(),
1295 true /*Instance*/, false /*isVariadic*/,
1296 /*isPropertyAccessor=*/false,
1297 /*isSynthesizedAccessorStub=*/false,
1298 /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1299 ObjCMethodDecl::Required
, false);
1300 SmallVector
<ParmVarDecl
*, 2> Params
;
1301 ParmVarDecl
*object
= ParmVarDecl::Create(S
.Context
, AtIndexSetter
,
1302 SourceLocation(), SourceLocation(),
1303 &S
.Context
.Idents
.get("object"),
1304 S
.Context
.getObjCIdType(),
1308 Params
.push_back(object
);
1309 ParmVarDecl
*key
= ParmVarDecl::Create(S
.Context
, AtIndexSetter
,
1310 SourceLocation(), SourceLocation(),
1311 arrayRef
? &S
.Context
.Idents
.get("index")
1312 : &S
.Context
.Idents
.get("key"),
1313 arrayRef
? S
.Context
.UnsignedLongTy
1314 : S
.Context
.getObjCIdType(),
1318 Params
.push_back(key
);
1319 AtIndexSetter
->setMethodParams(S
.Context
, Params
, None
);
1322 if (!AtIndexSetter
) {
1323 if (!BaseT
->isObjCIdType()) {
1324 S
.Diag(BaseExpr
->getExprLoc(),
1325 diag::err_objc_subscript_method_not_found
)
1326 << BaseExpr
->getType() << 1 << arrayRef
;
1330 S
.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector
,
1331 RefExpr
->getSourceRange(),
1336 if (AtIndexSetter
&& arrayRef
) {
1337 QualType T
= AtIndexSetter
->parameters()[1]->getType();
1338 if (!T
->isIntegralOrEnumerationType()) {
1339 S
.Diag(RefExpr
->getKeyExpr()->getExprLoc(),
1340 diag::err_objc_subscript_index_type
) << T
;
1341 S
.Diag(AtIndexSetter
->parameters()[1]->getLocation(),
1342 diag::note_parameter_type
) << T
;
1345 T
= AtIndexSetter
->parameters()[0]->getType();
1346 if (!T
->isObjCObjectPointerType()) {
1347 S
.Diag(RefExpr
->getBaseExpr()->getExprLoc(),
1348 diag::err_objc_subscript_object_type
) << T
<< arrayRef
;
1349 S
.Diag(AtIndexSetter
->parameters()[0]->getLocation(),
1350 diag::note_parameter_type
) << T
;
1354 else if (AtIndexSetter
&& !arrayRef
)
1355 for (unsigned i
=0; i
<2; i
++) {
1356 QualType T
= AtIndexSetter
->parameters()[i
]->getType();
1357 if (!T
->isObjCObjectPointerType()) {
1359 S
.Diag(RefExpr
->getKeyExpr()->getExprLoc(),
1360 diag::err_objc_subscript_key_type
) << T
;
1362 S
.Diag(RefExpr
->getBaseExpr()->getExprLoc(),
1363 diag::err_objc_subscript_dic_object_type
) << T
;
1364 S
.Diag(AtIndexSetter
->parameters()[i
]->getLocation(),
1365 diag::note_parameter_type
) << T
;
1373 // Get the object at "Index" position in the container.
1374 // [BaseExpr objectAtIndexedSubscript : IndexExpr];
1375 ExprResult
ObjCSubscriptOpBuilder::buildGet() {
1376 if (!findAtIndexGetter())
1379 QualType receiverType
= InstanceBase
->getType();
1381 // Build a message-send.
1383 Expr
*Index
= InstanceKey
;
1386 Expr
*args
[] = { Index
};
1387 assert(InstanceBase
);
1389 S
.DiagnoseUseOfDecl(AtIndexGetter
, GenericLoc
);
1390 msg
= S
.BuildInstanceMessageImplicit(InstanceBase
, receiverType
,
1392 AtIndexGetterSelector
, AtIndexGetter
,
1393 MultiExprArg(args
, 1));
1397 /// Store into the container the "op" object at "Index"'ed location
1398 /// by building this messaging expression:
1399 /// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1400 /// \param captureSetValueAsResult If true, capture the actual
1401 /// value being set as the value of the property operation.
1402 ExprResult
ObjCSubscriptOpBuilder::buildSet(Expr
*op
, SourceLocation opcLoc
,
1403 bool captureSetValueAsResult
) {
1404 if (!findAtIndexSetter())
1407 S
.DiagnoseUseOfDecl(AtIndexSetter
, GenericLoc
);
1408 QualType receiverType
= InstanceBase
->getType();
1409 Expr
*Index
= InstanceKey
;
1412 Expr
*args
[] = { op
, Index
};
1414 // Build a message-send.
1415 ExprResult msg
= S
.BuildInstanceMessageImplicit(InstanceBase
, receiverType
,
1417 AtIndexSetterSelector
,
1419 MultiExprArg(args
, 2));
1421 if (!msg
.isInvalid() && captureSetValueAsResult
) {
1422 ObjCMessageExpr
*msgExpr
=
1423 cast
<ObjCMessageExpr
>(msg
.get()->IgnoreImplicit());
1424 Expr
*arg
= msgExpr
->getArg(0);
1425 if (CanCaptureValue(arg
))
1426 msgExpr
->setArg(0, captureValueAsResult(arg
));
1432 //===----------------------------------------------------------------------===//
1433 // MSVC __declspec(property) references
1434 //===----------------------------------------------------------------------===//
1437 MSPropertyOpBuilder::getBaseMSProperty(MSPropertySubscriptExpr
*E
) {
1438 CallArgs
.insert(CallArgs
.begin(), E
->getIdx());
1439 Expr
*Base
= E
->getBase()->IgnoreParens();
1440 while (auto *MSPropSubscript
= dyn_cast
<MSPropertySubscriptExpr
>(Base
)) {
1441 CallArgs
.insert(CallArgs
.begin(), MSPropSubscript
->getIdx());
1442 Base
= MSPropSubscript
->getBase()->IgnoreParens();
1444 return cast
<MSPropertyRefExpr
>(Base
);
1447 Expr
*MSPropertyOpBuilder::rebuildAndCaptureObject(Expr
*syntacticBase
) {
1448 InstanceBase
= capture(RefExpr
->getBaseExpr());
1449 llvm::for_each(CallArgs
, [this](Expr
*&Arg
) { Arg
= capture(Arg
); });
1450 syntacticBase
= Rebuilder(S
, [=](Expr
*, unsigned Idx
) -> Expr
* {
1453 return InstanceBase
;
1455 assert(Idx
<= CallArgs
.size());
1456 return CallArgs
[Idx
- 1];
1458 }).rebuild(syntacticBase
);
1460 return syntacticBase
;
1463 ExprResult
MSPropertyOpBuilder::buildGet() {
1464 if (!RefExpr
->getPropertyDecl()->hasGetter()) {
1465 S
.Diag(RefExpr
->getMemberLoc(), diag::err_no_accessor_for_property
)
1466 << 0 /* getter */ << RefExpr
->getPropertyDecl();
1470 UnqualifiedId GetterName
;
1471 IdentifierInfo
*II
= RefExpr
->getPropertyDecl()->getGetterId();
1472 GetterName
.setIdentifier(II
, RefExpr
->getMemberLoc());
1474 SS
.Adopt(RefExpr
->getQualifierLoc());
1475 ExprResult GetterExpr
=
1476 S
.ActOnMemberAccessExpr(S
.getCurScope(), InstanceBase
, SourceLocation(),
1477 RefExpr
->isArrow() ? tok::arrow
: tok::period
, SS
,
1478 SourceLocation(), GetterName
, nullptr);
1479 if (GetterExpr
.isInvalid()) {
1480 S
.Diag(RefExpr
->getMemberLoc(),
1481 diag::err_cannot_find_suitable_accessor
) << 0 /* getter */
1482 << RefExpr
->getPropertyDecl();
1486 return S
.BuildCallExpr(S
.getCurScope(), GetterExpr
.get(),
1487 RefExpr
->getSourceRange().getBegin(), CallArgs
,
1488 RefExpr
->getSourceRange().getEnd());
1491 ExprResult
MSPropertyOpBuilder::buildSet(Expr
*op
, SourceLocation sl
,
1492 bool captureSetValueAsResult
) {
1493 if (!RefExpr
->getPropertyDecl()->hasSetter()) {
1494 S
.Diag(RefExpr
->getMemberLoc(), diag::err_no_accessor_for_property
)
1495 << 1 /* setter */ << RefExpr
->getPropertyDecl();
1499 UnqualifiedId SetterName
;
1500 IdentifierInfo
*II
= RefExpr
->getPropertyDecl()->getSetterId();
1501 SetterName
.setIdentifier(II
, RefExpr
->getMemberLoc());
1503 SS
.Adopt(RefExpr
->getQualifierLoc());
1504 ExprResult SetterExpr
=
1505 S
.ActOnMemberAccessExpr(S
.getCurScope(), InstanceBase
, SourceLocation(),
1506 RefExpr
->isArrow() ? tok::arrow
: tok::period
, SS
,
1507 SourceLocation(), SetterName
, nullptr);
1508 if (SetterExpr
.isInvalid()) {
1509 S
.Diag(RefExpr
->getMemberLoc(),
1510 diag::err_cannot_find_suitable_accessor
) << 1 /* setter */
1511 << RefExpr
->getPropertyDecl();
1515 SmallVector
<Expr
*, 4> ArgExprs
;
1516 ArgExprs
.append(CallArgs
.begin(), CallArgs
.end());
1517 ArgExprs
.push_back(op
);
1518 return S
.BuildCallExpr(S
.getCurScope(), SetterExpr
.get(),
1519 RefExpr
->getSourceRange().getBegin(), ArgExprs
,
1520 op
->getSourceRange().getEnd());
1523 //===----------------------------------------------------------------------===//
1524 // General Sema routines.
1525 //===----------------------------------------------------------------------===//
1527 ExprResult
Sema::checkPseudoObjectRValue(Expr
*E
) {
1528 Expr
*opaqueRef
= E
->IgnoreParens();
1529 if (ObjCPropertyRefExpr
*refExpr
1530 = dyn_cast
<ObjCPropertyRefExpr
>(opaqueRef
)) {
1531 ObjCPropertyOpBuilder
builder(*this, refExpr
, true);
1532 return builder
.buildRValueOperation(E
);
1534 else if (ObjCSubscriptRefExpr
*refExpr
1535 = dyn_cast
<ObjCSubscriptRefExpr
>(opaqueRef
)) {
1536 ObjCSubscriptOpBuilder
builder(*this, refExpr
, true);
1537 return builder
.buildRValueOperation(E
);
1538 } else if (MSPropertyRefExpr
*refExpr
1539 = dyn_cast
<MSPropertyRefExpr
>(opaqueRef
)) {
1540 MSPropertyOpBuilder
builder(*this, refExpr
, true);
1541 return builder
.buildRValueOperation(E
);
1542 } else if (MSPropertySubscriptExpr
*RefExpr
=
1543 dyn_cast
<MSPropertySubscriptExpr
>(opaqueRef
)) {
1544 MSPropertyOpBuilder
Builder(*this, RefExpr
, true);
1545 return Builder
.buildRValueOperation(E
);
1547 llvm_unreachable("unknown pseudo-object kind!");
1551 /// Check an increment or decrement of a pseudo-object expression.
1552 ExprResult
Sema::checkPseudoObjectIncDec(Scope
*Sc
, SourceLocation opcLoc
,
1553 UnaryOperatorKind opcode
, Expr
*op
) {
1554 // Do nothing if the operand is dependent.
1555 if (op
->isTypeDependent())
1556 return UnaryOperator::Create(Context
, op
, opcode
, Context
.DependentTy
,
1557 VK_PRValue
, OK_Ordinary
, opcLoc
, false,
1558 CurFPFeatureOverrides());
1560 assert(UnaryOperator::isIncrementDecrementOp(opcode
));
1561 Expr
*opaqueRef
= op
->IgnoreParens();
1562 if (ObjCPropertyRefExpr
*refExpr
1563 = dyn_cast
<ObjCPropertyRefExpr
>(opaqueRef
)) {
1564 ObjCPropertyOpBuilder
builder(*this, refExpr
, false);
1565 return builder
.buildIncDecOperation(Sc
, opcLoc
, opcode
, op
);
1566 } else if (isa
<ObjCSubscriptRefExpr
>(opaqueRef
)) {
1567 Diag(opcLoc
, diag::err_illegal_container_subscripting_op
);
1569 } else if (MSPropertyRefExpr
*refExpr
1570 = dyn_cast
<MSPropertyRefExpr
>(opaqueRef
)) {
1571 MSPropertyOpBuilder
builder(*this, refExpr
, false);
1572 return builder
.buildIncDecOperation(Sc
, opcLoc
, opcode
, op
);
1573 } else if (MSPropertySubscriptExpr
*RefExpr
1574 = dyn_cast
<MSPropertySubscriptExpr
>(opaqueRef
)) {
1575 MSPropertyOpBuilder
Builder(*this, RefExpr
, false);
1576 return Builder
.buildIncDecOperation(Sc
, opcLoc
, opcode
, op
);
1578 llvm_unreachable("unknown pseudo-object kind!");
1582 ExprResult
Sema::checkPseudoObjectAssignment(Scope
*S
, SourceLocation opcLoc
,
1583 BinaryOperatorKind opcode
,
1584 Expr
*LHS
, Expr
*RHS
) {
1585 // Do nothing if either argument is dependent.
1586 if (LHS
->isTypeDependent() || RHS
->isTypeDependent())
1587 return BinaryOperator::Create(Context
, LHS
, RHS
, opcode
,
1588 Context
.DependentTy
, VK_PRValue
, OK_Ordinary
,
1589 opcLoc
, CurFPFeatureOverrides());
1591 // Filter out non-overload placeholder types in the RHS.
1592 if (RHS
->getType()->isNonOverloadPlaceholderType()) {
1593 ExprResult result
= CheckPlaceholderExpr(RHS
);
1594 if (result
.isInvalid()) return ExprError();
1598 bool IsSimpleAssign
= opcode
== BO_Assign
;
1599 Expr
*opaqueRef
= LHS
->IgnoreParens();
1600 if (ObjCPropertyRefExpr
*refExpr
1601 = dyn_cast
<ObjCPropertyRefExpr
>(opaqueRef
)) {
1602 ObjCPropertyOpBuilder
builder(*this, refExpr
, IsSimpleAssign
);
1603 return builder
.buildAssignmentOperation(S
, opcLoc
, opcode
, LHS
, RHS
);
1604 } else if (ObjCSubscriptRefExpr
*refExpr
1605 = dyn_cast
<ObjCSubscriptRefExpr
>(opaqueRef
)) {
1606 ObjCSubscriptOpBuilder
builder(*this, refExpr
, IsSimpleAssign
);
1607 return builder
.buildAssignmentOperation(S
, opcLoc
, opcode
, LHS
, RHS
);
1608 } else if (MSPropertyRefExpr
*refExpr
1609 = dyn_cast
<MSPropertyRefExpr
>(opaqueRef
)) {
1610 MSPropertyOpBuilder
builder(*this, refExpr
, IsSimpleAssign
);
1611 return builder
.buildAssignmentOperation(S
, opcLoc
, opcode
, LHS
, RHS
);
1612 } else if (MSPropertySubscriptExpr
*RefExpr
1613 = dyn_cast
<MSPropertySubscriptExpr
>(opaqueRef
)) {
1614 MSPropertyOpBuilder
Builder(*this, RefExpr
, IsSimpleAssign
);
1615 return Builder
.buildAssignmentOperation(S
, opcLoc
, opcode
, LHS
, RHS
);
1617 llvm_unreachable("unknown pseudo-object kind!");
1621 /// Given a pseudo-object reference, rebuild it without the opaque
1622 /// values. Basically, undo the behavior of rebuildAndCaptureObject.
1623 /// This should never operate in-place.
1624 static Expr
*stripOpaqueValuesFromPseudoObjectRef(Sema
&S
, Expr
*E
) {
1626 [=](Expr
*E
, unsigned) -> Expr
* {
1627 return cast
<OpaqueValueExpr
>(E
)->getSourceExpr();
1632 /// Given a pseudo-object expression, recreate what it looks like
1633 /// syntactically without the attendant OpaqueValueExprs.
1635 /// This is a hack which should be removed when TreeTransform is
1636 /// capable of rebuilding a tree without stripping implicit
1638 Expr
*Sema::recreateSyntacticForm(PseudoObjectExpr
*E
) {
1639 Expr
*syntax
= E
->getSyntacticForm();
1640 if (UnaryOperator
*uop
= dyn_cast
<UnaryOperator
>(syntax
)) {
1641 Expr
*op
= stripOpaqueValuesFromPseudoObjectRef(*this, uop
->getSubExpr());
1642 return UnaryOperator::Create(Context
, op
, uop
->getOpcode(), uop
->getType(),
1643 uop
->getValueKind(), uop
->getObjectKind(),
1644 uop
->getOperatorLoc(), uop
->canOverflow(),
1645 CurFPFeatureOverrides());
1646 } else if (CompoundAssignOperator
*cop
1647 = dyn_cast
<CompoundAssignOperator
>(syntax
)) {
1648 Expr
*lhs
= stripOpaqueValuesFromPseudoObjectRef(*this, cop
->getLHS());
1649 Expr
*rhs
= cast
<OpaqueValueExpr
>(cop
->getRHS())->getSourceExpr();
1650 return CompoundAssignOperator::Create(
1651 Context
, lhs
, rhs
, cop
->getOpcode(), cop
->getType(),
1652 cop
->getValueKind(), cop
->getObjectKind(), cop
->getOperatorLoc(),
1653 CurFPFeatureOverrides(), cop
->getComputationLHSType(),
1654 cop
->getComputationResultType());
1656 } else if (BinaryOperator
*bop
= dyn_cast
<BinaryOperator
>(syntax
)) {
1657 Expr
*lhs
= stripOpaqueValuesFromPseudoObjectRef(*this, bop
->getLHS());
1658 Expr
*rhs
= cast
<OpaqueValueExpr
>(bop
->getRHS())->getSourceExpr();
1659 return BinaryOperator::Create(Context
, lhs
, rhs
, bop
->getOpcode(),
1660 bop
->getType(), bop
->getValueKind(),
1661 bop
->getObjectKind(), bop
->getOperatorLoc(),
1662 CurFPFeatureOverrides());
1664 } else if (isa
<CallExpr
>(syntax
)) {
1667 assert(syntax
->hasPlaceholderType(BuiltinType::PseudoObject
));
1668 return stripOpaqueValuesFromPseudoObjectRef(*this, syntax
);