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