1 //===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ExprObjC interface and subclasses.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_EXPROBJC_H
15 #define LLVM_CLANG_AST_EXPROBJC_H
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/Basic/IdentifierTable.h"
25 /// ObjCStringLiteral, used for Objective-C string literals
27 class ObjCStringLiteral
: public Expr
{
31 ObjCStringLiteral(StringLiteral
*SL
, QualType T
, SourceLocation L
)
32 : Expr(ObjCStringLiteralClass
, T
, VK_RValue
, OK_Ordinary
, false, false),
33 String(SL
), AtLoc(L
) {}
34 explicit ObjCStringLiteral(EmptyShell Empty
)
35 : Expr(ObjCStringLiteralClass
, Empty
) {}
37 StringLiteral
*getString() { return cast
<StringLiteral
>(String
); }
38 const StringLiteral
*getString() const { return cast
<StringLiteral
>(String
); }
39 void setString(StringLiteral
*S
) { String
= S
; }
41 SourceLocation
getAtLoc() const { return AtLoc
; }
42 void setAtLoc(SourceLocation L
) { AtLoc
= L
; }
44 virtual SourceRange
getSourceRange() const {
45 return SourceRange(AtLoc
, String
->getLocEnd());
48 static bool classof(const Stmt
*T
) {
49 return T
->getStmtClass() == ObjCStringLiteralClass
;
51 static bool classof(const ObjCStringLiteral
*) { return true; }
54 virtual child_iterator
child_begin();
55 virtual child_iterator
child_end();
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
;
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(EncodedType
), AtLoc(at
), RParenLoc(rp
) {}
72 explicit ObjCEncodeExpr(EmptyShell Empty
) : Expr(ObjCEncodeExprClass
, Empty
){}
75 SourceLocation
getAtLoc() const { return AtLoc
; }
76 void setAtLoc(SourceLocation L
) { AtLoc
= L
; }
77 SourceLocation
getRParenLoc() const { return RParenLoc
; }
78 void setRParenLoc(SourceLocation L
) { RParenLoc
= L
; }
80 QualType
getEncodedType() const { return EncodedType
->getType(); }
82 TypeSourceInfo
*getEncodedTypeSourceInfo() const { return EncodedType
; }
83 void setEncodedTypeSourceInfo(TypeSourceInfo
*EncType
) {
84 EncodedType
= EncType
;
87 virtual SourceRange
getSourceRange() const {
88 return SourceRange(AtLoc
, RParenLoc
);
91 static bool classof(const Stmt
*T
) {
92 return T
->getStmtClass() == ObjCEncodeExprClass
;
94 static bool classof(const ObjCEncodeExpr
*) { return true; }
97 virtual child_iterator
child_begin();
98 virtual child_iterator
child_end();
101 /// ObjCSelectorExpr used for @selector in Objective-C.
102 class ObjCSelectorExpr
: public Expr
{
104 SourceLocation AtLoc
, RParenLoc
;
106 ObjCSelectorExpr(QualType T
, Selector selInfo
,
107 SourceLocation at
, SourceLocation rp
)
108 : Expr(ObjCSelectorExprClass
, T
, VK_RValue
, OK_Ordinary
, false, false),
109 SelName(selInfo
), AtLoc(at
), RParenLoc(rp
){}
110 explicit ObjCSelectorExpr(EmptyShell Empty
)
111 : Expr(ObjCSelectorExprClass
, Empty
) {}
113 Selector
getSelector() const { return SelName
; }
114 void setSelector(Selector S
) { SelName
= S
; }
116 SourceLocation
getAtLoc() const { return AtLoc
; }
117 SourceLocation
getRParenLoc() const { return RParenLoc
; }
118 void setAtLoc(SourceLocation L
) { AtLoc
= L
; }
119 void setRParenLoc(SourceLocation L
) { RParenLoc
= L
; }
121 virtual SourceRange
getSourceRange() const {
122 return SourceRange(AtLoc
, RParenLoc
);
125 /// getNumArgs - Return the number of actual arguments to this call.
126 unsigned getNumArgs() const { return SelName
.getNumArgs(); }
128 static bool classof(const Stmt
*T
) {
129 return T
->getStmtClass() == ObjCSelectorExprClass
;
131 static bool classof(const ObjCSelectorExpr
*) { return true; }
134 virtual child_iterator
child_begin();
135 virtual child_iterator
child_end();
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
;
146 ObjCProtocolExpr(QualType T
, ObjCProtocolDecl
*protocol
,
147 SourceLocation at
, SourceLocation rp
)
148 : Expr(ObjCProtocolExprClass
, T
, VK_RValue
, OK_Ordinary
, false, false),
149 TheProtocol(protocol
), AtLoc(at
), RParenLoc(rp
) {}
150 explicit ObjCProtocolExpr(EmptyShell Empty
)
151 : Expr(ObjCProtocolExprClass
, Empty
) {}
153 ObjCProtocolDecl
*getProtocol() const { return TheProtocol
; }
154 void setProtocol(ObjCProtocolDecl
*P
) { TheProtocol
= P
; }
156 SourceLocation
getAtLoc() const { return AtLoc
; }
157 SourceLocation
getRParenLoc() const { return RParenLoc
; }
158 void setAtLoc(SourceLocation L
) { AtLoc
= L
; }
159 void setRParenLoc(SourceLocation L
) { RParenLoc
= L
; }
161 virtual SourceRange
getSourceRange() const {
162 return SourceRange(AtLoc
, RParenLoc
);
165 static bool classof(const Stmt
*T
) {
166 return T
->getStmtClass() == ObjCProtocolExprClass
;
168 static bool classof(const ObjCProtocolExpr
*) { return true; }
171 virtual child_iterator
child_begin();
172 virtual child_iterator
child_end();
175 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
176 class ObjCIvarRefExpr
: public Expr
{
177 class ObjCIvarDecl
*D
;
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).
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()), D(d
),
189 Loc(l
), Base(base
), IsArrow(arrow
),
190 IsFreeIvar(freeIvar
) {}
192 explicit ObjCIvarRefExpr(EmptyShell Empty
)
193 : Expr(ObjCIvarRefExprClass
, Empty
) {}
195 ObjCIvarDecl
*getDecl() { return D
; }
196 const ObjCIvarDecl
*getDecl() const { return D
; }
197 void setDecl(ObjCIvarDecl
*d
) { D
= d
; }
199 const Expr
*getBase() const { return cast
<Expr
>(Base
); }
200 Expr
*getBase() { return cast
<Expr
>(Base
); }
201 void setBase(Expr
* base
) { Base
= base
; }
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
; }
208 SourceLocation
getLocation() const { return Loc
; }
209 void setLocation(SourceLocation L
) { Loc
= L
; }
211 virtual SourceRange
getSourceRange() const {
212 return isFreeIvar() ? SourceRange(Loc
)
213 : SourceRange(getBase()->getLocStart(), Loc
);
216 static bool classof(const Stmt
*T
) {
217 return T
->getStmtClass() == ObjCIvarRefExprClass
;
219 static bool classof(const ObjCIvarRefExpr
*) { return true; }
222 virtual child_iterator
child_begin();
223 virtual child_iterator
child_end();
226 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
229 class ObjCPropertyRefExpr
: public Expr
{
231 /// If the bool is true, this is an implicit property reference; the
232 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
233 /// if the bool is false, this is an explicit property reference;
234 /// the pointer is an ObjCPropertyDecl and Setter is always null.
235 llvm::PointerIntPair
<NamedDecl
*, 1, bool> PropertyOrGetter
;
236 ObjCMethodDecl
*Setter
;
238 SourceLocation IdLoc
;
240 /// \brief When the receiver in property access is 'super', this is
241 /// the location of the 'super' keyword. When it's an interface,
242 /// this is that interface.
243 SourceLocation ReceiverLoc
;
244 llvm::PointerUnion3
<Stmt
*, Type
*, ObjCInterfaceDecl
*> Receiver
;
247 ObjCPropertyRefExpr(ObjCPropertyDecl
*PD
, QualType t
,
248 ExprValueKind VK
, ExprObjectKind OK
,
249 SourceLocation l
, Expr
*base
)
250 : Expr(ObjCPropertyRefExprClass
, t
, VK
, OK
,
251 /*TypeDependent=*/false, base
->isValueDependent()),
252 PropertyOrGetter(PD
, false), Setter(0),
253 IdLoc(l
), ReceiverLoc(), Receiver(base
) {
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 PropertyOrGetter(PD
, false), Setter(0),
262 IdLoc(l
), ReceiverLoc(sl
), Receiver(st
.getTypePtr()) {
265 ObjCPropertyRefExpr(ObjCMethodDecl
*Getter
, ObjCMethodDecl
*Setter
,
266 QualType T
, ExprValueKind VK
, ExprObjectKind OK
,
267 SourceLocation IdLoc
, Expr
*Base
)
268 : Expr(ObjCPropertyRefExprClass
, T
, VK
, OK
, false,
269 Base
->isValueDependent()),
270 PropertyOrGetter(Getter
, true), Setter(Setter
),
271 IdLoc(IdLoc
), ReceiverLoc(), Receiver(Base
) {
274 ObjCPropertyRefExpr(ObjCMethodDecl
*Getter
, ObjCMethodDecl
*Setter
,
275 QualType T
, ExprValueKind VK
, ExprObjectKind OK
,
276 SourceLocation IdLoc
,
277 SourceLocation SuperLoc
, QualType SuperTy
)
278 : Expr(ObjCPropertyRefExprClass
, T
, VK
, OK
, false, false),
279 PropertyOrGetter(Getter
, true), Setter(Setter
),
280 IdLoc(IdLoc
), ReceiverLoc(SuperLoc
), Receiver(SuperTy
.getTypePtr()) {
283 ObjCPropertyRefExpr(ObjCMethodDecl
*Getter
, ObjCMethodDecl
*Setter
,
284 QualType T
, ExprValueKind VK
, ExprObjectKind OK
,
285 SourceLocation IdLoc
,
286 SourceLocation ReceiverLoc
, ObjCInterfaceDecl
*Receiver
)
287 : Expr(ObjCPropertyRefExprClass
, T
, VK
, OK
, false, false),
288 PropertyOrGetter(Getter
, true), Setter(Setter
),
289 IdLoc(IdLoc
), ReceiverLoc(ReceiverLoc
), Receiver(Receiver
) {
292 explicit ObjCPropertyRefExpr(EmptyShell Empty
)
293 : Expr(ObjCPropertyRefExprClass
, Empty
) {}
295 bool isImplicitProperty() const { return PropertyOrGetter
.getInt(); }
296 bool isExplicitProperty() const { return !PropertyOrGetter
.getInt(); }
298 ObjCPropertyDecl
*getExplicitProperty() const {
299 assert(!isImplicitProperty());
300 return cast
<ObjCPropertyDecl
>(PropertyOrGetter
.getPointer());
303 ObjCMethodDecl
*getImplicitPropertyGetter() const {
304 assert(isImplicitProperty());
305 return cast_or_null
<ObjCMethodDecl
>(PropertyOrGetter
.getPointer());
308 ObjCMethodDecl
*getImplicitPropertySetter() const {
309 assert(isImplicitProperty());
313 Selector
getGetterSelector() const {
314 if (isImplicitProperty())
315 return getImplicitPropertyGetter()->getSelector();
316 return getExplicitProperty()->getGetterName();
319 Selector
getSetterSelector() const {
320 if (isImplicitProperty())
321 return getImplicitPropertySetter()->getSelector();
322 return getExplicitProperty()->getSetterName();
325 const Expr
*getBase() const {
326 return cast
<Expr
>(Receiver
.get
<Stmt
*>());
329 return cast
<Expr
>(Receiver
.get
<Stmt
*>());
332 SourceLocation
getLocation() const { return IdLoc
; }
334 SourceLocation
getReceiverLocation() const { return ReceiverLoc
; }
335 QualType
getSuperReceiverType() const {
336 return QualType(Receiver
.get
<Type
*>(), 0);
338 ObjCInterfaceDecl
*getClassReceiver() const {
339 return Receiver
.get
<ObjCInterfaceDecl
*>();
341 bool isObjectReceiver() const { return Receiver
.is
<Stmt
*>(); }
342 bool isSuperReceiver() const { return Receiver
.is
<Type
*>(); }
343 bool isClassReceiver() const { return Receiver
.is
<ObjCInterfaceDecl
*>(); }
345 virtual SourceRange
getSourceRange() const {
346 return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
347 : getReceiverLocation()),
351 static bool classof(const Stmt
*T
) {
352 return T
->getStmtClass() == ObjCPropertyRefExprClass
;
354 static bool classof(const ObjCPropertyRefExpr
*) { return true; }
357 virtual child_iterator
child_begin();
358 virtual child_iterator
child_end();
360 friend class ASTStmtReader
;
361 void setExplicitProperty(ObjCPropertyDecl
*D
) {
362 PropertyOrGetter
.setPointer(D
);
363 PropertyOrGetter
.setInt(false);
366 void setImplicitProperty(ObjCMethodDecl
*Getter
, ObjCMethodDecl
*Setter
) {
367 PropertyOrGetter
.setPointer(Getter
);
368 PropertyOrGetter
.setInt(true);
369 this->Setter
= Setter
;
371 void setBase(Expr
*Base
) { Receiver
= Base
; }
372 void setSuperReceiver(QualType T
) { Receiver
= T
.getTypePtr(); }
373 void setClassReceiver(ObjCInterfaceDecl
*D
) { Receiver
= D
; }
375 void setLocation(SourceLocation L
) { IdLoc
= L
; }
376 void setReceiverLocation(SourceLocation Loc
) { ReceiverLoc
= Loc
; }
379 /// \brief An expression that sends a message to the given Objective-C
382 /// The following contains two message send expressions:
385 /// [[NSString alloc] initWithString:@"Hello"]
388 /// The innermost message send invokes the "alloc" class method on the
389 /// NSString class, while the outermost message send invokes the
390 /// "initWithString" instance method on the object returned from
391 /// NSString's "alloc". In all, an Objective-C message send can take
392 /// on four different (although related) forms:
394 /// 1. Send to an object instance.
395 /// 2. Send to a class.
396 /// 3. Send to the superclass instance of the current class.
397 /// 4. Send to the superclass of the current class.
399 /// All four kinds of message sends are modeled by the ObjCMessageExpr
400 /// class, and can be distinguished via \c getReceiverKind(). Example:
402 class ObjCMessageExpr
: public Expr
{
403 /// \brief The number of arguments in the message send, not
404 /// including the receiver.
405 unsigned NumArgs
: 16;
407 /// \brief The kind of message send this is, which is one of the
408 /// ReceiverKind values.
410 /// We pad this out to a byte to avoid excessive masking and shifting.
413 /// \brief Whether we have an actual method prototype in \c
414 /// SelectorOrMethod.
416 /// When non-zero, we have a method declaration; otherwise, we just
418 unsigned HasMethod
: 8;
420 /// \brief When the message expression is a send to 'super', this is
421 /// the location of the 'super' keyword.
422 SourceLocation SuperLoc
;
424 /// \brief Stores either the selector that this message is sending
425 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
426 /// referring to the method that we type-checked against.
427 uintptr_t SelectorOrMethod
;
429 /// \brief Location of the selector.
430 SourceLocation SelectorLoc
;
432 /// \brief The source locations of the open and close square
433 /// brackets ('[' and ']', respectively).
434 SourceLocation LBracLoc
, RBracLoc
;
436 ObjCMessageExpr(EmptyShell Empty
, unsigned NumArgs
)
437 : Expr(ObjCMessageExprClass
, Empty
), NumArgs(NumArgs
), Kind(0),
438 HasMethod(0), SelectorOrMethod(0) { }
440 ObjCMessageExpr(QualType T
, ExprValueKind VK
,
441 SourceLocation LBracLoc
,
442 SourceLocation SuperLoc
,
443 bool IsInstanceSuper
,
446 SourceLocation SelLoc
,
447 ObjCMethodDecl
*Method
,
448 Expr
**Args
, unsigned NumArgs
,
449 SourceLocation RBracLoc
);
450 ObjCMessageExpr(QualType T
, ExprValueKind VK
,
451 SourceLocation LBracLoc
,
452 TypeSourceInfo
*Receiver
,
454 SourceLocation SelLoc
,
455 ObjCMethodDecl
*Method
,
456 Expr
**Args
, unsigned NumArgs
,
457 SourceLocation RBracLoc
);
458 ObjCMessageExpr(QualType T
, ExprValueKind VK
,
459 SourceLocation LBracLoc
,
462 SourceLocation SelLoc
,
463 ObjCMethodDecl
*Method
,
464 Expr
**Args
, unsigned NumArgs
,
465 SourceLocation RBracLoc
);
467 /// \brief Retrieve the pointer value of the message receiver.
468 void *getReceiverPointer() const {
469 return *const_cast<void **>(
470 reinterpret_cast<const void * const*>(this + 1));
473 /// \brief Set the pointer value of the message receiver.
474 void setReceiverPointer(void *Value
) {
475 *reinterpret_cast<void **>(this + 1) = Value
;
479 /// \brief The kind of receiver this message is sending to.
481 /// \brief The receiver is a class.
483 /// \brief The receiver is an object instance.
485 /// \brief The receiver is a superclass.
487 /// \brief The receiver is the instance of the superclass object.
491 /// \brief Create a message send to super.
493 /// \param Context The ASTContext in which this expression will be created.
495 /// \param T The result type of this message.
497 /// \param VK The value kind of this message. A message returning
498 /// a l-value or r-value reference will be an l-value or x-value,
501 /// \param LBrac The location of the open square bracket '['.
503 /// \param SuperLoc The location of the "super" keyword.
505 /// \param IsInstanceSuper Whether this is an instance "super"
506 /// message (otherwise, it's a class "super" message).
508 /// \param Sel The selector used to determine which method gets called.
510 /// \param Method The Objective-C method against which this message
511 /// send was type-checked. May be NULL.
513 /// \param Args The message send arguments.
515 /// \param NumArgs The number of arguments.
517 /// \param RBracLoc The location of the closing square bracket ']'.
518 static ObjCMessageExpr
*Create(ASTContext
&Context
, QualType T
,
520 SourceLocation LBracLoc
,
521 SourceLocation SuperLoc
,
522 bool IsInstanceSuper
,
525 SourceLocation SelLoc
,
526 ObjCMethodDecl
*Method
,
527 Expr
**Args
, unsigned NumArgs
,
528 SourceLocation RBracLoc
);
530 /// \brief Create a class message send.
532 /// \param Context The ASTContext in which this expression will be created.
534 /// \param T The result type of this message.
536 /// \param VK The value kind of this message. A message returning
537 /// a l-value or r-value reference will be an l-value or x-value,
540 /// \param LBrac The location of the open square bracket '['.
542 /// \param Receiver The type of the receiver, including
543 /// source-location information.
545 /// \param Sel The selector used to determine which method gets called.
547 /// \param Method The Objective-C method against which this message
548 /// send was type-checked. May be NULL.
550 /// \param Args The message send arguments.
552 /// \param NumArgs The number of arguments.
554 /// \param RBracLoc The location of the closing square bracket ']'.
555 static ObjCMessageExpr
*Create(ASTContext
&Context
, QualType T
,
557 SourceLocation LBracLoc
,
558 TypeSourceInfo
*Receiver
,
560 SourceLocation SelLoc
,
561 ObjCMethodDecl
*Method
,
562 Expr
**Args
, unsigned NumArgs
,
563 SourceLocation RBracLoc
);
565 /// \brief Create an instance message send.
567 /// \param Context The ASTContext in which this expression will be created.
569 /// \param T The result type of this message.
571 /// \param VK The value kind of this message. A message returning
572 /// a l-value or r-value reference will be an l-value or x-value,
575 /// \param LBrac The location of the open square bracket '['.
577 /// \param Receiver The expression used to produce the object that
578 /// will receive this message.
580 /// \param Sel The selector used to determine which method gets called.
582 /// \param Method The Objective-C method against which this message
583 /// send was type-checked. May be NULL.
585 /// \param Args The message send arguments.
587 /// \param NumArgs The number of arguments.
589 /// \param RBracLoc The location of the closing square bracket ']'.
590 static ObjCMessageExpr
*Create(ASTContext
&Context
, QualType T
,
592 SourceLocation LBracLoc
,
595 SourceLocation SelLoc
,
596 ObjCMethodDecl
*Method
,
597 Expr
**Args
, unsigned NumArgs
,
598 SourceLocation RBracLoc
);
600 /// \brief Create an empty Objective-C message expression, to be
601 /// filled in by subsequent calls.
603 /// \param Context The context in which the message send will be created.
605 /// \param NumArgs The number of message arguments, not including
607 static ObjCMessageExpr
*CreateEmpty(ASTContext
&Context
, unsigned NumArgs
);
609 /// \brief Determine the kind of receiver that this message is being
611 ReceiverKind
getReceiverKind() const { return (ReceiverKind
)Kind
; }
613 /// \brief Determine whether this is an instance message to either a
614 /// computed object or to super.
615 bool isInstanceMessage() const {
616 return getReceiverKind() == Instance
|| getReceiverKind() == SuperInstance
;
619 /// \brief Determine whether this is an class message to either a
620 /// specified class or to super.
621 bool isClassMessage() const {
622 return getReceiverKind() == Class
|| getReceiverKind() == SuperClass
;
625 /// \brief Returns the receiver of an instance message.
627 /// \brief Returns the object expression for an instance message, or
628 /// NULL for a message that is not an instance message.
629 Expr
*getInstanceReceiver() {
630 if (getReceiverKind() == Instance
)
631 return static_cast<Expr
*>(getReceiverPointer());
635 const Expr
*getInstanceReceiver() const {
636 return const_cast<ObjCMessageExpr
*>(this)->getInstanceReceiver();
639 /// \brief Turn this message send into an instance message that
640 /// computes the receiver object with the given expression.
641 void setInstanceReceiver(Expr
*rec
) {
643 setReceiverPointer(rec
);
646 /// \brief Returns the type of a class message send, or NULL if the
647 /// message is not a class message.
648 QualType
getClassReceiver() const {
649 if (TypeSourceInfo
*TSInfo
= getClassReceiverTypeInfo())
650 return TSInfo
->getType();
655 /// \brief Returns a type-source information of a class message
656 /// send, or NULL if the message is not a class message.
657 TypeSourceInfo
*getClassReceiverTypeInfo() const {
658 if (getReceiverKind() == Class
)
659 return reinterpret_cast<TypeSourceInfo
*>(getReceiverPointer());
663 void setClassReceiver(TypeSourceInfo
*TSInfo
) {
665 setReceiverPointer(TSInfo
);
668 /// \brief Retrieve the location of the 'super' keyword for a class
669 /// or instance message to 'super', otherwise an invalid source location.
670 SourceLocation
getSuperLoc() const {
671 if (getReceiverKind() == SuperInstance
|| getReceiverKind() == SuperClass
)
674 return SourceLocation();
677 /// \brief Retrieve the Objective-C interface to which this message
678 /// is being directed, if known.
680 /// This routine cross-cuts all of the different kinds of message
681 /// sends to determine what the underlying (statically known) type
682 /// of the receiver will be; use \c getReceiverKind() to determine
683 /// whether the message is a class or an instance method, whether it
684 /// is a send to super or not, etc.
686 /// \returns The Objective-C interface if known, otherwise NULL.
687 ObjCInterfaceDecl
*getReceiverInterface() const;
689 /// \brief Retrieve the type referred to by 'super'.
691 /// The returned type will either be an ObjCInterfaceType (for an
692 /// class message to super) or an ObjCObjectPointerType that refers
693 /// to a class (for an instance message to super);
694 QualType
getSuperType() const {
695 if (getReceiverKind() == SuperInstance
|| getReceiverKind() == SuperClass
)
696 return QualType::getFromOpaquePtr(getReceiverPointer());
701 void setSuper(SourceLocation Loc
, QualType T
, bool IsInstanceSuper
) {
702 Kind
= IsInstanceSuper
? SuperInstance
: SuperClass
;
704 setReceiverPointer(T
.getAsOpaquePtr());
707 Selector
getSelector() const;
709 void setSelector(Selector S
) {
711 SelectorOrMethod
= reinterpret_cast<uintptr_t>(S
.getAsOpaquePtr());
714 const ObjCMethodDecl
*getMethodDecl() const {
716 return reinterpret_cast<const ObjCMethodDecl
*>(SelectorOrMethod
);
721 ObjCMethodDecl
*getMethodDecl() {
723 return reinterpret_cast<ObjCMethodDecl
*>(SelectorOrMethod
);
728 void setMethodDecl(ObjCMethodDecl
*MD
) {
730 SelectorOrMethod
= reinterpret_cast<uintptr_t>(MD
);
733 /// \brief Return the number of actual arguments in this message,
734 /// not counting the receiver.
735 unsigned getNumArgs() const { return NumArgs
; }
737 /// \brief Retrieve the arguments to this message, not including the
740 return reinterpret_cast<Stmt
**>(this + 1) + 1;
742 const Stmt
* const *getArgs() const {
743 return reinterpret_cast<const Stmt
* const *>(this + 1) + 1;
746 /// getArg - Return the specified argument.
747 Expr
*getArg(unsigned Arg
) {
748 assert(Arg
< NumArgs
&& "Arg access out of range!");
749 return cast
<Expr
>(getArgs()[Arg
]);
751 const Expr
*getArg(unsigned Arg
) const {
752 assert(Arg
< NumArgs
&& "Arg access out of range!");
753 return cast
<Expr
>(getArgs()[Arg
]);
755 /// setArg - Set the specified argument.
756 void setArg(unsigned Arg
, Expr
*ArgExpr
) {
757 assert(Arg
< NumArgs
&& "Arg access out of range!");
758 getArgs()[Arg
] = ArgExpr
;
761 SourceLocation
getLeftLoc() const { return LBracLoc
; }
762 SourceLocation
getRightLoc() const { return RBracLoc
; }
763 SourceLocation
getSelectorLoc() const { return SelectorLoc
; }
765 void setSourceRange(SourceRange R
) {
766 LBracLoc
= R
.getBegin();
767 RBracLoc
= R
.getEnd();
769 virtual SourceRange
getSourceRange() const {
770 return SourceRange(LBracLoc
, RBracLoc
);
773 static bool classof(const Stmt
*T
) {
774 return T
->getStmtClass() == ObjCMessageExprClass
;
776 static bool classof(const ObjCMessageExpr
*) { return true; }
779 virtual child_iterator
child_begin();
780 virtual child_iterator
child_end();
782 typedef ExprIterator arg_iterator
;
783 typedef ConstExprIterator const_arg_iterator
;
785 arg_iterator
arg_begin() { return getArgs(); }
786 arg_iterator
arg_end() { return getArgs() + NumArgs
; }
787 const_arg_iterator
arg_begin() const { return getArgs(); }
788 const_arg_iterator
arg_end() const { return getArgs() + NumArgs
; }
790 friend class ASTStmtReader
;
791 friend class ASTStmtWriter
;
794 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
795 /// (similiar in spirit to MemberExpr).
796 class ObjCIsaExpr
: public Expr
{
797 /// Base - the expression for the base object pointer.
800 /// IsaMemberLoc - This is the location of the 'isa'.
801 SourceLocation IsaMemberLoc
;
803 /// IsArrow - True if this is "X->F", false if this is "X.F".
806 ObjCIsaExpr(Expr
*base
, bool isarrow
, SourceLocation l
, QualType ty
)
807 : Expr(ObjCIsaExprClass
, ty
, VK_LValue
, OK_Ordinary
,
808 /*TypeDependent=*/false, base
->isValueDependent()),
809 Base(base
), IsaMemberLoc(l
), IsArrow(isarrow
) {}
811 /// \brief Build an empty expression.
812 explicit ObjCIsaExpr(EmptyShell Empty
) : Expr(ObjCIsaExprClass
, Empty
) { }
814 void setBase(Expr
*E
) { Base
= E
; }
815 Expr
*getBase() const { return cast
<Expr
>(Base
); }
817 bool isArrow() const { return IsArrow
; }
818 void setArrow(bool A
) { IsArrow
= A
; }
820 /// getMemberLoc - Return the location of the "member", in X->F, it is the
822 SourceLocation
getIsaMemberLoc() const { return IsaMemberLoc
; }
823 void setIsaMemberLoc(SourceLocation L
) { IsaMemberLoc
= L
; }
825 virtual SourceRange
getSourceRange() const {
826 return SourceRange(getBase()->getLocStart(), IsaMemberLoc
);
829 virtual SourceLocation
getExprLoc() const { return IsaMemberLoc
; }
831 static bool classof(const Stmt
*T
) {
832 return T
->getStmtClass() == ObjCIsaExprClass
;
834 static bool classof(const ObjCIsaExpr
*) { return true; }
837 virtual child_iterator
child_begin();
838 virtual child_iterator
child_end();
841 } // end namespace clang