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