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,
34 String(SL), AtLoc(L) {}
35 explicit ObjCStringLiteral(EmptyShell Empty)
36 : Expr(ObjCStringLiteralClass, Empty) {}
38 StringLiteral *getString() { return cast<StringLiteral>(String); }
39 const StringLiteral *getString() const { return cast<StringLiteral>(String); }
40 void setString(StringLiteral *S) { String = S; }
42 SourceLocation getAtLoc() const { return AtLoc; }
43 void setAtLoc(SourceLocation L) { AtLoc = L; }
45 SourceRange getSourceRange() const {
46 return SourceRange(AtLoc, String->getLocEnd());
49 static bool classof(const Stmt *T) {
50 return T->getStmtClass() == ObjCStringLiteralClass;
52 static bool classof(const ObjCStringLiteral *) { return true; }
55 child_range children() { return child_range(&String, &String+1); }
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->getType()->containsUnexpandedParameterPack()),
71 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
73 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
76 SourceLocation getAtLoc() const { return AtLoc; }
77 void setAtLoc(SourceLocation L) { AtLoc = L; }
78 SourceLocation getRParenLoc() const { return RParenLoc; }
79 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
81 QualType getEncodedType() const { return EncodedType->getType(); }
83 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
84 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
85 EncodedType = EncType;
88 SourceRange getSourceRange() const {
89 return SourceRange(AtLoc, RParenLoc);
92 static bool classof(const Stmt *T) {
93 return T->getStmtClass() == ObjCEncodeExprClass;
95 static bool classof(const ObjCEncodeExpr *) { return true; }
98 child_range children() { return child_range(); }
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,
110 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
111 explicit ObjCSelectorExpr(EmptyShell Empty)
112 : Expr(ObjCSelectorExprClass, Empty) {}
114 Selector getSelector() const { return SelName; }
115 void setSelector(Selector S) { SelName = S; }
117 SourceLocation getAtLoc() const { return AtLoc; }
118 SourceLocation getRParenLoc() const { return RParenLoc; }
119 void setAtLoc(SourceLocation L) { AtLoc = L; }
120 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
122 SourceRange getSourceRange() const {
123 return SourceRange(AtLoc, RParenLoc);
126 /// getNumArgs - Return the number of actual arguments to this call.
127 unsigned getNumArgs() const { return SelName.getNumArgs(); }
129 static bool classof(const Stmt *T) {
130 return T->getStmtClass() == ObjCSelectorExprClass;
132 static bool classof(const ObjCSelectorExpr *) { return true; }
135 child_range children() { return child_range(); }
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,
150 TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
151 explicit ObjCProtocolExpr(EmptyShell Empty)
152 : Expr(ObjCProtocolExprClass, Empty) {}
154 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
155 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
157 SourceLocation getAtLoc() const { return AtLoc; }
158 SourceLocation getRParenLoc() const { return RParenLoc; }
159 void setAtLoc(SourceLocation L) { AtLoc = L; }
160 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
162 SourceRange getSourceRange() const {
163 return SourceRange(AtLoc, RParenLoc);
166 static bool classof(const Stmt *T) {
167 return T->getStmtClass() == ObjCProtocolExprClass;
169 static bool classof(const ObjCProtocolExpr *) { return true; }
172 child_range children() { return child_range(); }
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(),
189 base->containsUnexpandedParameterPack()),
190 D(d), Loc(l), Base(base), IsArrow(arrow), 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 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 child_range children() { return child_range(&Base, &Base+1); }
225 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
228 class ObjCPropertyRefExpr : public Expr {
230 /// If the bool is true, this is an implicit property reference; the
231 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
232 /// if the bool is false, this is an explicit property reference;
233 /// the pointer is an ObjCPropertyDecl and Setter is always null.
234 llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
235 ObjCMethodDecl *Setter;
237 SourceLocation IdLoc;
239 /// \brief When the receiver in property access is 'super', this is
240 /// the location of the 'super' keyword. When it's an interface,
241 /// this is that interface.
242 SourceLocation ReceiverLoc;
243 llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
246 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
247 ExprValueKind VK, ExprObjectKind OK,
248 SourceLocation l, Expr *base)
249 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
250 /*TypeDependent=*/false, base->isValueDependent(),
251 base->containsUnexpandedParameterPack()),
252 PropertyOrGetter(PD, false), Setter(0),
253 IdLoc(l), ReceiverLoc(), Receiver(base) {
256 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
257 ExprValueKind VK, ExprObjectKind OK,
258 SourceLocation l, SourceLocation sl, QualType st)
259 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
260 /*TypeDependent=*/false, false,
261 st->containsUnexpandedParameterPack()),
262 PropertyOrGetter(PD, false), Setter(0),
263 IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
266 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
267 QualType T, ExprValueKind VK, ExprObjectKind OK,
268 SourceLocation IdLoc, Expr *Base)
269 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
270 Base->isValueDependent(),
271 Base->containsUnexpandedParameterPack()),
272 PropertyOrGetter(Getter, true), Setter(Setter),
273 IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
276 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
277 QualType T, ExprValueKind VK, ExprObjectKind OK,
278 SourceLocation IdLoc,
279 SourceLocation SuperLoc, QualType SuperTy)
280 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
281 PropertyOrGetter(Getter, true), Setter(Setter),
282 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
285 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
286 QualType T, ExprValueKind VK, ExprObjectKind OK,
287 SourceLocation IdLoc,
288 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
289 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false),
290 PropertyOrGetter(Getter, true), Setter(Setter),
291 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
294 explicit ObjCPropertyRefExpr(EmptyShell Empty)
295 : Expr(ObjCPropertyRefExprClass, Empty) {}
297 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
298 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
300 ObjCPropertyDecl *getExplicitProperty() const {
301 assert(!isImplicitProperty());
302 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
305 ObjCMethodDecl *getImplicitPropertyGetter() const {
306 assert(isImplicitProperty());
307 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
310 ObjCMethodDecl *getImplicitPropertySetter() const {
311 assert(isImplicitProperty());
315 Selector getGetterSelector() const {
316 if (isImplicitProperty())
317 return getImplicitPropertyGetter()->getSelector();
318 return getExplicitProperty()->getGetterName();
321 Selector getSetterSelector() const {
322 if (isImplicitProperty())
323 return getImplicitPropertySetter()->getSelector();
324 return getExplicitProperty()->getSetterName();
327 const Expr *getBase() const {
328 return cast<Expr>(Receiver.get<Stmt*>());
331 return cast<Expr>(Receiver.get<Stmt*>());
334 SourceLocation getLocation() const { return IdLoc; }
336 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
337 QualType getSuperReceiverType() const {
338 return QualType(Receiver.get<const Type*>(), 0);
340 QualType getGetterResultType() const {
342 if (isExplicitProperty()) {
343 const ObjCPropertyDecl *PDecl = getExplicitProperty();
344 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
345 ResultType = Getter->getResultType();
347 ResultType = getType();
349 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
350 ResultType = Getter->getResultType(); // with reference!
355 QualType getSetterArgType() const {
357 if (isImplicitProperty()) {
358 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
359 ObjCMethodDecl::param_iterator P = Setter->param_begin();
360 ArgType = (*P)->getType();
362 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
363 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
364 ObjCMethodDecl::param_iterator P = Setter->param_begin();
365 ArgType = (*P)->getType();
367 if (ArgType.isNull())
373 ObjCInterfaceDecl *getClassReceiver() const {
374 return Receiver.get<ObjCInterfaceDecl*>();
376 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
377 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
378 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
380 SourceRange getSourceRange() const {
381 return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
382 : getReceiverLocation()),
386 static bool classof(const Stmt *T) {
387 return T->getStmtClass() == ObjCPropertyRefExprClass;
389 static bool classof(const ObjCPropertyRefExpr *) { return true; }
392 child_range children() {
393 if (Receiver.is<Stmt*>()) {
394 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
395 return child_range(begin, begin+1);
397 return child_range();
401 friend class ASTStmtReader;
402 void setExplicitProperty(ObjCPropertyDecl *D) {
403 PropertyOrGetter.setPointer(D);
404 PropertyOrGetter.setInt(false);
407 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) {
408 PropertyOrGetter.setPointer(Getter);
409 PropertyOrGetter.setInt(true);
410 this->Setter = Setter;
412 void setBase(Expr *Base) { Receiver = Base; }
413 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
414 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
416 void setLocation(SourceLocation L) { IdLoc = L; }
417 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
420 /// \brief An expression that sends a message to the given Objective-C
423 /// The following contains two message send expressions:
426 /// [[NSString alloc] initWithString:@"Hello"]
429 /// The innermost message send invokes the "alloc" class method on the
430 /// NSString class, while the outermost message send invokes the
431 /// "initWithString" instance method on the object returned from
432 /// NSString's "alloc". In all, an Objective-C message send can take
433 /// on four different (although related) forms:
435 /// 1. Send to an object instance.
436 /// 2. Send to a class.
437 /// 3. Send to the superclass instance of the current class.
438 /// 4. Send to the superclass of the current class.
440 /// All four kinds of message sends are modeled by the ObjCMessageExpr
441 /// class, and can be distinguished via \c getReceiverKind(). Example:
443 class ObjCMessageExpr : public Expr {
444 /// \brief The number of arguments in the message send, not
445 /// including the receiver.
446 unsigned NumArgs : 16;
448 /// \brief The kind of message send this is, which is one of the
449 /// ReceiverKind values.
451 /// We pad this out to a byte to avoid excessive masking and shifting.
454 /// \brief Whether we have an actual method prototype in \c
455 /// SelectorOrMethod.
457 /// When non-zero, we have a method declaration; otherwise, we just
459 unsigned HasMethod : 8;
461 /// \brief When the message expression is a send to 'super', this is
462 /// the location of the 'super' keyword.
463 SourceLocation SuperLoc;
465 /// \brief Stores either the selector that this message is sending
466 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
467 /// referring to the method that we type-checked against.
468 uintptr_t SelectorOrMethod;
470 /// \brief Location of the selector.
471 SourceLocation SelectorLoc;
473 /// \brief The source locations of the open and close square
474 /// brackets ('[' and ']', respectively).
475 SourceLocation LBracLoc, RBracLoc;
477 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
478 : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
479 HasMethod(0), SelectorOrMethod(0) { }
481 ObjCMessageExpr(QualType T, ExprValueKind VK,
482 SourceLocation LBracLoc,
483 SourceLocation SuperLoc,
484 bool IsInstanceSuper,
487 SourceLocation SelLoc,
488 ObjCMethodDecl *Method,
489 Expr **Args, unsigned NumArgs,
490 SourceLocation RBracLoc);
491 ObjCMessageExpr(QualType T, ExprValueKind VK,
492 SourceLocation LBracLoc,
493 TypeSourceInfo *Receiver,
495 SourceLocation SelLoc,
496 ObjCMethodDecl *Method,
497 Expr **Args, unsigned NumArgs,
498 SourceLocation RBracLoc);
499 ObjCMessageExpr(QualType T, ExprValueKind VK,
500 SourceLocation LBracLoc,
503 SourceLocation SelLoc,
504 ObjCMethodDecl *Method,
505 Expr **Args, unsigned NumArgs,
506 SourceLocation RBracLoc);
508 /// \brief Retrieve the pointer value of the message receiver.
509 void *getReceiverPointer() const {
510 return *const_cast<void **>(
511 reinterpret_cast<const void * const*>(this + 1));
514 /// \brief Set the pointer value of the message receiver.
515 void setReceiverPointer(void *Value) {
516 *reinterpret_cast<void **>(this + 1) = Value;
520 /// \brief The kind of receiver this message is sending to.
522 /// \brief The receiver is a class.
524 /// \brief The receiver is an object instance.
526 /// \brief The receiver is a superclass.
528 /// \brief The receiver is the instance of the superclass object.
532 /// \brief Create a message send to super.
534 /// \param Context The ASTContext in which this expression will be created.
536 /// \param T The result type of this message.
538 /// \param VK The value kind of this message. A message returning
539 /// a l-value or r-value reference will be an l-value or x-value,
542 /// \param LBrac The location of the open square bracket '['.
544 /// \param SuperLoc The location of the "super" keyword.
546 /// \param IsInstanceSuper Whether this is an instance "super"
547 /// message (otherwise, it's a class "super" message).
549 /// \param Sel The selector used to determine which method gets called.
551 /// \param Method The Objective-C method against which this message
552 /// send was type-checked. May be NULL.
554 /// \param Args The message send arguments.
556 /// \param NumArgs The number of arguments.
558 /// \param RBracLoc The location of the closing square bracket ']'.
559 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
561 SourceLocation LBracLoc,
562 SourceLocation SuperLoc,
563 bool IsInstanceSuper,
566 SourceLocation SelLoc,
567 ObjCMethodDecl *Method,
568 Expr **Args, unsigned NumArgs,
569 SourceLocation RBracLoc);
571 /// \brief Create a class message send.
573 /// \param Context The ASTContext in which this expression will be created.
575 /// \param T The result type of this message.
577 /// \param VK The value kind of this message. A message returning
578 /// a l-value or r-value reference will be an l-value or x-value,
581 /// \param LBrac The location of the open square bracket '['.
583 /// \param Receiver The type of the receiver, including
584 /// source-location information.
586 /// \param Sel The selector used to determine which method gets called.
588 /// \param Method The Objective-C method against which this message
589 /// send was type-checked. May be NULL.
591 /// \param Args The message send arguments.
593 /// \param NumArgs The number of arguments.
595 /// \param RBracLoc The location of the closing square bracket ']'.
596 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
598 SourceLocation LBracLoc,
599 TypeSourceInfo *Receiver,
601 SourceLocation SelLoc,
602 ObjCMethodDecl *Method,
603 Expr **Args, unsigned NumArgs,
604 SourceLocation RBracLoc);
606 /// \brief Create an instance message send.
608 /// \param Context The ASTContext in which this expression will be created.
610 /// \param T The result type of this message.
612 /// \param VK The value kind of this message. A message returning
613 /// a l-value or r-value reference will be an l-value or x-value,
616 /// \param LBrac The location of the open square bracket '['.
618 /// \param Receiver The expression used to produce the object that
619 /// will receive this message.
621 /// \param Sel The selector used to determine which method gets called.
623 /// \param Method The Objective-C method against which this message
624 /// send was type-checked. May be NULL.
626 /// \param Args The message send arguments.
628 /// \param NumArgs The number of arguments.
630 /// \param RBracLoc The location of the closing square bracket ']'.
631 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
633 SourceLocation LBracLoc,
636 SourceLocation SelLoc,
637 ObjCMethodDecl *Method,
638 Expr **Args, unsigned NumArgs,
639 SourceLocation RBracLoc);
641 /// \brief Create an empty Objective-C message expression, to be
642 /// filled in by subsequent calls.
644 /// \param Context The context in which the message send will be created.
646 /// \param NumArgs The number of message arguments, not including
648 static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
650 /// \brief Determine the kind of receiver that this message is being
652 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
654 /// \brief Source range of the receiver.
655 SourceRange getReceiverRange() const;
657 /// \brief Determine whether this is an instance message to either a
658 /// computed object or to super.
659 bool isInstanceMessage() const {
660 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
663 /// \brief Determine whether this is an class message to either a
664 /// specified class or to super.
665 bool isClassMessage() const {
666 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
669 /// \brief Returns the receiver of an instance message.
671 /// \brief Returns the object expression for an instance message, or
672 /// NULL for a message that is not an instance message.
673 Expr *getInstanceReceiver() {
674 if (getReceiverKind() == Instance)
675 return static_cast<Expr *>(getReceiverPointer());
679 const Expr *getInstanceReceiver() const {
680 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
683 /// \brief Turn this message send into an instance message that
684 /// computes the receiver object with the given expression.
685 void setInstanceReceiver(Expr *rec) {
687 setReceiverPointer(rec);
690 /// \brief Returns the type of a class message send, or NULL if the
691 /// message is not a class message.
692 QualType getClassReceiver() const {
693 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
694 return TSInfo->getType();
699 /// \brief Returns a type-source information of a class message
700 /// send, or NULL if the message is not a class message.
701 TypeSourceInfo *getClassReceiverTypeInfo() const {
702 if (getReceiverKind() == Class)
703 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
707 void setClassReceiver(TypeSourceInfo *TSInfo) {
709 setReceiverPointer(TSInfo);
712 /// \brief Retrieve the location of the 'super' keyword for a class
713 /// or instance message to 'super', otherwise an invalid source location.
714 SourceLocation getSuperLoc() const {
715 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
718 return SourceLocation();
721 /// \brief Retrieve the Objective-C interface to which this message
722 /// is being directed, if known.
724 /// This routine cross-cuts all of the different kinds of message
725 /// sends to determine what the underlying (statically known) type
726 /// of the receiver will be; use \c getReceiverKind() to determine
727 /// whether the message is a class or an instance method, whether it
728 /// is a send to super or not, etc.
730 /// \returns The Objective-C interface if known, otherwise NULL.
731 ObjCInterfaceDecl *getReceiverInterface() const;
733 /// \brief Retrieve the type referred to by 'super'.
735 /// The returned type will either be an ObjCInterfaceType (for an
736 /// class message to super) or an ObjCObjectPointerType that refers
737 /// to a class (for an instance message to super);
738 QualType getSuperType() const {
739 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
740 return QualType::getFromOpaquePtr(getReceiverPointer());
745 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
746 Kind = IsInstanceSuper? SuperInstance : SuperClass;
748 setReceiverPointer(T.getAsOpaquePtr());
751 Selector getSelector() const;
753 void setSelector(Selector S) {
755 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
758 const ObjCMethodDecl *getMethodDecl() const {
760 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
765 ObjCMethodDecl *getMethodDecl() {
767 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
772 void setMethodDecl(ObjCMethodDecl *MD) {
774 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
777 ObjCMethodFamily getMethodFamily() const {
778 if (HasMethod) return getMethodDecl()->getMethodFamily();
779 return getSelector().getMethodFamily();
782 /// \brief Return the number of actual arguments in this message,
783 /// not counting the receiver.
784 unsigned getNumArgs() const { return NumArgs; }
786 /// \brief Retrieve the arguments to this message, not including the
789 return reinterpret_cast<Expr **>(this + 1) + 1;
791 const Expr * const *getArgs() const {
792 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
795 /// getArg - Return the specified argument.
796 Expr *getArg(unsigned Arg) {
797 assert(Arg < NumArgs && "Arg access out of range!");
798 return cast<Expr>(getArgs()[Arg]);
800 const Expr *getArg(unsigned Arg) const {
801 assert(Arg < NumArgs && "Arg access out of range!");
802 return cast<Expr>(getArgs()[Arg]);
804 /// setArg - Set the specified argument.
805 void setArg(unsigned Arg, Expr *ArgExpr) {
806 assert(Arg < NumArgs && "Arg access out of range!");
807 getArgs()[Arg] = ArgExpr;
810 SourceLocation getLeftLoc() const { return LBracLoc; }
811 SourceLocation getRightLoc() const { return RBracLoc; }
812 SourceLocation getSelectorLoc() const { return SelectorLoc; }
814 void setSourceRange(SourceRange R) {
815 LBracLoc = R.getBegin();
816 RBracLoc = R.getEnd();
818 SourceRange getSourceRange() const {
819 return SourceRange(LBracLoc, RBracLoc);
822 static bool classof(const Stmt *T) {
823 return T->getStmtClass() == ObjCMessageExprClass;
825 static bool classof(const ObjCMessageExpr *) { return true; }
828 child_range children();
830 typedef ExprIterator arg_iterator;
831 typedef ConstExprIterator const_arg_iterator;
833 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
834 arg_iterator arg_end() {
835 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
837 const_arg_iterator arg_begin() const {
838 return reinterpret_cast<Stmt const * const*>(getArgs());
840 const_arg_iterator arg_end() const {
841 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
844 friend class ASTStmtReader;
845 friend class ASTStmtWriter;
848 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
849 /// (similar in spirit to MemberExpr).
850 class ObjCIsaExpr : public Expr {
851 /// Base - the expression for the base object pointer.
854 /// IsaMemberLoc - This is the location of the 'isa'.
855 SourceLocation IsaMemberLoc;
857 /// IsArrow - True if this is "X->F", false if this is "X.F".
860 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
861 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
862 /*TypeDependent=*/false, base->isValueDependent(),
863 /*ContainsUnexpandedParameterPack=*/false),
864 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
866 /// \brief Build an empty expression.
867 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
869 void setBase(Expr *E) { Base = E; }
870 Expr *getBase() const { return cast<Expr>(Base); }
872 bool isArrow() const { return IsArrow; }
873 void setArrow(bool A) { IsArrow = A; }
875 /// getMemberLoc - Return the location of the "member", in X->F, it is the
877 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
878 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
880 SourceRange getSourceRange() const {
881 return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
884 SourceLocation getExprLoc() const { return IsaMemberLoc; }
886 static bool classof(const Stmt *T) {
887 return T->getStmtClass() == ObjCIsaExprClass;
889 static bool classof(const ObjCIsaExpr *) { return true; }
892 child_range children() { return child_range(&Base, &Base+1); }
895 } // end namespace clang