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/AST/SelectorLocationsKind.h"
20 #include "clang/Basic/IdentifierTable.h"
26 /// ObjCStringLiteral, used for Objective-C string literals
28 class ObjCStringLiteral : public Expr {
32 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
33 : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false,
35 String(SL), AtLoc(L) {}
36 explicit ObjCStringLiteral(EmptyShell Empty)
37 : Expr(ObjCStringLiteralClass, Empty) {}
39 StringLiteral *getString() { return cast<StringLiteral>(String); }
40 const StringLiteral *getString() const { return cast<StringLiteral>(String); }
41 void setString(StringLiteral *S) { String = S; }
43 SourceLocation getAtLoc() const { return AtLoc; }
44 void setAtLoc(SourceLocation L) { AtLoc = L; }
46 SourceRange getSourceRange() const {
47 return SourceRange(AtLoc, String->getLocEnd());
50 static bool classof(const Stmt *T) {
51 return T->getStmtClass() == ObjCStringLiteralClass;
53 static bool classof(const ObjCStringLiteral *) { return true; }
56 child_range children() { return child_range(&String, &String+1); }
59 /// ObjCEncodeExpr, used for @encode in Objective-C. @encode has the same type
60 /// and behavior as StringLiteral except that the string initializer is obtained
61 /// from ASTContext with the encoding type as an argument.
62 class ObjCEncodeExpr : public Expr {
63 TypeSourceInfo *EncodedType;
64 SourceLocation AtLoc, RParenLoc;
66 ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
67 SourceLocation at, SourceLocation rp)
68 : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary,
69 EncodedType->getType()->isDependentType(),
70 EncodedType->getType()->isDependentType(),
71 EncodedType->getType()->isInstantiationDependentType(),
72 EncodedType->getType()->containsUnexpandedParameterPack()),
73 EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
75 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
78 SourceLocation getAtLoc() const { return AtLoc; }
79 void setAtLoc(SourceLocation L) { AtLoc = L; }
80 SourceLocation getRParenLoc() const { return RParenLoc; }
81 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
83 QualType getEncodedType() const { return EncodedType->getType(); }
85 TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
86 void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
87 EncodedType = EncType;
90 SourceRange getSourceRange() const {
91 return SourceRange(AtLoc, RParenLoc);
94 static bool classof(const Stmt *T) {
95 return T->getStmtClass() == ObjCEncodeExprClass;
97 static bool classof(const ObjCEncodeExpr *) { return true; }
100 child_range children() { return child_range(); }
103 /// ObjCSelectorExpr used for @selector in Objective-C.
104 class ObjCSelectorExpr : public Expr {
106 SourceLocation AtLoc, RParenLoc;
108 ObjCSelectorExpr(QualType T, Selector selInfo,
109 SourceLocation at, SourceLocation rp)
110 : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false,
112 SelName(selInfo), AtLoc(at), RParenLoc(rp){}
113 explicit ObjCSelectorExpr(EmptyShell Empty)
114 : Expr(ObjCSelectorExprClass, Empty) {}
116 Selector getSelector() const { return SelName; }
117 void setSelector(Selector S) { SelName = S; }
119 SourceLocation getAtLoc() const { return AtLoc; }
120 SourceLocation getRParenLoc() const { return RParenLoc; }
121 void setAtLoc(SourceLocation L) { AtLoc = L; }
122 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
124 SourceRange getSourceRange() const {
125 return SourceRange(AtLoc, RParenLoc);
128 /// getNumArgs - Return the number of actual arguments to this call.
129 unsigned getNumArgs() const { return SelName.getNumArgs(); }
131 static bool classof(const Stmt *T) {
132 return T->getStmtClass() == ObjCSelectorExprClass;
134 static bool classof(const ObjCSelectorExpr *) { return true; }
137 child_range children() { return child_range(); }
140 /// ObjCProtocolExpr used for protocol expression in Objective-C. This is used
141 /// as: @protocol(foo), as in:
142 /// obj conformsToProtocol:@protocol(foo)]
143 /// The return type is "Protocol*".
144 class ObjCProtocolExpr : public Expr {
145 ObjCProtocolDecl *TheProtocol;
146 SourceLocation AtLoc, RParenLoc;
148 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol,
149 SourceLocation at, SourceLocation rp)
150 : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false,
152 TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {}
153 explicit ObjCProtocolExpr(EmptyShell Empty)
154 : Expr(ObjCProtocolExprClass, Empty) {}
156 ObjCProtocolDecl *getProtocol() const { return TheProtocol; }
157 void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; }
159 SourceLocation getAtLoc() const { return AtLoc; }
160 SourceLocation getRParenLoc() const { return RParenLoc; }
161 void setAtLoc(SourceLocation L) { AtLoc = L; }
162 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
164 SourceRange getSourceRange() const {
165 return SourceRange(AtLoc, RParenLoc);
168 static bool classof(const Stmt *T) {
169 return T->getStmtClass() == ObjCProtocolExprClass;
171 static bool classof(const ObjCProtocolExpr *) { return true; }
174 child_range children() { return child_range(); }
177 /// ObjCIvarRefExpr - A reference to an ObjC instance variable.
178 class ObjCIvarRefExpr : public Expr {
179 class ObjCIvarDecl *D;
182 bool IsArrow:1; // True if this is "X->F", false if this is "X.F".
183 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed).
186 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t,
187 SourceLocation l, Expr *base,
188 bool arrow = false, bool freeIvar = false) :
189 Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary,
190 /*TypeDependent=*/false, base->isValueDependent(),
191 base->isInstantiationDependent(),
192 base->containsUnexpandedParameterPack()),
193 D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {}
195 explicit ObjCIvarRefExpr(EmptyShell Empty)
196 : Expr(ObjCIvarRefExprClass, Empty) {}
198 ObjCIvarDecl *getDecl() { return D; }
199 const ObjCIvarDecl *getDecl() const { return D; }
200 void setDecl(ObjCIvarDecl *d) { D = d; }
202 const Expr *getBase() const { return cast<Expr>(Base); }
203 Expr *getBase() { return cast<Expr>(Base); }
204 void setBase(Expr * base) { Base = base; }
206 bool isArrow() const { return IsArrow; }
207 bool isFreeIvar() const { return IsFreeIvar; }
208 void setIsArrow(bool A) { IsArrow = A; }
209 void setIsFreeIvar(bool A) { IsFreeIvar = A; }
211 SourceLocation getLocation() const { return Loc; }
212 void setLocation(SourceLocation L) { Loc = L; }
214 SourceRange getSourceRange() const {
215 return isFreeIvar() ? SourceRange(Loc)
216 : SourceRange(getBase()->getLocStart(), Loc);
219 static bool classof(const Stmt *T) {
220 return T->getStmtClass() == ObjCIvarRefExprClass;
222 static bool classof(const ObjCIvarRefExpr *) { return true; }
225 child_range children() { return child_range(&Base, &Base+1); }
228 /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC
231 class ObjCPropertyRefExpr : public Expr {
233 /// If the bool is true, this is an implicit property reference; the
234 /// pointer is an (optional) ObjCMethodDecl and Setter may be set.
235 /// if the bool is false, this is an explicit property reference;
236 /// the pointer is an ObjCPropertyDecl and Setter is always null.
237 llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
238 ObjCMethodDecl *Setter;
240 SourceLocation IdLoc;
242 /// \brief When the receiver in property access is 'super', this is
243 /// the location of the 'super' keyword. When it's an interface,
244 /// this is that interface.
245 SourceLocation ReceiverLoc;
246 llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver;
249 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
250 ExprValueKind VK, ExprObjectKind OK,
251 SourceLocation l, Expr *base)
252 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
253 /*TypeDependent=*/false, base->isValueDependent(),
254 base->isInstantiationDependent(),
255 base->containsUnexpandedParameterPack()),
256 PropertyOrGetter(PD, false), Setter(0),
257 IdLoc(l), ReceiverLoc(), Receiver(base) {
260 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
261 ExprValueKind VK, ExprObjectKind OK,
262 SourceLocation l, SourceLocation sl, QualType st)
263 : Expr(ObjCPropertyRefExprClass, t, VK, OK,
264 /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
265 st->containsUnexpandedParameterPack()),
266 PropertyOrGetter(PD, false), Setter(0),
267 IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
270 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
271 QualType T, ExprValueKind VK, ExprObjectKind OK,
272 SourceLocation IdLoc, Expr *Base)
273 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
274 Base->isValueDependent(), Base->isInstantiationDependent(),
275 Base->containsUnexpandedParameterPack()),
276 PropertyOrGetter(Getter, true), Setter(Setter),
277 IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
280 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
281 QualType T, ExprValueKind VK, ExprObjectKind OK,
282 SourceLocation IdLoc,
283 SourceLocation SuperLoc, QualType SuperTy)
284 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
285 PropertyOrGetter(Getter, true), Setter(Setter),
286 IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
289 ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
290 QualType T, ExprValueKind VK, ExprObjectKind OK,
291 SourceLocation IdLoc,
292 SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
293 : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
294 PropertyOrGetter(Getter, true), Setter(Setter),
295 IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
298 explicit ObjCPropertyRefExpr(EmptyShell Empty)
299 : Expr(ObjCPropertyRefExprClass, Empty) {}
301 bool isImplicitProperty() const { return PropertyOrGetter.getInt(); }
302 bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); }
304 ObjCPropertyDecl *getExplicitProperty() const {
305 assert(!isImplicitProperty());
306 return cast<ObjCPropertyDecl>(PropertyOrGetter.getPointer());
309 ObjCMethodDecl *getImplicitPropertyGetter() const {
310 assert(isImplicitProperty());
311 return cast_or_null<ObjCMethodDecl>(PropertyOrGetter.getPointer());
314 ObjCMethodDecl *getImplicitPropertySetter() const {
315 assert(isImplicitProperty());
319 Selector getGetterSelector() const {
320 if (isImplicitProperty())
321 return getImplicitPropertyGetter()->getSelector();
322 return getExplicitProperty()->getGetterName();
325 Selector getSetterSelector() const {
326 if (isImplicitProperty())
327 return getImplicitPropertySetter()->getSelector();
328 return getExplicitProperty()->getSetterName();
331 const Expr *getBase() const {
332 return cast<Expr>(Receiver.get<Stmt*>());
335 return cast<Expr>(Receiver.get<Stmt*>());
338 SourceLocation getLocation() const { return IdLoc; }
340 SourceLocation getReceiverLocation() const { return ReceiverLoc; }
341 QualType getSuperReceiverType() const {
342 return QualType(Receiver.get<const Type*>(), 0);
344 QualType getGetterResultType() const {
346 if (isExplicitProperty()) {
347 const ObjCPropertyDecl *PDecl = getExplicitProperty();
348 if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
349 ResultType = Getter->getResultType();
351 ResultType = getType();
353 const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
354 ResultType = Getter->getResultType(); // with reference!
359 QualType getSetterArgType() const {
361 if (isImplicitProperty()) {
362 const ObjCMethodDecl *Setter = getImplicitPropertySetter();
363 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
364 ArgType = (*P)->getType();
366 if (ObjCPropertyDecl *PDecl = getExplicitProperty())
367 if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) {
368 ObjCMethodDecl::param_const_iterator P = Setter->param_begin();
369 ArgType = (*P)->getType();
371 if (ArgType.isNull())
377 ObjCInterfaceDecl *getClassReceiver() const {
378 return Receiver.get<ObjCInterfaceDecl*>();
380 bool isObjectReceiver() const { return Receiver.is<Stmt*>(); }
381 bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
382 bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
384 SourceRange getSourceRange() const {
385 return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
386 : getReceiverLocation()),
390 static bool classof(const Stmt *T) {
391 return T->getStmtClass() == ObjCPropertyRefExprClass;
393 static bool classof(const ObjCPropertyRefExpr *) { return true; }
396 child_range children() {
397 if (Receiver.is<Stmt*>()) {
398 Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack!
399 return child_range(begin, begin+1);
401 return child_range();
405 friend class ASTStmtReader;
406 void setExplicitProperty(ObjCPropertyDecl *D) {
407 PropertyOrGetter.setPointer(D);
408 PropertyOrGetter.setInt(false);
411 void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) {
412 PropertyOrGetter.setPointer(Getter);
413 PropertyOrGetter.setInt(true);
414 this->Setter = Setter;
416 void setBase(Expr *Base) { Receiver = Base; }
417 void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
418 void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; }
420 void setLocation(SourceLocation L) { IdLoc = L; }
421 void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
424 /// \brief An expression that sends a message to the given Objective-C
427 /// The following contains two message send expressions:
430 /// [[NSString alloc] initWithString:@"Hello"]
433 /// The innermost message send invokes the "alloc" class method on the
434 /// NSString class, while the outermost message send invokes the
435 /// "initWithString" instance method on the object returned from
436 /// NSString's "alloc". In all, an Objective-C message send can take
437 /// on four different (although related) forms:
439 /// 1. Send to an object instance.
440 /// 2. Send to a class.
441 /// 3. Send to the superclass instance of the current class.
442 /// 4. Send to the superclass of the current class.
444 /// All four kinds of message sends are modeled by the ObjCMessageExpr
445 /// class, and can be distinguished via \c getReceiverKind(). Example:
447 class ObjCMessageExpr : public Expr {
448 /// \brief Stores either the selector that this message is sending
449 /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
450 /// referring to the method that we type-checked against.
451 uintptr_t SelectorOrMethod;
453 enum { NumArgsBitWidth = 16 };
455 /// \brief The number of arguments in the message send, not
456 /// including the receiver.
457 unsigned NumArgs : NumArgsBitWidth;
459 void setNumArgs(unsigned Num) {
460 assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!");
464 /// \brief The kind of message send this is, which is one of the
465 /// ReceiverKind values.
467 /// We pad this out to a byte to avoid excessive masking and shifting.
470 /// \brief Whether we have an actual method prototype in \c
471 /// SelectorOrMethod.
473 /// When non-zero, we have a method declaration; otherwise, we just
475 unsigned HasMethod : 1;
477 /// \brief Whether this message send is a "delegate init call",
478 /// i.e. a call of an init method on self from within an init method.
479 unsigned IsDelegateInitCall : 1;
481 /// \brief Whether the locations of the selector identifiers are in a
482 /// "standard" position, a enum SelectorLocationsKind.
483 unsigned SelLocsKind : 2;
485 /// \brief When the message expression is a send to 'super', this is
486 /// the location of the 'super' keyword.
487 SourceLocation SuperLoc;
489 /// \brief The source locations of the open and close square
490 /// brackets ('[' and ']', respectively).
491 SourceLocation LBracLoc, RBracLoc;
493 ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
494 : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0),
495 HasMethod(0), IsDelegateInitCall(0) {
499 ObjCMessageExpr(QualType T, ExprValueKind VK,
500 SourceLocation LBracLoc,
501 SourceLocation SuperLoc,
502 bool IsInstanceSuper,
505 ArrayRef<SourceLocation> SelLocs,
506 SelectorLocationsKind SelLocsK,
507 ObjCMethodDecl *Method,
508 ArrayRef<Expr *> Args,
509 SourceLocation RBracLoc);
510 ObjCMessageExpr(QualType T, ExprValueKind VK,
511 SourceLocation LBracLoc,
512 TypeSourceInfo *Receiver,
514 ArrayRef<SourceLocation> SelLocs,
515 SelectorLocationsKind SelLocsK,
516 ObjCMethodDecl *Method,
517 ArrayRef<Expr *> Args,
518 SourceLocation RBracLoc);
519 ObjCMessageExpr(QualType T, ExprValueKind VK,
520 SourceLocation LBracLoc,
523 ArrayRef<SourceLocation> SelLocs,
524 SelectorLocationsKind SelLocsK,
525 ObjCMethodDecl *Method,
526 ArrayRef<Expr *> Args,
527 SourceLocation RBracLoc);
529 void initArgsAndSelLocs(ArrayRef<Expr *> Args,
530 ArrayRef<SourceLocation> SelLocs,
531 SelectorLocationsKind SelLocsK);
533 /// \brief Retrieve the pointer value of the message receiver.
534 void *getReceiverPointer() const {
535 return *const_cast<void **>(
536 reinterpret_cast<const void * const*>(this + 1));
539 /// \brief Set the pointer value of the message receiver.
540 void setReceiverPointer(void *Value) {
541 *reinterpret_cast<void **>(this + 1) = Value;
544 SelectorLocationsKind getSelLocsKind() const {
545 return (SelectorLocationsKind)SelLocsKind;
547 bool hasStandardSelLocs() const {
548 return getSelLocsKind() != SelLoc_NonStandard;
551 /// \brief Get a pointer to the stored selector identifiers locations array.
552 /// No locations will be stored if HasStandardSelLocs is true.
553 SourceLocation *getStoredSelLocs() {
554 return reinterpret_cast<SourceLocation*>(getArgs() + getNumArgs());
556 const SourceLocation *getStoredSelLocs() const {
557 return reinterpret_cast<const SourceLocation*>(getArgs() + getNumArgs());
560 /// \brief Get the number of stored selector identifiers locations.
561 /// No locations will be stored if HasStandardSelLocs is true.
562 unsigned getNumStoredSelLocs() const {
563 if (hasStandardSelLocs())
565 return getNumSelectorLocs();
568 static ObjCMessageExpr *alloc(ASTContext &C,
569 ArrayRef<Expr *> Args,
570 SourceLocation RBraceLoc,
571 ArrayRef<SourceLocation> SelLocs,
573 SelectorLocationsKind &SelLocsK);
574 static ObjCMessageExpr *alloc(ASTContext &C,
576 unsigned NumStoredSelLocs);
579 /// \brief The kind of receiver this message is sending to.
581 /// \brief The receiver is a class.
583 /// \brief The receiver is an object instance.
585 /// \brief The receiver is a superclass.
587 /// \brief The receiver is the instance of the superclass object.
591 /// \brief Create a message send to super.
593 /// \param Context The ASTContext in which this expression will be created.
595 /// \param T The result type of this message.
597 /// \param VK The value kind of this message. A message returning
598 /// a l-value or r-value reference will be an l-value or x-value,
601 /// \param LBrac The location of the open square bracket '['.
603 /// \param SuperLoc The location of the "super" keyword.
605 /// \param IsInstanceSuper Whether this is an instance "super"
606 /// message (otherwise, it's a class "super" message).
608 /// \param Sel The selector used to determine which method gets called.
610 /// \param Method The Objective-C method against which this message
611 /// send was type-checked. May be NULL.
613 /// \param Args The message send arguments.
615 /// \param NumArgs The number of arguments.
617 /// \param RBracLoc The location of the closing square bracket ']'.
618 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
620 SourceLocation LBracLoc,
621 SourceLocation SuperLoc,
622 bool IsInstanceSuper,
625 ArrayRef<SourceLocation> SelLocs,
626 ObjCMethodDecl *Method,
627 ArrayRef<Expr *> Args,
628 SourceLocation RBracLoc);
630 /// \brief Create a class message send.
632 /// \param Context The ASTContext in which this expression will be created.
634 /// \param T The result type of this message.
636 /// \param VK The value kind of this message. A message returning
637 /// a l-value or r-value reference will be an l-value or x-value,
640 /// \param LBrac The location of the open square bracket '['.
642 /// \param Receiver The type of the receiver, including
643 /// source-location information.
645 /// \param Sel The selector used to determine which method gets called.
647 /// \param Method The Objective-C method against which this message
648 /// send was type-checked. May be NULL.
650 /// \param Args The message send arguments.
652 /// \param NumArgs The number of arguments.
654 /// \param RBracLoc The location of the closing square bracket ']'.
655 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
657 SourceLocation LBracLoc,
658 TypeSourceInfo *Receiver,
660 ArrayRef<SourceLocation> SelLocs,
661 ObjCMethodDecl *Method,
662 ArrayRef<Expr *> Args,
663 SourceLocation RBracLoc);
665 /// \brief Create an instance message send.
667 /// \param Context The ASTContext in which this expression will be created.
669 /// \param T The result type of this message.
671 /// \param VK The value kind of this message. A message returning
672 /// a l-value or r-value reference will be an l-value or x-value,
675 /// \param LBrac The location of the open square bracket '['.
677 /// \param Receiver The expression used to produce the object that
678 /// will receive this message.
680 /// \param Sel The selector used to determine which method gets called.
682 /// \param Method The Objective-C method against which this message
683 /// send was type-checked. May be NULL.
685 /// \param Args The message send arguments.
687 /// \param NumArgs The number of arguments.
689 /// \param RBracLoc The location of the closing square bracket ']'.
690 static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
692 SourceLocation LBracLoc,
695 ArrayRef<SourceLocation> SeLocs,
696 ObjCMethodDecl *Method,
697 ArrayRef<Expr *> Args,
698 SourceLocation RBracLoc);
700 /// \brief Create an empty Objective-C message expression, to be
701 /// filled in by subsequent calls.
703 /// \param Context The context in which the message send will be created.
705 /// \param NumArgs The number of message arguments, not including
707 static ObjCMessageExpr *CreateEmpty(ASTContext &Context,
709 unsigned NumStoredSelLocs);
711 /// \brief Determine the kind of receiver that this message is being
713 ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
715 /// \brief Source range of the receiver.
716 SourceRange getReceiverRange() const;
718 /// \brief Determine whether this is an instance message to either a
719 /// computed object or to super.
720 bool isInstanceMessage() const {
721 return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
724 /// \brief Determine whether this is an class message to either a
725 /// specified class or to super.
726 bool isClassMessage() const {
727 return getReceiverKind() == Class || getReceiverKind() == SuperClass;
730 /// \brief Returns the receiver of an instance message.
732 /// \brief Returns the object expression for an instance message, or
733 /// NULL for a message that is not an instance message.
734 Expr *getInstanceReceiver() {
735 if (getReceiverKind() == Instance)
736 return static_cast<Expr *>(getReceiverPointer());
740 const Expr *getInstanceReceiver() const {
741 return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
744 /// \brief Turn this message send into an instance message that
745 /// computes the receiver object with the given expression.
746 void setInstanceReceiver(Expr *rec) {
748 setReceiverPointer(rec);
751 /// \brief Returns the type of a class message send, or NULL if the
752 /// message is not a class message.
753 QualType getClassReceiver() const {
754 if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
755 return TSInfo->getType();
760 /// \brief Returns a type-source information of a class message
761 /// send, or NULL if the message is not a class message.
762 TypeSourceInfo *getClassReceiverTypeInfo() const {
763 if (getReceiverKind() == Class)
764 return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
768 void setClassReceiver(TypeSourceInfo *TSInfo) {
770 setReceiverPointer(TSInfo);
773 /// \brief Retrieve the location of the 'super' keyword for a class
774 /// or instance message to 'super', otherwise an invalid source location.
775 SourceLocation getSuperLoc() const {
776 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
779 return SourceLocation();
782 /// \brief Retrieve the Objective-C interface to which this message
783 /// is being directed, if known.
785 /// This routine cross-cuts all of the different kinds of message
786 /// sends to determine what the underlying (statically known) type
787 /// of the receiver will be; use \c getReceiverKind() to determine
788 /// whether the message is a class or an instance method, whether it
789 /// is a send to super or not, etc.
791 /// \returns The Objective-C interface if known, otherwise NULL.
792 ObjCInterfaceDecl *getReceiverInterface() const;
794 /// \brief Retrieve the type referred to by 'super'.
796 /// The returned type will either be an ObjCInterfaceType (for an
797 /// class message to super) or an ObjCObjectPointerType that refers
798 /// to a class (for an instance message to super);
799 QualType getSuperType() const {
800 if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
801 return QualType::getFromOpaquePtr(getReceiverPointer());
806 void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
807 Kind = IsInstanceSuper? SuperInstance : SuperClass;
809 setReceiverPointer(T.getAsOpaquePtr());
812 Selector getSelector() const;
814 void setSelector(Selector S) {
816 SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
819 const ObjCMethodDecl *getMethodDecl() const {
821 return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
826 ObjCMethodDecl *getMethodDecl() {
828 return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
833 void setMethodDecl(ObjCMethodDecl *MD) {
835 SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
838 ObjCMethodFamily getMethodFamily() const {
839 if (HasMethod) return getMethodDecl()->getMethodFamily();
840 return getSelector().getMethodFamily();
843 /// \brief Return the number of actual arguments in this message,
844 /// not counting the receiver.
845 unsigned getNumArgs() const { return NumArgs; }
847 /// \brief Retrieve the arguments to this message, not including the
850 return reinterpret_cast<Expr **>(this + 1) + 1;
852 const Expr * const *getArgs() const {
853 return reinterpret_cast<const Expr * const *>(this + 1) + 1;
856 /// getArg - Return the specified argument.
857 Expr *getArg(unsigned Arg) {
858 assert(Arg < NumArgs && "Arg access out of range!");
859 return cast<Expr>(getArgs()[Arg]);
861 const Expr *getArg(unsigned Arg) const {
862 assert(Arg < NumArgs && "Arg access out of range!");
863 return cast<Expr>(getArgs()[Arg]);
865 /// setArg - Set the specified argument.
866 void setArg(unsigned Arg, Expr *ArgExpr) {
867 assert(Arg < NumArgs && "Arg access out of range!");
868 getArgs()[Arg] = ArgExpr;
871 /// isDelegateInitCall - Answers whether this message send has been
872 /// tagged as a "delegate init call", i.e. a call to a method in the
873 /// -init family on self from within an -init method implementation.
874 bool isDelegateInitCall() const { return IsDelegateInitCall; }
875 void setDelegateInitCall(bool isDelegate) { IsDelegateInitCall = isDelegate; }
877 SourceLocation getLeftLoc() const { return LBracLoc; }
878 SourceLocation getRightLoc() const { return RBracLoc; }
880 SourceLocation getSelectorStartLoc() const { return getSelectorLoc(0); }
881 SourceLocation getSelectorLoc(unsigned Index) const {
882 assert(Index < getNumSelectorLocs() && "Index out of range!");
883 if (hasStandardSelLocs())
884 return getStandardSelectorLoc(Index, getSelector(),
885 getSelLocsKind() == SelLoc_StandardWithSpace,
886 llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
889 return getStoredSelLocs()[Index];
892 void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
894 unsigned getNumSelectorLocs() const {
895 Selector Sel = getSelector();
896 if (Sel.isUnarySelector())
898 return Sel.getNumArgs();
901 void setSourceRange(SourceRange R) {
902 LBracLoc = R.getBegin();
903 RBracLoc = R.getEnd();
905 SourceRange getSourceRange() const {
906 return SourceRange(LBracLoc, RBracLoc);
909 static bool classof(const Stmt *T) {
910 return T->getStmtClass() == ObjCMessageExprClass;
912 static bool classof(const ObjCMessageExpr *) { return true; }
915 child_range children();
917 typedef ExprIterator arg_iterator;
918 typedef ConstExprIterator const_arg_iterator;
920 arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); }
921 arg_iterator arg_end() {
922 return reinterpret_cast<Stmt **>(getArgs() + NumArgs);
924 const_arg_iterator arg_begin() const {
925 return reinterpret_cast<Stmt const * const*>(getArgs());
927 const_arg_iterator arg_end() const {
928 return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs);
931 friend class ASTStmtReader;
932 friend class ASTStmtWriter;
935 /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
936 /// (similar in spirit to MemberExpr).
937 class ObjCIsaExpr : public Expr {
938 /// Base - the expression for the base object pointer.
941 /// IsaMemberLoc - This is the location of the 'isa'.
942 SourceLocation IsaMemberLoc;
944 /// IsArrow - True if this is "X->F", false if this is "X.F".
947 ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
948 : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary,
949 /*TypeDependent=*/false, base->isValueDependent(),
950 base->isInstantiationDependent(),
951 /*ContainsUnexpandedParameterPack=*/false),
952 Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
954 /// \brief Build an empty expression.
955 explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { }
957 void setBase(Expr *E) { Base = E; }
958 Expr *getBase() const { return cast<Expr>(Base); }
960 bool isArrow() const { return IsArrow; }
961 void setArrow(bool A) { IsArrow = A; }
963 /// getMemberLoc - Return the location of the "member", in X->F, it is the
965 SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
966 void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
968 SourceRange getSourceRange() const {
969 return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
972 SourceLocation getExprLoc() const { return IsaMemberLoc; }
974 static bool classof(const Stmt *T) {
975 return T->getStmtClass() == ObjCIsaExprClass;
977 static bool classof(const ObjCIsaExpr *) { return true; }
980 child_range children() { return child_range(&Base, &Base+1); }
984 /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function
985 /// argument by indirect copy-restore in ARC. This is used to support
986 /// passing indirect arguments with the wrong lifetime, e.g. when
987 /// passing the address of a __strong local variable to an 'out'
988 /// parameter. This expression kind is only valid in an "argument"
989 /// position to some sort of call expression.
991 /// The parameter must have type 'pointer to T', and the argument must
992 /// have type 'pointer to U', where T and U agree except possibly in
993 /// qualification. If the argument value is null, then a null pointer
994 /// is passed; otherwise it points to an object A, and:
995 /// 1. A temporary object B of type T is initialized, either by
996 /// zero-initialization (used when initializing an 'out' parameter)
997 /// or copy-initialization (used when initializing an 'inout'
999 /// 2. The address of the temporary is passed to the function.
1000 /// 3. If the call completes normally, A is move-assigned from B.
1001 /// 4. Finally, A is destroyed immediately.
1003 /// Currently 'T' must be a retainable object lifetime and must be
1004 /// __autoreleasing; this qualifier is ignored when initializing
1006 class ObjCIndirectCopyRestoreExpr : public Expr {
1009 // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1;
1011 friend class ASTReader;
1012 friend class ASTStmtReader;
1014 void setShouldCopy(bool shouldCopy) {
1015 ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy;
1018 explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty)
1019 : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { }
1022 ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy)
1023 : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary,
1024 operand->isTypeDependent(), operand->isValueDependent(),
1025 operand->isInstantiationDependent(),
1026 operand->containsUnexpandedParameterPack()),
1028 setShouldCopy(shouldCopy);
1031 Expr *getSubExpr() { return cast<Expr>(Operand); }
1032 const Expr *getSubExpr() const { return cast<Expr>(Operand); }
1034 /// shouldCopy - True if we should do the 'copy' part of the
1035 /// copy-restore. If false, the temporary will be zero-initialized.
1036 bool shouldCopy() const { return ObjCIndirectCopyRestoreExprBits.ShouldCopy; }
1038 child_range children() { return child_range(&Operand, &Operand+1); }
1040 // Source locations are determined by the subexpression.
1041 SourceRange getSourceRange() const { return Operand->getSourceRange(); }
1042 SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); }
1044 static bool classof(const Stmt *s) {
1045 return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
1047 static bool classof(const ObjCIndirectCopyRestoreExpr *) { return true; }
1050 /// \brief An Objective-C "bridged" cast expression, which casts between
1051 /// Objective-C pointers and C pointers, transferring ownership in the process.
1054 /// NSString *str = (__bridge_transfer NSString *)CFCreateString();
1056 class ObjCBridgedCastExpr : public ExplicitCastExpr {
1057 SourceLocation LParenLoc;
1058 SourceLocation BridgeKeywordLoc;
1061 friend class ASTStmtReader;
1062 friend class ASTStmtWriter;
1065 ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind,
1066 CastKind CK, SourceLocation BridgeKeywordLoc,
1067 TypeSourceInfo *TSInfo, Expr *Operand)
1068 : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
1069 CK, Operand, 0, TSInfo),
1070 LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { }
1072 /// \brief Construct an empty Objective-C bridged cast.
1073 explicit ObjCBridgedCastExpr(EmptyShell Shell)
1074 : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { }
1076 SourceLocation getLParenLoc() const { return LParenLoc; }
1078 /// \brief Determine which kind of bridge is being performed via this cast.
1079 ObjCBridgeCastKind getBridgeKind() const {
1080 return static_cast<ObjCBridgeCastKind>(Kind);
1083 /// \brief Retrieve the kind of bridge being performed as a string.
1084 StringRef getBridgeKindName() const;
1086 /// \brief The location of the bridge keyword.
1087 SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
1089 SourceRange getSourceRange() const {
1090 return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
1093 static bool classof(const Stmt *T) {
1094 return T->getStmtClass() == ObjCBridgedCastExprClass;
1096 static bool classof(const ObjCBridgedCastExpr *) { return true; }
1100 } // end namespace clang