ExprObjC.h revision 0389e6bd0159bfdd08f7c50a37543b6e3adf0c33
16762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
26762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//
36762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//                     The LLVM Compiler Infrastructure
46762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//
56762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver// This file is distributed under the University of Illinois Open Source
66762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver// License. See LICENSE.TXT for details.
76762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//
86762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//===----------------------------------------------------------------------===//
96762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//
106762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//  This file defines the ExprObjC interface and subclasses.
116762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//
126762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver//===----------------------------------------------------------------------===//
136762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
146762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver#ifndef LLVM_CLANG_AST_EXPROBJC_H
156762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver#define LLVM_CLANG_AST_EXPROBJC_H
166762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
176762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver#include "clang/AST/Expr.h"
186762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver#include "clang/Basic/IdentifierTable.h"
196762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
206762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruvernamespace clang {
216762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  class IdentifierInfo;
226762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  class ASTContext;
236762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  class ObjCMethodDecl;
246762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  class ObjCPropertyDecl;
256762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
266762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver/// ObjCStringLiteral, used for Objective-C string literals
276762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver/// i.e. @"foo".
286762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverclass ObjCStringLiteral : public Expr {
296762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  Stmt *String;
306762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  SourceLocation AtLoc;
316762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverpublic:
326762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
336762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {}
346762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  explicit ObjCStringLiteral(EmptyShell Empty)
356762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    : Expr(ObjCStringLiteralClass, Empty) {}
366762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
376762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  StringLiteral *getString() { return cast<StringLiteral>(String); }
386762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  const StringLiteral *getString() const { return cast<StringLiteral>(String); }
396762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  void setString(StringLiteral *S) { String = S; }
406762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
416762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  SourceLocation getAtLoc() const { return AtLoc; }
426762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  void setAtLoc(SourceLocation L) { AtLoc = L; }
436762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
446762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  virtual SourceRange getSourceRange() const {
456762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    return SourceRange(AtLoc, String->getLocEnd());
466762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  }
476762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
486762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  static bool classof(const Stmt *T) {
496762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    return T->getStmtClass() == ObjCStringLiteralClass;
506762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  }
516762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  static bool classof(const ObjCStringLiteral *) { return true; }
526762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
536762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  // Iterators
546762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  virtual child_iterator child_begin();
556762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  virtual child_iterator child_end();
566762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver};
576762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
586762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver/// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
596762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver/// and behavior as StringLiteral except that the string initializer is obtained
606762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver/// from ASTContext with the encoding type as an argument.
616762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverclass ObjCEncodeExpr : public Expr {
626762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  QualType EncType;
636762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  SourceLocation AtLoc, RParenLoc;
646762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverpublic:
656762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  ObjCEncodeExpr(QualType T, QualType ET,
666762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                 SourceLocation at, SourceLocation rp)
676762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {}
686762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
696762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
706762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
716762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
726762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  SourceLocation getAtLoc() const { return AtLoc; }
736762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  void setAtLoc(SourceLocation L) { AtLoc = L; }
746762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  SourceLocation getRParenLoc() const { return RParenLoc; }
756762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
766762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
776762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  QualType getEncodedType() const { return EncType; }
786762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  void setEncodedType(QualType T) { EncType = T; }
796762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
806762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
816762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  virtual SourceRange getSourceRange() const {
826762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    return SourceRange(AtLoc, RParenLoc);
836762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  }
846762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
856762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  static bool classof(const Stmt *T) {
866762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver    return T->getStmtClass() == ObjCEncodeExprClass;
876762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  }
886762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  static bool classof(const ObjCEncodeExpr *) { return true; }
896762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
906762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  // Iterators
916762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  virtual child_iterator child_begin();
926762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  virtual child_iterator child_end();
936762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver};
946762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
956762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver/// ObjCSelectorExpr used for @selector in Objective-C.
966762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverclass ObjCSelectorExpr : public Expr {
976762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  Selector SelName;
986762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  SourceLocation AtLoc, RParenLoc;
996762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruverpublic:
1006762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  ObjCSelectorExpr(QualType T, Selector selInfo,
1016762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver                   SourceLocation at, SourceLocation rp)
1026762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){}
1036762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver  explicit ObjCSelectorExpr(EmptyShell Empty)
1046762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver   : Expr(ObjCSelectorExprClass, Empty) {}
1056762350ca0e11ca69ecb2c7bcf78cbafa2103ad6Ben Gruver
106  Selector getSelector() const { return SelName; }
107  void setSelector(Selector S) { SelName = S; }
108
109  SourceLocation getAtLoc() const { return AtLoc; }
110  SourceLocation getRParenLoc() const { return RParenLoc; }
111  void setAtLoc(SourceLocation L) { AtLoc = L; }
112  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
113
114  virtual SourceRange getSourceRange() const {
115    return SourceRange(AtLoc, RParenLoc);
116  }
117
118  /// getNumArgs - Return the number of actual arguments to this call.
119  unsigned getNumArgs() const { return SelName.getNumArgs(); }
120
121  static bool classof(const Stmt *T) {
122    return T->getStmtClass() == ObjCSelectorExprClass;
123  }
124  static bool classof(const ObjCSelectorExpr *) { return true; }
125
126  // Iterators
127  virtual child_iterator child_begin();
128  virtual child_iterator child_end();
129};
130
131/// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
132/// as: @protocol(foo), as in:
133///   obj conformsToProtocol:@protocol(foo)]
134/// The return type is "Protocol*".
135class ObjCProtocolExpr : public Expr {
136  ObjCProtocolDecl *Protocol;
137  SourceLocation AtLoc, RParenLoc;
138public:
139  ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
140                   SourceLocation at, SourceLocation rp)
141  : Expr(ObjCProtocolExprClass, T), Protocol(protocol),
142    AtLoc(at), RParenLoc(rp) {}
143  explicit ObjCProtocolExpr(EmptyShell Empty)
144    : Expr(ObjCProtocolExprClass, Empty) {}
145
146  ObjCProtocolDecl *getProtocol() const { return Protocol; }
147  void setProtocol(ObjCProtocolDecl *P) { Protocol = P; }
148
149  SourceLocation getAtLoc() const { return AtLoc; }
150  SourceLocation getRParenLoc() const { return RParenLoc; }
151  void setAtLoc(SourceLocation L) { AtLoc = L; }
152  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
153
154  virtual SourceRange getSourceRange() const {
155    return SourceRange(AtLoc, RParenLoc);
156  }
157
158  static bool classof(const Stmt *T) {
159    return T->getStmtClass() == ObjCProtocolExprClass;
160  }
161  static bool classof(const ObjCProtocolExpr *) { return true; }
162
163  // Iterators
164  virtual child_iterator child_begin();
165  virtual child_iterator child_end();
166};
167
168/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
169class ObjCIvarRefExpr : public Expr {
170  class ObjCIvarDecl *D;
171  SourceLocation Loc;
172  Stmt *Base;
173  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
174  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
175
176public:
177  ObjCIvarRefExpr(ObjCIvarDecl *d,
178                  QualType t, SourceLocation l, Expr *base=0,
179                  bool arrow = false, bool freeIvar = false) :
180    Expr(ObjCIvarRefExprClass, t), D(d),
181    Loc(l), Base(base), IsArrow(arrow),
182    IsFreeIvar(freeIvar) {}
183
184  explicit ObjCIvarRefExpr(EmptyShell Empty)
185    : Expr(ObjCIvarRefExprClass, Empty) {}
186
187  ObjCIvarDecl *getDecl() { return D; }
188  const ObjCIvarDecl *getDecl() const { return D; }
189  void setDecl(ObjCIvarDecl *d) { D = d; }
190
191  const Expr *getBase() const { return cast<Expr>(Base); }
192  Expr *getBase() { return cast<Expr>(Base); }
193  void setBase(Expr * base) { Base = base; }
194
195  bool isArrow() const { return IsArrow; }
196  bool isFreeIvar() const { return IsFreeIvar; }
197  void setIsArrow(bool A) { IsArrow = A; }
198  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
199
200  SourceLocation getLocation() const { return Loc; }
201  void setLocation(SourceLocation L) { Loc = L; }
202
203  virtual SourceRange getSourceRange() const {
204    return isFreeIvar() ? SourceRange(Loc)
205    : SourceRange(getBase()->getLocStart(), Loc);
206  }
207
208  static bool classof(const Stmt *T) {
209    return T->getStmtClass() == ObjCIvarRefExprClass;
210  }
211  static bool classof(const ObjCIvarRefExpr *) { return true; }
212
213  // Iterators
214  virtual child_iterator child_begin();
215  virtual child_iterator child_end();
216};
217
218/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
219/// property.
220///
221class ObjCPropertyRefExpr : public Expr {
222private:
223  ObjCPropertyDecl *AsProperty;
224  SourceLocation IdLoc;
225  Stmt *Base;
226public:
227  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
228                      SourceLocation l, Expr *base)
229    : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) {
230  }
231
232  explicit ObjCPropertyRefExpr(EmptyShell Empty)
233    : Expr(ObjCPropertyRefExprClass, Empty) {}
234
235  ObjCPropertyDecl *getProperty() const { return AsProperty; }
236  void setProperty(ObjCPropertyDecl *D) { AsProperty = D; }
237
238  const Expr *getBase() const { return cast<Expr>(Base); }
239  Expr *getBase() { return cast<Expr>(Base); }
240  void setBase(Expr *base) { Base = base; }
241
242  SourceLocation getLocation() const { return IdLoc; }
243  void setLocation(SourceLocation L) { IdLoc = L; }
244
245  virtual SourceRange getSourceRange() const {
246    return SourceRange(getBase()->getLocStart(), IdLoc);
247  }
248
249  static bool classof(const Stmt *T) {
250    return T->getStmtClass() == ObjCPropertyRefExprClass;
251  }
252  static bool classof(const ObjCPropertyRefExpr *) { return true; }
253
254  // Iterators
255  virtual child_iterator child_begin();
256  virtual child_iterator child_end();
257};
258
259/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties
260/// (i.e. methods following the property naming convention). KVC stands for
261/// Key Value Encoding, a generic concept for accessing or setting a 'Key'
262/// value for an object.
263///
264class ObjCKVCRefExpr : public Expr {
265  ObjCMethodDecl *Setter;
266  ObjCMethodDecl *Getter;
267  SourceLocation Loc;
268  // FIXME: Swizzle these into a single pointer.
269  Stmt *Base;
270  ObjCInterfaceDecl *ClassProp;
271  SourceLocation ClassLoc;
272
273public:
274  ObjCKVCRefExpr(ObjCMethodDecl *getter,
275                 QualType t,
276                 ObjCMethodDecl *setter,
277                 SourceLocation l, Expr *base)
278    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
279      Getter(getter), Loc(l), Base(base), ClassProp(0),
280      ClassLoc(SourceLocation()) {
281    }
282  ObjCKVCRefExpr(ObjCMethodDecl *getter,
283                 QualType t,
284                 ObjCMethodDecl *setter,
285                 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL)
286    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
287      Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) {
288    }
289  explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){}
290
291  ObjCMethodDecl *getGetterMethod() const { return Getter; }
292  ObjCMethodDecl *getSetterMethod() const { return Setter; }
293  ObjCInterfaceDecl *getClassProp() const { return ClassProp; }
294  void setGetterMethod(ObjCMethodDecl *D) { Getter = D; }
295  void setSetterMethod(ObjCMethodDecl *D) { Setter = D; }
296  void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; }
297
298  virtual SourceRange getSourceRange() const {
299    if (Base)
300      return SourceRange(getBase()->getLocStart(), Loc);
301    return SourceRange(ClassLoc, Loc);
302  }
303  const Expr *getBase() const { return cast<Expr>(Base); }
304  Expr *getBase() { return cast<Expr>(Base); }
305  void setBase(Expr *base) { Base = base; }
306
307  SourceLocation getLocation() const { return Loc; }
308  void setLocation(SourceLocation L) { Loc = L; }
309  SourceLocation getClassLoc() const { return ClassLoc; }
310  void setClassLoc(SourceLocation L) { ClassLoc = L; }
311
312  static bool classof(const Stmt *T) {
313    return T->getStmtClass() == ObjCKVCRefExprClass;
314  }
315  static bool classof(const ObjCKVCRefExpr *) { return true; }
316
317  // Iterators
318  virtual child_iterator child_begin();
319  virtual child_iterator child_end();
320};
321
322class ObjCMessageExpr : public Expr {
323  // SubExprs - The receiver and arguments of the message expression.
324  Stmt **SubExprs;
325
326  // NumArgs - The number of arguments (not including the receiver) to the
327  //  message expression.
328  unsigned NumArgs;
329
330  // A unigue name for this message.
331  Selector SelName;
332
333  // A method prototype for this message (optional).
334  // FIXME: Since method decls contain the selector, and most messages have a
335  // prototype, consider devising a scheme for unifying SelName/MethodProto.
336  ObjCMethodDecl *MethodProto;
337
338  SourceLocation LBracloc, RBracloc;
339
340  // Constants for indexing into SubExprs.
341  enum { RECEIVER=0, ARGS_START=1 };
342
343  // Bit-swizzling flags.
344  enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
345  unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
346
347  // constructor used during deserialization
348  ObjCMessageExpr(Selector selInfo, QualType retType,
349                  SourceLocation LBrac, SourceLocation RBrac,
350                  Stmt **subexprs, unsigned nargs)
351  : Expr(ObjCMessageExprClass, retType), SubExprs(subexprs),
352    NumArgs(nargs), SelName(selInfo), MethodProto(NULL),
353    LBracloc(LBrac), RBracloc(RBrac) {}
354
355public:
356  /// This constructor is used to represent class messages where the
357  /// ObjCInterfaceDecl* of the receiver is not known.
358  ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
359                  QualType retType, ObjCMethodDecl *methDecl,
360                  SourceLocation LBrac, SourceLocation RBrac,
361                  Expr **ArgExprs, unsigned NumArgs);
362
363  /// This constructor is used to represent class messages where the
364  /// ObjCInterfaceDecl* of the receiver is known.
365  // FIXME: clsName should be typed to ObjCInterfaceType
366  ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
367                  QualType retType, ObjCMethodDecl *methDecl,
368                  SourceLocation LBrac, SourceLocation RBrac,
369                  Expr **ArgExprs, unsigned NumArgs);
370
371  // constructor for instance messages.
372  ObjCMessageExpr(Expr *receiver, Selector selInfo,
373                  QualType retType, ObjCMethodDecl *methDecl,
374                  SourceLocation LBrac, SourceLocation RBrac,
375                  Expr **ArgExprs, unsigned NumArgs);
376
377  explicit ObjCMessageExpr(EmptyShell Empty)
378    : Expr(ObjCMessageExprClass, Empty) {}
379
380  ~ObjCMessageExpr() {
381    delete [] SubExprs;
382  }
383
384  /// getReceiver - Returns the receiver of the message expression.
385  ///  This can be NULL if the message is for class methods.  For
386  ///  class methods, use getClassName.
387  /// FIXME: need to handle/detect 'super' usage within a class method.
388  Expr *getReceiver() {
389    uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
390    return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
391  }
392  const Expr *getReceiver() const {
393    return const_cast<ObjCMessageExpr*>(this)->getReceiver();
394  }
395  // FIXME: need setters for different receiver types.
396  void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; }
397  Selector getSelector() const { return SelName; }
398  void setSelector(Selector S) { SelName = S; }
399
400  const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
401  ObjCMethodDecl *getMethodDecl() { return MethodProto; }
402  void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
403
404  typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
405
406  /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
407  ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
408  ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
409  ///  was available when this ObjCMessageExpr object was constructed.
410  ClassInfo getClassInfo() const;
411  void setClassInfo(const ClassInfo &C);
412
413  /// getClassName - For class methods, this returns the invoked class,
414  ///  and returns NULL otherwise.  For instance methods, use getReceiver.
415  IdentifierInfo *getClassName() const {
416    return getClassInfo().second;
417  }
418
419  /// getNumArgs - Return the number of actual arguments to this call.
420  unsigned getNumArgs() const { return NumArgs; }
421  void setNumArgs(unsigned nArgs) { NumArgs = nArgs; }
422
423  /// getArg - Return the specified argument.
424  Expr *getArg(unsigned Arg) {
425    assert(Arg < NumArgs && "Arg access out of range!");
426    return cast<Expr>(SubExprs[Arg+ARGS_START]);
427  }
428  const Expr *getArg(unsigned Arg) const {
429    assert(Arg < NumArgs && "Arg access out of range!");
430    return cast<Expr>(SubExprs[Arg+ARGS_START]);
431  }
432  /// setArg - Set the specified argument.
433  void setArg(unsigned Arg, Expr *ArgExpr) {
434    assert(Arg < NumArgs && "Arg access out of range!");
435    SubExprs[Arg+ARGS_START] = ArgExpr;
436  }
437
438  SourceLocation getLeftLoc() const { return LBracloc; }
439  SourceLocation getRightLoc() const { return RBracloc; }
440
441  void setLeftLoc(SourceLocation L) { LBracloc = L; }
442  void setRightLoc(SourceLocation L) { RBracloc = L; }
443
444  void setSourceRange(SourceRange R) {
445    LBracloc = R.getBegin();
446    RBracloc = R.getEnd();
447  }
448  virtual SourceRange getSourceRange() const {
449    return SourceRange(LBracloc, RBracloc);
450  }
451
452  static bool classof(const Stmt *T) {
453    return T->getStmtClass() == ObjCMessageExprClass;
454  }
455  static bool classof(const ObjCMessageExpr *) { return true; }
456
457  // Iterators
458  virtual child_iterator child_begin();
459  virtual child_iterator child_end();
460
461  typedef ExprIterator arg_iterator;
462  typedef ConstExprIterator const_arg_iterator;
463
464  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
465  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
466  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
467  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
468};
469
470/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
471/// which refers to the object on which the current method is executing.
472class ObjCSuperExpr : public Expr {
473  SourceLocation Loc;
474public:
475  ObjCSuperExpr(SourceLocation L, QualType Type)
476    : Expr(ObjCSuperExprClass, Type), Loc(L) { }
477  explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}
478
479  SourceLocation getLoc() const { return Loc; }
480  void setLoc(SourceLocation L) { Loc = L; }
481
482  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
483
484  static bool classof(const Stmt *T) {
485    return T->getStmtClass() == ObjCSuperExprClass;
486  }
487  static bool classof(const ObjCSuperExpr *) { return true; }
488
489  // Iterators
490  virtual child_iterator child_begin();
491  virtual child_iterator child_end();
492};
493
494}  // end namespace clang
495
496#endif
497