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