summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/ExprObjC.h
blob: 51b99610cd9d166db2d66e4b01959648f9bdacf1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the ExprObjC interface and subclasses.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_EXPROBJC_H
#define LLVM_CLANG_AST_EXPROBJC_H

#include "clang/AST/Expr.h"
#include "clang/Basic/IdentifierTable.h"

namespace clang {
  class IdentifierInfo;
  class ASTContext;
  class ObjCMethodDecl;
  class ObjCPropertyDecl;
  
/// ObjCStringLiteral, used for Objective-C string literals
/// i.e. @"foo".
class ObjCStringLiteral : public Expr {
  Stmt *String;
  SourceLocation AtLoc;
public:
  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
    : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {}
  explicit ObjCStringLiteral(EmptyShell Empty)
    : Expr(ObjCStringLiteralClass, Empty) {}

  StringLiteral *getString() { return cast<StringLiteral>(String); }
  const StringLiteral *getString() const { return cast<StringLiteral>(String); }
  void setString(StringLiteral *S) { String = S; }

  SourceLocation getAtLoc() const { return AtLoc; }
  void setAtLoc(SourceLocation L) { AtLoc = L; }

  virtual SourceRange getSourceRange() const { 
    return SourceRange(AtLoc, String->getLocEnd());
  }
  
  static bool classof(const Stmt *T) { 
    return T->getStmtClass() == ObjCStringLiteralClass; 
  }
  static bool classof(const ObjCStringLiteral *) { return true; }  
  
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};
  
/// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
/// and behavior as StringLiteral except that the string initializer is obtained
/// from ASTContext with the encoding type as an argument.
class ObjCEncodeExpr : public Expr {
  QualType EncType;
  SourceLocation AtLoc, RParenLoc;
public:
  ObjCEncodeExpr(QualType T, QualType ET, 
                 SourceLocation at, SourceLocation rp)
    : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {}
  
  explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}

  
  SourceLocation getAtLoc() const { return AtLoc; }
  void setAtLoc(SourceLocation L) { AtLoc = L; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
  
  QualType getEncodedType() const { return EncType; }
  void setEncodedType(QualType T) { EncType = T; }

  
  virtual SourceRange getSourceRange() const {
    return SourceRange(AtLoc, RParenLoc);
  }
  
  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ObjCEncodeExprClass;
  }
  static bool classof(const ObjCEncodeExpr *) { return true; }
  
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};

/// ObjCSelectorExpr used for @selector in Objective-C.
class ObjCSelectorExpr : public Expr {
  Selector SelName;
  SourceLocation AtLoc, RParenLoc;
public:
  ObjCSelectorExpr(QualType T, Selector selInfo,
                   SourceLocation at, SourceLocation rp)
  : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){}
  explicit ObjCSelectorExpr(EmptyShell Empty)
   : Expr(ObjCSelectorExprClass, Empty) {}

  Selector getSelector() const { return SelName; }
  void setSelector(Selector S) { SelName = S; }
  
  SourceLocation getAtLoc() const { return AtLoc; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setAtLoc(SourceLocation L) { AtLoc = L; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }

  virtual SourceRange getSourceRange() const {
    return SourceRange(AtLoc, RParenLoc);
  }
  
  /// getNumArgs - Return the number of actual arguments to this call.
  unsigned getNumArgs() const { return SelName.getNumArgs(); }
  
  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ObjCSelectorExprClass;
  }
  static bool classof(const ObjCSelectorExpr *) { return true; }
  
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};
  
/// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
/// as: @protocol(foo), as in:
///   obj conformsToProtocol:@protocol(foo)]
/// The return type is "Protocol*".
class ObjCProtocolExpr : public Expr {    
  ObjCProtocolDecl *Protocol;    
  SourceLocation AtLoc, RParenLoc;
public:
  ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
                   SourceLocation at, SourceLocation rp)
  : Expr(ObjCProtocolExprClass, T), Protocol(protocol),
    AtLoc(at), RParenLoc(rp) {}
  explicit ObjCProtocolExpr(EmptyShell Empty)
    : Expr(ObjCProtocolExprClass, Empty) {}

  ObjCProtocolDecl *getProtocol() const { return Protocol; }
  void setProtocol(ObjCProtocolDecl *P) { Protocol = P; }
    
  SourceLocation getAtLoc() const { return AtLoc; }
  SourceLocation getRParenLoc() const { return RParenLoc; }
  void setAtLoc(SourceLocation L) { AtLoc = L; }
  void setRParenLoc(SourceLocation L) { RParenLoc = L; }

  virtual SourceRange getSourceRange() const {
    return SourceRange(AtLoc, RParenLoc);
  }
        
  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ObjCProtocolExprClass;
  }
  static bool classof(const ObjCProtocolExpr *) { return true; }
    
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};

/// ObjCIvarRefExpr - A reference to an ObjC instance variable.
class ObjCIvarRefExpr : public Expr {
  class ObjCIvarDecl *D;
  SourceLocation Loc;
  Stmt *Base;
  bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
  bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
  
public:
  ObjCIvarRefExpr(ObjCIvarDecl *d,
                  QualType t, SourceLocation l, Expr *base=0, 
                  bool arrow = false, bool freeIvar = false) : 
    Expr(ObjCIvarRefExprClass, t), D(d),
    Loc(l), Base(base), IsArrow(arrow),
    IsFreeIvar(freeIvar) {}
  
  explicit ObjCIvarRefExpr(EmptyShell Empty)
    : Expr(ObjCIvarRefExprClass, Empty) {}

  ObjCIvarDecl *getDecl() { return D; }
  const ObjCIvarDecl *getDecl() const { return D; }
  void setDecl(ObjCIvarDecl *d) { D = d; }
  
  const Expr *getBase() const { return cast<Expr>(Base); }
  Expr *getBase() { return cast<Expr>(Base); }
  void setBase(Expr * base) { Base = base; }
  
  bool isArrow() const { return IsArrow; }
  bool isFreeIvar() const { return IsFreeIvar; }
  void setIsArrow(bool A) { IsArrow = A; }
  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
  
  SourceLocation getLocation() const { return Loc; }
  void setLocation(SourceLocation L) { Loc = L; }

  virtual SourceRange getSourceRange() const { 
    return isFreeIvar() ? SourceRange(Loc)
    : SourceRange(getBase()->getLocStart(), Loc); 
  }
  
  static bool classof(const Stmt *T) { 
    return T->getStmtClass() == ObjCIvarRefExprClass; 
  }
  static bool classof(const ObjCIvarRefExpr *) { return true; }
  
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};

/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
/// property.
///
class ObjCPropertyRefExpr : public Expr {
private:
  ObjCPropertyDecl *AsProperty;
  SourceLocation IdLoc;
  Stmt *Base;
public:
  ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 
                      SourceLocation l, Expr *base)
    : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) {
  }
  
  explicit ObjCPropertyRefExpr(EmptyShell Empty)
    : Expr(ObjCPropertyRefExprClass, Empty) {}

  ObjCPropertyDecl *getProperty() const { return AsProperty; }
  void setProperty(ObjCPropertyDecl *D) { AsProperty = D; }
  
  const Expr *getBase() const { return cast<Expr>(Base); }
  Expr *getBase() { return cast<Expr>(Base); }
  void setBase(Expr *base) { Base = base; }
  
  SourceLocation getLocation() const { return IdLoc; }
  void setLocation(SourceLocation L) { IdLoc = L; }

  virtual SourceRange getSourceRange() const {
    return SourceRange(getBase()->getLocStart(), IdLoc);
  }
  
  static bool classof(const Stmt *T) { 
    return T->getStmtClass() == ObjCPropertyRefExprClass; 
  }
  static bool classof(const ObjCPropertyRefExpr *) { return true; }
  
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};

/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties 
/// (i.e. methods following the property naming convention). KVC stands for
/// Key Value Encoding, a generic concept for accessing or setting a 'Key'
/// value for an object.
///
class ObjCKVCRefExpr : public Expr {
  ObjCMethodDecl *Setter;
  ObjCMethodDecl *Getter;
  SourceLocation Loc;
  // FIXME: Swizzle these into a single pointer.
  Stmt *Base;
  ObjCInterfaceDecl *ClassProp;
  SourceLocation ClassLoc;
    
public:
  ObjCKVCRefExpr(ObjCMethodDecl *getter,
                 QualType t, 
                 ObjCMethodDecl *setter,
                 SourceLocation l, Expr *base)
    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
      Getter(getter), Loc(l), Base(base), ClassProp(0),
      ClassLoc(SourceLocation()) {
    }
  ObjCKVCRefExpr(ObjCMethodDecl *getter,
                 QualType t, 
                 ObjCMethodDecl *setter,
                 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL)
    : Expr(ObjCKVCRefExprClass, t), Setter(setter),
      Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) {
    }
  explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){}

  ObjCMethodDecl *getGetterMethod() const { return Getter; }
  ObjCMethodDecl *getSetterMethod() const { return Setter; }
  ObjCInterfaceDecl *getClassProp() const { return ClassProp; }
  void setGetterMethod(ObjCMethodDecl *D) { Getter = D; }
  void setSetterMethod(ObjCMethodDecl *D) { Setter = D; }
  void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; }
  
  virtual SourceRange getSourceRange() const {
    if (Base)
      return SourceRange(getBase()->getLocStart(), Loc);
    return SourceRange(ClassLoc, Loc);
  }
  const Expr *getBase() const { return cast_or_null<Expr>(Base); }
  Expr *getBase() { return cast_or_null<Expr>(Base); }
  void setBase(Expr *base) { Base = base; }
    
  SourceLocation getLocation() const { return Loc; }
  void setLocation(SourceLocation L) { Loc = L; }
  SourceLocation getClassLoc() const { return ClassLoc; }
  void setClassLoc(SourceLocation L) { ClassLoc = L; }
    
  static bool classof(const Stmt *T) { 
    return T->getStmtClass() == ObjCKVCRefExprClass; 
  }
  static bool classof(const ObjCKVCRefExpr *) { return true; }
    
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};
  
class ObjCMessageExpr : public Expr {
  // SubExprs - The receiver and arguments of the message expression.
  Stmt **SubExprs;
  
  // NumArgs - The number of arguments (not including the receiver) to the
  //  message expression.
  unsigned NumArgs;
  
  // A unigue name for this message.
  Selector SelName;
  
  // A method prototype for this message (optional). 
  // FIXME: Since method decls contain the selector, and most messages have a
  // prototype, consider devising a scheme for unifying SelName/MethodProto.
  ObjCMethodDecl *MethodProto;

  SourceLocation LBracloc, RBracloc;

  // Constants for indexing into SubExprs.
  enum { RECEIVER=0, ARGS_START=1 };

  // Bit-swizzling flags.
  enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
  unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
  
public:
  /// This constructor is used to represent class messages where the
  /// ObjCInterfaceDecl* of the receiver is not known.
  ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo,
                  QualType retType, ObjCMethodDecl *methDecl,
                  SourceLocation LBrac, SourceLocation RBrac,
                  Expr **ArgExprs, unsigned NumArgs);

  /// This constructor is used to represent class messages where the
  /// ObjCInterfaceDecl* of the receiver is known.
  // FIXME: clsName should be typed to ObjCInterfaceType
  ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo,
                  QualType retType, ObjCMethodDecl *methDecl,
                  SourceLocation LBrac, SourceLocation RBrac,
                  Expr **ArgExprs, unsigned NumArgs);
  
  // constructor for instance messages.
  ObjCMessageExpr(Expr *receiver, Selector selInfo,
                  QualType retType, ObjCMethodDecl *methDecl,
                  SourceLocation LBrac, SourceLocation RBrac,
                  Expr **ArgExprs, unsigned NumArgs);
                  
  explicit ObjCMessageExpr(EmptyShell Empty)
    : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
  
  ~ObjCMessageExpr() {
    delete [] SubExprs;
  }
  
  /// getReceiver - Returns the receiver of the message expression.
  ///  This can be NULL if the message is for class methods.  For
  ///  class methods, use getClassName.
  /// FIXME: need to handle/detect 'super' usage within a class method.
  Expr *getReceiver() { 
    uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
    return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
  }  
  const Expr *getReceiver() const {
    return const_cast<ObjCMessageExpr*>(this)->getReceiver();
  }
  // FIXME: need setters for different receiver types.
  void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; }
  Selector getSelector() const { return SelName; }
  void setSelector(Selector S) { SelName = S; }
  
  const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
  ObjCMethodDecl *getMethodDecl() { return MethodProto; }
  void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
  
  typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
  
  /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
  ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
  ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
  ///  was available when this ObjCMessageExpr object was constructed.  
  ClassInfo getClassInfo() const; 
  void setClassInfo(const ClassInfo &C);
  
  /// getClassName - For class methods, this returns the invoked class,
  ///  and returns NULL otherwise.  For instance methods, use getReceiver.  
  IdentifierInfo *getClassName() const {
    return getClassInfo().second;
  }
  
  /// getNumArgs - Return the number of actual arguments to this call.
  unsigned getNumArgs() const { return NumArgs; }
  void setNumArgs(unsigned nArgs) { 
    NumArgs = nArgs; 
    // FIXME: should always allocate SubExprs via the ASTContext's
    // allocator.
    if (!SubExprs)
      SubExprs = new Stmt* [NumArgs + 1];
  }
  
  /// getArg - Return the specified argument.
  Expr *getArg(unsigned Arg) {
    assert(Arg < NumArgs && "Arg access out of range!");
    return cast<Expr>(SubExprs[Arg+ARGS_START]);
  }
  const Expr *getArg(unsigned Arg) const {
    assert(Arg < NumArgs && "Arg access out of range!");
    return cast<Expr>(SubExprs[Arg+ARGS_START]);
  }
  /// setArg - Set the specified argument.
  void setArg(unsigned Arg, Expr *ArgExpr) {
    assert(Arg < NumArgs && "Arg access out of range!");
    SubExprs[Arg+ARGS_START] = ArgExpr;
  }
  
  SourceLocation getLeftLoc() const { return LBracloc; }
  SourceLocation getRightLoc() const { return RBracloc; }

  void setLeftLoc(SourceLocation L) { LBracloc = L; }
  void setRightLoc(SourceLocation L) { RBracloc = L; }
  
  void setSourceRange(SourceRange R) {
    LBracloc = R.getBegin();
    RBracloc = R.getEnd();
  }
  virtual SourceRange getSourceRange() const {
    return SourceRange(LBracloc, RBracloc);
  }

  static bool classof(const Stmt *T) {
    return T->getStmtClass() == ObjCMessageExprClass;
  }
  static bool classof(const ObjCMessageExpr *) { return true; }
  
  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
  
  typedef ExprIterator arg_iterator;
  typedef ConstExprIterator const_arg_iterator;
  
  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
};

/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
/// which refers to the object on which the current method is executing.
class ObjCSuperExpr : public Expr {
  SourceLocation Loc;
public:
  ObjCSuperExpr(SourceLocation L, QualType Type) 
    : Expr(ObjCSuperExprClass, Type), Loc(L) { }
  explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}

  SourceLocation getLoc() const { return Loc; }
  void setLoc(SourceLocation L) { Loc = L; }
  
  virtual SourceRange getSourceRange() const { return SourceRange(Loc); }

  static bool classof(const Stmt *T) { 
    return T->getStmtClass() == ObjCSuperExprClass;
  }
  static bool classof(const ObjCSuperExpr *) { return true; }

  // Iterators
  virtual child_iterator child_begin();
  virtual child_iterator child_end();
};

}  // end namespace clang

#endif
OpenPOWER on IntegriCloud