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