Keep the source location of the selector in ObjCMessageExpr.
[clang.git] / include / clang / AST / ExprObjC.h
blobaaad04b3040071ac9d53517a58c5eb03e16576ca
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.
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"
21 namespace clang {
22 class IdentifierInfo;
23 class ASTContext;
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 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; }
53 // Iterators
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;
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(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; }
96 // Iterators
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 {
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 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; }
133 // Iterators
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;
145 public:
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; }
170 // Iterators
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;
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).
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()), 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; }
221 // Iterators
222 virtual child_iterator child_begin();
223 virtual child_iterator child_end();
226 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
227 /// property.
229 class ObjCPropertyRefExpr : public Expr {
230 private:
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;
246 public:
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());
310 return Setter;
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*>());
328 Expr *getBase() {
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()),
348 IdLoc);
351 static bool classof(const Stmt *T) {
352 return T->getStmtClass() == ObjCPropertyRefExprClass;
354 static bool classof(const ObjCPropertyRefExpr *) { return true; }
356 // Iterators
357 virtual child_iterator child_begin();
358 virtual child_iterator child_end();
359 private:
360 friend class ASTStmtReader;
361 void setExplicitProperty(ObjCPropertyDecl *D) {
362 PropertyOrGetter.setPointer(D);
363 PropertyOrGetter.setInt(false);
364 Setter = 0;
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
380 /// object or class.
382 /// The following contains two message send expressions:
384 /// \code
385 /// [[NSString alloc] initWithString:@"Hello"]
386 /// \endcode
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.
411 unsigned Kind : 8;
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
417 /// have a selector.
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,
444 QualType SuperType,
445 Selector Sel,
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,
453 Selector Sel,
454 SourceLocation SelLoc,
455 ObjCMethodDecl *Method,
456 Expr **Args, unsigned NumArgs,
457 SourceLocation RBracLoc);
458 ObjCMessageExpr(QualType T, ExprValueKind VK,
459 SourceLocation LBracLoc,
460 Expr *Receiver,
461 Selector Sel,
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;
478 public:
479 /// \brief The kind of receiver this message is sending to.
480 enum ReceiverKind {
481 /// \brief The receiver is a class.
482 Class = 0,
483 /// \brief The receiver is an object instance.
484 Instance,
485 /// \brief The receiver is a superclass.
486 SuperClass,
487 /// \brief The receiver is the instance of the superclass object.
488 SuperInstance
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,
499 /// respectively.
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,
519 ExprValueKind VK,
520 SourceLocation LBracLoc,
521 SourceLocation SuperLoc,
522 bool IsInstanceSuper,
523 QualType SuperType,
524 Selector Sel,
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,
538 /// respectively.
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,
556 ExprValueKind VK,
557 SourceLocation LBracLoc,
558 TypeSourceInfo *Receiver,
559 Selector Sel,
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,
573 /// respectively.
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,
591 ExprValueKind VK,
592 SourceLocation LBracLoc,
593 Expr *Receiver,
594 Selector Sel,
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
606 /// the receiver.
607 static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
609 /// \brief Determine the kind of receiver that this message is being
610 /// sent to.
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());
633 return 0;
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) {
642 Kind = Instance;
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();
652 return QualType();
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());
660 return 0;
663 void setClassReceiver(TypeSourceInfo *TSInfo) {
664 Kind = Class;
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)
672 return SuperLoc;
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());
698 return QualType();
701 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
702 Kind = IsInstanceSuper? SuperInstance : SuperClass;
703 SuperLoc = Loc;
704 setReceiverPointer(T.getAsOpaquePtr());
707 Selector getSelector() const;
709 void setSelector(Selector S) {
710 HasMethod = false;
711 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
714 const ObjCMethodDecl *getMethodDecl() const {
715 if (HasMethod)
716 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
718 return 0;
721 ObjCMethodDecl *getMethodDecl() {
722 if (HasMethod)
723 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
725 return 0;
728 void setMethodDecl(ObjCMethodDecl *MD) {
729 HasMethod = true;
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
738 /// receiver.
739 Stmt **getArgs() {
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; }
778 // Iterators
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.
798 Stmt *Base;
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".
804 bool IsArrow;
805 public:
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
821 /// location of 'F'.
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; }
836 // Iterators
837 virtual child_iterator child_begin();
838 virtual child_iterator child_end();
841 } // end namespace clang
843 #endif