ExprObjC.h revision 3a57a3765b6192a94ff4e5997ae0489a1471b308
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///
267
268class ObjCKVCRefExpr : public Expr {
269private:
270
271  ObjCMethodDecl *Setter;
272  ObjCMethodDecl *Getter;
273  SourceLocation Loc;
274  // FIXME: Swizzle these into a single pointer.
275  Stmt *Base;
276  ObjCInterfaceDecl *ClassProp;
277  SourceLocation ClassLoc;
278
279public:
280  ObjCKVCRefExpr(ObjCMethodDecl *getter,
281                 QualType t,
282                 ObjCMethodDecl *setter,
283                 SourceLocation l, Expr *base)
284    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
285      Getter(getter), Loc(l), Base(base), ClassProp(0), ClassLoc(SourceLocation()) {
286    }
287  ObjCKVCRefExpr(ObjCMethodDecl *getter,
288                 QualType t,
289                 ObjCMethodDecl *setter,
290                 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL)
291    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
292      Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) {
293    }
294
295  ObjCMethodDecl *getGetterMethod() const {
296      return Getter;
297  }
298  ObjCMethodDecl *getSetterMethod() const {
299    return Setter;
300  }
301
302  ObjCInterfaceDecl *getClassProp() const {
303    return ClassProp;
304  }
305
306  virtual SourceRange getSourceRange() const {
307    if (Base)
308      return SourceRange(getBase()->getLocStart(), Loc);
309    return SourceRange(ClassLoc, Loc);
310  }
311  const Expr *getBase() const { return cast<Expr>(Base); }
312  Expr *getBase() { return cast<Expr>(Base); }
313  void setBase(Expr * base) { Base = base; }
314
315  SourceLocation getLocation() const { return Loc; }
316
317  static bool classof(const Stmt *T) {
318    return T->getStmtClass() == ObjCKVCRefExprClass;
319  }
320  static bool classof(const ObjCKVCRefExpr *) { return true; }
321
322  // Iterators
323  virtual child_iterator child_begin();
324  virtual child_iterator child_end();
325
326  virtual void EmitImpl(llvm::Serializer& S) const;
327  static ObjCKVCRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
328};
329
330class ObjCMessageExpr : public Expr {
331  // SubExprs - The receiver and arguments of the message expression.
332  Stmt **SubExprs;
333
334  // NumArgs - The number of arguments (not including the receiver) to the
335  //  message expression.
336  unsigned NumArgs;
337
338  // A unigue name for this message.
339  Selector SelName;
340
341  // A method prototype for this message (optional).
342  // FIXME: Since method decls contain the selector, and most messages have a
343  // prototype, consider devising a scheme for unifying SelName/MethodProto.
344  ObjCMethodDecl *MethodProto;
345
346  SourceLocation LBracloc, RBracloc;
347
348  // Constants for indexing into SubExprs.
349  enum { RECEIVER=0, ARGS_START=1 };
350
351  // Bit-swizziling flags.
352  enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
353  unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
354
355  // constructor used during deserialization
356  ObjCMessageExpr(Selector selInfo, QualType retType,
357                  SourceLocation LBrac, SourceLocation RBrac,
358                  Stmt **subexprs, unsigned nargs)
359  : Expr(ObjCMessageExprClass, retType), SubExprs(subexprs),
360    NumArgs(nargs), SelName(selInfo), MethodProto(NULL),
361    LBracloc(LBrac), RBracloc(RBrac) {}
362
363public:
364  /// This constructor is used to represent class messages where the
365  /// ObjCInterfaceDecl* of the receiver is not known.
366  ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
367                  QualType retType, ObjCMethodDecl *methDecl,
368                  SourceLocation LBrac, SourceLocation RBrac,
369                  Expr **ArgExprs, unsigned NumArgs);
370
371  /// This constructor is used to represent class messages where the
372  /// ObjCInterfaceDecl* of the receiver is known.
373  // FIXME: clsName should be typed to ObjCInterfaceType
374  ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
375                  QualType retType, ObjCMethodDecl *methDecl,
376                  SourceLocation LBrac, SourceLocation RBrac,
377                  Expr **ArgExprs, unsigned NumArgs);
378
379  // constructor for instance messages.
380  ObjCMessageExpr(Expr *receiver, Selector selInfo,
381                  QualType retType, ObjCMethodDecl *methDecl,
382                  SourceLocation LBrac, SourceLocation RBrac,
383                  Expr **ArgExprs, unsigned NumArgs);
384
385  ~ObjCMessageExpr() {
386    delete [] SubExprs;
387  }
388
389  /// getReceiver - Returns the receiver of the message expression.
390  ///  This can be NULL if the message is for class methods.  For
391  ///  class methods, use getClassName.
392  /// FIXME: need to handle/detect 'super' usage within a class method.
393  Expr *getReceiver() {
394    uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
395    return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
396  }
397  const Expr *getReceiver() const {
398    return const_cast<ObjCMessageExpr*>(this)->getReceiver();
399  }
400
401  Selector getSelector() const { return SelName; }
402
403  const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
404  ObjCMethodDecl *getMethodDecl() { return MethodProto; }
405
406  typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
407
408  /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
409  ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
410  ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
411  ///  was available when this ObjCMessageExpr object was constructed.
412  ClassInfo getClassInfo() const;
413
414  /// getClassName - For class methods, this returns the invoked class,
415  ///  and returns NULL otherwise.  For instance methods, use getReceiver.
416  IdentifierInfo *getClassName() const {
417    return getClassInfo().second;
418  }
419
420
421  /// getNumArgs - Return the number of actual arguments to this call.
422  unsigned getNumArgs() const { return NumArgs; }
423
424  /// getArg - Return the specified argument.
425  Expr *getArg(unsigned Arg) {
426    assert(Arg < NumArgs && "Arg access out of range!");
427    return cast<Expr>(SubExprs[Arg+ARGS_START]);
428  }
429  const Expr *getArg(unsigned Arg) const {
430    assert(Arg < NumArgs && "Arg access out of range!");
431    return cast<Expr>(SubExprs[Arg+ARGS_START]);
432  }
433  /// setArg - Set the specified argument.
434  void setArg(unsigned Arg, Expr *ArgExpr) {
435    assert(Arg < NumArgs && "Arg access out of range!");
436    SubExprs[Arg+ARGS_START] = ArgExpr;
437  }
438
439  virtual SourceRange getSourceRange() const {
440    return SourceRange(LBracloc, RBracloc);
441  }
442
443  static bool classof(const Stmt *T) {
444    return T->getStmtClass() == ObjCMessageExprClass;
445  }
446  static bool classof(const ObjCMessageExpr *) { return true; }
447
448  // Iterators
449  virtual child_iterator child_begin();
450  virtual child_iterator child_end();
451
452  typedef ExprIterator arg_iterator;
453  typedef ConstExprIterator const_arg_iterator;
454
455  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
456  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
457  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
458  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
459
460  // Serialization.
461  virtual void EmitImpl(llvm::Serializer& S) const;
462  static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
463};
464
465/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
466/// which refers to the object on which the current method is executing.
467class ObjCSuperExpr : public Expr {
468  SourceLocation Loc;
469
470public:
471  ObjCSuperExpr(SourceLocation L, QualType Type)
472    : Expr(ObjCSuperExprClass, Type), Loc(L) { }
473
474  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
475
476  static bool classof(const Stmt *T) {
477    return T->getStmtClass() == ObjCSuperExprClass;
478  }
479  static bool classof(const ObjCSuperExpr *) { return true; }
480
481  // Iterators
482  virtual child_iterator child_begin();
483  virtual child_iterator child_end();
484
485  virtual void EmitImpl(llvm::Serializer& S) const;
486  static ObjCSuperExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
487};
488
489}  // end namespace clang
490
491#endif
492