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