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