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()->isInstantiationDependentType(),
71 EncodedType->getType()->containsUnexpandedParameterPack()),
72 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
74 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
77 SourceLocation getAtLoc() const { return AtLoc; }
78 void setAtLoc(SourceLocation L) { AtLoc = L; }
79 SourceLocation getRParenLoc() const { return RParenLoc; }
80 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
82 QualType getEncodedType() const { return EncodedType->getType(); }
84 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
85 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
86 EncodedType = EncType;
89 SourceRange getSourceRange() const {
90 return SourceRange(AtLoc, RParenLoc);
93 static bool classof(const Stmt *T) {
94 return T->getStmtClass() == ObjCEncodeExprClass;
96 static bool classof(const ObjCEncodeExpr *) { return true; }
99 child_range children() { return child_range(); }
102 /// ObjCSelectorExpr used for @selector in Objective-C.
103 class ObjCSelectorExpr : public Expr {
105 SourceLocation AtLoc, RParenLoc;
107 ObjCSelectorExpr(QualType T, Selector selInfo,
108 SourceLocation at, SourceLocation rp)
109 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
111 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
112 explicit ObjCSelectorExpr(EmptyShell Empty)
113 : Expr(ObjCSelectorExprClass, Empty) {}
115 Selector getSelector() const { return SelName; }
116 void setSelector(Selector S) { SelName = S; }
118 SourceLocation getAtLoc() const { return AtLoc; }
119 SourceLocation getRParenLoc() const { return RParenLoc; }
120 void setAtLoc(SourceLocation L) { AtLoc = L; }
121 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
123 SourceRange getSourceRange() const {
124 return SourceRange(AtLoc, RParenLoc);
127 /// getNumArgs - Return the number of actual arguments to this call.
128 unsigned getNumArgs() const { return SelName.getNumArgs(); }
130 static bool classof(const Stmt *T) {
131 return T->getStmtClass() == ObjCSelectorExprClass;
133 static bool classof(const ObjCSelectorExpr *) { return true; }
136 child_range children() { return child_range(); }
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;
147 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
148 SourceLocation at, SourceLocation rp)
149 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
151 TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
152 explicit ObjCProtocolExpr(EmptyShell Empty)
153 : Expr(ObjCProtocolExprClass, Empty) {}
155 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
156 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
158 SourceLocation getAtLoc() const { return AtLoc; }
159 SourceLocation getRParenLoc() const { return RParenLoc; }
160 void setAtLoc(SourceLocation L) { AtLoc = L; }
161 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
163 SourceRange getSourceRange() const {
164 return SourceRange(AtLoc, RParenLoc);
167 static bool classof(const Stmt *T) {
168 return T->getStmtClass() == ObjCProtocolExprClass;
170 static bool classof(const ObjCProtocolExpr *) { return true; }
173 child_range children() { return child_range(); }
176 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
177 class ObjCIvarRefExpr : public Expr {
178 class ObjCIvarDecl *D;
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).
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) {}
194 explicit ObjCIvarRefExpr(EmptyShell Empty)
195 : Expr(ObjCIvarRefExprClass, Empty) {}
197 ObjCIvarDecl *getDecl() { return D; }
198 const ObjCIvarDecl *getDecl() const { return D; }
199 void setDecl(ObjCIvarDecl *d) { D = d; }
201 const Expr *getBase() const { return cast<Expr>(Base); }
202 Expr *getBase() { return cast<Expr>(Base); }
203 void setBase(Expr * base) { Base = base; }
205 bool isArrow() const { return IsArrow; }
206 bool isFreeIvar() const { return IsFreeIvar; }
207 void setIsArrow(bool A) { IsArrow = A; }
208 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
210 SourceLocation getLocation() const { return Loc; }
211 void setLocation(SourceLocation L) { Loc = L; }
213 SourceRange getSourceRange() const {
214 return isFreeIvar() ? SourceRange(Loc)
215 : SourceRange(getBase()->getLocStart(), Loc);
218 static bool classof(const Stmt *T) {
219 return T->getStmtClass() == ObjCIvarRefExprClass;
221 static bool classof(const ObjCIvarRefExpr *) { return true; }
224 child_range children() { return child_range(&Base, &Base+1); }
227 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
230 class ObjCPropertyRefExpr : public Expr {
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;
239 SourceLocation IdLoc;
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;
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) {
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()) {
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) {
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()) {
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) {
297 explicit ObjCPropertyRefExpr(EmptyShell Empty)
298 : Expr(ObjCPropertyRefExprClass, Empty) {}
300 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
301 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
303 ObjCPropertyDecl *getExplicitProperty() const {
304 assert(!isImplicitProperty());
305 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
308 ObjCMethodDecl *getImplicitPropertyGetter() const {
309 assert(isImplicitProperty());
310 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
313 ObjCMethodDecl *getImplicitPropertySetter() const {
314 assert(isImplicitProperty());
318 Selector getGetterSelector() const {
319 if (isImplicitProperty())
320 return getImplicitPropertyGetter()->getSelector();
321 return getExplicitProperty()->getGetterName();
324 Selector getSetterSelector() const {
325 if (isImplicitProperty())
326 return getImplicitPropertySetter()->getSelector();
327 return getExplicitProperty()->getSetterName();
330 const Expr *getBase() const {
331 return cast<Expr>(Receiver.get<Stmt*>());
334 return cast<Expr>(Receiver.get<Stmt*>());
337 SourceLocation getLocation() const { return IdLoc; }
339 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
340 QualType getSuperReceiverType() const {
341 return QualType(Receiver.get<const Type*>(), 0);
343 QualType getGetterResultType() const {
345 if (isExplicitProperty()) {
346 const ObjCPropertyDecl *PDecl = getExplicitProperty();
347 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
348 ResultType = Getter->getResultType();
350 ResultType = getType();
352 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
353 ResultType = Getter->getResultType(); // with reference!
358 QualType getSetterArgType() const {
360 if (isImplicitProperty()) {
361 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
362 ObjCMethodDecl::param_iterator P = Setter->param_begin();
363 ArgType = (*P)->getType();
365 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
366 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
367 ObjCMethodDecl::param_iterator P = Setter->param_begin();
368 ArgType = (*P)->getType();
370 if (ArgType.isNull())
376 ObjCInterfaceDecl *getClassReceiver() const {
377 return Receiver.get<ObjCInterfaceDecl*>();
379 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
380 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
381 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
383 SourceRange getSourceRange() const {
384 return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
385 : getReceiverLocation()),
389 static bool classof(const Stmt *T) {
390 return T->getStmtClass() == ObjCPropertyRefExprClass;
392 static bool classof(const ObjCPropertyRefExpr *) { return true; }
395 child_range children() {
396 if (Receiver.is<Stmt*>()) {
397 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
398 return child_range(begin, begin+1);
400 return child_range();
404 friend class ASTStmtReader;
405 void setExplicitProperty(ObjCPropertyDecl *D) {
406 PropertyOrGetter.setPointer(D);
407 PropertyOrGetter.setInt(false);
410 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) {
411 PropertyOrGetter.setPointer(Getter);
412 PropertyOrGetter.setInt(true);
413 this->Setter = Setter;
415 void setBase(Expr *Base) { Receiver = Base; }
416 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
417 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
419 void setLocation(SourceLocation L) { IdLoc = L; }
420 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
423 /// \brief An expression that sends a message to the given Objective-C
426 /// The following contains two message send expressions:
429 /// [[NSString alloc] initWithString:@"Hello"]
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:
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.
443 /// All four kinds of message sends are modeled by the ObjCMessageExpr
444 /// class, and can be distinguished via \c getReceiverKind(). Example:
446 class ObjCMessageExpr : public Expr {
447 /// \brief The number of arguments in the message send, not
448 /// including the receiver.
449 unsigned NumArgs : 16;
451 /// \brief The kind of message send this is, which is one of the
452 /// ReceiverKind values.
454 /// We pad this out to a byte to avoid excessive masking and shifting.
457 /// \brief Whether we have an actual method prototype in \c
458 /// SelectorOrMethod.
460 /// When non-zero, we have a method declaration; otherwise, we just
462 unsigned HasMethod : 1;
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;
468 /// \brief When the message expression is a send to 'super', this is
469 /// the location of the 'super' keyword.
470 SourceLocation SuperLoc;
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;
477 /// \brief Location of the selector.
478 SourceLocation SelectorLoc;
480 /// \brief The source locations of the open and close square
481 /// brackets ('[' and ']', respectively).
482 SourceLocation LBracLoc, RBracLoc;
484 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
485 : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
486 HasMethod(0), IsDelegateInitCall(0), SelectorOrMethod(0) { }
488 ObjCMessageExpr(QualType T, ExprValueKind VK,
489 SourceLocation LBracLoc,
490 SourceLocation SuperLoc,
491 bool IsInstanceSuper,
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,
502 SourceLocation SelLoc,
503 ObjCMethodDecl *Method,
504 Expr **Args, unsigned NumArgs,
505 SourceLocation RBracLoc);
506 ObjCMessageExpr(QualType T, ExprValueKind VK,
507 SourceLocation LBracLoc,
510 SourceLocation SelLoc,
511 ObjCMethodDecl *Method,
512 Expr **Args, unsigned NumArgs,
513 SourceLocation RBracLoc);
515 /// \brief Retrieve the pointer value of the message receiver.
516 void *getReceiverPointer() const {
517 return *const_cast<void **>(
518 reinterpret_cast<const void * const*>(this + 1));
521 /// \brief Set the pointer value of the message receiver.
522 void setReceiverPointer(void *Value) {
523 *reinterpret_cast<void **>(this + 1) = Value;
527 /// \brief The kind of receiver this message is sending to.
529 /// \brief The receiver is a class.
531 /// \brief The receiver is an object instance.
533 /// \brief The receiver is a superclass.
535 /// \brief The receiver is the instance of the superclass object.
539 /// \brief Create a message send to super.
541 /// \param Context The ASTContext in which this expression will be created.
543 /// \param T The result type of this message.
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,
549 /// \param LBrac The location of the open square bracket '['.
551 /// \param SuperLoc The location of the "super" keyword.
553 /// \param IsInstanceSuper Whether this is an instance "super"
554 /// message (otherwise, it's a class "super" message).
556 /// \param Sel The selector used to determine which method gets called.
558 /// \param Method The Objective-C method against which this message
559 /// send was type-checked. May be NULL.
561 /// \param Args The message send arguments.
563 /// \param NumArgs The number of arguments.
565 /// \param RBracLoc The location of the closing square bracket ']'.
566 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
568 SourceLocation LBracLoc,
569 SourceLocation SuperLoc,
570 bool IsInstanceSuper,
573 SourceLocation SelLoc,
574 ObjCMethodDecl *Method,
575 Expr **Args, unsigned NumArgs,
576 SourceLocation RBracLoc);
578 /// \brief Create a class message send.
580 /// \param Context The ASTContext in which this expression will be created.
582 /// \param T The result type of this message.
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,
588 /// \param LBrac The location of the open square bracket '['.
590 /// \param Receiver The type of the receiver, including
591 /// source-location information.
593 /// \param Sel The selector used to determine which method gets called.
595 /// \param Method The Objective-C method against which this message
596 /// send was type-checked. May be NULL.
598 /// \param Args The message send arguments.
600 /// \param NumArgs The number of arguments.
602 /// \param RBracLoc The location of the closing square bracket ']'.
603 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
605 SourceLocation LBracLoc,
606 TypeSourceInfo *Receiver,
608 SourceLocation SelLoc,
609 ObjCMethodDecl *Method,
610 Expr **Args, unsigned NumArgs,
611 SourceLocation RBracLoc);
613 /// \brief Create an instance message send.
615 /// \param Context The ASTContext in which this expression will be created.
617 /// \param T The result type of this message.
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,
623 /// \param LBrac The location of the open square bracket '['.
625 /// \param Receiver The expression used to produce the object that
626 /// will receive this message.
628 /// \param Sel The selector used to determine which method gets called.
630 /// \param Method The Objective-C method against which this message
631 /// send was type-checked. May be NULL.
633 /// \param Args The message send arguments.
635 /// \param NumArgs The number of arguments.
637 /// \param RBracLoc The location of the closing square bracket ']'.
638 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
640 SourceLocation LBracLoc,
643 SourceLocation SelLoc,
644 ObjCMethodDecl *Method,
645 Expr **Args, unsigned NumArgs,
646 SourceLocation RBracLoc);
648 /// \brief Create an empty Objective-C message expression, to be
649 /// filled in by subsequent calls.
651 /// \param Context The context in which the message send will be created.
653 /// \param NumArgs The number of message arguments, not including
655 static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
657 /// \brief Determine the kind of receiver that this message is being
659 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
661 /// \brief Source range of the receiver.
662 SourceRange getReceiverRange() const;
664 /// \brief Determine whether this is an instance message to either a
665 /// computed object or to super.
666 bool isInstanceMessage() const {
667 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
670 /// \brief Determine whether this is an class message to either a
671 /// specified class or to super.
672 bool isClassMessage() const {
673 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
676 /// \brief Returns the receiver of an instance message.
678 /// \brief Returns the object expression for an instance message, or
679 /// NULL for a message that is not an instance message.
680 Expr *getInstanceReceiver() {
681 if (getReceiverKind() == Instance)
682 return static_cast<Expr *>(getReceiverPointer());
686 const Expr *getInstanceReceiver() const {
687 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
690 /// \brief Turn this message send into an instance message that
691 /// computes the receiver object with the given expression.
692 void setInstanceReceiver(Expr *rec) {
694 setReceiverPointer(rec);
697 /// \brief Returns the type of a class message send, or NULL if the
698 /// message is not a class message.
699 QualType getClassReceiver() const {
700 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
701 return TSInfo->getType();
706 /// \brief Returns a type-source information of a class message
707 /// send, or NULL if the message is not a class message.
708 TypeSourceInfo *getClassReceiverTypeInfo() const {
709 if (getReceiverKind() == Class)
710 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
714 void setClassReceiver(TypeSourceInfo *TSInfo) {
716 setReceiverPointer(TSInfo);
719 /// \brief Retrieve the location of the 'super' keyword for a class
720 /// or instance message to 'super', otherwise an invalid source location.
721 SourceLocation getSuperLoc() const {
722 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
725 return SourceLocation();
728 /// \brief Retrieve the Objective-C interface to which this message
729 /// is being directed, if known.
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.
737 /// \returns The Objective-C interface if known, otherwise NULL.
738 ObjCInterfaceDecl *getReceiverInterface() const;
740 /// \brief Retrieve the type referred to by 'super'.
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);
745 QualType getSuperType() const {
746 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
747 return QualType::getFromOpaquePtr(getReceiverPointer());
752 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
753 Kind = IsInstanceSuper? SuperInstance : SuperClass;
755 setReceiverPointer(T.getAsOpaquePtr());
758 Selector getSelector() const;
760 void setSelector(Selector S) {
762 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
765 const ObjCMethodDecl *getMethodDecl() const {
767 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
772 ObjCMethodDecl *getMethodDecl() {
774 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
779 void setMethodDecl(ObjCMethodDecl *MD) {
781 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
784 ObjCMethodFamily getMethodFamily() const {
785 if (HasMethod) return getMethodDecl()->getMethodFamily();
786 return getSelector().getMethodFamily();
789 /// \brief Return the number of actual arguments in this message,
790 /// not counting the receiver.
791 unsigned getNumArgs() const { return NumArgs; }
793 /// \brief Retrieve the arguments to this message, not including the
796 return reinterpret_cast<Expr **>(this + 1) + 1;
798 const Expr * const *getArgs() const {
799 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
802 /// getArg - Return the specified argument.
803 Expr *getArg(unsigned Arg) {
804 assert(Arg < NumArgs && "Arg access out of range!");
805 return cast<Expr>(getArgs()[Arg]);
807 const Expr *getArg(unsigned Arg) const {
808 assert(Arg < NumArgs && "Arg access out of range!");
809 return cast<Expr>(getArgs()[Arg]);
811 /// setArg - Set the specified argument.
812 void setArg(unsigned Arg, Expr *ArgExpr) {
813 assert(Arg < NumArgs && "Arg access out of range!");
814 getArgs()[Arg] = ArgExpr;
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.
820 bool isDelegateInitCall() const { return IsDelegateInitCall; }
821 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
823 SourceLocation getLeftLoc() const { return LBracLoc; }
824 SourceLocation getRightLoc() const { return RBracLoc; }
825 SourceLocation getSelectorLoc() const { return SelectorLoc; }
827 void setSourceRange(SourceRange R) {
828 LBracLoc = R.getBegin();
829 RBracLoc = R.getEnd();
831 SourceRange getSourceRange() const {
832 return SourceRange(LBracLoc, RBracLoc);
835 static bool classof(const Stmt *T) {
836 return T->getStmtClass() == ObjCMessageExprClass;
838 static bool classof(const ObjCMessageExpr *) { return true; }
841 child_range children();
843 typedef ExprIterator arg_iterator;
844 typedef ConstExprIterator const_arg_iterator;
846 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
847 arg_iterator arg_end() {
848 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
850 const_arg_iterator arg_begin() const {
851 return reinterpret_cast<Stmt const * const*>(getArgs());
853 const_arg_iterator arg_end() const {
854 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
857 friend class ASTStmtReader;
858 friend class ASTStmtWriter;
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.
867 /// IsaMemberLoc - This is the location of the 'isa'.
868 SourceLocation IsaMemberLoc;
870 /// IsArrow - True if this is "X->F", false if this is "X.F".
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) {}
880 /// \brief Build an empty expression.
881 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
883 void setBase(Expr *E) { Base = E; }
884 Expr *getBase() const { return cast<Expr>(Base); }
886 bool isArrow() const { return IsArrow; }
887 void setArrow(bool A) { IsArrow = A; }
889 /// getMemberLoc - Return the location of the "member", in X->F, it is the
891 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
892 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
894 SourceRange getSourceRange() const {
895 return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
898 SourceLocation getExprLoc() const { return IsaMemberLoc; }
900 static bool classof(const Stmt *T) {
901 return T->getStmtClass() == ObjCIsaExprClass;
903 static bool classof(const ObjCIsaExpr *) { return true; }
906 child_range children() { return child_range(&Base, &Base+1); }
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.
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'
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.
929 /// Currently 'T' must be a retainable object lifetime and must be
930 /// __autoreleasing; this qualifier is ignored when initializing
932 class ObjCIndirectCopyRestoreExpr : public Expr {
935 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
937 friend class ASTReader;
938 friend class ASTStmtReader;
940 void setShouldCopy(bool shouldCopy) {
941 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
944 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
945 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
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()),
954 setShouldCopy(shouldCopy);
957 Expr *getSubExpr() { return cast<Expr>(Operand); }
958 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
960 /// shouldCopy - True if we should do the 'copy' part of the
961 /// copy-restore. If false, the temporary will be zero-initialized.
962 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
964 child_range children() { return child_range(&Operand, &Operand+1); }
966 // Source locations are determined by the subexpression.
967 SourceRange getSourceRange() const { return Operand->getSourceRange(); }
968 SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); }
970 static bool classof(const Stmt *s) {
971 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
973 static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
976 /// \brief An Objective-C "bridged" cast expression, which casts between
977 /// Objective-C pointers and C pointers, transferring ownership in the process.
980 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
982 class ObjCBridgedCastExpr : public ExplicitCastExpr {
983 SourceLocation LParenLoc;
984 SourceLocation BridgeKeywordLoc;
987 friend class ASTStmtReader;
988 friend class ASTStmtWriter;
991 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
992 SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo,
994 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
995 CK_BitCast, Operand, 0, TSInfo),
996 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
998 /// \brief Construct an empty Objective-C bridged cast.
999 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1000 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
1002 SourceLocation getLParenLoc() const { return LParenLoc; }
1004 /// \brief Determine which kind of bridge is being performed via this cast.
1005 ObjCBridgeCastKind getBridgeKind() const {
1006 return static_cast<ObjCBridgeCastKind>(Kind);
1009 /// \brief Retrieve the kind of bridge being performed as a string.
1010 llvm::StringRef getBridgeKindName() const;
1012 /// \brief The location of the bridge keyword.
1013 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1015 SourceRange getSourceRange() const {
1016 return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
1019 static bool classof(const Stmt *T) {
1020 return T->getStmtClass() == ObjCBridgedCastExprClass;
1022 static bool classof(const ObjCBridgedCastExpr *) { return true; }
1026 } // end namespace clang