]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h
Upgrade libcompiler_rt from revision 117047 to 132478.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / ExprObjC.h
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/DeclObjC.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/Basic/IdentifierTable.h"
20
21 namespace clang {
22   class IdentifierInfo;
23   class ASTContext;
24
25 /// ObjCStringLiteral, used for Objective-C string literals
26 /// i.e. @"foo".
27 class ObjCStringLiteral : public Expr {
28   Stmt *String;
29   SourceLocation AtLoc;
30 public:
31   ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
32     : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
33            false),
34       String(SL), AtLoc(L) {}
35   explicit ObjCStringLiteral(EmptyShell Empty)
36     : Expr(ObjCStringLiteralClass, Empty) {}
37
38   StringLiteral *getString() { return cast<StringLiteral>(String); }
39   const StringLiteral *getString() const { return cast<StringLiteral>(String); }
40   void setString(StringLiteral *S) { String = S; }
41
42   SourceLocation getAtLoc() const { return AtLoc; }
43   void setAtLoc(SourceLocation L) { AtLoc = L; }
44
45   SourceRange getSourceRange() const {
46     return SourceRange(AtLoc, String->getLocEnd());
47   }
48
49   static bool classof(const Stmt *T) {
50     return T->getStmtClass() == ObjCStringLiteralClass;
51   }
52   static bool classof(const ObjCStringLiteral *) { return true; }
53
54   // Iterators
55   child_range children() { return child_range(&String, &String+1); }
56 };
57
58 /// ObjCEncodeExpr, used for @encode in Objective-C.  @encode has the same type
59 /// and behavior as StringLiteral except that the string initializer is obtained
60 /// from ASTContext with the encoding type as an argument.
61 class ObjCEncodeExpr : public Expr {
62   TypeSourceInfo *EncodedType;
63   SourceLocation AtLoc, RParenLoc;
64 public:
65   ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
66                  SourceLocation at, SourceLocation rp)
67     : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
68            EncodedType->getType()->isDependentType(),
69            EncodedType->getType()->isDependentType(),
70            EncodedType->getType()->containsUnexpandedParameterPack()), 
71       EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
72
73   explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
74
75
76   SourceLocation getAtLoc() const { return AtLoc; }
77   void setAtLoc(SourceLocation L) { AtLoc = L; }
78   SourceLocation getRParenLoc() const { return RParenLoc; }
79   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
80
81   QualType getEncodedType() const { return EncodedType->getType(); }
82
83   TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
84   void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { 
85     EncodedType = EncType; 
86   }
87
88   SourceRange getSourceRange() const {
89     return SourceRange(AtLoc, RParenLoc);
90   }
91
92   static bool classof(const Stmt *T) {
93     return T->getStmtClass() == ObjCEncodeExprClass;
94   }
95   static bool classof(const ObjCEncodeExpr *) { return true; }
96
97   // Iterators
98   child_range children() { return child_range(); }
99 };
100
101 /// ObjCSelectorExpr used for @selector in Objective-C.
102 class ObjCSelectorExpr : public Expr {
103   Selector SelName;
104   SourceLocation AtLoc, RParenLoc;
105 public:
106   ObjCSelectorExpr(QualType T, Selector selInfo,
107                    SourceLocation at, SourceLocation rp)
108     : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, 
109            false),
110     SelName(selInfo), AtLoc(at), RParenLoc(rp){}
111   explicit ObjCSelectorExpr(EmptyShell Empty)
112    : Expr(ObjCSelectorExprClass, Empty) {}
113
114   Selector getSelector() const { return SelName; }
115   void setSelector(Selector S) { SelName = S; }
116
117   SourceLocation getAtLoc() const { return AtLoc; }
118   SourceLocation getRParenLoc() const { return RParenLoc; }
119   void setAtLoc(SourceLocation L) { AtLoc = L; }
120   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
121
122   SourceRange getSourceRange() const {
123     return SourceRange(AtLoc, RParenLoc);
124   }
125
126   /// getNumArgs - Return the number of actual arguments to this call.
127   unsigned getNumArgs() const { return SelName.getNumArgs(); }
128
129   static bool classof(const Stmt *T) {
130     return T->getStmtClass() == ObjCSelectorExprClass;
131   }
132   static bool classof(const ObjCSelectorExpr *) { return true; }
133
134   // Iterators
135   child_range children() { return child_range(); }
136 };
137
138 /// ObjCProtocolExpr used for protocol expression in Objective-C.  This is used
139 /// as: @protocol(foo), as in:
140 ///   obj conformsToProtocol:@protocol(foo)]
141 /// The return type is "Protocol*".
142 class ObjCProtocolExpr : public Expr {
143   ObjCProtocolDecl *TheProtocol;
144   SourceLocation AtLoc, RParenLoc;
145 public:
146   ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
147                    SourceLocation at, SourceLocation rp)
148     : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
149            false),
150       TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
151   explicit ObjCProtocolExpr(EmptyShell Empty)
152     : Expr(ObjCProtocolExprClass, Empty) {}
153
154   ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
155   void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
156
157   SourceLocation getAtLoc() const { return AtLoc; }
158   SourceLocation getRParenLoc() const { return RParenLoc; }
159   void setAtLoc(SourceLocation L) { AtLoc = L; }
160   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
161
162   SourceRange getSourceRange() const {
163     return SourceRange(AtLoc, RParenLoc);
164   }
165
166   static bool classof(const Stmt *T) {
167     return T->getStmtClass() == ObjCProtocolExprClass;
168   }
169   static bool classof(const ObjCProtocolExpr *) { return true; }
170
171   // Iterators
172   child_range children() { return child_range(); }
173 };
174
175 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
176 class ObjCIvarRefExpr : public Expr {
177   class ObjCIvarDecl *D;
178   SourceLocation Loc;
179   Stmt *Base;
180   bool IsArrow:1;      // True if this is "X->F", false if this is "X.F".
181   bool IsFreeIvar:1;   // True if ivar reference has no base (self assumed).
182
183 public:
184   ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
185                   SourceLocation l, Expr *base,
186                   bool arrow = false, bool freeIvar = false) :
187     Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
188          /*TypeDependent=*/false, base->isValueDependent(), 
189          base->containsUnexpandedParameterPack()), 
190     D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {}
191
192   explicit ObjCIvarRefExpr(EmptyShell Empty)
193     : Expr(ObjCIvarRefExprClass, Empty) {}
194
195   ObjCIvarDecl *getDecl() { return D; }
196   const ObjCIvarDecl *getDecl() const { return D; }
197   void setDecl(ObjCIvarDecl *d) { D = d; }
198
199   const Expr *getBase() const { return cast<Expr>(Base); }
200   Expr *getBase() { return cast<Expr>(Base); }
201   void setBase(Expr * base) { Base = base; }
202
203   bool isArrow() const { return IsArrow; }
204   bool isFreeIvar() const { return IsFreeIvar; }
205   void setIsArrow(bool A) { IsArrow = A; }
206   void setIsFreeIvar(bool A) { IsFreeIvar = A; }
207
208   SourceLocation getLocation() const { return Loc; }
209   void setLocation(SourceLocation L) { Loc = L; }
210
211   SourceRange getSourceRange() const {
212     return isFreeIvar() ? SourceRange(Loc)
213     : SourceRange(getBase()->getLocStart(), Loc);
214   }
215
216   static bool classof(const Stmt *T) {
217     return T->getStmtClass() == ObjCIvarRefExprClass;
218   }
219   static bool classof(const ObjCIvarRefExpr *) { return true; }
220
221   // Iterators
222   child_range children() { return child_range(&Base, &Base+1); }
223 };
224
225 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
226 /// property.
227 ///
228 class ObjCPropertyRefExpr : public Expr {
229 private:
230   /// If the bool is true, this is an implicit property reference; the
231   /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
232   /// if the bool is false, this is an explicit property reference;
233   /// the pointer is an ObjCPropertyDecl and Setter is always null.
234   llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
235   ObjCMethodDecl *Setter;
236
237   SourceLocation IdLoc;
238   
239   /// \brief When the receiver in property access is 'super', this is
240   /// the location of the 'super' keyword.  When it's an interface,
241   /// this is that interface.
242   SourceLocation ReceiverLoc;
243   llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
244   
245 public:
246   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
247                       ExprValueKind VK, ExprObjectKind OK,
248                       SourceLocation l, Expr *base)
249     : Expr(ObjCPropertyRefExprClass, t, VK, OK,
250            /*TypeDependent=*/false, base->isValueDependent(),
251            base->containsUnexpandedParameterPack()),
252       PropertyOrGetter(PD, false), Setter(0),
253       IdLoc(l), ReceiverLoc(), Receiver(base) {
254   }
255   
256   ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
257                       ExprValueKind VK, ExprObjectKind OK,
258                       SourceLocation l, SourceLocation sl, QualType st)
259     : Expr(ObjCPropertyRefExprClass, t, VK, OK,
260            /*TypeDependent=*/false, false, 
261            st->containsUnexpandedParameterPack()),
262       PropertyOrGetter(PD, false), Setter(0),
263       IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
264   }
265
266   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
267                       QualType T, ExprValueKind VK, ExprObjectKind OK,
268                       SourceLocation IdLoc, Expr *Base)
269     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
270            Base->isValueDependent(), 
271            Base->containsUnexpandedParameterPack()),
272       PropertyOrGetter(Getter, true), Setter(Setter),
273       IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
274   }
275
276   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
277                       QualType T, ExprValueKind VK, ExprObjectKind OK,
278                       SourceLocation IdLoc,
279                       SourceLocation SuperLoc, QualType SuperTy)
280     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
281       PropertyOrGetter(Getter, true), Setter(Setter),
282       IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
283   }
284
285   ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
286                       QualType T, ExprValueKind VK, ExprObjectKind OK,
287                       SourceLocation IdLoc,
288                       SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
289     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
290       PropertyOrGetter(Getter, true), Setter(Setter),
291       IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
292   }
293
294   explicit ObjCPropertyRefExpr(EmptyShell Empty)
295     : Expr(ObjCPropertyRefExprClass, Empty) {}
296
297   bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
298   bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
299
300   ObjCPropertyDecl *getExplicitProperty() const {
301     assert(!isImplicitProperty());
302     return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
303   }
304
305   ObjCMethodDecl *getImplicitPropertyGetter() const {
306     assert(isImplicitProperty());
307     return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
308   }
309
310   ObjCMethodDecl *getImplicitPropertySetter() const {
311     assert(isImplicitProperty());
312     return Setter;
313   }
314
315   Selector getGetterSelector() const {
316     if (isImplicitProperty())
317       return getImplicitPropertyGetter()->getSelector();
318     return getExplicitProperty()->getGetterName();
319   }
320
321   Selector getSetterSelector() const {
322     if (isImplicitProperty())
323       return getImplicitPropertySetter()->getSelector();
324     return getExplicitProperty()->getSetterName();
325   }
326
327   const Expr *getBase() const { 
328     return cast<Expr>(Receiver.get<Stmt*>()); 
329   }
330   Expr *getBase() { 
331     return cast<Expr>(Receiver.get<Stmt*>()); 
332   }
333
334   SourceLocation getLocation() const { return IdLoc; }
335   
336   SourceLocation getReceiverLocation() const { return ReceiverLoc; }
337   QualType getSuperReceiverType() const { 
338     return QualType(Receiver.get<const Type*>(), 0); 
339   }
340   QualType getGetterResultType() const {
341     QualType ResultType;
342     if (isExplicitProperty()) {
343       const ObjCPropertyDecl *PDecl = getExplicitProperty();
344       if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
345         ResultType = Getter->getResultType();
346       else
347         ResultType = getType();
348     } else {
349       const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
350       ResultType = Getter->getResultType(); // with reference!
351     }
352     return ResultType;
353   }
354   
355   QualType getSetterArgType() const {
356     QualType ArgType;
357     if (isImplicitProperty()) {
358       const ObjCMethodDecl *Setter = getImplicitPropertySetter();
359       ObjCMethodDecl::param_iterator P = Setter->param_begin(); 
360       ArgType = (*P)->getType();
361     } else {
362       if (ObjCPropertyDecl *PDecl = getExplicitProperty())
363         if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
364           ObjCMethodDecl::param_iterator P = Setter->param_begin(); 
365           ArgType = (*P)->getType();
366         }
367       if (ArgType.isNull())
368         ArgType = getType();
369     }
370     return ArgType;
371   }
372   
373   ObjCInterfaceDecl *getClassReceiver() const {
374     return Receiver.get<ObjCInterfaceDecl*>();
375   }
376   bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
377   bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
378   bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
379
380   SourceRange getSourceRange() const {
381     return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
382                                            : getReceiverLocation()), 
383                        IdLoc);
384   }
385
386   static bool classof(const Stmt *T) {
387     return T->getStmtClass() == ObjCPropertyRefExprClass;
388   }
389   static bool classof(const ObjCPropertyRefExpr *) { return true; }
390
391   // Iterators
392   child_range children() {
393     if (Receiver.is<Stmt*>()) {
394       Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
395       return child_range(begin, begin+1);
396     }
397     return child_range();
398   }
399
400 private:
401   friend class ASTStmtReader;
402   void setExplicitProperty(ObjCPropertyDecl *D) {
403     PropertyOrGetter.setPointer(D);
404     PropertyOrGetter.setInt(false);
405     Setter = 0;
406   }
407   void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) {
408     PropertyOrGetter.setPointer(Getter);
409     PropertyOrGetter.setInt(true);
410     this->Setter = Setter;
411   }
412   void setBase(Expr *Base) { Receiver = Base; }
413   void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
414   void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
415
416   void setLocation(SourceLocation L) { IdLoc = L; }
417   void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
418 };
419
420 /// \brief An expression that sends a message to the given Objective-C
421 /// object or class.
422 ///
423 /// The following contains two message send expressions:
424 ///
425 /// \code
426 ///   [[NSString alloc] initWithString:@"Hello"]
427 /// \endcode
428 ///
429 /// The innermost message send invokes the "alloc" class method on the
430 /// NSString class, while the outermost message send invokes the
431 /// "initWithString" instance method on the object returned from
432 /// NSString's "alloc". In all, an Objective-C message send can take
433 /// on four different (although related) forms:
434 ///
435 ///   1. Send to an object instance.
436 ///   2. Send to a class.
437 ///   3. Send to the superclass instance of the current class.
438 ///   4. Send to the superclass of the current class.
439 ///
440 /// All four kinds of message sends are modeled by the ObjCMessageExpr
441 /// class, and can be distinguished via \c getReceiverKind(). Example:
442 ///
443 class ObjCMessageExpr : public Expr {
444   /// \brief The number of arguments in the message send, not
445   /// including the receiver.
446   unsigned NumArgs : 16;
447
448   /// \brief The kind of message send this is, which is one of the
449   /// ReceiverKind values.
450   ///
451   /// We pad this out to a byte to avoid excessive masking and shifting.
452   unsigned Kind : 8;
453
454   /// \brief Whether we have an actual method prototype in \c
455   /// SelectorOrMethod.
456   ///
457   /// When non-zero, we have a method declaration; otherwise, we just
458   /// have a selector.
459   unsigned HasMethod : 8;
460
461   /// \brief When the message expression is a send to 'super', this is
462   /// the location of the 'super' keyword.
463   SourceLocation SuperLoc;
464
465   /// \brief Stores either the selector that this message is sending
466   /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
467   /// referring to the method that we type-checked against.
468   uintptr_t SelectorOrMethod;
469
470   /// \brief Location of the selector.
471   SourceLocation SelectorLoc;
472
473   /// \brief The source locations of the open and close square
474   /// brackets ('[' and ']', respectively).
475   SourceLocation LBracLoc, RBracLoc;
476
477   ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
478     : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), 
479       HasMethod(0), SelectorOrMethod(0) { }
480
481   ObjCMessageExpr(QualType T, ExprValueKind VK,
482                   SourceLocation LBracLoc,
483                   SourceLocation SuperLoc,
484                   bool IsInstanceSuper,
485                   QualType SuperType,
486                   Selector Sel, 
487                   SourceLocation SelLoc,
488                   ObjCMethodDecl *Method,
489                   Expr **Args, unsigned NumArgs,
490                   SourceLocation RBracLoc);
491   ObjCMessageExpr(QualType T, ExprValueKind VK,
492                   SourceLocation LBracLoc,
493                   TypeSourceInfo *Receiver,
494                   Selector Sel, 
495                   SourceLocation SelLoc,
496                   ObjCMethodDecl *Method,
497                   Expr **Args, unsigned NumArgs,
498                   SourceLocation RBracLoc);
499   ObjCMessageExpr(QualType T, ExprValueKind VK,
500                   SourceLocation LBracLoc,
501                   Expr *Receiver,
502                   Selector Sel, 
503                   SourceLocation SelLoc,
504                   ObjCMethodDecl *Method,
505                   Expr **Args, unsigned NumArgs,
506                   SourceLocation RBracLoc);
507
508   /// \brief Retrieve the pointer value of the message receiver.
509   void *getReceiverPointer() const {
510     return *const_cast<void **>(
511                              reinterpret_cast<const void * const*>(this + 1));
512   }
513
514   /// \brief Set the pointer value of the message receiver.
515   void setReceiverPointer(void *Value) {
516     *reinterpret_cast<void **>(this + 1) = Value;
517   }
518
519 public:
520   /// \brief The kind of receiver this message is sending to.
521   enum ReceiverKind {
522     /// \brief The receiver is a class.
523     Class = 0,
524     /// \brief The receiver is an object instance.
525     Instance,
526     /// \brief The receiver is a superclass.
527     SuperClass,
528     /// \brief The receiver is the instance of the superclass object.
529     SuperInstance
530   };
531
532   /// \brief Create a message send to super.
533   ///
534   /// \param Context The ASTContext in which this expression will be created.
535   ///
536   /// \param T The result type of this message.
537   ///
538   /// \param VK The value kind of this message.  A message returning
539   /// a l-value or r-value reference will be an l-value or x-value,
540   /// respectively.
541   ///
542   /// \param LBrac The location of the open square bracket '['.
543   ///
544   /// \param SuperLoc The location of the "super" keyword.
545   ///
546   /// \param IsInstanceSuper Whether this is an instance "super"
547   /// message (otherwise, it's a class "super" message).
548   ///
549   /// \param Sel The selector used to determine which method gets called.
550   ///
551   /// \param Method The Objective-C method against which this message
552   /// send was type-checked. May be NULL.
553   ///
554   /// \param Args The message send arguments.
555   ///
556   /// \param NumArgs The number of arguments.
557   ///
558   /// \param RBracLoc The location of the closing square bracket ']'.
559   static ObjCMessageExpr *Create(ASTContext &Context, QualType T, 
560                                  ExprValueKind VK,
561                                  SourceLocation LBracLoc,
562                                  SourceLocation SuperLoc,
563                                  bool IsInstanceSuper,
564                                  QualType SuperType,
565                                  Selector Sel, 
566                                  SourceLocation SelLoc,
567                                  ObjCMethodDecl *Method,
568                                  Expr **Args, unsigned NumArgs,
569                                  SourceLocation RBracLoc);
570
571   /// \brief Create a class message send.
572   ///
573   /// \param Context The ASTContext in which this expression will be created.
574   ///
575   /// \param T The result type of this message.
576   ///
577   /// \param VK The value kind of this message.  A message returning
578   /// a l-value or r-value reference will be an l-value or x-value,
579   /// respectively.
580   ///
581   /// \param LBrac The location of the open square bracket '['.
582   ///
583   /// \param Receiver The type of the receiver, including
584   /// source-location information.
585   ///
586   /// \param Sel The selector used to determine which method gets called.
587   ///
588   /// \param Method The Objective-C method against which this message
589   /// send was type-checked. May be NULL.
590   ///
591   /// \param Args The message send arguments.
592   ///
593   /// \param NumArgs The number of arguments.
594   ///
595   /// \param RBracLoc The location of the closing square bracket ']'.
596   static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
597                                  ExprValueKind VK,
598                                  SourceLocation LBracLoc,
599                                  TypeSourceInfo *Receiver,
600                                  Selector Sel, 
601                                  SourceLocation SelLoc,
602                                  ObjCMethodDecl *Method,
603                                  Expr **Args, unsigned NumArgs,
604                                  SourceLocation RBracLoc);
605
606   /// \brief Create an instance message send.
607   ///
608   /// \param Context The ASTContext in which this expression will be created.
609   ///
610   /// \param T The result type of this message.
611   ///
612   /// \param VK The value kind of this message.  A message returning
613   /// a l-value or r-value reference will be an l-value or x-value,
614   /// respectively.
615   ///
616   /// \param LBrac The location of the open square bracket '['.
617   ///
618   /// \param Receiver The expression used to produce the object that
619   /// will receive this message.
620   ///
621   /// \param Sel The selector used to determine which method gets called.
622   ///
623   /// \param Method The Objective-C method against which this message
624   /// send was type-checked. May be NULL.
625   ///
626   /// \param Args The message send arguments.
627   ///
628   /// \param NumArgs The number of arguments.
629   ///
630   /// \param RBracLoc The location of the closing square bracket ']'.
631   static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
632                                  ExprValueKind VK,
633                                  SourceLocation LBracLoc,
634                                  Expr *Receiver,
635                                  Selector Sel, 
636                                  SourceLocation SelLoc,
637                                  ObjCMethodDecl *Method,
638                                  Expr **Args, unsigned NumArgs,
639                                  SourceLocation RBracLoc);
640
641   /// \brief Create an empty Objective-C message expression, to be
642   /// filled in by subsequent calls.
643   ///
644   /// \param Context The context in which the message send will be created.
645   ///
646   /// \param NumArgs The number of message arguments, not including
647   /// the receiver.
648   static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
649
650   /// \brief Determine the kind of receiver that this message is being
651   /// sent to.
652   ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
653
654   /// \brief Source range of the receiver.
655   SourceRange getReceiverRange() const;
656
657   /// \brief Determine whether this is an instance message to either a
658   /// computed object or to super.
659   bool isInstanceMessage() const {
660     return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
661   }
662
663   /// \brief Determine whether this is an class message to either a
664   /// specified class or to super.
665   bool isClassMessage() const {
666     return getReceiverKind() == Class || getReceiverKind() == SuperClass;
667   }
668
669   /// \brief Returns the receiver of an instance message.
670   ///
671   /// \brief Returns the object expression for an instance message, or
672   /// NULL for a message that is not an instance message.
673   Expr *getInstanceReceiver() {
674     if (getReceiverKind() == Instance)
675       return static_cast<Expr *>(getReceiverPointer());
676
677     return 0;
678   }
679   const Expr *getInstanceReceiver() const {
680     return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
681   }
682
683   /// \brief Turn this message send into an instance message that
684   /// computes the receiver object with the given expression.
685   void setInstanceReceiver(Expr *rec) { 
686     Kind = Instance;
687     setReceiverPointer(rec);
688   }
689   
690   /// \brief Returns the type of a class message send, or NULL if the
691   /// message is not a class message.
692   QualType getClassReceiver() const { 
693     if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
694       return TSInfo->getType();
695
696     return QualType();
697   }
698
699   /// \brief Returns a type-source information of a class message
700   /// send, or NULL if the message is not a class message.
701   TypeSourceInfo *getClassReceiverTypeInfo() const {
702     if (getReceiverKind() == Class)
703       return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
704     return 0;
705   }
706
707   void setClassReceiver(TypeSourceInfo *TSInfo) {
708     Kind = Class;
709     setReceiverPointer(TSInfo);
710   }
711
712   /// \brief Retrieve the location of the 'super' keyword for a class
713   /// or instance message to 'super', otherwise an invalid source location.
714   SourceLocation getSuperLoc() const { 
715     if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
716       return SuperLoc;
717
718     return SourceLocation();
719   }
720
721   /// \brief Retrieve the Objective-C interface to which this message
722   /// is being directed, if known.
723   ///
724   /// This routine cross-cuts all of the different kinds of message
725   /// sends to determine what the underlying (statically known) type
726   /// of the receiver will be; use \c getReceiverKind() to determine
727   /// whether the message is a class or an instance method, whether it
728   /// is a send to super or not, etc.
729   ///
730   /// \returns The Objective-C interface if known, otherwise NULL.
731   ObjCInterfaceDecl *getReceiverInterface() const;
732
733   /// \brief Retrieve the type referred to by 'super'. 
734   ///
735   /// The returned type will either be an ObjCInterfaceType (for an
736   /// class message to super) or an ObjCObjectPointerType that refers
737   /// to a class (for an instance message to super);
738   QualType getSuperType() const {
739     if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
740       return QualType::getFromOpaquePtr(getReceiverPointer());
741
742     return QualType();
743   }
744
745   void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
746     Kind = IsInstanceSuper? SuperInstance : SuperClass;
747     SuperLoc = Loc;
748     setReceiverPointer(T.getAsOpaquePtr());
749   }
750
751   Selector getSelector() const;
752
753   void setSelector(Selector S) { 
754     HasMethod = false;
755     SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
756   }
757
758   const ObjCMethodDecl *getMethodDecl() const { 
759     if (HasMethod)
760       return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
761
762     return 0;
763   }
764
765   ObjCMethodDecl *getMethodDecl() { 
766     if (HasMethod)
767       return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
768
769     return 0;
770   }
771
772   void setMethodDecl(ObjCMethodDecl *MD) { 
773     HasMethod = true;
774     SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
775   }
776
777   ObjCMethodFamily getMethodFamily() const {
778     if (HasMethod) return getMethodDecl()->getMethodFamily();
779     return getSelector().getMethodFamily();
780   }
781
782   /// \brief Return the number of actual arguments in this message,
783   /// not counting the receiver.
784   unsigned getNumArgs() const { return NumArgs; }
785
786   /// \brief Retrieve the arguments to this message, not including the
787   /// receiver.
788   Expr **getArgs() {
789     return reinterpret_cast<Expr **>(this + 1) + 1;
790   }
791   const Expr * const *getArgs() const {
792     return reinterpret_cast<const Expr * const *>(this + 1) + 1;
793   }
794
795   /// getArg - Return the specified argument.
796   Expr *getArg(unsigned Arg) {
797     assert(Arg < NumArgs && "Arg access out of range!");
798     return cast<Expr>(getArgs()[Arg]);
799   }
800   const Expr *getArg(unsigned Arg) const {
801     assert(Arg < NumArgs && "Arg access out of range!");
802     return cast<Expr>(getArgs()[Arg]);
803   }
804   /// setArg - Set the specified argument.
805   void setArg(unsigned Arg, Expr *ArgExpr) {
806     assert(Arg < NumArgs && "Arg access out of range!");
807     getArgs()[Arg] = ArgExpr;
808   }
809
810   SourceLocation getLeftLoc() const { return LBracLoc; }
811   SourceLocation getRightLoc() const { return RBracLoc; }
812   SourceLocation getSelectorLoc() const { return SelectorLoc; }
813
814   void setSourceRange(SourceRange R) {
815     LBracLoc = R.getBegin();
816     RBracLoc = R.getEnd();
817   }
818   SourceRange getSourceRange() const {
819     return SourceRange(LBracLoc, RBracLoc);
820   }
821
822   static bool classof(const Stmt *T) {
823     return T->getStmtClass() == ObjCMessageExprClass;
824   }
825   static bool classof(const ObjCMessageExpr *) { return true; }
826
827   // Iterators
828   child_range children();
829
830   typedef ExprIterator arg_iterator;
831   typedef ConstExprIterator const_arg_iterator;
832
833   arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
834   arg_iterator arg_end()   { 
835     return reinterpret_cast<Stmt **>(getArgs() + NumArgs); 
836   }
837   const_arg_iterator arg_begin() const { 
838     return reinterpret_cast<Stmt const * const*>(getArgs()); 
839   }
840   const_arg_iterator arg_end() const { 
841     return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); 
842   }
843
844   friend class ASTStmtReader;
845   friend class ASTStmtWriter;
846 };
847
848 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
849 /// (similar in spirit to MemberExpr).
850 class ObjCIsaExpr : public Expr {
851   /// Base - the expression for the base object pointer.
852   Stmt *Base;
853
854   /// IsaMemberLoc - This is the location of the 'isa'.
855   SourceLocation IsaMemberLoc;
856
857   /// IsArrow - True if this is "X->F", false if this is "X.F".
858   bool IsArrow;
859 public:
860   ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
861     : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
862            /*TypeDependent=*/false, base->isValueDependent(),
863            /*ContainsUnexpandedParameterPack=*/false),
864       Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
865
866   /// \brief Build an empty expression.
867   explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
868
869   void setBase(Expr *E) { Base = E; }
870   Expr *getBase() const { return cast<Expr>(Base); }
871
872   bool isArrow() const { return IsArrow; }
873   void setArrow(bool A) { IsArrow = A; }
874
875   /// getMemberLoc - Return the location of the "member", in X->F, it is the
876   /// location of 'F'.
877   SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
878   void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
879
880   SourceRange getSourceRange() const {
881     return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
882   }
883
884   SourceLocation getExprLoc() const { return IsaMemberLoc; }
885
886   static bool classof(const Stmt *T) {
887     return T->getStmtClass() == ObjCIsaExprClass;
888   }
889   static bool classof(const ObjCIsaExpr *) { return true; }
890
891   // Iterators
892   child_range children() { return child_range(&Base, &Base+1); }
893 };
894
895 }  // end namespace clang
896
897 #endif