ExprObjC.h revision eaf2bb89eb2aad3b80673de30febe52df43c10ec
15a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
25a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//
35a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//                     The LLVM Compiler Infrastructure
45a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//
55a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner// This file is distributed under the University of Illinois Open Source
65a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner// License. See LICENSE.TXT for details.
75a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//
85a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//===----------------------------------------------------------------------===//
95a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//
105a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//  This file defines the ExprObjC interface and subclasses.
115a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//
125a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner//===----------------------------------------------------------------------===//
135a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
145a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifndef LLVM_CLANG_AST_EXPROBJC_H
155a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#define LLVM_CLANG_AST_EXPROBJC_H
165a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
175a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include "clang/AST/Expr.h"
185a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include "clang/Basic/IdentifierTable.h"
195a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
205a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnernamespace clang {
215a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  class IdentifierInfo;
225a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  class ASTContext;
235a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  class ObjCMethodDecl;
245a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  class ObjCPropertyDecl;
255a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
265a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner/// ObjCStringLiteral, used for Objective-C string literals
275a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner/// i.e. @"foo".
285a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnerclass ObjCStringLiteral : public Expr {
295a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  Stmt *String;
305a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  SourceLocation AtLoc;
315a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnerpublic:
325a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
335a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner    : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {}
345a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
355a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  StringLiteral* getString() { return cast<StringLiteral>(String); }
365a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  const StringLiteral* getString() const { return cast<StringLiteral>(String); }
375a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
385a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  SourceLocation getAtLoc() const { return AtLoc; }
395a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
405a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  virtual SourceRange getSourceRange() const {
415a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner    return SourceRange(AtLoc, String->getLocEnd());
425a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  }
435a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
445a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  static bool classof(const Stmt *T) {
455a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner    return T->getStmtClass() == ObjCStringLiteralClass;
465a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  }
475a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  static bool classof(const ObjCStringLiteral *) { return true; }
485a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
495a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  // Iterators
505a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  virtual child_iterator child_begin();
515a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  virtual child_iterator child_end();
525a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
535a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  virtual void EmitImpl(llvm::Serializer& S) const;
545a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner  static ObjCStringLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
555a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner};
565a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner
575a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner/// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
585a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner/// 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  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,
167                  QualType t, SourceLocation l, Expr *base=0,
168                  bool arrow = false, bool freeIvar = false) :
169    Expr(ObjCIvarRefExprClass, t), D(d),
170    Loc(l), Base(base), IsArrow(arrow),
171    IsFreeIvar(freeIvar) {}
172
173  ObjCIvarDecl *getDecl() { return D; }
174  const ObjCIvarDecl *getDecl() const { return D; }
175  virtual SourceRange getSourceRange() const {
176    return isFreeIvar() ? SourceRange(Loc)
177                        : SourceRange(getBase()->getLocStart(), Loc);
178  }
179  const Expr *getBase() const { return cast<Expr>(Base); }
180  Expr *getBase() { return cast<Expr>(Base); }
181  void setBase(Expr * base) { Base = base; }
182  bool isArrow() const { return IsArrow; }
183  bool isFreeIvar() const { return IsFreeIvar; }
184
185  SourceLocation getLocation() const { return Loc; }
186
187  static bool classof(const Stmt *T) {
188    return T->getStmtClass() == ObjCIvarRefExprClass;
189  }
190  static bool classof(const ObjCIvarRefExpr *) { return true; }
191
192  // Iterators
193  virtual child_iterator child_begin();
194  virtual child_iterator child_end();
195
196  virtual void EmitImpl(llvm::Serializer& S) const;
197  static ObjCIvarRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
198};
199
200/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
201/// property.
202///
203class ObjCPropertyRefExpr : public Expr {
204private:
205  ObjCPropertyDecl *AsProperty;
206  SourceLocation IdLoc;
207  Stmt *Base;
208
209public:
210  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
211                      SourceLocation l, Expr *base)
212    : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) {
213  }
214  ObjCPropertyDecl *getProperty() const {
215    return AsProperty;
216  }
217
218  virtual SourceRange getSourceRange() const {
219    return SourceRange(getBase()->getLocStart(), IdLoc);
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