ExprObjC.h revision f40f0d5a382395e0301d7dcbeaa2b8e90b8973b1
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 Location of the selector.
430  SourceLocation SelectorLoc;
431
432  /// \brief The source locations of the open and close square
433  /// brackets ('[' and ']', respectively).
434  SourceLocation LBracLoc, RBracLoc;
435
436  ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
437    : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
438      HasMethod(0), SelectorOrMethod(0) { }
439
440  ObjCMessageExpr(QualType T, ExprValueKind VK,
441                  SourceLocation LBracLoc,
442                  SourceLocation SuperLoc,
443                  bool IsInstanceSuper,
444                  QualType SuperType,
445                  Selector Sel,
446                  SourceLocation SelLoc,
447                  ObjCMethodDecl *Method,
448                  Expr **Args, unsigned NumArgs,
449                  SourceLocation RBracLoc);
450  ObjCMessageExpr(QualType T, ExprValueKind VK,
451                  SourceLocation LBracLoc,
452                  TypeSourceInfo *Receiver,
453                  Selector Sel,
454                  SourceLocation SelLoc,
455                  ObjCMethodDecl *Method,
456                  Expr **Args, unsigned NumArgs,
457                  SourceLocation RBracLoc);
458  ObjCMessageExpr(QualType T, ExprValueKind VK,
459                  SourceLocation LBracLoc,
460                  Expr *Receiver,
461                  Selector Sel,
462                  SourceLocation SelLoc,
463                  ObjCMethodDecl *Method,
464                  Expr **Args, unsigned NumArgs,
465                  SourceLocation RBracLoc);
466
467  /// \brief Retrieve the pointer value of the message receiver.
468  void *getReceiverPointer() const {
469    return *const_cast<void **>(
470                             reinterpret_cast<const void * const*>(this + 1));
471  }
472
473  /// \brief Set the pointer value of the message receiver.
474  void setReceiverPointer(void *Value) {
475    *reinterpret_cast<void **>(this + 1) = Value;
476  }
477
478public:
479  /// \brief The kind of receiver this message is sending to.
480  enum ReceiverKind {
481    /// \brief The receiver is a class.
482    Class = 0,
483    /// \brief The receiver is an object instance.
484    Instance,
485    /// \brief The receiver is a superclass.
486    SuperClass,
487    /// \brief The receiver is the instance of the superclass object.
488    SuperInstance
489  };
490
491  /// \brief Create a message send to super.
492  ///
493  /// \param Context The ASTContext in which this expression will be created.
494  ///
495  /// \param T The result type of this message.
496  ///
497  /// \param VK The value kind of this message.  A message returning
498  /// a l-value or r-value reference will be an l-value or x-value,
499  /// respectively.
500  ///
501  /// \param LBrac The location of the open square bracket '['.
502  ///
503  /// \param SuperLoc The location of the "super" keyword.
504  ///
505  /// \param IsInstanceSuper Whether this is an instance "super"
506  /// message (otherwise, it's a class "super" message).
507  ///
508  /// \param Sel The selector used to determine which method gets called.
509  ///
510  /// \param Method The Objective-C method against which this message
511  /// send was type-checked. May be NULL.
512  ///
513  /// \param Args The message send arguments.
514  ///
515  /// \param NumArgs The number of arguments.
516  ///
517  /// \param RBracLoc The location of the closing square bracket ']'.
518  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
519                                 ExprValueKind VK,
520                                 SourceLocation LBracLoc,
521                                 SourceLocation SuperLoc,
522                                 bool IsInstanceSuper,
523                                 QualType SuperType,
524                                 Selector Sel,
525                                 SourceLocation SelLoc,
526                                 ObjCMethodDecl *Method,
527                                 Expr **Args, unsigned NumArgs,
528                                 SourceLocation RBracLoc);
529
530  /// \brief Create a class message send.
531  ///
532  /// \param Context The ASTContext in which this expression will be created.
533  ///
534  /// \param T The result type of this message.
535  ///
536  /// \param VK The value kind of this message.  A message returning
537  /// a l-value or r-value reference will be an l-value or x-value,
538  /// respectively.
539  ///
540  /// \param LBrac The location of the open square bracket '['.
541  ///
542  /// \param Receiver The type of the receiver, including
543  /// source-location information.
544  ///
545  /// \param Sel The selector used to determine which method gets called.
546  ///
547  /// \param Method The Objective-C method against which this message
548  /// send was type-checked. May be NULL.
549  ///
550  /// \param Args The message send arguments.
551  ///
552  /// \param NumArgs The number of arguments.
553  ///
554  /// \param RBracLoc The location of the closing square bracket ']'.
555  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
556                                 ExprValueKind VK,
557                                 SourceLocation LBracLoc,
558                                 TypeSourceInfo *Receiver,
559                                 Selector Sel,
560                                 SourceLocation SelLoc,
561                                 ObjCMethodDecl *Method,
562                                 Expr **Args, unsigned NumArgs,
563                                 SourceLocation RBracLoc);
564
565  /// \brief Create an instance message send.
566  ///
567  /// \param Context The ASTContext in which this expression will be created.
568  ///
569  /// \param T The result type of this message.
570  ///
571  /// \param VK The value kind of this message.  A message returning
572  /// a l-value or r-value reference will be an l-value or x-value,
573  /// respectively.
574  ///
575  /// \param LBrac The location of the open square bracket '['.
576  ///
577  /// \param Receiver The expression used to produce the object that
578  /// will receive this message.
579  ///
580  /// \param Sel The selector used to determine which method gets called.
581  ///
582  /// \param Method The Objective-C method against which this message
583  /// send was type-checked. May be NULL.
584  ///
585  /// \param Args The message send arguments.
586  ///
587  /// \param NumArgs The number of arguments.
588  ///
589  /// \param RBracLoc The location of the closing square bracket ']'.
590  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
591                                 ExprValueKind VK,
592                                 SourceLocation LBracLoc,
593                                 Expr *Receiver,
594                                 Selector Sel,
595                                 SourceLocation SelLoc,
596                                 ObjCMethodDecl *Method,
597                                 Expr **Args, unsigned NumArgs,
598                                 SourceLocation RBracLoc);
599
600  /// \brief Create an empty Objective-C message expression, to be
601  /// filled in by subsequent calls.
602  ///
603  /// \param Context The context in which the message send will be created.
604  ///
605  /// \param NumArgs The number of message arguments, not including
606  /// the receiver.
607  static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
608
609  /// \brief Determine the kind of receiver that this message is being
610  /// sent to.
611  ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
612
613  /// \brief Determine whether this is an instance message to either a
614  /// computed object or to super.
615  bool isInstanceMessage() const {
616    return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
617  }
618
619  /// \brief Determine whether this is an class message to either a
620  /// specified class or to super.
621  bool isClassMessage() const {
622    return getReceiverKind() == Class || getReceiverKind() == SuperClass;
623  }
624
625  /// \brief Returns the receiver of an instance message.
626  ///
627  /// \brief Returns the object expression for an instance message, or
628  /// NULL for a message that is not an instance message.
629  Expr *getInstanceReceiver() {
630    if (getReceiverKind() == Instance)
631      return static_cast<Expr *>(getReceiverPointer());
632
633    return 0;
634  }
635  const Expr *getInstanceReceiver() const {
636    return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
637  }
638
639  /// \brief Turn this message send into an instance message that
640  /// computes the receiver object with the given expression.
641  void setInstanceReceiver(Expr *rec) {
642    Kind = Instance;
643    setReceiverPointer(rec);
644  }
645
646  /// \brief Returns the type of a class message send, or NULL if the
647  /// message is not a class message.
648  QualType getClassReceiver() const {
649    if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
650      return TSInfo->getType();
651
652    return QualType();
653  }
654
655  /// \brief Returns a type-source information of a class message
656  /// send, or NULL if the message is not a class message.
657  TypeSourceInfo *getClassReceiverTypeInfo() const {
658    if (getReceiverKind() == Class)
659      return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
660    return 0;
661  }
662
663  void setClassReceiver(TypeSourceInfo *TSInfo) {
664    Kind = Class;
665    setReceiverPointer(TSInfo);
666  }
667
668  /// \brief Retrieve the location of the 'super' keyword for a class
669  /// or instance message to 'super', otherwise an invalid source location.
670  SourceLocation getSuperLoc() const {
671    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
672      return SuperLoc;
673
674    return SourceLocation();
675  }
676
677  /// \brief Retrieve the Objective-C interface to which this message
678  /// is being directed, if known.
679  ///
680  /// This routine cross-cuts all of the different kinds of message
681  /// sends to determine what the underlying (statically known) type
682  /// of the receiver will be; use \c getReceiverKind() to determine
683  /// whether the message is a class or an instance method, whether it
684  /// is a send to super or not, etc.
685  ///
686  /// \returns The Objective-C interface if known, otherwise NULL.
687  ObjCInterfaceDecl *getReceiverInterface() const;
688
689  /// \brief Retrieve the type referred to by 'super'.
690  ///
691  /// The returned type will either be an ObjCInterfaceType (for an
692  /// class message to super) or an ObjCObjectPointerType that refers
693  /// to a class (for an instance message to super);
694  QualType getSuperType() const {
695    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
696      return QualType::getFromOpaquePtr(getReceiverPointer());
697
698    return QualType();
699  }
700
701  void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
702    Kind = IsInstanceSuper? SuperInstance : SuperClass;
703    SuperLoc = Loc;
704    setReceiverPointer(T.getAsOpaquePtr());
705  }
706
707  Selector getSelector() const;
708
709  void setSelector(Selector S) {
710    HasMethod = false;
711    SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
712  }
713
714  const ObjCMethodDecl *getMethodDecl() const {
715    if (HasMethod)
716      return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
717
718    return 0;
719  }
720
721  ObjCMethodDecl *getMethodDecl() {
722    if (HasMethod)
723      return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
724
725    return 0;
726  }
727
728  void setMethodDecl(ObjCMethodDecl *MD) {
729    HasMethod = true;
730    SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
731  }
732
733  /// \brief Return the number of actual arguments in this message,
734  /// not counting the receiver.
735  unsigned getNumArgs() const { return NumArgs; }
736
737  /// \brief Retrieve the arguments to this message, not including the
738  /// receiver.
739  Stmt **getArgs() {
740    return reinterpret_cast<Stmt **>(this + 1) + 1;
741  }
742  const Stmt * const *getArgs() const {
743    return reinterpret_cast<const Stmt * const *>(this + 1) + 1;
744  }
745
746  /// getArg - Return the specified argument.
747  Expr *getArg(unsigned Arg) {
748    assert(Arg < NumArgs && "Arg access out of range!");
749    return cast<Expr>(getArgs()[Arg]);
750  }
751  const Expr *getArg(unsigned Arg) const {
752    assert(Arg < NumArgs && "Arg access out of range!");
753    return cast<Expr>(getArgs()[Arg]);
754  }
755  /// setArg - Set the specified argument.
756  void setArg(unsigned Arg, Expr *ArgExpr) {
757    assert(Arg < NumArgs && "Arg access out of range!");
758    getArgs()[Arg] = ArgExpr;
759  }
760
761  SourceLocation getLeftLoc() const { return LBracLoc; }
762  SourceLocation getRightLoc() const { return RBracLoc; }
763  SourceLocation getSelectorLoc() const { return SelectorLoc; }
764
765  void setSourceRange(SourceRange R) {
766    LBracLoc = R.getBegin();
767    RBracLoc = R.getEnd();
768  }
769  virtual SourceRange getSourceRange() const {
770    return SourceRange(LBracLoc, RBracLoc);
771  }
772
773  static bool classof(const Stmt *T) {
774    return T->getStmtClass() == ObjCMessageExprClass;
775  }
776  static bool classof(const ObjCMessageExpr *) { return true; }
777
778  // Iterators
779  virtual child_iterator child_begin();
780  virtual child_iterator child_end();
781
782  typedef ExprIterator arg_iterator;
783  typedef ConstExprIterator const_arg_iterator;
784
785  arg_iterator arg_begin() { return getArgs(); }
786  arg_iterator arg_end()   { return getArgs() + NumArgs; }
787  const_arg_iterator arg_begin() const { return getArgs(); }
788  const_arg_iterator arg_end() const { return getArgs() + NumArgs; }
789
790  friend class ASTStmtReader;
791  friend class ASTStmtWriter;
792};
793
794/// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
795/// (similiar in spirit to MemberExpr).
796class ObjCIsaExpr : public Expr {
797  /// Base - the expression for the base object pointer.
798  Stmt *Base;
799
800  /// IsaMemberLoc - This is the location of the 'isa'.
801  SourceLocation IsaMemberLoc;
802
803  /// IsArrow - True if this is "X->F", false if this is "X.F".
804  bool IsArrow;
805public:
806  ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
807    : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
808           /*TypeDependent=*/false, base->isValueDependent()),
809      Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
810
811  /// \brief Build an empty expression.
812  explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
813
814  void setBase(Expr *E) { Base = E; }
815  Expr *getBase() const { return cast<Expr>(Base); }
816
817  bool isArrow() const { return IsArrow; }
818  void setArrow(bool A) { IsArrow = A; }
819
820  /// getMemberLoc - Return the location of the "member", in X->F, it is the
821  /// location of 'F'.
822  SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
823  void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
824
825  virtual SourceRange getSourceRange() const {
826    return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
827  }
828
829  virtual SourceLocation getExprLoc() const { return IsaMemberLoc; }
830
831  static bool classof(const Stmt *T) {
832    return T->getStmtClass() == ObjCIsaExprClass;
833  }
834  static bool classof(const ObjCIsaExpr *) { return true; }
835
836  // Iterators
837  virtual child_iterator child_begin();
838  virtual child_iterator child_end();
839};
840
841}  // end namespace clang
842
843#endif
844