ExprObjC.h revision 12f78a6741a4cb3d904340f8d3d2714568b50e7a
1//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
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 defines the ExprObjC interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_EXPROBJC_H
15#define LLVM_CLANG_AST_EXPROBJC_H
16
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/Expr.h"
19#include "clang/Basic/IdentifierTable.h"
20
21namespace clang {
22  class IdentifierInfo;
23  class ASTContext;
24
25/// ObjCStringLiteral, used for Objective-C string literals
26/// i.e. @"foo".
27class ObjCStringLiteral : public Expr {
28  Stmt *String;
29  SourceLocation AtLoc;
30public:
31  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
32    : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false),
33      String(SL), AtLoc(L) {}
34  explicit ObjCStringLiteral(EmptyShell Empty)
35    : Expr(ObjCStringLiteralClass, Empty) {}
36
37  StringLiteral *getString() { return cast<StringLiteral>(String); }
38  const StringLiteral *getString() const { return cast<StringLiteral>(String); }
39  void setString(StringLiteral *S) { String = S; }
40
41  SourceLocation getAtLoc() const { return AtLoc; }
42  void setAtLoc(SourceLocation L) { AtLoc = L; }
43
44  virtual SourceRange getSourceRange() const {
45    return SourceRange(AtLoc, String->getLocEnd());
46  }
47
48  static bool classof(const Stmt *T) {
49    return T->getStmtClass() == ObjCStringLiteralClass;
50  }
51  static bool classof(const ObjCStringLiteral *) { return true; }
52
53  // Iterators
54  virtual child_iterator child_begin();
55  virtual child_iterator child_end();
56};
57
58/// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
59/// and behavior as StringLiteral except that the string initializer is obtained
60/// from ASTContext with the encoding type as an argument.
61class ObjCEncodeExpr : public Expr {
62  TypeSourceInfo *EncodedType;
63  SourceLocation AtLoc, RParenLoc;
64public:
65  ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
66                 SourceLocation at, SourceLocation rp)
67    : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
68           EncodedType->getType()->isDependentType(),
69           EncodedType->getType()->isDependentType()),
70      EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
71
72  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
73
74
75  SourceLocation getAtLoc() const { return AtLoc; }
76  void setAtLoc(SourceLocation L) { AtLoc = L; }
77  SourceLocation getRParenLoc() const { return RParenLoc; }
78  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
79
80  QualType getEncodedType() const { return EncodedType->getType(); }
81
82  TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
83  void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
84    EncodedType = EncType;
85  }
86
87  virtual SourceRange getSourceRange() const {
88    return SourceRange(AtLoc, RParenLoc);
89  }
90
91  static bool classof(const Stmt *T) {
92    return T->getStmtClass() == ObjCEncodeExprClass;
93  }
94  static bool classof(const ObjCEncodeExpr *) { return true; }
95
96  // Iterators
97  virtual child_iterator child_begin();
98  virtual child_iterator child_end();
99};
100
101/// ObjCSelectorExpr used for @selector in Objective-C.
102class ObjCSelectorExpr : public Expr {
103  Selector SelName;
104  SourceLocation AtLoc, RParenLoc;
105public:
106  ObjCSelectorExpr(QualType T, Selector selInfo,
107                   SourceLocation at, SourceLocation rp)
108  : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false),
109    SelName(selInfo), AtLoc(at), RParenLoc(rp){}
110  explicit ObjCSelectorExpr(EmptyShell Empty)
111   : Expr(ObjCSelectorExprClass, Empty) {}
112
113  Selector getSelector() const { return SelName; }
114  void setSelector(Selector S) { SelName = S; }
115
116  SourceLocation getAtLoc() const { return AtLoc; }
117  SourceLocation getRParenLoc() const { return RParenLoc; }
118  void setAtLoc(SourceLocation L) { AtLoc = L; }
119  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
120
121  virtual SourceRange getSourceRange() const {
122    return SourceRange(AtLoc, RParenLoc);
123  }
124
125  /// getNumArgs - Return the number of actual arguments to this call.
126  unsigned getNumArgs() const { return SelName.getNumArgs(); }
127
128  static bool classof(const Stmt *T) {
129    return T->getStmtClass() == ObjCSelectorExprClass;
130  }
131  static bool classof(const ObjCSelectorExpr *) { return true; }
132
133  // Iterators
134  virtual child_iterator child_begin();
135  virtual child_iterator child_end();
136};
137
138/// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
139/// as: @protocol(foo), as in:
140///   obj conformsToProtocol:@protocol(foo)]
141/// The return type is "Protocol*".
142class ObjCProtocolExpr : public Expr {
143  ObjCProtocolDecl *TheProtocol;
144  SourceLocation AtLoc, RParenLoc;
145public:
146  ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
147                   SourceLocation at, SourceLocation rp)
148  : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false),
149    TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
150  explicit ObjCProtocolExpr(EmptyShell Empty)
151    : Expr(ObjCProtocolExprClass, Empty) {}
152
153  ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
154  void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
155
156  SourceLocation getAtLoc() const { return AtLoc; }
157  SourceLocation getRParenLoc() const { return RParenLoc; }
158  void setAtLoc(SourceLocation L) { AtLoc = L; }
159  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
160
161  virtual SourceRange getSourceRange() const {
162    return SourceRange(AtLoc, RParenLoc);
163  }
164
165  static bool classof(const Stmt *T) {
166    return T->getStmtClass() == ObjCProtocolExprClass;
167  }
168  static bool classof(const ObjCProtocolExpr *) { return true; }
169
170  // Iterators
171  virtual child_iterator child_begin();
172  virtual child_iterator child_end();
173};
174
175/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
176class ObjCIvarRefExpr : public Expr {
177  class ObjCIvarDecl *D;
178  SourceLocation Loc;
179  Stmt *Base;
180  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
181  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
182
183public:
184  ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
185                  SourceLocation l, Expr *base,
186                  bool arrow = false, bool freeIvar = false) :
187    Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
188         /*TypeDependent=*/false, base->isValueDependent()), D(d),
189         Loc(l), Base(base), IsArrow(arrow),
190         IsFreeIvar(freeIvar) {}
191
192  explicit ObjCIvarRefExpr(EmptyShell Empty)
193    : Expr(ObjCIvarRefExprClass, Empty) {}
194
195  ObjCIvarDecl *getDecl() { return D; }
196  const ObjCIvarDecl *getDecl() const { return D; }
197  void setDecl(ObjCIvarDecl *d) { D = d; }
198
199  const Expr *getBase() const { return cast<Expr>(Base); }
200  Expr *getBase() { return cast<Expr>(Base); }
201  void setBase(Expr * base) { Base = base; }
202
203  bool isArrow() const { return IsArrow; }
204  bool isFreeIvar() const { return IsFreeIvar; }
205  void setIsArrow(bool A) { IsArrow = A; }
206  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
207
208  SourceLocation getLocation() const { return Loc; }
209  void setLocation(SourceLocation L) { Loc = L; }
210
211  virtual SourceRange getSourceRange() const {
212    return isFreeIvar() ? SourceRange(Loc)
213    : SourceRange(getBase()->getLocStart(), Loc);
214  }
215
216  static bool classof(const Stmt *T) {
217    return T->getStmtClass() == ObjCIvarRefExprClass;
218  }
219  static bool classof(const ObjCIvarRefExpr *) { return true; }
220
221  // Iterators
222  virtual child_iterator child_begin();
223  virtual child_iterator child_end();
224};
225
226/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
227/// property.
228///
229class ObjCPropertyRefExpr : public Expr {
230private:
231  /// If the bool is true, this is an implicit property reference; the
232  /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
233  /// if the bool is false, this is an explicit property reference;
234  /// the pointer is an ObjCPropertyDecl and Setter is always null.
235  llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
236  ObjCMethodDecl *Setter;
237
238  SourceLocation IdLoc;
239
240  /// \brief When the receiver in property access is 'super', this is
241  /// the location of the 'super' keyword.  When it's an interface,
242  /// this is that interface.
243  SourceLocation ReceiverLoc;
244  llvm::PointerUnion3<Stmt*, Type*, ObjCInterfaceDecl*> Receiver;
245
246public:
247  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
248                      ExprValueKind VK, ExprObjectKind OK,
249                      SourceLocation l, Expr *base)
250    : Expr(ObjCPropertyRefExprClass, t, VK, OK,
251           /*TypeDependent=*/false, base->isValueDependent()),
252      PropertyOrGetter(PD, false), Setter(0),
253      IdLoc(l), ReceiverLoc(), Receiver(base) {
254  }
255
256  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
257                      ExprValueKind VK, ExprObjectKind OK,
258                      SourceLocation l, SourceLocation sl, QualType st)
259    : Expr(ObjCPropertyRefExprClass, t, VK, OK,
260           /*TypeDependent=*/false, false),
261      PropertyOrGetter(PD, false), Setter(0),
262      IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
263  }
264
265  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
266                      QualType T, ExprValueKind VK, ExprObjectKind OK,
267                      SourceLocation IdLoc, Expr *Base)
268    : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
269           Base->isValueDependent()),
270      PropertyOrGetter(Getter, true), Setter(Setter),
271      IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
272  }
273
274  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
275                      QualType T, ExprValueKind VK, ExprObjectKind OK,
276                      SourceLocation IdLoc,
277                      SourceLocation SuperLoc, QualType SuperTy)
278    : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false),
279      PropertyOrGetter(Getter, true), Setter(Setter),
280      IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
281  }
282
283  ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
284                      QualType T, ExprValueKind VK, ExprObjectKind OK,
285                      SourceLocation IdLoc,
286                      SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
287    : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false),
288      PropertyOrGetter(Getter, true), Setter(Setter),
289      IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
290  }
291
292  explicit ObjCPropertyRefExpr(EmptyShell Empty)
293    : Expr(ObjCPropertyRefExprClass, Empty) {}
294
295  bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
296  bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
297
298  ObjCPropertyDecl *getExplicitProperty() const {
299    assert(!isImplicitProperty());
300    return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
301  }
302
303  ObjCMethodDecl *getImplicitPropertyGetter() const {
304    assert(isImplicitProperty());
305    return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
306  }
307
308  ObjCMethodDecl *getImplicitPropertySetter() const {
309    assert(isImplicitProperty());
310    return Setter;
311  }
312
313  Selector getGetterSelector() const {
314    if (isImplicitProperty())
315      return getImplicitPropertyGetter()->getSelector();
316    return getExplicitProperty()->getGetterName();
317  }
318
319  Selector getSetterSelector() const {
320    if (isImplicitProperty())
321      return getImplicitPropertySetter()->getSelector();
322    return getExplicitProperty()->getSetterName();
323  }
324
325  const Expr *getBase() const {
326    return cast<Expr>(Receiver.get<Stmt*>());
327  }
328  Expr *getBase() {
329    return cast<Expr>(Receiver.get<Stmt*>());
330  }
331
332  SourceLocation getLocation() const { return IdLoc; }
333
334  SourceLocation getReceiverLocation() const { return ReceiverLoc; }
335  QualType getSuperReceiverType() const {
336    return QualType(Receiver.get<Type*>(), 0);
337  }
338  ObjCInterfaceDecl *getClassReceiver() const {
339    return Receiver.get<ObjCInterfaceDecl*>();
340  }
341  bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
342  bool isSuperReceiver() const { return Receiver.is<Type*>(); }
343  bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
344
345  virtual SourceRange getSourceRange() const {
346    return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
347                                           : getReceiverLocation()),
348                       IdLoc);
349  }
350
351  static bool classof(const Stmt *T) {
352    return T->getStmtClass() == ObjCPropertyRefExprClass;
353  }
354  static bool classof(const ObjCPropertyRefExpr *) { return true; }
355
356  // Iterators
357  virtual child_iterator child_begin();
358  virtual child_iterator child_end();
359private:
360  friend class ASTStmtReader;
361  void setExplicitProperty(ObjCPropertyDecl *D) {
362    PropertyOrGetter.setPointer(D);
363    PropertyOrGetter.setInt(false);
364    Setter = 0;
365  }
366  void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) {
367    PropertyOrGetter.setPointer(Getter);
368    PropertyOrGetter.setInt(true);
369    this->Setter = Setter;
370  }
371  void setBase(Expr *Base) { Receiver = Base; }
372  void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
373  void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
374
375  void setLocation(SourceLocation L) { IdLoc = L; }
376  void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
377};
378
379/// \brief An expression that sends a message to the given Objective-C
380/// object or class.
381///
382/// The following contains two message send expressions:
383///
384/// \code
385///   [[NSString alloc] initWithString:@"Hello"]
386/// \endcode
387///
388/// The innermost message send invokes the "alloc" class method on the
389/// NSString class, while the outermost message send invokes the
390/// "initWithString" instance method on the object returned from
391/// NSString's "alloc". In all, an Objective-C message send can take
392/// on four different (although related) forms:
393///
394///   1. Send to an object instance.
395///   2. Send to a class.
396///   3. Send to the superclass instance of the current class.
397///   4. Send to the superclass of the current class.
398///
399/// All four kinds of message sends are modeled by the ObjCMessageExpr
400/// class, and can be distinguished via \c getReceiverKind(). Example:
401///
402class ObjCMessageExpr : public Expr {
403  /// \brief The number of arguments in the message send, not
404  /// including the receiver.
405  unsigned NumArgs : 16;
406
407  /// \brief The kind of message send this is, which is one of the
408  /// ReceiverKind values.
409  ///
410  /// We pad this out to a byte to avoid excessive masking and shifting.
411  unsigned Kind : 8;
412
413  /// \brief Whether we have an actual method prototype in \c
414  /// SelectorOrMethod.
415  ///
416  /// When non-zero, we have a method declaration; otherwise, we just
417  /// have a selector.
418  unsigned HasMethod : 8;
419
420  /// \brief When the message expression is a send to 'super', this is
421  /// the location of the 'super' keyword.
422  SourceLocation SuperLoc;
423
424  /// \brief Stores either the selector that this message is sending
425  /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
426  /// referring to the method that we type-checked against.
427  uintptr_t SelectorOrMethod;
428
429  /// \brief The source locations of the open and close square
430  /// brackets ('[' and ']', respectively).
431  SourceLocation LBracLoc, RBracLoc;
432
433  ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
434    : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
435      HasMethod(0), SelectorOrMethod(0) { }
436
437  ObjCMessageExpr(QualType T, ExprValueKind VK,
438                  SourceLocation LBracLoc,
439                  SourceLocation SuperLoc,
440                  bool IsInstanceSuper,
441                  QualType SuperType,
442                  Selector Sel,
443                  ObjCMethodDecl *Method,
444                  Expr **Args, unsigned NumArgs,
445                  SourceLocation RBracLoc);
446  ObjCMessageExpr(QualType T, ExprValueKind VK,
447                  SourceLocation LBracLoc,
448                  TypeSourceInfo *Receiver,
449                  Selector Sel,
450                  ObjCMethodDecl *Method,
451                  Expr **Args, unsigned NumArgs,
452                  SourceLocation RBracLoc);
453  ObjCMessageExpr(QualType T, ExprValueKind VK,
454                  SourceLocation LBracLoc,
455                  Expr *Receiver,
456                  Selector Sel,
457                  ObjCMethodDecl *Method,
458                  Expr **Args, unsigned NumArgs,
459                  SourceLocation RBracLoc);
460
461  /// \brief Retrieve the pointer value of the message receiver.
462  void *getReceiverPointer() const {
463    return *const_cast<void **>(
464                             reinterpret_cast<const void * const*>(this + 1));
465  }
466
467  /// \brief Set the pointer value of the message receiver.
468  void setReceiverPointer(void *Value) {
469    *reinterpret_cast<void **>(this + 1) = Value;
470  }
471
472public:
473  /// \brief The kind of receiver this message is sending to.
474  enum ReceiverKind {
475    /// \brief The receiver is a class.
476    Class = 0,
477    /// \brief The receiver is an object instance.
478    Instance,
479    /// \brief The receiver is a superclass.
480    SuperClass,
481    /// \brief The receiver is the instance of the superclass object.
482    SuperInstance
483  };
484
485  /// \brief Create a message send to super.
486  ///
487  /// \param Context The ASTContext in which this expression will be created.
488  ///
489  /// \param T The result type of this message.
490  ///
491  /// \param VK The value kind of this message.  A message returning
492  /// a l-value or r-value reference will be an l-value or x-value,
493  /// respectively.
494  ///
495  /// \param LBrac The location of the open square bracket '['.
496  ///
497  /// \param SuperLoc The location of the "super" keyword.
498  ///
499  /// \param IsInstanceSuper Whether this is an instance "super"
500  /// message (otherwise, it's a class "super" message).
501  ///
502  /// \param Sel The selector used to determine which method gets called.
503  ///
504  /// \param Method The Objective-C method against which this message
505  /// send was type-checked. May be NULL.
506  ///
507  /// \param Args The message send arguments.
508  ///
509  /// \param NumArgs The number of arguments.
510  ///
511  /// \param RBracLoc The location of the closing square bracket ']'.
512  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
513                                 ExprValueKind VK,
514                                 SourceLocation LBracLoc,
515                                 SourceLocation SuperLoc,
516                                 bool IsInstanceSuper,
517                                 QualType SuperType,
518                                 Selector Sel,
519                                 ObjCMethodDecl *Method,
520                                 Expr **Args, unsigned NumArgs,
521                                 SourceLocation RBracLoc);
522
523  /// \brief Create a class message send.
524  ///
525  /// \param Context The ASTContext in which this expression will be created.
526  ///
527  /// \param T The result type of this message.
528  ///
529  /// \param VK The value kind of this message.  A message returning
530  /// a l-value or r-value reference will be an l-value or x-value,
531  /// respectively.
532  ///
533  /// \param LBrac The location of the open square bracket '['.
534  ///
535  /// \param Receiver The type of the receiver, including
536  /// source-location information.
537  ///
538  /// \param Sel The selector used to determine which method gets called.
539  ///
540  /// \param Method The Objective-C method against which this message
541  /// send was type-checked. May be NULL.
542  ///
543  /// \param Args The message send arguments.
544  ///
545  /// \param NumArgs The number of arguments.
546  ///
547  /// \param RBracLoc The location of the closing square bracket ']'.
548  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
549                                 ExprValueKind VK,
550                                 SourceLocation LBracLoc,
551                                 TypeSourceInfo *Receiver,
552                                 Selector Sel,
553                                 ObjCMethodDecl *Method,
554                                 Expr **Args, unsigned NumArgs,
555                                 SourceLocation RBracLoc);
556
557  /// \brief Create an instance message send.
558  ///
559  /// \param Context The ASTContext in which this expression will be created.
560  ///
561  /// \param T The result type of this message.
562  ///
563  /// \param VK The value kind of this message.  A message returning
564  /// a l-value or r-value reference will be an l-value or x-value,
565  /// respectively.
566  ///
567  /// \param LBrac The location of the open square bracket '['.
568  ///
569  /// \param Receiver The expression used to produce the object that
570  /// will receive this message.
571  ///
572  /// \param Sel The selector used to determine which method gets called.
573  ///
574  /// \param Method The Objective-C method against which this message
575  /// send was type-checked. May be NULL.
576  ///
577  /// \param Args The message send arguments.
578  ///
579  /// \param NumArgs The number of arguments.
580  ///
581  /// \param RBracLoc The location of the closing square bracket ']'.
582  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
583                                 ExprValueKind VK,
584                                 SourceLocation LBracLoc,
585                                 Expr *Receiver,
586                                 Selector Sel,
587                                 ObjCMethodDecl *Method,
588                                 Expr **Args, unsigned NumArgs,
589                                 SourceLocation RBracLoc);
590
591  /// \brief Create an empty Objective-C message expression, to be
592  /// filled in by subsequent calls.
593  ///
594  /// \param Context The context in which the message send will be created.
595  ///
596  /// \param NumArgs The number of message arguments, not including
597  /// the receiver.
598  static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
599
600  /// \brief Determine the kind of receiver that this message is being
601  /// sent to.
602  ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
603
604  /// \brief Determine whether this is an instance message to either a
605  /// computed object or to super.
606  bool isInstanceMessage() const {
607    return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
608  }
609
610  /// \brief Determine whether this is an class message to either a
611  /// specified class or to super.
612  bool isClassMessage() const {
613    return getReceiverKind() == Class || getReceiverKind() == SuperClass;
614  }
615
616  /// \brief Returns the receiver of an instance message.
617  ///
618  /// \brief Returns the object expression for an instance message, or
619  /// NULL for a message that is not an instance message.
620  Expr *getInstanceReceiver() {
621    if (getReceiverKind() == Instance)
622      return static_cast<Expr *>(getReceiverPointer());
623
624    return 0;
625  }
626  const Expr *getInstanceReceiver() const {
627    return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
628  }
629
630  /// \brief Turn this message send into an instance message that
631  /// computes the receiver object with the given expression.
632  void setInstanceReceiver(Expr *rec) {
633    Kind = Instance;
634    setReceiverPointer(rec);
635  }
636
637  /// \brief Returns the type of a class message send, or NULL if the
638  /// message is not a class message.
639  QualType getClassReceiver() const {
640    if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
641      return TSInfo->getType();
642
643    return QualType();
644  }
645
646  /// \brief Returns a type-source information of a class message
647  /// send, or NULL if the message is not a class message.
648  TypeSourceInfo *getClassReceiverTypeInfo() const {
649    if (getReceiverKind() == Class)
650      return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
651    return 0;
652  }
653
654  void setClassReceiver(TypeSourceInfo *TSInfo) {
655    Kind = Class;
656    setReceiverPointer(TSInfo);
657  }
658
659  /// \brief Retrieve the location of the 'super' keyword for a class
660  /// or instance message to 'super', otherwise an invalid source location.
661  SourceLocation getSuperLoc() const {
662    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
663      return SuperLoc;
664
665    return SourceLocation();
666  }
667
668  /// \brief Retrieve the Objective-C interface to which this message
669  /// is being directed, if known.
670  ///
671  /// This routine cross-cuts all of the different kinds of message
672  /// sends to determine what the underlying (statically known) type
673  /// of the receiver will be; use \c getReceiverKind() to determine
674  /// whether the message is a class or an instance method, whether it
675  /// is a send to super or not, etc.
676  ///
677  /// \returns The Objective-C interface if known, otherwise NULL.
678  ObjCInterfaceDecl *getReceiverInterface() const;
679
680  /// \brief Retrieve the type referred to by 'super'.
681  ///
682  /// The returned type will either be an ObjCInterfaceType (for an
683  /// class message to super) or an ObjCObjectPointerType that refers
684  /// to a class (for an instance message to super);
685  QualType getSuperType() const {
686    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
687      return QualType::getFromOpaquePtr(getReceiverPointer());
688
689    return QualType();
690  }
691
692  void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
693    Kind = IsInstanceSuper? SuperInstance : SuperClass;
694    SuperLoc = Loc;
695    setReceiverPointer(T.getAsOpaquePtr());
696  }
697
698  Selector getSelector() const;
699
700  void setSelector(Selector S) {
701    HasMethod = false;
702    SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
703  }
704
705  const ObjCMethodDecl *getMethodDecl() const {
706    if (HasMethod)
707      return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
708
709    return 0;
710  }
711
712  ObjCMethodDecl *getMethodDecl() {
713    if (HasMethod)
714      return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
715
716    return 0;
717  }
718
719  void setMethodDecl(ObjCMethodDecl *MD) {
720    HasMethod = true;
721    SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
722  }
723
724  /// \brief Return the number of actual arguments in this message,
725  /// not counting the receiver.
726  unsigned getNumArgs() const { return NumArgs; }
727
728  /// \brief Retrieve the arguments to this message, not including the
729  /// receiver.
730  Stmt **getArgs() {
731    return reinterpret_cast<Stmt **>(this + 1) + 1;
732  }
733  const Stmt * const *getArgs() const {
734    return reinterpret_cast<const Stmt * const *>(this + 1) + 1;
735  }
736
737  /// getArg - Return the specified argument.
738  Expr *getArg(unsigned Arg) {
739    assert(Arg < NumArgs && "Arg access out of range!");
740    return cast<Expr>(getArgs()[Arg]);
741  }
742  const Expr *getArg(unsigned Arg) const {
743    assert(Arg < NumArgs && "Arg access out of range!");
744    return cast<Expr>(getArgs()[Arg]);
745  }
746  /// setArg - Set the specified argument.
747  void setArg(unsigned Arg, Expr *ArgExpr) {
748    assert(Arg < NumArgs && "Arg access out of range!");
749    getArgs()[Arg] = ArgExpr;
750  }
751
752  SourceLocation getLeftLoc() const { return LBracLoc; }
753  SourceLocation getRightLoc() const { return RBracLoc; }
754
755  void setLeftLoc(SourceLocation L) { LBracLoc = L; }
756  void setRightLoc(SourceLocation L) { RBracLoc = L; }
757
758  void setSourceRange(SourceRange R) {
759    LBracLoc = R.getBegin();
760    RBracLoc = R.getEnd();
761  }
762  virtual SourceRange getSourceRange() const {
763    return SourceRange(LBracLoc, RBracLoc);
764  }
765
766  static bool classof(const Stmt *T) {
767    return T->getStmtClass() == ObjCMessageExprClass;
768  }
769  static bool classof(const ObjCMessageExpr *) { return true; }
770
771  // Iterators
772  virtual child_iterator child_begin();
773  virtual child_iterator child_end();
774
775  typedef ExprIterator arg_iterator;
776  typedef ConstExprIterator const_arg_iterator;
777
778  arg_iterator arg_begin() { return getArgs(); }
779  arg_iterator arg_end()   { return getArgs() + NumArgs; }
780  const_arg_iterator arg_begin() const { return getArgs(); }
781  const_arg_iterator arg_end() const { return getArgs() + NumArgs; }
782};
783
784/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
785/// (similiar in spirit to MemberExpr).
786class ObjCIsaExpr : public Expr {
787  /// Base - the expression for the base object pointer.
788  Stmt *Base;
789
790  /// IsaMemberLoc - This is the location of the 'isa'.
791  SourceLocation IsaMemberLoc;
792
793  /// IsArrow - True if this is "X->F", false if this is "X.F".
794  bool IsArrow;
795public:
796  ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
797    : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
798           /*TypeDependent=*/false, base->isValueDependent()),
799      Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
800
801  /// \brief Build an empty expression.
802  explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
803
804  void setBase(Expr *E) { Base = E; }
805  Expr *getBase() const { return cast<Expr>(Base); }
806
807  bool isArrow() const { return IsArrow; }
808  void setArrow(bool A) { IsArrow = A; }
809
810  /// getMemberLoc - Return the location of the "member", in X->F, it is the
811  /// location of 'F'.
812  SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
813  void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
814
815  virtual SourceRange getSourceRange() const {
816    return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
817  }
818
819  virtual SourceLocation getExprLoc() const { return IsaMemberLoc; }
820
821  static bool classof(const Stmt *T) {
822    return T->getStmtClass() == ObjCIsaExprClass;
823  }
824  static bool classof(const ObjCIsaExpr *) { return true; }
825
826  // Iterators
827  virtual child_iterator child_begin();
828  virtual child_iterator child_end();
829};
830
831}  // end namespace clang
832
833#endif
834