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