ExprObjC.h revision 262f9cf85294a1a0713420abc79d40f64aef7240
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  ObjCStringLiteral* Clone(ASTContext &C) const;
38
39  StringLiteral *getString() { return cast<StringLiteral>(String); }
40  const StringLiteral *getString() const { return cast<StringLiteral>(String); }
41  void setString(StringLiteral *S) { String = S; }
42
43  SourceLocation getAtLoc() const { return AtLoc; }
44  void setAtLoc(SourceLocation L) { AtLoc = L; }
45
46  virtual SourceRange getSourceRange() const {
47    return SourceRange(AtLoc, String->getLocEnd());
48  }
49
50  static bool classof(const Stmt *T) {
51    return T->getStmtClass() == ObjCStringLiteralClass;
52  }
53  static bool classof(const ObjCStringLiteral *) { return true; }
54
55  // Iterators
56  virtual child_iterator child_begin();
57  virtual child_iterator child_end();
58};
59
60/// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
61/// and behavior as StringLiteral except that the string initializer is obtained
62/// from ASTContext with the encoding type as an argument.
63class ObjCEncodeExpr : public Expr {
64  QualType EncType;
65  SourceLocation AtLoc, RParenLoc;
66public:
67  ObjCEncodeExpr(QualType T, QualType ET,
68                 SourceLocation at, SourceLocation rp)
69    : Expr(ObjCEncodeExprClass, T, ET->isDependentType(),
70           ET->isDependentType()), EncType(ET), AtLoc(at), RParenLoc(rp) {}
71
72  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
73
74
75  SourceLocation getAtLoc() const { return AtLoc; }
76  void setAtLoc(SourceLocation L) { AtLoc = L; }
77  SourceLocation getRParenLoc() const { return RParenLoc; }
78  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
79
80  QualType getEncodedType() const { return EncType; }
81  void setEncodedType(QualType T) { EncType = T; }
82
83
84  virtual SourceRange getSourceRange() const {
85    return SourceRange(AtLoc, RParenLoc);
86  }
87
88  static bool classof(const Stmt *T) {
89    return T->getStmtClass() == ObjCEncodeExprClass;
90  }
91  static bool classof(const ObjCEncodeExpr *) { return true; }
92
93  // Iterators
94  virtual child_iterator child_begin();
95  virtual child_iterator child_end();
96};
97
98/// ObjCSelectorExpr used for @selector in Objective-C.
99class ObjCSelectorExpr : public Expr {
100  Selector SelName;
101  SourceLocation AtLoc, RParenLoc;
102public:
103  ObjCSelectorExpr(QualType T, Selector selInfo,
104                   SourceLocation at, SourceLocation rp)
105  : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){}
106  explicit ObjCSelectorExpr(EmptyShell Empty)
107   : Expr(ObjCSelectorExprClass, Empty) {}
108
109  ObjCSelectorExpr *Clone(ASTContext &C) const;
110
111  Selector getSelector() const { return SelName; }
112  void setSelector(Selector S) { SelName = S; }
113
114  SourceLocation getAtLoc() const { return AtLoc; }
115  SourceLocation getRParenLoc() const { return RParenLoc; }
116  void setAtLoc(SourceLocation L) { AtLoc = L; }
117  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
118
119  virtual SourceRange getSourceRange() const {
120    return SourceRange(AtLoc, RParenLoc);
121  }
122
123  /// getNumArgs - Return the number of actual arguments to this call.
124  unsigned getNumArgs() const { return SelName.getNumArgs(); }
125
126  static bool classof(const Stmt *T) {
127    return T->getStmtClass() == ObjCSelectorExprClass;
128  }
129  static bool classof(const ObjCSelectorExpr *) { return true; }
130
131  // Iterators
132  virtual child_iterator child_begin();
133  virtual child_iterator child_end();
134};
135
136/// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
137/// as: @protocol(foo), as in:
138///   obj conformsToProtocol:@protocol(foo)]
139/// The return type is "Protocol*".
140class ObjCProtocolExpr : public Expr {
141  ObjCProtocolDecl *TheProtocol;
142  SourceLocation AtLoc, RParenLoc;
143public:
144  ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
145                   SourceLocation at, SourceLocation rp)
146  : Expr(ObjCProtocolExprClass, T), TheProtocol(protocol),
147    AtLoc(at), RParenLoc(rp) {}
148  explicit ObjCProtocolExpr(EmptyShell Empty)
149    : Expr(ObjCProtocolExprClass, Empty) {}
150
151  ObjCProtocolExpr *Clone(ASTContext &C) const;
152
153  ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
154  void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
155
156  SourceLocation getAtLoc() const { return AtLoc; }
157  SourceLocation getRParenLoc() const { return RParenLoc; }
158  void setAtLoc(SourceLocation L) { AtLoc = L; }
159  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
160
161  virtual SourceRange getSourceRange() const {
162    return SourceRange(AtLoc, RParenLoc);
163  }
164
165  static bool classof(const Stmt *T) {
166    return T->getStmtClass() == ObjCProtocolExprClass;
167  }
168  static bool classof(const ObjCProtocolExpr *) { return true; }
169
170  // Iterators
171  virtual child_iterator child_begin();
172  virtual child_iterator child_end();
173};
174
175/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
176class ObjCIvarRefExpr : public Expr {
177  class ObjCIvarDecl *D;
178  SourceLocation Loc;
179  Stmt *Base;
180  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
181  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
182
183public:
184  ObjCIvarRefExpr(ObjCIvarDecl *d,
185                  QualType t, SourceLocation l, Expr *base=0,
186                  bool arrow = false, bool freeIvar = false) :
187    Expr(ObjCIvarRefExprClass, t), D(d),
188    Loc(l), Base(base), IsArrow(arrow),
189    IsFreeIvar(freeIvar) {}
190
191  explicit ObjCIvarRefExpr(EmptyShell Empty)
192    : Expr(ObjCIvarRefExprClass, Empty) {}
193
194  ObjCIvarDecl *getDecl() { return D; }
195  const ObjCIvarDecl *getDecl() const { return D; }
196  void setDecl(ObjCIvarDecl *d) { D = d; }
197
198  const Expr *getBase() const { return cast<Expr>(Base); }
199  Expr *getBase() { return cast<Expr>(Base); }
200  void setBase(Expr * base) { Base = base; }
201
202  bool isArrow() const { return IsArrow; }
203  bool isFreeIvar() const { return IsFreeIvar; }
204  void setIsArrow(bool A) { IsArrow = A; }
205  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
206
207  SourceLocation getLocation() const { return Loc; }
208  void setLocation(SourceLocation L) { Loc = L; }
209
210  virtual SourceRange getSourceRange() const {
211    return isFreeIvar() ? SourceRange(Loc)
212    : SourceRange(getBase()->getLocStart(), Loc);
213  }
214
215  static bool classof(const Stmt *T) {
216    return T->getStmtClass() == ObjCIvarRefExprClass;
217  }
218  static bool classof(const ObjCIvarRefExpr *) { return true; }
219
220  // Iterators
221  virtual child_iterator child_begin();
222  virtual child_iterator child_end();
223};
224
225/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
226/// property.
227///
228class ObjCPropertyRefExpr : public Expr {
229private:
230  ObjCPropertyDecl *AsProperty;
231  SourceLocation IdLoc;
232  Stmt *Base;
233public:
234  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
235                      SourceLocation l, Expr *base)
236    : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) {
237  }
238
239  explicit ObjCPropertyRefExpr(EmptyShell Empty)
240    : Expr(ObjCPropertyRefExprClass, Empty) {}
241
242  ObjCPropertyDecl *getProperty() const { return AsProperty; }
243  void setProperty(ObjCPropertyDecl *D) { AsProperty = D; }
244
245  const Expr *getBase() const { return cast<Expr>(Base); }
246  Expr *getBase() { return cast<Expr>(Base); }
247  void setBase(Expr *base) { Base = base; }
248
249  SourceLocation getLocation() const { return IdLoc; }
250  void setLocation(SourceLocation L) { IdLoc = L; }
251
252  virtual SourceRange getSourceRange() const {
253    return SourceRange(getBase()->getLocStart(), IdLoc);
254  }
255
256  static bool classof(const Stmt *T) {
257    return T->getStmtClass() == ObjCPropertyRefExprClass;
258  }
259  static bool classof(const ObjCPropertyRefExpr *) { return true; }
260
261  // Iterators
262  virtual child_iterator child_begin();
263  virtual child_iterator child_end();
264};
265
266/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties
267/// (i.e. methods following the property naming convention). KVC stands for
268/// Key Value Encoding, a generic concept for accessing or setting a 'Key'
269/// value for an object.
270///
271class ObjCKVCRefExpr : public Expr {
272  ObjCMethodDecl *Setter;
273  ObjCMethodDecl *Getter;
274  SourceLocation Loc;
275  // FIXME: Swizzle these into a single pointer.
276  Stmt *Base;
277  ObjCInterfaceDecl *ClassProp;
278  SourceLocation ClassLoc;
279
280public:
281  ObjCKVCRefExpr(ObjCMethodDecl *getter,
282                 QualType t,
283                 ObjCMethodDecl *setter,
284                 SourceLocation l, Expr *base)
285    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
286      Getter(getter), Loc(l), Base(base), ClassProp(0),
287      ClassLoc(SourceLocation()) {
288    }
289  ObjCKVCRefExpr(ObjCMethodDecl *getter,
290                 QualType t,
291                 ObjCMethodDecl *setter,
292                 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL)
293    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
294      Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) {
295    }
296  explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){}
297
298  ObjCMethodDecl *getGetterMethod() const { return Getter; }
299  ObjCMethodDecl *getSetterMethod() const { return Setter; }
300  ObjCInterfaceDecl *getClassProp() const { return ClassProp; }
301  void setGetterMethod(ObjCMethodDecl *D) { Getter = D; }
302  void setSetterMethod(ObjCMethodDecl *D) { Setter = D; }
303  void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; }
304
305  virtual SourceRange getSourceRange() const {
306    if (Base)
307      return SourceRange(getBase()->getLocStart(), Loc);
308    return SourceRange(ClassLoc, Loc);
309  }
310  const Expr *getBase() const { return cast_or_null<Expr>(Base); }
311  Expr *getBase() { return cast_or_null<Expr>(Base); }
312  void setBase(Expr *base) { Base = base; }
313
314  SourceLocation getLocation() const { return Loc; }
315  void setLocation(SourceLocation L) { Loc = L; }
316  SourceLocation getClassLoc() const { return ClassLoc; }
317  void setClassLoc(SourceLocation L) { ClassLoc = L; }
318
319  static bool classof(const Stmt *T) {
320    return T->getStmtClass() == ObjCKVCRefExprClass;
321  }
322  static bool classof(const ObjCKVCRefExpr *) { return true; }
323
324  // Iterators
325  virtual child_iterator child_begin();
326  virtual child_iterator child_end();
327};
328
329class ObjCMessageExpr : public Expr {
330  // SubExprs - The receiver and arguments of the message expression.
331  Stmt **SubExprs;
332
333  // NumArgs - The number of arguments (not including the receiver) to the
334  //  message expression.
335  unsigned NumArgs;
336
337  // A unigue name for this message.
338  Selector SelName;
339
340  // A method prototype for this message (optional).
341  // FIXME: Since method decls contain the selector, and most messages have a
342  // prototype, consider devising a scheme for unifying SelName/MethodProto.
343  ObjCMethodDecl *MethodProto;
344
345  SourceLocation LBracloc, RBracloc;
346
347  // Constants for indexing into SubExprs.
348  enum { RECEIVER=0, ARGS_START=1 };
349
350  // Bit-swizzling flags.
351  enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
352  unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
353
354public:
355  /// This constructor is used to represent class messages where the
356  /// ObjCInterfaceDecl* of the receiver is not known.
357  ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
358                  QualType retType, ObjCMethodDecl *methDecl,
359                  SourceLocation LBrac, SourceLocation RBrac,
360                  Expr **ArgExprs, unsigned NumArgs);
361
362  /// This constructor is used to represent class messages where the
363  /// ObjCInterfaceDecl* of the receiver is known.
364  // FIXME: clsName should be typed to ObjCInterfaceType
365  ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
366                  QualType retType, ObjCMethodDecl *methDecl,
367                  SourceLocation LBrac, SourceLocation RBrac,
368                  Expr **ArgExprs, unsigned NumArgs);
369
370  // constructor for instance messages.
371  ObjCMessageExpr(Expr *receiver, Selector selInfo,
372                  QualType retType, ObjCMethodDecl *methDecl,
373                  SourceLocation LBrac, SourceLocation RBrac,
374                  Expr **ArgExprs, unsigned NumArgs);
375
376  explicit ObjCMessageExpr(EmptyShell Empty)
377    : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
378
379  ~ObjCMessageExpr() {
380    delete [] SubExprs;
381  }
382
383  /// getReceiver - Returns the receiver of the message expression.
384  ///  This can be NULL if the message is for class methods.  For
385  ///  class methods, use getClassName.
386  /// FIXME: need to handle/detect 'super' usage within a class method.
387  Expr *getReceiver() {
388    uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
389    return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
390  }
391  const Expr *getReceiver() const {
392    return const_cast<ObjCMessageExpr*>(this)->getReceiver();
393  }
394  // FIXME: need setters for different receiver types.
395  void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; }
396  Selector getSelector() const { return SelName; }
397  void setSelector(Selector S) { SelName = S; }
398
399  const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
400  ObjCMethodDecl *getMethodDecl() { return MethodProto; }
401  void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
402
403  typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
404
405  /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
406  ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
407  ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
408  ///  was available when this ObjCMessageExpr object was constructed.
409  ClassInfo getClassInfo() const;
410  void setClassInfo(const ClassInfo &C);
411
412  /// getClassName - For class methods, this returns the invoked class,
413  ///  and returns NULL otherwise.  For instance methods, use getReceiver.
414  IdentifierInfo *getClassName() const {
415    return getClassInfo().second;
416  }
417
418  /// getNumArgs - Return the number of actual arguments to this call.
419  unsigned getNumArgs() const { return NumArgs; }
420  void setNumArgs(unsigned nArgs) {
421    NumArgs = nArgs;
422    // FIXME: should always allocate SubExprs via the ASTContext's
423    // allocator.
424    if (!SubExprs)
425      SubExprs = new Stmt* [NumArgs + 1];
426  }
427
428  /// getArg - Return the specified argument.
429  Expr *getArg(unsigned Arg) {
430    assert(Arg < NumArgs && "Arg access out of range!");
431    return cast<Expr>(SubExprs[Arg+ARGS_START]);
432  }
433  const Expr *getArg(unsigned Arg) const {
434    assert(Arg < NumArgs && "Arg access out of range!");
435    return cast<Expr>(SubExprs[Arg+ARGS_START]);
436  }
437  /// setArg - Set the specified argument.
438  void setArg(unsigned Arg, Expr *ArgExpr) {
439    assert(Arg < NumArgs && "Arg access out of range!");
440    SubExprs[Arg+ARGS_START] = ArgExpr;
441  }
442
443  SourceLocation getLeftLoc() const { return LBracloc; }
444  SourceLocation getRightLoc() const { return RBracloc; }
445
446  void setLeftLoc(SourceLocation L) { LBracloc = L; }
447  void setRightLoc(SourceLocation L) { RBracloc = L; }
448
449  void setSourceRange(SourceRange R) {
450    LBracloc = R.getBegin();
451    RBracloc = R.getEnd();
452  }
453  virtual SourceRange getSourceRange() const {
454    return SourceRange(LBracloc, RBracloc);
455  }
456
457  static bool classof(const Stmt *T) {
458    return T->getStmtClass() == ObjCMessageExprClass;
459  }
460  static bool classof(const ObjCMessageExpr *) { return true; }
461
462  // Iterators
463  virtual child_iterator child_begin();
464  virtual child_iterator child_end();
465
466  typedef ExprIterator arg_iterator;
467  typedef ConstExprIterator const_arg_iterator;
468
469  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
470  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
471  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
472  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
473};
474
475/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
476/// which refers to the object on which the current method is executing.
477class ObjCSuperExpr : public Expr {
478  SourceLocation Loc;
479public:
480  ObjCSuperExpr(SourceLocation L, QualType Type)
481    : Expr(ObjCSuperExprClass, Type), Loc(L) { }
482  explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}
483
484  SourceLocation getLoc() const { return Loc; }
485  void setLoc(SourceLocation L) { Loc = L; }
486
487  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
488
489  static bool classof(const Stmt *T) {
490    return T->getStmtClass() == ObjCSuperExprClass;
491  }
492  static bool classof(const ObjCSuperExpr *) { return true; }
493
494  // Iterators
495  virtual child_iterator child_begin();
496  virtual child_iterator child_end();
497};
498
499}  // end namespace clang
500
501#endif
502