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