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