ExprObjC.h revision aaa63a761c6671a08e3f4f463435b72739fa194b
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  FieldDecl *FD;
160  SourceLocation Loc;
161  Stmt *Base;
162  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
163  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
164
165public:
166  ObjCIvarRefExpr(ObjCIvarDecl *d, FieldDecl *fd,
167                  QualType t, SourceLocation l, Expr *base=0,
168                  bool arrow = false, bool freeIvar = false) :
169    Expr(ObjCIvarRefExprClass, t), D(d), FD(fd),
170    Loc(l), Base(base), IsArrow(arrow),
171    IsFreeIvar(freeIvar) {}
172
173  ObjCIvarDecl *getDecl() { return D; }
174  FieldDecl *getFieldDecl() { return FD; }
175  const FieldDecl *getFieldDecl() const { return FD; }
176  const ObjCIvarDecl *getDecl() const { return D; }
177  virtual SourceRange getSourceRange() const {
178    return isFreeIvar() ? SourceRange(Loc)
179                        : SourceRange(getBase()->getLocStart(), Loc);
180  }
181  const Expr *getBase() const { return cast<Expr>(Base); }
182  Expr *getBase() { return cast<Expr>(Base); }
183  void setBase(Expr * base) { Base = base; }
184  bool isArrow() const { return IsArrow; }
185  bool isFreeIvar() const { return IsFreeIvar; }
186
187  SourceLocation getLocation() const { return Loc; }
188
189  static bool classof(const Stmt *T) {
190    return T->getStmtClass() == ObjCIvarRefExprClass;
191  }
192  static bool classof(const ObjCIvarRefExpr *) { return true; }
193
194  // Iterators
195  virtual child_iterator child_begin();
196  virtual child_iterator child_end();
197
198  virtual void EmitImpl(llvm::Serializer& S) const;
199  static ObjCIvarRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
200};
201
202/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
203/// property.
204///
205class ObjCPropertyRefExpr : public Expr {
206private:
207  ObjCPropertyDecl *AsProperty;
208  SourceLocation IdLoc;
209  Stmt *Base;
210
211public:
212  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
213                      SourceLocation l, Expr *base)
214    : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) {
215  }
216  ObjCPropertyDecl *getProperty() const {
217    return AsProperty;
218  }
219
220  virtual SourceRange getSourceRange() const {
221    return SourceRange(getBase()->getLocStart(), IdLoc);
222  }
223  const Expr *getBase() const { return cast<Expr>(Base); }
224  Expr *getBase() { return cast<Expr>(Base); }
225  void setBase(Expr * base) { Base = base; }
226
227  SourceLocation getLocation() const { return IdLoc; }
228
229  static bool classof(const Stmt *T) {
230    return T->getStmtClass() == ObjCPropertyRefExprClass;
231  }
232  static bool classof(const ObjCPropertyRefExpr *) { return true; }
233
234  // Iterators
235  virtual child_iterator child_begin();
236  virtual child_iterator child_end();
237
238  virtual void EmitImpl(llvm::Serializer& S) const;
239  static ObjCPropertyRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
240};
241
242/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties
243/// (i.e. methods following the property naming convention). KVC stands for
244/// Key Value Encoding, a generic concept for accessing or setting a 'Key'
245/// value for an object.
246///
247
248class ObjCKVCRefExpr : public Expr {
249private:
250
251  ObjCMethodDecl *Setter;
252  ObjCMethodDecl *Getter;
253  SourceLocation Loc;
254  Stmt *Base;
255
256public:
257  ObjCKVCRefExpr(ObjCMethodDecl *getter,
258                 QualType t,
259                 ObjCMethodDecl *setter,
260                 SourceLocation l, Expr *base)
261    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
262      Getter(getter), Loc(l), Base(base) {
263    }
264
265  ObjCMethodDecl *getGetterMethod() const {
266      return Getter;
267  }
268  ObjCMethodDecl *getSetterMethod() const {
269    return Setter;
270  }
271
272  virtual SourceRange getSourceRange() const {
273    return SourceRange(getBase()->getLocStart(), Loc);
274  }
275  const Expr *getBase() const { return cast<Expr>(Base); }
276  Expr *getBase() { return cast<Expr>(Base); }
277  void setBase(Expr * base) { Base = base; }
278
279  SourceLocation getLocation() const { return Loc; }
280
281  static bool classof(const Stmt *T) {
282    return T->getStmtClass() == ObjCKVCRefExprClass;
283  }
284  static bool classof(const ObjCKVCRefExpr *) { return true; }
285
286  // Iterators
287  virtual child_iterator child_begin();
288  virtual child_iterator child_end();
289
290  virtual void EmitImpl(llvm::Serializer& S) const;
291  static ObjCKVCRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
292};
293
294class ObjCMessageExpr : public Expr {
295  // SubExprs - The receiver and arguments of the message expression.
296  Stmt **SubExprs;
297
298  // NumArgs - The number of arguments (not including the receiver) to the
299  //  message expression.
300  unsigned NumArgs;
301
302  // A unigue name for this message.
303  Selector SelName;
304
305  // A method prototype for this message (optional).
306  // FIXME: Since method decls contain the selector, and most messages have a
307  // prototype, consider devising a scheme for unifying SelName/MethodProto.
308  ObjCMethodDecl *MethodProto;
309
310  SourceLocation LBracloc, RBracloc;
311
312  // Constants for indexing into SubExprs.
313  enum { RECEIVER=0, ARGS_START=1 };
314
315  // Bit-swizziling flags.
316  enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
317  unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
318
319  // constructor used during deserialization
320  ObjCMessageExpr(Selector selInfo, QualType retType,
321                  SourceLocation LBrac, SourceLocation RBrac,
322                  Stmt **subexprs, unsigned nargs)
323  : Expr(ObjCMessageExprClass, retType), SubExprs(subexprs),
324    NumArgs(nargs), SelName(selInfo), MethodProto(NULL),
325    LBracloc(LBrac), RBracloc(RBrac) {}
326
327public:
328  /// This constructor is used to represent class messages where the
329  /// ObjCInterfaceDecl* of the receiver is not known.
330  ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
331                  QualType retType, ObjCMethodDecl *methDecl,
332                  SourceLocation LBrac, SourceLocation RBrac,
333                  Expr **ArgExprs, unsigned NumArgs);
334
335  /// This constructor is used to represent class messages where the
336  /// ObjCInterfaceDecl* of the receiver is known.
337  // FIXME: clsName should be typed to ObjCInterfaceType
338  ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
339                  QualType retType, ObjCMethodDecl *methDecl,
340                  SourceLocation LBrac, SourceLocation RBrac,
341                  Expr **ArgExprs, unsigned NumArgs);
342
343  // constructor for instance messages.
344  ObjCMessageExpr(Expr *receiver, Selector selInfo,
345                  QualType retType, ObjCMethodDecl *methDecl,
346                  SourceLocation LBrac, SourceLocation RBrac,
347                  Expr **ArgExprs, unsigned NumArgs);
348
349  ~ObjCMessageExpr() {
350    delete [] SubExprs;
351  }
352
353  /// getReceiver - Returns the receiver of the message expression.
354  ///  This can be NULL if the message is for class methods.  For
355  ///  class methods, use getClassName.
356  /// FIXME: need to handle/detect 'super' usage within a class method.
357  Expr *getReceiver() {
358    uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
359    return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
360  }
361  const Expr *getReceiver() const {
362    return const_cast<ObjCMessageExpr*>(this)->getReceiver();
363  }
364
365  Selector getSelector() const { return SelName; }
366
367  const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
368  ObjCMethodDecl *getMethodDecl() { return MethodProto; }
369
370  typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
371
372  /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
373  ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
374  ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
375  ///  was available when this ObjCMessageExpr object was constructed.
376  ClassInfo getClassInfo() const;
377
378  /// getClassName - For class methods, this returns the invoked class,
379  ///  and returns NULL otherwise.  For instance methods, use getReceiver.
380  IdentifierInfo *getClassName() const {
381    return getClassInfo().second;
382  }
383
384
385  /// getNumArgs - Return the number of actual arguments to this call.
386  unsigned getNumArgs() const { return NumArgs; }
387
388  /// getArg - Return the specified argument.
389  Expr *getArg(unsigned Arg) {
390    assert(Arg < NumArgs && "Arg access out of range!");
391    return cast<Expr>(SubExprs[Arg+ARGS_START]);
392  }
393  const Expr *getArg(unsigned Arg) const {
394    assert(Arg < NumArgs && "Arg access out of range!");
395    return cast<Expr>(SubExprs[Arg+ARGS_START]);
396  }
397  /// setArg - Set the specified argument.
398  void setArg(unsigned Arg, Expr *ArgExpr) {
399    assert(Arg < NumArgs && "Arg access out of range!");
400    SubExprs[Arg+ARGS_START] = ArgExpr;
401  }
402
403  virtual SourceRange getSourceRange() const {
404    return SourceRange(LBracloc, RBracloc);
405  }
406
407  static bool classof(const Stmt *T) {
408    return T->getStmtClass() == ObjCMessageExprClass;
409  }
410  static bool classof(const ObjCMessageExpr *) { return true; }
411
412  // Iterators
413  virtual child_iterator child_begin();
414  virtual child_iterator child_end();
415
416  typedef ExprIterator arg_iterator;
417  typedef ConstExprIterator const_arg_iterator;
418
419  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
420  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
421  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
422  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
423
424  // Serialization.
425  virtual void EmitImpl(llvm::Serializer& S) const;
426  static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
427};
428
429/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
430/// which refers to the object on which the current method is executing.
431class ObjCSuperExpr : public Expr {
432  SourceLocation Loc;
433
434public:
435  ObjCSuperExpr(SourceLocation L, QualType Type)
436    : Expr(ObjCSuperExprClass, Type), Loc(L) { }
437
438  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
439
440  static bool classof(const Stmt *T) {
441    return T->getStmtClass() == ObjCSuperExprClass;
442  }
443  static bool classof(const ObjCSuperExpr *) { return true; }
444
445  // Iterators
446  virtual child_iterator child_begin();
447  virtual child_iterator child_end();
448
449  virtual void EmitImpl(llvm::Serializer& S) const;
450  static ObjCSuperExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
451};
452
453}  // end namespace clang
454
455#endif
456