ExprObjC.h revision 405bad07391494d2eb025f8222c256c66b56e5f8
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/Expr.h"
18#include "clang/Basic/IdentifierTable.h"
19
20namespace clang {
21  class IdentifierInfo;
22  class ASTContext;
23  class ObjCMethodDecl;
24  class ObjCPropertyDecl;
25
26/// ObjCStringLiteral, used for Objective-C string literals
27/// i.e. @"foo".
28class ObjCStringLiteral : public Expr {
29  Stmt *String;
30  SourceLocation AtLoc;
31public:
32  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
33    : Expr(ObjCStringLiteralClass, T), 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  QualType EncType;
63  SourceLocation AtLoc, RParenLoc;
64public:
65  ObjCEncodeExpr(QualType T, QualType ET,
66                 SourceLocation at, SourceLocation rp)
67    : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {}
68
69  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
70
71
72  SourceLocation getAtLoc() const { return AtLoc; }
73  void setAtLoc(SourceLocation L) { AtLoc = L; }
74  SourceLocation getRParenLoc() const { return RParenLoc; }
75  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
76
77  QualType getEncodedType() const { return EncType; }
78  void setEncodedType(QualType T) { EncType = T; }
79
80
81  virtual SourceRange getSourceRange() const {
82    return SourceRange(AtLoc, RParenLoc);
83  }
84
85  static bool classof(const Stmt *T) {
86    return T->getStmtClass() == ObjCEncodeExprClass;
87  }
88  static bool classof(const ObjCEncodeExpr *) { return true; }
89
90  // Iterators
91  virtual child_iterator child_begin();
92  virtual child_iterator child_end();
93};
94
95/// ObjCSelectorExpr used for @selector in Objective-C.
96class ObjCSelectorExpr : public Expr {
97  Selector SelName;
98  SourceLocation AtLoc, RParenLoc;
99public:
100  ObjCSelectorExpr(QualType T, Selector selInfo,
101                   SourceLocation at, SourceLocation rp)
102  : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){}
103  explicit ObjCSelectorExpr(EmptyShell Empty)
104   : Expr(ObjCSelectorExprClass, Empty) {}
105
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_or_null<Expr>(Base); }
304  Expr *getBase() { return cast_or_null<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), SubExprs(0), NumArgs(0) {}
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) {
422    NumArgs = nArgs;
423    // FIXME: should always allocate SubExprs via the ASTContext's
424    // allocator.
425    if (!SubExprs)
426      SubExprs = new Stmt* [NumArgs + 1];
427  }
428
429  /// getArg - Return the specified argument.
430  Expr *getArg(unsigned Arg) {
431    assert(Arg < NumArgs && "Arg access out of range!");
432    return cast<Expr>(SubExprs[Arg+ARGS_START]);
433  }
434  const Expr *getArg(unsigned Arg) const {
435    assert(Arg < NumArgs && "Arg access out of range!");
436    return cast<Expr>(SubExprs[Arg+ARGS_START]);
437  }
438  /// setArg - Set the specified argument.
439  void setArg(unsigned Arg, Expr *ArgExpr) {
440    assert(Arg < NumArgs && "Arg access out of range!");
441    SubExprs[Arg+ARGS_START] = ArgExpr;
442  }
443
444  SourceLocation getLeftLoc() const { return LBracloc; }
445  SourceLocation getRightLoc() const { return RBracloc; }
446
447  void setLeftLoc(SourceLocation L) { LBracloc = L; }
448  void setRightLoc(SourceLocation L) { RBracloc = L; }
449
450  void setSourceRange(SourceRange R) {
451    LBracloc = R.getBegin();
452    RBracloc = R.getEnd();
453  }
454  virtual SourceRange getSourceRange() const {
455    return SourceRange(LBracloc, RBracloc);
456  }
457
458  static bool classof(const Stmt *T) {
459    return T->getStmtClass() == ObjCMessageExprClass;
460  }
461  static bool classof(const ObjCMessageExpr *) { return true; }
462
463  // Iterators
464  virtual child_iterator child_begin();
465  virtual child_iterator child_end();
466
467  typedef ExprIterator arg_iterator;
468  typedef ConstExprIterator const_arg_iterator;
469
470  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
471  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
472  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
473  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
474};
475
476/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
477/// which refers to the object on which the current method is executing.
478class ObjCSuperExpr : public Expr {
479  SourceLocation Loc;
480public:
481  ObjCSuperExpr(SourceLocation L, QualType Type)
482    : Expr(ObjCSuperExprClass, Type), Loc(L) { }
483  explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}
484
485  SourceLocation getLoc() const { return Loc; }
486  void setLoc(SourceLocation L) { Loc = L; }
487
488  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
489
490  static bool classof(const Stmt *T) {
491    return T->getStmtClass() == ObjCSuperExprClass;
492  }
493  static bool classof(const ObjCSuperExpr *) { return true; }
494
495  // Iterators
496  virtual child_iterator child_begin();
497  virtual child_iterator child_end();
498};
499
500}  // end namespace clang
501
502#endif
503